ipsec: Deprecated the old IPsec Tunnel interface
[vpp.git] / src / vat / api_format.c
1 /*
2  *------------------------------------------------------------------
3  * api_format.c
4  *
5  * Copyright (c) 2014-2020 Cisco and/or its affiliates.
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at:
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *------------------------------------------------------------------
18  */
19
20 #include <vat/vat.h>
21 #include <vlib/pci/pci.h>
22 #include <vpp/api/types.h>
23 #include <vppinfra/socket.h>
24 #include <vlibapi/api.h>
25 #include <vlibmemory/api.h>
26 #include <vnet/ip/ip.h>
27 #include <vnet/ip-neighbor/ip_neighbor.h>
28 #include <vnet/ip/ip_types_api.h>
29 #include <vnet/l2/l2_input.h>
30 #include <vnet/vxlan/vxlan.h>
31 #include <vnet/vxlan-gpe/vxlan_gpe.h>
32 #include <vnet/udp/udp_local.h>
33
34 #include <vpp/api/vpe_msg_enum.h>
35 #include <vnet/l2/l2_classify.h>
36 #include <vnet/l2/l2_vtr.h>
37 #include <vnet/classify/in_out_acl.h>
38 #include <vnet/classify/policer_classify.h>
39 #include <vnet/classify/flow_classify.h>
40 #include <vnet/mpls/mpls.h>
41 #include <vnet/ipsec/ipsec.h>
42 #include <inttypes.h>
43 #include <vnet/ip/ip6_hop_by_hop.h>
44 #include <vnet/ip/ip_source_and_port_range_check.h>
45 #include <vnet/policer/xlate.h>
46 #include <vnet/span/span.h>
47 #include <vnet/policer/policer.h>
48 #include <vnet/policer/police.h>
49 #include <vnet/mfib/mfib_types.h>
50 #include <vnet/bonding/node.h>
51 #include <vnet/qos/qos_types.h>
52 #include <vnet/ethernet/ethernet_types_api.h>
53 #include <vnet/ip/ip_types_api.h>
54 #include "vat/json_format.h"
55 #include <vnet/ip/ip_types_api.h>
56 #include <vnet/ethernet/ethernet_types_api.h>
57
58 #include <inttypes.h>
59 #include <sys/stat.h>
60
61 #define vl_typedefs             /* define message structures */
62 #include <vpp/api/vpe_all_api_h.h>
63 #undef vl_typedefs
64
65 /* declare message handlers for each api */
66
67 #define vl_endianfun            /* define message structures */
68 #include <vpp/api/vpe_all_api_h.h>
69 #undef vl_endianfun
70
71 /* instantiate all the print functions we know about */
72 #if VPP_API_TEST_BUILTIN == 0
73 #define vl_print(handle, ...)
74 #else
75 #define vl_print(handle, ...) vlib_cli_output (handle, __VA_ARGS__)
76 #endif
77 #define vl_printfun
78 #include <vpp/api/vpe_all_api_h.h>
79 #undef vl_printfun
80
81 #define __plugin_msg_base 0
82 #include <vlibapi/vat_helper_macros.h>
83
84 #include <vnet/format_fns.h>
85
86 void vl_api_set_elog_main (elog_main_t * m);
87 int vl_api_set_elog_trace_api_messages (int enable);
88
89 #if VPP_API_TEST_BUILTIN == 0
90 #include <netdb.h>
91
92 u32
93 vl (void *p)
94 {
95   return vec_len (p);
96 }
97
98 int
99 vat_socket_connect (vat_main_t * vam)
100 {
101   int rv;
102   api_main_t *am = vlibapi_get_main ();
103   vam->socket_client_main = &socket_client_main;
104   if ((rv = vl_socket_client_connect ((char *) vam->socket_name,
105                                       "vpp_api_test",
106                                       0 /* default socket rx, tx buffer */ )))
107     return rv;
108
109   /* vpp expects the client index in network order */
110   vam->my_client_index = htonl (socket_client_main.client_index);
111   am->my_client_index = vam->my_client_index;
112   return 0;
113 }
114 #else /* vpp built-in case, we don't do sockets... */
115 int
116 vat_socket_connect (vat_main_t * vam)
117 {
118   return 0;
119 }
120
121 int
122 vl_socket_client_read (int wait)
123 {
124   return -1;
125 };
126
127 int
128 vl_socket_client_write ()
129 {
130   return -1;
131 };
132
133 void *
134 vl_socket_client_msg_alloc (int nbytes)
135 {
136   return 0;
137 }
138 #endif
139
140
141 f64
142 vat_time_now (vat_main_t * vam)
143 {
144 #if VPP_API_TEST_BUILTIN
145   return vlib_time_now (vam->vlib_main);
146 #else
147   return clib_time_now (&vam->clib_time);
148 #endif
149 }
150
151 void
152 errmsg (char *fmt, ...)
153 {
154   vat_main_t *vam = &vat_main;
155   va_list va;
156   u8 *s;
157
158   va_start (va, fmt);
159   s = va_format (0, fmt, &va);
160   va_end (va);
161
162   vec_add1 (s, 0);
163
164 #if VPP_API_TEST_BUILTIN
165   vlib_cli_output (vam->vlib_main, (char *) s);
166 #else
167   {
168     if (vam->ifp != stdin)
169       fformat (vam->ofp, "%s(%d): \n", vam->current_file,
170                vam->input_line_number);
171     else
172       fformat (vam->ofp, "%s\n", (char *) s);
173     fflush (vam->ofp);
174   }
175 #endif
176
177   vec_free (s);
178 }
179
180 #if VPP_API_TEST_BUILTIN == 0
181 static uword
182 api_unformat_sw_if_index (unformat_input_t * input, va_list * args)
183 {
184   vat_main_t *vam = va_arg (*args, vat_main_t *);
185   u32 *result = va_arg (*args, u32 *);
186   u8 *if_name;
187   uword *p;
188
189   if (!unformat (input, "%s", &if_name))
190     return 0;
191
192   p = hash_get_mem (vam->sw_if_index_by_interface_name, if_name);
193   if (p == 0)
194     return 0;
195   *result = p[0];
196   return 1;
197 }
198
199 static uword
200 api_unformat_hw_if_index (unformat_input_t * input, va_list * args)
201 {
202   return 0;
203 }
204
205 /* Parse an IP4 address %d.%d.%d.%d. */
206 uword
207 unformat_ip4_address (unformat_input_t * input, va_list * args)
208 {
209   u8 *result = va_arg (*args, u8 *);
210   unsigned a[4];
211
212   if (!unformat (input, "%d.%d.%d.%d", &a[0], &a[1], &a[2], &a[3]))
213     return 0;
214
215   if (a[0] >= 256 || a[1] >= 256 || a[2] >= 256 || a[3] >= 256)
216     return 0;
217
218   result[0] = a[0];
219   result[1] = a[1];
220   result[2] = a[2];
221   result[3] = a[3];
222
223   return 1;
224 }
225
226 uword
227 unformat_ethernet_address (unformat_input_t * input, va_list * args)
228 {
229   u8 *result = va_arg (*args, u8 *);
230   u32 i, a[6];
231
232   if (!unformat (input, "%_%x:%x:%x:%x:%x:%x%_",
233                  &a[0], &a[1], &a[2], &a[3], &a[4], &a[5]))
234     return 0;
235
236   /* Check range. */
237   for (i = 0; i < 6; i++)
238     if (a[i] >= (1 << 8))
239       return 0;
240
241   for (i = 0; i < 6; i++)
242     result[i] = a[i];
243
244   return 1;
245 }
246
247 /* Returns ethernet type as an int in host byte order. */
248 uword
249 unformat_ethernet_type_host_byte_order (unformat_input_t * input,
250                                         va_list * args)
251 {
252   u16 *result = va_arg (*args, u16 *);
253   int type;
254
255   /* Numeric type. */
256   if (unformat (input, "0x%x", &type) || unformat (input, "%d", &type))
257     {
258       if (type >= (1 << 16))
259         return 0;
260       *result = type;
261       return 1;
262     }
263   return 0;
264 }
265
266 /* Parse an IP46 address. */
267 uword
268 unformat_ip46_address (unformat_input_t * input, va_list * args)
269 {
270   ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
271   ip46_type_t type = va_arg (*args, ip46_type_t);
272   if ((type != IP46_TYPE_IP6) &&
273       unformat (input, "%U", unformat_ip4_address, &ip46->ip4))
274     {
275       ip46_address_mask_ip4 (ip46);
276       return 1;
277     }
278   else if ((type != IP46_TYPE_IP4) &&
279            unformat (input, "%U", unformat_ip6_address, &ip46->ip6))
280     {
281       return 1;
282     }
283   return 0;
284 }
285
286 /* Parse an IP6 address. */
287 uword
288 unformat_ip6_address (unformat_input_t * input, va_list * args)
289 {
290   ip6_address_t *result = va_arg (*args, ip6_address_t *);
291   u16 hex_quads[8];
292   uword hex_quad, n_hex_quads, hex_digit, n_hex_digits;
293   uword c, n_colon, double_colon_index;
294
295   n_hex_quads = hex_quad = n_hex_digits = n_colon = 0;
296   double_colon_index = ARRAY_LEN (hex_quads);
297   while ((c = unformat_get_input (input)) != UNFORMAT_END_OF_INPUT)
298     {
299       hex_digit = 16;
300       if (c >= '0' && c <= '9')
301         hex_digit = c - '0';
302       else if (c >= 'a' && c <= 'f')
303         hex_digit = c + 10 - 'a';
304       else if (c >= 'A' && c <= 'F')
305         hex_digit = c + 10 - 'A';
306       else if (c == ':' && n_colon < 2)
307         n_colon++;
308       else
309         {
310           unformat_put_input (input);
311           break;
312         }
313
314       /* Too many hex quads. */
315       if (n_hex_quads >= ARRAY_LEN (hex_quads))
316         return 0;
317
318       if (hex_digit < 16)
319         {
320           hex_quad = (hex_quad << 4) | hex_digit;
321
322           /* Hex quad must fit in 16 bits. */
323           if (n_hex_digits >= 4)
324             return 0;
325
326           n_colon = 0;
327           n_hex_digits++;
328         }
329
330       /* Save position of :: */
331       if (n_colon == 2)
332         {
333           /* More than one :: ? */
334           if (double_colon_index < ARRAY_LEN (hex_quads))
335             return 0;
336           double_colon_index = n_hex_quads;
337         }
338
339       if (n_colon > 0 && n_hex_digits > 0)
340         {
341           hex_quads[n_hex_quads++] = hex_quad;
342           hex_quad = 0;
343           n_hex_digits = 0;
344         }
345     }
346
347   if (n_hex_digits > 0)
348     hex_quads[n_hex_quads++] = hex_quad;
349
350   {
351     word i;
352
353     /* Expand :: to appropriate number of zero hex quads. */
354     if (double_colon_index < ARRAY_LEN (hex_quads))
355       {
356         word n_zero = ARRAY_LEN (hex_quads) - n_hex_quads;
357
358         for (i = n_hex_quads - 1; i >= (signed) double_colon_index; i--)
359           hex_quads[n_zero + i] = hex_quads[i];
360
361         for (i = 0; i < n_zero; i++)
362           hex_quads[double_colon_index + i] = 0;
363
364         n_hex_quads = ARRAY_LEN (hex_quads);
365       }
366
367     /* Too few hex quads given. */
368     if (n_hex_quads < ARRAY_LEN (hex_quads))
369       return 0;
370
371     for (i = 0; i < ARRAY_LEN (hex_quads); i++)
372       result->as_u16[i] = clib_host_to_net_u16 (hex_quads[i]);
373
374     return 1;
375   }
376 }
377
378 uword
379 unformat_ipsec_policy_action (unformat_input_t * input, va_list * args)
380 {
381   u32 *r = va_arg (*args, u32 *);
382
383   if (0);
384 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_POLICY_ACTION_##f;
385   foreach_ipsec_policy_action
386 #undef _
387     else
388     return 0;
389   return 1;
390 }
391
392 u8 *
393 format_ipsec_crypto_alg (u8 * s, va_list * args)
394 {
395   u32 i = va_arg (*args, u32);
396   u8 *t = 0;
397
398   switch (i)
399     {
400 #define _(v,f,str) case IPSEC_CRYPTO_ALG_##f: t = (u8 *) str; break;
401       foreach_ipsec_crypto_alg
402 #undef _
403     default:
404       return format (s, "unknown");
405     }
406   return format (s, "%s", t);
407 }
408
409 u8 *
410 format_ipsec_integ_alg (u8 * s, va_list * args)
411 {
412   u32 i = va_arg (*args, u32);
413   u8 *t = 0;
414
415   switch (i)
416     {
417 #define _(v,f,str) case IPSEC_INTEG_ALG_##f: t = (u8 *) str; break;
418       foreach_ipsec_integ_alg
419 #undef _
420     default:
421       return format (s, "unknown");
422     }
423   return format (s, "%s", t);
424 }
425
426 #else /* VPP_API_TEST_BUILTIN == 1 */
427 static uword
428 api_unformat_sw_if_index (unformat_input_t * input, va_list * args)
429 {
430   vat_main_t *vam __clib_unused = va_arg (*args, vat_main_t *);
431   vnet_main_t *vnm = vnet_get_main ();
432   u32 *result = va_arg (*args, u32 *);
433
434   return unformat (input, "%U", unformat_vnet_sw_interface, vnm, result);
435 }
436
437 static uword
438 api_unformat_hw_if_index (unformat_input_t * input, va_list * args)
439 {
440   vat_main_t *vam __clib_unused = va_arg (*args, vat_main_t *);
441   vnet_main_t *vnm = vnet_get_main ();
442   u32 *result = va_arg (*args, u32 *);
443
444   return unformat (input, "%U", unformat_vnet_hw_interface, vnm, result);
445 }
446
447 #endif /* VPP_API_TEST_BUILTIN */
448
449 uword
450 unformat_ipsec_api_crypto_alg (unformat_input_t * input, va_list * args)
451 {
452   u32 *r = va_arg (*args, u32 *);
453
454   if (0);
455 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_API_CRYPTO_ALG_##f;
456   foreach_ipsec_crypto_alg
457 #undef _
458     else
459     return 0;
460   return 1;
461 }
462
463 uword
464 unformat_ipsec_api_integ_alg (unformat_input_t * input, va_list * args)
465 {
466   u32 *r = va_arg (*args, u32 *);
467
468   if (0);
469 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_API_INTEG_ALG_##f;
470   foreach_ipsec_integ_alg
471 #undef _
472     else
473     return 0;
474   return 1;
475 }
476
477 static uword
478 unformat_policer_rate_type (unformat_input_t * input, va_list * args)
479 {
480   u8 *r = va_arg (*args, u8 *);
481
482   if (unformat (input, "kbps"))
483     *r = SSE2_QOS_RATE_KBPS;
484   else if (unformat (input, "pps"))
485     *r = SSE2_QOS_RATE_PPS;
486   else
487     return 0;
488   return 1;
489 }
490
491 static uword
492 unformat_policer_round_type (unformat_input_t * input, va_list * args)
493 {
494   u8 *r = va_arg (*args, u8 *);
495
496   if (unformat (input, "closest"))
497     *r = SSE2_QOS_ROUND_TO_CLOSEST;
498   else if (unformat (input, "up"))
499     *r = SSE2_QOS_ROUND_TO_UP;
500   else if (unformat (input, "down"))
501     *r = SSE2_QOS_ROUND_TO_DOWN;
502   else
503     return 0;
504   return 1;
505 }
506
507 static uword
508 unformat_policer_type (unformat_input_t * input, va_list * args)
509 {
510   u8 *r = va_arg (*args, u8 *);
511
512   if (unformat (input, "1r2c"))
513     *r = SSE2_QOS_POLICER_TYPE_1R2C;
514   else if (unformat (input, "1r3c"))
515     *r = SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697;
516   else if (unformat (input, "2r3c-2698"))
517     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698;
518   else if (unformat (input, "2r3c-4115"))
519     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115;
520   else if (unformat (input, "2r3c-mef5cf1"))
521     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1;
522   else
523     return 0;
524   return 1;
525 }
526
527 static uword
528 unformat_dscp (unformat_input_t * input, va_list * va)
529 {
530   u8 *r = va_arg (*va, u8 *);
531
532   if (0);
533 #define _(v,f,str) else if (unformat (input, str)) *r = VNET_DSCP_##f;
534   foreach_vnet_dscp
535 #undef _
536     else
537     return 0;
538   return 1;
539 }
540
541 static uword
542 unformat_policer_action_type (unformat_input_t * input, va_list * va)
543 {
544   sse2_qos_pol_action_params_st *a
545     = va_arg (*va, sse2_qos_pol_action_params_st *);
546
547   if (unformat (input, "drop"))
548     a->action_type = SSE2_QOS_ACTION_DROP;
549   else if (unformat (input, "transmit"))
550     a->action_type = SSE2_QOS_ACTION_TRANSMIT;
551   else if (unformat (input, "mark-and-transmit %U", unformat_dscp, &a->dscp))
552     a->action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
553   else
554     return 0;
555   return 1;
556 }
557
558 static uword
559 unformat_policer_classify_table_type (unformat_input_t * input, va_list * va)
560 {
561   u32 *r = va_arg (*va, u32 *);
562   u32 tid;
563
564   if (unformat (input, "ip4"))
565     tid = POLICER_CLASSIFY_TABLE_IP4;
566   else if (unformat (input, "ip6"))
567     tid = POLICER_CLASSIFY_TABLE_IP6;
568   else if (unformat (input, "l2"))
569     tid = POLICER_CLASSIFY_TABLE_L2;
570   else
571     return 0;
572
573   *r = tid;
574   return 1;
575 }
576
577 static uword
578 unformat_flow_classify_table_type (unformat_input_t * input, va_list * va)
579 {
580   u32 *r = va_arg (*va, u32 *);
581   u32 tid;
582
583   if (unformat (input, "ip4"))
584     tid = FLOW_CLASSIFY_TABLE_IP4;
585   else if (unformat (input, "ip6"))
586     tid = FLOW_CLASSIFY_TABLE_IP6;
587   else
588     return 0;
589
590   *r = tid;
591   return 1;
592 }
593
594 #if (VPP_API_TEST_BUILTIN==0)
595
596 static const char *mfib_flag_names[] = MFIB_ENTRY_NAMES_SHORT;
597 static const char *mfib_flag_long_names[] = MFIB_ENTRY_NAMES_LONG;
598 static const char *mfib_itf_flag_long_names[] = MFIB_ITF_NAMES_LONG;
599 static const char *mfib_itf_flag_names[] = MFIB_ITF_NAMES_SHORT;
600
601 uword
602 unformat_mfib_itf_flags (unformat_input_t * input, va_list * args)
603 {
604   mfib_itf_flags_t old, *iflags = va_arg (*args, mfib_itf_flags_t *);
605   mfib_itf_attribute_t attr;
606
607   old = *iflags;
608   FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
609   {
610     if (unformat (input, mfib_itf_flag_long_names[attr]))
611       *iflags |= (1 << attr);
612   }
613   FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
614   {
615     if (unformat (input, mfib_itf_flag_names[attr]))
616       *iflags |= (1 << attr);
617   }
618
619   return (old == *iflags ? 0 : 1);
620 }
621
622 uword
623 unformat_mfib_entry_flags (unformat_input_t * input, va_list * args)
624 {
625   mfib_entry_flags_t old, *eflags = va_arg (*args, mfib_entry_flags_t *);
626   mfib_entry_attribute_t attr;
627
628   old = *eflags;
629   FOR_EACH_MFIB_ATTRIBUTE (attr)
630   {
631     if (unformat (input, mfib_flag_long_names[attr]))
632       *eflags |= (1 << attr);
633   }
634   FOR_EACH_MFIB_ATTRIBUTE (attr)
635   {
636     if (unformat (input, mfib_flag_names[attr]))
637       *eflags |= (1 << attr);
638   }
639
640   return (old == *eflags ? 0 : 1);
641 }
642
643 u8 *
644 format_ip4_address (u8 * s, va_list * args)
645 {
646   u8 *a = va_arg (*args, u8 *);
647   return format (s, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]);
648 }
649
650 u8 *
651 format_ip6_address (u8 * s, va_list * args)
652 {
653   ip6_address_t *a = va_arg (*args, ip6_address_t *);
654   u32 i, i_max_n_zero, max_n_zeros, i_first_zero, n_zeros, last_double_colon;
655
656   i_max_n_zero = ARRAY_LEN (a->as_u16);
657   max_n_zeros = 0;
658   i_first_zero = i_max_n_zero;
659   n_zeros = 0;
660   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
661     {
662       u32 is_zero = a->as_u16[i] == 0;
663       if (is_zero && i_first_zero >= ARRAY_LEN (a->as_u16))
664         {
665           i_first_zero = i;
666           n_zeros = 0;
667         }
668       n_zeros += is_zero;
669       if ((!is_zero && n_zeros > max_n_zeros)
670           || (i + 1 >= ARRAY_LEN (a->as_u16) && n_zeros > max_n_zeros))
671         {
672           i_max_n_zero = i_first_zero;
673           max_n_zeros = n_zeros;
674           i_first_zero = ARRAY_LEN (a->as_u16);
675           n_zeros = 0;
676         }
677     }
678
679   last_double_colon = 0;
680   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
681     {
682       if (i == i_max_n_zero && max_n_zeros > 1)
683         {
684           s = format (s, "::");
685           i += max_n_zeros - 1;
686           last_double_colon = 1;
687         }
688       else
689         {
690           s = format (s, "%s%x",
691                       (last_double_colon || i == 0) ? "" : ":",
692                       clib_net_to_host_u16 (a->as_u16[i]));
693           last_double_colon = 0;
694         }
695     }
696
697   return s;
698 }
699
700 /* Format an IP46 address. */
701 u8 *
702 format_ip46_address (u8 * s, va_list * args)
703 {
704   ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
705   ip46_type_t type = va_arg (*args, ip46_type_t);
706   int is_ip4 = 1;
707
708   switch (type)
709     {
710     case IP46_TYPE_ANY:
711       is_ip4 = ip46_address_is_ip4 (ip46);
712       break;
713     case IP46_TYPE_IP4:
714       is_ip4 = 1;
715       break;
716     case IP46_TYPE_IP6:
717       is_ip4 = 0;
718       break;
719     }
720
721   return is_ip4 ?
722     format (s, "%U", format_ip4_address, &ip46->ip4) :
723     format (s, "%U", format_ip6_address, &ip46->ip6);
724 }
725
726 u8 *
727 format_ethernet_address (u8 * s, va_list * args)
728 {
729   u8 *a = va_arg (*args, u8 *);
730
731   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
732                  a[0], a[1], a[2], a[3], a[4], a[5]);
733 }
734 #endif
735
736 static void
737 increment_v4_address (vl_api_ip4_address_t * i)
738 {
739   ip4_address_t *a = (ip4_address_t *) i;
740   u32 v;
741
742   v = ntohl (a->as_u32) + 1;
743   a->as_u32 = ntohl (v);
744 }
745
746 static void
747 increment_v6_address (vl_api_ip6_address_t * i)
748 {
749   ip6_address_t *a = (ip6_address_t *) i;
750   u64 v0, v1;
751
752   v0 = clib_net_to_host_u64 (a->as_u64[0]);
753   v1 = clib_net_to_host_u64 (a->as_u64[1]);
754
755   v1 += 1;
756   if (v1 == 0)
757     v0 += 1;
758   a->as_u64[0] = clib_net_to_host_u64 (v0);
759   a->as_u64[1] = clib_net_to_host_u64 (v1);
760 }
761
762 static void
763 increment_address (vl_api_address_t * a)
764 {
765   if (a->af == ADDRESS_IP4)
766     increment_v4_address (&a->un.ip4);
767   else if (a->af == ADDRESS_IP6)
768     increment_v6_address (&a->un.ip6);
769 }
770
771 static void
772 set_ip4_address (vl_api_address_t * a, u32 v)
773 {
774   if (a->af == ADDRESS_IP4)
775     {
776       ip4_address_t *i = (ip4_address_t *) & a->un.ip4;
777       i->as_u32 = v;
778     }
779 }
780
781 void
782 ip_set (ip46_address_t * dst, void *src, u8 is_ip4)
783 {
784   if (is_ip4)
785     dst->ip4.as_u32 = ((ip4_address_t *) src)->as_u32;
786   else
787     clib_memcpy_fast (&dst->ip6, (ip6_address_t *) src,
788                       sizeof (ip6_address_t));
789 }
790
791 static void
792 increment_mac_address (u8 * mac)
793 {
794   u64 tmp = *((u64 *) mac);
795   tmp = clib_net_to_host_u64 (tmp);
796   tmp += 1 << 16;               /* skip unused (least significant) octets */
797   tmp = clib_host_to_net_u64 (tmp);
798
799   clib_memcpy (mac, &tmp, 6);
800 }
801
802 static void
803 vat_json_object_add_address (vat_json_node_t * node,
804                              const char *str, const vl_api_address_t * addr)
805 {
806   if (ADDRESS_IP6 == addr->af)
807     {
808       struct in6_addr ip6;
809
810       clib_memcpy (&ip6, &addr->un.ip6, sizeof (ip6));
811       vat_json_object_add_ip6 (node, str, ip6);
812     }
813   else
814     {
815       struct in_addr ip4;
816
817       clib_memcpy (&ip4, &addr->un.ip4, sizeof (ip4));
818       vat_json_object_add_ip4 (node, str, ip4);
819     }
820 }
821
822 static void
823 vat_json_object_add_prefix (vat_json_node_t * node,
824                             const vl_api_prefix_t * prefix)
825 {
826   vat_json_object_add_uint (node, "len", prefix->len);
827   vat_json_object_add_address (node, "address", &prefix->address);
828 }
829
830 static void vl_api_create_loopback_reply_t_handler
831   (vl_api_create_loopback_reply_t * mp)
832 {
833   vat_main_t *vam = &vat_main;
834   i32 retval = ntohl (mp->retval);
835
836   vam->retval = retval;
837   vam->regenerate_interface_table = 1;
838   vam->sw_if_index = ntohl (mp->sw_if_index);
839   vam->result_ready = 1;
840 }
841
842 static void vl_api_create_loopback_reply_t_handler_json
843   (vl_api_create_loopback_reply_t * mp)
844 {
845   vat_main_t *vam = &vat_main;
846   vat_json_node_t node;
847
848   vat_json_init_object (&node);
849   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
850   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
851
852   vat_json_print (vam->ofp, &node);
853   vat_json_free (&node);
854   vam->retval = ntohl (mp->retval);
855   vam->result_ready = 1;
856 }
857
858 static void vl_api_create_loopback_instance_reply_t_handler
859   (vl_api_create_loopback_instance_reply_t * mp)
860 {
861   vat_main_t *vam = &vat_main;
862   i32 retval = ntohl (mp->retval);
863
864   vam->retval = retval;
865   vam->regenerate_interface_table = 1;
866   vam->sw_if_index = ntohl (mp->sw_if_index);
867   vam->result_ready = 1;
868 }
869
870 static void vl_api_create_loopback_instance_reply_t_handler_json
871   (vl_api_create_loopback_instance_reply_t * mp)
872 {
873   vat_main_t *vam = &vat_main;
874   vat_json_node_t node;
875
876   vat_json_init_object (&node);
877   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
878   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
879
880   vat_json_print (vam->ofp, &node);
881   vat_json_free (&node);
882   vam->retval = ntohl (mp->retval);
883   vam->result_ready = 1;
884 }
885
886 static void vl_api_af_packet_create_reply_t_handler
887   (vl_api_af_packet_create_reply_t * mp)
888 {
889   vat_main_t *vam = &vat_main;
890   i32 retval = ntohl (mp->retval);
891
892   vam->retval = retval;
893   vam->regenerate_interface_table = 1;
894   vam->sw_if_index = ntohl (mp->sw_if_index);
895   vam->result_ready = 1;
896 }
897
898 static void vl_api_af_packet_create_reply_t_handler_json
899   (vl_api_af_packet_create_reply_t * mp)
900 {
901   vat_main_t *vam = &vat_main;
902   vat_json_node_t node;
903
904   vat_json_init_object (&node);
905   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
906   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
907
908   vat_json_print (vam->ofp, &node);
909   vat_json_free (&node);
910
911   vam->retval = ntohl (mp->retval);
912   vam->result_ready = 1;
913 }
914
915 static void vl_api_create_vlan_subif_reply_t_handler
916   (vl_api_create_vlan_subif_reply_t * mp)
917 {
918   vat_main_t *vam = &vat_main;
919   i32 retval = ntohl (mp->retval);
920
921   vam->retval = retval;
922   vam->regenerate_interface_table = 1;
923   vam->sw_if_index = ntohl (mp->sw_if_index);
924   vam->result_ready = 1;
925 }
926
927 static void vl_api_create_vlan_subif_reply_t_handler_json
928   (vl_api_create_vlan_subif_reply_t * mp)
929 {
930   vat_main_t *vam = &vat_main;
931   vat_json_node_t node;
932
933   vat_json_init_object (&node);
934   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
935   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
936
937   vat_json_print (vam->ofp, &node);
938   vat_json_free (&node);
939
940   vam->retval = ntohl (mp->retval);
941   vam->result_ready = 1;
942 }
943
944 static void vl_api_create_subif_reply_t_handler
945   (vl_api_create_subif_reply_t * mp)
946 {
947   vat_main_t *vam = &vat_main;
948   i32 retval = ntohl (mp->retval);
949
950   vam->retval = retval;
951   vam->regenerate_interface_table = 1;
952   vam->sw_if_index = ntohl (mp->sw_if_index);
953   vam->result_ready = 1;
954 }
955
956 static void vl_api_create_subif_reply_t_handler_json
957   (vl_api_create_subif_reply_t * mp)
958 {
959   vat_main_t *vam = &vat_main;
960   vat_json_node_t node;
961
962   vat_json_init_object (&node);
963   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
964   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
965
966   vat_json_print (vam->ofp, &node);
967   vat_json_free (&node);
968
969   vam->retval = ntohl (mp->retval);
970   vam->result_ready = 1;
971 }
972
973 static void vl_api_interface_name_renumber_reply_t_handler
974   (vl_api_interface_name_renumber_reply_t * mp)
975 {
976   vat_main_t *vam = &vat_main;
977   i32 retval = ntohl (mp->retval);
978
979   vam->retval = retval;
980   vam->regenerate_interface_table = 1;
981   vam->result_ready = 1;
982 }
983
984 static void vl_api_interface_name_renumber_reply_t_handler_json
985   (vl_api_interface_name_renumber_reply_t * mp)
986 {
987   vat_main_t *vam = &vat_main;
988   vat_json_node_t node;
989
990   vat_json_init_object (&node);
991   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
992
993   vat_json_print (vam->ofp, &node);
994   vat_json_free (&node);
995
996   vam->retval = ntohl (mp->retval);
997   vam->result_ready = 1;
998 }
999
1000 /*
1001  * Special-case: build the interface table, maintain
1002  * the next loopback sw_if_index vbl.
1003  */
1004 static void vl_api_sw_interface_details_t_handler
1005   (vl_api_sw_interface_details_t * mp)
1006 {
1007   vat_main_t *vam = &vat_main;
1008   u8 *s = format (0, "%s%c", mp->interface_name, 0);
1009
1010   hash_set_mem (vam->sw_if_index_by_interface_name, s,
1011                 ntohl (mp->sw_if_index));
1012
1013   /* In sub interface case, fill the sub interface table entry */
1014   if (mp->sw_if_index != mp->sup_sw_if_index)
1015     {
1016       sw_interface_subif_t *sub = NULL;
1017
1018       vec_add2 (vam->sw_if_subif_table, sub, 1);
1019
1020       vec_validate (sub->interface_name, strlen ((char *) s) + 1);
1021       strncpy ((char *) sub->interface_name, (char *) s,
1022                vec_len (sub->interface_name));
1023       sub->sw_if_index = ntohl (mp->sw_if_index);
1024       sub->sub_id = ntohl (mp->sub_id);
1025
1026       sub->raw_flags = ntohl (mp->sub_if_flags & SUB_IF_API_FLAG_MASK_VNET);
1027
1028       sub->sub_number_of_tags = mp->sub_number_of_tags;
1029       sub->sub_outer_vlan_id = ntohs (mp->sub_outer_vlan_id);
1030       sub->sub_inner_vlan_id = ntohs (mp->sub_inner_vlan_id);
1031
1032       /* vlan tag rewrite */
1033       sub->vtr_op = ntohl (mp->vtr_op);
1034       sub->vtr_push_dot1q = ntohl (mp->vtr_push_dot1q);
1035       sub->vtr_tag1 = ntohl (mp->vtr_tag1);
1036       sub->vtr_tag2 = ntohl (mp->vtr_tag2);
1037     }
1038 }
1039
1040 static void vl_api_sw_interface_details_t_handler_json
1041   (vl_api_sw_interface_details_t * mp)
1042 {
1043   vat_main_t *vam = &vat_main;
1044   vat_json_node_t *node = NULL;
1045
1046   if (VAT_JSON_ARRAY != vam->json_tree.type)
1047     {
1048       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1049       vat_json_init_array (&vam->json_tree);
1050     }
1051   node = vat_json_array_add (&vam->json_tree);
1052
1053   vat_json_init_object (node);
1054   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
1055   vat_json_object_add_uint (node, "sup_sw_if_index",
1056                             ntohl (mp->sup_sw_if_index));
1057   vat_json_object_add_bytes (node, "l2_address", mp->l2_address,
1058                              sizeof (mp->l2_address));
1059   vat_json_object_add_string_copy (node, "interface_name",
1060                                    mp->interface_name);
1061   vat_json_object_add_string_copy (node, "interface_dev_type",
1062                                    mp->interface_dev_type);
1063   vat_json_object_add_uint (node, "flags", mp->flags);
1064   vat_json_object_add_uint (node, "link_duplex", mp->link_duplex);
1065   vat_json_object_add_uint (node, "link_speed", mp->link_speed);
1066   vat_json_object_add_uint (node, "mtu", ntohs (mp->link_mtu));
1067   vat_json_object_add_uint (node, "sub_id", ntohl (mp->sub_id));
1068   vat_json_object_add_uint (node, "sub_number_of_tags",
1069                             mp->sub_number_of_tags);
1070   vat_json_object_add_uint (node, "sub_outer_vlan_id",
1071                             ntohs (mp->sub_outer_vlan_id));
1072   vat_json_object_add_uint (node, "sub_inner_vlan_id",
1073                             ntohs (mp->sub_inner_vlan_id));
1074   vat_json_object_add_uint (node, "sub_if_flags", ntohl (mp->sub_if_flags));
1075   vat_json_object_add_uint (node, "vtr_op", ntohl (mp->vtr_op));
1076   vat_json_object_add_uint (node, "vtr_push_dot1q",
1077                             ntohl (mp->vtr_push_dot1q));
1078   vat_json_object_add_uint (node, "vtr_tag1", ntohl (mp->vtr_tag1));
1079   vat_json_object_add_uint (node, "vtr_tag2", ntohl (mp->vtr_tag2));
1080   if (ntohl (mp->sub_if_flags) & SUB_IF_API_FLAG_DOT1AH)
1081     {
1082       vat_json_object_add_string_copy (node, "pbb_vtr_dmac",
1083                                        format (0, "%U",
1084                                                format_ethernet_address,
1085                                                &mp->b_dmac));
1086       vat_json_object_add_string_copy (node, "pbb_vtr_smac",
1087                                        format (0, "%U",
1088                                                format_ethernet_address,
1089                                                &mp->b_smac));
1090       vat_json_object_add_uint (node, "pbb_vtr_b_vlanid", mp->b_vlanid);
1091       vat_json_object_add_uint (node, "pbb_vtr_i_sid", mp->i_sid);
1092     }
1093 }
1094
1095 #if VPP_API_TEST_BUILTIN == 0
1096 static void vl_api_sw_interface_event_t_handler
1097   (vl_api_sw_interface_event_t * mp)
1098 {
1099   vat_main_t *vam = &vat_main;
1100   if (vam->interface_event_display)
1101     errmsg ("interface flags: sw_if_index %d %s %s",
1102             ntohl (mp->sw_if_index),
1103             ((ntohl (mp->flags)) & IF_STATUS_API_FLAG_ADMIN_UP) ?
1104             "admin-up" : "admin-down",
1105             ((ntohl (mp->flags)) & IF_STATUS_API_FLAG_LINK_UP) ?
1106             "link-up" : "link-down");
1107 }
1108 #endif
1109
1110 __clib_unused static void
1111 vl_api_sw_interface_event_t_handler_json (vl_api_sw_interface_event_t * mp)
1112 {
1113   /* JSON output not supported */
1114 }
1115
1116 static void
1117 vl_api_cli_reply_t_handler (vl_api_cli_reply_t * mp)
1118 {
1119   vat_main_t *vam = &vat_main;
1120   i32 retval = ntohl (mp->retval);
1121
1122   vam->retval = retval;
1123   vam->shmem_result = uword_to_pointer (mp->reply_in_shmem, u8 *);
1124   vam->result_ready = 1;
1125 }
1126
1127 static void
1128 vl_api_cli_reply_t_handler_json (vl_api_cli_reply_t * mp)
1129 {
1130   vat_main_t *vam = &vat_main;
1131   vat_json_node_t node;
1132   void *oldheap;
1133   u8 *reply;
1134
1135   vat_json_init_object (&node);
1136   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1137   vat_json_object_add_uint (&node, "reply_in_shmem",
1138                             ntohl (mp->reply_in_shmem));
1139   /* Toss the shared-memory original... */
1140   oldheap = vl_msg_push_heap ();
1141
1142   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
1143   vec_free (reply);
1144
1145   vl_msg_pop_heap (oldheap);
1146
1147   vat_json_print (vam->ofp, &node);
1148   vat_json_free (&node);
1149
1150   vam->retval = ntohl (mp->retval);
1151   vam->result_ready = 1;
1152 }
1153
1154 static void
1155 vl_api_cli_inband_reply_t_handler (vl_api_cli_inband_reply_t * mp)
1156 {
1157   vat_main_t *vam = &vat_main;
1158   i32 retval = ntohl (mp->retval);
1159
1160   vec_reset_length (vam->cmd_reply);
1161
1162   vam->retval = retval;
1163   if (retval == 0)
1164     vam->cmd_reply = vl_api_from_api_to_new_vec (mp, &mp->reply);
1165   vam->result_ready = 1;
1166 }
1167
1168 static void
1169 vl_api_cli_inband_reply_t_handler_json (vl_api_cli_inband_reply_t * mp)
1170 {
1171   vat_main_t *vam = &vat_main;
1172   vat_json_node_t node;
1173   u8 *reply = 0;                /* reply vector */
1174
1175   reply = vl_api_from_api_to_new_vec (mp, &mp->reply);
1176   vec_reset_length (vam->cmd_reply);
1177
1178   vat_json_init_object (&node);
1179   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1180   vat_json_object_add_string_copy (&node, "reply", reply);
1181
1182   vat_json_print (vam->ofp, &node);
1183   vat_json_free (&node);
1184   vec_free (reply);
1185
1186   vam->retval = ntohl (mp->retval);
1187   vam->result_ready = 1;
1188 }
1189
1190 static void vl_api_classify_add_del_table_reply_t_handler
1191   (vl_api_classify_add_del_table_reply_t * mp)
1192 {
1193   vat_main_t *vam = &vat_main;
1194   i32 retval = ntohl (mp->retval);
1195   if (vam->async_mode)
1196     {
1197       vam->async_errors += (retval < 0);
1198     }
1199   else
1200     {
1201       vam->retval = retval;
1202       if (retval == 0 &&
1203           ((mp->new_table_index != 0xFFFFFFFF) ||
1204            (mp->skip_n_vectors != 0xFFFFFFFF) ||
1205            (mp->match_n_vectors != 0xFFFFFFFF)))
1206         /*
1207          * Note: this is just barely thread-safe, depends on
1208          * the main thread spinning waiting for an answer...
1209          */
1210         errmsg ("new index %d, skip_n_vectors %d, match_n_vectors %d",
1211                 ntohl (mp->new_table_index),
1212                 ntohl (mp->skip_n_vectors), ntohl (mp->match_n_vectors));
1213       vam->result_ready = 1;
1214     }
1215 }
1216
1217 static void vl_api_classify_add_del_table_reply_t_handler_json
1218   (vl_api_classify_add_del_table_reply_t * mp)
1219 {
1220   vat_main_t *vam = &vat_main;
1221   vat_json_node_t node;
1222
1223   vat_json_init_object (&node);
1224   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1225   vat_json_object_add_uint (&node, "new_table_index",
1226                             ntohl (mp->new_table_index));
1227   vat_json_object_add_uint (&node, "skip_n_vectors",
1228                             ntohl (mp->skip_n_vectors));
1229   vat_json_object_add_uint (&node, "match_n_vectors",
1230                             ntohl (mp->match_n_vectors));
1231
1232   vat_json_print (vam->ofp, &node);
1233   vat_json_free (&node);
1234
1235   vam->retval = ntohl (mp->retval);
1236   vam->result_ready = 1;
1237 }
1238
1239 static void vl_api_get_node_index_reply_t_handler
1240   (vl_api_get_node_index_reply_t * mp)
1241 {
1242   vat_main_t *vam = &vat_main;
1243   i32 retval = ntohl (mp->retval);
1244   if (vam->async_mode)
1245     {
1246       vam->async_errors += (retval < 0);
1247     }
1248   else
1249     {
1250       vam->retval = retval;
1251       if (retval == 0)
1252         errmsg ("node index %d", ntohl (mp->node_index));
1253       vam->result_ready = 1;
1254     }
1255 }
1256
1257 static void vl_api_get_node_index_reply_t_handler_json
1258   (vl_api_get_node_index_reply_t * mp)
1259 {
1260   vat_main_t *vam = &vat_main;
1261   vat_json_node_t node;
1262
1263   vat_json_init_object (&node);
1264   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1265   vat_json_object_add_uint (&node, "node_index", ntohl (mp->node_index));
1266
1267   vat_json_print (vam->ofp, &node);
1268   vat_json_free (&node);
1269
1270   vam->retval = ntohl (mp->retval);
1271   vam->result_ready = 1;
1272 }
1273
1274 static void vl_api_get_next_index_reply_t_handler
1275   (vl_api_get_next_index_reply_t * mp)
1276 {
1277   vat_main_t *vam = &vat_main;
1278   i32 retval = ntohl (mp->retval);
1279   if (vam->async_mode)
1280     {
1281       vam->async_errors += (retval < 0);
1282     }
1283   else
1284     {
1285       vam->retval = retval;
1286       if (retval == 0)
1287         errmsg ("next node index %d", ntohl (mp->next_index));
1288       vam->result_ready = 1;
1289     }
1290 }
1291
1292 static void vl_api_get_next_index_reply_t_handler_json
1293   (vl_api_get_next_index_reply_t * mp)
1294 {
1295   vat_main_t *vam = &vat_main;
1296   vat_json_node_t node;
1297
1298   vat_json_init_object (&node);
1299   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1300   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1301
1302   vat_json_print (vam->ofp, &node);
1303   vat_json_free (&node);
1304
1305   vam->retval = ntohl (mp->retval);
1306   vam->result_ready = 1;
1307 }
1308
1309 static void vl_api_add_node_next_reply_t_handler
1310   (vl_api_add_node_next_reply_t * mp)
1311 {
1312   vat_main_t *vam = &vat_main;
1313   i32 retval = ntohl (mp->retval);
1314   if (vam->async_mode)
1315     {
1316       vam->async_errors += (retval < 0);
1317     }
1318   else
1319     {
1320       vam->retval = retval;
1321       if (retval == 0)
1322         errmsg ("next index %d", ntohl (mp->next_index));
1323       vam->result_ready = 1;
1324     }
1325 }
1326
1327 static void vl_api_add_node_next_reply_t_handler_json
1328   (vl_api_add_node_next_reply_t * mp)
1329 {
1330   vat_main_t *vam = &vat_main;
1331   vat_json_node_t node;
1332
1333   vat_json_init_object (&node);
1334   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1335   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1336
1337   vat_json_print (vam->ofp, &node);
1338   vat_json_free (&node);
1339
1340   vam->retval = ntohl (mp->retval);
1341   vam->result_ready = 1;
1342 }
1343
1344 static void vl_api_show_version_reply_t_handler
1345   (vl_api_show_version_reply_t * mp)
1346 {
1347   vat_main_t *vam = &vat_main;
1348   i32 retval = ntohl (mp->retval);
1349
1350   if (retval >= 0)
1351     {
1352       errmsg ("        program: %s", mp->program);
1353       errmsg ("        version: %s", mp->version);
1354       errmsg ("     build date: %s", mp->build_date);
1355       errmsg ("build directory: %s", mp->build_directory);
1356     }
1357   vam->retval = retval;
1358   vam->result_ready = 1;
1359 }
1360
1361 static void vl_api_show_version_reply_t_handler_json
1362   (vl_api_show_version_reply_t * mp)
1363 {
1364   vat_main_t *vam = &vat_main;
1365   vat_json_node_t node;
1366
1367   vat_json_init_object (&node);
1368   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1369   vat_json_object_add_string_copy (&node, "program", mp->program);
1370   vat_json_object_add_string_copy (&node, "version", mp->version);
1371   vat_json_object_add_string_copy (&node, "build_date", mp->build_date);
1372   vat_json_object_add_string_copy (&node, "build_directory",
1373                                    mp->build_directory);
1374
1375   vat_json_print (vam->ofp, &node);
1376   vat_json_free (&node);
1377
1378   vam->retval = ntohl (mp->retval);
1379   vam->result_ready = 1;
1380 }
1381
1382 static void vl_api_show_threads_reply_t_handler
1383   (vl_api_show_threads_reply_t * mp)
1384 {
1385   vat_main_t *vam = &vat_main;
1386   i32 retval = ntohl (mp->retval);
1387   int i, count = 0;
1388
1389   if (retval >= 0)
1390     count = ntohl (mp->count);
1391
1392   for (i = 0; i < count; i++)
1393     print (vam->ofp,
1394            "\n%-2d %-11s %-11s %-5d %-6d %-4d %-6d",
1395            ntohl (mp->thread_data[i].id), mp->thread_data[i].name,
1396            mp->thread_data[i].type, ntohl (mp->thread_data[i].pid),
1397            ntohl (mp->thread_data[i].cpu_id), ntohl (mp->thread_data[i].core),
1398            ntohl (mp->thread_data[i].cpu_socket));
1399
1400   vam->retval = retval;
1401   vam->result_ready = 1;
1402 }
1403
1404 static void vl_api_show_threads_reply_t_handler_json
1405   (vl_api_show_threads_reply_t * mp)
1406 {
1407   vat_main_t *vam = &vat_main;
1408   vat_json_node_t node;
1409   vl_api_thread_data_t *td;
1410   i32 retval = ntohl (mp->retval);
1411   int i, count = 0;
1412
1413   if (retval >= 0)
1414     count = ntohl (mp->count);
1415
1416   vat_json_init_object (&node);
1417   vat_json_object_add_int (&node, "retval", retval);
1418   vat_json_object_add_uint (&node, "count", count);
1419
1420   for (i = 0; i < count; i++)
1421     {
1422       td = &mp->thread_data[i];
1423       vat_json_object_add_uint (&node, "id", ntohl (td->id));
1424       vat_json_object_add_string_copy (&node, "name", td->name);
1425       vat_json_object_add_string_copy (&node, "type", td->type);
1426       vat_json_object_add_uint (&node, "pid", ntohl (td->pid));
1427       vat_json_object_add_int (&node, "cpu_id", ntohl (td->cpu_id));
1428       vat_json_object_add_int (&node, "core", ntohl (td->id));
1429       vat_json_object_add_int (&node, "cpu_socket", ntohl (td->cpu_socket));
1430     }
1431
1432   vat_json_print (vam->ofp, &node);
1433   vat_json_free (&node);
1434
1435   vam->retval = retval;
1436   vam->result_ready = 1;
1437 }
1438
1439 static int
1440 api_show_threads (vat_main_t * vam)
1441 {
1442   vl_api_show_threads_t *mp;
1443   int ret;
1444
1445   print (vam->ofp,
1446          "\n%-2s %-11s %-11s %-5s %-6s %-4s %-6s",
1447          "ID", "Name", "Type", "LWP", "cpu_id", "Core", "Socket");
1448
1449   M (SHOW_THREADS, mp);
1450
1451   S (mp);
1452   W (ret);
1453   return ret;
1454 }
1455
1456 static void
1457 vl_api_l2_macs_event_t_handler (vl_api_l2_macs_event_t * mp)
1458 {
1459   u32 n_macs = ntohl (mp->n_macs);
1460   errmsg ("L2MAC event received with pid %d cl-idx %d for %d macs: \n",
1461           ntohl (mp->pid), mp->client_index, n_macs);
1462   int i;
1463   for (i = 0; i < n_macs; i++)
1464     {
1465       vl_api_mac_entry_t *mac = &mp->mac[i];
1466       errmsg (" [%d] sw_if_index %d  mac_addr %U  action %d \n",
1467               i + 1, ntohl (mac->sw_if_index),
1468               format_ethernet_address, mac->mac_addr, mac->action);
1469       if (i == 1000)
1470         break;
1471     }
1472 }
1473
1474 static void
1475 vl_api_l2_macs_event_t_handler_json (vl_api_l2_macs_event_t * mp)
1476 {
1477   /* JSON output not supported */
1478 }
1479
1480 #define vl_api_bridge_domain_details_t_endian vl_noop_handler
1481 #define vl_api_bridge_domain_details_t_print vl_noop_handler
1482
1483 /*
1484  * Special-case: build the bridge domain table, maintain
1485  * the next bd id vbl.
1486  */
1487 static void vl_api_bridge_domain_details_t_handler
1488   (vl_api_bridge_domain_details_t * mp)
1489 {
1490   vat_main_t *vam = &vat_main;
1491   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1492   int i;
1493
1494   print (vam->ofp, "\n%-3s %-3s %-3s %-3s %-3s %-6s %-3s",
1495          " ID", "LRN", "FWD", "FLD", "BVI", "UU-FWD", "#IF");
1496
1497   print (vam->ofp, "%3d %3d %3d %3d %3d %6d %3d",
1498          ntohl (mp->bd_id), mp->learn, mp->forward,
1499          mp->flood, ntohl (mp->bvi_sw_if_index),
1500          ntohl (mp->uu_fwd_sw_if_index), n_sw_ifs);
1501
1502   if (n_sw_ifs)
1503     {
1504       vl_api_bridge_domain_sw_if_t *sw_ifs;
1505       print (vam->ofp, "\n\n%s %s  %s", "sw_if_index", "SHG",
1506              "Interface Name");
1507
1508       sw_ifs = mp->sw_if_details;
1509       for (i = 0; i < n_sw_ifs; i++)
1510         {
1511           u8 *sw_if_name = 0;
1512           u32 sw_if_index;
1513           hash_pair_t *p;
1514
1515           sw_if_index = ntohl (sw_ifs->sw_if_index);
1516
1517           /* *INDENT-OFF* */
1518           hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
1519                              ({
1520                                if ((u32) p->value[0] == sw_if_index)
1521                                  {
1522                                    sw_if_name = (u8 *)(p->key);
1523                                    break;
1524                                  }
1525                              }));
1526           /* *INDENT-ON* */
1527           print (vam->ofp, "%7d     %3d  %s", sw_if_index,
1528                  sw_ifs->shg, sw_if_name ? (char *) sw_if_name :
1529                  "sw_if_index not found!");
1530
1531           sw_ifs++;
1532         }
1533     }
1534 }
1535
1536 static void vl_api_bridge_domain_details_t_handler_json
1537   (vl_api_bridge_domain_details_t * mp)
1538 {
1539   vat_main_t *vam = &vat_main;
1540   vat_json_node_t *node, *array = NULL;
1541   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1542
1543   if (VAT_JSON_ARRAY != vam->json_tree.type)
1544     {
1545       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1546       vat_json_init_array (&vam->json_tree);
1547     }
1548   node = vat_json_array_add (&vam->json_tree);
1549
1550   vat_json_init_object (node);
1551   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1552   vat_json_object_add_uint (node, "flood", mp->flood);
1553   vat_json_object_add_uint (node, "forward", mp->forward);
1554   vat_json_object_add_uint (node, "learn", mp->learn);
1555   vat_json_object_add_uint (node, "bvi_sw_if_index",
1556                             ntohl (mp->bvi_sw_if_index));
1557   vat_json_object_add_uint (node, "n_sw_ifs", n_sw_ifs);
1558   array = vat_json_object_add (node, "sw_if");
1559   vat_json_init_array (array);
1560
1561
1562
1563   if (n_sw_ifs)
1564     {
1565       vl_api_bridge_domain_sw_if_t *sw_ifs;
1566       int i;
1567
1568       sw_ifs = mp->sw_if_details;
1569       for (i = 0; i < n_sw_ifs; i++)
1570         {
1571           node = vat_json_array_add (array);
1572           vat_json_init_object (node);
1573           vat_json_object_add_uint (node, "sw_if_index",
1574                                     ntohl (sw_ifs->sw_if_index));
1575           vat_json_object_add_uint (node, "shg", sw_ifs->shg);
1576           sw_ifs++;
1577         }
1578     }
1579 }
1580
1581 static void vl_api_control_ping_reply_t_handler
1582   (vl_api_control_ping_reply_t * mp)
1583 {
1584   vat_main_t *vam = &vat_main;
1585   i32 retval = ntohl (mp->retval);
1586   if (vam->async_mode)
1587     {
1588       vam->async_errors += (retval < 0);
1589     }
1590   else
1591     {
1592       vam->retval = retval;
1593       vam->result_ready = 1;
1594     }
1595   if (vam->socket_client_main)
1596     vam->socket_client_main->control_pings_outstanding--;
1597 }
1598
1599 static void vl_api_control_ping_reply_t_handler_json
1600   (vl_api_control_ping_reply_t * mp)
1601 {
1602   vat_main_t *vam = &vat_main;
1603   i32 retval = ntohl (mp->retval);
1604
1605   if (VAT_JSON_NONE != vam->json_tree.type)
1606     {
1607       vat_json_print (vam->ofp, &vam->json_tree);
1608       vat_json_free (&vam->json_tree);
1609       vam->json_tree.type = VAT_JSON_NONE;
1610     }
1611   else
1612     {
1613       /* just print [] */
1614       vat_json_init_array (&vam->json_tree);
1615       vat_json_print (vam->ofp, &vam->json_tree);
1616       vam->json_tree.type = VAT_JSON_NONE;
1617     }
1618
1619   vam->retval = retval;
1620   vam->result_ready = 1;
1621 }
1622
1623 static void
1624   vl_api_bridge_domain_set_mac_age_reply_t_handler
1625   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1626 {
1627   vat_main_t *vam = &vat_main;
1628   i32 retval = ntohl (mp->retval);
1629   if (vam->async_mode)
1630     {
1631       vam->async_errors += (retval < 0);
1632     }
1633   else
1634     {
1635       vam->retval = retval;
1636       vam->result_ready = 1;
1637     }
1638 }
1639
1640 static void vl_api_bridge_domain_set_mac_age_reply_t_handler_json
1641   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1642 {
1643   vat_main_t *vam = &vat_main;
1644   vat_json_node_t node;
1645
1646   vat_json_init_object (&node);
1647   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1648
1649   vat_json_print (vam->ofp, &node);
1650   vat_json_free (&node);
1651
1652   vam->retval = ntohl (mp->retval);
1653   vam->result_ready = 1;
1654 }
1655
1656 static void
1657 vl_api_l2_flags_reply_t_handler (vl_api_l2_flags_reply_t * mp)
1658 {
1659   vat_main_t *vam = &vat_main;
1660   i32 retval = ntohl (mp->retval);
1661   if (vam->async_mode)
1662     {
1663       vam->async_errors += (retval < 0);
1664     }
1665   else
1666     {
1667       vam->retval = retval;
1668       vam->result_ready = 1;
1669     }
1670 }
1671
1672 static void vl_api_l2_flags_reply_t_handler_json
1673   (vl_api_l2_flags_reply_t * mp)
1674 {
1675   vat_main_t *vam = &vat_main;
1676   vat_json_node_t node;
1677
1678   vat_json_init_object (&node);
1679   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1680   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1681                             ntohl (mp->resulting_feature_bitmap));
1682
1683   vat_json_print (vam->ofp, &node);
1684   vat_json_free (&node);
1685
1686   vam->retval = ntohl (mp->retval);
1687   vam->result_ready = 1;
1688 }
1689
1690 static void vl_api_bridge_flags_reply_t_handler
1691   (vl_api_bridge_flags_reply_t * mp)
1692 {
1693   vat_main_t *vam = &vat_main;
1694   i32 retval = ntohl (mp->retval);
1695   if (vam->async_mode)
1696     {
1697       vam->async_errors += (retval < 0);
1698     }
1699   else
1700     {
1701       vam->retval = retval;
1702       vam->result_ready = 1;
1703     }
1704 }
1705
1706 static void vl_api_bridge_flags_reply_t_handler_json
1707   (vl_api_bridge_flags_reply_t * mp)
1708 {
1709   vat_main_t *vam = &vat_main;
1710   vat_json_node_t node;
1711
1712   vat_json_init_object (&node);
1713   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1714   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1715                             ntohl (mp->resulting_feature_bitmap));
1716
1717   vat_json_print (vam->ofp, &node);
1718   vat_json_free (&node);
1719
1720   vam->retval = ntohl (mp->retval);
1721   vam->result_ready = 1;
1722 }
1723
1724 static void
1725 vl_api_tap_create_v2_reply_t_handler (vl_api_tap_create_v2_reply_t * mp)
1726 {
1727   vat_main_t *vam = &vat_main;
1728   i32 retval = ntohl (mp->retval);
1729   if (vam->async_mode)
1730     {
1731       vam->async_errors += (retval < 0);
1732     }
1733   else
1734     {
1735       vam->retval = retval;
1736       vam->sw_if_index = ntohl (mp->sw_if_index);
1737       vam->result_ready = 1;
1738     }
1739
1740 }
1741
1742 static void vl_api_tap_create_v2_reply_t_handler_json
1743   (vl_api_tap_create_v2_reply_t * mp)
1744 {
1745   vat_main_t *vam = &vat_main;
1746   vat_json_node_t node;
1747
1748   vat_json_init_object (&node);
1749   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1750   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1751
1752   vat_json_print (vam->ofp, &node);
1753   vat_json_free (&node);
1754
1755   vam->retval = ntohl (mp->retval);
1756   vam->result_ready = 1;
1757
1758 }
1759
1760 static void
1761 vl_api_tap_delete_v2_reply_t_handler (vl_api_tap_delete_v2_reply_t * mp)
1762 {
1763   vat_main_t *vam = &vat_main;
1764   i32 retval = ntohl (mp->retval);
1765   if (vam->async_mode)
1766     {
1767       vam->async_errors += (retval < 0);
1768     }
1769   else
1770     {
1771       vam->retval = retval;
1772       vam->result_ready = 1;
1773     }
1774 }
1775
1776 static void vl_api_tap_delete_v2_reply_t_handler_json
1777   (vl_api_tap_delete_v2_reply_t * mp)
1778 {
1779   vat_main_t *vam = &vat_main;
1780   vat_json_node_t node;
1781
1782   vat_json_init_object (&node);
1783   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1784
1785   vat_json_print (vam->ofp, &node);
1786   vat_json_free (&node);
1787
1788   vam->retval = ntohl (mp->retval);
1789   vam->result_ready = 1;
1790 }
1791
1792 static void
1793 vl_api_virtio_pci_create_reply_t_handler (vl_api_virtio_pci_create_reply_t *
1794                                           mp)
1795 {
1796   vat_main_t *vam = &vat_main;
1797   i32 retval = ntohl (mp->retval);
1798   if (vam->async_mode)
1799     {
1800       vam->async_errors += (retval < 0);
1801     }
1802   else
1803     {
1804       vam->retval = retval;
1805       vam->sw_if_index = ntohl (mp->sw_if_index);
1806       vam->result_ready = 1;
1807     }
1808 }
1809
1810 static void vl_api_virtio_pci_create_reply_t_handler_json
1811   (vl_api_virtio_pci_create_reply_t * mp)
1812 {
1813   vat_main_t *vam = &vat_main;
1814   vat_json_node_t node;
1815
1816   vat_json_init_object (&node);
1817   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1818   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1819
1820   vat_json_print (vam->ofp, &node);
1821   vat_json_free (&node);
1822
1823   vam->retval = ntohl (mp->retval);
1824   vam->result_ready = 1;
1825
1826 }
1827
1828 static void
1829   vl_api_virtio_pci_create_v2_reply_t_handler
1830   (vl_api_virtio_pci_create_v2_reply_t * mp)
1831 {
1832   vat_main_t *vam = &vat_main;
1833   i32 retval = ntohl (mp->retval);
1834   if (vam->async_mode)
1835     {
1836       vam->async_errors += (retval < 0);
1837     }
1838   else
1839     {
1840       vam->retval = retval;
1841       vam->sw_if_index = ntohl (mp->sw_if_index);
1842       vam->result_ready = 1;
1843     }
1844 }
1845
1846 static void vl_api_virtio_pci_create_v2_reply_t_handler_json
1847   (vl_api_virtio_pci_create_v2_reply_t * mp)
1848 {
1849   vat_main_t *vam = &vat_main;
1850   vat_json_node_t node;
1851
1852   vat_json_init_object (&node);
1853   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1854   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1855
1856   vat_json_print (vam->ofp, &node);
1857   vat_json_free (&node);
1858
1859   vam->retval = ntohl (mp->retval);
1860   vam->result_ready = 1;
1861 }
1862
1863 static void
1864 vl_api_virtio_pci_delete_reply_t_handler (vl_api_virtio_pci_delete_reply_t *
1865                                           mp)
1866 {
1867   vat_main_t *vam = &vat_main;
1868   i32 retval = ntohl (mp->retval);
1869   if (vam->async_mode)
1870     {
1871       vam->async_errors += (retval < 0);
1872     }
1873   else
1874     {
1875       vam->retval = retval;
1876       vam->result_ready = 1;
1877     }
1878 }
1879
1880 static void vl_api_virtio_pci_delete_reply_t_handler_json
1881   (vl_api_virtio_pci_delete_reply_t * mp)
1882 {
1883   vat_main_t *vam = &vat_main;
1884   vat_json_node_t node;
1885
1886   vat_json_init_object (&node);
1887   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1888
1889   vat_json_print (vam->ofp, &node);
1890   vat_json_free (&node);
1891
1892   vam->retval = ntohl (mp->retval);
1893   vam->result_ready = 1;
1894 }
1895
1896 static void
1897 vl_api_bond_create_reply_t_handler (vl_api_bond_create_reply_t * mp)
1898 {
1899   vat_main_t *vam = &vat_main;
1900   i32 retval = ntohl (mp->retval);
1901
1902   if (vam->async_mode)
1903     {
1904       vam->async_errors += (retval < 0);
1905     }
1906   else
1907     {
1908       vam->retval = retval;
1909       vam->sw_if_index = ntohl (mp->sw_if_index);
1910       vam->result_ready = 1;
1911     }
1912 }
1913
1914 static void vl_api_bond_create_reply_t_handler_json
1915   (vl_api_bond_create_reply_t * mp)
1916 {
1917   vat_main_t *vam = &vat_main;
1918   vat_json_node_t node;
1919
1920   vat_json_init_object (&node);
1921   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1922   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1923
1924   vat_json_print (vam->ofp, &node);
1925   vat_json_free (&node);
1926
1927   vam->retval = ntohl (mp->retval);
1928   vam->result_ready = 1;
1929 }
1930
1931 static void
1932 vl_api_bond_create2_reply_t_handler (vl_api_bond_create2_reply_t * mp)
1933 {
1934   vat_main_t *vam = &vat_main;
1935   i32 retval = ntohl (mp->retval);
1936
1937   if (vam->async_mode)
1938     {
1939       vam->async_errors += (retval < 0);
1940     }
1941   else
1942     {
1943       vam->retval = retval;
1944       vam->sw_if_index = ntohl (mp->sw_if_index);
1945       vam->result_ready = 1;
1946     }
1947 }
1948
1949 static void vl_api_bond_create2_reply_t_handler_json
1950   (vl_api_bond_create2_reply_t * mp)
1951 {
1952   vat_main_t *vam = &vat_main;
1953   vat_json_node_t node;
1954
1955   vat_json_init_object (&node);
1956   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1957   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1958
1959   vat_json_print (vam->ofp, &node);
1960   vat_json_free (&node);
1961
1962   vam->retval = ntohl (mp->retval);
1963   vam->result_ready = 1;
1964 }
1965
1966 static void
1967 vl_api_bond_delete_reply_t_handler (vl_api_bond_delete_reply_t * mp)
1968 {
1969   vat_main_t *vam = &vat_main;
1970   i32 retval = ntohl (mp->retval);
1971
1972   if (vam->async_mode)
1973     {
1974       vam->async_errors += (retval < 0);
1975     }
1976   else
1977     {
1978       vam->retval = retval;
1979       vam->result_ready = 1;
1980     }
1981 }
1982
1983 static void vl_api_bond_delete_reply_t_handler_json
1984   (vl_api_bond_delete_reply_t * mp)
1985 {
1986   vat_main_t *vam = &vat_main;
1987   vat_json_node_t node;
1988
1989   vat_json_init_object (&node);
1990   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1991
1992   vat_json_print (vam->ofp, &node);
1993   vat_json_free (&node);
1994
1995   vam->retval = ntohl (mp->retval);
1996   vam->result_ready = 1;
1997 }
1998
1999 static void
2000 vl_api_bond_add_member_reply_t_handler (vl_api_bond_add_member_reply_t * mp)
2001 {
2002   vat_main_t *vam = &vat_main;
2003   i32 retval = ntohl (mp->retval);
2004
2005   if (vam->async_mode)
2006     {
2007       vam->async_errors += (retval < 0);
2008     }
2009   else
2010     {
2011       vam->retval = retval;
2012       vam->result_ready = 1;
2013     }
2014 }
2015
2016 static void vl_api_bond_add_member_reply_t_handler_json
2017   (vl_api_bond_add_member_reply_t * mp)
2018 {
2019   vat_main_t *vam = &vat_main;
2020   vat_json_node_t node;
2021
2022   vat_json_init_object (&node);
2023   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2024
2025   vat_json_print (vam->ofp, &node);
2026   vat_json_free (&node);
2027
2028   vam->retval = ntohl (mp->retval);
2029   vam->result_ready = 1;
2030 }
2031
2032 static void
2033 vl_api_bond_detach_member_reply_t_handler (vl_api_bond_detach_member_reply_t *
2034                                            mp)
2035 {
2036   vat_main_t *vam = &vat_main;
2037   i32 retval = ntohl (mp->retval);
2038
2039   if (vam->async_mode)
2040     {
2041       vam->async_errors += (retval < 0);
2042     }
2043   else
2044     {
2045       vam->retval = retval;
2046       vam->result_ready = 1;
2047     }
2048 }
2049
2050 static void vl_api_bond_detach_member_reply_t_handler_json
2051   (vl_api_bond_detach_member_reply_t * mp)
2052 {
2053   vat_main_t *vam = &vat_main;
2054   vat_json_node_t node;
2055
2056   vat_json_init_object (&node);
2057   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2058
2059   vat_json_print (vam->ofp, &node);
2060   vat_json_free (&node);
2061
2062   vam->retval = ntohl (mp->retval);
2063   vam->result_ready = 1;
2064 }
2065
2066 static int
2067 api_sw_interface_set_bond_weight (vat_main_t * vam)
2068 {
2069   unformat_input_t *i = vam->input;
2070   vl_api_sw_interface_set_bond_weight_t *mp;
2071   u32 sw_if_index = ~0;
2072   u32 weight = 0;
2073   u8 weight_enter = 0;
2074   int ret;
2075
2076   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2077     {
2078       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
2079         ;
2080       else if (unformat (i, "sw_if_index %d", &sw_if_index))
2081         ;
2082       else if (unformat (i, "weight %u", &weight))
2083         weight_enter = 1;
2084       else
2085         break;
2086     }
2087
2088   if (sw_if_index == ~0)
2089     {
2090       errmsg ("missing interface name or sw_if_index");
2091       return -99;
2092     }
2093   if (weight_enter == 0)
2094     {
2095       errmsg ("missing valid weight");
2096       return -99;
2097     }
2098
2099   /* Construct the API message */
2100   M (SW_INTERFACE_SET_BOND_WEIGHT, mp);
2101   mp->sw_if_index = ntohl (sw_if_index);
2102   mp->weight = ntohl (weight);
2103
2104   S (mp);
2105   W (ret);
2106   return ret;
2107 }
2108
2109 static void vl_api_sw_bond_interface_details_t_handler
2110   (vl_api_sw_bond_interface_details_t * mp)
2111 {
2112   vat_main_t *vam = &vat_main;
2113
2114   print (vam->ofp,
2115          "%-16s %-12d %-12U %-13U %-14u %-14u",
2116          mp->interface_name, ntohl (mp->sw_if_index),
2117          format_bond_mode, ntohl (mp->mode), format_bond_load_balance,
2118          ntohl (mp->lb), ntohl (mp->active_members), ntohl (mp->members));
2119 }
2120
2121 static void vl_api_sw_bond_interface_details_t_handler_json
2122   (vl_api_sw_bond_interface_details_t * mp)
2123 {
2124   vat_main_t *vam = &vat_main;
2125   vat_json_node_t *node = NULL;
2126
2127   if (VAT_JSON_ARRAY != vam->json_tree.type)
2128     {
2129       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2130       vat_json_init_array (&vam->json_tree);
2131     }
2132   node = vat_json_array_add (&vam->json_tree);
2133
2134   vat_json_init_object (node);
2135   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
2136   vat_json_object_add_string_copy (node, "interface_name",
2137                                    mp->interface_name);
2138   vat_json_object_add_uint (node, "mode", ntohl (mp->mode));
2139   vat_json_object_add_uint (node, "load_balance", ntohl (mp->lb));
2140   vat_json_object_add_uint (node, "active_members",
2141                             ntohl (mp->active_members));
2142   vat_json_object_add_uint (node, "members", ntohl (mp->members));
2143 }
2144
2145 static int
2146 api_sw_bond_interface_dump (vat_main_t * vam)
2147 {
2148   unformat_input_t *i = vam->input;
2149   vl_api_sw_bond_interface_dump_t *mp;
2150   vl_api_control_ping_t *mp_ping;
2151   int ret;
2152   u32 sw_if_index = ~0;
2153
2154   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2155     {
2156       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
2157         ;
2158       else if (unformat (i, "sw_if_index %d", &sw_if_index))
2159         ;
2160       else
2161         break;
2162     }
2163
2164   print (vam->ofp,
2165          "\n%-16s %-12s %-12s %-13s %-14s %-14s",
2166          "interface name", "sw_if_index", "mode", "load balance",
2167          "active members", "members");
2168
2169   /* Get list of bond interfaces */
2170   M (SW_BOND_INTERFACE_DUMP, mp);
2171   mp->sw_if_index = ntohl (sw_if_index);
2172   S (mp);
2173
2174   /* Use a control ping for synchronization */
2175   MPING (CONTROL_PING, mp_ping);
2176   S (mp_ping);
2177
2178   W (ret);
2179   return ret;
2180 }
2181
2182 static void vl_api_sw_member_interface_details_t_handler
2183   (vl_api_sw_member_interface_details_t * mp)
2184 {
2185   vat_main_t *vam = &vat_main;
2186
2187   print (vam->ofp,
2188          "%-25s %-12d %-7d %-12d %-10d %-10d", mp->interface_name,
2189          ntohl (mp->sw_if_index), mp->is_passive, mp->is_long_timeout,
2190          ntohl (mp->weight), mp->is_local_numa);
2191 }
2192
2193 static void vl_api_sw_member_interface_details_t_handler_json
2194   (vl_api_sw_member_interface_details_t * mp)
2195 {
2196   vat_main_t *vam = &vat_main;
2197   vat_json_node_t *node = NULL;
2198
2199   if (VAT_JSON_ARRAY != vam->json_tree.type)
2200     {
2201       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2202       vat_json_init_array (&vam->json_tree);
2203     }
2204   node = vat_json_array_add (&vam->json_tree);
2205
2206   vat_json_init_object (node);
2207   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
2208   vat_json_object_add_string_copy (node, "interface_name",
2209                                    mp->interface_name);
2210   vat_json_object_add_uint (node, "passive", mp->is_passive);
2211   vat_json_object_add_uint (node, "long_timeout", mp->is_long_timeout);
2212   vat_json_object_add_uint (node, "weight", ntohl (mp->weight));
2213   vat_json_object_add_uint (node, "is_local_numa", mp->is_local_numa);
2214 }
2215
2216 static int
2217 api_sw_member_interface_dump (vat_main_t * vam)
2218 {
2219   unformat_input_t *i = vam->input;
2220   vl_api_sw_member_interface_dump_t *mp;
2221   vl_api_control_ping_t *mp_ping;
2222   u32 sw_if_index = ~0;
2223   u8 sw_if_index_set = 0;
2224   int ret;
2225
2226   /* Parse args required to build the message */
2227   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2228     {
2229       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
2230         sw_if_index_set = 1;
2231       else if (unformat (i, "sw_if_index %d", &sw_if_index))
2232         sw_if_index_set = 1;
2233       else
2234         break;
2235     }
2236
2237   if (sw_if_index_set == 0)
2238     {
2239       errmsg ("missing vpp interface name. ");
2240       return -99;
2241     }
2242
2243   print (vam->ofp,
2244          "\n%-25s %-12s %-7s %-12s %-10s %-10s",
2245          "member interface name", "sw_if_index", "passive", "long_timeout",
2246          "weight", "local numa");
2247
2248   /* Get list of bond interfaces */
2249   M (SW_MEMBER_INTERFACE_DUMP, mp);
2250   mp->sw_if_index = ntohl (sw_if_index);
2251   S (mp);
2252
2253   /* Use a control ping for synchronization */
2254   MPING (CONTROL_PING, mp_ping);
2255   S (mp_ping);
2256
2257   W (ret);
2258   return ret;
2259 }
2260
2261 static void vl_api_mpls_tunnel_add_del_reply_t_handler
2262   (vl_api_mpls_tunnel_add_del_reply_t * mp)
2263 {
2264   vat_main_t *vam = &vat_main;
2265   i32 retval = ntohl (mp->retval);
2266   if (vam->async_mode)
2267     {
2268       vam->async_errors += (retval < 0);
2269     }
2270   else
2271     {
2272       vam->retval = retval;
2273       vam->sw_if_index = ntohl (mp->sw_if_index);
2274       vam->result_ready = 1;
2275     }
2276   vam->regenerate_interface_table = 1;
2277 }
2278
2279 static void vl_api_mpls_tunnel_add_del_reply_t_handler_json
2280   (vl_api_mpls_tunnel_add_del_reply_t * mp)
2281 {
2282   vat_main_t *vam = &vat_main;
2283   vat_json_node_t node;
2284
2285   vat_json_init_object (&node);
2286   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2287   vat_json_object_add_uint (&node, "tunnel_sw_if_index",
2288                             ntohl (mp->sw_if_index));
2289
2290   vat_json_print (vam->ofp, &node);
2291   vat_json_free (&node);
2292
2293   vam->retval = ntohl (mp->retval);
2294   vam->result_ready = 1;
2295 }
2296
2297 static void vl_api_vxlan_add_del_tunnel_reply_t_handler
2298   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
2299 {
2300   vat_main_t *vam = &vat_main;
2301   i32 retval = ntohl (mp->retval);
2302   if (vam->async_mode)
2303     {
2304       vam->async_errors += (retval < 0);
2305     }
2306   else
2307     {
2308       vam->retval = retval;
2309       vam->sw_if_index = ntohl (mp->sw_if_index);
2310       vam->result_ready = 1;
2311     }
2312   vam->regenerate_interface_table = 1;
2313 }
2314
2315 static void vl_api_vxlan_add_del_tunnel_reply_t_handler_json
2316   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
2317 {
2318   vat_main_t *vam = &vat_main;
2319   vat_json_node_t node;
2320
2321   vat_json_init_object (&node);
2322   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2323   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2324
2325   vat_json_print (vam->ofp, &node);
2326   vat_json_free (&node);
2327
2328   vam->retval = ntohl (mp->retval);
2329   vam->result_ready = 1;
2330 }
2331
2332 static void vl_api_vxlan_offload_rx_reply_t_handler
2333   (vl_api_vxlan_offload_rx_reply_t * mp)
2334 {
2335   vat_main_t *vam = &vat_main;
2336   i32 retval = ntohl (mp->retval);
2337   if (vam->async_mode)
2338     {
2339       vam->async_errors += (retval < 0);
2340     }
2341   else
2342     {
2343       vam->retval = retval;
2344       vam->result_ready = 1;
2345     }
2346 }
2347
2348 static void vl_api_vxlan_offload_rx_reply_t_handler_json
2349   (vl_api_vxlan_offload_rx_reply_t * mp)
2350 {
2351   vat_main_t *vam = &vat_main;
2352   vat_json_node_t node;
2353
2354   vat_json_init_object (&node);
2355   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2356
2357   vat_json_print (vam->ofp, &node);
2358   vat_json_free (&node);
2359
2360   vam->retval = ntohl (mp->retval);
2361   vam->result_ready = 1;
2362 }
2363
2364 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler
2365   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
2366 {
2367   vat_main_t *vam = &vat_main;
2368   i32 retval = ntohl (mp->retval);
2369   if (vam->async_mode)
2370     {
2371       vam->async_errors += (retval < 0);
2372     }
2373   else
2374     {
2375       vam->retval = retval;
2376       vam->sw_if_index = ntohl (mp->sw_if_index);
2377       vam->result_ready = 1;
2378     }
2379   vam->regenerate_interface_table = 1;
2380 }
2381
2382 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler_json
2383   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
2384 {
2385   vat_main_t *vam = &vat_main;
2386   vat_json_node_t node;
2387
2388   vat_json_init_object (&node);
2389   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2390   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2391
2392   vat_json_print (vam->ofp, &node);
2393   vat_json_free (&node);
2394
2395   vam->retval = ntohl (mp->retval);
2396   vam->result_ready = 1;
2397 }
2398
2399 static void vl_api_create_vhost_user_if_reply_t_handler
2400   (vl_api_create_vhost_user_if_reply_t * mp)
2401 {
2402   vat_main_t *vam = &vat_main;
2403   i32 retval = ntohl (mp->retval);
2404   if (vam->async_mode)
2405     {
2406       vam->async_errors += (retval < 0);
2407     }
2408   else
2409     {
2410       vam->retval = retval;
2411       vam->sw_if_index = ntohl (mp->sw_if_index);
2412       vam->result_ready = 1;
2413     }
2414   vam->regenerate_interface_table = 1;
2415 }
2416
2417 static void vl_api_create_vhost_user_if_reply_t_handler_json
2418   (vl_api_create_vhost_user_if_reply_t * mp)
2419 {
2420   vat_main_t *vam = &vat_main;
2421   vat_json_node_t node;
2422
2423   vat_json_init_object (&node);
2424   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2425   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2426
2427   vat_json_print (vam->ofp, &node);
2428   vat_json_free (&node);
2429
2430   vam->retval = ntohl (mp->retval);
2431   vam->result_ready = 1;
2432 }
2433
2434 static void vl_api_ip_address_details_t_handler
2435   (vl_api_ip_address_details_t * mp)
2436 {
2437   vat_main_t *vam = &vat_main;
2438   static ip_address_details_t empty_ip_address_details = { {0} };
2439   ip_address_details_t *address = NULL;
2440   ip_details_t *current_ip_details = NULL;
2441   ip_details_t *details = NULL;
2442
2443   details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
2444
2445   if (!details || vam->current_sw_if_index >= vec_len (details)
2446       || !details[vam->current_sw_if_index].present)
2447     {
2448       errmsg ("ip address details arrived but not stored");
2449       errmsg ("ip_dump should be called first");
2450       return;
2451     }
2452
2453   current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
2454
2455 #define addresses (current_ip_details->addr)
2456
2457   vec_validate_init_empty (addresses, vec_len (addresses),
2458                            empty_ip_address_details);
2459
2460   address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
2461
2462   clib_memcpy (&address->ip, &mp->prefix.address.un, sizeof (address->ip));
2463   address->prefix_length = mp->prefix.len;
2464 #undef addresses
2465 }
2466
2467 static void vl_api_ip_address_details_t_handler_json
2468   (vl_api_ip_address_details_t * mp)
2469 {
2470   vat_main_t *vam = &vat_main;
2471   vat_json_node_t *node = NULL;
2472
2473   if (VAT_JSON_ARRAY != vam->json_tree.type)
2474     {
2475       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2476       vat_json_init_array (&vam->json_tree);
2477     }
2478   node = vat_json_array_add (&vam->json_tree);
2479
2480   vat_json_init_object (node);
2481   vat_json_object_add_prefix (node, &mp->prefix);
2482 }
2483
2484 static void
2485 vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
2486 {
2487   vat_main_t *vam = &vat_main;
2488   static ip_details_t empty_ip_details = { 0 };
2489   ip_details_t *ip = NULL;
2490   u32 sw_if_index = ~0;
2491
2492   sw_if_index = ntohl (mp->sw_if_index);
2493
2494   vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2495                            sw_if_index, empty_ip_details);
2496
2497   ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2498                          sw_if_index);
2499
2500   ip->present = 1;
2501 }
2502
2503 static void
2504 vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
2505 {
2506   vat_main_t *vam = &vat_main;
2507
2508   if (VAT_JSON_ARRAY != vam->json_tree.type)
2509     {
2510       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2511       vat_json_init_array (&vam->json_tree);
2512     }
2513   vat_json_array_add_uint (&vam->json_tree,
2514                            clib_net_to_host_u32 (mp->sw_if_index));
2515 }
2516
2517 static void vl_api_get_first_msg_id_reply_t_handler
2518   (vl_api_get_first_msg_id_reply_t * mp)
2519 {
2520   vat_main_t *vam = &vat_main;
2521   i32 retval = ntohl (mp->retval);
2522
2523   if (vam->async_mode)
2524     {
2525       vam->async_errors += (retval < 0);
2526     }
2527   else
2528     {
2529       vam->retval = retval;
2530       vam->result_ready = 1;
2531     }
2532   if (retval >= 0)
2533     {
2534       errmsg ("first message id %d", ntohs (mp->first_msg_id));
2535     }
2536 }
2537
2538 static void vl_api_get_first_msg_id_reply_t_handler_json
2539   (vl_api_get_first_msg_id_reply_t * mp)
2540 {
2541   vat_main_t *vam = &vat_main;
2542   vat_json_node_t node;
2543
2544   vat_json_init_object (&node);
2545   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2546   vat_json_object_add_uint (&node, "first_msg_id",
2547                             (uint) ntohs (mp->first_msg_id));
2548
2549   vat_json_print (vam->ofp, &node);
2550   vat_json_free (&node);
2551
2552   vam->retval = ntohl (mp->retval);
2553   vam->result_ready = 1;
2554 }
2555
2556 static void vl_api_get_node_graph_reply_t_handler
2557   (vl_api_get_node_graph_reply_t * mp)
2558 {
2559   vat_main_t *vam = &vat_main;
2560   i32 retval = ntohl (mp->retval);
2561   u8 *pvt_copy, *reply;
2562   void *oldheap;
2563   vlib_node_t *node;
2564   int i;
2565
2566   if (vam->async_mode)
2567     {
2568       vam->async_errors += (retval < 0);
2569     }
2570   else
2571     {
2572       vam->retval = retval;
2573       vam->result_ready = 1;
2574     }
2575
2576   /* "Should never happen..." */
2577   if (retval != 0)
2578     return;
2579
2580   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2581   pvt_copy = vec_dup (reply);
2582
2583   /* Toss the shared-memory original... */
2584   oldheap = vl_msg_push_heap ();
2585
2586   vec_free (reply);
2587
2588   vl_msg_pop_heap (oldheap);
2589
2590   if (vam->graph_nodes)
2591     {
2592       hash_free (vam->graph_node_index_by_name);
2593
2594       for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
2595         {
2596           node = vam->graph_nodes[0][i];
2597           vec_free (node->name);
2598           vec_free (node->next_nodes);
2599           vec_free (node);
2600         }
2601       vec_free (vam->graph_nodes[0]);
2602       vec_free (vam->graph_nodes);
2603     }
2604
2605   vam->graph_node_index_by_name = hash_create_string (0, sizeof (uword));
2606   vam->graph_nodes = vlib_node_unserialize (pvt_copy);
2607   vec_free (pvt_copy);
2608
2609   for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
2610     {
2611       node = vam->graph_nodes[0][i];
2612       hash_set_mem (vam->graph_node_index_by_name, node->name, i);
2613     }
2614 }
2615
2616 static void vl_api_get_node_graph_reply_t_handler_json
2617   (vl_api_get_node_graph_reply_t * mp)
2618 {
2619   vat_main_t *vam = &vat_main;
2620   void *oldheap;
2621   vat_json_node_t node;
2622   u8 *reply;
2623
2624   /* $$$$ make this real? */
2625   vat_json_init_object (&node);
2626   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2627   vat_json_object_add_uint (&node, "reply_in_shmem", mp->reply_in_shmem);
2628
2629   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2630
2631   /* Toss the shared-memory original... */
2632   oldheap = vl_msg_push_heap ();
2633
2634   vec_free (reply);
2635
2636   vl_msg_pop_heap (oldheap);
2637
2638   vat_json_print (vam->ofp, &node);
2639   vat_json_free (&node);
2640
2641   vam->retval = ntohl (mp->retval);
2642   vam->result_ready = 1;
2643 }
2644
2645 static u8 *
2646 format_policer_type (u8 * s, va_list * va)
2647 {
2648   u32 i = va_arg (*va, u32);
2649
2650   if (i == SSE2_QOS_POLICER_TYPE_1R2C)
2651     s = format (s, "1r2c");
2652   else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
2653     s = format (s, "1r3c");
2654   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
2655     s = format (s, "2r3c-2698");
2656   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
2657     s = format (s, "2r3c-4115");
2658   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
2659     s = format (s, "2r3c-mef5cf1");
2660   else
2661     s = format (s, "ILLEGAL");
2662   return s;
2663 }
2664
2665 static u8 *
2666 format_policer_rate_type (u8 * s, va_list * va)
2667 {
2668   u32 i = va_arg (*va, u32);
2669
2670   if (i == SSE2_QOS_RATE_KBPS)
2671     s = format (s, "kbps");
2672   else if (i == SSE2_QOS_RATE_PPS)
2673     s = format (s, "pps");
2674   else
2675     s = format (s, "ILLEGAL");
2676   return s;
2677 }
2678
2679 static u8 *
2680 format_policer_round_type (u8 * s, va_list * va)
2681 {
2682   u32 i = va_arg (*va, u32);
2683
2684   if (i == SSE2_QOS_ROUND_TO_CLOSEST)
2685     s = format (s, "closest");
2686   else if (i == SSE2_QOS_ROUND_TO_UP)
2687     s = format (s, "up");
2688   else if (i == SSE2_QOS_ROUND_TO_DOWN)
2689     s = format (s, "down");
2690   else
2691     s = format (s, "ILLEGAL");
2692   return s;
2693 }
2694
2695 static u8 *
2696 format_policer_action_type (u8 * s, va_list * va)
2697 {
2698   u32 i = va_arg (*va, u32);
2699
2700   if (i == SSE2_QOS_ACTION_DROP)
2701     s = format (s, "drop");
2702   else if (i == SSE2_QOS_ACTION_TRANSMIT)
2703     s = format (s, "transmit");
2704   else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
2705     s = format (s, "mark-and-transmit");
2706   else
2707     s = format (s, "ILLEGAL");
2708   return s;
2709 }
2710
2711 static u8 *
2712 format_dscp (u8 * s, va_list * va)
2713 {
2714   u32 i = va_arg (*va, u32);
2715   char *t = 0;
2716
2717   switch (i)
2718     {
2719 #define _(v,f,str) case VNET_DSCP_##f: t = str; break;
2720       foreach_vnet_dscp
2721 #undef _
2722     default:
2723       return format (s, "ILLEGAL");
2724     }
2725   s = format (s, "%s", t);
2726   return s;
2727 }
2728
2729 static void
2730 vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
2731 {
2732   vat_main_t *vam = &vat_main;
2733   u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
2734
2735   if (mp->conform_action.type == SSE2_QOS_ACTION_API_MARK_AND_TRANSMIT)
2736     conform_dscp_str = format (0, "%U", format_dscp, mp->conform_action.dscp);
2737   else
2738     conform_dscp_str = format (0, "");
2739
2740   if (mp->exceed_action.type == SSE2_QOS_ACTION_API_MARK_AND_TRANSMIT)
2741     exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_action.dscp);
2742   else
2743     exceed_dscp_str = format (0, "");
2744
2745   if (mp->violate_action.type == SSE2_QOS_ACTION_API_MARK_AND_TRANSMIT)
2746     violate_dscp_str = format (0, "%U", format_dscp, mp->violate_action.dscp);
2747   else
2748     violate_dscp_str = format (0, "");
2749
2750   print (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
2751          "rate type %U, round type %U, %s rate, %s color-aware, "
2752          "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
2753          "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
2754          "conform action %U%s, exceed action %U%s, violate action %U%s",
2755          mp->name,
2756          format_policer_type, mp->type,
2757          ntohl (mp->cir),
2758          ntohl (mp->eir),
2759          clib_net_to_host_u64 (mp->cb),
2760          clib_net_to_host_u64 (mp->eb),
2761          format_policer_rate_type, mp->rate_type,
2762          format_policer_round_type, mp->round_type,
2763          mp->single_rate ? "single" : "dual",
2764          mp->color_aware ? "is" : "not",
2765          ntohl (mp->cir_tokens_per_period),
2766          ntohl (mp->pir_tokens_per_period),
2767          ntohl (mp->scale),
2768          ntohl (mp->current_limit),
2769          ntohl (mp->current_bucket),
2770          ntohl (mp->extended_limit),
2771          ntohl (mp->extended_bucket),
2772          clib_net_to_host_u64 (mp->last_update_time),
2773          format_policer_action_type, mp->conform_action.type,
2774          conform_dscp_str,
2775          format_policer_action_type, mp->exceed_action.type,
2776          exceed_dscp_str,
2777          format_policer_action_type, mp->violate_action.type,
2778          violate_dscp_str);
2779
2780   vec_free (conform_dscp_str);
2781   vec_free (exceed_dscp_str);
2782   vec_free (violate_dscp_str);
2783 }
2784
2785 static void vl_api_policer_details_t_handler_json
2786   (vl_api_policer_details_t * mp)
2787 {
2788   vat_main_t *vam = &vat_main;
2789   vat_json_node_t *node;
2790   u8 *rate_type_str, *round_type_str, *type_str;
2791   u8 *conform_action_str, *exceed_action_str, *violate_action_str;
2792
2793   rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
2794   round_type_str =
2795     format (0, "%U", format_policer_round_type, mp->round_type);
2796   type_str = format (0, "%U", format_policer_type, mp->type);
2797   conform_action_str = format (0, "%U", format_policer_action_type,
2798                                mp->conform_action.type);
2799   exceed_action_str = format (0, "%U", format_policer_action_type,
2800                               mp->exceed_action.type);
2801   violate_action_str = format (0, "%U", format_policer_action_type,
2802                                mp->violate_action.type);
2803
2804   if (VAT_JSON_ARRAY != vam->json_tree.type)
2805     {
2806       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2807       vat_json_init_array (&vam->json_tree);
2808     }
2809   node = vat_json_array_add (&vam->json_tree);
2810
2811   vat_json_init_object (node);
2812   vat_json_object_add_string_copy (node, "name", mp->name);
2813   vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
2814   vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
2815   vat_json_object_add_uint (node, "cb", clib_net_to_host_u64 (mp->cb));
2816   vat_json_object_add_uint (node, "eb", clib_net_to_host_u64 (mp->eb));
2817   vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
2818   vat_json_object_add_string_copy (node, "round_type", round_type_str);
2819   vat_json_object_add_string_copy (node, "type", type_str);
2820   vat_json_object_add_uint (node, "single_rate", mp->single_rate);
2821   vat_json_object_add_uint (node, "color_aware", mp->color_aware);
2822   vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
2823   vat_json_object_add_uint (node, "cir_tokens_per_period",
2824                             ntohl (mp->cir_tokens_per_period));
2825   vat_json_object_add_uint (node, "eir_tokens_per_period",
2826                             ntohl (mp->pir_tokens_per_period));
2827   vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
2828   vat_json_object_add_uint (node, "current_bucket",
2829                             ntohl (mp->current_bucket));
2830   vat_json_object_add_uint (node, "extended_limit",
2831                             ntohl (mp->extended_limit));
2832   vat_json_object_add_uint (node, "extended_bucket",
2833                             ntohl (mp->extended_bucket));
2834   vat_json_object_add_uint (node, "last_update_time",
2835                             ntohl (mp->last_update_time));
2836   vat_json_object_add_string_copy (node, "conform_action",
2837                                    conform_action_str);
2838   if (mp->conform_action.type == SSE2_QOS_ACTION_API_MARK_AND_TRANSMIT)
2839     {
2840       u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_action.dscp);
2841       vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
2842       vec_free (dscp_str);
2843     }
2844   vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
2845   if (mp->exceed_action.type == SSE2_QOS_ACTION_API_MARK_AND_TRANSMIT)
2846     {
2847       u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_action.dscp);
2848       vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
2849       vec_free (dscp_str);
2850     }
2851   vat_json_object_add_string_copy (node, "violate_action",
2852                                    violate_action_str);
2853   if (mp->violate_action.type == SSE2_QOS_ACTION_API_MARK_AND_TRANSMIT)
2854     {
2855       u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_action.dscp);
2856       vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
2857       vec_free (dscp_str);
2858     }
2859
2860   vec_free (rate_type_str);
2861   vec_free (round_type_str);
2862   vec_free (type_str);
2863   vec_free (conform_action_str);
2864   vec_free (exceed_action_str);
2865   vec_free (violate_action_str);
2866 }
2867
2868 static void
2869 vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
2870                                            mp)
2871 {
2872   vat_main_t *vam = &vat_main;
2873   int i, count = ntohl (mp->count);
2874
2875   if (count > 0)
2876     print (vam->ofp, "classify table ids (%d) : ", count);
2877   for (i = 0; i < count; i++)
2878     {
2879       print (vam->ofp, "%d", ntohl (mp->ids[i]));
2880       print (vam->ofp, (i < count - 1) ? "," : "");
2881     }
2882   vam->retval = ntohl (mp->retval);
2883   vam->result_ready = 1;
2884 }
2885
2886 static void
2887   vl_api_classify_table_ids_reply_t_handler_json
2888   (vl_api_classify_table_ids_reply_t * mp)
2889 {
2890   vat_main_t *vam = &vat_main;
2891   int i, count = ntohl (mp->count);
2892
2893   if (count > 0)
2894     {
2895       vat_json_node_t node;
2896
2897       vat_json_init_object (&node);
2898       for (i = 0; i < count; i++)
2899         {
2900           vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
2901         }
2902       vat_json_print (vam->ofp, &node);
2903       vat_json_free (&node);
2904     }
2905   vam->retval = ntohl (mp->retval);
2906   vam->result_ready = 1;
2907 }
2908
2909 static void
2910   vl_api_classify_table_by_interface_reply_t_handler
2911   (vl_api_classify_table_by_interface_reply_t * mp)
2912 {
2913   vat_main_t *vam = &vat_main;
2914   u32 table_id;
2915
2916   table_id = ntohl (mp->l2_table_id);
2917   if (table_id != ~0)
2918     print (vam->ofp, "l2 table id : %d", table_id);
2919   else
2920     print (vam->ofp, "l2 table id : No input ACL tables configured");
2921   table_id = ntohl (mp->ip4_table_id);
2922   if (table_id != ~0)
2923     print (vam->ofp, "ip4 table id : %d", table_id);
2924   else
2925     print (vam->ofp, "ip4 table id : No input ACL tables configured");
2926   table_id = ntohl (mp->ip6_table_id);
2927   if (table_id != ~0)
2928     print (vam->ofp, "ip6 table id : %d", table_id);
2929   else
2930     print (vam->ofp, "ip6 table id : No input ACL tables configured");
2931   vam->retval = ntohl (mp->retval);
2932   vam->result_ready = 1;
2933 }
2934
2935 static void
2936   vl_api_classify_table_by_interface_reply_t_handler_json
2937   (vl_api_classify_table_by_interface_reply_t * mp)
2938 {
2939   vat_main_t *vam = &vat_main;
2940   vat_json_node_t node;
2941
2942   vat_json_init_object (&node);
2943
2944   vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
2945   vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
2946   vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
2947
2948   vat_json_print (vam->ofp, &node);
2949   vat_json_free (&node);
2950
2951   vam->retval = ntohl (mp->retval);
2952   vam->result_ready = 1;
2953 }
2954
2955 static void vl_api_policer_add_del_reply_t_handler
2956   (vl_api_policer_add_del_reply_t * mp)
2957 {
2958   vat_main_t *vam = &vat_main;
2959   i32 retval = ntohl (mp->retval);
2960   if (vam->async_mode)
2961     {
2962       vam->async_errors += (retval < 0);
2963     }
2964   else
2965     {
2966       vam->retval = retval;
2967       vam->result_ready = 1;
2968       if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
2969         /*
2970          * Note: this is just barely thread-safe, depends on
2971          * the main thread spinning waiting for an answer...
2972          */
2973         errmsg ("policer index %d", ntohl (mp->policer_index));
2974     }
2975 }
2976
2977 static void vl_api_policer_add_del_reply_t_handler_json
2978   (vl_api_policer_add_del_reply_t * mp)
2979 {
2980   vat_main_t *vam = &vat_main;
2981   vat_json_node_t node;
2982
2983   vat_json_init_object (&node);
2984   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2985   vat_json_object_add_uint (&node, "policer_index",
2986                             ntohl (mp->policer_index));
2987
2988   vat_json_print (vam->ofp, &node);
2989   vat_json_free (&node);
2990
2991   vam->retval = ntohl (mp->retval);
2992   vam->result_ready = 1;
2993 }
2994
2995 /* Format hex dump. */
2996 u8 *
2997 format_hex_bytes (u8 * s, va_list * va)
2998 {
2999   u8 *bytes = va_arg (*va, u8 *);
3000   int n_bytes = va_arg (*va, int);
3001   uword i;
3002
3003   /* Print short or long form depending on byte count. */
3004   uword short_form = n_bytes <= 32;
3005   u32 indent = format_get_indent (s);
3006
3007   if (n_bytes == 0)
3008     return s;
3009
3010   for (i = 0; i < n_bytes; i++)
3011     {
3012       if (!short_form && (i % 32) == 0)
3013         s = format (s, "%08x: ", i);
3014       s = format (s, "%02x", bytes[i]);
3015       if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
3016         s = format (s, "\n%U", format_white_space, indent);
3017     }
3018
3019   return s;
3020 }
3021
3022 static void
3023 vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
3024                                             * mp)
3025 {
3026   vat_main_t *vam = &vat_main;
3027   i32 retval = ntohl (mp->retval);
3028   if (retval == 0)
3029     {
3030       print (vam->ofp, "classify table info :");
3031       print (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d",
3032              ntohl (mp->active_sessions), ntohl (mp->next_table_index),
3033              ntohl (mp->miss_next_index));
3034       print (vam->ofp, "nbuckets: %d skip: %d match: %d",
3035              ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
3036              ntohl (mp->match_n_vectors));
3037       print (vam->ofp, "mask: %U", format_hex_bytes, mp->mask,
3038              ntohl (mp->mask_length));
3039     }
3040   vam->retval = retval;
3041   vam->result_ready = 1;
3042 }
3043
3044 static void
3045   vl_api_classify_table_info_reply_t_handler_json
3046   (vl_api_classify_table_info_reply_t * mp)
3047 {
3048   vat_main_t *vam = &vat_main;
3049   vat_json_node_t node;
3050
3051   i32 retval = ntohl (mp->retval);
3052   if (retval == 0)
3053     {
3054       vat_json_init_object (&node);
3055
3056       vat_json_object_add_int (&node, "sessions",
3057                                ntohl (mp->active_sessions));
3058       vat_json_object_add_int (&node, "nexttbl",
3059                                ntohl (mp->next_table_index));
3060       vat_json_object_add_int (&node, "nextnode",
3061                                ntohl (mp->miss_next_index));
3062       vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
3063       vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
3064       vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
3065       u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
3066                       ntohl (mp->mask_length), 0);
3067       vat_json_object_add_string_copy (&node, "mask", s);
3068
3069       vat_json_print (vam->ofp, &node);
3070       vat_json_free (&node);
3071     }
3072   vam->retval = ntohl (mp->retval);
3073   vam->result_ready = 1;
3074 }
3075
3076 static void
3077 vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
3078                                            mp)
3079 {
3080   vat_main_t *vam = &vat_main;
3081
3082   print (vam->ofp, "next_index: %d advance: %d opaque: %d ",
3083          ntohl (mp->hit_next_index), ntohl (mp->advance),
3084          ntohl (mp->opaque_index));
3085   print (vam->ofp, "mask: %U", format_hex_bytes, mp->match,
3086          ntohl (mp->match_length));
3087 }
3088
3089 static void
3090   vl_api_classify_session_details_t_handler_json
3091   (vl_api_classify_session_details_t * mp)
3092 {
3093   vat_main_t *vam = &vat_main;
3094   vat_json_node_t *node = NULL;
3095
3096   if (VAT_JSON_ARRAY != vam->json_tree.type)
3097     {
3098       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3099       vat_json_init_array (&vam->json_tree);
3100     }
3101   node = vat_json_array_add (&vam->json_tree);
3102
3103   vat_json_init_object (node);
3104   vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
3105   vat_json_object_add_int (node, "advance", ntohl (mp->advance));
3106   vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
3107   u8 *s =
3108     format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
3109             0);
3110   vat_json_object_add_string_copy (node, "match", s);
3111 }
3112
3113 static void vl_api_pg_create_interface_reply_t_handler
3114   (vl_api_pg_create_interface_reply_t * mp)
3115 {
3116   vat_main_t *vam = &vat_main;
3117
3118   vam->retval = ntohl (mp->retval);
3119   vam->result_ready = 1;
3120 }
3121
3122 static void vl_api_pg_create_interface_reply_t_handler_json
3123   (vl_api_pg_create_interface_reply_t * mp)
3124 {
3125   vat_main_t *vam = &vat_main;
3126   vat_json_node_t node;
3127
3128   i32 retval = ntohl (mp->retval);
3129   if (retval == 0)
3130     {
3131       vat_json_init_object (&node);
3132
3133       vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
3134
3135       vat_json_print (vam->ofp, &node);
3136       vat_json_free (&node);
3137     }
3138   vam->retval = ntohl (mp->retval);
3139   vam->result_ready = 1;
3140 }
3141
3142 static void vl_api_policer_classify_details_t_handler
3143   (vl_api_policer_classify_details_t * mp)
3144 {
3145   vat_main_t *vam = &vat_main;
3146
3147   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
3148          ntohl (mp->table_index));
3149 }
3150
3151 static void vl_api_policer_classify_details_t_handler_json
3152   (vl_api_policer_classify_details_t * mp)
3153 {
3154   vat_main_t *vam = &vat_main;
3155   vat_json_node_t *node;
3156
3157   if (VAT_JSON_ARRAY != vam->json_tree.type)
3158     {
3159       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3160       vat_json_init_array (&vam->json_tree);
3161     }
3162   node = vat_json_array_add (&vam->json_tree);
3163
3164   vat_json_init_object (node);
3165   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
3166   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
3167 }
3168
3169 static void vl_api_flow_classify_details_t_handler
3170   (vl_api_flow_classify_details_t * mp)
3171 {
3172   vat_main_t *vam = &vat_main;
3173
3174   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
3175          ntohl (mp->table_index));
3176 }
3177
3178 static void vl_api_flow_classify_details_t_handler_json
3179   (vl_api_flow_classify_details_t * mp)
3180 {
3181   vat_main_t *vam = &vat_main;
3182   vat_json_node_t *node;
3183
3184   if (VAT_JSON_ARRAY != vam->json_tree.type)
3185     {
3186       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3187       vat_json_init_array (&vam->json_tree);
3188     }
3189   node = vat_json_array_add (&vam->json_tree);
3190
3191   vat_json_init_object (node);
3192   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
3193   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
3194 }
3195
3196 /*
3197  * Generate boilerplate reply handlers, which
3198  * dig the return value out of the xxx_reply_t API message,
3199  * stick it into vam->retval, and set vam->result_ready
3200  *
3201  * Could also do this by pointing N message decode slots at
3202  * a single function, but that could break in subtle ways.
3203  */
3204
3205 #define foreach_standard_reply_retval_handler           \
3206 _(sw_interface_set_flags_reply)                         \
3207 _(sw_interface_add_del_address_reply)                   \
3208 _(sw_interface_set_rx_mode_reply)                       \
3209 _(sw_interface_set_rx_placement_reply)                  \
3210 _(sw_interface_set_table_reply)                         \
3211 _(sw_interface_set_mpls_enable_reply)                   \
3212 _(sw_interface_set_vpath_reply)                         \
3213 _(sw_interface_set_vxlan_bypass_reply)                  \
3214 _(sw_interface_set_vxlan_gpe_bypass_reply)              \
3215 _(sw_interface_set_l2_bridge_reply)                     \
3216 _(sw_interface_set_bond_weight_reply)                   \
3217 _(bridge_domain_add_del_reply)                          \
3218 _(sw_interface_set_l2_xconnect_reply)                   \
3219 _(l2fib_add_del_reply)                                  \
3220 _(l2fib_flush_int_reply)                                \
3221 _(l2fib_flush_bd_reply)                                 \
3222 _(ip_route_add_del_reply)                               \
3223 _(ip_table_add_del_reply)                               \
3224 _(ip_table_replace_begin_reply)                         \
3225 _(ip_table_flush_reply)                                 \
3226 _(ip_table_replace_end_reply)                           \
3227 _(ip_mroute_add_del_reply)                              \
3228 _(mpls_route_add_del_reply)                             \
3229 _(mpls_table_add_del_reply)                             \
3230 _(mpls_ip_bind_unbind_reply)                            \
3231 _(bier_route_add_del_reply)                             \
3232 _(bier_table_add_del_reply)                             \
3233 _(sw_interface_set_unnumbered_reply)                    \
3234 _(set_ip_flow_hash_reply)                               \
3235 _(sw_interface_ip6_enable_disable_reply)                \
3236 _(l2_patch_add_del_reply)                               \
3237 _(sr_mpls_policy_add_reply)                             \
3238 _(sr_mpls_policy_mod_reply)                             \
3239 _(sr_mpls_policy_del_reply)                             \
3240 _(sr_policy_add_reply)                                  \
3241 _(sr_policy_mod_reply)                                  \
3242 _(sr_policy_del_reply)                                  \
3243 _(sr_localsid_add_del_reply)                            \
3244 _(sr_steering_add_del_reply)                            \
3245 _(classify_add_del_session_reply)                       \
3246 _(classify_set_interface_ip_table_reply)                \
3247 _(classify_set_interface_l2_tables_reply)               \
3248 _(l2_fib_clear_table_reply)                             \
3249 _(l2_interface_efp_filter_reply)                        \
3250 _(l2_interface_vlan_tag_rewrite_reply)                  \
3251 _(modify_vhost_user_if_reply)                           \
3252 _(delete_vhost_user_if_reply)                           \
3253 _(want_l2_macs_events_reply)                            \
3254 _(input_acl_set_interface_reply)                        \
3255 _(ipsec_spd_add_del_reply)                              \
3256 _(ipsec_interface_add_del_spd_reply)                    \
3257 _(ipsec_spd_entry_add_del_reply)                        \
3258 _(ipsec_sad_entry_add_del_reply)                        \
3259 _(delete_loopback_reply)                                \
3260 _(bd_ip_mac_add_del_reply)                              \
3261 _(bd_ip_mac_flush_reply)                                \
3262 _(want_interface_events_reply)                          \
3263 _(cop_interface_enable_disable_reply)                   \
3264 _(cop_whitelist_enable_disable_reply)                   \
3265 _(sw_interface_clear_stats_reply)                       \
3266 _(ioam_enable_reply)                                    \
3267 _(ioam_disable_reply)                                   \
3268 _(af_packet_delete_reply)                               \
3269 _(policer_classify_set_interface_reply)                 \
3270 _(set_ipfix_exporter_reply)                             \
3271 _(set_ipfix_classify_stream_reply)                      \
3272 _(ipfix_classify_table_add_del_reply)                   \
3273 _(flow_classify_set_interface_reply)                    \
3274 _(sw_interface_span_enable_disable_reply)               \
3275 _(pg_capture_reply)                                     \
3276 _(pg_enable_disable_reply)                              \
3277 _(pg_interface_enable_disable_coalesce_reply)           \
3278 _(ip_source_and_port_range_check_add_del_reply)         \
3279 _(ip_source_and_port_range_check_interface_add_del_reply)\
3280 _(delete_subif_reply)                                   \
3281 _(l2_interface_pbb_tag_rewrite_reply)                   \
3282 _(set_punt_reply)                                       \
3283 _(feature_enable_disable_reply)                         \
3284 _(feature_gso_enable_disable_reply)                     \
3285 _(sw_interface_tag_add_del_reply)                       \
3286 _(sw_interface_add_del_mac_address_reply)               \
3287 _(hw_interface_set_mtu_reply)                           \
3288 _(p2p_ethernet_add_reply)                               \
3289 _(p2p_ethernet_del_reply)                               \
3290 _(tcp_configure_src_addresses_reply)                    \
3291 _(session_rule_add_del_reply)                           \
3292 _(ip_container_proxy_add_del_reply)                     \
3293 _(output_acl_set_interface_reply)                       \
3294 _(qos_record_enable_disable_reply)                      \
3295 _(flow_add_reply)
3296
3297 #define _(n)                                    \
3298     static void vl_api_##n##_t_handler          \
3299     (vl_api_##n##_t * mp)                       \
3300     {                                           \
3301         vat_main_t * vam = &vat_main;           \
3302         i32 retval = ntohl(mp->retval);         \
3303         if (vam->async_mode) {                  \
3304             vam->async_errors += (retval < 0);  \
3305         } else {                                \
3306             vam->retval = retval;               \
3307             vam->result_ready = 1;              \
3308         }                                       \
3309     }
3310 foreach_standard_reply_retval_handler;
3311 #undef _
3312
3313 #define _(n)                                    \
3314     static void vl_api_##n##_t_handler_json     \
3315     (vl_api_##n##_t * mp)                       \
3316     {                                           \
3317         vat_main_t * vam = &vat_main;           \
3318         vat_json_node_t node;                   \
3319         vat_json_init_object(&node);            \
3320         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
3321         vat_json_print(vam->ofp, &node);        \
3322         vam->retval = ntohl(mp->retval);        \
3323         vam->result_ready = 1;                  \
3324     }
3325 foreach_standard_reply_retval_handler;
3326 #undef _
3327
3328 /*
3329  * Table of message reply handlers, must include boilerplate handlers
3330  * we just generated
3331  */
3332
3333 #define foreach_vpe_api_reply_msg                                       \
3334 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
3335 _(CREATE_LOOPBACK_INSTANCE_REPLY, create_loopback_instance_reply)       \
3336 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
3337 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
3338 _(CONTROL_PING_REPLY, control_ping_reply)                               \
3339 _(CLI_REPLY, cli_reply)                                                 \
3340 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
3341 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
3342   sw_interface_add_del_address_reply)                                   \
3343 _(SW_INTERFACE_SET_RX_MODE_REPLY, sw_interface_set_rx_mode_reply)       \
3344 _(SW_INTERFACE_SET_RX_PLACEMENT_REPLY, sw_interface_set_rx_placement_reply)     \
3345 _(SW_INTERFACE_RX_PLACEMENT_DETAILS, sw_interface_rx_placement_details) \
3346 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
3347 _(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
3348 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
3349 _(SW_INTERFACE_SET_VXLAN_BYPASS_REPLY, sw_interface_set_vxlan_bypass_reply) \
3350 _(SW_INTERFACE_SET_VXLAN_GPE_BYPASS_REPLY, sw_interface_set_vxlan_gpe_bypass_reply) \
3351 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
3352   sw_interface_set_l2_xconnect_reply)                                   \
3353 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
3354   sw_interface_set_l2_bridge_reply)                                     \
3355 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
3356 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
3357 _(BRIDGE_DOMAIN_SET_MAC_AGE_REPLY, bridge_domain_set_mac_age_reply)     \
3358 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
3359 _(L2FIB_FLUSH_INT_REPLY, l2fib_flush_int_reply)                         \
3360 _(L2FIB_FLUSH_BD_REPLY, l2fib_flush_bd_reply)                           \
3361 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
3362 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
3363 _(TAP_CREATE_V2_REPLY, tap_create_v2_reply)                             \
3364 _(TAP_DELETE_V2_REPLY, tap_delete_v2_reply)                             \
3365 _(SW_INTERFACE_TAP_V2_DETAILS, sw_interface_tap_v2_details)             \
3366 _(VIRTIO_PCI_CREATE_REPLY, virtio_pci_create_reply)                     \
3367 _(VIRTIO_PCI_CREATE_V2_REPLY, virtio_pci_create_v2_reply)               \
3368 _(VIRTIO_PCI_DELETE_REPLY, virtio_pci_delete_reply)                     \
3369 _(SW_INTERFACE_VIRTIO_PCI_DETAILS, sw_interface_virtio_pci_details)     \
3370 _(BOND_CREATE_REPLY, bond_create_reply)                                 \
3371 _(BOND_CREATE2_REPLY, bond_create2_reply)                               \
3372 _(BOND_DELETE_REPLY, bond_delete_reply)                                 \
3373 _(BOND_ADD_MEMBER_REPLY, bond_add_member_reply)                         \
3374 _(BOND_DETACH_MEMBER_REPLY, bond_detach_member_reply)                   \
3375 _(SW_INTERFACE_SET_BOND_WEIGHT_REPLY, sw_interface_set_bond_weight_reply) \
3376 _(SW_BOND_INTERFACE_DETAILS, sw_bond_interface_details)                 \
3377 _(SW_MEMBER_INTERFACE_DETAILS, sw_member_interface_details)               \
3378 _(IP_ROUTE_ADD_DEL_REPLY, ip_route_add_del_reply)                       \
3379 _(IP_TABLE_ADD_DEL_REPLY, ip_table_add_del_reply)                       \
3380 _(IP_TABLE_REPLACE_BEGIN_REPLY, ip_table_replace_begin_reply)           \
3381 _(IP_TABLE_FLUSH_REPLY, ip_table_flush_reply)                           \
3382 _(IP_TABLE_REPLACE_END_REPLY, ip_table_replace_end_reply)               \
3383 _(IP_MROUTE_ADD_DEL_REPLY, ip_mroute_add_del_reply)                     \
3384 _(MPLS_TABLE_ADD_DEL_REPLY, mpls_table_add_del_reply)                   \
3385 _(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply)                   \
3386 _(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply)                 \
3387 _(BIER_ROUTE_ADD_DEL_REPLY, bier_route_add_del_reply)                   \
3388 _(BIER_TABLE_ADD_DEL_REPLY, bier_table_add_del_reply)                   \
3389 _(MPLS_TUNNEL_ADD_DEL_REPLY, mpls_tunnel_add_del_reply)                 \
3390 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
3391   sw_interface_set_unnumbered_reply)                                    \
3392 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
3393 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
3394 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
3395 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
3396   sw_interface_ip6_enable_disable_reply)                                \
3397 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
3398 _(SR_MPLS_POLICY_ADD_REPLY, sr_mpls_policy_add_reply)                   \
3399 _(SR_MPLS_POLICY_MOD_REPLY, sr_mpls_policy_mod_reply)                   \
3400 _(SR_MPLS_POLICY_DEL_REPLY, sr_mpls_policy_del_reply)                   \
3401 _(SR_POLICY_ADD_REPLY, sr_policy_add_reply)                             \
3402 _(SR_POLICY_MOD_REPLY, sr_policy_mod_reply)                             \
3403 _(SR_POLICY_DEL_REPLY, sr_policy_del_reply)                             \
3404 _(SR_LOCALSID_ADD_DEL_REPLY, sr_localsid_add_del_reply)                 \
3405 _(SR_STEERING_ADD_DEL_REPLY, sr_steering_add_del_reply)                 \
3406 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
3407 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
3408 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
3409 classify_set_interface_ip_table_reply)                                  \
3410 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
3411   classify_set_interface_l2_tables_reply)                               \
3412 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
3413 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
3414 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
3415 _(VXLAN_OFFLOAD_RX_REPLY, vxlan_offload_rx_reply)               \
3416 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
3417 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
3418 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
3419 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
3420 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
3421 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
3422 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
3423 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
3424 _(SHOW_VERSION_REPLY, show_version_reply)                               \
3425 _(SHOW_THREADS_REPLY, show_threads_reply)                               \
3426 _(L2_FIB_TABLE_DETAILS, l2_fib_table_details)                           \
3427 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)       \
3428 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
3429 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
3430 _(WANT_L2_MACS_EVENTS_REPLY, want_l2_macs_events_reply)                 \
3431 _(L2_MACS_EVENT, l2_macs_event)                                         \
3432 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
3433 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
3434 _(IP_DETAILS, ip_details)                                               \
3435 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
3436 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
3437 _(IPSEC_SPD_ENTRY_ADD_DEL_REPLY, ipsec_spd_entry_add_del_reply)         \
3438 _(IPSEC_SAD_ENTRY_ADD_DEL_REPLY, ipsec_sad_entry_add_del_reply)         \
3439 _(IPSEC_SA_DETAILS, ipsec_sa_details)                                   \
3440 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
3441 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
3442 _(BD_IP_MAC_FLUSH_REPLY, bd_ip_mac_flush_reply)                         \
3443 _(BD_IP_MAC_DETAILS, bd_ip_mac_details)                                 \
3444 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
3445 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
3446 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
3447 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
3448 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
3449 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
3450 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
3451 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
3452 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
3453 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
3454 _(AF_PACKET_DETAILS, af_packet_details)                                 \
3455 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
3456 _(POLICER_DETAILS, policer_details)                                     \
3457 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
3458 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
3459 _(MPLS_TUNNEL_DETAILS, mpls_tunnel_details)                             \
3460 _(MPLS_TABLE_DETAILS, mpls_table_details)                               \
3461 _(MPLS_ROUTE_DETAILS, mpls_route_details)                               \
3462 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
3463 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
3464 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
3465 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
3466 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
3467 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
3468 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
3469 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
3470 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
3471 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
3472 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
3473 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
3474 _(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
3475 _(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details)                 \
3476 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
3477 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
3478 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
3479 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
3480 _(PG_INTERFACE_ENABLE_DISABLE_COALESCE_REPLY, pg_interface_enable_disable_coalesce_reply) \
3481 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
3482  ip_source_and_port_range_check_add_del_reply)                          \
3483 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
3484  ip_source_and_port_range_check_interface_add_del_reply)                \
3485 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
3486 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
3487 _(SET_PUNT_REPLY, set_punt_reply)                                       \
3488 _(IP_TABLE_DETAILS, ip_table_details)                                   \
3489 _(IP_ROUTE_DETAILS, ip_route_details)                                   \
3490 _(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply)           \
3491 _(FEATURE_GSO_ENABLE_DISABLE_REPLY, feature_gso_enable_disable_reply)   \
3492 _(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply)       \
3493 _(SW_INTERFACE_ADD_DEL_MAC_ADDRESS_REPLY, sw_interface_add_del_mac_address_reply) \
3494 _(L2_XCONNECT_DETAILS, l2_xconnect_details)                             \
3495 _(HW_INTERFACE_SET_MTU_REPLY, hw_interface_set_mtu_reply)               \
3496 _(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply)           \
3497 _(P2P_ETHERNET_ADD_REPLY, p2p_ethernet_add_reply)                       \
3498 _(P2P_ETHERNET_DEL_REPLY, p2p_ethernet_del_reply)                       \
3499 _(TCP_CONFIGURE_SRC_ADDRESSES_REPLY, tcp_configure_src_addresses_reply) \
3500 _(APP_NAMESPACE_ADD_DEL_REPLY, app_namespace_add_del_reply)             \
3501 _(SESSION_RULE_ADD_DEL_REPLY, session_rule_add_del_reply)               \
3502 _(SESSION_RULES_DETAILS, session_rules_details)                         \
3503 _(IP_CONTAINER_PROXY_ADD_DEL_REPLY, ip_container_proxy_add_del_reply)   \
3504 _(OUTPUT_ACL_SET_INTERFACE_REPLY, output_acl_set_interface_reply)       \
3505 _(QOS_RECORD_ENABLE_DISABLE_REPLY, qos_record_enable_disable_reply)             \
3506 _(FLOW_ADD_REPLY, flow_add_reply)   \
3507
3508 #define foreach_standalone_reply_msg                                    \
3509 _(SW_INTERFACE_EVENT, sw_interface_event)
3510
3511 typedef struct
3512 {
3513   u8 *name;
3514   u32 value;
3515 } name_sort_t;
3516
3517 #define STR_VTR_OP_CASE(op)     \
3518     case L2_VTR_ ## op:         \
3519         return "" # op;
3520
3521 static const char *
3522 str_vtr_op (u32 vtr_op)
3523 {
3524   switch (vtr_op)
3525     {
3526       STR_VTR_OP_CASE (DISABLED);
3527       STR_VTR_OP_CASE (PUSH_1);
3528       STR_VTR_OP_CASE (PUSH_2);
3529       STR_VTR_OP_CASE (POP_1);
3530       STR_VTR_OP_CASE (POP_2);
3531       STR_VTR_OP_CASE (TRANSLATE_1_1);
3532       STR_VTR_OP_CASE (TRANSLATE_1_2);
3533       STR_VTR_OP_CASE (TRANSLATE_2_1);
3534       STR_VTR_OP_CASE (TRANSLATE_2_2);
3535     }
3536
3537   return "UNKNOWN";
3538 }
3539
3540 static int
3541 dump_sub_interface_table (vat_main_t * vam)
3542 {
3543   const sw_interface_subif_t *sub = NULL;
3544
3545   if (vam->json_output)
3546     {
3547       clib_warning
3548         ("JSON output supported only for VPE API calls and dump_stats_table");
3549       return -99;
3550     }
3551
3552   print (vam->ofp,
3553          "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
3554          "Interface", "sw_if_index",
3555          "sub id", "dot1ad", "tags", "outer id",
3556          "inner id", "exact", "default", "outer any", "inner any");
3557
3558   vec_foreach (sub, vam->sw_if_subif_table)
3559   {
3560     print (vam->ofp,
3561            "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
3562            sub->interface_name,
3563            sub->sw_if_index,
3564            sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
3565            sub->sub_number_of_tags, sub->sub_outer_vlan_id,
3566            sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
3567            sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
3568     if (sub->vtr_op != L2_VTR_DISABLED)
3569       {
3570         print (vam->ofp,
3571                "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
3572                "tag1: %d tag2: %d ]",
3573                str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
3574                sub->vtr_tag1, sub->vtr_tag2);
3575       }
3576   }
3577
3578   return 0;
3579 }
3580
3581 static int
3582 name_sort_cmp (void *a1, void *a2)
3583 {
3584   name_sort_t *n1 = a1;
3585   name_sort_t *n2 = a2;
3586
3587   return strcmp ((char *) n1->name, (char *) n2->name);
3588 }
3589
3590 static int
3591 dump_interface_table (vat_main_t * vam)
3592 {
3593   hash_pair_t *p;
3594   name_sort_t *nses = 0, *ns;
3595
3596   if (vam->json_output)
3597     {
3598       clib_warning
3599         ("JSON output supported only for VPE API calls and dump_stats_table");
3600       return -99;
3601     }
3602
3603   /* *INDENT-OFF* */
3604   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
3605   ({
3606     vec_add2 (nses, ns, 1);
3607     ns->name = (u8 *)(p->key);
3608     ns->value = (u32) p->value[0];
3609   }));
3610   /* *INDENT-ON* */
3611
3612   vec_sort_with_function (nses, name_sort_cmp);
3613
3614   print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
3615   vec_foreach (ns, nses)
3616   {
3617     print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
3618   }
3619   vec_free (nses);
3620   return 0;
3621 }
3622
3623 static int
3624 dump_ip_table (vat_main_t * vam, int is_ipv6)
3625 {
3626   const ip_details_t *det = NULL;
3627   const ip_address_details_t *address = NULL;
3628   u32 i = ~0;
3629
3630   print (vam->ofp, "%-12s", "sw_if_index");
3631
3632   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
3633   {
3634     i++;
3635     if (!det->present)
3636       {
3637         continue;
3638       }
3639     print (vam->ofp, "%-12d", i);
3640     print (vam->ofp, "            %-30s%-13s", "Address", "Prefix length");
3641     if (!det->addr)
3642       {
3643         continue;
3644       }
3645     vec_foreach (address, det->addr)
3646     {
3647       print (vam->ofp,
3648              "            %-30U%-13d",
3649              is_ipv6 ? format_ip6_address : format_ip4_address,
3650              address->ip, address->prefix_length);
3651     }
3652   }
3653
3654   return 0;
3655 }
3656
3657 static int
3658 dump_ipv4_table (vat_main_t * vam)
3659 {
3660   if (vam->json_output)
3661     {
3662       clib_warning
3663         ("JSON output supported only for VPE API calls and dump_stats_table");
3664       return -99;
3665     }
3666
3667   return dump_ip_table (vam, 0);
3668 }
3669
3670 static int
3671 dump_ipv6_table (vat_main_t * vam)
3672 {
3673   if (vam->json_output)
3674     {
3675       clib_warning
3676         ("JSON output supported only for VPE API calls and dump_stats_table");
3677       return -99;
3678     }
3679
3680   return dump_ip_table (vam, 1);
3681 }
3682
3683 /*
3684  * Pass CLI buffers directly in the CLI_INBAND API message,
3685  * instead of an additional shared memory area.
3686  */
3687 static int
3688 exec_inband (vat_main_t * vam)
3689 {
3690   vl_api_cli_inband_t *mp;
3691   unformat_input_t *i = vam->input;
3692   int ret;
3693
3694   if (vec_len (i->buffer) == 0)
3695     return -1;
3696
3697   if (vam->exec_mode == 0 && unformat (i, "mode"))
3698     {
3699       vam->exec_mode = 1;
3700       return 0;
3701     }
3702   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
3703     {
3704       vam->exec_mode = 0;
3705       return 0;
3706     }
3707
3708   /*
3709    * In order for the CLI command to work, it
3710    * must be a vector ending in \n, not a C-string ending
3711    * in \n\0.
3712    */
3713   M2 (CLI_INBAND, mp, vec_len (vam->input->buffer));
3714   vl_api_vec_to_api_string (vam->input->buffer, &mp->cmd);
3715
3716   S (mp);
3717   W (ret);
3718   /* json responses may or may not include a useful reply... */
3719   if (vec_len (vam->cmd_reply))
3720     print (vam->ofp, "%v", (char *) (vam->cmd_reply));
3721   return ret;
3722 }
3723
3724 int
3725 exec (vat_main_t * vam)
3726 {
3727   return exec_inband (vam);
3728 }
3729
3730 static int
3731 api_create_loopback (vat_main_t * vam)
3732 {
3733   unformat_input_t *i = vam->input;
3734   vl_api_create_loopback_t *mp;
3735   vl_api_create_loopback_instance_t *mp_lbi;
3736   u8 mac_address[6];
3737   u8 mac_set = 0;
3738   u8 is_specified = 0;
3739   u32 user_instance = 0;
3740   int ret;
3741
3742   clib_memset (mac_address, 0, sizeof (mac_address));
3743
3744   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
3745     {
3746       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
3747         mac_set = 1;
3748       if (unformat (i, "instance %d", &user_instance))
3749         is_specified = 1;
3750       else
3751         break;
3752     }
3753
3754   if (is_specified)
3755     {
3756       M (CREATE_LOOPBACK_INSTANCE, mp_lbi);
3757       mp_lbi->is_specified = is_specified;
3758       if (is_specified)
3759         mp_lbi->user_instance = htonl (user_instance);
3760       if (mac_set)
3761         clib_memcpy (mp_lbi->mac_address, mac_address, sizeof (mac_address));
3762       S (mp_lbi);
3763     }
3764   else
3765     {
3766       /* Construct the API message */
3767       M (CREATE_LOOPBACK, mp);
3768       if (mac_set)
3769         clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
3770       S (mp);
3771     }
3772
3773   W (ret);
3774   return ret;
3775 }
3776
3777 static int
3778 api_delete_loopback (vat_main_t * vam)
3779 {
3780   unformat_input_t *i = vam->input;
3781   vl_api_delete_loopback_t *mp;
3782   u32 sw_if_index = ~0;
3783   int ret;
3784
3785   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
3786     {
3787       if (unformat (i, "sw_if_index %d", &sw_if_index))
3788         ;
3789       else
3790         break;
3791     }
3792
3793   if (sw_if_index == ~0)
3794     {
3795       errmsg ("missing sw_if_index");
3796       return -99;
3797     }
3798
3799   /* Construct the API message */
3800   M (DELETE_LOOPBACK, mp);
3801   mp->sw_if_index = ntohl (sw_if_index);
3802
3803   S (mp);
3804   W (ret);
3805   return ret;
3806 }
3807
3808 static int
3809 api_want_interface_events (vat_main_t * vam)
3810 {
3811   unformat_input_t *i = vam->input;
3812   vl_api_want_interface_events_t *mp;
3813   int enable = -1;
3814   int ret;
3815
3816   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
3817     {
3818       if (unformat (i, "enable"))
3819         enable = 1;
3820       else if (unformat (i, "disable"))
3821         enable = 0;
3822       else
3823         break;
3824     }
3825
3826   if (enable == -1)
3827     {
3828       errmsg ("missing enable|disable");
3829       return -99;
3830     }
3831
3832   M (WANT_INTERFACE_EVENTS, mp);
3833   mp->enable_disable = enable;
3834
3835   vam->interface_event_display = enable;
3836
3837   S (mp);
3838   W (ret);
3839   return ret;
3840 }
3841
3842
3843 /* Note: non-static, called once to set up the initial intfc table */
3844 int
3845 api_sw_interface_dump (vat_main_t * vam)
3846 {
3847   vl_api_sw_interface_dump_t *mp;
3848   vl_api_control_ping_t *mp_ping;
3849   hash_pair_t *p;
3850   name_sort_t *nses = 0, *ns;
3851   sw_interface_subif_t *sub = NULL;
3852   int ret;
3853
3854   /* Toss the old name table */
3855   /* *INDENT-OFF* */
3856   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
3857   ({
3858     vec_add2 (nses, ns, 1);
3859     ns->name = (u8 *)(p->key);
3860     ns->value = (u32) p->value[0];
3861   }));
3862   /* *INDENT-ON* */
3863
3864   hash_free (vam->sw_if_index_by_interface_name);
3865
3866   vec_foreach (ns, nses) vec_free (ns->name);
3867
3868   vec_free (nses);
3869
3870   vec_foreach (sub, vam->sw_if_subif_table)
3871   {
3872     vec_free (sub->interface_name);
3873   }
3874   vec_free (vam->sw_if_subif_table);
3875
3876   /* recreate the interface name hash table */
3877   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
3878
3879   /*
3880    * Ask for all interface names. Otherwise, the epic catalog of
3881    * name filters becomes ridiculously long, and vat ends up needing
3882    * to be taught about new interface types.
3883    */
3884   M (SW_INTERFACE_DUMP, mp);
3885   S (mp);
3886
3887   /* Use a control ping for synchronization */
3888   MPING (CONTROL_PING, mp_ping);
3889   S (mp_ping);
3890
3891   W (ret);
3892   return ret;
3893 }
3894
3895 static int
3896 api_sw_interface_set_flags (vat_main_t * vam)
3897 {
3898   unformat_input_t *i = vam->input;
3899   vl_api_sw_interface_set_flags_t *mp;
3900   u32 sw_if_index;
3901   u8 sw_if_index_set = 0;
3902   u8 admin_up = 0;
3903   int ret;
3904
3905   /* Parse args required to build the message */
3906   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
3907     {
3908       if (unformat (i, "admin-up"))
3909         admin_up = 1;
3910       else if (unformat (i, "admin-down"))
3911         admin_up = 0;
3912       else
3913         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
3914         sw_if_index_set = 1;
3915       else if (unformat (i, "sw_if_index %d", &sw_if_index))
3916         sw_if_index_set = 1;
3917       else
3918         break;
3919     }
3920
3921   if (sw_if_index_set == 0)
3922     {
3923       errmsg ("missing interface name or sw_if_index");
3924       return -99;
3925     }
3926
3927   /* Construct the API message */
3928   M (SW_INTERFACE_SET_FLAGS, mp);
3929   mp->sw_if_index = ntohl (sw_if_index);
3930   mp->flags = ntohl ((admin_up) ? IF_STATUS_API_FLAG_ADMIN_UP : 0);
3931
3932   /* send it... */
3933   S (mp);
3934
3935   /* Wait for a reply, return the good/bad news... */
3936   W (ret);
3937   return ret;
3938 }
3939
3940 static int
3941 api_sw_interface_set_rx_mode (vat_main_t * vam)
3942 {
3943   unformat_input_t *i = vam->input;
3944   vl_api_sw_interface_set_rx_mode_t *mp;
3945   u32 sw_if_index;
3946   u8 sw_if_index_set = 0;
3947   int ret;
3948   u8 queue_id_valid = 0;
3949   u32 queue_id;
3950   vnet_hw_if_rx_mode mode = VNET_HW_IF_RX_MODE_UNKNOWN;
3951
3952   /* Parse args required to build the message */
3953   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
3954     {
3955       if (unformat (i, "queue %d", &queue_id))
3956         queue_id_valid = 1;
3957       else if (unformat (i, "polling"))
3958         mode = VNET_HW_IF_RX_MODE_POLLING;
3959       else if (unformat (i, "interrupt"))
3960         mode = VNET_HW_IF_RX_MODE_INTERRUPT;
3961       else if (unformat (i, "adaptive"))
3962         mode = VNET_HW_IF_RX_MODE_ADAPTIVE;
3963       else
3964         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
3965         sw_if_index_set = 1;
3966       else if (unformat (i, "sw_if_index %d", &sw_if_index))
3967         sw_if_index_set = 1;
3968       else
3969         break;
3970     }
3971
3972   if (sw_if_index_set == 0)
3973     {
3974       errmsg ("missing interface name or sw_if_index");
3975       return -99;
3976     }
3977   if (mode == VNET_HW_IF_RX_MODE_UNKNOWN)
3978     {
3979       errmsg ("missing rx-mode");
3980       return -99;
3981     }
3982
3983   /* Construct the API message */
3984   M (SW_INTERFACE_SET_RX_MODE, mp);
3985   mp->sw_if_index = ntohl (sw_if_index);
3986   mp->mode = (vl_api_rx_mode_t) mode;
3987   mp->queue_id_valid = queue_id_valid;
3988   mp->queue_id = queue_id_valid ? ntohl (queue_id) : ~0;
3989
3990   /* send it... */
3991   S (mp);
3992
3993   /* Wait for a reply, return the good/bad news... */
3994   W (ret);
3995   return ret;
3996 }
3997
3998 static int
3999 api_sw_interface_set_rx_placement (vat_main_t * vam)
4000 {
4001   unformat_input_t *i = vam->input;
4002   vl_api_sw_interface_set_rx_placement_t *mp;
4003   u32 sw_if_index;
4004   u8 sw_if_index_set = 0;
4005   int ret;
4006   u8 is_main = 0;
4007   u32 queue_id, thread_index;
4008
4009   /* Parse args required to build the message */
4010   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4011     {
4012       if (unformat (i, "queue %d", &queue_id))
4013         ;
4014       else if (unformat (i, "main"))
4015         is_main = 1;
4016       else if (unformat (i, "worker %d", &thread_index))
4017         ;
4018       else
4019         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
4020         sw_if_index_set = 1;
4021       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4022         sw_if_index_set = 1;
4023       else
4024         break;
4025     }
4026
4027   if (sw_if_index_set == 0)
4028     {
4029       errmsg ("missing interface name or sw_if_index");
4030       return -99;
4031     }
4032
4033   if (is_main)
4034     thread_index = 0;
4035   /* Construct the API message */
4036   M (SW_INTERFACE_SET_RX_PLACEMENT, mp);
4037   mp->sw_if_index = ntohl (sw_if_index);
4038   mp->worker_id = ntohl (thread_index);
4039   mp->queue_id = ntohl (queue_id);
4040   mp->is_main = is_main;
4041
4042   /* send it... */
4043   S (mp);
4044   /* Wait for a reply, return the good/bad news... */
4045   W (ret);
4046   return ret;
4047 }
4048
4049 static void vl_api_sw_interface_rx_placement_details_t_handler
4050   (vl_api_sw_interface_rx_placement_details_t * mp)
4051 {
4052   vat_main_t *vam = &vat_main;
4053   u32 worker_id = ntohl (mp->worker_id);
4054
4055   print (vam->ofp,
4056          "\n%-11d %-11s %-6d %-5d %-9s",
4057          ntohl (mp->sw_if_index), (worker_id == 0) ? "main" : "worker",
4058          worker_id, ntohl (mp->queue_id),
4059          (mp->mode ==
4060           1) ? "polling" : ((mp->mode == 2) ? "interrupt" : "adaptive"));
4061 }
4062
4063 static void vl_api_sw_interface_rx_placement_details_t_handler_json
4064   (vl_api_sw_interface_rx_placement_details_t * mp)
4065 {
4066   vat_main_t *vam = &vat_main;
4067   vat_json_node_t *node = NULL;
4068
4069   if (VAT_JSON_ARRAY != vam->json_tree.type)
4070     {
4071       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4072       vat_json_init_array (&vam->json_tree);
4073     }
4074   node = vat_json_array_add (&vam->json_tree);
4075
4076   vat_json_init_object (node);
4077   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
4078   vat_json_object_add_uint (node, "worker_id", ntohl (mp->worker_id));
4079   vat_json_object_add_uint (node, "queue_id", ntohl (mp->queue_id));
4080   vat_json_object_add_uint (node, "mode", mp->mode);
4081 }
4082
4083 static int
4084 api_sw_interface_rx_placement_dump (vat_main_t * vam)
4085 {
4086   unformat_input_t *i = vam->input;
4087   vl_api_sw_interface_rx_placement_dump_t *mp;
4088   vl_api_control_ping_t *mp_ping;
4089   int ret;
4090   u32 sw_if_index;
4091   u8 sw_if_index_set = 0;
4092
4093   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4094     {
4095       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
4096         sw_if_index_set++;
4097       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4098         sw_if_index_set++;
4099       else
4100         break;
4101     }
4102
4103   print (vam->ofp,
4104          "\n%-11s %-11s %-6s %-5s %-4s",
4105          "sw_if_index", "main/worker", "thread", "queue", "mode");
4106
4107   /* Dump Interface rx placement */
4108   M (SW_INTERFACE_RX_PLACEMENT_DUMP, mp);
4109
4110   if (sw_if_index_set)
4111     mp->sw_if_index = htonl (sw_if_index);
4112   else
4113     mp->sw_if_index = ~0;
4114
4115   S (mp);
4116
4117   /* Use a control ping for synchronization */
4118   MPING (CONTROL_PING, mp_ping);
4119   S (mp_ping);
4120
4121   W (ret);
4122   return ret;
4123 }
4124
4125 static int
4126 api_sw_interface_clear_stats (vat_main_t * vam)
4127 {
4128   unformat_input_t *i = vam->input;
4129   vl_api_sw_interface_clear_stats_t *mp;
4130   u32 sw_if_index;
4131   u8 sw_if_index_set = 0;
4132   int ret;
4133
4134   /* Parse args required to build the message */
4135   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4136     {
4137       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
4138         sw_if_index_set = 1;
4139       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4140         sw_if_index_set = 1;
4141       else
4142         break;
4143     }
4144
4145   /* Construct the API message */
4146   M (SW_INTERFACE_CLEAR_STATS, mp);
4147
4148   if (sw_if_index_set == 1)
4149     mp->sw_if_index = ntohl (sw_if_index);
4150   else
4151     mp->sw_if_index = ~0;
4152
4153   /* send it... */
4154   S (mp);
4155
4156   /* Wait for a reply, return the good/bad news... */
4157   W (ret);
4158   return ret;
4159 }
4160
4161 static int
4162 api_sw_interface_add_del_address (vat_main_t * vam)
4163 {
4164   unformat_input_t *i = vam->input;
4165   vl_api_sw_interface_add_del_address_t *mp;
4166   u32 sw_if_index;
4167   u8 sw_if_index_set = 0;
4168   u8 is_add = 1, del_all = 0;
4169   u32 address_length = 0;
4170   u8 v4_address_set = 0;
4171   u8 v6_address_set = 0;
4172   ip4_address_t v4address;
4173   ip6_address_t v6address;
4174   int ret;
4175
4176   /* Parse args required to build the message */
4177   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4178     {
4179       if (unformat (i, "del-all"))
4180         del_all = 1;
4181       else if (unformat (i, "del"))
4182         is_add = 0;
4183       else
4184         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
4185         sw_if_index_set = 1;
4186       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4187         sw_if_index_set = 1;
4188       else if (unformat (i, "%U/%d",
4189                          unformat_ip4_address, &v4address, &address_length))
4190         v4_address_set = 1;
4191       else if (unformat (i, "%U/%d",
4192                          unformat_ip6_address, &v6address, &address_length))
4193         v6_address_set = 1;
4194       else
4195         break;
4196     }
4197
4198   if (sw_if_index_set == 0)
4199     {
4200       errmsg ("missing interface name or sw_if_index");
4201       return -99;
4202     }
4203   if (v4_address_set && v6_address_set)
4204     {
4205       errmsg ("both v4 and v6 addresses set");
4206       return -99;
4207     }
4208   if (!v4_address_set && !v6_address_set && !del_all)
4209     {
4210       errmsg ("no addresses set");
4211       return -99;
4212     }
4213
4214   /* Construct the API message */
4215   M (SW_INTERFACE_ADD_DEL_ADDRESS, mp);
4216
4217   mp->sw_if_index = ntohl (sw_if_index);
4218   mp->is_add = is_add;
4219   mp->del_all = del_all;
4220   if (v6_address_set)
4221     {
4222       mp->prefix.address.af = ADDRESS_IP6;
4223       clib_memcpy (mp->prefix.address.un.ip6, &v6address, sizeof (v6address));
4224     }
4225   else
4226     {
4227       mp->prefix.address.af = ADDRESS_IP4;
4228       clib_memcpy (mp->prefix.address.un.ip4, &v4address, sizeof (v4address));
4229     }
4230   mp->prefix.len = address_length;
4231
4232   /* send it... */
4233   S (mp);
4234
4235   /* Wait for a reply, return good/bad news  */
4236   W (ret);
4237   return ret;
4238 }
4239
4240 static int
4241 api_sw_interface_set_mpls_enable (vat_main_t * vam)
4242 {
4243   unformat_input_t *i = vam->input;
4244   vl_api_sw_interface_set_mpls_enable_t *mp;
4245   u32 sw_if_index;
4246   u8 sw_if_index_set = 0;
4247   u8 enable = 1;
4248   int ret;
4249
4250   /* Parse args required to build the message */
4251   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4252     {
4253       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
4254         sw_if_index_set = 1;
4255       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4256         sw_if_index_set = 1;
4257       else if (unformat (i, "disable"))
4258         enable = 0;
4259       else if (unformat (i, "dis"))
4260         enable = 0;
4261       else
4262         break;
4263     }
4264
4265   if (sw_if_index_set == 0)
4266     {
4267       errmsg ("missing interface name or sw_if_index");
4268       return -99;
4269     }
4270
4271   /* Construct the API message */
4272   M (SW_INTERFACE_SET_MPLS_ENABLE, mp);
4273
4274   mp->sw_if_index = ntohl (sw_if_index);
4275   mp->enable = enable;
4276
4277   /* send it... */
4278   S (mp);
4279
4280   /* Wait for a reply... */
4281   W (ret);
4282   return ret;
4283 }
4284
4285 static int
4286 api_sw_interface_set_table (vat_main_t * vam)
4287 {
4288   unformat_input_t *i = vam->input;
4289   vl_api_sw_interface_set_table_t *mp;
4290   u32 sw_if_index, vrf_id = 0;
4291   u8 sw_if_index_set = 0;
4292   u8 is_ipv6 = 0;
4293   int ret;
4294
4295   /* Parse args required to build the message */
4296   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4297     {
4298       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
4299         sw_if_index_set = 1;
4300       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4301         sw_if_index_set = 1;
4302       else if (unformat (i, "vrf %d", &vrf_id))
4303         ;
4304       else if (unformat (i, "ipv6"))
4305         is_ipv6 = 1;
4306       else
4307         break;
4308     }
4309
4310   if (sw_if_index_set == 0)
4311     {
4312       errmsg ("missing interface name or sw_if_index");
4313       return -99;
4314     }
4315
4316   /* Construct the API message */
4317   M (SW_INTERFACE_SET_TABLE, mp);
4318
4319   mp->sw_if_index = ntohl (sw_if_index);
4320   mp->is_ipv6 = is_ipv6;
4321   mp->vrf_id = ntohl (vrf_id);
4322
4323   /* send it... */
4324   S (mp);
4325
4326   /* Wait for a reply... */
4327   W (ret);
4328   return ret;
4329 }
4330
4331 static void vl_api_sw_interface_get_table_reply_t_handler
4332   (vl_api_sw_interface_get_table_reply_t * mp)
4333 {
4334   vat_main_t *vam = &vat_main;
4335
4336   print (vam->ofp, "%d", ntohl (mp->vrf_id));
4337
4338   vam->retval = ntohl (mp->retval);
4339   vam->result_ready = 1;
4340
4341 }
4342
4343 static void vl_api_sw_interface_get_table_reply_t_handler_json
4344   (vl_api_sw_interface_get_table_reply_t * mp)
4345 {
4346   vat_main_t *vam = &vat_main;
4347   vat_json_node_t node;
4348
4349   vat_json_init_object (&node);
4350   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
4351   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
4352
4353   vat_json_print (vam->ofp, &node);
4354   vat_json_free (&node);
4355
4356   vam->retval = ntohl (mp->retval);
4357   vam->result_ready = 1;
4358 }
4359
4360 static int
4361 api_sw_interface_get_table (vat_main_t * vam)
4362 {
4363   unformat_input_t *i = vam->input;
4364   vl_api_sw_interface_get_table_t *mp;
4365   u32 sw_if_index;
4366   u8 sw_if_index_set = 0;
4367   u8 is_ipv6 = 0;
4368   int ret;
4369
4370   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4371     {
4372       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
4373         sw_if_index_set = 1;
4374       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4375         sw_if_index_set = 1;
4376       else if (unformat (i, "ipv6"))
4377         is_ipv6 = 1;
4378       else
4379         break;
4380     }
4381
4382   if (sw_if_index_set == 0)
4383     {
4384       errmsg ("missing interface name or sw_if_index");
4385       return -99;
4386     }
4387
4388   M (SW_INTERFACE_GET_TABLE, mp);
4389   mp->sw_if_index = htonl (sw_if_index);
4390   mp->is_ipv6 = is_ipv6;
4391
4392   S (mp);
4393   W (ret);
4394   return ret;
4395 }
4396
4397 static int
4398 api_sw_interface_set_vpath (vat_main_t * vam)
4399 {
4400   unformat_input_t *i = vam->input;
4401   vl_api_sw_interface_set_vpath_t *mp;
4402   u32 sw_if_index = 0;
4403   u8 sw_if_index_set = 0;
4404   u8 is_enable = 0;
4405   int ret;
4406
4407   /* Parse args required to build the message */
4408   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4409     {
4410       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
4411         sw_if_index_set = 1;
4412       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4413         sw_if_index_set = 1;
4414       else if (unformat (i, "enable"))
4415         is_enable = 1;
4416       else if (unformat (i, "disable"))
4417         is_enable = 0;
4418       else
4419         break;
4420     }
4421
4422   if (sw_if_index_set == 0)
4423     {
4424       errmsg ("missing interface name or sw_if_index");
4425       return -99;
4426     }
4427
4428   /* Construct the API message */
4429   M (SW_INTERFACE_SET_VPATH, mp);
4430
4431   mp->sw_if_index = ntohl (sw_if_index);
4432   mp->enable = is_enable;
4433
4434   /* send it... */
4435   S (mp);
4436
4437   /* Wait for a reply... */
4438   W (ret);
4439   return ret;
4440 }
4441
4442 static int
4443 api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
4444 {
4445   unformat_input_t *i = vam->input;
4446   vl_api_sw_interface_set_vxlan_bypass_t *mp;
4447   u32 sw_if_index = 0;
4448   u8 sw_if_index_set = 0;
4449   u8 is_enable = 1;
4450   u8 is_ipv6 = 0;
4451   int ret;
4452
4453   /* Parse args required to build the message */
4454   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4455     {
4456       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
4457         sw_if_index_set = 1;
4458       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4459         sw_if_index_set = 1;
4460       else if (unformat (i, "enable"))
4461         is_enable = 1;
4462       else if (unformat (i, "disable"))
4463         is_enable = 0;
4464       else if (unformat (i, "ip4"))
4465         is_ipv6 = 0;
4466       else if (unformat (i, "ip6"))
4467         is_ipv6 = 1;
4468       else
4469         break;
4470     }
4471
4472   if (sw_if_index_set == 0)
4473     {
4474       errmsg ("missing interface name or sw_if_index");
4475       return -99;
4476     }
4477
4478   /* Construct the API message */
4479   M (SW_INTERFACE_SET_VXLAN_BYPASS, mp);
4480
4481   mp->sw_if_index = ntohl (sw_if_index);
4482   mp->enable = is_enable;
4483   mp->is_ipv6 = is_ipv6;
4484
4485   /* send it... */
4486   S (mp);
4487
4488   /* Wait for a reply... */
4489   W (ret);
4490   return ret;
4491 }
4492
4493 static int
4494 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
4495 {
4496   unformat_input_t *i = vam->input;
4497   vl_api_sw_interface_set_l2_xconnect_t *mp;
4498   u32 rx_sw_if_index;
4499   u8 rx_sw_if_index_set = 0;
4500   u32 tx_sw_if_index;
4501   u8 tx_sw_if_index_set = 0;
4502   u8 enable = 1;
4503   int ret;
4504
4505   /* Parse args required to build the message */
4506   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4507     {
4508       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
4509         rx_sw_if_index_set = 1;
4510       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
4511         tx_sw_if_index_set = 1;
4512       else if (unformat (i, "rx"))
4513         {
4514           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4515             {
4516               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
4517                             &rx_sw_if_index))
4518                 rx_sw_if_index_set = 1;
4519             }
4520           else
4521             break;
4522         }
4523       else if (unformat (i, "tx"))
4524         {
4525           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4526             {
4527               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
4528                             &tx_sw_if_index))
4529                 tx_sw_if_index_set = 1;
4530             }
4531           else
4532             break;
4533         }
4534       else if (unformat (i, "enable"))
4535         enable = 1;
4536       else if (unformat (i, "disable"))
4537         enable = 0;
4538       else
4539         break;
4540     }
4541
4542   if (rx_sw_if_index_set == 0)
4543     {
4544       errmsg ("missing rx interface name or rx_sw_if_index");
4545       return -99;
4546     }
4547
4548   if (enable && (tx_sw_if_index_set == 0))
4549     {
4550       errmsg ("missing tx interface name or tx_sw_if_index");
4551       return -99;
4552     }
4553
4554   M (SW_INTERFACE_SET_L2_XCONNECT, mp);
4555
4556   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
4557   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
4558   mp->enable = enable;
4559
4560   S (mp);
4561   W (ret);
4562   return ret;
4563 }
4564
4565 static int
4566 api_sw_interface_set_l2_bridge (vat_main_t * vam)
4567 {
4568   unformat_input_t *i = vam->input;
4569   vl_api_sw_interface_set_l2_bridge_t *mp;
4570   vl_api_l2_port_type_t port_type;
4571   u32 rx_sw_if_index;
4572   u8 rx_sw_if_index_set = 0;
4573   u32 bd_id;
4574   u8 bd_id_set = 0;
4575   u32 shg = 0;
4576   u8 enable = 1;
4577   int ret;
4578
4579   port_type = L2_API_PORT_TYPE_NORMAL;
4580
4581   /* Parse args required to build the message */
4582   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4583     {
4584       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
4585         rx_sw_if_index_set = 1;
4586       else if (unformat (i, "bd_id %d", &bd_id))
4587         bd_id_set = 1;
4588       else
4589         if (unformat
4590             (i, "%U", api_unformat_sw_if_index, vam, &rx_sw_if_index))
4591         rx_sw_if_index_set = 1;
4592       else if (unformat (i, "shg %d", &shg))
4593         ;
4594       else if (unformat (i, "bvi"))
4595         port_type = L2_API_PORT_TYPE_BVI;
4596       else if (unformat (i, "uu-fwd"))
4597         port_type = L2_API_PORT_TYPE_UU_FWD;
4598       else if (unformat (i, "enable"))
4599         enable = 1;
4600       else if (unformat (i, "disable"))
4601         enable = 0;
4602       else
4603         break;
4604     }
4605
4606   if (rx_sw_if_index_set == 0)
4607     {
4608       errmsg ("missing rx interface name or sw_if_index");
4609       return -99;
4610     }
4611
4612   if (enable && (bd_id_set == 0))
4613     {
4614       errmsg ("missing bridge domain");
4615       return -99;
4616     }
4617
4618   M (SW_INTERFACE_SET_L2_BRIDGE, mp);
4619
4620   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
4621   mp->bd_id = ntohl (bd_id);
4622   mp->shg = (u8) shg;
4623   mp->port_type = ntohl (port_type);
4624   mp->enable = enable;
4625
4626   S (mp);
4627   W (ret);
4628   return ret;
4629 }
4630
4631 static int
4632 api_bridge_domain_dump (vat_main_t * vam)
4633 {
4634   unformat_input_t *i = vam->input;
4635   vl_api_bridge_domain_dump_t *mp;
4636   vl_api_control_ping_t *mp_ping;
4637   u32 bd_id = ~0;
4638   int ret;
4639
4640   /* Parse args required to build the message */
4641   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4642     {
4643       if (unformat (i, "bd_id %d", &bd_id))
4644         ;
4645       else
4646         break;
4647     }
4648
4649   M (BRIDGE_DOMAIN_DUMP, mp);
4650   mp->bd_id = ntohl (bd_id);
4651   S (mp);
4652
4653   /* Use a control ping for synchronization */
4654   MPING (CONTROL_PING, mp_ping);
4655   S (mp_ping);
4656
4657   W (ret);
4658   return ret;
4659 }
4660
4661 static int
4662 api_bridge_domain_add_del (vat_main_t * vam)
4663 {
4664   unformat_input_t *i = vam->input;
4665   vl_api_bridge_domain_add_del_t *mp;
4666   u32 bd_id = ~0;
4667   u8 is_add = 1;
4668   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
4669   u8 *bd_tag = NULL;
4670   u32 mac_age = 0;
4671   int ret;
4672
4673   /* Parse args required to build the message */
4674   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4675     {
4676       if (unformat (i, "bd_id %d", &bd_id))
4677         ;
4678       else if (unformat (i, "flood %d", &flood))
4679         ;
4680       else if (unformat (i, "uu-flood %d", &uu_flood))
4681         ;
4682       else if (unformat (i, "forward %d", &forward))
4683         ;
4684       else if (unformat (i, "learn %d", &learn))
4685         ;
4686       else if (unformat (i, "arp-term %d", &arp_term))
4687         ;
4688       else if (unformat (i, "mac-age %d", &mac_age))
4689         ;
4690       else if (unformat (i, "bd-tag %s", &bd_tag))
4691         ;
4692       else if (unformat (i, "del"))
4693         {
4694           is_add = 0;
4695           flood = uu_flood = forward = learn = 0;
4696         }
4697       else
4698         break;
4699     }
4700
4701   if (bd_id == ~0)
4702     {
4703       errmsg ("missing bridge domain");
4704       ret = -99;
4705       goto done;
4706     }
4707
4708   if (mac_age > 255)
4709     {
4710       errmsg ("mac age must be less than 256 ");
4711       ret = -99;
4712       goto done;
4713     }
4714
4715   if ((bd_tag) && (vec_len (bd_tag) > 63))
4716     {
4717       errmsg ("bd-tag cannot be longer than 63");
4718       ret = -99;
4719       goto done;
4720     }
4721
4722   M (BRIDGE_DOMAIN_ADD_DEL, mp);
4723
4724   mp->bd_id = ntohl (bd_id);
4725   mp->flood = flood;
4726   mp->uu_flood = uu_flood;
4727   mp->forward = forward;
4728   mp->learn = learn;
4729   mp->arp_term = arp_term;
4730   mp->is_add = is_add;
4731   mp->mac_age = (u8) mac_age;
4732   if (bd_tag)
4733     {
4734       clib_memcpy (mp->bd_tag, bd_tag, vec_len (bd_tag));
4735       mp->bd_tag[vec_len (bd_tag)] = 0;
4736     }
4737   S (mp);
4738   W (ret);
4739
4740 done:
4741   vec_free (bd_tag);
4742   return ret;
4743 }
4744
4745 static int
4746 api_l2fib_flush_bd (vat_main_t * vam)
4747 {
4748   unformat_input_t *i = vam->input;
4749   vl_api_l2fib_flush_bd_t *mp;
4750   u32 bd_id = ~0;
4751   int ret;
4752
4753   /* Parse args required to build the message */
4754   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4755     {
4756       if (unformat (i, "bd_id %d", &bd_id));
4757       else
4758         break;
4759     }
4760
4761   if (bd_id == ~0)
4762     {
4763       errmsg ("missing bridge domain");
4764       return -99;
4765     }
4766
4767   M (L2FIB_FLUSH_BD, mp);
4768
4769   mp->bd_id = htonl (bd_id);
4770
4771   S (mp);
4772   W (ret);
4773   return ret;
4774 }
4775
4776 static int
4777 api_l2fib_flush_int (vat_main_t * vam)
4778 {
4779   unformat_input_t *i = vam->input;
4780   vl_api_l2fib_flush_int_t *mp;
4781   u32 sw_if_index = ~0;
4782   int ret;
4783
4784   /* Parse args required to build the message */
4785   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4786     {
4787       if (unformat (i, "sw_if_index %d", &sw_if_index));
4788       else
4789         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index));
4790       else
4791         break;
4792     }
4793
4794   if (sw_if_index == ~0)
4795     {
4796       errmsg ("missing interface name or sw_if_index");
4797       return -99;
4798     }
4799
4800   M (L2FIB_FLUSH_INT, mp);
4801
4802   mp->sw_if_index = ntohl (sw_if_index);
4803
4804   S (mp);
4805   W (ret);
4806   return ret;
4807 }
4808
4809 static int
4810 api_l2fib_add_del (vat_main_t * vam)
4811 {
4812   unformat_input_t *i = vam->input;
4813   vl_api_l2fib_add_del_t *mp;
4814   f64 timeout;
4815   u8 mac[6] = { 0 };
4816   u8 mac_set = 0;
4817   u32 bd_id;
4818   u8 bd_id_set = 0;
4819   u32 sw_if_index = 0;
4820   u8 sw_if_index_set = 0;
4821   u8 is_add = 1;
4822   u8 static_mac = 0;
4823   u8 filter_mac = 0;
4824   u8 bvi_mac = 0;
4825   int count = 1;
4826   f64 before = 0;
4827   int j;
4828
4829   /* Parse args required to build the message */
4830   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4831     {
4832       if (unformat (i, "mac %U", unformat_ethernet_address, mac))
4833         mac_set = 1;
4834       else if (unformat (i, "bd_id %d", &bd_id))
4835         bd_id_set = 1;
4836       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4837         sw_if_index_set = 1;
4838       else if (unformat (i, "sw_if"))
4839         {
4840           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4841             {
4842               if (unformat
4843                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
4844                 sw_if_index_set = 1;
4845             }
4846           else
4847             break;
4848         }
4849       else if (unformat (i, "static"))
4850         static_mac = 1;
4851       else if (unformat (i, "filter"))
4852         {
4853           filter_mac = 1;
4854           static_mac = 1;
4855         }
4856       else if (unformat (i, "bvi"))
4857         {
4858           bvi_mac = 1;
4859           static_mac = 1;
4860         }
4861       else if (unformat (i, "del"))
4862         is_add = 0;
4863       else if (unformat (i, "count %d", &count))
4864         ;
4865       else
4866         break;
4867     }
4868
4869   if (mac_set == 0)
4870     {
4871       errmsg ("missing mac address");
4872       return -99;
4873     }
4874
4875   if (bd_id_set == 0)
4876     {
4877       errmsg ("missing bridge domain");
4878       return -99;
4879     }
4880
4881   if (is_add && sw_if_index_set == 0 && filter_mac == 0)
4882     {
4883       errmsg ("missing interface name or sw_if_index");
4884       return -99;
4885     }
4886
4887   if (count > 1)
4888     {
4889       /* Turn on async mode */
4890       vam->async_mode = 1;
4891       vam->async_errors = 0;
4892       before = vat_time_now (vam);
4893     }
4894
4895   for (j = 0; j < count; j++)
4896     {
4897       M (L2FIB_ADD_DEL, mp);
4898
4899       clib_memcpy (mp->mac, mac, 6);
4900       mp->bd_id = ntohl (bd_id);
4901       mp->is_add = is_add;
4902       mp->sw_if_index = ntohl (sw_if_index);
4903
4904       if (is_add)
4905         {
4906           mp->static_mac = static_mac;
4907           mp->filter_mac = filter_mac;
4908           mp->bvi_mac = bvi_mac;
4909         }
4910       increment_mac_address (mac);
4911       /* send it... */
4912       S (mp);
4913     }
4914
4915   if (count > 1)
4916     {
4917       vl_api_control_ping_t *mp_ping;
4918       f64 after;
4919
4920       /* Shut off async mode */
4921       vam->async_mode = 0;
4922
4923       MPING (CONTROL_PING, mp_ping);
4924       S (mp_ping);
4925
4926       timeout = vat_time_now (vam) + 1.0;
4927       while (vat_time_now (vam) < timeout)
4928         if (vam->result_ready == 1)
4929           goto out;
4930       vam->retval = -99;
4931
4932     out:
4933       if (vam->retval == -99)
4934         errmsg ("timeout");
4935
4936       if (vam->async_errors > 0)
4937         {
4938           errmsg ("%d asynchronous errors", vam->async_errors);
4939           vam->retval = -98;
4940         }
4941       vam->async_errors = 0;
4942       after = vat_time_now (vam);
4943
4944       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
4945              count, after - before, count / (after - before));
4946     }
4947   else
4948     {
4949       int ret;
4950
4951       /* Wait for a reply... */
4952       W (ret);
4953       return ret;
4954     }
4955   /* Return the good/bad news */
4956   return (vam->retval);
4957 }
4958
4959 static int
4960 api_bridge_domain_set_mac_age (vat_main_t * vam)
4961 {
4962   unformat_input_t *i = vam->input;
4963   vl_api_bridge_domain_set_mac_age_t *mp;
4964   u32 bd_id = ~0;
4965   u32 mac_age = 0;
4966   int ret;
4967
4968   /* Parse args required to build the message */
4969   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4970     {
4971       if (unformat (i, "bd_id %d", &bd_id));
4972       else if (unformat (i, "mac-age %d", &mac_age));
4973       else
4974         break;
4975     }
4976
4977   if (bd_id == ~0)
4978     {
4979       errmsg ("missing bridge domain");
4980       return -99;
4981     }
4982
4983   if (mac_age > 255)
4984     {
4985       errmsg ("mac age must be less than 256 ");
4986       return -99;
4987     }
4988
4989   M (BRIDGE_DOMAIN_SET_MAC_AGE, mp);
4990
4991   mp->bd_id = htonl (bd_id);
4992   mp->mac_age = (u8) mac_age;
4993
4994   S (mp);
4995   W (ret);
4996   return ret;
4997 }
4998
4999 static int
5000 api_l2_flags (vat_main_t * vam)
5001 {
5002   unformat_input_t *i = vam->input;
5003   vl_api_l2_flags_t *mp;
5004   u32 sw_if_index;
5005   u32 flags = 0;
5006   u8 sw_if_index_set = 0;
5007   u8 is_set = 0;
5008   int ret;
5009
5010   /* Parse args required to build the message */
5011   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5012     {
5013       if (unformat (i, "sw_if_index %d", &sw_if_index))
5014         sw_if_index_set = 1;
5015       else if (unformat (i, "sw_if"))
5016         {
5017           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5018             {
5019               if (unformat
5020                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5021                 sw_if_index_set = 1;
5022             }
5023           else
5024             break;
5025         }
5026       else if (unformat (i, "learn"))
5027         flags |= L2_LEARN;
5028       else if (unformat (i, "forward"))
5029         flags |= L2_FWD;
5030       else if (unformat (i, "flood"))
5031         flags |= L2_FLOOD;
5032       else if (unformat (i, "uu-flood"))
5033         flags |= L2_UU_FLOOD;
5034       else if (unformat (i, "arp-term"))
5035         flags |= L2_ARP_TERM;
5036       else if (unformat (i, "off"))
5037         is_set = 0;
5038       else if (unformat (i, "disable"))
5039         is_set = 0;
5040       else
5041         break;
5042     }
5043
5044   if (sw_if_index_set == 0)
5045     {
5046       errmsg ("missing interface name or sw_if_index");
5047       return -99;
5048     }
5049
5050   M (L2_FLAGS, mp);
5051
5052   mp->sw_if_index = ntohl (sw_if_index);
5053   mp->feature_bitmap = ntohl (flags);
5054   mp->is_set = is_set;
5055
5056   S (mp);
5057   W (ret);
5058   return ret;
5059 }
5060
5061 static int
5062 api_bridge_flags (vat_main_t * vam)
5063 {
5064   unformat_input_t *i = vam->input;
5065   vl_api_bridge_flags_t *mp;
5066   u32 bd_id;
5067   u8 bd_id_set = 0;
5068   u8 is_set = 1;
5069   bd_flags_t flags = 0;
5070   int ret;
5071
5072   /* Parse args required to build the message */
5073   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5074     {
5075       if (unformat (i, "bd_id %d", &bd_id))
5076         bd_id_set = 1;
5077       else if (unformat (i, "learn"))
5078         flags |= BRIDGE_API_FLAG_LEARN;
5079       else if (unformat (i, "forward"))
5080         flags |= BRIDGE_API_FLAG_FWD;
5081       else if (unformat (i, "flood"))
5082         flags |= BRIDGE_API_FLAG_FLOOD;
5083       else if (unformat (i, "uu-flood"))
5084         flags |= BRIDGE_API_FLAG_UU_FLOOD;
5085       else if (unformat (i, "arp-term"))
5086         flags |= BRIDGE_API_FLAG_ARP_TERM;
5087       else if (unformat (i, "off"))
5088         is_set = 0;
5089       else if (unformat (i, "disable"))
5090         is_set = 0;
5091       else
5092         break;
5093     }
5094
5095   if (bd_id_set == 0)
5096     {
5097       errmsg ("missing bridge domain");
5098       return -99;
5099     }
5100
5101   M (BRIDGE_FLAGS, mp);
5102
5103   mp->bd_id = ntohl (bd_id);
5104   mp->flags = ntohl (flags);
5105   mp->is_set = is_set;
5106
5107   S (mp);
5108   W (ret);
5109   return ret;
5110 }
5111
5112 static int
5113 api_bd_ip_mac_add_del (vat_main_t * vam)
5114 {
5115   vl_api_address_t ip = VL_API_ZERO_ADDRESS;
5116   vl_api_mac_address_t mac = { 0 };
5117   unformat_input_t *i = vam->input;
5118   vl_api_bd_ip_mac_add_del_t *mp;
5119   u32 bd_id;
5120   u8 is_add = 1;
5121   u8 bd_id_set = 0;
5122   u8 ip_set = 0;
5123   u8 mac_set = 0;
5124   int ret;
5125
5126
5127   /* Parse args required to build the message */
5128   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5129     {
5130       if (unformat (i, "bd_id %d", &bd_id))
5131         {
5132           bd_id_set++;
5133         }
5134       else if (unformat (i, "%U", unformat_vl_api_address, &ip))
5135         {
5136           ip_set++;
5137         }
5138       else if (unformat (i, "%U", unformat_vl_api_mac_address, &mac))
5139         {
5140           mac_set++;
5141         }
5142       else if (unformat (i, "del"))
5143         is_add = 0;
5144       else
5145         break;
5146     }
5147
5148   if (bd_id_set == 0)
5149     {
5150       errmsg ("missing bridge domain");
5151       return -99;
5152     }
5153   else if (ip_set == 0)
5154     {
5155       errmsg ("missing IP address");
5156       return -99;
5157     }
5158   else if (mac_set == 0)
5159     {
5160       errmsg ("missing MAC address");
5161       return -99;
5162     }
5163
5164   M (BD_IP_MAC_ADD_DEL, mp);
5165
5166   mp->entry.bd_id = ntohl (bd_id);
5167   mp->is_add = is_add;
5168
5169   clib_memcpy (&mp->entry.ip, &ip, sizeof (ip));
5170   clib_memcpy (&mp->entry.mac, &mac, sizeof (mac));
5171
5172   S (mp);
5173   W (ret);
5174   return ret;
5175 }
5176
5177 static int
5178 api_bd_ip_mac_flush (vat_main_t * vam)
5179 {
5180   unformat_input_t *i = vam->input;
5181   vl_api_bd_ip_mac_flush_t *mp;
5182   u32 bd_id;
5183   u8 bd_id_set = 0;
5184   int ret;
5185
5186   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5187     {
5188       if (unformat (i, "bd_id %d", &bd_id))
5189         {
5190           bd_id_set++;
5191         }
5192       else
5193         break;
5194     }
5195
5196   if (bd_id_set == 0)
5197     {
5198       errmsg ("missing bridge domain");
5199       return -99;
5200     }
5201
5202   M (BD_IP_MAC_FLUSH, mp);
5203
5204   mp->bd_id = ntohl (bd_id);
5205
5206   S (mp);
5207   W (ret);
5208   return ret;
5209 }
5210
5211 static void vl_api_bd_ip_mac_details_t_handler
5212   (vl_api_bd_ip_mac_details_t * mp)
5213 {
5214   vat_main_t *vam = &vat_main;
5215
5216   print (vam->ofp,
5217          "\n%-5d %U %U",
5218          ntohl (mp->entry.bd_id),
5219          format_vl_api_mac_address, mp->entry.mac,
5220          format_vl_api_address, &mp->entry.ip);
5221 }
5222
5223 static void vl_api_bd_ip_mac_details_t_handler_json
5224   (vl_api_bd_ip_mac_details_t * mp)
5225 {
5226   vat_main_t *vam = &vat_main;
5227   vat_json_node_t *node = NULL;
5228
5229   if (VAT_JSON_ARRAY != vam->json_tree.type)
5230     {
5231       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5232       vat_json_init_array (&vam->json_tree);
5233     }
5234   node = vat_json_array_add (&vam->json_tree);
5235
5236   vat_json_init_object (node);
5237   vat_json_object_add_uint (node, "bd_id", ntohl (mp->entry.bd_id));
5238   vat_json_object_add_string_copy (node, "mac_address",
5239                                    format (0, "%U", format_vl_api_mac_address,
5240                                            &mp->entry.mac));
5241   u8 *ip = 0;
5242
5243   ip = format (0, "%U", format_vl_api_address, &mp->entry.ip);
5244   vat_json_object_add_string_copy (node, "ip_address", ip);
5245   vec_free (ip);
5246 }
5247
5248 static int
5249 api_bd_ip_mac_dump (vat_main_t * vam)
5250 {
5251   unformat_input_t *i = vam->input;
5252   vl_api_bd_ip_mac_dump_t *mp;
5253   vl_api_control_ping_t *mp_ping;
5254   int ret;
5255   u32 bd_id;
5256   u8 bd_id_set = 0;
5257
5258   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5259     {
5260       if (unformat (i, "bd_id %d", &bd_id))
5261         {
5262           bd_id_set++;
5263         }
5264       else
5265         break;
5266     }
5267
5268   print (vam->ofp,
5269          "\n%-5s %-7s %-20s %-30s",
5270          "bd_id", "is_ipv6", "mac_address", "ip_address");
5271
5272   /* Dump Bridge Domain Ip to Mac entries */
5273   M (BD_IP_MAC_DUMP, mp);
5274
5275   if (bd_id_set)
5276     mp->bd_id = htonl (bd_id);
5277   else
5278     mp->bd_id = ~0;
5279
5280   S (mp);
5281
5282   /* Use a control ping for synchronization */
5283   MPING (CONTROL_PING, mp_ping);
5284   S (mp_ping);
5285
5286   W (ret);
5287   return ret;
5288 }
5289
5290 static int
5291 api_tap_create_v2 (vat_main_t * vam)
5292 {
5293   unformat_input_t *i = vam->input;
5294   vl_api_tap_create_v2_t *mp;
5295   u8 mac_address[6];
5296   u8 random_mac = 1;
5297   u32 id = ~0;
5298   u32 num_rx_queues = 0;
5299   u8 *host_if_name = 0;
5300   u8 host_if_name_set = 0;
5301   u8 *host_ns = 0;
5302   u8 host_ns_set = 0;
5303   u8 host_mac_addr[6];
5304   u8 host_mac_addr_set = 0;
5305   u8 *host_bridge = 0;
5306   u8 host_bridge_set = 0;
5307   u8 host_ip4_prefix_set = 0;
5308   u8 host_ip6_prefix_set = 0;
5309   ip4_address_t host_ip4_addr;
5310   ip4_address_t host_ip4_gw;
5311   u8 host_ip4_gw_set = 0;
5312   u32 host_ip4_prefix_len = 0;
5313   ip6_address_t host_ip6_addr;
5314   ip6_address_t host_ip6_gw;
5315   u8 host_ip6_gw_set = 0;
5316   u32 host_ip6_prefix_len = 0;
5317   u32 host_mtu_size = 0;
5318   u8 host_mtu_set = 0;
5319   u32 tap_flags = 0;
5320   int ret;
5321   u32 rx_ring_sz = 0, tx_ring_sz = 0;
5322
5323   clib_memset (mac_address, 0, sizeof (mac_address));
5324
5325   /* Parse args required to build the message */
5326   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5327     {
5328       if (unformat (i, "id %u", &id))
5329         ;
5330       else
5331         if (unformat
5332             (i, "hw-addr %U", unformat_ethernet_address, mac_address))
5333         random_mac = 0;
5334       else if (unformat (i, "host-if-name %s", &host_if_name))
5335         host_if_name_set = 1;
5336       else if (unformat (i, "num-rx-queues %u", &num_rx_queues))
5337         ;
5338       else if (unformat (i, "host-ns %s", &host_ns))
5339         host_ns_set = 1;
5340       else if (unformat (i, "host-mac-addr %U", unformat_ethernet_address,
5341                          host_mac_addr))
5342         host_mac_addr_set = 1;
5343       else if (unformat (i, "host-bridge %s", &host_bridge))
5344         host_bridge_set = 1;
5345       else if (unformat (i, "host-ip4-addr %U/%u", unformat_ip4_address,
5346                          &host_ip4_addr, &host_ip4_prefix_len))
5347         host_ip4_prefix_set = 1;
5348       else if (unformat (i, "host-ip6-addr %U/%u", unformat_ip6_address,
5349                          &host_ip6_addr, &host_ip6_prefix_len))
5350         host_ip6_prefix_set = 1;
5351       else if (unformat (i, "host-ip4-gw %U", unformat_ip4_address,
5352                          &host_ip4_gw))
5353         host_ip4_gw_set = 1;
5354       else if (unformat (i, "host-ip6-gw %U", unformat_ip6_address,
5355                          &host_ip6_gw))
5356         host_ip6_gw_set = 1;
5357       else if (unformat (i, "rx-ring-size %u", &rx_ring_sz))
5358         ;
5359       else if (unformat (i, "tx-ring-size %u", &tx_ring_sz))
5360         ;
5361       else if (unformat (i, "host-mtu-size %u", &host_mtu_size))
5362         host_mtu_set = 1;
5363       else if (unformat (i, "no-gso"))
5364         tap_flags &= ~TAP_API_FLAG_GSO;
5365       else if (unformat (i, "gso"))
5366         tap_flags |= TAP_API_FLAG_GSO;
5367       else if (unformat (i, "csum-offload"))
5368         tap_flags |= TAP_API_FLAG_CSUM_OFFLOAD;
5369       else if (unformat (i, "persist"))
5370         tap_flags |= TAP_API_FLAG_PERSIST;
5371       else if (unformat (i, "attach"))
5372         tap_flags |= TAP_API_FLAG_ATTACH;
5373       else if (unformat (i, "tun"))
5374         tap_flags |= TAP_API_FLAG_TUN;
5375       else if (unformat (i, "gro-coalesce"))
5376         tap_flags |= TAP_API_FLAG_GRO_COALESCE;
5377       else if (unformat (i, "packed"))
5378         tap_flags |= TAP_API_FLAG_PACKED;
5379       else if (unformat (i, "in-order"))
5380         tap_flags |= TAP_API_FLAG_IN_ORDER;
5381       else
5382         break;
5383     }
5384
5385   if (vec_len (host_if_name) > 63)
5386     {
5387       errmsg ("tap name too long. ");
5388       return -99;
5389     }
5390   if (vec_len (host_ns) > 63)
5391     {
5392       errmsg ("host name space too long. ");
5393       return -99;
5394     }
5395   if (vec_len (host_bridge) > 63)
5396     {
5397       errmsg ("host bridge name too long. ");
5398       return -99;
5399     }
5400   if (host_ip4_prefix_len > 32)
5401     {
5402       errmsg ("host ip4 prefix length not valid. ");
5403       return -99;
5404     }
5405   if (host_ip6_prefix_len > 128)
5406     {
5407       errmsg ("host ip6 prefix length not valid. ");
5408       return -99;
5409     }
5410   if (!is_pow2 (rx_ring_sz))
5411     {
5412       errmsg ("rx ring size must be power of 2. ");
5413       return -99;
5414     }
5415   if (rx_ring_sz > 32768)
5416     {
5417       errmsg ("rx ring size must be 32768 or lower. ");
5418       return -99;
5419     }
5420   if (!is_pow2 (tx_ring_sz))
5421     {
5422       errmsg ("tx ring size must be power of 2. ");
5423       return -99;
5424     }
5425   if (tx_ring_sz > 32768)
5426     {
5427       errmsg ("tx ring size must be 32768 or lower. ");
5428       return -99;
5429     }
5430   if (host_mtu_set && (host_mtu_size < 64 || host_mtu_size > 65355))
5431     {
5432       errmsg ("host MTU size must be in between 64 and 65355. ");
5433       return -99;
5434     }
5435
5436   /* Construct the API message */
5437   M (TAP_CREATE_V2, mp);
5438
5439   mp->id = ntohl (id);
5440   mp->use_random_mac = random_mac;
5441   mp->num_rx_queues = (u8) num_rx_queues;
5442   mp->tx_ring_sz = ntohs (tx_ring_sz);
5443   mp->rx_ring_sz = ntohs (rx_ring_sz);
5444   mp->host_mtu_set = host_mtu_set;
5445   mp->host_mtu_size = ntohl (host_mtu_size);
5446   mp->host_mac_addr_set = host_mac_addr_set;
5447   mp->host_ip4_prefix_set = host_ip4_prefix_set;
5448   mp->host_ip6_prefix_set = host_ip6_prefix_set;
5449   mp->host_ip4_gw_set = host_ip4_gw_set;
5450   mp->host_ip6_gw_set = host_ip6_gw_set;
5451   mp->tap_flags = ntohl (tap_flags);
5452   mp->host_namespace_set = host_ns_set;
5453   mp->host_if_name_set = host_if_name_set;
5454   mp->host_bridge_set = host_bridge_set;
5455
5456   if (random_mac == 0)
5457     clib_memcpy (mp->mac_address, mac_address, 6);
5458   if (host_mac_addr_set)
5459     clib_memcpy (mp->host_mac_addr, host_mac_addr, 6);
5460   if (host_if_name_set)
5461     clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
5462   if (host_ns_set)
5463     clib_memcpy (mp->host_namespace, host_ns, vec_len (host_ns));
5464   if (host_bridge_set)
5465     clib_memcpy (mp->host_bridge, host_bridge, vec_len (host_bridge));
5466   if (host_ip4_prefix_set)
5467     {
5468       clib_memcpy (mp->host_ip4_prefix.address, &host_ip4_addr, 4);
5469       mp->host_ip4_prefix.len = (u8) host_ip4_prefix_len;
5470     }
5471   if (host_ip6_prefix_set)
5472     {
5473       clib_memcpy (mp->host_ip6_prefix.address, &host_ip6_addr, 16);
5474       mp->host_ip6_prefix.len = (u8) host_ip6_prefix_len;
5475     }
5476   if (host_ip4_gw_set)
5477     clib_memcpy (mp->host_ip4_gw, &host_ip4_gw, 4);
5478   if (host_ip6_gw_set)
5479     clib_memcpy (mp->host_ip6_gw, &host_ip6_gw, 16);
5480
5481   vec_free (host_ns);
5482   vec_free (host_if_name);
5483   vec_free (host_bridge);
5484
5485   /* send it... */
5486   S (mp);
5487
5488   /* Wait for a reply... */
5489   W (ret);
5490   return ret;
5491 }
5492
5493 static int
5494 api_tap_delete_v2 (vat_main_t * vam)
5495 {
5496   unformat_input_t *i = vam->input;
5497   vl_api_tap_delete_v2_t *mp;
5498   u32 sw_if_index = ~0;
5499   u8 sw_if_index_set = 0;
5500   int ret;
5501
5502   /* Parse args required to build the message */
5503   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5504     {
5505       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5506         sw_if_index_set = 1;
5507       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5508         sw_if_index_set = 1;
5509       else
5510         break;
5511     }
5512
5513   if (sw_if_index_set == 0)
5514     {
5515       errmsg ("missing vpp interface name. ");
5516       return -99;
5517     }
5518
5519   /* Construct the API message */
5520   M (TAP_DELETE_V2, mp);
5521
5522   mp->sw_if_index = ntohl (sw_if_index);
5523
5524   /* send it... */
5525   S (mp);
5526
5527   /* Wait for a reply... */
5528   W (ret);
5529   return ret;
5530 }
5531
5532 uword
5533 unformat_vlib_pci_addr (unformat_input_t * input, va_list * args)
5534 {
5535   vlib_pci_addr_t *addr = va_arg (*args, vlib_pci_addr_t *);
5536   u32 x[4];
5537
5538   if (!unformat (input, "%x:%x:%x.%x", &x[0], &x[1], &x[2], &x[3]))
5539     return 0;
5540
5541   addr->domain = x[0];
5542   addr->bus = x[1];
5543   addr->slot = x[2];
5544   addr->function = x[3];
5545
5546   return 1;
5547 }
5548
5549 static int
5550 api_virtio_pci_create_v2 (vat_main_t * vam)
5551 {
5552   unformat_input_t *i = vam->input;
5553   vl_api_virtio_pci_create_v2_t *mp;
5554   u8 mac_address[6];
5555   u8 random_mac = 1;
5556   u32 pci_addr = 0;
5557   u64 features = (u64) ~ (0ULL);
5558   u32 virtio_flags = 0;
5559   int ret;
5560
5561   clib_memset (mac_address, 0, sizeof (mac_address));
5562
5563   /* Parse args required to build the message */
5564   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5565     {
5566       if (unformat (i, "hw-addr %U", unformat_ethernet_address, mac_address))
5567         {
5568           random_mac = 0;
5569         }
5570       else if (unformat (i, "pci-addr %U", unformat_vlib_pci_addr, &pci_addr))
5571         ;
5572       else if (unformat (i, "features 0x%llx", &features))
5573         ;
5574       else if (unformat (i, "gso-enabled"))
5575         virtio_flags |= VIRTIO_API_FLAG_GSO;
5576       else if (unformat (i, "csum-offload-enabled"))
5577         virtio_flags |= VIRTIO_API_FLAG_CSUM_OFFLOAD;
5578       else if (unformat (i, "gro-coalesce"))
5579         virtio_flags |= VIRTIO_API_FLAG_GRO_COALESCE;
5580       else if (unformat (i, "packed"))
5581         virtio_flags |= VIRTIO_API_FLAG_PACKED;
5582       else if (unformat (i, "in-order"))
5583         virtio_flags |= VIRTIO_API_FLAG_IN_ORDER;
5584       else if (unformat (i, "buffering"))
5585         virtio_flags |= VIRTIO_API_FLAG_BUFFERING;
5586       else
5587         break;
5588     }
5589
5590   if (pci_addr == 0)
5591     {
5592       errmsg ("pci address must be non zero. ");
5593       return -99;
5594     }
5595
5596   /* Construct the API message */
5597   M (VIRTIO_PCI_CREATE_V2, mp);
5598
5599   mp->use_random_mac = random_mac;
5600
5601   mp->pci_addr.domain = htons (((vlib_pci_addr_t) pci_addr).domain);
5602   mp->pci_addr.bus = ((vlib_pci_addr_t) pci_addr).bus;
5603   mp->pci_addr.slot = ((vlib_pci_addr_t) pci_addr).slot;
5604   mp->pci_addr.function = ((vlib_pci_addr_t) pci_addr).function;
5605
5606   mp->features = clib_host_to_net_u64 (features);
5607   mp->virtio_flags = clib_host_to_net_u32 (virtio_flags);
5608
5609   if (random_mac == 0)
5610     clib_memcpy (mp->mac_address, mac_address, 6);
5611
5612   /* send it... */
5613   S (mp);
5614
5615   /* Wait for a reply... */
5616   W (ret);
5617   return ret;
5618 }
5619
5620 static int
5621 api_virtio_pci_delete (vat_main_t * vam)
5622 {
5623   unformat_input_t *i = vam->input;
5624   vl_api_virtio_pci_delete_t *mp;
5625   u32 sw_if_index = ~0;
5626   u8 sw_if_index_set = 0;
5627   int ret;
5628
5629   /* Parse args required to build the message */
5630   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5631     {
5632       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5633         sw_if_index_set = 1;
5634       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5635         sw_if_index_set = 1;
5636       else
5637         break;
5638     }
5639
5640   if (sw_if_index_set == 0)
5641     {
5642       errmsg ("missing vpp interface name. ");
5643       return -99;
5644     }
5645
5646   /* Construct the API message */
5647   M (VIRTIO_PCI_DELETE, mp);
5648
5649   mp->sw_if_index = htonl (sw_if_index);
5650
5651   /* send it... */
5652   S (mp);
5653
5654   /* Wait for a reply... */
5655   W (ret);
5656   return ret;
5657 }
5658
5659 static int
5660 api_bond_create (vat_main_t * vam)
5661 {
5662   unformat_input_t *i = vam->input;
5663   vl_api_bond_create_t *mp;
5664   u8 mac_address[6];
5665   u8 custom_mac = 0;
5666   int ret;
5667   u8 mode;
5668   u8 lb;
5669   u8 mode_is_set = 0;
5670   u32 id = ~0;
5671   u8 numa_only = 0;
5672
5673   clib_memset (mac_address, 0, sizeof (mac_address));
5674   lb = BOND_LB_L2;
5675
5676   /* Parse args required to build the message */
5677   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5678     {
5679       if (unformat (i, "mode %U", unformat_bond_mode, &mode))
5680         mode_is_set = 1;
5681       else if (((mode == BOND_MODE_LACP) || (mode == BOND_MODE_XOR))
5682                && unformat (i, "lb %U", unformat_bond_load_balance, &lb))
5683         ;
5684       else if (unformat (i, "hw-addr %U", unformat_ethernet_address,
5685                          mac_address))
5686         custom_mac = 1;
5687       else if (unformat (i, "numa-only"))
5688         numa_only = 1;
5689       else if (unformat (i, "id %u", &id))
5690         ;
5691       else
5692         break;
5693     }
5694
5695   if (mode_is_set == 0)
5696     {
5697       errmsg ("Missing bond mode. ");
5698       return -99;
5699     }
5700
5701   /* Construct the API message */
5702   M (BOND_CREATE, mp);
5703
5704   mp->use_custom_mac = custom_mac;
5705
5706   mp->mode = htonl (mode);
5707   mp->lb = htonl (lb);
5708   mp->id = htonl (id);
5709   mp->numa_only = numa_only;
5710
5711   if (custom_mac)
5712     clib_memcpy (mp->mac_address, mac_address, 6);
5713
5714   /* send it... */
5715   S (mp);
5716
5717   /* Wait for a reply... */
5718   W (ret);
5719   return ret;
5720 }
5721
5722 static int
5723 api_bond_create2 (vat_main_t * vam)
5724 {
5725   unformat_input_t *i = vam->input;
5726   vl_api_bond_create2_t *mp;
5727   u8 mac_address[6];
5728   u8 custom_mac = 0;
5729   int ret;
5730   u8 mode;
5731   u8 lb;
5732   u8 mode_is_set = 0;
5733   u32 id = ~0;
5734   u8 numa_only = 0;
5735   u8 gso = 0;
5736
5737   clib_memset (mac_address, 0, sizeof (mac_address));
5738   lb = BOND_LB_L2;
5739
5740   /* Parse args required to build the message */
5741   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5742     {
5743       if (unformat (i, "mode %U", unformat_bond_mode, &mode))
5744         mode_is_set = 1;
5745       else if (((mode == BOND_MODE_LACP) || (mode == BOND_MODE_XOR))
5746                && unformat (i, "lb %U", unformat_bond_load_balance, &lb))
5747         ;
5748       else if (unformat (i, "hw-addr %U", unformat_ethernet_address,
5749                          mac_address))
5750         custom_mac = 1;
5751       else if (unformat (i, "numa-only"))
5752         numa_only = 1;
5753       else if (unformat (i, "gso"))
5754         gso = 1;
5755       else if (unformat (i, "id %u", &id))
5756         ;
5757       else
5758         break;
5759     }
5760
5761   if (mode_is_set == 0)
5762     {
5763       errmsg ("Missing bond mode. ");
5764       return -99;
5765     }
5766
5767   /* Construct the API message */
5768   M (BOND_CREATE2, mp);
5769
5770   mp->use_custom_mac = custom_mac;
5771
5772   mp->mode = htonl (mode);
5773   mp->lb = htonl (lb);
5774   mp->id = htonl (id);
5775   mp->numa_only = numa_only;
5776   mp->enable_gso = gso;
5777
5778   if (custom_mac)
5779     clib_memcpy (mp->mac_address, mac_address, 6);
5780
5781   /* send it... */
5782   S (mp);
5783
5784   /* Wait for a reply... */
5785   W (ret);
5786   return ret;
5787 }
5788
5789 static int
5790 api_bond_delete (vat_main_t * vam)
5791 {
5792   unformat_input_t *i = vam->input;
5793   vl_api_bond_delete_t *mp;
5794   u32 sw_if_index = ~0;
5795   u8 sw_if_index_set = 0;
5796   int ret;
5797
5798   /* Parse args required to build the message */
5799   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5800     {
5801       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5802         sw_if_index_set = 1;
5803       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5804         sw_if_index_set = 1;
5805       else
5806         break;
5807     }
5808
5809   if (sw_if_index_set == 0)
5810     {
5811       errmsg ("missing vpp interface name. ");
5812       return -99;
5813     }
5814
5815   /* Construct the API message */
5816   M (BOND_DELETE, mp);
5817
5818   mp->sw_if_index = ntohl (sw_if_index);
5819
5820   /* send it... */
5821   S (mp);
5822
5823   /* Wait for a reply... */
5824   W (ret);
5825   return ret;
5826 }
5827
5828 static int
5829 api_bond_add_member (vat_main_t * vam)
5830 {
5831   unformat_input_t *i = vam->input;
5832   vl_api_bond_add_member_t *mp;
5833   u32 bond_sw_if_index;
5834   int ret;
5835   u8 is_passive;
5836   u8 is_long_timeout;
5837   u32 bond_sw_if_index_is_set = 0;
5838   u32 sw_if_index;
5839   u8 sw_if_index_is_set = 0;
5840
5841   /* Parse args required to build the message */
5842   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5843     {
5844       if (unformat (i, "sw_if_index %d", &sw_if_index))
5845         sw_if_index_is_set = 1;
5846       else if (unformat (i, "bond %u", &bond_sw_if_index))
5847         bond_sw_if_index_is_set = 1;
5848       else if (unformat (i, "passive %d", &is_passive))
5849         ;
5850       else if (unformat (i, "long-timeout %d", &is_long_timeout))
5851         ;
5852       else
5853         break;
5854     }
5855
5856   if (bond_sw_if_index_is_set == 0)
5857     {
5858       errmsg ("Missing bond sw_if_index. ");
5859       return -99;
5860     }
5861   if (sw_if_index_is_set == 0)
5862     {
5863       errmsg ("Missing member sw_if_index. ");
5864       return -99;
5865     }
5866
5867   /* Construct the API message */
5868   M (BOND_ADD_MEMBER, mp);
5869
5870   mp->bond_sw_if_index = ntohl (bond_sw_if_index);
5871   mp->sw_if_index = ntohl (sw_if_index);
5872   mp->is_long_timeout = is_long_timeout;
5873   mp->is_passive = is_passive;
5874
5875   /* send it... */
5876   S (mp);
5877
5878   /* Wait for a reply... */
5879   W (ret);
5880   return ret;
5881 }
5882
5883 static int
5884 api_bond_detach_member (vat_main_t * vam)
5885 {
5886   unformat_input_t *i = vam->input;
5887   vl_api_bond_detach_member_t *mp;
5888   u32 sw_if_index = ~0;
5889   u8 sw_if_index_set = 0;
5890   int ret;
5891
5892   /* Parse args required to build the message */
5893   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5894     {
5895       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5896         sw_if_index_set = 1;
5897       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5898         sw_if_index_set = 1;
5899       else
5900         break;
5901     }
5902
5903   if (sw_if_index_set == 0)
5904     {
5905       errmsg ("missing vpp interface name. ");
5906       return -99;
5907     }
5908
5909   /* Construct the API message */
5910   M (BOND_DETACH_MEMBER, mp);
5911
5912   mp->sw_if_index = ntohl (sw_if_index);
5913
5914   /* send it... */
5915   S (mp);
5916
5917   /* Wait for a reply... */
5918   W (ret);
5919   return ret;
5920 }
5921
5922 static int
5923 api_ip_table_add_del (vat_main_t * vam)
5924 {
5925   unformat_input_t *i = vam->input;
5926   vl_api_ip_table_add_del_t *mp;
5927   u32 table_id = ~0;
5928   u8 is_ipv6 = 0;
5929   u8 is_add = 1;
5930   int ret = 0;
5931
5932   /* Parse args required to build the message */
5933   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5934     {
5935       if (unformat (i, "ipv6"))
5936         is_ipv6 = 1;
5937       else if (unformat (i, "del"))
5938         is_add = 0;
5939       else if (unformat (i, "add"))
5940         is_add = 1;
5941       else if (unformat (i, "table %d", &table_id))
5942         ;
5943       else
5944         {
5945           clib_warning ("parse error '%U'", format_unformat_error, i);
5946           return -99;
5947         }
5948     }
5949
5950   if (~0 == table_id)
5951     {
5952       errmsg ("missing table-ID");
5953       return -99;
5954     }
5955
5956   /* Construct the API message */
5957   M (IP_TABLE_ADD_DEL, mp);
5958
5959   mp->table.table_id = ntohl (table_id);
5960   mp->table.is_ip6 = is_ipv6;
5961   mp->is_add = is_add;
5962
5963   /* send it... */
5964   S (mp);
5965
5966   /* Wait for a reply... */
5967   W (ret);
5968
5969   return ret;
5970 }
5971
5972 uword
5973 unformat_fib_path (unformat_input_t * input, va_list * args)
5974 {
5975   vat_main_t *vam = va_arg (*args, vat_main_t *);
5976   vl_api_fib_path_t *path = va_arg (*args, vl_api_fib_path_t *);
5977   u32 weight, preference;
5978   mpls_label_t out_label;
5979
5980   clib_memset (path, 0, sizeof (*path));
5981   path->weight = 1;
5982   path->sw_if_index = ~0;
5983   path->rpf_id = ~0;
5984   path->n_labels = 0;
5985
5986   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
5987     {
5988       if (unformat (input, "%U %U",
5989                     unformat_vl_api_ip4_address,
5990                     &path->nh.address.ip4,
5991                     api_unformat_sw_if_index, vam, &path->sw_if_index))
5992         {
5993           path->proto = FIB_API_PATH_NH_PROTO_IP4;
5994         }
5995       else if (unformat (input, "%U %U",
5996                          unformat_vl_api_ip6_address,
5997                          &path->nh.address.ip6,
5998                          api_unformat_sw_if_index, vam, &path->sw_if_index))
5999         {
6000           path->proto = FIB_API_PATH_NH_PROTO_IP6;
6001         }
6002       else if (unformat (input, "weight %u", &weight))
6003         {
6004           path->weight = weight;
6005         }
6006       else if (unformat (input, "preference %u", &preference))
6007         {
6008           path->preference = preference;
6009         }
6010       else if (unformat (input, "%U next-hop-table %d",
6011                          unformat_vl_api_ip4_address,
6012                          &path->nh.address.ip4, &path->table_id))
6013         {
6014           path->proto = FIB_API_PATH_NH_PROTO_IP4;
6015         }
6016       else if (unformat (input, "%U next-hop-table %d",
6017                          unformat_vl_api_ip6_address,
6018                          &path->nh.address.ip6, &path->table_id))
6019         {
6020           path->proto = FIB_API_PATH_NH_PROTO_IP6;
6021         }
6022       else if (unformat (input, "%U",
6023                          unformat_vl_api_ip4_address, &path->nh.address.ip4))
6024         {
6025           /*
6026            * the recursive next-hops are by default in the default table
6027            */
6028           path->table_id = 0;
6029           path->sw_if_index = ~0;
6030           path->proto = FIB_API_PATH_NH_PROTO_IP4;
6031         }
6032       else if (unformat (input, "%U",
6033                          unformat_vl_api_ip6_address, &path->nh.address.ip6))
6034         {
6035           /*
6036            * the recursive next-hops are by default in the default table
6037            */
6038           path->table_id = 0;
6039           path->sw_if_index = ~0;
6040           path->proto = FIB_API_PATH_NH_PROTO_IP6;
6041         }
6042       else if (unformat (input, "resolve-via-host"))
6043         {
6044           path->flags |= FIB_API_PATH_FLAG_RESOLVE_VIA_HOST;
6045         }
6046       else if (unformat (input, "resolve-via-attached"))
6047         {
6048           path->flags |= FIB_API_PATH_FLAG_RESOLVE_VIA_ATTACHED;
6049         }
6050       else if (unformat (input, "ip4-lookup-in-table %d", &path->table_id))
6051         {
6052           path->type = FIB_API_PATH_TYPE_LOCAL;
6053           path->sw_if_index = ~0;
6054           path->proto = FIB_API_PATH_NH_PROTO_IP4;
6055         }
6056       else if (unformat (input, "ip6-lookup-in-table %d", &path->table_id))
6057         {
6058           path->type = FIB_API_PATH_TYPE_LOCAL;
6059           path->sw_if_index = ~0;
6060           path->proto = FIB_API_PATH_NH_PROTO_IP6;
6061         }
6062       else if (unformat (input, "sw_if_index %d", &path->sw_if_index))
6063         ;
6064       else if (unformat (input, "via-label %d", &path->nh.via_label))
6065         {
6066           path->proto = FIB_API_PATH_NH_PROTO_MPLS;
6067           path->sw_if_index = ~0;
6068         }
6069       else if (unformat (input, "l2-input-on %d", &path->sw_if_index))
6070         {
6071           path->proto = FIB_API_PATH_NH_PROTO_ETHERNET;
6072           path->type = FIB_API_PATH_TYPE_INTERFACE_RX;
6073         }
6074       else if (unformat (input, "local"))
6075         {
6076           path->type = FIB_API_PATH_TYPE_LOCAL;
6077         }
6078       else if (unformat (input, "out-labels"))
6079         {
6080           while (unformat (input, "%d", &out_label))
6081             {
6082               path->label_stack[path->n_labels].label = out_label;
6083               path->label_stack[path->n_labels].is_uniform = 0;
6084               path->label_stack[path->n_labels].ttl = 64;
6085               path->n_labels++;
6086             }
6087         }
6088       else if (unformat (input, "via"))
6089         {
6090           /* new path, back up and return */
6091           unformat_put_input (input);
6092           unformat_put_input (input);
6093           unformat_put_input (input);
6094           unformat_put_input (input);
6095           break;
6096         }
6097       else
6098         {
6099           return (0);
6100         }
6101     }
6102
6103   path->proto = ntohl (path->proto);
6104   path->type = ntohl (path->type);
6105   path->flags = ntohl (path->flags);
6106   path->table_id = ntohl (path->table_id);
6107   path->sw_if_index = ntohl (path->sw_if_index);
6108
6109   return (1);
6110 }
6111
6112 static int
6113 api_ip_route_add_del (vat_main_t * vam)
6114 {
6115   unformat_input_t *i = vam->input;
6116   vl_api_ip_route_add_del_t *mp;
6117   u32 vrf_id = 0;
6118   u8 is_add = 1;
6119   u8 is_multipath = 0;
6120   u8 prefix_set = 0;
6121   u8 path_count = 0;
6122   vl_api_prefix_t pfx = { };
6123   vl_api_fib_path_t paths[8];
6124   int count = 1;
6125   int j;
6126   f64 before = 0;
6127   u32 random_add_del = 0;
6128   u32 *random_vector = 0;
6129   u32 random_seed = 0xdeaddabe;
6130
6131   /* Parse args required to build the message */
6132   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6133     {
6134       if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
6135         prefix_set = 1;
6136       else if (unformat (i, "del"))
6137         is_add = 0;
6138       else if (unformat (i, "add"))
6139         is_add = 1;
6140       else if (unformat (i, "vrf %d", &vrf_id))
6141         ;
6142       else if (unformat (i, "count %d", &count))
6143         ;
6144       else if (unformat (i, "random"))
6145         random_add_del = 1;
6146       else if (unformat (i, "multipath"))
6147         is_multipath = 1;
6148       else if (unformat (i, "seed %d", &random_seed))
6149         ;
6150       else
6151         if (unformat
6152             (i, "via %U", unformat_fib_path, vam, &paths[path_count]))
6153         {
6154           path_count++;
6155           if (8 == path_count)
6156             {
6157               errmsg ("max 8 paths");
6158               return -99;
6159             }
6160         }
6161       else
6162         {
6163           clib_warning ("parse error '%U'", format_unformat_error, i);
6164           return -99;
6165         }
6166     }
6167
6168   if (!path_count)
6169     {
6170       errmsg ("specify a path; via ...");
6171       return -99;
6172     }
6173   if (prefix_set == 0)
6174     {
6175       errmsg ("missing prefix");
6176       return -99;
6177     }
6178
6179   /* Generate a pile of unique, random routes */
6180   if (random_add_del)
6181     {
6182       ip4_address_t *i = (ip4_address_t *) & paths[0].nh.address.ip4;
6183       u32 this_random_address;
6184       uword *random_hash;
6185
6186       random_hash = hash_create (count, sizeof (uword));
6187
6188       hash_set (random_hash, i->as_u32, 1);
6189       for (j = 0; j <= count; j++)
6190         {
6191           do
6192             {
6193               this_random_address = random_u32 (&random_seed);
6194               this_random_address =
6195                 clib_host_to_net_u32 (this_random_address);
6196             }
6197           while (hash_get (random_hash, this_random_address));
6198           vec_add1 (random_vector, this_random_address);
6199           hash_set (random_hash, this_random_address, 1);
6200         }
6201       hash_free (random_hash);
6202       set_ip4_address (&pfx.address, random_vector[0]);
6203     }
6204
6205   if (count > 1)
6206     {
6207       /* Turn on async mode */
6208       vam->async_mode = 1;
6209       vam->async_errors = 0;
6210       before = vat_time_now (vam);
6211     }
6212
6213   for (j = 0; j < count; j++)
6214     {
6215       /* Construct the API message */
6216       M2 (IP_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t) * path_count);
6217
6218       mp->is_add = is_add;
6219       mp->is_multipath = is_multipath;
6220
6221       clib_memcpy (&mp->route.prefix, &pfx, sizeof (pfx));
6222       mp->route.table_id = ntohl (vrf_id);
6223       mp->route.n_paths = path_count;
6224
6225       clib_memcpy (&mp->route.paths, &paths, sizeof (paths[0]) * path_count);
6226
6227       if (random_add_del)
6228         set_ip4_address (&pfx.address, random_vector[j + 1]);
6229       else
6230         increment_address (&pfx.address);
6231       /* send it... */
6232       S (mp);
6233       /* If we receive SIGTERM, stop now... */
6234       if (vam->do_exit)
6235         break;
6236     }
6237
6238   /* When testing multiple add/del ops, use a control-ping to sync */
6239   if (count > 1)
6240     {
6241       vl_api_control_ping_t *mp_ping;
6242       f64 after;
6243       f64 timeout;
6244
6245       /* Shut off async mode */
6246       vam->async_mode = 0;
6247
6248       MPING (CONTROL_PING, mp_ping);
6249       S (mp_ping);
6250
6251       timeout = vat_time_now (vam) + 1.0;
6252       while (vat_time_now (vam) < timeout)
6253         if (vam->result_ready == 1)
6254           goto out;
6255       vam->retval = -99;
6256
6257     out:
6258       if (vam->retval == -99)
6259         errmsg ("timeout");
6260
6261       if (vam->async_errors > 0)
6262         {
6263           errmsg ("%d asynchronous errors", vam->async_errors);
6264           vam->retval = -98;
6265         }
6266       vam->async_errors = 0;
6267       after = vat_time_now (vam);
6268
6269       /* slim chance, but we might have eaten SIGTERM on the first iteration */
6270       if (j > 0)
6271         count = j;
6272
6273       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
6274              count, after - before, count / (after - before));
6275     }
6276   else
6277     {
6278       int ret;
6279
6280       /* Wait for a reply... */
6281       W (ret);
6282       return ret;
6283     }
6284
6285   /* Return the good/bad news */
6286   return (vam->retval);
6287 }
6288
6289 static int
6290 api_ip_mroute_add_del (vat_main_t * vam)
6291 {
6292   unformat_input_t *i = vam->input;
6293   u8 path_set = 0, prefix_set = 0, is_add = 1;
6294   vl_api_ip_mroute_add_del_t *mp;
6295   mfib_entry_flags_t eflags = 0;
6296   vl_api_mfib_path_t path;
6297   vl_api_mprefix_t pfx = { };
6298   u32 vrf_id = 0;
6299   int ret;
6300
6301   /* Parse args required to build the message */
6302   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6303     {
6304       if (unformat (i, "%U", unformat_vl_api_mprefix, &pfx))
6305         {
6306           prefix_set = 1;
6307           pfx.grp_address_length = htons (pfx.grp_address_length);
6308         }
6309       else if (unformat (i, "del"))
6310         is_add = 0;
6311       else if (unformat (i, "add"))
6312         is_add = 1;
6313       else if (unformat (i, "vrf %d", &vrf_id))
6314         ;
6315       else if (unformat (i, "%U", unformat_mfib_itf_flags, &path.itf_flags))
6316         path.itf_flags = htonl (path.itf_flags);
6317       else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
6318         ;
6319       else if (unformat (i, "via %U", unformat_fib_path, vam, &path.path))
6320         path_set = 1;
6321       else
6322         {
6323           clib_warning ("parse error '%U'", format_unformat_error, i);
6324           return -99;
6325         }
6326     }
6327
6328   if (prefix_set == 0)
6329     {
6330       errmsg ("missing addresses\n");
6331       return -99;
6332     }
6333   if (path_set == 0)
6334     {
6335       errmsg ("missing path\n");
6336       return -99;
6337     }
6338
6339   /* Construct the API message */
6340   M (IP_MROUTE_ADD_DEL, mp);
6341
6342   mp->is_add = is_add;
6343   mp->is_multipath = 1;
6344
6345   clib_memcpy (&mp->route.prefix, &pfx, sizeof (pfx));
6346   mp->route.table_id = htonl (vrf_id);
6347   mp->route.n_paths = 1;
6348   mp->route.entry_flags = htonl (eflags);
6349
6350   clib_memcpy (&mp->route.paths, &path, sizeof (path));
6351
6352   /* send it... */
6353   S (mp);
6354   /* Wait for a reply... */
6355   W (ret);
6356   return ret;
6357 }
6358
6359 static int
6360 api_mpls_table_add_del (vat_main_t * vam)
6361 {
6362   unformat_input_t *i = vam->input;
6363   vl_api_mpls_table_add_del_t *mp;
6364   u32 table_id = ~0;
6365   u8 is_add = 1;
6366   int ret = 0;
6367
6368   /* Parse args required to build the message */
6369   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6370     {
6371       if (unformat (i, "table %d", &table_id))
6372         ;
6373       else if (unformat (i, "del"))
6374         is_add = 0;
6375       else if (unformat (i, "add"))
6376         is_add = 1;
6377       else
6378         {
6379           clib_warning ("parse error '%U'", format_unformat_error, i);
6380           return -99;
6381         }
6382     }
6383
6384   if (~0 == table_id)
6385     {
6386       errmsg ("missing table-ID");
6387       return -99;
6388     }
6389
6390   /* Construct the API message */
6391   M (MPLS_TABLE_ADD_DEL, mp);
6392
6393   mp->mt_table.mt_table_id = ntohl (table_id);
6394   mp->mt_is_add = is_add;
6395
6396   /* send it... */
6397   S (mp);
6398
6399   /* Wait for a reply... */
6400   W (ret);
6401
6402   return ret;
6403 }
6404
6405 static int
6406 api_mpls_route_add_del (vat_main_t * vam)
6407 {
6408   u8 is_add = 1, path_count = 0, is_multipath = 0, is_eos = 0;
6409   mpls_label_t local_label = MPLS_LABEL_INVALID;
6410   unformat_input_t *i = vam->input;
6411   vl_api_mpls_route_add_del_t *mp;
6412   vl_api_fib_path_t paths[8];
6413   int count = 1, j;
6414   f64 before = 0;
6415
6416   /* Parse args required to build the message */
6417   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6418     {
6419       if (unformat (i, "%d", &local_label))
6420         ;
6421       else if (unformat (i, "eos"))
6422         is_eos = 1;
6423       else if (unformat (i, "non-eos"))
6424         is_eos = 0;
6425       else if (unformat (i, "del"))
6426         is_add = 0;
6427       else if (unformat (i, "add"))
6428         is_add = 1;
6429       else if (unformat (i, "multipath"))
6430         is_multipath = 1;
6431       else if (unformat (i, "count %d", &count))
6432         ;
6433       else
6434         if (unformat
6435             (i, "via %U", unformat_fib_path, vam, &paths[path_count]))
6436         {
6437           path_count++;
6438           if (8 == path_count)
6439             {
6440               errmsg ("max 8 paths");
6441               return -99;
6442             }
6443         }
6444       else
6445         {
6446           clib_warning ("parse error '%U'", format_unformat_error, i);
6447           return -99;
6448         }
6449     }
6450
6451   if (!path_count)
6452     {
6453       errmsg ("specify a path; via ...");
6454       return -99;
6455     }
6456
6457   if (MPLS_LABEL_INVALID == local_label)
6458     {
6459       errmsg ("missing label");
6460       return -99;
6461     }
6462
6463   if (count > 1)
6464     {
6465       /* Turn on async mode */
6466       vam->async_mode = 1;
6467       vam->async_errors = 0;
6468       before = vat_time_now (vam);
6469     }
6470
6471   for (j = 0; j < count; j++)
6472     {
6473       /* Construct the API message */
6474       M2 (MPLS_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t) * path_count);
6475
6476       mp->mr_is_add = is_add;
6477       mp->mr_is_multipath = is_multipath;
6478
6479       mp->mr_route.mr_label = local_label;
6480       mp->mr_route.mr_eos = is_eos;
6481       mp->mr_route.mr_table_id = 0;
6482       mp->mr_route.mr_n_paths = path_count;
6483
6484       clib_memcpy (&mp->mr_route.mr_paths, paths,
6485                    sizeof (paths[0]) * path_count);
6486
6487       local_label++;
6488
6489       /* send it... */
6490       S (mp);
6491       /* If we receive SIGTERM, stop now... */
6492       if (vam->do_exit)
6493         break;
6494     }
6495
6496   /* When testing multiple add/del ops, use a control-ping to sync */
6497   if (count > 1)
6498     {
6499       vl_api_control_ping_t *mp_ping;
6500       f64 after;
6501       f64 timeout;
6502
6503       /* Shut off async mode */
6504       vam->async_mode = 0;
6505
6506       MPING (CONTROL_PING, mp_ping);
6507       S (mp_ping);
6508
6509       timeout = vat_time_now (vam) + 1.0;
6510       while (vat_time_now (vam) < timeout)
6511         if (vam->result_ready == 1)
6512           goto out;
6513       vam->retval = -99;
6514
6515     out:
6516       if (vam->retval == -99)
6517         errmsg ("timeout");
6518
6519       if (vam->async_errors > 0)
6520         {
6521           errmsg ("%d asynchronous errors", vam->async_errors);
6522           vam->retval = -98;
6523         }
6524       vam->async_errors = 0;
6525       after = vat_time_now (vam);
6526
6527       /* slim chance, but we might have eaten SIGTERM on the first iteration */
6528       if (j > 0)
6529         count = j;
6530
6531       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
6532              count, after - before, count / (after - before));
6533     }
6534   else
6535     {
6536       int ret;
6537
6538       /* Wait for a reply... */
6539       W (ret);
6540       return ret;
6541     }
6542
6543   /* Return the good/bad news */
6544   return (vam->retval);
6545   return (0);
6546 }
6547
6548 static int
6549 api_mpls_ip_bind_unbind (vat_main_t * vam)
6550 {
6551   unformat_input_t *i = vam->input;
6552   vl_api_mpls_ip_bind_unbind_t *mp;
6553   u32 ip_table_id = 0;
6554   u8 is_bind = 1;
6555   vl_api_prefix_t pfx;
6556   u8 prefix_set = 0;
6557   mpls_label_t local_label = MPLS_LABEL_INVALID;
6558   int ret;
6559
6560   /* Parse args required to build the message */
6561   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6562     {
6563       if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
6564         prefix_set = 1;
6565       else if (unformat (i, "%d", &local_label))
6566         ;
6567       else if (unformat (i, "table-id %d", &ip_table_id))
6568         ;
6569       else if (unformat (i, "unbind"))
6570         is_bind = 0;
6571       else if (unformat (i, "bind"))
6572         is_bind = 1;
6573       else
6574         {
6575           clib_warning ("parse error '%U'", format_unformat_error, i);
6576           return -99;
6577         }
6578     }
6579
6580   if (!prefix_set)
6581     {
6582       errmsg ("IP prefix not set");
6583       return -99;
6584     }
6585
6586   if (MPLS_LABEL_INVALID == local_label)
6587     {
6588       errmsg ("missing label");
6589       return -99;
6590     }
6591
6592   /* Construct the API message */
6593   M (MPLS_IP_BIND_UNBIND, mp);
6594
6595   mp->mb_is_bind = is_bind;
6596   mp->mb_ip_table_id = ntohl (ip_table_id);
6597   mp->mb_mpls_table_id = 0;
6598   mp->mb_label = ntohl (local_label);
6599   clib_memcpy (&mp->mb_prefix, &pfx, sizeof (pfx));
6600
6601   /* send it... */
6602   S (mp);
6603
6604   /* Wait for a reply... */
6605   W (ret);
6606   return ret;
6607   return (0);
6608 }
6609
6610 static int
6611 api_sr_mpls_policy_add (vat_main_t * vam)
6612 {
6613   unformat_input_t *i = vam->input;
6614   vl_api_sr_mpls_policy_add_t *mp;
6615   u32 bsid = 0;
6616   u32 weight = 1;
6617   u8 type = 0;
6618   u8 n_segments = 0;
6619   u32 sid;
6620   u32 *segments = NULL;
6621   int ret;
6622
6623   /* Parse args required to build the message */
6624   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6625     {
6626       if (unformat (i, "bsid %d", &bsid))
6627         ;
6628       else if (unformat (i, "weight %d", &weight))
6629         ;
6630       else if (unformat (i, "spray"))
6631         type = 1;
6632       else if (unformat (i, "next %d", &sid))
6633         {
6634           n_segments += 1;
6635           vec_add1 (segments, htonl (sid));
6636         }
6637       else
6638         {
6639           clib_warning ("parse error '%U'", format_unformat_error, i);
6640           return -99;
6641         }
6642     }
6643
6644   if (bsid == 0)
6645     {
6646       errmsg ("bsid not set");
6647       return -99;
6648     }
6649
6650   if (n_segments == 0)
6651     {
6652       errmsg ("no sid in segment stack");
6653       return -99;
6654     }
6655
6656   /* Construct the API message */
6657   M2 (SR_MPLS_POLICY_ADD, mp, sizeof (u32) * n_segments);
6658
6659   mp->bsid = htonl (bsid);
6660   mp->weight = htonl (weight);
6661   mp->is_spray = type;
6662   mp->n_segments = n_segments;
6663   memcpy (mp->segments, segments, sizeof (u32) * n_segments);
6664   vec_free (segments);
6665
6666   /* send it... */
6667   S (mp);
6668
6669   /* Wait for a reply... */
6670   W (ret);
6671   return ret;
6672 }
6673
6674 static int
6675 api_sr_mpls_policy_del (vat_main_t * vam)
6676 {
6677   unformat_input_t *i = vam->input;
6678   vl_api_sr_mpls_policy_del_t *mp;
6679   u32 bsid = 0;
6680   int ret;
6681
6682   /* Parse args required to build the message */
6683   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6684     {
6685       if (unformat (i, "bsid %d", &bsid))
6686         ;
6687       else
6688         {
6689           clib_warning ("parse error '%U'", format_unformat_error, i);
6690           return -99;
6691         }
6692     }
6693
6694   if (bsid == 0)
6695     {
6696       errmsg ("bsid not set");
6697       return -99;
6698     }
6699
6700   /* Construct the API message */
6701   M (SR_MPLS_POLICY_DEL, mp);
6702
6703   mp->bsid = htonl (bsid);
6704
6705   /* send it... */
6706   S (mp);
6707
6708   /* Wait for a reply... */
6709   W (ret);
6710   return ret;
6711 }
6712
6713 static int
6714 api_bier_table_add_del (vat_main_t * vam)
6715 {
6716   unformat_input_t *i = vam->input;
6717   vl_api_bier_table_add_del_t *mp;
6718   u8 is_add = 1;
6719   u32 set = 0, sub_domain = 0, hdr_len = 3;
6720   mpls_label_t local_label = MPLS_LABEL_INVALID;
6721   int ret;
6722
6723   /* Parse args required to build the message */
6724   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6725     {
6726       if (unformat (i, "sub-domain %d", &sub_domain))
6727         ;
6728       else if (unformat (i, "set %d", &set))
6729         ;
6730       else if (unformat (i, "label %d", &local_label))
6731         ;
6732       else if (unformat (i, "hdr-len %d", &hdr_len))
6733         ;
6734       else if (unformat (i, "add"))
6735         is_add = 1;
6736       else if (unformat (i, "del"))
6737         is_add = 0;
6738       else
6739         {
6740           clib_warning ("parse error '%U'", format_unformat_error, i);
6741           return -99;
6742         }
6743     }
6744
6745   if (MPLS_LABEL_INVALID == local_label)
6746     {
6747       errmsg ("missing label\n");
6748       return -99;
6749     }
6750
6751   /* Construct the API message */
6752   M (BIER_TABLE_ADD_DEL, mp);
6753
6754   mp->bt_is_add = is_add;
6755   mp->bt_label = ntohl (local_label);
6756   mp->bt_tbl_id.bt_set = set;
6757   mp->bt_tbl_id.bt_sub_domain = sub_domain;
6758   mp->bt_tbl_id.bt_hdr_len_id = hdr_len;
6759
6760   /* send it... */
6761   S (mp);
6762
6763   /* Wait for a reply... */
6764   W (ret);
6765
6766   return (ret);
6767 }
6768
6769 static int
6770 api_bier_route_add_del (vat_main_t * vam)
6771 {
6772   unformat_input_t *i = vam->input;
6773   vl_api_bier_route_add_del_t *mp;
6774   u8 is_add = 1;
6775   u32 set = 0, sub_domain = 0, hdr_len = 3, bp = 0;
6776   ip4_address_t v4_next_hop_address;
6777   ip6_address_t v6_next_hop_address;
6778   u8 next_hop_set = 0;
6779   u8 next_hop_proto_is_ip4 = 1;
6780   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
6781   int ret;
6782
6783   /* Parse args required to build the message */
6784   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6785     {
6786       if (unformat (i, "%U", unformat_ip4_address, &v4_next_hop_address))
6787         {
6788           next_hop_proto_is_ip4 = 1;
6789           next_hop_set = 1;
6790         }
6791       else if (unformat (i, "%U", unformat_ip6_address, &v6_next_hop_address))
6792         {
6793           next_hop_proto_is_ip4 = 0;
6794           next_hop_set = 1;
6795         }
6796       if (unformat (i, "sub-domain %d", &sub_domain))
6797         ;
6798       else if (unformat (i, "set %d", &set))
6799         ;
6800       else if (unformat (i, "hdr-len %d", &hdr_len))
6801         ;
6802       else if (unformat (i, "bp %d", &bp))
6803         ;
6804       else if (unformat (i, "add"))
6805         is_add = 1;
6806       else if (unformat (i, "del"))
6807         is_add = 0;
6808       else if (unformat (i, "out-label %d", &next_hop_out_label))
6809         ;
6810       else
6811         {
6812           clib_warning ("parse error '%U'", format_unformat_error, i);
6813           return -99;
6814         }
6815     }
6816
6817   if (!next_hop_set || (MPLS_LABEL_INVALID == next_hop_out_label))
6818     {
6819       errmsg ("next hop / label set\n");
6820       return -99;
6821     }
6822   if (0 == bp)
6823     {
6824       errmsg ("bit=position not set\n");
6825       return -99;
6826     }
6827
6828   /* Construct the API message */
6829   M2 (BIER_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t));
6830
6831   mp->br_is_add = is_add;
6832   mp->br_route.br_tbl_id.bt_set = set;
6833   mp->br_route.br_tbl_id.bt_sub_domain = sub_domain;
6834   mp->br_route.br_tbl_id.bt_hdr_len_id = hdr_len;
6835   mp->br_route.br_bp = ntohs (bp);
6836   mp->br_route.br_n_paths = 1;
6837   mp->br_route.br_paths[0].n_labels = 1;
6838   mp->br_route.br_paths[0].label_stack[0].label = ntohl (next_hop_out_label);
6839   mp->br_route.br_paths[0].proto = (next_hop_proto_is_ip4 ?
6840                                     FIB_API_PATH_NH_PROTO_IP4 :
6841                                     FIB_API_PATH_NH_PROTO_IP6);
6842
6843   if (next_hop_proto_is_ip4)
6844     {
6845       clib_memcpy (&mp->br_route.br_paths[0].nh.address.ip4,
6846                    &v4_next_hop_address, sizeof (v4_next_hop_address));
6847     }
6848   else
6849     {
6850       clib_memcpy (&mp->br_route.br_paths[0].nh.address.ip6,
6851                    &v6_next_hop_address, sizeof (v6_next_hop_address));
6852     }
6853
6854   /* send it... */
6855   S (mp);
6856
6857   /* Wait for a reply... */
6858   W (ret);
6859
6860   return (ret);
6861 }
6862
6863 static int
6864 api_mpls_tunnel_add_del (vat_main_t * vam)
6865 {
6866   unformat_input_t *i = vam->input;
6867   vl_api_mpls_tunnel_add_del_t *mp;
6868
6869   vl_api_fib_path_t paths[8];
6870   u32 sw_if_index = ~0;
6871   u8 path_count = 0;
6872   u8 l2_only = 0;
6873   u8 is_add = 1;
6874   int ret;
6875
6876   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6877     {
6878       if (unformat (i, "add"))
6879         is_add = 1;
6880       else
6881         if (unformat
6882             (i, "del %U", api_unformat_sw_if_index, vam, &sw_if_index))
6883         is_add = 0;
6884       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
6885         is_add = 0;
6886       else if (unformat (i, "l2-only"))
6887         l2_only = 1;
6888       else
6889         if (unformat
6890             (i, "via %U", unformat_fib_path, vam, &paths[path_count]))
6891         {
6892           path_count++;
6893           if (8 == path_count)
6894             {
6895               errmsg ("max 8 paths");
6896               return -99;
6897             }
6898         }
6899       else
6900         {
6901           clib_warning ("parse error '%U'", format_unformat_error, i);
6902           return -99;
6903         }
6904     }
6905
6906   M2 (MPLS_TUNNEL_ADD_DEL, mp, sizeof (vl_api_fib_path_t) * path_count);
6907
6908   mp->mt_is_add = is_add;
6909   mp->mt_tunnel.mt_sw_if_index = ntohl (sw_if_index);
6910   mp->mt_tunnel.mt_l2_only = l2_only;
6911   mp->mt_tunnel.mt_is_multicast = 0;
6912   mp->mt_tunnel.mt_n_paths = path_count;
6913
6914   clib_memcpy (&mp->mt_tunnel.mt_paths, &paths,
6915                sizeof (paths[0]) * path_count);
6916
6917   S (mp);
6918   W (ret);
6919   return ret;
6920 }
6921
6922 static int
6923 api_sw_interface_set_unnumbered (vat_main_t * vam)
6924 {
6925   unformat_input_t *i = vam->input;
6926   vl_api_sw_interface_set_unnumbered_t *mp;
6927   u32 sw_if_index;
6928   u32 unnum_sw_index = ~0;
6929   u8 is_add = 1;
6930   u8 sw_if_index_set = 0;
6931   int ret;
6932
6933   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6934     {
6935       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6936         sw_if_index_set = 1;
6937       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6938         sw_if_index_set = 1;
6939       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
6940         ;
6941       else if (unformat (i, "del"))
6942         is_add = 0;
6943       else
6944         {
6945           clib_warning ("parse error '%U'", format_unformat_error, i);
6946           return -99;
6947         }
6948     }
6949
6950   if (sw_if_index_set == 0)
6951     {
6952       errmsg ("missing interface name or sw_if_index");
6953       return -99;
6954     }
6955
6956   M (SW_INTERFACE_SET_UNNUMBERED, mp);
6957
6958   mp->sw_if_index = ntohl (sw_if_index);
6959   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
6960   mp->is_add = is_add;
6961
6962   S (mp);
6963   W (ret);
6964   return ret;
6965 }
6966
6967
6968 static int
6969 api_create_vlan_subif (vat_main_t * vam)
6970 {
6971   unformat_input_t *i = vam->input;
6972   vl_api_create_vlan_subif_t *mp;
6973   u32 sw_if_index;
6974   u8 sw_if_index_set = 0;
6975   u32 vlan_id;
6976   u8 vlan_id_set = 0;
6977   int ret;
6978
6979   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6980     {
6981       if (unformat (i, "sw_if_index %d", &sw_if_index))
6982         sw_if_index_set = 1;
6983       else
6984         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6985         sw_if_index_set = 1;
6986       else if (unformat (i, "vlan %d", &vlan_id))
6987         vlan_id_set = 1;
6988       else
6989         {
6990           clib_warning ("parse error '%U'", format_unformat_error, i);
6991           return -99;
6992         }
6993     }
6994
6995   if (sw_if_index_set == 0)
6996     {
6997       errmsg ("missing interface name or sw_if_index");
6998       return -99;
6999     }
7000
7001   if (vlan_id_set == 0)
7002     {
7003       errmsg ("missing vlan_id");
7004       return -99;
7005     }
7006   M (CREATE_VLAN_SUBIF, mp);
7007
7008   mp->sw_if_index = ntohl (sw_if_index);
7009   mp->vlan_id = ntohl (vlan_id);
7010
7011   S (mp);
7012   W (ret);
7013   return ret;
7014 }
7015
7016 #define foreach_create_subif_bit                \
7017 _(no_tags)                                      \
7018 _(one_tag)                                      \
7019 _(two_tags)                                     \
7020 _(dot1ad)                                       \
7021 _(exact_match)                                  \
7022 _(default_sub)                                  \
7023 _(outer_vlan_id_any)                            \
7024 _(inner_vlan_id_any)
7025
7026 #define foreach_create_subif_flag               \
7027 _(0, "no_tags")                                 \
7028 _(1, "one_tag")                                 \
7029 _(2, "two_tags")                                \
7030 _(3, "dot1ad")                                  \
7031 _(4, "exact_match")                             \
7032 _(5, "default_sub")                             \
7033 _(6, "outer_vlan_id_any")                       \
7034 _(7, "inner_vlan_id_any")
7035
7036 static int
7037 api_create_subif (vat_main_t * vam)
7038 {
7039   unformat_input_t *i = vam->input;
7040   vl_api_create_subif_t *mp;
7041   u32 sw_if_index;
7042   u8 sw_if_index_set = 0;
7043   u32 sub_id;
7044   u8 sub_id_set = 0;
7045   u32 __attribute__ ((unused)) no_tags = 0;
7046   u32 __attribute__ ((unused)) one_tag = 0;
7047   u32 __attribute__ ((unused)) two_tags = 0;
7048   u32 __attribute__ ((unused)) dot1ad = 0;
7049   u32 __attribute__ ((unused)) exact_match = 0;
7050   u32 __attribute__ ((unused)) default_sub = 0;
7051   u32 __attribute__ ((unused)) outer_vlan_id_any = 0;
7052   u32 __attribute__ ((unused)) inner_vlan_id_any = 0;
7053   u32 tmp;
7054   u16 outer_vlan_id = 0;
7055   u16 inner_vlan_id = 0;
7056   int ret;
7057
7058   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7059     {
7060       if (unformat (i, "sw_if_index %d", &sw_if_index))
7061         sw_if_index_set = 1;
7062       else
7063         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7064         sw_if_index_set = 1;
7065       else if (unformat (i, "sub_id %d", &sub_id))
7066         sub_id_set = 1;
7067       else if (unformat (i, "outer_vlan_id %d", &tmp))
7068         outer_vlan_id = tmp;
7069       else if (unformat (i, "inner_vlan_id %d", &tmp))
7070         inner_vlan_id = tmp;
7071
7072 #define _(a) else if (unformat (i, #a)) a = 1 ;
7073       foreach_create_subif_bit
7074 #undef _
7075         else
7076         {
7077           clib_warning ("parse error '%U'", format_unformat_error, i);
7078           return -99;
7079         }
7080     }
7081
7082   if (sw_if_index_set == 0)
7083     {
7084       errmsg ("missing interface name or sw_if_index");
7085       return -99;
7086     }
7087
7088   if (sub_id_set == 0)
7089     {
7090       errmsg ("missing sub_id");
7091       return -99;
7092     }
7093   M (CREATE_SUBIF, mp);
7094
7095   mp->sw_if_index = ntohl (sw_if_index);
7096   mp->sub_id = ntohl (sub_id);
7097
7098 #define _(a,b) mp->sub_if_flags |= (1 << a);
7099   foreach_create_subif_flag;
7100 #undef _
7101
7102   mp->outer_vlan_id = ntohs (outer_vlan_id);
7103   mp->inner_vlan_id = ntohs (inner_vlan_id);
7104
7105   S (mp);
7106   W (ret);
7107   return ret;
7108 }
7109
7110 static int
7111 api_ip_table_replace_begin (vat_main_t * vam)
7112 {
7113   unformat_input_t *i = vam->input;
7114   vl_api_ip_table_replace_begin_t *mp;
7115   u32 table_id = 0;
7116   u8 is_ipv6 = 0;
7117
7118   int ret;
7119   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7120     {
7121       if (unformat (i, "table %d", &table_id))
7122         ;
7123       else if (unformat (i, "ipv6"))
7124         is_ipv6 = 1;
7125       else
7126         {
7127           clib_warning ("parse error '%U'", format_unformat_error, i);
7128           return -99;
7129         }
7130     }
7131
7132   M (IP_TABLE_REPLACE_BEGIN, mp);
7133
7134   mp->table.table_id = ntohl (table_id);
7135   mp->table.is_ip6 = is_ipv6;
7136
7137   S (mp);
7138   W (ret);
7139   return ret;
7140 }
7141
7142 static int
7143 api_ip_table_flush (vat_main_t * vam)
7144 {
7145   unformat_input_t *i = vam->input;
7146   vl_api_ip_table_flush_t *mp;
7147   u32 table_id = 0;
7148   u8 is_ipv6 = 0;
7149
7150   int ret;
7151   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7152     {
7153       if (unformat (i, "table %d", &table_id))
7154         ;
7155       else if (unformat (i, "ipv6"))
7156         is_ipv6 = 1;
7157       else
7158         {
7159           clib_warning ("parse error '%U'", format_unformat_error, i);
7160           return -99;
7161         }
7162     }
7163
7164   M (IP_TABLE_FLUSH, mp);
7165
7166   mp->table.table_id = ntohl (table_id);
7167   mp->table.is_ip6 = is_ipv6;
7168
7169   S (mp);
7170   W (ret);
7171   return ret;
7172 }
7173
7174 static int
7175 api_ip_table_replace_end (vat_main_t * vam)
7176 {
7177   unformat_input_t *i = vam->input;
7178   vl_api_ip_table_replace_end_t *mp;
7179   u32 table_id = 0;
7180   u8 is_ipv6 = 0;
7181
7182   int ret;
7183   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7184     {
7185       if (unformat (i, "table %d", &table_id))
7186         ;
7187       else if (unformat (i, "ipv6"))
7188         is_ipv6 = 1;
7189       else
7190         {
7191           clib_warning ("parse error '%U'", format_unformat_error, i);
7192           return -99;
7193         }
7194     }
7195
7196   M (IP_TABLE_REPLACE_END, mp);
7197
7198   mp->table.table_id = ntohl (table_id);
7199   mp->table.is_ip6 = is_ipv6;
7200
7201   S (mp);
7202   W (ret);
7203   return ret;
7204 }
7205
7206 static int
7207 api_set_ip_flow_hash (vat_main_t * vam)
7208 {
7209   unformat_input_t *i = vam->input;
7210   vl_api_set_ip_flow_hash_t *mp;
7211   u32 vrf_id = 0;
7212   u8 is_ipv6 = 0;
7213   u8 vrf_id_set = 0;
7214   u8 src = 0;
7215   u8 dst = 0;
7216   u8 sport = 0;
7217   u8 dport = 0;
7218   u8 proto = 0;
7219   u8 reverse = 0;
7220   int ret;
7221
7222   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7223     {
7224       if (unformat (i, "vrf %d", &vrf_id))
7225         vrf_id_set = 1;
7226       else if (unformat (i, "ipv6"))
7227         is_ipv6 = 1;
7228       else if (unformat (i, "src"))
7229         src = 1;
7230       else if (unformat (i, "dst"))
7231         dst = 1;
7232       else if (unformat (i, "sport"))
7233         sport = 1;
7234       else if (unformat (i, "dport"))
7235         dport = 1;
7236       else if (unformat (i, "proto"))
7237         proto = 1;
7238       else if (unformat (i, "reverse"))
7239         reverse = 1;
7240
7241       else
7242         {
7243           clib_warning ("parse error '%U'", format_unformat_error, i);
7244           return -99;
7245         }
7246     }
7247
7248   if (vrf_id_set == 0)
7249     {
7250       errmsg ("missing vrf id");
7251       return -99;
7252     }
7253
7254   M (SET_IP_FLOW_HASH, mp);
7255   mp->src = src;
7256   mp->dst = dst;
7257   mp->sport = sport;
7258   mp->dport = dport;
7259   mp->proto = proto;
7260   mp->reverse = reverse;
7261   mp->vrf_id = ntohl (vrf_id);
7262   mp->is_ipv6 = is_ipv6;
7263
7264   S (mp);
7265   W (ret);
7266   return ret;
7267 }
7268
7269 static int
7270 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
7271 {
7272   unformat_input_t *i = vam->input;
7273   vl_api_sw_interface_ip6_enable_disable_t *mp;
7274   u32 sw_if_index;
7275   u8 sw_if_index_set = 0;
7276   u8 enable = 0;
7277   int ret;
7278
7279   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7280     {
7281       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7282         sw_if_index_set = 1;
7283       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7284         sw_if_index_set = 1;
7285       else if (unformat (i, "enable"))
7286         enable = 1;
7287       else if (unformat (i, "disable"))
7288         enable = 0;
7289       else
7290         {
7291           clib_warning ("parse error '%U'", format_unformat_error, i);
7292           return -99;
7293         }
7294     }
7295
7296   if (sw_if_index_set == 0)
7297     {
7298       errmsg ("missing interface name or sw_if_index");
7299       return -99;
7300     }
7301
7302   M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
7303
7304   mp->sw_if_index = ntohl (sw_if_index);
7305   mp->enable = enable;
7306
7307   S (mp);
7308   W (ret);
7309   return ret;
7310 }
7311
7312
7313 static int
7314 api_l2_patch_add_del (vat_main_t * vam)
7315 {
7316   unformat_input_t *i = vam->input;
7317   vl_api_l2_patch_add_del_t *mp;
7318   u32 rx_sw_if_index;
7319   u8 rx_sw_if_index_set = 0;
7320   u32 tx_sw_if_index;
7321   u8 tx_sw_if_index_set = 0;
7322   u8 is_add = 1;
7323   int ret;
7324
7325   /* Parse args required to build the message */
7326   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7327     {
7328       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
7329         rx_sw_if_index_set = 1;
7330       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
7331         tx_sw_if_index_set = 1;
7332       else if (unformat (i, "rx"))
7333         {
7334           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7335             {
7336               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
7337                             &rx_sw_if_index))
7338                 rx_sw_if_index_set = 1;
7339             }
7340           else
7341             break;
7342         }
7343       else if (unformat (i, "tx"))
7344         {
7345           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7346             {
7347               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
7348                             &tx_sw_if_index))
7349                 tx_sw_if_index_set = 1;
7350             }
7351           else
7352             break;
7353         }
7354       else if (unformat (i, "del"))
7355         is_add = 0;
7356       else
7357         break;
7358     }
7359
7360   if (rx_sw_if_index_set == 0)
7361     {
7362       errmsg ("missing rx interface name or rx_sw_if_index");
7363       return -99;
7364     }
7365
7366   if (tx_sw_if_index_set == 0)
7367     {
7368       errmsg ("missing tx interface name or tx_sw_if_index");
7369       return -99;
7370     }
7371
7372   M (L2_PATCH_ADD_DEL, mp);
7373
7374   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
7375   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
7376   mp->is_add = is_add;
7377
7378   S (mp);
7379   W (ret);
7380   return ret;
7381 }
7382
7383 u8 is_del;
7384 u8 localsid_addr[16];
7385 u8 end_psp;
7386 u8 behavior;
7387 u32 sw_if_index;
7388 u32 vlan_index;
7389 u32 fib_table;
7390 u8 nh_addr[16];
7391
7392 static int
7393 api_sr_localsid_add_del (vat_main_t * vam)
7394 {
7395   unformat_input_t *i = vam->input;
7396   vl_api_sr_localsid_add_del_t *mp;
7397
7398   u8 is_del;
7399   ip6_address_t localsid;
7400   u8 end_psp = 0;
7401   u8 behavior = ~0;
7402   u32 sw_if_index;
7403   u32 fib_table = ~(u32) 0;
7404   ip46_address_t nh_addr;
7405   clib_memset (&nh_addr, 0, sizeof (ip46_address_t));
7406
7407   bool nexthop_set = 0;
7408
7409   int ret;
7410
7411   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7412     {
7413       if (unformat (i, "del"))
7414         is_del = 1;
7415       else if (unformat (i, "address %U", unformat_ip6_address, &localsid));
7416       else if (unformat (i, "next-hop %U", unformat_ip46_address, &nh_addr))
7417         nexthop_set = 1;
7418       else if (unformat (i, "behavior %u", &behavior));
7419       else if (unformat (i, "sw_if_index %u", &sw_if_index));
7420       else if (unformat (i, "fib-table %u", &fib_table));
7421       else if (unformat (i, "end.psp %u", &behavior));
7422       else
7423         break;
7424     }
7425
7426   M (SR_LOCALSID_ADD_DEL, mp);
7427
7428   clib_memcpy (mp->localsid, &localsid, sizeof (mp->localsid));
7429
7430   if (nexthop_set)
7431     {
7432       clib_memcpy (&mp->nh_addr.un, &nh_addr, sizeof (mp->nh_addr.un));
7433     }
7434   mp->behavior = behavior;
7435   mp->sw_if_index = ntohl (sw_if_index);
7436   mp->fib_table = ntohl (fib_table);
7437   mp->end_psp = end_psp;
7438   mp->is_del = is_del;
7439
7440   S (mp);
7441   W (ret);
7442   return ret;
7443 }
7444
7445 static int
7446 api_ioam_enable (vat_main_t * vam)
7447 {
7448   unformat_input_t *input = vam->input;
7449   vl_api_ioam_enable_t *mp;
7450   u32 id = 0;
7451   int has_trace_option = 0;
7452   int has_pot_option = 0;
7453   int has_seqno_option = 0;
7454   int has_analyse_option = 0;
7455   int ret;
7456
7457   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7458     {
7459       if (unformat (input, "trace"))
7460         has_trace_option = 1;
7461       else if (unformat (input, "pot"))
7462         has_pot_option = 1;
7463       else if (unformat (input, "seqno"))
7464         has_seqno_option = 1;
7465       else if (unformat (input, "analyse"))
7466         has_analyse_option = 1;
7467       else
7468         break;
7469     }
7470   M (IOAM_ENABLE, mp);
7471   mp->id = htons (id);
7472   mp->seqno = has_seqno_option;
7473   mp->analyse = has_analyse_option;
7474   mp->pot_enable = has_pot_option;
7475   mp->trace_enable = has_trace_option;
7476
7477   S (mp);
7478   W (ret);
7479   return ret;
7480 }
7481
7482
7483 static int
7484 api_ioam_disable (vat_main_t * vam)
7485 {
7486   vl_api_ioam_disable_t *mp;
7487   int ret;
7488
7489   M (IOAM_DISABLE, mp);
7490   S (mp);
7491   W (ret);
7492   return ret;
7493 }
7494
7495 #define foreach_tcp_proto_field                 \
7496 _(src_port)                                     \
7497 _(dst_port)
7498
7499 #define foreach_udp_proto_field                 \
7500 _(src_port)                                     \
7501 _(dst_port)
7502
7503 #define foreach_ip4_proto_field                 \
7504 _(src_address)                                  \
7505 _(dst_address)                                  \
7506 _(tos)                                          \
7507 _(length)                                       \
7508 _(fragment_id)                                  \
7509 _(ttl)                                          \
7510 _(protocol)                                     \
7511 _(checksum)
7512
7513 typedef struct
7514 {
7515   u16 src_port, dst_port;
7516 } tcpudp_header_t;
7517
7518 #if VPP_API_TEST_BUILTIN == 0
7519 uword
7520 unformat_tcp_mask (unformat_input_t * input, va_list * args)
7521 {
7522   u8 **maskp = va_arg (*args, u8 **);
7523   u8 *mask = 0;
7524   u8 found_something = 0;
7525   tcp_header_t *tcp;
7526
7527 #define _(a) u8 a=0;
7528   foreach_tcp_proto_field;
7529 #undef _
7530
7531   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7532     {
7533       if (0);
7534 #define _(a) else if (unformat (input, #a)) a=1;
7535       foreach_tcp_proto_field
7536 #undef _
7537         else
7538         break;
7539     }
7540
7541 #define _(a) found_something += a;
7542   foreach_tcp_proto_field;
7543 #undef _
7544
7545   if (found_something == 0)
7546     return 0;
7547
7548   vec_validate (mask, sizeof (*tcp) - 1);
7549
7550   tcp = (tcp_header_t *) mask;
7551
7552 #define _(a) if (a) clib_memset (&tcp->a, 0xff, sizeof (tcp->a));
7553   foreach_tcp_proto_field;
7554 #undef _
7555
7556   *maskp = mask;
7557   return 1;
7558 }
7559
7560 uword
7561 unformat_udp_mask (unformat_input_t * input, va_list * args)
7562 {
7563   u8 **maskp = va_arg (*args, u8 **);
7564   u8 *mask = 0;
7565   u8 found_something = 0;
7566   udp_header_t *udp;
7567
7568 #define _(a) u8 a=0;
7569   foreach_udp_proto_field;
7570 #undef _
7571
7572   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7573     {
7574       if (0);
7575 #define _(a) else if (unformat (input, #a)) a=1;
7576       foreach_udp_proto_field
7577 #undef _
7578         else
7579         break;
7580     }
7581
7582 #define _(a) found_something += a;
7583   foreach_udp_proto_field;
7584 #undef _
7585
7586   if (found_something == 0)
7587     return 0;
7588
7589   vec_validate (mask, sizeof (*udp) - 1);
7590
7591   udp = (udp_header_t *) mask;
7592
7593 #define _(a) if (a) clib_memset (&udp->a, 0xff, sizeof (udp->a));
7594   foreach_udp_proto_field;
7595 #undef _
7596
7597   *maskp = mask;
7598   return 1;
7599 }
7600
7601 uword
7602 unformat_l4_mask (unformat_input_t * input, va_list * args)
7603 {
7604   u8 **maskp = va_arg (*args, u8 **);
7605   u16 src_port = 0, dst_port = 0;
7606   tcpudp_header_t *tcpudp;
7607
7608   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7609     {
7610       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
7611         return 1;
7612       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
7613         return 1;
7614       else if (unformat (input, "src_port"))
7615         src_port = 0xFFFF;
7616       else if (unformat (input, "dst_port"))
7617         dst_port = 0xFFFF;
7618       else
7619         return 0;
7620     }
7621
7622   if (!src_port && !dst_port)
7623     return 0;
7624
7625   u8 *mask = 0;
7626   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
7627
7628   tcpudp = (tcpudp_header_t *) mask;
7629   tcpudp->src_port = src_port;
7630   tcpudp->dst_port = dst_port;
7631
7632   *maskp = mask;
7633
7634   return 1;
7635 }
7636
7637 uword
7638 unformat_ip4_mask (unformat_input_t * input, va_list * args)
7639 {
7640   u8 **maskp = va_arg (*args, u8 **);
7641   u8 *mask = 0;
7642   u8 found_something = 0;
7643   ip4_header_t *ip;
7644
7645 #define _(a) u8 a=0;
7646   foreach_ip4_proto_field;
7647 #undef _
7648   u8 version = 0;
7649   u8 hdr_length = 0;
7650
7651
7652   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7653     {
7654       if (unformat (input, "version"))
7655         version = 1;
7656       else if (unformat (input, "hdr_length"))
7657         hdr_length = 1;
7658       else if (unformat (input, "src"))
7659         src_address = 1;
7660       else if (unformat (input, "dst"))
7661         dst_address = 1;
7662       else if (unformat (input, "proto"))
7663         protocol = 1;
7664
7665 #define _(a) else if (unformat (input, #a)) a=1;
7666       foreach_ip4_proto_field
7667 #undef _
7668         else
7669         break;
7670     }
7671
7672 #define _(a) found_something += a;
7673   foreach_ip4_proto_field;
7674 #undef _
7675
7676   if (found_something == 0)
7677     return 0;
7678
7679   vec_validate (mask, sizeof (*ip) - 1);
7680
7681   ip = (ip4_header_t *) mask;
7682
7683 #define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
7684   foreach_ip4_proto_field;
7685 #undef _
7686
7687   ip->ip_version_and_header_length = 0;
7688
7689   if (version)
7690     ip->ip_version_and_header_length |= 0xF0;
7691
7692   if (hdr_length)
7693     ip->ip_version_and_header_length |= 0x0F;
7694
7695   *maskp = mask;
7696   return 1;
7697 }
7698
7699 #define foreach_ip6_proto_field                 \
7700 _(src_address)                                  \
7701 _(dst_address)                                  \
7702 _(payload_length)                               \
7703 _(hop_limit)                                    \
7704 _(protocol)
7705
7706 uword
7707 unformat_ip6_mask (unformat_input_t * input, va_list * args)
7708 {
7709   u8 **maskp = va_arg (*args, u8 **);
7710   u8 *mask = 0;
7711   u8 found_something = 0;
7712   ip6_header_t *ip;
7713   u32 ip_version_traffic_class_and_flow_label;
7714
7715 #define _(a) u8 a=0;
7716   foreach_ip6_proto_field;
7717 #undef _
7718   u8 version = 0;
7719   u8 traffic_class = 0;
7720   u8 flow_label = 0;
7721
7722   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7723     {
7724       if (unformat (input, "version"))
7725         version = 1;
7726       else if (unformat (input, "traffic-class"))
7727         traffic_class = 1;
7728       else if (unformat (input, "flow-label"))
7729         flow_label = 1;
7730       else if (unformat (input, "src"))
7731         src_address = 1;
7732       else if (unformat (input, "dst"))
7733         dst_address = 1;
7734       else if (unformat (input, "proto"))
7735         protocol = 1;
7736
7737 #define _(a) else if (unformat (input, #a)) a=1;
7738       foreach_ip6_proto_field
7739 #undef _
7740         else
7741         break;
7742     }
7743
7744 #define _(a) found_something += a;
7745   foreach_ip6_proto_field;
7746 #undef _
7747
7748   if (found_something == 0)
7749     return 0;
7750
7751   vec_validate (mask, sizeof (*ip) - 1);
7752
7753   ip = (ip6_header_t *) mask;
7754
7755 #define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
7756   foreach_ip6_proto_field;
7757 #undef _
7758
7759   ip_version_traffic_class_and_flow_label = 0;
7760
7761   if (version)
7762     ip_version_traffic_class_and_flow_label |= 0xF0000000;
7763
7764   if (traffic_class)
7765     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
7766
7767   if (flow_label)
7768     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
7769
7770   ip->ip_version_traffic_class_and_flow_label =
7771     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
7772
7773   *maskp = mask;
7774   return 1;
7775 }
7776
7777 uword
7778 unformat_l3_mask (unformat_input_t * input, va_list * args)
7779 {
7780   u8 **maskp = va_arg (*args, u8 **);
7781
7782   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7783     {
7784       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
7785         return 1;
7786       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
7787         return 1;
7788       else
7789         break;
7790     }
7791   return 0;
7792 }
7793
7794 uword
7795 unformat_l2_mask (unformat_input_t * input, va_list * args)
7796 {
7797   u8 **maskp = va_arg (*args, u8 **);
7798   u8 *mask = 0;
7799   u8 src = 0;
7800   u8 dst = 0;
7801   u8 proto = 0;
7802   u8 tag1 = 0;
7803   u8 tag2 = 0;
7804   u8 ignore_tag1 = 0;
7805   u8 ignore_tag2 = 0;
7806   u8 cos1 = 0;
7807   u8 cos2 = 0;
7808   u8 dot1q = 0;
7809   u8 dot1ad = 0;
7810   int len = 14;
7811
7812   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7813     {
7814       if (unformat (input, "src"))
7815         src = 1;
7816       else if (unformat (input, "dst"))
7817         dst = 1;
7818       else if (unformat (input, "proto"))
7819         proto = 1;
7820       else if (unformat (input, "tag1"))
7821         tag1 = 1;
7822       else if (unformat (input, "tag2"))
7823         tag2 = 1;
7824       else if (unformat (input, "ignore-tag1"))
7825         ignore_tag1 = 1;
7826       else if (unformat (input, "ignore-tag2"))
7827         ignore_tag2 = 1;
7828       else if (unformat (input, "cos1"))
7829         cos1 = 1;
7830       else if (unformat (input, "cos2"))
7831         cos2 = 1;
7832       else if (unformat (input, "dot1q"))
7833         dot1q = 1;
7834       else if (unformat (input, "dot1ad"))
7835         dot1ad = 1;
7836       else
7837         break;
7838     }
7839   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
7840        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
7841     return 0;
7842
7843   if (tag1 || ignore_tag1 || cos1 || dot1q)
7844     len = 18;
7845   if (tag2 || ignore_tag2 || cos2 || dot1ad)
7846     len = 22;
7847
7848   vec_validate (mask, len - 1);
7849
7850   if (dst)
7851     clib_memset (mask, 0xff, 6);
7852
7853   if (src)
7854     clib_memset (mask + 6, 0xff, 6);
7855
7856   if (tag2 || dot1ad)
7857     {
7858       /* inner vlan tag */
7859       if (tag2)
7860         {
7861           mask[19] = 0xff;
7862           mask[18] = 0x0f;
7863         }
7864       if (cos2)
7865         mask[18] |= 0xe0;
7866       if (proto)
7867         mask[21] = mask[20] = 0xff;
7868       if (tag1)
7869         {
7870           mask[15] = 0xff;
7871           mask[14] = 0x0f;
7872         }
7873       if (cos1)
7874         mask[14] |= 0xe0;
7875       *maskp = mask;
7876       return 1;
7877     }
7878   if (tag1 | dot1q)
7879     {
7880       if (tag1)
7881         {
7882           mask[15] = 0xff;
7883           mask[14] = 0x0f;
7884         }
7885       if (cos1)
7886         mask[14] |= 0xe0;
7887       if (proto)
7888         mask[16] = mask[17] = 0xff;
7889
7890       *maskp = mask;
7891       return 1;
7892     }
7893   if (cos2)
7894     mask[18] |= 0xe0;
7895   if (cos1)
7896     mask[14] |= 0xe0;
7897   if (proto)
7898     mask[12] = mask[13] = 0xff;
7899
7900   *maskp = mask;
7901   return 1;
7902 }
7903
7904 uword
7905 unformat_classify_mask (unformat_input_t * input, va_list * args)
7906 {
7907   u8 **maskp = va_arg (*args, u8 **);
7908   u32 *skipp = va_arg (*args, u32 *);
7909   u32 *matchp = va_arg (*args, u32 *);
7910   u32 match;
7911   u8 *mask = 0;
7912   u8 *l2 = 0;
7913   u8 *l3 = 0;
7914   u8 *l4 = 0;
7915   int i;
7916
7917   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7918     {
7919       if (unformat (input, "hex %U", unformat_hex_string, &mask))
7920         ;
7921       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
7922         ;
7923       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
7924         ;
7925       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
7926         ;
7927       else
7928         break;
7929     }
7930
7931   if (l4 && !l3)
7932     {
7933       vec_free (mask);
7934       vec_free (l2);
7935       vec_free (l4);
7936       return 0;
7937     }
7938
7939   if (mask || l2 || l3 || l4)
7940     {
7941       if (l2 || l3 || l4)
7942         {
7943           /* "With a free Ethernet header in every package" */
7944           if (l2 == 0)
7945             vec_validate (l2, 13);
7946           mask = l2;
7947           if (vec_len (l3))
7948             {
7949               vec_append (mask, l3);
7950               vec_free (l3);
7951             }
7952           if (vec_len (l4))
7953             {
7954               vec_append (mask, l4);
7955               vec_free (l4);
7956             }
7957         }
7958
7959       /* Scan forward looking for the first significant mask octet */
7960       for (i = 0; i < vec_len (mask); i++)
7961         if (mask[i])
7962           break;
7963
7964       /* compute (skip, match) params */
7965       *skipp = i / sizeof (u32x4);
7966       vec_delete (mask, *skipp * sizeof (u32x4), 0);
7967
7968       /* Pad mask to an even multiple of the vector size */
7969       while (vec_len (mask) % sizeof (u32x4))
7970         vec_add1 (mask, 0);
7971
7972       match = vec_len (mask) / sizeof (u32x4);
7973
7974       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
7975         {
7976           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
7977           if (*tmp || *(tmp + 1))
7978             break;
7979           match--;
7980         }
7981       if (match == 0)
7982         clib_warning ("BUG: match 0");
7983
7984       _vec_len (mask) = match * sizeof (u32x4);
7985
7986       *matchp = match;
7987       *maskp = mask;
7988
7989       return 1;
7990     }
7991
7992   return 0;
7993 }
7994 #endif /* VPP_API_TEST_BUILTIN */
7995
7996 #define foreach_l2_next                         \
7997 _(drop, DROP)                                   \
7998 _(ethernet, ETHERNET_INPUT)                     \
7999 _(ip4, IP4_INPUT)                               \
8000 _(ip6, IP6_INPUT)
8001
8002 uword
8003 unformat_l2_next_index (unformat_input_t * input, va_list * args)
8004 {
8005   u32 *miss_next_indexp = va_arg (*args, u32 *);
8006   u32 next_index = 0;
8007   u32 tmp;
8008
8009 #define _(n,N) \
8010   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
8011   foreach_l2_next;
8012 #undef _
8013
8014   if (unformat (input, "%d", &tmp))
8015     {
8016       next_index = tmp;
8017       goto out;
8018     }
8019
8020   return 0;
8021
8022 out:
8023   *miss_next_indexp = next_index;
8024   return 1;
8025 }
8026
8027 #define foreach_ip_next                         \
8028 _(drop, DROP)                                   \
8029 _(local, LOCAL)                                 \
8030 _(rewrite, REWRITE)
8031
8032 uword
8033 api_unformat_ip_next_index (unformat_input_t * input, va_list * args)
8034 {
8035   u32 *miss_next_indexp = va_arg (*args, u32 *);
8036   u32 next_index = 0;
8037   u32 tmp;
8038
8039 #define _(n,N) \
8040   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
8041   foreach_ip_next;
8042 #undef _
8043
8044   if (unformat (input, "%d", &tmp))
8045     {
8046       next_index = tmp;
8047       goto out;
8048     }
8049
8050   return 0;
8051
8052 out:
8053   *miss_next_indexp = next_index;
8054   return 1;
8055 }
8056
8057 #define foreach_acl_next                        \
8058 _(deny, DENY)
8059
8060 uword
8061 api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
8062 {
8063   u32 *miss_next_indexp = va_arg (*args, u32 *);
8064   u32 next_index = 0;
8065   u32 tmp;
8066
8067 #define _(n,N) \
8068   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
8069   foreach_acl_next;
8070 #undef _
8071
8072   if (unformat (input, "permit"))
8073     {
8074       next_index = ~0;
8075       goto out;
8076     }
8077   else if (unformat (input, "%d", &tmp))
8078     {
8079       next_index = tmp;
8080       goto out;
8081     }
8082
8083   return 0;
8084
8085 out:
8086   *miss_next_indexp = next_index;
8087   return 1;
8088 }
8089
8090 uword
8091 unformat_policer_precolor (unformat_input_t * input, va_list * args)
8092 {
8093   u32 *r = va_arg (*args, u32 *);
8094
8095   if (unformat (input, "conform-color"))
8096     *r = POLICE_CONFORM;
8097   else if (unformat (input, "exceed-color"))
8098     *r = POLICE_EXCEED;
8099   else
8100     return 0;
8101
8102   return 1;
8103 }
8104
8105 static int
8106 api_classify_add_del_table (vat_main_t * vam)
8107 {
8108   unformat_input_t *i = vam->input;
8109   vl_api_classify_add_del_table_t *mp;
8110
8111   u32 nbuckets = 2;
8112   u32 skip = ~0;
8113   u32 match = ~0;
8114   int is_add = 1;
8115   int del_chain = 0;
8116   u32 table_index = ~0;
8117   u32 next_table_index = ~0;
8118   u32 miss_next_index = ~0;
8119   u32 memory_size = 32 << 20;
8120   u8 *mask = 0;
8121   u32 current_data_flag = 0;
8122   int current_data_offset = 0;
8123   int ret;
8124
8125   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8126     {
8127       if (unformat (i, "del"))
8128         is_add = 0;
8129       else if (unformat (i, "del-chain"))
8130         {
8131           is_add = 0;
8132           del_chain = 1;
8133         }
8134       else if (unformat (i, "buckets %d", &nbuckets))
8135         ;
8136       else if (unformat (i, "memory_size %d", &memory_size))
8137         ;
8138       else if (unformat (i, "skip %d", &skip))
8139         ;
8140       else if (unformat (i, "match %d", &match))
8141         ;
8142       else if (unformat (i, "table %d", &table_index))
8143         ;
8144       else if (unformat (i, "mask %U", unformat_classify_mask,
8145                          &mask, &skip, &match))
8146         ;
8147       else if (unformat (i, "next-table %d", &next_table_index))
8148         ;
8149       else if (unformat (i, "miss-next %U", api_unformat_ip_next_index,
8150                          &miss_next_index))
8151         ;
8152       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
8153                          &miss_next_index))
8154         ;
8155       else if (unformat (i, "acl-miss-next %U", api_unformat_acl_next_index,
8156                          &miss_next_index))
8157         ;
8158       else if (unformat (i, "current-data-flag %d", &current_data_flag))
8159         ;
8160       else if (unformat (i, "current-data-offset %d", &current_data_offset))
8161         ;
8162       else
8163         break;
8164     }
8165
8166   if (is_add && mask == 0)
8167     {
8168       errmsg ("Mask required");
8169       return -99;
8170     }
8171
8172   if (is_add && skip == ~0)
8173     {
8174       errmsg ("skip count required");
8175       return -99;
8176     }
8177
8178   if (is_add && match == ~0)
8179     {
8180       errmsg ("match count required");
8181       return -99;
8182     }
8183
8184   if (!is_add && table_index == ~0)
8185     {
8186       errmsg ("table index required for delete");
8187       return -99;
8188     }
8189
8190   M2 (CLASSIFY_ADD_DEL_TABLE, mp, vec_len (mask));
8191
8192   mp->is_add = is_add;
8193   mp->del_chain = del_chain;
8194   mp->table_index = ntohl (table_index);
8195   mp->nbuckets = ntohl (nbuckets);
8196   mp->memory_size = ntohl (memory_size);
8197   mp->skip_n_vectors = ntohl (skip);
8198   mp->match_n_vectors = ntohl (match);
8199   mp->next_table_index = ntohl (next_table_index);
8200   mp->miss_next_index = ntohl (miss_next_index);
8201   mp->current_data_flag = ntohl (current_data_flag);
8202   mp->current_data_offset = ntohl (current_data_offset);
8203   mp->mask_len = ntohl (vec_len (mask));
8204   clib_memcpy (mp->mask, mask, vec_len (mask));
8205
8206   vec_free (mask);
8207
8208   S (mp);
8209   W (ret);
8210   return ret;
8211 }
8212
8213 #if VPP_API_TEST_BUILTIN == 0
8214 uword
8215 unformat_l4_match (unformat_input_t * input, va_list * args)
8216 {
8217   u8 **matchp = va_arg (*args, u8 **);
8218
8219   u8 *proto_header = 0;
8220   int src_port = 0;
8221   int dst_port = 0;
8222
8223   tcpudp_header_t h;
8224
8225   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8226     {
8227       if (unformat (input, "src_port %d", &src_port))
8228         ;
8229       else if (unformat (input, "dst_port %d", &dst_port))
8230         ;
8231       else
8232         return 0;
8233     }
8234
8235   h.src_port = clib_host_to_net_u16 (src_port);
8236   h.dst_port = clib_host_to_net_u16 (dst_port);
8237   vec_validate (proto_header, sizeof (h) - 1);
8238   memcpy (proto_header, &h, sizeof (h));
8239
8240   *matchp = proto_header;
8241
8242   return 1;
8243 }
8244
8245 uword
8246 unformat_ip4_match (unformat_input_t * input, va_list * args)
8247 {
8248   u8 **matchp = va_arg (*args, u8 **);
8249   u8 *match = 0;
8250   ip4_header_t *ip;
8251   int version = 0;
8252   u32 version_val;
8253   int hdr_length = 0;
8254   u32 hdr_length_val;
8255   int src = 0, dst = 0;
8256   ip4_address_t src_val, dst_val;
8257   int proto = 0;
8258   u32 proto_val;
8259   int tos = 0;
8260   u32 tos_val;
8261   int length = 0;
8262   u32 length_val;
8263   int fragment_id = 0;
8264   u32 fragment_id_val;
8265   int ttl = 0;
8266   int ttl_val;
8267   int checksum = 0;
8268   u32 checksum_val;
8269
8270   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8271     {
8272       if (unformat (input, "version %d", &version_val))
8273         version = 1;
8274       else if (unformat (input, "hdr_length %d", &hdr_length_val))
8275         hdr_length = 1;
8276       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
8277         src = 1;
8278       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
8279         dst = 1;
8280       else if (unformat (input, "proto %d", &proto_val))
8281         proto = 1;
8282       else if (unformat (input, "tos %d", &tos_val))
8283         tos = 1;
8284       else if (unformat (input, "length %d", &length_val))
8285         length = 1;
8286       else if (unformat (input, "fragment_id %d", &fragment_id_val))
8287         fragment_id = 1;
8288       else if (unformat (input, "ttl %d", &ttl_val))
8289         ttl = 1;
8290       else if (unformat (input, "checksum %d", &checksum_val))
8291         checksum = 1;
8292       else
8293         break;
8294     }
8295
8296   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
8297       + ttl + checksum == 0)
8298     return 0;
8299
8300   /*
8301    * Aligned because we use the real comparison functions
8302    */
8303   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
8304
8305   ip = (ip4_header_t *) match;
8306
8307   /* These are realistically matched in practice */
8308   if (src)
8309     ip->src_address.as_u32 = src_val.as_u32;
8310
8311   if (dst)
8312     ip->dst_address.as_u32 = dst_val.as_u32;
8313
8314   if (proto)
8315     ip->protocol = proto_val;
8316
8317
8318   /* These are not, but they're included for completeness */
8319   if (version)
8320     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
8321
8322   if (hdr_length)
8323     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
8324
8325   if (tos)
8326     ip->tos = tos_val;
8327
8328   if (length)
8329     ip->length = clib_host_to_net_u16 (length_val);
8330
8331   if (ttl)
8332     ip->ttl = ttl_val;
8333
8334   if (checksum)
8335     ip->checksum = clib_host_to_net_u16 (checksum_val);
8336
8337   *matchp = match;
8338   return 1;
8339 }
8340
8341 uword
8342 unformat_ip6_match (unformat_input_t * input, va_list * args)
8343 {
8344   u8 **matchp = va_arg (*args, u8 **);
8345   u8 *match = 0;
8346   ip6_header_t *ip;
8347   int version = 0;
8348   u32 version_val;
8349   u8 traffic_class = 0;
8350   u32 traffic_class_val = 0;
8351   u8 flow_label = 0;
8352   u8 flow_label_val;
8353   int src = 0, dst = 0;
8354   ip6_address_t src_val, dst_val;
8355   int proto = 0;
8356   u32 proto_val;
8357   int payload_length = 0;
8358   u32 payload_length_val;
8359   int hop_limit = 0;
8360   int hop_limit_val;
8361   u32 ip_version_traffic_class_and_flow_label;
8362
8363   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8364     {
8365       if (unformat (input, "version %d", &version_val))
8366         version = 1;
8367       else if (unformat (input, "traffic_class %d", &traffic_class_val))
8368         traffic_class = 1;
8369       else if (unformat (input, "flow_label %d", &flow_label_val))
8370         flow_label = 1;
8371       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
8372         src = 1;
8373       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
8374         dst = 1;
8375       else if (unformat (input, "proto %d", &proto_val))
8376         proto = 1;
8377       else if (unformat (input, "payload_length %d", &payload_length_val))
8378         payload_length = 1;
8379       else if (unformat (input, "hop_limit %d", &hop_limit_val))
8380         hop_limit = 1;
8381       else
8382         break;
8383     }
8384
8385   if (version + traffic_class + flow_label + src + dst + proto +
8386       payload_length + hop_limit == 0)
8387     return 0;
8388
8389   /*
8390    * Aligned because we use the real comparison functions
8391    */
8392   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
8393
8394   ip = (ip6_header_t *) match;
8395
8396   if (src)
8397     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
8398
8399   if (dst)
8400     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
8401
8402   if (proto)
8403     ip->protocol = proto_val;
8404
8405   ip_version_traffic_class_and_flow_label = 0;
8406
8407   if (version)
8408     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
8409
8410   if (traffic_class)
8411     ip_version_traffic_class_and_flow_label |=
8412       (traffic_class_val & 0xFF) << 20;
8413
8414   if (flow_label)
8415     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
8416
8417   ip->ip_version_traffic_class_and_flow_label =
8418     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
8419
8420   if (payload_length)
8421     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
8422
8423   if (hop_limit)
8424     ip->hop_limit = hop_limit_val;
8425
8426   *matchp = match;
8427   return 1;
8428 }
8429
8430 uword
8431 unformat_l3_match (unformat_input_t * input, va_list * args)
8432 {
8433   u8 **matchp = va_arg (*args, u8 **);
8434
8435   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8436     {
8437       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
8438         return 1;
8439       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
8440         return 1;
8441       else
8442         break;
8443     }
8444   return 0;
8445 }
8446
8447 uword
8448 unformat_vlan_tag (unformat_input_t * input, va_list * args)
8449 {
8450   u8 *tagp = va_arg (*args, u8 *);
8451   u32 tag;
8452
8453   if (unformat (input, "%d", &tag))
8454     {
8455       tagp[0] = (tag >> 8) & 0x0F;
8456       tagp[1] = tag & 0xFF;
8457       return 1;
8458     }
8459
8460   return 0;
8461 }
8462
8463 uword
8464 unformat_l2_match (unformat_input_t * input, va_list * args)
8465 {
8466   u8 **matchp = va_arg (*args, u8 **);
8467   u8 *match = 0;
8468   u8 src = 0;
8469   u8 src_val[6];
8470   u8 dst = 0;
8471   u8 dst_val[6];
8472   u8 proto = 0;
8473   u16 proto_val;
8474   u8 tag1 = 0;
8475   u8 tag1_val[2];
8476   u8 tag2 = 0;
8477   u8 tag2_val[2];
8478   int len = 14;
8479   u8 ignore_tag1 = 0;
8480   u8 ignore_tag2 = 0;
8481   u8 cos1 = 0;
8482   u8 cos2 = 0;
8483   u32 cos1_val = 0;
8484   u32 cos2_val = 0;
8485
8486   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8487     {
8488       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
8489         src = 1;
8490       else
8491         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
8492         dst = 1;
8493       else if (unformat (input, "proto %U",
8494                          unformat_ethernet_type_host_byte_order, &proto_val))
8495         proto = 1;
8496       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
8497         tag1 = 1;
8498       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
8499         tag2 = 1;
8500       else if (unformat (input, "ignore-tag1"))
8501         ignore_tag1 = 1;
8502       else if (unformat (input, "ignore-tag2"))
8503         ignore_tag2 = 1;
8504       else if (unformat (input, "cos1 %d", &cos1_val))
8505         cos1 = 1;
8506       else if (unformat (input, "cos2 %d", &cos2_val))
8507         cos2 = 1;
8508       else
8509         break;
8510     }
8511   if ((src + dst + proto + tag1 + tag2 +
8512        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
8513     return 0;
8514
8515   if (tag1 || ignore_tag1 || cos1)
8516     len = 18;
8517   if (tag2 || ignore_tag2 || cos2)
8518     len = 22;
8519
8520   vec_validate_aligned (match, len - 1, sizeof (u32x4));
8521
8522   if (dst)
8523     clib_memcpy (match, dst_val, 6);
8524
8525   if (src)
8526     clib_memcpy (match + 6, src_val, 6);
8527
8528   if (tag2)
8529     {
8530       /* inner vlan tag */
8531       match[19] = tag2_val[1];
8532       match[18] = tag2_val[0];
8533       if (cos2)
8534         match[18] |= (cos2_val & 0x7) << 5;
8535       if (proto)
8536         {
8537           match[21] = proto_val & 0xff;
8538           match[20] = proto_val >> 8;
8539         }
8540       if (tag1)
8541         {
8542           match[15] = tag1_val[1];
8543           match[14] = tag1_val[0];
8544         }
8545       if (cos1)
8546         match[14] |= (cos1_val & 0x7) << 5;
8547       *matchp = match;
8548       return 1;
8549     }
8550   if (tag1)
8551     {
8552       match[15] = tag1_val[1];
8553       match[14] = tag1_val[0];
8554       if (proto)
8555         {
8556           match[17] = proto_val & 0xff;
8557           match[16] = proto_val >> 8;
8558         }
8559       if (cos1)
8560         match[14] |= (cos1_val & 0x7) << 5;
8561
8562       *matchp = match;
8563       return 1;
8564     }
8565   if (cos2)
8566     match[18] |= (cos2_val & 0x7) << 5;
8567   if (cos1)
8568     match[14] |= (cos1_val & 0x7) << 5;
8569   if (proto)
8570     {
8571       match[13] = proto_val & 0xff;
8572       match[12] = proto_val >> 8;
8573     }
8574
8575   *matchp = match;
8576   return 1;
8577 }
8578
8579 uword
8580 unformat_qos_source (unformat_input_t * input, va_list * args)
8581 {
8582   int *qs = va_arg (*args, int *);
8583
8584   if (unformat (input, "ip"))
8585     *qs = QOS_SOURCE_IP;
8586   else if (unformat (input, "mpls"))
8587     *qs = QOS_SOURCE_MPLS;
8588   else if (unformat (input, "ext"))
8589     *qs = QOS_SOURCE_EXT;
8590   else if (unformat (input, "vlan"))
8591     *qs = QOS_SOURCE_VLAN;
8592   else
8593     return 0;
8594
8595   return 1;
8596 }
8597 #endif
8598
8599 uword
8600 api_unformat_classify_match (unformat_input_t * input, va_list * args)
8601 {
8602   u8 **matchp = va_arg (*args, u8 **);
8603   u32 skip_n_vectors = va_arg (*args, u32);
8604   u32 match_n_vectors = va_arg (*args, u32);
8605
8606   u8 *match = 0;
8607   u8 *l2 = 0;
8608   u8 *l3 = 0;
8609   u8 *l4 = 0;
8610
8611   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8612     {
8613       if (unformat (input, "hex %U", unformat_hex_string, &match))
8614         ;
8615       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
8616         ;
8617       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
8618         ;
8619       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
8620         ;
8621       else
8622         break;
8623     }
8624
8625   if (l4 && !l3)
8626     {
8627       vec_free (match);
8628       vec_free (l2);
8629       vec_free (l4);
8630       return 0;
8631     }
8632
8633   if (match || l2 || l3 || l4)
8634     {
8635       if (l2 || l3 || l4)
8636         {
8637           /* "Win a free Ethernet header in every packet" */
8638           if (l2 == 0)
8639             vec_validate_aligned (l2, 13, sizeof (u32x4));
8640           match = l2;
8641           if (vec_len (l3))
8642             {
8643               vec_append_aligned (match, l3, sizeof (u32x4));
8644               vec_free (l3);
8645             }
8646           if (vec_len (l4))
8647             {
8648               vec_append_aligned (match, l4, sizeof (u32x4));
8649               vec_free (l4);
8650             }
8651         }
8652
8653       /* Make sure the vector is big enough even if key is all 0's */
8654       vec_validate_aligned
8655         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
8656          sizeof (u32x4));
8657
8658       /* Set size, include skipped vectors */
8659       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
8660
8661       *matchp = match;
8662
8663       return 1;
8664     }
8665
8666   return 0;
8667 }
8668
8669 static int
8670 api_classify_add_del_session (vat_main_t * vam)
8671 {
8672   unformat_input_t *i = vam->input;
8673   vl_api_classify_add_del_session_t *mp;
8674   int is_add = 1;
8675   u32 table_index = ~0;
8676   u32 hit_next_index = ~0;
8677   u32 opaque_index = ~0;
8678   u8 *match = 0;
8679   i32 advance = 0;
8680   u32 skip_n_vectors = 0;
8681   u32 match_n_vectors = 0;
8682   u32 action = 0;
8683   u32 metadata = 0;
8684   int ret;
8685
8686   /*
8687    * Warning: you have to supply skip_n and match_n
8688    * because the API client cant simply look at the classify
8689    * table object.
8690    */
8691
8692   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8693     {
8694       if (unformat (i, "del"))
8695         is_add = 0;
8696       else if (unformat (i, "hit-next %U", api_unformat_ip_next_index,
8697                          &hit_next_index))
8698         ;
8699       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
8700                          &hit_next_index))
8701         ;
8702       else if (unformat (i, "acl-hit-next %U", api_unformat_acl_next_index,
8703                          &hit_next_index))
8704         ;
8705       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
8706         ;
8707       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
8708         ;
8709       else if (unformat (i, "opaque-index %d", &opaque_index))
8710         ;
8711       else if (unformat (i, "skip_n %d", &skip_n_vectors))
8712         ;
8713       else if (unformat (i, "match_n %d", &match_n_vectors))
8714         ;
8715       else if (unformat (i, "match %U", api_unformat_classify_match,
8716                          &match, skip_n_vectors, match_n_vectors))
8717         ;
8718       else if (unformat (i, "advance %d", &advance))
8719         ;
8720       else if (unformat (i, "table-index %d", &table_index))
8721         ;
8722       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
8723         action = 1;
8724       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
8725         action = 2;
8726       else if (unformat (i, "action %d", &action))
8727         ;
8728       else if (unformat (i, "metadata %d", &metadata))
8729         ;
8730       else
8731         break;
8732     }
8733
8734   if (table_index == ~0)
8735     {
8736       errmsg ("Table index required");
8737       return -99;
8738     }
8739
8740   if (is_add && match == 0)
8741     {
8742       errmsg ("Match value required");
8743       return -99;
8744     }
8745
8746   M2 (CLASSIFY_ADD_DEL_SESSION, mp, vec_len (match));
8747
8748   mp->is_add = is_add;
8749   mp->table_index = ntohl (table_index);
8750   mp->hit_next_index = ntohl (hit_next_index);
8751   mp->opaque_index = ntohl (opaque_index);
8752   mp->advance = ntohl (advance);
8753   mp->action = action;
8754   mp->metadata = ntohl (metadata);
8755   mp->match_len = ntohl (vec_len (match));
8756   clib_memcpy (mp->match, match, vec_len (match));
8757   vec_free (match);
8758
8759   S (mp);
8760   W (ret);
8761   return ret;
8762 }
8763
8764 static int
8765 api_classify_set_interface_ip_table (vat_main_t * vam)
8766 {
8767   unformat_input_t *i = vam->input;
8768   vl_api_classify_set_interface_ip_table_t *mp;
8769   u32 sw_if_index;
8770   int sw_if_index_set;
8771   u32 table_index = ~0;
8772   u8 is_ipv6 = 0;
8773   int ret;
8774
8775   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8776     {
8777       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8778         sw_if_index_set = 1;
8779       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8780         sw_if_index_set = 1;
8781       else if (unformat (i, "table %d", &table_index))
8782         ;
8783       else
8784         {
8785           clib_warning ("parse error '%U'", format_unformat_error, i);
8786           return -99;
8787         }
8788     }
8789
8790   if (sw_if_index_set == 0)
8791     {
8792       errmsg ("missing interface name or sw_if_index");
8793       return -99;
8794     }
8795
8796
8797   M (CLASSIFY_SET_INTERFACE_IP_TABLE, mp);
8798
8799   mp->sw_if_index = ntohl (sw_if_index);
8800   mp->table_index = ntohl (table_index);
8801   mp->is_ipv6 = is_ipv6;
8802
8803   S (mp);
8804   W (ret);
8805   return ret;
8806 }
8807
8808 static int
8809 api_classify_set_interface_l2_tables (vat_main_t * vam)
8810 {
8811   unformat_input_t *i = vam->input;
8812   vl_api_classify_set_interface_l2_tables_t *mp;
8813   u32 sw_if_index;
8814   int sw_if_index_set;
8815   u32 ip4_table_index = ~0;
8816   u32 ip6_table_index = ~0;
8817   u32 other_table_index = ~0;
8818   u32 is_input = 1;
8819   int ret;
8820
8821   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8822     {
8823       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8824         sw_if_index_set = 1;
8825       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8826         sw_if_index_set = 1;
8827       else if (unformat (i, "ip4-table %d", &ip4_table_index))
8828         ;
8829       else if (unformat (i, "ip6-table %d", &ip6_table_index))
8830         ;
8831       else if (unformat (i, "other-table %d", &other_table_index))
8832         ;
8833       else if (unformat (i, "is-input %d", &is_input))
8834         ;
8835       else
8836         {
8837           clib_warning ("parse error '%U'", format_unformat_error, i);
8838           return -99;
8839         }
8840     }
8841
8842   if (sw_if_index_set == 0)
8843     {
8844       errmsg ("missing interface name or sw_if_index");
8845       return -99;
8846     }
8847
8848
8849   M (CLASSIFY_SET_INTERFACE_L2_TABLES, mp);
8850
8851   mp->sw_if_index = ntohl (sw_if_index);
8852   mp->ip4_table_index = ntohl (ip4_table_index);
8853   mp->ip6_table_index = ntohl (ip6_table_index);
8854   mp->other_table_index = ntohl (other_table_index);
8855   mp->is_input = (u8) is_input;
8856
8857   S (mp);
8858   W (ret);
8859   return ret;
8860 }
8861
8862 static int
8863 api_set_ipfix_exporter (vat_main_t * vam)
8864 {
8865   unformat_input_t *i = vam->input;
8866   vl_api_set_ipfix_exporter_t *mp;
8867   ip4_address_t collector_address;
8868   u8 collector_address_set = 0;
8869   u32 collector_port = ~0;
8870   ip4_address_t src_address;
8871   u8 src_address_set = 0;
8872   u32 vrf_id = ~0;
8873   u32 path_mtu = ~0;
8874   u32 template_interval = ~0;
8875   u8 udp_checksum = 0;
8876   int ret;
8877
8878   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8879     {
8880       if (unformat (i, "collector_address %U", unformat_ip4_address,
8881                     &collector_address))
8882         collector_address_set = 1;
8883       else if (unformat (i, "collector_port %d", &collector_port))
8884         ;
8885       else if (unformat (i, "src_address %U", unformat_ip4_address,
8886                          &src_address))
8887         src_address_set = 1;
8888       else if (unformat (i, "vrf_id %d", &vrf_id))
8889         ;
8890       else if (unformat (i, "path_mtu %d", &path_mtu))
8891         ;
8892       else if (unformat (i, "template_interval %d", &template_interval))
8893         ;
8894       else if (unformat (i, "udp_checksum"))
8895         udp_checksum = 1;
8896       else
8897         break;
8898     }
8899
8900   if (collector_address_set == 0)
8901     {
8902       errmsg ("collector_address required");
8903       return -99;
8904     }
8905
8906   if (src_address_set == 0)
8907     {
8908       errmsg ("src_address required");
8909       return -99;
8910     }
8911
8912   M (SET_IPFIX_EXPORTER, mp);
8913
8914   memcpy (mp->collector_address.un.ip4, collector_address.data,
8915           sizeof (collector_address.data));
8916   mp->collector_port = htons ((u16) collector_port);
8917   memcpy (mp->src_address.un.ip4, src_address.data,
8918           sizeof (src_address.data));
8919   mp->vrf_id = htonl (vrf_id);
8920   mp->path_mtu = htonl (path_mtu);
8921   mp->template_interval = htonl (template_interval);
8922   mp->udp_checksum = udp_checksum;
8923
8924   S (mp);
8925   W (ret);
8926   return ret;
8927 }
8928
8929 static int
8930 api_set_ipfix_classify_stream (vat_main_t * vam)
8931 {
8932   unformat_input_t *i = vam->input;
8933   vl_api_set_ipfix_classify_stream_t *mp;
8934   u32 domain_id = 0;
8935   u32 src_port = UDP_DST_PORT_ipfix;
8936   int ret;
8937
8938   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8939     {
8940       if (unformat (i, "domain %d", &domain_id))
8941         ;
8942       else if (unformat (i, "src_port %d", &src_port))
8943         ;
8944       else
8945         {
8946           errmsg ("unknown input `%U'", format_unformat_error, i);
8947           return -99;
8948         }
8949     }
8950
8951   M (SET_IPFIX_CLASSIFY_STREAM, mp);
8952
8953   mp->domain_id = htonl (domain_id);
8954   mp->src_port = htons ((u16) src_port);
8955
8956   S (mp);
8957   W (ret);
8958   return ret;
8959 }
8960
8961 static int
8962 api_ipfix_classify_table_add_del (vat_main_t * vam)
8963 {
8964   unformat_input_t *i = vam->input;
8965   vl_api_ipfix_classify_table_add_del_t *mp;
8966   int is_add = -1;
8967   u32 classify_table_index = ~0;
8968   u8 ip_version = 0;
8969   u8 transport_protocol = 255;
8970   int ret;
8971
8972   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8973     {
8974       if (unformat (i, "add"))
8975         is_add = 1;
8976       else if (unformat (i, "del"))
8977         is_add = 0;
8978       else if (unformat (i, "table %d", &classify_table_index))
8979         ;
8980       else if (unformat (i, "ip4"))
8981         ip_version = 4;
8982       else if (unformat (i, "ip6"))
8983         ip_version = 6;
8984       else if (unformat (i, "tcp"))
8985         transport_protocol = 6;
8986       else if (unformat (i, "udp"))
8987         transport_protocol = 17;
8988       else
8989         {
8990           errmsg ("unknown input `%U'", format_unformat_error, i);
8991           return -99;
8992         }
8993     }
8994
8995   if (is_add == -1)
8996     {
8997       errmsg ("expecting: add|del");
8998       return -99;
8999     }
9000   if (classify_table_index == ~0)
9001     {
9002       errmsg ("classifier table not specified");
9003       return -99;
9004     }
9005   if (ip_version == 0)
9006     {
9007       errmsg ("IP version not specified");
9008       return -99;
9009     }
9010
9011   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, mp);
9012
9013   mp->is_add = is_add;
9014   mp->table_id = htonl (classify_table_index);
9015   mp->ip_version = ip_version;
9016   mp->transport_protocol = transport_protocol;
9017
9018   S (mp);
9019   W (ret);
9020   return ret;
9021 }
9022
9023 static int
9024 api_get_node_index (vat_main_t * vam)
9025 {
9026   unformat_input_t *i = vam->input;
9027   vl_api_get_node_index_t *mp;
9028   u8 *name = 0;
9029   int ret;
9030
9031   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9032     {
9033       if (unformat (i, "node %s", &name))
9034         ;
9035       else
9036         break;
9037     }
9038   if (name == 0)
9039     {
9040       errmsg ("node name required");
9041       return -99;
9042     }
9043   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
9044     {
9045       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
9046       return -99;
9047     }
9048
9049   M (GET_NODE_INDEX, mp);
9050   clib_memcpy (mp->node_name, name, vec_len (name));
9051   vec_free (name);
9052
9053   S (mp);
9054   W (ret);
9055   return ret;
9056 }
9057
9058 static int
9059 api_get_next_index (vat_main_t * vam)
9060 {
9061   unformat_input_t *i = vam->input;
9062   vl_api_get_next_index_t *mp;
9063   u8 *node_name = 0, *next_node_name = 0;
9064   int ret;
9065
9066   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9067     {
9068       if (unformat (i, "node-name %s", &node_name))
9069         ;
9070       else if (unformat (i, "next-node-name %s", &next_node_name))
9071         break;
9072     }
9073
9074   if (node_name == 0)
9075     {
9076       errmsg ("node name required");
9077       return -99;
9078     }
9079   if (vec_len (node_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   if (next_node_name == 0)
9086     {
9087       errmsg ("next node name required");
9088       return -99;
9089     }
9090   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
9091     {
9092       errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
9093       return -99;
9094     }
9095
9096   M (GET_NEXT_INDEX, mp);
9097   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
9098   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
9099   vec_free (node_name);
9100   vec_free (next_node_name);
9101
9102   S (mp);
9103   W (ret);
9104   return ret;
9105 }
9106
9107 static int
9108 api_add_node_next (vat_main_t * vam)
9109 {
9110   unformat_input_t *i = vam->input;
9111   vl_api_add_node_next_t *mp;
9112   u8 *name = 0;
9113   u8 *next = 0;
9114   int ret;
9115
9116   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9117     {
9118       if (unformat (i, "node %s", &name))
9119         ;
9120       else if (unformat (i, "next %s", &next))
9121         ;
9122       else
9123         break;
9124     }
9125   if (name == 0)
9126     {
9127       errmsg ("node name required");
9128       return -99;
9129     }
9130   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
9131     {
9132       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
9133       return -99;
9134     }
9135   if (next == 0)
9136     {
9137       errmsg ("next node required");
9138       return -99;
9139     }
9140   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
9141     {
9142       errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
9143       return -99;
9144     }
9145
9146   M (ADD_NODE_NEXT, mp);
9147   clib_memcpy (mp->node_name, name, vec_len (name));
9148   clib_memcpy (mp->next_name, next, vec_len (next));
9149   vec_free (name);
9150   vec_free (next);
9151
9152   S (mp);
9153   W (ret);
9154   return ret;
9155 }
9156
9157 static void vl_api_sw_interface_tap_v2_details_t_handler
9158   (vl_api_sw_interface_tap_v2_details_t * mp)
9159 {
9160   vat_main_t *vam = &vat_main;
9161
9162   u8 *ip4 =
9163     format (0, "%U/%d", format_ip4_address, mp->host_ip4_prefix.address,
9164             mp->host_ip4_prefix.len);
9165   u8 *ip6 =
9166     format (0, "%U/%d", format_ip6_address, mp->host_ip6_prefix.address,
9167             mp->host_ip6_prefix.len);
9168
9169   print (vam->ofp,
9170          "\n%-16s %-12d %-5d %-12d %-12d %-14U %-30s %-20s %-20s %-30s 0x%-08x",
9171          mp->dev_name, ntohl (mp->sw_if_index), ntohl (mp->id),
9172          ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
9173          format_ethernet_address, mp->host_mac_addr, mp->host_namespace,
9174          mp->host_bridge, ip4, ip6, ntohl (mp->tap_flags));
9175
9176   vec_free (ip4);
9177   vec_free (ip6);
9178 }
9179
9180 static void vl_api_sw_interface_tap_v2_details_t_handler_json
9181   (vl_api_sw_interface_tap_v2_details_t * mp)
9182 {
9183   vat_main_t *vam = &vat_main;
9184   vat_json_node_t *node = NULL;
9185
9186   if (VAT_JSON_ARRAY != vam->json_tree.type)
9187     {
9188       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9189       vat_json_init_array (&vam->json_tree);
9190     }
9191   node = vat_json_array_add (&vam->json_tree);
9192
9193   vat_json_init_object (node);
9194   vat_json_object_add_uint (node, "id", ntohl (mp->id));
9195   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
9196   vat_json_object_add_uint (node, "tap_flags", ntohl (mp->tap_flags));
9197   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
9198   vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
9199   vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
9200   vat_json_object_add_string_copy (node, "host_mac_addr",
9201                                    format (0, "%U", format_ethernet_address,
9202                                            &mp->host_mac_addr));
9203   vat_json_object_add_string_copy (node, "host_namespace",
9204                                    mp->host_namespace);
9205   vat_json_object_add_string_copy (node, "host_bridge", mp->host_bridge);
9206   vat_json_object_add_string_copy (node, "host_ip4_addr",
9207                                    format (0, "%U/%d", format_ip4_address,
9208                                            mp->host_ip4_prefix.address,
9209                                            mp->host_ip4_prefix.len));
9210   vat_json_object_add_string_copy (node, "host_ip6_prefix",
9211                                    format (0, "%U/%d", format_ip6_address,
9212                                            mp->host_ip6_prefix.address,
9213                                            mp->host_ip6_prefix.len));
9214
9215 }
9216
9217 static int
9218 api_sw_interface_tap_v2_dump (vat_main_t * vam)
9219 {
9220   vl_api_sw_interface_tap_v2_dump_t *mp;
9221   vl_api_control_ping_t *mp_ping;
9222   int ret;
9223
9224   print (vam->ofp,
9225          "\n%-16s %-12s %-5s %-12s %-12s %-14s %-30s %-20s %-20s %-30s",
9226          "dev_name", "sw_if_index", "id", "rx_ring_sz", "tx_ring_sz",
9227          "host_mac_addr", "host_namespace", "host_bridge", "host_ip4_addr",
9228          "host_ip6_addr");
9229
9230   /* Get list of tap interfaces */
9231   M (SW_INTERFACE_TAP_V2_DUMP, mp);
9232   S (mp);
9233
9234   /* Use a control ping for synchronization */
9235   MPING (CONTROL_PING, mp_ping);
9236   S (mp_ping);
9237
9238   W (ret);
9239   return ret;
9240 }
9241
9242 static void vl_api_sw_interface_virtio_pci_details_t_handler
9243   (vl_api_sw_interface_virtio_pci_details_t * mp)
9244 {
9245   vat_main_t *vam = &vat_main;
9246
9247   typedef union
9248   {
9249     struct
9250     {
9251       u16 domain;
9252       u8 bus;
9253       u8 slot:5;
9254       u8 function:3;
9255     };
9256     u32 as_u32;
9257   } pci_addr_t;
9258   pci_addr_t addr;
9259
9260   addr.domain = ntohs (mp->pci_addr.domain);
9261   addr.bus = mp->pci_addr.bus;
9262   addr.slot = mp->pci_addr.slot;
9263   addr.function = mp->pci_addr.function;
9264
9265   u8 *pci_addr = format (0, "%04x:%02x:%02x.%x", addr.domain, addr.bus,
9266                          addr.slot, addr.function);
9267
9268   print (vam->ofp,
9269          "\n%-12s %-12d %-12d %-12d %-17U 0x%-08llx",
9270          pci_addr, ntohl (mp->sw_if_index),
9271          ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
9272          format_ethernet_address, mp->mac_addr,
9273          clib_net_to_host_u64 (mp->features));
9274   vec_free (pci_addr);
9275 }
9276
9277 static void vl_api_sw_interface_virtio_pci_details_t_handler_json
9278   (vl_api_sw_interface_virtio_pci_details_t * mp)
9279 {
9280   vat_main_t *vam = &vat_main;
9281   vat_json_node_t *node = NULL;
9282   vlib_pci_addr_t pci_addr;
9283
9284   if (VAT_JSON_ARRAY != vam->json_tree.type)
9285     {
9286       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9287       vat_json_init_array (&vam->json_tree);
9288     }
9289   node = vat_json_array_add (&vam->json_tree);
9290
9291   pci_addr.domain = ntohs (mp->pci_addr.domain);
9292   pci_addr.bus = mp->pci_addr.bus;
9293   pci_addr.slot = mp->pci_addr.slot;
9294   pci_addr.function = mp->pci_addr.function;
9295
9296   vat_json_init_object (node);
9297   vat_json_object_add_uint (node, "pci-addr", pci_addr.as_u32);
9298   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
9299   vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
9300   vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
9301   vat_json_object_add_uint (node, "features",
9302                             clib_net_to_host_u64 (mp->features));
9303   vat_json_object_add_string_copy (node, "mac_addr",
9304                                    format (0, "%U", format_ethernet_address,
9305                                            &mp->mac_addr));
9306 }
9307
9308 static int
9309 api_sw_interface_virtio_pci_dump (vat_main_t * vam)
9310 {
9311   vl_api_sw_interface_virtio_pci_dump_t *mp;
9312   vl_api_control_ping_t *mp_ping;
9313   int ret;
9314
9315   print (vam->ofp,
9316          "\n%-12s %-12s %-12s %-12s %-17s %-08s",
9317          "pci_addr", "sw_if_index", "rx_ring_sz", "tx_ring_sz",
9318          "mac_addr", "features");
9319
9320   /* Get list of tap interfaces */
9321   M (SW_INTERFACE_VIRTIO_PCI_DUMP, mp);
9322   S (mp);
9323
9324   /* Use a control ping for synchronization */
9325   MPING (CONTROL_PING, mp_ping);
9326   S (mp_ping);
9327
9328   W (ret);
9329   return ret;
9330 }
9331
9332 static int
9333 api_vxlan_offload_rx (vat_main_t * vam)
9334 {
9335   unformat_input_t *line_input = vam->input;
9336   vl_api_vxlan_offload_rx_t *mp;
9337   u32 hw_if_index = ~0, rx_if_index = ~0;
9338   u8 is_add = 1;
9339   int ret;
9340
9341   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
9342     {
9343       if (unformat (line_input, "del"))
9344         is_add = 0;
9345       else if (unformat (line_input, "hw %U", api_unformat_hw_if_index, vam,
9346                          &hw_if_index))
9347         ;
9348       else if (unformat (line_input, "hw hw_if_index %u", &hw_if_index))
9349         ;
9350       else if (unformat (line_input, "rx %U", api_unformat_sw_if_index, vam,
9351                          &rx_if_index))
9352         ;
9353       else if (unformat (line_input, "rx sw_if_index %u", &rx_if_index))
9354         ;
9355       else
9356         {
9357           errmsg ("parse error '%U'", format_unformat_error, line_input);
9358           return -99;
9359         }
9360     }
9361
9362   if (hw_if_index == ~0)
9363     {
9364       errmsg ("no hw interface");
9365       return -99;
9366     }
9367
9368   if (rx_if_index == ~0)
9369     {
9370       errmsg ("no rx tunnel");
9371       return -99;
9372     }
9373
9374   M (VXLAN_OFFLOAD_RX, mp);
9375
9376   mp->hw_if_index = ntohl (hw_if_index);
9377   mp->sw_if_index = ntohl (rx_if_index);
9378   mp->enable = is_add;
9379
9380   S (mp);
9381   W (ret);
9382   return ret;
9383 }
9384
9385 static uword unformat_vxlan_decap_next
9386   (unformat_input_t * input, va_list * args)
9387 {
9388   u32 *result = va_arg (*args, u32 *);
9389   u32 tmp;
9390
9391   if (unformat (input, "l2"))
9392     *result = VXLAN_INPUT_NEXT_L2_INPUT;
9393   else if (unformat (input, "%d", &tmp))
9394     *result = tmp;
9395   else
9396     return 0;
9397   return 1;
9398 }
9399
9400 static int
9401 api_vxlan_add_del_tunnel (vat_main_t * vam)
9402 {
9403   unformat_input_t *line_input = vam->input;
9404   vl_api_vxlan_add_del_tunnel_t *mp;
9405   ip46_address_t src, dst;
9406   u8 is_add = 1;
9407   u8 ipv4_set = 0, ipv6_set = 0;
9408   u8 src_set = 0;
9409   u8 dst_set = 0;
9410   u8 grp_set = 0;
9411   u32 instance = ~0;
9412   u32 mcast_sw_if_index = ~0;
9413   u32 encap_vrf_id = 0;
9414   u32 decap_next_index = ~0;
9415   u32 vni = 0;
9416   int ret;
9417
9418   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
9419   clib_memset (&src, 0, sizeof src);
9420   clib_memset (&dst, 0, sizeof dst);
9421
9422   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
9423     {
9424       if (unformat (line_input, "del"))
9425         is_add = 0;
9426       else if (unformat (line_input, "instance %d", &instance))
9427         ;
9428       else
9429         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
9430         {
9431           ipv4_set = 1;
9432           src_set = 1;
9433         }
9434       else
9435         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
9436         {
9437           ipv4_set = 1;
9438           dst_set = 1;
9439         }
9440       else
9441         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
9442         {
9443           ipv6_set = 1;
9444           src_set = 1;
9445         }
9446       else
9447         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
9448         {
9449           ipv6_set = 1;
9450           dst_set = 1;
9451         }
9452       else if (unformat (line_input, "group %U %U",
9453                          unformat_ip4_address, &dst.ip4,
9454                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
9455         {
9456           grp_set = dst_set = 1;
9457           ipv4_set = 1;
9458         }
9459       else if (unformat (line_input, "group %U",
9460                          unformat_ip4_address, &dst.ip4))
9461         {
9462           grp_set = dst_set = 1;
9463           ipv4_set = 1;
9464         }
9465       else if (unformat (line_input, "group %U %U",
9466                          unformat_ip6_address, &dst.ip6,
9467                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
9468         {
9469           grp_set = dst_set = 1;
9470           ipv6_set = 1;
9471         }
9472       else if (unformat (line_input, "group %U",
9473                          unformat_ip6_address, &dst.ip6))
9474         {
9475           grp_set = dst_set = 1;
9476           ipv6_set = 1;
9477         }
9478       else
9479         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
9480         ;
9481       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
9482         ;
9483       else if (unformat (line_input, "decap-next %U",
9484                          unformat_vxlan_decap_next, &decap_next_index))
9485         ;
9486       else if (unformat (line_input, "vni %d", &vni))
9487         ;
9488       else
9489         {
9490           errmsg ("parse error '%U'", format_unformat_error, line_input);
9491           return -99;
9492         }
9493     }
9494
9495   if (src_set == 0)
9496     {
9497       errmsg ("tunnel src address not specified");
9498       return -99;
9499     }
9500   if (dst_set == 0)
9501     {
9502       errmsg ("tunnel dst address not specified");
9503       return -99;
9504     }
9505
9506   if (grp_set && !ip46_address_is_multicast (&dst))
9507     {
9508       errmsg ("tunnel group address not multicast");
9509       return -99;
9510     }
9511   if (grp_set && mcast_sw_if_index == ~0)
9512     {
9513       errmsg ("tunnel nonexistent multicast device");
9514       return -99;
9515     }
9516   if (grp_set == 0 && ip46_address_is_multicast (&dst))
9517     {
9518       errmsg ("tunnel dst address must be unicast");
9519       return -99;
9520     }
9521
9522
9523   if (ipv4_set && ipv6_set)
9524     {
9525       errmsg ("both IPv4 and IPv6 addresses specified");
9526       return -99;
9527     }
9528
9529   if ((vni == 0) || (vni >> 24))
9530     {
9531       errmsg ("vni not specified or out of range");
9532       return -99;
9533     }
9534
9535   M (VXLAN_ADD_DEL_TUNNEL, mp);
9536
9537   if (ipv6_set)
9538     {
9539       clib_memcpy (mp->src_address.un.ip6, &src.ip6, sizeof (src.ip6));
9540       clib_memcpy (mp->dst_address.un.ip6, &dst.ip6, sizeof (dst.ip6));
9541     }
9542   else
9543     {
9544       clib_memcpy (mp->src_address.un.ip4, &src.ip4, sizeof (src.ip4));
9545       clib_memcpy (mp->dst_address.un.ip4, &dst.ip4, sizeof (dst.ip4));
9546     }
9547   mp->src_address.af = ipv6_set;
9548   mp->dst_address.af = ipv6_set;
9549
9550   mp->instance = htonl (instance);
9551   mp->encap_vrf_id = ntohl (encap_vrf_id);
9552   mp->decap_next_index = ntohl (decap_next_index);
9553   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
9554   mp->vni = ntohl (vni);
9555   mp->is_add = is_add;
9556
9557   S (mp);
9558   W (ret);
9559   return ret;
9560 }
9561
9562 static void vl_api_vxlan_tunnel_details_t_handler
9563   (vl_api_vxlan_tunnel_details_t * mp)
9564 {
9565   vat_main_t *vam = &vat_main;
9566   ip46_address_t src =
9567     to_ip46 (mp->dst_address.af, (u8 *) & mp->dst_address.un);
9568   ip46_address_t dst =
9569     to_ip46 (mp->dst_address.af, (u8 *) & mp->src_address.un);
9570
9571   print (vam->ofp, "%11d%11d%24U%24U%14d%18d%13d%19d",
9572          ntohl (mp->sw_if_index),
9573          ntohl (mp->instance),
9574          format_ip46_address, &src, IP46_TYPE_ANY,
9575          format_ip46_address, &dst, IP46_TYPE_ANY,
9576          ntohl (mp->encap_vrf_id),
9577          ntohl (mp->decap_next_index), ntohl (mp->vni),
9578          ntohl (mp->mcast_sw_if_index));
9579 }
9580
9581 static void vl_api_vxlan_tunnel_details_t_handler_json
9582   (vl_api_vxlan_tunnel_details_t * mp)
9583 {
9584   vat_main_t *vam = &vat_main;
9585   vat_json_node_t *node = NULL;
9586
9587   if (VAT_JSON_ARRAY != vam->json_tree.type)
9588     {
9589       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9590       vat_json_init_array (&vam->json_tree);
9591     }
9592   node = vat_json_array_add (&vam->json_tree);
9593
9594   vat_json_init_object (node);
9595   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
9596
9597   vat_json_object_add_uint (node, "instance", ntohl (mp->instance));
9598
9599   if (mp->src_address.af)
9600     {
9601       struct in6_addr ip6;
9602
9603       clib_memcpy (&ip6, mp->src_address.un.ip6, sizeof (ip6));
9604       vat_json_object_add_ip6 (node, "src_address", ip6);
9605       clib_memcpy (&ip6, mp->dst_address.un.ip6, sizeof (ip6));
9606       vat_json_object_add_ip6 (node, "dst_address", ip6);
9607     }
9608   else
9609     {
9610       struct in_addr ip4;
9611
9612       clib_memcpy (&ip4, mp->src_address.un.ip4, sizeof (ip4));
9613       vat_json_object_add_ip4 (node, "src_address", ip4);
9614       clib_memcpy (&ip4, mp->dst_address.un.ip4, sizeof (ip4));
9615       vat_json_object_add_ip4 (node, "dst_address", ip4);
9616     }
9617   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
9618   vat_json_object_add_uint (node, "decap_next_index",
9619                             ntohl (mp->decap_next_index));
9620   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
9621   vat_json_object_add_uint (node, "mcast_sw_if_index",
9622                             ntohl (mp->mcast_sw_if_index));
9623 }
9624
9625 static int
9626 api_vxlan_tunnel_dump (vat_main_t * vam)
9627 {
9628   unformat_input_t *i = vam->input;
9629   vl_api_vxlan_tunnel_dump_t *mp;
9630   vl_api_control_ping_t *mp_ping;
9631   u32 sw_if_index;
9632   u8 sw_if_index_set = 0;
9633   int ret;
9634
9635   /* Parse args required to build the message */
9636   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9637     {
9638       if (unformat (i, "sw_if_index %d", &sw_if_index))
9639         sw_if_index_set = 1;
9640       else
9641         break;
9642     }
9643
9644   if (sw_if_index_set == 0)
9645     {
9646       sw_if_index = ~0;
9647     }
9648
9649   if (!vam->json_output)
9650     {
9651       print (vam->ofp, "%11s%11s%24s%24s%14s%18s%13s%19s",
9652              "sw_if_index", "instance", "src_address", "dst_address",
9653              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
9654     }
9655
9656   /* Get list of vxlan-tunnel interfaces */
9657   M (VXLAN_TUNNEL_DUMP, mp);
9658
9659   mp->sw_if_index = htonl (sw_if_index);
9660
9661   S (mp);
9662
9663   /* Use a control ping for synchronization */
9664   MPING (CONTROL_PING, mp_ping);
9665   S (mp_ping);
9666
9667   W (ret);
9668   return ret;
9669 }
9670
9671 static int
9672 api_l2_fib_clear_table (vat_main_t * vam)
9673 {
9674 //  unformat_input_t * i = vam->input;
9675   vl_api_l2_fib_clear_table_t *mp;
9676   int ret;
9677
9678   M (L2_FIB_CLEAR_TABLE, mp);
9679
9680   S (mp);
9681   W (ret);
9682   return ret;
9683 }
9684
9685 static int
9686 api_l2_interface_efp_filter (vat_main_t * vam)
9687 {
9688   unformat_input_t *i = vam->input;
9689   vl_api_l2_interface_efp_filter_t *mp;
9690   u32 sw_if_index;
9691   u8 enable = 1;
9692   u8 sw_if_index_set = 0;
9693   int ret;
9694
9695   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9696     {
9697       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9698         sw_if_index_set = 1;
9699       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9700         sw_if_index_set = 1;
9701       else if (unformat (i, "enable"))
9702         enable = 1;
9703       else if (unformat (i, "disable"))
9704         enable = 0;
9705       else
9706         {
9707           clib_warning ("parse error '%U'", format_unformat_error, i);
9708           return -99;
9709         }
9710     }
9711
9712   if (sw_if_index_set == 0)
9713     {
9714       errmsg ("missing sw_if_index");
9715       return -99;
9716     }
9717
9718   M (L2_INTERFACE_EFP_FILTER, mp);
9719
9720   mp->sw_if_index = ntohl (sw_if_index);
9721   mp->enable_disable = enable;
9722
9723   S (mp);
9724   W (ret);
9725   return ret;
9726 }
9727
9728 #define foreach_vtr_op                          \
9729 _("disable",  L2_VTR_DISABLED)                  \
9730 _("push-1",  L2_VTR_PUSH_1)                     \
9731 _("push-2",  L2_VTR_PUSH_2)                     \
9732 _("pop-1",  L2_VTR_POP_1)                       \
9733 _("pop-2",  L2_VTR_POP_2)                       \
9734 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
9735 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
9736 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
9737 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
9738
9739 static int
9740 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
9741 {
9742   unformat_input_t *i = vam->input;
9743   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
9744   u32 sw_if_index;
9745   u8 sw_if_index_set = 0;
9746   u8 vtr_op_set = 0;
9747   u32 vtr_op = 0;
9748   u32 push_dot1q = 1;
9749   u32 tag1 = ~0;
9750   u32 tag2 = ~0;
9751   int ret;
9752
9753   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9754     {
9755       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9756         sw_if_index_set = 1;
9757       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9758         sw_if_index_set = 1;
9759       else if (unformat (i, "vtr_op %d", &vtr_op))
9760         vtr_op_set = 1;
9761 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
9762       foreach_vtr_op
9763 #undef _
9764         else if (unformat (i, "push_dot1q %d", &push_dot1q))
9765         ;
9766       else if (unformat (i, "tag1 %d", &tag1))
9767         ;
9768       else if (unformat (i, "tag2 %d", &tag2))
9769         ;
9770       else
9771         {
9772           clib_warning ("parse error '%U'", format_unformat_error, i);
9773           return -99;
9774         }
9775     }
9776
9777   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
9778     {
9779       errmsg ("missing vtr operation or sw_if_index");
9780       return -99;
9781     }
9782
9783   M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
9784   mp->sw_if_index = ntohl (sw_if_index);
9785   mp->vtr_op = ntohl (vtr_op);
9786   mp->push_dot1q = ntohl (push_dot1q);
9787   mp->tag1 = ntohl (tag1);
9788   mp->tag2 = ntohl (tag2);
9789
9790   S (mp);
9791   W (ret);
9792   return ret;
9793 }
9794
9795 static int
9796 api_create_vhost_user_if (vat_main_t * vam)
9797 {
9798   unformat_input_t *i = vam->input;
9799   vl_api_create_vhost_user_if_t *mp;
9800   u8 *file_name;
9801   u8 is_server = 0;
9802   u8 file_name_set = 0;
9803   u32 custom_dev_instance = ~0;
9804   u8 hwaddr[6];
9805   u8 use_custom_mac = 0;
9806   u8 disable_mrg_rxbuf = 0;
9807   u8 disable_indirect_desc = 0;
9808   u8 *tag = 0;
9809   u8 enable_gso = 0;
9810   u8 enable_packed = 0;
9811   int ret;
9812
9813   /* Shut up coverity */
9814   clib_memset (hwaddr, 0, sizeof (hwaddr));
9815
9816   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9817     {
9818       if (unformat (i, "socket %s", &file_name))
9819         {
9820           file_name_set = 1;
9821         }
9822       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
9823         ;
9824       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
9825         use_custom_mac = 1;
9826       else if (unformat (i, "server"))
9827         is_server = 1;
9828       else if (unformat (i, "disable_mrg_rxbuf"))
9829         disable_mrg_rxbuf = 1;
9830       else if (unformat (i, "disable_indirect_desc"))
9831         disable_indirect_desc = 1;
9832       else if (unformat (i, "gso"))
9833         enable_gso = 1;
9834       else if (unformat (i, "packed"))
9835         enable_packed = 1;
9836       else if (unformat (i, "tag %s", &tag))
9837         ;
9838       else
9839         break;
9840     }
9841
9842   if (file_name_set == 0)
9843     {
9844       errmsg ("missing socket file name");
9845       return -99;
9846     }
9847
9848   if (vec_len (file_name) > 255)
9849     {
9850       errmsg ("socket file name too long");
9851       return -99;
9852     }
9853   vec_add1 (file_name, 0);
9854
9855   M (CREATE_VHOST_USER_IF, mp);
9856
9857   mp->is_server = is_server;
9858   mp->disable_mrg_rxbuf = disable_mrg_rxbuf;
9859   mp->disable_indirect_desc = disable_indirect_desc;
9860   mp->enable_gso = enable_gso;
9861   mp->enable_packed = enable_packed;
9862   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
9863   vec_free (file_name);
9864   if (custom_dev_instance != ~0)
9865     {
9866       mp->renumber = 1;
9867       mp->custom_dev_instance = ntohl (custom_dev_instance);
9868     }
9869
9870   mp->use_custom_mac = use_custom_mac;
9871   clib_memcpy (mp->mac_address, hwaddr, 6);
9872   if (tag)
9873     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
9874   vec_free (tag);
9875
9876   S (mp);
9877   W (ret);
9878   return ret;
9879 }
9880
9881 static int
9882 api_modify_vhost_user_if (vat_main_t * vam)
9883 {
9884   unformat_input_t *i = vam->input;
9885   vl_api_modify_vhost_user_if_t *mp;
9886   u8 *file_name;
9887   u8 is_server = 0;
9888   u8 file_name_set = 0;
9889   u32 custom_dev_instance = ~0;
9890   u8 sw_if_index_set = 0;
9891   u32 sw_if_index = (u32) ~ 0;
9892   u8 enable_gso = 0;
9893   u8 enable_packed = 0;
9894   int ret;
9895
9896   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9897     {
9898       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9899         sw_if_index_set = 1;
9900       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9901         sw_if_index_set = 1;
9902       else if (unformat (i, "socket %s", &file_name))
9903         {
9904           file_name_set = 1;
9905         }
9906       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
9907         ;
9908       else if (unformat (i, "server"))
9909         is_server = 1;
9910       else if (unformat (i, "gso"))
9911         enable_gso = 1;
9912       else if (unformat (i, "packed"))
9913         enable_packed = 1;
9914       else
9915         break;
9916     }
9917
9918   if (sw_if_index_set == 0)
9919     {
9920       errmsg ("missing sw_if_index or interface name");
9921       return -99;
9922     }
9923
9924   if (file_name_set == 0)
9925     {
9926       errmsg ("missing socket file name");
9927       return -99;
9928     }
9929
9930   if (vec_len (file_name) > 255)
9931     {
9932       errmsg ("socket file name too long");
9933       return -99;
9934     }
9935   vec_add1 (file_name, 0);
9936
9937   M (MODIFY_VHOST_USER_IF, mp);
9938
9939   mp->sw_if_index = ntohl (sw_if_index);
9940   mp->is_server = is_server;
9941   mp->enable_gso = enable_gso;
9942   mp->enable_packed = enable_packed;
9943   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
9944   vec_free (file_name);
9945   if (custom_dev_instance != ~0)
9946     {
9947       mp->renumber = 1;
9948       mp->custom_dev_instance = ntohl (custom_dev_instance);
9949     }
9950
9951   S (mp);
9952   W (ret);
9953   return ret;
9954 }
9955
9956 static int
9957 api_delete_vhost_user_if (vat_main_t * vam)
9958 {
9959   unformat_input_t *i = vam->input;
9960   vl_api_delete_vhost_user_if_t *mp;
9961   u32 sw_if_index = ~0;
9962   u8 sw_if_index_set = 0;
9963   int ret;
9964
9965   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9966     {
9967       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9968         sw_if_index_set = 1;
9969       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9970         sw_if_index_set = 1;
9971       else
9972         break;
9973     }
9974
9975   if (sw_if_index_set == 0)
9976     {
9977       errmsg ("missing sw_if_index or interface name");
9978       return -99;
9979     }
9980
9981
9982   M (DELETE_VHOST_USER_IF, mp);
9983
9984   mp->sw_if_index = ntohl (sw_if_index);
9985
9986   S (mp);
9987   W (ret);
9988   return ret;
9989 }
9990
9991 static void vl_api_sw_interface_vhost_user_details_t_handler
9992   (vl_api_sw_interface_vhost_user_details_t * mp)
9993 {
9994   vat_main_t *vam = &vat_main;
9995   u64 features;
9996
9997   features =
9998     clib_net_to_host_u32 (mp->features_first_32) | ((u64)
9999                                                     clib_net_to_host_u32
10000                                                     (mp->features_last_32) <<
10001                                                     32);
10002
10003   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s",
10004          (char *) mp->interface_name,
10005          ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
10006          features, mp->is_server,
10007          ntohl (mp->num_regions), (char *) mp->sock_filename);
10008   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
10009 }
10010
10011 static void vl_api_sw_interface_vhost_user_details_t_handler_json
10012   (vl_api_sw_interface_vhost_user_details_t * mp)
10013 {
10014   vat_main_t *vam = &vat_main;
10015   vat_json_node_t *node = NULL;
10016
10017   if (VAT_JSON_ARRAY != vam->json_tree.type)
10018     {
10019       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10020       vat_json_init_array (&vam->json_tree);
10021     }
10022   node = vat_json_array_add (&vam->json_tree);
10023
10024   vat_json_init_object (node);
10025   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10026   vat_json_object_add_string_copy (node, "interface_name",
10027                                    mp->interface_name);
10028   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
10029                             ntohl (mp->virtio_net_hdr_sz));
10030   vat_json_object_add_uint (node, "features_first_32",
10031                             clib_net_to_host_u32 (mp->features_first_32));
10032   vat_json_object_add_uint (node, "features_last_32",
10033                             clib_net_to_host_u32 (mp->features_last_32));
10034   vat_json_object_add_uint (node, "is_server", mp->is_server);
10035   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
10036   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
10037   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
10038 }
10039
10040 static int
10041 api_sw_interface_vhost_user_dump (vat_main_t * vam)
10042 {
10043   unformat_input_t *i = vam->input;
10044   vl_api_sw_interface_vhost_user_dump_t *mp;
10045   vl_api_control_ping_t *mp_ping;
10046   int ret;
10047   u32 sw_if_index = ~0;
10048
10049   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10050     {
10051       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10052         ;
10053       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10054         ;
10055       else
10056         break;
10057     }
10058
10059   print (vam->ofp,
10060          "Interface name            idx hdr_sz features server regions filename");
10061
10062   /* Get list of vhost-user interfaces */
10063   M (SW_INTERFACE_VHOST_USER_DUMP, mp);
10064   mp->sw_if_index = ntohl (sw_if_index);
10065   S (mp);
10066
10067   /* Use a control ping for synchronization */
10068   MPING (CONTROL_PING, mp_ping);
10069   S (mp_ping);
10070
10071   W (ret);
10072   return ret;
10073 }
10074
10075 static int
10076 api_show_version (vat_main_t * vam)
10077 {
10078   vl_api_show_version_t *mp;
10079   int ret;
10080
10081   M (SHOW_VERSION, mp);
10082
10083   S (mp);
10084   W (ret);
10085   return ret;
10086 }
10087
10088
10089 static int
10090 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
10091 {
10092   unformat_input_t *line_input = vam->input;
10093   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
10094   ip46_address_t local, remote;
10095   u8 is_add = 1;
10096   u8 local_set = 0;
10097   u8 remote_set = 0;
10098   u8 grp_set = 0;
10099   u32 mcast_sw_if_index = ~0;
10100   u32 encap_vrf_id = 0;
10101   u32 decap_vrf_id = 0;
10102   u8 protocol = ~0;
10103   u32 vni;
10104   u8 vni_set = 0;
10105   int ret;
10106
10107   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10108     {
10109       if (unformat (line_input, "del"))
10110         is_add = 0;
10111       else if (unformat (line_input, "local %U",
10112                          unformat_ip46_address, &local))
10113         {
10114           local_set = 1;
10115         }
10116       else if (unformat (line_input, "remote %U",
10117                          unformat_ip46_address, &remote))
10118         {
10119           remote_set = 1;
10120         }
10121       else if (unformat (line_input, "group %U %U",
10122                          unformat_ip46_address, &remote,
10123                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
10124         {
10125           grp_set = remote_set = 1;
10126         }
10127       else if (unformat (line_input, "group %U",
10128                          unformat_ip46_address, &remote))
10129         {
10130           grp_set = remote_set = 1;
10131         }
10132       else
10133         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
10134         ;
10135       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
10136         ;
10137       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
10138         ;
10139       else if (unformat (line_input, "vni %d", &vni))
10140         vni_set = 1;
10141       else if (unformat (line_input, "next-ip4"))
10142         protocol = 1;
10143       else if (unformat (line_input, "next-ip6"))
10144         protocol = 2;
10145       else if (unformat (line_input, "next-ethernet"))
10146         protocol = 3;
10147       else if (unformat (line_input, "next-nsh"))
10148         protocol = 4;
10149       else
10150         {
10151           errmsg ("parse error '%U'", format_unformat_error, line_input);
10152           return -99;
10153         }
10154     }
10155
10156   if (local_set == 0)
10157     {
10158       errmsg ("tunnel local address not specified");
10159       return -99;
10160     }
10161   if (remote_set == 0)
10162     {
10163       errmsg ("tunnel remote address not specified");
10164       return -99;
10165     }
10166   if (grp_set && mcast_sw_if_index == ~0)
10167     {
10168       errmsg ("tunnel nonexistent multicast device");
10169       return -99;
10170     }
10171   if (ip46_address_is_ip4 (&local) != ip46_address_is_ip4 (&remote))
10172     {
10173       errmsg ("both IPv4 and IPv6 addresses specified");
10174       return -99;
10175     }
10176
10177   if (vni_set == 0)
10178     {
10179       errmsg ("vni not specified");
10180       return -99;
10181     }
10182
10183   M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
10184
10185   ip_address_encode (&local,
10186                      ip46_address_is_ip4 (&local) ? IP46_TYPE_IP4 :
10187                      IP46_TYPE_IP6, &mp->local);
10188   ip_address_encode (&remote,
10189                      ip46_address_is_ip4 (&remote) ? IP46_TYPE_IP4 :
10190                      IP46_TYPE_IP6, &mp->remote);
10191
10192   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
10193   mp->encap_vrf_id = ntohl (encap_vrf_id);
10194   mp->decap_vrf_id = ntohl (decap_vrf_id);
10195   mp->protocol = protocol;
10196   mp->vni = ntohl (vni);
10197   mp->is_add = is_add;
10198
10199   S (mp);
10200   W (ret);
10201   return ret;
10202 }
10203
10204 static void vl_api_vxlan_gpe_tunnel_details_t_handler
10205   (vl_api_vxlan_gpe_tunnel_details_t * mp)
10206 {
10207   vat_main_t *vam = &vat_main;
10208   ip46_address_t local, remote;
10209
10210   ip_address_decode (&mp->local, &local);
10211   ip_address_decode (&mp->remote, &remote);
10212
10213   print (vam->ofp, "%11d%24U%24U%13d%12d%19d%14d%14d",
10214          ntohl (mp->sw_if_index),
10215          format_ip46_address, &local, IP46_TYPE_ANY,
10216          format_ip46_address, &remote, IP46_TYPE_ANY,
10217          ntohl (mp->vni), mp->protocol,
10218          ntohl (mp->mcast_sw_if_index),
10219          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
10220 }
10221
10222
10223 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
10224   (vl_api_vxlan_gpe_tunnel_details_t * mp)
10225 {
10226   vat_main_t *vam = &vat_main;
10227   vat_json_node_t *node = NULL;
10228   struct in_addr ip4;
10229   struct in6_addr ip6;
10230   ip46_address_t local, remote;
10231
10232   ip_address_decode (&mp->local, &local);
10233   ip_address_decode (&mp->remote, &remote);
10234
10235   if (VAT_JSON_ARRAY != vam->json_tree.type)
10236     {
10237       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10238       vat_json_init_array (&vam->json_tree);
10239     }
10240   node = vat_json_array_add (&vam->json_tree);
10241
10242   vat_json_init_object (node);
10243   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10244   if (ip46_address_is_ip4 (&local))
10245     {
10246       clib_memcpy (&ip4, &local.ip4, sizeof (ip4));
10247       vat_json_object_add_ip4 (node, "local", ip4);
10248       clib_memcpy (&ip4, &remote.ip4, sizeof (ip4));
10249       vat_json_object_add_ip4 (node, "remote", ip4);
10250     }
10251   else
10252     {
10253       clib_memcpy (&ip6, &local.ip6, sizeof (ip6));
10254       vat_json_object_add_ip6 (node, "local", ip6);
10255       clib_memcpy (&ip6, &remote.ip6, sizeof (ip6));
10256       vat_json_object_add_ip6 (node, "remote", ip6);
10257     }
10258   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
10259   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
10260   vat_json_object_add_uint (node, "mcast_sw_if_index",
10261                             ntohl (mp->mcast_sw_if_index));
10262   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
10263   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
10264   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
10265 }
10266
10267 static int
10268 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
10269 {
10270   unformat_input_t *i = vam->input;
10271   vl_api_vxlan_gpe_tunnel_dump_t *mp;
10272   vl_api_control_ping_t *mp_ping;
10273   u32 sw_if_index;
10274   u8 sw_if_index_set = 0;
10275   int ret;
10276
10277   /* Parse args required to build the message */
10278   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10279     {
10280       if (unformat (i, "sw_if_index %d", &sw_if_index))
10281         sw_if_index_set = 1;
10282       else
10283         break;
10284     }
10285
10286   if (sw_if_index_set == 0)
10287     {
10288       sw_if_index = ~0;
10289     }
10290
10291   if (!vam->json_output)
10292     {
10293       print (vam->ofp, "%11s%24s%24s%13s%15s%19s%14s%14s",
10294              "sw_if_index", "local", "remote", "vni",
10295              "protocol", "mcast_sw_if_index", "encap_vrf_id", "decap_vrf_id");
10296     }
10297
10298   /* Get list of vxlan-tunnel interfaces */
10299   M (VXLAN_GPE_TUNNEL_DUMP, mp);
10300
10301   mp->sw_if_index = htonl (sw_if_index);
10302
10303   S (mp);
10304
10305   /* Use a control ping for synchronization */
10306   MPING (CONTROL_PING, mp_ping);
10307   S (mp_ping);
10308
10309   W (ret);
10310   return ret;
10311 }
10312
10313 static void vl_api_l2_fib_table_details_t_handler
10314   (vl_api_l2_fib_table_details_t * mp)
10315 {
10316   vat_main_t *vam = &vat_main;
10317
10318   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
10319          "       %d       %d     %d",
10320          ntohl (mp->bd_id), format_ethernet_address, mp->mac,
10321          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
10322          mp->bvi_mac);
10323 }
10324
10325 static void vl_api_l2_fib_table_details_t_handler_json
10326   (vl_api_l2_fib_table_details_t * mp)
10327 {
10328   vat_main_t *vam = &vat_main;
10329   vat_json_node_t *node = NULL;
10330
10331   if (VAT_JSON_ARRAY != vam->json_tree.type)
10332     {
10333       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10334       vat_json_init_array (&vam->json_tree);
10335     }
10336   node = vat_json_array_add (&vam->json_tree);
10337
10338   vat_json_init_object (node);
10339   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
10340   vat_json_object_add_bytes (node, "mac", mp->mac, 6);
10341   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10342   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
10343   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
10344   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
10345 }
10346
10347 static int
10348 api_l2_fib_table_dump (vat_main_t * vam)
10349 {
10350   unformat_input_t *i = vam->input;
10351   vl_api_l2_fib_table_dump_t *mp;
10352   vl_api_control_ping_t *mp_ping;
10353   u32 bd_id;
10354   u8 bd_id_set = 0;
10355   int ret;
10356
10357   /* Parse args required to build the message */
10358   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10359     {
10360       if (unformat (i, "bd_id %d", &bd_id))
10361         bd_id_set = 1;
10362       else
10363         break;
10364     }
10365
10366   if (bd_id_set == 0)
10367     {
10368       errmsg ("missing bridge domain");
10369       return -99;
10370     }
10371
10372   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
10373
10374   /* Get list of l2 fib entries */
10375   M (L2_FIB_TABLE_DUMP, mp);
10376
10377   mp->bd_id = ntohl (bd_id);
10378   S (mp);
10379
10380   /* Use a control ping for synchronization */
10381   MPING (CONTROL_PING, mp_ping);
10382   S (mp_ping);
10383
10384   W (ret);
10385   return ret;
10386 }
10387
10388
10389 static int
10390 api_interface_name_renumber (vat_main_t * vam)
10391 {
10392   unformat_input_t *line_input = vam->input;
10393   vl_api_interface_name_renumber_t *mp;
10394   u32 sw_if_index = ~0;
10395   u32 new_show_dev_instance = ~0;
10396   int ret;
10397
10398   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10399     {
10400       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
10401                     &sw_if_index))
10402         ;
10403       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
10404         ;
10405       else if (unformat (line_input, "new_show_dev_instance %d",
10406                          &new_show_dev_instance))
10407         ;
10408       else
10409         break;
10410     }
10411
10412   if (sw_if_index == ~0)
10413     {
10414       errmsg ("missing interface name or sw_if_index");
10415       return -99;
10416     }
10417
10418   if (new_show_dev_instance == ~0)
10419     {
10420       errmsg ("missing new_show_dev_instance");
10421       return -99;
10422     }
10423
10424   M (INTERFACE_NAME_RENUMBER, mp);
10425
10426   mp->sw_if_index = ntohl (sw_if_index);
10427   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
10428
10429   S (mp);
10430   W (ret);
10431   return ret;
10432 }
10433
10434 static int
10435 api_want_l2_macs_events (vat_main_t * vam)
10436 {
10437   unformat_input_t *line_input = vam->input;
10438   vl_api_want_l2_macs_events_t *mp;
10439   u8 enable_disable = 1;
10440   u32 scan_delay = 0;
10441   u32 max_macs_in_event = 0;
10442   u32 learn_limit = 0;
10443   int ret;
10444
10445   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10446     {
10447       if (unformat (line_input, "learn-limit %d", &learn_limit))
10448         ;
10449       else if (unformat (line_input, "scan-delay %d", &scan_delay))
10450         ;
10451       else if (unformat (line_input, "max-entries %d", &max_macs_in_event))
10452         ;
10453       else if (unformat (line_input, "disable"))
10454         enable_disable = 0;
10455       else
10456         break;
10457     }
10458
10459   M (WANT_L2_MACS_EVENTS, mp);
10460   mp->enable_disable = enable_disable;
10461   mp->pid = htonl (getpid ());
10462   mp->learn_limit = htonl (learn_limit);
10463   mp->scan_delay = (u8) scan_delay;
10464   mp->max_macs_in_event = (u8) (max_macs_in_event / 10);
10465   S (mp);
10466   W (ret);
10467   return ret;
10468 }
10469
10470 static int
10471 api_input_acl_set_interface (vat_main_t * vam)
10472 {
10473   unformat_input_t *i = vam->input;
10474   vl_api_input_acl_set_interface_t *mp;
10475   u32 sw_if_index;
10476   int sw_if_index_set;
10477   u32 ip4_table_index = ~0;
10478   u32 ip6_table_index = ~0;
10479   u32 l2_table_index = ~0;
10480   u8 is_add = 1;
10481   int ret;
10482
10483   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10484     {
10485       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10486         sw_if_index_set = 1;
10487       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10488         sw_if_index_set = 1;
10489       else if (unformat (i, "del"))
10490         is_add = 0;
10491       else if (unformat (i, "ip4-table %d", &ip4_table_index))
10492         ;
10493       else if (unformat (i, "ip6-table %d", &ip6_table_index))
10494         ;
10495       else if (unformat (i, "l2-table %d", &l2_table_index))
10496         ;
10497       else
10498         {
10499           clib_warning ("parse error '%U'", format_unformat_error, i);
10500           return -99;
10501         }
10502     }
10503
10504   if (sw_if_index_set == 0)
10505     {
10506       errmsg ("missing interface name or sw_if_index");
10507       return -99;
10508     }
10509
10510   M (INPUT_ACL_SET_INTERFACE, mp);
10511
10512   mp->sw_if_index = ntohl (sw_if_index);
10513   mp->ip4_table_index = ntohl (ip4_table_index);
10514   mp->ip6_table_index = ntohl (ip6_table_index);
10515   mp->l2_table_index = ntohl (l2_table_index);
10516   mp->is_add = is_add;
10517
10518   S (mp);
10519   W (ret);
10520   return ret;
10521 }
10522
10523 static int
10524 api_output_acl_set_interface (vat_main_t * vam)
10525 {
10526   unformat_input_t *i = vam->input;
10527   vl_api_output_acl_set_interface_t *mp;
10528   u32 sw_if_index;
10529   int sw_if_index_set;
10530   u32 ip4_table_index = ~0;
10531   u32 ip6_table_index = ~0;
10532   u32 l2_table_index = ~0;
10533   u8 is_add = 1;
10534   int ret;
10535
10536   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10537     {
10538       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10539         sw_if_index_set = 1;
10540       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10541         sw_if_index_set = 1;
10542       else if (unformat (i, "del"))
10543         is_add = 0;
10544       else if (unformat (i, "ip4-table %d", &ip4_table_index))
10545         ;
10546       else if (unformat (i, "ip6-table %d", &ip6_table_index))
10547         ;
10548       else if (unformat (i, "l2-table %d", &l2_table_index))
10549         ;
10550       else
10551         {
10552           clib_warning ("parse error '%U'", format_unformat_error, i);
10553           return -99;
10554         }
10555     }
10556
10557   if (sw_if_index_set == 0)
10558     {
10559       errmsg ("missing interface name or sw_if_index");
10560       return -99;
10561     }
10562
10563   M (OUTPUT_ACL_SET_INTERFACE, mp);
10564
10565   mp->sw_if_index = ntohl (sw_if_index);
10566   mp->ip4_table_index = ntohl (ip4_table_index);
10567   mp->ip6_table_index = ntohl (ip6_table_index);
10568   mp->l2_table_index = ntohl (l2_table_index);
10569   mp->is_add = is_add;
10570
10571   S (mp);
10572   W (ret);
10573   return ret;
10574 }
10575
10576 static int
10577 api_ip_address_dump (vat_main_t * vam)
10578 {
10579   unformat_input_t *i = vam->input;
10580   vl_api_ip_address_dump_t *mp;
10581   vl_api_control_ping_t *mp_ping;
10582   u32 sw_if_index = ~0;
10583   u8 sw_if_index_set = 0;
10584   u8 ipv4_set = 0;
10585   u8 ipv6_set = 0;
10586   int ret;
10587
10588   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10589     {
10590       if (unformat (i, "sw_if_index %d", &sw_if_index))
10591         sw_if_index_set = 1;
10592       else
10593         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10594         sw_if_index_set = 1;
10595       else if (unformat (i, "ipv4"))
10596         ipv4_set = 1;
10597       else if (unformat (i, "ipv6"))
10598         ipv6_set = 1;
10599       else
10600         break;
10601     }
10602
10603   if (ipv4_set && ipv6_set)
10604     {
10605       errmsg ("ipv4 and ipv6 flags cannot be both set");
10606       return -99;
10607     }
10608
10609   if ((!ipv4_set) && (!ipv6_set))
10610     {
10611       errmsg ("no ipv4 nor ipv6 flag set");
10612       return -99;
10613     }
10614
10615   if (sw_if_index_set == 0)
10616     {
10617       errmsg ("missing interface name or sw_if_index");
10618       return -99;
10619     }
10620
10621   vam->current_sw_if_index = sw_if_index;
10622   vam->is_ipv6 = ipv6_set;
10623
10624   M (IP_ADDRESS_DUMP, mp);
10625   mp->sw_if_index = ntohl (sw_if_index);
10626   mp->is_ipv6 = ipv6_set;
10627   S (mp);
10628
10629   /* Use a control ping for synchronization */
10630   MPING (CONTROL_PING, mp_ping);
10631   S (mp_ping);
10632
10633   W (ret);
10634   return ret;
10635 }
10636
10637 static int
10638 api_ip_dump (vat_main_t * vam)
10639 {
10640   vl_api_ip_dump_t *mp;
10641   vl_api_control_ping_t *mp_ping;
10642   unformat_input_t *in = vam->input;
10643   int ipv4_set = 0;
10644   int ipv6_set = 0;
10645   int is_ipv6;
10646   int i;
10647   int ret;
10648
10649   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
10650     {
10651       if (unformat (in, "ipv4"))
10652         ipv4_set = 1;
10653       else if (unformat (in, "ipv6"))
10654         ipv6_set = 1;
10655       else
10656         break;
10657     }
10658
10659   if (ipv4_set && ipv6_set)
10660     {
10661       errmsg ("ipv4 and ipv6 flags cannot be both set");
10662       return -99;
10663     }
10664
10665   if ((!ipv4_set) && (!ipv6_set))
10666     {
10667       errmsg ("no ipv4 nor ipv6 flag set");
10668       return -99;
10669     }
10670
10671   is_ipv6 = ipv6_set;
10672   vam->is_ipv6 = is_ipv6;
10673
10674   /* free old data */
10675   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
10676     {
10677       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
10678     }
10679   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
10680
10681   M (IP_DUMP, mp);
10682   mp->is_ipv6 = ipv6_set;
10683   S (mp);
10684
10685   /* Use a control ping for synchronization */
10686   MPING (CONTROL_PING, mp_ping);
10687   S (mp_ping);
10688
10689   W (ret);
10690   return ret;
10691 }
10692
10693 static int
10694 api_ipsec_spd_add_del (vat_main_t * vam)
10695 {
10696   unformat_input_t *i = vam->input;
10697   vl_api_ipsec_spd_add_del_t *mp;
10698   u32 spd_id = ~0;
10699   u8 is_add = 1;
10700   int ret;
10701
10702   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10703     {
10704       if (unformat (i, "spd_id %d", &spd_id))
10705         ;
10706       else if (unformat (i, "del"))
10707         is_add = 0;
10708       else
10709         {
10710           clib_warning ("parse error '%U'", format_unformat_error, i);
10711           return -99;
10712         }
10713     }
10714   if (spd_id == ~0)
10715     {
10716       errmsg ("spd_id must be set");
10717       return -99;
10718     }
10719
10720   M (IPSEC_SPD_ADD_DEL, mp);
10721
10722   mp->spd_id = ntohl (spd_id);
10723   mp->is_add = is_add;
10724
10725   S (mp);
10726   W (ret);
10727   return ret;
10728 }
10729
10730 static int
10731 api_ipsec_interface_add_del_spd (vat_main_t * vam)
10732 {
10733   unformat_input_t *i = vam->input;
10734   vl_api_ipsec_interface_add_del_spd_t *mp;
10735   u32 sw_if_index;
10736   u8 sw_if_index_set = 0;
10737   u32 spd_id = (u32) ~ 0;
10738   u8 is_add = 1;
10739   int ret;
10740
10741   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10742     {
10743       if (unformat (i, "del"))
10744         is_add = 0;
10745       else if (unformat (i, "spd_id %d", &spd_id))
10746         ;
10747       else
10748         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10749         sw_if_index_set = 1;
10750       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10751         sw_if_index_set = 1;
10752       else
10753         {
10754           clib_warning ("parse error '%U'", format_unformat_error, i);
10755           return -99;
10756         }
10757
10758     }
10759
10760   if (spd_id == (u32) ~ 0)
10761     {
10762       errmsg ("spd_id must be set");
10763       return -99;
10764     }
10765
10766   if (sw_if_index_set == 0)
10767     {
10768       errmsg ("missing interface name or sw_if_index");
10769       return -99;
10770     }
10771
10772   M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
10773
10774   mp->spd_id = ntohl (spd_id);
10775   mp->sw_if_index = ntohl (sw_if_index);
10776   mp->is_add = is_add;
10777
10778   S (mp);
10779   W (ret);
10780   return ret;
10781 }
10782
10783 static int
10784 api_ipsec_spd_entry_add_del (vat_main_t * vam)
10785 {
10786   unformat_input_t *i = vam->input;
10787   vl_api_ipsec_spd_entry_add_del_t *mp;
10788   u8 is_add = 1, is_outbound = 0;
10789   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
10790   i32 priority = 0;
10791   u32 rport_start = 0, rport_stop = (u32) ~ 0;
10792   u32 lport_start = 0, lport_stop = (u32) ~ 0;
10793   vl_api_address_t laddr_start = { }, laddr_stop =
10794   {
10795   }, raddr_start =
10796   {
10797   }, raddr_stop =
10798   {
10799   };
10800   int ret;
10801
10802   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10803     {
10804       if (unformat (i, "del"))
10805         is_add = 0;
10806       if (unformat (i, "outbound"))
10807         is_outbound = 1;
10808       if (unformat (i, "inbound"))
10809         is_outbound = 0;
10810       else if (unformat (i, "spd_id %d", &spd_id))
10811         ;
10812       else if (unformat (i, "sa_id %d", &sa_id))
10813         ;
10814       else if (unformat (i, "priority %d", &priority))
10815         ;
10816       else if (unformat (i, "protocol %d", &protocol))
10817         ;
10818       else if (unformat (i, "lport_start %d", &lport_start))
10819         ;
10820       else if (unformat (i, "lport_stop %d", &lport_stop))
10821         ;
10822       else if (unformat (i, "rport_start %d", &rport_start))
10823         ;
10824       else if (unformat (i, "rport_stop %d", &rport_stop))
10825         ;
10826       else if (unformat (i, "laddr_start %U",
10827                          unformat_vl_api_address, &laddr_start))
10828         ;
10829       else if (unformat (i, "laddr_stop %U", unformat_vl_api_address,
10830                          &laddr_stop))
10831         ;
10832       else if (unformat (i, "raddr_start %U", unformat_vl_api_address,
10833                          &raddr_start))
10834         ;
10835       else if (unformat (i, "raddr_stop %U", unformat_vl_api_address,
10836                          &raddr_stop))
10837         ;
10838       else
10839         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
10840         {
10841           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
10842             {
10843               clib_warning ("unsupported action: 'resolve'");
10844               return -99;
10845             }
10846         }
10847       else
10848         {
10849           clib_warning ("parse error '%U'", format_unformat_error, i);
10850           return -99;
10851         }
10852
10853     }
10854
10855   M (IPSEC_SPD_ENTRY_ADD_DEL, mp);
10856
10857   mp->is_add = is_add;
10858
10859   mp->entry.spd_id = ntohl (spd_id);
10860   mp->entry.priority = ntohl (priority);
10861   mp->entry.is_outbound = is_outbound;
10862
10863   clib_memcpy (&mp->entry.remote_address_start, &raddr_start,
10864                sizeof (vl_api_address_t));
10865   clib_memcpy (&mp->entry.remote_address_stop, &raddr_stop,
10866                sizeof (vl_api_address_t));
10867   clib_memcpy (&mp->entry.local_address_start, &laddr_start,
10868                sizeof (vl_api_address_t));
10869   clib_memcpy (&mp->entry.local_address_stop, &laddr_stop,
10870                sizeof (vl_api_address_t));
10871
10872   mp->entry.protocol = (u8) protocol;
10873   mp->entry.local_port_start = ntohs ((u16) lport_start);
10874   mp->entry.local_port_stop = ntohs ((u16) lport_stop);
10875   mp->entry.remote_port_start = ntohs ((u16) rport_start);
10876   mp->entry.remote_port_stop = ntohs ((u16) rport_stop);
10877   mp->entry.policy = (u8) policy;
10878   mp->entry.sa_id = ntohl (sa_id);
10879
10880   S (mp);
10881   W (ret);
10882   return ret;
10883 }
10884
10885 static int
10886 api_ipsec_sad_entry_add_del (vat_main_t * vam)
10887 {
10888   unformat_input_t *i = vam->input;
10889   vl_api_ipsec_sad_entry_add_del_t *mp;
10890   u32 sad_id = 0, spi = 0;
10891   u8 *ck = 0, *ik = 0;
10892   u8 is_add = 1;
10893
10894   vl_api_ipsec_crypto_alg_t crypto_alg = IPSEC_API_CRYPTO_ALG_NONE;
10895   vl_api_ipsec_integ_alg_t integ_alg = IPSEC_API_INTEG_ALG_NONE;
10896   vl_api_ipsec_sad_flags_t flags = IPSEC_API_SAD_FLAG_NONE;
10897   vl_api_ipsec_proto_t protocol = IPSEC_API_PROTO_AH;
10898   vl_api_address_t tun_src, tun_dst;
10899   int ret;
10900
10901   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10902     {
10903       if (unformat (i, "del"))
10904         is_add = 0;
10905       else if (unformat (i, "sad_id %d", &sad_id))
10906         ;
10907       else if (unformat (i, "spi %d", &spi))
10908         ;
10909       else if (unformat (i, "esp"))
10910         protocol = IPSEC_API_PROTO_ESP;
10911       else
10912         if (unformat (i, "tunnel_src %U", unformat_vl_api_address, &tun_src))
10913         {
10914           flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL;
10915           if (ADDRESS_IP6 == tun_src.af)
10916             flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL_V6;
10917         }
10918       else
10919         if (unformat (i, "tunnel_dst %U", unformat_vl_api_address, &tun_dst))
10920         {
10921           flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL;
10922           if (ADDRESS_IP6 == tun_src.af)
10923             flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL_V6;
10924         }
10925       else
10926         if (unformat (i, "crypto_alg %U",
10927                       unformat_ipsec_api_crypto_alg, &crypto_alg))
10928         ;
10929       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
10930         ;
10931       else if (unformat (i, "integ_alg %U",
10932                          unformat_ipsec_api_integ_alg, &integ_alg))
10933         ;
10934       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
10935         ;
10936       else
10937         {
10938           clib_warning ("parse error '%U'", format_unformat_error, i);
10939           return -99;
10940         }
10941
10942     }
10943
10944   M (IPSEC_SAD_ENTRY_ADD_DEL, mp);
10945
10946   mp->is_add = is_add;
10947   mp->entry.sad_id = ntohl (sad_id);
10948   mp->entry.protocol = protocol;
10949   mp->entry.spi = ntohl (spi);
10950   mp->entry.flags = flags;
10951
10952   mp->entry.crypto_algorithm = crypto_alg;
10953   mp->entry.integrity_algorithm = integ_alg;
10954   mp->entry.crypto_key.length = vec_len (ck);
10955   mp->entry.integrity_key.length = vec_len (ik);
10956
10957   if (mp->entry.crypto_key.length > sizeof (mp->entry.crypto_key.data))
10958     mp->entry.crypto_key.length = sizeof (mp->entry.crypto_key.data);
10959
10960   if (mp->entry.integrity_key.length > sizeof (mp->entry.integrity_key.data))
10961     mp->entry.integrity_key.length = sizeof (mp->entry.integrity_key.data);
10962
10963   if (ck)
10964     clib_memcpy (mp->entry.crypto_key.data, ck, mp->entry.crypto_key.length);
10965   if (ik)
10966     clib_memcpy (mp->entry.integrity_key.data, ik,
10967                  mp->entry.integrity_key.length);
10968
10969   if (flags & IPSEC_API_SAD_FLAG_IS_TUNNEL)
10970     {
10971       clib_memcpy (&mp->entry.tunnel_src, &tun_src,
10972                    sizeof (mp->entry.tunnel_src));
10973       clib_memcpy (&mp->entry.tunnel_dst, &tun_dst,
10974                    sizeof (mp->entry.tunnel_dst));
10975     }
10976
10977   S (mp);
10978   W (ret);
10979   return ret;
10980 }
10981
10982 static void
10983 vl_api_ipsec_sa_details_t_handler (vl_api_ipsec_sa_details_t * mp)
10984 {
10985   vat_main_t *vam = &vat_main;
10986
10987   print (vam->ofp, "sa_id %u sw_if_index %u spi %u proto %u crypto_alg %u "
10988          "crypto_key %U integ_alg %u integ_key %U flags %x "
10989          "tunnel_src_addr %U tunnel_dst_addr %U "
10990          "salt %u seq_outbound %lu last_seq_inbound %lu "
10991          "replay_window %lu stat_index %u\n",
10992          ntohl (mp->entry.sad_id),
10993          ntohl (mp->sw_if_index),
10994          ntohl (mp->entry.spi),
10995          ntohl (mp->entry.protocol),
10996          ntohl (mp->entry.crypto_algorithm),
10997          format_hex_bytes, mp->entry.crypto_key.data,
10998          mp->entry.crypto_key.length, ntohl (mp->entry.integrity_algorithm),
10999          format_hex_bytes, mp->entry.integrity_key.data,
11000          mp->entry.integrity_key.length, ntohl (mp->entry.flags),
11001          format_vl_api_address, &mp->entry.tunnel_src, format_vl_api_address,
11002          &mp->entry.tunnel_dst, ntohl (mp->salt),
11003          clib_net_to_host_u64 (mp->seq_outbound),
11004          clib_net_to_host_u64 (mp->last_seq_inbound),
11005          clib_net_to_host_u64 (mp->replay_window), ntohl (mp->stat_index));
11006 }
11007
11008 #define vl_api_ipsec_sa_details_t_endian vl_noop_handler
11009 #define vl_api_ipsec_sa_details_t_print vl_noop_handler
11010
11011 static void vl_api_ipsec_sa_details_t_handler_json
11012   (vl_api_ipsec_sa_details_t * mp)
11013 {
11014   vat_main_t *vam = &vat_main;
11015   vat_json_node_t *node = NULL;
11016   vl_api_ipsec_sad_flags_t flags;
11017
11018   if (VAT_JSON_ARRAY != vam->json_tree.type)
11019     {
11020       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11021       vat_json_init_array (&vam->json_tree);
11022     }
11023   node = vat_json_array_add (&vam->json_tree);
11024
11025   vat_json_init_object (node);
11026   vat_json_object_add_uint (node, "sa_id", ntohl (mp->entry.sad_id));
11027   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11028   vat_json_object_add_uint (node, "spi", ntohl (mp->entry.spi));
11029   vat_json_object_add_uint (node, "proto", ntohl (mp->entry.protocol));
11030   vat_json_object_add_uint (node, "crypto_alg",
11031                             ntohl (mp->entry.crypto_algorithm));
11032   vat_json_object_add_uint (node, "integ_alg",
11033                             ntohl (mp->entry.integrity_algorithm));
11034   flags = ntohl (mp->entry.flags);
11035   vat_json_object_add_uint (node, "use_esn",
11036                             ! !(flags & IPSEC_API_SAD_FLAG_USE_ESN));
11037   vat_json_object_add_uint (node, "use_anti_replay",
11038                             ! !(flags & IPSEC_API_SAD_FLAG_USE_ANTI_REPLAY));
11039   vat_json_object_add_uint (node, "is_tunnel",
11040                             ! !(flags & IPSEC_API_SAD_FLAG_IS_TUNNEL));
11041   vat_json_object_add_uint (node, "is_tunnel_ip6",
11042                             ! !(flags & IPSEC_API_SAD_FLAG_IS_TUNNEL_V6));
11043   vat_json_object_add_uint (node, "udp_encap",
11044                             ! !(flags & IPSEC_API_SAD_FLAG_UDP_ENCAP));
11045   vat_json_object_add_bytes (node, "crypto_key", mp->entry.crypto_key.data,
11046                              mp->entry.crypto_key.length);
11047   vat_json_object_add_bytes (node, "integ_key", mp->entry.integrity_key.data,
11048                              mp->entry.integrity_key.length);
11049   vat_json_object_add_address (node, "src", &mp->entry.tunnel_src);
11050   vat_json_object_add_address (node, "dst", &mp->entry.tunnel_dst);
11051   vat_json_object_add_uint (node, "replay_window",
11052                             clib_net_to_host_u64 (mp->replay_window));
11053   vat_json_object_add_uint (node, "stat_index", ntohl (mp->stat_index));
11054 }
11055
11056 static int
11057 api_ipsec_sa_dump (vat_main_t * vam)
11058 {
11059   unformat_input_t *i = vam->input;
11060   vl_api_ipsec_sa_dump_t *mp;
11061   vl_api_control_ping_t *mp_ping;
11062   u32 sa_id = ~0;
11063   int ret;
11064
11065   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11066     {
11067       if (unformat (i, "sa_id %d", &sa_id))
11068         ;
11069       else
11070         {
11071           clib_warning ("parse error '%U'", format_unformat_error, i);
11072           return -99;
11073         }
11074     }
11075
11076   M (IPSEC_SA_DUMP, mp);
11077
11078   mp->sa_id = ntohl (sa_id);
11079
11080   S (mp);
11081
11082   /* Use a control ping for synchronization */
11083   M (CONTROL_PING, mp_ping);
11084   S (mp_ping);
11085
11086   W (ret);
11087   return ret;
11088 }
11089
11090 static int
11091 api_get_first_msg_id (vat_main_t * vam)
11092 {
11093   vl_api_get_first_msg_id_t *mp;
11094   unformat_input_t *i = vam->input;
11095   u8 *name;
11096   u8 name_set = 0;
11097   int ret;
11098
11099   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11100     {
11101       if (unformat (i, "client %s", &name))
11102         name_set = 1;
11103       else
11104         break;
11105     }
11106
11107   if (name_set == 0)
11108     {
11109       errmsg ("missing client name");
11110       return -99;
11111     }
11112   vec_add1 (name, 0);
11113
11114   if (vec_len (name) > 63)
11115     {
11116       errmsg ("client name too long");
11117       return -99;
11118     }
11119
11120   M (GET_FIRST_MSG_ID, mp);
11121   clib_memcpy (mp->name, name, vec_len (name));
11122   S (mp);
11123   W (ret);
11124   return ret;
11125 }
11126
11127 static int
11128 api_cop_interface_enable_disable (vat_main_t * vam)
11129 {
11130   unformat_input_t *line_input = vam->input;
11131   vl_api_cop_interface_enable_disable_t *mp;
11132   u32 sw_if_index = ~0;
11133   u8 enable_disable = 1;
11134   int ret;
11135
11136   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11137     {
11138       if (unformat (line_input, "disable"))
11139         enable_disable = 0;
11140       if (unformat (line_input, "enable"))
11141         enable_disable = 1;
11142       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
11143                          vam, &sw_if_index))
11144         ;
11145       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
11146         ;
11147       else
11148         break;
11149     }
11150
11151   if (sw_if_index == ~0)
11152     {
11153       errmsg ("missing interface name or sw_if_index");
11154       return -99;
11155     }
11156
11157   /* Construct the API message */
11158   M (COP_INTERFACE_ENABLE_DISABLE, mp);
11159   mp->sw_if_index = ntohl (sw_if_index);
11160   mp->enable_disable = enable_disable;
11161
11162   /* send it... */
11163   S (mp);
11164   /* Wait for the reply */
11165   W (ret);
11166   return ret;
11167 }
11168
11169 static int
11170 api_cop_whitelist_enable_disable (vat_main_t * vam)
11171 {
11172   unformat_input_t *line_input = vam->input;
11173   vl_api_cop_whitelist_enable_disable_t *mp;
11174   u32 sw_if_index = ~0;
11175   u8 ip4 = 0, ip6 = 0, default_cop = 0;
11176   u32 fib_id = 0;
11177   int ret;
11178
11179   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11180     {
11181       if (unformat (line_input, "ip4"))
11182         ip4 = 1;
11183       else if (unformat (line_input, "ip6"))
11184         ip6 = 1;
11185       else if (unformat (line_input, "default"))
11186         default_cop = 1;
11187       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
11188                          vam, &sw_if_index))
11189         ;
11190       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
11191         ;
11192       else if (unformat (line_input, "fib-id %d", &fib_id))
11193         ;
11194       else
11195         break;
11196     }
11197
11198   if (sw_if_index == ~0)
11199     {
11200       errmsg ("missing interface name or sw_if_index");
11201       return -99;
11202     }
11203
11204   /* Construct the API message */
11205   M (COP_WHITELIST_ENABLE_DISABLE, mp);
11206   mp->sw_if_index = ntohl (sw_if_index);
11207   mp->fib_id = ntohl (fib_id);
11208   mp->ip4 = ip4;
11209   mp->ip6 = ip6;
11210   mp->default_cop = default_cop;
11211
11212   /* send it... */
11213   S (mp);
11214   /* Wait for the reply */
11215   W (ret);
11216   return ret;
11217 }
11218
11219 static int
11220 api_get_node_graph (vat_main_t * vam)
11221 {
11222   vl_api_get_node_graph_t *mp;
11223   int ret;
11224
11225   M (GET_NODE_GRAPH, mp);
11226
11227   /* send it... */
11228   S (mp);
11229   /* Wait for the reply */
11230   W (ret);
11231   return ret;
11232 }
11233
11234 static int
11235 api_af_packet_create (vat_main_t * vam)
11236 {
11237   unformat_input_t *i = vam->input;
11238   vl_api_af_packet_create_t *mp;
11239   u8 *host_if_name = 0;
11240   u8 hw_addr[6];
11241   u8 random_hw_addr = 1;
11242   int ret;
11243
11244   clib_memset (hw_addr, 0, sizeof (hw_addr));
11245
11246   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11247     {
11248       if (unformat (i, "name %s", &host_if_name))
11249         vec_add1 (host_if_name, 0);
11250       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
11251         random_hw_addr = 0;
11252       else
11253         break;
11254     }
11255
11256   if (!vec_len (host_if_name))
11257     {
11258       errmsg ("host-interface name must be specified");
11259       return -99;
11260     }
11261
11262   if (vec_len (host_if_name) > 64)
11263     {
11264       errmsg ("host-interface name too long");
11265       return -99;
11266     }
11267
11268   M (AF_PACKET_CREATE, mp);
11269
11270   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
11271   clib_memcpy (mp->hw_addr, hw_addr, 6);
11272   mp->use_random_hw_addr = random_hw_addr;
11273   vec_free (host_if_name);
11274
11275   S (mp);
11276
11277   /* *INDENT-OFF* */
11278   W2 (ret,
11279       ({
11280         if (ret == 0)
11281           fprintf (vam->ofp ? vam->ofp : stderr,
11282                    " new sw_if_index = %d\n", vam->sw_if_index);
11283       }));
11284   /* *INDENT-ON* */
11285   return ret;
11286 }
11287
11288 static int
11289 api_af_packet_delete (vat_main_t * vam)
11290 {
11291   unformat_input_t *i = vam->input;
11292   vl_api_af_packet_delete_t *mp;
11293   u8 *host_if_name = 0;
11294   int ret;
11295
11296   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11297     {
11298       if (unformat (i, "name %s", &host_if_name))
11299         vec_add1 (host_if_name, 0);
11300       else
11301         break;
11302     }
11303
11304   if (!vec_len (host_if_name))
11305     {
11306       errmsg ("host-interface name must be specified");
11307       return -99;
11308     }
11309
11310   if (vec_len (host_if_name) > 64)
11311     {
11312       errmsg ("host-interface name too long");
11313       return -99;
11314     }
11315
11316   M (AF_PACKET_DELETE, mp);
11317
11318   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
11319   vec_free (host_if_name);
11320
11321   S (mp);
11322   W (ret);
11323   return ret;
11324 }
11325
11326 static void vl_api_af_packet_details_t_handler
11327   (vl_api_af_packet_details_t * mp)
11328 {
11329   vat_main_t *vam = &vat_main;
11330
11331   print (vam->ofp, "%-16s %d",
11332          mp->host_if_name, clib_net_to_host_u32 (mp->sw_if_index));
11333 }
11334
11335 static void vl_api_af_packet_details_t_handler_json
11336   (vl_api_af_packet_details_t * mp)
11337 {
11338   vat_main_t *vam = &vat_main;
11339   vat_json_node_t *node = NULL;
11340
11341   if (VAT_JSON_ARRAY != vam->json_tree.type)
11342     {
11343       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11344       vat_json_init_array (&vam->json_tree);
11345     }
11346   node = vat_json_array_add (&vam->json_tree);
11347
11348   vat_json_init_object (node);
11349   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11350   vat_json_object_add_string_copy (node, "dev_name", mp->host_if_name);
11351 }
11352
11353 static int
11354 api_af_packet_dump (vat_main_t * vam)
11355 {
11356   vl_api_af_packet_dump_t *mp;
11357   vl_api_control_ping_t *mp_ping;
11358   int ret;
11359
11360   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
11361   /* Get list of tap interfaces */
11362   M (AF_PACKET_DUMP, mp);
11363   S (mp);
11364
11365   /* Use a control ping for synchronization */
11366   MPING (CONTROL_PING, mp_ping);
11367   S (mp_ping);
11368
11369   W (ret);
11370   return ret;
11371 }
11372
11373 static int
11374 api_policer_add_del (vat_main_t * vam)
11375 {
11376   unformat_input_t *i = vam->input;
11377   vl_api_policer_add_del_t *mp;
11378   u8 is_add = 1;
11379   u8 *name = 0;
11380   u32 cir = 0;
11381   u32 eir = 0;
11382   u64 cb = 0;
11383   u64 eb = 0;
11384   u8 rate_type = 0;
11385   u8 round_type = 0;
11386   u8 type = 0;
11387   u8 color_aware = 0;
11388   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
11389   int ret;
11390
11391   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
11392   conform_action.dscp = 0;
11393   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
11394   exceed_action.dscp = 0;
11395   violate_action.action_type = SSE2_QOS_ACTION_DROP;
11396   violate_action.dscp = 0;
11397
11398   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11399     {
11400       if (unformat (i, "del"))
11401         is_add = 0;
11402       else if (unformat (i, "name %s", &name))
11403         vec_add1 (name, 0);
11404       else if (unformat (i, "cir %u", &cir))
11405         ;
11406       else if (unformat (i, "eir %u", &eir))
11407         ;
11408       else if (unformat (i, "cb %u", &cb))
11409         ;
11410       else if (unformat (i, "eb %u", &eb))
11411         ;
11412       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
11413                          &rate_type))
11414         ;
11415       else if (unformat (i, "round_type %U", unformat_policer_round_type,
11416                          &round_type))
11417         ;
11418       else if (unformat (i, "type %U", unformat_policer_type, &type))
11419         ;
11420       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
11421                          &conform_action))
11422         ;
11423       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
11424                          &exceed_action))
11425         ;
11426       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
11427                          &violate_action))
11428         ;
11429       else if (unformat (i, "color-aware"))
11430         color_aware = 1;
11431       else
11432         break;
11433     }
11434
11435   if (!vec_len (name))
11436     {
11437       errmsg ("policer name must be specified");
11438       return -99;
11439     }
11440
11441   if (vec_len (name) > 64)
11442     {
11443       errmsg ("policer name too long");
11444       return -99;
11445     }
11446
11447   M (POLICER_ADD_DEL, mp);
11448
11449   clib_memcpy (mp->name, name, vec_len (name));
11450   vec_free (name);
11451   mp->is_add = is_add;
11452   mp->cir = ntohl (cir);
11453   mp->eir = ntohl (eir);
11454   mp->cb = clib_net_to_host_u64 (cb);
11455   mp->eb = clib_net_to_host_u64 (eb);
11456   mp->rate_type = rate_type;
11457   mp->round_type = round_type;
11458   mp->type = type;
11459   mp->conform_action.type = conform_action.action_type;
11460   mp->conform_action.dscp = conform_action.dscp;
11461   mp->exceed_action.type = exceed_action.action_type;
11462   mp->exceed_action.dscp = exceed_action.dscp;
11463   mp->violate_action.type = violate_action.action_type;
11464   mp->violate_action.dscp = violate_action.dscp;
11465   mp->color_aware = color_aware;
11466
11467   S (mp);
11468   W (ret);
11469   return ret;
11470 }
11471
11472 static int
11473 api_policer_dump (vat_main_t * vam)
11474 {
11475   unformat_input_t *i = vam->input;
11476   vl_api_policer_dump_t *mp;
11477   vl_api_control_ping_t *mp_ping;
11478   u8 *match_name = 0;
11479   u8 match_name_valid = 0;
11480   int ret;
11481
11482   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11483     {
11484       if (unformat (i, "name %s", &match_name))
11485         {
11486           vec_add1 (match_name, 0);
11487           match_name_valid = 1;
11488         }
11489       else
11490         break;
11491     }
11492
11493   M (POLICER_DUMP, mp);
11494   mp->match_name_valid = match_name_valid;
11495   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
11496   vec_free (match_name);
11497   /* send it... */
11498   S (mp);
11499
11500   /* Use a control ping for synchronization */
11501   MPING (CONTROL_PING, mp_ping);
11502   S (mp_ping);
11503
11504   /* Wait for a reply... */
11505   W (ret);
11506   return ret;
11507 }
11508
11509 static int
11510 api_policer_classify_set_interface (vat_main_t * vam)
11511 {
11512   unformat_input_t *i = vam->input;
11513   vl_api_policer_classify_set_interface_t *mp;
11514   u32 sw_if_index;
11515   int sw_if_index_set;
11516   u32 ip4_table_index = ~0;
11517   u32 ip6_table_index = ~0;
11518   u32 l2_table_index = ~0;
11519   u8 is_add = 1;
11520   int ret;
11521
11522   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11523     {
11524       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11525         sw_if_index_set = 1;
11526       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11527         sw_if_index_set = 1;
11528       else if (unformat (i, "del"))
11529         is_add = 0;
11530       else if (unformat (i, "ip4-table %d", &ip4_table_index))
11531         ;
11532       else if (unformat (i, "ip6-table %d", &ip6_table_index))
11533         ;
11534       else if (unformat (i, "l2-table %d", &l2_table_index))
11535         ;
11536       else
11537         {
11538           clib_warning ("parse error '%U'", format_unformat_error, i);
11539           return -99;
11540         }
11541     }
11542
11543   if (sw_if_index_set == 0)
11544     {
11545       errmsg ("missing interface name or sw_if_index");
11546       return -99;
11547     }
11548
11549   M (POLICER_CLASSIFY_SET_INTERFACE, mp);
11550
11551   mp->sw_if_index = ntohl (sw_if_index);
11552   mp->ip4_table_index = ntohl (ip4_table_index);
11553   mp->ip6_table_index = ntohl (ip6_table_index);
11554   mp->l2_table_index = ntohl (l2_table_index);
11555   mp->is_add = is_add;
11556
11557   S (mp);
11558   W (ret);
11559   return ret;
11560 }
11561
11562 static int
11563 api_policer_classify_dump (vat_main_t * vam)
11564 {
11565   unformat_input_t *i = vam->input;
11566   vl_api_policer_classify_dump_t *mp;
11567   vl_api_control_ping_t *mp_ping;
11568   u8 type = POLICER_CLASSIFY_N_TABLES;
11569   int ret;
11570
11571   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
11572     ;
11573   else
11574     {
11575       errmsg ("classify table type must be specified");
11576       return -99;
11577     }
11578
11579   if (!vam->json_output)
11580     {
11581       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
11582     }
11583
11584   M (POLICER_CLASSIFY_DUMP, mp);
11585   mp->type = type;
11586   /* send it... */
11587   S (mp);
11588
11589   /* Use a control ping for synchronization */
11590   MPING (CONTROL_PING, mp_ping);
11591   S (mp_ping);
11592
11593   /* Wait for a reply... */
11594   W (ret);
11595   return ret;
11596 }
11597
11598 static u8 *
11599 format_fib_api_path_nh_proto (u8 * s, va_list * args)
11600 {
11601   vl_api_fib_path_nh_proto_t proto =
11602     va_arg (*args, vl_api_fib_path_nh_proto_t);
11603
11604   switch (proto)
11605     {
11606     case FIB_API_PATH_NH_PROTO_IP4:
11607       s = format (s, "ip4");
11608       break;
11609     case FIB_API_PATH_NH_PROTO_IP6:
11610       s = format (s, "ip6");
11611       break;
11612     case FIB_API_PATH_NH_PROTO_MPLS:
11613       s = format (s, "mpls");
11614       break;
11615     case FIB_API_PATH_NH_PROTO_BIER:
11616       s = format (s, "bier");
11617       break;
11618     case FIB_API_PATH_NH_PROTO_ETHERNET:
11619       s = format (s, "ethernet");
11620       break;
11621     }
11622
11623   return (s);
11624 }
11625
11626 static u8 *
11627 format_vl_api_ip_address_union (u8 * s, va_list * args)
11628 {
11629   vl_api_address_family_t af = va_arg (*args, int);
11630   const vl_api_address_union_t *u = va_arg (*args, vl_api_address_union_t *);
11631
11632   switch (af)
11633     {
11634     case ADDRESS_IP4:
11635       s = format (s, "%U", format_ip4_address, u->ip4);
11636       break;
11637     case ADDRESS_IP6:
11638       s = format (s, "%U", format_ip6_address, u->ip6);
11639       break;
11640     }
11641   return (s);
11642 }
11643
11644 static u8 *
11645 format_vl_api_fib_path_type (u8 * s, va_list * args)
11646 {
11647   vl_api_fib_path_type_t t = va_arg (*args, vl_api_fib_path_type_t);
11648
11649   switch (t)
11650     {
11651     case FIB_API_PATH_TYPE_NORMAL:
11652       s = format (s, "normal");
11653       break;
11654     case FIB_API_PATH_TYPE_LOCAL:
11655       s = format (s, "local");
11656       break;
11657     case FIB_API_PATH_TYPE_DROP:
11658       s = format (s, "drop");
11659       break;
11660     case FIB_API_PATH_TYPE_UDP_ENCAP:
11661       s = format (s, "udp-encap");
11662       break;
11663     case FIB_API_PATH_TYPE_BIER_IMP:
11664       s = format (s, "bier-imp");
11665       break;
11666     case FIB_API_PATH_TYPE_ICMP_UNREACH:
11667       s = format (s, "unreach");
11668       break;
11669     case FIB_API_PATH_TYPE_ICMP_PROHIBIT:
11670       s = format (s, "prohibit");
11671       break;
11672     case FIB_API_PATH_TYPE_SOURCE_LOOKUP:
11673       s = format (s, "src-lookup");
11674       break;
11675     case FIB_API_PATH_TYPE_DVR:
11676       s = format (s, "dvr");
11677       break;
11678     case FIB_API_PATH_TYPE_INTERFACE_RX:
11679       s = format (s, "interface-rx");
11680       break;
11681     case FIB_API_PATH_TYPE_CLASSIFY:
11682       s = format (s, "classify");
11683       break;
11684     }
11685
11686   return (s);
11687 }
11688
11689 static void
11690 vl_api_fib_path_print (vat_main_t * vam, vl_api_fib_path_t * fp)
11691 {
11692   print (vam->ofp,
11693          "  weight %d, sw_if_index %d, type %U, afi %U, next_hop %U",
11694          ntohl (fp->weight), ntohl (fp->sw_if_index),
11695          format_vl_api_fib_path_type, fp->type,
11696          format_fib_api_path_nh_proto, fp->proto,
11697          format_vl_api_ip_address_union, &fp->nh.address);
11698 }
11699
11700 static void
11701 vl_api_mpls_fib_path_json_print (vat_json_node_t * node,
11702                                  vl_api_fib_path_t * fp)
11703 {
11704   struct in_addr ip4;
11705   struct in6_addr ip6;
11706
11707   vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
11708   vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
11709   vat_json_object_add_uint (node, "type", fp->type);
11710   vat_json_object_add_uint (node, "next_hop_proto", fp->proto);
11711   if (fp->proto == FIB_API_PATH_NH_PROTO_IP4)
11712     {
11713       clib_memcpy (&ip4, &fp->nh.address.ip4, sizeof (ip4));
11714       vat_json_object_add_ip4 (node, "next_hop", ip4);
11715     }
11716   else if (fp->proto == FIB_API_PATH_NH_PROTO_IP6)
11717     {
11718       clib_memcpy (&ip6, &fp->nh.address.ip6, sizeof (ip6));
11719       vat_json_object_add_ip6 (node, "next_hop", ip6);
11720     }
11721 }
11722
11723 static void
11724 vl_api_mpls_tunnel_details_t_handler (vl_api_mpls_tunnel_details_t * mp)
11725 {
11726   vat_main_t *vam = &vat_main;
11727   int count = ntohl (mp->mt_tunnel.mt_n_paths);
11728   vl_api_fib_path_t *fp;
11729   i32 i;
11730
11731   print (vam->ofp, "sw_if_index %d via:",
11732          ntohl (mp->mt_tunnel.mt_sw_if_index));
11733   fp = mp->mt_tunnel.mt_paths;
11734   for (i = 0; i < count; i++)
11735     {
11736       vl_api_fib_path_print (vam, fp);
11737       fp++;
11738     }
11739
11740   print (vam->ofp, "");
11741 }
11742
11743 #define vl_api_mpls_tunnel_details_t_endian vl_noop_handler
11744 #define vl_api_mpls_tunnel_details_t_print vl_noop_handler
11745
11746 static void
11747 vl_api_mpls_tunnel_details_t_handler_json (vl_api_mpls_tunnel_details_t * mp)
11748 {
11749   vat_main_t *vam = &vat_main;
11750   vat_json_node_t *node = NULL;
11751   int count = ntohl (mp->mt_tunnel.mt_n_paths);
11752   vl_api_fib_path_t *fp;
11753   i32 i;
11754
11755   if (VAT_JSON_ARRAY != vam->json_tree.type)
11756     {
11757       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11758       vat_json_init_array (&vam->json_tree);
11759     }
11760   node = vat_json_array_add (&vam->json_tree);
11761
11762   vat_json_init_object (node);
11763   vat_json_object_add_uint (node, "sw_if_index",
11764                             ntohl (mp->mt_tunnel.mt_sw_if_index));
11765
11766   vat_json_object_add_uint (node, "l2_only", mp->mt_tunnel.mt_l2_only);
11767
11768   fp = mp->mt_tunnel.mt_paths;
11769   for (i = 0; i < count; i++)
11770     {
11771       vl_api_mpls_fib_path_json_print (node, fp);
11772       fp++;
11773     }
11774 }
11775
11776 static int
11777 api_mpls_tunnel_dump (vat_main_t * vam)
11778 {
11779   vl_api_mpls_tunnel_dump_t *mp;
11780   vl_api_control_ping_t *mp_ping;
11781   int ret;
11782
11783   M (MPLS_TUNNEL_DUMP, mp);
11784
11785   S (mp);
11786
11787   /* Use a control ping for synchronization */
11788   MPING (CONTROL_PING, mp_ping);
11789   S (mp_ping);
11790
11791   W (ret);
11792   return ret;
11793 }
11794
11795 #define vl_api_mpls_table_details_t_endian vl_noop_handler
11796 #define vl_api_mpls_table_details_t_print vl_noop_handler
11797
11798
11799 static void
11800 vl_api_mpls_table_details_t_handler (vl_api_mpls_table_details_t * mp)
11801 {
11802   vat_main_t *vam = &vat_main;
11803
11804   print (vam->ofp, "table-id %d,", ntohl (mp->mt_table.mt_table_id));
11805 }
11806
11807 static void vl_api_mpls_table_details_t_handler_json
11808   (vl_api_mpls_table_details_t * mp)
11809 {
11810   vat_main_t *vam = &vat_main;
11811   vat_json_node_t *node = NULL;
11812
11813   if (VAT_JSON_ARRAY != vam->json_tree.type)
11814     {
11815       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11816       vat_json_init_array (&vam->json_tree);
11817     }
11818   node = vat_json_array_add (&vam->json_tree);
11819
11820   vat_json_init_object (node);
11821   vat_json_object_add_uint (node, "table", ntohl (mp->mt_table.mt_table_id));
11822 }
11823
11824 static int
11825 api_mpls_table_dump (vat_main_t * vam)
11826 {
11827   vl_api_mpls_table_dump_t *mp;
11828   vl_api_control_ping_t *mp_ping;
11829   int ret;
11830
11831   M (MPLS_TABLE_DUMP, mp);
11832   S (mp);
11833
11834   /* Use a control ping for synchronization */
11835   MPING (CONTROL_PING, mp_ping);
11836   S (mp_ping);
11837
11838   W (ret);
11839   return ret;
11840 }
11841
11842 #define vl_api_mpls_route_details_t_endian vl_noop_handler
11843 #define vl_api_mpls_route_details_t_print vl_noop_handler
11844
11845 static void
11846 vl_api_mpls_route_details_t_handler (vl_api_mpls_route_details_t * mp)
11847 {
11848   vat_main_t *vam = &vat_main;
11849   int count = (int) clib_net_to_host_u32 (mp->mr_route.mr_n_paths);
11850   vl_api_fib_path_t *fp;
11851   int i;
11852
11853   print (vam->ofp,
11854          "table-id %d, label %u, ess_bit %u",
11855          ntohl (mp->mr_route.mr_table_id),
11856          ntohl (mp->mr_route.mr_label), mp->mr_route.mr_eos);
11857   fp = mp->mr_route.mr_paths;
11858   for (i = 0; i < count; i++)
11859     {
11860       vl_api_fib_path_print (vam, fp);
11861       fp++;
11862     }
11863 }
11864
11865 static void vl_api_mpls_route_details_t_handler_json
11866   (vl_api_mpls_route_details_t * mp)
11867 {
11868   vat_main_t *vam = &vat_main;
11869   int count = (int) clib_host_to_net_u32 (mp->mr_route.mr_n_paths);
11870   vat_json_node_t *node = NULL;
11871   vl_api_fib_path_t *fp;
11872   int i;
11873
11874   if (VAT_JSON_ARRAY != vam->json_tree.type)
11875     {
11876       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11877       vat_json_init_array (&vam->json_tree);
11878     }
11879   node = vat_json_array_add (&vam->json_tree);
11880
11881   vat_json_init_object (node);
11882   vat_json_object_add_uint (node, "table", ntohl (mp->mr_route.mr_table_id));
11883   vat_json_object_add_uint (node, "s_bit", mp->mr_route.mr_eos);
11884   vat_json_object_add_uint (node, "label", ntohl (mp->mr_route.mr_label));
11885   vat_json_object_add_uint (node, "path_count", count);
11886   fp = mp->mr_route.mr_paths;
11887   for (i = 0; i < count; i++)
11888     {
11889       vl_api_mpls_fib_path_json_print (node, fp);
11890       fp++;
11891     }
11892 }
11893
11894 static int
11895 api_mpls_route_dump (vat_main_t * vam)
11896 {
11897   unformat_input_t *input = vam->input;
11898   vl_api_mpls_route_dump_t *mp;
11899   vl_api_control_ping_t *mp_ping;
11900   u32 table_id;
11901   int ret;
11902
11903   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11904     {
11905       if (unformat (input, "table_id %d", &table_id))
11906         ;
11907       else
11908         break;
11909     }
11910   if (table_id == ~0)
11911     {
11912       errmsg ("missing table id");
11913       return -99;
11914     }
11915
11916   M (MPLS_ROUTE_DUMP, mp);
11917
11918   mp->table.mt_table_id = ntohl (table_id);
11919   S (mp);
11920
11921   /* Use a control ping for synchronization */
11922   MPING (CONTROL_PING, mp_ping);
11923   S (mp_ping);
11924
11925   W (ret);
11926   return ret;
11927 }
11928
11929 #define vl_api_ip_table_details_t_endian vl_noop_handler
11930 #define vl_api_ip_table_details_t_print vl_noop_handler
11931
11932 static void
11933 vl_api_ip_table_details_t_handler (vl_api_ip_table_details_t * mp)
11934 {
11935   vat_main_t *vam = &vat_main;
11936
11937   print (vam->ofp,
11938          "%s; table-id %d, prefix %U/%d",
11939          mp->table.name, ntohl (mp->table.table_id));
11940 }
11941
11942
11943 static void vl_api_ip_table_details_t_handler_json
11944   (vl_api_ip_table_details_t * mp)
11945 {
11946   vat_main_t *vam = &vat_main;
11947   vat_json_node_t *node = NULL;
11948
11949   if (VAT_JSON_ARRAY != vam->json_tree.type)
11950     {
11951       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11952       vat_json_init_array (&vam->json_tree);
11953     }
11954   node = vat_json_array_add (&vam->json_tree);
11955
11956   vat_json_init_object (node);
11957   vat_json_object_add_uint (node, "table", ntohl (mp->table.table_id));
11958 }
11959
11960 static int
11961 api_ip_table_dump (vat_main_t * vam)
11962 {
11963   vl_api_ip_table_dump_t *mp;
11964   vl_api_control_ping_t *mp_ping;
11965   int ret;
11966
11967   M (IP_TABLE_DUMP, mp);
11968   S (mp);
11969
11970   /* Use a control ping for synchronization */
11971   MPING (CONTROL_PING, mp_ping);
11972   S (mp_ping);
11973
11974   W (ret);
11975   return ret;
11976 }
11977
11978 static int
11979 api_ip_mtable_dump (vat_main_t * vam)
11980 {
11981   vl_api_ip_mtable_dump_t *mp;
11982   vl_api_control_ping_t *mp_ping;
11983   int ret;
11984
11985   M (IP_MTABLE_DUMP, mp);
11986   S (mp);
11987
11988   /* Use a control ping for synchronization */
11989   MPING (CONTROL_PING, mp_ping);
11990   S (mp_ping);
11991
11992   W (ret);
11993   return ret;
11994 }
11995
11996 static int
11997 api_ip_mroute_dump (vat_main_t * vam)
11998 {
11999   unformat_input_t *input = vam->input;
12000   vl_api_control_ping_t *mp_ping;
12001   vl_api_ip_mroute_dump_t *mp;
12002   int ret, is_ip6;
12003   u32 table_id;
12004
12005   is_ip6 = 0;
12006   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12007     {
12008       if (unformat (input, "table_id %d", &table_id))
12009         ;
12010       else if (unformat (input, "ip6"))
12011         is_ip6 = 1;
12012       else if (unformat (input, "ip4"))
12013         is_ip6 = 0;
12014       else
12015         break;
12016     }
12017   if (table_id == ~0)
12018     {
12019       errmsg ("missing table id");
12020       return -99;
12021     }
12022
12023   M (IP_MROUTE_DUMP, mp);
12024   mp->table.table_id = table_id;
12025   mp->table.is_ip6 = is_ip6;
12026   S (mp);
12027
12028   /* Use a control ping for synchronization */
12029   MPING (CONTROL_PING, mp_ping);
12030   S (mp_ping);
12031
12032   W (ret);
12033   return ret;
12034 }
12035
12036 #define vl_api_ip_route_details_t_endian vl_noop_handler
12037 #define vl_api_ip_route_details_t_print vl_noop_handler
12038
12039 static void
12040 vl_api_ip_route_details_t_handler (vl_api_ip_route_details_t * mp)
12041 {
12042   vat_main_t *vam = &vat_main;
12043   u8 count = mp->route.n_paths;
12044   vl_api_fib_path_t *fp;
12045   int i;
12046
12047   print (vam->ofp,
12048          "table-id %d, prefix %U/%d",
12049          ntohl (mp->route.table_id),
12050          format_ip46_address, mp->route.prefix.address, mp->route.prefix.len);
12051   for (i = 0; i < count; i++)
12052     {
12053       fp = &mp->route.paths[i];
12054
12055       vl_api_fib_path_print (vam, fp);
12056       fp++;
12057     }
12058 }
12059
12060 static void vl_api_ip_route_details_t_handler_json
12061   (vl_api_ip_route_details_t * mp)
12062 {
12063   vat_main_t *vam = &vat_main;
12064   u8 count = mp->route.n_paths;
12065   vat_json_node_t *node = NULL;
12066   struct in_addr ip4;
12067   struct in6_addr ip6;
12068   vl_api_fib_path_t *fp;
12069   int i;
12070
12071   if (VAT_JSON_ARRAY != vam->json_tree.type)
12072     {
12073       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12074       vat_json_init_array (&vam->json_tree);
12075     }
12076   node = vat_json_array_add (&vam->json_tree);
12077
12078   vat_json_init_object (node);
12079   vat_json_object_add_uint (node, "table", ntohl (mp->route.table_id));
12080   if (ADDRESS_IP6 == mp->route.prefix.address.af)
12081     {
12082       clib_memcpy (&ip6, &mp->route.prefix.address.un.ip6, sizeof (ip6));
12083       vat_json_object_add_ip6 (node, "prefix", ip6);
12084     }
12085   else
12086     {
12087       clib_memcpy (&ip4, &mp->route.prefix.address.un.ip4, sizeof (ip4));
12088       vat_json_object_add_ip4 (node, "prefix", ip4);
12089     }
12090   vat_json_object_add_uint (node, "mask_length", mp->route.prefix.len);
12091   vat_json_object_add_uint (node, "path_count", count);
12092   for (i = 0; i < count; i++)
12093     {
12094       fp = &mp->route.paths[i];
12095       vl_api_mpls_fib_path_json_print (node, fp);
12096     }
12097 }
12098
12099 static int
12100 api_ip_route_dump (vat_main_t * vam)
12101 {
12102   unformat_input_t *input = vam->input;
12103   vl_api_ip_route_dump_t *mp;
12104   vl_api_control_ping_t *mp_ping;
12105   u32 table_id;
12106   u8 is_ip6;
12107   int ret;
12108
12109   is_ip6 = 0;
12110   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12111     {
12112       if (unformat (input, "table_id %d", &table_id))
12113         ;
12114       else if (unformat (input, "ip6"))
12115         is_ip6 = 1;
12116       else if (unformat (input, "ip4"))
12117         is_ip6 = 0;
12118       else
12119         break;
12120     }
12121   if (table_id == ~0)
12122     {
12123       errmsg ("missing table id");
12124       return -99;
12125     }
12126
12127   M (IP_ROUTE_DUMP, mp);
12128
12129   mp->table.table_id = table_id;
12130   mp->table.is_ip6 = is_ip6;
12131
12132   S (mp);
12133
12134   /* Use a control ping for synchronization */
12135   MPING (CONTROL_PING, mp_ping);
12136   S (mp_ping);
12137
12138   W (ret);
12139   return ret;
12140 }
12141
12142 int
12143 api_classify_table_ids (vat_main_t * vam)
12144 {
12145   vl_api_classify_table_ids_t *mp;
12146   int ret;
12147
12148   /* Construct the API message */
12149   M (CLASSIFY_TABLE_IDS, mp);
12150   mp->context = 0;
12151
12152   S (mp);
12153   W (ret);
12154   return ret;
12155 }
12156
12157 int
12158 api_classify_table_by_interface (vat_main_t * vam)
12159 {
12160   unformat_input_t *input = vam->input;
12161   vl_api_classify_table_by_interface_t *mp;
12162
12163   u32 sw_if_index = ~0;
12164   int ret;
12165   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12166     {
12167       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12168         ;
12169       else if (unformat (input, "sw_if_index %d", &sw_if_index))
12170         ;
12171       else
12172         break;
12173     }
12174   if (sw_if_index == ~0)
12175     {
12176       errmsg ("missing interface name or sw_if_index");
12177       return -99;
12178     }
12179
12180   /* Construct the API message */
12181   M (CLASSIFY_TABLE_BY_INTERFACE, mp);
12182   mp->context = 0;
12183   mp->sw_if_index = ntohl (sw_if_index);
12184
12185   S (mp);
12186   W (ret);
12187   return ret;
12188 }
12189
12190 int
12191 api_classify_table_info (vat_main_t * vam)
12192 {
12193   unformat_input_t *input = vam->input;
12194   vl_api_classify_table_info_t *mp;
12195
12196   u32 table_id = ~0;
12197   int ret;
12198   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12199     {
12200       if (unformat (input, "table_id %d", &table_id))
12201         ;
12202       else
12203         break;
12204     }
12205   if (table_id == ~0)
12206     {
12207       errmsg ("missing table id");
12208       return -99;
12209     }
12210
12211   /* Construct the API message */
12212   M (CLASSIFY_TABLE_INFO, mp);
12213   mp->context = 0;
12214   mp->table_id = ntohl (table_id);
12215
12216   S (mp);
12217   W (ret);
12218   return ret;
12219 }
12220
12221 int
12222 api_classify_session_dump (vat_main_t * vam)
12223 {
12224   unformat_input_t *input = vam->input;
12225   vl_api_classify_session_dump_t *mp;
12226   vl_api_control_ping_t *mp_ping;
12227
12228   u32 table_id = ~0;
12229   int ret;
12230   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12231     {
12232       if (unformat (input, "table_id %d", &table_id))
12233         ;
12234       else
12235         break;
12236     }
12237   if (table_id == ~0)
12238     {
12239       errmsg ("missing table id");
12240       return -99;
12241     }
12242
12243   /* Construct the API message */
12244   M (CLASSIFY_SESSION_DUMP, mp);
12245   mp->context = 0;
12246   mp->table_id = ntohl (table_id);
12247   S (mp);
12248
12249   /* Use a control ping for synchronization */
12250   MPING (CONTROL_PING, mp_ping);
12251   S (mp_ping);
12252
12253   W (ret);
12254   return ret;
12255 }
12256
12257 static void
12258 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
12259 {
12260   vat_main_t *vam = &vat_main;
12261
12262   print (vam->ofp, "collector_address %U, collector_port %d, "
12263          "src_address %U, vrf_id %d, path_mtu %u, "
12264          "template_interval %u, udp_checksum %d",
12265          format_ip4_address, mp->collector_address,
12266          ntohs (mp->collector_port),
12267          format_ip4_address, mp->src_address,
12268          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
12269          ntohl (mp->template_interval), mp->udp_checksum);
12270
12271   vam->retval = 0;
12272   vam->result_ready = 1;
12273 }
12274
12275 static void
12276   vl_api_ipfix_exporter_details_t_handler_json
12277   (vl_api_ipfix_exporter_details_t * mp)
12278 {
12279   vat_main_t *vam = &vat_main;
12280   vat_json_node_t node;
12281   struct in_addr collector_address;
12282   struct in_addr src_address;
12283
12284   vat_json_init_object (&node);
12285   clib_memcpy (&collector_address, &mp->collector_address,
12286                sizeof (collector_address));
12287   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
12288   vat_json_object_add_uint (&node, "collector_port",
12289                             ntohs (mp->collector_port));
12290   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
12291   vat_json_object_add_ip4 (&node, "src_address", src_address);
12292   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
12293   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
12294   vat_json_object_add_uint (&node, "template_interval",
12295                             ntohl (mp->template_interval));
12296   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
12297
12298   vat_json_print (vam->ofp, &node);
12299   vat_json_free (&node);
12300   vam->retval = 0;
12301   vam->result_ready = 1;
12302 }
12303
12304 int
12305 api_ipfix_exporter_dump (vat_main_t * vam)
12306 {
12307   vl_api_ipfix_exporter_dump_t *mp;
12308   int ret;
12309
12310   /* Construct the API message */
12311   M (IPFIX_EXPORTER_DUMP, mp);
12312   mp->context = 0;
12313
12314   S (mp);
12315   W (ret);
12316   return ret;
12317 }
12318
12319 static int
12320 api_ipfix_classify_stream_dump (vat_main_t * vam)
12321 {
12322   vl_api_ipfix_classify_stream_dump_t *mp;
12323   int ret;
12324
12325   /* Construct the API message */
12326   M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
12327   mp->context = 0;
12328
12329   S (mp);
12330   W (ret);
12331   return ret;
12332   /* NOTREACHED */
12333   return 0;
12334 }
12335
12336 static void
12337   vl_api_ipfix_classify_stream_details_t_handler
12338   (vl_api_ipfix_classify_stream_details_t * mp)
12339 {
12340   vat_main_t *vam = &vat_main;
12341   print (vam->ofp, "domain_id %d, src_port %d",
12342          ntohl (mp->domain_id), ntohs (mp->src_port));
12343   vam->retval = 0;
12344   vam->result_ready = 1;
12345 }
12346
12347 static void
12348   vl_api_ipfix_classify_stream_details_t_handler_json
12349   (vl_api_ipfix_classify_stream_details_t * mp)
12350 {
12351   vat_main_t *vam = &vat_main;
12352   vat_json_node_t node;
12353
12354   vat_json_init_object (&node);
12355   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
12356   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
12357
12358   vat_json_print (vam->ofp, &node);
12359   vat_json_free (&node);
12360   vam->retval = 0;
12361   vam->result_ready = 1;
12362 }
12363
12364 static int
12365 api_ipfix_classify_table_dump (vat_main_t * vam)
12366 {
12367   vl_api_ipfix_classify_table_dump_t *mp;
12368   vl_api_control_ping_t *mp_ping;
12369   int ret;
12370
12371   if (!vam->json_output)
12372     {
12373       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
12374              "transport_protocol");
12375     }
12376
12377   /* Construct the API message */
12378   M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
12379
12380   /* send it... */
12381   S (mp);
12382
12383   /* Use a control ping for synchronization */
12384   MPING (CONTROL_PING, mp_ping);
12385   S (mp_ping);
12386
12387   W (ret);
12388   return ret;
12389 }
12390
12391 static void
12392   vl_api_ipfix_classify_table_details_t_handler
12393   (vl_api_ipfix_classify_table_details_t * mp)
12394 {
12395   vat_main_t *vam = &vat_main;
12396   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
12397          mp->transport_protocol);
12398 }
12399
12400 static void
12401   vl_api_ipfix_classify_table_details_t_handler_json
12402   (vl_api_ipfix_classify_table_details_t * mp)
12403 {
12404   vat_json_node_t *node = NULL;
12405   vat_main_t *vam = &vat_main;
12406
12407   if (VAT_JSON_ARRAY != vam->json_tree.type)
12408     {
12409       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12410       vat_json_init_array (&vam->json_tree);
12411     }
12412
12413   node = vat_json_array_add (&vam->json_tree);
12414   vat_json_init_object (node);
12415
12416   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
12417   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
12418   vat_json_object_add_uint (node, "transport_protocol",
12419                             mp->transport_protocol);
12420 }
12421
12422 static int
12423 api_sw_interface_span_enable_disable (vat_main_t * vam)
12424 {
12425   unformat_input_t *i = vam->input;
12426   vl_api_sw_interface_span_enable_disable_t *mp;
12427   u32 src_sw_if_index = ~0;
12428   u32 dst_sw_if_index = ~0;
12429   u8 state = 3;
12430   int ret;
12431   u8 is_l2 = 0;
12432
12433   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12434     {
12435       if (unformat
12436           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
12437         ;
12438       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
12439         ;
12440       else
12441         if (unformat
12442             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
12443         ;
12444       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
12445         ;
12446       else if (unformat (i, "disable"))
12447         state = 0;
12448       else if (unformat (i, "rx"))
12449         state = 1;
12450       else if (unformat (i, "tx"))
12451         state = 2;
12452       else if (unformat (i, "both"))
12453         state = 3;
12454       else if (unformat (i, "l2"))
12455         is_l2 = 1;
12456       else
12457         break;
12458     }
12459
12460   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
12461
12462   mp->sw_if_index_from = htonl (src_sw_if_index);
12463   mp->sw_if_index_to = htonl (dst_sw_if_index);
12464   mp->state = state;
12465   mp->is_l2 = is_l2;
12466
12467   S (mp);
12468   W (ret);
12469   return ret;
12470 }
12471
12472 static void
12473 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
12474                                             * mp)
12475 {
12476   vat_main_t *vam = &vat_main;
12477   u8 *sw_if_from_name = 0;
12478   u8 *sw_if_to_name = 0;
12479   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
12480   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
12481   char *states[] = { "none", "rx", "tx", "both" };
12482   hash_pair_t *p;
12483
12484   /* *INDENT-OFF* */
12485   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
12486   ({
12487     if ((u32) p->value[0] == sw_if_index_from)
12488       {
12489         sw_if_from_name = (u8 *)(p->key);
12490         if (sw_if_to_name)
12491           break;
12492       }
12493     if ((u32) p->value[0] == sw_if_index_to)
12494       {
12495         sw_if_to_name = (u8 *)(p->key);
12496         if (sw_if_from_name)
12497           break;
12498       }
12499   }));
12500   /* *INDENT-ON* */
12501   print (vam->ofp, "%20s => %20s (%s) %s",
12502          sw_if_from_name, sw_if_to_name, states[mp->state],
12503          mp->is_l2 ? "l2" : "device");
12504 }
12505
12506 static void
12507   vl_api_sw_interface_span_details_t_handler_json
12508   (vl_api_sw_interface_span_details_t * mp)
12509 {
12510   vat_main_t *vam = &vat_main;
12511   vat_json_node_t *node = NULL;
12512   u8 *sw_if_from_name = 0;
12513   u8 *sw_if_to_name = 0;
12514   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
12515   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
12516   hash_pair_t *p;
12517
12518   /* *INDENT-OFF* */
12519   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
12520   ({
12521     if ((u32) p->value[0] == sw_if_index_from)
12522       {
12523         sw_if_from_name = (u8 *)(p->key);
12524         if (sw_if_to_name)
12525           break;
12526       }
12527     if ((u32) p->value[0] == sw_if_index_to)
12528       {
12529         sw_if_to_name = (u8 *)(p->key);
12530         if (sw_if_from_name)
12531           break;
12532       }
12533   }));
12534   /* *INDENT-ON* */
12535
12536   if (VAT_JSON_ARRAY != vam->json_tree.type)
12537     {
12538       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12539       vat_json_init_array (&vam->json_tree);
12540     }
12541   node = vat_json_array_add (&vam->json_tree);
12542
12543   vat_json_init_object (node);
12544   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
12545   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
12546   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
12547   if (0 != sw_if_to_name)
12548     {
12549       vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
12550     }
12551   vat_json_object_add_uint (node, "state", mp->state);
12552   vat_json_object_add_uint (node, "is-l2", mp->is_l2);
12553 }
12554
12555 static int
12556 api_sw_interface_span_dump (vat_main_t * vam)
12557 {
12558   unformat_input_t *input = vam->input;
12559   vl_api_sw_interface_span_dump_t *mp;
12560   vl_api_control_ping_t *mp_ping;
12561   u8 is_l2 = 0;
12562   int ret;
12563
12564   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12565     {
12566       if (unformat (input, "l2"))
12567         is_l2 = 1;
12568       else
12569         break;
12570     }
12571
12572   M (SW_INTERFACE_SPAN_DUMP, mp);
12573   mp->is_l2 = is_l2;
12574   S (mp);
12575
12576   /* Use a control ping for synchronization */
12577   MPING (CONTROL_PING, mp_ping);
12578   S (mp_ping);
12579
12580   W (ret);
12581   return ret;
12582 }
12583
12584 int
12585 api_pg_create_interface (vat_main_t * vam)
12586 {
12587   unformat_input_t *input = vam->input;
12588   vl_api_pg_create_interface_t *mp;
12589
12590   u32 if_id = ~0, gso_size = 0;
12591   u8 gso_enabled = 0;
12592   int ret;
12593   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12594     {
12595       if (unformat (input, "if_id %d", &if_id))
12596         ;
12597       else if (unformat (input, "gso-enabled"))
12598         {
12599           gso_enabled = 1;
12600           if (unformat (input, "gso-size %u", &gso_size))
12601             ;
12602           else
12603             {
12604               errmsg ("missing gso-size");
12605               return -99;
12606             }
12607         }
12608       else
12609         break;
12610     }
12611   if (if_id == ~0)
12612     {
12613       errmsg ("missing pg interface index");
12614       return -99;
12615     }
12616
12617   /* Construct the API message */
12618   M (PG_CREATE_INTERFACE, mp);
12619   mp->context = 0;
12620   mp->interface_id = ntohl (if_id);
12621   mp->gso_enabled = gso_enabled;
12622
12623   S (mp);
12624   W (ret);
12625   return ret;
12626 }
12627
12628 int
12629 api_pg_capture (vat_main_t * vam)
12630 {
12631   unformat_input_t *input = vam->input;
12632   vl_api_pg_capture_t *mp;
12633
12634   u32 if_id = ~0;
12635   u8 enable = 1;
12636   u32 count = 1;
12637   u8 pcap_file_set = 0;
12638   u8 *pcap_file = 0;
12639   int ret;
12640   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12641     {
12642       if (unformat (input, "if_id %d", &if_id))
12643         ;
12644       else if (unformat (input, "pcap %s", &pcap_file))
12645         pcap_file_set = 1;
12646       else if (unformat (input, "count %d", &count))
12647         ;
12648       else if (unformat (input, "disable"))
12649         enable = 0;
12650       else
12651         break;
12652     }
12653   if (if_id == ~0)
12654     {
12655       errmsg ("missing pg interface index");
12656       return -99;
12657     }
12658   if (pcap_file_set > 0)
12659     {
12660       if (vec_len (pcap_file) > 255)
12661         {
12662           errmsg ("pcap file name is too long");
12663           return -99;
12664         }
12665     }
12666
12667   /* Construct the API message */
12668   M (PG_CAPTURE, mp);
12669   mp->context = 0;
12670   mp->interface_id = ntohl (if_id);
12671   mp->is_enabled = enable;
12672   mp->count = ntohl (count);
12673   if (pcap_file_set != 0)
12674     {
12675       vl_api_vec_to_api_string (pcap_file, &mp->pcap_file_name);
12676     }
12677   vec_free (pcap_file);
12678
12679   S (mp);
12680   W (ret);
12681   return ret;
12682 }
12683
12684 int
12685 api_pg_enable_disable (vat_main_t * vam)
12686 {
12687   unformat_input_t *input = vam->input;
12688   vl_api_pg_enable_disable_t *mp;
12689
12690   u8 enable = 1;
12691   u8 stream_name_set = 0;
12692   u8 *stream_name = 0;
12693   int ret;
12694   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12695     {
12696       if (unformat (input, "stream %s", &stream_name))
12697         stream_name_set = 1;
12698       else if (unformat (input, "disable"))
12699         enable = 0;
12700       else
12701         break;
12702     }
12703
12704   if (stream_name_set > 0)
12705     {
12706       if (vec_len (stream_name) > 255)
12707         {
12708           errmsg ("stream name too long");
12709           return -99;
12710         }
12711     }
12712
12713   /* Construct the API message */
12714   M (PG_ENABLE_DISABLE, mp);
12715   mp->context = 0;
12716   mp->is_enabled = enable;
12717   if (stream_name_set != 0)
12718     {
12719       vl_api_vec_to_api_string (stream_name, &mp->stream_name);
12720     }
12721   vec_free (stream_name);
12722
12723   S (mp);
12724   W (ret);
12725   return ret;
12726 }
12727
12728 int
12729 api_pg_interface_enable_disable_coalesce (vat_main_t * vam)
12730 {
12731   unformat_input_t *input = vam->input;
12732   vl_api_pg_interface_enable_disable_coalesce_t *mp;
12733
12734   u32 sw_if_index = ~0;
12735   u8 enable = 1;
12736   int ret;
12737   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12738     {
12739       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12740         ;
12741       else if (unformat (input, "sw_if_index %d", &sw_if_index))
12742         ;
12743       else if (unformat (input, "disable"))
12744         enable = 0;
12745       else
12746         break;
12747     }
12748
12749   if (sw_if_index == ~0)
12750     {
12751       errmsg ("Interface required but not specified");
12752       return -99;
12753     }
12754
12755   /* Construct the API message */
12756   M (PG_INTERFACE_ENABLE_DISABLE_COALESCE, mp);
12757   mp->context = 0;
12758   mp->coalesce_enabled = enable;
12759   mp->sw_if_index = htonl (sw_if_index);
12760
12761   S (mp);
12762   W (ret);
12763   return ret;
12764 }
12765
12766 int
12767 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
12768 {
12769   unformat_input_t *input = vam->input;
12770   vl_api_ip_source_and_port_range_check_add_del_t *mp;
12771
12772   u16 *low_ports = 0;
12773   u16 *high_ports = 0;
12774   u16 this_low;
12775   u16 this_hi;
12776   vl_api_prefix_t prefix;
12777   u32 tmp, tmp2;
12778   u8 prefix_set = 0;
12779   u32 vrf_id = ~0;
12780   u8 is_add = 1;
12781   int ret;
12782
12783   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12784     {
12785       if (unformat (input, "%U", unformat_vl_api_prefix, &prefix))
12786         prefix_set = 1;
12787       else if (unformat (input, "vrf %d", &vrf_id))
12788         ;
12789       else if (unformat (input, "del"))
12790         is_add = 0;
12791       else if (unformat (input, "port %d", &tmp))
12792         {
12793           if (tmp == 0 || tmp > 65535)
12794             {
12795               errmsg ("port %d out of range", tmp);
12796               return -99;
12797             }
12798           this_low = tmp;
12799           this_hi = this_low + 1;
12800           vec_add1 (low_ports, this_low);
12801           vec_add1 (high_ports, this_hi);
12802         }
12803       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
12804         {
12805           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
12806             {
12807               errmsg ("incorrect range parameters");
12808               return -99;
12809             }
12810           this_low = tmp;
12811           /* Note: in debug CLI +1 is added to high before
12812              passing to real fn that does "the work"
12813              (ip_source_and_port_range_check_add_del).
12814              This fn is a wrapper around the binary API fn a
12815              control plane will call, which expects this increment
12816              to have occurred. Hence letting the binary API control
12817              plane fn do the increment for consistency between VAT
12818              and other control planes.
12819            */
12820           this_hi = tmp2;
12821           vec_add1 (low_ports, this_low);
12822           vec_add1 (high_ports, this_hi);
12823         }
12824       else
12825         break;
12826     }
12827
12828   if (prefix_set == 0)
12829     {
12830       errmsg ("<address>/<mask> not specified");
12831       return -99;
12832     }
12833
12834   if (vrf_id == ~0)
12835     {
12836       errmsg ("VRF ID required, not specified");
12837       return -99;
12838     }
12839
12840   if (vrf_id == 0)
12841     {
12842       errmsg
12843         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
12844       return -99;
12845     }
12846
12847   if (vec_len (low_ports) == 0)
12848     {
12849       errmsg ("At least one port or port range required");
12850       return -99;
12851     }
12852
12853   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
12854
12855   mp->is_add = is_add;
12856
12857   clib_memcpy (&mp->prefix, &prefix, sizeof (prefix));
12858
12859   mp->number_of_ranges = vec_len (low_ports);
12860
12861   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
12862   vec_free (low_ports);
12863
12864   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
12865   vec_free (high_ports);
12866
12867   mp->vrf_id = ntohl (vrf_id);
12868
12869   S (mp);
12870   W (ret);
12871   return ret;
12872 }
12873
12874 int
12875 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
12876 {
12877   unformat_input_t *input = vam->input;
12878   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
12879   u32 sw_if_index = ~0;
12880   int vrf_set = 0;
12881   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
12882   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
12883   u8 is_add = 1;
12884   int ret;
12885
12886   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12887     {
12888       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12889         ;
12890       else if (unformat (input, "sw_if_index %d", &sw_if_index))
12891         ;
12892       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
12893         vrf_set = 1;
12894       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
12895         vrf_set = 1;
12896       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
12897         vrf_set = 1;
12898       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
12899         vrf_set = 1;
12900       else if (unformat (input, "del"))
12901         is_add = 0;
12902       else
12903         break;
12904     }
12905
12906   if (sw_if_index == ~0)
12907     {
12908       errmsg ("Interface required but not specified");
12909       return -99;
12910     }
12911
12912   if (vrf_set == 0)
12913     {
12914       errmsg ("VRF ID required but not specified");
12915       return -99;
12916     }
12917
12918   if (tcp_out_vrf_id == 0
12919       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
12920     {
12921       errmsg
12922         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
12923       return -99;
12924     }
12925
12926   /* Construct the API message */
12927   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
12928
12929   mp->sw_if_index = ntohl (sw_if_index);
12930   mp->is_add = is_add;
12931   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
12932   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
12933   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
12934   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
12935
12936   /* send it... */
12937   S (mp);
12938
12939   /* Wait for a reply... */
12940   W (ret);
12941   return ret;
12942 }
12943
12944 static int
12945 api_set_punt (vat_main_t * vam)
12946 {
12947   unformat_input_t *i = vam->input;
12948   vl_api_address_family_t af;
12949   vl_api_set_punt_t *mp;
12950   u32 protocol = ~0;
12951   u32 port = ~0;
12952   int is_add = 1;
12953   int ret;
12954
12955   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12956     {
12957       if (unformat (i, "%U", unformat_vl_api_address_family, &af))
12958         ;
12959       else if (unformat (i, "protocol %d", &protocol))
12960         ;
12961       else if (unformat (i, "port %d", &port))
12962         ;
12963       else if (unformat (i, "del"))
12964         is_add = 0;
12965       else
12966         {
12967           clib_warning ("parse error '%U'", format_unformat_error, i);
12968           return -99;
12969         }
12970     }
12971
12972   M (SET_PUNT, mp);
12973
12974   mp->is_add = (u8) is_add;
12975   mp->punt.type = PUNT_API_TYPE_L4;
12976   mp->punt.punt.l4.af = af;
12977   mp->punt.punt.l4.protocol = (u8) protocol;
12978   mp->punt.punt.l4.port = htons ((u16) port);
12979
12980   S (mp);
12981   W (ret);
12982   return ret;
12983 }
12984
12985 static int
12986 api_delete_subif (vat_main_t * vam)
12987 {
12988   unformat_input_t *i = vam->input;
12989   vl_api_delete_subif_t *mp;
12990   u32 sw_if_index = ~0;
12991   int ret;
12992
12993   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12994     {
12995       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12996         ;
12997       if (unformat (i, "sw_if_index %d", &sw_if_index))
12998         ;
12999       else
13000         break;
13001     }
13002
13003   if (sw_if_index == ~0)
13004     {
13005       errmsg ("missing sw_if_index");
13006       return -99;
13007     }
13008
13009   /* Construct the API message */
13010   M (DELETE_SUBIF, mp);
13011   mp->sw_if_index = ntohl (sw_if_index);
13012
13013   S (mp);
13014   W (ret);
13015   return ret;
13016 }
13017
13018 #define foreach_pbb_vtr_op      \
13019 _("disable",  L2_VTR_DISABLED)  \
13020 _("pop",  L2_VTR_POP_2)         \
13021 _("push",  L2_VTR_PUSH_2)
13022
13023 static int
13024 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
13025 {
13026   unformat_input_t *i = vam->input;
13027   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
13028   u32 sw_if_index = ~0, vtr_op = ~0;
13029   u16 outer_tag = ~0;
13030   u8 dmac[6], smac[6];
13031   u8 dmac_set = 0, smac_set = 0;
13032   u16 vlanid = 0;
13033   u32 sid = ~0;
13034   u32 tmp;
13035   int ret;
13036
13037   /* Shut up coverity */
13038   clib_memset (dmac, 0, sizeof (dmac));
13039   clib_memset (smac, 0, sizeof (smac));
13040
13041   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13042     {
13043       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13044         ;
13045       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13046         ;
13047       else if (unformat (i, "vtr_op %d", &vtr_op))
13048         ;
13049 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
13050       foreach_pbb_vtr_op
13051 #undef _
13052         else if (unformat (i, "translate_pbb_stag"))
13053         {
13054           if (unformat (i, "%d", &tmp))
13055             {
13056               vtr_op = L2_VTR_TRANSLATE_2_1;
13057               outer_tag = tmp;
13058             }
13059           else
13060             {
13061               errmsg
13062                 ("translate_pbb_stag operation requires outer tag definition");
13063               return -99;
13064             }
13065         }
13066       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
13067         dmac_set++;
13068       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
13069         smac_set++;
13070       else if (unformat (i, "sid %d", &sid))
13071         ;
13072       else if (unformat (i, "vlanid %d", &tmp))
13073         vlanid = tmp;
13074       else
13075         {
13076           clib_warning ("parse error '%U'", format_unformat_error, i);
13077           return -99;
13078         }
13079     }
13080
13081   if ((sw_if_index == ~0) || (vtr_op == ~0))
13082     {
13083       errmsg ("missing sw_if_index or vtr operation");
13084       return -99;
13085     }
13086   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
13087       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
13088     {
13089       errmsg
13090         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
13091       return -99;
13092     }
13093
13094   M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
13095   mp->sw_if_index = ntohl (sw_if_index);
13096   mp->vtr_op = ntohl (vtr_op);
13097   mp->outer_tag = ntohs (outer_tag);
13098   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
13099   clib_memcpy (mp->b_smac, smac, sizeof (smac));
13100   mp->b_vlanid = ntohs (vlanid);
13101   mp->i_sid = ntohl (sid);
13102
13103   S (mp);
13104   W (ret);
13105   return ret;
13106 }
13107
13108 static int
13109 api_flow_classify_set_interface (vat_main_t * vam)
13110 {
13111   unformat_input_t *i = vam->input;
13112   vl_api_flow_classify_set_interface_t *mp;
13113   u32 sw_if_index;
13114   int sw_if_index_set;
13115   u32 ip4_table_index = ~0;
13116   u32 ip6_table_index = ~0;
13117   u8 is_add = 1;
13118   int ret;
13119
13120   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13121     {
13122       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13123         sw_if_index_set = 1;
13124       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13125         sw_if_index_set = 1;
13126       else if (unformat (i, "del"))
13127         is_add = 0;
13128       else if (unformat (i, "ip4-table %d", &ip4_table_index))
13129         ;
13130       else if (unformat (i, "ip6-table %d", &ip6_table_index))
13131         ;
13132       else
13133         {
13134           clib_warning ("parse error '%U'", format_unformat_error, i);
13135           return -99;
13136         }
13137     }
13138
13139   if (sw_if_index_set == 0)
13140     {
13141       errmsg ("missing interface name or sw_if_index");
13142       return -99;
13143     }
13144
13145   M (FLOW_CLASSIFY_SET_INTERFACE, mp);
13146
13147   mp->sw_if_index = ntohl (sw_if_index);
13148   mp->ip4_table_index = ntohl (ip4_table_index);
13149   mp->ip6_table_index = ntohl (ip6_table_index);
13150   mp->is_add = is_add;
13151
13152   S (mp);
13153   W (ret);
13154   return ret;
13155 }
13156
13157 static int
13158 api_flow_classify_dump (vat_main_t * vam)
13159 {
13160   unformat_input_t *i = vam->input;
13161   vl_api_flow_classify_dump_t *mp;
13162   vl_api_control_ping_t *mp_ping;
13163   u8 type = FLOW_CLASSIFY_N_TABLES;
13164   int ret;
13165
13166   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
13167     ;
13168   else
13169     {
13170       errmsg ("classify table type must be specified");
13171       return -99;
13172     }
13173
13174   if (!vam->json_output)
13175     {
13176       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
13177     }
13178
13179   M (FLOW_CLASSIFY_DUMP, mp);
13180   mp->type = type;
13181   /* send it... */
13182   S (mp);
13183
13184   /* Use a control ping for synchronization */
13185   MPING (CONTROL_PING, mp_ping);
13186   S (mp_ping);
13187
13188   /* Wait for a reply... */
13189   W (ret);
13190   return ret;
13191 }
13192
13193 static int
13194 api_feature_enable_disable (vat_main_t * vam)
13195 {
13196   unformat_input_t *i = vam->input;
13197   vl_api_feature_enable_disable_t *mp;
13198   u8 *arc_name = 0;
13199   u8 *feature_name = 0;
13200   u32 sw_if_index = ~0;
13201   u8 enable = 1;
13202   int ret;
13203
13204   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13205     {
13206       if (unformat (i, "arc_name %s", &arc_name))
13207         ;
13208       else if (unformat (i, "feature_name %s", &feature_name))
13209         ;
13210       else
13211         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13212         ;
13213       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13214         ;
13215       else if (unformat (i, "disable"))
13216         enable = 0;
13217       else
13218         break;
13219     }
13220
13221   if (arc_name == 0)
13222     {
13223       errmsg ("missing arc name");
13224       return -99;
13225     }
13226   if (vec_len (arc_name) > 63)
13227     {
13228       errmsg ("arc name too long");
13229     }
13230
13231   if (feature_name == 0)
13232     {
13233       errmsg ("missing feature name");
13234       return -99;
13235     }
13236   if (vec_len (feature_name) > 63)
13237     {
13238       errmsg ("feature name too long");
13239     }
13240
13241   if (sw_if_index == ~0)
13242     {
13243       errmsg ("missing interface name or sw_if_index");
13244       return -99;
13245     }
13246
13247   /* Construct the API message */
13248   M (FEATURE_ENABLE_DISABLE, mp);
13249   mp->sw_if_index = ntohl (sw_if_index);
13250   mp->enable = enable;
13251   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
13252   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
13253   vec_free (arc_name);
13254   vec_free (feature_name);
13255
13256   S (mp);
13257   W (ret);
13258   return ret;
13259 }
13260
13261 static int
13262 api_feature_gso_enable_disable (vat_main_t * vam)
13263 {
13264   unformat_input_t *i = vam->input;
13265   vl_api_feature_gso_enable_disable_t *mp;
13266   u32 sw_if_index = ~0;
13267   u8 enable = 1;
13268   int ret;
13269
13270   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13271     {
13272       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13273         ;
13274       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13275         ;
13276       else if (unformat (i, "enable"))
13277         enable = 1;
13278       else if (unformat (i, "disable"))
13279         enable = 0;
13280       else
13281         break;
13282     }
13283
13284   if (sw_if_index == ~0)
13285     {
13286       errmsg ("missing interface name or sw_if_index");
13287       return -99;
13288     }
13289
13290   /* Construct the API message */
13291   M (FEATURE_GSO_ENABLE_DISABLE, mp);
13292   mp->sw_if_index = ntohl (sw_if_index);
13293   mp->enable_disable = enable;
13294
13295   S (mp);
13296   W (ret);
13297   return ret;
13298 }
13299
13300 static int
13301 api_sw_interface_tag_add_del (vat_main_t * vam)
13302 {
13303   unformat_input_t *i = vam->input;
13304   vl_api_sw_interface_tag_add_del_t *mp;
13305   u32 sw_if_index = ~0;
13306   u8 *tag = 0;
13307   u8 enable = 1;
13308   int ret;
13309
13310   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13311     {
13312       if (unformat (i, "tag %s", &tag))
13313         ;
13314       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13315         ;
13316       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13317         ;
13318       else if (unformat (i, "del"))
13319         enable = 0;
13320       else
13321         break;
13322     }
13323
13324   if (sw_if_index == ~0)
13325     {
13326       errmsg ("missing interface name or sw_if_index");
13327       return -99;
13328     }
13329
13330   if (enable && (tag == 0))
13331     {
13332       errmsg ("no tag specified");
13333       return -99;
13334     }
13335
13336   /* Construct the API message */
13337   M (SW_INTERFACE_TAG_ADD_DEL, mp);
13338   mp->sw_if_index = ntohl (sw_if_index);
13339   mp->is_add = enable;
13340   if (enable)
13341     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
13342   vec_free (tag);
13343
13344   S (mp);
13345   W (ret);
13346   return ret;
13347 }
13348
13349 static int
13350 api_sw_interface_add_del_mac_address (vat_main_t * vam)
13351 {
13352   unformat_input_t *i = vam->input;
13353   vl_api_mac_address_t mac = { 0 };
13354   vl_api_sw_interface_add_del_mac_address_t *mp;
13355   u32 sw_if_index = ~0;
13356   u8 is_add = 1;
13357   u8 mac_set = 0;
13358   int ret;
13359
13360   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13361     {
13362       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13363         ;
13364       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13365         ;
13366       else if (unformat (i, "%U", unformat_vl_api_mac_address, &mac))
13367         mac_set++;
13368       else if (unformat (i, "del"))
13369         is_add = 0;
13370       else
13371         break;
13372     }
13373
13374   if (sw_if_index == ~0)
13375     {
13376       errmsg ("missing interface name or sw_if_index");
13377       return -99;
13378     }
13379
13380   if (!mac_set)
13381     {
13382       errmsg ("missing MAC address");
13383       return -99;
13384     }
13385
13386   /* Construct the API message */
13387   M (SW_INTERFACE_ADD_DEL_MAC_ADDRESS, mp);
13388   mp->sw_if_index = ntohl (sw_if_index);
13389   mp->is_add = is_add;
13390   clib_memcpy (&mp->addr, &mac, sizeof (mac));
13391
13392   S (mp);
13393   W (ret);
13394   return ret;
13395 }
13396
13397 static void vl_api_l2_xconnect_details_t_handler
13398   (vl_api_l2_xconnect_details_t * mp)
13399 {
13400   vat_main_t *vam = &vat_main;
13401
13402   print (vam->ofp, "%15d%15d",
13403          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
13404 }
13405
13406 static void vl_api_l2_xconnect_details_t_handler_json
13407   (vl_api_l2_xconnect_details_t * mp)
13408 {
13409   vat_main_t *vam = &vat_main;
13410   vat_json_node_t *node = NULL;
13411
13412   if (VAT_JSON_ARRAY != vam->json_tree.type)
13413     {
13414       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13415       vat_json_init_array (&vam->json_tree);
13416     }
13417   node = vat_json_array_add (&vam->json_tree);
13418
13419   vat_json_init_object (node);
13420   vat_json_object_add_uint (node, "rx_sw_if_index",
13421                             ntohl (mp->rx_sw_if_index));
13422   vat_json_object_add_uint (node, "tx_sw_if_index",
13423                             ntohl (mp->tx_sw_if_index));
13424 }
13425
13426 static int
13427 api_l2_xconnect_dump (vat_main_t * vam)
13428 {
13429   vl_api_l2_xconnect_dump_t *mp;
13430   vl_api_control_ping_t *mp_ping;
13431   int ret;
13432
13433   if (!vam->json_output)
13434     {
13435       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
13436     }
13437
13438   M (L2_XCONNECT_DUMP, mp);
13439
13440   S (mp);
13441
13442   /* Use a control ping for synchronization */
13443   MPING (CONTROL_PING, mp_ping);
13444   S (mp_ping);
13445
13446   W (ret);
13447   return ret;
13448 }
13449
13450 static int
13451 api_hw_interface_set_mtu (vat_main_t * vam)
13452 {
13453   unformat_input_t *i = vam->input;
13454   vl_api_hw_interface_set_mtu_t *mp;
13455   u32 sw_if_index = ~0;
13456   u32 mtu = 0;
13457   int ret;
13458
13459   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13460     {
13461       if (unformat (i, "mtu %d", &mtu))
13462         ;
13463       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13464         ;
13465       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13466         ;
13467       else
13468         break;
13469     }
13470
13471   if (sw_if_index == ~0)
13472     {
13473       errmsg ("missing interface name or sw_if_index");
13474       return -99;
13475     }
13476
13477   if (mtu == 0)
13478     {
13479       errmsg ("no mtu specified");
13480       return -99;
13481     }
13482
13483   /* Construct the API message */
13484   M (HW_INTERFACE_SET_MTU, mp);
13485   mp->sw_if_index = ntohl (sw_if_index);
13486   mp->mtu = ntohs ((u16) mtu);
13487
13488   S (mp);
13489   W (ret);
13490   return ret;
13491 }
13492
13493 static int
13494 api_p2p_ethernet_add (vat_main_t * vam)
13495 {
13496   unformat_input_t *i = vam->input;
13497   vl_api_p2p_ethernet_add_t *mp;
13498   u32 parent_if_index = ~0;
13499   u32 sub_id = ~0;
13500   u8 remote_mac[6];
13501   u8 mac_set = 0;
13502   int ret;
13503
13504   clib_memset (remote_mac, 0, sizeof (remote_mac));
13505   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13506     {
13507       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
13508         ;
13509       else if (unformat (i, "sw_if_index %d", &parent_if_index))
13510         ;
13511       else
13512         if (unformat
13513             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
13514         mac_set++;
13515       else if (unformat (i, "sub_id %d", &sub_id))
13516         ;
13517       else
13518         {
13519           clib_warning ("parse error '%U'", format_unformat_error, i);
13520           return -99;
13521         }
13522     }
13523
13524   if (parent_if_index == ~0)
13525     {
13526       errmsg ("missing interface name or sw_if_index");
13527       return -99;
13528     }
13529   if (mac_set == 0)
13530     {
13531       errmsg ("missing remote mac address");
13532       return -99;
13533     }
13534   if (sub_id == ~0)
13535     {
13536       errmsg ("missing sub-interface id");
13537       return -99;
13538     }
13539
13540   M (P2P_ETHERNET_ADD, mp);
13541   mp->parent_if_index = ntohl (parent_if_index);
13542   mp->subif_id = ntohl (sub_id);
13543   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
13544
13545   S (mp);
13546   W (ret);
13547   return ret;
13548 }
13549
13550 static int
13551 api_p2p_ethernet_del (vat_main_t * vam)
13552 {
13553   unformat_input_t *i = vam->input;
13554   vl_api_p2p_ethernet_del_t *mp;
13555   u32 parent_if_index = ~0;
13556   u8 remote_mac[6];
13557   u8 mac_set = 0;
13558   int ret;
13559
13560   clib_memset (remote_mac, 0, sizeof (remote_mac));
13561   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13562     {
13563       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
13564         ;
13565       else if (unformat (i, "sw_if_index %d", &parent_if_index))
13566         ;
13567       else
13568         if (unformat
13569             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
13570         mac_set++;
13571       else
13572         {
13573           clib_warning ("parse error '%U'", format_unformat_error, i);
13574           return -99;
13575         }
13576     }
13577
13578   if (parent_if_index == ~0)
13579     {
13580       errmsg ("missing interface name or sw_if_index");
13581       return -99;
13582     }
13583   if (mac_set == 0)
13584     {
13585       errmsg ("missing remote mac address");
13586       return -99;
13587     }
13588
13589   M (P2P_ETHERNET_DEL, mp);
13590   mp->parent_if_index = ntohl (parent_if_index);
13591   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
13592
13593   S (mp);
13594   W (ret);
13595   return ret;
13596 }
13597
13598 static int
13599 api_tcp_configure_src_addresses (vat_main_t * vam)
13600 {
13601   vl_api_tcp_configure_src_addresses_t *mp;
13602   unformat_input_t *i = vam->input;
13603   vl_api_address_t first, last;
13604   u8 range_set = 0;
13605   u32 vrf_id = 0;
13606   int ret;
13607
13608   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13609     {
13610       if (unformat (i, "%U - %U",
13611                     unformat_vl_api_address, &first,
13612                     unformat_vl_api_address, &last))
13613         {
13614           if (range_set)
13615             {
13616               errmsg ("one range per message (range already set)");
13617               return -99;
13618             }
13619           range_set = 1;
13620         }
13621       else if (unformat (i, "vrf %d", &vrf_id))
13622         ;
13623       else
13624         break;
13625     }
13626
13627   if (range_set == 0)
13628     {
13629       errmsg ("address range not set");
13630       return -99;
13631     }
13632
13633   M (TCP_CONFIGURE_SRC_ADDRESSES, mp);
13634
13635   mp->vrf_id = ntohl (vrf_id);
13636   clib_memcpy (&mp->first_address, &first, sizeof (first));
13637   clib_memcpy (&mp->last_address, &last, sizeof (last));
13638
13639   S (mp);
13640   W (ret);
13641   return ret;
13642 }
13643
13644 static void vl_api_app_namespace_add_del_reply_t_handler
13645   (vl_api_app_namespace_add_del_reply_t * mp)
13646 {
13647   vat_main_t *vam = &vat_main;
13648   i32 retval = ntohl (mp->retval);
13649   if (vam->async_mode)
13650     {
13651       vam->async_errors += (retval < 0);
13652     }
13653   else
13654     {
13655       vam->retval = retval;
13656       if (retval == 0)
13657         errmsg ("app ns index %d\n", ntohl (mp->appns_index));
13658       vam->result_ready = 1;
13659     }
13660 }
13661
13662 static void vl_api_app_namespace_add_del_reply_t_handler_json
13663   (vl_api_app_namespace_add_del_reply_t * mp)
13664 {
13665   vat_main_t *vam = &vat_main;
13666   vat_json_node_t node;
13667
13668   vat_json_init_object (&node);
13669   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
13670   vat_json_object_add_uint (&node, "appns_index", ntohl (mp->appns_index));
13671
13672   vat_json_print (vam->ofp, &node);
13673   vat_json_free (&node);
13674
13675   vam->retval = ntohl (mp->retval);
13676   vam->result_ready = 1;
13677 }
13678
13679 static int
13680 api_app_namespace_add_del (vat_main_t * vam)
13681 {
13682   vl_api_app_namespace_add_del_t *mp;
13683   unformat_input_t *i = vam->input;
13684   u8 *ns_id = 0, secret_set = 0, sw_if_index_set = 0;
13685   u32 sw_if_index, ip4_fib_id, ip6_fib_id;
13686   u64 secret;
13687   int ret;
13688
13689   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13690     {
13691       if (unformat (i, "id %_%v%_", &ns_id))
13692         ;
13693       else if (unformat (i, "secret %lu", &secret))
13694         secret_set = 1;
13695       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13696         sw_if_index_set = 1;
13697       else if (unformat (i, "ip4_fib_id %d", &ip4_fib_id))
13698         ;
13699       else if (unformat (i, "ip6_fib_id %d", &ip6_fib_id))
13700         ;
13701       else
13702         break;
13703     }
13704   if (!ns_id || !secret_set || !sw_if_index_set)
13705     {
13706       errmsg ("namespace id, secret and sw_if_index must be set");
13707       return -99;
13708     }
13709   if (vec_len (ns_id) > 64)
13710     {
13711       errmsg ("namespace id too long");
13712       return -99;
13713     }
13714   M (APP_NAMESPACE_ADD_DEL, mp);
13715
13716   vl_api_vec_to_api_string (ns_id, &mp->namespace_id);
13717   mp->secret = clib_host_to_net_u64 (secret);
13718   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
13719   mp->ip4_fib_id = clib_host_to_net_u32 (ip4_fib_id);
13720   mp->ip6_fib_id = clib_host_to_net_u32 (ip6_fib_id);
13721   vec_free (ns_id);
13722   S (mp);
13723   W (ret);
13724   return ret;
13725 }
13726
13727 static int
13728 api_sock_init_shm (vat_main_t * vam)
13729 {
13730 #if VPP_API_TEST_BUILTIN == 0
13731   unformat_input_t *i = vam->input;
13732   vl_api_shm_elem_config_t *config = 0;
13733   u64 size = 64 << 20;
13734   int rv;
13735
13736   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13737     {
13738       if (unformat (i, "size %U", unformat_memory_size, &size))
13739         ;
13740       else
13741         break;
13742     }
13743
13744   /*
13745    * Canned custom ring allocator config.
13746    * Should probably parse all of this
13747    */
13748   vec_validate (config, 6);
13749   config[0].type = VL_API_VLIB_RING;
13750   config[0].size = 256;
13751   config[0].count = 32;
13752
13753   config[1].type = VL_API_VLIB_RING;
13754   config[1].size = 1024;
13755   config[1].count = 16;
13756
13757   config[2].type = VL_API_VLIB_RING;
13758   config[2].size = 4096;
13759   config[2].count = 2;
13760
13761   config[3].type = VL_API_CLIENT_RING;
13762   config[3].size = 256;
13763   config[3].count = 32;
13764
13765   config[4].type = VL_API_CLIENT_RING;
13766   config[4].size = 1024;
13767   config[4].count = 16;
13768
13769   config[5].type = VL_API_CLIENT_RING;
13770   config[5].size = 4096;
13771   config[5].count = 2;
13772
13773   config[6].type = VL_API_QUEUE;
13774   config[6].count = 128;
13775   config[6].size = sizeof (uword);
13776
13777   rv = vl_socket_client_init_shm (config, 1 /* want_pthread */ );
13778   if (!rv)
13779     vam->client_index_invalid = 1;
13780   return rv;
13781 #else
13782   return -99;
13783 #endif
13784 }
13785
13786 static void
13787 vl_api_session_rules_details_t_handler (vl_api_session_rules_details_t * mp)
13788 {
13789   vat_main_t *vam = &vat_main;
13790   fib_prefix_t lcl, rmt;
13791
13792   ip_prefix_decode (&mp->lcl, &lcl);
13793   ip_prefix_decode (&mp->rmt, &rmt);
13794
13795   if (lcl.fp_proto == FIB_PROTOCOL_IP4)
13796     {
13797       print (vam->ofp,
13798              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
13799              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
13800              mp->scope, format_ip4_address, &lcl.fp_addr.ip4, lcl.fp_len,
13801              clib_net_to_host_u16 (mp->lcl_port), format_ip4_address,
13802              &rmt.fp_addr.ip4, rmt.fp_len,
13803              clib_net_to_host_u16 (mp->rmt_port),
13804              clib_net_to_host_u32 (mp->action_index), mp->tag);
13805     }
13806   else
13807     {
13808       print (vam->ofp,
13809              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
13810              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
13811              mp->scope, format_ip6_address, &lcl.fp_addr.ip6, lcl.fp_len,
13812              clib_net_to_host_u16 (mp->lcl_port), format_ip6_address,
13813              &rmt.fp_addr.ip6, rmt.fp_len,
13814              clib_net_to_host_u16 (mp->rmt_port),
13815              clib_net_to_host_u32 (mp->action_index), mp->tag);
13816     }
13817 }
13818
13819 static void
13820 vl_api_session_rules_details_t_handler_json (vl_api_session_rules_details_t *
13821                                              mp)
13822 {
13823   vat_main_t *vam = &vat_main;
13824   vat_json_node_t *node = NULL;
13825   struct in6_addr ip6;
13826   struct in_addr ip4;
13827
13828   fib_prefix_t lcl, rmt;
13829
13830   ip_prefix_decode (&mp->lcl, &lcl);
13831   ip_prefix_decode (&mp->rmt, &rmt);
13832
13833   if (VAT_JSON_ARRAY != vam->json_tree.type)
13834     {
13835       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13836       vat_json_init_array (&vam->json_tree);
13837     }
13838   node = vat_json_array_add (&vam->json_tree);
13839   vat_json_init_object (node);
13840
13841   vat_json_object_add_uint (node, "appns_index",
13842                             clib_net_to_host_u32 (mp->appns_index));
13843   vat_json_object_add_uint (node, "transport_proto", mp->transport_proto);
13844   vat_json_object_add_uint (node, "scope", mp->scope);
13845   vat_json_object_add_uint (node, "action_index",
13846                             clib_net_to_host_u32 (mp->action_index));
13847   vat_json_object_add_uint (node, "lcl_port",
13848                             clib_net_to_host_u16 (mp->lcl_port));
13849   vat_json_object_add_uint (node, "rmt_port",
13850                             clib_net_to_host_u16 (mp->rmt_port));
13851   vat_json_object_add_uint (node, "lcl_plen", lcl.fp_len);
13852   vat_json_object_add_uint (node, "rmt_plen", rmt.fp_len);
13853   vat_json_object_add_string_copy (node, "tag", mp->tag);
13854   if (lcl.fp_proto == FIB_PROTOCOL_IP4)
13855     {
13856       clib_memcpy (&ip4, &lcl.fp_addr.ip4, sizeof (ip4));
13857       vat_json_object_add_ip4 (node, "lcl_ip", ip4);
13858       clib_memcpy (&ip4, &rmt.fp_addr.ip4, sizeof (ip4));
13859       vat_json_object_add_ip4 (node, "rmt_ip", ip4);
13860     }
13861   else
13862     {
13863       clib_memcpy (&ip6, &lcl.fp_addr.ip6, sizeof (ip6));
13864       vat_json_object_add_ip6 (node, "lcl_ip", ip6);
13865       clib_memcpy (&ip6, &rmt.fp_addr.ip6, sizeof (ip6));
13866       vat_json_object_add_ip6 (node, "rmt_ip", ip6);
13867     }
13868 }
13869
13870 static int
13871 api_session_rule_add_del (vat_main_t * vam)
13872 {
13873   vl_api_session_rule_add_del_t *mp;
13874   unformat_input_t *i = vam->input;
13875   u32 proto = ~0, lcl_port, rmt_port, action = 0, lcl_plen, rmt_plen;
13876   u32 appns_index = 0, scope = 0;
13877   ip4_address_t lcl_ip4, rmt_ip4;
13878   ip6_address_t lcl_ip6, rmt_ip6;
13879   u8 is_ip4 = 1, conn_set = 0;
13880   u8 is_add = 1, *tag = 0;
13881   int ret;
13882   fib_prefix_t lcl, rmt;
13883
13884   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13885     {
13886       if (unformat (i, "del"))
13887         is_add = 0;
13888       else if (unformat (i, "add"))
13889         ;
13890       else if (unformat (i, "proto tcp"))
13891         proto = 0;
13892       else if (unformat (i, "proto udp"))
13893         proto = 1;
13894       else if (unformat (i, "appns %d", &appns_index))
13895         ;
13896       else if (unformat (i, "scope %d", &scope))
13897         ;
13898       else if (unformat (i, "tag %_%v%_", &tag))
13899         ;
13900       else
13901         if (unformat
13902             (i, "%U/%d %d %U/%d %d", unformat_ip4_address, &lcl_ip4,
13903              &lcl_plen, &lcl_port, unformat_ip4_address, &rmt_ip4, &rmt_plen,
13904              &rmt_port))
13905         {
13906           is_ip4 = 1;
13907           conn_set = 1;
13908         }
13909       else
13910         if (unformat
13911             (i, "%U/%d %d %U/%d %d", unformat_ip6_address, &lcl_ip6,
13912              &lcl_plen, &lcl_port, unformat_ip6_address, &rmt_ip6, &rmt_plen,
13913              &rmt_port))
13914         {
13915           is_ip4 = 0;
13916           conn_set = 1;
13917         }
13918       else if (unformat (i, "action %d", &action))
13919         ;
13920       else
13921         break;
13922     }
13923   if (proto == ~0 || !conn_set || action == ~0)
13924     {
13925       errmsg ("transport proto, connection and action must be set");
13926       return -99;
13927     }
13928
13929   if (scope > 3)
13930     {
13931       errmsg ("scope should be 0-3");
13932       return -99;
13933     }
13934
13935   M (SESSION_RULE_ADD_DEL, mp);
13936
13937   clib_memset (&lcl, 0, sizeof (lcl));
13938   clib_memset (&rmt, 0, sizeof (rmt));
13939   if (is_ip4)
13940     {
13941       ip_set (&lcl.fp_addr, &lcl_ip4, 1);
13942       ip_set (&rmt.fp_addr, &rmt_ip4, 1);
13943       lcl.fp_len = lcl_plen;
13944       rmt.fp_len = rmt_plen;
13945     }
13946   else
13947     {
13948       ip_set (&lcl.fp_addr, &lcl_ip6, 0);
13949       ip_set (&rmt.fp_addr, &rmt_ip6, 0);
13950       lcl.fp_len = lcl_plen;
13951       rmt.fp_len = rmt_plen;
13952     }
13953
13954
13955   ip_prefix_encode (&lcl, &mp->lcl);
13956   ip_prefix_encode (&rmt, &mp->rmt);
13957   mp->lcl_port = clib_host_to_net_u16 ((u16) lcl_port);
13958   mp->rmt_port = clib_host_to_net_u16 ((u16) rmt_port);
13959   mp->transport_proto =
13960     proto ? TRANSPORT_PROTO_API_UDP : TRANSPORT_PROTO_API_TCP;
13961   mp->action_index = clib_host_to_net_u32 (action);
13962   mp->appns_index = clib_host_to_net_u32 (appns_index);
13963   mp->scope = scope;
13964   mp->is_add = is_add;
13965   if (tag)
13966     {
13967       clib_memcpy (mp->tag, tag, vec_len (tag));
13968       vec_free (tag);
13969     }
13970
13971   S (mp);
13972   W (ret);
13973   return ret;
13974 }
13975
13976 static int
13977 api_session_rules_dump (vat_main_t * vam)
13978 {
13979   vl_api_session_rules_dump_t *mp;
13980   vl_api_control_ping_t *mp_ping;
13981   int ret;
13982
13983   if (!vam->json_output)
13984     {
13985       print (vam->ofp, "%=20s", "Session Rules");
13986     }
13987
13988   M (SESSION_RULES_DUMP, mp);
13989   /* send it... */
13990   S (mp);
13991
13992   /* Use a control ping for synchronization */
13993   MPING (CONTROL_PING, mp_ping);
13994   S (mp_ping);
13995
13996   /* Wait for a reply... */
13997   W (ret);
13998   return ret;
13999 }
14000
14001 static int
14002 api_ip_container_proxy_add_del (vat_main_t * vam)
14003 {
14004   vl_api_ip_container_proxy_add_del_t *mp;
14005   unformat_input_t *i = vam->input;
14006   u32 sw_if_index = ~0;
14007   vl_api_prefix_t pfx = { };
14008   u8 is_add = 1;
14009   int ret;
14010
14011   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14012     {
14013       if (unformat (i, "del"))
14014         is_add = 0;
14015       else if (unformat (i, "add"))
14016         ;
14017       if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
14018         ;
14019       else if (unformat (i, "sw_if_index %u", &sw_if_index))
14020         ;
14021       else
14022         break;
14023     }
14024   if (sw_if_index == ~0 || pfx.len == 0)
14025     {
14026       errmsg ("address and sw_if_index must be set");
14027       return -99;
14028     }
14029
14030   M (IP_CONTAINER_PROXY_ADD_DEL, mp);
14031
14032   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
14033   mp->is_add = is_add;
14034   clib_memcpy (&mp->pfx, &pfx, sizeof (pfx));
14035
14036   S (mp);
14037   W (ret);
14038   return ret;
14039 }
14040
14041 static int
14042 api_qos_record_enable_disable (vat_main_t * vam)
14043 {
14044   unformat_input_t *i = vam->input;
14045   vl_api_qos_record_enable_disable_t *mp;
14046   u32 sw_if_index, qs = 0xff;
14047   u8 sw_if_index_set = 0;
14048   u8 enable = 1;
14049   int ret;
14050
14051   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14052     {
14053       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14054         sw_if_index_set = 1;
14055       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14056         sw_if_index_set = 1;
14057       else if (unformat (i, "%U", unformat_qos_source, &qs))
14058         ;
14059       else if (unformat (i, "disable"))
14060         enable = 0;
14061       else
14062         {
14063           clib_warning ("parse error '%U'", format_unformat_error, i);
14064           return -99;
14065         }
14066     }
14067
14068   if (sw_if_index_set == 0)
14069     {
14070       errmsg ("missing interface name or sw_if_index");
14071       return -99;
14072     }
14073   if (qs == 0xff)
14074     {
14075       errmsg ("input location must be specified");
14076       return -99;
14077     }
14078
14079   M (QOS_RECORD_ENABLE_DISABLE, mp);
14080
14081   mp->record.sw_if_index = ntohl (sw_if_index);
14082   mp->record.input_source = qs;
14083   mp->enable = enable;
14084
14085   S (mp);
14086   W (ret);
14087   return ret;
14088 }
14089
14090
14091 static int
14092 q_or_quit (vat_main_t * vam)
14093 {
14094 #if VPP_API_TEST_BUILTIN == 0
14095   longjmp (vam->jump_buf, 1);
14096 #endif
14097   return 0;                     /* not so much */
14098 }
14099
14100 static int
14101 q (vat_main_t * vam)
14102 {
14103   return q_or_quit (vam);
14104 }
14105
14106 static int
14107 quit (vat_main_t * vam)
14108 {
14109   return q_or_quit (vam);
14110 }
14111
14112 static int
14113 comment (vat_main_t * vam)
14114 {
14115   return 0;
14116 }
14117
14118 static int
14119 elog_save (vat_main_t * vam)
14120 {
14121 #if VPP_API_TEST_BUILTIN == 0
14122   elog_main_t *em = &vam->elog_main;
14123   unformat_input_t *i = vam->input;
14124   char *file, *chroot_file;
14125   clib_error_t *error;
14126
14127   if (!unformat (i, "%s", &file))
14128     {
14129       errmsg ("expected file name, got `%U'", format_unformat_error, i);
14130       return 0;
14131     }
14132
14133   /* It's fairly hard to get "../oopsie" through unformat; just in case */
14134   if (strstr (file, "..") || index (file, '/'))
14135     {
14136       errmsg ("illegal characters in filename '%s'", file);
14137       return 0;
14138     }
14139
14140   chroot_file = (char *) format (0, "/tmp/%s%c", file, 0);
14141
14142   vec_free (file);
14143
14144   errmsg ("Saving %wd of %wd events to %s",
14145           elog_n_events_in_buffer (em),
14146           elog_buffer_capacity (em), chroot_file);
14147
14148   error = elog_write_file (em, chroot_file, 1 /* flush ring */ );
14149   vec_free (chroot_file);
14150
14151   if (error)
14152     clib_error_report (error);
14153 #else
14154   errmsg ("Use the vpp event loger...");
14155 #endif
14156
14157   return 0;
14158 }
14159
14160 static int
14161 elog_setup (vat_main_t * vam)
14162 {
14163 #if VPP_API_TEST_BUILTIN == 0
14164   elog_main_t *em = &vam->elog_main;
14165   unformat_input_t *i = vam->input;
14166   u32 nevents = 128 << 10;
14167
14168   (void) unformat (i, "nevents %d", &nevents);
14169
14170   elog_init (em, nevents);
14171   vl_api_set_elog_main (em);
14172   vl_api_set_elog_trace_api_messages (1);
14173   errmsg ("Event logger initialized with %u events", nevents);
14174 #else
14175   errmsg ("Use the vpp event loger...");
14176 #endif
14177   return 0;
14178 }
14179
14180 static int
14181 elog_enable (vat_main_t * vam)
14182 {
14183 #if VPP_API_TEST_BUILTIN == 0
14184   elog_main_t *em = &vam->elog_main;
14185
14186   elog_enable_disable (em, 1 /* enable */ );
14187   vl_api_set_elog_trace_api_messages (1);
14188   errmsg ("Event logger enabled...");
14189 #else
14190   errmsg ("Use the vpp event loger...");
14191 #endif
14192   return 0;
14193 }
14194
14195 static int
14196 elog_disable (vat_main_t * vam)
14197 {
14198 #if VPP_API_TEST_BUILTIN == 0
14199   elog_main_t *em = &vam->elog_main;
14200
14201   elog_enable_disable (em, 0 /* enable */ );
14202   vl_api_set_elog_trace_api_messages (1);
14203   errmsg ("Event logger disabled...");
14204 #else
14205   errmsg ("Use the vpp event loger...");
14206 #endif
14207   return 0;
14208 }
14209
14210 static int
14211 statseg (vat_main_t * vam)
14212 {
14213   ssvm_private_t *ssvmp = &vam->stat_segment;
14214   ssvm_shared_header_t *shared_header = ssvmp->sh;
14215   vlib_counter_t **counters;
14216   u64 thread0_index1_packets;
14217   u64 thread0_index1_bytes;
14218   f64 vector_rate, input_rate;
14219   uword *p;
14220
14221   uword *counter_vector_by_name;
14222   if (vam->stat_segment_lockp == 0)
14223     {
14224       errmsg ("Stat segment not mapped...");
14225       return -99;
14226     }
14227
14228   /* look up "/if/rx for sw_if_index 1 as a test */
14229
14230   clib_spinlock_lock (vam->stat_segment_lockp);
14231
14232   counter_vector_by_name = (uword *) shared_header->opaque[1];
14233
14234   p = hash_get_mem (counter_vector_by_name, "/if/rx");
14235   if (p == 0)
14236     {
14237       clib_spinlock_unlock (vam->stat_segment_lockp);
14238       errmsg ("/if/tx not found?");
14239       return -99;
14240     }
14241
14242   /* Fish per-thread vector of combined counters from shared memory */
14243   counters = (vlib_counter_t **) p[0];
14244
14245   if (vec_len (counters[0]) < 2)
14246     {
14247       clib_spinlock_unlock (vam->stat_segment_lockp);
14248       errmsg ("/if/tx vector length %d", vec_len (counters[0]));
14249       return -99;
14250     }
14251
14252   /* Read thread 0 sw_if_index 1 counter */
14253   thread0_index1_packets = counters[0][1].packets;
14254   thread0_index1_bytes = counters[0][1].bytes;
14255
14256   p = hash_get_mem (counter_vector_by_name, "vector_rate");
14257   if (p == 0)
14258     {
14259       clib_spinlock_unlock (vam->stat_segment_lockp);
14260       errmsg ("vector_rate not found?");
14261       return -99;
14262     }
14263
14264   vector_rate = *(f64 *) (p[0]);
14265   p = hash_get_mem (counter_vector_by_name, "input_rate");
14266   if (p == 0)
14267     {
14268       clib_spinlock_unlock (vam->stat_segment_lockp);
14269       errmsg ("input_rate not found?");
14270       return -99;
14271     }
14272   input_rate = *(f64 *) (p[0]);
14273
14274   clib_spinlock_unlock (vam->stat_segment_lockp);
14275
14276   print (vam->ofp, "vector_rate %.2f input_rate %.2f",
14277          vector_rate, input_rate);
14278   print (vam->ofp, "thread 0 sw_if_index 1 rx pkts %lld, bytes %lld",
14279          thread0_index1_packets, thread0_index1_bytes);
14280
14281   return 0;
14282 }
14283
14284 static int
14285 cmd_cmp (void *a1, void *a2)
14286 {
14287   u8 **c1 = a1;
14288   u8 **c2 = a2;
14289
14290   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
14291 }
14292
14293 static int
14294 help (vat_main_t * vam)
14295 {
14296   u8 **cmds = 0;
14297   u8 *name = 0;
14298   hash_pair_t *p;
14299   unformat_input_t *i = vam->input;
14300   int j;
14301
14302   if (unformat (i, "%s", &name))
14303     {
14304       uword *hs;
14305
14306       vec_add1 (name, 0);
14307
14308       hs = hash_get_mem (vam->help_by_name, name);
14309       if (hs)
14310         print (vam->ofp, "usage: %s %s", name, hs[0]);
14311       else
14312         print (vam->ofp, "No such msg / command '%s'", name);
14313       vec_free (name);
14314       return 0;
14315     }
14316
14317   print (vam->ofp, "Help is available for the following:");
14318
14319     /* *INDENT-OFF* */
14320     hash_foreach_pair (p, vam->function_by_name,
14321     ({
14322       vec_add1 (cmds, (u8 *)(p->key));
14323     }));
14324     /* *INDENT-ON* */
14325
14326   vec_sort_with_function (cmds, cmd_cmp);
14327
14328   for (j = 0; j < vec_len (cmds); j++)
14329     print (vam->ofp, "%s", cmds[j]);
14330
14331   vec_free (cmds);
14332   return 0;
14333 }
14334
14335 static int
14336 set (vat_main_t * vam)
14337 {
14338   u8 *name = 0, *value = 0;
14339   unformat_input_t *i = vam->input;
14340
14341   if (unformat (i, "%s", &name))
14342     {
14343       /* The input buffer is a vector, not a string. */
14344       value = vec_dup (i->buffer);
14345       vec_delete (value, i->index, 0);
14346       /* Almost certainly has a trailing newline */
14347       if (value[vec_len (value) - 1] == '\n')
14348         value[vec_len (value) - 1] = 0;
14349       /* Make sure it's a proper string, one way or the other */
14350       vec_add1 (value, 0);
14351       (void) clib_macro_set_value (&vam->macro_main,
14352                                    (char *) name, (char *) value);
14353     }
14354   else
14355     errmsg ("usage: set <name> <value>");
14356
14357   vec_free (name);
14358   vec_free (value);
14359   return 0;
14360 }
14361
14362 static int
14363 unset (vat_main_t * vam)
14364 {
14365   u8 *name = 0;
14366
14367   if (unformat (vam->input, "%s", &name))
14368     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
14369       errmsg ("unset: %s wasn't set", name);
14370   vec_free (name);
14371   return 0;
14372 }
14373
14374 typedef struct
14375 {
14376   u8 *name;
14377   u8 *value;
14378 } macro_sort_t;
14379
14380
14381 static int
14382 macro_sort_cmp (void *a1, void *a2)
14383 {
14384   macro_sort_t *s1 = a1;
14385   macro_sort_t *s2 = a2;
14386
14387   return strcmp ((char *) (s1->name), (char *) (s2->name));
14388 }
14389
14390 static int
14391 dump_macro_table (vat_main_t * vam)
14392 {
14393   macro_sort_t *sort_me = 0, *sm;
14394   int i;
14395   hash_pair_t *p;
14396
14397     /* *INDENT-OFF* */
14398     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
14399     ({
14400       vec_add2 (sort_me, sm, 1);
14401       sm->name = (u8 *)(p->key);
14402       sm->value = (u8 *) (p->value[0]);
14403     }));
14404     /* *INDENT-ON* */
14405
14406   vec_sort_with_function (sort_me, macro_sort_cmp);
14407
14408   if (vec_len (sort_me))
14409     print (vam->ofp, "%-15s%s", "Name", "Value");
14410   else
14411     print (vam->ofp, "The macro table is empty...");
14412
14413   for (i = 0; i < vec_len (sort_me); i++)
14414     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
14415   return 0;
14416 }
14417
14418 static int
14419 dump_node_table (vat_main_t * vam)
14420 {
14421   int i, j;
14422   vlib_node_t *node, *next_node;
14423
14424   if (vec_len (vam->graph_nodes) == 0)
14425     {
14426       print (vam->ofp, "Node table empty, issue get_node_graph...");
14427       return 0;
14428     }
14429
14430   for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
14431     {
14432       node = vam->graph_nodes[0][i];
14433       print (vam->ofp, "[%d] %s", i, node->name);
14434       for (j = 0; j < vec_len (node->next_nodes); j++)
14435         {
14436           if (node->next_nodes[j] != ~0)
14437             {
14438               next_node = vam->graph_nodes[0][node->next_nodes[j]];
14439               print (vam->ofp, "  [%d] %s", j, next_node->name);
14440             }
14441         }
14442     }
14443   return 0;
14444 }
14445
14446 static int
14447 value_sort_cmp (void *a1, void *a2)
14448 {
14449   name_sort_t *n1 = a1;
14450   name_sort_t *n2 = a2;
14451
14452   if (n1->value < n2->value)
14453     return -1;
14454   if (n1->value > n2->value)
14455     return 1;
14456   return 0;
14457 }
14458
14459
14460 static int
14461 dump_msg_api_table (vat_main_t * vam)
14462 {
14463   api_main_t *am = vlibapi_get_main ();
14464   name_sort_t *nses = 0, *ns;
14465   hash_pair_t *hp;
14466   int i;
14467
14468   /* *INDENT-OFF* */
14469   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
14470   ({
14471     vec_add2 (nses, ns, 1);
14472     ns->name = (u8 *)(hp->key);
14473     ns->value = (u32) hp->value[0];
14474   }));
14475   /* *INDENT-ON* */
14476
14477   vec_sort_with_function (nses, value_sort_cmp);
14478
14479   for (i = 0; i < vec_len (nses); i++)
14480     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
14481   vec_free (nses);
14482   return 0;
14483 }
14484
14485 static int
14486 get_msg_id (vat_main_t * vam)
14487 {
14488   u8 *name_and_crc;
14489   u32 message_index;
14490
14491   if (unformat (vam->input, "%s", &name_and_crc))
14492     {
14493       message_index = vl_msg_api_get_msg_index (name_and_crc);
14494       if (message_index == ~0)
14495         {
14496           print (vam->ofp, " '%s' not found", name_and_crc);
14497           return 0;
14498         }
14499       print (vam->ofp, " '%s' has message index %d",
14500              name_and_crc, message_index);
14501       return 0;
14502     }
14503   errmsg ("name_and_crc required...");
14504   return 0;
14505 }
14506
14507 static int
14508 search_node_table (vat_main_t * vam)
14509 {
14510   unformat_input_t *line_input = vam->input;
14511   u8 *node_to_find;
14512   int j;
14513   vlib_node_t *node, *next_node;
14514   uword *p;
14515
14516   if (vam->graph_node_index_by_name == 0)
14517     {
14518       print (vam->ofp, "Node table empty, issue get_node_graph...");
14519       return 0;
14520     }
14521
14522   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14523     {
14524       if (unformat (line_input, "%s", &node_to_find))
14525         {
14526           vec_add1 (node_to_find, 0);
14527           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
14528           if (p == 0)
14529             {
14530               print (vam->ofp, "%s not found...", node_to_find);
14531               goto out;
14532             }
14533           node = vam->graph_nodes[0][p[0]];
14534           print (vam->ofp, "[%d] %s", p[0], node->name);
14535           for (j = 0; j < vec_len (node->next_nodes); j++)
14536             {
14537               if (node->next_nodes[j] != ~0)
14538                 {
14539                   next_node = vam->graph_nodes[0][node->next_nodes[j]];
14540                   print (vam->ofp, "  [%d] %s", j, next_node->name);
14541                 }
14542             }
14543         }
14544
14545       else
14546         {
14547           clib_warning ("parse error '%U'", format_unformat_error,
14548                         line_input);
14549           return -99;
14550         }
14551
14552     out:
14553       vec_free (node_to_find);
14554
14555     }
14556
14557   return 0;
14558 }
14559
14560
14561 static int
14562 script (vat_main_t * vam)
14563 {
14564 #if (VPP_API_TEST_BUILTIN==0)
14565   u8 *s = 0;
14566   char *save_current_file;
14567   unformat_input_t save_input;
14568   jmp_buf save_jump_buf;
14569   u32 save_line_number;
14570
14571   FILE *new_fp, *save_ifp;
14572
14573   if (unformat (vam->input, "%s", &s))
14574     {
14575       new_fp = fopen ((char *) s, "r");
14576       if (new_fp == 0)
14577         {
14578           errmsg ("Couldn't open script file %s", s);
14579           vec_free (s);
14580           return -99;
14581         }
14582     }
14583   else
14584     {
14585       errmsg ("Missing script name");
14586       return -99;
14587     }
14588
14589   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
14590   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
14591   save_ifp = vam->ifp;
14592   save_line_number = vam->input_line_number;
14593   save_current_file = (char *) vam->current_file;
14594
14595   vam->input_line_number = 0;
14596   vam->ifp = new_fp;
14597   vam->current_file = s;
14598   do_one_file (vam);
14599
14600   clib_memcpy (&vam->input, &save_input, sizeof (save_input));
14601   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
14602   vam->ifp = save_ifp;
14603   vam->input_line_number = save_line_number;
14604   vam->current_file = (u8 *) save_current_file;
14605   vec_free (s);
14606
14607   return 0;
14608 #else
14609   clib_warning ("use the exec command...");
14610   return -99;
14611 #endif
14612 }
14613
14614 static int
14615 echo (vat_main_t * vam)
14616 {
14617   print (vam->ofp, "%v", vam->input->buffer);
14618   return 0;
14619 }
14620
14621 /* List of API message constructors, CLI names map to api_xxx */
14622 #define foreach_vpe_api_msg                                             \
14623 _(create_loopback,"[mac <mac-addr>] [instance <instance>]")             \
14624 _(sw_interface_dump,"")                                                 \
14625 _(sw_interface_set_flags,                                               \
14626   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
14627 _(sw_interface_add_del_address,                                         \
14628   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
14629 _(sw_interface_set_rx_mode,                                             \
14630   "<intfc> | sw_if_index <id> [queue <id>] <polling | interrupt | adaptive>") \
14631 _(sw_interface_set_rx_placement,                                        \
14632   "<intfc> | sw_if_index <id> [queue <id>] [worker <id> | main]")       \
14633 _(sw_interface_rx_placement_dump,                                       \
14634   "[<intfc> | sw_if_index <id>]")                                         \
14635 _(sw_interface_set_table,                                               \
14636   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
14637 _(sw_interface_set_mpls_enable,                                         \
14638   "<intfc> | sw_if_index [disable | dis]")                              \
14639 _(sw_interface_set_vpath,                                               \
14640   "<intfc> | sw_if_index <id> enable | disable")                        \
14641 _(sw_interface_set_vxlan_bypass,                                        \
14642   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
14643 _(sw_interface_set_l2_xconnect,                                         \
14644   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
14645   "enable | disable")                                                   \
14646 _(sw_interface_set_l2_bridge,                                           \
14647   "{<intfc> | sw_if_index <id>} bd_id <bridge-domain-id>\n"             \
14648   "[shg <split-horizon-group>] [bvi]\n"                                 \
14649   "enable | disable")                                                   \
14650 _(bridge_domain_set_mac_age, "bd_id <bridge-domain-id> mac-age 0-255")  \
14651 _(bridge_domain_add_del,                                                \
14652   "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") \
14653 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
14654 _(l2fib_add_del,                                                        \
14655   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
14656 _(l2fib_flush_bd, "bd_id <bridge-domain-id>")                           \
14657 _(l2fib_flush_int, "<intfc> | sw_if_index <id>")                        \
14658 _(l2_flags,                                                             \
14659   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
14660 _(bridge_flags,                                                         \
14661   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
14662 _(tap_create_v2,                                                        \
14663   "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]") \
14664 _(tap_delete_v2,                                                        \
14665   "<vpp-if-name> | sw_if_index <id>")                                   \
14666 _(sw_interface_tap_v2_dump, "")                                         \
14667 _(virtio_pci_create_v2,                                                    \
14668   "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]") \
14669 _(virtio_pci_delete,                                                    \
14670   "<vpp-if-name> | sw_if_index <id>")                                   \
14671 _(sw_interface_virtio_pci_dump, "")                                     \
14672 _(bond_create,                                                          \
14673   "[hw-addr <mac-addr>] {round-robin | active-backup | "                \
14674   "broadcast | {lacp | xor} [load-balance { l2 | l23 | l34 }]} "        \
14675   "[id <if-id>]")                                                       \
14676 _(bond_create2,                                                         \
14677   "[hw-addr <mac-addr>] {mode round-robin | active-backup | "           \
14678   "broadcast | {lacp | xor} [load-balance { l2 | l23 | l34 }]} "        \
14679   "[id <if-id>] [gso]")                                                 \
14680 _(bond_delete,                                                          \
14681   "<vpp-if-name> | sw_if_index <id>")                                   \
14682 _(bond_add_member,                                                      \
14683   "sw_if_index <n> bond <sw_if_index> [is_passive] [is_long_timeout]")  \
14684 _(bond_detach_member,                                                   \
14685   "sw_if_index <n>")                                                    \
14686  _(sw_interface_set_bond_weight, "<intfc> | sw_if_index <nn> weight <value>") \
14687  _(sw_bond_interface_dump, "<intfc> | sw_if_index <nn>")                \
14688  _(sw_member_interface_dump,                                            \
14689   "<vpp-if-name> | sw_if_index <id>")                                   \
14690 _(ip_table_add_del,                                                     \
14691   "table <n> [ipv6] [add | del]\n")                                     \
14692 _(ip_route_add_del,                                                     \
14693   "<addr>/<mask> via <<addr>|<intfc>|sw_if_index <id>|via-label <n>>\n" \
14694   "[table-id <n>] [<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"\
14695   "[weight <n>] [drop] [local] [classify <n>]  [out-label <n>]\n"       \
14696   "[multipath] [count <n>] [del]")                                      \
14697 _(ip_mroute_add_del,                                                    \
14698   "<src> <grp>/<mask> [table-id <n>]\n"                                 \
14699   "[<intfc> | sw_if_index <id>] [local] [del]")                         \
14700 _(mpls_table_add_del,                                                   \
14701   "table <n> [add | del]\n")                                            \
14702 _(mpls_route_add_del,                                                   \
14703   "<label> <eos> via <addr | next-hop-table <n> | via-label <n> |\n"    \
14704   "lookup-ip4-table <n> | lookup-in-ip6-table <n> |\n"                  \
14705   "l2-input-on <intfc> | l2-input-on sw_if_index <id>>\n"               \
14706   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>] [weight <n>]\n"  \
14707   "[drop] [local] [classify <n>] [out-label <n>] [multipath]\n"         \
14708   "[count <n>] [del]")                                                  \
14709 _(mpls_ip_bind_unbind,                                                  \
14710   "<label> <addr/len>")                                                 \
14711 _(mpls_tunnel_add_del,                                                  \
14712   "[add | del <intfc | sw_if_index <id>>] via <addr | via-label <n>>\n" \
14713   "[<intfc> | sw_if_index <id> | next-hop-table <id>]\n"                \
14714   "[l2-only]  [out-label <n>]")                                         \
14715 _(sr_mpls_policy_add,                                                   \
14716   "bsid <id> [weight <n>] [spray] next <sid> [next <sid>]")             \
14717 _(sr_mpls_policy_del,                                                   \
14718   "bsid <id>")                                                          \
14719 _(bier_table_add_del,                                                   \
14720   "<label> <sub-domain> <set> <bsl> [del]")                             \
14721 _(bier_route_add_del,                                                   \
14722   "<bit-position> <sub-domain> <set> <bsl> via <addr> [table-id <n>]\n" \
14723   "[<intfc> | sw_if_index <id>]"                                        \
14724   "[weight <n>] [del] [multipath]")                                     \
14725 _(sw_interface_set_unnumbered,                                          \
14726   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
14727 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
14728 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
14729   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
14730   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
14731   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
14732 _(ip_table_replace_begin, "table <n> [ipv6]")                           \
14733 _(ip_table_flush, "table <n> [ipv6]")                                   \
14734 _(ip_table_replace_end, "table <n> [ipv6]")                             \
14735 _(set_ip_flow_hash,                                                     \
14736   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
14737 _(sw_interface_ip6_enable_disable,                                      \
14738   "<intfc> | sw_if_index <id> enable | disable")                        \
14739 _(l2_patch_add_del,                                                     \
14740   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
14741   "enable | disable")                                                   \
14742 _(sr_localsid_add_del,                                                  \
14743   "(del) address <addr> next_hop <addr> behavior <beh>\n"               \
14744   "fib-table <num> (end.psp) sw_if_index <num>")                        \
14745 _(classify_add_del_table,                                               \
14746   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
14747   " [del] [del-chain] mask <mask-value>\n"                              \
14748   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
14749   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
14750 _(classify_add_del_session,                                             \
14751   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
14752   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
14753   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
14754   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
14755 _(classify_set_interface_ip_table,                                      \
14756   "<intfc> | sw_if_index <nn> table <nn>")                              \
14757 _(classify_set_interface_l2_tables,                                     \
14758   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
14759   "  [other-table <nn>]")                                               \
14760 _(get_node_index, "node <node-name")                                    \
14761 _(add_node_next, "node <node-name> next <next-node-name>")              \
14762 _(vxlan_offload_rx,                                                     \
14763   "hw { <interface name> | hw_if_index <nn>} "                          \
14764   "rx { <vxlan tunnel name> | sw_if_index <nn> } [del]")                \
14765 _(vxlan_add_del_tunnel,                                                 \
14766   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
14767   "{ <intfc> | mcast_sw_if_index <nn> } [instance <id>]}\n"             \
14768   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
14769 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
14770 _(l2_fib_clear_table, "")                                               \
14771 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
14772 _(l2_interface_vlan_tag_rewrite,                                        \
14773   "<intfc> | sw_if_index <nn> \n"                                       \
14774   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
14775   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
14776 _(create_vhost_user_if,                                                 \
14777         "socket <filename> [server] [renumber <dev_instance>] "         \
14778         "[disable_mrg_rxbuf] [disable_indirect_desc] [gso] "            \
14779         "[mac <mac_address>] [packed]")                                 \
14780 _(modify_vhost_user_if,                                                 \
14781         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
14782         "[server] [renumber <dev_instance>] [gso] [packed]")            \
14783 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
14784 _(sw_interface_vhost_user_dump, "<intfc> | sw_if_index <nn>")           \
14785 _(show_version, "")                                                     \
14786 _(show_threads, "")                                                     \
14787 _(vxlan_gpe_add_del_tunnel,                                             \
14788   "local <addr> remote <addr>  | group <mcast-ip-addr>\n"               \
14789   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
14790   "vni <nn> [encap-vrf-id <nn>] [decap-vrf-id <nn>]\n"                  \
14791   "[next-ip4][next-ip6][next-ethernet] [next-nsh] [del]\n")             \
14792 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
14793 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
14794 _(interface_name_renumber,                                              \
14795   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
14796 _(input_acl_set_interface,                                              \
14797   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
14798   "  [l2-table <nn>] [del]")                                            \
14799 _(want_l2_macs_events, "[disable] [learn-limit <n>] [scan-delay <n>] [max-entries <n>]") \
14800 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
14801 _(ip_dump, "ipv4 | ipv6")                                               \
14802 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
14803 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
14804   "  spid_id <n> ")                                                     \
14805 _(ipsec_sad_entry_add_del, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
14806   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
14807   "  integ_alg <alg> integ_key <hex>")                                  \
14808 _(ipsec_spd_entry_add_del, "spd_id <n> priority <n> action <action>\n"  \
14809   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
14810   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
14811   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
14812 _(ipsec_sa_dump, "[sa_id <n>]")                                         \
14813 _(delete_loopback,"sw_if_index <nn>")                                   \
14814 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
14815 _(bd_ip_mac_flush, "bd_id <bridge-domain-id>")                          \
14816 _(bd_ip_mac_dump, "[bd_id] <bridge-domain-id>")                         \
14817 _(want_interface_events,  "enable|disable")                             \
14818 _(get_first_msg_id, "client <name>")                                    \
14819 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
14820 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
14821   "fib-id <nn> [ip4][ip6][default]")                                    \
14822 _(get_node_graph, " ")                                                  \
14823 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
14824 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
14825 _(ioam_disable, "")                                                     \
14826 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
14827 _(af_packet_delete, "name <host interface name>")                       \
14828 _(af_packet_dump, "")                                                   \
14829 _(policer_add_del, "name <policer name> <params> [del]")                \
14830 _(policer_dump, "[name <policer name>]")                                \
14831 _(policer_classify_set_interface,                                       \
14832   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
14833   "  [l2-table <nn>] [del]")                                            \
14834 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
14835 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
14836 _(mpls_table_dump, "")                                                  \
14837 _(mpls_route_dump, "table-id <ID>")                                     \
14838 _(classify_table_ids, "")                                               \
14839 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
14840 _(classify_table_info, "table_id <nn>")                                 \
14841 _(classify_session_dump, "table_id <nn>")                               \
14842 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
14843     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
14844     "[template_interval <nn>] [udp_checksum]")                          \
14845 _(ipfix_exporter_dump, "")                                              \
14846 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
14847 _(ipfix_classify_stream_dump, "")                                       \
14848 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
14849 _(ipfix_classify_table_dump, "")                                        \
14850 _(sw_interface_span_enable_disable, "[l2] [src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
14851 _(sw_interface_span_dump, "[l2]")                                           \
14852 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
14853 _(pg_create_interface, "if_id <nn> [gso-enabled gso-size <size>]")      \
14854 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
14855 _(pg_enable_disable, "[stream <id>] disable")                           \
14856 _(pg_interface_enable_disable_coalesce, "<intf> | sw_if_index <nn> enable | disable")  \
14857 _(ip_source_and_port_range_check_add_del,                               \
14858   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
14859 _(ip_source_and_port_range_check_interface_add_del,                     \
14860   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
14861   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
14862 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
14863 _(l2_interface_pbb_tag_rewrite,                                         \
14864   "<intfc> | sw_if_index <nn> \n"                                       \
14865   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
14866   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
14867 _(set_punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
14868 _(flow_classify_set_interface,                                          \
14869   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
14870 _(flow_classify_dump, "type [ip4|ip6]")                                 \
14871 _(ip_table_dump, "")                                                    \
14872 _(ip_route_dump, "table-id [ip4|ip6]")                                  \
14873 _(ip_mtable_dump, "")                                                   \
14874 _(ip_mroute_dump, "table-id [ip4|ip6]")                                 \
14875 _(feature_enable_disable, "arc_name <arc_name> "                        \
14876   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
14877 _(feature_gso_enable_disable, "<intfc> | sw_if_index <nn> "             \
14878   "[enable | disable] ")                                                \
14879 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
14880 "[disable]")                                                            \
14881 _(sw_interface_add_del_mac_address, "<intfc> | sw_if_index <nn> "       \
14882   "mac <mac-address> [del]")                                            \
14883 _(l2_xconnect_dump, "")                                                 \
14884 _(hw_interface_set_mtu, "<intfc> | hw_if_index <nn> mtu <nn>")        \
14885 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")          \
14886 _(p2p_ethernet_add, "<intfc> | sw_if_index <nn> remote_mac <mac-address> sub_id <id>") \
14887 _(p2p_ethernet_del, "<intfc> | sw_if_index <nn> remote_mac <mac-address>") \
14888 _(tcp_configure_src_addresses, "<ip4|6>first-<ip4|6>last [vrf <id>]")   \
14889 _(sock_init_shm, "size <nnn>")                                          \
14890 _(app_namespace_add_del, "[add] id <ns-id> secret <nn> sw_if_index <nn>")\
14891 _(session_rule_add_del, "[add|del] proto <tcp/udp> <lcl-ip>/<plen> "    \
14892   "<lcl-port> <rmt-ip>/<plen> <rmt-port> action <nn>")                  \
14893 _(session_rules_dump, "")                                               \
14894 _(ip_container_proxy_add_del, "[add|del] <address> <sw_if_index>")      \
14895 _(output_acl_set_interface,                                             \
14896   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
14897   "  [l2-table <nn>] [del]")                                            \
14898 _(qos_record_enable_disable, "<record-source> <intfc> | sw_if_index <id> [disable]")
14899
14900 /* List of command functions, CLI names map directly to functions */
14901 #define foreach_cli_function                                    \
14902 _(comment, "usage: comment <ignore-rest-of-line>")              \
14903 _(dump_interface_table, "usage: dump_interface_table")          \
14904 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
14905 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
14906 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
14907 _(dump_macro_table, "usage: dump_macro_table ")                 \
14908 _(dump_node_table, "usage: dump_node_table")                    \
14909 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
14910 _(elog_setup, "usage: elog_setup [nevents, default 128K]")      \
14911 _(elog_disable, "usage: elog_disable")                          \
14912 _(elog_enable, "usage: elog_enable")                            \
14913 _(elog_save, "usage: elog_save <filename>")                     \
14914 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
14915 _(echo, "usage: echo <message>")                                \
14916 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
14917 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
14918 _(help, "usage: help")                                          \
14919 _(q, "usage: quit")                                             \
14920 _(quit, "usage: quit")                                          \
14921 _(search_node_table, "usage: search_node_table <name>...")      \
14922 _(set, "usage: set <variable-name> <value>")                    \
14923 _(script, "usage: script <file-name>")                          \
14924 _(statseg, "usage: statseg")                                    \
14925 _(unset, "usage: unset <variable-name>")
14926
14927 #define _(N,n)                                  \
14928     static void vl_api_##n##_t_handler_uni      \
14929     (vl_api_##n##_t * mp)                       \
14930     {                                           \
14931         vat_main_t * vam = &vat_main;           \
14932         if (vam->json_output) {                 \
14933             vl_api_##n##_t_handler_json(mp);    \
14934         } else {                                \
14935             vl_api_##n##_t_handler(mp);         \
14936         }                                       \
14937     }
14938 foreach_vpe_api_reply_msg;
14939 #if VPP_API_TEST_BUILTIN == 0
14940 foreach_standalone_reply_msg;
14941 #endif
14942 #undef _
14943
14944 void
14945 vat_api_hookup (vat_main_t * vam)
14946 {
14947 #define _(N,n)                                                  \
14948     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
14949                            vl_api_##n##_t_handler_uni,          \
14950                            vl_noop_handler,                     \
14951                            vl_api_##n##_t_endian,               \
14952                            vl_api_##n##_t_print,                \
14953                            sizeof(vl_api_##n##_t), 1);
14954   foreach_vpe_api_reply_msg;
14955 #if VPP_API_TEST_BUILTIN == 0
14956   foreach_standalone_reply_msg;
14957 #endif
14958 #undef _
14959
14960 #if (VPP_API_TEST_BUILTIN==0)
14961   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
14962
14963   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
14964
14965   vam->function_by_name = hash_create_string (0, sizeof (uword));
14966
14967   vam->help_by_name = hash_create_string (0, sizeof (uword));
14968 #endif
14969
14970   /* API messages we can send */
14971 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
14972   foreach_vpe_api_msg;
14973 #undef _
14974
14975   /* Help strings */
14976 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
14977   foreach_vpe_api_msg;
14978 #undef _
14979
14980   /* CLI functions */
14981 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
14982   foreach_cli_function;
14983 #undef _
14984
14985   /* Help strings */
14986 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
14987   foreach_cli_function;
14988 #undef _
14989 }
14990
14991 #if VPP_API_TEST_BUILTIN
14992 static clib_error_t *
14993 vat_api_hookup_shim (vlib_main_t * vm)
14994 {
14995   vat_api_hookup (&vat_main);
14996   return 0;
14997 }
14998
14999 VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
15000 #endif
15001
15002 /*
15003  * fd.io coding-style-patch-verification: ON
15004  *
15005  * Local Variables:
15006  * eval: (c-set-style "gnu")
15007  * End:
15008  */