vhost: Add event index for interrupt notification to driver
[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 #include <vnet/format_fns.h>
85
86 void vl_api_set_elog_main (elog_main_t * m);
87 int vl_api_set_elog_trace_api_messages (int enable);
88
89 #if VPP_API_TEST_BUILTIN == 0
90 #include <netdb.h>
91
92 u32
93 vl (void *p)
94 {
95   return vec_len (p);
96 }
97
98 int
99 vat_socket_connect (vat_main_t * vam)
100 {
101   int rv;
102   api_main_t *am = vlibapi_get_main ();
103   vam->socket_client_main = &socket_client_main;
104   if ((rv = vl_socket_client_connect ((char *) vam->socket_name,
105                                       "vpp_api_test",
106                                       0 /* default socket rx, tx buffer */ )))
107     return rv;
108
109   /* vpp expects the client index in network order */
110   vam->my_client_index = htonl (socket_client_main.client_index);
111   am->my_client_index = vam->my_client_index;
112   return 0;
113 }
114 #else /* vpp built-in case, we don't do sockets... */
115 int
116 vat_socket_connect (vat_main_t * vam)
117 {
118   return 0;
119 }
120
121 int
122 vl_socket_client_read (int wait)
123 {
124   return -1;
125 };
126
127 int
128 vl_socket_client_write ()
129 {
130   return -1;
131 };
132
133 void *
134 vl_socket_client_msg_alloc (int nbytes)
135 {
136   return 0;
137 }
138 #endif
139
140
141 f64
142 vat_time_now (vat_main_t * vam)
143 {
144 #if VPP_API_TEST_BUILTIN
145   return vlib_time_now (vam->vlib_main);
146 #else
147   return clib_time_now (&vam->clib_time);
148 #endif
149 }
150
151 void
152 errmsg (char *fmt, ...)
153 {
154   vat_main_t *vam = &vat_main;
155   va_list va;
156   u8 *s;
157
158   va_start (va, fmt);
159   s = va_format (0, fmt, &va);
160   va_end (va);
161
162   vec_add1 (s, 0);
163
164 #if VPP_API_TEST_BUILTIN
165   vlib_cli_output (vam->vlib_main, (char *) s);
166 #else
167   {
168     if (vam->ifp != stdin)
169       fformat (vam->ofp, "%s(%d): \n", vam->current_file,
170                vam->input_line_number);
171     else
172       fformat (vam->ofp, "%s\n", (char *) s);
173     fflush (vam->ofp);
174   }
175 #endif
176
177   vec_free (s);
178 }
179
180 #if VPP_API_TEST_BUILTIN == 0
181 static uword
182 api_unformat_sw_if_index (unformat_input_t * input, va_list * args)
183 {
184   vat_main_t *vam = va_arg (*args, vat_main_t *);
185   u32 *result = va_arg (*args, u32 *);
186   u8 *if_name;
187   uword *p;
188
189   if (!unformat (input, "%s", &if_name))
190     return 0;
191
192   p = hash_get_mem (vam->sw_if_index_by_interface_name, if_name);
193   if (p == 0)
194     return 0;
195   *result = p[0];
196   return 1;
197 }
198
199 static uword
200 api_unformat_hw_if_index (unformat_input_t * input, va_list * args)
201 {
202   return 0;
203 }
204
205 /* Parse an IP4 address %d.%d.%d.%d. */
206 uword
207 unformat_ip4_address (unformat_input_t * input, va_list * args)
208 {
209   u8 *result = va_arg (*args, u8 *);
210   unsigned a[4];
211
212   if (!unformat (input, "%d.%d.%d.%d", &a[0], &a[1], &a[2], &a[3]))
213     return 0;
214
215   if (a[0] >= 256 || a[1] >= 256 || a[2] >= 256 || a[3] >= 256)
216     return 0;
217
218   result[0] = a[0];
219   result[1] = a[1];
220   result[2] = a[2];
221   result[3] = a[3];
222
223   return 1;
224 }
225
226 uword
227 unformat_ethernet_address (unformat_input_t * input, va_list * args)
228 {
229   u8 *result = va_arg (*args, u8 *);
230   u32 i, a[6];
231
232   if (!unformat (input, "%_%x:%x:%x:%x:%x:%x%_",
233                  &a[0], &a[1], &a[2], &a[3], &a[4], &a[5]))
234     return 0;
235
236   /* Check range. */
237   for (i = 0; i < 6; i++)
238     if (a[i] >= (1 << 8))
239       return 0;
240
241   for (i = 0; i < 6; i++)
242     result[i] = a[i];
243
244   return 1;
245 }
246
247 /* Returns ethernet type as an int in host byte order. */
248 uword
249 unformat_ethernet_type_host_byte_order (unformat_input_t * input,
250                                         va_list * args)
251 {
252   u16 *result = va_arg (*args, u16 *);
253   int type;
254
255   /* Numeric type. */
256   if (unformat (input, "0x%x", &type) || unformat (input, "%d", &type))
257     {
258       if (type >= (1 << 16))
259         return 0;
260       *result = type;
261       return 1;
262     }
263   return 0;
264 }
265
266 /* Parse an IP46 address. */
267 uword
268 unformat_ip46_address (unformat_input_t * input, va_list * args)
269 {
270   ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
271   ip46_type_t type = va_arg (*args, ip46_type_t);
272   if ((type != IP46_TYPE_IP6) &&
273       unformat (input, "%U", unformat_ip4_address, &ip46->ip4))
274     {
275       ip46_address_mask_ip4 (ip46);
276       return 1;
277     }
278   else if ((type != IP46_TYPE_IP4) &&
279            unformat (input, "%U", unformat_ip6_address, &ip46->ip6))
280     {
281       return 1;
282     }
283   return 0;
284 }
285
286 /* Parse an IP6 address. */
287 uword
288 unformat_ip6_address (unformat_input_t * input, va_list * args)
289 {
290   ip6_address_t *result = va_arg (*args, ip6_address_t *);
291   u16 hex_quads[8];
292   uword hex_quad, n_hex_quads, hex_digit, n_hex_digits;
293   uword c, n_colon, double_colon_index;
294
295   n_hex_quads = hex_quad = n_hex_digits = n_colon = 0;
296   double_colon_index = ARRAY_LEN (hex_quads);
297   while ((c = unformat_get_input (input)) != UNFORMAT_END_OF_INPUT)
298     {
299       hex_digit = 16;
300       if (c >= '0' && c <= '9')
301         hex_digit = c - '0';
302       else if (c >= 'a' && c <= 'f')
303         hex_digit = c + 10 - 'a';
304       else if (c >= 'A' && c <= 'F')
305         hex_digit = c + 10 - 'A';
306       else if (c == ':' && n_colon < 2)
307         n_colon++;
308       else
309         {
310           unformat_put_input (input);
311           break;
312         }
313
314       /* Too many hex quads. */
315       if (n_hex_quads >= ARRAY_LEN (hex_quads))
316         return 0;
317
318       if (hex_digit < 16)
319         {
320           hex_quad = (hex_quad << 4) | hex_digit;
321
322           /* Hex quad must fit in 16 bits. */
323           if (n_hex_digits >= 4)
324             return 0;
325
326           n_colon = 0;
327           n_hex_digits++;
328         }
329
330       /* Save position of :: */
331       if (n_colon == 2)
332         {
333           /* More than one :: ? */
334           if (double_colon_index < ARRAY_LEN (hex_quads))
335             return 0;
336           double_colon_index = n_hex_quads;
337         }
338
339       if (n_colon > 0 && n_hex_digits > 0)
340         {
341           hex_quads[n_hex_quads++] = hex_quad;
342           hex_quad = 0;
343           n_hex_digits = 0;
344         }
345     }
346
347   if (n_hex_digits > 0)
348     hex_quads[n_hex_quads++] = hex_quad;
349
350   {
351     word i;
352
353     /* Expand :: to appropriate number of zero hex quads. */
354     if (double_colon_index < ARRAY_LEN (hex_quads))
355       {
356         word n_zero = ARRAY_LEN (hex_quads) - n_hex_quads;
357
358         for (i = n_hex_quads - 1; i >= (signed) double_colon_index; i--)
359           hex_quads[n_zero + i] = hex_quads[i];
360
361         for (i = 0; i < n_zero; i++)
362           hex_quads[double_colon_index + i] = 0;
363
364         n_hex_quads = ARRAY_LEN (hex_quads);
365       }
366
367     /* Too few hex quads given. */
368     if (n_hex_quads < ARRAY_LEN (hex_quads))
369       return 0;
370
371     for (i = 0; i < ARRAY_LEN (hex_quads); i++)
372       result->as_u16[i] = clib_host_to_net_u16 (hex_quads[i]);
373
374     return 1;
375   }
376 }
377
378 uword
379 unformat_ipsec_policy_action (unformat_input_t * input, va_list * args)
380 {
381   u32 *r = va_arg (*args, u32 *);
382
383   if (0);
384 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_POLICY_ACTION_##f;
385   foreach_ipsec_policy_action
386 #undef _
387     else
388     return 0;
389   return 1;
390 }
391
392 u8 *
393 format_ipsec_crypto_alg (u8 * s, va_list * args)
394 {
395   u32 i = va_arg (*args, u32);
396   u8 *t = 0;
397
398   switch (i)
399     {
400 #define _(v,f,str) case IPSEC_CRYPTO_ALG_##f: t = (u8 *) str; break;
401       foreach_ipsec_crypto_alg
402 #undef _
403     default:
404       return format (s, "unknown");
405     }
406   return format (s, "%s", t);
407 }
408
409 u8 *
410 format_ipsec_integ_alg (u8 * s, va_list * args)
411 {
412   u32 i = va_arg (*args, u32);
413   u8 *t = 0;
414
415   switch (i)
416     {
417 #define _(v,f,str) case IPSEC_INTEG_ALG_##f: t = (u8 *) str; break;
418       foreach_ipsec_integ_alg
419 #undef _
420     default:
421       return format (s, "unknown");
422     }
423   return format (s, "%s", t);
424 }
425
426 #else /* VPP_API_TEST_BUILTIN == 1 */
427 static uword
428 api_unformat_sw_if_index (unformat_input_t * input, va_list * args)
429 {
430   vat_main_t *vam __clib_unused = va_arg (*args, vat_main_t *);
431   vnet_main_t *vnm = vnet_get_main ();
432   u32 *result = va_arg (*args, u32 *);
433
434   return unformat (input, "%U", unformat_vnet_sw_interface, vnm, result);
435 }
436
437 static uword
438 api_unformat_hw_if_index (unformat_input_t * input, va_list * args)
439 {
440   vat_main_t *vam __clib_unused = va_arg (*args, vat_main_t *);
441   vnet_main_t *vnm = vnet_get_main ();
442   u32 *result = va_arg (*args, u32 *);
443
444   return unformat (input, "%U", unformat_vnet_hw_interface, vnm, result);
445 }
446
447 #endif /* VPP_API_TEST_BUILTIN */
448
449 uword
450 unformat_ipsec_api_crypto_alg (unformat_input_t * input, va_list * args)
451 {
452   u32 *r = va_arg (*args, u32 *);
453
454   if (0);
455 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_API_CRYPTO_ALG_##f;
456   foreach_ipsec_crypto_alg
457 #undef _
458     else
459     return 0;
460   return 1;
461 }
462
463 uword
464 unformat_ipsec_api_integ_alg (unformat_input_t * input, va_list * args)
465 {
466   u32 *r = va_arg (*args, u32 *);
467
468   if (0);
469 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_API_INTEG_ALG_##f;
470   foreach_ipsec_integ_alg
471 #undef _
472     else
473     return 0;
474   return 1;
475 }
476
477 static uword
478 unformat_policer_rate_type (unformat_input_t * input, va_list * args)
479 {
480   u8 *r = va_arg (*args, u8 *);
481
482   if (unformat (input, "kbps"))
483     *r = SSE2_QOS_RATE_KBPS;
484   else if (unformat (input, "pps"))
485     *r = SSE2_QOS_RATE_PPS;
486   else
487     return 0;
488   return 1;
489 }
490
491 static uword
492 unformat_policer_round_type (unformat_input_t * input, va_list * args)
493 {
494   u8 *r = va_arg (*args, u8 *);
495
496   if (unformat (input, "closest"))
497     *r = SSE2_QOS_ROUND_TO_CLOSEST;
498   else if (unformat (input, "up"))
499     *r = SSE2_QOS_ROUND_TO_UP;
500   else if (unformat (input, "down"))
501     *r = SSE2_QOS_ROUND_TO_DOWN;
502   else
503     return 0;
504   return 1;
505 }
506
507 static uword
508 unformat_policer_type (unformat_input_t * input, va_list * args)
509 {
510   u8 *r = va_arg (*args, u8 *);
511
512   if (unformat (input, "1r2c"))
513     *r = SSE2_QOS_POLICER_TYPE_1R2C;
514   else if (unformat (input, "1r3c"))
515     *r = SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697;
516   else if (unformat (input, "2r3c-2698"))
517     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698;
518   else if (unformat (input, "2r3c-4115"))
519     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115;
520   else if (unformat (input, "2r3c-mef5cf1"))
521     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1;
522   else
523     return 0;
524   return 1;
525 }
526
527 static uword
528 unformat_dscp (unformat_input_t * input, va_list * va)
529 {
530   u8 *r = va_arg (*va, u8 *);
531
532   if (0);
533 #define _(v,f,str) else if (unformat (input, str)) *r = VNET_DSCP_##f;
534   foreach_vnet_dscp
535 #undef _
536     else
537     return 0;
538   return 1;
539 }
540
541 static uword
542 unformat_policer_action_type (unformat_input_t * input, va_list * va)
543 {
544   sse2_qos_pol_action_params_st *a
545     = va_arg (*va, sse2_qos_pol_action_params_st *);
546
547   if (unformat (input, "drop"))
548     a->action_type = SSE2_QOS_ACTION_DROP;
549   else if (unformat (input, "transmit"))
550     a->action_type = SSE2_QOS_ACTION_TRANSMIT;
551   else if (unformat (input, "mark-and-transmit %U", unformat_dscp, &a->dscp))
552     a->action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
553   else
554     return 0;
555   return 1;
556 }
557
558 static uword
559 unformat_policer_classify_table_type (unformat_input_t * input, va_list * va)
560 {
561   u32 *r = va_arg (*va, u32 *);
562   u32 tid;
563
564   if (unformat (input, "ip4"))
565     tid = POLICER_CLASSIFY_TABLE_IP4;
566   else if (unformat (input, "ip6"))
567     tid = POLICER_CLASSIFY_TABLE_IP6;
568   else if (unformat (input, "l2"))
569     tid = POLICER_CLASSIFY_TABLE_L2;
570   else
571     return 0;
572
573   *r = tid;
574   return 1;
575 }
576
577 static uword
578 unformat_flow_classify_table_type (unformat_input_t * input, va_list * va)
579 {
580   u32 *r = va_arg (*va, u32 *);
581   u32 tid;
582
583   if (unformat (input, "ip4"))
584     tid = FLOW_CLASSIFY_TABLE_IP4;
585   else if (unformat (input, "ip6"))
586     tid = FLOW_CLASSIFY_TABLE_IP6;
587   else
588     return 0;
589
590   *r = tid;
591   return 1;
592 }
593
594 #if (VPP_API_TEST_BUILTIN==0)
595
596 static const char *mfib_flag_names[] = MFIB_ENTRY_NAMES_SHORT;
597 static const char *mfib_flag_long_names[] = MFIB_ENTRY_NAMES_LONG;
598 static const char *mfib_itf_flag_long_names[] = MFIB_ITF_NAMES_LONG;
599 static const char *mfib_itf_flag_names[] = MFIB_ITF_NAMES_SHORT;
600
601 uword
602 unformat_mfib_itf_flags (unformat_input_t * input, va_list * args)
603 {
604   mfib_itf_flags_t old, *iflags = va_arg (*args, mfib_itf_flags_t *);
605   mfib_itf_attribute_t attr;
606
607   old = *iflags;
608   FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
609   {
610     if (unformat (input, mfib_itf_flag_long_names[attr]))
611       *iflags |= (1 << attr);
612   }
613   FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
614   {
615     if (unformat (input, mfib_itf_flag_names[attr]))
616       *iflags |= (1 << attr);
617   }
618
619   return (old == *iflags ? 0 : 1);
620 }
621
622 uword
623 unformat_mfib_entry_flags (unformat_input_t * input, va_list * args)
624 {
625   mfib_entry_flags_t old, *eflags = va_arg (*args, mfib_entry_flags_t *);
626   mfib_entry_attribute_t attr;
627
628   old = *eflags;
629   FOR_EACH_MFIB_ATTRIBUTE (attr)
630   {
631     if (unformat (input, mfib_flag_long_names[attr]))
632       *eflags |= (1 << attr);
633   }
634   FOR_EACH_MFIB_ATTRIBUTE (attr)
635   {
636     if (unformat (input, mfib_flag_names[attr]))
637       *eflags |= (1 << attr);
638   }
639
640   return (old == *eflags ? 0 : 1);
641 }
642
643 u8 *
644 format_ip4_address (u8 * s, va_list * args)
645 {
646   u8 *a = va_arg (*args, u8 *);
647   return format (s, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]);
648 }
649
650 u8 *
651 format_ip6_address (u8 * s, va_list * args)
652 {
653   ip6_address_t *a = va_arg (*args, ip6_address_t *);
654   u32 i, i_max_n_zero, max_n_zeros, i_first_zero, n_zeros, last_double_colon;
655
656   i_max_n_zero = ARRAY_LEN (a->as_u16);
657   max_n_zeros = 0;
658   i_first_zero = i_max_n_zero;
659   n_zeros = 0;
660   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
661     {
662       u32 is_zero = a->as_u16[i] == 0;
663       if (is_zero && i_first_zero >= ARRAY_LEN (a->as_u16))
664         {
665           i_first_zero = i;
666           n_zeros = 0;
667         }
668       n_zeros += is_zero;
669       if ((!is_zero && n_zeros > max_n_zeros)
670           || (i + 1 >= ARRAY_LEN (a->as_u16) && n_zeros > max_n_zeros))
671         {
672           i_max_n_zero = i_first_zero;
673           max_n_zeros = n_zeros;
674           i_first_zero = ARRAY_LEN (a->as_u16);
675           n_zeros = 0;
676         }
677     }
678
679   last_double_colon = 0;
680   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
681     {
682       if (i == i_max_n_zero && max_n_zeros > 1)
683         {
684           s = format (s, "::");
685           i += max_n_zeros - 1;
686           last_double_colon = 1;
687         }
688       else
689         {
690           s = format (s, "%s%x",
691                       (last_double_colon || i == 0) ? "" : ":",
692                       clib_net_to_host_u16 (a->as_u16[i]));
693           last_double_colon = 0;
694         }
695     }
696
697   return s;
698 }
699
700 /* Format an IP46 address. */
701 u8 *
702 format_ip46_address (u8 * s, va_list * args)
703 {
704   ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
705   ip46_type_t type = va_arg (*args, ip46_type_t);
706   int is_ip4 = 1;
707
708   switch (type)
709     {
710     case IP46_TYPE_ANY:
711       is_ip4 = ip46_address_is_ip4 (ip46);
712       break;
713     case IP46_TYPE_IP4:
714       is_ip4 = 1;
715       break;
716     case IP46_TYPE_IP6:
717       is_ip4 = 0;
718       break;
719     }
720
721   return is_ip4 ?
722     format (s, "%U", format_ip4_address, &ip46->ip4) :
723     format (s, "%U", format_ip6_address, &ip46->ip6);
724 }
725
726 u8 *
727 format_ethernet_address (u8 * s, va_list * args)
728 {
729   u8 *a = va_arg (*args, u8 *);
730
731   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
732                  a[0], a[1], a[2], a[3], a[4], a[5]);
733 }
734 #endif
735
736 static void
737 increment_v4_address (vl_api_ip4_address_t * i)
738 {
739   ip4_address_t *a = (ip4_address_t *) i;
740   u32 v;
741
742   v = ntohl (a->as_u32) + 1;
743   a->as_u32 = ntohl (v);
744 }
745
746 static void
747 increment_v6_address (vl_api_ip6_address_t * i)
748 {
749   ip6_address_t *a = (ip6_address_t *) i;
750   u64 v0, v1;
751
752   v0 = clib_net_to_host_u64 (a->as_u64[0]);
753   v1 = clib_net_to_host_u64 (a->as_u64[1]);
754
755   v1 += 1;
756   if (v1 == 0)
757     v0 += 1;
758   a->as_u64[0] = clib_net_to_host_u64 (v0);
759   a->as_u64[1] = clib_net_to_host_u64 (v1);
760 }
761
762 static void
763 increment_address (vl_api_address_t * a)
764 {
765   if (a->af == ADDRESS_IP4)
766     increment_v4_address (&a->un.ip4);
767   else if (a->af == ADDRESS_IP6)
768     increment_v6_address (&a->un.ip6);
769 }
770
771 static void
772 set_ip4_address (vl_api_address_t * a, u32 v)
773 {
774   if (a->af == ADDRESS_IP4)
775     {
776       ip4_address_t *i = (ip4_address_t *) & a->un.ip4;
777       i->as_u32 = v;
778     }
779 }
780
781 void
782 ip_set (ip46_address_t * dst, void *src, u8 is_ip4)
783 {
784   if (is_ip4)
785     dst->ip4.as_u32 = ((ip4_address_t *) src)->as_u32;
786   else
787     clib_memcpy_fast (&dst->ip6, (ip6_address_t *) src,
788                       sizeof (ip6_address_t));
789 }
790
791 static void
792 increment_mac_address (u8 * mac)
793 {
794   u64 tmp = *((u64 *) mac);
795   tmp = clib_net_to_host_u64 (tmp);
796   tmp += 1 << 16;               /* skip unused (least significant) octets */
797   tmp = clib_host_to_net_u64 (tmp);
798
799   clib_memcpy (mac, &tmp, 6);
800 }
801
802 static void
803 vat_json_object_add_address (vat_json_node_t * node,
804                              const char *str, const vl_api_address_t * addr)
805 {
806   if (ADDRESS_IP6 == addr->af)
807     {
808       struct in6_addr ip6;
809
810       clib_memcpy (&ip6, &addr->un.ip6, sizeof (ip6));
811       vat_json_object_add_ip6 (node, str, ip6);
812     }
813   else
814     {
815       struct in_addr ip4;
816
817       clib_memcpy (&ip4, &addr->un.ip4, sizeof (ip4));
818       vat_json_object_add_ip4 (node, str, ip4);
819     }
820 }
821
822 static void
823 vat_json_object_add_prefix (vat_json_node_t * node,
824                             const vl_api_prefix_t * prefix)
825 {
826   vat_json_object_add_uint (node, "len", prefix->len);
827   vat_json_object_add_address (node, "address", &prefix->address);
828 }
829
830 static void vl_api_create_loopback_reply_t_handler
831   (vl_api_create_loopback_reply_t * mp)
832 {
833   vat_main_t *vam = &vat_main;
834   i32 retval = ntohl (mp->retval);
835
836   vam->retval = retval;
837   vam->regenerate_interface_table = 1;
838   vam->sw_if_index = ntohl (mp->sw_if_index);
839   vam->result_ready = 1;
840 }
841
842 static void vl_api_create_loopback_reply_t_handler_json
843   (vl_api_create_loopback_reply_t * mp)
844 {
845   vat_main_t *vam = &vat_main;
846   vat_json_node_t node;
847
848   vat_json_init_object (&node);
849   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
850   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
851
852   vat_json_print (vam->ofp, &node);
853   vat_json_free (&node);
854   vam->retval = ntohl (mp->retval);
855   vam->result_ready = 1;
856 }
857
858 static void vl_api_create_loopback_instance_reply_t_handler
859   (vl_api_create_loopback_instance_reply_t * mp)
860 {
861   vat_main_t *vam = &vat_main;
862   i32 retval = ntohl (mp->retval);
863
864   vam->retval = retval;
865   vam->regenerate_interface_table = 1;
866   vam->sw_if_index = ntohl (mp->sw_if_index);
867   vam->result_ready = 1;
868 }
869
870 static void vl_api_create_loopback_instance_reply_t_handler_json
871   (vl_api_create_loopback_instance_reply_t * mp)
872 {
873   vat_main_t *vam = &vat_main;
874   vat_json_node_t node;
875
876   vat_json_init_object (&node);
877   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
878   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
879
880   vat_json_print (vam->ofp, &node);
881   vat_json_free (&node);
882   vam->retval = ntohl (mp->retval);
883   vam->result_ready = 1;
884 }
885
886 static void vl_api_af_packet_create_reply_t_handler
887   (vl_api_af_packet_create_reply_t * mp)
888 {
889   vat_main_t *vam = &vat_main;
890   i32 retval = ntohl (mp->retval);
891
892   vam->retval = retval;
893   vam->regenerate_interface_table = 1;
894   vam->sw_if_index = ntohl (mp->sw_if_index);
895   vam->result_ready = 1;
896 }
897
898 static void vl_api_af_packet_create_reply_t_handler_json
899   (vl_api_af_packet_create_reply_t * mp)
900 {
901   vat_main_t *vam = &vat_main;
902   vat_json_node_t node;
903
904   vat_json_init_object (&node);
905   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
906   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
907
908   vat_json_print (vam->ofp, &node);
909   vat_json_free (&node);
910
911   vam->retval = ntohl (mp->retval);
912   vam->result_ready = 1;
913 }
914
915 static void vl_api_create_vlan_subif_reply_t_handler
916   (vl_api_create_vlan_subif_reply_t * mp)
917 {
918   vat_main_t *vam = &vat_main;
919   i32 retval = ntohl (mp->retval);
920
921   vam->retval = retval;
922   vam->regenerate_interface_table = 1;
923   vam->sw_if_index = ntohl (mp->sw_if_index);
924   vam->result_ready = 1;
925 }
926
927 static void vl_api_create_vlan_subif_reply_t_handler_json
928   (vl_api_create_vlan_subif_reply_t * mp)
929 {
930   vat_main_t *vam = &vat_main;
931   vat_json_node_t node;
932
933   vat_json_init_object (&node);
934   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
935   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
936
937   vat_json_print (vam->ofp, &node);
938   vat_json_free (&node);
939
940   vam->retval = ntohl (mp->retval);
941   vam->result_ready = 1;
942 }
943
944 static void vl_api_create_subif_reply_t_handler
945   (vl_api_create_subif_reply_t * mp)
946 {
947   vat_main_t *vam = &vat_main;
948   i32 retval = ntohl (mp->retval);
949
950   vam->retval = retval;
951   vam->regenerate_interface_table = 1;
952   vam->sw_if_index = ntohl (mp->sw_if_index);
953   vam->result_ready = 1;
954 }
955
956 static void vl_api_create_subif_reply_t_handler_json
957   (vl_api_create_subif_reply_t * mp)
958 {
959   vat_main_t *vam = &vat_main;
960   vat_json_node_t node;
961
962   vat_json_init_object (&node);
963   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
964   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
965
966   vat_json_print (vam->ofp, &node);
967   vat_json_free (&node);
968
969   vam->retval = ntohl (mp->retval);
970   vam->result_ready = 1;
971 }
972
973 static void vl_api_interface_name_renumber_reply_t_handler
974   (vl_api_interface_name_renumber_reply_t * mp)
975 {
976   vat_main_t *vam = &vat_main;
977   i32 retval = ntohl (mp->retval);
978
979   vam->retval = retval;
980   vam->regenerate_interface_table = 1;
981   vam->result_ready = 1;
982 }
983
984 static void vl_api_interface_name_renumber_reply_t_handler_json
985   (vl_api_interface_name_renumber_reply_t * mp)
986 {
987   vat_main_t *vam = &vat_main;
988   vat_json_node_t node;
989
990   vat_json_init_object (&node);
991   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
992
993   vat_json_print (vam->ofp, &node);
994   vat_json_free (&node);
995
996   vam->retval = ntohl (mp->retval);
997   vam->result_ready = 1;
998 }
999
1000 /*
1001  * Special-case: build the interface table, maintain
1002  * the next loopback sw_if_index vbl.
1003  */
1004 static void vl_api_sw_interface_details_t_handler
1005   (vl_api_sw_interface_details_t * mp)
1006 {
1007   vat_main_t *vam = &vat_main;
1008   u8 *s = format (0, "%s%c", mp->interface_name, 0);
1009
1010   hash_set_mem (vam->sw_if_index_by_interface_name, s,
1011                 ntohl (mp->sw_if_index));
1012
1013   /* In sub interface case, fill the sub interface table entry */
1014   if (mp->sw_if_index != mp->sup_sw_if_index)
1015     {
1016       sw_interface_subif_t *sub = NULL;
1017
1018       vec_add2 (vam->sw_if_subif_table, sub, 1);
1019
1020       vec_validate (sub->interface_name, strlen ((char *) s) + 1);
1021       strncpy ((char *) sub->interface_name, (char *) s,
1022                vec_len (sub->interface_name));
1023       sub->sw_if_index = ntohl (mp->sw_if_index);
1024       sub->sub_id = ntohl (mp->sub_id);
1025
1026       sub->raw_flags = ntohl (mp->sub_if_flags & SUB_IF_API_FLAG_MASK_VNET);
1027
1028       sub->sub_number_of_tags = mp->sub_number_of_tags;
1029       sub->sub_outer_vlan_id = ntohs (mp->sub_outer_vlan_id);
1030       sub->sub_inner_vlan_id = ntohs (mp->sub_inner_vlan_id);
1031
1032       /* vlan tag rewrite */
1033       sub->vtr_op = ntohl (mp->vtr_op);
1034       sub->vtr_push_dot1q = ntohl (mp->vtr_push_dot1q);
1035       sub->vtr_tag1 = ntohl (mp->vtr_tag1);
1036       sub->vtr_tag2 = ntohl (mp->vtr_tag2);
1037     }
1038 }
1039
1040 static void vl_api_sw_interface_details_t_handler_json
1041   (vl_api_sw_interface_details_t * mp)
1042 {
1043   vat_main_t *vam = &vat_main;
1044   vat_json_node_t *node = NULL;
1045
1046   if (VAT_JSON_ARRAY != vam->json_tree.type)
1047     {
1048       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1049       vat_json_init_array (&vam->json_tree);
1050     }
1051   node = vat_json_array_add (&vam->json_tree);
1052
1053   vat_json_init_object (node);
1054   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
1055   vat_json_object_add_uint (node, "sup_sw_if_index",
1056                             ntohl (mp->sup_sw_if_index));
1057   vat_json_object_add_bytes (node, "l2_address", mp->l2_address,
1058                              sizeof (mp->l2_address));
1059   vat_json_object_add_string_copy (node, "interface_name",
1060                                    mp->interface_name);
1061   vat_json_object_add_string_copy (node, "interface_dev_type",
1062                                    mp->interface_dev_type);
1063   vat_json_object_add_uint (node, "flags", mp->flags);
1064   vat_json_object_add_uint (node, "link_duplex", mp->link_duplex);
1065   vat_json_object_add_uint (node, "link_speed", mp->link_speed);
1066   vat_json_object_add_uint (node, "mtu", ntohs (mp->link_mtu));
1067   vat_json_object_add_uint (node, "sub_id", ntohl (mp->sub_id));
1068   vat_json_object_add_uint (node, "sub_number_of_tags",
1069                             mp->sub_number_of_tags);
1070   vat_json_object_add_uint (node, "sub_outer_vlan_id",
1071                             ntohs (mp->sub_outer_vlan_id));
1072   vat_json_object_add_uint (node, "sub_inner_vlan_id",
1073                             ntohs (mp->sub_inner_vlan_id));
1074   vat_json_object_add_uint (node, "sub_if_flags", ntohl (mp->sub_if_flags));
1075   vat_json_object_add_uint (node, "vtr_op", ntohl (mp->vtr_op));
1076   vat_json_object_add_uint (node, "vtr_push_dot1q",
1077                             ntohl (mp->vtr_push_dot1q));
1078   vat_json_object_add_uint (node, "vtr_tag1", ntohl (mp->vtr_tag1));
1079   vat_json_object_add_uint (node, "vtr_tag2", ntohl (mp->vtr_tag2));
1080   if (ntohl (mp->sub_if_flags) & SUB_IF_API_FLAG_DOT1AH)
1081     {
1082       vat_json_object_add_string_copy (node, "pbb_vtr_dmac",
1083                                        format (0, "%U",
1084                                                format_ethernet_address,
1085                                                &mp->b_dmac));
1086       vat_json_object_add_string_copy (node, "pbb_vtr_smac",
1087                                        format (0, "%U",
1088                                                format_ethernet_address,
1089                                                &mp->b_smac));
1090       vat_json_object_add_uint (node, "pbb_vtr_b_vlanid", mp->b_vlanid);
1091       vat_json_object_add_uint (node, "pbb_vtr_i_sid", mp->i_sid);
1092     }
1093 }
1094
1095 #if VPP_API_TEST_BUILTIN == 0
1096 static void vl_api_sw_interface_event_t_handler
1097   (vl_api_sw_interface_event_t * mp)
1098 {
1099   vat_main_t *vam = &vat_main;
1100   if (vam->interface_event_display)
1101     errmsg ("interface flags: sw_if_index %d %s %s",
1102             ntohl (mp->sw_if_index),
1103             ((ntohl (mp->flags)) & IF_STATUS_API_FLAG_ADMIN_UP) ?
1104             "admin-up" : "admin-down",
1105             ((ntohl (mp->flags)) & IF_STATUS_API_FLAG_LINK_UP) ?
1106             "link-up" : "link-down");
1107 }
1108 #endif
1109
1110 __clib_unused static void
1111 vl_api_sw_interface_event_t_handler_json (vl_api_sw_interface_event_t * mp)
1112 {
1113   /* JSON output not supported */
1114 }
1115
1116 static void
1117 vl_api_cli_reply_t_handler (vl_api_cli_reply_t * mp)
1118 {
1119   vat_main_t *vam = &vat_main;
1120   i32 retval = ntohl (mp->retval);
1121
1122   vam->retval = retval;
1123   vam->shmem_result = uword_to_pointer (mp->reply_in_shmem, u8 *);
1124   vam->result_ready = 1;
1125 }
1126
1127 static void
1128 vl_api_cli_reply_t_handler_json (vl_api_cli_reply_t * mp)
1129 {
1130   vat_main_t *vam = &vat_main;
1131   vat_json_node_t node;
1132   void *oldheap;
1133   u8 *reply;
1134
1135   vat_json_init_object (&node);
1136   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1137   vat_json_object_add_uint (&node, "reply_in_shmem",
1138                             ntohl (mp->reply_in_shmem));
1139   /* Toss the shared-memory original... */
1140   oldheap = vl_msg_push_heap ();
1141
1142   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
1143   vec_free (reply);
1144
1145   vl_msg_pop_heap (oldheap);
1146
1147   vat_json_print (vam->ofp, &node);
1148   vat_json_free (&node);
1149
1150   vam->retval = ntohl (mp->retval);
1151   vam->result_ready = 1;
1152 }
1153
1154 static void
1155 vl_api_cli_inband_reply_t_handler (vl_api_cli_inband_reply_t * mp)
1156 {
1157   vat_main_t *vam = &vat_main;
1158   i32 retval = ntohl (mp->retval);
1159
1160   vec_reset_length (vam->cmd_reply);
1161
1162   vam->retval = retval;
1163   if (retval == 0)
1164     vam->cmd_reply = vl_api_from_api_to_new_vec (mp, &mp->reply);
1165   vam->result_ready = 1;
1166 }
1167
1168 static void
1169 vl_api_cli_inband_reply_t_handler_json (vl_api_cli_inband_reply_t * mp)
1170 {
1171   vat_main_t *vam = &vat_main;
1172   vat_json_node_t node;
1173   u8 *reply = 0;                /* reply vector */
1174
1175   reply = vl_api_from_api_to_new_vec (mp, &mp->reply);
1176   vec_reset_length (vam->cmd_reply);
1177
1178   vat_json_init_object (&node);
1179   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1180   vat_json_object_add_string_copy (&node, "reply", reply);
1181
1182   vat_json_print (vam->ofp, &node);
1183   vat_json_free (&node);
1184   vec_free (reply);
1185
1186   vam->retval = ntohl (mp->retval);
1187   vam->result_ready = 1;
1188 }
1189
1190 static void vl_api_classify_add_del_table_reply_t_handler
1191   (vl_api_classify_add_del_table_reply_t * mp)
1192 {
1193   vat_main_t *vam = &vat_main;
1194   i32 retval = ntohl (mp->retval);
1195   if (vam->async_mode)
1196     {
1197       vam->async_errors += (retval < 0);
1198     }
1199   else
1200     {
1201       vam->retval = retval;
1202       if (retval == 0 &&
1203           ((mp->new_table_index != 0xFFFFFFFF) ||
1204            (mp->skip_n_vectors != 0xFFFFFFFF) ||
1205            (mp->match_n_vectors != 0xFFFFFFFF)))
1206         /*
1207          * Note: this is just barely thread-safe, depends on
1208          * the main thread spinning waiting for an answer...
1209          */
1210         errmsg ("new index %d, skip_n_vectors %d, match_n_vectors %d",
1211                 ntohl (mp->new_table_index),
1212                 ntohl (mp->skip_n_vectors), ntohl (mp->match_n_vectors));
1213       vam->result_ready = 1;
1214     }
1215 }
1216
1217 static void vl_api_classify_add_del_table_reply_t_handler_json
1218   (vl_api_classify_add_del_table_reply_t * mp)
1219 {
1220   vat_main_t *vam = &vat_main;
1221   vat_json_node_t node;
1222
1223   vat_json_init_object (&node);
1224   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1225   vat_json_object_add_uint (&node, "new_table_index",
1226                             ntohl (mp->new_table_index));
1227   vat_json_object_add_uint (&node, "skip_n_vectors",
1228                             ntohl (mp->skip_n_vectors));
1229   vat_json_object_add_uint (&node, "match_n_vectors",
1230                             ntohl (mp->match_n_vectors));
1231
1232   vat_json_print (vam->ofp, &node);
1233   vat_json_free (&node);
1234
1235   vam->retval = ntohl (mp->retval);
1236   vam->result_ready = 1;
1237 }
1238
1239 static void vl_api_get_node_index_reply_t_handler
1240   (vl_api_get_node_index_reply_t * mp)
1241 {
1242   vat_main_t *vam = &vat_main;
1243   i32 retval = ntohl (mp->retval);
1244   if (vam->async_mode)
1245     {
1246       vam->async_errors += (retval < 0);
1247     }
1248   else
1249     {
1250       vam->retval = retval;
1251       if (retval == 0)
1252         errmsg ("node index %d", ntohl (mp->node_index));
1253       vam->result_ready = 1;
1254     }
1255 }
1256
1257 static void vl_api_get_node_index_reply_t_handler_json
1258   (vl_api_get_node_index_reply_t * mp)
1259 {
1260   vat_main_t *vam = &vat_main;
1261   vat_json_node_t node;
1262
1263   vat_json_init_object (&node);
1264   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1265   vat_json_object_add_uint (&node, "node_index", ntohl (mp->node_index));
1266
1267   vat_json_print (vam->ofp, &node);
1268   vat_json_free (&node);
1269
1270   vam->retval = ntohl (mp->retval);
1271   vam->result_ready = 1;
1272 }
1273
1274 static void vl_api_get_next_index_reply_t_handler
1275   (vl_api_get_next_index_reply_t * mp)
1276 {
1277   vat_main_t *vam = &vat_main;
1278   i32 retval = ntohl (mp->retval);
1279   if (vam->async_mode)
1280     {
1281       vam->async_errors += (retval < 0);
1282     }
1283   else
1284     {
1285       vam->retval = retval;
1286       if (retval == 0)
1287         errmsg ("next node index %d", ntohl (mp->next_index));
1288       vam->result_ready = 1;
1289     }
1290 }
1291
1292 static void vl_api_get_next_index_reply_t_handler_json
1293   (vl_api_get_next_index_reply_t * mp)
1294 {
1295   vat_main_t *vam = &vat_main;
1296   vat_json_node_t node;
1297
1298   vat_json_init_object (&node);
1299   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1300   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1301
1302   vat_json_print (vam->ofp, &node);
1303   vat_json_free (&node);
1304
1305   vam->retval = ntohl (mp->retval);
1306   vam->result_ready = 1;
1307 }
1308
1309 static void vl_api_add_node_next_reply_t_handler
1310   (vl_api_add_node_next_reply_t * mp)
1311 {
1312   vat_main_t *vam = &vat_main;
1313   i32 retval = ntohl (mp->retval);
1314   if (vam->async_mode)
1315     {
1316       vam->async_errors += (retval < 0);
1317     }
1318   else
1319     {
1320       vam->retval = retval;
1321       if (retval == 0)
1322         errmsg ("next index %d", ntohl (mp->next_index));
1323       vam->result_ready = 1;
1324     }
1325 }
1326
1327 static void vl_api_add_node_next_reply_t_handler_json
1328   (vl_api_add_node_next_reply_t * mp)
1329 {
1330   vat_main_t *vam = &vat_main;
1331   vat_json_node_t node;
1332
1333   vat_json_init_object (&node);
1334   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1335   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1336
1337   vat_json_print (vam->ofp, &node);
1338   vat_json_free (&node);
1339
1340   vam->retval = ntohl (mp->retval);
1341   vam->result_ready = 1;
1342 }
1343
1344 static void vl_api_show_version_reply_t_handler
1345   (vl_api_show_version_reply_t * mp)
1346 {
1347   vat_main_t *vam = &vat_main;
1348   i32 retval = ntohl (mp->retval);
1349
1350   if (retval >= 0)
1351     {
1352       errmsg ("        program: %s", mp->program);
1353       errmsg ("        version: %s", mp->version);
1354       errmsg ("     build date: %s", mp->build_date);
1355       errmsg ("build directory: %s", mp->build_directory);
1356     }
1357   vam->retval = retval;
1358   vam->result_ready = 1;
1359 }
1360
1361 static void vl_api_show_version_reply_t_handler_json
1362   (vl_api_show_version_reply_t * mp)
1363 {
1364   vat_main_t *vam = &vat_main;
1365   vat_json_node_t node;
1366
1367   vat_json_init_object (&node);
1368   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1369   vat_json_object_add_string_copy (&node, "program", mp->program);
1370   vat_json_object_add_string_copy (&node, "version", mp->version);
1371   vat_json_object_add_string_copy (&node, "build_date", mp->build_date);
1372   vat_json_object_add_string_copy (&node, "build_directory",
1373                                    mp->build_directory);
1374
1375   vat_json_print (vam->ofp, &node);
1376   vat_json_free (&node);
1377
1378   vam->retval = ntohl (mp->retval);
1379   vam->result_ready = 1;
1380 }
1381
1382 static void vl_api_show_threads_reply_t_handler
1383   (vl_api_show_threads_reply_t * mp)
1384 {
1385   vat_main_t *vam = &vat_main;
1386   i32 retval = ntohl (mp->retval);
1387   int i, count = 0;
1388
1389   if (retval >= 0)
1390     count = ntohl (mp->count);
1391
1392   for (i = 0; i < count; i++)
1393     print (vam->ofp,
1394            "\n%-2d %-11s %-11s %-5d %-6d %-4d %-6d",
1395            ntohl (mp->thread_data[i].id), mp->thread_data[i].name,
1396            mp->thread_data[i].type, ntohl (mp->thread_data[i].pid),
1397            ntohl (mp->thread_data[i].cpu_id), ntohl (mp->thread_data[i].core),
1398            ntohl (mp->thread_data[i].cpu_socket));
1399
1400   vam->retval = retval;
1401   vam->result_ready = 1;
1402 }
1403
1404 static void vl_api_show_threads_reply_t_handler_json
1405   (vl_api_show_threads_reply_t * mp)
1406 {
1407   vat_main_t *vam = &vat_main;
1408   vat_json_node_t node;
1409   vl_api_thread_data_t *td;
1410   i32 retval = ntohl (mp->retval);
1411   int i, count = 0;
1412
1413   if (retval >= 0)
1414     count = ntohl (mp->count);
1415
1416   vat_json_init_object (&node);
1417   vat_json_object_add_int (&node, "retval", retval);
1418   vat_json_object_add_uint (&node, "count", count);
1419
1420   for (i = 0; i < count; i++)
1421     {
1422       td = &mp->thread_data[i];
1423       vat_json_object_add_uint (&node, "id", ntohl (td->id));
1424       vat_json_object_add_string_copy (&node, "name", td->name);
1425       vat_json_object_add_string_copy (&node, "type", td->type);
1426       vat_json_object_add_uint (&node, "pid", ntohl (td->pid));
1427       vat_json_object_add_int (&node, "cpu_id", ntohl (td->cpu_id));
1428       vat_json_object_add_int (&node, "core", ntohl (td->id));
1429       vat_json_object_add_int (&node, "cpu_socket", ntohl (td->cpu_socket));
1430     }
1431
1432   vat_json_print (vam->ofp, &node);
1433   vat_json_free (&node);
1434
1435   vam->retval = retval;
1436   vam->result_ready = 1;
1437 }
1438
1439 static int
1440 api_show_threads (vat_main_t * vam)
1441 {
1442   vl_api_show_threads_t *mp;
1443   int ret;
1444
1445   print (vam->ofp,
1446          "\n%-2s %-11s %-11s %-5s %-6s %-4s %-6s",
1447          "ID", "Name", "Type", "LWP", "cpu_id", "Core", "Socket");
1448
1449   M (SHOW_THREADS, mp);
1450
1451   S (mp);
1452   W (ret);
1453   return ret;
1454 }
1455
1456 static void
1457 vl_api_l2_macs_event_t_handler (vl_api_l2_macs_event_t * mp)
1458 {
1459   u32 n_macs = ntohl (mp->n_macs);
1460   errmsg ("L2MAC event received with pid %d cl-idx %d for %d macs: \n",
1461           ntohl (mp->pid), mp->client_index, n_macs);
1462   int i;
1463   for (i = 0; i < n_macs; i++)
1464     {
1465       vl_api_mac_entry_t *mac = &mp->mac[i];
1466       errmsg (" [%d] sw_if_index %d  mac_addr %U  action %d \n",
1467               i + 1, ntohl (mac->sw_if_index),
1468               format_ethernet_address, mac->mac_addr, mac->action);
1469       if (i == 1000)
1470         break;
1471     }
1472 }
1473
1474 static void
1475 vl_api_l2_macs_event_t_handler_json (vl_api_l2_macs_event_t * mp)
1476 {
1477   /* JSON output not supported */
1478 }
1479
1480 #define vl_api_bridge_domain_details_t_endian vl_noop_handler
1481 #define vl_api_bridge_domain_details_t_print vl_noop_handler
1482
1483 /*
1484  * Special-case: build the bridge domain table, maintain
1485  * the next bd id vbl.
1486  */
1487 static void vl_api_bridge_domain_details_t_handler
1488   (vl_api_bridge_domain_details_t * mp)
1489 {
1490   vat_main_t *vam = &vat_main;
1491   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1492   int i;
1493
1494   print (vam->ofp, "\n%-3s %-3s %-3s %-3s %-3s %-6s %-3s",
1495          " ID", "LRN", "FWD", "FLD", "BVI", "UU-FWD", "#IF");
1496
1497   print (vam->ofp, "%3d %3d %3d %3d %3d %6d %3d",
1498          ntohl (mp->bd_id), mp->learn, mp->forward,
1499          mp->flood, ntohl (mp->bvi_sw_if_index),
1500          ntohl (mp->uu_fwd_sw_if_index), n_sw_ifs);
1501
1502   if (n_sw_ifs)
1503     {
1504       vl_api_bridge_domain_sw_if_t *sw_ifs;
1505       print (vam->ofp, "\n\n%s %s  %s", "sw_if_index", "SHG",
1506              "Interface Name");
1507
1508       sw_ifs = mp->sw_if_details;
1509       for (i = 0; i < n_sw_ifs; i++)
1510         {
1511           u8 *sw_if_name = 0;
1512           u32 sw_if_index;
1513           hash_pair_t *p;
1514
1515           sw_if_index = ntohl (sw_ifs->sw_if_index);
1516
1517           /* *INDENT-OFF* */
1518           hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
1519                              ({
1520                                if ((u32) p->value[0] == sw_if_index)
1521                                  {
1522                                    sw_if_name = (u8 *)(p->key);
1523                                    break;
1524                                  }
1525                              }));
1526           /* *INDENT-ON* */
1527           print (vam->ofp, "%7d     %3d  %s", sw_if_index,
1528                  sw_ifs->shg, sw_if_name ? (char *) sw_if_name :
1529                  "sw_if_index not found!");
1530
1531           sw_ifs++;
1532         }
1533     }
1534 }
1535
1536 static void vl_api_bridge_domain_details_t_handler_json
1537   (vl_api_bridge_domain_details_t * mp)
1538 {
1539   vat_main_t *vam = &vat_main;
1540   vat_json_node_t *node, *array = NULL;
1541   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1542
1543   if (VAT_JSON_ARRAY != vam->json_tree.type)
1544     {
1545       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1546       vat_json_init_array (&vam->json_tree);
1547     }
1548   node = vat_json_array_add (&vam->json_tree);
1549
1550   vat_json_init_object (node);
1551   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1552   vat_json_object_add_uint (node, "flood", mp->flood);
1553   vat_json_object_add_uint (node, "forward", mp->forward);
1554   vat_json_object_add_uint (node, "learn", mp->learn);
1555   vat_json_object_add_uint (node, "bvi_sw_if_index",
1556                             ntohl (mp->bvi_sw_if_index));
1557   vat_json_object_add_uint (node, "n_sw_ifs", n_sw_ifs);
1558   array = vat_json_object_add (node, "sw_if");
1559   vat_json_init_array (array);
1560
1561
1562
1563   if (n_sw_ifs)
1564     {
1565       vl_api_bridge_domain_sw_if_t *sw_ifs;
1566       int i;
1567
1568       sw_ifs = mp->sw_if_details;
1569       for (i = 0; i < n_sw_ifs; i++)
1570         {
1571           node = vat_json_array_add (array);
1572           vat_json_init_object (node);
1573           vat_json_object_add_uint (node, "sw_if_index",
1574                                     ntohl (sw_ifs->sw_if_index));
1575           vat_json_object_add_uint (node, "shg", sw_ifs->shg);
1576           sw_ifs++;
1577         }
1578     }
1579 }
1580
1581 static void vl_api_control_ping_reply_t_handler
1582   (vl_api_control_ping_reply_t * mp)
1583 {
1584   vat_main_t *vam = &vat_main;
1585   i32 retval = ntohl (mp->retval);
1586   if (vam->async_mode)
1587     {
1588       vam->async_errors += (retval < 0);
1589     }
1590   else
1591     {
1592       vam->retval = retval;
1593       vam->result_ready = 1;
1594     }
1595   if (vam->socket_client_main)
1596     vam->socket_client_main->control_pings_outstanding--;
1597 }
1598
1599 static void vl_api_control_ping_reply_t_handler_json
1600   (vl_api_control_ping_reply_t * mp)
1601 {
1602   vat_main_t *vam = &vat_main;
1603   i32 retval = ntohl (mp->retval);
1604
1605   if (VAT_JSON_NONE != vam->json_tree.type)
1606     {
1607       vat_json_print (vam->ofp, &vam->json_tree);
1608       vat_json_free (&vam->json_tree);
1609       vam->json_tree.type = VAT_JSON_NONE;
1610     }
1611   else
1612     {
1613       /* just print [] */
1614       vat_json_init_array (&vam->json_tree);
1615       vat_json_print (vam->ofp, &vam->json_tree);
1616       vam->json_tree.type = VAT_JSON_NONE;
1617     }
1618
1619   vam->retval = retval;
1620   vam->result_ready = 1;
1621 }
1622
1623 static void
1624   vl_api_bridge_domain_set_mac_age_reply_t_handler
1625   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1626 {
1627   vat_main_t *vam = &vat_main;
1628   i32 retval = ntohl (mp->retval);
1629   if (vam->async_mode)
1630     {
1631       vam->async_errors += (retval < 0);
1632     }
1633   else
1634     {
1635       vam->retval = retval;
1636       vam->result_ready = 1;
1637     }
1638 }
1639
1640 static void vl_api_bridge_domain_set_mac_age_reply_t_handler_json
1641   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1642 {
1643   vat_main_t *vam = &vat_main;
1644   vat_json_node_t node;
1645
1646   vat_json_init_object (&node);
1647   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1648
1649   vat_json_print (vam->ofp, &node);
1650   vat_json_free (&node);
1651
1652   vam->retval = ntohl (mp->retval);
1653   vam->result_ready = 1;
1654 }
1655
1656 static void
1657 vl_api_l2_flags_reply_t_handler (vl_api_l2_flags_reply_t * mp)
1658 {
1659   vat_main_t *vam = &vat_main;
1660   i32 retval = ntohl (mp->retval);
1661   if (vam->async_mode)
1662     {
1663       vam->async_errors += (retval < 0);
1664     }
1665   else
1666     {
1667       vam->retval = retval;
1668       vam->result_ready = 1;
1669     }
1670 }
1671
1672 static void vl_api_l2_flags_reply_t_handler_json
1673   (vl_api_l2_flags_reply_t * mp)
1674 {
1675   vat_main_t *vam = &vat_main;
1676   vat_json_node_t node;
1677
1678   vat_json_init_object (&node);
1679   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1680   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1681                             ntohl (mp->resulting_feature_bitmap));
1682
1683   vat_json_print (vam->ofp, &node);
1684   vat_json_free (&node);
1685
1686   vam->retval = ntohl (mp->retval);
1687   vam->result_ready = 1;
1688 }
1689
1690 static void vl_api_bridge_flags_reply_t_handler
1691   (vl_api_bridge_flags_reply_t * mp)
1692 {
1693   vat_main_t *vam = &vat_main;
1694   i32 retval = ntohl (mp->retval);
1695   if (vam->async_mode)
1696     {
1697       vam->async_errors += (retval < 0);
1698     }
1699   else
1700     {
1701       vam->retval = retval;
1702       vam->result_ready = 1;
1703     }
1704 }
1705
1706 static void vl_api_bridge_flags_reply_t_handler_json
1707   (vl_api_bridge_flags_reply_t * mp)
1708 {
1709   vat_main_t *vam = &vat_main;
1710   vat_json_node_t node;
1711
1712   vat_json_init_object (&node);
1713   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1714   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1715                             ntohl (mp->resulting_feature_bitmap));
1716
1717   vat_json_print (vam->ofp, &node);
1718   vat_json_free (&node);
1719
1720   vam->retval = ntohl (mp->retval);
1721   vam->result_ready = 1;
1722 }
1723
1724 static void
1725 vl_api_tap_create_v2_reply_t_handler (vl_api_tap_create_v2_reply_t * mp)
1726 {
1727   vat_main_t *vam = &vat_main;
1728   i32 retval = ntohl (mp->retval);
1729   if (vam->async_mode)
1730     {
1731       vam->async_errors += (retval < 0);
1732     }
1733   else
1734     {
1735       vam->retval = retval;
1736       vam->sw_if_index = ntohl (mp->sw_if_index);
1737       vam->result_ready = 1;
1738     }
1739
1740 }
1741
1742 static void vl_api_tap_create_v2_reply_t_handler_json
1743   (vl_api_tap_create_v2_reply_t * mp)
1744 {
1745   vat_main_t *vam = &vat_main;
1746   vat_json_node_t node;
1747
1748   vat_json_init_object (&node);
1749   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1750   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1751
1752   vat_json_print (vam->ofp, &node);
1753   vat_json_free (&node);
1754
1755   vam->retval = ntohl (mp->retval);
1756   vam->result_ready = 1;
1757
1758 }
1759
1760 static void
1761 vl_api_tap_delete_v2_reply_t_handler (vl_api_tap_delete_v2_reply_t * mp)
1762 {
1763   vat_main_t *vam = &vat_main;
1764   i32 retval = ntohl (mp->retval);
1765   if (vam->async_mode)
1766     {
1767       vam->async_errors += (retval < 0);
1768     }
1769   else
1770     {
1771       vam->retval = retval;
1772       vam->result_ready = 1;
1773     }
1774 }
1775
1776 static void vl_api_tap_delete_v2_reply_t_handler_json
1777   (vl_api_tap_delete_v2_reply_t * mp)
1778 {
1779   vat_main_t *vam = &vat_main;
1780   vat_json_node_t node;
1781
1782   vat_json_init_object (&node);
1783   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1784
1785   vat_json_print (vam->ofp, &node);
1786   vat_json_free (&node);
1787
1788   vam->retval = ntohl (mp->retval);
1789   vam->result_ready = 1;
1790 }
1791
1792 static void
1793 vl_api_virtio_pci_create_reply_t_handler (vl_api_virtio_pci_create_reply_t *
1794                                           mp)
1795 {
1796   vat_main_t *vam = &vat_main;
1797   i32 retval = ntohl (mp->retval);
1798   if (vam->async_mode)
1799     {
1800       vam->async_errors += (retval < 0);
1801     }
1802   else
1803     {
1804       vam->retval = retval;
1805       vam->sw_if_index = ntohl (mp->sw_if_index);
1806       vam->result_ready = 1;
1807     }
1808 }
1809
1810 static void vl_api_virtio_pci_create_reply_t_handler_json
1811   (vl_api_virtio_pci_create_reply_t * mp)
1812 {
1813   vat_main_t *vam = &vat_main;
1814   vat_json_node_t node;
1815
1816   vat_json_init_object (&node);
1817   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1818   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1819
1820   vat_json_print (vam->ofp, &node);
1821   vat_json_free (&node);
1822
1823   vam->retval = ntohl (mp->retval);
1824   vam->result_ready = 1;
1825
1826 }
1827
1828 static void
1829   vl_api_virtio_pci_create_v2_reply_t_handler
1830   (vl_api_virtio_pci_create_v2_reply_t * mp)
1831 {
1832   vat_main_t *vam = &vat_main;
1833   i32 retval = ntohl (mp->retval);
1834   if (vam->async_mode)
1835     {
1836       vam->async_errors += (retval < 0);
1837     }
1838   else
1839     {
1840       vam->retval = retval;
1841       vam->sw_if_index = ntohl (mp->sw_if_index);
1842       vam->result_ready = 1;
1843     }
1844 }
1845
1846 static void vl_api_virtio_pci_create_v2_reply_t_handler_json
1847   (vl_api_virtio_pci_create_v2_reply_t * mp)
1848 {
1849   vat_main_t *vam = &vat_main;
1850   vat_json_node_t node;
1851
1852   vat_json_init_object (&node);
1853   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1854   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1855
1856   vat_json_print (vam->ofp, &node);
1857   vat_json_free (&node);
1858
1859   vam->retval = ntohl (mp->retval);
1860   vam->result_ready = 1;
1861 }
1862
1863 static void
1864 vl_api_virtio_pci_delete_reply_t_handler (vl_api_virtio_pci_delete_reply_t *
1865                                           mp)
1866 {
1867   vat_main_t *vam = &vat_main;
1868   i32 retval = ntohl (mp->retval);
1869   if (vam->async_mode)
1870     {
1871       vam->async_errors += (retval < 0);
1872     }
1873   else
1874     {
1875       vam->retval = retval;
1876       vam->result_ready = 1;
1877     }
1878 }
1879
1880 static void vl_api_virtio_pci_delete_reply_t_handler_json
1881   (vl_api_virtio_pci_delete_reply_t * mp)
1882 {
1883   vat_main_t *vam = &vat_main;
1884   vat_json_node_t node;
1885
1886   vat_json_init_object (&node);
1887   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1888
1889   vat_json_print (vam->ofp, &node);
1890   vat_json_free (&node);
1891
1892   vam->retval = ntohl (mp->retval);
1893   vam->result_ready = 1;
1894 }
1895
1896 static void
1897 vl_api_bond_create_reply_t_handler (vl_api_bond_create_reply_t * mp)
1898 {
1899   vat_main_t *vam = &vat_main;
1900   i32 retval = ntohl (mp->retval);
1901
1902   if (vam->async_mode)
1903     {
1904       vam->async_errors += (retval < 0);
1905     }
1906   else
1907     {
1908       vam->retval = retval;
1909       vam->sw_if_index = ntohl (mp->sw_if_index);
1910       vam->result_ready = 1;
1911     }
1912 }
1913
1914 static void vl_api_bond_create_reply_t_handler_json
1915   (vl_api_bond_create_reply_t * mp)
1916 {
1917   vat_main_t *vam = &vat_main;
1918   vat_json_node_t node;
1919
1920   vat_json_init_object (&node);
1921   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1922   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1923
1924   vat_json_print (vam->ofp, &node);
1925   vat_json_free (&node);
1926
1927   vam->retval = ntohl (mp->retval);
1928   vam->result_ready = 1;
1929 }
1930
1931 static void
1932 vl_api_bond_create2_reply_t_handler (vl_api_bond_create2_reply_t * mp)
1933 {
1934   vat_main_t *vam = &vat_main;
1935   i32 retval = ntohl (mp->retval);
1936
1937   if (vam->async_mode)
1938     {
1939       vam->async_errors += (retval < 0);
1940     }
1941   else
1942     {
1943       vam->retval = retval;
1944       vam->sw_if_index = ntohl (mp->sw_if_index);
1945       vam->result_ready = 1;
1946     }
1947 }
1948
1949 static void vl_api_bond_create2_reply_t_handler_json
1950   (vl_api_bond_create2_reply_t * mp)
1951 {
1952   vat_main_t *vam = &vat_main;
1953   vat_json_node_t node;
1954
1955   vat_json_init_object (&node);
1956   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1957   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1958
1959   vat_json_print (vam->ofp, &node);
1960   vat_json_free (&node);
1961
1962   vam->retval = ntohl (mp->retval);
1963   vam->result_ready = 1;
1964 }
1965
1966 static void
1967 vl_api_bond_delete_reply_t_handler (vl_api_bond_delete_reply_t * mp)
1968 {
1969   vat_main_t *vam = &vat_main;
1970   i32 retval = ntohl (mp->retval);
1971
1972   if (vam->async_mode)
1973     {
1974       vam->async_errors += (retval < 0);
1975     }
1976   else
1977     {
1978       vam->retval = retval;
1979       vam->result_ready = 1;
1980     }
1981 }
1982
1983 static void vl_api_bond_delete_reply_t_handler_json
1984   (vl_api_bond_delete_reply_t * mp)
1985 {
1986   vat_main_t *vam = &vat_main;
1987   vat_json_node_t node;
1988
1989   vat_json_init_object (&node);
1990   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1991
1992   vat_json_print (vam->ofp, &node);
1993   vat_json_free (&node);
1994
1995   vam->retval = ntohl (mp->retval);
1996   vam->result_ready = 1;
1997 }
1998
1999 static void
2000 vl_api_bond_add_member_reply_t_handler (vl_api_bond_add_member_reply_t * mp)
2001 {
2002   vat_main_t *vam = &vat_main;
2003   i32 retval = ntohl (mp->retval);
2004
2005   if (vam->async_mode)
2006     {
2007       vam->async_errors += (retval < 0);
2008     }
2009   else
2010     {
2011       vam->retval = retval;
2012       vam->result_ready = 1;
2013     }
2014 }
2015
2016 static void vl_api_bond_add_member_reply_t_handler_json
2017   (vl_api_bond_add_member_reply_t * mp)
2018 {
2019   vat_main_t *vam = &vat_main;
2020   vat_json_node_t node;
2021
2022   vat_json_init_object (&node);
2023   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2024
2025   vat_json_print (vam->ofp, &node);
2026   vat_json_free (&node);
2027
2028   vam->retval = ntohl (mp->retval);
2029   vam->result_ready = 1;
2030 }
2031
2032 static void
2033 vl_api_bond_detach_member_reply_t_handler (vl_api_bond_detach_member_reply_t *
2034                                            mp)
2035 {
2036   vat_main_t *vam = &vat_main;
2037   i32 retval = ntohl (mp->retval);
2038
2039   if (vam->async_mode)
2040     {
2041       vam->async_errors += (retval < 0);
2042     }
2043   else
2044     {
2045       vam->retval = retval;
2046       vam->result_ready = 1;
2047     }
2048 }
2049
2050 static void vl_api_bond_detach_member_reply_t_handler_json
2051   (vl_api_bond_detach_member_reply_t * mp)
2052 {
2053   vat_main_t *vam = &vat_main;
2054   vat_json_node_t node;
2055
2056   vat_json_init_object (&node);
2057   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2058
2059   vat_json_print (vam->ofp, &node);
2060   vat_json_free (&node);
2061
2062   vam->retval = ntohl (mp->retval);
2063   vam->result_ready = 1;
2064 }
2065
2066 static int
2067 api_sw_interface_set_bond_weight (vat_main_t * vam)
2068 {
2069   unformat_input_t *i = vam->input;
2070   vl_api_sw_interface_set_bond_weight_t *mp;
2071   u32 sw_if_index = ~0;
2072   u32 weight = 0;
2073   u8 weight_enter = 0;
2074   int ret;
2075
2076   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2077     {
2078       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
2079         ;
2080       else if (unformat (i, "sw_if_index %d", &sw_if_index))
2081         ;
2082       else if (unformat (i, "weight %u", &weight))
2083         weight_enter = 1;
2084       else
2085         break;
2086     }
2087
2088   if (sw_if_index == ~0)
2089     {
2090       errmsg ("missing interface name or sw_if_index");
2091       return -99;
2092     }
2093   if (weight_enter == 0)
2094     {
2095       errmsg ("missing valid weight");
2096       return -99;
2097     }
2098
2099   /* Construct the API message */
2100   M (SW_INTERFACE_SET_BOND_WEIGHT, mp);
2101   mp->sw_if_index = ntohl (sw_if_index);
2102   mp->weight = ntohl (weight);
2103
2104   S (mp);
2105   W (ret);
2106   return ret;
2107 }
2108
2109 static void vl_api_sw_bond_interface_details_t_handler
2110   (vl_api_sw_bond_interface_details_t * mp)
2111 {
2112   vat_main_t *vam = &vat_main;
2113
2114   print (vam->ofp,
2115          "%-16s %-12d %-12U %-13U %-14u %-14u",
2116          mp->interface_name, ntohl (mp->sw_if_index),
2117          format_bond_mode, ntohl (mp->mode), format_bond_load_balance,
2118          ntohl (mp->lb), ntohl (mp->active_members), ntohl (mp->members));
2119 }
2120
2121 static void vl_api_sw_bond_interface_details_t_handler_json
2122   (vl_api_sw_bond_interface_details_t * mp)
2123 {
2124   vat_main_t *vam = &vat_main;
2125   vat_json_node_t *node = NULL;
2126
2127   if (VAT_JSON_ARRAY != vam->json_tree.type)
2128     {
2129       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2130       vat_json_init_array (&vam->json_tree);
2131     }
2132   node = vat_json_array_add (&vam->json_tree);
2133
2134   vat_json_init_object (node);
2135   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
2136   vat_json_object_add_string_copy (node, "interface_name",
2137                                    mp->interface_name);
2138   vat_json_object_add_uint (node, "mode", ntohl (mp->mode));
2139   vat_json_object_add_uint (node, "load_balance", ntohl (mp->lb));
2140   vat_json_object_add_uint (node, "active_members",
2141                             ntohl (mp->active_members));
2142   vat_json_object_add_uint (node, "members", ntohl (mp->members));
2143 }
2144
2145 static int
2146 api_sw_bond_interface_dump (vat_main_t * vam)
2147 {
2148   unformat_input_t *i = vam->input;
2149   vl_api_sw_bond_interface_dump_t *mp;
2150   vl_api_control_ping_t *mp_ping;
2151   int ret;
2152   u32 sw_if_index = ~0;
2153
2154   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2155     {
2156       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
2157         ;
2158       else if (unformat (i, "sw_if_index %d", &sw_if_index))
2159         ;
2160       else
2161         break;
2162     }
2163
2164   print (vam->ofp,
2165          "\n%-16s %-12s %-12s %-13s %-14s %-14s",
2166          "interface name", "sw_if_index", "mode", "load balance",
2167          "active members", "members");
2168
2169   /* Get list of bond interfaces */
2170   M (SW_BOND_INTERFACE_DUMP, mp);
2171   mp->sw_if_index = ntohl (sw_if_index);
2172   S (mp);
2173
2174   /* Use a control ping for synchronization */
2175   MPING (CONTROL_PING, mp_ping);
2176   S (mp_ping);
2177
2178   W (ret);
2179   return ret;
2180 }
2181
2182 static void vl_api_sw_member_interface_details_t_handler
2183   (vl_api_sw_member_interface_details_t * mp)
2184 {
2185   vat_main_t *vam = &vat_main;
2186
2187   print (vam->ofp,
2188          "%-25s %-12d %-7d %-12d %-10d %-10d", mp->interface_name,
2189          ntohl (mp->sw_if_index), mp->is_passive, mp->is_long_timeout,
2190          ntohl (mp->weight), mp->is_local_numa);
2191 }
2192
2193 static void vl_api_sw_member_interface_details_t_handler_json
2194   (vl_api_sw_member_interface_details_t * mp)
2195 {
2196   vat_main_t *vam = &vat_main;
2197   vat_json_node_t *node = NULL;
2198
2199   if (VAT_JSON_ARRAY != vam->json_tree.type)
2200     {
2201       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2202       vat_json_init_array (&vam->json_tree);
2203     }
2204   node = vat_json_array_add (&vam->json_tree);
2205
2206   vat_json_init_object (node);
2207   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
2208   vat_json_object_add_string_copy (node, "interface_name",
2209                                    mp->interface_name);
2210   vat_json_object_add_uint (node, "passive", mp->is_passive);
2211   vat_json_object_add_uint (node, "long_timeout", mp->is_long_timeout);
2212   vat_json_object_add_uint (node, "weight", ntohl (mp->weight));
2213   vat_json_object_add_uint (node, "is_local_numa", mp->is_local_numa);
2214 }
2215
2216 static int
2217 api_sw_member_interface_dump (vat_main_t * vam)
2218 {
2219   unformat_input_t *i = vam->input;
2220   vl_api_sw_member_interface_dump_t *mp;
2221   vl_api_control_ping_t *mp_ping;
2222   u32 sw_if_index = ~0;
2223   u8 sw_if_index_set = 0;
2224   int ret;
2225
2226   /* Parse args required to build the message */
2227   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2228     {
2229       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
2230         sw_if_index_set = 1;
2231       else if (unformat (i, "sw_if_index %d", &sw_if_index))
2232         sw_if_index_set = 1;
2233       else
2234         break;
2235     }
2236
2237   if (sw_if_index_set == 0)
2238     {
2239       errmsg ("missing vpp interface name. ");
2240       return -99;
2241     }
2242
2243   print (vam->ofp,
2244          "\n%-25s %-12s %-7s %-12s %-10s %-10s",
2245          "member interface name", "sw_if_index", "passive", "long_timeout",
2246          "weight", "local numa");
2247
2248   /* Get list of bond interfaces */
2249   M (SW_MEMBER_INTERFACE_DUMP, mp);
2250   mp->sw_if_index = ntohl (sw_if_index);
2251   S (mp);
2252
2253   /* Use a control ping for synchronization */
2254   MPING (CONTROL_PING, mp_ping);
2255   S (mp_ping);
2256
2257   W (ret);
2258   return ret;
2259 }
2260
2261 static void vl_api_mpls_tunnel_add_del_reply_t_handler
2262   (vl_api_mpls_tunnel_add_del_reply_t * mp)
2263 {
2264   vat_main_t *vam = &vat_main;
2265   i32 retval = ntohl (mp->retval);
2266   if (vam->async_mode)
2267     {
2268       vam->async_errors += (retval < 0);
2269     }
2270   else
2271     {
2272       vam->retval = retval;
2273       vam->sw_if_index = ntohl (mp->sw_if_index);
2274       vam->result_ready = 1;
2275     }
2276   vam->regenerate_interface_table = 1;
2277 }
2278
2279 static void vl_api_mpls_tunnel_add_del_reply_t_handler_json
2280   (vl_api_mpls_tunnel_add_del_reply_t * mp)
2281 {
2282   vat_main_t *vam = &vat_main;
2283   vat_json_node_t node;
2284
2285   vat_json_init_object (&node);
2286   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2287   vat_json_object_add_uint (&node, "tunnel_sw_if_index",
2288                             ntohl (mp->sw_if_index));
2289
2290   vat_json_print (vam->ofp, &node);
2291   vat_json_free (&node);
2292
2293   vam->retval = ntohl (mp->retval);
2294   vam->result_ready = 1;
2295 }
2296
2297 static void vl_api_vxlan_add_del_tunnel_reply_t_handler
2298   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
2299 {
2300   vat_main_t *vam = &vat_main;
2301   i32 retval = ntohl (mp->retval);
2302   if (vam->async_mode)
2303     {
2304       vam->async_errors += (retval < 0);
2305     }
2306   else
2307     {
2308       vam->retval = retval;
2309       vam->sw_if_index = ntohl (mp->sw_if_index);
2310       vam->result_ready = 1;
2311     }
2312   vam->regenerate_interface_table = 1;
2313 }
2314
2315 static void vl_api_vxlan_add_del_tunnel_reply_t_handler_json
2316   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
2317 {
2318   vat_main_t *vam = &vat_main;
2319   vat_json_node_t node;
2320
2321   vat_json_init_object (&node);
2322   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2323   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2324
2325   vat_json_print (vam->ofp, &node);
2326   vat_json_free (&node);
2327
2328   vam->retval = ntohl (mp->retval);
2329   vam->result_ready = 1;
2330 }
2331
2332 static void vl_api_vxlan_offload_rx_reply_t_handler
2333   (vl_api_vxlan_offload_rx_reply_t * mp)
2334 {
2335   vat_main_t *vam = &vat_main;
2336   i32 retval = ntohl (mp->retval);
2337   if (vam->async_mode)
2338     {
2339       vam->async_errors += (retval < 0);
2340     }
2341   else
2342     {
2343       vam->retval = retval;
2344       vam->result_ready = 1;
2345     }
2346 }
2347
2348 static void vl_api_vxlan_offload_rx_reply_t_handler_json
2349   (vl_api_vxlan_offload_rx_reply_t * mp)
2350 {
2351   vat_main_t *vam = &vat_main;
2352   vat_json_node_t node;
2353
2354   vat_json_init_object (&node);
2355   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2356
2357   vat_json_print (vam->ofp, &node);
2358   vat_json_free (&node);
2359
2360   vam->retval = ntohl (mp->retval);
2361   vam->result_ready = 1;
2362 }
2363
2364 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler
2365   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
2366 {
2367   vat_main_t *vam = &vat_main;
2368   i32 retval = ntohl (mp->retval);
2369   if (vam->async_mode)
2370     {
2371       vam->async_errors += (retval < 0);
2372     }
2373   else
2374     {
2375       vam->retval = retval;
2376       vam->sw_if_index = ntohl (mp->sw_if_index);
2377       vam->result_ready = 1;
2378     }
2379   vam->regenerate_interface_table = 1;
2380 }
2381
2382 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler_json
2383   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
2384 {
2385   vat_main_t *vam = &vat_main;
2386   vat_json_node_t node;
2387
2388   vat_json_init_object (&node);
2389   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2390   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2391
2392   vat_json_print (vam->ofp, &node);
2393   vat_json_free (&node);
2394
2395   vam->retval = ntohl (mp->retval);
2396   vam->result_ready = 1;
2397 }
2398
2399 static void vl_api_create_vhost_user_if_reply_t_handler
2400   (vl_api_create_vhost_user_if_reply_t * mp)
2401 {
2402   vat_main_t *vam = &vat_main;
2403   i32 retval = ntohl (mp->retval);
2404   if (vam->async_mode)
2405     {
2406       vam->async_errors += (retval < 0);
2407     }
2408   else
2409     {
2410       vam->retval = retval;
2411       vam->sw_if_index = ntohl (mp->sw_if_index);
2412       vam->result_ready = 1;
2413     }
2414   vam->regenerate_interface_table = 1;
2415 }
2416
2417 static void vl_api_create_vhost_user_if_reply_t_handler_json
2418   (vl_api_create_vhost_user_if_reply_t * mp)
2419 {
2420   vat_main_t *vam = &vat_main;
2421   vat_json_node_t node;
2422
2423   vat_json_init_object (&node);
2424   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2425   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2426
2427   vat_json_print (vam->ofp, &node);
2428   vat_json_free (&node);
2429
2430   vam->retval = ntohl (mp->retval);
2431   vam->result_ready = 1;
2432 }
2433
2434 static void vl_api_create_vhost_user_if_v2_reply_t_handler
2435   (vl_api_create_vhost_user_if_v2_reply_t * mp)
2436 {
2437   vat_main_t *vam = &vat_main;
2438   i32 retval = ntohl (mp->retval);
2439   if (vam->async_mode)
2440     {
2441       vam->async_errors += (retval < 0);
2442     }
2443   else
2444     {
2445       vam->retval = retval;
2446       vam->sw_if_index = ntohl (mp->sw_if_index);
2447       vam->result_ready = 1;
2448     }
2449   vam->regenerate_interface_table = 1;
2450 }
2451
2452 static void vl_api_create_vhost_user_if_v2_reply_t_handler_json
2453   (vl_api_create_vhost_user_if_v2_reply_t * mp)
2454 {
2455   vat_main_t *vam = &vat_main;
2456   vat_json_node_t node;
2457
2458   vat_json_init_object (&node);
2459   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2460   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2461
2462   vat_json_print (vam->ofp, &node);
2463   vat_json_free (&node);
2464
2465   vam->retval = ntohl (mp->retval);
2466   vam->result_ready = 1;
2467 }
2468
2469 static void vl_api_ip_address_details_t_handler
2470   (vl_api_ip_address_details_t * mp)
2471 {
2472   vat_main_t *vam = &vat_main;
2473   static ip_address_details_t empty_ip_address_details = { {0} };
2474   ip_address_details_t *address = NULL;
2475   ip_details_t *current_ip_details = NULL;
2476   ip_details_t *details = NULL;
2477
2478   details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
2479
2480   if (!details || vam->current_sw_if_index >= vec_len (details)
2481       || !details[vam->current_sw_if_index].present)
2482     {
2483       errmsg ("ip address details arrived but not stored");
2484       errmsg ("ip_dump should be called first");
2485       return;
2486     }
2487
2488   current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
2489
2490 #define addresses (current_ip_details->addr)
2491
2492   vec_validate_init_empty (addresses, vec_len (addresses),
2493                            empty_ip_address_details);
2494
2495   address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
2496
2497   clib_memcpy (&address->ip, &mp->prefix.address.un, sizeof (address->ip));
2498   address->prefix_length = mp->prefix.len;
2499 #undef addresses
2500 }
2501
2502 static void vl_api_ip_address_details_t_handler_json
2503   (vl_api_ip_address_details_t * mp)
2504 {
2505   vat_main_t *vam = &vat_main;
2506   vat_json_node_t *node = NULL;
2507
2508   if (VAT_JSON_ARRAY != vam->json_tree.type)
2509     {
2510       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2511       vat_json_init_array (&vam->json_tree);
2512     }
2513   node = vat_json_array_add (&vam->json_tree);
2514
2515   vat_json_init_object (node);
2516   vat_json_object_add_prefix (node, &mp->prefix);
2517 }
2518
2519 static void
2520 vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
2521 {
2522   vat_main_t *vam = &vat_main;
2523   static ip_details_t empty_ip_details = { 0 };
2524   ip_details_t *ip = NULL;
2525   u32 sw_if_index = ~0;
2526
2527   sw_if_index = ntohl (mp->sw_if_index);
2528
2529   vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2530                            sw_if_index, empty_ip_details);
2531
2532   ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2533                          sw_if_index);
2534
2535   ip->present = 1;
2536 }
2537
2538 static void
2539 vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
2540 {
2541   vat_main_t *vam = &vat_main;
2542
2543   if (VAT_JSON_ARRAY != vam->json_tree.type)
2544     {
2545       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2546       vat_json_init_array (&vam->json_tree);
2547     }
2548   vat_json_array_add_uint (&vam->json_tree,
2549                            clib_net_to_host_u32 (mp->sw_if_index));
2550 }
2551
2552 static void vl_api_get_first_msg_id_reply_t_handler
2553   (vl_api_get_first_msg_id_reply_t * mp)
2554 {
2555   vat_main_t *vam = &vat_main;
2556   i32 retval = ntohl (mp->retval);
2557
2558   if (vam->async_mode)
2559     {
2560       vam->async_errors += (retval < 0);
2561     }
2562   else
2563     {
2564       vam->retval = retval;
2565       vam->result_ready = 1;
2566     }
2567   if (retval >= 0)
2568     {
2569       errmsg ("first message id %d", ntohs (mp->first_msg_id));
2570     }
2571 }
2572
2573 static void vl_api_get_first_msg_id_reply_t_handler_json
2574   (vl_api_get_first_msg_id_reply_t * mp)
2575 {
2576   vat_main_t *vam = &vat_main;
2577   vat_json_node_t node;
2578
2579   vat_json_init_object (&node);
2580   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2581   vat_json_object_add_uint (&node, "first_msg_id",
2582                             (uint) ntohs (mp->first_msg_id));
2583
2584   vat_json_print (vam->ofp, &node);
2585   vat_json_free (&node);
2586
2587   vam->retval = ntohl (mp->retval);
2588   vam->result_ready = 1;
2589 }
2590
2591 static void vl_api_get_node_graph_reply_t_handler
2592   (vl_api_get_node_graph_reply_t * mp)
2593 {
2594   vat_main_t *vam = &vat_main;
2595   i32 retval = ntohl (mp->retval);
2596   u8 *pvt_copy, *reply;
2597   void *oldheap;
2598   vlib_node_t *node;
2599   int i;
2600
2601   if (vam->async_mode)
2602     {
2603       vam->async_errors += (retval < 0);
2604     }
2605   else
2606     {
2607       vam->retval = retval;
2608       vam->result_ready = 1;
2609     }
2610
2611   /* "Should never happen..." */
2612   if (retval != 0)
2613     return;
2614
2615   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2616   pvt_copy = vec_dup (reply);
2617
2618   /* Toss the shared-memory original... */
2619   oldheap = vl_msg_push_heap ();
2620
2621   vec_free (reply);
2622
2623   vl_msg_pop_heap (oldheap);
2624
2625   if (vam->graph_nodes)
2626     {
2627       hash_free (vam->graph_node_index_by_name);
2628
2629       for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
2630         {
2631           node = vam->graph_nodes[0][i];
2632           vec_free (node->name);
2633           vec_free (node->next_nodes);
2634           vec_free (node);
2635         }
2636       vec_free (vam->graph_nodes[0]);
2637       vec_free (vam->graph_nodes);
2638     }
2639
2640   vam->graph_node_index_by_name = hash_create_string (0, sizeof (uword));
2641   vam->graph_nodes = vlib_node_unserialize (pvt_copy);
2642   vec_free (pvt_copy);
2643
2644   for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
2645     {
2646       node = vam->graph_nodes[0][i];
2647       hash_set_mem (vam->graph_node_index_by_name, node->name, i);
2648     }
2649 }
2650
2651 static void vl_api_get_node_graph_reply_t_handler_json
2652   (vl_api_get_node_graph_reply_t * mp)
2653 {
2654   vat_main_t *vam = &vat_main;
2655   void *oldheap;
2656   vat_json_node_t node;
2657   u8 *reply;
2658
2659   /* $$$$ make this real? */
2660   vat_json_init_object (&node);
2661   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2662   vat_json_object_add_uint (&node, "reply_in_shmem", mp->reply_in_shmem);
2663
2664   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2665
2666   /* Toss the shared-memory original... */
2667   oldheap = vl_msg_push_heap ();
2668
2669   vec_free (reply);
2670
2671   vl_msg_pop_heap (oldheap);
2672
2673   vat_json_print (vam->ofp, &node);
2674   vat_json_free (&node);
2675
2676   vam->retval = ntohl (mp->retval);
2677   vam->result_ready = 1;
2678 }
2679
2680 static u8 *
2681 format_policer_type (u8 * s, va_list * va)
2682 {
2683   u32 i = va_arg (*va, u32);
2684
2685   if (i == SSE2_QOS_POLICER_TYPE_1R2C)
2686     s = format (s, "1r2c");
2687   else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
2688     s = format (s, "1r3c");
2689   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
2690     s = format (s, "2r3c-2698");
2691   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
2692     s = format (s, "2r3c-4115");
2693   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
2694     s = format (s, "2r3c-mef5cf1");
2695   else
2696     s = format (s, "ILLEGAL");
2697   return s;
2698 }
2699
2700 static u8 *
2701 format_policer_rate_type (u8 * s, va_list * va)
2702 {
2703   u32 i = va_arg (*va, u32);
2704
2705   if (i == SSE2_QOS_RATE_KBPS)
2706     s = format (s, "kbps");
2707   else if (i == SSE2_QOS_RATE_PPS)
2708     s = format (s, "pps");
2709   else
2710     s = format (s, "ILLEGAL");
2711   return s;
2712 }
2713
2714 static u8 *
2715 format_policer_round_type (u8 * s, va_list * va)
2716 {
2717   u32 i = va_arg (*va, u32);
2718
2719   if (i == SSE2_QOS_ROUND_TO_CLOSEST)
2720     s = format (s, "closest");
2721   else if (i == SSE2_QOS_ROUND_TO_UP)
2722     s = format (s, "up");
2723   else if (i == SSE2_QOS_ROUND_TO_DOWN)
2724     s = format (s, "down");
2725   else
2726     s = format (s, "ILLEGAL");
2727   return s;
2728 }
2729
2730 static u8 *
2731 format_policer_action_type (u8 * s, va_list * va)
2732 {
2733   u32 i = va_arg (*va, u32);
2734
2735   if (i == SSE2_QOS_ACTION_DROP)
2736     s = format (s, "drop");
2737   else if (i == SSE2_QOS_ACTION_TRANSMIT)
2738     s = format (s, "transmit");
2739   else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2740     s = format (s, "mark-and-transmit");
2741   else
2742     s = format (s, "ILLEGAL");
2743   return s;
2744 }
2745
2746 static u8 *
2747 format_dscp (u8 * s, va_list * va)
2748 {
2749   u32 i = va_arg (*va, u32);
2750   char *t = 0;
2751
2752   switch (i)
2753     {
2754 #define _(v,f,str) case VNET_DSCP_##f: t = str; break;
2755       foreach_vnet_dscp
2756 #undef _
2757     default:
2758       return format (s, "ILLEGAL");
2759     }
2760   s = format (s, "%s", t);
2761   return s;
2762 }
2763
2764 static void
2765 vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
2766 {
2767   vat_main_t *vam = &vat_main;
2768   u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
2769
2770   if (mp->conform_action.type == SSE2_QOS_ACTION_API_MARK_AND_TRANSMIT)
2771     conform_dscp_str = format (0, "%U", format_dscp, mp->conform_action.dscp);
2772   else
2773     conform_dscp_str = format (0, "");
2774
2775   if (mp->exceed_action.type == SSE2_QOS_ACTION_API_MARK_AND_TRANSMIT)
2776     exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_action.dscp);
2777   else
2778     exceed_dscp_str = format (0, "");
2779
2780   if (mp->violate_action.type == SSE2_QOS_ACTION_API_MARK_AND_TRANSMIT)
2781     violate_dscp_str = format (0, "%U", format_dscp, mp->violate_action.dscp);
2782   else
2783     violate_dscp_str = format (0, "");
2784
2785   print (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
2786          "rate type %U, round type %U, %s rate, %s color-aware, "
2787          "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
2788          "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
2789          "conform action %U%s, exceed action %U%s, violate action %U%s",
2790          mp->name,
2791          format_policer_type, mp->type,
2792          ntohl (mp->cir),
2793          ntohl (mp->eir),
2794          clib_net_to_host_u64 (mp->cb),
2795          clib_net_to_host_u64 (mp->eb),
2796          format_policer_rate_type, mp->rate_type,
2797          format_policer_round_type, mp->round_type,
2798          mp->single_rate ? "single" : "dual",
2799          mp->color_aware ? "is" : "not",
2800          ntohl (mp->cir_tokens_per_period),
2801          ntohl (mp->pir_tokens_per_period),
2802          ntohl (mp->scale),
2803          ntohl (mp->current_limit),
2804          ntohl (mp->current_bucket),
2805          ntohl (mp->extended_limit),
2806          ntohl (mp->extended_bucket),
2807          clib_net_to_host_u64 (mp->last_update_time),
2808          format_policer_action_type, mp->conform_action.type,
2809          conform_dscp_str,
2810          format_policer_action_type, mp->exceed_action.type,
2811          exceed_dscp_str,
2812          format_policer_action_type, mp->violate_action.type,
2813          violate_dscp_str);
2814
2815   vec_free (conform_dscp_str);
2816   vec_free (exceed_dscp_str);
2817   vec_free (violate_dscp_str);
2818 }
2819
2820 static void vl_api_policer_details_t_handler_json
2821   (vl_api_policer_details_t * mp)
2822 {
2823   vat_main_t *vam = &vat_main;
2824   vat_json_node_t *node;
2825   u8 *rate_type_str, *round_type_str, *type_str;
2826   u8 *conform_action_str, *exceed_action_str, *violate_action_str;
2827
2828   rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
2829   round_type_str =
2830     format (0, "%U", format_policer_round_type, mp->round_type);
2831   type_str = format (0, "%U", format_policer_type, mp->type);
2832   conform_action_str = format (0, "%U", format_policer_action_type,
2833                                mp->conform_action.type);
2834   exceed_action_str = format (0, "%U", format_policer_action_type,
2835                               mp->exceed_action.type);
2836   violate_action_str = format (0, "%U", format_policer_action_type,
2837                                mp->violate_action.type);
2838
2839   if (VAT_JSON_ARRAY != vam->json_tree.type)
2840     {
2841       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2842       vat_json_init_array (&vam->json_tree);
2843     }
2844   node = vat_json_array_add (&vam->json_tree);
2845
2846   vat_json_init_object (node);
2847   vat_json_object_add_string_copy (node, "name", mp->name);
2848   vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
2849   vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
2850   vat_json_object_add_uint (node, "cb", clib_net_to_host_u64 (mp->cb));
2851   vat_json_object_add_uint (node, "eb", clib_net_to_host_u64 (mp->eb));
2852   vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
2853   vat_json_object_add_string_copy (node, "round_type", round_type_str);
2854   vat_json_object_add_string_copy (node, "type", type_str);
2855   vat_json_object_add_uint (node, "single_rate", mp->single_rate);
2856   vat_json_object_add_uint (node, "color_aware", mp->color_aware);
2857   vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
2858   vat_json_object_add_uint (node, "cir_tokens_per_period",
2859                             ntohl (mp->cir_tokens_per_period));
2860   vat_json_object_add_uint (node, "eir_tokens_per_period",
2861                             ntohl (mp->pir_tokens_per_period));
2862   vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
2863   vat_json_object_add_uint (node, "current_bucket",
2864                             ntohl (mp->current_bucket));
2865   vat_json_object_add_uint (node, "extended_limit",
2866                             ntohl (mp->extended_limit));
2867   vat_json_object_add_uint (node, "extended_bucket",
2868                             ntohl (mp->extended_bucket));
2869   vat_json_object_add_uint (node, "last_update_time",
2870                             ntohl (mp->last_update_time));
2871   vat_json_object_add_string_copy (node, "conform_action",
2872                                    conform_action_str);
2873   if (mp->conform_action.type == SSE2_QOS_ACTION_API_MARK_AND_TRANSMIT)
2874     {
2875       u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_action.dscp);
2876       vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
2877       vec_free (dscp_str);
2878     }
2879   vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
2880   if (mp->exceed_action.type == SSE2_QOS_ACTION_API_MARK_AND_TRANSMIT)
2881     {
2882       u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_action.dscp);
2883       vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
2884       vec_free (dscp_str);
2885     }
2886   vat_json_object_add_string_copy (node, "violate_action",
2887                                    violate_action_str);
2888   if (mp->violate_action.type == SSE2_QOS_ACTION_API_MARK_AND_TRANSMIT)
2889     {
2890       u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_action.dscp);
2891       vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
2892       vec_free (dscp_str);
2893     }
2894
2895   vec_free (rate_type_str);
2896   vec_free (round_type_str);
2897   vec_free (type_str);
2898   vec_free (conform_action_str);
2899   vec_free (exceed_action_str);
2900   vec_free (violate_action_str);
2901 }
2902
2903 static void
2904 vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
2905                                            mp)
2906 {
2907   vat_main_t *vam = &vat_main;
2908   int i, count = ntohl (mp->count);
2909
2910   if (count > 0)
2911     print (vam->ofp, "classify table ids (%d) : ", count);
2912   for (i = 0; i < count; i++)
2913     {
2914       print (vam->ofp, "%d", ntohl (mp->ids[i]));
2915       print (vam->ofp, (i < count - 1) ? "," : "");
2916     }
2917   vam->retval = ntohl (mp->retval);
2918   vam->result_ready = 1;
2919 }
2920
2921 static void
2922   vl_api_classify_table_ids_reply_t_handler_json
2923   (vl_api_classify_table_ids_reply_t * mp)
2924 {
2925   vat_main_t *vam = &vat_main;
2926   int i, count = ntohl (mp->count);
2927
2928   if (count > 0)
2929     {
2930       vat_json_node_t node;
2931
2932       vat_json_init_object (&node);
2933       for (i = 0; i < count; i++)
2934         {
2935           vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
2936         }
2937       vat_json_print (vam->ofp, &node);
2938       vat_json_free (&node);
2939     }
2940   vam->retval = ntohl (mp->retval);
2941   vam->result_ready = 1;
2942 }
2943
2944 static void
2945   vl_api_classify_table_by_interface_reply_t_handler
2946   (vl_api_classify_table_by_interface_reply_t * mp)
2947 {
2948   vat_main_t *vam = &vat_main;
2949   u32 table_id;
2950
2951   table_id = ntohl (mp->l2_table_id);
2952   if (table_id != ~0)
2953     print (vam->ofp, "l2 table id : %d", table_id);
2954   else
2955     print (vam->ofp, "l2 table id : No input ACL tables configured");
2956   table_id = ntohl (mp->ip4_table_id);
2957   if (table_id != ~0)
2958     print (vam->ofp, "ip4 table id : %d", table_id);
2959   else
2960     print (vam->ofp, "ip4 table id : No input ACL tables configured");
2961   table_id = ntohl (mp->ip6_table_id);
2962   if (table_id != ~0)
2963     print (vam->ofp, "ip6 table id : %d", table_id);
2964   else
2965     print (vam->ofp, "ip6 table id : No input ACL tables configured");
2966   vam->retval = ntohl (mp->retval);
2967   vam->result_ready = 1;
2968 }
2969
2970 static void
2971   vl_api_classify_table_by_interface_reply_t_handler_json
2972   (vl_api_classify_table_by_interface_reply_t * mp)
2973 {
2974   vat_main_t *vam = &vat_main;
2975   vat_json_node_t node;
2976
2977   vat_json_init_object (&node);
2978
2979   vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
2980   vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
2981   vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
2982
2983   vat_json_print (vam->ofp, &node);
2984   vat_json_free (&node);
2985
2986   vam->retval = ntohl (mp->retval);
2987   vam->result_ready = 1;
2988 }
2989
2990 static void vl_api_policer_add_del_reply_t_handler
2991   (vl_api_policer_add_del_reply_t * mp)
2992 {
2993   vat_main_t *vam = &vat_main;
2994   i32 retval = ntohl (mp->retval);
2995   if (vam->async_mode)
2996     {
2997       vam->async_errors += (retval < 0);
2998     }
2999   else
3000     {
3001       vam->retval = retval;
3002       vam->result_ready = 1;
3003       if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
3004         /*
3005          * Note: this is just barely thread-safe, depends on
3006          * the main thread spinning waiting for an answer...
3007          */
3008         errmsg ("policer index %d", ntohl (mp->policer_index));
3009     }
3010 }
3011
3012 static void vl_api_policer_add_del_reply_t_handler_json
3013   (vl_api_policer_add_del_reply_t * mp)
3014 {
3015   vat_main_t *vam = &vat_main;
3016   vat_json_node_t node;
3017
3018   vat_json_init_object (&node);
3019   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
3020   vat_json_object_add_uint (&node, "policer_index",
3021                             ntohl (mp->policer_index));
3022
3023   vat_json_print (vam->ofp, &node);
3024   vat_json_free (&node);
3025
3026   vam->retval = ntohl (mp->retval);
3027   vam->result_ready = 1;
3028 }
3029
3030 /* Format hex dump. */
3031 u8 *
3032 format_hex_bytes (u8 * s, va_list * va)
3033 {
3034   u8 *bytes = va_arg (*va, u8 *);
3035   int n_bytes = va_arg (*va, int);
3036   uword i;
3037
3038   /* Print short or long form depending on byte count. */
3039   uword short_form = n_bytes <= 32;
3040   u32 indent = format_get_indent (s);
3041
3042   if (n_bytes == 0)
3043     return s;
3044
3045   for (i = 0; i < n_bytes; i++)
3046     {
3047       if (!short_form && (i % 32) == 0)
3048         s = format (s, "%08x: ", i);
3049       s = format (s, "%02x", bytes[i]);
3050       if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
3051         s = format (s, "\n%U", format_white_space, indent);
3052     }
3053
3054   return s;
3055 }
3056
3057 static void
3058 vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
3059                                             * mp)
3060 {
3061   vat_main_t *vam = &vat_main;
3062   i32 retval = ntohl (mp->retval);
3063   if (retval == 0)
3064     {
3065       print (vam->ofp, "classify table info :");
3066       print (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d",
3067              ntohl (mp->active_sessions), ntohl (mp->next_table_index),
3068              ntohl (mp->miss_next_index));
3069       print (vam->ofp, "nbuckets: %d skip: %d match: %d",
3070              ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
3071              ntohl (mp->match_n_vectors));
3072       print (vam->ofp, "mask: %U", format_hex_bytes, mp->mask,
3073              ntohl (mp->mask_length));
3074     }
3075   vam->retval = retval;
3076   vam->result_ready = 1;
3077 }
3078
3079 static void
3080   vl_api_classify_table_info_reply_t_handler_json
3081   (vl_api_classify_table_info_reply_t * mp)
3082 {
3083   vat_main_t *vam = &vat_main;
3084   vat_json_node_t node;
3085
3086   i32 retval = ntohl (mp->retval);
3087   if (retval == 0)
3088     {
3089       vat_json_init_object (&node);
3090
3091       vat_json_object_add_int (&node, "sessions",
3092                                ntohl (mp->active_sessions));
3093       vat_json_object_add_int (&node, "nexttbl",
3094                                ntohl (mp->next_table_index));
3095       vat_json_object_add_int (&node, "nextnode",
3096                                ntohl (mp->miss_next_index));
3097       vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
3098       vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
3099       vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
3100       u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
3101                       ntohl (mp->mask_length), 0);
3102       vat_json_object_add_string_copy (&node, "mask", s);
3103
3104       vat_json_print (vam->ofp, &node);
3105       vat_json_free (&node);
3106     }
3107   vam->retval = ntohl (mp->retval);
3108   vam->result_ready = 1;
3109 }
3110
3111 static void
3112 vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
3113                                            mp)
3114 {
3115   vat_main_t *vam = &vat_main;
3116
3117   print (vam->ofp, "next_index: %d advance: %d opaque: %d ",
3118          ntohl (mp->hit_next_index), ntohl (mp->advance),
3119          ntohl (mp->opaque_index));
3120   print (vam->ofp, "mask: %U", format_hex_bytes, mp->match,
3121          ntohl (mp->match_length));
3122 }
3123
3124 static void
3125   vl_api_classify_session_details_t_handler_json
3126   (vl_api_classify_session_details_t * mp)
3127 {
3128   vat_main_t *vam = &vat_main;
3129   vat_json_node_t *node = NULL;
3130
3131   if (VAT_JSON_ARRAY != vam->json_tree.type)
3132     {
3133       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3134       vat_json_init_array (&vam->json_tree);
3135     }
3136   node = vat_json_array_add (&vam->json_tree);
3137
3138   vat_json_init_object (node);
3139   vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
3140   vat_json_object_add_int (node, "advance", ntohl (mp->advance));
3141   vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
3142   u8 *s =
3143     format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
3144             0);
3145   vat_json_object_add_string_copy (node, "match", s);
3146 }
3147
3148 static void vl_api_pg_create_interface_reply_t_handler
3149   (vl_api_pg_create_interface_reply_t * mp)
3150 {
3151   vat_main_t *vam = &vat_main;
3152
3153   vam->retval = ntohl (mp->retval);
3154   vam->result_ready = 1;
3155 }
3156
3157 static void vl_api_pg_create_interface_reply_t_handler_json
3158   (vl_api_pg_create_interface_reply_t * mp)
3159 {
3160   vat_main_t *vam = &vat_main;
3161   vat_json_node_t node;
3162
3163   i32 retval = ntohl (mp->retval);
3164   if (retval == 0)
3165     {
3166       vat_json_init_object (&node);
3167
3168       vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
3169
3170       vat_json_print (vam->ofp, &node);
3171       vat_json_free (&node);
3172     }
3173   vam->retval = ntohl (mp->retval);
3174   vam->result_ready = 1;
3175 }
3176
3177 static void vl_api_policer_classify_details_t_handler
3178   (vl_api_policer_classify_details_t * mp)
3179 {
3180   vat_main_t *vam = &vat_main;
3181
3182   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
3183          ntohl (mp->table_index));
3184 }
3185
3186 static void vl_api_policer_classify_details_t_handler_json
3187   (vl_api_policer_classify_details_t * mp)
3188 {
3189   vat_main_t *vam = &vat_main;
3190   vat_json_node_t *node;
3191
3192   if (VAT_JSON_ARRAY != vam->json_tree.type)
3193     {
3194       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3195       vat_json_init_array (&vam->json_tree);
3196     }
3197   node = vat_json_array_add (&vam->json_tree);
3198
3199   vat_json_init_object (node);
3200   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
3201   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
3202 }
3203
3204 static void vl_api_flow_classify_details_t_handler
3205   (vl_api_flow_classify_details_t * mp)
3206 {
3207   vat_main_t *vam = &vat_main;
3208
3209   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
3210          ntohl (mp->table_index));
3211 }
3212
3213 static void vl_api_flow_classify_details_t_handler_json
3214   (vl_api_flow_classify_details_t * mp)
3215 {
3216   vat_main_t *vam = &vat_main;
3217   vat_json_node_t *node;
3218
3219   if (VAT_JSON_ARRAY != vam->json_tree.type)
3220     {
3221       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3222       vat_json_init_array (&vam->json_tree);
3223     }
3224   node = vat_json_array_add (&vam->json_tree);
3225
3226   vat_json_init_object (node);
3227   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
3228   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
3229 }
3230
3231 /*
3232  * Generate boilerplate reply handlers, which
3233  * dig the return value out of the xxx_reply_t API message,
3234  * stick it into vam->retval, and set vam->result_ready
3235  *
3236  * Could also do this by pointing N message decode slots at
3237  * a single function, but that could break in subtle ways.
3238  */
3239
3240 #define foreach_standard_reply_retval_handler           \
3241 _(sw_interface_set_flags_reply)                         \
3242 _(sw_interface_add_del_address_reply)                   \
3243 _(sw_interface_set_rx_mode_reply)                       \
3244 _(sw_interface_set_rx_placement_reply)                  \
3245 _(sw_interface_set_table_reply)                         \
3246 _(sw_interface_set_mpls_enable_reply)                   \
3247 _(sw_interface_set_vpath_reply)                         \
3248 _(sw_interface_set_vxlan_bypass_reply)                  \
3249 _(sw_interface_set_vxlan_gpe_bypass_reply)              \
3250 _(sw_interface_set_l2_bridge_reply)                     \
3251 _(sw_interface_set_bond_weight_reply)                   \
3252 _(bridge_domain_add_del_reply)                          \
3253 _(sw_interface_set_l2_xconnect_reply)                   \
3254 _(l2fib_add_del_reply)                                  \
3255 _(l2fib_flush_int_reply)                                \
3256 _(l2fib_flush_bd_reply)                                 \
3257 _(ip_route_add_del_reply)                               \
3258 _(ip_table_add_del_reply)                               \
3259 _(ip_table_replace_begin_reply)                         \
3260 _(ip_table_flush_reply)                                 \
3261 _(ip_table_replace_end_reply)                           \
3262 _(ip_mroute_add_del_reply)                              \
3263 _(mpls_route_add_del_reply)                             \
3264 _(mpls_table_add_del_reply)                             \
3265 _(mpls_ip_bind_unbind_reply)                            \
3266 _(bier_route_add_del_reply)                             \
3267 _(bier_table_add_del_reply)                             \
3268 _(sw_interface_set_unnumbered_reply)                    \
3269 _(set_ip_flow_hash_reply)                               \
3270 _(sw_interface_ip6_enable_disable_reply)                \
3271 _(l2_patch_add_del_reply)                               \
3272 _(sr_mpls_policy_add_reply)                             \
3273 _(sr_mpls_policy_mod_reply)                             \
3274 _(sr_mpls_policy_del_reply)                             \
3275 _(sr_policy_add_reply)                                  \
3276 _(sr_policy_mod_reply)                                  \
3277 _(sr_policy_del_reply)                                  \
3278 _(sr_localsid_add_del_reply)                            \
3279 _(sr_steering_add_del_reply)                            \
3280 _(classify_add_del_session_reply)                       \
3281 _(classify_set_interface_ip_table_reply)                \
3282 _(classify_set_interface_l2_tables_reply)               \
3283 _(l2_fib_clear_table_reply)                             \
3284 _(l2_interface_efp_filter_reply)                        \
3285 _(l2_interface_vlan_tag_rewrite_reply)                  \
3286 _(modify_vhost_user_if_reply)                           \
3287 _(modify_vhost_user_if_v2_reply)                        \
3288 _(delete_vhost_user_if_reply)                           \
3289 _(want_l2_macs_events_reply)                            \
3290 _(input_acl_set_interface_reply)                        \
3291 _(ipsec_spd_add_del_reply)                              \
3292 _(ipsec_interface_add_del_spd_reply)                    \
3293 _(ipsec_spd_entry_add_del_reply)                        \
3294 _(ipsec_sad_entry_add_del_reply)                        \
3295 _(delete_loopback_reply)                                \
3296 _(bd_ip_mac_add_del_reply)                              \
3297 _(bd_ip_mac_flush_reply)                                \
3298 _(want_interface_events_reply)                          \
3299 _(cop_interface_enable_disable_reply)                   \
3300 _(cop_whitelist_enable_disable_reply)                   \
3301 _(sw_interface_clear_stats_reply)                       \
3302 _(ioam_enable_reply)                                    \
3303 _(ioam_disable_reply)                                   \
3304 _(af_packet_delete_reply)                               \
3305 _(policer_classify_set_interface_reply)                 \
3306 _(set_ipfix_exporter_reply)                             \
3307 _(set_ipfix_classify_stream_reply)                      \
3308 _(ipfix_classify_table_add_del_reply)                   \
3309 _(flow_classify_set_interface_reply)                    \
3310 _(sw_interface_span_enable_disable_reply)               \
3311 _(pg_capture_reply)                                     \
3312 _(pg_enable_disable_reply)                              \
3313 _(pg_interface_enable_disable_coalesce_reply)           \
3314 _(ip_source_and_port_range_check_add_del_reply)         \
3315 _(ip_source_and_port_range_check_interface_add_del_reply)\
3316 _(delete_subif_reply)                                   \
3317 _(l2_interface_pbb_tag_rewrite_reply)                   \
3318 _(set_punt_reply)                                       \
3319 _(feature_enable_disable_reply)                         \
3320 _(feature_gso_enable_disable_reply)                     \
3321 _(sw_interface_tag_add_del_reply)                       \
3322 _(sw_interface_add_del_mac_address_reply)               \
3323 _(hw_interface_set_mtu_reply)                           \
3324 _(p2p_ethernet_add_reply)                               \
3325 _(p2p_ethernet_del_reply)                               \
3326 _(tcp_configure_src_addresses_reply)                    \
3327 _(session_rule_add_del_reply)                           \
3328 _(ip_container_proxy_add_del_reply)                     \
3329 _(output_acl_set_interface_reply)                       \
3330 _(qos_record_enable_disable_reply)                      \
3331 _(flow_add_reply)
3332
3333 #define _(n)                                    \
3334     static void vl_api_##n##_t_handler          \
3335     (vl_api_##n##_t * mp)                       \
3336     {                                           \
3337         vat_main_t * vam = &vat_main;           \
3338         i32 retval = ntohl(mp->retval);         \
3339         if (vam->async_mode) {                  \
3340             vam->async_errors += (retval < 0);  \
3341         } else {                                \
3342             vam->retval = retval;               \
3343             vam->result_ready = 1;              \
3344         }                                       \
3345     }
3346 foreach_standard_reply_retval_handler;
3347 #undef _
3348
3349 #define _(n)                                    \
3350     static void vl_api_##n##_t_handler_json     \
3351     (vl_api_##n##_t * mp)                       \
3352     {                                           \
3353         vat_main_t * vam = &vat_main;           \
3354         vat_json_node_t node;                   \
3355         vat_json_init_object(&node);            \
3356         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
3357         vat_json_print(vam->ofp, &node);        \
3358         vam->retval = ntohl(mp->retval);        \
3359         vam->result_ready = 1;                  \
3360     }
3361 foreach_standard_reply_retval_handler;
3362 #undef _
3363
3364 /*
3365  * Table of message reply handlers, must include boilerplate handlers
3366  * we just generated
3367  */
3368
3369 #define foreach_vpe_api_reply_msg                                       \
3370 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
3371 _(CREATE_LOOPBACK_INSTANCE_REPLY, create_loopback_instance_reply)       \
3372 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
3373 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
3374 _(CONTROL_PING_REPLY, control_ping_reply)                               \
3375 _(CLI_REPLY, cli_reply)                                                 \
3376 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
3377 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
3378   sw_interface_add_del_address_reply)                                   \
3379 _(SW_INTERFACE_SET_RX_MODE_REPLY, sw_interface_set_rx_mode_reply)       \
3380 _(SW_INTERFACE_SET_RX_PLACEMENT_REPLY, sw_interface_set_rx_placement_reply)     \
3381 _(SW_INTERFACE_RX_PLACEMENT_DETAILS, sw_interface_rx_placement_details) \
3382 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
3383 _(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
3384 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
3385 _(SW_INTERFACE_SET_VXLAN_BYPASS_REPLY, sw_interface_set_vxlan_bypass_reply) \
3386 _(SW_INTERFACE_SET_VXLAN_GPE_BYPASS_REPLY, sw_interface_set_vxlan_gpe_bypass_reply) \
3387 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
3388   sw_interface_set_l2_xconnect_reply)                                   \
3389 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
3390   sw_interface_set_l2_bridge_reply)                                     \
3391 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
3392 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
3393 _(BRIDGE_DOMAIN_SET_MAC_AGE_REPLY, bridge_domain_set_mac_age_reply)     \
3394 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
3395 _(L2FIB_FLUSH_INT_REPLY, l2fib_flush_int_reply)                         \
3396 _(L2FIB_FLUSH_BD_REPLY, l2fib_flush_bd_reply)                           \
3397 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
3398 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
3399 _(TAP_CREATE_V2_REPLY, tap_create_v2_reply)                             \
3400 _(TAP_DELETE_V2_REPLY, tap_delete_v2_reply)                             \
3401 _(SW_INTERFACE_TAP_V2_DETAILS, sw_interface_tap_v2_details)             \
3402 _(VIRTIO_PCI_CREATE_REPLY, virtio_pci_create_reply)                     \
3403 _(VIRTIO_PCI_CREATE_V2_REPLY, virtio_pci_create_v2_reply)               \
3404 _(VIRTIO_PCI_DELETE_REPLY, virtio_pci_delete_reply)                     \
3405 _(SW_INTERFACE_VIRTIO_PCI_DETAILS, sw_interface_virtio_pci_details)     \
3406 _(BOND_CREATE_REPLY, bond_create_reply)                                 \
3407 _(BOND_CREATE2_REPLY, bond_create2_reply)                               \
3408 _(BOND_DELETE_REPLY, bond_delete_reply)                                 \
3409 _(BOND_ADD_MEMBER_REPLY, bond_add_member_reply)                         \
3410 _(BOND_DETACH_MEMBER_REPLY, bond_detach_member_reply)                   \
3411 _(SW_INTERFACE_SET_BOND_WEIGHT_REPLY, sw_interface_set_bond_weight_reply) \
3412 _(SW_BOND_INTERFACE_DETAILS, sw_bond_interface_details)                 \
3413 _(SW_MEMBER_INTERFACE_DETAILS, sw_member_interface_details)               \
3414 _(IP_ROUTE_ADD_DEL_REPLY, ip_route_add_del_reply)                       \
3415 _(IP_TABLE_ADD_DEL_REPLY, ip_table_add_del_reply)                       \
3416 _(IP_TABLE_REPLACE_BEGIN_REPLY, ip_table_replace_begin_reply)           \
3417 _(IP_TABLE_FLUSH_REPLY, ip_table_flush_reply)                           \
3418 _(IP_TABLE_REPLACE_END_REPLY, ip_table_replace_end_reply)               \
3419 _(IP_MROUTE_ADD_DEL_REPLY, ip_mroute_add_del_reply)                     \
3420 _(MPLS_TABLE_ADD_DEL_REPLY, mpls_table_add_del_reply)                   \
3421 _(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply)                   \
3422 _(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply)                 \
3423 _(BIER_ROUTE_ADD_DEL_REPLY, bier_route_add_del_reply)                   \
3424 _(BIER_TABLE_ADD_DEL_REPLY, bier_table_add_del_reply)                   \
3425 _(MPLS_TUNNEL_ADD_DEL_REPLY, mpls_tunnel_add_del_reply)                 \
3426 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
3427   sw_interface_set_unnumbered_reply)                                    \
3428 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
3429 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
3430 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
3431 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
3432   sw_interface_ip6_enable_disable_reply)                                \
3433 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
3434 _(SR_MPLS_POLICY_ADD_REPLY, sr_mpls_policy_add_reply)                   \
3435 _(SR_MPLS_POLICY_MOD_REPLY, sr_mpls_policy_mod_reply)                   \
3436 _(SR_MPLS_POLICY_DEL_REPLY, sr_mpls_policy_del_reply)                   \
3437 _(SR_POLICY_ADD_REPLY, sr_policy_add_reply)                             \
3438 _(SR_POLICY_MOD_REPLY, sr_policy_mod_reply)                             \
3439 _(SR_POLICY_DEL_REPLY, sr_policy_del_reply)                             \
3440 _(SR_LOCALSID_ADD_DEL_REPLY, sr_localsid_add_del_reply)                 \
3441 _(SR_STEERING_ADD_DEL_REPLY, sr_steering_add_del_reply)                 \
3442 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
3443 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
3444 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
3445 classify_set_interface_ip_table_reply)                                  \
3446 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
3447   classify_set_interface_l2_tables_reply)                               \
3448 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
3449 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
3450 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
3451 _(VXLAN_OFFLOAD_RX_REPLY, vxlan_offload_rx_reply)               \
3452 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
3453 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
3454 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
3455 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
3456 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
3457 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
3458 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
3459 _(CREATE_VHOST_USER_IF_V2_REPLY, create_vhost_user_if_v2_reply)         \
3460 _(MODIFY_VHOST_USER_IF_V2_REPLY, modify_vhost_user_if_v2_reply)         \
3461 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
3462 _(SHOW_VERSION_REPLY, show_version_reply)                               \
3463 _(SHOW_THREADS_REPLY, show_threads_reply)                               \
3464 _(L2_FIB_TABLE_DETAILS, l2_fib_table_details)                           \
3465 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)       \
3466 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
3467 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
3468 _(WANT_L2_MACS_EVENTS_REPLY, want_l2_macs_events_reply)                 \
3469 _(L2_MACS_EVENT, l2_macs_event)                                         \
3470 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
3471 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
3472 _(IP_DETAILS, ip_details)                                               \
3473 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
3474 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
3475 _(IPSEC_SPD_ENTRY_ADD_DEL_REPLY, ipsec_spd_entry_add_del_reply)         \
3476 _(IPSEC_SAD_ENTRY_ADD_DEL_REPLY, ipsec_sad_entry_add_del_reply)         \
3477 _(IPSEC_SA_DETAILS, ipsec_sa_details)                                   \
3478 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
3479 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
3480 _(BD_IP_MAC_FLUSH_REPLY, bd_ip_mac_flush_reply)                         \
3481 _(BD_IP_MAC_DETAILS, bd_ip_mac_details)                                 \
3482 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
3483 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
3484 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
3485 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
3486 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
3487 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
3488 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
3489 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
3490 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
3491 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
3492 _(AF_PACKET_DETAILS, af_packet_details)                                 \
3493 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
3494 _(POLICER_DETAILS, policer_details)                                     \
3495 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
3496 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
3497 _(MPLS_TUNNEL_DETAILS, mpls_tunnel_details)                             \
3498 _(MPLS_TABLE_DETAILS, mpls_table_details)                               \
3499 _(MPLS_ROUTE_DETAILS, mpls_route_details)                               \
3500 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
3501 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
3502 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
3503 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
3504 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
3505 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
3506 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
3507 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
3508 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
3509 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
3510 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
3511 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
3512 _(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
3513 _(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details)                 \
3514 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
3515 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
3516 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
3517 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
3518 _(PG_INTERFACE_ENABLE_DISABLE_COALESCE_REPLY, pg_interface_enable_disable_coalesce_reply) \
3519 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
3520  ip_source_and_port_range_check_add_del_reply)                          \
3521 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
3522  ip_source_and_port_range_check_interface_add_del_reply)                \
3523 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
3524 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
3525 _(SET_PUNT_REPLY, set_punt_reply)                                       \
3526 _(IP_TABLE_DETAILS, ip_table_details)                                   \
3527 _(IP_ROUTE_DETAILS, ip_route_details)                                   \
3528 _(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply)           \
3529 _(FEATURE_GSO_ENABLE_DISABLE_REPLY, feature_gso_enable_disable_reply)   \
3530 _(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply)       \
3531 _(SW_INTERFACE_ADD_DEL_MAC_ADDRESS_REPLY, sw_interface_add_del_mac_address_reply) \
3532 _(L2_XCONNECT_DETAILS, l2_xconnect_details)                             \
3533 _(HW_INTERFACE_SET_MTU_REPLY, hw_interface_set_mtu_reply)               \
3534 _(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply)           \
3535 _(P2P_ETHERNET_ADD_REPLY, p2p_ethernet_add_reply)                       \
3536 _(P2P_ETHERNET_DEL_REPLY, p2p_ethernet_del_reply)                       \
3537 _(TCP_CONFIGURE_SRC_ADDRESSES_REPLY, tcp_configure_src_addresses_reply) \
3538 _(APP_NAMESPACE_ADD_DEL_REPLY, app_namespace_add_del_reply)             \
3539 _(SESSION_RULE_ADD_DEL_REPLY, session_rule_add_del_reply)               \
3540 _(SESSION_RULES_DETAILS, session_rules_details)                         \
3541 _(IP_CONTAINER_PROXY_ADD_DEL_REPLY, ip_container_proxy_add_del_reply)   \
3542 _(OUTPUT_ACL_SET_INTERFACE_REPLY, output_acl_set_interface_reply)       \
3543 _(QOS_RECORD_ENABLE_DISABLE_REPLY, qos_record_enable_disable_reply)             \
3544 _(FLOW_ADD_REPLY, flow_add_reply)   \
3545
3546 #define foreach_standalone_reply_msg                                    \
3547 _(SW_INTERFACE_EVENT, sw_interface_event)
3548
3549 typedef struct
3550 {
3551   u8 *name;
3552   u32 value;
3553 } name_sort_t;
3554
3555 #define STR_VTR_OP_CASE(op)     \
3556     case L2_VTR_ ## op:         \
3557         return "" # op;
3558
3559 static const char *
3560 str_vtr_op (u32 vtr_op)
3561 {
3562   switch (vtr_op)
3563     {
3564       STR_VTR_OP_CASE (DISABLED);
3565       STR_VTR_OP_CASE (PUSH_1);
3566       STR_VTR_OP_CASE (PUSH_2);
3567       STR_VTR_OP_CASE (POP_1);
3568       STR_VTR_OP_CASE (POP_2);
3569       STR_VTR_OP_CASE (TRANSLATE_1_1);
3570       STR_VTR_OP_CASE (TRANSLATE_1_2);
3571       STR_VTR_OP_CASE (TRANSLATE_2_1);
3572       STR_VTR_OP_CASE (TRANSLATE_2_2);
3573     }
3574
3575   return "UNKNOWN";
3576 }
3577
3578 static int
3579 dump_sub_interface_table (vat_main_t * vam)
3580 {
3581   const sw_interface_subif_t *sub = NULL;
3582
3583   if (vam->json_output)
3584     {
3585       clib_warning
3586         ("JSON output supported only for VPE API calls and dump_stats_table");
3587       return -99;
3588     }
3589
3590   print (vam->ofp,
3591          "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
3592          "Interface", "sw_if_index",
3593          "sub id", "dot1ad", "tags", "outer id",
3594          "inner id", "exact", "default", "outer any", "inner any");
3595
3596   vec_foreach (sub, vam->sw_if_subif_table)
3597   {
3598     print (vam->ofp,
3599            "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
3600            sub->interface_name,
3601            sub->sw_if_index,
3602            sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
3603            sub->sub_number_of_tags, sub->sub_outer_vlan_id,
3604            sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
3605            sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
3606     if (sub->vtr_op != L2_VTR_DISABLED)
3607       {
3608         print (vam->ofp,
3609                "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
3610                "tag1: %d tag2: %d ]",
3611                str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
3612                sub->vtr_tag1, sub->vtr_tag2);
3613       }
3614   }
3615
3616   return 0;
3617 }
3618
3619 static int
3620 name_sort_cmp (void *a1, void *a2)
3621 {
3622   name_sort_t *n1 = a1;
3623   name_sort_t *n2 = a2;
3624
3625   return strcmp ((char *) n1->name, (char *) n2->name);
3626 }
3627
3628 static int
3629 dump_interface_table (vat_main_t * vam)
3630 {
3631   hash_pair_t *p;
3632   name_sort_t *nses = 0, *ns;
3633
3634   if (vam->json_output)
3635     {
3636       clib_warning
3637         ("JSON output supported only for VPE API calls and dump_stats_table");
3638       return -99;
3639     }
3640
3641   /* *INDENT-OFF* */
3642   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
3643   ({
3644     vec_add2 (nses, ns, 1);
3645     ns->name = (u8 *)(p->key);
3646     ns->value = (u32) p->value[0];
3647   }));
3648   /* *INDENT-ON* */
3649
3650   vec_sort_with_function (nses, name_sort_cmp);
3651
3652   print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
3653   vec_foreach (ns, nses)
3654   {
3655     print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
3656   }
3657   vec_free (nses);
3658   return 0;
3659 }
3660
3661 static int
3662 dump_ip_table (vat_main_t * vam, int is_ipv6)
3663 {
3664   const ip_details_t *det = NULL;
3665   const ip_address_details_t *address = NULL;
3666   u32 i = ~0;
3667
3668   print (vam->ofp, "%-12s", "sw_if_index");
3669
3670   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
3671   {
3672     i++;
3673     if (!det->present)
3674       {
3675         continue;
3676       }
3677     print (vam->ofp, "%-12d", i);
3678     print (vam->ofp, "            %-30s%-13s", "Address", "Prefix length");
3679     if (!det->addr)
3680       {
3681         continue;
3682       }
3683     vec_foreach (address, det->addr)
3684     {
3685       print (vam->ofp,
3686              "            %-30U%-13d",
3687              is_ipv6 ? format_ip6_address : format_ip4_address,
3688              address->ip, address->prefix_length);
3689     }
3690   }
3691
3692   return 0;
3693 }
3694
3695 static int
3696 dump_ipv4_table (vat_main_t * vam)
3697 {
3698   if (vam->json_output)
3699     {
3700       clib_warning
3701         ("JSON output supported only for VPE API calls and dump_stats_table");
3702       return -99;
3703     }
3704
3705   return dump_ip_table (vam, 0);
3706 }
3707
3708 static int
3709 dump_ipv6_table (vat_main_t * vam)
3710 {
3711   if (vam->json_output)
3712     {
3713       clib_warning
3714         ("JSON output supported only for VPE API calls and dump_stats_table");
3715       return -99;
3716     }
3717
3718   return dump_ip_table (vam, 1);
3719 }
3720
3721 /*
3722  * Pass CLI buffers directly in the CLI_INBAND API message,
3723  * instead of an additional shared memory area.
3724  */
3725 static int
3726 exec_inband (vat_main_t * vam)
3727 {
3728   vl_api_cli_inband_t *mp;
3729   unformat_input_t *i = vam->input;
3730   int ret;
3731
3732   if (vec_len (i->buffer) == 0)
3733     return -1;
3734
3735   if (vam->exec_mode == 0 && unformat (i, "mode"))
3736     {
3737       vam->exec_mode = 1;
3738       return 0;
3739     }
3740   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
3741     {
3742       vam->exec_mode = 0;
3743       return 0;
3744     }
3745
3746   /*
3747    * In order for the CLI command to work, it
3748    * must be a vector ending in \n, not a C-string ending
3749    * in \n\0.
3750    */
3751   M2 (CLI_INBAND, mp, vec_len (vam->input->buffer));
3752   vl_api_vec_to_api_string (vam->input->buffer, &mp->cmd);
3753
3754   S (mp);
3755   W (ret);
3756   /* json responses may or may not include a useful reply... */
3757   if (vec_len (vam->cmd_reply))
3758     print (vam->ofp, "%v", (char *) (vam->cmd_reply));
3759   return ret;
3760 }
3761
3762 int
3763 exec (vat_main_t * vam)
3764 {
3765   return exec_inband (vam);
3766 }
3767
3768 static int
3769 api_create_loopback (vat_main_t * vam)
3770 {
3771   unformat_input_t *i = vam->input;
3772   vl_api_create_loopback_t *mp;
3773   vl_api_create_loopback_instance_t *mp_lbi;
3774   u8 mac_address[6];
3775   u8 mac_set = 0;
3776   u8 is_specified = 0;
3777   u32 user_instance = 0;
3778   int ret;
3779
3780   clib_memset (mac_address, 0, sizeof (mac_address));
3781
3782   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
3783     {
3784       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
3785         mac_set = 1;
3786       if (unformat (i, "instance %d", &user_instance))
3787         is_specified = 1;
3788       else
3789         break;
3790     }
3791
3792   if (is_specified)
3793     {
3794       M (CREATE_LOOPBACK_INSTANCE, mp_lbi);
3795       mp_lbi->is_specified = is_specified;
3796       if (is_specified)
3797         mp_lbi->user_instance = htonl (user_instance);
3798       if (mac_set)
3799         clib_memcpy (mp_lbi->mac_address, mac_address, sizeof (mac_address));
3800       S (mp_lbi);
3801     }
3802   else
3803     {
3804       /* Construct the API message */
3805       M (CREATE_LOOPBACK, mp);
3806       if (mac_set)
3807         clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
3808       S (mp);
3809     }
3810
3811   W (ret);
3812   return ret;
3813 }
3814
3815 static int
3816 api_delete_loopback (vat_main_t * vam)
3817 {
3818   unformat_input_t *i = vam->input;
3819   vl_api_delete_loopback_t *mp;
3820   u32 sw_if_index = ~0;
3821   int ret;
3822
3823   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
3824     {
3825       if (unformat (i, "sw_if_index %d", &sw_if_index))
3826         ;
3827       else
3828         break;
3829     }
3830
3831   if (sw_if_index == ~0)
3832     {
3833       errmsg ("missing sw_if_index");
3834       return -99;
3835     }
3836
3837   /* Construct the API message */
3838   M (DELETE_LOOPBACK, mp);
3839   mp->sw_if_index = ntohl (sw_if_index);
3840
3841   S (mp);
3842   W (ret);
3843   return ret;
3844 }
3845
3846 static int
3847 api_want_interface_events (vat_main_t * vam)
3848 {
3849   unformat_input_t *i = vam->input;
3850   vl_api_want_interface_events_t *mp;
3851   int enable = -1;
3852   int ret;
3853
3854   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
3855     {
3856       if (unformat (i, "enable"))
3857         enable = 1;
3858       else if (unformat (i, "disable"))
3859         enable = 0;
3860       else
3861         break;
3862     }
3863
3864   if (enable == -1)
3865     {
3866       errmsg ("missing enable|disable");
3867       return -99;
3868     }
3869
3870   M (WANT_INTERFACE_EVENTS, mp);
3871   mp->enable_disable = enable;
3872
3873   vam->interface_event_display = enable;
3874
3875   S (mp);
3876   W (ret);
3877   return ret;
3878 }
3879
3880
3881 /* Note: non-static, called once to set up the initial intfc table */
3882 int
3883 api_sw_interface_dump (vat_main_t * vam)
3884 {
3885   vl_api_sw_interface_dump_t *mp;
3886   vl_api_control_ping_t *mp_ping;
3887   hash_pair_t *p;
3888   name_sort_t *nses = 0, *ns;
3889   sw_interface_subif_t *sub = NULL;
3890   int ret;
3891
3892   /* Toss the old name table */
3893   /* *INDENT-OFF* */
3894   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
3895   ({
3896     vec_add2 (nses, ns, 1);
3897     ns->name = (u8 *)(p->key);
3898     ns->value = (u32) p->value[0];
3899   }));
3900   /* *INDENT-ON* */
3901
3902   hash_free (vam->sw_if_index_by_interface_name);
3903
3904   vec_foreach (ns, nses) vec_free (ns->name);
3905
3906   vec_free (nses);
3907
3908   vec_foreach (sub, vam->sw_if_subif_table)
3909   {
3910     vec_free (sub->interface_name);
3911   }
3912   vec_free (vam->sw_if_subif_table);
3913
3914   /* recreate the interface name hash table */
3915   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
3916
3917   /*
3918    * Ask for all interface names. Otherwise, the epic catalog of
3919    * name filters becomes ridiculously long, and vat ends up needing
3920    * to be taught about new interface types.
3921    */
3922   M (SW_INTERFACE_DUMP, mp);
3923   S (mp);
3924
3925   /* Use a control ping for synchronization */
3926   MPING (CONTROL_PING, mp_ping);
3927   S (mp_ping);
3928
3929   W (ret);
3930   return ret;
3931 }
3932
3933 static int
3934 api_sw_interface_set_flags (vat_main_t * vam)
3935 {
3936   unformat_input_t *i = vam->input;
3937   vl_api_sw_interface_set_flags_t *mp;
3938   u32 sw_if_index;
3939   u8 sw_if_index_set = 0;
3940   u8 admin_up = 0;
3941   int ret;
3942
3943   /* Parse args required to build the message */
3944   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
3945     {
3946       if (unformat (i, "admin-up"))
3947         admin_up = 1;
3948       else if (unformat (i, "admin-down"))
3949         admin_up = 0;
3950       else
3951         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
3952         sw_if_index_set = 1;
3953       else if (unformat (i, "sw_if_index %d", &sw_if_index))
3954         sw_if_index_set = 1;
3955       else
3956         break;
3957     }
3958
3959   if (sw_if_index_set == 0)
3960     {
3961       errmsg ("missing interface name or sw_if_index");
3962       return -99;
3963     }
3964
3965   /* Construct the API message */
3966   M (SW_INTERFACE_SET_FLAGS, mp);
3967   mp->sw_if_index = ntohl (sw_if_index);
3968   mp->flags = ntohl ((admin_up) ? IF_STATUS_API_FLAG_ADMIN_UP : 0);
3969
3970   /* send it... */
3971   S (mp);
3972
3973   /* Wait for a reply, return the good/bad news... */
3974   W (ret);
3975   return ret;
3976 }
3977
3978 static int
3979 api_sw_interface_set_rx_mode (vat_main_t * vam)
3980 {
3981   unformat_input_t *i = vam->input;
3982   vl_api_sw_interface_set_rx_mode_t *mp;
3983   u32 sw_if_index;
3984   u8 sw_if_index_set = 0;
3985   int ret;
3986   u8 queue_id_valid = 0;
3987   u32 queue_id;
3988   vnet_hw_if_rx_mode mode = VNET_HW_IF_RX_MODE_UNKNOWN;
3989
3990   /* Parse args required to build the message */
3991   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
3992     {
3993       if (unformat (i, "queue %d", &queue_id))
3994         queue_id_valid = 1;
3995       else if (unformat (i, "polling"))
3996         mode = VNET_HW_IF_RX_MODE_POLLING;
3997       else if (unformat (i, "interrupt"))
3998         mode = VNET_HW_IF_RX_MODE_INTERRUPT;
3999       else if (unformat (i, "adaptive"))
4000         mode = VNET_HW_IF_RX_MODE_ADAPTIVE;
4001       else
4002         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
4003         sw_if_index_set = 1;
4004       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4005         sw_if_index_set = 1;
4006       else
4007         break;
4008     }
4009
4010   if (sw_if_index_set == 0)
4011     {
4012       errmsg ("missing interface name or sw_if_index");
4013       return -99;
4014     }
4015   if (mode == VNET_HW_IF_RX_MODE_UNKNOWN)
4016     {
4017       errmsg ("missing rx-mode");
4018       return -99;
4019     }
4020
4021   /* Construct the API message */
4022   M (SW_INTERFACE_SET_RX_MODE, mp);
4023   mp->sw_if_index = ntohl (sw_if_index);
4024   mp->mode = (vl_api_rx_mode_t) mode;
4025   mp->queue_id_valid = queue_id_valid;
4026   mp->queue_id = queue_id_valid ? ntohl (queue_id) : ~0;
4027
4028   /* send it... */
4029   S (mp);
4030
4031   /* Wait for a reply, return the good/bad news... */
4032   W (ret);
4033   return ret;
4034 }
4035
4036 static int
4037 api_sw_interface_set_rx_placement (vat_main_t * vam)
4038 {
4039   unformat_input_t *i = vam->input;
4040   vl_api_sw_interface_set_rx_placement_t *mp;
4041   u32 sw_if_index;
4042   u8 sw_if_index_set = 0;
4043   int ret;
4044   u8 is_main = 0;
4045   u32 queue_id, thread_index;
4046
4047   /* Parse args required to build the message */
4048   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4049     {
4050       if (unformat (i, "queue %d", &queue_id))
4051         ;
4052       else if (unformat (i, "main"))
4053         is_main = 1;
4054       else if (unformat (i, "worker %d", &thread_index))
4055         ;
4056       else
4057         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
4058         sw_if_index_set = 1;
4059       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4060         sw_if_index_set = 1;
4061       else
4062         break;
4063     }
4064
4065   if (sw_if_index_set == 0)
4066     {
4067       errmsg ("missing interface name or sw_if_index");
4068       return -99;
4069     }
4070
4071   if (is_main)
4072     thread_index = 0;
4073   /* Construct the API message */
4074   M (SW_INTERFACE_SET_RX_PLACEMENT, mp);
4075   mp->sw_if_index = ntohl (sw_if_index);
4076   mp->worker_id = ntohl (thread_index);
4077   mp->queue_id = ntohl (queue_id);
4078   mp->is_main = is_main;
4079
4080   /* send it... */
4081   S (mp);
4082   /* Wait for a reply, return the good/bad news... */
4083   W (ret);
4084   return ret;
4085 }
4086
4087 static void vl_api_sw_interface_rx_placement_details_t_handler
4088   (vl_api_sw_interface_rx_placement_details_t * mp)
4089 {
4090   vat_main_t *vam = &vat_main;
4091   u32 worker_id = ntohl (mp->worker_id);
4092
4093   print (vam->ofp,
4094          "\n%-11d %-11s %-6d %-5d %-9s",
4095          ntohl (mp->sw_if_index), (worker_id == 0) ? "main" : "worker",
4096          worker_id, ntohl (mp->queue_id),
4097          (mp->mode ==
4098           1) ? "polling" : ((mp->mode == 2) ? "interrupt" : "adaptive"));
4099 }
4100
4101 static void vl_api_sw_interface_rx_placement_details_t_handler_json
4102   (vl_api_sw_interface_rx_placement_details_t * mp)
4103 {
4104   vat_main_t *vam = &vat_main;
4105   vat_json_node_t *node = NULL;
4106
4107   if (VAT_JSON_ARRAY != vam->json_tree.type)
4108     {
4109       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4110       vat_json_init_array (&vam->json_tree);
4111     }
4112   node = vat_json_array_add (&vam->json_tree);
4113
4114   vat_json_init_object (node);
4115   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
4116   vat_json_object_add_uint (node, "worker_id", ntohl (mp->worker_id));
4117   vat_json_object_add_uint (node, "queue_id", ntohl (mp->queue_id));
4118   vat_json_object_add_uint (node, "mode", mp->mode);
4119 }
4120
4121 static int
4122 api_sw_interface_rx_placement_dump (vat_main_t * vam)
4123 {
4124   unformat_input_t *i = vam->input;
4125   vl_api_sw_interface_rx_placement_dump_t *mp;
4126   vl_api_control_ping_t *mp_ping;
4127   int ret;
4128   u32 sw_if_index;
4129   u8 sw_if_index_set = 0;
4130
4131   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4132     {
4133       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
4134         sw_if_index_set++;
4135       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4136         sw_if_index_set++;
4137       else
4138         break;
4139     }
4140
4141   print (vam->ofp,
4142          "\n%-11s %-11s %-6s %-5s %-4s",
4143          "sw_if_index", "main/worker", "thread", "queue", "mode");
4144
4145   /* Dump Interface rx placement */
4146   M (SW_INTERFACE_RX_PLACEMENT_DUMP, mp);
4147
4148   if (sw_if_index_set)
4149     mp->sw_if_index = htonl (sw_if_index);
4150   else
4151     mp->sw_if_index = ~0;
4152
4153   S (mp);
4154
4155   /* Use a control ping for synchronization */
4156   MPING (CONTROL_PING, mp_ping);
4157   S (mp_ping);
4158
4159   W (ret);
4160   return ret;
4161 }
4162
4163 static int
4164 api_sw_interface_clear_stats (vat_main_t * vam)
4165 {
4166   unformat_input_t *i = vam->input;
4167   vl_api_sw_interface_clear_stats_t *mp;
4168   u32 sw_if_index;
4169   u8 sw_if_index_set = 0;
4170   int ret;
4171
4172   /* Parse args required to build the message */
4173   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4174     {
4175       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
4176         sw_if_index_set = 1;
4177       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4178         sw_if_index_set = 1;
4179       else
4180         break;
4181     }
4182
4183   /* Construct the API message */
4184   M (SW_INTERFACE_CLEAR_STATS, mp);
4185
4186   if (sw_if_index_set == 1)
4187     mp->sw_if_index = ntohl (sw_if_index);
4188   else
4189     mp->sw_if_index = ~0;
4190
4191   /* send it... */
4192   S (mp);
4193
4194   /* Wait for a reply, return the good/bad news... */
4195   W (ret);
4196   return ret;
4197 }
4198
4199 static int
4200 api_sw_interface_add_del_address (vat_main_t * vam)
4201 {
4202   unformat_input_t *i = vam->input;
4203   vl_api_sw_interface_add_del_address_t *mp;
4204   u32 sw_if_index;
4205   u8 sw_if_index_set = 0;
4206   u8 is_add = 1, del_all = 0;
4207   u32 address_length = 0;
4208   u8 v4_address_set = 0;
4209   u8 v6_address_set = 0;
4210   ip4_address_t v4address;
4211   ip6_address_t v6address;
4212   int ret;
4213
4214   /* Parse args required to build the message */
4215   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4216     {
4217       if (unformat (i, "del-all"))
4218         del_all = 1;
4219       else if (unformat (i, "del"))
4220         is_add = 0;
4221       else
4222         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
4223         sw_if_index_set = 1;
4224       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4225         sw_if_index_set = 1;
4226       else if (unformat (i, "%U/%d",
4227                          unformat_ip4_address, &v4address, &address_length))
4228         v4_address_set = 1;
4229       else if (unformat (i, "%U/%d",
4230                          unformat_ip6_address, &v6address, &address_length))
4231         v6_address_set = 1;
4232       else
4233         break;
4234     }
4235
4236   if (sw_if_index_set == 0)
4237     {
4238       errmsg ("missing interface name or sw_if_index");
4239       return -99;
4240     }
4241   if (v4_address_set && v6_address_set)
4242     {
4243       errmsg ("both v4 and v6 addresses set");
4244       return -99;
4245     }
4246   if (!v4_address_set && !v6_address_set && !del_all)
4247     {
4248       errmsg ("no addresses set");
4249       return -99;
4250     }
4251
4252   /* Construct the API message */
4253   M (SW_INTERFACE_ADD_DEL_ADDRESS, mp);
4254
4255   mp->sw_if_index = ntohl (sw_if_index);
4256   mp->is_add = is_add;
4257   mp->del_all = del_all;
4258   if (v6_address_set)
4259     {
4260       mp->prefix.address.af = ADDRESS_IP6;
4261       clib_memcpy (mp->prefix.address.un.ip6, &v6address, sizeof (v6address));
4262     }
4263   else
4264     {
4265       mp->prefix.address.af = ADDRESS_IP4;
4266       clib_memcpy (mp->prefix.address.un.ip4, &v4address, sizeof (v4address));
4267     }
4268   mp->prefix.len = address_length;
4269
4270   /* send it... */
4271   S (mp);
4272
4273   /* Wait for a reply, return good/bad news  */
4274   W (ret);
4275   return ret;
4276 }
4277
4278 static int
4279 api_sw_interface_set_mpls_enable (vat_main_t * vam)
4280 {
4281   unformat_input_t *i = vam->input;
4282   vl_api_sw_interface_set_mpls_enable_t *mp;
4283   u32 sw_if_index;
4284   u8 sw_if_index_set = 0;
4285   u8 enable = 1;
4286   int ret;
4287
4288   /* Parse args required to build the message */
4289   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4290     {
4291       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
4292         sw_if_index_set = 1;
4293       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4294         sw_if_index_set = 1;
4295       else if (unformat (i, "disable"))
4296         enable = 0;
4297       else if (unformat (i, "dis"))
4298         enable = 0;
4299       else
4300         break;
4301     }
4302
4303   if (sw_if_index_set == 0)
4304     {
4305       errmsg ("missing interface name or sw_if_index");
4306       return -99;
4307     }
4308
4309   /* Construct the API message */
4310   M (SW_INTERFACE_SET_MPLS_ENABLE, mp);
4311
4312   mp->sw_if_index = ntohl (sw_if_index);
4313   mp->enable = enable;
4314
4315   /* send it... */
4316   S (mp);
4317
4318   /* Wait for a reply... */
4319   W (ret);
4320   return ret;
4321 }
4322
4323 static int
4324 api_sw_interface_set_table (vat_main_t * vam)
4325 {
4326   unformat_input_t *i = vam->input;
4327   vl_api_sw_interface_set_table_t *mp;
4328   u32 sw_if_index, vrf_id = 0;
4329   u8 sw_if_index_set = 0;
4330   u8 is_ipv6 = 0;
4331   int ret;
4332
4333   /* Parse args required to build the message */
4334   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4335     {
4336       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
4337         sw_if_index_set = 1;
4338       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4339         sw_if_index_set = 1;
4340       else if (unformat (i, "vrf %d", &vrf_id))
4341         ;
4342       else if (unformat (i, "ipv6"))
4343         is_ipv6 = 1;
4344       else
4345         break;
4346     }
4347
4348   if (sw_if_index_set == 0)
4349     {
4350       errmsg ("missing interface name or sw_if_index");
4351       return -99;
4352     }
4353
4354   /* Construct the API message */
4355   M (SW_INTERFACE_SET_TABLE, mp);
4356
4357   mp->sw_if_index = ntohl (sw_if_index);
4358   mp->is_ipv6 = is_ipv6;
4359   mp->vrf_id = ntohl (vrf_id);
4360
4361   /* send it... */
4362   S (mp);
4363
4364   /* Wait for a reply... */
4365   W (ret);
4366   return ret;
4367 }
4368
4369 static void vl_api_sw_interface_get_table_reply_t_handler
4370   (vl_api_sw_interface_get_table_reply_t * mp)
4371 {
4372   vat_main_t *vam = &vat_main;
4373
4374   print (vam->ofp, "%d", ntohl (mp->vrf_id));
4375
4376   vam->retval = ntohl (mp->retval);
4377   vam->result_ready = 1;
4378
4379 }
4380
4381 static void vl_api_sw_interface_get_table_reply_t_handler_json
4382   (vl_api_sw_interface_get_table_reply_t * mp)
4383 {
4384   vat_main_t *vam = &vat_main;
4385   vat_json_node_t node;
4386
4387   vat_json_init_object (&node);
4388   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
4389   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
4390
4391   vat_json_print (vam->ofp, &node);
4392   vat_json_free (&node);
4393
4394   vam->retval = ntohl (mp->retval);
4395   vam->result_ready = 1;
4396 }
4397
4398 static int
4399 api_sw_interface_get_table (vat_main_t * vam)
4400 {
4401   unformat_input_t *i = vam->input;
4402   vl_api_sw_interface_get_table_t *mp;
4403   u32 sw_if_index;
4404   u8 sw_if_index_set = 0;
4405   u8 is_ipv6 = 0;
4406   int ret;
4407
4408   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4409     {
4410       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
4411         sw_if_index_set = 1;
4412       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4413         sw_if_index_set = 1;
4414       else if (unformat (i, "ipv6"))
4415         is_ipv6 = 1;
4416       else
4417         break;
4418     }
4419
4420   if (sw_if_index_set == 0)
4421     {
4422       errmsg ("missing interface name or sw_if_index");
4423       return -99;
4424     }
4425
4426   M (SW_INTERFACE_GET_TABLE, mp);
4427   mp->sw_if_index = htonl (sw_if_index);
4428   mp->is_ipv6 = is_ipv6;
4429
4430   S (mp);
4431   W (ret);
4432   return ret;
4433 }
4434
4435 static int
4436 api_sw_interface_set_vpath (vat_main_t * vam)
4437 {
4438   unformat_input_t *i = vam->input;
4439   vl_api_sw_interface_set_vpath_t *mp;
4440   u32 sw_if_index = 0;
4441   u8 sw_if_index_set = 0;
4442   u8 is_enable = 0;
4443   int ret;
4444
4445   /* Parse args required to build the message */
4446   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4447     {
4448       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
4449         sw_if_index_set = 1;
4450       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4451         sw_if_index_set = 1;
4452       else if (unformat (i, "enable"))
4453         is_enable = 1;
4454       else if (unformat (i, "disable"))
4455         is_enable = 0;
4456       else
4457         break;
4458     }
4459
4460   if (sw_if_index_set == 0)
4461     {
4462       errmsg ("missing interface name or sw_if_index");
4463       return -99;
4464     }
4465
4466   /* Construct the API message */
4467   M (SW_INTERFACE_SET_VPATH, mp);
4468
4469   mp->sw_if_index = ntohl (sw_if_index);
4470   mp->enable = is_enable;
4471
4472   /* send it... */
4473   S (mp);
4474
4475   /* Wait for a reply... */
4476   W (ret);
4477   return ret;
4478 }
4479
4480 static int
4481 api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
4482 {
4483   unformat_input_t *i = vam->input;
4484   vl_api_sw_interface_set_vxlan_bypass_t *mp;
4485   u32 sw_if_index = 0;
4486   u8 sw_if_index_set = 0;
4487   u8 is_enable = 1;
4488   u8 is_ipv6 = 0;
4489   int ret;
4490
4491   /* Parse args required to build the message */
4492   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4493     {
4494       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
4495         sw_if_index_set = 1;
4496       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4497         sw_if_index_set = 1;
4498       else if (unformat (i, "enable"))
4499         is_enable = 1;
4500       else if (unformat (i, "disable"))
4501         is_enable = 0;
4502       else if (unformat (i, "ip4"))
4503         is_ipv6 = 0;
4504       else if (unformat (i, "ip6"))
4505         is_ipv6 = 1;
4506       else
4507         break;
4508     }
4509
4510   if (sw_if_index_set == 0)
4511     {
4512       errmsg ("missing interface name or sw_if_index");
4513       return -99;
4514     }
4515
4516   /* Construct the API message */
4517   M (SW_INTERFACE_SET_VXLAN_BYPASS, mp);
4518
4519   mp->sw_if_index = ntohl (sw_if_index);
4520   mp->enable = is_enable;
4521   mp->is_ipv6 = is_ipv6;
4522
4523   /* send it... */
4524   S (mp);
4525
4526   /* Wait for a reply... */
4527   W (ret);
4528   return ret;
4529 }
4530
4531 static int
4532 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
4533 {
4534   unformat_input_t *i = vam->input;
4535   vl_api_sw_interface_set_l2_xconnect_t *mp;
4536   u32 rx_sw_if_index;
4537   u8 rx_sw_if_index_set = 0;
4538   u32 tx_sw_if_index;
4539   u8 tx_sw_if_index_set = 0;
4540   u8 enable = 1;
4541   int ret;
4542
4543   /* Parse args required to build the message */
4544   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4545     {
4546       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
4547         rx_sw_if_index_set = 1;
4548       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
4549         tx_sw_if_index_set = 1;
4550       else if (unformat (i, "rx"))
4551         {
4552           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4553             {
4554               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
4555                             &rx_sw_if_index))
4556                 rx_sw_if_index_set = 1;
4557             }
4558           else
4559             break;
4560         }
4561       else if (unformat (i, "tx"))
4562         {
4563           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4564             {
4565               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
4566                             &tx_sw_if_index))
4567                 tx_sw_if_index_set = 1;
4568             }
4569           else
4570             break;
4571         }
4572       else if (unformat (i, "enable"))
4573         enable = 1;
4574       else if (unformat (i, "disable"))
4575         enable = 0;
4576       else
4577         break;
4578     }
4579
4580   if (rx_sw_if_index_set == 0)
4581     {
4582       errmsg ("missing rx interface name or rx_sw_if_index");
4583       return -99;
4584     }
4585
4586   if (enable && (tx_sw_if_index_set == 0))
4587     {
4588       errmsg ("missing tx interface name or tx_sw_if_index");
4589       return -99;
4590     }
4591
4592   M (SW_INTERFACE_SET_L2_XCONNECT, mp);
4593
4594   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
4595   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
4596   mp->enable = enable;
4597
4598   S (mp);
4599   W (ret);
4600   return ret;
4601 }
4602
4603 static int
4604 api_sw_interface_set_l2_bridge (vat_main_t * vam)
4605 {
4606   unformat_input_t *i = vam->input;
4607   vl_api_sw_interface_set_l2_bridge_t *mp;
4608   vl_api_l2_port_type_t port_type;
4609   u32 rx_sw_if_index;
4610   u8 rx_sw_if_index_set = 0;
4611   u32 bd_id;
4612   u8 bd_id_set = 0;
4613   u32 shg = 0;
4614   u8 enable = 1;
4615   int ret;
4616
4617   port_type = L2_API_PORT_TYPE_NORMAL;
4618
4619   /* Parse args required to build the message */
4620   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4621     {
4622       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
4623         rx_sw_if_index_set = 1;
4624       else if (unformat (i, "bd_id %d", &bd_id))
4625         bd_id_set = 1;
4626       else
4627         if (unformat
4628             (i, "%U", api_unformat_sw_if_index, vam, &rx_sw_if_index))
4629         rx_sw_if_index_set = 1;
4630       else if (unformat (i, "shg %d", &shg))
4631         ;
4632       else if (unformat (i, "bvi"))
4633         port_type = L2_API_PORT_TYPE_BVI;
4634       else if (unformat (i, "uu-fwd"))
4635         port_type = L2_API_PORT_TYPE_UU_FWD;
4636       else if (unformat (i, "enable"))
4637         enable = 1;
4638       else if (unformat (i, "disable"))
4639         enable = 0;
4640       else
4641         break;
4642     }
4643
4644   if (rx_sw_if_index_set == 0)
4645     {
4646       errmsg ("missing rx interface name or sw_if_index");
4647       return -99;
4648     }
4649
4650   if (enable && (bd_id_set == 0))
4651     {
4652       errmsg ("missing bridge domain");
4653       return -99;
4654     }
4655
4656   M (SW_INTERFACE_SET_L2_BRIDGE, mp);
4657
4658   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
4659   mp->bd_id = ntohl (bd_id);
4660   mp->shg = (u8) shg;
4661   mp->port_type = ntohl (port_type);
4662   mp->enable = enable;
4663
4664   S (mp);
4665   W (ret);
4666   return ret;
4667 }
4668
4669 static int
4670 api_bridge_domain_dump (vat_main_t * vam)
4671 {
4672   unformat_input_t *i = vam->input;
4673   vl_api_bridge_domain_dump_t *mp;
4674   vl_api_control_ping_t *mp_ping;
4675   u32 bd_id = ~0;
4676   int ret;
4677
4678   /* Parse args required to build the message */
4679   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4680     {
4681       if (unformat (i, "bd_id %d", &bd_id))
4682         ;
4683       else
4684         break;
4685     }
4686
4687   M (BRIDGE_DOMAIN_DUMP, mp);
4688   mp->bd_id = ntohl (bd_id);
4689   S (mp);
4690
4691   /* Use a control ping for synchronization */
4692   MPING (CONTROL_PING, mp_ping);
4693   S (mp_ping);
4694
4695   W (ret);
4696   return ret;
4697 }
4698
4699 static int
4700 api_bridge_domain_add_del (vat_main_t * vam)
4701 {
4702   unformat_input_t *i = vam->input;
4703   vl_api_bridge_domain_add_del_t *mp;
4704   u32 bd_id = ~0;
4705   u8 is_add = 1;
4706   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
4707   u8 *bd_tag = NULL;
4708   u32 mac_age = 0;
4709   int ret;
4710
4711   /* Parse args required to build the message */
4712   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4713     {
4714       if (unformat (i, "bd_id %d", &bd_id))
4715         ;
4716       else if (unformat (i, "flood %d", &flood))
4717         ;
4718       else if (unformat (i, "uu-flood %d", &uu_flood))
4719         ;
4720       else if (unformat (i, "forward %d", &forward))
4721         ;
4722       else if (unformat (i, "learn %d", &learn))
4723         ;
4724       else if (unformat (i, "arp-term %d", &arp_term))
4725         ;
4726       else if (unformat (i, "mac-age %d", &mac_age))
4727         ;
4728       else if (unformat (i, "bd-tag %s", &bd_tag))
4729         ;
4730       else if (unformat (i, "del"))
4731         {
4732           is_add = 0;
4733           flood = uu_flood = forward = learn = 0;
4734         }
4735       else
4736         break;
4737     }
4738
4739   if (bd_id == ~0)
4740     {
4741       errmsg ("missing bridge domain");
4742       ret = -99;
4743       goto done;
4744     }
4745
4746   if (mac_age > 255)
4747     {
4748       errmsg ("mac age must be less than 256 ");
4749       ret = -99;
4750       goto done;
4751     }
4752
4753   if ((bd_tag) && (vec_len (bd_tag) > 63))
4754     {
4755       errmsg ("bd-tag cannot be longer than 63");
4756       ret = -99;
4757       goto done;
4758     }
4759
4760   M (BRIDGE_DOMAIN_ADD_DEL, mp);
4761
4762   mp->bd_id = ntohl (bd_id);
4763   mp->flood = flood;
4764   mp->uu_flood = uu_flood;
4765   mp->forward = forward;
4766   mp->learn = learn;
4767   mp->arp_term = arp_term;
4768   mp->is_add = is_add;
4769   mp->mac_age = (u8) mac_age;
4770   if (bd_tag)
4771     {
4772       clib_memcpy (mp->bd_tag, bd_tag, vec_len (bd_tag));
4773       mp->bd_tag[vec_len (bd_tag)] = 0;
4774     }
4775   S (mp);
4776   W (ret);
4777
4778 done:
4779   vec_free (bd_tag);
4780   return ret;
4781 }
4782
4783 static int
4784 api_l2fib_flush_bd (vat_main_t * vam)
4785 {
4786   unformat_input_t *i = vam->input;
4787   vl_api_l2fib_flush_bd_t *mp;
4788   u32 bd_id = ~0;
4789   int ret;
4790
4791   /* Parse args required to build the message */
4792   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4793     {
4794       if (unformat (i, "bd_id %d", &bd_id));
4795       else
4796         break;
4797     }
4798
4799   if (bd_id == ~0)
4800     {
4801       errmsg ("missing bridge domain");
4802       return -99;
4803     }
4804
4805   M (L2FIB_FLUSH_BD, mp);
4806
4807   mp->bd_id = htonl (bd_id);
4808
4809   S (mp);
4810   W (ret);
4811   return ret;
4812 }
4813
4814 static int
4815 api_l2fib_flush_int (vat_main_t * vam)
4816 {
4817   unformat_input_t *i = vam->input;
4818   vl_api_l2fib_flush_int_t *mp;
4819   u32 sw_if_index = ~0;
4820   int ret;
4821
4822   /* Parse args required to build the message */
4823   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4824     {
4825       if (unformat (i, "sw_if_index %d", &sw_if_index));
4826       else
4827         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index));
4828       else
4829         break;
4830     }
4831
4832   if (sw_if_index == ~0)
4833     {
4834       errmsg ("missing interface name or sw_if_index");
4835       return -99;
4836     }
4837
4838   M (L2FIB_FLUSH_INT, mp);
4839
4840   mp->sw_if_index = ntohl (sw_if_index);
4841
4842   S (mp);
4843   W (ret);
4844   return ret;
4845 }
4846
4847 static int
4848 api_l2fib_add_del (vat_main_t * vam)
4849 {
4850   unformat_input_t *i = vam->input;
4851   vl_api_l2fib_add_del_t *mp;
4852   f64 timeout;
4853   u8 mac[6] = { 0 };
4854   u8 mac_set = 0;
4855   u32 bd_id;
4856   u8 bd_id_set = 0;
4857   u32 sw_if_index = 0;
4858   u8 sw_if_index_set = 0;
4859   u8 is_add = 1;
4860   u8 static_mac = 0;
4861   u8 filter_mac = 0;
4862   u8 bvi_mac = 0;
4863   int count = 1;
4864   f64 before = 0;
4865   int j;
4866
4867   /* Parse args required to build the message */
4868   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4869     {
4870       if (unformat (i, "mac %U", unformat_ethernet_address, mac))
4871         mac_set = 1;
4872       else if (unformat (i, "bd_id %d", &bd_id))
4873         bd_id_set = 1;
4874       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4875         sw_if_index_set = 1;
4876       else if (unformat (i, "sw_if"))
4877         {
4878           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4879             {
4880               if (unformat
4881                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
4882                 sw_if_index_set = 1;
4883             }
4884           else
4885             break;
4886         }
4887       else if (unformat (i, "static"))
4888         static_mac = 1;
4889       else if (unformat (i, "filter"))
4890         {
4891           filter_mac = 1;
4892           static_mac = 1;
4893         }
4894       else if (unformat (i, "bvi"))
4895         {
4896           bvi_mac = 1;
4897           static_mac = 1;
4898         }
4899       else if (unformat (i, "del"))
4900         is_add = 0;
4901       else if (unformat (i, "count %d", &count))
4902         ;
4903       else
4904         break;
4905     }
4906
4907   if (mac_set == 0)
4908     {
4909       errmsg ("missing mac address");
4910       return -99;
4911     }
4912
4913   if (bd_id_set == 0)
4914     {
4915       errmsg ("missing bridge domain");
4916       return -99;
4917     }
4918
4919   if (is_add && sw_if_index_set == 0 && filter_mac == 0)
4920     {
4921       errmsg ("missing interface name or sw_if_index");
4922       return -99;
4923     }
4924
4925   if (count > 1)
4926     {
4927       /* Turn on async mode */
4928       vam->async_mode = 1;
4929       vam->async_errors = 0;
4930       before = vat_time_now (vam);
4931     }
4932
4933   for (j = 0; j < count; j++)
4934     {
4935       M (L2FIB_ADD_DEL, mp);
4936
4937       clib_memcpy (mp->mac, mac, 6);
4938       mp->bd_id = ntohl (bd_id);
4939       mp->is_add = is_add;
4940       mp->sw_if_index = ntohl (sw_if_index);
4941
4942       if (is_add)
4943         {
4944           mp->static_mac = static_mac;
4945           mp->filter_mac = filter_mac;
4946           mp->bvi_mac = bvi_mac;
4947         }
4948       increment_mac_address (mac);
4949       /* send it... */
4950       S (mp);
4951     }
4952
4953   if (count > 1)
4954     {
4955       vl_api_control_ping_t *mp_ping;
4956       f64 after;
4957
4958       /* Shut off async mode */
4959       vam->async_mode = 0;
4960
4961       MPING (CONTROL_PING, mp_ping);
4962       S (mp_ping);
4963
4964       timeout = vat_time_now (vam) + 1.0;
4965       while (vat_time_now (vam) < timeout)
4966         if (vam->result_ready == 1)
4967           goto out;
4968       vam->retval = -99;
4969
4970     out:
4971       if (vam->retval == -99)
4972         errmsg ("timeout");
4973
4974       if (vam->async_errors > 0)
4975         {
4976           errmsg ("%d asynchronous errors", vam->async_errors);
4977           vam->retval = -98;
4978         }
4979       vam->async_errors = 0;
4980       after = vat_time_now (vam);
4981
4982       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
4983              count, after - before, count / (after - before));
4984     }
4985   else
4986     {
4987       int ret;
4988
4989       /* Wait for a reply... */
4990       W (ret);
4991       return ret;
4992     }
4993   /* Return the good/bad news */
4994   return (vam->retval);
4995 }
4996
4997 static int
4998 api_bridge_domain_set_mac_age (vat_main_t * vam)
4999 {
5000   unformat_input_t *i = vam->input;
5001   vl_api_bridge_domain_set_mac_age_t *mp;
5002   u32 bd_id = ~0;
5003   u32 mac_age = 0;
5004   int ret;
5005
5006   /* Parse args required to build the message */
5007   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5008     {
5009       if (unformat (i, "bd_id %d", &bd_id));
5010       else if (unformat (i, "mac-age %d", &mac_age));
5011       else
5012         break;
5013     }
5014
5015   if (bd_id == ~0)
5016     {
5017       errmsg ("missing bridge domain");
5018       return -99;
5019     }
5020
5021   if (mac_age > 255)
5022     {
5023       errmsg ("mac age must be less than 256 ");
5024       return -99;
5025     }
5026
5027   M (BRIDGE_DOMAIN_SET_MAC_AGE, mp);
5028
5029   mp->bd_id = htonl (bd_id);
5030   mp->mac_age = (u8) mac_age;
5031
5032   S (mp);
5033   W (ret);
5034   return ret;
5035 }
5036
5037 static int
5038 api_l2_flags (vat_main_t * vam)
5039 {
5040   unformat_input_t *i = vam->input;
5041   vl_api_l2_flags_t *mp;
5042   u32 sw_if_index;
5043   u32 flags = 0;
5044   u8 sw_if_index_set = 0;
5045   u8 is_set = 0;
5046   int ret;
5047
5048   /* Parse args required to build the message */
5049   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5050     {
5051       if (unformat (i, "sw_if_index %d", &sw_if_index))
5052         sw_if_index_set = 1;
5053       else if (unformat (i, "sw_if"))
5054         {
5055           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5056             {
5057               if (unformat
5058                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5059                 sw_if_index_set = 1;
5060             }
5061           else
5062             break;
5063         }
5064       else if (unformat (i, "learn"))
5065         flags |= L2_LEARN;
5066       else if (unformat (i, "forward"))
5067         flags |= L2_FWD;
5068       else if (unformat (i, "flood"))
5069         flags |= L2_FLOOD;
5070       else if (unformat (i, "uu-flood"))
5071         flags |= L2_UU_FLOOD;
5072       else if (unformat (i, "arp-term"))
5073         flags |= L2_ARP_TERM;
5074       else if (unformat (i, "off"))
5075         is_set = 0;
5076       else if (unformat (i, "disable"))
5077         is_set = 0;
5078       else
5079         break;
5080     }
5081
5082   if (sw_if_index_set == 0)
5083     {
5084       errmsg ("missing interface name or sw_if_index");
5085       return -99;
5086     }
5087
5088   M (L2_FLAGS, mp);
5089
5090   mp->sw_if_index = ntohl (sw_if_index);
5091   mp->feature_bitmap = ntohl (flags);
5092   mp->is_set = is_set;
5093
5094   S (mp);
5095   W (ret);
5096   return ret;
5097 }
5098
5099 static int
5100 api_bridge_flags (vat_main_t * vam)
5101 {
5102   unformat_input_t *i = vam->input;
5103   vl_api_bridge_flags_t *mp;
5104   u32 bd_id;
5105   u8 bd_id_set = 0;
5106   u8 is_set = 1;
5107   bd_flags_t flags = 0;
5108   int ret;
5109
5110   /* Parse args required to build the message */
5111   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5112     {
5113       if (unformat (i, "bd_id %d", &bd_id))
5114         bd_id_set = 1;
5115       else if (unformat (i, "learn"))
5116         flags |= BRIDGE_API_FLAG_LEARN;
5117       else if (unformat (i, "forward"))
5118         flags |= BRIDGE_API_FLAG_FWD;
5119       else if (unformat (i, "flood"))
5120         flags |= BRIDGE_API_FLAG_FLOOD;
5121       else if (unformat (i, "uu-flood"))
5122         flags |= BRIDGE_API_FLAG_UU_FLOOD;
5123       else if (unformat (i, "arp-term"))
5124         flags |= BRIDGE_API_FLAG_ARP_TERM;
5125       else if (unformat (i, "off"))
5126         is_set = 0;
5127       else if (unformat (i, "disable"))
5128         is_set = 0;
5129       else
5130         break;
5131     }
5132
5133   if (bd_id_set == 0)
5134     {
5135       errmsg ("missing bridge domain");
5136       return -99;
5137     }
5138
5139   M (BRIDGE_FLAGS, mp);
5140
5141   mp->bd_id = ntohl (bd_id);
5142   mp->flags = ntohl (flags);
5143   mp->is_set = is_set;
5144
5145   S (mp);
5146   W (ret);
5147   return ret;
5148 }
5149
5150 static int
5151 api_bd_ip_mac_add_del (vat_main_t * vam)
5152 {
5153   vl_api_address_t ip = VL_API_ZERO_ADDRESS;
5154   vl_api_mac_address_t mac = { 0 };
5155   unformat_input_t *i = vam->input;
5156   vl_api_bd_ip_mac_add_del_t *mp;
5157   u32 bd_id;
5158   u8 is_add = 1;
5159   u8 bd_id_set = 0;
5160   u8 ip_set = 0;
5161   u8 mac_set = 0;
5162   int ret;
5163
5164
5165   /* Parse args required to build the message */
5166   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5167     {
5168       if (unformat (i, "bd_id %d", &bd_id))
5169         {
5170           bd_id_set++;
5171         }
5172       else if (unformat (i, "%U", unformat_vl_api_address, &ip))
5173         {
5174           ip_set++;
5175         }
5176       else if (unformat (i, "%U", unformat_vl_api_mac_address, &mac))
5177         {
5178           mac_set++;
5179         }
5180       else if (unformat (i, "del"))
5181         is_add = 0;
5182       else
5183         break;
5184     }
5185
5186   if (bd_id_set == 0)
5187     {
5188       errmsg ("missing bridge domain");
5189       return -99;
5190     }
5191   else if (ip_set == 0)
5192     {
5193       errmsg ("missing IP address");
5194       return -99;
5195     }
5196   else if (mac_set == 0)
5197     {
5198       errmsg ("missing MAC address");
5199       return -99;
5200     }
5201
5202   M (BD_IP_MAC_ADD_DEL, mp);
5203
5204   mp->entry.bd_id = ntohl (bd_id);
5205   mp->is_add = is_add;
5206
5207   clib_memcpy (&mp->entry.ip, &ip, sizeof (ip));
5208   clib_memcpy (&mp->entry.mac, &mac, sizeof (mac));
5209
5210   S (mp);
5211   W (ret);
5212   return ret;
5213 }
5214
5215 static int
5216 api_bd_ip_mac_flush (vat_main_t * vam)
5217 {
5218   unformat_input_t *i = vam->input;
5219   vl_api_bd_ip_mac_flush_t *mp;
5220   u32 bd_id;
5221   u8 bd_id_set = 0;
5222   int ret;
5223
5224   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5225     {
5226       if (unformat (i, "bd_id %d", &bd_id))
5227         {
5228           bd_id_set++;
5229         }
5230       else
5231         break;
5232     }
5233
5234   if (bd_id_set == 0)
5235     {
5236       errmsg ("missing bridge domain");
5237       return -99;
5238     }
5239
5240   M (BD_IP_MAC_FLUSH, mp);
5241
5242   mp->bd_id = ntohl (bd_id);
5243
5244   S (mp);
5245   W (ret);
5246   return ret;
5247 }
5248
5249 static void vl_api_bd_ip_mac_details_t_handler
5250   (vl_api_bd_ip_mac_details_t * mp)
5251 {
5252   vat_main_t *vam = &vat_main;
5253
5254   print (vam->ofp,
5255          "\n%-5d %U %U",
5256          ntohl (mp->entry.bd_id),
5257          format_vl_api_mac_address, mp->entry.mac,
5258          format_vl_api_address, &mp->entry.ip);
5259 }
5260
5261 static void vl_api_bd_ip_mac_details_t_handler_json
5262   (vl_api_bd_ip_mac_details_t * mp)
5263 {
5264   vat_main_t *vam = &vat_main;
5265   vat_json_node_t *node = NULL;
5266
5267   if (VAT_JSON_ARRAY != vam->json_tree.type)
5268     {
5269       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5270       vat_json_init_array (&vam->json_tree);
5271     }
5272   node = vat_json_array_add (&vam->json_tree);
5273
5274   vat_json_init_object (node);
5275   vat_json_object_add_uint (node, "bd_id", ntohl (mp->entry.bd_id));
5276   vat_json_object_add_string_copy (node, "mac_address",
5277                                    format (0, "%U", format_vl_api_mac_address,
5278                                            &mp->entry.mac));
5279   u8 *ip = 0;
5280
5281   ip = format (0, "%U", format_vl_api_address, &mp->entry.ip);
5282   vat_json_object_add_string_copy (node, "ip_address", ip);
5283   vec_free (ip);
5284 }
5285
5286 static int
5287 api_bd_ip_mac_dump (vat_main_t * vam)
5288 {
5289   unformat_input_t *i = vam->input;
5290   vl_api_bd_ip_mac_dump_t *mp;
5291   vl_api_control_ping_t *mp_ping;
5292   int ret;
5293   u32 bd_id;
5294   u8 bd_id_set = 0;
5295
5296   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5297     {
5298       if (unformat (i, "bd_id %d", &bd_id))
5299         {
5300           bd_id_set++;
5301         }
5302       else
5303         break;
5304     }
5305
5306   print (vam->ofp,
5307          "\n%-5s %-7s %-20s %-30s",
5308          "bd_id", "is_ipv6", "mac_address", "ip_address");
5309
5310   /* Dump Bridge Domain Ip to Mac entries */
5311   M (BD_IP_MAC_DUMP, mp);
5312
5313   if (bd_id_set)
5314     mp->bd_id = htonl (bd_id);
5315   else
5316     mp->bd_id = ~0;
5317
5318   S (mp);
5319
5320   /* Use a control ping for synchronization */
5321   MPING (CONTROL_PING, mp_ping);
5322   S (mp_ping);
5323
5324   W (ret);
5325   return ret;
5326 }
5327
5328 static int
5329 api_tap_create_v2 (vat_main_t * vam)
5330 {
5331   unformat_input_t *i = vam->input;
5332   vl_api_tap_create_v2_t *mp;
5333   u8 mac_address[6];
5334   u8 random_mac = 1;
5335   u32 id = ~0;
5336   u32 num_rx_queues = 0;
5337   u8 *host_if_name = 0;
5338   u8 host_if_name_set = 0;
5339   u8 *host_ns = 0;
5340   u8 host_ns_set = 0;
5341   u8 host_mac_addr[6];
5342   u8 host_mac_addr_set = 0;
5343   u8 *host_bridge = 0;
5344   u8 host_bridge_set = 0;
5345   u8 host_ip4_prefix_set = 0;
5346   u8 host_ip6_prefix_set = 0;
5347   ip4_address_t host_ip4_addr;
5348   ip4_address_t host_ip4_gw;
5349   u8 host_ip4_gw_set = 0;
5350   u32 host_ip4_prefix_len = 0;
5351   ip6_address_t host_ip6_addr;
5352   ip6_address_t host_ip6_gw;
5353   u8 host_ip6_gw_set = 0;
5354   u32 host_ip6_prefix_len = 0;
5355   u32 host_mtu_size = 0;
5356   u8 host_mtu_set = 0;
5357   u32 tap_flags = 0;
5358   int ret;
5359   u32 rx_ring_sz = 0, tx_ring_sz = 0;
5360
5361   clib_memset (mac_address, 0, sizeof (mac_address));
5362
5363   /* Parse args required to build the message */
5364   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5365     {
5366       if (unformat (i, "id %u", &id))
5367         ;
5368       else
5369         if (unformat
5370             (i, "hw-addr %U", unformat_ethernet_address, mac_address))
5371         random_mac = 0;
5372       else if (unformat (i, "host-if-name %s", &host_if_name))
5373         host_if_name_set = 1;
5374       else if (unformat (i, "num-rx-queues %u", &num_rx_queues))
5375         ;
5376       else if (unformat (i, "host-ns %s", &host_ns))
5377         host_ns_set = 1;
5378       else if (unformat (i, "host-mac-addr %U", unformat_ethernet_address,
5379                          host_mac_addr))
5380         host_mac_addr_set = 1;
5381       else if (unformat (i, "host-bridge %s", &host_bridge))
5382         host_bridge_set = 1;
5383       else if (unformat (i, "host-ip4-addr %U/%u", unformat_ip4_address,
5384                          &host_ip4_addr, &host_ip4_prefix_len))
5385         host_ip4_prefix_set = 1;
5386       else if (unformat (i, "host-ip6-addr %U/%u", unformat_ip6_address,
5387                          &host_ip6_addr, &host_ip6_prefix_len))
5388         host_ip6_prefix_set = 1;
5389       else if (unformat (i, "host-ip4-gw %U", unformat_ip4_address,
5390                          &host_ip4_gw))
5391         host_ip4_gw_set = 1;
5392       else if (unformat (i, "host-ip6-gw %U", unformat_ip6_address,
5393                          &host_ip6_gw))
5394         host_ip6_gw_set = 1;
5395       else if (unformat (i, "rx-ring-size %u", &rx_ring_sz))
5396         ;
5397       else if (unformat (i, "tx-ring-size %u", &tx_ring_sz))
5398         ;
5399       else if (unformat (i, "host-mtu-size %u", &host_mtu_size))
5400         host_mtu_set = 1;
5401       else if (unformat (i, "no-gso"))
5402         tap_flags &= ~TAP_API_FLAG_GSO;
5403       else if (unformat (i, "gso"))
5404         tap_flags |= TAP_API_FLAG_GSO;
5405       else if (unformat (i, "csum-offload"))
5406         tap_flags |= TAP_API_FLAG_CSUM_OFFLOAD;
5407       else if (unformat (i, "persist"))
5408         tap_flags |= TAP_API_FLAG_PERSIST;
5409       else if (unformat (i, "attach"))
5410         tap_flags |= TAP_API_FLAG_ATTACH;
5411       else if (unformat (i, "tun"))
5412         tap_flags |= TAP_API_FLAG_TUN;
5413       else if (unformat (i, "gro-coalesce"))
5414         tap_flags |= TAP_API_FLAG_GRO_COALESCE;
5415       else if (unformat (i, "packed"))
5416         tap_flags |= TAP_API_FLAG_PACKED;
5417       else if (unformat (i, "in-order"))
5418         tap_flags |= TAP_API_FLAG_IN_ORDER;
5419       else
5420         break;
5421     }
5422
5423   if (vec_len (host_if_name) > 63)
5424     {
5425       errmsg ("tap name too long. ");
5426       return -99;
5427     }
5428   if (vec_len (host_ns) > 63)
5429     {
5430       errmsg ("host name space too long. ");
5431       return -99;
5432     }
5433   if (vec_len (host_bridge) > 63)
5434     {
5435       errmsg ("host bridge name too long. ");
5436       return -99;
5437     }
5438   if (host_ip4_prefix_len > 32)
5439     {
5440       errmsg ("host ip4 prefix length not valid. ");
5441       return -99;
5442     }
5443   if (host_ip6_prefix_len > 128)
5444     {
5445       errmsg ("host ip6 prefix length not valid. ");
5446       return -99;
5447     }
5448   if (!is_pow2 (rx_ring_sz))
5449     {
5450       errmsg ("rx ring size must be power of 2. ");
5451       return -99;
5452     }
5453   if (rx_ring_sz > 32768)
5454     {
5455       errmsg ("rx ring size must be 32768 or lower. ");
5456       return -99;
5457     }
5458   if (!is_pow2 (tx_ring_sz))
5459     {
5460       errmsg ("tx ring size must be power of 2. ");
5461       return -99;
5462     }
5463   if (tx_ring_sz > 32768)
5464     {
5465       errmsg ("tx ring size must be 32768 or lower. ");
5466       return -99;
5467     }
5468   if (host_mtu_set && (host_mtu_size < 64 || host_mtu_size > 65355))
5469     {
5470       errmsg ("host MTU size must be in between 64 and 65355. ");
5471       return -99;
5472     }
5473
5474   /* Construct the API message */
5475   M (TAP_CREATE_V2, mp);
5476
5477   mp->id = ntohl (id);
5478   mp->use_random_mac = random_mac;
5479   mp->num_rx_queues = (u8) num_rx_queues;
5480   mp->tx_ring_sz = ntohs (tx_ring_sz);
5481   mp->rx_ring_sz = ntohs (rx_ring_sz);
5482   mp->host_mtu_set = host_mtu_set;
5483   mp->host_mtu_size = ntohl (host_mtu_size);
5484   mp->host_mac_addr_set = host_mac_addr_set;
5485   mp->host_ip4_prefix_set = host_ip4_prefix_set;
5486   mp->host_ip6_prefix_set = host_ip6_prefix_set;
5487   mp->host_ip4_gw_set = host_ip4_gw_set;
5488   mp->host_ip6_gw_set = host_ip6_gw_set;
5489   mp->tap_flags = ntohl (tap_flags);
5490   mp->host_namespace_set = host_ns_set;
5491   mp->host_if_name_set = host_if_name_set;
5492   mp->host_bridge_set = host_bridge_set;
5493
5494   if (random_mac == 0)
5495     clib_memcpy (mp->mac_address, mac_address, 6);
5496   if (host_mac_addr_set)
5497     clib_memcpy (mp->host_mac_addr, host_mac_addr, 6);
5498   if (host_if_name_set)
5499     clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
5500   if (host_ns_set)
5501     clib_memcpy (mp->host_namespace, host_ns, vec_len (host_ns));
5502   if (host_bridge_set)
5503     clib_memcpy (mp->host_bridge, host_bridge, vec_len (host_bridge));
5504   if (host_ip4_prefix_set)
5505     {
5506       clib_memcpy (mp->host_ip4_prefix.address, &host_ip4_addr, 4);
5507       mp->host_ip4_prefix.len = (u8) host_ip4_prefix_len;
5508     }
5509   if (host_ip6_prefix_set)
5510     {
5511       clib_memcpy (mp->host_ip6_prefix.address, &host_ip6_addr, 16);
5512       mp->host_ip6_prefix.len = (u8) host_ip6_prefix_len;
5513     }
5514   if (host_ip4_gw_set)
5515     clib_memcpy (mp->host_ip4_gw, &host_ip4_gw, 4);
5516   if (host_ip6_gw_set)
5517     clib_memcpy (mp->host_ip6_gw, &host_ip6_gw, 16);
5518
5519   vec_free (host_ns);
5520   vec_free (host_if_name);
5521   vec_free (host_bridge);
5522
5523   /* send it... */
5524   S (mp);
5525
5526   /* Wait for a reply... */
5527   W (ret);
5528   return ret;
5529 }
5530
5531 static int
5532 api_tap_delete_v2 (vat_main_t * vam)
5533 {
5534   unformat_input_t *i = vam->input;
5535   vl_api_tap_delete_v2_t *mp;
5536   u32 sw_if_index = ~0;
5537   u8 sw_if_index_set = 0;
5538   int ret;
5539
5540   /* Parse args required to build the message */
5541   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5542     {
5543       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5544         sw_if_index_set = 1;
5545       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5546         sw_if_index_set = 1;
5547       else
5548         break;
5549     }
5550
5551   if (sw_if_index_set == 0)
5552     {
5553       errmsg ("missing vpp interface name. ");
5554       return -99;
5555     }
5556
5557   /* Construct the API message */
5558   M (TAP_DELETE_V2, mp);
5559
5560   mp->sw_if_index = ntohl (sw_if_index);
5561
5562   /* send it... */
5563   S (mp);
5564
5565   /* Wait for a reply... */
5566   W (ret);
5567   return ret;
5568 }
5569
5570 uword
5571 unformat_vlib_pci_addr (unformat_input_t * input, va_list * args)
5572 {
5573   vlib_pci_addr_t *addr = va_arg (*args, vlib_pci_addr_t *);
5574   u32 x[4];
5575
5576   if (!unformat (input, "%x:%x:%x.%x", &x[0], &x[1], &x[2], &x[3]))
5577     return 0;
5578
5579   addr->domain = x[0];
5580   addr->bus = x[1];
5581   addr->slot = x[2];
5582   addr->function = x[3];
5583
5584   return 1;
5585 }
5586
5587 static int
5588 api_virtio_pci_create_v2 (vat_main_t * vam)
5589 {
5590   unformat_input_t *i = vam->input;
5591   vl_api_virtio_pci_create_v2_t *mp;
5592   u8 mac_address[6];
5593   u8 random_mac = 1;
5594   u32 pci_addr = 0;
5595   u64 features = (u64) ~ (0ULL);
5596   u32 virtio_flags = 0;
5597   int ret;
5598
5599   clib_memset (mac_address, 0, sizeof (mac_address));
5600
5601   /* Parse args required to build the message */
5602   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5603     {
5604       if (unformat (i, "hw-addr %U", unformat_ethernet_address, mac_address))
5605         {
5606           random_mac = 0;
5607         }
5608       else if (unformat (i, "pci-addr %U", unformat_vlib_pci_addr, &pci_addr))
5609         ;
5610       else if (unformat (i, "features 0x%llx", &features))
5611         ;
5612       else if (unformat (i, "gso-enabled"))
5613         virtio_flags |= VIRTIO_API_FLAG_GSO;
5614       else if (unformat (i, "csum-offload-enabled"))
5615         virtio_flags |= VIRTIO_API_FLAG_CSUM_OFFLOAD;
5616       else if (unformat (i, "gro-coalesce"))
5617         virtio_flags |= VIRTIO_API_FLAG_GRO_COALESCE;
5618       else if (unformat (i, "packed"))
5619         virtio_flags |= VIRTIO_API_FLAG_PACKED;
5620       else if (unformat (i, "in-order"))
5621         virtio_flags |= VIRTIO_API_FLAG_IN_ORDER;
5622       else if (unformat (i, "buffering"))
5623         virtio_flags |= VIRTIO_API_FLAG_BUFFERING;
5624       else
5625         break;
5626     }
5627
5628   if (pci_addr == 0)
5629     {
5630       errmsg ("pci address must be non zero. ");
5631       return -99;
5632     }
5633
5634   /* Construct the API message */
5635   M (VIRTIO_PCI_CREATE_V2, mp);
5636
5637   mp->use_random_mac = random_mac;
5638
5639   mp->pci_addr.domain = htons (((vlib_pci_addr_t) pci_addr).domain);
5640   mp->pci_addr.bus = ((vlib_pci_addr_t) pci_addr).bus;
5641   mp->pci_addr.slot = ((vlib_pci_addr_t) pci_addr).slot;
5642   mp->pci_addr.function = ((vlib_pci_addr_t) pci_addr).function;
5643
5644   mp->features = clib_host_to_net_u64 (features);
5645   mp->virtio_flags = clib_host_to_net_u32 (virtio_flags);
5646
5647   if (random_mac == 0)
5648     clib_memcpy (mp->mac_address, mac_address, 6);
5649
5650   /* send it... */
5651   S (mp);
5652
5653   /* Wait for a reply... */
5654   W (ret);
5655   return ret;
5656 }
5657
5658 static int
5659 api_virtio_pci_delete (vat_main_t * vam)
5660 {
5661   unformat_input_t *i = vam->input;
5662   vl_api_virtio_pci_delete_t *mp;
5663   u32 sw_if_index = ~0;
5664   u8 sw_if_index_set = 0;
5665   int ret;
5666
5667   /* Parse args required to build the message */
5668   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5669     {
5670       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5671         sw_if_index_set = 1;
5672       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5673         sw_if_index_set = 1;
5674       else
5675         break;
5676     }
5677
5678   if (sw_if_index_set == 0)
5679     {
5680       errmsg ("missing vpp interface name. ");
5681       return -99;
5682     }
5683
5684   /* Construct the API message */
5685   M (VIRTIO_PCI_DELETE, mp);
5686
5687   mp->sw_if_index = htonl (sw_if_index);
5688
5689   /* send it... */
5690   S (mp);
5691
5692   /* Wait for a reply... */
5693   W (ret);
5694   return ret;
5695 }
5696
5697 static int
5698 api_bond_create (vat_main_t * vam)
5699 {
5700   unformat_input_t *i = vam->input;
5701   vl_api_bond_create_t *mp;
5702   u8 mac_address[6];
5703   u8 custom_mac = 0;
5704   int ret;
5705   u8 mode;
5706   u8 lb;
5707   u8 mode_is_set = 0;
5708   u32 id = ~0;
5709   u8 numa_only = 0;
5710
5711   clib_memset (mac_address, 0, sizeof (mac_address));
5712   lb = BOND_LB_L2;
5713
5714   /* Parse args required to build the message */
5715   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5716     {
5717       if (unformat (i, "mode %U", unformat_bond_mode, &mode))
5718         mode_is_set = 1;
5719       else if (((mode == BOND_MODE_LACP) || (mode == BOND_MODE_XOR))
5720                && unformat (i, "lb %U", unformat_bond_load_balance, &lb))
5721         ;
5722       else if (unformat (i, "hw-addr %U", unformat_ethernet_address,
5723                          mac_address))
5724         custom_mac = 1;
5725       else if (unformat (i, "numa-only"))
5726         numa_only = 1;
5727       else if (unformat (i, "id %u", &id))
5728         ;
5729       else
5730         break;
5731     }
5732
5733   if (mode_is_set == 0)
5734     {
5735       errmsg ("Missing bond mode. ");
5736       return -99;
5737     }
5738
5739   /* Construct the API message */
5740   M (BOND_CREATE, mp);
5741
5742   mp->use_custom_mac = custom_mac;
5743
5744   mp->mode = htonl (mode);
5745   mp->lb = htonl (lb);
5746   mp->id = htonl (id);
5747   mp->numa_only = numa_only;
5748
5749   if (custom_mac)
5750     clib_memcpy (mp->mac_address, mac_address, 6);
5751
5752   /* send it... */
5753   S (mp);
5754
5755   /* Wait for a reply... */
5756   W (ret);
5757   return ret;
5758 }
5759
5760 static int
5761 api_bond_create2 (vat_main_t * vam)
5762 {
5763   unformat_input_t *i = vam->input;
5764   vl_api_bond_create2_t *mp;
5765   u8 mac_address[6];
5766   u8 custom_mac = 0;
5767   int ret;
5768   u8 mode;
5769   u8 lb;
5770   u8 mode_is_set = 0;
5771   u32 id = ~0;
5772   u8 numa_only = 0;
5773   u8 gso = 0;
5774
5775   clib_memset (mac_address, 0, sizeof (mac_address));
5776   lb = BOND_LB_L2;
5777
5778   /* Parse args required to build the message */
5779   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5780     {
5781       if (unformat (i, "mode %U", unformat_bond_mode, &mode))
5782         mode_is_set = 1;
5783       else if (((mode == BOND_MODE_LACP) || (mode == BOND_MODE_XOR))
5784                && unformat (i, "lb %U", unformat_bond_load_balance, &lb))
5785         ;
5786       else if (unformat (i, "hw-addr %U", unformat_ethernet_address,
5787                          mac_address))
5788         custom_mac = 1;
5789       else if (unformat (i, "numa-only"))
5790         numa_only = 1;
5791       else if (unformat (i, "gso"))
5792         gso = 1;
5793       else if (unformat (i, "id %u", &id))
5794         ;
5795       else
5796         break;
5797     }
5798
5799   if (mode_is_set == 0)
5800     {
5801       errmsg ("Missing bond mode. ");
5802       return -99;
5803     }
5804
5805   /* Construct the API message */
5806   M (BOND_CREATE2, mp);
5807
5808   mp->use_custom_mac = custom_mac;
5809
5810   mp->mode = htonl (mode);
5811   mp->lb = htonl (lb);
5812   mp->id = htonl (id);
5813   mp->numa_only = numa_only;
5814   mp->enable_gso = gso;
5815
5816   if (custom_mac)
5817     clib_memcpy (mp->mac_address, mac_address, 6);
5818
5819   /* send it... */
5820   S (mp);
5821
5822   /* Wait for a reply... */
5823   W (ret);
5824   return ret;
5825 }
5826
5827 static int
5828 api_bond_delete (vat_main_t * vam)
5829 {
5830   unformat_input_t *i = vam->input;
5831   vl_api_bond_delete_t *mp;
5832   u32 sw_if_index = ~0;
5833   u8 sw_if_index_set = 0;
5834   int ret;
5835
5836   /* Parse args required to build the message */
5837   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5838     {
5839       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5840         sw_if_index_set = 1;
5841       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5842         sw_if_index_set = 1;
5843       else
5844         break;
5845     }
5846
5847   if (sw_if_index_set == 0)
5848     {
5849       errmsg ("missing vpp interface name. ");
5850       return -99;
5851     }
5852
5853   /* Construct the API message */
5854   M (BOND_DELETE, mp);
5855
5856   mp->sw_if_index = ntohl (sw_if_index);
5857
5858   /* send it... */
5859   S (mp);
5860
5861   /* Wait for a reply... */
5862   W (ret);
5863   return ret;
5864 }
5865
5866 static int
5867 api_bond_add_member (vat_main_t * vam)
5868 {
5869   unformat_input_t *i = vam->input;
5870   vl_api_bond_add_member_t *mp;
5871   u32 bond_sw_if_index;
5872   int ret;
5873   u8 is_passive;
5874   u8 is_long_timeout;
5875   u32 bond_sw_if_index_is_set = 0;
5876   u32 sw_if_index;
5877   u8 sw_if_index_is_set = 0;
5878
5879   /* Parse args required to build the message */
5880   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5881     {
5882       if (unformat (i, "sw_if_index %d", &sw_if_index))
5883         sw_if_index_is_set = 1;
5884       else if (unformat (i, "bond %u", &bond_sw_if_index))
5885         bond_sw_if_index_is_set = 1;
5886       else if (unformat (i, "passive %d", &is_passive))
5887         ;
5888       else if (unformat (i, "long-timeout %d", &is_long_timeout))
5889         ;
5890       else
5891         break;
5892     }
5893
5894   if (bond_sw_if_index_is_set == 0)
5895     {
5896       errmsg ("Missing bond sw_if_index. ");
5897       return -99;
5898     }
5899   if (sw_if_index_is_set == 0)
5900     {
5901       errmsg ("Missing member sw_if_index. ");
5902       return -99;
5903     }
5904
5905   /* Construct the API message */
5906   M (BOND_ADD_MEMBER, mp);
5907
5908   mp->bond_sw_if_index = ntohl (bond_sw_if_index);
5909   mp->sw_if_index = ntohl (sw_if_index);
5910   mp->is_long_timeout = is_long_timeout;
5911   mp->is_passive = is_passive;
5912
5913   /* send it... */
5914   S (mp);
5915
5916   /* Wait for a reply... */
5917   W (ret);
5918   return ret;
5919 }
5920
5921 static int
5922 api_bond_detach_member (vat_main_t * vam)
5923 {
5924   unformat_input_t *i = vam->input;
5925   vl_api_bond_detach_member_t *mp;
5926   u32 sw_if_index = ~0;
5927   u8 sw_if_index_set = 0;
5928   int ret;
5929
5930   /* Parse args required to build the message */
5931   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5932     {
5933       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5934         sw_if_index_set = 1;
5935       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5936         sw_if_index_set = 1;
5937       else
5938         break;
5939     }
5940
5941   if (sw_if_index_set == 0)
5942     {
5943       errmsg ("missing vpp interface name. ");
5944       return -99;
5945     }
5946
5947   /* Construct the API message */
5948   M (BOND_DETACH_MEMBER, mp);
5949
5950   mp->sw_if_index = ntohl (sw_if_index);
5951
5952   /* send it... */
5953   S (mp);
5954
5955   /* Wait for a reply... */
5956   W (ret);
5957   return ret;
5958 }
5959
5960 static int
5961 api_ip_table_add_del (vat_main_t * vam)
5962 {
5963   unformat_input_t *i = vam->input;
5964   vl_api_ip_table_add_del_t *mp;
5965   u32 table_id = ~0;
5966   u8 is_ipv6 = 0;
5967   u8 is_add = 1;
5968   int ret = 0;
5969
5970   /* Parse args required to build the message */
5971   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5972     {
5973       if (unformat (i, "ipv6"))
5974         is_ipv6 = 1;
5975       else if (unformat (i, "del"))
5976         is_add = 0;
5977       else if (unformat (i, "add"))
5978         is_add = 1;
5979       else if (unformat (i, "table %d", &table_id))
5980         ;
5981       else
5982         {
5983           clib_warning ("parse error '%U'", format_unformat_error, i);
5984           return -99;
5985         }
5986     }
5987
5988   if (~0 == table_id)
5989     {
5990       errmsg ("missing table-ID");
5991       return -99;
5992     }
5993
5994   /* Construct the API message */
5995   M (IP_TABLE_ADD_DEL, mp);
5996
5997   mp->table.table_id = ntohl (table_id);
5998   mp->table.is_ip6 = is_ipv6;
5999   mp->is_add = is_add;
6000
6001   /* send it... */
6002   S (mp);
6003
6004   /* Wait for a reply... */
6005   W (ret);
6006
6007   return ret;
6008 }
6009
6010 uword
6011 unformat_fib_path (unformat_input_t * input, va_list * args)
6012 {
6013   vat_main_t *vam = va_arg (*args, vat_main_t *);
6014   vl_api_fib_path_t *path = va_arg (*args, vl_api_fib_path_t *);
6015   u32 weight, preference;
6016   mpls_label_t out_label;
6017
6018   clib_memset (path, 0, sizeof (*path));
6019   path->weight = 1;
6020   path->sw_if_index = ~0;
6021   path->rpf_id = ~0;
6022   path->n_labels = 0;
6023
6024   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
6025     {
6026       if (unformat (input, "%U %U",
6027                     unformat_vl_api_ip4_address,
6028                     &path->nh.address.ip4,
6029                     api_unformat_sw_if_index, vam, &path->sw_if_index))
6030         {
6031           path->proto = FIB_API_PATH_NH_PROTO_IP4;
6032         }
6033       else if (unformat (input, "%U %U",
6034                          unformat_vl_api_ip6_address,
6035                          &path->nh.address.ip6,
6036                          api_unformat_sw_if_index, vam, &path->sw_if_index))
6037         {
6038           path->proto = FIB_API_PATH_NH_PROTO_IP6;
6039         }
6040       else if (unformat (input, "weight %u", &weight))
6041         {
6042           path->weight = weight;
6043         }
6044       else if (unformat (input, "preference %u", &preference))
6045         {
6046           path->preference = preference;
6047         }
6048       else if (unformat (input, "%U next-hop-table %d",
6049                          unformat_vl_api_ip4_address,
6050                          &path->nh.address.ip4, &path->table_id))
6051         {
6052           path->proto = FIB_API_PATH_NH_PROTO_IP4;
6053         }
6054       else if (unformat (input, "%U next-hop-table %d",
6055                          unformat_vl_api_ip6_address,
6056                          &path->nh.address.ip6, &path->table_id))
6057         {
6058           path->proto = FIB_API_PATH_NH_PROTO_IP6;
6059         }
6060       else if (unformat (input, "%U",
6061                          unformat_vl_api_ip4_address, &path->nh.address.ip4))
6062         {
6063           /*
6064            * the recursive next-hops are by default in the default table
6065            */
6066           path->table_id = 0;
6067           path->sw_if_index = ~0;
6068           path->proto = FIB_API_PATH_NH_PROTO_IP4;
6069         }
6070       else if (unformat (input, "%U",
6071                          unformat_vl_api_ip6_address, &path->nh.address.ip6))
6072         {
6073           /*
6074            * the recursive next-hops are by default in the default table
6075            */
6076           path->table_id = 0;
6077           path->sw_if_index = ~0;
6078           path->proto = FIB_API_PATH_NH_PROTO_IP6;
6079         }
6080       else if (unformat (input, "resolve-via-host"))
6081         {
6082           path->flags |= FIB_API_PATH_FLAG_RESOLVE_VIA_HOST;
6083         }
6084       else if (unformat (input, "resolve-via-attached"))
6085         {
6086           path->flags |= FIB_API_PATH_FLAG_RESOLVE_VIA_ATTACHED;
6087         }
6088       else if (unformat (input, "ip4-lookup-in-table %d", &path->table_id))
6089         {
6090           path->type = FIB_API_PATH_TYPE_LOCAL;
6091           path->sw_if_index = ~0;
6092           path->proto = FIB_API_PATH_NH_PROTO_IP4;
6093         }
6094       else if (unformat (input, "ip6-lookup-in-table %d", &path->table_id))
6095         {
6096           path->type = FIB_API_PATH_TYPE_LOCAL;
6097           path->sw_if_index = ~0;
6098           path->proto = FIB_API_PATH_NH_PROTO_IP6;
6099         }
6100       else if (unformat (input, "sw_if_index %d", &path->sw_if_index))
6101         ;
6102       else if (unformat (input, "via-label %d", &path->nh.via_label))
6103         {
6104           path->proto = FIB_API_PATH_NH_PROTO_MPLS;
6105           path->sw_if_index = ~0;
6106         }
6107       else if (unformat (input, "l2-input-on %d", &path->sw_if_index))
6108         {
6109           path->proto = FIB_API_PATH_NH_PROTO_ETHERNET;
6110           path->type = FIB_API_PATH_TYPE_INTERFACE_RX;
6111         }
6112       else if (unformat (input, "local"))
6113         {
6114           path->type = FIB_API_PATH_TYPE_LOCAL;
6115         }
6116       else if (unformat (input, "out-labels"))
6117         {
6118           while (unformat (input, "%d", &out_label))
6119             {
6120               path->label_stack[path->n_labels].label = out_label;
6121               path->label_stack[path->n_labels].is_uniform = 0;
6122               path->label_stack[path->n_labels].ttl = 64;
6123               path->n_labels++;
6124             }
6125         }
6126       else if (unformat (input, "via"))
6127         {
6128           /* new path, back up and return */
6129           unformat_put_input (input);
6130           unformat_put_input (input);
6131           unformat_put_input (input);
6132           unformat_put_input (input);
6133           break;
6134         }
6135       else
6136         {
6137           return (0);
6138         }
6139     }
6140
6141   path->proto = ntohl (path->proto);
6142   path->type = ntohl (path->type);
6143   path->flags = ntohl (path->flags);
6144   path->table_id = ntohl (path->table_id);
6145   path->sw_if_index = ntohl (path->sw_if_index);
6146
6147   return (1);
6148 }
6149
6150 static int
6151 api_ip_route_add_del (vat_main_t * vam)
6152 {
6153   unformat_input_t *i = vam->input;
6154   vl_api_ip_route_add_del_t *mp;
6155   u32 vrf_id = 0;
6156   u8 is_add = 1;
6157   u8 is_multipath = 0;
6158   u8 prefix_set = 0;
6159   u8 path_count = 0;
6160   vl_api_prefix_t pfx = { };
6161   vl_api_fib_path_t paths[8];
6162   int count = 1;
6163   int j;
6164   f64 before = 0;
6165   u32 random_add_del = 0;
6166   u32 *random_vector = 0;
6167   u32 random_seed = 0xdeaddabe;
6168
6169   /* Parse args required to build the message */
6170   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6171     {
6172       if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
6173         prefix_set = 1;
6174       else if (unformat (i, "del"))
6175         is_add = 0;
6176       else if (unformat (i, "add"))
6177         is_add = 1;
6178       else if (unformat (i, "vrf %d", &vrf_id))
6179         ;
6180       else if (unformat (i, "count %d", &count))
6181         ;
6182       else if (unformat (i, "random"))
6183         random_add_del = 1;
6184       else if (unformat (i, "multipath"))
6185         is_multipath = 1;
6186       else if (unformat (i, "seed %d", &random_seed))
6187         ;
6188       else
6189         if (unformat
6190             (i, "via %U", unformat_fib_path, vam, &paths[path_count]))
6191         {
6192           path_count++;
6193           if (8 == path_count)
6194             {
6195               errmsg ("max 8 paths");
6196               return -99;
6197             }
6198         }
6199       else
6200         {
6201           clib_warning ("parse error '%U'", format_unformat_error, i);
6202           return -99;
6203         }
6204     }
6205
6206   if (!path_count)
6207     {
6208       errmsg ("specify a path; via ...");
6209       return -99;
6210     }
6211   if (prefix_set == 0)
6212     {
6213       errmsg ("missing prefix");
6214       return -99;
6215     }
6216
6217   /* Generate a pile of unique, random routes */
6218   if (random_add_del)
6219     {
6220       ip4_address_t *i = (ip4_address_t *) & paths[0].nh.address.ip4;
6221       u32 this_random_address;
6222       uword *random_hash;
6223
6224       random_hash = hash_create (count, sizeof (uword));
6225
6226       hash_set (random_hash, i->as_u32, 1);
6227       for (j = 0; j <= count; j++)
6228         {
6229           do
6230             {
6231               this_random_address = random_u32 (&random_seed);
6232               this_random_address =
6233                 clib_host_to_net_u32 (this_random_address);
6234             }
6235           while (hash_get (random_hash, this_random_address));
6236           vec_add1 (random_vector, this_random_address);
6237           hash_set (random_hash, this_random_address, 1);
6238         }
6239       hash_free (random_hash);
6240       set_ip4_address (&pfx.address, random_vector[0]);
6241     }
6242
6243   if (count > 1)
6244     {
6245       /* Turn on async mode */
6246       vam->async_mode = 1;
6247       vam->async_errors = 0;
6248       before = vat_time_now (vam);
6249     }
6250
6251   for (j = 0; j < count; j++)
6252     {
6253       /* Construct the API message */
6254       M2 (IP_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t) * path_count);
6255
6256       mp->is_add = is_add;
6257       mp->is_multipath = is_multipath;
6258
6259       clib_memcpy (&mp->route.prefix, &pfx, sizeof (pfx));
6260       mp->route.table_id = ntohl (vrf_id);
6261       mp->route.n_paths = path_count;
6262
6263       clib_memcpy (&mp->route.paths, &paths, sizeof (paths[0]) * path_count);
6264
6265       if (random_add_del)
6266         set_ip4_address (&pfx.address, random_vector[j + 1]);
6267       else
6268         increment_address (&pfx.address);
6269       /* send it... */
6270       S (mp);
6271       /* If we receive SIGTERM, stop now... */
6272       if (vam->do_exit)
6273         break;
6274     }
6275
6276   /* When testing multiple add/del ops, use a control-ping to sync */
6277   if (count > 1)
6278     {
6279       vl_api_control_ping_t *mp_ping;
6280       f64 after;
6281       f64 timeout;
6282
6283       /* Shut off async mode */
6284       vam->async_mode = 0;
6285
6286       MPING (CONTROL_PING, mp_ping);
6287       S (mp_ping);
6288
6289       timeout = vat_time_now (vam) + 1.0;
6290       while (vat_time_now (vam) < timeout)
6291         if (vam->result_ready == 1)
6292           goto out;
6293       vam->retval = -99;
6294
6295     out:
6296       if (vam->retval == -99)
6297         errmsg ("timeout");
6298
6299       if (vam->async_errors > 0)
6300         {
6301           errmsg ("%d asynchronous errors", vam->async_errors);
6302           vam->retval = -98;
6303         }
6304       vam->async_errors = 0;
6305       after = vat_time_now (vam);
6306
6307       /* slim chance, but we might have eaten SIGTERM on the first iteration */
6308       if (j > 0)
6309         count = j;
6310
6311       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
6312              count, after - before, count / (after - before));
6313     }
6314   else
6315     {
6316       int ret;
6317
6318       /* Wait for a reply... */
6319       W (ret);
6320       return ret;
6321     }
6322
6323   /* Return the good/bad news */
6324   return (vam->retval);
6325 }
6326
6327 static int
6328 api_ip_mroute_add_del (vat_main_t * vam)
6329 {
6330   unformat_input_t *i = vam->input;
6331   u8 path_set = 0, prefix_set = 0, is_add = 1;
6332   vl_api_ip_mroute_add_del_t *mp;
6333   mfib_entry_flags_t eflags = 0;
6334   vl_api_mfib_path_t path;
6335   vl_api_mprefix_t pfx = { };
6336   u32 vrf_id = 0;
6337   int ret;
6338
6339   /* Parse args required to build the message */
6340   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6341     {
6342       if (unformat (i, "%U", unformat_vl_api_mprefix, &pfx))
6343         {
6344           prefix_set = 1;
6345           pfx.grp_address_length = htons (pfx.grp_address_length);
6346         }
6347       else if (unformat (i, "del"))
6348         is_add = 0;
6349       else if (unformat (i, "add"))
6350         is_add = 1;
6351       else if (unformat (i, "vrf %d", &vrf_id))
6352         ;
6353       else if (unformat (i, "%U", unformat_mfib_itf_flags, &path.itf_flags))
6354         path.itf_flags = htonl (path.itf_flags);
6355       else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
6356         ;
6357       else if (unformat (i, "via %U", unformat_fib_path, vam, &path.path))
6358         path_set = 1;
6359       else
6360         {
6361           clib_warning ("parse error '%U'", format_unformat_error, i);
6362           return -99;
6363         }
6364     }
6365
6366   if (prefix_set == 0)
6367     {
6368       errmsg ("missing addresses\n");
6369       return -99;
6370     }
6371   if (path_set == 0)
6372     {
6373       errmsg ("missing path\n");
6374       return -99;
6375     }
6376
6377   /* Construct the API message */
6378   M (IP_MROUTE_ADD_DEL, mp);
6379
6380   mp->is_add = is_add;
6381   mp->is_multipath = 1;
6382
6383   clib_memcpy (&mp->route.prefix, &pfx, sizeof (pfx));
6384   mp->route.table_id = htonl (vrf_id);
6385   mp->route.n_paths = 1;
6386   mp->route.entry_flags = htonl (eflags);
6387
6388   clib_memcpy (&mp->route.paths, &path, sizeof (path));
6389
6390   /* send it... */
6391   S (mp);
6392   /* Wait for a reply... */
6393   W (ret);
6394   return ret;
6395 }
6396
6397 static int
6398 api_mpls_table_add_del (vat_main_t * vam)
6399 {
6400   unformat_input_t *i = vam->input;
6401   vl_api_mpls_table_add_del_t *mp;
6402   u32 table_id = ~0;
6403   u8 is_add = 1;
6404   int ret = 0;
6405
6406   /* Parse args required to build the message */
6407   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6408     {
6409       if (unformat (i, "table %d", &table_id))
6410         ;
6411       else if (unformat (i, "del"))
6412         is_add = 0;
6413       else if (unformat (i, "add"))
6414         is_add = 1;
6415       else
6416         {
6417           clib_warning ("parse error '%U'", format_unformat_error, i);
6418           return -99;
6419         }
6420     }
6421
6422   if (~0 == table_id)
6423     {
6424       errmsg ("missing table-ID");
6425       return -99;
6426     }
6427
6428   /* Construct the API message */
6429   M (MPLS_TABLE_ADD_DEL, mp);
6430
6431   mp->mt_table.mt_table_id = ntohl (table_id);
6432   mp->mt_is_add = is_add;
6433
6434   /* send it... */
6435   S (mp);
6436
6437   /* Wait for a reply... */
6438   W (ret);
6439
6440   return ret;
6441 }
6442
6443 static int
6444 api_mpls_route_add_del (vat_main_t * vam)
6445 {
6446   u8 is_add = 1, path_count = 0, is_multipath = 0, is_eos = 0;
6447   mpls_label_t local_label = MPLS_LABEL_INVALID;
6448   unformat_input_t *i = vam->input;
6449   vl_api_mpls_route_add_del_t *mp;
6450   vl_api_fib_path_t paths[8];
6451   int count = 1, j;
6452   f64 before = 0;
6453
6454   /* Parse args required to build the message */
6455   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6456     {
6457       if (unformat (i, "%d", &local_label))
6458         ;
6459       else if (unformat (i, "eos"))
6460         is_eos = 1;
6461       else if (unformat (i, "non-eos"))
6462         is_eos = 0;
6463       else if (unformat (i, "del"))
6464         is_add = 0;
6465       else if (unformat (i, "add"))
6466         is_add = 1;
6467       else if (unformat (i, "multipath"))
6468         is_multipath = 1;
6469       else if (unformat (i, "count %d", &count))
6470         ;
6471       else
6472         if (unformat
6473             (i, "via %U", unformat_fib_path, vam, &paths[path_count]))
6474         {
6475           path_count++;
6476           if (8 == path_count)
6477             {
6478               errmsg ("max 8 paths");
6479               return -99;
6480             }
6481         }
6482       else
6483         {
6484           clib_warning ("parse error '%U'", format_unformat_error, i);
6485           return -99;
6486         }
6487     }
6488
6489   if (!path_count)
6490     {
6491       errmsg ("specify a path; via ...");
6492       return -99;
6493     }
6494
6495   if (MPLS_LABEL_INVALID == local_label)
6496     {
6497       errmsg ("missing label");
6498       return -99;
6499     }
6500
6501   if (count > 1)
6502     {
6503       /* Turn on async mode */
6504       vam->async_mode = 1;
6505       vam->async_errors = 0;
6506       before = vat_time_now (vam);
6507     }
6508
6509   for (j = 0; j < count; j++)
6510     {
6511       /* Construct the API message */
6512       M2 (MPLS_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t) * path_count);
6513
6514       mp->mr_is_add = is_add;
6515       mp->mr_is_multipath = is_multipath;
6516
6517       mp->mr_route.mr_label = local_label;
6518       mp->mr_route.mr_eos = is_eos;
6519       mp->mr_route.mr_table_id = 0;
6520       mp->mr_route.mr_n_paths = path_count;
6521
6522       clib_memcpy (&mp->mr_route.mr_paths, paths,
6523                    sizeof (paths[0]) * path_count);
6524
6525       local_label++;
6526
6527       /* send it... */
6528       S (mp);
6529       /* If we receive SIGTERM, stop now... */
6530       if (vam->do_exit)
6531         break;
6532     }
6533
6534   /* When testing multiple add/del ops, use a control-ping to sync */
6535   if (count > 1)
6536     {
6537       vl_api_control_ping_t *mp_ping;
6538       f64 after;
6539       f64 timeout;
6540
6541       /* Shut off async mode */
6542       vam->async_mode = 0;
6543
6544       MPING (CONTROL_PING, mp_ping);
6545       S (mp_ping);
6546
6547       timeout = vat_time_now (vam) + 1.0;
6548       while (vat_time_now (vam) < timeout)
6549         if (vam->result_ready == 1)
6550           goto out;
6551       vam->retval = -99;
6552
6553     out:
6554       if (vam->retval == -99)
6555         errmsg ("timeout");
6556
6557       if (vam->async_errors > 0)
6558         {
6559           errmsg ("%d asynchronous errors", vam->async_errors);
6560           vam->retval = -98;
6561         }
6562       vam->async_errors = 0;
6563       after = vat_time_now (vam);
6564
6565       /* slim chance, but we might have eaten SIGTERM on the first iteration */
6566       if (j > 0)
6567         count = j;
6568
6569       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
6570              count, after - before, count / (after - before));
6571     }
6572   else
6573     {
6574       int ret;
6575
6576       /* Wait for a reply... */
6577       W (ret);
6578       return ret;
6579     }
6580
6581   /* Return the good/bad news */
6582   return (vam->retval);
6583   return (0);
6584 }
6585
6586 static int
6587 api_mpls_ip_bind_unbind (vat_main_t * vam)
6588 {
6589   unformat_input_t *i = vam->input;
6590   vl_api_mpls_ip_bind_unbind_t *mp;
6591   u32 ip_table_id = 0;
6592   u8 is_bind = 1;
6593   vl_api_prefix_t pfx;
6594   u8 prefix_set = 0;
6595   mpls_label_t local_label = MPLS_LABEL_INVALID;
6596   int ret;
6597
6598   /* Parse args required to build the message */
6599   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6600     {
6601       if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
6602         prefix_set = 1;
6603       else if (unformat (i, "%d", &local_label))
6604         ;
6605       else if (unformat (i, "table-id %d", &ip_table_id))
6606         ;
6607       else if (unformat (i, "unbind"))
6608         is_bind = 0;
6609       else if (unformat (i, "bind"))
6610         is_bind = 1;
6611       else
6612         {
6613           clib_warning ("parse error '%U'", format_unformat_error, i);
6614           return -99;
6615         }
6616     }
6617
6618   if (!prefix_set)
6619     {
6620       errmsg ("IP prefix not set");
6621       return -99;
6622     }
6623
6624   if (MPLS_LABEL_INVALID == local_label)
6625     {
6626       errmsg ("missing label");
6627       return -99;
6628     }
6629
6630   /* Construct the API message */
6631   M (MPLS_IP_BIND_UNBIND, mp);
6632
6633   mp->mb_is_bind = is_bind;
6634   mp->mb_ip_table_id = ntohl (ip_table_id);
6635   mp->mb_mpls_table_id = 0;
6636   mp->mb_label = ntohl (local_label);
6637   clib_memcpy (&mp->mb_prefix, &pfx, sizeof (pfx));
6638
6639   /* send it... */
6640   S (mp);
6641
6642   /* Wait for a reply... */
6643   W (ret);
6644   return ret;
6645   return (0);
6646 }
6647
6648 static int
6649 api_sr_mpls_policy_add (vat_main_t * vam)
6650 {
6651   unformat_input_t *i = vam->input;
6652   vl_api_sr_mpls_policy_add_t *mp;
6653   u32 bsid = 0;
6654   u32 weight = 1;
6655   u8 type = 0;
6656   u8 n_segments = 0;
6657   u32 sid;
6658   u32 *segments = NULL;
6659   int ret;
6660
6661   /* Parse args required to build the message */
6662   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6663     {
6664       if (unformat (i, "bsid %d", &bsid))
6665         ;
6666       else if (unformat (i, "weight %d", &weight))
6667         ;
6668       else if (unformat (i, "spray"))
6669         type = 1;
6670       else if (unformat (i, "next %d", &sid))
6671         {
6672           n_segments += 1;
6673           vec_add1 (segments, htonl (sid));
6674         }
6675       else
6676         {
6677           clib_warning ("parse error '%U'", format_unformat_error, i);
6678           return -99;
6679         }
6680     }
6681
6682   if (bsid == 0)
6683     {
6684       errmsg ("bsid not set");
6685       return -99;
6686     }
6687
6688   if (n_segments == 0)
6689     {
6690       errmsg ("no sid in segment stack");
6691       return -99;
6692     }
6693
6694   /* Construct the API message */
6695   M2 (SR_MPLS_POLICY_ADD, mp, sizeof (u32) * n_segments);
6696
6697   mp->bsid = htonl (bsid);
6698   mp->weight = htonl (weight);
6699   mp->is_spray = type;
6700   mp->n_segments = n_segments;
6701   memcpy (mp->segments, segments, sizeof (u32) * n_segments);
6702   vec_free (segments);
6703
6704   /* send it... */
6705   S (mp);
6706
6707   /* Wait for a reply... */
6708   W (ret);
6709   return ret;
6710 }
6711
6712 static int
6713 api_sr_mpls_policy_del (vat_main_t * vam)
6714 {
6715   unformat_input_t *i = vam->input;
6716   vl_api_sr_mpls_policy_del_t *mp;
6717   u32 bsid = 0;
6718   int ret;
6719
6720   /* Parse args required to build the message */
6721   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6722     {
6723       if (unformat (i, "bsid %d", &bsid))
6724         ;
6725       else
6726         {
6727           clib_warning ("parse error '%U'", format_unformat_error, i);
6728           return -99;
6729         }
6730     }
6731
6732   if (bsid == 0)
6733     {
6734       errmsg ("bsid not set");
6735       return -99;
6736     }
6737
6738   /* Construct the API message */
6739   M (SR_MPLS_POLICY_DEL, mp);
6740
6741   mp->bsid = htonl (bsid);
6742
6743   /* send it... */
6744   S (mp);
6745
6746   /* Wait for a reply... */
6747   W (ret);
6748   return ret;
6749 }
6750
6751 static int
6752 api_bier_table_add_del (vat_main_t * vam)
6753 {
6754   unformat_input_t *i = vam->input;
6755   vl_api_bier_table_add_del_t *mp;
6756   u8 is_add = 1;
6757   u32 set = 0, sub_domain = 0, hdr_len = 3;
6758   mpls_label_t local_label = MPLS_LABEL_INVALID;
6759   int ret;
6760
6761   /* Parse args required to build the message */
6762   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6763     {
6764       if (unformat (i, "sub-domain %d", &sub_domain))
6765         ;
6766       else if (unformat (i, "set %d", &set))
6767         ;
6768       else if (unformat (i, "label %d", &local_label))
6769         ;
6770       else if (unformat (i, "hdr-len %d", &hdr_len))
6771         ;
6772       else if (unformat (i, "add"))
6773         is_add = 1;
6774       else if (unformat (i, "del"))
6775         is_add = 0;
6776       else
6777         {
6778           clib_warning ("parse error '%U'", format_unformat_error, i);
6779           return -99;
6780         }
6781     }
6782
6783   if (MPLS_LABEL_INVALID == local_label)
6784     {
6785       errmsg ("missing label\n");
6786       return -99;
6787     }
6788
6789   /* Construct the API message */
6790   M (BIER_TABLE_ADD_DEL, mp);
6791
6792   mp->bt_is_add = is_add;
6793   mp->bt_label = ntohl (local_label);
6794   mp->bt_tbl_id.bt_set = set;
6795   mp->bt_tbl_id.bt_sub_domain = sub_domain;
6796   mp->bt_tbl_id.bt_hdr_len_id = hdr_len;
6797
6798   /* send it... */
6799   S (mp);
6800
6801   /* Wait for a reply... */
6802   W (ret);
6803
6804   return (ret);
6805 }
6806
6807 static int
6808 api_bier_route_add_del (vat_main_t * vam)
6809 {
6810   unformat_input_t *i = vam->input;
6811   vl_api_bier_route_add_del_t *mp;
6812   u8 is_add = 1;
6813   u32 set = 0, sub_domain = 0, hdr_len = 3, bp = 0;
6814   ip4_address_t v4_next_hop_address;
6815   ip6_address_t v6_next_hop_address;
6816   u8 next_hop_set = 0;
6817   u8 next_hop_proto_is_ip4 = 1;
6818   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
6819   int ret;
6820
6821   /* Parse args required to build the message */
6822   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6823     {
6824       if (unformat (i, "%U", unformat_ip4_address, &v4_next_hop_address))
6825         {
6826           next_hop_proto_is_ip4 = 1;
6827           next_hop_set = 1;
6828         }
6829       else if (unformat (i, "%U", unformat_ip6_address, &v6_next_hop_address))
6830         {
6831           next_hop_proto_is_ip4 = 0;
6832           next_hop_set = 1;
6833         }
6834       if (unformat (i, "sub-domain %d", &sub_domain))
6835         ;
6836       else if (unformat (i, "set %d", &set))
6837         ;
6838       else if (unformat (i, "hdr-len %d", &hdr_len))
6839         ;
6840       else if (unformat (i, "bp %d", &bp))
6841         ;
6842       else if (unformat (i, "add"))
6843         is_add = 1;
6844       else if (unformat (i, "del"))
6845         is_add = 0;
6846       else if (unformat (i, "out-label %d", &next_hop_out_label))
6847         ;
6848       else
6849         {
6850           clib_warning ("parse error '%U'", format_unformat_error, i);
6851           return -99;
6852         }
6853     }
6854
6855   if (!next_hop_set || (MPLS_LABEL_INVALID == next_hop_out_label))
6856     {
6857       errmsg ("next hop / label set\n");
6858       return -99;
6859     }
6860   if (0 == bp)
6861     {
6862       errmsg ("bit=position not set\n");
6863       return -99;
6864     }
6865
6866   /* Construct the API message */
6867   M2 (BIER_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t));
6868
6869   mp->br_is_add = is_add;
6870   mp->br_route.br_tbl_id.bt_set = set;
6871   mp->br_route.br_tbl_id.bt_sub_domain = sub_domain;
6872   mp->br_route.br_tbl_id.bt_hdr_len_id = hdr_len;
6873   mp->br_route.br_bp = ntohs (bp);
6874   mp->br_route.br_n_paths = 1;
6875   mp->br_route.br_paths[0].n_labels = 1;
6876   mp->br_route.br_paths[0].label_stack[0].label = ntohl (next_hop_out_label);
6877   mp->br_route.br_paths[0].proto = (next_hop_proto_is_ip4 ?
6878                                     FIB_API_PATH_NH_PROTO_IP4 :
6879                                     FIB_API_PATH_NH_PROTO_IP6);
6880
6881   if (next_hop_proto_is_ip4)
6882     {
6883       clib_memcpy (&mp->br_route.br_paths[0].nh.address.ip4,
6884                    &v4_next_hop_address, sizeof (v4_next_hop_address));
6885     }
6886   else
6887     {
6888       clib_memcpy (&mp->br_route.br_paths[0].nh.address.ip6,
6889                    &v6_next_hop_address, sizeof (v6_next_hop_address));
6890     }
6891
6892   /* send it... */
6893   S (mp);
6894
6895   /* Wait for a reply... */
6896   W (ret);
6897
6898   return (ret);
6899 }
6900
6901 static int
6902 api_mpls_tunnel_add_del (vat_main_t * vam)
6903 {
6904   unformat_input_t *i = vam->input;
6905   vl_api_mpls_tunnel_add_del_t *mp;
6906
6907   vl_api_fib_path_t paths[8];
6908   u32 sw_if_index = ~0;
6909   u8 path_count = 0;
6910   u8 l2_only = 0;
6911   u8 is_add = 1;
6912   int ret;
6913
6914   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6915     {
6916       if (unformat (i, "add"))
6917         is_add = 1;
6918       else
6919         if (unformat
6920             (i, "del %U", api_unformat_sw_if_index, vam, &sw_if_index))
6921         is_add = 0;
6922       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
6923         is_add = 0;
6924       else if (unformat (i, "l2-only"))
6925         l2_only = 1;
6926       else
6927         if (unformat
6928             (i, "via %U", unformat_fib_path, vam, &paths[path_count]))
6929         {
6930           path_count++;
6931           if (8 == path_count)
6932             {
6933               errmsg ("max 8 paths");
6934               return -99;
6935             }
6936         }
6937       else
6938         {
6939           clib_warning ("parse error '%U'", format_unformat_error, i);
6940           return -99;
6941         }
6942     }
6943
6944   M2 (MPLS_TUNNEL_ADD_DEL, mp, sizeof (vl_api_fib_path_t) * path_count);
6945
6946   mp->mt_is_add = is_add;
6947   mp->mt_tunnel.mt_sw_if_index = ntohl (sw_if_index);
6948   mp->mt_tunnel.mt_l2_only = l2_only;
6949   mp->mt_tunnel.mt_is_multicast = 0;
6950   mp->mt_tunnel.mt_n_paths = path_count;
6951
6952   clib_memcpy (&mp->mt_tunnel.mt_paths, &paths,
6953                sizeof (paths[0]) * path_count);
6954
6955   S (mp);
6956   W (ret);
6957   return ret;
6958 }
6959
6960 static int
6961 api_sw_interface_set_unnumbered (vat_main_t * vam)
6962 {
6963   unformat_input_t *i = vam->input;
6964   vl_api_sw_interface_set_unnumbered_t *mp;
6965   u32 sw_if_index;
6966   u32 unnum_sw_index = ~0;
6967   u8 is_add = 1;
6968   u8 sw_if_index_set = 0;
6969   int ret;
6970
6971   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6972     {
6973       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6974         sw_if_index_set = 1;
6975       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6976         sw_if_index_set = 1;
6977       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
6978         ;
6979       else if (unformat (i, "del"))
6980         is_add = 0;
6981       else
6982         {
6983           clib_warning ("parse error '%U'", format_unformat_error, i);
6984           return -99;
6985         }
6986     }
6987
6988   if (sw_if_index_set == 0)
6989     {
6990       errmsg ("missing interface name or sw_if_index");
6991       return -99;
6992     }
6993
6994   M (SW_INTERFACE_SET_UNNUMBERED, mp);
6995
6996   mp->sw_if_index = ntohl (sw_if_index);
6997   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
6998   mp->is_add = is_add;
6999
7000   S (mp);
7001   W (ret);
7002   return ret;
7003 }
7004
7005
7006 static int
7007 api_create_vlan_subif (vat_main_t * vam)
7008 {
7009   unformat_input_t *i = vam->input;
7010   vl_api_create_vlan_subif_t *mp;
7011   u32 sw_if_index;
7012   u8 sw_if_index_set = 0;
7013   u32 vlan_id;
7014   u8 vlan_id_set = 0;
7015   int ret;
7016
7017   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7018     {
7019       if (unformat (i, "sw_if_index %d", &sw_if_index))
7020         sw_if_index_set = 1;
7021       else
7022         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7023         sw_if_index_set = 1;
7024       else if (unformat (i, "vlan %d", &vlan_id))
7025         vlan_id_set = 1;
7026       else
7027         {
7028           clib_warning ("parse error '%U'", format_unformat_error, i);
7029           return -99;
7030         }
7031     }
7032
7033   if (sw_if_index_set == 0)
7034     {
7035       errmsg ("missing interface name or sw_if_index");
7036       return -99;
7037     }
7038
7039   if (vlan_id_set == 0)
7040     {
7041       errmsg ("missing vlan_id");
7042       return -99;
7043     }
7044   M (CREATE_VLAN_SUBIF, mp);
7045
7046   mp->sw_if_index = ntohl (sw_if_index);
7047   mp->vlan_id = ntohl (vlan_id);
7048
7049   S (mp);
7050   W (ret);
7051   return ret;
7052 }
7053
7054 #define foreach_create_subif_bit                \
7055 _(no_tags)                                      \
7056 _(one_tag)                                      \
7057 _(two_tags)                                     \
7058 _(dot1ad)                                       \
7059 _(exact_match)                                  \
7060 _(default_sub)                                  \
7061 _(outer_vlan_id_any)                            \
7062 _(inner_vlan_id_any)
7063
7064 #define foreach_create_subif_flag               \
7065 _(0, "no_tags")                                 \
7066 _(1, "one_tag")                                 \
7067 _(2, "two_tags")                                \
7068 _(3, "dot1ad")                                  \
7069 _(4, "exact_match")                             \
7070 _(5, "default_sub")                             \
7071 _(6, "outer_vlan_id_any")                       \
7072 _(7, "inner_vlan_id_any")
7073
7074 static int
7075 api_create_subif (vat_main_t * vam)
7076 {
7077   unformat_input_t *i = vam->input;
7078   vl_api_create_subif_t *mp;
7079   u32 sw_if_index;
7080   u8 sw_if_index_set = 0;
7081   u32 sub_id;
7082   u8 sub_id_set = 0;
7083   u32 __attribute__ ((unused)) no_tags = 0;
7084   u32 __attribute__ ((unused)) one_tag = 0;
7085   u32 __attribute__ ((unused)) two_tags = 0;
7086   u32 __attribute__ ((unused)) dot1ad = 0;
7087   u32 __attribute__ ((unused)) exact_match = 0;
7088   u32 __attribute__ ((unused)) default_sub = 0;
7089   u32 __attribute__ ((unused)) outer_vlan_id_any = 0;
7090   u32 __attribute__ ((unused)) inner_vlan_id_any = 0;
7091   u32 tmp;
7092   u16 outer_vlan_id = 0;
7093   u16 inner_vlan_id = 0;
7094   int ret;
7095
7096   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7097     {
7098       if (unformat (i, "sw_if_index %d", &sw_if_index))
7099         sw_if_index_set = 1;
7100       else
7101         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7102         sw_if_index_set = 1;
7103       else if (unformat (i, "sub_id %d", &sub_id))
7104         sub_id_set = 1;
7105       else if (unformat (i, "outer_vlan_id %d", &tmp))
7106         outer_vlan_id = tmp;
7107       else if (unformat (i, "inner_vlan_id %d", &tmp))
7108         inner_vlan_id = tmp;
7109
7110 #define _(a) else if (unformat (i, #a)) a = 1 ;
7111       foreach_create_subif_bit
7112 #undef _
7113         else
7114         {
7115           clib_warning ("parse error '%U'", format_unformat_error, i);
7116           return -99;
7117         }
7118     }
7119
7120   if (sw_if_index_set == 0)
7121     {
7122       errmsg ("missing interface name or sw_if_index");
7123       return -99;
7124     }
7125
7126   if (sub_id_set == 0)
7127     {
7128       errmsg ("missing sub_id");
7129       return -99;
7130     }
7131   M (CREATE_SUBIF, mp);
7132
7133   mp->sw_if_index = ntohl (sw_if_index);
7134   mp->sub_id = ntohl (sub_id);
7135
7136 #define _(a,b) mp->sub_if_flags |= (1 << a);
7137   foreach_create_subif_flag;
7138 #undef _
7139
7140   mp->outer_vlan_id = ntohs (outer_vlan_id);
7141   mp->inner_vlan_id = ntohs (inner_vlan_id);
7142
7143   S (mp);
7144   W (ret);
7145   return ret;
7146 }
7147
7148 static int
7149 api_ip_table_replace_begin (vat_main_t * vam)
7150 {
7151   unformat_input_t *i = vam->input;
7152   vl_api_ip_table_replace_begin_t *mp;
7153   u32 table_id = 0;
7154   u8 is_ipv6 = 0;
7155
7156   int ret;
7157   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7158     {
7159       if (unformat (i, "table %d", &table_id))
7160         ;
7161       else if (unformat (i, "ipv6"))
7162         is_ipv6 = 1;
7163       else
7164         {
7165           clib_warning ("parse error '%U'", format_unformat_error, i);
7166           return -99;
7167         }
7168     }
7169
7170   M (IP_TABLE_REPLACE_BEGIN, mp);
7171
7172   mp->table.table_id = ntohl (table_id);
7173   mp->table.is_ip6 = is_ipv6;
7174
7175   S (mp);
7176   W (ret);
7177   return ret;
7178 }
7179
7180 static int
7181 api_ip_table_flush (vat_main_t * vam)
7182 {
7183   unformat_input_t *i = vam->input;
7184   vl_api_ip_table_flush_t *mp;
7185   u32 table_id = 0;
7186   u8 is_ipv6 = 0;
7187
7188   int ret;
7189   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7190     {
7191       if (unformat (i, "table %d", &table_id))
7192         ;
7193       else if (unformat (i, "ipv6"))
7194         is_ipv6 = 1;
7195       else
7196         {
7197           clib_warning ("parse error '%U'", format_unformat_error, i);
7198           return -99;
7199         }
7200     }
7201
7202   M (IP_TABLE_FLUSH, mp);
7203
7204   mp->table.table_id = ntohl (table_id);
7205   mp->table.is_ip6 = is_ipv6;
7206
7207   S (mp);
7208   W (ret);
7209   return ret;
7210 }
7211
7212 static int
7213 api_ip_table_replace_end (vat_main_t * vam)
7214 {
7215   unformat_input_t *i = vam->input;
7216   vl_api_ip_table_replace_end_t *mp;
7217   u32 table_id = 0;
7218   u8 is_ipv6 = 0;
7219
7220   int ret;
7221   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7222     {
7223       if (unformat (i, "table %d", &table_id))
7224         ;
7225       else if (unformat (i, "ipv6"))
7226         is_ipv6 = 1;
7227       else
7228         {
7229           clib_warning ("parse error '%U'", format_unformat_error, i);
7230           return -99;
7231         }
7232     }
7233
7234   M (IP_TABLE_REPLACE_END, mp);
7235
7236   mp->table.table_id = ntohl (table_id);
7237   mp->table.is_ip6 = is_ipv6;
7238
7239   S (mp);
7240   W (ret);
7241   return ret;
7242 }
7243
7244 static int
7245 api_set_ip_flow_hash (vat_main_t * vam)
7246 {
7247   unformat_input_t *i = vam->input;
7248   vl_api_set_ip_flow_hash_t *mp;
7249   u32 vrf_id = 0;
7250   u8 is_ipv6 = 0;
7251   u8 vrf_id_set = 0;
7252   u8 src = 0;
7253   u8 dst = 0;
7254   u8 sport = 0;
7255   u8 dport = 0;
7256   u8 proto = 0;
7257   u8 reverse = 0;
7258   int ret;
7259
7260   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7261     {
7262       if (unformat (i, "vrf %d", &vrf_id))
7263         vrf_id_set = 1;
7264       else if (unformat (i, "ipv6"))
7265         is_ipv6 = 1;
7266       else if (unformat (i, "src"))
7267         src = 1;
7268       else if (unformat (i, "dst"))
7269         dst = 1;
7270       else if (unformat (i, "sport"))
7271         sport = 1;
7272       else if (unformat (i, "dport"))
7273         dport = 1;
7274       else if (unformat (i, "proto"))
7275         proto = 1;
7276       else if (unformat (i, "reverse"))
7277         reverse = 1;
7278
7279       else
7280         {
7281           clib_warning ("parse error '%U'", format_unformat_error, i);
7282           return -99;
7283         }
7284     }
7285
7286   if (vrf_id_set == 0)
7287     {
7288       errmsg ("missing vrf id");
7289       return -99;
7290     }
7291
7292   M (SET_IP_FLOW_HASH, mp);
7293   mp->src = src;
7294   mp->dst = dst;
7295   mp->sport = sport;
7296   mp->dport = dport;
7297   mp->proto = proto;
7298   mp->reverse = reverse;
7299   mp->vrf_id = ntohl (vrf_id);
7300   mp->is_ipv6 = is_ipv6;
7301
7302   S (mp);
7303   W (ret);
7304   return ret;
7305 }
7306
7307 static int
7308 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
7309 {
7310   unformat_input_t *i = vam->input;
7311   vl_api_sw_interface_ip6_enable_disable_t *mp;
7312   u32 sw_if_index;
7313   u8 sw_if_index_set = 0;
7314   u8 enable = 0;
7315   int ret;
7316
7317   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7318     {
7319       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7320         sw_if_index_set = 1;
7321       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7322         sw_if_index_set = 1;
7323       else if (unformat (i, "enable"))
7324         enable = 1;
7325       else if (unformat (i, "disable"))
7326         enable = 0;
7327       else
7328         {
7329           clib_warning ("parse error '%U'", format_unformat_error, i);
7330           return -99;
7331         }
7332     }
7333
7334   if (sw_if_index_set == 0)
7335     {
7336       errmsg ("missing interface name or sw_if_index");
7337       return -99;
7338     }
7339
7340   M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
7341
7342   mp->sw_if_index = ntohl (sw_if_index);
7343   mp->enable = enable;
7344
7345   S (mp);
7346   W (ret);
7347   return ret;
7348 }
7349
7350
7351 static int
7352 api_l2_patch_add_del (vat_main_t * vam)
7353 {
7354   unformat_input_t *i = vam->input;
7355   vl_api_l2_patch_add_del_t *mp;
7356   u32 rx_sw_if_index;
7357   u8 rx_sw_if_index_set = 0;
7358   u32 tx_sw_if_index;
7359   u8 tx_sw_if_index_set = 0;
7360   u8 is_add = 1;
7361   int ret;
7362
7363   /* Parse args required to build the message */
7364   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7365     {
7366       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
7367         rx_sw_if_index_set = 1;
7368       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
7369         tx_sw_if_index_set = 1;
7370       else if (unformat (i, "rx"))
7371         {
7372           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7373             {
7374               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
7375                             &rx_sw_if_index))
7376                 rx_sw_if_index_set = 1;
7377             }
7378           else
7379             break;
7380         }
7381       else if (unformat (i, "tx"))
7382         {
7383           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7384             {
7385               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
7386                             &tx_sw_if_index))
7387                 tx_sw_if_index_set = 1;
7388             }
7389           else
7390             break;
7391         }
7392       else if (unformat (i, "del"))
7393         is_add = 0;
7394       else
7395         break;
7396     }
7397
7398   if (rx_sw_if_index_set == 0)
7399     {
7400       errmsg ("missing rx interface name or rx_sw_if_index");
7401       return -99;
7402     }
7403
7404   if (tx_sw_if_index_set == 0)
7405     {
7406       errmsg ("missing tx interface name or tx_sw_if_index");
7407       return -99;
7408     }
7409
7410   M (L2_PATCH_ADD_DEL, mp);
7411
7412   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
7413   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
7414   mp->is_add = is_add;
7415
7416   S (mp);
7417   W (ret);
7418   return ret;
7419 }
7420
7421 u8 is_del;
7422 u8 localsid_addr[16];
7423 u8 end_psp;
7424 u8 behavior;
7425 u32 sw_if_index;
7426 u32 vlan_index;
7427 u32 fib_table;
7428 u8 nh_addr[16];
7429
7430 static int
7431 api_sr_localsid_add_del (vat_main_t * vam)
7432 {
7433   unformat_input_t *i = vam->input;
7434   vl_api_sr_localsid_add_del_t *mp;
7435
7436   u8 is_del;
7437   ip6_address_t localsid;
7438   u8 end_psp = 0;
7439   u8 behavior = ~0;
7440   u32 sw_if_index;
7441   u32 fib_table = ~(u32) 0;
7442   ip46_address_t nh_addr;
7443   clib_memset (&nh_addr, 0, sizeof (ip46_address_t));
7444
7445   bool nexthop_set = 0;
7446
7447   int ret;
7448
7449   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7450     {
7451       if (unformat (i, "del"))
7452         is_del = 1;
7453       else if (unformat (i, "address %U", unformat_ip6_address, &localsid));
7454       else if (unformat (i, "next-hop %U", unformat_ip46_address, &nh_addr))
7455         nexthop_set = 1;
7456       else if (unformat (i, "behavior %u", &behavior));
7457       else if (unformat (i, "sw_if_index %u", &sw_if_index));
7458       else if (unformat (i, "fib-table %u", &fib_table));
7459       else if (unformat (i, "end.psp %u", &behavior));
7460       else
7461         break;
7462     }
7463
7464   M (SR_LOCALSID_ADD_DEL, mp);
7465
7466   clib_memcpy (mp->localsid, &localsid, sizeof (mp->localsid));
7467
7468   if (nexthop_set)
7469     {
7470       clib_memcpy (&mp->nh_addr.un, &nh_addr, sizeof (mp->nh_addr.un));
7471     }
7472   mp->behavior = behavior;
7473   mp->sw_if_index = ntohl (sw_if_index);
7474   mp->fib_table = ntohl (fib_table);
7475   mp->end_psp = end_psp;
7476   mp->is_del = is_del;
7477
7478   S (mp);
7479   W (ret);
7480   return ret;
7481 }
7482
7483 static int
7484 api_ioam_enable (vat_main_t * vam)
7485 {
7486   unformat_input_t *input = vam->input;
7487   vl_api_ioam_enable_t *mp;
7488   u32 id = 0;
7489   int has_trace_option = 0;
7490   int has_pot_option = 0;
7491   int has_seqno_option = 0;
7492   int has_analyse_option = 0;
7493   int ret;
7494
7495   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7496     {
7497       if (unformat (input, "trace"))
7498         has_trace_option = 1;
7499       else if (unformat (input, "pot"))
7500         has_pot_option = 1;
7501       else if (unformat (input, "seqno"))
7502         has_seqno_option = 1;
7503       else if (unformat (input, "analyse"))
7504         has_analyse_option = 1;
7505       else
7506         break;
7507     }
7508   M (IOAM_ENABLE, mp);
7509   mp->id = htons (id);
7510   mp->seqno = has_seqno_option;
7511   mp->analyse = has_analyse_option;
7512   mp->pot_enable = has_pot_option;
7513   mp->trace_enable = has_trace_option;
7514
7515   S (mp);
7516   W (ret);
7517   return ret;
7518 }
7519
7520
7521 static int
7522 api_ioam_disable (vat_main_t * vam)
7523 {
7524   vl_api_ioam_disable_t *mp;
7525   int ret;
7526
7527   M (IOAM_DISABLE, mp);
7528   S (mp);
7529   W (ret);
7530   return ret;
7531 }
7532
7533 #define foreach_tcp_proto_field                 \
7534 _(src_port)                                     \
7535 _(dst_port)
7536
7537 #define foreach_udp_proto_field                 \
7538 _(src_port)                                     \
7539 _(dst_port)
7540
7541 #define foreach_ip4_proto_field                 \
7542 _(src_address)                                  \
7543 _(dst_address)                                  \
7544 _(tos)                                          \
7545 _(length)                                       \
7546 _(fragment_id)                                  \
7547 _(ttl)                                          \
7548 _(protocol)                                     \
7549 _(checksum)
7550
7551 typedef struct
7552 {
7553   u16 src_port, dst_port;
7554 } tcpudp_header_t;
7555
7556 #if VPP_API_TEST_BUILTIN == 0
7557 uword
7558 unformat_tcp_mask (unformat_input_t * input, va_list * args)
7559 {
7560   u8 **maskp = va_arg (*args, u8 **);
7561   u8 *mask = 0;
7562   u8 found_something = 0;
7563   tcp_header_t *tcp;
7564
7565 #define _(a) u8 a=0;
7566   foreach_tcp_proto_field;
7567 #undef _
7568
7569   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7570     {
7571       if (0);
7572 #define _(a) else if (unformat (input, #a)) a=1;
7573       foreach_tcp_proto_field
7574 #undef _
7575         else
7576         break;
7577     }
7578
7579 #define _(a) found_something += a;
7580   foreach_tcp_proto_field;
7581 #undef _
7582
7583   if (found_something == 0)
7584     return 0;
7585
7586   vec_validate (mask, sizeof (*tcp) - 1);
7587
7588   tcp = (tcp_header_t *) mask;
7589
7590 #define _(a) if (a) clib_memset (&tcp->a, 0xff, sizeof (tcp->a));
7591   foreach_tcp_proto_field;
7592 #undef _
7593
7594   *maskp = mask;
7595   return 1;
7596 }
7597
7598 uword
7599 unformat_udp_mask (unformat_input_t * input, va_list * args)
7600 {
7601   u8 **maskp = va_arg (*args, u8 **);
7602   u8 *mask = 0;
7603   u8 found_something = 0;
7604   udp_header_t *udp;
7605
7606 #define _(a) u8 a=0;
7607   foreach_udp_proto_field;
7608 #undef _
7609
7610   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7611     {
7612       if (0);
7613 #define _(a) else if (unformat (input, #a)) a=1;
7614       foreach_udp_proto_field
7615 #undef _
7616         else
7617         break;
7618     }
7619
7620 #define _(a) found_something += a;
7621   foreach_udp_proto_field;
7622 #undef _
7623
7624   if (found_something == 0)
7625     return 0;
7626
7627   vec_validate (mask, sizeof (*udp) - 1);
7628
7629   udp = (udp_header_t *) mask;
7630
7631 #define _(a) if (a) clib_memset (&udp->a, 0xff, sizeof (udp->a));
7632   foreach_udp_proto_field;
7633 #undef _
7634
7635   *maskp = mask;
7636   return 1;
7637 }
7638
7639 uword
7640 unformat_l4_mask (unformat_input_t * input, va_list * args)
7641 {
7642   u8 **maskp = va_arg (*args, u8 **);
7643   u16 src_port = 0, dst_port = 0;
7644   tcpudp_header_t *tcpudp;
7645
7646   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7647     {
7648       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
7649         return 1;
7650       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
7651         return 1;
7652       else if (unformat (input, "src_port"))
7653         src_port = 0xFFFF;
7654       else if (unformat (input, "dst_port"))
7655         dst_port = 0xFFFF;
7656       else
7657         return 0;
7658     }
7659
7660   if (!src_port && !dst_port)
7661     return 0;
7662
7663   u8 *mask = 0;
7664   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
7665
7666   tcpudp = (tcpudp_header_t *) mask;
7667   tcpudp->src_port = src_port;
7668   tcpudp->dst_port = dst_port;
7669
7670   *maskp = mask;
7671
7672   return 1;
7673 }
7674
7675 uword
7676 unformat_ip4_mask (unformat_input_t * input, va_list * args)
7677 {
7678   u8 **maskp = va_arg (*args, u8 **);
7679   u8 *mask = 0;
7680   u8 found_something = 0;
7681   ip4_header_t *ip;
7682
7683 #define _(a) u8 a=0;
7684   foreach_ip4_proto_field;
7685 #undef _
7686   u8 version = 0;
7687   u8 hdr_length = 0;
7688
7689
7690   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7691     {
7692       if (unformat (input, "version"))
7693         version = 1;
7694       else if (unformat (input, "hdr_length"))
7695         hdr_length = 1;
7696       else if (unformat (input, "src"))
7697         src_address = 1;
7698       else if (unformat (input, "dst"))
7699         dst_address = 1;
7700       else if (unformat (input, "proto"))
7701         protocol = 1;
7702
7703 #define _(a) else if (unformat (input, #a)) a=1;
7704       foreach_ip4_proto_field
7705 #undef _
7706         else
7707         break;
7708     }
7709
7710 #define _(a) found_something += a;
7711   foreach_ip4_proto_field;
7712 #undef _
7713
7714   if (found_something == 0)
7715     return 0;
7716
7717   vec_validate (mask, sizeof (*ip) - 1);
7718
7719   ip = (ip4_header_t *) mask;
7720
7721 #define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
7722   foreach_ip4_proto_field;
7723 #undef _
7724
7725   ip->ip_version_and_header_length = 0;
7726
7727   if (version)
7728     ip->ip_version_and_header_length |= 0xF0;
7729
7730   if (hdr_length)
7731     ip->ip_version_and_header_length |= 0x0F;
7732
7733   *maskp = mask;
7734   return 1;
7735 }
7736
7737 #define foreach_ip6_proto_field                 \
7738 _(src_address)                                  \
7739 _(dst_address)                                  \
7740 _(payload_length)                               \
7741 _(hop_limit)                                    \
7742 _(protocol)
7743
7744 uword
7745 unformat_ip6_mask (unformat_input_t * input, va_list * args)
7746 {
7747   u8 **maskp = va_arg (*args, u8 **);
7748   u8 *mask = 0;
7749   u8 found_something = 0;
7750   ip6_header_t *ip;
7751   u32 ip_version_traffic_class_and_flow_label;
7752
7753 #define _(a) u8 a=0;
7754   foreach_ip6_proto_field;
7755 #undef _
7756   u8 version = 0;
7757   u8 traffic_class = 0;
7758   u8 flow_label = 0;
7759
7760   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7761     {
7762       if (unformat (input, "version"))
7763         version = 1;
7764       else if (unformat (input, "traffic-class"))
7765         traffic_class = 1;
7766       else if (unformat (input, "flow-label"))
7767         flow_label = 1;
7768       else if (unformat (input, "src"))
7769         src_address = 1;
7770       else if (unformat (input, "dst"))
7771         dst_address = 1;
7772       else if (unformat (input, "proto"))
7773         protocol = 1;
7774
7775 #define _(a) else if (unformat (input, #a)) a=1;
7776       foreach_ip6_proto_field
7777 #undef _
7778         else
7779         break;
7780     }
7781
7782 #define _(a) found_something += a;
7783   foreach_ip6_proto_field;
7784 #undef _
7785
7786   if (found_something == 0)
7787     return 0;
7788
7789   vec_validate (mask, sizeof (*ip) - 1);
7790
7791   ip = (ip6_header_t *) mask;
7792
7793 #define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
7794   foreach_ip6_proto_field;
7795 #undef _
7796
7797   ip_version_traffic_class_and_flow_label = 0;
7798
7799   if (version)
7800     ip_version_traffic_class_and_flow_label |= 0xF0000000;
7801
7802   if (traffic_class)
7803     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
7804
7805   if (flow_label)
7806     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
7807
7808   ip->ip_version_traffic_class_and_flow_label =
7809     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
7810
7811   *maskp = mask;
7812   return 1;
7813 }
7814
7815 uword
7816 unformat_l3_mask (unformat_input_t * input, va_list * args)
7817 {
7818   u8 **maskp = va_arg (*args, u8 **);
7819
7820   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7821     {
7822       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
7823         return 1;
7824       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
7825         return 1;
7826       else
7827         break;
7828     }
7829   return 0;
7830 }
7831
7832 uword
7833 unformat_l2_mask (unformat_input_t * input, va_list * args)
7834 {
7835   u8 **maskp = va_arg (*args, u8 **);
7836   u8 *mask = 0;
7837   u8 src = 0;
7838   u8 dst = 0;
7839   u8 proto = 0;
7840   u8 tag1 = 0;
7841   u8 tag2 = 0;
7842   u8 ignore_tag1 = 0;
7843   u8 ignore_tag2 = 0;
7844   u8 cos1 = 0;
7845   u8 cos2 = 0;
7846   u8 dot1q = 0;
7847   u8 dot1ad = 0;
7848   int len = 14;
7849
7850   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7851     {
7852       if (unformat (input, "src"))
7853         src = 1;
7854       else if (unformat (input, "dst"))
7855         dst = 1;
7856       else if (unformat (input, "proto"))
7857         proto = 1;
7858       else if (unformat (input, "tag1"))
7859         tag1 = 1;
7860       else if (unformat (input, "tag2"))
7861         tag2 = 1;
7862       else if (unformat (input, "ignore-tag1"))
7863         ignore_tag1 = 1;
7864       else if (unformat (input, "ignore-tag2"))
7865         ignore_tag2 = 1;
7866       else if (unformat (input, "cos1"))
7867         cos1 = 1;
7868       else if (unformat (input, "cos2"))
7869         cos2 = 1;
7870       else if (unformat (input, "dot1q"))
7871         dot1q = 1;
7872       else if (unformat (input, "dot1ad"))
7873         dot1ad = 1;
7874       else
7875         break;
7876     }
7877   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
7878        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
7879     return 0;
7880
7881   if (tag1 || ignore_tag1 || cos1 || dot1q)
7882     len = 18;
7883   if (tag2 || ignore_tag2 || cos2 || dot1ad)
7884     len = 22;
7885
7886   vec_validate (mask, len - 1);
7887
7888   if (dst)
7889     clib_memset (mask, 0xff, 6);
7890
7891   if (src)
7892     clib_memset (mask + 6, 0xff, 6);
7893
7894   if (tag2 || dot1ad)
7895     {
7896       /* inner vlan tag */
7897       if (tag2)
7898         {
7899           mask[19] = 0xff;
7900           mask[18] = 0x0f;
7901         }
7902       if (cos2)
7903         mask[18] |= 0xe0;
7904       if (proto)
7905         mask[21] = mask[20] = 0xff;
7906       if (tag1)
7907         {
7908           mask[15] = 0xff;
7909           mask[14] = 0x0f;
7910         }
7911       if (cos1)
7912         mask[14] |= 0xe0;
7913       *maskp = mask;
7914       return 1;
7915     }
7916   if (tag1 | dot1q)
7917     {
7918       if (tag1)
7919         {
7920           mask[15] = 0xff;
7921           mask[14] = 0x0f;
7922         }
7923       if (cos1)
7924         mask[14] |= 0xe0;
7925       if (proto)
7926         mask[16] = mask[17] = 0xff;
7927
7928       *maskp = mask;
7929       return 1;
7930     }
7931   if (cos2)
7932     mask[18] |= 0xe0;
7933   if (cos1)
7934     mask[14] |= 0xe0;
7935   if (proto)
7936     mask[12] = mask[13] = 0xff;
7937
7938   *maskp = mask;
7939   return 1;
7940 }
7941
7942 uword
7943 unformat_classify_mask (unformat_input_t * input, va_list * args)
7944 {
7945   u8 **maskp = va_arg (*args, u8 **);
7946   u32 *skipp = va_arg (*args, u32 *);
7947   u32 *matchp = va_arg (*args, u32 *);
7948   u32 match;
7949   u8 *mask = 0;
7950   u8 *l2 = 0;
7951   u8 *l3 = 0;
7952   u8 *l4 = 0;
7953   int i;
7954
7955   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7956     {
7957       if (unformat (input, "hex %U", unformat_hex_string, &mask))
7958         ;
7959       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
7960         ;
7961       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
7962         ;
7963       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
7964         ;
7965       else
7966         break;
7967     }
7968
7969   if (l4 && !l3)
7970     {
7971       vec_free (mask);
7972       vec_free (l2);
7973       vec_free (l4);
7974       return 0;
7975     }
7976
7977   if (mask || l2 || l3 || l4)
7978     {
7979       if (l2 || l3 || l4)
7980         {
7981           /* "With a free Ethernet header in every package" */
7982           if (l2 == 0)
7983             vec_validate (l2, 13);
7984           mask = l2;
7985           if (vec_len (l3))
7986             {
7987               vec_append (mask, l3);
7988               vec_free (l3);
7989             }
7990           if (vec_len (l4))
7991             {
7992               vec_append (mask, l4);
7993               vec_free (l4);
7994             }
7995         }
7996
7997       /* Scan forward looking for the first significant mask octet */
7998       for (i = 0; i < vec_len (mask); i++)
7999         if (mask[i])
8000           break;
8001
8002       /* compute (skip, match) params */
8003       *skipp = i / sizeof (u32x4);
8004       vec_delete (mask, *skipp * sizeof (u32x4), 0);
8005
8006       /* Pad mask to an even multiple of the vector size */
8007       while (vec_len (mask) % sizeof (u32x4))
8008         vec_add1 (mask, 0);
8009
8010       match = vec_len (mask) / sizeof (u32x4);
8011
8012       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
8013         {
8014           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
8015           if (*tmp || *(tmp + 1))
8016             break;
8017           match--;
8018         }
8019       if (match == 0)
8020         clib_warning ("BUG: match 0");
8021
8022       _vec_len (mask) = match * sizeof (u32x4);
8023
8024       *matchp = match;
8025       *maskp = mask;
8026
8027       return 1;
8028     }
8029
8030   return 0;
8031 }
8032 #endif /* VPP_API_TEST_BUILTIN */
8033
8034 #define foreach_l2_next                         \
8035 _(drop, DROP)                                   \
8036 _(ethernet, ETHERNET_INPUT)                     \
8037 _(ip4, IP4_INPUT)                               \
8038 _(ip6, IP6_INPUT)
8039
8040 uword
8041 unformat_l2_next_index (unformat_input_t * input, va_list * args)
8042 {
8043   u32 *miss_next_indexp = va_arg (*args, u32 *);
8044   u32 next_index = 0;
8045   u32 tmp;
8046
8047 #define _(n,N) \
8048   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
8049   foreach_l2_next;
8050 #undef _
8051
8052   if (unformat (input, "%d", &tmp))
8053     {
8054       next_index = tmp;
8055       goto out;
8056     }
8057
8058   return 0;
8059
8060 out:
8061   *miss_next_indexp = next_index;
8062   return 1;
8063 }
8064
8065 #define foreach_ip_next                         \
8066 _(drop, DROP)                                   \
8067 _(local, LOCAL)                                 \
8068 _(rewrite, REWRITE)
8069
8070 uword
8071 api_unformat_ip_next_index (unformat_input_t * input, va_list * args)
8072 {
8073   u32 *miss_next_indexp = va_arg (*args, u32 *);
8074   u32 next_index = 0;
8075   u32 tmp;
8076
8077 #define _(n,N) \
8078   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
8079   foreach_ip_next;
8080 #undef _
8081
8082   if (unformat (input, "%d", &tmp))
8083     {
8084       next_index = tmp;
8085       goto out;
8086     }
8087
8088   return 0;
8089
8090 out:
8091   *miss_next_indexp = next_index;
8092   return 1;
8093 }
8094
8095 #define foreach_acl_next                        \
8096 _(deny, DENY)
8097
8098 uword
8099 api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
8100 {
8101   u32 *miss_next_indexp = va_arg (*args, u32 *);
8102   u32 next_index = 0;
8103   u32 tmp;
8104
8105 #define _(n,N) \
8106   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
8107   foreach_acl_next;
8108 #undef _
8109
8110   if (unformat (input, "permit"))
8111     {
8112       next_index = ~0;
8113       goto out;
8114     }
8115   else if (unformat (input, "%d", &tmp))
8116     {
8117       next_index = tmp;
8118       goto out;
8119     }
8120
8121   return 0;
8122
8123 out:
8124   *miss_next_indexp = next_index;
8125   return 1;
8126 }
8127
8128 uword
8129 unformat_policer_precolor (unformat_input_t * input, va_list * args)
8130 {
8131   u32 *r = va_arg (*args, u32 *);
8132
8133   if (unformat (input, "conform-color"))
8134     *r = POLICE_CONFORM;
8135   else if (unformat (input, "exceed-color"))
8136     *r = POLICE_EXCEED;
8137   else
8138     return 0;
8139
8140   return 1;
8141 }
8142
8143 static int
8144 api_classify_add_del_table (vat_main_t * vam)
8145 {
8146   unformat_input_t *i = vam->input;
8147   vl_api_classify_add_del_table_t *mp;
8148
8149   u32 nbuckets = 2;
8150   u32 skip = ~0;
8151   u32 match = ~0;
8152   int is_add = 1;
8153   int del_chain = 0;
8154   u32 table_index = ~0;
8155   u32 next_table_index = ~0;
8156   u32 miss_next_index = ~0;
8157   u32 memory_size = 32 << 20;
8158   u8 *mask = 0;
8159   u32 current_data_flag = 0;
8160   int current_data_offset = 0;
8161   int ret;
8162
8163   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8164     {
8165       if (unformat (i, "del"))
8166         is_add = 0;
8167       else if (unformat (i, "del-chain"))
8168         {
8169           is_add = 0;
8170           del_chain = 1;
8171         }
8172       else if (unformat (i, "buckets %d", &nbuckets))
8173         ;
8174       else if (unformat (i, "memory_size %d", &memory_size))
8175         ;
8176       else if (unformat (i, "skip %d", &skip))
8177         ;
8178       else if (unformat (i, "match %d", &match))
8179         ;
8180       else if (unformat (i, "table %d", &table_index))
8181         ;
8182       else if (unformat (i, "mask %U", unformat_classify_mask,
8183                          &mask, &skip, &match))
8184         ;
8185       else if (unformat (i, "next-table %d", &next_table_index))
8186         ;
8187       else if (unformat (i, "miss-next %U", api_unformat_ip_next_index,
8188                          &miss_next_index))
8189         ;
8190       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
8191                          &miss_next_index))
8192         ;
8193       else if (unformat (i, "acl-miss-next %U", api_unformat_acl_next_index,
8194                          &miss_next_index))
8195         ;
8196       else if (unformat (i, "current-data-flag %d", &current_data_flag))
8197         ;
8198       else if (unformat (i, "current-data-offset %d", &current_data_offset))
8199         ;
8200       else
8201         break;
8202     }
8203
8204   if (is_add && mask == 0)
8205     {
8206       errmsg ("Mask required");
8207       return -99;
8208     }
8209
8210   if (is_add && skip == ~0)
8211     {
8212       errmsg ("skip count required");
8213       return -99;
8214     }
8215
8216   if (is_add && match == ~0)
8217     {
8218       errmsg ("match count required");
8219       return -99;
8220     }
8221
8222   if (!is_add && table_index == ~0)
8223     {
8224       errmsg ("table index required for delete");
8225       return -99;
8226     }
8227
8228   M2 (CLASSIFY_ADD_DEL_TABLE, mp, vec_len (mask));
8229
8230   mp->is_add = is_add;
8231   mp->del_chain = del_chain;
8232   mp->table_index = ntohl (table_index);
8233   mp->nbuckets = ntohl (nbuckets);
8234   mp->memory_size = ntohl (memory_size);
8235   mp->skip_n_vectors = ntohl (skip);
8236   mp->match_n_vectors = ntohl (match);
8237   mp->next_table_index = ntohl (next_table_index);
8238   mp->miss_next_index = ntohl (miss_next_index);
8239   mp->current_data_flag = ntohl (current_data_flag);
8240   mp->current_data_offset = ntohl (current_data_offset);
8241   mp->mask_len = ntohl (vec_len (mask));
8242   clib_memcpy (mp->mask, mask, vec_len (mask));
8243
8244   vec_free (mask);
8245
8246   S (mp);
8247   W (ret);
8248   return ret;
8249 }
8250
8251 #if VPP_API_TEST_BUILTIN == 0
8252 uword
8253 unformat_l4_match (unformat_input_t * input, va_list * args)
8254 {
8255   u8 **matchp = va_arg (*args, u8 **);
8256
8257   u8 *proto_header = 0;
8258   int src_port = 0;
8259   int dst_port = 0;
8260
8261   tcpudp_header_t h;
8262
8263   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8264     {
8265       if (unformat (input, "src_port %d", &src_port))
8266         ;
8267       else if (unformat (input, "dst_port %d", &dst_port))
8268         ;
8269       else
8270         return 0;
8271     }
8272
8273   h.src_port = clib_host_to_net_u16 (src_port);
8274   h.dst_port = clib_host_to_net_u16 (dst_port);
8275   vec_validate (proto_header, sizeof (h) - 1);
8276   memcpy (proto_header, &h, sizeof (h));
8277
8278   *matchp = proto_header;
8279
8280   return 1;
8281 }
8282
8283 uword
8284 unformat_ip4_match (unformat_input_t * input, va_list * args)
8285 {
8286   u8 **matchp = va_arg (*args, u8 **);
8287   u8 *match = 0;
8288   ip4_header_t *ip;
8289   int version = 0;
8290   u32 version_val;
8291   int hdr_length = 0;
8292   u32 hdr_length_val;
8293   int src = 0, dst = 0;
8294   ip4_address_t src_val, dst_val;
8295   int proto = 0;
8296   u32 proto_val;
8297   int tos = 0;
8298   u32 tos_val;
8299   int length = 0;
8300   u32 length_val;
8301   int fragment_id = 0;
8302   u32 fragment_id_val;
8303   int ttl = 0;
8304   int ttl_val;
8305   int checksum = 0;
8306   u32 checksum_val;
8307
8308   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8309     {
8310       if (unformat (input, "version %d", &version_val))
8311         version = 1;
8312       else if (unformat (input, "hdr_length %d", &hdr_length_val))
8313         hdr_length = 1;
8314       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
8315         src = 1;
8316       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
8317         dst = 1;
8318       else if (unformat (input, "proto %d", &proto_val))
8319         proto = 1;
8320       else if (unformat (input, "tos %d", &tos_val))
8321         tos = 1;
8322       else if (unformat (input, "length %d", &length_val))
8323         length = 1;
8324       else if (unformat (input, "fragment_id %d", &fragment_id_val))
8325         fragment_id = 1;
8326       else if (unformat (input, "ttl %d", &ttl_val))
8327         ttl = 1;
8328       else if (unformat (input, "checksum %d", &checksum_val))
8329         checksum = 1;
8330       else
8331         break;
8332     }
8333
8334   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
8335       + ttl + checksum == 0)
8336     return 0;
8337
8338   /*
8339    * Aligned because we use the real comparison functions
8340    */
8341   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
8342
8343   ip = (ip4_header_t *) match;
8344
8345   /* These are realistically matched in practice */
8346   if (src)
8347     ip->src_address.as_u32 = src_val.as_u32;
8348
8349   if (dst)
8350     ip->dst_address.as_u32 = dst_val.as_u32;
8351
8352   if (proto)
8353     ip->protocol = proto_val;
8354
8355
8356   /* These are not, but they're included for completeness */
8357   if (version)
8358     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
8359
8360   if (hdr_length)
8361     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
8362
8363   if (tos)
8364     ip->tos = tos_val;
8365
8366   if (length)
8367     ip->length = clib_host_to_net_u16 (length_val);
8368
8369   if (ttl)
8370     ip->ttl = ttl_val;
8371
8372   if (checksum)
8373     ip->checksum = clib_host_to_net_u16 (checksum_val);
8374
8375   *matchp = match;
8376   return 1;
8377 }
8378
8379 uword
8380 unformat_ip6_match (unformat_input_t * input, va_list * args)
8381 {
8382   u8 **matchp = va_arg (*args, u8 **);
8383   u8 *match = 0;
8384   ip6_header_t *ip;
8385   int version = 0;
8386   u32 version_val;
8387   u8 traffic_class = 0;
8388   u32 traffic_class_val = 0;
8389   u8 flow_label = 0;
8390   u8 flow_label_val;
8391   int src = 0, dst = 0;
8392   ip6_address_t src_val, dst_val;
8393   int proto = 0;
8394   u32 proto_val;
8395   int payload_length = 0;
8396   u32 payload_length_val;
8397   int hop_limit = 0;
8398   int hop_limit_val;
8399   u32 ip_version_traffic_class_and_flow_label;
8400
8401   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8402     {
8403       if (unformat (input, "version %d", &version_val))
8404         version = 1;
8405       else if (unformat (input, "traffic_class %d", &traffic_class_val))
8406         traffic_class = 1;
8407       else if (unformat (input, "flow_label %d", &flow_label_val))
8408         flow_label = 1;
8409       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
8410         src = 1;
8411       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
8412         dst = 1;
8413       else if (unformat (input, "proto %d", &proto_val))
8414         proto = 1;
8415       else if (unformat (input, "payload_length %d", &payload_length_val))
8416         payload_length = 1;
8417       else if (unformat (input, "hop_limit %d", &hop_limit_val))
8418         hop_limit = 1;
8419       else
8420         break;
8421     }
8422
8423   if (version + traffic_class + flow_label + src + dst + proto +
8424       payload_length + hop_limit == 0)
8425     return 0;
8426
8427   /*
8428    * Aligned because we use the real comparison functions
8429    */
8430   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
8431
8432   ip = (ip6_header_t *) match;
8433
8434   if (src)
8435     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
8436
8437   if (dst)
8438     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
8439
8440   if (proto)
8441     ip->protocol = proto_val;
8442
8443   ip_version_traffic_class_and_flow_label = 0;
8444
8445   if (version)
8446     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
8447
8448   if (traffic_class)
8449     ip_version_traffic_class_and_flow_label |=
8450       (traffic_class_val & 0xFF) << 20;
8451
8452   if (flow_label)
8453     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
8454
8455   ip->ip_version_traffic_class_and_flow_label =
8456     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
8457
8458   if (payload_length)
8459     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
8460
8461   if (hop_limit)
8462     ip->hop_limit = hop_limit_val;
8463
8464   *matchp = match;
8465   return 1;
8466 }
8467
8468 uword
8469 unformat_l3_match (unformat_input_t * input, va_list * args)
8470 {
8471   u8 **matchp = va_arg (*args, u8 **);
8472
8473   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8474     {
8475       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
8476         return 1;
8477       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
8478         return 1;
8479       else
8480         break;
8481     }
8482   return 0;
8483 }
8484
8485 uword
8486 unformat_vlan_tag (unformat_input_t * input, va_list * args)
8487 {
8488   u8 *tagp = va_arg (*args, u8 *);
8489   u32 tag;
8490
8491   if (unformat (input, "%d", &tag))
8492     {
8493       tagp[0] = (tag >> 8) & 0x0F;
8494       tagp[1] = tag & 0xFF;
8495       return 1;
8496     }
8497
8498   return 0;
8499 }
8500
8501 uword
8502 unformat_l2_match (unformat_input_t * input, va_list * args)
8503 {
8504   u8 **matchp = va_arg (*args, u8 **);
8505   u8 *match = 0;
8506   u8 src = 0;
8507   u8 src_val[6];
8508   u8 dst = 0;
8509   u8 dst_val[6];
8510   u8 proto = 0;
8511   u16 proto_val;
8512   u8 tag1 = 0;
8513   u8 tag1_val[2];
8514   u8 tag2 = 0;
8515   u8 tag2_val[2];
8516   int len = 14;
8517   u8 ignore_tag1 = 0;
8518   u8 ignore_tag2 = 0;
8519   u8 cos1 = 0;
8520   u8 cos2 = 0;
8521   u32 cos1_val = 0;
8522   u32 cos2_val = 0;
8523
8524   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8525     {
8526       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
8527         src = 1;
8528       else
8529         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
8530         dst = 1;
8531       else if (unformat (input, "proto %U",
8532                          unformat_ethernet_type_host_byte_order, &proto_val))
8533         proto = 1;
8534       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
8535         tag1 = 1;
8536       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
8537         tag2 = 1;
8538       else if (unformat (input, "ignore-tag1"))
8539         ignore_tag1 = 1;
8540       else if (unformat (input, "ignore-tag2"))
8541         ignore_tag2 = 1;
8542       else if (unformat (input, "cos1 %d", &cos1_val))
8543         cos1 = 1;
8544       else if (unformat (input, "cos2 %d", &cos2_val))
8545         cos2 = 1;
8546       else
8547         break;
8548     }
8549   if ((src + dst + proto + tag1 + tag2 +
8550        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
8551     return 0;
8552
8553   if (tag1 || ignore_tag1 || cos1)
8554     len = 18;
8555   if (tag2 || ignore_tag2 || cos2)
8556     len = 22;
8557
8558   vec_validate_aligned (match, len - 1, sizeof (u32x4));
8559
8560   if (dst)
8561     clib_memcpy (match, dst_val, 6);
8562
8563   if (src)
8564     clib_memcpy (match + 6, src_val, 6);
8565
8566   if (tag2)
8567     {
8568       /* inner vlan tag */
8569       match[19] = tag2_val[1];
8570       match[18] = tag2_val[0];
8571       if (cos2)
8572         match[18] |= (cos2_val & 0x7) << 5;
8573       if (proto)
8574         {
8575           match[21] = proto_val & 0xff;
8576           match[20] = proto_val >> 8;
8577         }
8578       if (tag1)
8579         {
8580           match[15] = tag1_val[1];
8581           match[14] = tag1_val[0];
8582         }
8583       if (cos1)
8584         match[14] |= (cos1_val & 0x7) << 5;
8585       *matchp = match;
8586       return 1;
8587     }
8588   if (tag1)
8589     {
8590       match[15] = tag1_val[1];
8591       match[14] = tag1_val[0];
8592       if (proto)
8593         {
8594           match[17] = proto_val & 0xff;
8595           match[16] = proto_val >> 8;
8596         }
8597       if (cos1)
8598         match[14] |= (cos1_val & 0x7) << 5;
8599
8600       *matchp = match;
8601       return 1;
8602     }
8603   if (cos2)
8604     match[18] |= (cos2_val & 0x7) << 5;
8605   if (cos1)
8606     match[14] |= (cos1_val & 0x7) << 5;
8607   if (proto)
8608     {
8609       match[13] = proto_val & 0xff;
8610       match[12] = proto_val >> 8;
8611     }
8612
8613   *matchp = match;
8614   return 1;
8615 }
8616
8617 uword
8618 unformat_qos_source (unformat_input_t * input, va_list * args)
8619 {
8620   int *qs = va_arg (*args, int *);
8621
8622   if (unformat (input, "ip"))
8623     *qs = QOS_SOURCE_IP;
8624   else if (unformat (input, "mpls"))
8625     *qs = QOS_SOURCE_MPLS;
8626   else if (unformat (input, "ext"))
8627     *qs = QOS_SOURCE_EXT;
8628   else if (unformat (input, "vlan"))
8629     *qs = QOS_SOURCE_VLAN;
8630   else
8631     return 0;
8632
8633   return 1;
8634 }
8635 #endif
8636
8637 uword
8638 api_unformat_classify_match (unformat_input_t * input, va_list * args)
8639 {
8640   u8 **matchp = va_arg (*args, u8 **);
8641   u32 skip_n_vectors = va_arg (*args, u32);
8642   u32 match_n_vectors = va_arg (*args, u32);
8643
8644   u8 *match = 0;
8645   u8 *l2 = 0;
8646   u8 *l3 = 0;
8647   u8 *l4 = 0;
8648
8649   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8650     {
8651       if (unformat (input, "hex %U", unformat_hex_string, &match))
8652         ;
8653       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
8654         ;
8655       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
8656         ;
8657       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
8658         ;
8659       else
8660         break;
8661     }
8662
8663   if (l4 && !l3)
8664     {
8665       vec_free (match);
8666       vec_free (l2);
8667       vec_free (l4);
8668       return 0;
8669     }
8670
8671   if (match || l2 || l3 || l4)
8672     {
8673       if (l2 || l3 || l4)
8674         {
8675           /* "Win a free Ethernet header in every packet" */
8676           if (l2 == 0)
8677             vec_validate_aligned (l2, 13, sizeof (u32x4));
8678           match = l2;
8679           if (vec_len (l3))
8680             {
8681               vec_append_aligned (match, l3, sizeof (u32x4));
8682               vec_free (l3);
8683             }
8684           if (vec_len (l4))
8685             {
8686               vec_append_aligned (match, l4, sizeof (u32x4));
8687               vec_free (l4);
8688             }
8689         }
8690
8691       /* Make sure the vector is big enough even if key is all 0's */
8692       vec_validate_aligned
8693         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
8694          sizeof (u32x4));
8695
8696       /* Set size, include skipped vectors */
8697       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
8698
8699       *matchp = match;
8700
8701       return 1;
8702     }
8703
8704   return 0;
8705 }
8706
8707 static int
8708 api_classify_add_del_session (vat_main_t * vam)
8709 {
8710   unformat_input_t *i = vam->input;
8711   vl_api_classify_add_del_session_t *mp;
8712   int is_add = 1;
8713   u32 table_index = ~0;
8714   u32 hit_next_index = ~0;
8715   u32 opaque_index = ~0;
8716   u8 *match = 0;
8717   i32 advance = 0;
8718   u32 skip_n_vectors = 0;
8719   u32 match_n_vectors = 0;
8720   u32 action = 0;
8721   u32 metadata = 0;
8722   int ret;
8723
8724   /*
8725    * Warning: you have to supply skip_n and match_n
8726    * because the API client cant simply look at the classify
8727    * table object.
8728    */
8729
8730   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8731     {
8732       if (unformat (i, "del"))
8733         is_add = 0;
8734       else if (unformat (i, "hit-next %U", api_unformat_ip_next_index,
8735                          &hit_next_index))
8736         ;
8737       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
8738                          &hit_next_index))
8739         ;
8740       else if (unformat (i, "acl-hit-next %U", api_unformat_acl_next_index,
8741                          &hit_next_index))
8742         ;
8743       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
8744         ;
8745       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
8746         ;
8747       else if (unformat (i, "opaque-index %d", &opaque_index))
8748         ;
8749       else if (unformat (i, "skip_n %d", &skip_n_vectors))
8750         ;
8751       else if (unformat (i, "match_n %d", &match_n_vectors))
8752         ;
8753       else if (unformat (i, "match %U", api_unformat_classify_match,
8754                          &match, skip_n_vectors, match_n_vectors))
8755         ;
8756       else if (unformat (i, "advance %d", &advance))
8757         ;
8758       else if (unformat (i, "table-index %d", &table_index))
8759         ;
8760       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
8761         action = 1;
8762       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
8763         action = 2;
8764       else if (unformat (i, "action %d", &action))
8765         ;
8766       else if (unformat (i, "metadata %d", &metadata))
8767         ;
8768       else
8769         break;
8770     }
8771
8772   if (table_index == ~0)
8773     {
8774       errmsg ("Table index required");
8775       return -99;
8776     }
8777
8778   if (is_add && match == 0)
8779     {
8780       errmsg ("Match value required");
8781       return -99;
8782     }
8783
8784   M2 (CLASSIFY_ADD_DEL_SESSION, mp, vec_len (match));
8785
8786   mp->is_add = is_add;
8787   mp->table_index = ntohl (table_index);
8788   mp->hit_next_index = ntohl (hit_next_index);
8789   mp->opaque_index = ntohl (opaque_index);
8790   mp->advance = ntohl (advance);
8791   mp->action = action;
8792   mp->metadata = ntohl (metadata);
8793   mp->match_len = ntohl (vec_len (match));
8794   clib_memcpy (mp->match, match, vec_len (match));
8795   vec_free (match);
8796
8797   S (mp);
8798   W (ret);
8799   return ret;
8800 }
8801
8802 static int
8803 api_classify_set_interface_ip_table (vat_main_t * vam)
8804 {
8805   unformat_input_t *i = vam->input;
8806   vl_api_classify_set_interface_ip_table_t *mp;
8807   u32 sw_if_index;
8808   int sw_if_index_set;
8809   u32 table_index = ~0;
8810   u8 is_ipv6 = 0;
8811   int ret;
8812
8813   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8814     {
8815       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8816         sw_if_index_set = 1;
8817       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8818         sw_if_index_set = 1;
8819       else if (unformat (i, "table %d", &table_index))
8820         ;
8821       else
8822         {
8823           clib_warning ("parse error '%U'", format_unformat_error, i);
8824           return -99;
8825         }
8826     }
8827
8828   if (sw_if_index_set == 0)
8829     {
8830       errmsg ("missing interface name or sw_if_index");
8831       return -99;
8832     }
8833
8834
8835   M (CLASSIFY_SET_INTERFACE_IP_TABLE, mp);
8836
8837   mp->sw_if_index = ntohl (sw_if_index);
8838   mp->table_index = ntohl (table_index);
8839   mp->is_ipv6 = is_ipv6;
8840
8841   S (mp);
8842   W (ret);
8843   return ret;
8844 }
8845
8846 static int
8847 api_classify_set_interface_l2_tables (vat_main_t * vam)
8848 {
8849   unformat_input_t *i = vam->input;
8850   vl_api_classify_set_interface_l2_tables_t *mp;
8851   u32 sw_if_index;
8852   int sw_if_index_set;
8853   u32 ip4_table_index = ~0;
8854   u32 ip6_table_index = ~0;
8855   u32 other_table_index = ~0;
8856   u32 is_input = 1;
8857   int ret;
8858
8859   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8860     {
8861       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8862         sw_if_index_set = 1;
8863       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8864         sw_if_index_set = 1;
8865       else if (unformat (i, "ip4-table %d", &ip4_table_index))
8866         ;
8867       else if (unformat (i, "ip6-table %d", &ip6_table_index))
8868         ;
8869       else if (unformat (i, "other-table %d", &other_table_index))
8870         ;
8871       else if (unformat (i, "is-input %d", &is_input))
8872         ;
8873       else
8874         {
8875           clib_warning ("parse error '%U'", format_unformat_error, i);
8876           return -99;
8877         }
8878     }
8879
8880   if (sw_if_index_set == 0)
8881     {
8882       errmsg ("missing interface name or sw_if_index");
8883       return -99;
8884     }
8885
8886
8887   M (CLASSIFY_SET_INTERFACE_L2_TABLES, mp);
8888
8889   mp->sw_if_index = ntohl (sw_if_index);
8890   mp->ip4_table_index = ntohl (ip4_table_index);
8891   mp->ip6_table_index = ntohl (ip6_table_index);
8892   mp->other_table_index = ntohl (other_table_index);
8893   mp->is_input = (u8) is_input;
8894
8895   S (mp);
8896   W (ret);
8897   return ret;
8898 }
8899
8900 static int
8901 api_set_ipfix_exporter (vat_main_t * vam)
8902 {
8903   unformat_input_t *i = vam->input;
8904   vl_api_set_ipfix_exporter_t *mp;
8905   ip4_address_t collector_address;
8906   u8 collector_address_set = 0;
8907   u32 collector_port = ~0;
8908   ip4_address_t src_address;
8909   u8 src_address_set = 0;
8910   u32 vrf_id = ~0;
8911   u32 path_mtu = ~0;
8912   u32 template_interval = ~0;
8913   u8 udp_checksum = 0;
8914   int ret;
8915
8916   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8917     {
8918       if (unformat (i, "collector_address %U", unformat_ip4_address,
8919                     &collector_address))
8920         collector_address_set = 1;
8921       else if (unformat (i, "collector_port %d", &collector_port))
8922         ;
8923       else if (unformat (i, "src_address %U", unformat_ip4_address,
8924                          &src_address))
8925         src_address_set = 1;
8926       else if (unformat (i, "vrf_id %d", &vrf_id))
8927         ;
8928       else if (unformat (i, "path_mtu %d", &path_mtu))
8929         ;
8930       else if (unformat (i, "template_interval %d", &template_interval))
8931         ;
8932       else if (unformat (i, "udp_checksum"))
8933         udp_checksum = 1;
8934       else
8935         break;
8936     }
8937
8938   if (collector_address_set == 0)
8939     {
8940       errmsg ("collector_address required");
8941       return -99;
8942     }
8943
8944   if (src_address_set == 0)
8945     {
8946       errmsg ("src_address required");
8947       return -99;
8948     }
8949
8950   M (SET_IPFIX_EXPORTER, mp);
8951
8952   memcpy (mp->collector_address.un.ip4, collector_address.data,
8953           sizeof (collector_address.data));
8954   mp->collector_port = htons ((u16) collector_port);
8955   memcpy (mp->src_address.un.ip4, src_address.data,
8956           sizeof (src_address.data));
8957   mp->vrf_id = htonl (vrf_id);
8958   mp->path_mtu = htonl (path_mtu);
8959   mp->template_interval = htonl (template_interval);
8960   mp->udp_checksum = udp_checksum;
8961
8962   S (mp);
8963   W (ret);
8964   return ret;
8965 }
8966
8967 static int
8968 api_set_ipfix_classify_stream (vat_main_t * vam)
8969 {
8970   unformat_input_t *i = vam->input;
8971   vl_api_set_ipfix_classify_stream_t *mp;
8972   u32 domain_id = 0;
8973   u32 src_port = UDP_DST_PORT_ipfix;
8974   int ret;
8975
8976   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8977     {
8978       if (unformat (i, "domain %d", &domain_id))
8979         ;
8980       else if (unformat (i, "src_port %d", &src_port))
8981         ;
8982       else
8983         {
8984           errmsg ("unknown input `%U'", format_unformat_error, i);
8985           return -99;
8986         }
8987     }
8988
8989   M (SET_IPFIX_CLASSIFY_STREAM, mp);
8990
8991   mp->domain_id = htonl (domain_id);
8992   mp->src_port = htons ((u16) src_port);
8993
8994   S (mp);
8995   W (ret);
8996   return ret;
8997 }
8998
8999 static int
9000 api_ipfix_classify_table_add_del (vat_main_t * vam)
9001 {
9002   unformat_input_t *i = vam->input;
9003   vl_api_ipfix_classify_table_add_del_t *mp;
9004   int is_add = -1;
9005   u32 classify_table_index = ~0;
9006   u8 ip_version = 0;
9007   u8 transport_protocol = 255;
9008   int ret;
9009
9010   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9011     {
9012       if (unformat (i, "add"))
9013         is_add = 1;
9014       else if (unformat (i, "del"))
9015         is_add = 0;
9016       else if (unformat (i, "table %d", &classify_table_index))
9017         ;
9018       else if (unformat (i, "ip4"))
9019         ip_version = 4;
9020       else if (unformat (i, "ip6"))
9021         ip_version = 6;
9022       else if (unformat (i, "tcp"))
9023         transport_protocol = 6;
9024       else if (unformat (i, "udp"))
9025         transport_protocol = 17;
9026       else
9027         {
9028           errmsg ("unknown input `%U'", format_unformat_error, i);
9029           return -99;
9030         }
9031     }
9032
9033   if (is_add == -1)
9034     {
9035       errmsg ("expecting: add|del");
9036       return -99;
9037     }
9038   if (classify_table_index == ~0)
9039     {
9040       errmsg ("classifier table not specified");
9041       return -99;
9042     }
9043   if (ip_version == 0)
9044     {
9045       errmsg ("IP version not specified");
9046       return -99;
9047     }
9048
9049   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, mp);
9050
9051   mp->is_add = is_add;
9052   mp->table_id = htonl (classify_table_index);
9053   mp->ip_version = ip_version;
9054   mp->transport_protocol = transport_protocol;
9055
9056   S (mp);
9057   W (ret);
9058   return ret;
9059 }
9060
9061 static int
9062 api_get_node_index (vat_main_t * vam)
9063 {
9064   unformat_input_t *i = vam->input;
9065   vl_api_get_node_index_t *mp;
9066   u8 *name = 0;
9067   int ret;
9068
9069   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9070     {
9071       if (unformat (i, "node %s", &name))
9072         ;
9073       else
9074         break;
9075     }
9076   if (name == 0)
9077     {
9078       errmsg ("node name required");
9079       return -99;
9080     }
9081   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
9082     {
9083       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
9084       return -99;
9085     }
9086
9087   M (GET_NODE_INDEX, mp);
9088   clib_memcpy (mp->node_name, name, vec_len (name));
9089   vec_free (name);
9090
9091   S (mp);
9092   W (ret);
9093   return ret;
9094 }
9095
9096 static int
9097 api_get_next_index (vat_main_t * vam)
9098 {
9099   unformat_input_t *i = vam->input;
9100   vl_api_get_next_index_t *mp;
9101   u8 *node_name = 0, *next_node_name = 0;
9102   int ret;
9103
9104   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9105     {
9106       if (unformat (i, "node-name %s", &node_name))
9107         ;
9108       else if (unformat (i, "next-node-name %s", &next_node_name))
9109         break;
9110     }
9111
9112   if (node_name == 0)
9113     {
9114       errmsg ("node name required");
9115       return -99;
9116     }
9117   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
9118     {
9119       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
9120       return -99;
9121     }
9122
9123   if (next_node_name == 0)
9124     {
9125       errmsg ("next node name required");
9126       return -99;
9127     }
9128   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
9129     {
9130       errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
9131       return -99;
9132     }
9133
9134   M (GET_NEXT_INDEX, mp);
9135   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
9136   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
9137   vec_free (node_name);
9138   vec_free (next_node_name);
9139
9140   S (mp);
9141   W (ret);
9142   return ret;
9143 }
9144
9145 static int
9146 api_add_node_next (vat_main_t * vam)
9147 {
9148   unformat_input_t *i = vam->input;
9149   vl_api_add_node_next_t *mp;
9150   u8 *name = 0;
9151   u8 *next = 0;
9152   int ret;
9153
9154   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9155     {
9156       if (unformat (i, "node %s", &name))
9157         ;
9158       else if (unformat (i, "next %s", &next))
9159         ;
9160       else
9161         break;
9162     }
9163   if (name == 0)
9164     {
9165       errmsg ("node name required");
9166       return -99;
9167     }
9168   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
9169     {
9170       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
9171       return -99;
9172     }
9173   if (next == 0)
9174     {
9175       errmsg ("next node required");
9176       return -99;
9177     }
9178   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
9179     {
9180       errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
9181       return -99;
9182     }
9183
9184   M (ADD_NODE_NEXT, mp);
9185   clib_memcpy (mp->node_name, name, vec_len (name));
9186   clib_memcpy (mp->next_name, next, vec_len (next));
9187   vec_free (name);
9188   vec_free (next);
9189
9190   S (mp);
9191   W (ret);
9192   return ret;
9193 }
9194
9195 static void vl_api_sw_interface_tap_v2_details_t_handler
9196   (vl_api_sw_interface_tap_v2_details_t * mp)
9197 {
9198   vat_main_t *vam = &vat_main;
9199
9200   u8 *ip4 =
9201     format (0, "%U/%d", format_ip4_address, mp->host_ip4_prefix.address,
9202             mp->host_ip4_prefix.len);
9203   u8 *ip6 =
9204     format (0, "%U/%d", format_ip6_address, mp->host_ip6_prefix.address,
9205             mp->host_ip6_prefix.len);
9206
9207   print (vam->ofp,
9208          "\n%-16s %-12d %-5d %-12d %-12d %-14U %-30s %-20s %-20s %-30s 0x%-08x",
9209          mp->dev_name, ntohl (mp->sw_if_index), ntohl (mp->id),
9210          ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
9211          format_ethernet_address, mp->host_mac_addr, mp->host_namespace,
9212          mp->host_bridge, ip4, ip6, ntohl (mp->tap_flags));
9213
9214   vec_free (ip4);
9215   vec_free (ip6);
9216 }
9217
9218 static void vl_api_sw_interface_tap_v2_details_t_handler_json
9219   (vl_api_sw_interface_tap_v2_details_t * mp)
9220 {
9221   vat_main_t *vam = &vat_main;
9222   vat_json_node_t *node = NULL;
9223
9224   if (VAT_JSON_ARRAY != vam->json_tree.type)
9225     {
9226       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9227       vat_json_init_array (&vam->json_tree);
9228     }
9229   node = vat_json_array_add (&vam->json_tree);
9230
9231   vat_json_init_object (node);
9232   vat_json_object_add_uint (node, "id", ntohl (mp->id));
9233   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
9234   vat_json_object_add_uint (node, "tap_flags", ntohl (mp->tap_flags));
9235   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
9236   vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
9237   vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
9238   vat_json_object_add_string_copy (node, "host_mac_addr",
9239                                    format (0, "%U", format_ethernet_address,
9240                                            &mp->host_mac_addr));
9241   vat_json_object_add_string_copy (node, "host_namespace",
9242                                    mp->host_namespace);
9243   vat_json_object_add_string_copy (node, "host_bridge", mp->host_bridge);
9244   vat_json_object_add_string_copy (node, "host_ip4_addr",
9245                                    format (0, "%U/%d", format_ip4_address,
9246                                            mp->host_ip4_prefix.address,
9247                                            mp->host_ip4_prefix.len));
9248   vat_json_object_add_string_copy (node, "host_ip6_prefix",
9249                                    format (0, "%U/%d", format_ip6_address,
9250                                            mp->host_ip6_prefix.address,
9251                                            mp->host_ip6_prefix.len));
9252
9253 }
9254
9255 static int
9256 api_sw_interface_tap_v2_dump (vat_main_t * vam)
9257 {
9258   vl_api_sw_interface_tap_v2_dump_t *mp;
9259   vl_api_control_ping_t *mp_ping;
9260   int ret;
9261
9262   print (vam->ofp,
9263          "\n%-16s %-12s %-5s %-12s %-12s %-14s %-30s %-20s %-20s %-30s",
9264          "dev_name", "sw_if_index", "id", "rx_ring_sz", "tx_ring_sz",
9265          "host_mac_addr", "host_namespace", "host_bridge", "host_ip4_addr",
9266          "host_ip6_addr");
9267
9268   /* Get list of tap interfaces */
9269   M (SW_INTERFACE_TAP_V2_DUMP, mp);
9270   S (mp);
9271
9272   /* Use a control ping for synchronization */
9273   MPING (CONTROL_PING, mp_ping);
9274   S (mp_ping);
9275
9276   W (ret);
9277   return ret;
9278 }
9279
9280 static void vl_api_sw_interface_virtio_pci_details_t_handler
9281   (vl_api_sw_interface_virtio_pci_details_t * mp)
9282 {
9283   vat_main_t *vam = &vat_main;
9284
9285   typedef union
9286   {
9287     struct
9288     {
9289       u16 domain;
9290       u8 bus;
9291       u8 slot:5;
9292       u8 function:3;
9293     };
9294     u32 as_u32;
9295   } pci_addr_t;
9296   pci_addr_t addr;
9297
9298   addr.domain = ntohs (mp->pci_addr.domain);
9299   addr.bus = mp->pci_addr.bus;
9300   addr.slot = mp->pci_addr.slot;
9301   addr.function = mp->pci_addr.function;
9302
9303   u8 *pci_addr = format (0, "%04x:%02x:%02x.%x", addr.domain, addr.bus,
9304                          addr.slot, addr.function);
9305
9306   print (vam->ofp,
9307          "\n%-12s %-12d %-12d %-12d %-17U 0x%-08llx",
9308          pci_addr, ntohl (mp->sw_if_index),
9309          ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
9310          format_ethernet_address, mp->mac_addr,
9311          clib_net_to_host_u64 (mp->features));
9312   vec_free (pci_addr);
9313 }
9314
9315 static void vl_api_sw_interface_virtio_pci_details_t_handler_json
9316   (vl_api_sw_interface_virtio_pci_details_t * mp)
9317 {
9318   vat_main_t *vam = &vat_main;
9319   vat_json_node_t *node = NULL;
9320   vlib_pci_addr_t pci_addr;
9321
9322   if (VAT_JSON_ARRAY != vam->json_tree.type)
9323     {
9324       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9325       vat_json_init_array (&vam->json_tree);
9326     }
9327   node = vat_json_array_add (&vam->json_tree);
9328
9329   pci_addr.domain = ntohs (mp->pci_addr.domain);
9330   pci_addr.bus = mp->pci_addr.bus;
9331   pci_addr.slot = mp->pci_addr.slot;
9332   pci_addr.function = mp->pci_addr.function;
9333
9334   vat_json_init_object (node);
9335   vat_json_object_add_uint (node, "pci-addr", pci_addr.as_u32);
9336   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
9337   vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
9338   vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
9339   vat_json_object_add_uint (node, "features",
9340                             clib_net_to_host_u64 (mp->features));
9341   vat_json_object_add_string_copy (node, "mac_addr",
9342                                    format (0, "%U", format_ethernet_address,
9343                                            &mp->mac_addr));
9344 }
9345
9346 static int
9347 api_sw_interface_virtio_pci_dump (vat_main_t * vam)
9348 {
9349   vl_api_sw_interface_virtio_pci_dump_t *mp;
9350   vl_api_control_ping_t *mp_ping;
9351   int ret;
9352
9353   print (vam->ofp,
9354          "\n%-12s %-12s %-12s %-12s %-17s %-08s",
9355          "pci_addr", "sw_if_index", "rx_ring_sz", "tx_ring_sz",
9356          "mac_addr", "features");
9357
9358   /* Get list of tap interfaces */
9359   M (SW_INTERFACE_VIRTIO_PCI_DUMP, mp);
9360   S (mp);
9361
9362   /* Use a control ping for synchronization */
9363   MPING (CONTROL_PING, mp_ping);
9364   S (mp_ping);
9365
9366   W (ret);
9367   return ret;
9368 }
9369
9370 static int
9371 api_vxlan_offload_rx (vat_main_t * vam)
9372 {
9373   unformat_input_t *line_input = vam->input;
9374   vl_api_vxlan_offload_rx_t *mp;
9375   u32 hw_if_index = ~0, rx_if_index = ~0;
9376   u8 is_add = 1;
9377   int ret;
9378
9379   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
9380     {
9381       if (unformat (line_input, "del"))
9382         is_add = 0;
9383       else if (unformat (line_input, "hw %U", api_unformat_hw_if_index, vam,
9384                          &hw_if_index))
9385         ;
9386       else if (unformat (line_input, "hw hw_if_index %u", &hw_if_index))
9387         ;
9388       else if (unformat (line_input, "rx %U", api_unformat_sw_if_index, vam,
9389                          &rx_if_index))
9390         ;
9391       else if (unformat (line_input, "rx sw_if_index %u", &rx_if_index))
9392         ;
9393       else
9394         {
9395           errmsg ("parse error '%U'", format_unformat_error, line_input);
9396           return -99;
9397         }
9398     }
9399
9400   if (hw_if_index == ~0)
9401     {
9402       errmsg ("no hw interface");
9403       return -99;
9404     }
9405
9406   if (rx_if_index == ~0)
9407     {
9408       errmsg ("no rx tunnel");
9409       return -99;
9410     }
9411
9412   M (VXLAN_OFFLOAD_RX, mp);
9413
9414   mp->hw_if_index = ntohl (hw_if_index);
9415   mp->sw_if_index = ntohl (rx_if_index);
9416   mp->enable = is_add;
9417
9418   S (mp);
9419   W (ret);
9420   return ret;
9421 }
9422
9423 static uword unformat_vxlan_decap_next
9424   (unformat_input_t * input, va_list * args)
9425 {
9426   u32 *result = va_arg (*args, u32 *);
9427   u32 tmp;
9428
9429   if (unformat (input, "l2"))
9430     *result = VXLAN_INPUT_NEXT_L2_INPUT;
9431   else if (unformat (input, "%d", &tmp))
9432     *result = tmp;
9433   else
9434     return 0;
9435   return 1;
9436 }
9437
9438 static int
9439 api_vxlan_add_del_tunnel (vat_main_t * vam)
9440 {
9441   unformat_input_t *line_input = vam->input;
9442   vl_api_vxlan_add_del_tunnel_t *mp;
9443   ip46_address_t src, dst;
9444   u8 is_add = 1;
9445   u8 ipv4_set = 0, ipv6_set = 0;
9446   u8 src_set = 0;
9447   u8 dst_set = 0;
9448   u8 grp_set = 0;
9449   u32 instance = ~0;
9450   u32 mcast_sw_if_index = ~0;
9451   u32 encap_vrf_id = 0;
9452   u32 decap_next_index = ~0;
9453   u32 vni = 0;
9454   int ret;
9455
9456   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
9457   clib_memset (&src, 0, sizeof src);
9458   clib_memset (&dst, 0, sizeof dst);
9459
9460   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
9461     {
9462       if (unformat (line_input, "del"))
9463         is_add = 0;
9464       else if (unformat (line_input, "instance %d", &instance))
9465         ;
9466       else
9467         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
9468         {
9469           ipv4_set = 1;
9470           src_set = 1;
9471         }
9472       else
9473         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
9474         {
9475           ipv4_set = 1;
9476           dst_set = 1;
9477         }
9478       else
9479         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
9480         {
9481           ipv6_set = 1;
9482           src_set = 1;
9483         }
9484       else
9485         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
9486         {
9487           ipv6_set = 1;
9488           dst_set = 1;
9489         }
9490       else if (unformat (line_input, "group %U %U",
9491                          unformat_ip4_address, &dst.ip4,
9492                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
9493         {
9494           grp_set = dst_set = 1;
9495           ipv4_set = 1;
9496         }
9497       else if (unformat (line_input, "group %U",
9498                          unformat_ip4_address, &dst.ip4))
9499         {
9500           grp_set = dst_set = 1;
9501           ipv4_set = 1;
9502         }
9503       else if (unformat (line_input, "group %U %U",
9504                          unformat_ip6_address, &dst.ip6,
9505                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
9506         {
9507           grp_set = dst_set = 1;
9508           ipv6_set = 1;
9509         }
9510       else if (unformat (line_input, "group %U",
9511                          unformat_ip6_address, &dst.ip6))
9512         {
9513           grp_set = dst_set = 1;
9514           ipv6_set = 1;
9515         }
9516       else
9517         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
9518         ;
9519       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
9520         ;
9521       else if (unformat (line_input, "decap-next %U",
9522                          unformat_vxlan_decap_next, &decap_next_index))
9523         ;
9524       else if (unformat (line_input, "vni %d", &vni))
9525         ;
9526       else
9527         {
9528           errmsg ("parse error '%U'", format_unformat_error, line_input);
9529           return -99;
9530         }
9531     }
9532
9533   if (src_set == 0)
9534     {
9535       errmsg ("tunnel src address not specified");
9536       return -99;
9537     }
9538   if (dst_set == 0)
9539     {
9540       errmsg ("tunnel dst address not specified");
9541       return -99;
9542     }
9543
9544   if (grp_set && !ip46_address_is_multicast (&dst))
9545     {
9546       errmsg ("tunnel group address not multicast");
9547       return -99;
9548     }
9549   if (grp_set && mcast_sw_if_index == ~0)
9550     {
9551       errmsg ("tunnel nonexistent multicast device");
9552       return -99;
9553     }
9554   if (grp_set == 0 && ip46_address_is_multicast (&dst))
9555     {
9556       errmsg ("tunnel dst address must be unicast");
9557       return -99;
9558     }
9559
9560
9561   if (ipv4_set && ipv6_set)
9562     {
9563       errmsg ("both IPv4 and IPv6 addresses specified");
9564       return -99;
9565     }
9566
9567   if ((vni == 0) || (vni >> 24))
9568     {
9569       errmsg ("vni not specified or out of range");
9570       return -99;
9571     }
9572
9573   M (VXLAN_ADD_DEL_TUNNEL, mp);
9574
9575   if (ipv6_set)
9576     {
9577       clib_memcpy (mp->src_address.un.ip6, &src.ip6, sizeof (src.ip6));
9578       clib_memcpy (mp->dst_address.un.ip6, &dst.ip6, sizeof (dst.ip6));
9579     }
9580   else
9581     {
9582       clib_memcpy (mp->src_address.un.ip4, &src.ip4, sizeof (src.ip4));
9583       clib_memcpy (mp->dst_address.un.ip4, &dst.ip4, sizeof (dst.ip4));
9584     }
9585   mp->src_address.af = ipv6_set;
9586   mp->dst_address.af = ipv6_set;
9587
9588   mp->instance = htonl (instance);
9589   mp->encap_vrf_id = ntohl (encap_vrf_id);
9590   mp->decap_next_index = ntohl (decap_next_index);
9591   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
9592   mp->vni = ntohl (vni);
9593   mp->is_add = is_add;
9594
9595   S (mp);
9596   W (ret);
9597   return ret;
9598 }
9599
9600 static void vl_api_vxlan_tunnel_details_t_handler
9601   (vl_api_vxlan_tunnel_details_t * mp)
9602 {
9603   vat_main_t *vam = &vat_main;
9604   ip46_address_t src =
9605     to_ip46 (mp->dst_address.af, (u8 *) & mp->dst_address.un);
9606   ip46_address_t dst =
9607     to_ip46 (mp->dst_address.af, (u8 *) & mp->src_address.un);
9608
9609   print (vam->ofp, "%11d%11d%24U%24U%14d%18d%13d%19d",
9610          ntohl (mp->sw_if_index),
9611          ntohl (mp->instance),
9612          format_ip46_address, &src, IP46_TYPE_ANY,
9613          format_ip46_address, &dst, IP46_TYPE_ANY,
9614          ntohl (mp->encap_vrf_id),
9615          ntohl (mp->decap_next_index), ntohl (mp->vni),
9616          ntohl (mp->mcast_sw_if_index));
9617 }
9618
9619 static void vl_api_vxlan_tunnel_details_t_handler_json
9620   (vl_api_vxlan_tunnel_details_t * mp)
9621 {
9622   vat_main_t *vam = &vat_main;
9623   vat_json_node_t *node = NULL;
9624
9625   if (VAT_JSON_ARRAY != vam->json_tree.type)
9626     {
9627       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9628       vat_json_init_array (&vam->json_tree);
9629     }
9630   node = vat_json_array_add (&vam->json_tree);
9631
9632   vat_json_init_object (node);
9633   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
9634
9635   vat_json_object_add_uint (node, "instance", ntohl (mp->instance));
9636
9637   if (mp->src_address.af)
9638     {
9639       struct in6_addr ip6;
9640
9641       clib_memcpy (&ip6, mp->src_address.un.ip6, sizeof (ip6));
9642       vat_json_object_add_ip6 (node, "src_address", ip6);
9643       clib_memcpy (&ip6, mp->dst_address.un.ip6, sizeof (ip6));
9644       vat_json_object_add_ip6 (node, "dst_address", ip6);
9645     }
9646   else
9647     {
9648       struct in_addr ip4;
9649
9650       clib_memcpy (&ip4, mp->src_address.un.ip4, sizeof (ip4));
9651       vat_json_object_add_ip4 (node, "src_address", ip4);
9652       clib_memcpy (&ip4, mp->dst_address.un.ip4, sizeof (ip4));
9653       vat_json_object_add_ip4 (node, "dst_address", ip4);
9654     }
9655   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
9656   vat_json_object_add_uint (node, "decap_next_index",
9657                             ntohl (mp->decap_next_index));
9658   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
9659   vat_json_object_add_uint (node, "mcast_sw_if_index",
9660                             ntohl (mp->mcast_sw_if_index));
9661 }
9662
9663 static int
9664 api_vxlan_tunnel_dump (vat_main_t * vam)
9665 {
9666   unformat_input_t *i = vam->input;
9667   vl_api_vxlan_tunnel_dump_t *mp;
9668   vl_api_control_ping_t *mp_ping;
9669   u32 sw_if_index;
9670   u8 sw_if_index_set = 0;
9671   int ret;
9672
9673   /* Parse args required to build the message */
9674   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9675     {
9676       if (unformat (i, "sw_if_index %d", &sw_if_index))
9677         sw_if_index_set = 1;
9678       else
9679         break;
9680     }
9681
9682   if (sw_if_index_set == 0)
9683     {
9684       sw_if_index = ~0;
9685     }
9686
9687   if (!vam->json_output)
9688     {
9689       print (vam->ofp, "%11s%11s%24s%24s%14s%18s%13s%19s",
9690              "sw_if_index", "instance", "src_address", "dst_address",
9691              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
9692     }
9693
9694   /* Get list of vxlan-tunnel interfaces */
9695   M (VXLAN_TUNNEL_DUMP, mp);
9696
9697   mp->sw_if_index = htonl (sw_if_index);
9698
9699   S (mp);
9700
9701   /* Use a control ping for synchronization */
9702   MPING (CONTROL_PING, mp_ping);
9703   S (mp_ping);
9704
9705   W (ret);
9706   return ret;
9707 }
9708
9709 static int
9710 api_l2_fib_clear_table (vat_main_t * vam)
9711 {
9712 //  unformat_input_t * i = vam->input;
9713   vl_api_l2_fib_clear_table_t *mp;
9714   int ret;
9715
9716   M (L2_FIB_CLEAR_TABLE, mp);
9717
9718   S (mp);
9719   W (ret);
9720   return ret;
9721 }
9722
9723 static int
9724 api_l2_interface_efp_filter (vat_main_t * vam)
9725 {
9726   unformat_input_t *i = vam->input;
9727   vl_api_l2_interface_efp_filter_t *mp;
9728   u32 sw_if_index;
9729   u8 enable = 1;
9730   u8 sw_if_index_set = 0;
9731   int ret;
9732
9733   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9734     {
9735       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9736         sw_if_index_set = 1;
9737       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9738         sw_if_index_set = 1;
9739       else if (unformat (i, "enable"))
9740         enable = 1;
9741       else if (unformat (i, "disable"))
9742         enable = 0;
9743       else
9744         {
9745           clib_warning ("parse error '%U'", format_unformat_error, i);
9746           return -99;
9747         }
9748     }
9749
9750   if (sw_if_index_set == 0)
9751     {
9752       errmsg ("missing sw_if_index");
9753       return -99;
9754     }
9755
9756   M (L2_INTERFACE_EFP_FILTER, mp);
9757
9758   mp->sw_if_index = ntohl (sw_if_index);
9759   mp->enable_disable = enable;
9760
9761   S (mp);
9762   W (ret);
9763   return ret;
9764 }
9765
9766 #define foreach_vtr_op                          \
9767 _("disable",  L2_VTR_DISABLED)                  \
9768 _("push-1",  L2_VTR_PUSH_1)                     \
9769 _("push-2",  L2_VTR_PUSH_2)                     \
9770 _("pop-1",  L2_VTR_POP_1)                       \
9771 _("pop-2",  L2_VTR_POP_2)                       \
9772 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
9773 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
9774 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
9775 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
9776
9777 static int
9778 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
9779 {
9780   unformat_input_t *i = vam->input;
9781   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
9782   u32 sw_if_index;
9783   u8 sw_if_index_set = 0;
9784   u8 vtr_op_set = 0;
9785   u32 vtr_op = 0;
9786   u32 push_dot1q = 1;
9787   u32 tag1 = ~0;
9788   u32 tag2 = ~0;
9789   int ret;
9790
9791   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9792     {
9793       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9794         sw_if_index_set = 1;
9795       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9796         sw_if_index_set = 1;
9797       else if (unformat (i, "vtr_op %d", &vtr_op))
9798         vtr_op_set = 1;
9799 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
9800       foreach_vtr_op
9801 #undef _
9802         else if (unformat (i, "push_dot1q %d", &push_dot1q))
9803         ;
9804       else if (unformat (i, "tag1 %d", &tag1))
9805         ;
9806       else if (unformat (i, "tag2 %d", &tag2))
9807         ;
9808       else
9809         {
9810           clib_warning ("parse error '%U'", format_unformat_error, i);
9811           return -99;
9812         }
9813     }
9814
9815   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
9816     {
9817       errmsg ("missing vtr operation or sw_if_index");
9818       return -99;
9819     }
9820
9821   M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
9822   mp->sw_if_index = ntohl (sw_if_index);
9823   mp->vtr_op = ntohl (vtr_op);
9824   mp->push_dot1q = ntohl (push_dot1q);
9825   mp->tag1 = ntohl (tag1);
9826   mp->tag2 = ntohl (tag2);
9827
9828   S (mp);
9829   W (ret);
9830   return ret;
9831 }
9832
9833 static int
9834 api_create_vhost_user_if (vat_main_t * vam)
9835 {
9836   unformat_input_t *i = vam->input;
9837   vl_api_create_vhost_user_if_t *mp;
9838   u8 *file_name;
9839   u8 is_server = 0;
9840   u8 file_name_set = 0;
9841   u32 custom_dev_instance = ~0;
9842   u8 hwaddr[6];
9843   u8 use_custom_mac = 0;
9844   u8 disable_mrg_rxbuf = 0;
9845   u8 disable_indirect_desc = 0;
9846   u8 *tag = 0;
9847   u8 enable_gso = 0;
9848   u8 enable_packed = 0;
9849   int ret;
9850
9851   /* Shut up coverity */
9852   clib_memset (hwaddr, 0, sizeof (hwaddr));
9853
9854   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9855     {
9856       if (unformat (i, "socket %s", &file_name))
9857         {
9858           file_name_set = 1;
9859         }
9860       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
9861         ;
9862       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
9863         use_custom_mac = 1;
9864       else if (unformat (i, "server"))
9865         is_server = 1;
9866       else if (unformat (i, "disable_mrg_rxbuf"))
9867         disable_mrg_rxbuf = 1;
9868       else if (unformat (i, "disable_indirect_desc"))
9869         disable_indirect_desc = 1;
9870       else if (unformat (i, "gso"))
9871         enable_gso = 1;
9872       else if (unformat (i, "packed"))
9873         enable_packed = 1;
9874       else if (unformat (i, "tag %s", &tag))
9875         ;
9876       else
9877         break;
9878     }
9879
9880   if (file_name_set == 0)
9881     {
9882       errmsg ("missing socket file name");
9883       return -99;
9884     }
9885
9886   if (vec_len (file_name) > 255)
9887     {
9888       errmsg ("socket file name too long");
9889       return -99;
9890     }
9891   vec_add1 (file_name, 0);
9892
9893   M (CREATE_VHOST_USER_IF, mp);
9894
9895   mp->is_server = is_server;
9896   mp->disable_mrg_rxbuf = disable_mrg_rxbuf;
9897   mp->disable_indirect_desc = disable_indirect_desc;
9898   mp->enable_gso = enable_gso;
9899   mp->enable_packed = enable_packed;
9900   mp->custom_dev_instance = ntohl (custom_dev_instance);
9901   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
9902   vec_free (file_name);
9903   if (custom_dev_instance != ~0)
9904     mp->renumber = 1;
9905
9906   mp->use_custom_mac = use_custom_mac;
9907   clib_memcpy (mp->mac_address, hwaddr, 6);
9908   if (tag)
9909     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
9910   vec_free (tag);
9911
9912   S (mp);
9913   W (ret);
9914   return ret;
9915 }
9916
9917 static int
9918 api_modify_vhost_user_if (vat_main_t * vam)
9919 {
9920   unformat_input_t *i = vam->input;
9921   vl_api_modify_vhost_user_if_t *mp;
9922   u8 *file_name;
9923   u8 is_server = 0;
9924   u8 file_name_set = 0;
9925   u32 custom_dev_instance = ~0;
9926   u8 sw_if_index_set = 0;
9927   u32 sw_if_index = (u32) ~ 0;
9928   u8 enable_gso = 0;
9929   u8 enable_packed = 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
9951         break;
9952     }
9953
9954   if (sw_if_index_set == 0)
9955     {
9956       errmsg ("missing sw_if_index or interface name");
9957       return -99;
9958     }
9959
9960   if (file_name_set == 0)
9961     {
9962       errmsg ("missing socket file name");
9963       return -99;
9964     }
9965
9966   if (vec_len (file_name) > 255)
9967     {
9968       errmsg ("socket file name too long");
9969       return -99;
9970     }
9971   vec_add1 (file_name, 0);
9972
9973   M (MODIFY_VHOST_USER_IF, mp);
9974
9975   mp->sw_if_index = ntohl (sw_if_index);
9976   mp->is_server = is_server;
9977   mp->enable_gso = enable_gso;
9978   mp->enable_packed = enable_packed;
9979   mp->custom_dev_instance = ntohl (custom_dev_instance);
9980   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
9981   vec_free (file_name);
9982   if (custom_dev_instance != ~0)
9983     mp->renumber = 1;
9984
9985   S (mp);
9986   W (ret);
9987   return ret;
9988 }
9989
9990 static int
9991 api_create_vhost_user_if_v2 (vat_main_t * vam)
9992 {
9993   unformat_input_t *i = vam->input;
9994   vl_api_create_vhost_user_if_v2_t *mp;
9995   u8 *file_name;
9996   u8 is_server = 0;
9997   u8 file_name_set = 0;
9998   u32 custom_dev_instance = ~0;
9999   u8 hwaddr[6];
10000   u8 use_custom_mac = 0;
10001   u8 disable_mrg_rxbuf = 0;
10002   u8 disable_indirect_desc = 0;
10003   u8 *tag = 0;
10004   u8 enable_gso = 0;
10005   u8 enable_packed = 0;
10006   u8 enable_event_idx = 0;
10007   int ret;
10008
10009   /* Shut up coverity */
10010   clib_memset (hwaddr, 0, sizeof (hwaddr));
10011
10012   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10013     {
10014       if (unformat (i, "socket %s", &file_name))
10015         {
10016           file_name_set = 1;
10017         }
10018       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
10019         ;
10020       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
10021         use_custom_mac = 1;
10022       else if (unformat (i, "server"))
10023         is_server = 1;
10024       else if (unformat (i, "disable_mrg_rxbuf"))
10025         disable_mrg_rxbuf = 1;
10026       else if (unformat (i, "disable_indirect_desc"))
10027         disable_indirect_desc = 1;
10028       else if (unformat (i, "gso"))
10029         enable_gso = 1;
10030       else if (unformat (i, "packed"))
10031         enable_packed = 1;
10032       else if (unformat (i, "event-idx"))
10033         enable_event_idx = 1;
10034       else if (unformat (i, "tag %s", &tag))
10035         ;
10036       else
10037         break;
10038     }
10039
10040   if (file_name_set == 0)
10041     {
10042       errmsg ("missing socket file name");
10043       return -99;
10044     }
10045
10046   if (vec_len (file_name) > 255)
10047     {
10048       errmsg ("socket file name too long");
10049       return -99;
10050     }
10051   vec_add1 (file_name, 0);
10052
10053   M (CREATE_VHOST_USER_IF_V2, mp);
10054
10055   mp->is_server = is_server;
10056   mp->disable_mrg_rxbuf = disable_mrg_rxbuf;
10057   mp->disable_indirect_desc = disable_indirect_desc;
10058   mp->enable_gso = enable_gso;
10059   mp->enable_packed = enable_packed;
10060   mp->enable_event_idx = enable_event_idx;
10061   mp->custom_dev_instance = ntohl (custom_dev_instance);
10062   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
10063   vec_free (file_name);
10064   if (custom_dev_instance != ~0)
10065     mp->renumber = 1;
10066
10067   mp->use_custom_mac = use_custom_mac;
10068   clib_memcpy (mp->mac_address, hwaddr, 6);
10069   if (tag)
10070     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
10071   vec_free (tag);
10072
10073   S (mp);
10074   W (ret);
10075   return ret;
10076 }
10077
10078 static int
10079 api_modify_vhost_user_if_v2 (vat_main_t * vam)
10080 {
10081   unformat_input_t *i = vam->input;
10082   vl_api_modify_vhost_user_if_v2_t *mp;
10083   u8 *file_name;
10084   u8 is_server = 0;
10085   u8 file_name_set = 0;
10086   u32 custom_dev_instance = ~0;
10087   u8 sw_if_index_set = 0;
10088   u32 sw_if_index = (u32) ~ 0;
10089   u8 enable_gso = 0;
10090   u8 enable_packed = 0;
10091   u8 enable_event_idx = 0;
10092   int ret;
10093
10094   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10095     {
10096       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10097         sw_if_index_set = 1;
10098       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10099         sw_if_index_set = 1;
10100       else if (unformat (i, "socket %s", &file_name))
10101         {
10102           file_name_set = 1;
10103         }
10104       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
10105         ;
10106       else if (unformat (i, "server"))
10107         is_server = 1;
10108       else if (unformat (i, "gso"))
10109         enable_gso = 1;
10110       else if (unformat (i, "packed"))
10111         enable_packed = 1;
10112       else if (unformat (i, "event-idx"))
10113         enable_event_idx = 1;
10114       else
10115         break;
10116     }
10117
10118   if (sw_if_index_set == 0)
10119     {
10120       errmsg ("missing sw_if_index or interface name");
10121       return -99;
10122     }
10123
10124   if (file_name_set == 0)
10125     {
10126       errmsg ("missing socket file name");
10127       return -99;
10128     }
10129
10130   if (vec_len (file_name) > 255)
10131     {
10132       errmsg ("socket file name too long");
10133       return -99;
10134     }
10135   vec_add1 (file_name, 0);
10136
10137   M (MODIFY_VHOST_USER_IF_V2, mp);
10138
10139   mp->sw_if_index = ntohl (sw_if_index);
10140   mp->is_server = is_server;
10141   mp->enable_gso = enable_gso;
10142   mp->enable_packed = enable_packed;
10143   mp->enable_event_idx = enable_event_idx;
10144   mp->custom_dev_instance = ntohl (custom_dev_instance);
10145   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
10146   vec_free (file_name);
10147   if (custom_dev_instance != ~0)
10148     mp->renumber = 1;
10149
10150   S (mp);
10151   W (ret);
10152   return ret;
10153 }
10154
10155 static int
10156 api_delete_vhost_user_if (vat_main_t * vam)
10157 {
10158   unformat_input_t *i = vam->input;
10159   vl_api_delete_vhost_user_if_t *mp;
10160   u32 sw_if_index = ~0;
10161   u8 sw_if_index_set = 0;
10162   int ret;
10163
10164   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10165     {
10166       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10167         sw_if_index_set = 1;
10168       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10169         sw_if_index_set = 1;
10170       else
10171         break;
10172     }
10173
10174   if (sw_if_index_set == 0)
10175     {
10176       errmsg ("missing sw_if_index or interface name");
10177       return -99;
10178     }
10179
10180
10181   M (DELETE_VHOST_USER_IF, mp);
10182
10183   mp->sw_if_index = ntohl (sw_if_index);
10184
10185   S (mp);
10186   W (ret);
10187   return ret;
10188 }
10189
10190 static void vl_api_sw_interface_vhost_user_details_t_handler
10191   (vl_api_sw_interface_vhost_user_details_t * mp)
10192 {
10193   vat_main_t *vam = &vat_main;
10194   u64 features;
10195
10196   features =
10197     clib_net_to_host_u32 (mp->features_first_32) | ((u64)
10198                                                     clib_net_to_host_u32
10199                                                     (mp->features_last_32) <<
10200                                                     32);
10201
10202   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s",
10203          (char *) mp->interface_name,
10204          ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
10205          features, mp->is_server,
10206          ntohl (mp->num_regions), (char *) mp->sock_filename);
10207   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
10208 }
10209
10210 static void vl_api_sw_interface_vhost_user_details_t_handler_json
10211   (vl_api_sw_interface_vhost_user_details_t * mp)
10212 {
10213   vat_main_t *vam = &vat_main;
10214   vat_json_node_t *node = NULL;
10215
10216   if (VAT_JSON_ARRAY != vam->json_tree.type)
10217     {
10218       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10219       vat_json_init_array (&vam->json_tree);
10220     }
10221   node = vat_json_array_add (&vam->json_tree);
10222
10223   vat_json_init_object (node);
10224   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10225   vat_json_object_add_string_copy (node, "interface_name",
10226                                    mp->interface_name);
10227   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
10228                             ntohl (mp->virtio_net_hdr_sz));
10229   vat_json_object_add_uint (node, "features_first_32",
10230                             clib_net_to_host_u32 (mp->features_first_32));
10231   vat_json_object_add_uint (node, "features_last_32",
10232                             clib_net_to_host_u32 (mp->features_last_32));
10233   vat_json_object_add_uint (node, "is_server", mp->is_server);
10234   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
10235   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
10236   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
10237 }
10238
10239 static int
10240 api_sw_interface_vhost_user_dump (vat_main_t * vam)
10241 {
10242   unformat_input_t *i = vam->input;
10243   vl_api_sw_interface_vhost_user_dump_t *mp;
10244   vl_api_control_ping_t *mp_ping;
10245   int ret;
10246   u32 sw_if_index = ~0;
10247
10248   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10249     {
10250       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10251         ;
10252       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10253         ;
10254       else
10255         break;
10256     }
10257
10258   print (vam->ofp,
10259          "Interface name            idx hdr_sz features server regions filename");
10260
10261   /* Get list of vhost-user interfaces */
10262   M (SW_INTERFACE_VHOST_USER_DUMP, mp);
10263   mp->sw_if_index = ntohl (sw_if_index);
10264   S (mp);
10265
10266   /* Use a control ping for synchronization */
10267   MPING (CONTROL_PING, mp_ping);
10268   S (mp_ping);
10269
10270   W (ret);
10271   return ret;
10272 }
10273
10274 static int
10275 api_show_version (vat_main_t * vam)
10276 {
10277   vl_api_show_version_t *mp;
10278   int ret;
10279
10280   M (SHOW_VERSION, mp);
10281
10282   S (mp);
10283   W (ret);
10284   return ret;
10285 }
10286
10287
10288 static int
10289 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
10290 {
10291   unformat_input_t *line_input = vam->input;
10292   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
10293   ip46_address_t local, remote;
10294   u8 is_add = 1;
10295   u8 local_set = 0;
10296   u8 remote_set = 0;
10297   u8 grp_set = 0;
10298   u32 mcast_sw_if_index = ~0;
10299   u32 encap_vrf_id = 0;
10300   u32 decap_vrf_id = 0;
10301   u8 protocol = ~0;
10302   u32 vni;
10303   u8 vni_set = 0;
10304   int ret;
10305
10306   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10307     {
10308       if (unformat (line_input, "del"))
10309         is_add = 0;
10310       else if (unformat (line_input, "local %U",
10311                          unformat_ip46_address, &local))
10312         {
10313           local_set = 1;
10314         }
10315       else if (unformat (line_input, "remote %U",
10316                          unformat_ip46_address, &remote))
10317         {
10318           remote_set = 1;
10319         }
10320       else if (unformat (line_input, "group %U %U",
10321                          unformat_ip46_address, &remote,
10322                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
10323         {
10324           grp_set = remote_set = 1;
10325         }
10326       else if (unformat (line_input, "group %U",
10327                          unformat_ip46_address, &remote))
10328         {
10329           grp_set = remote_set = 1;
10330         }
10331       else
10332         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
10333         ;
10334       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
10335         ;
10336       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
10337         ;
10338       else if (unformat (line_input, "vni %d", &vni))
10339         vni_set = 1;
10340       else if (unformat (line_input, "next-ip4"))
10341         protocol = 1;
10342       else if (unformat (line_input, "next-ip6"))
10343         protocol = 2;
10344       else if (unformat (line_input, "next-ethernet"))
10345         protocol = 3;
10346       else if (unformat (line_input, "next-nsh"))
10347         protocol = 4;
10348       else
10349         {
10350           errmsg ("parse error '%U'", format_unformat_error, line_input);
10351           return -99;
10352         }
10353     }
10354
10355   if (local_set == 0)
10356     {
10357       errmsg ("tunnel local address not specified");
10358       return -99;
10359     }
10360   if (remote_set == 0)
10361     {
10362       errmsg ("tunnel remote address not specified");
10363       return -99;
10364     }
10365   if (grp_set && mcast_sw_if_index == ~0)
10366     {
10367       errmsg ("tunnel nonexistent multicast device");
10368       return -99;
10369     }
10370   if (ip46_address_is_ip4 (&local) != ip46_address_is_ip4 (&remote))
10371     {
10372       errmsg ("both IPv4 and IPv6 addresses specified");
10373       return -99;
10374     }
10375
10376   if (vni_set == 0)
10377     {
10378       errmsg ("vni not specified");
10379       return -99;
10380     }
10381
10382   M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
10383
10384   ip_address_encode (&local,
10385                      ip46_address_is_ip4 (&local) ? IP46_TYPE_IP4 :
10386                      IP46_TYPE_IP6, &mp->local);
10387   ip_address_encode (&remote,
10388                      ip46_address_is_ip4 (&remote) ? IP46_TYPE_IP4 :
10389                      IP46_TYPE_IP6, &mp->remote);
10390
10391   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
10392   mp->encap_vrf_id = ntohl (encap_vrf_id);
10393   mp->decap_vrf_id = ntohl (decap_vrf_id);
10394   mp->protocol = protocol;
10395   mp->vni = ntohl (vni);
10396   mp->is_add = is_add;
10397
10398   S (mp);
10399   W (ret);
10400   return ret;
10401 }
10402
10403 static void vl_api_vxlan_gpe_tunnel_details_t_handler
10404   (vl_api_vxlan_gpe_tunnel_details_t * mp)
10405 {
10406   vat_main_t *vam = &vat_main;
10407   ip46_address_t local, remote;
10408
10409   ip_address_decode (&mp->local, &local);
10410   ip_address_decode (&mp->remote, &remote);
10411
10412   print (vam->ofp, "%11d%24U%24U%13d%12d%19d%14d%14d",
10413          ntohl (mp->sw_if_index),
10414          format_ip46_address, &local, IP46_TYPE_ANY,
10415          format_ip46_address, &remote, IP46_TYPE_ANY,
10416          ntohl (mp->vni), mp->protocol,
10417          ntohl (mp->mcast_sw_if_index),
10418          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
10419 }
10420
10421
10422 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
10423   (vl_api_vxlan_gpe_tunnel_details_t * mp)
10424 {
10425   vat_main_t *vam = &vat_main;
10426   vat_json_node_t *node = NULL;
10427   struct in_addr ip4;
10428   struct in6_addr ip6;
10429   ip46_address_t local, remote;
10430
10431   ip_address_decode (&mp->local, &local);
10432   ip_address_decode (&mp->remote, &remote);
10433
10434   if (VAT_JSON_ARRAY != vam->json_tree.type)
10435     {
10436       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10437       vat_json_init_array (&vam->json_tree);
10438     }
10439   node = vat_json_array_add (&vam->json_tree);
10440
10441   vat_json_init_object (node);
10442   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10443   if (ip46_address_is_ip4 (&local))
10444     {
10445       clib_memcpy (&ip4, &local.ip4, sizeof (ip4));
10446       vat_json_object_add_ip4 (node, "local", ip4);
10447       clib_memcpy (&ip4, &remote.ip4, sizeof (ip4));
10448       vat_json_object_add_ip4 (node, "remote", ip4);
10449     }
10450   else
10451     {
10452       clib_memcpy (&ip6, &local.ip6, sizeof (ip6));
10453       vat_json_object_add_ip6 (node, "local", ip6);
10454       clib_memcpy (&ip6, &remote.ip6, sizeof (ip6));
10455       vat_json_object_add_ip6 (node, "remote", ip6);
10456     }
10457   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
10458   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
10459   vat_json_object_add_uint (node, "mcast_sw_if_index",
10460                             ntohl (mp->mcast_sw_if_index));
10461   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
10462   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
10463   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
10464 }
10465
10466 static int
10467 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
10468 {
10469   unformat_input_t *i = vam->input;
10470   vl_api_vxlan_gpe_tunnel_dump_t *mp;
10471   vl_api_control_ping_t *mp_ping;
10472   u32 sw_if_index;
10473   u8 sw_if_index_set = 0;
10474   int ret;
10475
10476   /* Parse args required to build the message */
10477   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10478     {
10479       if (unformat (i, "sw_if_index %d", &sw_if_index))
10480         sw_if_index_set = 1;
10481       else
10482         break;
10483     }
10484
10485   if (sw_if_index_set == 0)
10486     {
10487       sw_if_index = ~0;
10488     }
10489
10490   if (!vam->json_output)
10491     {
10492       print (vam->ofp, "%11s%24s%24s%13s%15s%19s%14s%14s",
10493              "sw_if_index", "local", "remote", "vni",
10494              "protocol", "mcast_sw_if_index", "encap_vrf_id", "decap_vrf_id");
10495     }
10496
10497   /* Get list of vxlan-tunnel interfaces */
10498   M (VXLAN_GPE_TUNNEL_DUMP, mp);
10499
10500   mp->sw_if_index = htonl (sw_if_index);
10501
10502   S (mp);
10503
10504   /* Use a control ping for synchronization */
10505   MPING (CONTROL_PING, mp_ping);
10506   S (mp_ping);
10507
10508   W (ret);
10509   return ret;
10510 }
10511
10512 static void vl_api_l2_fib_table_details_t_handler
10513   (vl_api_l2_fib_table_details_t * mp)
10514 {
10515   vat_main_t *vam = &vat_main;
10516
10517   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
10518          "       %d       %d     %d",
10519          ntohl (mp->bd_id), format_ethernet_address, mp->mac,
10520          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
10521          mp->bvi_mac);
10522 }
10523
10524 static void vl_api_l2_fib_table_details_t_handler_json
10525   (vl_api_l2_fib_table_details_t * mp)
10526 {
10527   vat_main_t *vam = &vat_main;
10528   vat_json_node_t *node = NULL;
10529
10530   if (VAT_JSON_ARRAY != vam->json_tree.type)
10531     {
10532       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10533       vat_json_init_array (&vam->json_tree);
10534     }
10535   node = vat_json_array_add (&vam->json_tree);
10536
10537   vat_json_init_object (node);
10538   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
10539   vat_json_object_add_bytes (node, "mac", mp->mac, 6);
10540   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10541   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
10542   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
10543   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
10544 }
10545
10546 static int
10547 api_l2_fib_table_dump (vat_main_t * vam)
10548 {
10549   unformat_input_t *i = vam->input;
10550   vl_api_l2_fib_table_dump_t *mp;
10551   vl_api_control_ping_t *mp_ping;
10552   u32 bd_id;
10553   u8 bd_id_set = 0;
10554   int ret;
10555
10556   /* Parse args required to build the message */
10557   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10558     {
10559       if (unformat (i, "bd_id %d", &bd_id))
10560         bd_id_set = 1;
10561       else
10562         break;
10563     }
10564
10565   if (bd_id_set == 0)
10566     {
10567       errmsg ("missing bridge domain");
10568       return -99;
10569     }
10570
10571   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
10572
10573   /* Get list of l2 fib entries */
10574   M (L2_FIB_TABLE_DUMP, mp);
10575
10576   mp->bd_id = ntohl (bd_id);
10577   S (mp);
10578
10579   /* Use a control ping for synchronization */
10580   MPING (CONTROL_PING, mp_ping);
10581   S (mp_ping);
10582
10583   W (ret);
10584   return ret;
10585 }
10586
10587
10588 static int
10589 api_interface_name_renumber (vat_main_t * vam)
10590 {
10591   unformat_input_t *line_input = vam->input;
10592   vl_api_interface_name_renumber_t *mp;
10593   u32 sw_if_index = ~0;
10594   u32 new_show_dev_instance = ~0;
10595   int ret;
10596
10597   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10598     {
10599       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
10600                     &sw_if_index))
10601         ;
10602       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
10603         ;
10604       else if (unformat (line_input, "new_show_dev_instance %d",
10605                          &new_show_dev_instance))
10606         ;
10607       else
10608         break;
10609     }
10610
10611   if (sw_if_index == ~0)
10612     {
10613       errmsg ("missing interface name or sw_if_index");
10614       return -99;
10615     }
10616
10617   if (new_show_dev_instance == ~0)
10618     {
10619       errmsg ("missing new_show_dev_instance");
10620       return -99;
10621     }
10622
10623   M (INTERFACE_NAME_RENUMBER, mp);
10624
10625   mp->sw_if_index = ntohl (sw_if_index);
10626   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
10627
10628   S (mp);
10629   W (ret);
10630   return ret;
10631 }
10632
10633 static int
10634 api_want_l2_macs_events (vat_main_t * vam)
10635 {
10636   unformat_input_t *line_input = vam->input;
10637   vl_api_want_l2_macs_events_t *mp;
10638   u8 enable_disable = 1;
10639   u32 scan_delay = 0;
10640   u32 max_macs_in_event = 0;
10641   u32 learn_limit = 0;
10642   int ret;
10643
10644   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10645     {
10646       if (unformat (line_input, "learn-limit %d", &learn_limit))
10647         ;
10648       else if (unformat (line_input, "scan-delay %d", &scan_delay))
10649         ;
10650       else if (unformat (line_input, "max-entries %d", &max_macs_in_event))
10651         ;
10652       else if (unformat (line_input, "disable"))
10653         enable_disable = 0;
10654       else
10655         break;
10656     }
10657
10658   M (WANT_L2_MACS_EVENTS, mp);
10659   mp->enable_disable = enable_disable;
10660   mp->pid = htonl (getpid ());
10661   mp->learn_limit = htonl (learn_limit);
10662   mp->scan_delay = (u8) scan_delay;
10663   mp->max_macs_in_event = (u8) (max_macs_in_event / 10);
10664   S (mp);
10665   W (ret);
10666   return ret;
10667 }
10668
10669 static int
10670 api_input_acl_set_interface (vat_main_t * vam)
10671 {
10672   unformat_input_t *i = vam->input;
10673   vl_api_input_acl_set_interface_t *mp;
10674   u32 sw_if_index;
10675   int sw_if_index_set;
10676   u32 ip4_table_index = ~0;
10677   u32 ip6_table_index = ~0;
10678   u32 l2_table_index = ~0;
10679   u8 is_add = 1;
10680   int ret;
10681
10682   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10683     {
10684       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10685         sw_if_index_set = 1;
10686       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10687         sw_if_index_set = 1;
10688       else if (unformat (i, "del"))
10689         is_add = 0;
10690       else if (unformat (i, "ip4-table %d", &ip4_table_index))
10691         ;
10692       else if (unformat (i, "ip6-table %d", &ip6_table_index))
10693         ;
10694       else if (unformat (i, "l2-table %d", &l2_table_index))
10695         ;
10696       else
10697         {
10698           clib_warning ("parse error '%U'", format_unformat_error, i);
10699           return -99;
10700         }
10701     }
10702
10703   if (sw_if_index_set == 0)
10704     {
10705       errmsg ("missing interface name or sw_if_index");
10706       return -99;
10707     }
10708
10709   M (INPUT_ACL_SET_INTERFACE, mp);
10710
10711   mp->sw_if_index = ntohl (sw_if_index);
10712   mp->ip4_table_index = ntohl (ip4_table_index);
10713   mp->ip6_table_index = ntohl (ip6_table_index);
10714   mp->l2_table_index = ntohl (l2_table_index);
10715   mp->is_add = is_add;
10716
10717   S (mp);
10718   W (ret);
10719   return ret;
10720 }
10721
10722 static int
10723 api_output_acl_set_interface (vat_main_t * vam)
10724 {
10725   unformat_input_t *i = vam->input;
10726   vl_api_output_acl_set_interface_t *mp;
10727   u32 sw_if_index;
10728   int sw_if_index_set;
10729   u32 ip4_table_index = ~0;
10730   u32 ip6_table_index = ~0;
10731   u32 l2_table_index = ~0;
10732   u8 is_add = 1;
10733   int ret;
10734
10735   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10736     {
10737       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10738         sw_if_index_set = 1;
10739       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10740         sw_if_index_set = 1;
10741       else if (unformat (i, "del"))
10742         is_add = 0;
10743       else if (unformat (i, "ip4-table %d", &ip4_table_index))
10744         ;
10745       else if (unformat (i, "ip6-table %d", &ip6_table_index))
10746         ;
10747       else if (unformat (i, "l2-table %d", &l2_table_index))
10748         ;
10749       else
10750         {
10751           clib_warning ("parse error '%U'", format_unformat_error, i);
10752           return -99;
10753         }
10754     }
10755
10756   if (sw_if_index_set == 0)
10757     {
10758       errmsg ("missing interface name or sw_if_index");
10759       return -99;
10760     }
10761
10762   M (OUTPUT_ACL_SET_INTERFACE, mp);
10763
10764   mp->sw_if_index = ntohl (sw_if_index);
10765   mp->ip4_table_index = ntohl (ip4_table_index);
10766   mp->ip6_table_index = ntohl (ip6_table_index);
10767   mp->l2_table_index = ntohl (l2_table_index);
10768   mp->is_add = is_add;
10769
10770   S (mp);
10771   W (ret);
10772   return ret;
10773 }
10774
10775 static int
10776 api_ip_address_dump (vat_main_t * vam)
10777 {
10778   unformat_input_t *i = vam->input;
10779   vl_api_ip_address_dump_t *mp;
10780   vl_api_control_ping_t *mp_ping;
10781   u32 sw_if_index = ~0;
10782   u8 sw_if_index_set = 0;
10783   u8 ipv4_set = 0;
10784   u8 ipv6_set = 0;
10785   int ret;
10786
10787   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10788     {
10789       if (unformat (i, "sw_if_index %d", &sw_if_index))
10790         sw_if_index_set = 1;
10791       else
10792         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10793         sw_if_index_set = 1;
10794       else if (unformat (i, "ipv4"))
10795         ipv4_set = 1;
10796       else if (unformat (i, "ipv6"))
10797         ipv6_set = 1;
10798       else
10799         break;
10800     }
10801
10802   if (ipv4_set && ipv6_set)
10803     {
10804       errmsg ("ipv4 and ipv6 flags cannot be both set");
10805       return -99;
10806     }
10807
10808   if ((!ipv4_set) && (!ipv6_set))
10809     {
10810       errmsg ("no ipv4 nor ipv6 flag set");
10811       return -99;
10812     }
10813
10814   if (sw_if_index_set == 0)
10815     {
10816       errmsg ("missing interface name or sw_if_index");
10817       return -99;
10818     }
10819
10820   vam->current_sw_if_index = sw_if_index;
10821   vam->is_ipv6 = ipv6_set;
10822
10823   M (IP_ADDRESS_DUMP, mp);
10824   mp->sw_if_index = ntohl (sw_if_index);
10825   mp->is_ipv6 = ipv6_set;
10826   S (mp);
10827
10828   /* Use a control ping for synchronization */
10829   MPING (CONTROL_PING, mp_ping);
10830   S (mp_ping);
10831
10832   W (ret);
10833   return ret;
10834 }
10835
10836 static int
10837 api_ip_dump (vat_main_t * vam)
10838 {
10839   vl_api_ip_dump_t *mp;
10840   vl_api_control_ping_t *mp_ping;
10841   unformat_input_t *in = vam->input;
10842   int ipv4_set = 0;
10843   int ipv6_set = 0;
10844   int is_ipv6;
10845   int i;
10846   int ret;
10847
10848   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
10849     {
10850       if (unformat (in, "ipv4"))
10851         ipv4_set = 1;
10852       else if (unformat (in, "ipv6"))
10853         ipv6_set = 1;
10854       else
10855         break;
10856     }
10857
10858   if (ipv4_set && ipv6_set)
10859     {
10860       errmsg ("ipv4 and ipv6 flags cannot be both set");
10861       return -99;
10862     }
10863
10864   if ((!ipv4_set) && (!ipv6_set))
10865     {
10866       errmsg ("no ipv4 nor ipv6 flag set");
10867       return -99;
10868     }
10869
10870   is_ipv6 = ipv6_set;
10871   vam->is_ipv6 = is_ipv6;
10872
10873   /* free old data */
10874   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
10875     {
10876       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
10877     }
10878   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
10879
10880   M (IP_DUMP, mp);
10881   mp->is_ipv6 = ipv6_set;
10882   S (mp);
10883
10884   /* Use a control ping for synchronization */
10885   MPING (CONTROL_PING, mp_ping);
10886   S (mp_ping);
10887
10888   W (ret);
10889   return ret;
10890 }
10891
10892 static int
10893 api_ipsec_spd_add_del (vat_main_t * vam)
10894 {
10895   unformat_input_t *i = vam->input;
10896   vl_api_ipsec_spd_add_del_t *mp;
10897   u32 spd_id = ~0;
10898   u8 is_add = 1;
10899   int ret;
10900
10901   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10902     {
10903       if (unformat (i, "spd_id %d", &spd_id))
10904         ;
10905       else if (unformat (i, "del"))
10906         is_add = 0;
10907       else
10908         {
10909           clib_warning ("parse error '%U'", format_unformat_error, i);
10910           return -99;
10911         }
10912     }
10913   if (spd_id == ~0)
10914     {
10915       errmsg ("spd_id must be set");
10916       return -99;
10917     }
10918
10919   M (IPSEC_SPD_ADD_DEL, mp);
10920
10921   mp->spd_id = ntohl (spd_id);
10922   mp->is_add = is_add;
10923
10924   S (mp);
10925   W (ret);
10926   return ret;
10927 }
10928
10929 static int
10930 api_ipsec_interface_add_del_spd (vat_main_t * vam)
10931 {
10932   unformat_input_t *i = vam->input;
10933   vl_api_ipsec_interface_add_del_spd_t *mp;
10934   u32 sw_if_index;
10935   u8 sw_if_index_set = 0;
10936   u32 spd_id = (u32) ~ 0;
10937   u8 is_add = 1;
10938   int ret;
10939
10940   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10941     {
10942       if (unformat (i, "del"))
10943         is_add = 0;
10944       else if (unformat (i, "spd_id %d", &spd_id))
10945         ;
10946       else
10947         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10948         sw_if_index_set = 1;
10949       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10950         sw_if_index_set = 1;
10951       else
10952         {
10953           clib_warning ("parse error '%U'", format_unformat_error, i);
10954           return -99;
10955         }
10956
10957     }
10958
10959   if (spd_id == (u32) ~ 0)
10960     {
10961       errmsg ("spd_id must be set");
10962       return -99;
10963     }
10964
10965   if (sw_if_index_set == 0)
10966     {
10967       errmsg ("missing interface name or sw_if_index");
10968       return -99;
10969     }
10970
10971   M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
10972
10973   mp->spd_id = ntohl (spd_id);
10974   mp->sw_if_index = ntohl (sw_if_index);
10975   mp->is_add = is_add;
10976
10977   S (mp);
10978   W (ret);
10979   return ret;
10980 }
10981
10982 static int
10983 api_ipsec_spd_entry_add_del (vat_main_t * vam)
10984 {
10985   unformat_input_t *i = vam->input;
10986   vl_api_ipsec_spd_entry_add_del_t *mp;
10987   u8 is_add = 1, is_outbound = 0;
10988   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
10989   i32 priority = 0;
10990   u32 rport_start = 0, rport_stop = (u32) ~ 0;
10991   u32 lport_start = 0, lport_stop = (u32) ~ 0;
10992   vl_api_address_t laddr_start = { }, laddr_stop =
10993   {
10994   }, raddr_start =
10995   {
10996   }, raddr_stop =
10997   {
10998   };
10999   int ret;
11000
11001   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11002     {
11003       if (unformat (i, "del"))
11004         is_add = 0;
11005       if (unformat (i, "outbound"))
11006         is_outbound = 1;
11007       if (unformat (i, "inbound"))
11008         is_outbound = 0;
11009       else if (unformat (i, "spd_id %d", &spd_id))
11010         ;
11011       else if (unformat (i, "sa_id %d", &sa_id))
11012         ;
11013       else if (unformat (i, "priority %d", &priority))
11014         ;
11015       else if (unformat (i, "protocol %d", &protocol))
11016         ;
11017       else if (unformat (i, "lport_start %d", &lport_start))
11018         ;
11019       else if (unformat (i, "lport_stop %d", &lport_stop))
11020         ;
11021       else if (unformat (i, "rport_start %d", &rport_start))
11022         ;
11023       else if (unformat (i, "rport_stop %d", &rport_stop))
11024         ;
11025       else if (unformat (i, "laddr_start %U",
11026                          unformat_vl_api_address, &laddr_start))
11027         ;
11028       else if (unformat (i, "laddr_stop %U", unformat_vl_api_address,
11029                          &laddr_stop))
11030         ;
11031       else if (unformat (i, "raddr_start %U", unformat_vl_api_address,
11032                          &raddr_start))
11033         ;
11034       else if (unformat (i, "raddr_stop %U", unformat_vl_api_address,
11035                          &raddr_stop))
11036         ;
11037       else
11038         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
11039         {
11040           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
11041             {
11042               clib_warning ("unsupported action: 'resolve'");
11043               return -99;
11044             }
11045         }
11046       else
11047         {
11048           clib_warning ("parse error '%U'", format_unformat_error, i);
11049           return -99;
11050         }
11051
11052     }
11053
11054   M (IPSEC_SPD_ENTRY_ADD_DEL, mp);
11055
11056   mp->is_add = is_add;
11057
11058   mp->entry.spd_id = ntohl (spd_id);
11059   mp->entry.priority = ntohl (priority);
11060   mp->entry.is_outbound = is_outbound;
11061
11062   clib_memcpy (&mp->entry.remote_address_start, &raddr_start,
11063                sizeof (vl_api_address_t));
11064   clib_memcpy (&mp->entry.remote_address_stop, &raddr_stop,
11065                sizeof (vl_api_address_t));
11066   clib_memcpy (&mp->entry.local_address_start, &laddr_start,
11067                sizeof (vl_api_address_t));
11068   clib_memcpy (&mp->entry.local_address_stop, &laddr_stop,
11069                sizeof (vl_api_address_t));
11070
11071   mp->entry.protocol = (u8) protocol;
11072   mp->entry.local_port_start = ntohs ((u16) lport_start);
11073   mp->entry.local_port_stop = ntohs ((u16) lport_stop);
11074   mp->entry.remote_port_start = ntohs ((u16) rport_start);
11075   mp->entry.remote_port_stop = ntohs ((u16) rport_stop);
11076   mp->entry.policy = (u8) policy;
11077   mp->entry.sa_id = ntohl (sa_id);
11078
11079   S (mp);
11080   W (ret);
11081   return ret;
11082 }
11083
11084 static int
11085 api_ipsec_sad_entry_add_del (vat_main_t * vam)
11086 {
11087   unformat_input_t *i = vam->input;
11088   vl_api_ipsec_sad_entry_add_del_t *mp;
11089   u32 sad_id = 0, spi = 0;
11090   u8 *ck = 0, *ik = 0;
11091   u8 is_add = 1;
11092
11093   vl_api_ipsec_crypto_alg_t crypto_alg = IPSEC_API_CRYPTO_ALG_NONE;
11094   vl_api_ipsec_integ_alg_t integ_alg = IPSEC_API_INTEG_ALG_NONE;
11095   vl_api_ipsec_sad_flags_t flags = IPSEC_API_SAD_FLAG_NONE;
11096   vl_api_ipsec_proto_t protocol = IPSEC_API_PROTO_AH;
11097   vl_api_address_t tun_src, tun_dst;
11098   int ret;
11099
11100   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11101     {
11102       if (unformat (i, "del"))
11103         is_add = 0;
11104       else if (unformat (i, "sad_id %d", &sad_id))
11105         ;
11106       else if (unformat (i, "spi %d", &spi))
11107         ;
11108       else if (unformat (i, "esp"))
11109         protocol = IPSEC_API_PROTO_ESP;
11110       else
11111         if (unformat (i, "tunnel_src %U", unformat_vl_api_address, &tun_src))
11112         {
11113           flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL;
11114           if (ADDRESS_IP6 == tun_src.af)
11115             flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL_V6;
11116         }
11117       else
11118         if (unformat (i, "tunnel_dst %U", unformat_vl_api_address, &tun_dst))
11119         {
11120           flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL;
11121           if (ADDRESS_IP6 == tun_src.af)
11122             flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL_V6;
11123         }
11124       else
11125         if (unformat (i, "crypto_alg %U",
11126                       unformat_ipsec_api_crypto_alg, &crypto_alg))
11127         ;
11128       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
11129         ;
11130       else if (unformat (i, "integ_alg %U",
11131                          unformat_ipsec_api_integ_alg, &integ_alg))
11132         ;
11133       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
11134         ;
11135       else
11136         {
11137           clib_warning ("parse error '%U'", format_unformat_error, i);
11138           return -99;
11139         }
11140
11141     }
11142
11143   M (IPSEC_SAD_ENTRY_ADD_DEL, mp);
11144
11145   mp->is_add = is_add;
11146   mp->entry.sad_id = ntohl (sad_id);
11147   mp->entry.protocol = protocol;
11148   mp->entry.spi = ntohl (spi);
11149   mp->entry.flags = flags;
11150
11151   mp->entry.crypto_algorithm = crypto_alg;
11152   mp->entry.integrity_algorithm = integ_alg;
11153   mp->entry.crypto_key.length = vec_len (ck);
11154   mp->entry.integrity_key.length = vec_len (ik);
11155
11156   if (mp->entry.crypto_key.length > sizeof (mp->entry.crypto_key.data))
11157     mp->entry.crypto_key.length = sizeof (mp->entry.crypto_key.data);
11158
11159   if (mp->entry.integrity_key.length > sizeof (mp->entry.integrity_key.data))
11160     mp->entry.integrity_key.length = sizeof (mp->entry.integrity_key.data);
11161
11162   if (ck)
11163     clib_memcpy (mp->entry.crypto_key.data, ck, mp->entry.crypto_key.length);
11164   if (ik)
11165     clib_memcpy (mp->entry.integrity_key.data, ik,
11166                  mp->entry.integrity_key.length);
11167
11168   if (flags & IPSEC_API_SAD_FLAG_IS_TUNNEL)
11169     {
11170       clib_memcpy (&mp->entry.tunnel_src, &tun_src,
11171                    sizeof (mp->entry.tunnel_src));
11172       clib_memcpy (&mp->entry.tunnel_dst, &tun_dst,
11173                    sizeof (mp->entry.tunnel_dst));
11174     }
11175
11176   S (mp);
11177   W (ret);
11178   return ret;
11179 }
11180
11181 static void
11182 vl_api_ipsec_sa_details_t_handler (vl_api_ipsec_sa_details_t * mp)
11183 {
11184   vat_main_t *vam = &vat_main;
11185
11186   print (vam->ofp, "sa_id %u sw_if_index %u spi %u proto %u crypto_alg %u "
11187          "crypto_key %U integ_alg %u integ_key %U flags %x "
11188          "tunnel_src_addr %U tunnel_dst_addr %U "
11189          "salt %u seq_outbound %lu last_seq_inbound %lu "
11190          "replay_window %lu stat_index %u\n",
11191          ntohl (mp->entry.sad_id),
11192          ntohl (mp->sw_if_index),
11193          ntohl (mp->entry.spi),
11194          ntohl (mp->entry.protocol),
11195          ntohl (mp->entry.crypto_algorithm),
11196          format_hex_bytes, mp->entry.crypto_key.data,
11197          mp->entry.crypto_key.length, ntohl (mp->entry.integrity_algorithm),
11198          format_hex_bytes, mp->entry.integrity_key.data,
11199          mp->entry.integrity_key.length, ntohl (mp->entry.flags),
11200          format_vl_api_address, &mp->entry.tunnel_src, format_vl_api_address,
11201          &mp->entry.tunnel_dst, ntohl (mp->salt),
11202          clib_net_to_host_u64 (mp->seq_outbound),
11203          clib_net_to_host_u64 (mp->last_seq_inbound),
11204          clib_net_to_host_u64 (mp->replay_window), ntohl (mp->stat_index));
11205 }
11206
11207 #define vl_api_ipsec_sa_details_t_endian vl_noop_handler
11208 #define vl_api_ipsec_sa_details_t_print vl_noop_handler
11209
11210 static void vl_api_ipsec_sa_details_t_handler_json
11211   (vl_api_ipsec_sa_details_t * mp)
11212 {
11213   vat_main_t *vam = &vat_main;
11214   vat_json_node_t *node = NULL;
11215   vl_api_ipsec_sad_flags_t flags;
11216
11217   if (VAT_JSON_ARRAY != vam->json_tree.type)
11218     {
11219       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11220       vat_json_init_array (&vam->json_tree);
11221     }
11222   node = vat_json_array_add (&vam->json_tree);
11223
11224   vat_json_init_object (node);
11225   vat_json_object_add_uint (node, "sa_id", ntohl (mp->entry.sad_id));
11226   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11227   vat_json_object_add_uint (node, "spi", ntohl (mp->entry.spi));
11228   vat_json_object_add_uint (node, "proto", ntohl (mp->entry.protocol));
11229   vat_json_object_add_uint (node, "crypto_alg",
11230                             ntohl (mp->entry.crypto_algorithm));
11231   vat_json_object_add_uint (node, "integ_alg",
11232                             ntohl (mp->entry.integrity_algorithm));
11233   flags = ntohl (mp->entry.flags);
11234   vat_json_object_add_uint (node, "use_esn",
11235                             ! !(flags & IPSEC_API_SAD_FLAG_USE_ESN));
11236   vat_json_object_add_uint (node, "use_anti_replay",
11237                             ! !(flags & IPSEC_API_SAD_FLAG_USE_ANTI_REPLAY));
11238   vat_json_object_add_uint (node, "is_tunnel",
11239                             ! !(flags & IPSEC_API_SAD_FLAG_IS_TUNNEL));
11240   vat_json_object_add_uint (node, "is_tunnel_ip6",
11241                             ! !(flags & IPSEC_API_SAD_FLAG_IS_TUNNEL_V6));
11242   vat_json_object_add_uint (node, "udp_encap",
11243                             ! !(flags & IPSEC_API_SAD_FLAG_UDP_ENCAP));
11244   vat_json_object_add_bytes (node, "crypto_key", mp->entry.crypto_key.data,
11245                              mp->entry.crypto_key.length);
11246   vat_json_object_add_bytes (node, "integ_key", mp->entry.integrity_key.data,
11247                              mp->entry.integrity_key.length);
11248   vat_json_object_add_address (node, "src", &mp->entry.tunnel_src);
11249   vat_json_object_add_address (node, "dst", &mp->entry.tunnel_dst);
11250   vat_json_object_add_uint (node, "replay_window",
11251                             clib_net_to_host_u64 (mp->replay_window));
11252   vat_json_object_add_uint (node, "stat_index", ntohl (mp->stat_index));
11253 }
11254
11255 static int
11256 api_ipsec_sa_dump (vat_main_t * vam)
11257 {
11258   unformat_input_t *i = vam->input;
11259   vl_api_ipsec_sa_dump_t *mp;
11260   vl_api_control_ping_t *mp_ping;
11261   u32 sa_id = ~0;
11262   int ret;
11263
11264   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11265     {
11266       if (unformat (i, "sa_id %d", &sa_id))
11267         ;
11268       else
11269         {
11270           clib_warning ("parse error '%U'", format_unformat_error, i);
11271           return -99;
11272         }
11273     }
11274
11275   M (IPSEC_SA_DUMP, mp);
11276
11277   mp->sa_id = ntohl (sa_id);
11278
11279   S (mp);
11280
11281   /* Use a control ping for synchronization */
11282   M (CONTROL_PING, mp_ping);
11283   S (mp_ping);
11284
11285   W (ret);
11286   return ret;
11287 }
11288
11289 static int
11290 api_get_first_msg_id (vat_main_t * vam)
11291 {
11292   vl_api_get_first_msg_id_t *mp;
11293   unformat_input_t *i = vam->input;
11294   u8 *name;
11295   u8 name_set = 0;
11296   int ret;
11297
11298   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11299     {
11300       if (unformat (i, "client %s", &name))
11301         name_set = 1;
11302       else
11303         break;
11304     }
11305
11306   if (name_set == 0)
11307     {
11308       errmsg ("missing client name");
11309       return -99;
11310     }
11311   vec_add1 (name, 0);
11312
11313   if (vec_len (name) > 63)
11314     {
11315       errmsg ("client name too long");
11316       return -99;
11317     }
11318
11319   M (GET_FIRST_MSG_ID, mp);
11320   clib_memcpy (mp->name, name, vec_len (name));
11321   S (mp);
11322   W (ret);
11323   return ret;
11324 }
11325
11326 static int
11327 api_cop_interface_enable_disable (vat_main_t * vam)
11328 {
11329   unformat_input_t *line_input = vam->input;
11330   vl_api_cop_interface_enable_disable_t *mp;
11331   u32 sw_if_index = ~0;
11332   u8 enable_disable = 1;
11333   int ret;
11334
11335   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11336     {
11337       if (unformat (line_input, "disable"))
11338         enable_disable = 0;
11339       if (unformat (line_input, "enable"))
11340         enable_disable = 1;
11341       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
11342                          vam, &sw_if_index))
11343         ;
11344       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
11345         ;
11346       else
11347         break;
11348     }
11349
11350   if (sw_if_index == ~0)
11351     {
11352       errmsg ("missing interface name or sw_if_index");
11353       return -99;
11354     }
11355
11356   /* Construct the API message */
11357   M (COP_INTERFACE_ENABLE_DISABLE, mp);
11358   mp->sw_if_index = ntohl (sw_if_index);
11359   mp->enable_disable = enable_disable;
11360
11361   /* send it... */
11362   S (mp);
11363   /* Wait for the reply */
11364   W (ret);
11365   return ret;
11366 }
11367
11368 static int
11369 api_cop_whitelist_enable_disable (vat_main_t * vam)
11370 {
11371   unformat_input_t *line_input = vam->input;
11372   vl_api_cop_whitelist_enable_disable_t *mp;
11373   u32 sw_if_index = ~0;
11374   u8 ip4 = 0, ip6 = 0, default_cop = 0;
11375   u32 fib_id = 0;
11376   int ret;
11377
11378   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11379     {
11380       if (unformat (line_input, "ip4"))
11381         ip4 = 1;
11382       else if (unformat (line_input, "ip6"))
11383         ip6 = 1;
11384       else if (unformat (line_input, "default"))
11385         default_cop = 1;
11386       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
11387                          vam, &sw_if_index))
11388         ;
11389       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
11390         ;
11391       else if (unformat (line_input, "fib-id %d", &fib_id))
11392         ;
11393       else
11394         break;
11395     }
11396
11397   if (sw_if_index == ~0)
11398     {
11399       errmsg ("missing interface name or sw_if_index");
11400       return -99;
11401     }
11402
11403   /* Construct the API message */
11404   M (COP_WHITELIST_ENABLE_DISABLE, mp);
11405   mp->sw_if_index = ntohl (sw_if_index);
11406   mp->fib_id = ntohl (fib_id);
11407   mp->ip4 = ip4;
11408   mp->ip6 = ip6;
11409   mp->default_cop = default_cop;
11410
11411   /* send it... */
11412   S (mp);
11413   /* Wait for the reply */
11414   W (ret);
11415   return ret;
11416 }
11417
11418 static int
11419 api_get_node_graph (vat_main_t * vam)
11420 {
11421   vl_api_get_node_graph_t *mp;
11422   int ret;
11423
11424   M (GET_NODE_GRAPH, mp);
11425
11426   /* send it... */
11427   S (mp);
11428   /* Wait for the reply */
11429   W (ret);
11430   return ret;
11431 }
11432
11433 static int
11434 api_af_packet_create (vat_main_t * vam)
11435 {
11436   unformat_input_t *i = vam->input;
11437   vl_api_af_packet_create_t *mp;
11438   u8 *host_if_name = 0;
11439   u8 hw_addr[6];
11440   u8 random_hw_addr = 1;
11441   int ret;
11442
11443   clib_memset (hw_addr, 0, sizeof (hw_addr));
11444
11445   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11446     {
11447       if (unformat (i, "name %s", &host_if_name))
11448         vec_add1 (host_if_name, 0);
11449       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
11450         random_hw_addr = 0;
11451       else
11452         break;
11453     }
11454
11455   if (!vec_len (host_if_name))
11456     {
11457       errmsg ("host-interface name must be specified");
11458       return -99;
11459     }
11460
11461   if (vec_len (host_if_name) > 64)
11462     {
11463       errmsg ("host-interface name too long");
11464       return -99;
11465     }
11466
11467   M (AF_PACKET_CREATE, mp);
11468
11469   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
11470   clib_memcpy (mp->hw_addr, hw_addr, 6);
11471   mp->use_random_hw_addr = random_hw_addr;
11472   vec_free (host_if_name);
11473
11474   S (mp);
11475
11476   /* *INDENT-OFF* */
11477   W2 (ret,
11478       ({
11479         if (ret == 0)
11480           fprintf (vam->ofp ? vam->ofp : stderr,
11481                    " new sw_if_index = %d\n", vam->sw_if_index);
11482       }));
11483   /* *INDENT-ON* */
11484   return ret;
11485 }
11486
11487 static int
11488 api_af_packet_delete (vat_main_t * vam)
11489 {
11490   unformat_input_t *i = vam->input;
11491   vl_api_af_packet_delete_t *mp;
11492   u8 *host_if_name = 0;
11493   int ret;
11494
11495   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11496     {
11497       if (unformat (i, "name %s", &host_if_name))
11498         vec_add1 (host_if_name, 0);
11499       else
11500         break;
11501     }
11502
11503   if (!vec_len (host_if_name))
11504     {
11505       errmsg ("host-interface name must be specified");
11506       return -99;
11507     }
11508
11509   if (vec_len (host_if_name) > 64)
11510     {
11511       errmsg ("host-interface name too long");
11512       return -99;
11513     }
11514
11515   M (AF_PACKET_DELETE, mp);
11516
11517   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
11518   vec_free (host_if_name);
11519
11520   S (mp);
11521   W (ret);
11522   return ret;
11523 }
11524
11525 static void vl_api_af_packet_details_t_handler
11526   (vl_api_af_packet_details_t * mp)
11527 {
11528   vat_main_t *vam = &vat_main;
11529
11530   print (vam->ofp, "%-16s %d",
11531          mp->host_if_name, clib_net_to_host_u32 (mp->sw_if_index));
11532 }
11533
11534 static void vl_api_af_packet_details_t_handler_json
11535   (vl_api_af_packet_details_t * mp)
11536 {
11537   vat_main_t *vam = &vat_main;
11538   vat_json_node_t *node = NULL;
11539
11540   if (VAT_JSON_ARRAY != vam->json_tree.type)
11541     {
11542       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11543       vat_json_init_array (&vam->json_tree);
11544     }
11545   node = vat_json_array_add (&vam->json_tree);
11546
11547   vat_json_init_object (node);
11548   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11549   vat_json_object_add_string_copy (node, "dev_name", mp->host_if_name);
11550 }
11551
11552 static int
11553 api_af_packet_dump (vat_main_t * vam)
11554 {
11555   vl_api_af_packet_dump_t *mp;
11556   vl_api_control_ping_t *mp_ping;
11557   int ret;
11558
11559   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
11560   /* Get list of tap interfaces */
11561   M (AF_PACKET_DUMP, mp);
11562   S (mp);
11563
11564   /* Use a control ping for synchronization */
11565   MPING (CONTROL_PING, mp_ping);
11566   S (mp_ping);
11567
11568   W (ret);
11569   return ret;
11570 }
11571
11572 static int
11573 api_policer_add_del (vat_main_t * vam)
11574 {
11575   unformat_input_t *i = vam->input;
11576   vl_api_policer_add_del_t *mp;
11577   u8 is_add = 1;
11578   u8 *name = 0;
11579   u32 cir = 0;
11580   u32 eir = 0;
11581   u64 cb = 0;
11582   u64 eb = 0;
11583   u8 rate_type = 0;
11584   u8 round_type = 0;
11585   u8 type = 0;
11586   u8 color_aware = 0;
11587   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
11588   int ret;
11589
11590   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
11591   conform_action.dscp = 0;
11592   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
11593   exceed_action.dscp = 0;
11594   violate_action.action_type = SSE2_QOS_ACTION_DROP;
11595   violate_action.dscp = 0;
11596
11597   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11598     {
11599       if (unformat (i, "del"))
11600         is_add = 0;
11601       else if (unformat (i, "name %s", &name))
11602         vec_add1 (name, 0);
11603       else if (unformat (i, "cir %u", &cir))
11604         ;
11605       else if (unformat (i, "eir %u", &eir))
11606         ;
11607       else if (unformat (i, "cb %u", &cb))
11608         ;
11609       else if (unformat (i, "eb %u", &eb))
11610         ;
11611       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
11612                          &rate_type))
11613         ;
11614       else if (unformat (i, "round_type %U", unformat_policer_round_type,
11615                          &round_type))
11616         ;
11617       else if (unformat (i, "type %U", unformat_policer_type, &type))
11618         ;
11619       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
11620                          &conform_action))
11621         ;
11622       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
11623                          &exceed_action))
11624         ;
11625       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
11626                          &violate_action))
11627         ;
11628       else if (unformat (i, "color-aware"))
11629         color_aware = 1;
11630       else
11631         break;
11632     }
11633
11634   if (!vec_len (name))
11635     {
11636       errmsg ("policer name must be specified");
11637       return -99;
11638     }
11639
11640   if (vec_len (name) > 64)
11641     {
11642       errmsg ("policer name too long");
11643       return -99;
11644     }
11645
11646   M (POLICER_ADD_DEL, mp);
11647
11648   clib_memcpy (mp->name, name, vec_len (name));
11649   vec_free (name);
11650   mp->is_add = is_add;
11651   mp->cir = ntohl (cir);
11652   mp->eir = ntohl (eir);
11653   mp->cb = clib_net_to_host_u64 (cb);
11654   mp->eb = clib_net_to_host_u64 (eb);
11655   mp->rate_type = rate_type;
11656   mp->round_type = round_type;
11657   mp->type = type;
11658   mp->conform_action.type = conform_action.action_type;
11659   mp->conform_action.dscp = conform_action.dscp;
11660   mp->exceed_action.type = exceed_action.action_type;
11661   mp->exceed_action.dscp = exceed_action.dscp;
11662   mp->violate_action.type = violate_action.action_type;
11663   mp->violate_action.dscp = violate_action.dscp;
11664   mp->color_aware = color_aware;
11665
11666   S (mp);
11667   W (ret);
11668   return ret;
11669 }
11670
11671 static int
11672 api_policer_dump (vat_main_t * vam)
11673 {
11674   unformat_input_t *i = vam->input;
11675   vl_api_policer_dump_t *mp;
11676   vl_api_control_ping_t *mp_ping;
11677   u8 *match_name = 0;
11678   u8 match_name_valid = 0;
11679   int ret;
11680
11681   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11682     {
11683       if (unformat (i, "name %s", &match_name))
11684         {
11685           vec_add1 (match_name, 0);
11686           match_name_valid = 1;
11687         }
11688       else
11689         break;
11690     }
11691
11692   M (POLICER_DUMP, mp);
11693   mp->match_name_valid = match_name_valid;
11694   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
11695   vec_free (match_name);
11696   /* send it... */
11697   S (mp);
11698
11699   /* Use a control ping for synchronization */
11700   MPING (CONTROL_PING, mp_ping);
11701   S (mp_ping);
11702
11703   /* Wait for a reply... */
11704   W (ret);
11705   return ret;
11706 }
11707
11708 static int
11709 api_policer_classify_set_interface (vat_main_t * vam)
11710 {
11711   unformat_input_t *i = vam->input;
11712   vl_api_policer_classify_set_interface_t *mp;
11713   u32 sw_if_index;
11714   int sw_if_index_set;
11715   u32 ip4_table_index = ~0;
11716   u32 ip6_table_index = ~0;
11717   u32 l2_table_index = ~0;
11718   u8 is_add = 1;
11719   int ret;
11720
11721   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11722     {
11723       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11724         sw_if_index_set = 1;
11725       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11726         sw_if_index_set = 1;
11727       else if (unformat (i, "del"))
11728         is_add = 0;
11729       else if (unformat (i, "ip4-table %d", &ip4_table_index))
11730         ;
11731       else if (unformat (i, "ip6-table %d", &ip6_table_index))
11732         ;
11733       else if (unformat (i, "l2-table %d", &l2_table_index))
11734         ;
11735       else
11736         {
11737           clib_warning ("parse error '%U'", format_unformat_error, i);
11738           return -99;
11739         }
11740     }
11741
11742   if (sw_if_index_set == 0)
11743     {
11744       errmsg ("missing interface name or sw_if_index");
11745       return -99;
11746     }
11747
11748   M (POLICER_CLASSIFY_SET_INTERFACE, mp);
11749
11750   mp->sw_if_index = ntohl (sw_if_index);
11751   mp->ip4_table_index = ntohl (ip4_table_index);
11752   mp->ip6_table_index = ntohl (ip6_table_index);
11753   mp->l2_table_index = ntohl (l2_table_index);
11754   mp->is_add = is_add;
11755
11756   S (mp);
11757   W (ret);
11758   return ret;
11759 }
11760
11761 static int
11762 api_policer_classify_dump (vat_main_t * vam)
11763 {
11764   unformat_input_t *i = vam->input;
11765   vl_api_policer_classify_dump_t *mp;
11766   vl_api_control_ping_t *mp_ping;
11767   u8 type = POLICER_CLASSIFY_N_TABLES;
11768   int ret;
11769
11770   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
11771     ;
11772   else
11773     {
11774       errmsg ("classify table type must be specified");
11775       return -99;
11776     }
11777
11778   if (!vam->json_output)
11779     {
11780       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
11781     }
11782
11783   M (POLICER_CLASSIFY_DUMP, mp);
11784   mp->type = type;
11785   /* send it... */
11786   S (mp);
11787
11788   /* Use a control ping for synchronization */
11789   MPING (CONTROL_PING, mp_ping);
11790   S (mp_ping);
11791
11792   /* Wait for a reply... */
11793   W (ret);
11794   return ret;
11795 }
11796
11797 static u8 *
11798 format_fib_api_path_nh_proto (u8 * s, va_list * args)
11799 {
11800   vl_api_fib_path_nh_proto_t proto =
11801     va_arg (*args, vl_api_fib_path_nh_proto_t);
11802
11803   switch (proto)
11804     {
11805     case FIB_API_PATH_NH_PROTO_IP4:
11806       s = format (s, "ip4");
11807       break;
11808     case FIB_API_PATH_NH_PROTO_IP6:
11809       s = format (s, "ip6");
11810       break;
11811     case FIB_API_PATH_NH_PROTO_MPLS:
11812       s = format (s, "mpls");
11813       break;
11814     case FIB_API_PATH_NH_PROTO_BIER:
11815       s = format (s, "bier");
11816       break;
11817     case FIB_API_PATH_NH_PROTO_ETHERNET:
11818       s = format (s, "ethernet");
11819       break;
11820     }
11821
11822   return (s);
11823 }
11824
11825 static u8 *
11826 format_vl_api_ip_address_union (u8 * s, va_list * args)
11827 {
11828   vl_api_address_family_t af = va_arg (*args, int);
11829   const vl_api_address_union_t *u = va_arg (*args, vl_api_address_union_t *);
11830
11831   switch (af)
11832     {
11833     case ADDRESS_IP4:
11834       s = format (s, "%U", format_ip4_address, u->ip4);
11835       break;
11836     case ADDRESS_IP6:
11837       s = format (s, "%U", format_ip6_address, u->ip6);
11838       break;
11839     }
11840   return (s);
11841 }
11842
11843 static u8 *
11844 format_vl_api_fib_path_type (u8 * s, va_list * args)
11845 {
11846   vl_api_fib_path_type_t t = va_arg (*args, vl_api_fib_path_type_t);
11847
11848   switch (t)
11849     {
11850     case FIB_API_PATH_TYPE_NORMAL:
11851       s = format (s, "normal");
11852       break;
11853     case FIB_API_PATH_TYPE_LOCAL:
11854       s = format (s, "local");
11855       break;
11856     case FIB_API_PATH_TYPE_DROP:
11857       s = format (s, "drop");
11858       break;
11859     case FIB_API_PATH_TYPE_UDP_ENCAP:
11860       s = format (s, "udp-encap");
11861       break;
11862     case FIB_API_PATH_TYPE_BIER_IMP:
11863       s = format (s, "bier-imp");
11864       break;
11865     case FIB_API_PATH_TYPE_ICMP_UNREACH:
11866       s = format (s, "unreach");
11867       break;
11868     case FIB_API_PATH_TYPE_ICMP_PROHIBIT:
11869       s = format (s, "prohibit");
11870       break;
11871     case FIB_API_PATH_TYPE_SOURCE_LOOKUP:
11872       s = format (s, "src-lookup");
11873       break;
11874     case FIB_API_PATH_TYPE_DVR:
11875       s = format (s, "dvr");
11876       break;
11877     case FIB_API_PATH_TYPE_INTERFACE_RX:
11878       s = format (s, "interface-rx");
11879       break;
11880     case FIB_API_PATH_TYPE_CLASSIFY:
11881       s = format (s, "classify");
11882       break;
11883     }
11884
11885   return (s);
11886 }
11887
11888 static void
11889 vl_api_fib_path_print (vat_main_t * vam, vl_api_fib_path_t * fp)
11890 {
11891   print (vam->ofp,
11892          "  weight %d, sw_if_index %d, type %U, afi %U, next_hop %U",
11893          ntohl (fp->weight), ntohl (fp->sw_if_index),
11894          format_vl_api_fib_path_type, fp->type,
11895          format_fib_api_path_nh_proto, fp->proto,
11896          format_vl_api_ip_address_union, &fp->nh.address);
11897 }
11898
11899 static void
11900 vl_api_mpls_fib_path_json_print (vat_json_node_t * node,
11901                                  vl_api_fib_path_t * fp)
11902 {
11903   struct in_addr ip4;
11904   struct in6_addr ip6;
11905
11906   vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
11907   vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
11908   vat_json_object_add_uint (node, "type", fp->type);
11909   vat_json_object_add_uint (node, "next_hop_proto", fp->proto);
11910   if (fp->proto == FIB_API_PATH_NH_PROTO_IP4)
11911     {
11912       clib_memcpy (&ip4, &fp->nh.address.ip4, sizeof (ip4));
11913       vat_json_object_add_ip4 (node, "next_hop", ip4);
11914     }
11915   else if (fp->proto == FIB_API_PATH_NH_PROTO_IP6)
11916     {
11917       clib_memcpy (&ip6, &fp->nh.address.ip6, sizeof (ip6));
11918       vat_json_object_add_ip6 (node, "next_hop", ip6);
11919     }
11920 }
11921
11922 static void
11923 vl_api_mpls_tunnel_details_t_handler (vl_api_mpls_tunnel_details_t * mp)
11924 {
11925   vat_main_t *vam = &vat_main;
11926   int count = ntohl (mp->mt_tunnel.mt_n_paths);
11927   vl_api_fib_path_t *fp;
11928   i32 i;
11929
11930   print (vam->ofp, "sw_if_index %d via:",
11931          ntohl (mp->mt_tunnel.mt_sw_if_index));
11932   fp = mp->mt_tunnel.mt_paths;
11933   for (i = 0; i < count; i++)
11934     {
11935       vl_api_fib_path_print (vam, fp);
11936       fp++;
11937     }
11938
11939   print (vam->ofp, "");
11940 }
11941
11942 #define vl_api_mpls_tunnel_details_t_endian vl_noop_handler
11943 #define vl_api_mpls_tunnel_details_t_print vl_noop_handler
11944
11945 static void
11946 vl_api_mpls_tunnel_details_t_handler_json (vl_api_mpls_tunnel_details_t * mp)
11947 {
11948   vat_main_t *vam = &vat_main;
11949   vat_json_node_t *node = NULL;
11950   int count = ntohl (mp->mt_tunnel.mt_n_paths);
11951   vl_api_fib_path_t *fp;
11952   i32 i;
11953
11954   if (VAT_JSON_ARRAY != vam->json_tree.type)
11955     {
11956       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11957       vat_json_init_array (&vam->json_tree);
11958     }
11959   node = vat_json_array_add (&vam->json_tree);
11960
11961   vat_json_init_object (node);
11962   vat_json_object_add_uint (node, "sw_if_index",
11963                             ntohl (mp->mt_tunnel.mt_sw_if_index));
11964
11965   vat_json_object_add_uint (node, "l2_only", mp->mt_tunnel.mt_l2_only);
11966
11967   fp = mp->mt_tunnel.mt_paths;
11968   for (i = 0; i < count; i++)
11969     {
11970       vl_api_mpls_fib_path_json_print (node, fp);
11971       fp++;
11972     }
11973 }
11974
11975 static int
11976 api_mpls_tunnel_dump (vat_main_t * vam)
11977 {
11978   vl_api_mpls_tunnel_dump_t *mp;
11979   vl_api_control_ping_t *mp_ping;
11980   int ret;
11981
11982   M (MPLS_TUNNEL_DUMP, mp);
11983
11984   S (mp);
11985
11986   /* Use a control ping for synchronization */
11987   MPING (CONTROL_PING, mp_ping);
11988   S (mp_ping);
11989
11990   W (ret);
11991   return ret;
11992 }
11993
11994 #define vl_api_mpls_table_details_t_endian vl_noop_handler
11995 #define vl_api_mpls_table_details_t_print vl_noop_handler
11996
11997
11998 static void
11999 vl_api_mpls_table_details_t_handler (vl_api_mpls_table_details_t * mp)
12000 {
12001   vat_main_t *vam = &vat_main;
12002
12003   print (vam->ofp, "table-id %d,", ntohl (mp->mt_table.mt_table_id));
12004 }
12005
12006 static void vl_api_mpls_table_details_t_handler_json
12007   (vl_api_mpls_table_details_t * mp)
12008 {
12009   vat_main_t *vam = &vat_main;
12010   vat_json_node_t *node = NULL;
12011
12012   if (VAT_JSON_ARRAY != vam->json_tree.type)
12013     {
12014       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12015       vat_json_init_array (&vam->json_tree);
12016     }
12017   node = vat_json_array_add (&vam->json_tree);
12018
12019   vat_json_init_object (node);
12020   vat_json_object_add_uint (node, "table", ntohl (mp->mt_table.mt_table_id));
12021 }
12022
12023 static int
12024 api_mpls_table_dump (vat_main_t * vam)
12025 {
12026   vl_api_mpls_table_dump_t *mp;
12027   vl_api_control_ping_t *mp_ping;
12028   int ret;
12029
12030   M (MPLS_TABLE_DUMP, mp);
12031   S (mp);
12032
12033   /* Use a control ping for synchronization */
12034   MPING (CONTROL_PING, mp_ping);
12035   S (mp_ping);
12036
12037   W (ret);
12038   return ret;
12039 }
12040
12041 #define vl_api_mpls_route_details_t_endian vl_noop_handler
12042 #define vl_api_mpls_route_details_t_print vl_noop_handler
12043
12044 static void
12045 vl_api_mpls_route_details_t_handler (vl_api_mpls_route_details_t * mp)
12046 {
12047   vat_main_t *vam = &vat_main;
12048   int count = (int) clib_net_to_host_u32 (mp->mr_route.mr_n_paths);
12049   vl_api_fib_path_t *fp;
12050   int i;
12051
12052   print (vam->ofp,
12053          "table-id %d, label %u, ess_bit %u",
12054          ntohl (mp->mr_route.mr_table_id),
12055          ntohl (mp->mr_route.mr_label), mp->mr_route.mr_eos);
12056   fp = mp->mr_route.mr_paths;
12057   for (i = 0; i < count; i++)
12058     {
12059       vl_api_fib_path_print (vam, fp);
12060       fp++;
12061     }
12062 }
12063
12064 static void vl_api_mpls_route_details_t_handler_json
12065   (vl_api_mpls_route_details_t * mp)
12066 {
12067   vat_main_t *vam = &vat_main;
12068   int count = (int) clib_host_to_net_u32 (mp->mr_route.mr_n_paths);
12069   vat_json_node_t *node = NULL;
12070   vl_api_fib_path_t *fp;
12071   int i;
12072
12073   if (VAT_JSON_ARRAY != vam->json_tree.type)
12074     {
12075       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12076       vat_json_init_array (&vam->json_tree);
12077     }
12078   node = vat_json_array_add (&vam->json_tree);
12079
12080   vat_json_init_object (node);
12081   vat_json_object_add_uint (node, "table", ntohl (mp->mr_route.mr_table_id));
12082   vat_json_object_add_uint (node, "s_bit", mp->mr_route.mr_eos);
12083   vat_json_object_add_uint (node, "label", ntohl (mp->mr_route.mr_label));
12084   vat_json_object_add_uint (node, "path_count", count);
12085   fp = mp->mr_route.mr_paths;
12086   for (i = 0; i < count; i++)
12087     {
12088       vl_api_mpls_fib_path_json_print (node, fp);
12089       fp++;
12090     }
12091 }
12092
12093 static int
12094 api_mpls_route_dump (vat_main_t * vam)
12095 {
12096   unformat_input_t *input = vam->input;
12097   vl_api_mpls_route_dump_t *mp;
12098   vl_api_control_ping_t *mp_ping;
12099   u32 table_id;
12100   int ret;
12101
12102   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12103     {
12104       if (unformat (input, "table_id %d", &table_id))
12105         ;
12106       else
12107         break;
12108     }
12109   if (table_id == ~0)
12110     {
12111       errmsg ("missing table id");
12112       return -99;
12113     }
12114
12115   M (MPLS_ROUTE_DUMP, mp);
12116
12117   mp->table.mt_table_id = ntohl (table_id);
12118   S (mp);
12119
12120   /* Use a control ping for synchronization */
12121   MPING (CONTROL_PING, mp_ping);
12122   S (mp_ping);
12123
12124   W (ret);
12125   return ret;
12126 }
12127
12128 #define vl_api_ip_table_details_t_endian vl_noop_handler
12129 #define vl_api_ip_table_details_t_print vl_noop_handler
12130
12131 static void
12132 vl_api_ip_table_details_t_handler (vl_api_ip_table_details_t * mp)
12133 {
12134   vat_main_t *vam = &vat_main;
12135
12136   print (vam->ofp,
12137          "%s; table-id %d, prefix %U/%d",
12138          mp->table.name, ntohl (mp->table.table_id));
12139 }
12140
12141
12142 static void vl_api_ip_table_details_t_handler_json
12143   (vl_api_ip_table_details_t * mp)
12144 {
12145   vat_main_t *vam = &vat_main;
12146   vat_json_node_t *node = NULL;
12147
12148   if (VAT_JSON_ARRAY != vam->json_tree.type)
12149     {
12150       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12151       vat_json_init_array (&vam->json_tree);
12152     }
12153   node = vat_json_array_add (&vam->json_tree);
12154
12155   vat_json_init_object (node);
12156   vat_json_object_add_uint (node, "table", ntohl (mp->table.table_id));
12157 }
12158
12159 static int
12160 api_ip_table_dump (vat_main_t * vam)
12161 {
12162   vl_api_ip_table_dump_t *mp;
12163   vl_api_control_ping_t *mp_ping;
12164   int ret;
12165
12166   M (IP_TABLE_DUMP, mp);
12167   S (mp);
12168
12169   /* Use a control ping for synchronization */
12170   MPING (CONTROL_PING, mp_ping);
12171   S (mp_ping);
12172
12173   W (ret);
12174   return ret;
12175 }
12176
12177 static int
12178 api_ip_mtable_dump (vat_main_t * vam)
12179 {
12180   vl_api_ip_mtable_dump_t *mp;
12181   vl_api_control_ping_t *mp_ping;
12182   int ret;
12183
12184   M (IP_MTABLE_DUMP, mp);
12185   S (mp);
12186
12187   /* Use a control ping for synchronization */
12188   MPING (CONTROL_PING, mp_ping);
12189   S (mp_ping);
12190
12191   W (ret);
12192   return ret;
12193 }
12194
12195 static int
12196 api_ip_mroute_dump (vat_main_t * vam)
12197 {
12198   unformat_input_t *input = vam->input;
12199   vl_api_control_ping_t *mp_ping;
12200   vl_api_ip_mroute_dump_t *mp;
12201   int ret, is_ip6;
12202   u32 table_id;
12203
12204   is_ip6 = 0;
12205   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12206     {
12207       if (unformat (input, "table_id %d", &table_id))
12208         ;
12209       else if (unformat (input, "ip6"))
12210         is_ip6 = 1;
12211       else if (unformat (input, "ip4"))
12212         is_ip6 = 0;
12213       else
12214         break;
12215     }
12216   if (table_id == ~0)
12217     {
12218       errmsg ("missing table id");
12219       return -99;
12220     }
12221
12222   M (IP_MROUTE_DUMP, mp);
12223   mp->table.table_id = table_id;
12224   mp->table.is_ip6 = is_ip6;
12225   S (mp);
12226
12227   /* Use a control ping for synchronization */
12228   MPING (CONTROL_PING, mp_ping);
12229   S (mp_ping);
12230
12231   W (ret);
12232   return ret;
12233 }
12234
12235 #define vl_api_ip_route_details_t_endian vl_noop_handler
12236 #define vl_api_ip_route_details_t_print vl_noop_handler
12237
12238 static void
12239 vl_api_ip_route_details_t_handler (vl_api_ip_route_details_t * mp)
12240 {
12241   vat_main_t *vam = &vat_main;
12242   u8 count = mp->route.n_paths;
12243   vl_api_fib_path_t *fp;
12244   int i;
12245
12246   print (vam->ofp,
12247          "table-id %d, prefix %U/%d",
12248          ntohl (mp->route.table_id),
12249          format_ip46_address, mp->route.prefix.address, mp->route.prefix.len);
12250   for (i = 0; i < count; i++)
12251     {
12252       fp = &mp->route.paths[i];
12253
12254       vl_api_fib_path_print (vam, fp);
12255       fp++;
12256     }
12257 }
12258
12259 static void vl_api_ip_route_details_t_handler_json
12260   (vl_api_ip_route_details_t * mp)
12261 {
12262   vat_main_t *vam = &vat_main;
12263   u8 count = mp->route.n_paths;
12264   vat_json_node_t *node = NULL;
12265   struct in_addr ip4;
12266   struct in6_addr ip6;
12267   vl_api_fib_path_t *fp;
12268   int i;
12269
12270   if (VAT_JSON_ARRAY != vam->json_tree.type)
12271     {
12272       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12273       vat_json_init_array (&vam->json_tree);
12274     }
12275   node = vat_json_array_add (&vam->json_tree);
12276
12277   vat_json_init_object (node);
12278   vat_json_object_add_uint (node, "table", ntohl (mp->route.table_id));
12279   if (ADDRESS_IP6 == mp->route.prefix.address.af)
12280     {
12281       clib_memcpy (&ip6, &mp->route.prefix.address.un.ip6, sizeof (ip6));
12282       vat_json_object_add_ip6 (node, "prefix", ip6);
12283     }
12284   else
12285     {
12286       clib_memcpy (&ip4, &mp->route.prefix.address.un.ip4, sizeof (ip4));
12287       vat_json_object_add_ip4 (node, "prefix", ip4);
12288     }
12289   vat_json_object_add_uint (node, "mask_length", mp->route.prefix.len);
12290   vat_json_object_add_uint (node, "path_count", count);
12291   for (i = 0; i < count; i++)
12292     {
12293       fp = &mp->route.paths[i];
12294       vl_api_mpls_fib_path_json_print (node, fp);
12295     }
12296 }
12297
12298 static int
12299 api_ip_route_dump (vat_main_t * vam)
12300 {
12301   unformat_input_t *input = vam->input;
12302   vl_api_ip_route_dump_t *mp;
12303   vl_api_control_ping_t *mp_ping;
12304   u32 table_id;
12305   u8 is_ip6;
12306   int ret;
12307
12308   is_ip6 = 0;
12309   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12310     {
12311       if (unformat (input, "table_id %d", &table_id))
12312         ;
12313       else if (unformat (input, "ip6"))
12314         is_ip6 = 1;
12315       else if (unformat (input, "ip4"))
12316         is_ip6 = 0;
12317       else
12318         break;
12319     }
12320   if (table_id == ~0)
12321     {
12322       errmsg ("missing table id");
12323       return -99;
12324     }
12325
12326   M (IP_ROUTE_DUMP, mp);
12327
12328   mp->table.table_id = table_id;
12329   mp->table.is_ip6 = is_ip6;
12330
12331   S (mp);
12332
12333   /* Use a control ping for synchronization */
12334   MPING (CONTROL_PING, mp_ping);
12335   S (mp_ping);
12336
12337   W (ret);
12338   return ret;
12339 }
12340
12341 int
12342 api_classify_table_ids (vat_main_t * vam)
12343 {
12344   vl_api_classify_table_ids_t *mp;
12345   int ret;
12346
12347   /* Construct the API message */
12348   M (CLASSIFY_TABLE_IDS, mp);
12349   mp->context = 0;
12350
12351   S (mp);
12352   W (ret);
12353   return ret;
12354 }
12355
12356 int
12357 api_classify_table_by_interface (vat_main_t * vam)
12358 {
12359   unformat_input_t *input = vam->input;
12360   vl_api_classify_table_by_interface_t *mp;
12361
12362   u32 sw_if_index = ~0;
12363   int ret;
12364   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12365     {
12366       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12367         ;
12368       else if (unformat (input, "sw_if_index %d", &sw_if_index))
12369         ;
12370       else
12371         break;
12372     }
12373   if (sw_if_index == ~0)
12374     {
12375       errmsg ("missing interface name or sw_if_index");
12376       return -99;
12377     }
12378
12379   /* Construct the API message */
12380   M (CLASSIFY_TABLE_BY_INTERFACE, mp);
12381   mp->context = 0;
12382   mp->sw_if_index = ntohl (sw_if_index);
12383
12384   S (mp);
12385   W (ret);
12386   return ret;
12387 }
12388
12389 int
12390 api_classify_table_info (vat_main_t * vam)
12391 {
12392   unformat_input_t *input = vam->input;
12393   vl_api_classify_table_info_t *mp;
12394
12395   u32 table_id = ~0;
12396   int ret;
12397   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12398     {
12399       if (unformat (input, "table_id %d", &table_id))
12400         ;
12401       else
12402         break;
12403     }
12404   if (table_id == ~0)
12405     {
12406       errmsg ("missing table id");
12407       return -99;
12408     }
12409
12410   /* Construct the API message */
12411   M (CLASSIFY_TABLE_INFO, mp);
12412   mp->context = 0;
12413   mp->table_id = ntohl (table_id);
12414
12415   S (mp);
12416   W (ret);
12417   return ret;
12418 }
12419
12420 int
12421 api_classify_session_dump (vat_main_t * vam)
12422 {
12423   unformat_input_t *input = vam->input;
12424   vl_api_classify_session_dump_t *mp;
12425   vl_api_control_ping_t *mp_ping;
12426
12427   u32 table_id = ~0;
12428   int ret;
12429   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12430     {
12431       if (unformat (input, "table_id %d", &table_id))
12432         ;
12433       else
12434         break;
12435     }
12436   if (table_id == ~0)
12437     {
12438       errmsg ("missing table id");
12439       return -99;
12440     }
12441
12442   /* Construct the API message */
12443   M (CLASSIFY_SESSION_DUMP, mp);
12444   mp->context = 0;
12445   mp->table_id = ntohl (table_id);
12446   S (mp);
12447
12448   /* Use a control ping for synchronization */
12449   MPING (CONTROL_PING, mp_ping);
12450   S (mp_ping);
12451
12452   W (ret);
12453   return ret;
12454 }
12455
12456 static void
12457 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
12458 {
12459   vat_main_t *vam = &vat_main;
12460
12461   print (vam->ofp, "collector_address %U, collector_port %d, "
12462          "src_address %U, vrf_id %d, path_mtu %u, "
12463          "template_interval %u, udp_checksum %d",
12464          format_ip4_address, mp->collector_address,
12465          ntohs (mp->collector_port),
12466          format_ip4_address, mp->src_address,
12467          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
12468          ntohl (mp->template_interval), mp->udp_checksum);
12469
12470   vam->retval = 0;
12471   vam->result_ready = 1;
12472 }
12473
12474 static void
12475   vl_api_ipfix_exporter_details_t_handler_json
12476   (vl_api_ipfix_exporter_details_t * mp)
12477 {
12478   vat_main_t *vam = &vat_main;
12479   vat_json_node_t node;
12480   struct in_addr collector_address;
12481   struct in_addr src_address;
12482
12483   vat_json_init_object (&node);
12484   clib_memcpy (&collector_address, &mp->collector_address,
12485                sizeof (collector_address));
12486   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
12487   vat_json_object_add_uint (&node, "collector_port",
12488                             ntohs (mp->collector_port));
12489   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
12490   vat_json_object_add_ip4 (&node, "src_address", src_address);
12491   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
12492   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
12493   vat_json_object_add_uint (&node, "template_interval",
12494                             ntohl (mp->template_interval));
12495   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
12496
12497   vat_json_print (vam->ofp, &node);
12498   vat_json_free (&node);
12499   vam->retval = 0;
12500   vam->result_ready = 1;
12501 }
12502
12503 int
12504 api_ipfix_exporter_dump (vat_main_t * vam)
12505 {
12506   vl_api_ipfix_exporter_dump_t *mp;
12507   int ret;
12508
12509   /* Construct the API message */
12510   M (IPFIX_EXPORTER_DUMP, mp);
12511   mp->context = 0;
12512
12513   S (mp);
12514   W (ret);
12515   return ret;
12516 }
12517
12518 static int
12519 api_ipfix_classify_stream_dump (vat_main_t * vam)
12520 {
12521   vl_api_ipfix_classify_stream_dump_t *mp;
12522   int ret;
12523
12524   /* Construct the API message */
12525   M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
12526   mp->context = 0;
12527
12528   S (mp);
12529   W (ret);
12530   return ret;
12531   /* NOTREACHED */
12532   return 0;
12533 }
12534
12535 static void
12536   vl_api_ipfix_classify_stream_details_t_handler
12537   (vl_api_ipfix_classify_stream_details_t * mp)
12538 {
12539   vat_main_t *vam = &vat_main;
12540   print (vam->ofp, "domain_id %d, src_port %d",
12541          ntohl (mp->domain_id), ntohs (mp->src_port));
12542   vam->retval = 0;
12543   vam->result_ready = 1;
12544 }
12545
12546 static void
12547   vl_api_ipfix_classify_stream_details_t_handler_json
12548   (vl_api_ipfix_classify_stream_details_t * mp)
12549 {
12550   vat_main_t *vam = &vat_main;
12551   vat_json_node_t node;
12552
12553   vat_json_init_object (&node);
12554   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
12555   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
12556
12557   vat_json_print (vam->ofp, &node);
12558   vat_json_free (&node);
12559   vam->retval = 0;
12560   vam->result_ready = 1;
12561 }
12562
12563 static int
12564 api_ipfix_classify_table_dump (vat_main_t * vam)
12565 {
12566   vl_api_ipfix_classify_table_dump_t *mp;
12567   vl_api_control_ping_t *mp_ping;
12568   int ret;
12569
12570   if (!vam->json_output)
12571     {
12572       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
12573              "transport_protocol");
12574     }
12575
12576   /* Construct the API message */
12577   M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
12578
12579   /* send it... */
12580   S (mp);
12581
12582   /* Use a control ping for synchronization */
12583   MPING (CONTROL_PING, mp_ping);
12584   S (mp_ping);
12585
12586   W (ret);
12587   return ret;
12588 }
12589
12590 static void
12591   vl_api_ipfix_classify_table_details_t_handler
12592   (vl_api_ipfix_classify_table_details_t * mp)
12593 {
12594   vat_main_t *vam = &vat_main;
12595   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
12596          mp->transport_protocol);
12597 }
12598
12599 static void
12600   vl_api_ipfix_classify_table_details_t_handler_json
12601   (vl_api_ipfix_classify_table_details_t * mp)
12602 {
12603   vat_json_node_t *node = NULL;
12604   vat_main_t *vam = &vat_main;
12605
12606   if (VAT_JSON_ARRAY != vam->json_tree.type)
12607     {
12608       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12609       vat_json_init_array (&vam->json_tree);
12610     }
12611
12612   node = vat_json_array_add (&vam->json_tree);
12613   vat_json_init_object (node);
12614
12615   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
12616   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
12617   vat_json_object_add_uint (node, "transport_protocol",
12618                             mp->transport_protocol);
12619 }
12620
12621 static int
12622 api_sw_interface_span_enable_disable (vat_main_t * vam)
12623 {
12624   unformat_input_t *i = vam->input;
12625   vl_api_sw_interface_span_enable_disable_t *mp;
12626   u32 src_sw_if_index = ~0;
12627   u32 dst_sw_if_index = ~0;
12628   u8 state = 3;
12629   int ret;
12630   u8 is_l2 = 0;
12631
12632   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12633     {
12634       if (unformat
12635           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
12636         ;
12637       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
12638         ;
12639       else
12640         if (unformat
12641             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
12642         ;
12643       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
12644         ;
12645       else if (unformat (i, "disable"))
12646         state = 0;
12647       else if (unformat (i, "rx"))
12648         state = 1;
12649       else if (unformat (i, "tx"))
12650         state = 2;
12651       else if (unformat (i, "both"))
12652         state = 3;
12653       else if (unformat (i, "l2"))
12654         is_l2 = 1;
12655       else
12656         break;
12657     }
12658
12659   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
12660
12661   mp->sw_if_index_from = htonl (src_sw_if_index);
12662   mp->sw_if_index_to = htonl (dst_sw_if_index);
12663   mp->state = state;
12664   mp->is_l2 = is_l2;
12665
12666   S (mp);
12667   W (ret);
12668   return ret;
12669 }
12670
12671 static void
12672 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
12673                                             * mp)
12674 {
12675   vat_main_t *vam = &vat_main;
12676   u8 *sw_if_from_name = 0;
12677   u8 *sw_if_to_name = 0;
12678   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
12679   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
12680   char *states[] = { "none", "rx", "tx", "both" };
12681   hash_pair_t *p;
12682
12683   /* *INDENT-OFF* */
12684   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
12685   ({
12686     if ((u32) p->value[0] == sw_if_index_from)
12687       {
12688         sw_if_from_name = (u8 *)(p->key);
12689         if (sw_if_to_name)
12690           break;
12691       }
12692     if ((u32) p->value[0] == sw_if_index_to)
12693       {
12694         sw_if_to_name = (u8 *)(p->key);
12695         if (sw_if_from_name)
12696           break;
12697       }
12698   }));
12699   /* *INDENT-ON* */
12700   print (vam->ofp, "%20s => %20s (%s) %s",
12701          sw_if_from_name, sw_if_to_name, states[mp->state],
12702          mp->is_l2 ? "l2" : "device");
12703 }
12704
12705 static void
12706   vl_api_sw_interface_span_details_t_handler_json
12707   (vl_api_sw_interface_span_details_t * mp)
12708 {
12709   vat_main_t *vam = &vat_main;
12710   vat_json_node_t *node = NULL;
12711   u8 *sw_if_from_name = 0;
12712   u8 *sw_if_to_name = 0;
12713   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
12714   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
12715   hash_pair_t *p;
12716
12717   /* *INDENT-OFF* */
12718   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
12719   ({
12720     if ((u32) p->value[0] == sw_if_index_from)
12721       {
12722         sw_if_from_name = (u8 *)(p->key);
12723         if (sw_if_to_name)
12724           break;
12725       }
12726     if ((u32) p->value[0] == sw_if_index_to)
12727       {
12728         sw_if_to_name = (u8 *)(p->key);
12729         if (sw_if_from_name)
12730           break;
12731       }
12732   }));
12733   /* *INDENT-ON* */
12734
12735   if (VAT_JSON_ARRAY != vam->json_tree.type)
12736     {
12737       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12738       vat_json_init_array (&vam->json_tree);
12739     }
12740   node = vat_json_array_add (&vam->json_tree);
12741
12742   vat_json_init_object (node);
12743   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
12744   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
12745   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
12746   if (0 != sw_if_to_name)
12747     {
12748       vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
12749     }
12750   vat_json_object_add_uint (node, "state", mp->state);
12751   vat_json_object_add_uint (node, "is-l2", mp->is_l2);
12752 }
12753
12754 static int
12755 api_sw_interface_span_dump (vat_main_t * vam)
12756 {
12757   unformat_input_t *input = vam->input;
12758   vl_api_sw_interface_span_dump_t *mp;
12759   vl_api_control_ping_t *mp_ping;
12760   u8 is_l2 = 0;
12761   int ret;
12762
12763   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12764     {
12765       if (unformat (input, "l2"))
12766         is_l2 = 1;
12767       else
12768         break;
12769     }
12770
12771   M (SW_INTERFACE_SPAN_DUMP, mp);
12772   mp->is_l2 = is_l2;
12773   S (mp);
12774
12775   /* Use a control ping for synchronization */
12776   MPING (CONTROL_PING, mp_ping);
12777   S (mp_ping);
12778
12779   W (ret);
12780   return ret;
12781 }
12782
12783 int
12784 api_pg_create_interface (vat_main_t * vam)
12785 {
12786   unformat_input_t *input = vam->input;
12787   vl_api_pg_create_interface_t *mp;
12788
12789   u32 if_id = ~0, gso_size = 0;
12790   u8 gso_enabled = 0;
12791   int ret;
12792   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12793     {
12794       if (unformat (input, "if_id %d", &if_id))
12795         ;
12796       else if (unformat (input, "gso-enabled"))
12797         {
12798           gso_enabled = 1;
12799           if (unformat (input, "gso-size %u", &gso_size))
12800             ;
12801           else
12802             {
12803               errmsg ("missing gso-size");
12804               return -99;
12805             }
12806         }
12807       else
12808         break;
12809     }
12810   if (if_id == ~0)
12811     {
12812       errmsg ("missing pg interface index");
12813       return -99;
12814     }
12815
12816   /* Construct the API message */
12817   M (PG_CREATE_INTERFACE, mp);
12818   mp->context = 0;
12819   mp->interface_id = ntohl (if_id);
12820   mp->gso_enabled = gso_enabled;
12821
12822   S (mp);
12823   W (ret);
12824   return ret;
12825 }
12826
12827 int
12828 api_pg_capture (vat_main_t * vam)
12829 {
12830   unformat_input_t *input = vam->input;
12831   vl_api_pg_capture_t *mp;
12832
12833   u32 if_id = ~0;
12834   u8 enable = 1;
12835   u32 count = 1;
12836   u8 pcap_file_set = 0;
12837   u8 *pcap_file = 0;
12838   int ret;
12839   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12840     {
12841       if (unformat (input, "if_id %d", &if_id))
12842         ;
12843       else if (unformat (input, "pcap %s", &pcap_file))
12844         pcap_file_set = 1;
12845       else if (unformat (input, "count %d", &count))
12846         ;
12847       else if (unformat (input, "disable"))
12848         enable = 0;
12849       else
12850         break;
12851     }
12852   if (if_id == ~0)
12853     {
12854       errmsg ("missing pg interface index");
12855       return -99;
12856     }
12857   if (pcap_file_set > 0)
12858     {
12859       if (vec_len (pcap_file) > 255)
12860         {
12861           errmsg ("pcap file name is too long");
12862           return -99;
12863         }
12864     }
12865
12866   /* Construct the API message */
12867   M (PG_CAPTURE, mp);
12868   mp->context = 0;
12869   mp->interface_id = ntohl (if_id);
12870   mp->is_enabled = enable;
12871   mp->count = ntohl (count);
12872   if (pcap_file_set != 0)
12873     {
12874       vl_api_vec_to_api_string (pcap_file, &mp->pcap_file_name);
12875     }
12876   vec_free (pcap_file);
12877
12878   S (mp);
12879   W (ret);
12880   return ret;
12881 }
12882
12883 int
12884 api_pg_enable_disable (vat_main_t * vam)
12885 {
12886   unformat_input_t *input = vam->input;
12887   vl_api_pg_enable_disable_t *mp;
12888
12889   u8 enable = 1;
12890   u8 stream_name_set = 0;
12891   u8 *stream_name = 0;
12892   int ret;
12893   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12894     {
12895       if (unformat (input, "stream %s", &stream_name))
12896         stream_name_set = 1;
12897       else if (unformat (input, "disable"))
12898         enable = 0;
12899       else
12900         break;
12901     }
12902
12903   if (stream_name_set > 0)
12904     {
12905       if (vec_len (stream_name) > 255)
12906         {
12907           errmsg ("stream name too long");
12908           return -99;
12909         }
12910     }
12911
12912   /* Construct the API message */
12913   M (PG_ENABLE_DISABLE, mp);
12914   mp->context = 0;
12915   mp->is_enabled = enable;
12916   if (stream_name_set != 0)
12917     {
12918       vl_api_vec_to_api_string (stream_name, &mp->stream_name);
12919     }
12920   vec_free (stream_name);
12921
12922   S (mp);
12923   W (ret);
12924   return ret;
12925 }
12926
12927 int
12928 api_pg_interface_enable_disable_coalesce (vat_main_t * vam)
12929 {
12930   unformat_input_t *input = vam->input;
12931   vl_api_pg_interface_enable_disable_coalesce_t *mp;
12932
12933   u32 sw_if_index = ~0;
12934   u8 enable = 1;
12935   int ret;
12936   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12937     {
12938       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12939         ;
12940       else if (unformat (input, "sw_if_index %d", &sw_if_index))
12941         ;
12942       else if (unformat (input, "disable"))
12943         enable = 0;
12944       else
12945         break;
12946     }
12947
12948   if (sw_if_index == ~0)
12949     {
12950       errmsg ("Interface required but not specified");
12951       return -99;
12952     }
12953
12954   /* Construct the API message */
12955   M (PG_INTERFACE_ENABLE_DISABLE_COALESCE, mp);
12956   mp->context = 0;
12957   mp->coalesce_enabled = enable;
12958   mp->sw_if_index = htonl (sw_if_index);
12959
12960   S (mp);
12961   W (ret);
12962   return ret;
12963 }
12964
12965 int
12966 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
12967 {
12968   unformat_input_t *input = vam->input;
12969   vl_api_ip_source_and_port_range_check_add_del_t *mp;
12970
12971   u16 *low_ports = 0;
12972   u16 *high_ports = 0;
12973   u16 this_low;
12974   u16 this_hi;
12975   vl_api_prefix_t prefix;
12976   u32 tmp, tmp2;
12977   u8 prefix_set = 0;
12978   u32 vrf_id = ~0;
12979   u8 is_add = 1;
12980   int ret;
12981
12982   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12983     {
12984       if (unformat (input, "%U", unformat_vl_api_prefix, &prefix))
12985         prefix_set = 1;
12986       else if (unformat (input, "vrf %d", &vrf_id))
12987         ;
12988       else if (unformat (input, "del"))
12989         is_add = 0;
12990       else if (unformat (input, "port %d", &tmp))
12991         {
12992           if (tmp == 0 || tmp > 65535)
12993             {
12994               errmsg ("port %d out of range", tmp);
12995               return -99;
12996             }
12997           this_low = tmp;
12998           this_hi = this_low + 1;
12999           vec_add1 (low_ports, this_low);
13000           vec_add1 (high_ports, this_hi);
13001         }
13002       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
13003         {
13004           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
13005             {
13006               errmsg ("incorrect range parameters");
13007               return -99;
13008             }
13009           this_low = tmp;
13010           /* Note: in debug CLI +1 is added to high before
13011              passing to real fn that does "the work"
13012              (ip_source_and_port_range_check_add_del).
13013              This fn is a wrapper around the binary API fn a
13014              control plane will call, which expects this increment
13015              to have occurred. Hence letting the binary API control
13016              plane fn do the increment for consistency between VAT
13017              and other control planes.
13018            */
13019           this_hi = tmp2;
13020           vec_add1 (low_ports, this_low);
13021           vec_add1 (high_ports, this_hi);
13022         }
13023       else
13024         break;
13025     }
13026
13027   if (prefix_set == 0)
13028     {
13029       errmsg ("<address>/<mask> not specified");
13030       return -99;
13031     }
13032
13033   if (vrf_id == ~0)
13034     {
13035       errmsg ("VRF ID required, not specified");
13036       return -99;
13037     }
13038
13039   if (vrf_id == 0)
13040     {
13041       errmsg
13042         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
13043       return -99;
13044     }
13045
13046   if (vec_len (low_ports) == 0)
13047     {
13048       errmsg ("At least one port or port range required");
13049       return -99;
13050     }
13051
13052   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
13053
13054   mp->is_add = is_add;
13055
13056   clib_memcpy (&mp->prefix, &prefix, sizeof (prefix));
13057
13058   mp->number_of_ranges = vec_len (low_ports);
13059
13060   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
13061   vec_free (low_ports);
13062
13063   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
13064   vec_free (high_ports);
13065
13066   mp->vrf_id = ntohl (vrf_id);
13067
13068   S (mp);
13069   W (ret);
13070   return ret;
13071 }
13072
13073 int
13074 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
13075 {
13076   unformat_input_t *input = vam->input;
13077   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
13078   u32 sw_if_index = ~0;
13079   int vrf_set = 0;
13080   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
13081   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
13082   u8 is_add = 1;
13083   int ret;
13084
13085   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13086     {
13087       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13088         ;
13089       else if (unformat (input, "sw_if_index %d", &sw_if_index))
13090         ;
13091       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
13092         vrf_set = 1;
13093       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
13094         vrf_set = 1;
13095       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
13096         vrf_set = 1;
13097       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
13098         vrf_set = 1;
13099       else if (unformat (input, "del"))
13100         is_add = 0;
13101       else
13102         break;
13103     }
13104
13105   if (sw_if_index == ~0)
13106     {
13107       errmsg ("Interface required but not specified");
13108       return -99;
13109     }
13110
13111   if (vrf_set == 0)
13112     {
13113       errmsg ("VRF ID required but not specified");
13114       return -99;
13115     }
13116
13117   if (tcp_out_vrf_id == 0
13118       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
13119     {
13120       errmsg
13121         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
13122       return -99;
13123     }
13124
13125   /* Construct the API message */
13126   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
13127
13128   mp->sw_if_index = ntohl (sw_if_index);
13129   mp->is_add = is_add;
13130   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
13131   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
13132   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
13133   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
13134
13135   /* send it... */
13136   S (mp);
13137
13138   /* Wait for a reply... */
13139   W (ret);
13140   return ret;
13141 }
13142
13143 static int
13144 api_set_punt (vat_main_t * vam)
13145 {
13146   unformat_input_t *i = vam->input;
13147   vl_api_address_family_t af;
13148   vl_api_set_punt_t *mp;
13149   u32 protocol = ~0;
13150   u32 port = ~0;
13151   int is_add = 1;
13152   int ret;
13153
13154   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13155     {
13156       if (unformat (i, "%U", unformat_vl_api_address_family, &af))
13157         ;
13158       else if (unformat (i, "protocol %d", &protocol))
13159         ;
13160       else if (unformat (i, "port %d", &port))
13161         ;
13162       else if (unformat (i, "del"))
13163         is_add = 0;
13164       else
13165         {
13166           clib_warning ("parse error '%U'", format_unformat_error, i);
13167           return -99;
13168         }
13169     }
13170
13171   M (SET_PUNT, mp);
13172
13173   mp->is_add = (u8) is_add;
13174   mp->punt.type = PUNT_API_TYPE_L4;
13175   mp->punt.punt.l4.af = af;
13176   mp->punt.punt.l4.protocol = (u8) protocol;
13177   mp->punt.punt.l4.port = htons ((u16) port);
13178
13179   S (mp);
13180   W (ret);
13181   return ret;
13182 }
13183
13184 static int
13185 api_delete_subif (vat_main_t * vam)
13186 {
13187   unformat_input_t *i = vam->input;
13188   vl_api_delete_subif_t *mp;
13189   u32 sw_if_index = ~0;
13190   int ret;
13191
13192   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13193     {
13194       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13195         ;
13196       if (unformat (i, "sw_if_index %d", &sw_if_index))
13197         ;
13198       else
13199         break;
13200     }
13201
13202   if (sw_if_index == ~0)
13203     {
13204       errmsg ("missing sw_if_index");
13205       return -99;
13206     }
13207
13208   /* Construct the API message */
13209   M (DELETE_SUBIF, mp);
13210   mp->sw_if_index = ntohl (sw_if_index);
13211
13212   S (mp);
13213   W (ret);
13214   return ret;
13215 }
13216
13217 #define foreach_pbb_vtr_op      \
13218 _("disable",  L2_VTR_DISABLED)  \
13219 _("pop",  L2_VTR_POP_2)         \
13220 _("push",  L2_VTR_PUSH_2)
13221
13222 static int
13223 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
13224 {
13225   unformat_input_t *i = vam->input;
13226   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
13227   u32 sw_if_index = ~0, vtr_op = ~0;
13228   u16 outer_tag = ~0;
13229   u8 dmac[6], smac[6];
13230   u8 dmac_set = 0, smac_set = 0;
13231   u16 vlanid = 0;
13232   u32 sid = ~0;
13233   u32 tmp;
13234   int ret;
13235
13236   /* Shut up coverity */
13237   clib_memset (dmac, 0, sizeof (dmac));
13238   clib_memset (smac, 0, sizeof (smac));
13239
13240   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13241     {
13242       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13243         ;
13244       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13245         ;
13246       else if (unformat (i, "vtr_op %d", &vtr_op))
13247         ;
13248 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
13249       foreach_pbb_vtr_op
13250 #undef _
13251         else if (unformat (i, "translate_pbb_stag"))
13252         {
13253           if (unformat (i, "%d", &tmp))
13254             {
13255               vtr_op = L2_VTR_TRANSLATE_2_1;
13256               outer_tag = tmp;
13257             }
13258           else
13259             {
13260               errmsg
13261                 ("translate_pbb_stag operation requires outer tag definition");
13262               return -99;
13263             }
13264         }
13265       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
13266         dmac_set++;
13267       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
13268         smac_set++;
13269       else if (unformat (i, "sid %d", &sid))
13270         ;
13271       else if (unformat (i, "vlanid %d", &tmp))
13272         vlanid = tmp;
13273       else
13274         {
13275           clib_warning ("parse error '%U'", format_unformat_error, i);
13276           return -99;
13277         }
13278     }
13279
13280   if ((sw_if_index == ~0) || (vtr_op == ~0))
13281     {
13282       errmsg ("missing sw_if_index or vtr operation");
13283       return -99;
13284     }
13285   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
13286       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
13287     {
13288       errmsg
13289         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
13290       return -99;
13291     }
13292
13293   M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
13294   mp->sw_if_index = ntohl (sw_if_index);
13295   mp->vtr_op = ntohl (vtr_op);
13296   mp->outer_tag = ntohs (outer_tag);
13297   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
13298   clib_memcpy (mp->b_smac, smac, sizeof (smac));
13299   mp->b_vlanid = ntohs (vlanid);
13300   mp->i_sid = ntohl (sid);
13301
13302   S (mp);
13303   W (ret);
13304   return ret;
13305 }
13306
13307 static int
13308 api_flow_classify_set_interface (vat_main_t * vam)
13309 {
13310   unformat_input_t *i = vam->input;
13311   vl_api_flow_classify_set_interface_t *mp;
13312   u32 sw_if_index;
13313   int sw_if_index_set;
13314   u32 ip4_table_index = ~0;
13315   u32 ip6_table_index = ~0;
13316   u8 is_add = 1;
13317   int ret;
13318
13319   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13320     {
13321       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13322         sw_if_index_set = 1;
13323       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13324         sw_if_index_set = 1;
13325       else if (unformat (i, "del"))
13326         is_add = 0;
13327       else if (unformat (i, "ip4-table %d", &ip4_table_index))
13328         ;
13329       else if (unformat (i, "ip6-table %d", &ip6_table_index))
13330         ;
13331       else
13332         {
13333           clib_warning ("parse error '%U'", format_unformat_error, i);
13334           return -99;
13335         }
13336     }
13337
13338   if (sw_if_index_set == 0)
13339     {
13340       errmsg ("missing interface name or sw_if_index");
13341       return -99;
13342     }
13343
13344   M (FLOW_CLASSIFY_SET_INTERFACE, mp);
13345
13346   mp->sw_if_index = ntohl (sw_if_index);
13347   mp->ip4_table_index = ntohl (ip4_table_index);
13348   mp->ip6_table_index = ntohl (ip6_table_index);
13349   mp->is_add = is_add;
13350
13351   S (mp);
13352   W (ret);
13353   return ret;
13354 }
13355
13356 static int
13357 api_flow_classify_dump (vat_main_t * vam)
13358 {
13359   unformat_input_t *i = vam->input;
13360   vl_api_flow_classify_dump_t *mp;
13361   vl_api_control_ping_t *mp_ping;
13362   u8 type = FLOW_CLASSIFY_N_TABLES;
13363   int ret;
13364
13365   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
13366     ;
13367   else
13368     {
13369       errmsg ("classify table type must be specified");
13370       return -99;
13371     }
13372
13373   if (!vam->json_output)
13374     {
13375       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
13376     }
13377
13378   M (FLOW_CLASSIFY_DUMP, mp);
13379   mp->type = type;
13380   /* send it... */
13381   S (mp);
13382
13383   /* Use a control ping for synchronization */
13384   MPING (CONTROL_PING, mp_ping);
13385   S (mp_ping);
13386
13387   /* Wait for a reply... */
13388   W (ret);
13389   return ret;
13390 }
13391
13392 static int
13393 api_feature_enable_disable (vat_main_t * vam)
13394 {
13395   unformat_input_t *i = vam->input;
13396   vl_api_feature_enable_disable_t *mp;
13397   u8 *arc_name = 0;
13398   u8 *feature_name = 0;
13399   u32 sw_if_index = ~0;
13400   u8 enable = 1;
13401   int ret;
13402
13403   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13404     {
13405       if (unformat (i, "arc_name %s", &arc_name))
13406         ;
13407       else if (unformat (i, "feature_name %s", &feature_name))
13408         ;
13409       else
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 if (unformat (i, "disable"))
13415         enable = 0;
13416       else
13417         break;
13418     }
13419
13420   if (arc_name == 0)
13421     {
13422       errmsg ("missing arc name");
13423       return -99;
13424     }
13425   if (vec_len (arc_name) > 63)
13426     {
13427       errmsg ("arc name too long");
13428     }
13429
13430   if (feature_name == 0)
13431     {
13432       errmsg ("missing feature name");
13433       return -99;
13434     }
13435   if (vec_len (feature_name) > 63)
13436     {
13437       errmsg ("feature name too long");
13438     }
13439
13440   if (sw_if_index == ~0)
13441     {
13442       errmsg ("missing interface name or sw_if_index");
13443       return -99;
13444     }
13445
13446   /* Construct the API message */
13447   M (FEATURE_ENABLE_DISABLE, mp);
13448   mp->sw_if_index = ntohl (sw_if_index);
13449   mp->enable = enable;
13450   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
13451   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
13452   vec_free (arc_name);
13453   vec_free (feature_name);
13454
13455   S (mp);
13456   W (ret);
13457   return ret;
13458 }
13459
13460 static int
13461 api_feature_gso_enable_disable (vat_main_t * vam)
13462 {
13463   unformat_input_t *i = vam->input;
13464   vl_api_feature_gso_enable_disable_t *mp;
13465   u32 sw_if_index = ~0;
13466   u8 enable = 1;
13467   int ret;
13468
13469   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13470     {
13471       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13472         ;
13473       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13474         ;
13475       else if (unformat (i, "enable"))
13476         enable = 1;
13477       else if (unformat (i, "disable"))
13478         enable = 0;
13479       else
13480         break;
13481     }
13482
13483   if (sw_if_index == ~0)
13484     {
13485       errmsg ("missing interface name or sw_if_index");
13486       return -99;
13487     }
13488
13489   /* Construct the API message */
13490   M (FEATURE_GSO_ENABLE_DISABLE, mp);
13491   mp->sw_if_index = ntohl (sw_if_index);
13492   mp->enable_disable = enable;
13493
13494   S (mp);
13495   W (ret);
13496   return ret;
13497 }
13498
13499 static int
13500 api_sw_interface_tag_add_del (vat_main_t * vam)
13501 {
13502   unformat_input_t *i = vam->input;
13503   vl_api_sw_interface_tag_add_del_t *mp;
13504   u32 sw_if_index = ~0;
13505   u8 *tag = 0;
13506   u8 enable = 1;
13507   int ret;
13508
13509   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13510     {
13511       if (unformat (i, "tag %s", &tag))
13512         ;
13513       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13514         ;
13515       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13516         ;
13517       else if (unformat (i, "del"))
13518         enable = 0;
13519       else
13520         break;
13521     }
13522
13523   if (sw_if_index == ~0)
13524     {
13525       errmsg ("missing interface name or sw_if_index");
13526       return -99;
13527     }
13528
13529   if (enable && (tag == 0))
13530     {
13531       errmsg ("no tag specified");
13532       return -99;
13533     }
13534
13535   /* Construct the API message */
13536   M (SW_INTERFACE_TAG_ADD_DEL, mp);
13537   mp->sw_if_index = ntohl (sw_if_index);
13538   mp->is_add = enable;
13539   if (enable)
13540     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
13541   vec_free (tag);
13542
13543   S (mp);
13544   W (ret);
13545   return ret;
13546 }
13547
13548 static int
13549 api_sw_interface_add_del_mac_address (vat_main_t * vam)
13550 {
13551   unformat_input_t *i = vam->input;
13552   vl_api_mac_address_t mac = { 0 };
13553   vl_api_sw_interface_add_del_mac_address_t *mp;
13554   u32 sw_if_index = ~0;
13555   u8 is_add = 1;
13556   u8 mac_set = 0;
13557   int ret;
13558
13559   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13560     {
13561       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13562         ;
13563       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13564         ;
13565       else if (unformat (i, "%U", unformat_vl_api_mac_address, &mac))
13566         mac_set++;
13567       else if (unformat (i, "del"))
13568         is_add = 0;
13569       else
13570         break;
13571     }
13572
13573   if (sw_if_index == ~0)
13574     {
13575       errmsg ("missing interface name or sw_if_index");
13576       return -99;
13577     }
13578
13579   if (!mac_set)
13580     {
13581       errmsg ("missing MAC address");
13582       return -99;
13583     }
13584
13585   /* Construct the API message */
13586   M (SW_INTERFACE_ADD_DEL_MAC_ADDRESS, mp);
13587   mp->sw_if_index = ntohl (sw_if_index);
13588   mp->is_add = is_add;
13589   clib_memcpy (&mp->addr, &mac, sizeof (mac));
13590
13591   S (mp);
13592   W (ret);
13593   return ret;
13594 }
13595
13596 static void vl_api_l2_xconnect_details_t_handler
13597   (vl_api_l2_xconnect_details_t * mp)
13598 {
13599   vat_main_t *vam = &vat_main;
13600
13601   print (vam->ofp, "%15d%15d",
13602          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
13603 }
13604
13605 static void vl_api_l2_xconnect_details_t_handler_json
13606   (vl_api_l2_xconnect_details_t * mp)
13607 {
13608   vat_main_t *vam = &vat_main;
13609   vat_json_node_t *node = NULL;
13610
13611   if (VAT_JSON_ARRAY != vam->json_tree.type)
13612     {
13613       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13614       vat_json_init_array (&vam->json_tree);
13615     }
13616   node = vat_json_array_add (&vam->json_tree);
13617
13618   vat_json_init_object (node);
13619   vat_json_object_add_uint (node, "rx_sw_if_index",
13620                             ntohl (mp->rx_sw_if_index));
13621   vat_json_object_add_uint (node, "tx_sw_if_index",
13622                             ntohl (mp->tx_sw_if_index));
13623 }
13624
13625 static int
13626 api_l2_xconnect_dump (vat_main_t * vam)
13627 {
13628   vl_api_l2_xconnect_dump_t *mp;
13629   vl_api_control_ping_t *mp_ping;
13630   int ret;
13631
13632   if (!vam->json_output)
13633     {
13634       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
13635     }
13636
13637   M (L2_XCONNECT_DUMP, mp);
13638
13639   S (mp);
13640
13641   /* Use a control ping for synchronization */
13642   MPING (CONTROL_PING, mp_ping);
13643   S (mp_ping);
13644
13645   W (ret);
13646   return ret;
13647 }
13648
13649 static int
13650 api_hw_interface_set_mtu (vat_main_t * vam)
13651 {
13652   unformat_input_t *i = vam->input;
13653   vl_api_hw_interface_set_mtu_t *mp;
13654   u32 sw_if_index = ~0;
13655   u32 mtu = 0;
13656   int ret;
13657
13658   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13659     {
13660       if (unformat (i, "mtu %d", &mtu))
13661         ;
13662       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13663         ;
13664       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13665         ;
13666       else
13667         break;
13668     }
13669
13670   if (sw_if_index == ~0)
13671     {
13672       errmsg ("missing interface name or sw_if_index");
13673       return -99;
13674     }
13675
13676   if (mtu == 0)
13677     {
13678       errmsg ("no mtu specified");
13679       return -99;
13680     }
13681
13682   /* Construct the API message */
13683   M (HW_INTERFACE_SET_MTU, mp);
13684   mp->sw_if_index = ntohl (sw_if_index);
13685   mp->mtu = ntohs ((u16) mtu);
13686
13687   S (mp);
13688   W (ret);
13689   return ret;
13690 }
13691
13692 static int
13693 api_p2p_ethernet_add (vat_main_t * vam)
13694 {
13695   unformat_input_t *i = vam->input;
13696   vl_api_p2p_ethernet_add_t *mp;
13697   u32 parent_if_index = ~0;
13698   u32 sub_id = ~0;
13699   u8 remote_mac[6];
13700   u8 mac_set = 0;
13701   int ret;
13702
13703   clib_memset (remote_mac, 0, sizeof (remote_mac));
13704   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13705     {
13706       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
13707         ;
13708       else if (unformat (i, "sw_if_index %d", &parent_if_index))
13709         ;
13710       else
13711         if (unformat
13712             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
13713         mac_set++;
13714       else if (unformat (i, "sub_id %d", &sub_id))
13715         ;
13716       else
13717         {
13718           clib_warning ("parse error '%U'", format_unformat_error, i);
13719           return -99;
13720         }
13721     }
13722
13723   if (parent_if_index == ~0)
13724     {
13725       errmsg ("missing interface name or sw_if_index");
13726       return -99;
13727     }
13728   if (mac_set == 0)
13729     {
13730       errmsg ("missing remote mac address");
13731       return -99;
13732     }
13733   if (sub_id == ~0)
13734     {
13735       errmsg ("missing sub-interface id");
13736       return -99;
13737     }
13738
13739   M (P2P_ETHERNET_ADD, mp);
13740   mp->parent_if_index = ntohl (parent_if_index);
13741   mp->subif_id = ntohl (sub_id);
13742   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
13743
13744   S (mp);
13745   W (ret);
13746   return ret;
13747 }
13748
13749 static int
13750 api_p2p_ethernet_del (vat_main_t * vam)
13751 {
13752   unformat_input_t *i = vam->input;
13753   vl_api_p2p_ethernet_del_t *mp;
13754   u32 parent_if_index = ~0;
13755   u8 remote_mac[6];
13756   u8 mac_set = 0;
13757   int ret;
13758
13759   clib_memset (remote_mac, 0, sizeof (remote_mac));
13760   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13761     {
13762       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
13763         ;
13764       else if (unformat (i, "sw_if_index %d", &parent_if_index))
13765         ;
13766       else
13767         if (unformat
13768             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
13769         mac_set++;
13770       else
13771         {
13772           clib_warning ("parse error '%U'", format_unformat_error, i);
13773           return -99;
13774         }
13775     }
13776
13777   if (parent_if_index == ~0)
13778     {
13779       errmsg ("missing interface name or sw_if_index");
13780       return -99;
13781     }
13782   if (mac_set == 0)
13783     {
13784       errmsg ("missing remote mac address");
13785       return -99;
13786     }
13787
13788   M (P2P_ETHERNET_DEL, mp);
13789   mp->parent_if_index = ntohl (parent_if_index);
13790   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
13791
13792   S (mp);
13793   W (ret);
13794   return ret;
13795 }
13796
13797 static int
13798 api_tcp_configure_src_addresses (vat_main_t * vam)
13799 {
13800   vl_api_tcp_configure_src_addresses_t *mp;
13801   unformat_input_t *i = vam->input;
13802   vl_api_address_t first, last;
13803   u8 range_set = 0;
13804   u32 vrf_id = 0;
13805   int ret;
13806
13807   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13808     {
13809       if (unformat (i, "%U - %U",
13810                     unformat_vl_api_address, &first,
13811                     unformat_vl_api_address, &last))
13812         {
13813           if (range_set)
13814             {
13815               errmsg ("one range per message (range already set)");
13816               return -99;
13817             }
13818           range_set = 1;
13819         }
13820       else if (unformat (i, "vrf %d", &vrf_id))
13821         ;
13822       else
13823         break;
13824     }
13825
13826   if (range_set == 0)
13827     {
13828       errmsg ("address range not set");
13829       return -99;
13830     }
13831
13832   M (TCP_CONFIGURE_SRC_ADDRESSES, mp);
13833
13834   mp->vrf_id = ntohl (vrf_id);
13835   clib_memcpy (&mp->first_address, &first, sizeof (first));
13836   clib_memcpy (&mp->last_address, &last, sizeof (last));
13837
13838   S (mp);
13839   W (ret);
13840   return ret;
13841 }
13842
13843 static void vl_api_app_namespace_add_del_reply_t_handler
13844   (vl_api_app_namespace_add_del_reply_t * mp)
13845 {
13846   vat_main_t *vam = &vat_main;
13847   i32 retval = ntohl (mp->retval);
13848   if (vam->async_mode)
13849     {
13850       vam->async_errors += (retval < 0);
13851     }
13852   else
13853     {
13854       vam->retval = retval;
13855       if (retval == 0)
13856         errmsg ("app ns index %d\n", ntohl (mp->appns_index));
13857       vam->result_ready = 1;
13858     }
13859 }
13860
13861 static void vl_api_app_namespace_add_del_reply_t_handler_json
13862   (vl_api_app_namespace_add_del_reply_t * mp)
13863 {
13864   vat_main_t *vam = &vat_main;
13865   vat_json_node_t node;
13866
13867   vat_json_init_object (&node);
13868   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
13869   vat_json_object_add_uint (&node, "appns_index", ntohl (mp->appns_index));
13870
13871   vat_json_print (vam->ofp, &node);
13872   vat_json_free (&node);
13873
13874   vam->retval = ntohl (mp->retval);
13875   vam->result_ready = 1;
13876 }
13877
13878 static int
13879 api_app_namespace_add_del (vat_main_t * vam)
13880 {
13881   vl_api_app_namespace_add_del_t *mp;
13882   unformat_input_t *i = vam->input;
13883   u8 *ns_id = 0, secret_set = 0, sw_if_index_set = 0;
13884   u32 sw_if_index, ip4_fib_id, ip6_fib_id;
13885   u64 secret;
13886   int ret;
13887
13888   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13889     {
13890       if (unformat (i, "id %_%v%_", &ns_id))
13891         ;
13892       else if (unformat (i, "secret %lu", &secret))
13893         secret_set = 1;
13894       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13895         sw_if_index_set = 1;
13896       else if (unformat (i, "ip4_fib_id %d", &ip4_fib_id))
13897         ;
13898       else if (unformat (i, "ip6_fib_id %d", &ip6_fib_id))
13899         ;
13900       else
13901         break;
13902     }
13903   if (!ns_id || !secret_set || !sw_if_index_set)
13904     {
13905       errmsg ("namespace id, secret and sw_if_index must be set");
13906       return -99;
13907     }
13908   if (vec_len (ns_id) > 64)
13909     {
13910       errmsg ("namespace id too long");
13911       return -99;
13912     }
13913   M (APP_NAMESPACE_ADD_DEL, mp);
13914
13915   vl_api_vec_to_api_string (ns_id, &mp->namespace_id);
13916   mp->secret = clib_host_to_net_u64 (secret);
13917   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
13918   mp->ip4_fib_id = clib_host_to_net_u32 (ip4_fib_id);
13919   mp->ip6_fib_id = clib_host_to_net_u32 (ip6_fib_id);
13920   vec_free (ns_id);
13921   S (mp);
13922   W (ret);
13923   return ret;
13924 }
13925
13926 static int
13927 api_sock_init_shm (vat_main_t * vam)
13928 {
13929 #if VPP_API_TEST_BUILTIN == 0
13930   unformat_input_t *i = vam->input;
13931   vl_api_shm_elem_config_t *config = 0;
13932   u64 size = 64 << 20;
13933   int rv;
13934
13935   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13936     {
13937       if (unformat (i, "size %U", unformat_memory_size, &size))
13938         ;
13939       else
13940         break;
13941     }
13942
13943   /*
13944    * Canned custom ring allocator config.
13945    * Should probably parse all of this
13946    */
13947   vec_validate (config, 6);
13948   config[0].type = VL_API_VLIB_RING;
13949   config[0].size = 256;
13950   config[0].count = 32;
13951
13952   config[1].type = VL_API_VLIB_RING;
13953   config[1].size = 1024;
13954   config[1].count = 16;
13955
13956   config[2].type = VL_API_VLIB_RING;
13957   config[2].size = 4096;
13958   config[2].count = 2;
13959
13960   config[3].type = VL_API_CLIENT_RING;
13961   config[3].size = 256;
13962   config[3].count = 32;
13963
13964   config[4].type = VL_API_CLIENT_RING;
13965   config[4].size = 1024;
13966   config[4].count = 16;
13967
13968   config[5].type = VL_API_CLIENT_RING;
13969   config[5].size = 4096;
13970   config[5].count = 2;
13971
13972   config[6].type = VL_API_QUEUE;
13973   config[6].count = 128;
13974   config[6].size = sizeof (uword);
13975
13976   rv = vl_socket_client_init_shm (config, 1 /* want_pthread */ );
13977   if (!rv)
13978     vam->client_index_invalid = 1;
13979   return rv;
13980 #else
13981   return -99;
13982 #endif
13983 }
13984
13985 static void
13986 vl_api_session_rules_details_t_handler (vl_api_session_rules_details_t * mp)
13987 {
13988   vat_main_t *vam = &vat_main;
13989   fib_prefix_t lcl, rmt;
13990
13991   ip_prefix_decode (&mp->lcl, &lcl);
13992   ip_prefix_decode (&mp->rmt, &rmt);
13993
13994   if (lcl.fp_proto == FIB_PROTOCOL_IP4)
13995     {
13996       print (vam->ofp,
13997              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
13998              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
13999              mp->scope, format_ip4_address, &lcl.fp_addr.ip4, lcl.fp_len,
14000              clib_net_to_host_u16 (mp->lcl_port), format_ip4_address,
14001              &rmt.fp_addr.ip4, rmt.fp_len,
14002              clib_net_to_host_u16 (mp->rmt_port),
14003              clib_net_to_host_u32 (mp->action_index), mp->tag);
14004     }
14005   else
14006     {
14007       print (vam->ofp,
14008              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
14009              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
14010              mp->scope, format_ip6_address, &lcl.fp_addr.ip6, lcl.fp_len,
14011              clib_net_to_host_u16 (mp->lcl_port), format_ip6_address,
14012              &rmt.fp_addr.ip6, rmt.fp_len,
14013              clib_net_to_host_u16 (mp->rmt_port),
14014              clib_net_to_host_u32 (mp->action_index), mp->tag);
14015     }
14016 }
14017
14018 static void
14019 vl_api_session_rules_details_t_handler_json (vl_api_session_rules_details_t *
14020                                              mp)
14021 {
14022   vat_main_t *vam = &vat_main;
14023   vat_json_node_t *node = NULL;
14024   struct in6_addr ip6;
14025   struct in_addr ip4;
14026
14027   fib_prefix_t lcl, rmt;
14028
14029   ip_prefix_decode (&mp->lcl, &lcl);
14030   ip_prefix_decode (&mp->rmt, &rmt);
14031
14032   if (VAT_JSON_ARRAY != vam->json_tree.type)
14033     {
14034       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14035       vat_json_init_array (&vam->json_tree);
14036     }
14037   node = vat_json_array_add (&vam->json_tree);
14038   vat_json_init_object (node);
14039
14040   vat_json_object_add_uint (node, "appns_index",
14041                             clib_net_to_host_u32 (mp->appns_index));
14042   vat_json_object_add_uint (node, "transport_proto", mp->transport_proto);
14043   vat_json_object_add_uint (node, "scope", mp->scope);
14044   vat_json_object_add_uint (node, "action_index",
14045                             clib_net_to_host_u32 (mp->action_index));
14046   vat_json_object_add_uint (node, "lcl_port",
14047                             clib_net_to_host_u16 (mp->lcl_port));
14048   vat_json_object_add_uint (node, "rmt_port",
14049                             clib_net_to_host_u16 (mp->rmt_port));
14050   vat_json_object_add_uint (node, "lcl_plen", lcl.fp_len);
14051   vat_json_object_add_uint (node, "rmt_plen", rmt.fp_len);
14052   vat_json_object_add_string_copy (node, "tag", mp->tag);
14053   if (lcl.fp_proto == FIB_PROTOCOL_IP4)
14054     {
14055       clib_memcpy (&ip4, &lcl.fp_addr.ip4, sizeof (ip4));
14056       vat_json_object_add_ip4 (node, "lcl_ip", ip4);
14057       clib_memcpy (&ip4, &rmt.fp_addr.ip4, sizeof (ip4));
14058       vat_json_object_add_ip4 (node, "rmt_ip", ip4);
14059     }
14060   else
14061     {
14062       clib_memcpy (&ip6, &lcl.fp_addr.ip6, sizeof (ip6));
14063       vat_json_object_add_ip6 (node, "lcl_ip", ip6);
14064       clib_memcpy (&ip6, &rmt.fp_addr.ip6, sizeof (ip6));
14065       vat_json_object_add_ip6 (node, "rmt_ip", ip6);
14066     }
14067 }
14068
14069 static int
14070 api_session_rule_add_del (vat_main_t * vam)
14071 {
14072   vl_api_session_rule_add_del_t *mp;
14073   unformat_input_t *i = vam->input;
14074   u32 proto = ~0, lcl_port, rmt_port, action = 0, lcl_plen, rmt_plen;
14075   u32 appns_index = 0, scope = 0;
14076   ip4_address_t lcl_ip4, rmt_ip4;
14077   ip6_address_t lcl_ip6, rmt_ip6;
14078   u8 is_ip4 = 1, conn_set = 0;
14079   u8 is_add = 1, *tag = 0;
14080   int ret;
14081   fib_prefix_t lcl, rmt;
14082
14083   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14084     {
14085       if (unformat (i, "del"))
14086         is_add = 0;
14087       else if (unformat (i, "add"))
14088         ;
14089       else if (unformat (i, "proto tcp"))
14090         proto = 0;
14091       else if (unformat (i, "proto udp"))
14092         proto = 1;
14093       else if (unformat (i, "appns %d", &appns_index))
14094         ;
14095       else if (unformat (i, "scope %d", &scope))
14096         ;
14097       else if (unformat (i, "tag %_%v%_", &tag))
14098         ;
14099       else
14100         if (unformat
14101             (i, "%U/%d %d %U/%d %d", unformat_ip4_address, &lcl_ip4,
14102              &lcl_plen, &lcl_port, unformat_ip4_address, &rmt_ip4, &rmt_plen,
14103              &rmt_port))
14104         {
14105           is_ip4 = 1;
14106           conn_set = 1;
14107         }
14108       else
14109         if (unformat
14110             (i, "%U/%d %d %U/%d %d", unformat_ip6_address, &lcl_ip6,
14111              &lcl_plen, &lcl_port, unformat_ip6_address, &rmt_ip6, &rmt_plen,
14112              &rmt_port))
14113         {
14114           is_ip4 = 0;
14115           conn_set = 1;
14116         }
14117       else if (unformat (i, "action %d", &action))
14118         ;
14119       else
14120         break;
14121     }
14122   if (proto == ~0 || !conn_set || action == ~0)
14123     {
14124       errmsg ("transport proto, connection and action must be set");
14125       return -99;
14126     }
14127
14128   if (scope > 3)
14129     {
14130       errmsg ("scope should be 0-3");
14131       return -99;
14132     }
14133
14134   M (SESSION_RULE_ADD_DEL, mp);
14135
14136   clib_memset (&lcl, 0, sizeof (lcl));
14137   clib_memset (&rmt, 0, sizeof (rmt));
14138   if (is_ip4)
14139     {
14140       ip_set (&lcl.fp_addr, &lcl_ip4, 1);
14141       ip_set (&rmt.fp_addr, &rmt_ip4, 1);
14142       lcl.fp_len = lcl_plen;
14143       rmt.fp_len = rmt_plen;
14144     }
14145   else
14146     {
14147       ip_set (&lcl.fp_addr, &lcl_ip6, 0);
14148       ip_set (&rmt.fp_addr, &rmt_ip6, 0);
14149       lcl.fp_len = lcl_plen;
14150       rmt.fp_len = rmt_plen;
14151     }
14152
14153
14154   ip_prefix_encode (&lcl, &mp->lcl);
14155   ip_prefix_encode (&rmt, &mp->rmt);
14156   mp->lcl_port = clib_host_to_net_u16 ((u16) lcl_port);
14157   mp->rmt_port = clib_host_to_net_u16 ((u16) rmt_port);
14158   mp->transport_proto =
14159     proto ? TRANSPORT_PROTO_API_UDP : TRANSPORT_PROTO_API_TCP;
14160   mp->action_index = clib_host_to_net_u32 (action);
14161   mp->appns_index = clib_host_to_net_u32 (appns_index);
14162   mp->scope = scope;
14163   mp->is_add = is_add;
14164   if (tag)
14165     {
14166       clib_memcpy (mp->tag, tag, vec_len (tag));
14167       vec_free (tag);
14168     }
14169
14170   S (mp);
14171   W (ret);
14172   return ret;
14173 }
14174
14175 static int
14176 api_session_rules_dump (vat_main_t * vam)
14177 {
14178   vl_api_session_rules_dump_t *mp;
14179   vl_api_control_ping_t *mp_ping;
14180   int ret;
14181
14182   if (!vam->json_output)
14183     {
14184       print (vam->ofp, "%=20s", "Session Rules");
14185     }
14186
14187   M (SESSION_RULES_DUMP, mp);
14188   /* send it... */
14189   S (mp);
14190
14191   /* Use a control ping for synchronization */
14192   MPING (CONTROL_PING, mp_ping);
14193   S (mp_ping);
14194
14195   /* Wait for a reply... */
14196   W (ret);
14197   return ret;
14198 }
14199
14200 static int
14201 api_ip_container_proxy_add_del (vat_main_t * vam)
14202 {
14203   vl_api_ip_container_proxy_add_del_t *mp;
14204   unformat_input_t *i = vam->input;
14205   u32 sw_if_index = ~0;
14206   vl_api_prefix_t pfx = { };
14207   u8 is_add = 1;
14208   int ret;
14209
14210   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14211     {
14212       if (unformat (i, "del"))
14213         is_add = 0;
14214       else if (unformat (i, "add"))
14215         ;
14216       if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
14217         ;
14218       else if (unformat (i, "sw_if_index %u", &sw_if_index))
14219         ;
14220       else
14221         break;
14222     }
14223   if (sw_if_index == ~0 || pfx.len == 0)
14224     {
14225       errmsg ("address and sw_if_index must be set");
14226       return -99;
14227     }
14228
14229   M (IP_CONTAINER_PROXY_ADD_DEL, mp);
14230
14231   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
14232   mp->is_add = is_add;
14233   clib_memcpy (&mp->pfx, &pfx, sizeof (pfx));
14234
14235   S (mp);
14236   W (ret);
14237   return ret;
14238 }
14239
14240 static int
14241 api_qos_record_enable_disable (vat_main_t * vam)
14242 {
14243   unformat_input_t *i = vam->input;
14244   vl_api_qos_record_enable_disable_t *mp;
14245   u32 sw_if_index, qs = 0xff;
14246   u8 sw_if_index_set = 0;
14247   u8 enable = 1;
14248   int ret;
14249
14250   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14251     {
14252       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14253         sw_if_index_set = 1;
14254       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14255         sw_if_index_set = 1;
14256       else if (unformat (i, "%U", unformat_qos_source, &qs))
14257         ;
14258       else if (unformat (i, "disable"))
14259         enable = 0;
14260       else
14261         {
14262           clib_warning ("parse error '%U'", format_unformat_error, i);
14263           return -99;
14264         }
14265     }
14266
14267   if (sw_if_index_set == 0)
14268     {
14269       errmsg ("missing interface name or sw_if_index");
14270       return -99;
14271     }
14272   if (qs == 0xff)
14273     {
14274       errmsg ("input location must be specified");
14275       return -99;
14276     }
14277
14278   M (QOS_RECORD_ENABLE_DISABLE, mp);
14279
14280   mp->record.sw_if_index = ntohl (sw_if_index);
14281   mp->record.input_source = qs;
14282   mp->enable = enable;
14283
14284   S (mp);
14285   W (ret);
14286   return ret;
14287 }
14288
14289
14290 static int
14291 q_or_quit (vat_main_t * vam)
14292 {
14293 #if VPP_API_TEST_BUILTIN == 0
14294   longjmp (vam->jump_buf, 1);
14295 #endif
14296   return 0;                     /* not so much */
14297 }
14298
14299 static int
14300 q (vat_main_t * vam)
14301 {
14302   return q_or_quit (vam);
14303 }
14304
14305 static int
14306 quit (vat_main_t * vam)
14307 {
14308   return q_or_quit (vam);
14309 }
14310
14311 static int
14312 comment (vat_main_t * vam)
14313 {
14314   return 0;
14315 }
14316
14317 static int
14318 elog_save (vat_main_t * vam)
14319 {
14320 #if VPP_API_TEST_BUILTIN == 0
14321   elog_main_t *em = &vam->elog_main;
14322   unformat_input_t *i = vam->input;
14323   char *file, *chroot_file;
14324   clib_error_t *error;
14325
14326   if (!unformat (i, "%s", &file))
14327     {
14328       errmsg ("expected file name, got `%U'", format_unformat_error, i);
14329       return 0;
14330     }
14331
14332   /* It's fairly hard to get "../oopsie" through unformat; just in case */
14333   if (strstr (file, "..") || index (file, '/'))
14334     {
14335       errmsg ("illegal characters in filename '%s'", file);
14336       return 0;
14337     }
14338
14339   chroot_file = (char *) format (0, "/tmp/%s%c", file, 0);
14340
14341   vec_free (file);
14342
14343   errmsg ("Saving %wd of %wd events to %s",
14344           elog_n_events_in_buffer (em),
14345           elog_buffer_capacity (em), chroot_file);
14346
14347   error = elog_write_file (em, chroot_file, 1 /* flush ring */ );
14348   vec_free (chroot_file);
14349
14350   if (error)
14351     clib_error_report (error);
14352 #else
14353   errmsg ("Use the vpp event loger...");
14354 #endif
14355
14356   return 0;
14357 }
14358
14359 static int
14360 elog_setup (vat_main_t * vam)
14361 {
14362 #if VPP_API_TEST_BUILTIN == 0
14363   elog_main_t *em = &vam->elog_main;
14364   unformat_input_t *i = vam->input;
14365   u32 nevents = 128 << 10;
14366
14367   (void) unformat (i, "nevents %d", &nevents);
14368
14369   elog_init (em, nevents);
14370   vl_api_set_elog_main (em);
14371   vl_api_set_elog_trace_api_messages (1);
14372   errmsg ("Event logger initialized with %u events", nevents);
14373 #else
14374   errmsg ("Use the vpp event loger...");
14375 #endif
14376   return 0;
14377 }
14378
14379 static int
14380 elog_enable (vat_main_t * vam)
14381 {
14382 #if VPP_API_TEST_BUILTIN == 0
14383   elog_main_t *em = &vam->elog_main;
14384
14385   elog_enable_disable (em, 1 /* enable */ );
14386   vl_api_set_elog_trace_api_messages (1);
14387   errmsg ("Event logger enabled...");
14388 #else
14389   errmsg ("Use the vpp event loger...");
14390 #endif
14391   return 0;
14392 }
14393
14394 static int
14395 elog_disable (vat_main_t * vam)
14396 {
14397 #if VPP_API_TEST_BUILTIN == 0
14398   elog_main_t *em = &vam->elog_main;
14399
14400   elog_enable_disable (em, 0 /* enable */ );
14401   vl_api_set_elog_trace_api_messages (1);
14402   errmsg ("Event logger disabled...");
14403 #else
14404   errmsg ("Use the vpp event loger...");
14405 #endif
14406   return 0;
14407 }
14408
14409 static int
14410 statseg (vat_main_t * vam)
14411 {
14412   ssvm_private_t *ssvmp = &vam->stat_segment;
14413   ssvm_shared_header_t *shared_header = ssvmp->sh;
14414   vlib_counter_t **counters;
14415   u64 thread0_index1_packets;
14416   u64 thread0_index1_bytes;
14417   f64 vector_rate, input_rate;
14418   uword *p;
14419
14420   uword *counter_vector_by_name;
14421   if (vam->stat_segment_lockp == 0)
14422     {
14423       errmsg ("Stat segment not mapped...");
14424       return -99;
14425     }
14426
14427   /* look up "/if/rx for sw_if_index 1 as a test */
14428
14429   clib_spinlock_lock (vam->stat_segment_lockp);
14430
14431   counter_vector_by_name = (uword *) shared_header->opaque[1];
14432
14433   p = hash_get_mem (counter_vector_by_name, "/if/rx");
14434   if (p == 0)
14435     {
14436       clib_spinlock_unlock (vam->stat_segment_lockp);
14437       errmsg ("/if/tx not found?");
14438       return -99;
14439     }
14440
14441   /* Fish per-thread vector of combined counters from shared memory */
14442   counters = (vlib_counter_t **) p[0];
14443
14444   if (vec_len (counters[0]) < 2)
14445     {
14446       clib_spinlock_unlock (vam->stat_segment_lockp);
14447       errmsg ("/if/tx vector length %d", vec_len (counters[0]));
14448       return -99;
14449     }
14450
14451   /* Read thread 0 sw_if_index 1 counter */
14452   thread0_index1_packets = counters[0][1].packets;
14453   thread0_index1_bytes = counters[0][1].bytes;
14454
14455   p = hash_get_mem (counter_vector_by_name, "vector_rate");
14456   if (p == 0)
14457     {
14458       clib_spinlock_unlock (vam->stat_segment_lockp);
14459       errmsg ("vector_rate not found?");
14460       return -99;
14461     }
14462
14463   vector_rate = *(f64 *) (p[0]);
14464   p = hash_get_mem (counter_vector_by_name, "input_rate");
14465   if (p == 0)
14466     {
14467       clib_spinlock_unlock (vam->stat_segment_lockp);
14468       errmsg ("input_rate not found?");
14469       return -99;
14470     }
14471   input_rate = *(f64 *) (p[0]);
14472
14473   clib_spinlock_unlock (vam->stat_segment_lockp);
14474
14475   print (vam->ofp, "vector_rate %.2f input_rate %.2f",
14476          vector_rate, input_rate);
14477   print (vam->ofp, "thread 0 sw_if_index 1 rx pkts %lld, bytes %lld",
14478          thread0_index1_packets, thread0_index1_bytes);
14479
14480   return 0;
14481 }
14482
14483 static int
14484 cmd_cmp (void *a1, void *a2)
14485 {
14486   u8 **c1 = a1;
14487   u8 **c2 = a2;
14488
14489   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
14490 }
14491
14492 static int
14493 help (vat_main_t * vam)
14494 {
14495   u8 **cmds = 0;
14496   u8 *name = 0;
14497   hash_pair_t *p;
14498   unformat_input_t *i = vam->input;
14499   int j;
14500
14501   if (unformat (i, "%s", &name))
14502     {
14503       uword *hs;
14504
14505       vec_add1 (name, 0);
14506
14507       hs = hash_get_mem (vam->help_by_name, name);
14508       if (hs)
14509         print (vam->ofp, "usage: %s %s", name, hs[0]);
14510       else
14511         print (vam->ofp, "No such msg / command '%s'", name);
14512       vec_free (name);
14513       return 0;
14514     }
14515
14516   print (vam->ofp, "Help is available for the following:");
14517
14518     /* *INDENT-OFF* */
14519     hash_foreach_pair (p, vam->function_by_name,
14520     ({
14521       vec_add1 (cmds, (u8 *)(p->key));
14522     }));
14523     /* *INDENT-ON* */
14524
14525   vec_sort_with_function (cmds, cmd_cmp);
14526
14527   for (j = 0; j < vec_len (cmds); j++)
14528     print (vam->ofp, "%s", cmds[j]);
14529
14530   vec_free (cmds);
14531   return 0;
14532 }
14533
14534 static int
14535 set (vat_main_t * vam)
14536 {
14537   u8 *name = 0, *value = 0;
14538   unformat_input_t *i = vam->input;
14539
14540   if (unformat (i, "%s", &name))
14541     {
14542       /* The input buffer is a vector, not a string. */
14543       value = vec_dup (i->buffer);
14544       vec_delete (value, i->index, 0);
14545       /* Almost certainly has a trailing newline */
14546       if (value[vec_len (value) - 1] == '\n')
14547         value[vec_len (value) - 1] = 0;
14548       /* Make sure it's a proper string, one way or the other */
14549       vec_add1 (value, 0);
14550       (void) clib_macro_set_value (&vam->macro_main,
14551                                    (char *) name, (char *) value);
14552     }
14553   else
14554     errmsg ("usage: set <name> <value>");
14555
14556   vec_free (name);
14557   vec_free (value);
14558   return 0;
14559 }
14560
14561 static int
14562 unset (vat_main_t * vam)
14563 {
14564   u8 *name = 0;
14565
14566   if (unformat (vam->input, "%s", &name))
14567     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
14568       errmsg ("unset: %s wasn't set", name);
14569   vec_free (name);
14570   return 0;
14571 }
14572
14573 typedef struct
14574 {
14575   u8 *name;
14576   u8 *value;
14577 } macro_sort_t;
14578
14579
14580 static int
14581 macro_sort_cmp (void *a1, void *a2)
14582 {
14583   macro_sort_t *s1 = a1;
14584   macro_sort_t *s2 = a2;
14585
14586   return strcmp ((char *) (s1->name), (char *) (s2->name));
14587 }
14588
14589 static int
14590 dump_macro_table (vat_main_t * vam)
14591 {
14592   macro_sort_t *sort_me = 0, *sm;
14593   int i;
14594   hash_pair_t *p;
14595
14596     /* *INDENT-OFF* */
14597     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
14598     ({
14599       vec_add2 (sort_me, sm, 1);
14600       sm->name = (u8 *)(p->key);
14601       sm->value = (u8 *) (p->value[0]);
14602     }));
14603     /* *INDENT-ON* */
14604
14605   vec_sort_with_function (sort_me, macro_sort_cmp);
14606
14607   if (vec_len (sort_me))
14608     print (vam->ofp, "%-15s%s", "Name", "Value");
14609   else
14610     print (vam->ofp, "The macro table is empty...");
14611
14612   for (i = 0; i < vec_len (sort_me); i++)
14613     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
14614   return 0;
14615 }
14616
14617 static int
14618 dump_node_table (vat_main_t * vam)
14619 {
14620   int i, j;
14621   vlib_node_t *node, *next_node;
14622
14623   if (vec_len (vam->graph_nodes) == 0)
14624     {
14625       print (vam->ofp, "Node table empty, issue get_node_graph...");
14626       return 0;
14627     }
14628
14629   for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
14630     {
14631       node = vam->graph_nodes[0][i];
14632       print (vam->ofp, "[%d] %s", i, node->name);
14633       for (j = 0; j < vec_len (node->next_nodes); j++)
14634         {
14635           if (node->next_nodes[j] != ~0)
14636             {
14637               next_node = vam->graph_nodes[0][node->next_nodes[j]];
14638               print (vam->ofp, "  [%d] %s", j, next_node->name);
14639             }
14640         }
14641     }
14642   return 0;
14643 }
14644
14645 static int
14646 value_sort_cmp (void *a1, void *a2)
14647 {
14648   name_sort_t *n1 = a1;
14649   name_sort_t *n2 = a2;
14650
14651   if (n1->value < n2->value)
14652     return -1;
14653   if (n1->value > n2->value)
14654     return 1;
14655   return 0;
14656 }
14657
14658
14659 static int
14660 dump_msg_api_table (vat_main_t * vam)
14661 {
14662   api_main_t *am = vlibapi_get_main ();
14663   name_sort_t *nses = 0, *ns;
14664   hash_pair_t *hp;
14665   int i;
14666
14667   /* *INDENT-OFF* */
14668   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
14669   ({
14670     vec_add2 (nses, ns, 1);
14671     ns->name = (u8 *)(hp->key);
14672     ns->value = (u32) hp->value[0];
14673   }));
14674   /* *INDENT-ON* */
14675
14676   vec_sort_with_function (nses, value_sort_cmp);
14677
14678   for (i = 0; i < vec_len (nses); i++)
14679     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
14680   vec_free (nses);
14681   return 0;
14682 }
14683
14684 static int
14685 get_msg_id (vat_main_t * vam)
14686 {
14687   u8 *name_and_crc;
14688   u32 message_index;
14689
14690   if (unformat (vam->input, "%s", &name_and_crc))
14691     {
14692       message_index = vl_msg_api_get_msg_index (name_and_crc);
14693       if (message_index == ~0)
14694         {
14695           print (vam->ofp, " '%s' not found", name_and_crc);
14696           return 0;
14697         }
14698       print (vam->ofp, " '%s' has message index %d",
14699              name_and_crc, message_index);
14700       return 0;
14701     }
14702   errmsg ("name_and_crc required...");
14703   return 0;
14704 }
14705
14706 static int
14707 search_node_table (vat_main_t * vam)
14708 {
14709   unformat_input_t *line_input = vam->input;
14710   u8 *node_to_find;
14711   int j;
14712   vlib_node_t *node, *next_node;
14713   uword *p;
14714
14715   if (vam->graph_node_index_by_name == 0)
14716     {
14717       print (vam->ofp, "Node table empty, issue get_node_graph...");
14718       return 0;
14719     }
14720
14721   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14722     {
14723       if (unformat (line_input, "%s", &node_to_find))
14724         {
14725           vec_add1 (node_to_find, 0);
14726           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
14727           if (p == 0)
14728             {
14729               print (vam->ofp, "%s not found...", node_to_find);
14730               goto out;
14731             }
14732           node = vam->graph_nodes[0][p[0]];
14733           print (vam->ofp, "[%d] %s", p[0], node->name);
14734           for (j = 0; j < vec_len (node->next_nodes); j++)
14735             {
14736               if (node->next_nodes[j] != ~0)
14737                 {
14738                   next_node = vam->graph_nodes[0][node->next_nodes[j]];
14739                   print (vam->ofp, "  [%d] %s", j, next_node->name);
14740                 }
14741             }
14742         }
14743
14744       else
14745         {
14746           clib_warning ("parse error '%U'", format_unformat_error,
14747                         line_input);
14748           return -99;
14749         }
14750
14751     out:
14752       vec_free (node_to_find);
14753
14754     }
14755
14756   return 0;
14757 }
14758
14759
14760 static int
14761 script (vat_main_t * vam)
14762 {
14763 #if (VPP_API_TEST_BUILTIN==0)
14764   u8 *s = 0;
14765   char *save_current_file;
14766   unformat_input_t save_input;
14767   jmp_buf save_jump_buf;
14768   u32 save_line_number;
14769
14770   FILE *new_fp, *save_ifp;
14771
14772   if (unformat (vam->input, "%s", &s))
14773     {
14774       new_fp = fopen ((char *) s, "r");
14775       if (new_fp == 0)
14776         {
14777           errmsg ("Couldn't open script file %s", s);
14778           vec_free (s);
14779           return -99;
14780         }
14781     }
14782   else
14783     {
14784       errmsg ("Missing script name");
14785       return -99;
14786     }
14787
14788   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
14789   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
14790   save_ifp = vam->ifp;
14791   save_line_number = vam->input_line_number;
14792   save_current_file = (char *) vam->current_file;
14793
14794   vam->input_line_number = 0;
14795   vam->ifp = new_fp;
14796   vam->current_file = s;
14797   do_one_file (vam);
14798
14799   clib_memcpy (&vam->input, &save_input, sizeof (save_input));
14800   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
14801   vam->ifp = save_ifp;
14802   vam->input_line_number = save_line_number;
14803   vam->current_file = (u8 *) save_current_file;
14804   vec_free (s);
14805
14806   return 0;
14807 #else
14808   clib_warning ("use the exec command...");
14809   return -99;
14810 #endif
14811 }
14812
14813 static int
14814 echo (vat_main_t * vam)
14815 {
14816   print (vam->ofp, "%v", vam->input->buffer);
14817   return 0;
14818 }
14819
14820 /* List of API message constructors, CLI names map to api_xxx */
14821 #define foreach_vpe_api_msg                                             \
14822 _(create_loopback,"[mac <mac-addr>] [instance <instance>]")             \
14823 _(sw_interface_dump,"")                                                 \
14824 _(sw_interface_set_flags,                                               \
14825   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
14826 _(sw_interface_add_del_address,                                         \
14827   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
14828 _(sw_interface_set_rx_mode,                                             \
14829   "<intfc> | sw_if_index <id> [queue <id>] <polling | interrupt | adaptive>") \
14830 _(sw_interface_set_rx_placement,                                        \
14831   "<intfc> | sw_if_index <id> [queue <id>] [worker <id> | main]")       \
14832 _(sw_interface_rx_placement_dump,                                       \
14833   "[<intfc> | sw_if_index <id>]")                                         \
14834 _(sw_interface_set_table,                                               \
14835   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
14836 _(sw_interface_set_mpls_enable,                                         \
14837   "<intfc> | sw_if_index [disable | dis]")                              \
14838 _(sw_interface_set_vpath,                                               \
14839   "<intfc> | sw_if_index <id> enable | disable")                        \
14840 _(sw_interface_set_vxlan_bypass,                                        \
14841   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
14842 _(sw_interface_set_l2_xconnect,                                         \
14843   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
14844   "enable | disable")                                                   \
14845 _(sw_interface_set_l2_bridge,                                           \
14846   "{<intfc> | sw_if_index <id>} bd_id <bridge-domain-id>\n"             \
14847   "[shg <split-horizon-group>] [bvi]\n"                                 \
14848   "enable | disable")                                                   \
14849 _(bridge_domain_set_mac_age, "bd_id <bridge-domain-id> mac-age 0-255")  \
14850 _(bridge_domain_add_del,                                                \
14851   "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") \
14852 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
14853 _(l2fib_add_del,                                                        \
14854   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
14855 _(l2fib_flush_bd, "bd_id <bridge-domain-id>")                           \
14856 _(l2fib_flush_int, "<intfc> | sw_if_index <id>")                        \
14857 _(l2_flags,                                                             \
14858   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
14859 _(bridge_flags,                                                         \
14860   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
14861 _(tap_create_v2,                                                        \
14862   "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]") \
14863 _(tap_delete_v2,                                                        \
14864   "<vpp-if-name> | sw_if_index <id>")                                   \
14865 _(sw_interface_tap_v2_dump, "")                                         \
14866 _(virtio_pci_create_v2,                                                    \
14867   "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]") \
14868 _(virtio_pci_delete,                                                    \
14869   "<vpp-if-name> | sw_if_index <id>")                                   \
14870 _(sw_interface_virtio_pci_dump, "")                                     \
14871 _(bond_create,                                                          \
14872   "[hw-addr <mac-addr>] {round-robin | active-backup | "                \
14873   "broadcast | {lacp | xor} [load-balance { l2 | l23 | l34 }]} "        \
14874   "[id <if-id>]")                                                       \
14875 _(bond_create2,                                                         \
14876   "[hw-addr <mac-addr>] {mode round-robin | active-backup | "           \
14877   "broadcast | {lacp | xor} [load-balance { l2 | l23 | l34 }]} "        \
14878   "[id <if-id>] [gso]")                                                 \
14879 _(bond_delete,                                                          \
14880   "<vpp-if-name> | sw_if_index <id>")                                   \
14881 _(bond_add_member,                                                      \
14882   "sw_if_index <n> bond <sw_if_index> [is_passive] [is_long_timeout]")  \
14883 _(bond_detach_member,                                                   \
14884   "sw_if_index <n>")                                                    \
14885  _(sw_interface_set_bond_weight, "<intfc> | sw_if_index <nn> weight <value>") \
14886  _(sw_bond_interface_dump, "<intfc> | sw_if_index <nn>")                \
14887  _(sw_member_interface_dump,                                            \
14888   "<vpp-if-name> | sw_if_index <id>")                                   \
14889 _(ip_table_add_del,                                                     \
14890   "table <n> [ipv6] [add | del]\n")                                     \
14891 _(ip_route_add_del,                                                     \
14892   "<addr>/<mask> via <<addr>|<intfc>|sw_if_index <id>|via-label <n>>\n" \
14893   "[table-id <n>] [<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"\
14894   "[weight <n>] [drop] [local] [classify <n>]  [out-label <n>]\n"       \
14895   "[multipath] [count <n>] [del]")                                      \
14896 _(ip_mroute_add_del,                                                    \
14897   "<src> <grp>/<mask> [table-id <n>]\n"                                 \
14898   "[<intfc> | sw_if_index <id>] [local] [del]")                         \
14899 _(mpls_table_add_del,                                                   \
14900   "table <n> [add | del]\n")                                            \
14901 _(mpls_route_add_del,                                                   \
14902   "<label> <eos> via <addr | next-hop-table <n> | via-label <n> |\n"    \
14903   "lookup-ip4-table <n> | lookup-in-ip6-table <n> |\n"                  \
14904   "l2-input-on <intfc> | l2-input-on sw_if_index <id>>\n"               \
14905   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>] [weight <n>]\n"  \
14906   "[drop] [local] [classify <n>] [out-label <n>] [multipath]\n"         \
14907   "[count <n>] [del]")                                                  \
14908 _(mpls_ip_bind_unbind,                                                  \
14909   "<label> <addr/len>")                                                 \
14910 _(mpls_tunnel_add_del,                                                  \
14911   "[add | del <intfc | sw_if_index <id>>] via <addr | via-label <n>>\n" \
14912   "[<intfc> | sw_if_index <id> | next-hop-table <id>]\n"                \
14913   "[l2-only]  [out-label <n>]")                                         \
14914 _(sr_mpls_policy_add,                                                   \
14915   "bsid <id> [weight <n>] [spray] next <sid> [next <sid>]")             \
14916 _(sr_mpls_policy_del,                                                   \
14917   "bsid <id>")                                                          \
14918 _(bier_table_add_del,                                                   \
14919   "<label> <sub-domain> <set> <bsl> [del]")                             \
14920 _(bier_route_add_del,                                                   \
14921   "<bit-position> <sub-domain> <set> <bsl> via <addr> [table-id <n>]\n" \
14922   "[<intfc> | sw_if_index <id>]"                                        \
14923   "[weight <n>] [del] [multipath]")                                     \
14924 _(sw_interface_set_unnumbered,                                          \
14925   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
14926 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
14927 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
14928   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
14929   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
14930   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
14931 _(ip_table_replace_begin, "table <n> [ipv6]")                           \
14932 _(ip_table_flush, "table <n> [ipv6]")                                   \
14933 _(ip_table_replace_end, "table <n> [ipv6]")                             \
14934 _(set_ip_flow_hash,                                                     \
14935   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
14936 _(sw_interface_ip6_enable_disable,                                      \
14937   "<intfc> | sw_if_index <id> enable | disable")                        \
14938 _(l2_patch_add_del,                                                     \
14939   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
14940   "enable | disable")                                                   \
14941 _(sr_localsid_add_del,                                                  \
14942   "(del) address <addr> next_hop <addr> behavior <beh>\n"               \
14943   "fib-table <num> (end.psp) sw_if_index <num>")                        \
14944 _(classify_add_del_table,                                               \
14945   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
14946   " [del] [del-chain] mask <mask-value>\n"                              \
14947   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
14948   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
14949 _(classify_add_del_session,                                             \
14950   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
14951   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
14952   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
14953   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
14954 _(classify_set_interface_ip_table,                                      \
14955   "<intfc> | sw_if_index <nn> table <nn>")                              \
14956 _(classify_set_interface_l2_tables,                                     \
14957   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
14958   "  [other-table <nn>]")                                               \
14959 _(get_node_index, "node <node-name")                                    \
14960 _(add_node_next, "node <node-name> next <next-node-name>")              \
14961 _(vxlan_offload_rx,                                                     \
14962   "hw { <interface name> | hw_if_index <nn>} "                          \
14963   "rx { <vxlan tunnel name> | sw_if_index <nn> } [del]")                \
14964 _(vxlan_add_del_tunnel,                                                 \
14965   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
14966   "{ <intfc> | mcast_sw_if_index <nn> } [instance <id>]}\n"             \
14967   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
14968 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
14969 _(l2_fib_clear_table, "")                                               \
14970 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
14971 _(l2_interface_vlan_tag_rewrite,                                        \
14972   "<intfc> | sw_if_index <nn> \n"                                       \
14973   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
14974   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
14975 _(create_vhost_user_if,                                                 \
14976         "socket <filename> [server] [renumber <dev_instance>] "         \
14977         "[disable_mrg_rxbuf] [disable_indirect_desc] [gso] "            \
14978         "[mac <mac_address>] [packed]")                                 \
14979 _(modify_vhost_user_if,                                                 \
14980         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
14981         "[server] [renumber <dev_instance>] [gso] [packed]")            \
14982 _(create_vhost_user_if_v2,                                              \
14983         "socket <filename> [server] [renumber <dev_instance>] "         \
14984         "[disable_mrg_rxbuf] [disable_indirect_desc] [gso] "            \
14985         "[mac <mac_address>] [packed] [event-idx]")                     \
14986 _(modify_vhost_user_if_v2,                                              \
14987         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
14988         "[server] [renumber <dev_instance>] [gso] [packed] [event-idx]")\
14989 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
14990 _(sw_interface_vhost_user_dump, "<intfc> | sw_if_index <nn>")           \
14991 _(show_version, "")                                                     \
14992 _(show_threads, "")                                                     \
14993 _(vxlan_gpe_add_del_tunnel,                                             \
14994   "local <addr> remote <addr>  | group <mcast-ip-addr>\n"               \
14995   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
14996   "vni <nn> [encap-vrf-id <nn>] [decap-vrf-id <nn>]\n"                  \
14997   "[next-ip4][next-ip6][next-ethernet] [next-nsh] [del]\n")             \
14998 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
14999 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
15000 _(interface_name_renumber,                                              \
15001   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
15002 _(input_acl_set_interface,                                              \
15003   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
15004   "  [l2-table <nn>] [del]")                                            \
15005 _(want_l2_macs_events, "[disable] [learn-limit <n>] [scan-delay <n>] [max-entries <n>]") \
15006 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
15007 _(ip_dump, "ipv4 | ipv6")                                               \
15008 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
15009 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
15010   "  spid_id <n> ")                                                     \
15011 _(ipsec_sad_entry_add_del, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
15012   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
15013   "  integ_alg <alg> integ_key <hex>")                                  \
15014 _(ipsec_spd_entry_add_del, "spd_id <n> priority <n> action <action>\n"  \
15015   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
15016   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
15017   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
15018 _(ipsec_sa_dump, "[sa_id <n>]")                                         \
15019 _(delete_loopback,"sw_if_index <nn>")                                   \
15020 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
15021 _(bd_ip_mac_flush, "bd_id <bridge-domain-id>")                          \
15022 _(bd_ip_mac_dump, "[bd_id] <bridge-domain-id>")                         \
15023 _(want_interface_events,  "enable|disable")                             \
15024 _(get_first_msg_id, "client <name>")                                    \
15025 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
15026 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
15027   "fib-id <nn> [ip4][ip6][default]")                                    \
15028 _(get_node_graph, " ")                                                  \
15029 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
15030 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
15031 _(ioam_disable, "")                                                     \
15032 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
15033 _(af_packet_delete, "name <host interface name>")                       \
15034 _(af_packet_dump, "")                                                   \
15035 _(policer_add_del, "name <policer name> <params> [del]")                \
15036 _(policer_dump, "[name <policer name>]")                                \
15037 _(policer_classify_set_interface,                                       \
15038   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
15039   "  [l2-table <nn>] [del]")                                            \
15040 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
15041 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
15042 _(mpls_table_dump, "")                                                  \
15043 _(mpls_route_dump, "table-id <ID>")                                     \
15044 _(classify_table_ids, "")                                               \
15045 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
15046 _(classify_table_info, "table_id <nn>")                                 \
15047 _(classify_session_dump, "table_id <nn>")                               \
15048 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
15049     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
15050     "[template_interval <nn>] [udp_checksum]")                          \
15051 _(ipfix_exporter_dump, "")                                              \
15052 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
15053 _(ipfix_classify_stream_dump, "")                                       \
15054 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
15055 _(ipfix_classify_table_dump, "")                                        \
15056 _(sw_interface_span_enable_disable, "[l2] [src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
15057 _(sw_interface_span_dump, "[l2]")                                           \
15058 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
15059 _(pg_create_interface, "if_id <nn> [gso-enabled gso-size <size>]")      \
15060 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
15061 _(pg_enable_disable, "[stream <id>] disable")                           \
15062 _(pg_interface_enable_disable_coalesce, "<intf> | sw_if_index <nn> enable | disable")  \
15063 _(ip_source_and_port_range_check_add_del,                               \
15064   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
15065 _(ip_source_and_port_range_check_interface_add_del,                     \
15066   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
15067   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
15068 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
15069 _(l2_interface_pbb_tag_rewrite,                                         \
15070   "<intfc> | sw_if_index <nn> \n"                                       \
15071   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
15072   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
15073 _(set_punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
15074 _(flow_classify_set_interface,                                          \
15075   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
15076 _(flow_classify_dump, "type [ip4|ip6]")                                 \
15077 _(ip_table_dump, "")                                                    \
15078 _(ip_route_dump, "table-id [ip4|ip6]")                                  \
15079 _(ip_mtable_dump, "")                                                   \
15080 _(ip_mroute_dump, "table-id [ip4|ip6]")                                 \
15081 _(feature_enable_disable, "arc_name <arc_name> "                        \
15082   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
15083 _(feature_gso_enable_disable, "<intfc> | sw_if_index <nn> "             \
15084   "[enable | disable] ")                                                \
15085 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
15086 "[disable]")                                                            \
15087 _(sw_interface_add_del_mac_address, "<intfc> | sw_if_index <nn> "       \
15088   "mac <mac-address> [del]")                                            \
15089 _(l2_xconnect_dump, "")                                                 \
15090 _(hw_interface_set_mtu, "<intfc> | hw_if_index <nn> mtu <nn>")        \
15091 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")          \
15092 _(p2p_ethernet_add, "<intfc> | sw_if_index <nn> remote_mac <mac-address> sub_id <id>") \
15093 _(p2p_ethernet_del, "<intfc> | sw_if_index <nn> remote_mac <mac-address>") \
15094 _(tcp_configure_src_addresses, "<ip4|6>first-<ip4|6>last [vrf <id>]")   \
15095 _(sock_init_shm, "size <nnn>")                                          \
15096 _(app_namespace_add_del, "[add] id <ns-id> secret <nn> sw_if_index <nn>")\
15097 _(session_rule_add_del, "[add|del] proto <tcp/udp> <lcl-ip>/<plen> "    \
15098   "<lcl-port> <rmt-ip>/<plen> <rmt-port> action <nn>")                  \
15099 _(session_rules_dump, "")                                               \
15100 _(ip_container_proxy_add_del, "[add|del] <address> <sw_if_index>")      \
15101 _(output_acl_set_interface,                                             \
15102   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
15103   "  [l2-table <nn>] [del]")                                            \
15104 _(qos_record_enable_disable, "<record-source> <intfc> | sw_if_index <id> [disable]")
15105
15106 /* List of command functions, CLI names map directly to functions */
15107 #define foreach_cli_function                                    \
15108 _(comment, "usage: comment <ignore-rest-of-line>")              \
15109 _(dump_interface_table, "usage: dump_interface_table")          \
15110 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
15111 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
15112 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
15113 _(dump_macro_table, "usage: dump_macro_table ")                 \
15114 _(dump_node_table, "usage: dump_node_table")                    \
15115 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
15116 _(elog_setup, "usage: elog_setup [nevents, default 128K]")      \
15117 _(elog_disable, "usage: elog_disable")                          \
15118 _(elog_enable, "usage: elog_enable")                            \
15119 _(elog_save, "usage: elog_save <filename>")                     \
15120 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
15121 _(echo, "usage: echo <message>")                                \
15122 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
15123 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
15124 _(help, "usage: help")                                          \
15125 _(q, "usage: quit")                                             \
15126 _(quit, "usage: quit")                                          \
15127 _(search_node_table, "usage: search_node_table <name>...")      \
15128 _(set, "usage: set <variable-name> <value>")                    \
15129 _(script, "usage: script <file-name>")                          \
15130 _(statseg, "usage: statseg")                                    \
15131 _(unset, "usage: unset <variable-name>")
15132
15133 #define _(N,n)                                  \
15134     static void vl_api_##n##_t_handler_uni      \
15135     (vl_api_##n##_t * mp)                       \
15136     {                                           \
15137         vat_main_t * vam = &vat_main;           \
15138         if (vam->json_output) {                 \
15139             vl_api_##n##_t_handler_json(mp);    \
15140         } else {                                \
15141             vl_api_##n##_t_handler(mp);         \
15142         }                                       \
15143     }
15144 foreach_vpe_api_reply_msg;
15145 #if VPP_API_TEST_BUILTIN == 0
15146 foreach_standalone_reply_msg;
15147 #endif
15148 #undef _
15149
15150 void
15151 vat_api_hookup (vat_main_t * vam)
15152 {
15153 #define _(N,n)                                                  \
15154     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
15155                            vl_api_##n##_t_handler_uni,          \
15156                            vl_noop_handler,                     \
15157                            vl_api_##n##_t_endian,               \
15158                            vl_api_##n##_t_print,                \
15159                            sizeof(vl_api_##n##_t), 1);
15160   foreach_vpe_api_reply_msg;
15161 #if VPP_API_TEST_BUILTIN == 0
15162   foreach_standalone_reply_msg;
15163 #endif
15164 #undef _
15165
15166 #if (VPP_API_TEST_BUILTIN==0)
15167   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
15168
15169   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
15170
15171   vam->function_by_name = hash_create_string (0, sizeof (uword));
15172
15173   vam->help_by_name = hash_create_string (0, sizeof (uword));
15174 #endif
15175
15176   /* API messages we can send */
15177 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
15178   foreach_vpe_api_msg;
15179 #undef _
15180
15181   /* Help strings */
15182 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
15183   foreach_vpe_api_msg;
15184 #undef _
15185
15186   /* CLI functions */
15187 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
15188   foreach_cli_function;
15189 #undef _
15190
15191   /* Help strings */
15192 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
15193   foreach_cli_function;
15194 #undef _
15195 }
15196
15197 #if VPP_API_TEST_BUILTIN
15198 static clib_error_t *
15199 vat_api_hookup_shim (vlib_main_t * vm)
15200 {
15201   vat_api_hookup (&vat_main);
15202   return 0;
15203 }
15204
15205 VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
15206 #endif
15207
15208 /*
15209  * fd.io coding-style-patch-verification: ON
15210  *
15211  * Local Variables:
15212  * eval: (c-set-style "gnu")
15213  * End:
15214  */