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