gre: Move to new API generated types/messages
[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 _(ipsec_tunnel_if_add_del_reply)                        \
3260 _(ipsec_tunnel_if_set_sa_reply)                         \
3261 _(delete_loopback_reply)                                \
3262 _(bd_ip_mac_add_del_reply)                              \
3263 _(bd_ip_mac_flush_reply)                                \
3264 _(want_interface_events_reply)                          \
3265 _(cop_interface_enable_disable_reply)                   \
3266 _(cop_whitelist_enable_disable_reply)                   \
3267 _(sw_interface_clear_stats_reply)                       \
3268 _(ioam_enable_reply)                                    \
3269 _(ioam_disable_reply)                                   \
3270 _(af_packet_delete_reply)                               \
3271 _(policer_classify_set_interface_reply)                 \
3272 _(set_ipfix_exporter_reply)                             \
3273 _(set_ipfix_classify_stream_reply)                      \
3274 _(ipfix_classify_table_add_del_reply)                   \
3275 _(flow_classify_set_interface_reply)                    \
3276 _(sw_interface_span_enable_disable_reply)               \
3277 _(pg_capture_reply)                                     \
3278 _(pg_enable_disable_reply)                              \
3279 _(pg_interface_enable_disable_coalesce_reply)           \
3280 _(ip_source_and_port_range_check_add_del_reply)         \
3281 _(ip_source_and_port_range_check_interface_add_del_reply)\
3282 _(delete_subif_reply)                                   \
3283 _(l2_interface_pbb_tag_rewrite_reply)                   \
3284 _(set_punt_reply)                                       \
3285 _(feature_enable_disable_reply)                         \
3286 _(feature_gso_enable_disable_reply)                     \
3287 _(sw_interface_tag_add_del_reply)                       \
3288 _(sw_interface_add_del_mac_address_reply)               \
3289 _(hw_interface_set_mtu_reply)                           \
3290 _(p2p_ethernet_add_reply)                               \
3291 _(p2p_ethernet_del_reply)                               \
3292 _(tcp_configure_src_addresses_reply)                    \
3293 _(session_rule_add_del_reply)                           \
3294 _(ip_container_proxy_add_del_reply)                     \
3295 _(output_acl_set_interface_reply)                       \
3296 _(qos_record_enable_disable_reply)                      \
3297 _(flow_add_reply)
3298
3299 #define _(n)                                    \
3300     static void vl_api_##n##_t_handler          \
3301     (vl_api_##n##_t * mp)                       \
3302     {                                           \
3303         vat_main_t * vam = &vat_main;           \
3304         i32 retval = ntohl(mp->retval);         \
3305         if (vam->async_mode) {                  \
3306             vam->async_errors += (retval < 0);  \
3307         } else {                                \
3308             vam->retval = retval;               \
3309             vam->result_ready = 1;              \
3310         }                                       \
3311     }
3312 foreach_standard_reply_retval_handler;
3313 #undef _
3314
3315 #define _(n)                                    \
3316     static void vl_api_##n##_t_handler_json     \
3317     (vl_api_##n##_t * mp)                       \
3318     {                                           \
3319         vat_main_t * vam = &vat_main;           \
3320         vat_json_node_t node;                   \
3321         vat_json_init_object(&node);            \
3322         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
3323         vat_json_print(vam->ofp, &node);        \
3324         vam->retval = ntohl(mp->retval);        \
3325         vam->result_ready = 1;                  \
3326     }
3327 foreach_standard_reply_retval_handler;
3328 #undef _
3329
3330 /*
3331  * Table of message reply handlers, must include boilerplate handlers
3332  * we just generated
3333  */
3334
3335 #define foreach_vpe_api_reply_msg                                       \
3336 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
3337 _(CREATE_LOOPBACK_INSTANCE_REPLY, create_loopback_instance_reply)       \
3338 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
3339 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
3340 _(CONTROL_PING_REPLY, control_ping_reply)                               \
3341 _(CLI_REPLY, cli_reply)                                                 \
3342 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
3343 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
3344   sw_interface_add_del_address_reply)                                   \
3345 _(SW_INTERFACE_SET_RX_MODE_REPLY, sw_interface_set_rx_mode_reply)       \
3346 _(SW_INTERFACE_SET_RX_PLACEMENT_REPLY, sw_interface_set_rx_placement_reply)     \
3347 _(SW_INTERFACE_RX_PLACEMENT_DETAILS, sw_interface_rx_placement_details) \
3348 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
3349 _(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
3350 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
3351 _(SW_INTERFACE_SET_VXLAN_BYPASS_REPLY, sw_interface_set_vxlan_bypass_reply) \
3352 _(SW_INTERFACE_SET_VXLAN_GPE_BYPASS_REPLY, sw_interface_set_vxlan_gpe_bypass_reply) \
3353 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
3354   sw_interface_set_l2_xconnect_reply)                                   \
3355 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
3356   sw_interface_set_l2_bridge_reply)                                     \
3357 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
3358 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
3359 _(BRIDGE_DOMAIN_SET_MAC_AGE_REPLY, bridge_domain_set_mac_age_reply)     \
3360 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
3361 _(L2FIB_FLUSH_INT_REPLY, l2fib_flush_int_reply)                         \
3362 _(L2FIB_FLUSH_BD_REPLY, l2fib_flush_bd_reply)                           \
3363 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
3364 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
3365 _(TAP_CREATE_V2_REPLY, tap_create_v2_reply)                             \
3366 _(TAP_DELETE_V2_REPLY, tap_delete_v2_reply)                             \
3367 _(SW_INTERFACE_TAP_V2_DETAILS, sw_interface_tap_v2_details)             \
3368 _(VIRTIO_PCI_CREATE_REPLY, virtio_pci_create_reply)                     \
3369 _(VIRTIO_PCI_CREATE_V2_REPLY, virtio_pci_create_v2_reply)               \
3370 _(VIRTIO_PCI_DELETE_REPLY, virtio_pci_delete_reply)                     \
3371 _(SW_INTERFACE_VIRTIO_PCI_DETAILS, sw_interface_virtio_pci_details)     \
3372 _(BOND_CREATE_REPLY, bond_create_reply)                                 \
3373 _(BOND_CREATE2_REPLY, bond_create2_reply)                               \
3374 _(BOND_DELETE_REPLY, bond_delete_reply)                                 \
3375 _(BOND_ADD_MEMBER_REPLY, bond_add_member_reply)                         \
3376 _(BOND_DETACH_MEMBER_REPLY, bond_detach_member_reply)                   \
3377 _(SW_INTERFACE_SET_BOND_WEIGHT_REPLY, sw_interface_set_bond_weight_reply) \
3378 _(SW_BOND_INTERFACE_DETAILS, sw_bond_interface_details)                 \
3379 _(SW_MEMBER_INTERFACE_DETAILS, sw_member_interface_details)               \
3380 _(IP_ROUTE_ADD_DEL_REPLY, ip_route_add_del_reply)                       \
3381 _(IP_TABLE_ADD_DEL_REPLY, ip_table_add_del_reply)                       \
3382 _(IP_TABLE_REPLACE_BEGIN_REPLY, ip_table_replace_begin_reply)           \
3383 _(IP_TABLE_FLUSH_REPLY, ip_table_flush_reply)                           \
3384 _(IP_TABLE_REPLACE_END_REPLY, ip_table_replace_end_reply)               \
3385 _(IP_MROUTE_ADD_DEL_REPLY, ip_mroute_add_del_reply)                     \
3386 _(MPLS_TABLE_ADD_DEL_REPLY, mpls_table_add_del_reply)                   \
3387 _(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply)                   \
3388 _(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply)                 \
3389 _(BIER_ROUTE_ADD_DEL_REPLY, bier_route_add_del_reply)                   \
3390 _(BIER_TABLE_ADD_DEL_REPLY, bier_table_add_del_reply)                   \
3391 _(MPLS_TUNNEL_ADD_DEL_REPLY, mpls_tunnel_add_del_reply)                 \
3392 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
3393   sw_interface_set_unnumbered_reply)                                    \
3394 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
3395 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
3396 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
3397 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
3398   sw_interface_ip6_enable_disable_reply)                                \
3399 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
3400 _(SR_MPLS_POLICY_ADD_REPLY, sr_mpls_policy_add_reply)                   \
3401 _(SR_MPLS_POLICY_MOD_REPLY, sr_mpls_policy_mod_reply)                   \
3402 _(SR_MPLS_POLICY_DEL_REPLY, sr_mpls_policy_del_reply)                   \
3403 _(SR_POLICY_ADD_REPLY, sr_policy_add_reply)                             \
3404 _(SR_POLICY_MOD_REPLY, sr_policy_mod_reply)                             \
3405 _(SR_POLICY_DEL_REPLY, sr_policy_del_reply)                             \
3406 _(SR_LOCALSID_ADD_DEL_REPLY, sr_localsid_add_del_reply)                 \
3407 _(SR_STEERING_ADD_DEL_REPLY, sr_steering_add_del_reply)                 \
3408 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
3409 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
3410 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
3411 classify_set_interface_ip_table_reply)                                  \
3412 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
3413   classify_set_interface_l2_tables_reply)                               \
3414 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
3415 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
3416 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
3417 _(VXLAN_OFFLOAD_RX_REPLY, vxlan_offload_rx_reply)               \
3418 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
3419 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
3420 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
3421 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
3422 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
3423 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
3424 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
3425 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
3426 _(SHOW_VERSION_REPLY, show_version_reply)                               \
3427 _(SHOW_THREADS_REPLY, show_threads_reply)                               \
3428 _(L2_FIB_TABLE_DETAILS, l2_fib_table_details)                           \
3429 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)       \
3430 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
3431 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
3432 _(WANT_L2_MACS_EVENTS_REPLY, want_l2_macs_events_reply)                 \
3433 _(L2_MACS_EVENT, l2_macs_event)                                         \
3434 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
3435 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
3436 _(IP_DETAILS, ip_details)                                               \
3437 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
3438 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
3439 _(IPSEC_SPD_ENTRY_ADD_DEL_REPLY, ipsec_spd_entry_add_del_reply)         \
3440 _(IPSEC_SAD_ENTRY_ADD_DEL_REPLY, ipsec_sad_entry_add_del_reply)         \
3441 _(IPSEC_SA_DETAILS, ipsec_sa_details)                                   \
3442 _(IPSEC_TUNNEL_IF_ADD_DEL_REPLY, ipsec_tunnel_if_add_del_reply)         \
3443 _(IPSEC_TUNNEL_IF_SET_SA_REPLY, ipsec_tunnel_if_set_sa_reply)           \
3444 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
3445 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
3446 _(BD_IP_MAC_FLUSH_REPLY, bd_ip_mac_flush_reply)                         \
3447 _(BD_IP_MAC_DETAILS, bd_ip_mac_details)                                 \
3448 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
3449 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
3450 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
3451 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
3452 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
3453 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
3454 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
3455 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
3456 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
3457 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
3458 _(AF_PACKET_DETAILS, af_packet_details)                                 \
3459 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
3460 _(POLICER_DETAILS, policer_details)                                     \
3461 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
3462 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
3463 _(MPLS_TUNNEL_DETAILS, mpls_tunnel_details)                             \
3464 _(MPLS_TABLE_DETAILS, mpls_table_details)                               \
3465 _(MPLS_ROUTE_DETAILS, mpls_route_details)                               \
3466 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
3467 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
3468 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
3469 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
3470 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
3471 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
3472 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
3473 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
3474 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
3475 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
3476 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
3477 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
3478 _(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
3479 _(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details)                 \
3480 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
3481 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
3482 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
3483 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
3484 _(PG_INTERFACE_ENABLE_DISABLE_COALESCE_REPLY, pg_interface_enable_disable_coalesce_reply) \
3485 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
3486  ip_source_and_port_range_check_add_del_reply)                          \
3487 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
3488  ip_source_and_port_range_check_interface_add_del_reply)                \
3489 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
3490 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
3491 _(SET_PUNT_REPLY, set_punt_reply)                                       \
3492 _(IP_TABLE_DETAILS, ip_table_details)                                   \
3493 _(IP_ROUTE_DETAILS, ip_route_details)                                   \
3494 _(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply)           \
3495 _(FEATURE_GSO_ENABLE_DISABLE_REPLY, feature_gso_enable_disable_reply)   \
3496 _(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply)       \
3497 _(SW_INTERFACE_ADD_DEL_MAC_ADDRESS_REPLY, sw_interface_add_del_mac_address_reply) \
3498 _(L2_XCONNECT_DETAILS, l2_xconnect_details)                             \
3499 _(HW_INTERFACE_SET_MTU_REPLY, hw_interface_set_mtu_reply)               \
3500 _(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply)           \
3501 _(P2P_ETHERNET_ADD_REPLY, p2p_ethernet_add_reply)                       \
3502 _(P2P_ETHERNET_DEL_REPLY, p2p_ethernet_del_reply)                       \
3503 _(TCP_CONFIGURE_SRC_ADDRESSES_REPLY, tcp_configure_src_addresses_reply) \
3504 _(APP_NAMESPACE_ADD_DEL_REPLY, app_namespace_add_del_reply)             \
3505 _(SESSION_RULE_ADD_DEL_REPLY, session_rule_add_del_reply)               \
3506 _(SESSION_RULES_DETAILS, session_rules_details)                         \
3507 _(IP_CONTAINER_PROXY_ADD_DEL_REPLY, ip_container_proxy_add_del_reply)   \
3508 _(OUTPUT_ACL_SET_INTERFACE_REPLY, output_acl_set_interface_reply)       \
3509 _(QOS_RECORD_ENABLE_DISABLE_REPLY, qos_record_enable_disable_reply)             \
3510 _(FLOW_ADD_REPLY, flow_add_reply)   \
3511
3512 #define foreach_standalone_reply_msg                                    \
3513 _(SW_INTERFACE_EVENT, sw_interface_event)
3514
3515 typedef struct
3516 {
3517   u8 *name;
3518   u32 value;
3519 } name_sort_t;
3520
3521 #define STR_VTR_OP_CASE(op)     \
3522     case L2_VTR_ ## op:         \
3523         return "" # op;
3524
3525 static const char *
3526 str_vtr_op (u32 vtr_op)
3527 {
3528   switch (vtr_op)
3529     {
3530       STR_VTR_OP_CASE (DISABLED);
3531       STR_VTR_OP_CASE (PUSH_1);
3532       STR_VTR_OP_CASE (PUSH_2);
3533       STR_VTR_OP_CASE (POP_1);
3534       STR_VTR_OP_CASE (POP_2);
3535       STR_VTR_OP_CASE (TRANSLATE_1_1);
3536       STR_VTR_OP_CASE (TRANSLATE_1_2);
3537       STR_VTR_OP_CASE (TRANSLATE_2_1);
3538       STR_VTR_OP_CASE (TRANSLATE_2_2);
3539     }
3540
3541   return "UNKNOWN";
3542 }
3543
3544 static int
3545 dump_sub_interface_table (vat_main_t * vam)
3546 {
3547   const sw_interface_subif_t *sub = NULL;
3548
3549   if (vam->json_output)
3550     {
3551       clib_warning
3552         ("JSON output supported only for VPE API calls and dump_stats_table");
3553       return -99;
3554     }
3555
3556   print (vam->ofp,
3557          "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
3558          "Interface", "sw_if_index",
3559          "sub id", "dot1ad", "tags", "outer id",
3560          "inner id", "exact", "default", "outer any", "inner any");
3561
3562   vec_foreach (sub, vam->sw_if_subif_table)
3563   {
3564     print (vam->ofp,
3565            "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
3566            sub->interface_name,
3567            sub->sw_if_index,
3568            sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
3569            sub->sub_number_of_tags, sub->sub_outer_vlan_id,
3570            sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
3571            sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
3572     if (sub->vtr_op != L2_VTR_DISABLED)
3573       {
3574         print (vam->ofp,
3575                "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
3576                "tag1: %d tag2: %d ]",
3577                str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
3578                sub->vtr_tag1, sub->vtr_tag2);
3579       }
3580   }
3581
3582   return 0;
3583 }
3584
3585 static int
3586 name_sort_cmp (void *a1, void *a2)
3587 {
3588   name_sort_t *n1 = a1;
3589   name_sort_t *n2 = a2;
3590
3591   return strcmp ((char *) n1->name, (char *) n2->name);
3592 }
3593
3594 static int
3595 dump_interface_table (vat_main_t * vam)
3596 {
3597   hash_pair_t *p;
3598   name_sort_t *nses = 0, *ns;
3599
3600   if (vam->json_output)
3601     {
3602       clib_warning
3603         ("JSON output supported only for VPE API calls and dump_stats_table");
3604       return -99;
3605     }
3606
3607   /* *INDENT-OFF* */
3608   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
3609   ({
3610     vec_add2 (nses, ns, 1);
3611     ns->name = (u8 *)(p->key);
3612     ns->value = (u32) p->value[0];
3613   }));
3614   /* *INDENT-ON* */
3615
3616   vec_sort_with_function (nses, name_sort_cmp);
3617
3618   print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
3619   vec_foreach (ns, nses)
3620   {
3621     print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
3622   }
3623   vec_free (nses);
3624   return 0;
3625 }
3626
3627 static int
3628 dump_ip_table (vat_main_t * vam, int is_ipv6)
3629 {
3630   const ip_details_t *det = NULL;
3631   const ip_address_details_t *address = NULL;
3632   u32 i = ~0;
3633
3634   print (vam->ofp, "%-12s", "sw_if_index");
3635
3636   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
3637   {
3638     i++;
3639     if (!det->present)
3640       {
3641         continue;
3642       }
3643     print (vam->ofp, "%-12d", i);
3644     print (vam->ofp, "            %-30s%-13s", "Address", "Prefix length");
3645     if (!det->addr)
3646       {
3647         continue;
3648       }
3649     vec_foreach (address, det->addr)
3650     {
3651       print (vam->ofp,
3652              "            %-30U%-13d",
3653              is_ipv6 ? format_ip6_address : format_ip4_address,
3654              address->ip, address->prefix_length);
3655     }
3656   }
3657
3658   return 0;
3659 }
3660
3661 static int
3662 dump_ipv4_table (vat_main_t * vam)
3663 {
3664   if (vam->json_output)
3665     {
3666       clib_warning
3667         ("JSON output supported only for VPE API calls and dump_stats_table");
3668       return -99;
3669     }
3670
3671   return dump_ip_table (vam, 0);
3672 }
3673
3674 static int
3675 dump_ipv6_table (vat_main_t * vam)
3676 {
3677   if (vam->json_output)
3678     {
3679       clib_warning
3680         ("JSON output supported only for VPE API calls and dump_stats_table");
3681       return -99;
3682     }
3683
3684   return dump_ip_table (vam, 1);
3685 }
3686
3687 /*
3688  * Pass CLI buffers directly in the CLI_INBAND API message,
3689  * instead of an additional shared memory area.
3690  */
3691 static int
3692 exec_inband (vat_main_t * vam)
3693 {
3694   vl_api_cli_inband_t *mp;
3695   unformat_input_t *i = vam->input;
3696   int ret;
3697
3698   if (vec_len (i->buffer) == 0)
3699     return -1;
3700
3701   if (vam->exec_mode == 0 && unformat (i, "mode"))
3702     {
3703       vam->exec_mode = 1;
3704       return 0;
3705     }
3706   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
3707     {
3708       vam->exec_mode = 0;
3709       return 0;
3710     }
3711
3712   /*
3713    * In order for the CLI command to work, it
3714    * must be a vector ending in \n, not a C-string ending
3715    * in \n\0.
3716    */
3717   M2 (CLI_INBAND, mp, vec_len (vam->input->buffer));
3718   vl_api_vec_to_api_string (vam->input->buffer, &mp->cmd);
3719
3720   S (mp);
3721   W (ret);
3722   /* json responses may or may not include a useful reply... */
3723   if (vec_len (vam->cmd_reply))
3724     print (vam->ofp, "%v", (char *) (vam->cmd_reply));
3725   return ret;
3726 }
3727
3728 int
3729 exec (vat_main_t * vam)
3730 {
3731   return exec_inband (vam);
3732 }
3733
3734 static int
3735 api_create_loopback (vat_main_t * vam)
3736 {
3737   unformat_input_t *i = vam->input;
3738   vl_api_create_loopback_t *mp;
3739   vl_api_create_loopback_instance_t *mp_lbi;
3740   u8 mac_address[6];
3741   u8 mac_set = 0;
3742   u8 is_specified = 0;
3743   u32 user_instance = 0;
3744   int ret;
3745
3746   clib_memset (mac_address, 0, sizeof (mac_address));
3747
3748   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
3749     {
3750       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
3751         mac_set = 1;
3752       if (unformat (i, "instance %d", &user_instance))
3753         is_specified = 1;
3754       else
3755         break;
3756     }
3757
3758   if (is_specified)
3759     {
3760       M (CREATE_LOOPBACK_INSTANCE, mp_lbi);
3761       mp_lbi->is_specified = is_specified;
3762       if (is_specified)
3763         mp_lbi->user_instance = htonl (user_instance);
3764       if (mac_set)
3765         clib_memcpy (mp_lbi->mac_address, mac_address, sizeof (mac_address));
3766       S (mp_lbi);
3767     }
3768   else
3769     {
3770       /* Construct the API message */
3771       M (CREATE_LOOPBACK, mp);
3772       if (mac_set)
3773         clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
3774       S (mp);
3775     }
3776
3777   W (ret);
3778   return ret;
3779 }
3780
3781 static int
3782 api_delete_loopback (vat_main_t * vam)
3783 {
3784   unformat_input_t *i = vam->input;
3785   vl_api_delete_loopback_t *mp;
3786   u32 sw_if_index = ~0;
3787   int ret;
3788
3789   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
3790     {
3791       if (unformat (i, "sw_if_index %d", &sw_if_index))
3792         ;
3793       else
3794         break;
3795     }
3796
3797   if (sw_if_index == ~0)
3798     {
3799       errmsg ("missing sw_if_index");
3800       return -99;
3801     }
3802
3803   /* Construct the API message */
3804   M (DELETE_LOOPBACK, mp);
3805   mp->sw_if_index = ntohl (sw_if_index);
3806
3807   S (mp);
3808   W (ret);
3809   return ret;
3810 }
3811
3812 static int
3813 api_want_interface_events (vat_main_t * vam)
3814 {
3815   unformat_input_t *i = vam->input;
3816   vl_api_want_interface_events_t *mp;
3817   int enable = -1;
3818   int ret;
3819
3820   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
3821     {
3822       if (unformat (i, "enable"))
3823         enable = 1;
3824       else if (unformat (i, "disable"))
3825         enable = 0;
3826       else
3827         break;
3828     }
3829
3830   if (enable == -1)
3831     {
3832       errmsg ("missing enable|disable");
3833       return -99;
3834     }
3835
3836   M (WANT_INTERFACE_EVENTS, mp);
3837   mp->enable_disable = enable;
3838
3839   vam->interface_event_display = enable;
3840
3841   S (mp);
3842   W (ret);
3843   return ret;
3844 }
3845
3846
3847 /* Note: non-static, called once to set up the initial intfc table */
3848 int
3849 api_sw_interface_dump (vat_main_t * vam)
3850 {
3851   vl_api_sw_interface_dump_t *mp;
3852   vl_api_control_ping_t *mp_ping;
3853   hash_pair_t *p;
3854   name_sort_t *nses = 0, *ns;
3855   sw_interface_subif_t *sub = NULL;
3856   int ret;
3857
3858   /* Toss the old name table */
3859   /* *INDENT-OFF* */
3860   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
3861   ({
3862     vec_add2 (nses, ns, 1);
3863     ns->name = (u8 *)(p->key);
3864     ns->value = (u32) p->value[0];
3865   }));
3866   /* *INDENT-ON* */
3867
3868   hash_free (vam->sw_if_index_by_interface_name);
3869
3870   vec_foreach (ns, nses) vec_free (ns->name);
3871
3872   vec_free (nses);
3873
3874   vec_foreach (sub, vam->sw_if_subif_table)
3875   {
3876     vec_free (sub->interface_name);
3877   }
3878   vec_free (vam->sw_if_subif_table);
3879
3880   /* recreate the interface name hash table */
3881   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
3882
3883   /*
3884    * Ask for all interface names. Otherwise, the epic catalog of
3885    * name filters becomes ridiculously long, and vat ends up needing
3886    * to be taught about new interface types.
3887    */
3888   M (SW_INTERFACE_DUMP, mp);
3889   S (mp);
3890
3891   /* Use a control ping for synchronization */
3892   MPING (CONTROL_PING, mp_ping);
3893   S (mp_ping);
3894
3895   W (ret);
3896   return ret;
3897 }
3898
3899 static int
3900 api_sw_interface_set_flags (vat_main_t * vam)
3901 {
3902   unformat_input_t *i = vam->input;
3903   vl_api_sw_interface_set_flags_t *mp;
3904   u32 sw_if_index;
3905   u8 sw_if_index_set = 0;
3906   u8 admin_up = 0;
3907   int ret;
3908
3909   /* Parse args required to build the message */
3910   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
3911     {
3912       if (unformat (i, "admin-up"))
3913         admin_up = 1;
3914       else if (unformat (i, "admin-down"))
3915         admin_up = 0;
3916       else
3917         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
3918         sw_if_index_set = 1;
3919       else if (unformat (i, "sw_if_index %d", &sw_if_index))
3920         sw_if_index_set = 1;
3921       else
3922         break;
3923     }
3924
3925   if (sw_if_index_set == 0)
3926     {
3927       errmsg ("missing interface name or sw_if_index");
3928       return -99;
3929     }
3930
3931   /* Construct the API message */
3932   M (SW_INTERFACE_SET_FLAGS, mp);
3933   mp->sw_if_index = ntohl (sw_if_index);
3934   mp->flags = ntohl ((admin_up) ? IF_STATUS_API_FLAG_ADMIN_UP : 0);
3935
3936   /* send it... */
3937   S (mp);
3938
3939   /* Wait for a reply, return the good/bad news... */
3940   W (ret);
3941   return ret;
3942 }
3943
3944 static int
3945 api_sw_interface_set_rx_mode (vat_main_t * vam)
3946 {
3947   unformat_input_t *i = vam->input;
3948   vl_api_sw_interface_set_rx_mode_t *mp;
3949   u32 sw_if_index;
3950   u8 sw_if_index_set = 0;
3951   int ret;
3952   u8 queue_id_valid = 0;
3953   u32 queue_id;
3954   vnet_hw_if_rx_mode mode = VNET_HW_IF_RX_MODE_UNKNOWN;
3955
3956   /* Parse args required to build the message */
3957   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
3958     {
3959       if (unformat (i, "queue %d", &queue_id))
3960         queue_id_valid = 1;
3961       else if (unformat (i, "polling"))
3962         mode = VNET_HW_IF_RX_MODE_POLLING;
3963       else if (unformat (i, "interrupt"))
3964         mode = VNET_HW_IF_RX_MODE_INTERRUPT;
3965       else if (unformat (i, "adaptive"))
3966         mode = VNET_HW_IF_RX_MODE_ADAPTIVE;
3967       else
3968         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
3969         sw_if_index_set = 1;
3970       else if (unformat (i, "sw_if_index %d", &sw_if_index))
3971         sw_if_index_set = 1;
3972       else
3973         break;
3974     }
3975
3976   if (sw_if_index_set == 0)
3977     {
3978       errmsg ("missing interface name or sw_if_index");
3979       return -99;
3980     }
3981   if (mode == VNET_HW_IF_RX_MODE_UNKNOWN)
3982     {
3983       errmsg ("missing rx-mode");
3984       return -99;
3985     }
3986
3987   /* Construct the API message */
3988   M (SW_INTERFACE_SET_RX_MODE, mp);
3989   mp->sw_if_index = ntohl (sw_if_index);
3990   mp->mode = (vl_api_rx_mode_t) mode;
3991   mp->queue_id_valid = queue_id_valid;
3992   mp->queue_id = queue_id_valid ? ntohl (queue_id) : ~0;
3993
3994   /* send it... */
3995   S (mp);
3996
3997   /* Wait for a reply, return the good/bad news... */
3998   W (ret);
3999   return ret;
4000 }
4001
4002 static int
4003 api_sw_interface_set_rx_placement (vat_main_t * vam)
4004 {
4005   unformat_input_t *i = vam->input;
4006   vl_api_sw_interface_set_rx_placement_t *mp;
4007   u32 sw_if_index;
4008   u8 sw_if_index_set = 0;
4009   int ret;
4010   u8 is_main = 0;
4011   u32 queue_id, thread_index;
4012
4013   /* Parse args required to build the message */
4014   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4015     {
4016       if (unformat (i, "queue %d", &queue_id))
4017         ;
4018       else if (unformat (i, "main"))
4019         is_main = 1;
4020       else if (unformat (i, "worker %d", &thread_index))
4021         ;
4022       else
4023         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
4024         sw_if_index_set = 1;
4025       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4026         sw_if_index_set = 1;
4027       else
4028         break;
4029     }
4030
4031   if (sw_if_index_set == 0)
4032     {
4033       errmsg ("missing interface name or sw_if_index");
4034       return -99;
4035     }
4036
4037   if (is_main)
4038     thread_index = 0;
4039   /* Construct the API message */
4040   M (SW_INTERFACE_SET_RX_PLACEMENT, mp);
4041   mp->sw_if_index = ntohl (sw_if_index);
4042   mp->worker_id = ntohl (thread_index);
4043   mp->queue_id = ntohl (queue_id);
4044   mp->is_main = is_main;
4045
4046   /* send it... */
4047   S (mp);
4048   /* Wait for a reply, return the good/bad news... */
4049   W (ret);
4050   return ret;
4051 }
4052
4053 static void vl_api_sw_interface_rx_placement_details_t_handler
4054   (vl_api_sw_interface_rx_placement_details_t * mp)
4055 {
4056   vat_main_t *vam = &vat_main;
4057   u32 worker_id = ntohl (mp->worker_id);
4058
4059   print (vam->ofp,
4060          "\n%-11d %-11s %-6d %-5d %-9s",
4061          ntohl (mp->sw_if_index), (worker_id == 0) ? "main" : "worker",
4062          worker_id, ntohl (mp->queue_id),
4063          (mp->mode ==
4064           1) ? "polling" : ((mp->mode == 2) ? "interrupt" : "adaptive"));
4065 }
4066
4067 static void vl_api_sw_interface_rx_placement_details_t_handler_json
4068   (vl_api_sw_interface_rx_placement_details_t * mp)
4069 {
4070   vat_main_t *vam = &vat_main;
4071   vat_json_node_t *node = NULL;
4072
4073   if (VAT_JSON_ARRAY != vam->json_tree.type)
4074     {
4075       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4076       vat_json_init_array (&vam->json_tree);
4077     }
4078   node = vat_json_array_add (&vam->json_tree);
4079
4080   vat_json_init_object (node);
4081   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
4082   vat_json_object_add_uint (node, "worker_id", ntohl (mp->worker_id));
4083   vat_json_object_add_uint (node, "queue_id", ntohl (mp->queue_id));
4084   vat_json_object_add_uint (node, "mode", mp->mode);
4085 }
4086
4087 static int
4088 api_sw_interface_rx_placement_dump (vat_main_t * vam)
4089 {
4090   unformat_input_t *i = vam->input;
4091   vl_api_sw_interface_rx_placement_dump_t *mp;
4092   vl_api_control_ping_t *mp_ping;
4093   int ret;
4094   u32 sw_if_index;
4095   u8 sw_if_index_set = 0;
4096
4097   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4098     {
4099       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
4100         sw_if_index_set++;
4101       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4102         sw_if_index_set++;
4103       else
4104         break;
4105     }
4106
4107   print (vam->ofp,
4108          "\n%-11s %-11s %-6s %-5s %-4s",
4109          "sw_if_index", "main/worker", "thread", "queue", "mode");
4110
4111   /* Dump Interface rx placement */
4112   M (SW_INTERFACE_RX_PLACEMENT_DUMP, mp);
4113
4114   if (sw_if_index_set)
4115     mp->sw_if_index = htonl (sw_if_index);
4116   else
4117     mp->sw_if_index = ~0;
4118
4119   S (mp);
4120
4121   /* Use a control ping for synchronization */
4122   MPING (CONTROL_PING, mp_ping);
4123   S (mp_ping);
4124
4125   W (ret);
4126   return ret;
4127 }
4128
4129 static int
4130 api_sw_interface_clear_stats (vat_main_t * vam)
4131 {
4132   unformat_input_t *i = vam->input;
4133   vl_api_sw_interface_clear_stats_t *mp;
4134   u32 sw_if_index;
4135   u8 sw_if_index_set = 0;
4136   int ret;
4137
4138   /* Parse args required to build the message */
4139   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4140     {
4141       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
4142         sw_if_index_set = 1;
4143       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4144         sw_if_index_set = 1;
4145       else
4146         break;
4147     }
4148
4149   /* Construct the API message */
4150   M (SW_INTERFACE_CLEAR_STATS, mp);
4151
4152   if (sw_if_index_set == 1)
4153     mp->sw_if_index = ntohl (sw_if_index);
4154   else
4155     mp->sw_if_index = ~0;
4156
4157   /* send it... */
4158   S (mp);
4159
4160   /* Wait for a reply, return the good/bad news... */
4161   W (ret);
4162   return ret;
4163 }
4164
4165 static int
4166 api_sw_interface_add_del_address (vat_main_t * vam)
4167 {
4168   unformat_input_t *i = vam->input;
4169   vl_api_sw_interface_add_del_address_t *mp;
4170   u32 sw_if_index;
4171   u8 sw_if_index_set = 0;
4172   u8 is_add = 1, del_all = 0;
4173   u32 address_length = 0;
4174   u8 v4_address_set = 0;
4175   u8 v6_address_set = 0;
4176   ip4_address_t v4address;
4177   ip6_address_t v6address;
4178   int ret;
4179
4180   /* Parse args required to build the message */
4181   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4182     {
4183       if (unformat (i, "del-all"))
4184         del_all = 1;
4185       else if (unformat (i, "del"))
4186         is_add = 0;
4187       else
4188         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
4189         sw_if_index_set = 1;
4190       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4191         sw_if_index_set = 1;
4192       else if (unformat (i, "%U/%d",
4193                          unformat_ip4_address, &v4address, &address_length))
4194         v4_address_set = 1;
4195       else if (unformat (i, "%U/%d",
4196                          unformat_ip6_address, &v6address, &address_length))
4197         v6_address_set = 1;
4198       else
4199         break;
4200     }
4201
4202   if (sw_if_index_set == 0)
4203     {
4204       errmsg ("missing interface name or sw_if_index");
4205       return -99;
4206     }
4207   if (v4_address_set && v6_address_set)
4208     {
4209       errmsg ("both v4 and v6 addresses set");
4210       return -99;
4211     }
4212   if (!v4_address_set && !v6_address_set && !del_all)
4213     {
4214       errmsg ("no addresses set");
4215       return -99;
4216     }
4217
4218   /* Construct the API message */
4219   M (SW_INTERFACE_ADD_DEL_ADDRESS, mp);
4220
4221   mp->sw_if_index = ntohl (sw_if_index);
4222   mp->is_add = is_add;
4223   mp->del_all = del_all;
4224   if (v6_address_set)
4225     {
4226       mp->prefix.address.af = ADDRESS_IP6;
4227       clib_memcpy (mp->prefix.address.un.ip6, &v6address, sizeof (v6address));
4228     }
4229   else
4230     {
4231       mp->prefix.address.af = ADDRESS_IP4;
4232       clib_memcpy (mp->prefix.address.un.ip4, &v4address, sizeof (v4address));
4233     }
4234   mp->prefix.len = address_length;
4235
4236   /* send it... */
4237   S (mp);
4238
4239   /* Wait for a reply, return good/bad news  */
4240   W (ret);
4241   return ret;
4242 }
4243
4244 static int
4245 api_sw_interface_set_mpls_enable (vat_main_t * vam)
4246 {
4247   unformat_input_t *i = vam->input;
4248   vl_api_sw_interface_set_mpls_enable_t *mp;
4249   u32 sw_if_index;
4250   u8 sw_if_index_set = 0;
4251   u8 enable = 1;
4252   int ret;
4253
4254   /* Parse args required to build the message */
4255   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4256     {
4257       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
4258         sw_if_index_set = 1;
4259       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4260         sw_if_index_set = 1;
4261       else if (unformat (i, "disable"))
4262         enable = 0;
4263       else if (unformat (i, "dis"))
4264         enable = 0;
4265       else
4266         break;
4267     }
4268
4269   if (sw_if_index_set == 0)
4270     {
4271       errmsg ("missing interface name or sw_if_index");
4272       return -99;
4273     }
4274
4275   /* Construct the API message */
4276   M (SW_INTERFACE_SET_MPLS_ENABLE, mp);
4277
4278   mp->sw_if_index = ntohl (sw_if_index);
4279   mp->enable = enable;
4280
4281   /* send it... */
4282   S (mp);
4283
4284   /* Wait for a reply... */
4285   W (ret);
4286   return ret;
4287 }
4288
4289 static int
4290 api_sw_interface_set_table (vat_main_t * vam)
4291 {
4292   unformat_input_t *i = vam->input;
4293   vl_api_sw_interface_set_table_t *mp;
4294   u32 sw_if_index, vrf_id = 0;
4295   u8 sw_if_index_set = 0;
4296   u8 is_ipv6 = 0;
4297   int ret;
4298
4299   /* Parse args required to build the message */
4300   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4301     {
4302       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
4303         sw_if_index_set = 1;
4304       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4305         sw_if_index_set = 1;
4306       else if (unformat (i, "vrf %d", &vrf_id))
4307         ;
4308       else if (unformat (i, "ipv6"))
4309         is_ipv6 = 1;
4310       else
4311         break;
4312     }
4313
4314   if (sw_if_index_set == 0)
4315     {
4316       errmsg ("missing interface name or sw_if_index");
4317       return -99;
4318     }
4319
4320   /* Construct the API message */
4321   M (SW_INTERFACE_SET_TABLE, mp);
4322
4323   mp->sw_if_index = ntohl (sw_if_index);
4324   mp->is_ipv6 = is_ipv6;
4325   mp->vrf_id = ntohl (vrf_id);
4326
4327   /* send it... */
4328   S (mp);
4329
4330   /* Wait for a reply... */
4331   W (ret);
4332   return ret;
4333 }
4334
4335 static void vl_api_sw_interface_get_table_reply_t_handler
4336   (vl_api_sw_interface_get_table_reply_t * mp)
4337 {
4338   vat_main_t *vam = &vat_main;
4339
4340   print (vam->ofp, "%d", ntohl (mp->vrf_id));
4341
4342   vam->retval = ntohl (mp->retval);
4343   vam->result_ready = 1;
4344
4345 }
4346
4347 static void vl_api_sw_interface_get_table_reply_t_handler_json
4348   (vl_api_sw_interface_get_table_reply_t * mp)
4349 {
4350   vat_main_t *vam = &vat_main;
4351   vat_json_node_t node;
4352
4353   vat_json_init_object (&node);
4354   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
4355   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
4356
4357   vat_json_print (vam->ofp, &node);
4358   vat_json_free (&node);
4359
4360   vam->retval = ntohl (mp->retval);
4361   vam->result_ready = 1;
4362 }
4363
4364 static int
4365 api_sw_interface_get_table (vat_main_t * vam)
4366 {
4367   unformat_input_t *i = vam->input;
4368   vl_api_sw_interface_get_table_t *mp;
4369   u32 sw_if_index;
4370   u8 sw_if_index_set = 0;
4371   u8 is_ipv6 = 0;
4372   int ret;
4373
4374   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4375     {
4376       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
4377         sw_if_index_set = 1;
4378       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4379         sw_if_index_set = 1;
4380       else if (unformat (i, "ipv6"))
4381         is_ipv6 = 1;
4382       else
4383         break;
4384     }
4385
4386   if (sw_if_index_set == 0)
4387     {
4388       errmsg ("missing interface name or sw_if_index");
4389       return -99;
4390     }
4391
4392   M (SW_INTERFACE_GET_TABLE, mp);
4393   mp->sw_if_index = htonl (sw_if_index);
4394   mp->is_ipv6 = is_ipv6;
4395
4396   S (mp);
4397   W (ret);
4398   return ret;
4399 }
4400
4401 static int
4402 api_sw_interface_set_vpath (vat_main_t * vam)
4403 {
4404   unformat_input_t *i = vam->input;
4405   vl_api_sw_interface_set_vpath_t *mp;
4406   u32 sw_if_index = 0;
4407   u8 sw_if_index_set = 0;
4408   u8 is_enable = 0;
4409   int ret;
4410
4411   /* Parse args required to build the message */
4412   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4413     {
4414       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
4415         sw_if_index_set = 1;
4416       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4417         sw_if_index_set = 1;
4418       else if (unformat (i, "enable"))
4419         is_enable = 1;
4420       else if (unformat (i, "disable"))
4421         is_enable = 0;
4422       else
4423         break;
4424     }
4425
4426   if (sw_if_index_set == 0)
4427     {
4428       errmsg ("missing interface name or sw_if_index");
4429       return -99;
4430     }
4431
4432   /* Construct the API message */
4433   M (SW_INTERFACE_SET_VPATH, mp);
4434
4435   mp->sw_if_index = ntohl (sw_if_index);
4436   mp->enable = is_enable;
4437
4438   /* send it... */
4439   S (mp);
4440
4441   /* Wait for a reply... */
4442   W (ret);
4443   return ret;
4444 }
4445
4446 static int
4447 api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
4448 {
4449   unformat_input_t *i = vam->input;
4450   vl_api_sw_interface_set_vxlan_bypass_t *mp;
4451   u32 sw_if_index = 0;
4452   u8 sw_if_index_set = 0;
4453   u8 is_enable = 1;
4454   u8 is_ipv6 = 0;
4455   int ret;
4456
4457   /* Parse args required to build the message */
4458   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4459     {
4460       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
4461         sw_if_index_set = 1;
4462       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4463         sw_if_index_set = 1;
4464       else if (unformat (i, "enable"))
4465         is_enable = 1;
4466       else if (unformat (i, "disable"))
4467         is_enable = 0;
4468       else if (unformat (i, "ip4"))
4469         is_ipv6 = 0;
4470       else if (unformat (i, "ip6"))
4471         is_ipv6 = 1;
4472       else
4473         break;
4474     }
4475
4476   if (sw_if_index_set == 0)
4477     {
4478       errmsg ("missing interface name or sw_if_index");
4479       return -99;
4480     }
4481
4482   /* Construct the API message */
4483   M (SW_INTERFACE_SET_VXLAN_BYPASS, mp);
4484
4485   mp->sw_if_index = ntohl (sw_if_index);
4486   mp->enable = is_enable;
4487   mp->is_ipv6 = is_ipv6;
4488
4489   /* send it... */
4490   S (mp);
4491
4492   /* Wait for a reply... */
4493   W (ret);
4494   return ret;
4495 }
4496
4497 static int
4498 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
4499 {
4500   unformat_input_t *i = vam->input;
4501   vl_api_sw_interface_set_l2_xconnect_t *mp;
4502   u32 rx_sw_if_index;
4503   u8 rx_sw_if_index_set = 0;
4504   u32 tx_sw_if_index;
4505   u8 tx_sw_if_index_set = 0;
4506   u8 enable = 1;
4507   int ret;
4508
4509   /* Parse args required to build the message */
4510   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4511     {
4512       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
4513         rx_sw_if_index_set = 1;
4514       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
4515         tx_sw_if_index_set = 1;
4516       else if (unformat (i, "rx"))
4517         {
4518           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4519             {
4520               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
4521                             &rx_sw_if_index))
4522                 rx_sw_if_index_set = 1;
4523             }
4524           else
4525             break;
4526         }
4527       else if (unformat (i, "tx"))
4528         {
4529           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4530             {
4531               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
4532                             &tx_sw_if_index))
4533                 tx_sw_if_index_set = 1;
4534             }
4535           else
4536             break;
4537         }
4538       else if (unformat (i, "enable"))
4539         enable = 1;
4540       else if (unformat (i, "disable"))
4541         enable = 0;
4542       else
4543         break;
4544     }
4545
4546   if (rx_sw_if_index_set == 0)
4547     {
4548       errmsg ("missing rx interface name or rx_sw_if_index");
4549       return -99;
4550     }
4551
4552   if (enable && (tx_sw_if_index_set == 0))
4553     {
4554       errmsg ("missing tx interface name or tx_sw_if_index");
4555       return -99;
4556     }
4557
4558   M (SW_INTERFACE_SET_L2_XCONNECT, mp);
4559
4560   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
4561   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
4562   mp->enable = enable;
4563
4564   S (mp);
4565   W (ret);
4566   return ret;
4567 }
4568
4569 static int
4570 api_sw_interface_set_l2_bridge (vat_main_t * vam)
4571 {
4572   unformat_input_t *i = vam->input;
4573   vl_api_sw_interface_set_l2_bridge_t *mp;
4574   vl_api_l2_port_type_t port_type;
4575   u32 rx_sw_if_index;
4576   u8 rx_sw_if_index_set = 0;
4577   u32 bd_id;
4578   u8 bd_id_set = 0;
4579   u32 shg = 0;
4580   u8 enable = 1;
4581   int ret;
4582
4583   port_type = L2_API_PORT_TYPE_NORMAL;
4584
4585   /* Parse args required to build the message */
4586   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4587     {
4588       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
4589         rx_sw_if_index_set = 1;
4590       else if (unformat (i, "bd_id %d", &bd_id))
4591         bd_id_set = 1;
4592       else
4593         if (unformat
4594             (i, "%U", api_unformat_sw_if_index, vam, &rx_sw_if_index))
4595         rx_sw_if_index_set = 1;
4596       else if (unformat (i, "shg %d", &shg))
4597         ;
4598       else if (unformat (i, "bvi"))
4599         port_type = L2_API_PORT_TYPE_BVI;
4600       else if (unformat (i, "uu-fwd"))
4601         port_type = L2_API_PORT_TYPE_UU_FWD;
4602       else if (unformat (i, "enable"))
4603         enable = 1;
4604       else if (unformat (i, "disable"))
4605         enable = 0;
4606       else
4607         break;
4608     }
4609
4610   if (rx_sw_if_index_set == 0)
4611     {
4612       errmsg ("missing rx interface name or sw_if_index");
4613       return -99;
4614     }
4615
4616   if (enable && (bd_id_set == 0))
4617     {
4618       errmsg ("missing bridge domain");
4619       return -99;
4620     }
4621
4622   M (SW_INTERFACE_SET_L2_BRIDGE, mp);
4623
4624   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
4625   mp->bd_id = ntohl (bd_id);
4626   mp->shg = (u8) shg;
4627   mp->port_type = ntohl (port_type);
4628   mp->enable = enable;
4629
4630   S (mp);
4631   W (ret);
4632   return ret;
4633 }
4634
4635 static int
4636 api_bridge_domain_dump (vat_main_t * vam)
4637 {
4638   unformat_input_t *i = vam->input;
4639   vl_api_bridge_domain_dump_t *mp;
4640   vl_api_control_ping_t *mp_ping;
4641   u32 bd_id = ~0;
4642   int ret;
4643
4644   /* Parse args required to build the message */
4645   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4646     {
4647       if (unformat (i, "bd_id %d", &bd_id))
4648         ;
4649       else
4650         break;
4651     }
4652
4653   M (BRIDGE_DOMAIN_DUMP, mp);
4654   mp->bd_id = ntohl (bd_id);
4655   S (mp);
4656
4657   /* Use a control ping for synchronization */
4658   MPING (CONTROL_PING, mp_ping);
4659   S (mp_ping);
4660
4661   W (ret);
4662   return ret;
4663 }
4664
4665 static int
4666 api_bridge_domain_add_del (vat_main_t * vam)
4667 {
4668   unformat_input_t *i = vam->input;
4669   vl_api_bridge_domain_add_del_t *mp;
4670   u32 bd_id = ~0;
4671   u8 is_add = 1;
4672   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
4673   u8 *bd_tag = NULL;
4674   u32 mac_age = 0;
4675   int ret;
4676
4677   /* Parse args required to build the message */
4678   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4679     {
4680       if (unformat (i, "bd_id %d", &bd_id))
4681         ;
4682       else if (unformat (i, "flood %d", &flood))
4683         ;
4684       else if (unformat (i, "uu-flood %d", &uu_flood))
4685         ;
4686       else if (unformat (i, "forward %d", &forward))
4687         ;
4688       else if (unformat (i, "learn %d", &learn))
4689         ;
4690       else if (unformat (i, "arp-term %d", &arp_term))
4691         ;
4692       else if (unformat (i, "mac-age %d", &mac_age))
4693         ;
4694       else if (unformat (i, "bd-tag %s", &bd_tag))
4695         ;
4696       else if (unformat (i, "del"))
4697         {
4698           is_add = 0;
4699           flood = uu_flood = forward = learn = 0;
4700         }
4701       else
4702         break;
4703     }
4704
4705   if (bd_id == ~0)
4706     {
4707       errmsg ("missing bridge domain");
4708       ret = -99;
4709       goto done;
4710     }
4711
4712   if (mac_age > 255)
4713     {
4714       errmsg ("mac age must be less than 256 ");
4715       ret = -99;
4716       goto done;
4717     }
4718
4719   if ((bd_tag) && (vec_len (bd_tag) > 63))
4720     {
4721       errmsg ("bd-tag cannot be longer than 63");
4722       ret = -99;
4723       goto done;
4724     }
4725
4726   M (BRIDGE_DOMAIN_ADD_DEL, mp);
4727
4728   mp->bd_id = ntohl (bd_id);
4729   mp->flood = flood;
4730   mp->uu_flood = uu_flood;
4731   mp->forward = forward;
4732   mp->learn = learn;
4733   mp->arp_term = arp_term;
4734   mp->is_add = is_add;
4735   mp->mac_age = (u8) mac_age;
4736   if (bd_tag)
4737     {
4738       clib_memcpy (mp->bd_tag, bd_tag, vec_len (bd_tag));
4739       mp->bd_tag[vec_len (bd_tag)] = 0;
4740     }
4741   S (mp);
4742   W (ret);
4743
4744 done:
4745   vec_free (bd_tag);
4746   return ret;
4747 }
4748
4749 static int
4750 api_l2fib_flush_bd (vat_main_t * vam)
4751 {
4752   unformat_input_t *i = vam->input;
4753   vl_api_l2fib_flush_bd_t *mp;
4754   u32 bd_id = ~0;
4755   int ret;
4756
4757   /* Parse args required to build the message */
4758   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4759     {
4760       if (unformat (i, "bd_id %d", &bd_id));
4761       else
4762         break;
4763     }
4764
4765   if (bd_id == ~0)
4766     {
4767       errmsg ("missing bridge domain");
4768       return -99;
4769     }
4770
4771   M (L2FIB_FLUSH_BD, mp);
4772
4773   mp->bd_id = htonl (bd_id);
4774
4775   S (mp);
4776   W (ret);
4777   return ret;
4778 }
4779
4780 static int
4781 api_l2fib_flush_int (vat_main_t * vam)
4782 {
4783   unformat_input_t *i = vam->input;
4784   vl_api_l2fib_flush_int_t *mp;
4785   u32 sw_if_index = ~0;
4786   int ret;
4787
4788   /* Parse args required to build the message */
4789   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4790     {
4791       if (unformat (i, "sw_if_index %d", &sw_if_index));
4792       else
4793         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index));
4794       else
4795         break;
4796     }
4797
4798   if (sw_if_index == ~0)
4799     {
4800       errmsg ("missing interface name or sw_if_index");
4801       return -99;
4802     }
4803
4804   M (L2FIB_FLUSH_INT, mp);
4805
4806   mp->sw_if_index = ntohl (sw_if_index);
4807
4808   S (mp);
4809   W (ret);
4810   return ret;
4811 }
4812
4813 static int
4814 api_l2fib_add_del (vat_main_t * vam)
4815 {
4816   unformat_input_t *i = vam->input;
4817   vl_api_l2fib_add_del_t *mp;
4818   f64 timeout;
4819   u8 mac[6] = { 0 };
4820   u8 mac_set = 0;
4821   u32 bd_id;
4822   u8 bd_id_set = 0;
4823   u32 sw_if_index = 0;
4824   u8 sw_if_index_set = 0;
4825   u8 is_add = 1;
4826   u8 static_mac = 0;
4827   u8 filter_mac = 0;
4828   u8 bvi_mac = 0;
4829   int count = 1;
4830   f64 before = 0;
4831   int j;
4832
4833   /* Parse args required to build the message */
4834   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4835     {
4836       if (unformat (i, "mac %U", unformat_ethernet_address, mac))
4837         mac_set = 1;
4838       else if (unformat (i, "bd_id %d", &bd_id))
4839         bd_id_set = 1;
4840       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4841         sw_if_index_set = 1;
4842       else if (unformat (i, "sw_if"))
4843         {
4844           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4845             {
4846               if (unformat
4847                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
4848                 sw_if_index_set = 1;
4849             }
4850           else
4851             break;
4852         }
4853       else if (unformat (i, "static"))
4854         static_mac = 1;
4855       else if (unformat (i, "filter"))
4856         {
4857           filter_mac = 1;
4858           static_mac = 1;
4859         }
4860       else if (unformat (i, "bvi"))
4861         {
4862           bvi_mac = 1;
4863           static_mac = 1;
4864         }
4865       else if (unformat (i, "del"))
4866         is_add = 0;
4867       else if (unformat (i, "count %d", &count))
4868         ;
4869       else
4870         break;
4871     }
4872
4873   if (mac_set == 0)
4874     {
4875       errmsg ("missing mac address");
4876       return -99;
4877     }
4878
4879   if (bd_id_set == 0)
4880     {
4881       errmsg ("missing bridge domain");
4882       return -99;
4883     }
4884
4885   if (is_add && sw_if_index_set == 0 && filter_mac == 0)
4886     {
4887       errmsg ("missing interface name or sw_if_index");
4888       return -99;
4889     }
4890
4891   if (count > 1)
4892     {
4893       /* Turn on async mode */
4894       vam->async_mode = 1;
4895       vam->async_errors = 0;
4896       before = vat_time_now (vam);
4897     }
4898
4899   for (j = 0; j < count; j++)
4900     {
4901       M (L2FIB_ADD_DEL, mp);
4902
4903       clib_memcpy (mp->mac, mac, 6);
4904       mp->bd_id = ntohl (bd_id);
4905       mp->is_add = is_add;
4906       mp->sw_if_index = ntohl (sw_if_index);
4907
4908       if (is_add)
4909         {
4910           mp->static_mac = static_mac;
4911           mp->filter_mac = filter_mac;
4912           mp->bvi_mac = bvi_mac;
4913         }
4914       increment_mac_address (mac);
4915       /* send it... */
4916       S (mp);
4917     }
4918
4919   if (count > 1)
4920     {
4921       vl_api_control_ping_t *mp_ping;
4922       f64 after;
4923
4924       /* Shut off async mode */
4925       vam->async_mode = 0;
4926
4927       MPING (CONTROL_PING, mp_ping);
4928       S (mp_ping);
4929
4930       timeout = vat_time_now (vam) + 1.0;
4931       while (vat_time_now (vam) < timeout)
4932         if (vam->result_ready == 1)
4933           goto out;
4934       vam->retval = -99;
4935
4936     out:
4937       if (vam->retval == -99)
4938         errmsg ("timeout");
4939
4940       if (vam->async_errors > 0)
4941         {
4942           errmsg ("%d asynchronous errors", vam->async_errors);
4943           vam->retval = -98;
4944         }
4945       vam->async_errors = 0;
4946       after = vat_time_now (vam);
4947
4948       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
4949              count, after - before, count / (after - before));
4950     }
4951   else
4952     {
4953       int ret;
4954
4955       /* Wait for a reply... */
4956       W (ret);
4957       return ret;
4958     }
4959   /* Return the good/bad news */
4960   return (vam->retval);
4961 }
4962
4963 static int
4964 api_bridge_domain_set_mac_age (vat_main_t * vam)
4965 {
4966   unformat_input_t *i = vam->input;
4967   vl_api_bridge_domain_set_mac_age_t *mp;
4968   u32 bd_id = ~0;
4969   u32 mac_age = 0;
4970   int ret;
4971
4972   /* Parse args required to build the message */
4973   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4974     {
4975       if (unformat (i, "bd_id %d", &bd_id));
4976       else if (unformat (i, "mac-age %d", &mac_age));
4977       else
4978         break;
4979     }
4980
4981   if (bd_id == ~0)
4982     {
4983       errmsg ("missing bridge domain");
4984       return -99;
4985     }
4986
4987   if (mac_age > 255)
4988     {
4989       errmsg ("mac age must be less than 256 ");
4990       return -99;
4991     }
4992
4993   M (BRIDGE_DOMAIN_SET_MAC_AGE, mp);
4994
4995   mp->bd_id = htonl (bd_id);
4996   mp->mac_age = (u8) mac_age;
4997
4998   S (mp);
4999   W (ret);
5000   return ret;
5001 }
5002
5003 static int
5004 api_l2_flags (vat_main_t * vam)
5005 {
5006   unformat_input_t *i = vam->input;
5007   vl_api_l2_flags_t *mp;
5008   u32 sw_if_index;
5009   u32 flags = 0;
5010   u8 sw_if_index_set = 0;
5011   u8 is_set = 0;
5012   int ret;
5013
5014   /* Parse args required to build the message */
5015   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5016     {
5017       if (unformat (i, "sw_if_index %d", &sw_if_index))
5018         sw_if_index_set = 1;
5019       else if (unformat (i, "sw_if"))
5020         {
5021           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5022             {
5023               if (unformat
5024                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5025                 sw_if_index_set = 1;
5026             }
5027           else
5028             break;
5029         }
5030       else if (unformat (i, "learn"))
5031         flags |= L2_LEARN;
5032       else if (unformat (i, "forward"))
5033         flags |= L2_FWD;
5034       else if (unformat (i, "flood"))
5035         flags |= L2_FLOOD;
5036       else if (unformat (i, "uu-flood"))
5037         flags |= L2_UU_FLOOD;
5038       else if (unformat (i, "arp-term"))
5039         flags |= L2_ARP_TERM;
5040       else if (unformat (i, "off"))
5041         is_set = 0;
5042       else if (unformat (i, "disable"))
5043         is_set = 0;
5044       else
5045         break;
5046     }
5047
5048   if (sw_if_index_set == 0)
5049     {
5050       errmsg ("missing interface name or sw_if_index");
5051       return -99;
5052     }
5053
5054   M (L2_FLAGS, mp);
5055
5056   mp->sw_if_index = ntohl (sw_if_index);
5057   mp->feature_bitmap = ntohl (flags);
5058   mp->is_set = is_set;
5059
5060   S (mp);
5061   W (ret);
5062   return ret;
5063 }
5064
5065 static int
5066 api_bridge_flags (vat_main_t * vam)
5067 {
5068   unformat_input_t *i = vam->input;
5069   vl_api_bridge_flags_t *mp;
5070   u32 bd_id;
5071   u8 bd_id_set = 0;
5072   u8 is_set = 1;
5073   bd_flags_t flags = 0;
5074   int ret;
5075
5076   /* Parse args required to build the message */
5077   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5078     {
5079       if (unformat (i, "bd_id %d", &bd_id))
5080         bd_id_set = 1;
5081       else if (unformat (i, "learn"))
5082         flags |= BRIDGE_API_FLAG_LEARN;
5083       else if (unformat (i, "forward"))
5084         flags |= BRIDGE_API_FLAG_FWD;
5085       else if (unformat (i, "flood"))
5086         flags |= BRIDGE_API_FLAG_FLOOD;
5087       else if (unformat (i, "uu-flood"))
5088         flags |= BRIDGE_API_FLAG_UU_FLOOD;
5089       else if (unformat (i, "arp-term"))
5090         flags |= BRIDGE_API_FLAG_ARP_TERM;
5091       else if (unformat (i, "off"))
5092         is_set = 0;
5093       else if (unformat (i, "disable"))
5094         is_set = 0;
5095       else
5096         break;
5097     }
5098
5099   if (bd_id_set == 0)
5100     {
5101       errmsg ("missing bridge domain");
5102       return -99;
5103     }
5104
5105   M (BRIDGE_FLAGS, mp);
5106
5107   mp->bd_id = ntohl (bd_id);
5108   mp->flags = ntohl (flags);
5109   mp->is_set = is_set;
5110
5111   S (mp);
5112   W (ret);
5113   return ret;
5114 }
5115
5116 static int
5117 api_bd_ip_mac_add_del (vat_main_t * vam)
5118 {
5119   vl_api_address_t ip = VL_API_ZERO_ADDRESS;
5120   vl_api_mac_address_t mac = { 0 };
5121   unformat_input_t *i = vam->input;
5122   vl_api_bd_ip_mac_add_del_t *mp;
5123   u32 bd_id;
5124   u8 is_add = 1;
5125   u8 bd_id_set = 0;
5126   u8 ip_set = 0;
5127   u8 mac_set = 0;
5128   int ret;
5129
5130
5131   /* Parse args required to build the message */
5132   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5133     {
5134       if (unformat (i, "bd_id %d", &bd_id))
5135         {
5136           bd_id_set++;
5137         }
5138       else if (unformat (i, "%U", unformat_vl_api_address, &ip))
5139         {
5140           ip_set++;
5141         }
5142       else if (unformat (i, "%U", unformat_vl_api_mac_address, &mac))
5143         {
5144           mac_set++;
5145         }
5146       else if (unformat (i, "del"))
5147         is_add = 0;
5148       else
5149         break;
5150     }
5151
5152   if (bd_id_set == 0)
5153     {
5154       errmsg ("missing bridge domain");
5155       return -99;
5156     }
5157   else if (ip_set == 0)
5158     {
5159       errmsg ("missing IP address");
5160       return -99;
5161     }
5162   else if (mac_set == 0)
5163     {
5164       errmsg ("missing MAC address");
5165       return -99;
5166     }
5167
5168   M (BD_IP_MAC_ADD_DEL, mp);
5169
5170   mp->entry.bd_id = ntohl (bd_id);
5171   mp->is_add = is_add;
5172
5173   clib_memcpy (&mp->entry.ip, &ip, sizeof (ip));
5174   clib_memcpy (&mp->entry.mac, &mac, sizeof (mac));
5175
5176   S (mp);
5177   W (ret);
5178   return ret;
5179 }
5180
5181 static int
5182 api_bd_ip_mac_flush (vat_main_t * vam)
5183 {
5184   unformat_input_t *i = vam->input;
5185   vl_api_bd_ip_mac_flush_t *mp;
5186   u32 bd_id;
5187   u8 bd_id_set = 0;
5188   int ret;
5189
5190   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5191     {
5192       if (unformat (i, "bd_id %d", &bd_id))
5193         {
5194           bd_id_set++;
5195         }
5196       else
5197         break;
5198     }
5199
5200   if (bd_id_set == 0)
5201     {
5202       errmsg ("missing bridge domain");
5203       return -99;
5204     }
5205
5206   M (BD_IP_MAC_FLUSH, mp);
5207
5208   mp->bd_id = ntohl (bd_id);
5209
5210   S (mp);
5211   W (ret);
5212   return ret;
5213 }
5214
5215 static void vl_api_bd_ip_mac_details_t_handler
5216   (vl_api_bd_ip_mac_details_t * mp)
5217 {
5218   vat_main_t *vam = &vat_main;
5219
5220   print (vam->ofp,
5221          "\n%-5d %U %U",
5222          ntohl (mp->entry.bd_id),
5223          format_vl_api_mac_address, mp->entry.mac,
5224          format_vl_api_address, &mp->entry.ip);
5225 }
5226
5227 static void vl_api_bd_ip_mac_details_t_handler_json
5228   (vl_api_bd_ip_mac_details_t * mp)
5229 {
5230   vat_main_t *vam = &vat_main;
5231   vat_json_node_t *node = NULL;
5232
5233   if (VAT_JSON_ARRAY != vam->json_tree.type)
5234     {
5235       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5236       vat_json_init_array (&vam->json_tree);
5237     }
5238   node = vat_json_array_add (&vam->json_tree);
5239
5240   vat_json_init_object (node);
5241   vat_json_object_add_uint (node, "bd_id", ntohl (mp->entry.bd_id));
5242   vat_json_object_add_string_copy (node, "mac_address",
5243                                    format (0, "%U", format_vl_api_mac_address,
5244                                            &mp->entry.mac));
5245   u8 *ip = 0;
5246
5247   ip = format (0, "%U", format_vl_api_address, &mp->entry.ip);
5248   vat_json_object_add_string_copy (node, "ip_address", ip);
5249   vec_free (ip);
5250 }
5251
5252 static int
5253 api_bd_ip_mac_dump (vat_main_t * vam)
5254 {
5255   unformat_input_t *i = vam->input;
5256   vl_api_bd_ip_mac_dump_t *mp;
5257   vl_api_control_ping_t *mp_ping;
5258   int ret;
5259   u32 bd_id;
5260   u8 bd_id_set = 0;
5261
5262   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5263     {
5264       if (unformat (i, "bd_id %d", &bd_id))
5265         {
5266           bd_id_set++;
5267         }
5268       else
5269         break;
5270     }
5271
5272   print (vam->ofp,
5273          "\n%-5s %-7s %-20s %-30s",
5274          "bd_id", "is_ipv6", "mac_address", "ip_address");
5275
5276   /* Dump Bridge Domain Ip to Mac entries */
5277   M (BD_IP_MAC_DUMP, mp);
5278
5279   if (bd_id_set)
5280     mp->bd_id = htonl (bd_id);
5281   else
5282     mp->bd_id = ~0;
5283
5284   S (mp);
5285
5286   /* Use a control ping for synchronization */
5287   MPING (CONTROL_PING, mp_ping);
5288   S (mp_ping);
5289
5290   W (ret);
5291   return ret;
5292 }
5293
5294 static int
5295 api_tap_create_v2 (vat_main_t * vam)
5296 {
5297   unformat_input_t *i = vam->input;
5298   vl_api_tap_create_v2_t *mp;
5299   u8 mac_address[6];
5300   u8 random_mac = 1;
5301   u32 id = ~0;
5302   u32 num_rx_queues = 0;
5303   u8 *host_if_name = 0;
5304   u8 host_if_name_set = 0;
5305   u8 *host_ns = 0;
5306   u8 host_ns_set = 0;
5307   u8 host_mac_addr[6];
5308   u8 host_mac_addr_set = 0;
5309   u8 *host_bridge = 0;
5310   u8 host_bridge_set = 0;
5311   u8 host_ip4_prefix_set = 0;
5312   u8 host_ip6_prefix_set = 0;
5313   ip4_address_t host_ip4_addr;
5314   ip4_address_t host_ip4_gw;
5315   u8 host_ip4_gw_set = 0;
5316   u32 host_ip4_prefix_len = 0;
5317   ip6_address_t host_ip6_addr;
5318   ip6_address_t host_ip6_gw;
5319   u8 host_ip6_gw_set = 0;
5320   u32 host_ip6_prefix_len = 0;
5321   u32 host_mtu_size = 0;
5322   u8 host_mtu_set = 0;
5323   u32 tap_flags = 0;
5324   int ret;
5325   u32 rx_ring_sz = 0, tx_ring_sz = 0;
5326
5327   clib_memset (mac_address, 0, sizeof (mac_address));
5328
5329   /* Parse args required to build the message */
5330   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5331     {
5332       if (unformat (i, "id %u", &id))
5333         ;
5334       else
5335         if (unformat
5336             (i, "hw-addr %U", unformat_ethernet_address, mac_address))
5337         random_mac = 0;
5338       else if (unformat (i, "host-if-name %s", &host_if_name))
5339         host_if_name_set = 1;
5340       else if (unformat (i, "num-rx-queues %u", &num_rx_queues))
5341         ;
5342       else if (unformat (i, "host-ns %s", &host_ns))
5343         host_ns_set = 1;
5344       else if (unformat (i, "host-mac-addr %U", unformat_ethernet_address,
5345                          host_mac_addr))
5346         host_mac_addr_set = 1;
5347       else if (unformat (i, "host-bridge %s", &host_bridge))
5348         host_bridge_set = 1;
5349       else if (unformat (i, "host-ip4-addr %U/%u", unformat_ip4_address,
5350                          &host_ip4_addr, &host_ip4_prefix_len))
5351         host_ip4_prefix_set = 1;
5352       else if (unformat (i, "host-ip6-addr %U/%u", unformat_ip6_address,
5353                          &host_ip6_addr, &host_ip6_prefix_len))
5354         host_ip6_prefix_set = 1;
5355       else if (unformat (i, "host-ip4-gw %U", unformat_ip4_address,
5356                          &host_ip4_gw))
5357         host_ip4_gw_set = 1;
5358       else if (unformat (i, "host-ip6-gw %U", unformat_ip6_address,
5359                          &host_ip6_gw))
5360         host_ip6_gw_set = 1;
5361       else if (unformat (i, "rx-ring-size %u", &rx_ring_sz))
5362         ;
5363       else if (unformat (i, "tx-ring-size %u", &tx_ring_sz))
5364         ;
5365       else if (unformat (i, "host-mtu-size %u", &host_mtu_size))
5366         host_mtu_set = 1;
5367       else if (unformat (i, "no-gso"))
5368         tap_flags &= ~TAP_API_FLAG_GSO;
5369       else if (unformat (i, "gso"))
5370         tap_flags |= TAP_API_FLAG_GSO;
5371       else if (unformat (i, "csum-offload"))
5372         tap_flags |= TAP_API_FLAG_CSUM_OFFLOAD;
5373       else if (unformat (i, "persist"))
5374         tap_flags |= TAP_API_FLAG_PERSIST;
5375       else if (unformat (i, "attach"))
5376         tap_flags |= TAP_API_FLAG_ATTACH;
5377       else if (unformat (i, "tun"))
5378         tap_flags |= TAP_API_FLAG_TUN;
5379       else if (unformat (i, "gro-coalesce"))
5380         tap_flags |= TAP_API_FLAG_GRO_COALESCE;
5381       else if (unformat (i, "packed"))
5382         tap_flags |= TAP_API_FLAG_PACKED;
5383       else if (unformat (i, "in-order"))
5384         tap_flags |= TAP_API_FLAG_IN_ORDER;
5385       else
5386         break;
5387     }
5388
5389   if (vec_len (host_if_name) > 63)
5390     {
5391       errmsg ("tap name too long. ");
5392       return -99;
5393     }
5394   if (vec_len (host_ns) > 63)
5395     {
5396       errmsg ("host name space too long. ");
5397       return -99;
5398     }
5399   if (vec_len (host_bridge) > 63)
5400     {
5401       errmsg ("host bridge name too long. ");
5402       return -99;
5403     }
5404   if (host_ip4_prefix_len > 32)
5405     {
5406       errmsg ("host ip4 prefix length not valid. ");
5407       return -99;
5408     }
5409   if (host_ip6_prefix_len > 128)
5410     {
5411       errmsg ("host ip6 prefix length not valid. ");
5412       return -99;
5413     }
5414   if (!is_pow2 (rx_ring_sz))
5415     {
5416       errmsg ("rx ring size must be power of 2. ");
5417       return -99;
5418     }
5419   if (rx_ring_sz > 32768)
5420     {
5421       errmsg ("rx ring size must be 32768 or lower. ");
5422       return -99;
5423     }
5424   if (!is_pow2 (tx_ring_sz))
5425     {
5426       errmsg ("tx ring size must be power of 2. ");
5427       return -99;
5428     }
5429   if (tx_ring_sz > 32768)
5430     {
5431       errmsg ("tx ring size must be 32768 or lower. ");
5432       return -99;
5433     }
5434   if (host_mtu_set && (host_mtu_size < 64 || host_mtu_size > 65355))
5435     {
5436       errmsg ("host MTU size must be in between 64 and 65355. ");
5437       return -99;
5438     }
5439
5440   /* Construct the API message */
5441   M (TAP_CREATE_V2, mp);
5442
5443   mp->id = ntohl (id);
5444   mp->use_random_mac = random_mac;
5445   mp->num_rx_queues = (u8) num_rx_queues;
5446   mp->tx_ring_sz = ntohs (tx_ring_sz);
5447   mp->rx_ring_sz = ntohs (rx_ring_sz);
5448   mp->host_mtu_set = host_mtu_set;
5449   mp->host_mtu_size = ntohl (host_mtu_size);
5450   mp->host_mac_addr_set = host_mac_addr_set;
5451   mp->host_ip4_prefix_set = host_ip4_prefix_set;
5452   mp->host_ip6_prefix_set = host_ip6_prefix_set;
5453   mp->host_ip4_gw_set = host_ip4_gw_set;
5454   mp->host_ip6_gw_set = host_ip6_gw_set;
5455   mp->tap_flags = ntohl (tap_flags);
5456   mp->host_namespace_set = host_ns_set;
5457   mp->host_if_name_set = host_if_name_set;
5458   mp->host_bridge_set = host_bridge_set;
5459
5460   if (random_mac == 0)
5461     clib_memcpy (mp->mac_address, mac_address, 6);
5462   if (host_mac_addr_set)
5463     clib_memcpy (mp->host_mac_addr, host_mac_addr, 6);
5464   if (host_if_name_set)
5465     clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
5466   if (host_ns_set)
5467     clib_memcpy (mp->host_namespace, host_ns, vec_len (host_ns));
5468   if (host_bridge_set)
5469     clib_memcpy (mp->host_bridge, host_bridge, vec_len (host_bridge));
5470   if (host_ip4_prefix_set)
5471     {
5472       clib_memcpy (mp->host_ip4_prefix.address, &host_ip4_addr, 4);
5473       mp->host_ip4_prefix.len = (u8) host_ip4_prefix_len;
5474     }
5475   if (host_ip6_prefix_set)
5476     {
5477       clib_memcpy (mp->host_ip6_prefix.address, &host_ip6_addr, 16);
5478       mp->host_ip6_prefix.len = (u8) host_ip6_prefix_len;
5479     }
5480   if (host_ip4_gw_set)
5481     clib_memcpy (mp->host_ip4_gw, &host_ip4_gw, 4);
5482   if (host_ip6_gw_set)
5483     clib_memcpy (mp->host_ip6_gw, &host_ip6_gw, 16);
5484
5485   vec_free (host_ns);
5486   vec_free (host_if_name);
5487   vec_free (host_bridge);
5488
5489   /* send it... */
5490   S (mp);
5491
5492   /* Wait for a reply... */
5493   W (ret);
5494   return ret;
5495 }
5496
5497 static int
5498 api_tap_delete_v2 (vat_main_t * vam)
5499 {
5500   unformat_input_t *i = vam->input;
5501   vl_api_tap_delete_v2_t *mp;
5502   u32 sw_if_index = ~0;
5503   u8 sw_if_index_set = 0;
5504   int ret;
5505
5506   /* Parse args required to build the message */
5507   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5508     {
5509       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5510         sw_if_index_set = 1;
5511       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5512         sw_if_index_set = 1;
5513       else
5514         break;
5515     }
5516
5517   if (sw_if_index_set == 0)
5518     {
5519       errmsg ("missing vpp interface name. ");
5520       return -99;
5521     }
5522
5523   /* Construct the API message */
5524   M (TAP_DELETE_V2, mp);
5525
5526   mp->sw_if_index = ntohl (sw_if_index);
5527
5528   /* send it... */
5529   S (mp);
5530
5531   /* Wait for a reply... */
5532   W (ret);
5533   return ret;
5534 }
5535
5536 uword
5537 unformat_vlib_pci_addr (unformat_input_t * input, va_list * args)
5538 {
5539   vlib_pci_addr_t *addr = va_arg (*args, vlib_pci_addr_t *);
5540   u32 x[4];
5541
5542   if (!unformat (input, "%x:%x:%x.%x", &x[0], &x[1], &x[2], &x[3]))
5543     return 0;
5544
5545   addr->domain = x[0];
5546   addr->bus = x[1];
5547   addr->slot = x[2];
5548   addr->function = x[3];
5549
5550   return 1;
5551 }
5552
5553 static int
5554 api_virtio_pci_create_v2 (vat_main_t * vam)
5555 {
5556   unformat_input_t *i = vam->input;
5557   vl_api_virtio_pci_create_v2_t *mp;
5558   u8 mac_address[6];
5559   u8 random_mac = 1;
5560   u32 pci_addr = 0;
5561   u64 features = (u64) ~ (0ULL);
5562   u32 virtio_flags = 0;
5563   int ret;
5564
5565   clib_memset (mac_address, 0, sizeof (mac_address));
5566
5567   /* Parse args required to build the message */
5568   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5569     {
5570       if (unformat (i, "hw-addr %U", unformat_ethernet_address, mac_address))
5571         {
5572           random_mac = 0;
5573         }
5574       else if (unformat (i, "pci-addr %U", unformat_vlib_pci_addr, &pci_addr))
5575         ;
5576       else if (unformat (i, "features 0x%llx", &features))
5577         ;
5578       else if (unformat (i, "gso-enabled"))
5579         virtio_flags |= VIRTIO_API_FLAG_GSO;
5580       else if (unformat (i, "csum-offload-enabled"))
5581         virtio_flags |= VIRTIO_API_FLAG_CSUM_OFFLOAD;
5582       else if (unformat (i, "gro-coalesce"))
5583         virtio_flags |= VIRTIO_API_FLAG_GRO_COALESCE;
5584       else if (unformat (i, "packed"))
5585         virtio_flags |= VIRTIO_API_FLAG_PACKED;
5586       else if (unformat (i, "in-order"))
5587         virtio_flags |= VIRTIO_API_FLAG_IN_ORDER;
5588       else if (unformat (i, "buffering"))
5589         virtio_flags |= VIRTIO_API_FLAG_BUFFERING;
5590       else
5591         break;
5592     }
5593
5594   if (pci_addr == 0)
5595     {
5596       errmsg ("pci address must be non zero. ");
5597       return -99;
5598     }
5599
5600   /* Construct the API message */
5601   M (VIRTIO_PCI_CREATE_V2, mp);
5602
5603   mp->use_random_mac = random_mac;
5604
5605   mp->pci_addr.domain = htons (((vlib_pci_addr_t) pci_addr).domain);
5606   mp->pci_addr.bus = ((vlib_pci_addr_t) pci_addr).bus;
5607   mp->pci_addr.slot = ((vlib_pci_addr_t) pci_addr).slot;
5608   mp->pci_addr.function = ((vlib_pci_addr_t) pci_addr).function;
5609
5610   mp->features = clib_host_to_net_u64 (features);
5611   mp->virtio_flags = clib_host_to_net_u32 (virtio_flags);
5612
5613   if (random_mac == 0)
5614     clib_memcpy (mp->mac_address, mac_address, 6);
5615
5616   /* send it... */
5617   S (mp);
5618
5619   /* Wait for a reply... */
5620   W (ret);
5621   return ret;
5622 }
5623
5624 static int
5625 api_virtio_pci_delete (vat_main_t * vam)
5626 {
5627   unformat_input_t *i = vam->input;
5628   vl_api_virtio_pci_delete_t *mp;
5629   u32 sw_if_index = ~0;
5630   u8 sw_if_index_set = 0;
5631   int ret;
5632
5633   /* Parse args required to build the message */
5634   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5635     {
5636       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5637         sw_if_index_set = 1;
5638       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5639         sw_if_index_set = 1;
5640       else
5641         break;
5642     }
5643
5644   if (sw_if_index_set == 0)
5645     {
5646       errmsg ("missing vpp interface name. ");
5647       return -99;
5648     }
5649
5650   /* Construct the API message */
5651   M (VIRTIO_PCI_DELETE, mp);
5652
5653   mp->sw_if_index = htonl (sw_if_index);
5654
5655   /* send it... */
5656   S (mp);
5657
5658   /* Wait for a reply... */
5659   W (ret);
5660   return ret;
5661 }
5662
5663 static int
5664 api_bond_create (vat_main_t * vam)
5665 {
5666   unformat_input_t *i = vam->input;
5667   vl_api_bond_create_t *mp;
5668   u8 mac_address[6];
5669   u8 custom_mac = 0;
5670   int ret;
5671   u8 mode;
5672   u8 lb;
5673   u8 mode_is_set = 0;
5674   u32 id = ~0;
5675   u8 numa_only = 0;
5676
5677   clib_memset (mac_address, 0, sizeof (mac_address));
5678   lb = BOND_LB_L2;
5679
5680   /* Parse args required to build the message */
5681   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5682     {
5683       if (unformat (i, "mode %U", unformat_bond_mode, &mode))
5684         mode_is_set = 1;
5685       else if (((mode == BOND_MODE_LACP) || (mode == BOND_MODE_XOR))
5686                && unformat (i, "lb %U", unformat_bond_load_balance, &lb))
5687         ;
5688       else if (unformat (i, "hw-addr %U", unformat_ethernet_address,
5689                          mac_address))
5690         custom_mac = 1;
5691       else if (unformat (i, "numa-only"))
5692         numa_only = 1;
5693       else if (unformat (i, "id %u", &id))
5694         ;
5695       else
5696         break;
5697     }
5698
5699   if (mode_is_set == 0)
5700     {
5701       errmsg ("Missing bond mode. ");
5702       return -99;
5703     }
5704
5705   /* Construct the API message */
5706   M (BOND_CREATE, mp);
5707
5708   mp->use_custom_mac = custom_mac;
5709
5710   mp->mode = htonl (mode);
5711   mp->lb = htonl (lb);
5712   mp->id = htonl (id);
5713   mp->numa_only = numa_only;
5714
5715   if (custom_mac)
5716     clib_memcpy (mp->mac_address, mac_address, 6);
5717
5718   /* send it... */
5719   S (mp);
5720
5721   /* Wait for a reply... */
5722   W (ret);
5723   return ret;
5724 }
5725
5726 static int
5727 api_bond_create2 (vat_main_t * vam)
5728 {
5729   unformat_input_t *i = vam->input;
5730   vl_api_bond_create2_t *mp;
5731   u8 mac_address[6];
5732   u8 custom_mac = 0;
5733   int ret;
5734   u8 mode;
5735   u8 lb;
5736   u8 mode_is_set = 0;
5737   u32 id = ~0;
5738   u8 numa_only = 0;
5739   u8 gso = 0;
5740
5741   clib_memset (mac_address, 0, sizeof (mac_address));
5742   lb = BOND_LB_L2;
5743
5744   /* Parse args required to build the message */
5745   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5746     {
5747       if (unformat (i, "mode %U", unformat_bond_mode, &mode))
5748         mode_is_set = 1;
5749       else if (((mode == BOND_MODE_LACP) || (mode == BOND_MODE_XOR))
5750                && unformat (i, "lb %U", unformat_bond_load_balance, &lb))
5751         ;
5752       else if (unformat (i, "hw-addr %U", unformat_ethernet_address,
5753                          mac_address))
5754         custom_mac = 1;
5755       else if (unformat (i, "numa-only"))
5756         numa_only = 1;
5757       else if (unformat (i, "gso"))
5758         gso = 1;
5759       else if (unformat (i, "id %u", &id))
5760         ;
5761       else
5762         break;
5763     }
5764
5765   if (mode_is_set == 0)
5766     {
5767       errmsg ("Missing bond mode. ");
5768       return -99;
5769     }
5770
5771   /* Construct the API message */
5772   M (BOND_CREATE2, mp);
5773
5774   mp->use_custom_mac = custom_mac;
5775
5776   mp->mode = htonl (mode);
5777   mp->lb = htonl (lb);
5778   mp->id = htonl (id);
5779   mp->numa_only = numa_only;
5780   mp->enable_gso = gso;
5781
5782   if (custom_mac)
5783     clib_memcpy (mp->mac_address, mac_address, 6);
5784
5785   /* send it... */
5786   S (mp);
5787
5788   /* Wait for a reply... */
5789   W (ret);
5790   return ret;
5791 }
5792
5793 static int
5794 api_bond_delete (vat_main_t * vam)
5795 {
5796   unformat_input_t *i = vam->input;
5797   vl_api_bond_delete_t *mp;
5798   u32 sw_if_index = ~0;
5799   u8 sw_if_index_set = 0;
5800   int ret;
5801
5802   /* Parse args required to build the message */
5803   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5804     {
5805       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5806         sw_if_index_set = 1;
5807       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5808         sw_if_index_set = 1;
5809       else
5810         break;
5811     }
5812
5813   if (sw_if_index_set == 0)
5814     {
5815       errmsg ("missing vpp interface name. ");
5816       return -99;
5817     }
5818
5819   /* Construct the API message */
5820   M (BOND_DELETE, mp);
5821
5822   mp->sw_if_index = ntohl (sw_if_index);
5823
5824   /* send it... */
5825   S (mp);
5826
5827   /* Wait for a reply... */
5828   W (ret);
5829   return ret;
5830 }
5831
5832 static int
5833 api_bond_add_member (vat_main_t * vam)
5834 {
5835   unformat_input_t *i = vam->input;
5836   vl_api_bond_add_member_t *mp;
5837   u32 bond_sw_if_index;
5838   int ret;
5839   u8 is_passive;
5840   u8 is_long_timeout;
5841   u32 bond_sw_if_index_is_set = 0;
5842   u32 sw_if_index;
5843   u8 sw_if_index_is_set = 0;
5844
5845   /* Parse args required to build the message */
5846   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5847     {
5848       if (unformat (i, "sw_if_index %d", &sw_if_index))
5849         sw_if_index_is_set = 1;
5850       else if (unformat (i, "bond %u", &bond_sw_if_index))
5851         bond_sw_if_index_is_set = 1;
5852       else if (unformat (i, "passive %d", &is_passive))
5853         ;
5854       else if (unformat (i, "long-timeout %d", &is_long_timeout))
5855         ;
5856       else
5857         break;
5858     }
5859
5860   if (bond_sw_if_index_is_set == 0)
5861     {
5862       errmsg ("Missing bond sw_if_index. ");
5863       return -99;
5864     }
5865   if (sw_if_index_is_set == 0)
5866     {
5867       errmsg ("Missing member sw_if_index. ");
5868       return -99;
5869     }
5870
5871   /* Construct the API message */
5872   M (BOND_ADD_MEMBER, mp);
5873
5874   mp->bond_sw_if_index = ntohl (bond_sw_if_index);
5875   mp->sw_if_index = ntohl (sw_if_index);
5876   mp->is_long_timeout = is_long_timeout;
5877   mp->is_passive = is_passive;
5878
5879   /* send it... */
5880   S (mp);
5881
5882   /* Wait for a reply... */
5883   W (ret);
5884   return ret;
5885 }
5886
5887 static int
5888 api_bond_detach_member (vat_main_t * vam)
5889 {
5890   unformat_input_t *i = vam->input;
5891   vl_api_bond_detach_member_t *mp;
5892   u32 sw_if_index = ~0;
5893   u8 sw_if_index_set = 0;
5894   int ret;
5895
5896   /* Parse args required to build the message */
5897   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5898     {
5899       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5900         sw_if_index_set = 1;
5901       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5902         sw_if_index_set = 1;
5903       else
5904         break;
5905     }
5906
5907   if (sw_if_index_set == 0)
5908     {
5909       errmsg ("missing vpp interface name. ");
5910       return -99;
5911     }
5912
5913   /* Construct the API message */
5914   M (BOND_DETACH_MEMBER, mp);
5915
5916   mp->sw_if_index = ntohl (sw_if_index);
5917
5918   /* send it... */
5919   S (mp);
5920
5921   /* Wait for a reply... */
5922   W (ret);
5923   return ret;
5924 }
5925
5926 static int
5927 api_ip_table_add_del (vat_main_t * vam)
5928 {
5929   unformat_input_t *i = vam->input;
5930   vl_api_ip_table_add_del_t *mp;
5931   u32 table_id = ~0;
5932   u8 is_ipv6 = 0;
5933   u8 is_add = 1;
5934   int ret = 0;
5935
5936   /* Parse args required to build the message */
5937   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5938     {
5939       if (unformat (i, "ipv6"))
5940         is_ipv6 = 1;
5941       else if (unformat (i, "del"))
5942         is_add = 0;
5943       else if (unformat (i, "add"))
5944         is_add = 1;
5945       else if (unformat (i, "table %d", &table_id))
5946         ;
5947       else
5948         {
5949           clib_warning ("parse error '%U'", format_unformat_error, i);
5950           return -99;
5951         }
5952     }
5953
5954   if (~0 == table_id)
5955     {
5956       errmsg ("missing table-ID");
5957       return -99;
5958     }
5959
5960   /* Construct the API message */
5961   M (IP_TABLE_ADD_DEL, mp);
5962
5963   mp->table.table_id = ntohl (table_id);
5964   mp->table.is_ip6 = is_ipv6;
5965   mp->is_add = is_add;
5966
5967   /* send it... */
5968   S (mp);
5969
5970   /* Wait for a reply... */
5971   W (ret);
5972
5973   return ret;
5974 }
5975
5976 uword
5977 unformat_fib_path (unformat_input_t * input, va_list * args)
5978 {
5979   vat_main_t *vam = va_arg (*args, vat_main_t *);
5980   vl_api_fib_path_t *path = va_arg (*args, vl_api_fib_path_t *);
5981   u32 weight, preference;
5982   mpls_label_t out_label;
5983
5984   clib_memset (path, 0, sizeof (*path));
5985   path->weight = 1;
5986   path->sw_if_index = ~0;
5987   path->rpf_id = ~0;
5988   path->n_labels = 0;
5989
5990   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
5991     {
5992       if (unformat (input, "%U %U",
5993                     unformat_vl_api_ip4_address,
5994                     &path->nh.address.ip4,
5995                     api_unformat_sw_if_index, vam, &path->sw_if_index))
5996         {
5997           path->proto = FIB_API_PATH_NH_PROTO_IP4;
5998         }
5999       else if (unformat (input, "%U %U",
6000                          unformat_vl_api_ip6_address,
6001                          &path->nh.address.ip6,
6002                          api_unformat_sw_if_index, vam, &path->sw_if_index))
6003         {
6004           path->proto = FIB_API_PATH_NH_PROTO_IP6;
6005         }
6006       else if (unformat (input, "weight %u", &weight))
6007         {
6008           path->weight = weight;
6009         }
6010       else if (unformat (input, "preference %u", &preference))
6011         {
6012           path->preference = preference;
6013         }
6014       else if (unformat (input, "%U next-hop-table %d",
6015                          unformat_vl_api_ip4_address,
6016                          &path->nh.address.ip4, &path->table_id))
6017         {
6018           path->proto = FIB_API_PATH_NH_PROTO_IP4;
6019         }
6020       else if (unformat (input, "%U next-hop-table %d",
6021                          unformat_vl_api_ip6_address,
6022                          &path->nh.address.ip6, &path->table_id))
6023         {
6024           path->proto = FIB_API_PATH_NH_PROTO_IP6;
6025         }
6026       else if (unformat (input, "%U",
6027                          unformat_vl_api_ip4_address, &path->nh.address.ip4))
6028         {
6029           /*
6030            * the recursive next-hops are by default in the default table
6031            */
6032           path->table_id = 0;
6033           path->sw_if_index = ~0;
6034           path->proto = FIB_API_PATH_NH_PROTO_IP4;
6035         }
6036       else if (unformat (input, "%U",
6037                          unformat_vl_api_ip6_address, &path->nh.address.ip6))
6038         {
6039           /*
6040            * the recursive next-hops are by default in the default table
6041            */
6042           path->table_id = 0;
6043           path->sw_if_index = ~0;
6044           path->proto = FIB_API_PATH_NH_PROTO_IP6;
6045         }
6046       else if (unformat (input, "resolve-via-host"))
6047         {
6048           path->flags |= FIB_API_PATH_FLAG_RESOLVE_VIA_HOST;
6049         }
6050       else if (unformat (input, "resolve-via-attached"))
6051         {
6052           path->flags |= FIB_API_PATH_FLAG_RESOLVE_VIA_ATTACHED;
6053         }
6054       else if (unformat (input, "ip4-lookup-in-table %d", &path->table_id))
6055         {
6056           path->type = FIB_API_PATH_TYPE_LOCAL;
6057           path->sw_if_index = ~0;
6058           path->proto = FIB_API_PATH_NH_PROTO_IP4;
6059         }
6060       else if (unformat (input, "ip6-lookup-in-table %d", &path->table_id))
6061         {
6062           path->type = FIB_API_PATH_TYPE_LOCAL;
6063           path->sw_if_index = ~0;
6064           path->proto = FIB_API_PATH_NH_PROTO_IP6;
6065         }
6066       else if (unformat (input, "sw_if_index %d", &path->sw_if_index))
6067         ;
6068       else if (unformat (input, "via-label %d", &path->nh.via_label))
6069         {
6070           path->proto = FIB_API_PATH_NH_PROTO_MPLS;
6071           path->sw_if_index = ~0;
6072         }
6073       else if (unformat (input, "l2-input-on %d", &path->sw_if_index))
6074         {
6075           path->proto = FIB_API_PATH_NH_PROTO_ETHERNET;
6076           path->type = FIB_API_PATH_TYPE_INTERFACE_RX;
6077         }
6078       else if (unformat (input, "local"))
6079         {
6080           path->type = FIB_API_PATH_TYPE_LOCAL;
6081         }
6082       else if (unformat (input, "out-labels"))
6083         {
6084           while (unformat (input, "%d", &out_label))
6085             {
6086               path->label_stack[path->n_labels].label = out_label;
6087               path->label_stack[path->n_labels].is_uniform = 0;
6088               path->label_stack[path->n_labels].ttl = 64;
6089               path->n_labels++;
6090             }
6091         }
6092       else if (unformat (input, "via"))
6093         {
6094           /* new path, back up and return */
6095           unformat_put_input (input);
6096           unformat_put_input (input);
6097           unformat_put_input (input);
6098           unformat_put_input (input);
6099           break;
6100         }
6101       else
6102         {
6103           return (0);
6104         }
6105     }
6106
6107   path->proto = ntohl (path->proto);
6108   path->type = ntohl (path->type);
6109   path->flags = ntohl (path->flags);
6110   path->table_id = ntohl (path->table_id);
6111   path->sw_if_index = ntohl (path->sw_if_index);
6112
6113   return (1);
6114 }
6115
6116 static int
6117 api_ip_route_add_del (vat_main_t * vam)
6118 {
6119   unformat_input_t *i = vam->input;
6120   vl_api_ip_route_add_del_t *mp;
6121   u32 vrf_id = 0;
6122   u8 is_add = 1;
6123   u8 is_multipath = 0;
6124   u8 prefix_set = 0;
6125   u8 path_count = 0;
6126   vl_api_prefix_t pfx = { };
6127   vl_api_fib_path_t paths[8];
6128   int count = 1;
6129   int j;
6130   f64 before = 0;
6131   u32 random_add_del = 0;
6132   u32 *random_vector = 0;
6133   u32 random_seed = 0xdeaddabe;
6134
6135   /* Parse args required to build the message */
6136   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6137     {
6138       if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
6139         prefix_set = 1;
6140       else if (unformat (i, "del"))
6141         is_add = 0;
6142       else if (unformat (i, "add"))
6143         is_add = 1;
6144       else if (unformat (i, "vrf %d", &vrf_id))
6145         ;
6146       else if (unformat (i, "count %d", &count))
6147         ;
6148       else if (unformat (i, "random"))
6149         random_add_del = 1;
6150       else if (unformat (i, "multipath"))
6151         is_multipath = 1;
6152       else if (unformat (i, "seed %d", &random_seed))
6153         ;
6154       else
6155         if (unformat
6156             (i, "via %U", unformat_fib_path, vam, &paths[path_count]))
6157         {
6158           path_count++;
6159           if (8 == path_count)
6160             {
6161               errmsg ("max 8 paths");
6162               return -99;
6163             }
6164         }
6165       else
6166         {
6167           clib_warning ("parse error '%U'", format_unformat_error, i);
6168           return -99;
6169         }
6170     }
6171
6172   if (!path_count)
6173     {
6174       errmsg ("specify a path; via ...");
6175       return -99;
6176     }
6177   if (prefix_set == 0)
6178     {
6179       errmsg ("missing prefix");
6180       return -99;
6181     }
6182
6183   /* Generate a pile of unique, random routes */
6184   if (random_add_del)
6185     {
6186       ip4_address_t *i = (ip4_address_t *) & paths[0].nh.address.ip4;
6187       u32 this_random_address;
6188       uword *random_hash;
6189
6190       random_hash = hash_create (count, sizeof (uword));
6191
6192       hash_set (random_hash, i->as_u32, 1);
6193       for (j = 0; j <= count; j++)
6194         {
6195           do
6196             {
6197               this_random_address = random_u32 (&random_seed);
6198               this_random_address =
6199                 clib_host_to_net_u32 (this_random_address);
6200             }
6201           while (hash_get (random_hash, this_random_address));
6202           vec_add1 (random_vector, this_random_address);
6203           hash_set (random_hash, this_random_address, 1);
6204         }
6205       hash_free (random_hash);
6206       set_ip4_address (&pfx.address, random_vector[0]);
6207     }
6208
6209   if (count > 1)
6210     {
6211       /* Turn on async mode */
6212       vam->async_mode = 1;
6213       vam->async_errors = 0;
6214       before = vat_time_now (vam);
6215     }
6216
6217   for (j = 0; j < count; j++)
6218     {
6219       /* Construct the API message */
6220       M2 (IP_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t) * path_count);
6221
6222       mp->is_add = is_add;
6223       mp->is_multipath = is_multipath;
6224
6225       clib_memcpy (&mp->route.prefix, &pfx, sizeof (pfx));
6226       mp->route.table_id = ntohl (vrf_id);
6227       mp->route.n_paths = path_count;
6228
6229       clib_memcpy (&mp->route.paths, &paths, sizeof (paths[0]) * path_count);
6230
6231       if (random_add_del)
6232         set_ip4_address (&pfx.address, random_vector[j + 1]);
6233       else
6234         increment_address (&pfx.address);
6235       /* send it... */
6236       S (mp);
6237       /* If we receive SIGTERM, stop now... */
6238       if (vam->do_exit)
6239         break;
6240     }
6241
6242   /* When testing multiple add/del ops, use a control-ping to sync */
6243   if (count > 1)
6244     {
6245       vl_api_control_ping_t *mp_ping;
6246       f64 after;
6247       f64 timeout;
6248
6249       /* Shut off async mode */
6250       vam->async_mode = 0;
6251
6252       MPING (CONTROL_PING, mp_ping);
6253       S (mp_ping);
6254
6255       timeout = vat_time_now (vam) + 1.0;
6256       while (vat_time_now (vam) < timeout)
6257         if (vam->result_ready == 1)
6258           goto out;
6259       vam->retval = -99;
6260
6261     out:
6262       if (vam->retval == -99)
6263         errmsg ("timeout");
6264
6265       if (vam->async_errors > 0)
6266         {
6267           errmsg ("%d asynchronous errors", vam->async_errors);
6268           vam->retval = -98;
6269         }
6270       vam->async_errors = 0;
6271       after = vat_time_now (vam);
6272
6273       /* slim chance, but we might have eaten SIGTERM on the first iteration */
6274       if (j > 0)
6275         count = j;
6276
6277       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
6278              count, after - before, count / (after - before));
6279     }
6280   else
6281     {
6282       int ret;
6283
6284       /* Wait for a reply... */
6285       W (ret);
6286       return ret;
6287     }
6288
6289   /* Return the good/bad news */
6290   return (vam->retval);
6291 }
6292
6293 static int
6294 api_ip_mroute_add_del (vat_main_t * vam)
6295 {
6296   unformat_input_t *i = vam->input;
6297   u8 path_set = 0, prefix_set = 0, is_add = 1;
6298   vl_api_ip_mroute_add_del_t *mp;
6299   mfib_entry_flags_t eflags = 0;
6300   vl_api_mfib_path_t path;
6301   vl_api_mprefix_t pfx = { };
6302   u32 vrf_id = 0;
6303   int ret;
6304
6305   /* Parse args required to build the message */
6306   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6307     {
6308       if (unformat (i, "%U", unformat_vl_api_mprefix, &pfx))
6309         {
6310           prefix_set = 1;
6311           pfx.grp_address_length = htons (pfx.grp_address_length);
6312         }
6313       else if (unformat (i, "del"))
6314         is_add = 0;
6315       else if (unformat (i, "add"))
6316         is_add = 1;
6317       else if (unformat (i, "vrf %d", &vrf_id))
6318         ;
6319       else if (unformat (i, "%U", unformat_mfib_itf_flags, &path.itf_flags))
6320         path.itf_flags = htonl (path.itf_flags);
6321       else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
6322         ;
6323       else if (unformat (i, "via %U", unformat_fib_path, vam, &path.path))
6324         path_set = 1;
6325       else
6326         {
6327           clib_warning ("parse error '%U'", format_unformat_error, i);
6328           return -99;
6329         }
6330     }
6331
6332   if (prefix_set == 0)
6333     {
6334       errmsg ("missing addresses\n");
6335       return -99;
6336     }
6337   if (path_set == 0)
6338     {
6339       errmsg ("missing path\n");
6340       return -99;
6341     }
6342
6343   /* Construct the API message */
6344   M (IP_MROUTE_ADD_DEL, mp);
6345
6346   mp->is_add = is_add;
6347   mp->is_multipath = 1;
6348
6349   clib_memcpy (&mp->route.prefix, &pfx, sizeof (pfx));
6350   mp->route.table_id = htonl (vrf_id);
6351   mp->route.n_paths = 1;
6352   mp->route.entry_flags = htonl (eflags);
6353
6354   clib_memcpy (&mp->route.paths, &path, sizeof (path));
6355
6356   /* send it... */
6357   S (mp);
6358   /* Wait for a reply... */
6359   W (ret);
6360   return ret;
6361 }
6362
6363 static int
6364 api_mpls_table_add_del (vat_main_t * vam)
6365 {
6366   unformat_input_t *i = vam->input;
6367   vl_api_mpls_table_add_del_t *mp;
6368   u32 table_id = ~0;
6369   u8 is_add = 1;
6370   int ret = 0;
6371
6372   /* Parse args required to build the message */
6373   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6374     {
6375       if (unformat (i, "table %d", &table_id))
6376         ;
6377       else if (unformat (i, "del"))
6378         is_add = 0;
6379       else if (unformat (i, "add"))
6380         is_add = 1;
6381       else
6382         {
6383           clib_warning ("parse error '%U'", format_unformat_error, i);
6384           return -99;
6385         }
6386     }
6387
6388   if (~0 == table_id)
6389     {
6390       errmsg ("missing table-ID");
6391       return -99;
6392     }
6393
6394   /* Construct the API message */
6395   M (MPLS_TABLE_ADD_DEL, mp);
6396
6397   mp->mt_table.mt_table_id = ntohl (table_id);
6398   mp->mt_is_add = is_add;
6399
6400   /* send it... */
6401   S (mp);
6402
6403   /* Wait for a reply... */
6404   W (ret);
6405
6406   return ret;
6407 }
6408
6409 static int
6410 api_mpls_route_add_del (vat_main_t * vam)
6411 {
6412   u8 is_add = 1, path_count = 0, is_multipath = 0, is_eos = 0;
6413   mpls_label_t local_label = MPLS_LABEL_INVALID;
6414   unformat_input_t *i = vam->input;
6415   vl_api_mpls_route_add_del_t *mp;
6416   vl_api_fib_path_t paths[8];
6417   int count = 1, j;
6418   f64 before = 0;
6419
6420   /* Parse args required to build the message */
6421   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6422     {
6423       if (unformat (i, "%d", &local_label))
6424         ;
6425       else if (unformat (i, "eos"))
6426         is_eos = 1;
6427       else if (unformat (i, "non-eos"))
6428         is_eos = 0;
6429       else if (unformat (i, "del"))
6430         is_add = 0;
6431       else if (unformat (i, "add"))
6432         is_add = 1;
6433       else if (unformat (i, "multipath"))
6434         is_multipath = 1;
6435       else if (unformat (i, "count %d", &count))
6436         ;
6437       else
6438         if (unformat
6439             (i, "via %U", unformat_fib_path, vam, &paths[path_count]))
6440         {
6441           path_count++;
6442           if (8 == path_count)
6443             {
6444               errmsg ("max 8 paths");
6445               return -99;
6446             }
6447         }
6448       else
6449         {
6450           clib_warning ("parse error '%U'", format_unformat_error, i);
6451           return -99;
6452         }
6453     }
6454
6455   if (!path_count)
6456     {
6457       errmsg ("specify a path; via ...");
6458       return -99;
6459     }
6460
6461   if (MPLS_LABEL_INVALID == local_label)
6462     {
6463       errmsg ("missing label");
6464       return -99;
6465     }
6466
6467   if (count > 1)
6468     {
6469       /* Turn on async mode */
6470       vam->async_mode = 1;
6471       vam->async_errors = 0;
6472       before = vat_time_now (vam);
6473     }
6474
6475   for (j = 0; j < count; j++)
6476     {
6477       /* Construct the API message */
6478       M2 (MPLS_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t) * path_count);
6479
6480       mp->mr_is_add = is_add;
6481       mp->mr_is_multipath = is_multipath;
6482
6483       mp->mr_route.mr_label = local_label;
6484       mp->mr_route.mr_eos = is_eos;
6485       mp->mr_route.mr_table_id = 0;
6486       mp->mr_route.mr_n_paths = path_count;
6487
6488       clib_memcpy (&mp->mr_route.mr_paths, paths,
6489                    sizeof (paths[0]) * path_count);
6490
6491       local_label++;
6492
6493       /* send it... */
6494       S (mp);
6495       /* If we receive SIGTERM, stop now... */
6496       if (vam->do_exit)
6497         break;
6498     }
6499
6500   /* When testing multiple add/del ops, use a control-ping to sync */
6501   if (count > 1)
6502     {
6503       vl_api_control_ping_t *mp_ping;
6504       f64 after;
6505       f64 timeout;
6506
6507       /* Shut off async mode */
6508       vam->async_mode = 0;
6509
6510       MPING (CONTROL_PING, mp_ping);
6511       S (mp_ping);
6512
6513       timeout = vat_time_now (vam) + 1.0;
6514       while (vat_time_now (vam) < timeout)
6515         if (vam->result_ready == 1)
6516           goto out;
6517       vam->retval = -99;
6518
6519     out:
6520       if (vam->retval == -99)
6521         errmsg ("timeout");
6522
6523       if (vam->async_errors > 0)
6524         {
6525           errmsg ("%d asynchronous errors", vam->async_errors);
6526           vam->retval = -98;
6527         }
6528       vam->async_errors = 0;
6529       after = vat_time_now (vam);
6530
6531       /* slim chance, but we might have eaten SIGTERM on the first iteration */
6532       if (j > 0)
6533         count = j;
6534
6535       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
6536              count, after - before, count / (after - before));
6537     }
6538   else
6539     {
6540       int ret;
6541
6542       /* Wait for a reply... */
6543       W (ret);
6544       return ret;
6545     }
6546
6547   /* Return the good/bad news */
6548   return (vam->retval);
6549   return (0);
6550 }
6551
6552 static int
6553 api_mpls_ip_bind_unbind (vat_main_t * vam)
6554 {
6555   unformat_input_t *i = vam->input;
6556   vl_api_mpls_ip_bind_unbind_t *mp;
6557   u32 ip_table_id = 0;
6558   u8 is_bind = 1;
6559   vl_api_prefix_t pfx;
6560   u8 prefix_set = 0;
6561   mpls_label_t local_label = MPLS_LABEL_INVALID;
6562   int ret;
6563
6564   /* Parse args required to build the message */
6565   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6566     {
6567       if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
6568         prefix_set = 1;
6569       else if (unformat (i, "%d", &local_label))
6570         ;
6571       else if (unformat (i, "table-id %d", &ip_table_id))
6572         ;
6573       else if (unformat (i, "unbind"))
6574         is_bind = 0;
6575       else if (unformat (i, "bind"))
6576         is_bind = 1;
6577       else
6578         {
6579           clib_warning ("parse error '%U'", format_unformat_error, i);
6580           return -99;
6581         }
6582     }
6583
6584   if (!prefix_set)
6585     {
6586       errmsg ("IP prefix not set");
6587       return -99;
6588     }
6589
6590   if (MPLS_LABEL_INVALID == local_label)
6591     {
6592       errmsg ("missing label");
6593       return -99;
6594     }
6595
6596   /* Construct the API message */
6597   M (MPLS_IP_BIND_UNBIND, mp);
6598
6599   mp->mb_is_bind = is_bind;
6600   mp->mb_ip_table_id = ntohl (ip_table_id);
6601   mp->mb_mpls_table_id = 0;
6602   mp->mb_label = ntohl (local_label);
6603   clib_memcpy (&mp->mb_prefix, &pfx, sizeof (pfx));
6604
6605   /* send it... */
6606   S (mp);
6607
6608   /* Wait for a reply... */
6609   W (ret);
6610   return ret;
6611   return (0);
6612 }
6613
6614 static int
6615 api_sr_mpls_policy_add (vat_main_t * vam)
6616 {
6617   unformat_input_t *i = vam->input;
6618   vl_api_sr_mpls_policy_add_t *mp;
6619   u32 bsid = 0;
6620   u32 weight = 1;
6621   u8 type = 0;
6622   u8 n_segments = 0;
6623   u32 sid;
6624   u32 *segments = NULL;
6625   int ret;
6626
6627   /* Parse args required to build the message */
6628   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6629     {
6630       if (unformat (i, "bsid %d", &bsid))
6631         ;
6632       else if (unformat (i, "weight %d", &weight))
6633         ;
6634       else if (unformat (i, "spray"))
6635         type = 1;
6636       else if (unformat (i, "next %d", &sid))
6637         {
6638           n_segments += 1;
6639           vec_add1 (segments, htonl (sid));
6640         }
6641       else
6642         {
6643           clib_warning ("parse error '%U'", format_unformat_error, i);
6644           return -99;
6645         }
6646     }
6647
6648   if (bsid == 0)
6649     {
6650       errmsg ("bsid not set");
6651       return -99;
6652     }
6653
6654   if (n_segments == 0)
6655     {
6656       errmsg ("no sid in segment stack");
6657       return -99;
6658     }
6659
6660   /* Construct the API message */
6661   M2 (SR_MPLS_POLICY_ADD, mp, sizeof (u32) * n_segments);
6662
6663   mp->bsid = htonl (bsid);
6664   mp->weight = htonl (weight);
6665   mp->is_spray = type;
6666   mp->n_segments = n_segments;
6667   memcpy (mp->segments, segments, sizeof (u32) * n_segments);
6668   vec_free (segments);
6669
6670   /* send it... */
6671   S (mp);
6672
6673   /* Wait for a reply... */
6674   W (ret);
6675   return ret;
6676 }
6677
6678 static int
6679 api_sr_mpls_policy_del (vat_main_t * vam)
6680 {
6681   unformat_input_t *i = vam->input;
6682   vl_api_sr_mpls_policy_del_t *mp;
6683   u32 bsid = 0;
6684   int ret;
6685
6686   /* Parse args required to build the message */
6687   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6688     {
6689       if (unformat (i, "bsid %d", &bsid))
6690         ;
6691       else
6692         {
6693           clib_warning ("parse error '%U'", format_unformat_error, i);
6694           return -99;
6695         }
6696     }
6697
6698   if (bsid == 0)
6699     {
6700       errmsg ("bsid not set");
6701       return -99;
6702     }
6703
6704   /* Construct the API message */
6705   M (SR_MPLS_POLICY_DEL, mp);
6706
6707   mp->bsid = htonl (bsid);
6708
6709   /* send it... */
6710   S (mp);
6711
6712   /* Wait for a reply... */
6713   W (ret);
6714   return ret;
6715 }
6716
6717 static int
6718 api_bier_table_add_del (vat_main_t * vam)
6719 {
6720   unformat_input_t *i = vam->input;
6721   vl_api_bier_table_add_del_t *mp;
6722   u8 is_add = 1;
6723   u32 set = 0, sub_domain = 0, hdr_len = 3;
6724   mpls_label_t local_label = MPLS_LABEL_INVALID;
6725   int ret;
6726
6727   /* Parse args required to build the message */
6728   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6729     {
6730       if (unformat (i, "sub-domain %d", &sub_domain))
6731         ;
6732       else if (unformat (i, "set %d", &set))
6733         ;
6734       else if (unformat (i, "label %d", &local_label))
6735         ;
6736       else if (unformat (i, "hdr-len %d", &hdr_len))
6737         ;
6738       else if (unformat (i, "add"))
6739         is_add = 1;
6740       else if (unformat (i, "del"))
6741         is_add = 0;
6742       else
6743         {
6744           clib_warning ("parse error '%U'", format_unformat_error, i);
6745           return -99;
6746         }
6747     }
6748
6749   if (MPLS_LABEL_INVALID == local_label)
6750     {
6751       errmsg ("missing label\n");
6752       return -99;
6753     }
6754
6755   /* Construct the API message */
6756   M (BIER_TABLE_ADD_DEL, mp);
6757
6758   mp->bt_is_add = is_add;
6759   mp->bt_label = ntohl (local_label);
6760   mp->bt_tbl_id.bt_set = set;
6761   mp->bt_tbl_id.bt_sub_domain = sub_domain;
6762   mp->bt_tbl_id.bt_hdr_len_id = hdr_len;
6763
6764   /* send it... */
6765   S (mp);
6766
6767   /* Wait for a reply... */
6768   W (ret);
6769
6770   return (ret);
6771 }
6772
6773 static int
6774 api_bier_route_add_del (vat_main_t * vam)
6775 {
6776   unformat_input_t *i = vam->input;
6777   vl_api_bier_route_add_del_t *mp;
6778   u8 is_add = 1;
6779   u32 set = 0, sub_domain = 0, hdr_len = 3, bp = 0;
6780   ip4_address_t v4_next_hop_address;
6781   ip6_address_t v6_next_hop_address;
6782   u8 next_hop_set = 0;
6783   u8 next_hop_proto_is_ip4 = 1;
6784   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
6785   int ret;
6786
6787   /* Parse args required to build the message */
6788   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6789     {
6790       if (unformat (i, "%U", unformat_ip4_address, &v4_next_hop_address))
6791         {
6792           next_hop_proto_is_ip4 = 1;
6793           next_hop_set = 1;
6794         }
6795       else if (unformat (i, "%U", unformat_ip6_address, &v6_next_hop_address))
6796         {
6797           next_hop_proto_is_ip4 = 0;
6798           next_hop_set = 1;
6799         }
6800       if (unformat (i, "sub-domain %d", &sub_domain))
6801         ;
6802       else if (unformat (i, "set %d", &set))
6803         ;
6804       else if (unformat (i, "hdr-len %d", &hdr_len))
6805         ;
6806       else if (unformat (i, "bp %d", &bp))
6807         ;
6808       else if (unformat (i, "add"))
6809         is_add = 1;
6810       else if (unformat (i, "del"))
6811         is_add = 0;
6812       else if (unformat (i, "out-label %d", &next_hop_out_label))
6813         ;
6814       else
6815         {
6816           clib_warning ("parse error '%U'", format_unformat_error, i);
6817           return -99;
6818         }
6819     }
6820
6821   if (!next_hop_set || (MPLS_LABEL_INVALID == next_hop_out_label))
6822     {
6823       errmsg ("next hop / label set\n");
6824       return -99;
6825     }
6826   if (0 == bp)
6827     {
6828       errmsg ("bit=position not set\n");
6829       return -99;
6830     }
6831
6832   /* Construct the API message */
6833   M2 (BIER_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t));
6834
6835   mp->br_is_add = is_add;
6836   mp->br_route.br_tbl_id.bt_set = set;
6837   mp->br_route.br_tbl_id.bt_sub_domain = sub_domain;
6838   mp->br_route.br_tbl_id.bt_hdr_len_id = hdr_len;
6839   mp->br_route.br_bp = ntohs (bp);
6840   mp->br_route.br_n_paths = 1;
6841   mp->br_route.br_paths[0].n_labels = 1;
6842   mp->br_route.br_paths[0].label_stack[0].label = ntohl (next_hop_out_label);
6843   mp->br_route.br_paths[0].proto = (next_hop_proto_is_ip4 ?
6844                                     FIB_API_PATH_NH_PROTO_IP4 :
6845                                     FIB_API_PATH_NH_PROTO_IP6);
6846
6847   if (next_hop_proto_is_ip4)
6848     {
6849       clib_memcpy (&mp->br_route.br_paths[0].nh.address.ip4,
6850                    &v4_next_hop_address, sizeof (v4_next_hop_address));
6851     }
6852   else
6853     {
6854       clib_memcpy (&mp->br_route.br_paths[0].nh.address.ip6,
6855                    &v6_next_hop_address, sizeof (v6_next_hop_address));
6856     }
6857
6858   /* send it... */
6859   S (mp);
6860
6861   /* Wait for a reply... */
6862   W (ret);
6863
6864   return (ret);
6865 }
6866
6867 static int
6868 api_mpls_tunnel_add_del (vat_main_t * vam)
6869 {
6870   unformat_input_t *i = vam->input;
6871   vl_api_mpls_tunnel_add_del_t *mp;
6872
6873   vl_api_fib_path_t paths[8];
6874   u32 sw_if_index = ~0;
6875   u8 path_count = 0;
6876   u8 l2_only = 0;
6877   u8 is_add = 1;
6878   int ret;
6879
6880   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6881     {
6882       if (unformat (i, "add"))
6883         is_add = 1;
6884       else
6885         if (unformat
6886             (i, "del %U", api_unformat_sw_if_index, vam, &sw_if_index))
6887         is_add = 0;
6888       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
6889         is_add = 0;
6890       else if (unformat (i, "l2-only"))
6891         l2_only = 1;
6892       else
6893         if (unformat
6894             (i, "via %U", unformat_fib_path, vam, &paths[path_count]))
6895         {
6896           path_count++;
6897           if (8 == path_count)
6898             {
6899               errmsg ("max 8 paths");
6900               return -99;
6901             }
6902         }
6903       else
6904         {
6905           clib_warning ("parse error '%U'", format_unformat_error, i);
6906           return -99;
6907         }
6908     }
6909
6910   M2 (MPLS_TUNNEL_ADD_DEL, mp, sizeof (vl_api_fib_path_t) * path_count);
6911
6912   mp->mt_is_add = is_add;
6913   mp->mt_tunnel.mt_sw_if_index = ntohl (sw_if_index);
6914   mp->mt_tunnel.mt_l2_only = l2_only;
6915   mp->mt_tunnel.mt_is_multicast = 0;
6916   mp->mt_tunnel.mt_n_paths = path_count;
6917
6918   clib_memcpy (&mp->mt_tunnel.mt_paths, &paths,
6919                sizeof (paths[0]) * path_count);
6920
6921   S (mp);
6922   W (ret);
6923   return ret;
6924 }
6925
6926 static int
6927 api_sw_interface_set_unnumbered (vat_main_t * vam)
6928 {
6929   unformat_input_t *i = vam->input;
6930   vl_api_sw_interface_set_unnumbered_t *mp;
6931   u32 sw_if_index;
6932   u32 unnum_sw_index = ~0;
6933   u8 is_add = 1;
6934   u8 sw_if_index_set = 0;
6935   int ret;
6936
6937   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6938     {
6939       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6940         sw_if_index_set = 1;
6941       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6942         sw_if_index_set = 1;
6943       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
6944         ;
6945       else if (unformat (i, "del"))
6946         is_add = 0;
6947       else
6948         {
6949           clib_warning ("parse error '%U'", format_unformat_error, i);
6950           return -99;
6951         }
6952     }
6953
6954   if (sw_if_index_set == 0)
6955     {
6956       errmsg ("missing interface name or sw_if_index");
6957       return -99;
6958     }
6959
6960   M (SW_INTERFACE_SET_UNNUMBERED, mp);
6961
6962   mp->sw_if_index = ntohl (sw_if_index);
6963   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
6964   mp->is_add = is_add;
6965
6966   S (mp);
6967   W (ret);
6968   return ret;
6969 }
6970
6971
6972 static int
6973 api_create_vlan_subif (vat_main_t * vam)
6974 {
6975   unformat_input_t *i = vam->input;
6976   vl_api_create_vlan_subif_t *mp;
6977   u32 sw_if_index;
6978   u8 sw_if_index_set = 0;
6979   u32 vlan_id;
6980   u8 vlan_id_set = 0;
6981   int ret;
6982
6983   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6984     {
6985       if (unformat (i, "sw_if_index %d", &sw_if_index))
6986         sw_if_index_set = 1;
6987       else
6988         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6989         sw_if_index_set = 1;
6990       else if (unformat (i, "vlan %d", &vlan_id))
6991         vlan_id_set = 1;
6992       else
6993         {
6994           clib_warning ("parse error '%U'", format_unformat_error, i);
6995           return -99;
6996         }
6997     }
6998
6999   if (sw_if_index_set == 0)
7000     {
7001       errmsg ("missing interface name or sw_if_index");
7002       return -99;
7003     }
7004
7005   if (vlan_id_set == 0)
7006     {
7007       errmsg ("missing vlan_id");
7008       return -99;
7009     }
7010   M (CREATE_VLAN_SUBIF, mp);
7011
7012   mp->sw_if_index = ntohl (sw_if_index);
7013   mp->vlan_id = ntohl (vlan_id);
7014
7015   S (mp);
7016   W (ret);
7017   return ret;
7018 }
7019
7020 #define foreach_create_subif_bit                \
7021 _(no_tags)                                      \
7022 _(one_tag)                                      \
7023 _(two_tags)                                     \
7024 _(dot1ad)                                       \
7025 _(exact_match)                                  \
7026 _(default_sub)                                  \
7027 _(outer_vlan_id_any)                            \
7028 _(inner_vlan_id_any)
7029
7030 #define foreach_create_subif_flag               \
7031 _(0, "no_tags")                                 \
7032 _(1, "one_tag")                                 \
7033 _(2, "two_tags")                                \
7034 _(3, "dot1ad")                                  \
7035 _(4, "exact_match")                             \
7036 _(5, "default_sub")                             \
7037 _(6, "outer_vlan_id_any")                       \
7038 _(7, "inner_vlan_id_any")
7039
7040 static int
7041 api_create_subif (vat_main_t * vam)
7042 {
7043   unformat_input_t *i = vam->input;
7044   vl_api_create_subif_t *mp;
7045   u32 sw_if_index;
7046   u8 sw_if_index_set = 0;
7047   u32 sub_id;
7048   u8 sub_id_set = 0;
7049   u32 __attribute__ ((unused)) no_tags = 0;
7050   u32 __attribute__ ((unused)) one_tag = 0;
7051   u32 __attribute__ ((unused)) two_tags = 0;
7052   u32 __attribute__ ((unused)) dot1ad = 0;
7053   u32 __attribute__ ((unused)) exact_match = 0;
7054   u32 __attribute__ ((unused)) default_sub = 0;
7055   u32 __attribute__ ((unused)) outer_vlan_id_any = 0;
7056   u32 __attribute__ ((unused)) inner_vlan_id_any = 0;
7057   u32 tmp;
7058   u16 outer_vlan_id = 0;
7059   u16 inner_vlan_id = 0;
7060   int ret;
7061
7062   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7063     {
7064       if (unformat (i, "sw_if_index %d", &sw_if_index))
7065         sw_if_index_set = 1;
7066       else
7067         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7068         sw_if_index_set = 1;
7069       else if (unformat (i, "sub_id %d", &sub_id))
7070         sub_id_set = 1;
7071       else if (unformat (i, "outer_vlan_id %d", &tmp))
7072         outer_vlan_id = tmp;
7073       else if (unformat (i, "inner_vlan_id %d", &tmp))
7074         inner_vlan_id = tmp;
7075
7076 #define _(a) else if (unformat (i, #a)) a = 1 ;
7077       foreach_create_subif_bit
7078 #undef _
7079         else
7080         {
7081           clib_warning ("parse error '%U'", format_unformat_error, i);
7082           return -99;
7083         }
7084     }
7085
7086   if (sw_if_index_set == 0)
7087     {
7088       errmsg ("missing interface name or sw_if_index");
7089       return -99;
7090     }
7091
7092   if (sub_id_set == 0)
7093     {
7094       errmsg ("missing sub_id");
7095       return -99;
7096     }
7097   M (CREATE_SUBIF, mp);
7098
7099   mp->sw_if_index = ntohl (sw_if_index);
7100   mp->sub_id = ntohl (sub_id);
7101
7102 #define _(a,b) mp->sub_if_flags |= (1 << a);
7103   foreach_create_subif_flag;
7104 #undef _
7105
7106   mp->outer_vlan_id = ntohs (outer_vlan_id);
7107   mp->inner_vlan_id = ntohs (inner_vlan_id);
7108
7109   S (mp);
7110   W (ret);
7111   return ret;
7112 }
7113
7114 static int
7115 api_ip_table_replace_begin (vat_main_t * vam)
7116 {
7117   unformat_input_t *i = vam->input;
7118   vl_api_ip_table_replace_begin_t *mp;
7119   u32 table_id = 0;
7120   u8 is_ipv6 = 0;
7121
7122   int ret;
7123   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7124     {
7125       if (unformat (i, "table %d", &table_id))
7126         ;
7127       else if (unformat (i, "ipv6"))
7128         is_ipv6 = 1;
7129       else
7130         {
7131           clib_warning ("parse error '%U'", format_unformat_error, i);
7132           return -99;
7133         }
7134     }
7135
7136   M (IP_TABLE_REPLACE_BEGIN, mp);
7137
7138   mp->table.table_id = ntohl (table_id);
7139   mp->table.is_ip6 = is_ipv6;
7140
7141   S (mp);
7142   W (ret);
7143   return ret;
7144 }
7145
7146 static int
7147 api_ip_table_flush (vat_main_t * vam)
7148 {
7149   unformat_input_t *i = vam->input;
7150   vl_api_ip_table_flush_t *mp;
7151   u32 table_id = 0;
7152   u8 is_ipv6 = 0;
7153
7154   int ret;
7155   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7156     {
7157       if (unformat (i, "table %d", &table_id))
7158         ;
7159       else if (unformat (i, "ipv6"))
7160         is_ipv6 = 1;
7161       else
7162         {
7163           clib_warning ("parse error '%U'", format_unformat_error, i);
7164           return -99;
7165         }
7166     }
7167
7168   M (IP_TABLE_FLUSH, mp);
7169
7170   mp->table.table_id = ntohl (table_id);
7171   mp->table.is_ip6 = is_ipv6;
7172
7173   S (mp);
7174   W (ret);
7175   return ret;
7176 }
7177
7178 static int
7179 api_ip_table_replace_end (vat_main_t * vam)
7180 {
7181   unformat_input_t *i = vam->input;
7182   vl_api_ip_table_replace_end_t *mp;
7183   u32 table_id = 0;
7184   u8 is_ipv6 = 0;
7185
7186   int ret;
7187   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7188     {
7189       if (unformat (i, "table %d", &table_id))
7190         ;
7191       else if (unformat (i, "ipv6"))
7192         is_ipv6 = 1;
7193       else
7194         {
7195           clib_warning ("parse error '%U'", format_unformat_error, i);
7196           return -99;
7197         }
7198     }
7199
7200   M (IP_TABLE_REPLACE_END, mp);
7201
7202   mp->table.table_id = ntohl (table_id);
7203   mp->table.is_ip6 = is_ipv6;
7204
7205   S (mp);
7206   W (ret);
7207   return ret;
7208 }
7209
7210 static int
7211 api_set_ip_flow_hash (vat_main_t * vam)
7212 {
7213   unformat_input_t *i = vam->input;
7214   vl_api_set_ip_flow_hash_t *mp;
7215   u32 vrf_id = 0;
7216   u8 is_ipv6 = 0;
7217   u8 vrf_id_set = 0;
7218   u8 src = 0;
7219   u8 dst = 0;
7220   u8 sport = 0;
7221   u8 dport = 0;
7222   u8 proto = 0;
7223   u8 reverse = 0;
7224   int ret;
7225
7226   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7227     {
7228       if (unformat (i, "vrf %d", &vrf_id))
7229         vrf_id_set = 1;
7230       else if (unformat (i, "ipv6"))
7231         is_ipv6 = 1;
7232       else if (unformat (i, "src"))
7233         src = 1;
7234       else if (unformat (i, "dst"))
7235         dst = 1;
7236       else if (unformat (i, "sport"))
7237         sport = 1;
7238       else if (unformat (i, "dport"))
7239         dport = 1;
7240       else if (unformat (i, "proto"))
7241         proto = 1;
7242       else if (unformat (i, "reverse"))
7243         reverse = 1;
7244
7245       else
7246         {
7247           clib_warning ("parse error '%U'", format_unformat_error, i);
7248           return -99;
7249         }
7250     }
7251
7252   if (vrf_id_set == 0)
7253     {
7254       errmsg ("missing vrf id");
7255       return -99;
7256     }
7257
7258   M (SET_IP_FLOW_HASH, mp);
7259   mp->src = src;
7260   mp->dst = dst;
7261   mp->sport = sport;
7262   mp->dport = dport;
7263   mp->proto = proto;
7264   mp->reverse = reverse;
7265   mp->vrf_id = ntohl (vrf_id);
7266   mp->is_ipv6 = is_ipv6;
7267
7268   S (mp);
7269   W (ret);
7270   return ret;
7271 }
7272
7273 static int
7274 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
7275 {
7276   unformat_input_t *i = vam->input;
7277   vl_api_sw_interface_ip6_enable_disable_t *mp;
7278   u32 sw_if_index;
7279   u8 sw_if_index_set = 0;
7280   u8 enable = 0;
7281   int ret;
7282
7283   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7284     {
7285       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7286         sw_if_index_set = 1;
7287       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7288         sw_if_index_set = 1;
7289       else if (unformat (i, "enable"))
7290         enable = 1;
7291       else if (unformat (i, "disable"))
7292         enable = 0;
7293       else
7294         {
7295           clib_warning ("parse error '%U'", format_unformat_error, i);
7296           return -99;
7297         }
7298     }
7299
7300   if (sw_if_index_set == 0)
7301     {
7302       errmsg ("missing interface name or sw_if_index");
7303       return -99;
7304     }
7305
7306   M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
7307
7308   mp->sw_if_index = ntohl (sw_if_index);
7309   mp->enable = enable;
7310
7311   S (mp);
7312   W (ret);
7313   return ret;
7314 }
7315
7316
7317 static int
7318 api_l2_patch_add_del (vat_main_t * vam)
7319 {
7320   unformat_input_t *i = vam->input;
7321   vl_api_l2_patch_add_del_t *mp;
7322   u32 rx_sw_if_index;
7323   u8 rx_sw_if_index_set = 0;
7324   u32 tx_sw_if_index;
7325   u8 tx_sw_if_index_set = 0;
7326   u8 is_add = 1;
7327   int ret;
7328
7329   /* Parse args required to build the message */
7330   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7331     {
7332       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
7333         rx_sw_if_index_set = 1;
7334       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
7335         tx_sw_if_index_set = 1;
7336       else if (unformat (i, "rx"))
7337         {
7338           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7339             {
7340               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
7341                             &rx_sw_if_index))
7342                 rx_sw_if_index_set = 1;
7343             }
7344           else
7345             break;
7346         }
7347       else if (unformat (i, "tx"))
7348         {
7349           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7350             {
7351               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
7352                             &tx_sw_if_index))
7353                 tx_sw_if_index_set = 1;
7354             }
7355           else
7356             break;
7357         }
7358       else if (unformat (i, "del"))
7359         is_add = 0;
7360       else
7361         break;
7362     }
7363
7364   if (rx_sw_if_index_set == 0)
7365     {
7366       errmsg ("missing rx interface name or rx_sw_if_index");
7367       return -99;
7368     }
7369
7370   if (tx_sw_if_index_set == 0)
7371     {
7372       errmsg ("missing tx interface name or tx_sw_if_index");
7373       return -99;
7374     }
7375
7376   M (L2_PATCH_ADD_DEL, mp);
7377
7378   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
7379   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
7380   mp->is_add = is_add;
7381
7382   S (mp);
7383   W (ret);
7384   return ret;
7385 }
7386
7387 u8 is_del;
7388 u8 localsid_addr[16];
7389 u8 end_psp;
7390 u8 behavior;
7391 u32 sw_if_index;
7392 u32 vlan_index;
7393 u32 fib_table;
7394 u8 nh_addr[16];
7395
7396 static int
7397 api_sr_localsid_add_del (vat_main_t * vam)
7398 {
7399   unformat_input_t *i = vam->input;
7400   vl_api_sr_localsid_add_del_t *mp;
7401
7402   u8 is_del;
7403   ip6_address_t localsid;
7404   u8 end_psp = 0;
7405   u8 behavior = ~0;
7406   u32 sw_if_index;
7407   u32 fib_table = ~(u32) 0;
7408   ip46_address_t nh_addr;
7409   clib_memset (&nh_addr, 0, sizeof (ip46_address_t));
7410
7411   bool nexthop_set = 0;
7412
7413   int ret;
7414
7415   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7416     {
7417       if (unformat (i, "del"))
7418         is_del = 1;
7419       else if (unformat (i, "address %U", unformat_ip6_address, &localsid));
7420       else if (unformat (i, "next-hop %U", unformat_ip46_address, &nh_addr))
7421         nexthop_set = 1;
7422       else if (unformat (i, "behavior %u", &behavior));
7423       else if (unformat (i, "sw_if_index %u", &sw_if_index));
7424       else if (unformat (i, "fib-table %u", &fib_table));
7425       else if (unformat (i, "end.psp %u", &behavior));
7426       else
7427         break;
7428     }
7429
7430   M (SR_LOCALSID_ADD_DEL, mp);
7431
7432   clib_memcpy (mp->localsid, &localsid, sizeof (mp->localsid));
7433
7434   if (nexthop_set)
7435     {
7436       clib_memcpy (&mp->nh_addr.un, &nh_addr, sizeof (mp->nh_addr.un));
7437     }
7438   mp->behavior = behavior;
7439   mp->sw_if_index = ntohl (sw_if_index);
7440   mp->fib_table = ntohl (fib_table);
7441   mp->end_psp = end_psp;
7442   mp->is_del = is_del;
7443
7444   S (mp);
7445   W (ret);
7446   return ret;
7447 }
7448
7449 static int
7450 api_ioam_enable (vat_main_t * vam)
7451 {
7452   unformat_input_t *input = vam->input;
7453   vl_api_ioam_enable_t *mp;
7454   u32 id = 0;
7455   int has_trace_option = 0;
7456   int has_pot_option = 0;
7457   int has_seqno_option = 0;
7458   int has_analyse_option = 0;
7459   int ret;
7460
7461   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7462     {
7463       if (unformat (input, "trace"))
7464         has_trace_option = 1;
7465       else if (unformat (input, "pot"))
7466         has_pot_option = 1;
7467       else if (unformat (input, "seqno"))
7468         has_seqno_option = 1;
7469       else if (unformat (input, "analyse"))
7470         has_analyse_option = 1;
7471       else
7472         break;
7473     }
7474   M (IOAM_ENABLE, mp);
7475   mp->id = htons (id);
7476   mp->seqno = has_seqno_option;
7477   mp->analyse = has_analyse_option;
7478   mp->pot_enable = has_pot_option;
7479   mp->trace_enable = has_trace_option;
7480
7481   S (mp);
7482   W (ret);
7483   return ret;
7484 }
7485
7486
7487 static int
7488 api_ioam_disable (vat_main_t * vam)
7489 {
7490   vl_api_ioam_disable_t *mp;
7491   int ret;
7492
7493   M (IOAM_DISABLE, mp);
7494   S (mp);
7495   W (ret);
7496   return ret;
7497 }
7498
7499 #define foreach_tcp_proto_field                 \
7500 _(src_port)                                     \
7501 _(dst_port)
7502
7503 #define foreach_udp_proto_field                 \
7504 _(src_port)                                     \
7505 _(dst_port)
7506
7507 #define foreach_ip4_proto_field                 \
7508 _(src_address)                                  \
7509 _(dst_address)                                  \
7510 _(tos)                                          \
7511 _(length)                                       \
7512 _(fragment_id)                                  \
7513 _(ttl)                                          \
7514 _(protocol)                                     \
7515 _(checksum)
7516
7517 typedef struct
7518 {
7519   u16 src_port, dst_port;
7520 } tcpudp_header_t;
7521
7522 #if VPP_API_TEST_BUILTIN == 0
7523 uword
7524 unformat_tcp_mask (unformat_input_t * input, va_list * args)
7525 {
7526   u8 **maskp = va_arg (*args, u8 **);
7527   u8 *mask = 0;
7528   u8 found_something = 0;
7529   tcp_header_t *tcp;
7530
7531 #define _(a) u8 a=0;
7532   foreach_tcp_proto_field;
7533 #undef _
7534
7535   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7536     {
7537       if (0);
7538 #define _(a) else if (unformat (input, #a)) a=1;
7539       foreach_tcp_proto_field
7540 #undef _
7541         else
7542         break;
7543     }
7544
7545 #define _(a) found_something += a;
7546   foreach_tcp_proto_field;
7547 #undef _
7548
7549   if (found_something == 0)
7550     return 0;
7551
7552   vec_validate (mask, sizeof (*tcp) - 1);
7553
7554   tcp = (tcp_header_t *) mask;
7555
7556 #define _(a) if (a) clib_memset (&tcp->a, 0xff, sizeof (tcp->a));
7557   foreach_tcp_proto_field;
7558 #undef _
7559
7560   *maskp = mask;
7561   return 1;
7562 }
7563
7564 uword
7565 unformat_udp_mask (unformat_input_t * input, va_list * args)
7566 {
7567   u8 **maskp = va_arg (*args, u8 **);
7568   u8 *mask = 0;
7569   u8 found_something = 0;
7570   udp_header_t *udp;
7571
7572 #define _(a) u8 a=0;
7573   foreach_udp_proto_field;
7574 #undef _
7575
7576   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7577     {
7578       if (0);
7579 #define _(a) else if (unformat (input, #a)) a=1;
7580       foreach_udp_proto_field
7581 #undef _
7582         else
7583         break;
7584     }
7585
7586 #define _(a) found_something += a;
7587   foreach_udp_proto_field;
7588 #undef _
7589
7590   if (found_something == 0)
7591     return 0;
7592
7593   vec_validate (mask, sizeof (*udp) - 1);
7594
7595   udp = (udp_header_t *) mask;
7596
7597 #define _(a) if (a) clib_memset (&udp->a, 0xff, sizeof (udp->a));
7598   foreach_udp_proto_field;
7599 #undef _
7600
7601   *maskp = mask;
7602   return 1;
7603 }
7604
7605 uword
7606 unformat_l4_mask (unformat_input_t * input, va_list * args)
7607 {
7608   u8 **maskp = va_arg (*args, u8 **);
7609   u16 src_port = 0, dst_port = 0;
7610   tcpudp_header_t *tcpudp;
7611
7612   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7613     {
7614       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
7615         return 1;
7616       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
7617         return 1;
7618       else if (unformat (input, "src_port"))
7619         src_port = 0xFFFF;
7620       else if (unformat (input, "dst_port"))
7621         dst_port = 0xFFFF;
7622       else
7623         return 0;
7624     }
7625
7626   if (!src_port && !dst_port)
7627     return 0;
7628
7629   u8 *mask = 0;
7630   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
7631
7632   tcpudp = (tcpudp_header_t *) mask;
7633   tcpudp->src_port = src_port;
7634   tcpudp->dst_port = dst_port;
7635
7636   *maskp = mask;
7637
7638   return 1;
7639 }
7640
7641 uword
7642 unformat_ip4_mask (unformat_input_t * input, va_list * args)
7643 {
7644   u8 **maskp = va_arg (*args, u8 **);
7645   u8 *mask = 0;
7646   u8 found_something = 0;
7647   ip4_header_t *ip;
7648
7649 #define _(a) u8 a=0;
7650   foreach_ip4_proto_field;
7651 #undef _
7652   u8 version = 0;
7653   u8 hdr_length = 0;
7654
7655
7656   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7657     {
7658       if (unformat (input, "version"))
7659         version = 1;
7660       else if (unformat (input, "hdr_length"))
7661         hdr_length = 1;
7662       else if (unformat (input, "src"))
7663         src_address = 1;
7664       else if (unformat (input, "dst"))
7665         dst_address = 1;
7666       else if (unformat (input, "proto"))
7667         protocol = 1;
7668
7669 #define _(a) else if (unformat (input, #a)) a=1;
7670       foreach_ip4_proto_field
7671 #undef _
7672         else
7673         break;
7674     }
7675
7676 #define _(a) found_something += a;
7677   foreach_ip4_proto_field;
7678 #undef _
7679
7680   if (found_something == 0)
7681     return 0;
7682
7683   vec_validate (mask, sizeof (*ip) - 1);
7684
7685   ip = (ip4_header_t *) mask;
7686
7687 #define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
7688   foreach_ip4_proto_field;
7689 #undef _
7690
7691   ip->ip_version_and_header_length = 0;
7692
7693   if (version)
7694     ip->ip_version_and_header_length |= 0xF0;
7695
7696   if (hdr_length)
7697     ip->ip_version_and_header_length |= 0x0F;
7698
7699   *maskp = mask;
7700   return 1;
7701 }
7702
7703 #define foreach_ip6_proto_field                 \
7704 _(src_address)                                  \
7705 _(dst_address)                                  \
7706 _(payload_length)                               \
7707 _(hop_limit)                                    \
7708 _(protocol)
7709
7710 uword
7711 unformat_ip6_mask (unformat_input_t * input, va_list * args)
7712 {
7713   u8 **maskp = va_arg (*args, u8 **);
7714   u8 *mask = 0;
7715   u8 found_something = 0;
7716   ip6_header_t *ip;
7717   u32 ip_version_traffic_class_and_flow_label;
7718
7719 #define _(a) u8 a=0;
7720   foreach_ip6_proto_field;
7721 #undef _
7722   u8 version = 0;
7723   u8 traffic_class = 0;
7724   u8 flow_label = 0;
7725
7726   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7727     {
7728       if (unformat (input, "version"))
7729         version = 1;
7730       else if (unformat (input, "traffic-class"))
7731         traffic_class = 1;
7732       else if (unformat (input, "flow-label"))
7733         flow_label = 1;
7734       else if (unformat (input, "src"))
7735         src_address = 1;
7736       else if (unformat (input, "dst"))
7737         dst_address = 1;
7738       else if (unformat (input, "proto"))
7739         protocol = 1;
7740
7741 #define _(a) else if (unformat (input, #a)) a=1;
7742       foreach_ip6_proto_field
7743 #undef _
7744         else
7745         break;
7746     }
7747
7748 #define _(a) found_something += a;
7749   foreach_ip6_proto_field;
7750 #undef _
7751
7752   if (found_something == 0)
7753     return 0;
7754
7755   vec_validate (mask, sizeof (*ip) - 1);
7756
7757   ip = (ip6_header_t *) mask;
7758
7759 #define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
7760   foreach_ip6_proto_field;
7761 #undef _
7762
7763   ip_version_traffic_class_and_flow_label = 0;
7764
7765   if (version)
7766     ip_version_traffic_class_and_flow_label |= 0xF0000000;
7767
7768   if (traffic_class)
7769     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
7770
7771   if (flow_label)
7772     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
7773
7774   ip->ip_version_traffic_class_and_flow_label =
7775     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
7776
7777   *maskp = mask;
7778   return 1;
7779 }
7780
7781 uword
7782 unformat_l3_mask (unformat_input_t * input, va_list * args)
7783 {
7784   u8 **maskp = va_arg (*args, u8 **);
7785
7786   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7787     {
7788       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
7789         return 1;
7790       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
7791         return 1;
7792       else
7793         break;
7794     }
7795   return 0;
7796 }
7797
7798 uword
7799 unformat_l2_mask (unformat_input_t * input, va_list * args)
7800 {
7801   u8 **maskp = va_arg (*args, u8 **);
7802   u8 *mask = 0;
7803   u8 src = 0;
7804   u8 dst = 0;
7805   u8 proto = 0;
7806   u8 tag1 = 0;
7807   u8 tag2 = 0;
7808   u8 ignore_tag1 = 0;
7809   u8 ignore_tag2 = 0;
7810   u8 cos1 = 0;
7811   u8 cos2 = 0;
7812   u8 dot1q = 0;
7813   u8 dot1ad = 0;
7814   int len = 14;
7815
7816   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7817     {
7818       if (unformat (input, "src"))
7819         src = 1;
7820       else if (unformat (input, "dst"))
7821         dst = 1;
7822       else if (unformat (input, "proto"))
7823         proto = 1;
7824       else if (unformat (input, "tag1"))
7825         tag1 = 1;
7826       else if (unformat (input, "tag2"))
7827         tag2 = 1;
7828       else if (unformat (input, "ignore-tag1"))
7829         ignore_tag1 = 1;
7830       else if (unformat (input, "ignore-tag2"))
7831         ignore_tag2 = 1;
7832       else if (unformat (input, "cos1"))
7833         cos1 = 1;
7834       else if (unformat (input, "cos2"))
7835         cos2 = 1;
7836       else if (unformat (input, "dot1q"))
7837         dot1q = 1;
7838       else if (unformat (input, "dot1ad"))
7839         dot1ad = 1;
7840       else
7841         break;
7842     }
7843   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
7844        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
7845     return 0;
7846
7847   if (tag1 || ignore_tag1 || cos1 || dot1q)
7848     len = 18;
7849   if (tag2 || ignore_tag2 || cos2 || dot1ad)
7850     len = 22;
7851
7852   vec_validate (mask, len - 1);
7853
7854   if (dst)
7855     clib_memset (mask, 0xff, 6);
7856
7857   if (src)
7858     clib_memset (mask + 6, 0xff, 6);
7859
7860   if (tag2 || dot1ad)
7861     {
7862       /* inner vlan tag */
7863       if (tag2)
7864         {
7865           mask[19] = 0xff;
7866           mask[18] = 0x0f;
7867         }
7868       if (cos2)
7869         mask[18] |= 0xe0;
7870       if (proto)
7871         mask[21] = mask[20] = 0xff;
7872       if (tag1)
7873         {
7874           mask[15] = 0xff;
7875           mask[14] = 0x0f;
7876         }
7877       if (cos1)
7878         mask[14] |= 0xe0;
7879       *maskp = mask;
7880       return 1;
7881     }
7882   if (tag1 | dot1q)
7883     {
7884       if (tag1)
7885         {
7886           mask[15] = 0xff;
7887           mask[14] = 0x0f;
7888         }
7889       if (cos1)
7890         mask[14] |= 0xe0;
7891       if (proto)
7892         mask[16] = mask[17] = 0xff;
7893
7894       *maskp = mask;
7895       return 1;
7896     }
7897   if (cos2)
7898     mask[18] |= 0xe0;
7899   if (cos1)
7900     mask[14] |= 0xe0;
7901   if (proto)
7902     mask[12] = mask[13] = 0xff;
7903
7904   *maskp = mask;
7905   return 1;
7906 }
7907
7908 uword
7909 unformat_classify_mask (unformat_input_t * input, va_list * args)
7910 {
7911   u8 **maskp = va_arg (*args, u8 **);
7912   u32 *skipp = va_arg (*args, u32 *);
7913   u32 *matchp = va_arg (*args, u32 *);
7914   u32 match;
7915   u8 *mask = 0;
7916   u8 *l2 = 0;
7917   u8 *l3 = 0;
7918   u8 *l4 = 0;
7919   int i;
7920
7921   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7922     {
7923       if (unformat (input, "hex %U", unformat_hex_string, &mask))
7924         ;
7925       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
7926         ;
7927       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
7928         ;
7929       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
7930         ;
7931       else
7932         break;
7933     }
7934
7935   if (l4 && !l3)
7936     {
7937       vec_free (mask);
7938       vec_free (l2);
7939       vec_free (l4);
7940       return 0;
7941     }
7942
7943   if (mask || l2 || l3 || l4)
7944     {
7945       if (l2 || l3 || l4)
7946         {
7947           /* "With a free Ethernet header in every package" */
7948           if (l2 == 0)
7949             vec_validate (l2, 13);
7950           mask = l2;
7951           if (vec_len (l3))
7952             {
7953               vec_append (mask, l3);
7954               vec_free (l3);
7955             }
7956           if (vec_len (l4))
7957             {
7958               vec_append (mask, l4);
7959               vec_free (l4);
7960             }
7961         }
7962
7963       /* Scan forward looking for the first significant mask octet */
7964       for (i = 0; i < vec_len (mask); i++)
7965         if (mask[i])
7966           break;
7967
7968       /* compute (skip, match) params */
7969       *skipp = i / sizeof (u32x4);
7970       vec_delete (mask, *skipp * sizeof (u32x4), 0);
7971
7972       /* Pad mask to an even multiple of the vector size */
7973       while (vec_len (mask) % sizeof (u32x4))
7974         vec_add1 (mask, 0);
7975
7976       match = vec_len (mask) / sizeof (u32x4);
7977
7978       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
7979         {
7980           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
7981           if (*tmp || *(tmp + 1))
7982             break;
7983           match--;
7984         }
7985       if (match == 0)
7986         clib_warning ("BUG: match 0");
7987
7988       _vec_len (mask) = match * sizeof (u32x4);
7989
7990       *matchp = match;
7991       *maskp = mask;
7992
7993       return 1;
7994     }
7995
7996   return 0;
7997 }
7998 #endif /* VPP_API_TEST_BUILTIN */
7999
8000 #define foreach_l2_next                         \
8001 _(drop, DROP)                                   \
8002 _(ethernet, ETHERNET_INPUT)                     \
8003 _(ip4, IP4_INPUT)                               \
8004 _(ip6, IP6_INPUT)
8005
8006 uword
8007 unformat_l2_next_index (unformat_input_t * input, va_list * args)
8008 {
8009   u32 *miss_next_indexp = va_arg (*args, u32 *);
8010   u32 next_index = 0;
8011   u32 tmp;
8012
8013 #define _(n,N) \
8014   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
8015   foreach_l2_next;
8016 #undef _
8017
8018   if (unformat (input, "%d", &tmp))
8019     {
8020       next_index = tmp;
8021       goto out;
8022     }
8023
8024   return 0;
8025
8026 out:
8027   *miss_next_indexp = next_index;
8028   return 1;
8029 }
8030
8031 #define foreach_ip_next                         \
8032 _(drop, DROP)                                   \
8033 _(local, LOCAL)                                 \
8034 _(rewrite, REWRITE)
8035
8036 uword
8037 api_unformat_ip_next_index (unformat_input_t * input, va_list * args)
8038 {
8039   u32 *miss_next_indexp = va_arg (*args, u32 *);
8040   u32 next_index = 0;
8041   u32 tmp;
8042
8043 #define _(n,N) \
8044   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
8045   foreach_ip_next;
8046 #undef _
8047
8048   if (unformat (input, "%d", &tmp))
8049     {
8050       next_index = tmp;
8051       goto out;
8052     }
8053
8054   return 0;
8055
8056 out:
8057   *miss_next_indexp = next_index;
8058   return 1;
8059 }
8060
8061 #define foreach_acl_next                        \
8062 _(deny, DENY)
8063
8064 uword
8065 api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
8066 {
8067   u32 *miss_next_indexp = va_arg (*args, u32 *);
8068   u32 next_index = 0;
8069   u32 tmp;
8070
8071 #define _(n,N) \
8072   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
8073   foreach_acl_next;
8074 #undef _
8075
8076   if (unformat (input, "permit"))
8077     {
8078       next_index = ~0;
8079       goto out;
8080     }
8081   else if (unformat (input, "%d", &tmp))
8082     {
8083       next_index = tmp;
8084       goto out;
8085     }
8086
8087   return 0;
8088
8089 out:
8090   *miss_next_indexp = next_index;
8091   return 1;
8092 }
8093
8094 uword
8095 unformat_policer_precolor (unformat_input_t * input, va_list * args)
8096 {
8097   u32 *r = va_arg (*args, u32 *);
8098
8099   if (unformat (input, "conform-color"))
8100     *r = POLICE_CONFORM;
8101   else if (unformat (input, "exceed-color"))
8102     *r = POLICE_EXCEED;
8103   else
8104     return 0;
8105
8106   return 1;
8107 }
8108
8109 static int
8110 api_classify_add_del_table (vat_main_t * vam)
8111 {
8112   unformat_input_t *i = vam->input;
8113   vl_api_classify_add_del_table_t *mp;
8114
8115   u32 nbuckets = 2;
8116   u32 skip = ~0;
8117   u32 match = ~0;
8118   int is_add = 1;
8119   int del_chain = 0;
8120   u32 table_index = ~0;
8121   u32 next_table_index = ~0;
8122   u32 miss_next_index = ~0;
8123   u32 memory_size = 32 << 20;
8124   u8 *mask = 0;
8125   u32 current_data_flag = 0;
8126   int current_data_offset = 0;
8127   int ret;
8128
8129   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8130     {
8131       if (unformat (i, "del"))
8132         is_add = 0;
8133       else if (unformat (i, "del-chain"))
8134         {
8135           is_add = 0;
8136           del_chain = 1;
8137         }
8138       else if (unformat (i, "buckets %d", &nbuckets))
8139         ;
8140       else if (unformat (i, "memory_size %d", &memory_size))
8141         ;
8142       else if (unformat (i, "skip %d", &skip))
8143         ;
8144       else if (unformat (i, "match %d", &match))
8145         ;
8146       else if (unformat (i, "table %d", &table_index))
8147         ;
8148       else if (unformat (i, "mask %U", unformat_classify_mask,
8149                          &mask, &skip, &match))
8150         ;
8151       else if (unformat (i, "next-table %d", &next_table_index))
8152         ;
8153       else if (unformat (i, "miss-next %U", api_unformat_ip_next_index,
8154                          &miss_next_index))
8155         ;
8156       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
8157                          &miss_next_index))
8158         ;
8159       else if (unformat (i, "acl-miss-next %U", api_unformat_acl_next_index,
8160                          &miss_next_index))
8161         ;
8162       else if (unformat (i, "current-data-flag %d", &current_data_flag))
8163         ;
8164       else if (unformat (i, "current-data-offset %d", &current_data_offset))
8165         ;
8166       else
8167         break;
8168     }
8169
8170   if (is_add && mask == 0)
8171     {
8172       errmsg ("Mask required");
8173       return -99;
8174     }
8175
8176   if (is_add && skip == ~0)
8177     {
8178       errmsg ("skip count required");
8179       return -99;
8180     }
8181
8182   if (is_add && match == ~0)
8183     {
8184       errmsg ("match count required");
8185       return -99;
8186     }
8187
8188   if (!is_add && table_index == ~0)
8189     {
8190       errmsg ("table index required for delete");
8191       return -99;
8192     }
8193
8194   M2 (CLASSIFY_ADD_DEL_TABLE, mp, vec_len (mask));
8195
8196   mp->is_add = is_add;
8197   mp->del_chain = del_chain;
8198   mp->table_index = ntohl (table_index);
8199   mp->nbuckets = ntohl (nbuckets);
8200   mp->memory_size = ntohl (memory_size);
8201   mp->skip_n_vectors = ntohl (skip);
8202   mp->match_n_vectors = ntohl (match);
8203   mp->next_table_index = ntohl (next_table_index);
8204   mp->miss_next_index = ntohl (miss_next_index);
8205   mp->current_data_flag = ntohl (current_data_flag);
8206   mp->current_data_offset = ntohl (current_data_offset);
8207   mp->mask_len = ntohl (vec_len (mask));
8208   clib_memcpy (mp->mask, mask, vec_len (mask));
8209
8210   vec_free (mask);
8211
8212   S (mp);
8213   W (ret);
8214   return ret;
8215 }
8216
8217 #if VPP_API_TEST_BUILTIN == 0
8218 uword
8219 unformat_l4_match (unformat_input_t * input, va_list * args)
8220 {
8221   u8 **matchp = va_arg (*args, u8 **);
8222
8223   u8 *proto_header = 0;
8224   int src_port = 0;
8225   int dst_port = 0;
8226
8227   tcpudp_header_t h;
8228
8229   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8230     {
8231       if (unformat (input, "src_port %d", &src_port))
8232         ;
8233       else if (unformat (input, "dst_port %d", &dst_port))
8234         ;
8235       else
8236         return 0;
8237     }
8238
8239   h.src_port = clib_host_to_net_u16 (src_port);
8240   h.dst_port = clib_host_to_net_u16 (dst_port);
8241   vec_validate (proto_header, sizeof (h) - 1);
8242   memcpy (proto_header, &h, sizeof (h));
8243
8244   *matchp = proto_header;
8245
8246   return 1;
8247 }
8248
8249 uword
8250 unformat_ip4_match (unformat_input_t * input, va_list * args)
8251 {
8252   u8 **matchp = va_arg (*args, u8 **);
8253   u8 *match = 0;
8254   ip4_header_t *ip;
8255   int version = 0;
8256   u32 version_val;
8257   int hdr_length = 0;
8258   u32 hdr_length_val;
8259   int src = 0, dst = 0;
8260   ip4_address_t src_val, dst_val;
8261   int proto = 0;
8262   u32 proto_val;
8263   int tos = 0;
8264   u32 tos_val;
8265   int length = 0;
8266   u32 length_val;
8267   int fragment_id = 0;
8268   u32 fragment_id_val;
8269   int ttl = 0;
8270   int ttl_val;
8271   int checksum = 0;
8272   u32 checksum_val;
8273
8274   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8275     {
8276       if (unformat (input, "version %d", &version_val))
8277         version = 1;
8278       else if (unformat (input, "hdr_length %d", &hdr_length_val))
8279         hdr_length = 1;
8280       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
8281         src = 1;
8282       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
8283         dst = 1;
8284       else if (unformat (input, "proto %d", &proto_val))
8285         proto = 1;
8286       else if (unformat (input, "tos %d", &tos_val))
8287         tos = 1;
8288       else if (unformat (input, "length %d", &length_val))
8289         length = 1;
8290       else if (unformat (input, "fragment_id %d", &fragment_id_val))
8291         fragment_id = 1;
8292       else if (unformat (input, "ttl %d", &ttl_val))
8293         ttl = 1;
8294       else if (unformat (input, "checksum %d", &checksum_val))
8295         checksum = 1;
8296       else
8297         break;
8298     }
8299
8300   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
8301       + ttl + checksum == 0)
8302     return 0;
8303
8304   /*
8305    * Aligned because we use the real comparison functions
8306    */
8307   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
8308
8309   ip = (ip4_header_t *) match;
8310
8311   /* These are realistically matched in practice */
8312   if (src)
8313     ip->src_address.as_u32 = src_val.as_u32;
8314
8315   if (dst)
8316     ip->dst_address.as_u32 = dst_val.as_u32;
8317
8318   if (proto)
8319     ip->protocol = proto_val;
8320
8321
8322   /* These are not, but they're included for completeness */
8323   if (version)
8324     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
8325
8326   if (hdr_length)
8327     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
8328
8329   if (tos)
8330     ip->tos = tos_val;
8331
8332   if (length)
8333     ip->length = clib_host_to_net_u16 (length_val);
8334
8335   if (ttl)
8336     ip->ttl = ttl_val;
8337
8338   if (checksum)
8339     ip->checksum = clib_host_to_net_u16 (checksum_val);
8340
8341   *matchp = match;
8342   return 1;
8343 }
8344
8345 uword
8346 unformat_ip6_match (unformat_input_t * input, va_list * args)
8347 {
8348   u8 **matchp = va_arg (*args, u8 **);
8349   u8 *match = 0;
8350   ip6_header_t *ip;
8351   int version = 0;
8352   u32 version_val;
8353   u8 traffic_class = 0;
8354   u32 traffic_class_val = 0;
8355   u8 flow_label = 0;
8356   u8 flow_label_val;
8357   int src = 0, dst = 0;
8358   ip6_address_t src_val, dst_val;
8359   int proto = 0;
8360   u32 proto_val;
8361   int payload_length = 0;
8362   u32 payload_length_val;
8363   int hop_limit = 0;
8364   int hop_limit_val;
8365   u32 ip_version_traffic_class_and_flow_label;
8366
8367   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8368     {
8369       if (unformat (input, "version %d", &version_val))
8370         version = 1;
8371       else if (unformat (input, "traffic_class %d", &traffic_class_val))
8372         traffic_class = 1;
8373       else if (unformat (input, "flow_label %d", &flow_label_val))
8374         flow_label = 1;
8375       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
8376         src = 1;
8377       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
8378         dst = 1;
8379       else if (unformat (input, "proto %d", &proto_val))
8380         proto = 1;
8381       else if (unformat (input, "payload_length %d", &payload_length_val))
8382         payload_length = 1;
8383       else if (unformat (input, "hop_limit %d", &hop_limit_val))
8384         hop_limit = 1;
8385       else
8386         break;
8387     }
8388
8389   if (version + traffic_class + flow_label + src + dst + proto +
8390       payload_length + hop_limit == 0)
8391     return 0;
8392
8393   /*
8394    * Aligned because we use the real comparison functions
8395    */
8396   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
8397
8398   ip = (ip6_header_t *) match;
8399
8400   if (src)
8401     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
8402
8403   if (dst)
8404     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
8405
8406   if (proto)
8407     ip->protocol = proto_val;
8408
8409   ip_version_traffic_class_and_flow_label = 0;
8410
8411   if (version)
8412     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
8413
8414   if (traffic_class)
8415     ip_version_traffic_class_and_flow_label |=
8416       (traffic_class_val & 0xFF) << 20;
8417
8418   if (flow_label)
8419     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
8420
8421   ip->ip_version_traffic_class_and_flow_label =
8422     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
8423
8424   if (payload_length)
8425     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
8426
8427   if (hop_limit)
8428     ip->hop_limit = hop_limit_val;
8429
8430   *matchp = match;
8431   return 1;
8432 }
8433
8434 uword
8435 unformat_l3_match (unformat_input_t * input, va_list * args)
8436 {
8437   u8 **matchp = va_arg (*args, u8 **);
8438
8439   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8440     {
8441       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
8442         return 1;
8443       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
8444         return 1;
8445       else
8446         break;
8447     }
8448   return 0;
8449 }
8450
8451 uword
8452 unformat_vlan_tag (unformat_input_t * input, va_list * args)
8453 {
8454   u8 *tagp = va_arg (*args, u8 *);
8455   u32 tag;
8456
8457   if (unformat (input, "%d", &tag))
8458     {
8459       tagp[0] = (tag >> 8) & 0x0F;
8460       tagp[1] = tag & 0xFF;
8461       return 1;
8462     }
8463
8464   return 0;
8465 }
8466
8467 uword
8468 unformat_l2_match (unformat_input_t * input, va_list * args)
8469 {
8470   u8 **matchp = va_arg (*args, u8 **);
8471   u8 *match = 0;
8472   u8 src = 0;
8473   u8 src_val[6];
8474   u8 dst = 0;
8475   u8 dst_val[6];
8476   u8 proto = 0;
8477   u16 proto_val;
8478   u8 tag1 = 0;
8479   u8 tag1_val[2];
8480   u8 tag2 = 0;
8481   u8 tag2_val[2];
8482   int len = 14;
8483   u8 ignore_tag1 = 0;
8484   u8 ignore_tag2 = 0;
8485   u8 cos1 = 0;
8486   u8 cos2 = 0;
8487   u32 cos1_val = 0;
8488   u32 cos2_val = 0;
8489
8490   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8491     {
8492       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
8493         src = 1;
8494       else
8495         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
8496         dst = 1;
8497       else if (unformat (input, "proto %U",
8498                          unformat_ethernet_type_host_byte_order, &proto_val))
8499         proto = 1;
8500       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
8501         tag1 = 1;
8502       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
8503         tag2 = 1;
8504       else if (unformat (input, "ignore-tag1"))
8505         ignore_tag1 = 1;
8506       else if (unformat (input, "ignore-tag2"))
8507         ignore_tag2 = 1;
8508       else if (unformat (input, "cos1 %d", &cos1_val))
8509         cos1 = 1;
8510       else if (unformat (input, "cos2 %d", &cos2_val))
8511         cos2 = 1;
8512       else
8513         break;
8514     }
8515   if ((src + dst + proto + tag1 + tag2 +
8516        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
8517     return 0;
8518
8519   if (tag1 || ignore_tag1 || cos1)
8520     len = 18;
8521   if (tag2 || ignore_tag2 || cos2)
8522     len = 22;
8523
8524   vec_validate_aligned (match, len - 1, sizeof (u32x4));
8525
8526   if (dst)
8527     clib_memcpy (match, dst_val, 6);
8528
8529   if (src)
8530     clib_memcpy (match + 6, src_val, 6);
8531
8532   if (tag2)
8533     {
8534       /* inner vlan tag */
8535       match[19] = tag2_val[1];
8536       match[18] = tag2_val[0];
8537       if (cos2)
8538         match[18] |= (cos2_val & 0x7) << 5;
8539       if (proto)
8540         {
8541           match[21] = proto_val & 0xff;
8542           match[20] = proto_val >> 8;
8543         }
8544       if (tag1)
8545         {
8546           match[15] = tag1_val[1];
8547           match[14] = tag1_val[0];
8548         }
8549       if (cos1)
8550         match[14] |= (cos1_val & 0x7) << 5;
8551       *matchp = match;
8552       return 1;
8553     }
8554   if (tag1)
8555     {
8556       match[15] = tag1_val[1];
8557       match[14] = tag1_val[0];
8558       if (proto)
8559         {
8560           match[17] = proto_val & 0xff;
8561           match[16] = proto_val >> 8;
8562         }
8563       if (cos1)
8564         match[14] |= (cos1_val & 0x7) << 5;
8565
8566       *matchp = match;
8567       return 1;
8568     }
8569   if (cos2)
8570     match[18] |= (cos2_val & 0x7) << 5;
8571   if (cos1)
8572     match[14] |= (cos1_val & 0x7) << 5;
8573   if (proto)
8574     {
8575       match[13] = proto_val & 0xff;
8576       match[12] = proto_val >> 8;
8577     }
8578
8579   *matchp = match;
8580   return 1;
8581 }
8582
8583 uword
8584 unformat_qos_source (unformat_input_t * input, va_list * args)
8585 {
8586   int *qs = va_arg (*args, int *);
8587
8588   if (unformat (input, "ip"))
8589     *qs = QOS_SOURCE_IP;
8590   else if (unformat (input, "mpls"))
8591     *qs = QOS_SOURCE_MPLS;
8592   else if (unformat (input, "ext"))
8593     *qs = QOS_SOURCE_EXT;
8594   else if (unformat (input, "vlan"))
8595     *qs = QOS_SOURCE_VLAN;
8596   else
8597     return 0;
8598
8599   return 1;
8600 }
8601 #endif
8602
8603 uword
8604 api_unformat_classify_match (unformat_input_t * input, va_list * args)
8605 {
8606   u8 **matchp = va_arg (*args, u8 **);
8607   u32 skip_n_vectors = va_arg (*args, u32);
8608   u32 match_n_vectors = va_arg (*args, u32);
8609
8610   u8 *match = 0;
8611   u8 *l2 = 0;
8612   u8 *l3 = 0;
8613   u8 *l4 = 0;
8614
8615   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8616     {
8617       if (unformat (input, "hex %U", unformat_hex_string, &match))
8618         ;
8619       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
8620         ;
8621       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
8622         ;
8623       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
8624         ;
8625       else
8626         break;
8627     }
8628
8629   if (l4 && !l3)
8630     {
8631       vec_free (match);
8632       vec_free (l2);
8633       vec_free (l4);
8634       return 0;
8635     }
8636
8637   if (match || l2 || l3 || l4)
8638     {
8639       if (l2 || l3 || l4)
8640         {
8641           /* "Win a free Ethernet header in every packet" */
8642           if (l2 == 0)
8643             vec_validate_aligned (l2, 13, sizeof (u32x4));
8644           match = l2;
8645           if (vec_len (l3))
8646             {
8647               vec_append_aligned (match, l3, sizeof (u32x4));
8648               vec_free (l3);
8649             }
8650           if (vec_len (l4))
8651             {
8652               vec_append_aligned (match, l4, sizeof (u32x4));
8653               vec_free (l4);
8654             }
8655         }
8656
8657       /* Make sure the vector is big enough even if key is all 0's */
8658       vec_validate_aligned
8659         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
8660          sizeof (u32x4));
8661
8662       /* Set size, include skipped vectors */
8663       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
8664
8665       *matchp = match;
8666
8667       return 1;
8668     }
8669
8670   return 0;
8671 }
8672
8673 static int
8674 api_classify_add_del_session (vat_main_t * vam)
8675 {
8676   unformat_input_t *i = vam->input;
8677   vl_api_classify_add_del_session_t *mp;
8678   int is_add = 1;
8679   u32 table_index = ~0;
8680   u32 hit_next_index = ~0;
8681   u32 opaque_index = ~0;
8682   u8 *match = 0;
8683   i32 advance = 0;
8684   u32 skip_n_vectors = 0;
8685   u32 match_n_vectors = 0;
8686   u32 action = 0;
8687   u32 metadata = 0;
8688   int ret;
8689
8690   /*
8691    * Warning: you have to supply skip_n and match_n
8692    * because the API client cant simply look at the classify
8693    * table object.
8694    */
8695
8696   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8697     {
8698       if (unformat (i, "del"))
8699         is_add = 0;
8700       else if (unformat (i, "hit-next %U", api_unformat_ip_next_index,
8701                          &hit_next_index))
8702         ;
8703       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
8704                          &hit_next_index))
8705         ;
8706       else if (unformat (i, "acl-hit-next %U", api_unformat_acl_next_index,
8707                          &hit_next_index))
8708         ;
8709       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
8710         ;
8711       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
8712         ;
8713       else if (unformat (i, "opaque-index %d", &opaque_index))
8714         ;
8715       else if (unformat (i, "skip_n %d", &skip_n_vectors))
8716         ;
8717       else if (unformat (i, "match_n %d", &match_n_vectors))
8718         ;
8719       else if (unformat (i, "match %U", api_unformat_classify_match,
8720                          &match, skip_n_vectors, match_n_vectors))
8721         ;
8722       else if (unformat (i, "advance %d", &advance))
8723         ;
8724       else if (unformat (i, "table-index %d", &table_index))
8725         ;
8726       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
8727         action = 1;
8728       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
8729         action = 2;
8730       else if (unformat (i, "action %d", &action))
8731         ;
8732       else if (unformat (i, "metadata %d", &metadata))
8733         ;
8734       else
8735         break;
8736     }
8737
8738   if (table_index == ~0)
8739     {
8740       errmsg ("Table index required");
8741       return -99;
8742     }
8743
8744   if (is_add && match == 0)
8745     {
8746       errmsg ("Match value required");
8747       return -99;
8748     }
8749
8750   M2 (CLASSIFY_ADD_DEL_SESSION, mp, vec_len (match));
8751
8752   mp->is_add = is_add;
8753   mp->table_index = ntohl (table_index);
8754   mp->hit_next_index = ntohl (hit_next_index);
8755   mp->opaque_index = ntohl (opaque_index);
8756   mp->advance = ntohl (advance);
8757   mp->action = action;
8758   mp->metadata = ntohl (metadata);
8759   mp->match_len = ntohl (vec_len (match));
8760   clib_memcpy (mp->match, match, vec_len (match));
8761   vec_free (match);
8762
8763   S (mp);
8764   W (ret);
8765   return ret;
8766 }
8767
8768 static int
8769 api_classify_set_interface_ip_table (vat_main_t * vam)
8770 {
8771   unformat_input_t *i = vam->input;
8772   vl_api_classify_set_interface_ip_table_t *mp;
8773   u32 sw_if_index;
8774   int sw_if_index_set;
8775   u32 table_index = ~0;
8776   u8 is_ipv6 = 0;
8777   int ret;
8778
8779   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8780     {
8781       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8782         sw_if_index_set = 1;
8783       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8784         sw_if_index_set = 1;
8785       else if (unformat (i, "table %d", &table_index))
8786         ;
8787       else
8788         {
8789           clib_warning ("parse error '%U'", format_unformat_error, i);
8790           return -99;
8791         }
8792     }
8793
8794   if (sw_if_index_set == 0)
8795     {
8796       errmsg ("missing interface name or sw_if_index");
8797       return -99;
8798     }
8799
8800
8801   M (CLASSIFY_SET_INTERFACE_IP_TABLE, mp);
8802
8803   mp->sw_if_index = ntohl (sw_if_index);
8804   mp->table_index = ntohl (table_index);
8805   mp->is_ipv6 = is_ipv6;
8806
8807   S (mp);
8808   W (ret);
8809   return ret;
8810 }
8811
8812 static int
8813 api_classify_set_interface_l2_tables (vat_main_t * vam)
8814 {
8815   unformat_input_t *i = vam->input;
8816   vl_api_classify_set_interface_l2_tables_t *mp;
8817   u32 sw_if_index;
8818   int sw_if_index_set;
8819   u32 ip4_table_index = ~0;
8820   u32 ip6_table_index = ~0;
8821   u32 other_table_index = ~0;
8822   u32 is_input = 1;
8823   int ret;
8824
8825   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8826     {
8827       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8828         sw_if_index_set = 1;
8829       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8830         sw_if_index_set = 1;
8831       else if (unformat (i, "ip4-table %d", &ip4_table_index))
8832         ;
8833       else if (unformat (i, "ip6-table %d", &ip6_table_index))
8834         ;
8835       else if (unformat (i, "other-table %d", &other_table_index))
8836         ;
8837       else if (unformat (i, "is-input %d", &is_input))
8838         ;
8839       else
8840         {
8841           clib_warning ("parse error '%U'", format_unformat_error, i);
8842           return -99;
8843         }
8844     }
8845
8846   if (sw_if_index_set == 0)
8847     {
8848       errmsg ("missing interface name or sw_if_index");
8849       return -99;
8850     }
8851
8852
8853   M (CLASSIFY_SET_INTERFACE_L2_TABLES, mp);
8854
8855   mp->sw_if_index = ntohl (sw_if_index);
8856   mp->ip4_table_index = ntohl (ip4_table_index);
8857   mp->ip6_table_index = ntohl (ip6_table_index);
8858   mp->other_table_index = ntohl (other_table_index);
8859   mp->is_input = (u8) is_input;
8860
8861   S (mp);
8862   W (ret);
8863   return ret;
8864 }
8865
8866 static int
8867 api_set_ipfix_exporter (vat_main_t * vam)
8868 {
8869   unformat_input_t *i = vam->input;
8870   vl_api_set_ipfix_exporter_t *mp;
8871   ip4_address_t collector_address;
8872   u8 collector_address_set = 0;
8873   u32 collector_port = ~0;
8874   ip4_address_t src_address;
8875   u8 src_address_set = 0;
8876   u32 vrf_id = ~0;
8877   u32 path_mtu = ~0;
8878   u32 template_interval = ~0;
8879   u8 udp_checksum = 0;
8880   int ret;
8881
8882   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8883     {
8884       if (unformat (i, "collector_address %U", unformat_ip4_address,
8885                     &collector_address))
8886         collector_address_set = 1;
8887       else if (unformat (i, "collector_port %d", &collector_port))
8888         ;
8889       else if (unformat (i, "src_address %U", unformat_ip4_address,
8890                          &src_address))
8891         src_address_set = 1;
8892       else if (unformat (i, "vrf_id %d", &vrf_id))
8893         ;
8894       else if (unformat (i, "path_mtu %d", &path_mtu))
8895         ;
8896       else if (unformat (i, "template_interval %d", &template_interval))
8897         ;
8898       else if (unformat (i, "udp_checksum"))
8899         udp_checksum = 1;
8900       else
8901         break;
8902     }
8903
8904   if (collector_address_set == 0)
8905     {
8906       errmsg ("collector_address required");
8907       return -99;
8908     }
8909
8910   if (src_address_set == 0)
8911     {
8912       errmsg ("src_address required");
8913       return -99;
8914     }
8915
8916   M (SET_IPFIX_EXPORTER, mp);
8917
8918   memcpy (mp->collector_address.un.ip4, collector_address.data,
8919           sizeof (collector_address.data));
8920   mp->collector_port = htons ((u16) collector_port);
8921   memcpy (mp->src_address.un.ip4, src_address.data,
8922           sizeof (src_address.data));
8923   mp->vrf_id = htonl (vrf_id);
8924   mp->path_mtu = htonl (path_mtu);
8925   mp->template_interval = htonl (template_interval);
8926   mp->udp_checksum = udp_checksum;
8927
8928   S (mp);
8929   W (ret);
8930   return ret;
8931 }
8932
8933 static int
8934 api_set_ipfix_classify_stream (vat_main_t * vam)
8935 {
8936   unformat_input_t *i = vam->input;
8937   vl_api_set_ipfix_classify_stream_t *mp;
8938   u32 domain_id = 0;
8939   u32 src_port = UDP_DST_PORT_ipfix;
8940   int ret;
8941
8942   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8943     {
8944       if (unformat (i, "domain %d", &domain_id))
8945         ;
8946       else if (unformat (i, "src_port %d", &src_port))
8947         ;
8948       else
8949         {
8950           errmsg ("unknown input `%U'", format_unformat_error, i);
8951           return -99;
8952         }
8953     }
8954
8955   M (SET_IPFIX_CLASSIFY_STREAM, mp);
8956
8957   mp->domain_id = htonl (domain_id);
8958   mp->src_port = htons ((u16) src_port);
8959
8960   S (mp);
8961   W (ret);
8962   return ret;
8963 }
8964
8965 static int
8966 api_ipfix_classify_table_add_del (vat_main_t * vam)
8967 {
8968   unformat_input_t *i = vam->input;
8969   vl_api_ipfix_classify_table_add_del_t *mp;
8970   int is_add = -1;
8971   u32 classify_table_index = ~0;
8972   u8 ip_version = 0;
8973   u8 transport_protocol = 255;
8974   int ret;
8975
8976   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8977     {
8978       if (unformat (i, "add"))
8979         is_add = 1;
8980       else if (unformat (i, "del"))
8981         is_add = 0;
8982       else if (unformat (i, "table %d", &classify_table_index))
8983         ;
8984       else if (unformat (i, "ip4"))
8985         ip_version = 4;
8986       else if (unformat (i, "ip6"))
8987         ip_version = 6;
8988       else if (unformat (i, "tcp"))
8989         transport_protocol = 6;
8990       else if (unformat (i, "udp"))
8991         transport_protocol = 17;
8992       else
8993         {
8994           errmsg ("unknown input `%U'", format_unformat_error, i);
8995           return -99;
8996         }
8997     }
8998
8999   if (is_add == -1)
9000     {
9001       errmsg ("expecting: add|del");
9002       return -99;
9003     }
9004   if (classify_table_index == ~0)
9005     {
9006       errmsg ("classifier table not specified");
9007       return -99;
9008     }
9009   if (ip_version == 0)
9010     {
9011       errmsg ("IP version not specified");
9012       return -99;
9013     }
9014
9015   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, mp);
9016
9017   mp->is_add = is_add;
9018   mp->table_id = htonl (classify_table_index);
9019   mp->ip_version = ip_version;
9020   mp->transport_protocol = transport_protocol;
9021
9022   S (mp);
9023   W (ret);
9024   return ret;
9025 }
9026
9027 static int
9028 api_get_node_index (vat_main_t * vam)
9029 {
9030   unformat_input_t *i = vam->input;
9031   vl_api_get_node_index_t *mp;
9032   u8 *name = 0;
9033   int ret;
9034
9035   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9036     {
9037       if (unformat (i, "node %s", &name))
9038         ;
9039       else
9040         break;
9041     }
9042   if (name == 0)
9043     {
9044       errmsg ("node name required");
9045       return -99;
9046     }
9047   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
9048     {
9049       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
9050       return -99;
9051     }
9052
9053   M (GET_NODE_INDEX, mp);
9054   clib_memcpy (mp->node_name, name, vec_len (name));
9055   vec_free (name);
9056
9057   S (mp);
9058   W (ret);
9059   return ret;
9060 }
9061
9062 static int
9063 api_get_next_index (vat_main_t * vam)
9064 {
9065   unformat_input_t *i = vam->input;
9066   vl_api_get_next_index_t *mp;
9067   u8 *node_name = 0, *next_node_name = 0;
9068   int ret;
9069
9070   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9071     {
9072       if (unformat (i, "node-name %s", &node_name))
9073         ;
9074       else if (unformat (i, "next-node-name %s", &next_node_name))
9075         break;
9076     }
9077
9078   if (node_name == 0)
9079     {
9080       errmsg ("node name required");
9081       return -99;
9082     }
9083   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
9084     {
9085       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
9086       return -99;
9087     }
9088
9089   if (next_node_name == 0)
9090     {
9091       errmsg ("next node name required");
9092       return -99;
9093     }
9094   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
9095     {
9096       errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
9097       return -99;
9098     }
9099
9100   M (GET_NEXT_INDEX, mp);
9101   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
9102   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
9103   vec_free (node_name);
9104   vec_free (next_node_name);
9105
9106   S (mp);
9107   W (ret);
9108   return ret;
9109 }
9110
9111 static int
9112 api_add_node_next (vat_main_t * vam)
9113 {
9114   unformat_input_t *i = vam->input;
9115   vl_api_add_node_next_t *mp;
9116   u8 *name = 0;
9117   u8 *next = 0;
9118   int ret;
9119
9120   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9121     {
9122       if (unformat (i, "node %s", &name))
9123         ;
9124       else if (unformat (i, "next %s", &next))
9125         ;
9126       else
9127         break;
9128     }
9129   if (name == 0)
9130     {
9131       errmsg ("node name required");
9132       return -99;
9133     }
9134   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
9135     {
9136       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
9137       return -99;
9138     }
9139   if (next == 0)
9140     {
9141       errmsg ("next node required");
9142       return -99;
9143     }
9144   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
9145     {
9146       errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
9147       return -99;
9148     }
9149
9150   M (ADD_NODE_NEXT, mp);
9151   clib_memcpy (mp->node_name, name, vec_len (name));
9152   clib_memcpy (mp->next_name, next, vec_len (next));
9153   vec_free (name);
9154   vec_free (next);
9155
9156   S (mp);
9157   W (ret);
9158   return ret;
9159 }
9160
9161 static void vl_api_sw_interface_tap_v2_details_t_handler
9162   (vl_api_sw_interface_tap_v2_details_t * mp)
9163 {
9164   vat_main_t *vam = &vat_main;
9165
9166   u8 *ip4 =
9167     format (0, "%U/%d", format_ip4_address, mp->host_ip4_prefix.address,
9168             mp->host_ip4_prefix.len);
9169   u8 *ip6 =
9170     format (0, "%U/%d", format_ip6_address, mp->host_ip6_prefix.address,
9171             mp->host_ip6_prefix.len);
9172
9173   print (vam->ofp,
9174          "\n%-16s %-12d %-5d %-12d %-12d %-14U %-30s %-20s %-20s %-30s 0x%-08x",
9175          mp->dev_name, ntohl (mp->sw_if_index), ntohl (mp->id),
9176          ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
9177          format_ethernet_address, mp->host_mac_addr, mp->host_namespace,
9178          mp->host_bridge, ip4, ip6, ntohl (mp->tap_flags));
9179
9180   vec_free (ip4);
9181   vec_free (ip6);
9182 }
9183
9184 static void vl_api_sw_interface_tap_v2_details_t_handler_json
9185   (vl_api_sw_interface_tap_v2_details_t * mp)
9186 {
9187   vat_main_t *vam = &vat_main;
9188   vat_json_node_t *node = NULL;
9189
9190   if (VAT_JSON_ARRAY != vam->json_tree.type)
9191     {
9192       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9193       vat_json_init_array (&vam->json_tree);
9194     }
9195   node = vat_json_array_add (&vam->json_tree);
9196
9197   vat_json_init_object (node);
9198   vat_json_object_add_uint (node, "id", ntohl (mp->id));
9199   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
9200   vat_json_object_add_uint (node, "tap_flags", ntohl (mp->tap_flags));
9201   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
9202   vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
9203   vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
9204   vat_json_object_add_string_copy (node, "host_mac_addr",
9205                                    format (0, "%U", format_ethernet_address,
9206                                            &mp->host_mac_addr));
9207   vat_json_object_add_string_copy (node, "host_namespace",
9208                                    mp->host_namespace);
9209   vat_json_object_add_string_copy (node, "host_bridge", mp->host_bridge);
9210   vat_json_object_add_string_copy (node, "host_ip4_addr",
9211                                    format (0, "%U/%d", format_ip4_address,
9212                                            mp->host_ip4_prefix.address,
9213                                            mp->host_ip4_prefix.len));
9214   vat_json_object_add_string_copy (node, "host_ip6_prefix",
9215                                    format (0, "%U/%d", format_ip6_address,
9216                                            mp->host_ip6_prefix.address,
9217                                            mp->host_ip6_prefix.len));
9218
9219 }
9220
9221 static int
9222 api_sw_interface_tap_v2_dump (vat_main_t * vam)
9223 {
9224   vl_api_sw_interface_tap_v2_dump_t *mp;
9225   vl_api_control_ping_t *mp_ping;
9226   int ret;
9227
9228   print (vam->ofp,
9229          "\n%-16s %-12s %-5s %-12s %-12s %-14s %-30s %-20s %-20s %-30s",
9230          "dev_name", "sw_if_index", "id", "rx_ring_sz", "tx_ring_sz",
9231          "host_mac_addr", "host_namespace", "host_bridge", "host_ip4_addr",
9232          "host_ip6_addr");
9233
9234   /* Get list of tap interfaces */
9235   M (SW_INTERFACE_TAP_V2_DUMP, mp);
9236   S (mp);
9237
9238   /* Use a control ping for synchronization */
9239   MPING (CONTROL_PING, mp_ping);
9240   S (mp_ping);
9241
9242   W (ret);
9243   return ret;
9244 }
9245
9246 static void vl_api_sw_interface_virtio_pci_details_t_handler
9247   (vl_api_sw_interface_virtio_pci_details_t * mp)
9248 {
9249   vat_main_t *vam = &vat_main;
9250
9251   typedef union
9252   {
9253     struct
9254     {
9255       u16 domain;
9256       u8 bus;
9257       u8 slot:5;
9258       u8 function:3;
9259     };
9260     u32 as_u32;
9261   } pci_addr_t;
9262   pci_addr_t addr;
9263
9264   addr.domain = ntohs (mp->pci_addr.domain);
9265   addr.bus = mp->pci_addr.bus;
9266   addr.slot = mp->pci_addr.slot;
9267   addr.function = mp->pci_addr.function;
9268
9269   u8 *pci_addr = format (0, "%04x:%02x:%02x.%x", addr.domain, addr.bus,
9270                          addr.slot, addr.function);
9271
9272   print (vam->ofp,
9273          "\n%-12s %-12d %-12d %-12d %-17U 0x%-08llx",
9274          pci_addr, ntohl (mp->sw_if_index),
9275          ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
9276          format_ethernet_address, mp->mac_addr,
9277          clib_net_to_host_u64 (mp->features));
9278   vec_free (pci_addr);
9279 }
9280
9281 static void vl_api_sw_interface_virtio_pci_details_t_handler_json
9282   (vl_api_sw_interface_virtio_pci_details_t * mp)
9283 {
9284   vat_main_t *vam = &vat_main;
9285   vat_json_node_t *node = NULL;
9286   vlib_pci_addr_t pci_addr;
9287
9288   if (VAT_JSON_ARRAY != vam->json_tree.type)
9289     {
9290       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9291       vat_json_init_array (&vam->json_tree);
9292     }
9293   node = vat_json_array_add (&vam->json_tree);
9294
9295   pci_addr.domain = ntohs (mp->pci_addr.domain);
9296   pci_addr.bus = mp->pci_addr.bus;
9297   pci_addr.slot = mp->pci_addr.slot;
9298   pci_addr.function = mp->pci_addr.function;
9299
9300   vat_json_init_object (node);
9301   vat_json_object_add_uint (node, "pci-addr", pci_addr.as_u32);
9302   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
9303   vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
9304   vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
9305   vat_json_object_add_uint (node, "features",
9306                             clib_net_to_host_u64 (mp->features));
9307   vat_json_object_add_string_copy (node, "mac_addr",
9308                                    format (0, "%U", format_ethernet_address,
9309                                            &mp->mac_addr));
9310 }
9311
9312 static int
9313 api_sw_interface_virtio_pci_dump (vat_main_t * vam)
9314 {
9315   vl_api_sw_interface_virtio_pci_dump_t *mp;
9316   vl_api_control_ping_t *mp_ping;
9317   int ret;
9318
9319   print (vam->ofp,
9320          "\n%-12s %-12s %-12s %-12s %-17s %-08s",
9321          "pci_addr", "sw_if_index", "rx_ring_sz", "tx_ring_sz",
9322          "mac_addr", "features");
9323
9324   /* Get list of tap interfaces */
9325   M (SW_INTERFACE_VIRTIO_PCI_DUMP, mp);
9326   S (mp);
9327
9328   /* Use a control ping for synchronization */
9329   MPING (CONTROL_PING, mp_ping);
9330   S (mp_ping);
9331
9332   W (ret);
9333   return ret;
9334 }
9335
9336 static int
9337 api_vxlan_offload_rx (vat_main_t * vam)
9338 {
9339   unformat_input_t *line_input = vam->input;
9340   vl_api_vxlan_offload_rx_t *mp;
9341   u32 hw_if_index = ~0, rx_if_index = ~0;
9342   u8 is_add = 1;
9343   int ret;
9344
9345   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
9346     {
9347       if (unformat (line_input, "del"))
9348         is_add = 0;
9349       else if (unformat (line_input, "hw %U", api_unformat_hw_if_index, vam,
9350                          &hw_if_index))
9351         ;
9352       else if (unformat (line_input, "hw hw_if_index %u", &hw_if_index))
9353         ;
9354       else if (unformat (line_input, "rx %U", api_unformat_sw_if_index, vam,
9355                          &rx_if_index))
9356         ;
9357       else if (unformat (line_input, "rx sw_if_index %u", &rx_if_index))
9358         ;
9359       else
9360         {
9361           errmsg ("parse error '%U'", format_unformat_error, line_input);
9362           return -99;
9363         }
9364     }
9365
9366   if (hw_if_index == ~0)
9367     {
9368       errmsg ("no hw interface");
9369       return -99;
9370     }
9371
9372   if (rx_if_index == ~0)
9373     {
9374       errmsg ("no rx tunnel");
9375       return -99;
9376     }
9377
9378   M (VXLAN_OFFLOAD_RX, mp);
9379
9380   mp->hw_if_index = ntohl (hw_if_index);
9381   mp->sw_if_index = ntohl (rx_if_index);
9382   mp->enable = is_add;
9383
9384   S (mp);
9385   W (ret);
9386   return ret;
9387 }
9388
9389 static uword unformat_vxlan_decap_next
9390   (unformat_input_t * input, va_list * args)
9391 {
9392   u32 *result = va_arg (*args, u32 *);
9393   u32 tmp;
9394
9395   if (unformat (input, "l2"))
9396     *result = VXLAN_INPUT_NEXT_L2_INPUT;
9397   else if (unformat (input, "%d", &tmp))
9398     *result = tmp;
9399   else
9400     return 0;
9401   return 1;
9402 }
9403
9404 static int
9405 api_vxlan_add_del_tunnel (vat_main_t * vam)
9406 {
9407   unformat_input_t *line_input = vam->input;
9408   vl_api_vxlan_add_del_tunnel_t *mp;
9409   ip46_address_t src, dst;
9410   u8 is_add = 1;
9411   u8 ipv4_set = 0, ipv6_set = 0;
9412   u8 src_set = 0;
9413   u8 dst_set = 0;
9414   u8 grp_set = 0;
9415   u32 instance = ~0;
9416   u32 mcast_sw_if_index = ~0;
9417   u32 encap_vrf_id = 0;
9418   u32 decap_next_index = ~0;
9419   u32 vni = 0;
9420   int ret;
9421
9422   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
9423   clib_memset (&src, 0, sizeof src);
9424   clib_memset (&dst, 0, sizeof dst);
9425
9426   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
9427     {
9428       if (unformat (line_input, "del"))
9429         is_add = 0;
9430       else if (unformat (line_input, "instance %d", &instance))
9431         ;
9432       else
9433         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
9434         {
9435           ipv4_set = 1;
9436           src_set = 1;
9437         }
9438       else
9439         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
9440         {
9441           ipv4_set = 1;
9442           dst_set = 1;
9443         }
9444       else
9445         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
9446         {
9447           ipv6_set = 1;
9448           src_set = 1;
9449         }
9450       else
9451         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
9452         {
9453           ipv6_set = 1;
9454           dst_set = 1;
9455         }
9456       else if (unformat (line_input, "group %U %U",
9457                          unformat_ip4_address, &dst.ip4,
9458                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
9459         {
9460           grp_set = dst_set = 1;
9461           ipv4_set = 1;
9462         }
9463       else if (unformat (line_input, "group %U",
9464                          unformat_ip4_address, &dst.ip4))
9465         {
9466           grp_set = dst_set = 1;
9467           ipv4_set = 1;
9468         }
9469       else if (unformat (line_input, "group %U %U",
9470                          unformat_ip6_address, &dst.ip6,
9471                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
9472         {
9473           grp_set = dst_set = 1;
9474           ipv6_set = 1;
9475         }
9476       else if (unformat (line_input, "group %U",
9477                          unformat_ip6_address, &dst.ip6))
9478         {
9479           grp_set = dst_set = 1;
9480           ipv6_set = 1;
9481         }
9482       else
9483         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
9484         ;
9485       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
9486         ;
9487       else if (unformat (line_input, "decap-next %U",
9488                          unformat_vxlan_decap_next, &decap_next_index))
9489         ;
9490       else if (unformat (line_input, "vni %d", &vni))
9491         ;
9492       else
9493         {
9494           errmsg ("parse error '%U'", format_unformat_error, line_input);
9495           return -99;
9496         }
9497     }
9498
9499   if (src_set == 0)
9500     {
9501       errmsg ("tunnel src address not specified");
9502       return -99;
9503     }
9504   if (dst_set == 0)
9505     {
9506       errmsg ("tunnel dst address not specified");
9507       return -99;
9508     }
9509
9510   if (grp_set && !ip46_address_is_multicast (&dst))
9511     {
9512       errmsg ("tunnel group address not multicast");
9513       return -99;
9514     }
9515   if (grp_set && mcast_sw_if_index == ~0)
9516     {
9517       errmsg ("tunnel nonexistent multicast device");
9518       return -99;
9519     }
9520   if (grp_set == 0 && ip46_address_is_multicast (&dst))
9521     {
9522       errmsg ("tunnel dst address must be unicast");
9523       return -99;
9524     }
9525
9526
9527   if (ipv4_set && ipv6_set)
9528     {
9529       errmsg ("both IPv4 and IPv6 addresses specified");
9530       return -99;
9531     }
9532
9533   if ((vni == 0) || (vni >> 24))
9534     {
9535       errmsg ("vni not specified or out of range");
9536       return -99;
9537     }
9538
9539   M (VXLAN_ADD_DEL_TUNNEL, mp);
9540
9541   if (ipv6_set)
9542     {
9543       clib_memcpy (mp->src_address.un.ip6, &src.ip6, sizeof (src.ip6));
9544       clib_memcpy (mp->dst_address.un.ip6, &dst.ip6, sizeof (dst.ip6));
9545     }
9546   else
9547     {
9548       clib_memcpy (mp->src_address.un.ip4, &src.ip4, sizeof (src.ip4));
9549       clib_memcpy (mp->dst_address.un.ip4, &dst.ip4, sizeof (dst.ip4));
9550     }
9551   mp->src_address.af = ipv6_set;
9552   mp->dst_address.af = ipv6_set;
9553
9554   mp->instance = htonl (instance);
9555   mp->encap_vrf_id = ntohl (encap_vrf_id);
9556   mp->decap_next_index = ntohl (decap_next_index);
9557   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
9558   mp->vni = ntohl (vni);
9559   mp->is_add = is_add;
9560
9561   S (mp);
9562   W (ret);
9563   return ret;
9564 }
9565
9566 static void vl_api_vxlan_tunnel_details_t_handler
9567   (vl_api_vxlan_tunnel_details_t * mp)
9568 {
9569   vat_main_t *vam = &vat_main;
9570   ip46_address_t src =
9571     to_ip46 (mp->dst_address.af, (u8 *) & mp->dst_address.un);
9572   ip46_address_t dst =
9573     to_ip46 (mp->dst_address.af, (u8 *) & mp->src_address.un);
9574
9575   print (vam->ofp, "%11d%11d%24U%24U%14d%18d%13d%19d",
9576          ntohl (mp->sw_if_index),
9577          ntohl (mp->instance),
9578          format_ip46_address, &src, IP46_TYPE_ANY,
9579          format_ip46_address, &dst, IP46_TYPE_ANY,
9580          ntohl (mp->encap_vrf_id),
9581          ntohl (mp->decap_next_index), ntohl (mp->vni),
9582          ntohl (mp->mcast_sw_if_index));
9583 }
9584
9585 static void vl_api_vxlan_tunnel_details_t_handler_json
9586   (vl_api_vxlan_tunnel_details_t * mp)
9587 {
9588   vat_main_t *vam = &vat_main;
9589   vat_json_node_t *node = NULL;
9590
9591   if (VAT_JSON_ARRAY != vam->json_tree.type)
9592     {
9593       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9594       vat_json_init_array (&vam->json_tree);
9595     }
9596   node = vat_json_array_add (&vam->json_tree);
9597
9598   vat_json_init_object (node);
9599   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
9600
9601   vat_json_object_add_uint (node, "instance", ntohl (mp->instance));
9602
9603   if (mp->src_address.af)
9604     {
9605       struct in6_addr ip6;
9606
9607       clib_memcpy (&ip6, mp->src_address.un.ip6, sizeof (ip6));
9608       vat_json_object_add_ip6 (node, "src_address", ip6);
9609       clib_memcpy (&ip6, mp->dst_address.un.ip6, sizeof (ip6));
9610       vat_json_object_add_ip6 (node, "dst_address", ip6);
9611     }
9612   else
9613     {
9614       struct in_addr ip4;
9615
9616       clib_memcpy (&ip4, mp->src_address.un.ip4, sizeof (ip4));
9617       vat_json_object_add_ip4 (node, "src_address", ip4);
9618       clib_memcpy (&ip4, mp->dst_address.un.ip4, sizeof (ip4));
9619       vat_json_object_add_ip4 (node, "dst_address", ip4);
9620     }
9621   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
9622   vat_json_object_add_uint (node, "decap_next_index",
9623                             ntohl (mp->decap_next_index));
9624   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
9625   vat_json_object_add_uint (node, "mcast_sw_if_index",
9626                             ntohl (mp->mcast_sw_if_index));
9627 }
9628
9629 static int
9630 api_vxlan_tunnel_dump (vat_main_t * vam)
9631 {
9632   unformat_input_t *i = vam->input;
9633   vl_api_vxlan_tunnel_dump_t *mp;
9634   vl_api_control_ping_t *mp_ping;
9635   u32 sw_if_index;
9636   u8 sw_if_index_set = 0;
9637   int ret;
9638
9639   /* Parse args required to build the message */
9640   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9641     {
9642       if (unformat (i, "sw_if_index %d", &sw_if_index))
9643         sw_if_index_set = 1;
9644       else
9645         break;
9646     }
9647
9648   if (sw_if_index_set == 0)
9649     {
9650       sw_if_index = ~0;
9651     }
9652
9653   if (!vam->json_output)
9654     {
9655       print (vam->ofp, "%11s%11s%24s%24s%14s%18s%13s%19s",
9656              "sw_if_index", "instance", "src_address", "dst_address",
9657              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
9658     }
9659
9660   /* Get list of vxlan-tunnel interfaces */
9661   M (VXLAN_TUNNEL_DUMP, mp);
9662
9663   mp->sw_if_index = htonl (sw_if_index);
9664
9665   S (mp);
9666
9667   /* Use a control ping for synchronization */
9668   MPING (CONTROL_PING, mp_ping);
9669   S (mp_ping);
9670
9671   W (ret);
9672   return ret;
9673 }
9674
9675 static int
9676 api_l2_fib_clear_table (vat_main_t * vam)
9677 {
9678 //  unformat_input_t * i = vam->input;
9679   vl_api_l2_fib_clear_table_t *mp;
9680   int ret;
9681
9682   M (L2_FIB_CLEAR_TABLE, mp);
9683
9684   S (mp);
9685   W (ret);
9686   return ret;
9687 }
9688
9689 static int
9690 api_l2_interface_efp_filter (vat_main_t * vam)
9691 {
9692   unformat_input_t *i = vam->input;
9693   vl_api_l2_interface_efp_filter_t *mp;
9694   u32 sw_if_index;
9695   u8 enable = 1;
9696   u8 sw_if_index_set = 0;
9697   int ret;
9698
9699   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9700     {
9701       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9702         sw_if_index_set = 1;
9703       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9704         sw_if_index_set = 1;
9705       else if (unformat (i, "enable"))
9706         enable = 1;
9707       else if (unformat (i, "disable"))
9708         enable = 0;
9709       else
9710         {
9711           clib_warning ("parse error '%U'", format_unformat_error, i);
9712           return -99;
9713         }
9714     }
9715
9716   if (sw_if_index_set == 0)
9717     {
9718       errmsg ("missing sw_if_index");
9719       return -99;
9720     }
9721
9722   M (L2_INTERFACE_EFP_FILTER, mp);
9723
9724   mp->sw_if_index = ntohl (sw_if_index);
9725   mp->enable_disable = enable;
9726
9727   S (mp);
9728   W (ret);
9729   return ret;
9730 }
9731
9732 #define foreach_vtr_op                          \
9733 _("disable",  L2_VTR_DISABLED)                  \
9734 _("push-1",  L2_VTR_PUSH_1)                     \
9735 _("push-2",  L2_VTR_PUSH_2)                     \
9736 _("pop-1",  L2_VTR_POP_1)                       \
9737 _("pop-2",  L2_VTR_POP_2)                       \
9738 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
9739 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
9740 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
9741 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
9742
9743 static int
9744 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
9745 {
9746   unformat_input_t *i = vam->input;
9747   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
9748   u32 sw_if_index;
9749   u8 sw_if_index_set = 0;
9750   u8 vtr_op_set = 0;
9751   u32 vtr_op = 0;
9752   u32 push_dot1q = 1;
9753   u32 tag1 = ~0;
9754   u32 tag2 = ~0;
9755   int ret;
9756
9757   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9758     {
9759       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9760         sw_if_index_set = 1;
9761       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9762         sw_if_index_set = 1;
9763       else if (unformat (i, "vtr_op %d", &vtr_op))
9764         vtr_op_set = 1;
9765 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
9766       foreach_vtr_op
9767 #undef _
9768         else if (unformat (i, "push_dot1q %d", &push_dot1q))
9769         ;
9770       else if (unformat (i, "tag1 %d", &tag1))
9771         ;
9772       else if (unformat (i, "tag2 %d", &tag2))
9773         ;
9774       else
9775         {
9776           clib_warning ("parse error '%U'", format_unformat_error, i);
9777           return -99;
9778         }
9779     }
9780
9781   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
9782     {
9783       errmsg ("missing vtr operation or sw_if_index");
9784       return -99;
9785     }
9786
9787   M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
9788   mp->sw_if_index = ntohl (sw_if_index);
9789   mp->vtr_op = ntohl (vtr_op);
9790   mp->push_dot1q = ntohl (push_dot1q);
9791   mp->tag1 = ntohl (tag1);
9792   mp->tag2 = ntohl (tag2);
9793
9794   S (mp);
9795   W (ret);
9796   return ret;
9797 }
9798
9799 static int
9800 api_create_vhost_user_if (vat_main_t * vam)
9801 {
9802   unformat_input_t *i = vam->input;
9803   vl_api_create_vhost_user_if_t *mp;
9804   u8 *file_name;
9805   u8 is_server = 0;
9806   u8 file_name_set = 0;
9807   u32 custom_dev_instance = ~0;
9808   u8 hwaddr[6];
9809   u8 use_custom_mac = 0;
9810   u8 disable_mrg_rxbuf = 0;
9811   u8 disable_indirect_desc = 0;
9812   u8 *tag = 0;
9813   u8 enable_gso = 0;
9814   u8 enable_packed = 0;
9815   int ret;
9816
9817   /* Shut up coverity */
9818   clib_memset (hwaddr, 0, sizeof (hwaddr));
9819
9820   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9821     {
9822       if (unformat (i, "socket %s", &file_name))
9823         {
9824           file_name_set = 1;
9825         }
9826       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
9827         ;
9828       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
9829         use_custom_mac = 1;
9830       else if (unformat (i, "server"))
9831         is_server = 1;
9832       else if (unformat (i, "disable_mrg_rxbuf"))
9833         disable_mrg_rxbuf = 1;
9834       else if (unformat (i, "disable_indirect_desc"))
9835         disable_indirect_desc = 1;
9836       else if (unformat (i, "gso"))
9837         enable_gso = 1;
9838       else if (unformat (i, "packed"))
9839         enable_packed = 1;
9840       else if (unformat (i, "tag %s", &tag))
9841         ;
9842       else
9843         break;
9844     }
9845
9846   if (file_name_set == 0)
9847     {
9848       errmsg ("missing socket file name");
9849       return -99;
9850     }
9851
9852   if (vec_len (file_name) > 255)
9853     {
9854       errmsg ("socket file name too long");
9855       return -99;
9856     }
9857   vec_add1 (file_name, 0);
9858
9859   M (CREATE_VHOST_USER_IF, mp);
9860
9861   mp->is_server = is_server;
9862   mp->disable_mrg_rxbuf = disable_mrg_rxbuf;
9863   mp->disable_indirect_desc = disable_indirect_desc;
9864   mp->enable_gso = enable_gso;
9865   mp->enable_packed = enable_packed;
9866   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
9867   vec_free (file_name);
9868   if (custom_dev_instance != ~0)
9869     {
9870       mp->renumber = 1;
9871       mp->custom_dev_instance = ntohl (custom_dev_instance);
9872     }
9873
9874   mp->use_custom_mac = use_custom_mac;
9875   clib_memcpy (mp->mac_address, hwaddr, 6);
9876   if (tag)
9877     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
9878   vec_free (tag);
9879
9880   S (mp);
9881   W (ret);
9882   return ret;
9883 }
9884
9885 static int
9886 api_modify_vhost_user_if (vat_main_t * vam)
9887 {
9888   unformat_input_t *i = vam->input;
9889   vl_api_modify_vhost_user_if_t *mp;
9890   u8 *file_name;
9891   u8 is_server = 0;
9892   u8 file_name_set = 0;
9893   u32 custom_dev_instance = ~0;
9894   u8 sw_if_index_set = 0;
9895   u32 sw_if_index = (u32) ~ 0;
9896   u8 enable_gso = 0;
9897   u8 enable_packed = 0;
9898   int ret;
9899
9900   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9901     {
9902       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9903         sw_if_index_set = 1;
9904       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9905         sw_if_index_set = 1;
9906       else if (unformat (i, "socket %s", &file_name))
9907         {
9908           file_name_set = 1;
9909         }
9910       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
9911         ;
9912       else if (unformat (i, "server"))
9913         is_server = 1;
9914       else if (unformat (i, "gso"))
9915         enable_gso = 1;
9916       else if (unformat (i, "packed"))
9917         enable_packed = 1;
9918       else
9919         break;
9920     }
9921
9922   if (sw_if_index_set == 0)
9923     {
9924       errmsg ("missing sw_if_index or interface name");
9925       return -99;
9926     }
9927
9928   if (file_name_set == 0)
9929     {
9930       errmsg ("missing socket file name");
9931       return -99;
9932     }
9933
9934   if (vec_len (file_name) > 255)
9935     {
9936       errmsg ("socket file name too long");
9937       return -99;
9938     }
9939   vec_add1 (file_name, 0);
9940
9941   M (MODIFY_VHOST_USER_IF, mp);
9942
9943   mp->sw_if_index = ntohl (sw_if_index);
9944   mp->is_server = is_server;
9945   mp->enable_gso = enable_gso;
9946   mp->enable_packed = enable_packed;
9947   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
9948   vec_free (file_name);
9949   if (custom_dev_instance != ~0)
9950     {
9951       mp->renumber = 1;
9952       mp->custom_dev_instance = ntohl (custom_dev_instance);
9953     }
9954
9955   S (mp);
9956   W (ret);
9957   return ret;
9958 }
9959
9960 static int
9961 api_delete_vhost_user_if (vat_main_t * vam)
9962 {
9963   unformat_input_t *i = vam->input;
9964   vl_api_delete_vhost_user_if_t *mp;
9965   u32 sw_if_index = ~0;
9966   u8 sw_if_index_set = 0;
9967   int ret;
9968
9969   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9970     {
9971       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9972         sw_if_index_set = 1;
9973       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9974         sw_if_index_set = 1;
9975       else
9976         break;
9977     }
9978
9979   if (sw_if_index_set == 0)
9980     {
9981       errmsg ("missing sw_if_index or interface name");
9982       return -99;
9983     }
9984
9985
9986   M (DELETE_VHOST_USER_IF, mp);
9987
9988   mp->sw_if_index = ntohl (sw_if_index);
9989
9990   S (mp);
9991   W (ret);
9992   return ret;
9993 }
9994
9995 static void vl_api_sw_interface_vhost_user_details_t_handler
9996   (vl_api_sw_interface_vhost_user_details_t * mp)
9997 {
9998   vat_main_t *vam = &vat_main;
9999   u64 features;
10000
10001   features =
10002     clib_net_to_host_u32 (mp->features_first_32) | ((u64)
10003                                                     clib_net_to_host_u32
10004                                                     (mp->features_last_32) <<
10005                                                     32);
10006
10007   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s",
10008          (char *) mp->interface_name,
10009          ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
10010          features, mp->is_server,
10011          ntohl (mp->num_regions), (char *) mp->sock_filename);
10012   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
10013 }
10014
10015 static void vl_api_sw_interface_vhost_user_details_t_handler_json
10016   (vl_api_sw_interface_vhost_user_details_t * mp)
10017 {
10018   vat_main_t *vam = &vat_main;
10019   vat_json_node_t *node = NULL;
10020
10021   if (VAT_JSON_ARRAY != vam->json_tree.type)
10022     {
10023       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10024       vat_json_init_array (&vam->json_tree);
10025     }
10026   node = vat_json_array_add (&vam->json_tree);
10027
10028   vat_json_init_object (node);
10029   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10030   vat_json_object_add_string_copy (node, "interface_name",
10031                                    mp->interface_name);
10032   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
10033                             ntohl (mp->virtio_net_hdr_sz));
10034   vat_json_object_add_uint (node, "features_first_32",
10035                             clib_net_to_host_u32 (mp->features_first_32));
10036   vat_json_object_add_uint (node, "features_last_32",
10037                             clib_net_to_host_u32 (mp->features_last_32));
10038   vat_json_object_add_uint (node, "is_server", mp->is_server);
10039   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
10040   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
10041   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
10042 }
10043
10044 static int
10045 api_sw_interface_vhost_user_dump (vat_main_t * vam)
10046 {
10047   unformat_input_t *i = vam->input;
10048   vl_api_sw_interface_vhost_user_dump_t *mp;
10049   vl_api_control_ping_t *mp_ping;
10050   int ret;
10051   u32 sw_if_index = ~0;
10052
10053   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10054     {
10055       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10056         ;
10057       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10058         ;
10059       else
10060         break;
10061     }
10062
10063   print (vam->ofp,
10064          "Interface name            idx hdr_sz features server regions filename");
10065
10066   /* Get list of vhost-user interfaces */
10067   M (SW_INTERFACE_VHOST_USER_DUMP, mp);
10068   mp->sw_if_index = ntohl (sw_if_index);
10069   S (mp);
10070
10071   /* Use a control ping for synchronization */
10072   MPING (CONTROL_PING, mp_ping);
10073   S (mp_ping);
10074
10075   W (ret);
10076   return ret;
10077 }
10078
10079 static int
10080 api_show_version (vat_main_t * vam)
10081 {
10082   vl_api_show_version_t *mp;
10083   int ret;
10084
10085   M (SHOW_VERSION, mp);
10086
10087   S (mp);
10088   W (ret);
10089   return ret;
10090 }
10091
10092
10093 static int
10094 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
10095 {
10096   unformat_input_t *line_input = vam->input;
10097   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
10098   ip46_address_t local, remote;
10099   u8 is_add = 1;
10100   u8 local_set = 0;
10101   u8 remote_set = 0;
10102   u8 grp_set = 0;
10103   u32 mcast_sw_if_index = ~0;
10104   u32 encap_vrf_id = 0;
10105   u32 decap_vrf_id = 0;
10106   u8 protocol = ~0;
10107   u32 vni;
10108   u8 vni_set = 0;
10109   int ret;
10110
10111   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10112     {
10113       if (unformat (line_input, "del"))
10114         is_add = 0;
10115       else if (unformat (line_input, "local %U",
10116                          unformat_ip46_address, &local))
10117         {
10118           local_set = 1;
10119         }
10120       else if (unformat (line_input, "remote %U",
10121                          unformat_ip46_address, &remote))
10122         {
10123           remote_set = 1;
10124         }
10125       else if (unformat (line_input, "group %U %U",
10126                          unformat_ip46_address, &remote,
10127                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
10128         {
10129           grp_set = remote_set = 1;
10130         }
10131       else if (unformat (line_input, "group %U",
10132                          unformat_ip46_address, &remote))
10133         {
10134           grp_set = remote_set = 1;
10135         }
10136       else
10137         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
10138         ;
10139       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
10140         ;
10141       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
10142         ;
10143       else if (unformat (line_input, "vni %d", &vni))
10144         vni_set = 1;
10145       else if (unformat (line_input, "next-ip4"))
10146         protocol = 1;
10147       else if (unformat (line_input, "next-ip6"))
10148         protocol = 2;
10149       else if (unformat (line_input, "next-ethernet"))
10150         protocol = 3;
10151       else if (unformat (line_input, "next-nsh"))
10152         protocol = 4;
10153       else
10154         {
10155           errmsg ("parse error '%U'", format_unformat_error, line_input);
10156           return -99;
10157         }
10158     }
10159
10160   if (local_set == 0)
10161     {
10162       errmsg ("tunnel local address not specified");
10163       return -99;
10164     }
10165   if (remote_set == 0)
10166     {
10167       errmsg ("tunnel remote address not specified");
10168       return -99;
10169     }
10170   if (grp_set && mcast_sw_if_index == ~0)
10171     {
10172       errmsg ("tunnel nonexistent multicast device");
10173       return -99;
10174     }
10175   if (ip46_address_is_ip4 (&local) != ip46_address_is_ip4 (&remote))
10176     {
10177       errmsg ("both IPv4 and IPv6 addresses specified");
10178       return -99;
10179     }
10180
10181   if (vni_set == 0)
10182     {
10183       errmsg ("vni not specified");
10184       return -99;
10185     }
10186
10187   M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
10188
10189   ip_address_encode (&local,
10190                      ip46_address_is_ip4 (&local) ? IP46_TYPE_IP4 :
10191                      IP46_TYPE_IP6, &mp->local);
10192   ip_address_encode (&remote,
10193                      ip46_address_is_ip4 (&remote) ? IP46_TYPE_IP4 :
10194                      IP46_TYPE_IP6, &mp->remote);
10195
10196   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
10197   mp->encap_vrf_id = ntohl (encap_vrf_id);
10198   mp->decap_vrf_id = ntohl (decap_vrf_id);
10199   mp->protocol = protocol;
10200   mp->vni = ntohl (vni);
10201   mp->is_add = is_add;
10202
10203   S (mp);
10204   W (ret);
10205   return ret;
10206 }
10207
10208 static void vl_api_vxlan_gpe_tunnel_details_t_handler
10209   (vl_api_vxlan_gpe_tunnel_details_t * mp)
10210 {
10211   vat_main_t *vam = &vat_main;
10212   ip46_address_t local, remote;
10213
10214   ip_address_decode (&mp->local, &local);
10215   ip_address_decode (&mp->remote, &remote);
10216
10217   print (vam->ofp, "%11d%24U%24U%13d%12d%19d%14d%14d",
10218          ntohl (mp->sw_if_index),
10219          format_ip46_address, &local, IP46_TYPE_ANY,
10220          format_ip46_address, &remote, IP46_TYPE_ANY,
10221          ntohl (mp->vni), mp->protocol,
10222          ntohl (mp->mcast_sw_if_index),
10223          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
10224 }
10225
10226
10227 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
10228   (vl_api_vxlan_gpe_tunnel_details_t * mp)
10229 {
10230   vat_main_t *vam = &vat_main;
10231   vat_json_node_t *node = NULL;
10232   struct in_addr ip4;
10233   struct in6_addr ip6;
10234   ip46_address_t local, remote;
10235
10236   ip_address_decode (&mp->local, &local);
10237   ip_address_decode (&mp->remote, &remote);
10238
10239   if (VAT_JSON_ARRAY != vam->json_tree.type)
10240     {
10241       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10242       vat_json_init_array (&vam->json_tree);
10243     }
10244   node = vat_json_array_add (&vam->json_tree);
10245
10246   vat_json_init_object (node);
10247   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10248   if (ip46_address_is_ip4 (&local))
10249     {
10250       clib_memcpy (&ip4, &local.ip4, sizeof (ip4));
10251       vat_json_object_add_ip4 (node, "local", ip4);
10252       clib_memcpy (&ip4, &remote.ip4, sizeof (ip4));
10253       vat_json_object_add_ip4 (node, "remote", ip4);
10254     }
10255   else
10256     {
10257       clib_memcpy (&ip6, &local.ip6, sizeof (ip6));
10258       vat_json_object_add_ip6 (node, "local", ip6);
10259       clib_memcpy (&ip6, &remote.ip6, sizeof (ip6));
10260       vat_json_object_add_ip6 (node, "remote", ip6);
10261     }
10262   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
10263   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
10264   vat_json_object_add_uint (node, "mcast_sw_if_index",
10265                             ntohl (mp->mcast_sw_if_index));
10266   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
10267   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
10268   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
10269 }
10270
10271 static int
10272 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
10273 {
10274   unformat_input_t *i = vam->input;
10275   vl_api_vxlan_gpe_tunnel_dump_t *mp;
10276   vl_api_control_ping_t *mp_ping;
10277   u32 sw_if_index;
10278   u8 sw_if_index_set = 0;
10279   int ret;
10280
10281   /* Parse args required to build the message */
10282   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10283     {
10284       if (unformat (i, "sw_if_index %d", &sw_if_index))
10285         sw_if_index_set = 1;
10286       else
10287         break;
10288     }
10289
10290   if (sw_if_index_set == 0)
10291     {
10292       sw_if_index = ~0;
10293     }
10294
10295   if (!vam->json_output)
10296     {
10297       print (vam->ofp, "%11s%24s%24s%13s%15s%19s%14s%14s",
10298              "sw_if_index", "local", "remote", "vni",
10299              "protocol", "mcast_sw_if_index", "encap_vrf_id", "decap_vrf_id");
10300     }
10301
10302   /* Get list of vxlan-tunnel interfaces */
10303   M (VXLAN_GPE_TUNNEL_DUMP, mp);
10304
10305   mp->sw_if_index = htonl (sw_if_index);
10306
10307   S (mp);
10308
10309   /* Use a control ping for synchronization */
10310   MPING (CONTROL_PING, mp_ping);
10311   S (mp_ping);
10312
10313   W (ret);
10314   return ret;
10315 }
10316
10317 static void vl_api_l2_fib_table_details_t_handler
10318   (vl_api_l2_fib_table_details_t * mp)
10319 {
10320   vat_main_t *vam = &vat_main;
10321
10322   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
10323          "       %d       %d     %d",
10324          ntohl (mp->bd_id), format_ethernet_address, mp->mac,
10325          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
10326          mp->bvi_mac);
10327 }
10328
10329 static void vl_api_l2_fib_table_details_t_handler_json
10330   (vl_api_l2_fib_table_details_t * mp)
10331 {
10332   vat_main_t *vam = &vat_main;
10333   vat_json_node_t *node = NULL;
10334
10335   if (VAT_JSON_ARRAY != vam->json_tree.type)
10336     {
10337       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10338       vat_json_init_array (&vam->json_tree);
10339     }
10340   node = vat_json_array_add (&vam->json_tree);
10341
10342   vat_json_init_object (node);
10343   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
10344   vat_json_object_add_bytes (node, "mac", mp->mac, 6);
10345   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10346   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
10347   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
10348   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
10349 }
10350
10351 static int
10352 api_l2_fib_table_dump (vat_main_t * vam)
10353 {
10354   unformat_input_t *i = vam->input;
10355   vl_api_l2_fib_table_dump_t *mp;
10356   vl_api_control_ping_t *mp_ping;
10357   u32 bd_id;
10358   u8 bd_id_set = 0;
10359   int ret;
10360
10361   /* Parse args required to build the message */
10362   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10363     {
10364       if (unformat (i, "bd_id %d", &bd_id))
10365         bd_id_set = 1;
10366       else
10367         break;
10368     }
10369
10370   if (bd_id_set == 0)
10371     {
10372       errmsg ("missing bridge domain");
10373       return -99;
10374     }
10375
10376   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
10377
10378   /* Get list of l2 fib entries */
10379   M (L2_FIB_TABLE_DUMP, mp);
10380
10381   mp->bd_id = ntohl (bd_id);
10382   S (mp);
10383
10384   /* Use a control ping for synchronization */
10385   MPING (CONTROL_PING, mp_ping);
10386   S (mp_ping);
10387
10388   W (ret);
10389   return ret;
10390 }
10391
10392
10393 static int
10394 api_interface_name_renumber (vat_main_t * vam)
10395 {
10396   unformat_input_t *line_input = vam->input;
10397   vl_api_interface_name_renumber_t *mp;
10398   u32 sw_if_index = ~0;
10399   u32 new_show_dev_instance = ~0;
10400   int ret;
10401
10402   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10403     {
10404       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
10405                     &sw_if_index))
10406         ;
10407       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
10408         ;
10409       else if (unformat (line_input, "new_show_dev_instance %d",
10410                          &new_show_dev_instance))
10411         ;
10412       else
10413         break;
10414     }
10415
10416   if (sw_if_index == ~0)
10417     {
10418       errmsg ("missing interface name or sw_if_index");
10419       return -99;
10420     }
10421
10422   if (new_show_dev_instance == ~0)
10423     {
10424       errmsg ("missing new_show_dev_instance");
10425       return -99;
10426     }
10427
10428   M (INTERFACE_NAME_RENUMBER, mp);
10429
10430   mp->sw_if_index = ntohl (sw_if_index);
10431   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
10432
10433   S (mp);
10434   W (ret);
10435   return ret;
10436 }
10437
10438 static int
10439 api_want_l2_macs_events (vat_main_t * vam)
10440 {
10441   unformat_input_t *line_input = vam->input;
10442   vl_api_want_l2_macs_events_t *mp;
10443   u8 enable_disable = 1;
10444   u32 scan_delay = 0;
10445   u32 max_macs_in_event = 0;
10446   u32 learn_limit = 0;
10447   int ret;
10448
10449   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10450     {
10451       if (unformat (line_input, "learn-limit %d", &learn_limit))
10452         ;
10453       else if (unformat (line_input, "scan-delay %d", &scan_delay))
10454         ;
10455       else if (unformat (line_input, "max-entries %d", &max_macs_in_event))
10456         ;
10457       else if (unformat (line_input, "disable"))
10458         enable_disable = 0;
10459       else
10460         break;
10461     }
10462
10463   M (WANT_L2_MACS_EVENTS, mp);
10464   mp->enable_disable = enable_disable;
10465   mp->pid = htonl (getpid ());
10466   mp->learn_limit = htonl (learn_limit);
10467   mp->scan_delay = (u8) scan_delay;
10468   mp->max_macs_in_event = (u8) (max_macs_in_event / 10);
10469   S (mp);
10470   W (ret);
10471   return ret;
10472 }
10473
10474 static int
10475 api_input_acl_set_interface (vat_main_t * vam)
10476 {
10477   unformat_input_t *i = vam->input;
10478   vl_api_input_acl_set_interface_t *mp;
10479   u32 sw_if_index;
10480   int sw_if_index_set;
10481   u32 ip4_table_index = ~0;
10482   u32 ip6_table_index = ~0;
10483   u32 l2_table_index = ~0;
10484   u8 is_add = 1;
10485   int ret;
10486
10487   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10488     {
10489       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10490         sw_if_index_set = 1;
10491       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10492         sw_if_index_set = 1;
10493       else if (unformat (i, "del"))
10494         is_add = 0;
10495       else if (unformat (i, "ip4-table %d", &ip4_table_index))
10496         ;
10497       else if (unformat (i, "ip6-table %d", &ip6_table_index))
10498         ;
10499       else if (unformat (i, "l2-table %d", &l2_table_index))
10500         ;
10501       else
10502         {
10503           clib_warning ("parse error '%U'", format_unformat_error, i);
10504           return -99;
10505         }
10506     }
10507
10508   if (sw_if_index_set == 0)
10509     {
10510       errmsg ("missing interface name or sw_if_index");
10511       return -99;
10512     }
10513
10514   M (INPUT_ACL_SET_INTERFACE, mp);
10515
10516   mp->sw_if_index = ntohl (sw_if_index);
10517   mp->ip4_table_index = ntohl (ip4_table_index);
10518   mp->ip6_table_index = ntohl (ip6_table_index);
10519   mp->l2_table_index = ntohl (l2_table_index);
10520   mp->is_add = is_add;
10521
10522   S (mp);
10523   W (ret);
10524   return ret;
10525 }
10526
10527 static int
10528 api_output_acl_set_interface (vat_main_t * vam)
10529 {
10530   unformat_input_t *i = vam->input;
10531   vl_api_output_acl_set_interface_t *mp;
10532   u32 sw_if_index;
10533   int sw_if_index_set;
10534   u32 ip4_table_index = ~0;
10535   u32 ip6_table_index = ~0;
10536   u32 l2_table_index = ~0;
10537   u8 is_add = 1;
10538   int ret;
10539
10540   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10541     {
10542       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10543         sw_if_index_set = 1;
10544       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10545         sw_if_index_set = 1;
10546       else if (unformat (i, "del"))
10547         is_add = 0;
10548       else if (unformat (i, "ip4-table %d", &ip4_table_index))
10549         ;
10550       else if (unformat (i, "ip6-table %d", &ip6_table_index))
10551         ;
10552       else if (unformat (i, "l2-table %d", &l2_table_index))
10553         ;
10554       else
10555         {
10556           clib_warning ("parse error '%U'", format_unformat_error, i);
10557           return -99;
10558         }
10559     }
10560
10561   if (sw_if_index_set == 0)
10562     {
10563       errmsg ("missing interface name or sw_if_index");
10564       return -99;
10565     }
10566
10567   M (OUTPUT_ACL_SET_INTERFACE, mp);
10568
10569   mp->sw_if_index = ntohl (sw_if_index);
10570   mp->ip4_table_index = ntohl (ip4_table_index);
10571   mp->ip6_table_index = ntohl (ip6_table_index);
10572   mp->l2_table_index = ntohl (l2_table_index);
10573   mp->is_add = is_add;
10574
10575   S (mp);
10576   W (ret);
10577   return ret;
10578 }
10579
10580 static int
10581 api_ip_address_dump (vat_main_t * vam)
10582 {
10583   unformat_input_t *i = vam->input;
10584   vl_api_ip_address_dump_t *mp;
10585   vl_api_control_ping_t *mp_ping;
10586   u32 sw_if_index = ~0;
10587   u8 sw_if_index_set = 0;
10588   u8 ipv4_set = 0;
10589   u8 ipv6_set = 0;
10590   int ret;
10591
10592   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10593     {
10594       if (unformat (i, "sw_if_index %d", &sw_if_index))
10595         sw_if_index_set = 1;
10596       else
10597         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10598         sw_if_index_set = 1;
10599       else if (unformat (i, "ipv4"))
10600         ipv4_set = 1;
10601       else if (unformat (i, "ipv6"))
10602         ipv6_set = 1;
10603       else
10604         break;
10605     }
10606
10607   if (ipv4_set && ipv6_set)
10608     {
10609       errmsg ("ipv4 and ipv6 flags cannot be both set");
10610       return -99;
10611     }
10612
10613   if ((!ipv4_set) && (!ipv6_set))
10614     {
10615       errmsg ("no ipv4 nor ipv6 flag set");
10616       return -99;
10617     }
10618
10619   if (sw_if_index_set == 0)
10620     {
10621       errmsg ("missing interface name or sw_if_index");
10622       return -99;
10623     }
10624
10625   vam->current_sw_if_index = sw_if_index;
10626   vam->is_ipv6 = ipv6_set;
10627
10628   M (IP_ADDRESS_DUMP, mp);
10629   mp->sw_if_index = ntohl (sw_if_index);
10630   mp->is_ipv6 = ipv6_set;
10631   S (mp);
10632
10633   /* Use a control ping for synchronization */
10634   MPING (CONTROL_PING, mp_ping);
10635   S (mp_ping);
10636
10637   W (ret);
10638   return ret;
10639 }
10640
10641 static int
10642 api_ip_dump (vat_main_t * vam)
10643 {
10644   vl_api_ip_dump_t *mp;
10645   vl_api_control_ping_t *mp_ping;
10646   unformat_input_t *in = vam->input;
10647   int ipv4_set = 0;
10648   int ipv6_set = 0;
10649   int is_ipv6;
10650   int i;
10651   int ret;
10652
10653   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
10654     {
10655       if (unformat (in, "ipv4"))
10656         ipv4_set = 1;
10657       else if (unformat (in, "ipv6"))
10658         ipv6_set = 1;
10659       else
10660         break;
10661     }
10662
10663   if (ipv4_set && ipv6_set)
10664     {
10665       errmsg ("ipv4 and ipv6 flags cannot be both set");
10666       return -99;
10667     }
10668
10669   if ((!ipv4_set) && (!ipv6_set))
10670     {
10671       errmsg ("no ipv4 nor ipv6 flag set");
10672       return -99;
10673     }
10674
10675   is_ipv6 = ipv6_set;
10676   vam->is_ipv6 = is_ipv6;
10677
10678   /* free old data */
10679   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
10680     {
10681       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
10682     }
10683   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
10684
10685   M (IP_DUMP, mp);
10686   mp->is_ipv6 = ipv6_set;
10687   S (mp);
10688
10689   /* Use a control ping for synchronization */
10690   MPING (CONTROL_PING, mp_ping);
10691   S (mp_ping);
10692
10693   W (ret);
10694   return ret;
10695 }
10696
10697 static int
10698 api_ipsec_spd_add_del (vat_main_t * vam)
10699 {
10700   unformat_input_t *i = vam->input;
10701   vl_api_ipsec_spd_add_del_t *mp;
10702   u32 spd_id = ~0;
10703   u8 is_add = 1;
10704   int ret;
10705
10706   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10707     {
10708       if (unformat (i, "spd_id %d", &spd_id))
10709         ;
10710       else if (unformat (i, "del"))
10711         is_add = 0;
10712       else
10713         {
10714           clib_warning ("parse error '%U'", format_unformat_error, i);
10715           return -99;
10716         }
10717     }
10718   if (spd_id == ~0)
10719     {
10720       errmsg ("spd_id must be set");
10721       return -99;
10722     }
10723
10724   M (IPSEC_SPD_ADD_DEL, mp);
10725
10726   mp->spd_id = ntohl (spd_id);
10727   mp->is_add = is_add;
10728
10729   S (mp);
10730   W (ret);
10731   return ret;
10732 }
10733
10734 static int
10735 api_ipsec_interface_add_del_spd (vat_main_t * vam)
10736 {
10737   unformat_input_t *i = vam->input;
10738   vl_api_ipsec_interface_add_del_spd_t *mp;
10739   u32 sw_if_index;
10740   u8 sw_if_index_set = 0;
10741   u32 spd_id = (u32) ~ 0;
10742   u8 is_add = 1;
10743   int ret;
10744
10745   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10746     {
10747       if (unformat (i, "del"))
10748         is_add = 0;
10749       else if (unformat (i, "spd_id %d", &spd_id))
10750         ;
10751       else
10752         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10753         sw_if_index_set = 1;
10754       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10755         sw_if_index_set = 1;
10756       else
10757         {
10758           clib_warning ("parse error '%U'", format_unformat_error, i);
10759           return -99;
10760         }
10761
10762     }
10763
10764   if (spd_id == (u32) ~ 0)
10765     {
10766       errmsg ("spd_id must be set");
10767       return -99;
10768     }
10769
10770   if (sw_if_index_set == 0)
10771     {
10772       errmsg ("missing interface name or sw_if_index");
10773       return -99;
10774     }
10775
10776   M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
10777
10778   mp->spd_id = ntohl (spd_id);
10779   mp->sw_if_index = ntohl (sw_if_index);
10780   mp->is_add = is_add;
10781
10782   S (mp);
10783   W (ret);
10784   return ret;
10785 }
10786
10787 static int
10788 api_ipsec_spd_entry_add_del (vat_main_t * vam)
10789 {
10790   unformat_input_t *i = vam->input;
10791   vl_api_ipsec_spd_entry_add_del_t *mp;
10792   u8 is_add = 1, is_outbound = 0;
10793   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
10794   i32 priority = 0;
10795   u32 rport_start = 0, rport_stop = (u32) ~ 0;
10796   u32 lport_start = 0, lport_stop = (u32) ~ 0;
10797   vl_api_address_t laddr_start = { }, laddr_stop =
10798   {
10799   }, raddr_start =
10800   {
10801   }, raddr_stop =
10802   {
10803   };
10804   int ret;
10805
10806   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10807     {
10808       if (unformat (i, "del"))
10809         is_add = 0;
10810       if (unformat (i, "outbound"))
10811         is_outbound = 1;
10812       if (unformat (i, "inbound"))
10813         is_outbound = 0;
10814       else if (unformat (i, "spd_id %d", &spd_id))
10815         ;
10816       else if (unformat (i, "sa_id %d", &sa_id))
10817         ;
10818       else if (unformat (i, "priority %d", &priority))
10819         ;
10820       else if (unformat (i, "protocol %d", &protocol))
10821         ;
10822       else if (unformat (i, "lport_start %d", &lport_start))
10823         ;
10824       else if (unformat (i, "lport_stop %d", &lport_stop))
10825         ;
10826       else if (unformat (i, "rport_start %d", &rport_start))
10827         ;
10828       else if (unformat (i, "rport_stop %d", &rport_stop))
10829         ;
10830       else if (unformat (i, "laddr_start %U",
10831                          unformat_vl_api_address, &laddr_start))
10832         ;
10833       else if (unformat (i, "laddr_stop %U", unformat_vl_api_address,
10834                          &laddr_stop))
10835         ;
10836       else if (unformat (i, "raddr_start %U", unformat_vl_api_address,
10837                          &raddr_start))
10838         ;
10839       else if (unformat (i, "raddr_stop %U", unformat_vl_api_address,
10840                          &raddr_stop))
10841         ;
10842       else
10843         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
10844         {
10845           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
10846             {
10847               clib_warning ("unsupported action: 'resolve'");
10848               return -99;
10849             }
10850         }
10851       else
10852         {
10853           clib_warning ("parse error '%U'", format_unformat_error, i);
10854           return -99;
10855         }
10856
10857     }
10858
10859   M (IPSEC_SPD_ENTRY_ADD_DEL, mp);
10860
10861   mp->is_add = is_add;
10862
10863   mp->entry.spd_id = ntohl (spd_id);
10864   mp->entry.priority = ntohl (priority);
10865   mp->entry.is_outbound = is_outbound;
10866
10867   clib_memcpy (&mp->entry.remote_address_start, &raddr_start,
10868                sizeof (vl_api_address_t));
10869   clib_memcpy (&mp->entry.remote_address_stop, &raddr_stop,
10870                sizeof (vl_api_address_t));
10871   clib_memcpy (&mp->entry.local_address_start, &laddr_start,
10872                sizeof (vl_api_address_t));
10873   clib_memcpy (&mp->entry.local_address_stop, &laddr_stop,
10874                sizeof (vl_api_address_t));
10875
10876   mp->entry.protocol = (u8) protocol;
10877   mp->entry.local_port_start = ntohs ((u16) lport_start);
10878   mp->entry.local_port_stop = ntohs ((u16) lport_stop);
10879   mp->entry.remote_port_start = ntohs ((u16) rport_start);
10880   mp->entry.remote_port_stop = ntohs ((u16) rport_stop);
10881   mp->entry.policy = (u8) policy;
10882   mp->entry.sa_id = ntohl (sa_id);
10883
10884   S (mp);
10885   W (ret);
10886   return ret;
10887 }
10888
10889 static int
10890 api_ipsec_sad_entry_add_del (vat_main_t * vam)
10891 {
10892   unformat_input_t *i = vam->input;
10893   vl_api_ipsec_sad_entry_add_del_t *mp;
10894   u32 sad_id = 0, spi = 0;
10895   u8 *ck = 0, *ik = 0;
10896   u8 is_add = 1;
10897
10898   vl_api_ipsec_crypto_alg_t crypto_alg = IPSEC_API_CRYPTO_ALG_NONE;
10899   vl_api_ipsec_integ_alg_t integ_alg = IPSEC_API_INTEG_ALG_NONE;
10900   vl_api_ipsec_sad_flags_t flags = IPSEC_API_SAD_FLAG_NONE;
10901   vl_api_ipsec_proto_t protocol = IPSEC_API_PROTO_AH;
10902   vl_api_address_t tun_src, tun_dst;
10903   int ret;
10904
10905   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10906     {
10907       if (unformat (i, "del"))
10908         is_add = 0;
10909       else if (unformat (i, "sad_id %d", &sad_id))
10910         ;
10911       else if (unformat (i, "spi %d", &spi))
10912         ;
10913       else if (unformat (i, "esp"))
10914         protocol = IPSEC_API_PROTO_ESP;
10915       else
10916         if (unformat (i, "tunnel_src %U", unformat_vl_api_address, &tun_src))
10917         {
10918           flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL;
10919           if (ADDRESS_IP6 == tun_src.af)
10920             flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL_V6;
10921         }
10922       else
10923         if (unformat (i, "tunnel_dst %U", unformat_vl_api_address, &tun_dst))
10924         {
10925           flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL;
10926           if (ADDRESS_IP6 == tun_src.af)
10927             flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL_V6;
10928         }
10929       else
10930         if (unformat (i, "crypto_alg %U",
10931                       unformat_ipsec_api_crypto_alg, &crypto_alg))
10932         ;
10933       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
10934         ;
10935       else if (unformat (i, "integ_alg %U",
10936                          unformat_ipsec_api_integ_alg, &integ_alg))
10937         ;
10938       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
10939         ;
10940       else
10941         {
10942           clib_warning ("parse error '%U'", format_unformat_error, i);
10943           return -99;
10944         }
10945
10946     }
10947
10948   M (IPSEC_SAD_ENTRY_ADD_DEL, mp);
10949
10950   mp->is_add = is_add;
10951   mp->entry.sad_id = ntohl (sad_id);
10952   mp->entry.protocol = protocol;
10953   mp->entry.spi = ntohl (spi);
10954   mp->entry.flags = flags;
10955
10956   mp->entry.crypto_algorithm = crypto_alg;
10957   mp->entry.integrity_algorithm = integ_alg;
10958   mp->entry.crypto_key.length = vec_len (ck);
10959   mp->entry.integrity_key.length = vec_len (ik);
10960
10961   if (mp->entry.crypto_key.length > sizeof (mp->entry.crypto_key.data))
10962     mp->entry.crypto_key.length = sizeof (mp->entry.crypto_key.data);
10963
10964   if (mp->entry.integrity_key.length > sizeof (mp->entry.integrity_key.data))
10965     mp->entry.integrity_key.length = sizeof (mp->entry.integrity_key.data);
10966
10967   if (ck)
10968     clib_memcpy (mp->entry.crypto_key.data, ck, mp->entry.crypto_key.length);
10969   if (ik)
10970     clib_memcpy (mp->entry.integrity_key.data, ik,
10971                  mp->entry.integrity_key.length);
10972
10973   if (flags & IPSEC_API_SAD_FLAG_IS_TUNNEL)
10974     {
10975       clib_memcpy (&mp->entry.tunnel_src, &tun_src,
10976                    sizeof (mp->entry.tunnel_src));
10977       clib_memcpy (&mp->entry.tunnel_dst, &tun_dst,
10978                    sizeof (mp->entry.tunnel_dst));
10979     }
10980
10981   S (mp);
10982   W (ret);
10983   return ret;
10984 }
10985
10986 static int
10987 api_ipsec_tunnel_if_add_del (vat_main_t * vam)
10988 {
10989   unformat_input_t *i = vam->input;
10990   vl_api_ipsec_tunnel_if_add_del_t *mp;
10991   u32 local_spi = 0, remote_spi = 0;
10992   u32 crypto_alg = 0, integ_alg = 0;
10993   u8 *lck = NULL, *rck = NULL;
10994   u8 *lik = NULL, *rik = NULL;
10995   vl_api_address_t local_ip = { 0 };
10996   vl_api_address_t remote_ip = { 0 };
10997   f64 before = 0;
10998   u8 is_add = 1;
10999   u8 esn = 0;
11000   u8 anti_replay = 0;
11001   u8 renumber = 0;
11002   u32 instance = ~0;
11003   u32 count = 1, jj;
11004   int ret = -1;
11005
11006   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11007     {
11008       if (unformat (i, "del"))
11009         is_add = 0;
11010       else if (unformat (i, "esn"))
11011         esn = 1;
11012       else if (unformat (i, "anti-replay"))
11013         anti_replay = 1;
11014       else if (unformat (i, "count %d", &count))
11015         ;
11016       else if (unformat (i, "local_spi %d", &local_spi))
11017         ;
11018       else if (unformat (i, "remote_spi %d", &remote_spi))
11019         ;
11020       else
11021         if (unformat (i, "local_ip %U", unformat_vl_api_address, &local_ip))
11022         ;
11023       else
11024         if (unformat (i, "remote_ip %U", unformat_vl_api_address, &remote_ip))
11025         ;
11026       else if (unformat (i, "local_crypto_key %U", unformat_hex_string, &lck))
11027         ;
11028       else
11029         if (unformat (i, "remote_crypto_key %U", unformat_hex_string, &rck))
11030         ;
11031       else if (unformat (i, "local_integ_key %U", unformat_hex_string, &lik))
11032         ;
11033       else if (unformat (i, "remote_integ_key %U", unformat_hex_string, &rik))
11034         ;
11035       else
11036         if (unformat
11037             (i, "crypto_alg %U", unformat_ipsec_api_crypto_alg, &crypto_alg))
11038         {
11039           if (crypto_alg >= IPSEC_CRYPTO_N_ALG)
11040             {
11041               errmsg ("unsupported crypto-alg: '%U'\n",
11042                       format_ipsec_crypto_alg, crypto_alg);
11043               return -99;
11044             }
11045         }
11046       else
11047         if (unformat
11048             (i, "integ_alg %U", unformat_ipsec_api_integ_alg, &integ_alg))
11049         {
11050           if (integ_alg >= IPSEC_INTEG_N_ALG)
11051             {
11052               errmsg ("unsupported integ-alg: '%U'\n",
11053                       format_ipsec_integ_alg, integ_alg);
11054               return -99;
11055             }
11056         }
11057       else if (unformat (i, "instance %u", &instance))
11058         renumber = 1;
11059       else
11060         {
11061           errmsg ("parse error '%U'\n", format_unformat_error, i);
11062           return -99;
11063         }
11064     }
11065
11066   if (count > 1)
11067     {
11068       /* Turn on async mode */
11069       vam->async_mode = 1;
11070       vam->async_errors = 0;
11071       before = vat_time_now (vam);
11072     }
11073
11074   for (jj = 0; jj < count; jj++)
11075     {
11076       M (IPSEC_TUNNEL_IF_ADD_DEL, mp);
11077
11078       mp->is_add = is_add;
11079       mp->esn = esn;
11080       mp->anti_replay = anti_replay;
11081
11082       if (jj > 0)
11083         increment_address (&remote_ip);
11084
11085       clib_memcpy (&mp->local_ip, &local_ip, sizeof (local_ip));
11086       clib_memcpy (&mp->remote_ip, &remote_ip, sizeof (remote_ip));
11087
11088       mp->local_spi = htonl (local_spi + jj);
11089       mp->remote_spi = htonl (remote_spi + jj);
11090       mp->crypto_alg = (u8) crypto_alg;
11091
11092       mp->local_crypto_key_len = 0;
11093       if (lck)
11094         {
11095           mp->local_crypto_key_len = vec_len (lck);
11096           if (mp->local_crypto_key_len > sizeof (mp->local_crypto_key))
11097             mp->local_crypto_key_len = sizeof (mp->local_crypto_key);
11098           clib_memcpy (mp->local_crypto_key, lck, mp->local_crypto_key_len);
11099         }
11100
11101       mp->remote_crypto_key_len = 0;
11102       if (rck)
11103         {
11104           mp->remote_crypto_key_len = vec_len (rck);
11105           if (mp->remote_crypto_key_len > sizeof (mp->remote_crypto_key))
11106             mp->remote_crypto_key_len = sizeof (mp->remote_crypto_key);
11107           clib_memcpy (mp->remote_crypto_key, rck, mp->remote_crypto_key_len);
11108         }
11109
11110       mp->integ_alg = (u8) integ_alg;
11111
11112       mp->local_integ_key_len = 0;
11113       if (lik)
11114         {
11115           mp->local_integ_key_len = vec_len (lik);
11116           if (mp->local_integ_key_len > sizeof (mp->local_integ_key))
11117             mp->local_integ_key_len = sizeof (mp->local_integ_key);
11118           clib_memcpy (mp->local_integ_key, lik, mp->local_integ_key_len);
11119         }
11120
11121       mp->remote_integ_key_len = 0;
11122       if (rik)
11123         {
11124           mp->remote_integ_key_len = vec_len (rik);
11125           if (mp->remote_integ_key_len > sizeof (mp->remote_integ_key))
11126             mp->remote_integ_key_len = sizeof (mp->remote_integ_key);
11127           clib_memcpy (mp->remote_integ_key, rik, mp->remote_integ_key_len);
11128         }
11129
11130       if (renumber)
11131         {
11132           mp->renumber = renumber;
11133           mp->show_instance = ntohl (instance);
11134         }
11135       S (mp);
11136     }
11137
11138   /* When testing multiple add/del ops, use a control-ping to sync */
11139   if (count > 1)
11140     {
11141       vl_api_control_ping_t *mp_ping;
11142       f64 after;
11143       f64 timeout;
11144
11145       /* Shut off async mode */
11146       vam->async_mode = 0;
11147
11148       MPING (CONTROL_PING, mp_ping);
11149       S (mp_ping);
11150
11151       timeout = vat_time_now (vam) + 1.0;
11152       while (vat_time_now (vam) < timeout)
11153         if (vam->result_ready == 1)
11154           goto out;
11155       vam->retval = -99;
11156
11157     out:
11158       if (vam->retval == -99)
11159         errmsg ("timeout");
11160
11161       if (vam->async_errors > 0)
11162         {
11163           errmsg ("%d asynchronous errors", vam->async_errors);
11164           vam->retval = -98;
11165         }
11166       vam->async_errors = 0;
11167       after = vat_time_now (vam);
11168
11169       /* slim chance, but we might have eaten SIGTERM on the first iteration */
11170       if (jj > 0)
11171         count = jj;
11172
11173       print (vam->ofp, "%d tunnels in %.6f secs, %.2f tunnels/sec",
11174              count, after - before, count / (after - before));
11175     }
11176   else
11177     {
11178       /* Wait for a reply... */
11179       W (ret);
11180       return ret;
11181     }
11182
11183   return ret;
11184 }
11185
11186 static void
11187 vl_api_ipsec_sa_details_t_handler (vl_api_ipsec_sa_details_t * mp)
11188 {
11189   vat_main_t *vam = &vat_main;
11190
11191   print (vam->ofp, "sa_id %u sw_if_index %u spi %u proto %u crypto_alg %u "
11192          "crypto_key %U integ_alg %u integ_key %U flags %x "
11193          "tunnel_src_addr %U tunnel_dst_addr %U "
11194          "salt %u seq_outbound %lu last_seq_inbound %lu "
11195          "replay_window %lu stat_index %u\n",
11196          ntohl (mp->entry.sad_id),
11197          ntohl (mp->sw_if_index),
11198          ntohl (mp->entry.spi),
11199          ntohl (mp->entry.protocol),
11200          ntohl (mp->entry.crypto_algorithm),
11201          format_hex_bytes, mp->entry.crypto_key.data,
11202          mp->entry.crypto_key.length, ntohl (mp->entry.integrity_algorithm),
11203          format_hex_bytes, mp->entry.integrity_key.data,
11204          mp->entry.integrity_key.length, ntohl (mp->entry.flags),
11205          format_vl_api_address, &mp->entry.tunnel_src, format_vl_api_address,
11206          &mp->entry.tunnel_dst, ntohl (mp->salt),
11207          clib_net_to_host_u64 (mp->seq_outbound),
11208          clib_net_to_host_u64 (mp->last_seq_inbound),
11209          clib_net_to_host_u64 (mp->replay_window), ntohl (mp->stat_index));
11210 }
11211
11212 #define vl_api_ipsec_sa_details_t_endian vl_noop_handler
11213 #define vl_api_ipsec_sa_details_t_print vl_noop_handler
11214
11215 static void vl_api_ipsec_sa_details_t_handler_json
11216   (vl_api_ipsec_sa_details_t * mp)
11217 {
11218   vat_main_t *vam = &vat_main;
11219   vat_json_node_t *node = NULL;
11220   vl_api_ipsec_sad_flags_t flags;
11221
11222   if (VAT_JSON_ARRAY != vam->json_tree.type)
11223     {
11224       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11225       vat_json_init_array (&vam->json_tree);
11226     }
11227   node = vat_json_array_add (&vam->json_tree);
11228
11229   vat_json_init_object (node);
11230   vat_json_object_add_uint (node, "sa_id", ntohl (mp->entry.sad_id));
11231   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11232   vat_json_object_add_uint (node, "spi", ntohl (mp->entry.spi));
11233   vat_json_object_add_uint (node, "proto", ntohl (mp->entry.protocol));
11234   vat_json_object_add_uint (node, "crypto_alg",
11235                             ntohl (mp->entry.crypto_algorithm));
11236   vat_json_object_add_uint (node, "integ_alg",
11237                             ntohl (mp->entry.integrity_algorithm));
11238   flags = ntohl (mp->entry.flags);
11239   vat_json_object_add_uint (node, "use_esn",
11240                             ! !(flags & IPSEC_API_SAD_FLAG_USE_ESN));
11241   vat_json_object_add_uint (node, "use_anti_replay",
11242                             ! !(flags & IPSEC_API_SAD_FLAG_USE_ANTI_REPLAY));
11243   vat_json_object_add_uint (node, "is_tunnel",
11244                             ! !(flags & IPSEC_API_SAD_FLAG_IS_TUNNEL));
11245   vat_json_object_add_uint (node, "is_tunnel_ip6",
11246                             ! !(flags & IPSEC_API_SAD_FLAG_IS_TUNNEL_V6));
11247   vat_json_object_add_uint (node, "udp_encap",
11248                             ! !(flags & IPSEC_API_SAD_FLAG_UDP_ENCAP));
11249   vat_json_object_add_bytes (node, "crypto_key", mp->entry.crypto_key.data,
11250                              mp->entry.crypto_key.length);
11251   vat_json_object_add_bytes (node, "integ_key", mp->entry.integrity_key.data,
11252                              mp->entry.integrity_key.length);
11253   vat_json_object_add_address (node, "src", &mp->entry.tunnel_src);
11254   vat_json_object_add_address (node, "dst", &mp->entry.tunnel_dst);
11255   vat_json_object_add_uint (node, "replay_window",
11256                             clib_net_to_host_u64 (mp->replay_window));
11257   vat_json_object_add_uint (node, "stat_index", ntohl (mp->stat_index));
11258 }
11259
11260 static int
11261 api_ipsec_sa_dump (vat_main_t * vam)
11262 {
11263   unformat_input_t *i = vam->input;
11264   vl_api_ipsec_sa_dump_t *mp;
11265   vl_api_control_ping_t *mp_ping;
11266   u32 sa_id = ~0;
11267   int ret;
11268
11269   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11270     {
11271       if (unformat (i, "sa_id %d", &sa_id))
11272         ;
11273       else
11274         {
11275           clib_warning ("parse error '%U'", format_unformat_error, i);
11276           return -99;
11277         }
11278     }
11279
11280   M (IPSEC_SA_DUMP, mp);
11281
11282   mp->sa_id = ntohl (sa_id);
11283
11284   S (mp);
11285
11286   /* Use a control ping for synchronization */
11287   M (CONTROL_PING, mp_ping);
11288   S (mp_ping);
11289
11290   W (ret);
11291   return ret;
11292 }
11293
11294 static int
11295 api_ipsec_tunnel_if_set_sa (vat_main_t * vam)
11296 {
11297   unformat_input_t *i = vam->input;
11298   vl_api_ipsec_tunnel_if_set_sa_t *mp;
11299   u32 sw_if_index = ~0;
11300   u32 sa_id = ~0;
11301   u8 is_outbound = (u8) ~ 0;
11302   int ret;
11303
11304   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11305     {
11306       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11307         ;
11308       else if (unformat (i, "sa_id %d", &sa_id))
11309         ;
11310       else if (unformat (i, "outbound"))
11311         is_outbound = 1;
11312       else if (unformat (i, "inbound"))
11313         is_outbound = 0;
11314       else
11315         {
11316           clib_warning ("parse error '%U'", format_unformat_error, i);
11317           return -99;
11318         }
11319     }
11320
11321   if (sw_if_index == ~0)
11322     {
11323       errmsg ("interface must be specified");
11324       return -99;
11325     }
11326
11327   if (sa_id == ~0)
11328     {
11329       errmsg ("SA ID must be specified");
11330       return -99;
11331     }
11332
11333   M (IPSEC_TUNNEL_IF_SET_SA, mp);
11334
11335   mp->sw_if_index = htonl (sw_if_index);
11336   mp->sa_id = htonl (sa_id);
11337   mp->is_outbound = is_outbound;
11338
11339   S (mp);
11340   W (ret);
11341
11342   return ret;
11343 }
11344
11345 static int
11346 api_get_first_msg_id (vat_main_t * vam)
11347 {
11348   vl_api_get_first_msg_id_t *mp;
11349   unformat_input_t *i = vam->input;
11350   u8 *name;
11351   u8 name_set = 0;
11352   int ret;
11353
11354   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11355     {
11356       if (unformat (i, "client %s", &name))
11357         name_set = 1;
11358       else
11359         break;
11360     }
11361
11362   if (name_set == 0)
11363     {
11364       errmsg ("missing client name");
11365       return -99;
11366     }
11367   vec_add1 (name, 0);
11368
11369   if (vec_len (name) > 63)
11370     {
11371       errmsg ("client name too long");
11372       return -99;
11373     }
11374
11375   M (GET_FIRST_MSG_ID, mp);
11376   clib_memcpy (mp->name, name, vec_len (name));
11377   S (mp);
11378   W (ret);
11379   return ret;
11380 }
11381
11382 static int
11383 api_cop_interface_enable_disable (vat_main_t * vam)
11384 {
11385   unformat_input_t *line_input = vam->input;
11386   vl_api_cop_interface_enable_disable_t *mp;
11387   u32 sw_if_index = ~0;
11388   u8 enable_disable = 1;
11389   int ret;
11390
11391   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11392     {
11393       if (unformat (line_input, "disable"))
11394         enable_disable = 0;
11395       if (unformat (line_input, "enable"))
11396         enable_disable = 1;
11397       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
11398                          vam, &sw_if_index))
11399         ;
11400       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
11401         ;
11402       else
11403         break;
11404     }
11405
11406   if (sw_if_index == ~0)
11407     {
11408       errmsg ("missing interface name or sw_if_index");
11409       return -99;
11410     }
11411
11412   /* Construct the API message */
11413   M (COP_INTERFACE_ENABLE_DISABLE, mp);
11414   mp->sw_if_index = ntohl (sw_if_index);
11415   mp->enable_disable = enable_disable;
11416
11417   /* send it... */
11418   S (mp);
11419   /* Wait for the reply */
11420   W (ret);
11421   return ret;
11422 }
11423
11424 static int
11425 api_cop_whitelist_enable_disable (vat_main_t * vam)
11426 {
11427   unformat_input_t *line_input = vam->input;
11428   vl_api_cop_whitelist_enable_disable_t *mp;
11429   u32 sw_if_index = ~0;
11430   u8 ip4 = 0, ip6 = 0, default_cop = 0;
11431   u32 fib_id = 0;
11432   int ret;
11433
11434   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11435     {
11436       if (unformat (line_input, "ip4"))
11437         ip4 = 1;
11438       else if (unformat (line_input, "ip6"))
11439         ip6 = 1;
11440       else if (unformat (line_input, "default"))
11441         default_cop = 1;
11442       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
11443                          vam, &sw_if_index))
11444         ;
11445       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
11446         ;
11447       else if (unformat (line_input, "fib-id %d", &fib_id))
11448         ;
11449       else
11450         break;
11451     }
11452
11453   if (sw_if_index == ~0)
11454     {
11455       errmsg ("missing interface name or sw_if_index");
11456       return -99;
11457     }
11458
11459   /* Construct the API message */
11460   M (COP_WHITELIST_ENABLE_DISABLE, mp);
11461   mp->sw_if_index = ntohl (sw_if_index);
11462   mp->fib_id = ntohl (fib_id);
11463   mp->ip4 = ip4;
11464   mp->ip6 = ip6;
11465   mp->default_cop = default_cop;
11466
11467   /* send it... */
11468   S (mp);
11469   /* Wait for the reply */
11470   W (ret);
11471   return ret;
11472 }
11473
11474 static int
11475 api_get_node_graph (vat_main_t * vam)
11476 {
11477   vl_api_get_node_graph_t *mp;
11478   int ret;
11479
11480   M (GET_NODE_GRAPH, mp);
11481
11482   /* send it... */
11483   S (mp);
11484   /* Wait for the reply */
11485   W (ret);
11486   return ret;
11487 }
11488
11489 static int
11490 api_af_packet_create (vat_main_t * vam)
11491 {
11492   unformat_input_t *i = vam->input;
11493   vl_api_af_packet_create_t *mp;
11494   u8 *host_if_name = 0;
11495   u8 hw_addr[6];
11496   u8 random_hw_addr = 1;
11497   int ret;
11498
11499   clib_memset (hw_addr, 0, sizeof (hw_addr));
11500
11501   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11502     {
11503       if (unformat (i, "name %s", &host_if_name))
11504         vec_add1 (host_if_name, 0);
11505       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
11506         random_hw_addr = 0;
11507       else
11508         break;
11509     }
11510
11511   if (!vec_len (host_if_name))
11512     {
11513       errmsg ("host-interface name must be specified");
11514       return -99;
11515     }
11516
11517   if (vec_len (host_if_name) > 64)
11518     {
11519       errmsg ("host-interface name too long");
11520       return -99;
11521     }
11522
11523   M (AF_PACKET_CREATE, mp);
11524
11525   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
11526   clib_memcpy (mp->hw_addr, hw_addr, 6);
11527   mp->use_random_hw_addr = random_hw_addr;
11528   vec_free (host_if_name);
11529
11530   S (mp);
11531
11532   /* *INDENT-OFF* */
11533   W2 (ret,
11534       ({
11535         if (ret == 0)
11536           fprintf (vam->ofp ? vam->ofp : stderr,
11537                    " new sw_if_index = %d\n", vam->sw_if_index);
11538       }));
11539   /* *INDENT-ON* */
11540   return ret;
11541 }
11542
11543 static int
11544 api_af_packet_delete (vat_main_t * vam)
11545 {
11546   unformat_input_t *i = vam->input;
11547   vl_api_af_packet_delete_t *mp;
11548   u8 *host_if_name = 0;
11549   int ret;
11550
11551   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11552     {
11553       if (unformat (i, "name %s", &host_if_name))
11554         vec_add1 (host_if_name, 0);
11555       else
11556         break;
11557     }
11558
11559   if (!vec_len (host_if_name))
11560     {
11561       errmsg ("host-interface name must be specified");
11562       return -99;
11563     }
11564
11565   if (vec_len (host_if_name) > 64)
11566     {
11567       errmsg ("host-interface name too long");
11568       return -99;
11569     }
11570
11571   M (AF_PACKET_DELETE, mp);
11572
11573   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
11574   vec_free (host_if_name);
11575
11576   S (mp);
11577   W (ret);
11578   return ret;
11579 }
11580
11581 static void vl_api_af_packet_details_t_handler
11582   (vl_api_af_packet_details_t * mp)
11583 {
11584   vat_main_t *vam = &vat_main;
11585
11586   print (vam->ofp, "%-16s %d",
11587          mp->host_if_name, clib_net_to_host_u32 (mp->sw_if_index));
11588 }
11589
11590 static void vl_api_af_packet_details_t_handler_json
11591   (vl_api_af_packet_details_t * mp)
11592 {
11593   vat_main_t *vam = &vat_main;
11594   vat_json_node_t *node = NULL;
11595
11596   if (VAT_JSON_ARRAY != vam->json_tree.type)
11597     {
11598       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11599       vat_json_init_array (&vam->json_tree);
11600     }
11601   node = vat_json_array_add (&vam->json_tree);
11602
11603   vat_json_init_object (node);
11604   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11605   vat_json_object_add_string_copy (node, "dev_name", mp->host_if_name);
11606 }
11607
11608 static int
11609 api_af_packet_dump (vat_main_t * vam)
11610 {
11611   vl_api_af_packet_dump_t *mp;
11612   vl_api_control_ping_t *mp_ping;
11613   int ret;
11614
11615   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
11616   /* Get list of tap interfaces */
11617   M (AF_PACKET_DUMP, mp);
11618   S (mp);
11619
11620   /* Use a control ping for synchronization */
11621   MPING (CONTROL_PING, mp_ping);
11622   S (mp_ping);
11623
11624   W (ret);
11625   return ret;
11626 }
11627
11628 static int
11629 api_policer_add_del (vat_main_t * vam)
11630 {
11631   unformat_input_t *i = vam->input;
11632   vl_api_policer_add_del_t *mp;
11633   u8 is_add = 1;
11634   u8 *name = 0;
11635   u32 cir = 0;
11636   u32 eir = 0;
11637   u64 cb = 0;
11638   u64 eb = 0;
11639   u8 rate_type = 0;
11640   u8 round_type = 0;
11641   u8 type = 0;
11642   u8 color_aware = 0;
11643   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
11644   int ret;
11645
11646   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
11647   conform_action.dscp = 0;
11648   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
11649   exceed_action.dscp = 0;
11650   violate_action.action_type = SSE2_QOS_ACTION_DROP;
11651   violate_action.dscp = 0;
11652
11653   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11654     {
11655       if (unformat (i, "del"))
11656         is_add = 0;
11657       else if (unformat (i, "name %s", &name))
11658         vec_add1 (name, 0);
11659       else if (unformat (i, "cir %u", &cir))
11660         ;
11661       else if (unformat (i, "eir %u", &eir))
11662         ;
11663       else if (unformat (i, "cb %u", &cb))
11664         ;
11665       else if (unformat (i, "eb %u", &eb))
11666         ;
11667       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
11668                          &rate_type))
11669         ;
11670       else if (unformat (i, "round_type %U", unformat_policer_round_type,
11671                          &round_type))
11672         ;
11673       else if (unformat (i, "type %U", unformat_policer_type, &type))
11674         ;
11675       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
11676                          &conform_action))
11677         ;
11678       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
11679                          &exceed_action))
11680         ;
11681       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
11682                          &violate_action))
11683         ;
11684       else if (unformat (i, "color-aware"))
11685         color_aware = 1;
11686       else
11687         break;
11688     }
11689
11690   if (!vec_len (name))
11691     {
11692       errmsg ("policer name must be specified");
11693       return -99;
11694     }
11695
11696   if (vec_len (name) > 64)
11697     {
11698       errmsg ("policer name too long");
11699       return -99;
11700     }
11701
11702   M (POLICER_ADD_DEL, mp);
11703
11704   clib_memcpy (mp->name, name, vec_len (name));
11705   vec_free (name);
11706   mp->is_add = is_add;
11707   mp->cir = ntohl (cir);
11708   mp->eir = ntohl (eir);
11709   mp->cb = clib_net_to_host_u64 (cb);
11710   mp->eb = clib_net_to_host_u64 (eb);
11711   mp->rate_type = rate_type;
11712   mp->round_type = round_type;
11713   mp->type = type;
11714   mp->conform_action.type = conform_action.action_type;
11715   mp->conform_action.dscp = conform_action.dscp;
11716   mp->exceed_action.type = exceed_action.action_type;
11717   mp->exceed_action.dscp = exceed_action.dscp;
11718   mp->violate_action.type = violate_action.action_type;
11719   mp->violate_action.dscp = violate_action.dscp;
11720   mp->color_aware = color_aware;
11721
11722   S (mp);
11723   W (ret);
11724   return ret;
11725 }
11726
11727 static int
11728 api_policer_dump (vat_main_t * vam)
11729 {
11730   unformat_input_t *i = vam->input;
11731   vl_api_policer_dump_t *mp;
11732   vl_api_control_ping_t *mp_ping;
11733   u8 *match_name = 0;
11734   u8 match_name_valid = 0;
11735   int ret;
11736
11737   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11738     {
11739       if (unformat (i, "name %s", &match_name))
11740         {
11741           vec_add1 (match_name, 0);
11742           match_name_valid = 1;
11743         }
11744       else
11745         break;
11746     }
11747
11748   M (POLICER_DUMP, mp);
11749   mp->match_name_valid = match_name_valid;
11750   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
11751   vec_free (match_name);
11752   /* send it... */
11753   S (mp);
11754
11755   /* Use a control ping for synchronization */
11756   MPING (CONTROL_PING, mp_ping);
11757   S (mp_ping);
11758
11759   /* Wait for a reply... */
11760   W (ret);
11761   return ret;
11762 }
11763
11764 static int
11765 api_policer_classify_set_interface (vat_main_t * vam)
11766 {
11767   unformat_input_t *i = vam->input;
11768   vl_api_policer_classify_set_interface_t *mp;
11769   u32 sw_if_index;
11770   int sw_if_index_set;
11771   u32 ip4_table_index = ~0;
11772   u32 ip6_table_index = ~0;
11773   u32 l2_table_index = ~0;
11774   u8 is_add = 1;
11775   int ret;
11776
11777   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11778     {
11779       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11780         sw_if_index_set = 1;
11781       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11782         sw_if_index_set = 1;
11783       else if (unformat (i, "del"))
11784         is_add = 0;
11785       else if (unformat (i, "ip4-table %d", &ip4_table_index))
11786         ;
11787       else if (unformat (i, "ip6-table %d", &ip6_table_index))
11788         ;
11789       else if (unformat (i, "l2-table %d", &l2_table_index))
11790         ;
11791       else
11792         {
11793           clib_warning ("parse error '%U'", format_unformat_error, i);
11794           return -99;
11795         }
11796     }
11797
11798   if (sw_if_index_set == 0)
11799     {
11800       errmsg ("missing interface name or sw_if_index");
11801       return -99;
11802     }
11803
11804   M (POLICER_CLASSIFY_SET_INTERFACE, mp);
11805
11806   mp->sw_if_index = ntohl (sw_if_index);
11807   mp->ip4_table_index = ntohl (ip4_table_index);
11808   mp->ip6_table_index = ntohl (ip6_table_index);
11809   mp->l2_table_index = ntohl (l2_table_index);
11810   mp->is_add = is_add;
11811
11812   S (mp);
11813   W (ret);
11814   return ret;
11815 }
11816
11817 static int
11818 api_policer_classify_dump (vat_main_t * vam)
11819 {
11820   unformat_input_t *i = vam->input;
11821   vl_api_policer_classify_dump_t *mp;
11822   vl_api_control_ping_t *mp_ping;
11823   u8 type = POLICER_CLASSIFY_N_TABLES;
11824   int ret;
11825
11826   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
11827     ;
11828   else
11829     {
11830       errmsg ("classify table type must be specified");
11831       return -99;
11832     }
11833
11834   if (!vam->json_output)
11835     {
11836       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
11837     }
11838
11839   M (POLICER_CLASSIFY_DUMP, mp);
11840   mp->type = type;
11841   /* send it... */
11842   S (mp);
11843
11844   /* Use a control ping for synchronization */
11845   MPING (CONTROL_PING, mp_ping);
11846   S (mp_ping);
11847
11848   /* Wait for a reply... */
11849   W (ret);
11850   return ret;
11851 }
11852
11853 static u8 *
11854 format_fib_api_path_nh_proto (u8 * s, va_list * args)
11855 {
11856   vl_api_fib_path_nh_proto_t proto =
11857     va_arg (*args, vl_api_fib_path_nh_proto_t);
11858
11859   switch (proto)
11860     {
11861     case FIB_API_PATH_NH_PROTO_IP4:
11862       s = format (s, "ip4");
11863       break;
11864     case FIB_API_PATH_NH_PROTO_IP6:
11865       s = format (s, "ip6");
11866       break;
11867     case FIB_API_PATH_NH_PROTO_MPLS:
11868       s = format (s, "mpls");
11869       break;
11870     case FIB_API_PATH_NH_PROTO_BIER:
11871       s = format (s, "bier");
11872       break;
11873     case FIB_API_PATH_NH_PROTO_ETHERNET:
11874       s = format (s, "ethernet");
11875       break;
11876     }
11877
11878   return (s);
11879 }
11880
11881 static u8 *
11882 format_vl_api_ip_address_union (u8 * s, va_list * args)
11883 {
11884   vl_api_address_family_t af = va_arg (*args, int);
11885   const vl_api_address_union_t *u = va_arg (*args, vl_api_address_union_t *);
11886
11887   switch (af)
11888     {
11889     case ADDRESS_IP4:
11890       s = format (s, "%U", format_ip4_address, u->ip4);
11891       break;
11892     case ADDRESS_IP6:
11893       s = format (s, "%U", format_ip6_address, u->ip6);
11894       break;
11895     }
11896   return (s);
11897 }
11898
11899 static u8 *
11900 format_vl_api_fib_path_type (u8 * s, va_list * args)
11901 {
11902   vl_api_fib_path_type_t t = va_arg (*args, vl_api_fib_path_type_t);
11903
11904   switch (t)
11905     {
11906     case FIB_API_PATH_TYPE_NORMAL:
11907       s = format (s, "normal");
11908       break;
11909     case FIB_API_PATH_TYPE_LOCAL:
11910       s = format (s, "local");
11911       break;
11912     case FIB_API_PATH_TYPE_DROP:
11913       s = format (s, "drop");
11914       break;
11915     case FIB_API_PATH_TYPE_UDP_ENCAP:
11916       s = format (s, "udp-encap");
11917       break;
11918     case FIB_API_PATH_TYPE_BIER_IMP:
11919       s = format (s, "bier-imp");
11920       break;
11921     case FIB_API_PATH_TYPE_ICMP_UNREACH:
11922       s = format (s, "unreach");
11923       break;
11924     case FIB_API_PATH_TYPE_ICMP_PROHIBIT:
11925       s = format (s, "prohibit");
11926       break;
11927     case FIB_API_PATH_TYPE_SOURCE_LOOKUP:
11928       s = format (s, "src-lookup");
11929       break;
11930     case FIB_API_PATH_TYPE_DVR:
11931       s = format (s, "dvr");
11932       break;
11933     case FIB_API_PATH_TYPE_INTERFACE_RX:
11934       s = format (s, "interface-rx");
11935       break;
11936     case FIB_API_PATH_TYPE_CLASSIFY:
11937       s = format (s, "classify");
11938       break;
11939     }
11940
11941   return (s);
11942 }
11943
11944 static void
11945 vl_api_fib_path_print (vat_main_t * vam, vl_api_fib_path_t * fp)
11946 {
11947   print (vam->ofp,
11948          "  weight %d, sw_if_index %d, type %U, afi %U, next_hop %U",
11949          ntohl (fp->weight), ntohl (fp->sw_if_index),
11950          format_vl_api_fib_path_type, fp->type,
11951          format_fib_api_path_nh_proto, fp->proto,
11952          format_vl_api_ip_address_union, &fp->nh.address);
11953 }
11954
11955 static void
11956 vl_api_mpls_fib_path_json_print (vat_json_node_t * node,
11957                                  vl_api_fib_path_t * fp)
11958 {
11959   struct in_addr ip4;
11960   struct in6_addr ip6;
11961
11962   vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
11963   vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
11964   vat_json_object_add_uint (node, "type", fp->type);
11965   vat_json_object_add_uint (node, "next_hop_proto", fp->proto);
11966   if (fp->proto == FIB_API_PATH_NH_PROTO_IP4)
11967     {
11968       clib_memcpy (&ip4, &fp->nh.address.ip4, sizeof (ip4));
11969       vat_json_object_add_ip4 (node, "next_hop", ip4);
11970     }
11971   else if (fp->proto == FIB_API_PATH_NH_PROTO_IP6)
11972     {
11973       clib_memcpy (&ip6, &fp->nh.address.ip6, sizeof (ip6));
11974       vat_json_object_add_ip6 (node, "next_hop", ip6);
11975     }
11976 }
11977
11978 static void
11979 vl_api_mpls_tunnel_details_t_handler (vl_api_mpls_tunnel_details_t * mp)
11980 {
11981   vat_main_t *vam = &vat_main;
11982   int count = ntohl (mp->mt_tunnel.mt_n_paths);
11983   vl_api_fib_path_t *fp;
11984   i32 i;
11985
11986   print (vam->ofp, "sw_if_index %d via:",
11987          ntohl (mp->mt_tunnel.mt_sw_if_index));
11988   fp = mp->mt_tunnel.mt_paths;
11989   for (i = 0; i < count; i++)
11990     {
11991       vl_api_fib_path_print (vam, fp);
11992       fp++;
11993     }
11994
11995   print (vam->ofp, "");
11996 }
11997
11998 #define vl_api_mpls_tunnel_details_t_endian vl_noop_handler
11999 #define vl_api_mpls_tunnel_details_t_print vl_noop_handler
12000
12001 static void
12002 vl_api_mpls_tunnel_details_t_handler_json (vl_api_mpls_tunnel_details_t * mp)
12003 {
12004   vat_main_t *vam = &vat_main;
12005   vat_json_node_t *node = NULL;
12006   int count = ntohl (mp->mt_tunnel.mt_n_paths);
12007   vl_api_fib_path_t *fp;
12008   i32 i;
12009
12010   if (VAT_JSON_ARRAY != vam->json_tree.type)
12011     {
12012       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12013       vat_json_init_array (&vam->json_tree);
12014     }
12015   node = vat_json_array_add (&vam->json_tree);
12016
12017   vat_json_init_object (node);
12018   vat_json_object_add_uint (node, "sw_if_index",
12019                             ntohl (mp->mt_tunnel.mt_sw_if_index));
12020
12021   vat_json_object_add_uint (node, "l2_only", mp->mt_tunnel.mt_l2_only);
12022
12023   fp = mp->mt_tunnel.mt_paths;
12024   for (i = 0; i < count; i++)
12025     {
12026       vl_api_mpls_fib_path_json_print (node, fp);
12027       fp++;
12028     }
12029 }
12030
12031 static int
12032 api_mpls_tunnel_dump (vat_main_t * vam)
12033 {
12034   vl_api_mpls_tunnel_dump_t *mp;
12035   vl_api_control_ping_t *mp_ping;
12036   int ret;
12037
12038   M (MPLS_TUNNEL_DUMP, mp);
12039
12040   S (mp);
12041
12042   /* Use a control ping for synchronization */
12043   MPING (CONTROL_PING, mp_ping);
12044   S (mp_ping);
12045
12046   W (ret);
12047   return ret;
12048 }
12049
12050 #define vl_api_mpls_table_details_t_endian vl_noop_handler
12051 #define vl_api_mpls_table_details_t_print vl_noop_handler
12052
12053
12054 static void
12055 vl_api_mpls_table_details_t_handler (vl_api_mpls_table_details_t * mp)
12056 {
12057   vat_main_t *vam = &vat_main;
12058
12059   print (vam->ofp, "table-id %d,", ntohl (mp->mt_table.mt_table_id));
12060 }
12061
12062 static void vl_api_mpls_table_details_t_handler_json
12063   (vl_api_mpls_table_details_t * mp)
12064 {
12065   vat_main_t *vam = &vat_main;
12066   vat_json_node_t *node = NULL;
12067
12068   if (VAT_JSON_ARRAY != vam->json_tree.type)
12069     {
12070       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12071       vat_json_init_array (&vam->json_tree);
12072     }
12073   node = vat_json_array_add (&vam->json_tree);
12074
12075   vat_json_init_object (node);
12076   vat_json_object_add_uint (node, "table", ntohl (mp->mt_table.mt_table_id));
12077 }
12078
12079 static int
12080 api_mpls_table_dump (vat_main_t * vam)
12081 {
12082   vl_api_mpls_table_dump_t *mp;
12083   vl_api_control_ping_t *mp_ping;
12084   int ret;
12085
12086   M (MPLS_TABLE_DUMP, mp);
12087   S (mp);
12088
12089   /* Use a control ping for synchronization */
12090   MPING (CONTROL_PING, mp_ping);
12091   S (mp_ping);
12092
12093   W (ret);
12094   return ret;
12095 }
12096
12097 #define vl_api_mpls_route_details_t_endian vl_noop_handler
12098 #define vl_api_mpls_route_details_t_print vl_noop_handler
12099
12100 static void
12101 vl_api_mpls_route_details_t_handler (vl_api_mpls_route_details_t * mp)
12102 {
12103   vat_main_t *vam = &vat_main;
12104   int count = (int) clib_net_to_host_u32 (mp->mr_route.mr_n_paths);
12105   vl_api_fib_path_t *fp;
12106   int i;
12107
12108   print (vam->ofp,
12109          "table-id %d, label %u, ess_bit %u",
12110          ntohl (mp->mr_route.mr_table_id),
12111          ntohl (mp->mr_route.mr_label), mp->mr_route.mr_eos);
12112   fp = mp->mr_route.mr_paths;
12113   for (i = 0; i < count; i++)
12114     {
12115       vl_api_fib_path_print (vam, fp);
12116       fp++;
12117     }
12118 }
12119
12120 static void vl_api_mpls_route_details_t_handler_json
12121   (vl_api_mpls_route_details_t * mp)
12122 {
12123   vat_main_t *vam = &vat_main;
12124   int count = (int) clib_host_to_net_u32 (mp->mr_route.mr_n_paths);
12125   vat_json_node_t *node = NULL;
12126   vl_api_fib_path_t *fp;
12127   int i;
12128
12129   if (VAT_JSON_ARRAY != vam->json_tree.type)
12130     {
12131       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12132       vat_json_init_array (&vam->json_tree);
12133     }
12134   node = vat_json_array_add (&vam->json_tree);
12135
12136   vat_json_init_object (node);
12137   vat_json_object_add_uint (node, "table", ntohl (mp->mr_route.mr_table_id));
12138   vat_json_object_add_uint (node, "s_bit", mp->mr_route.mr_eos);
12139   vat_json_object_add_uint (node, "label", ntohl (mp->mr_route.mr_label));
12140   vat_json_object_add_uint (node, "path_count", count);
12141   fp = mp->mr_route.mr_paths;
12142   for (i = 0; i < count; i++)
12143     {
12144       vl_api_mpls_fib_path_json_print (node, fp);
12145       fp++;
12146     }
12147 }
12148
12149 static int
12150 api_mpls_route_dump (vat_main_t * vam)
12151 {
12152   unformat_input_t *input = vam->input;
12153   vl_api_mpls_route_dump_t *mp;
12154   vl_api_control_ping_t *mp_ping;
12155   u32 table_id;
12156   int ret;
12157
12158   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12159     {
12160       if (unformat (input, "table_id %d", &table_id))
12161         ;
12162       else
12163         break;
12164     }
12165   if (table_id == ~0)
12166     {
12167       errmsg ("missing table id");
12168       return -99;
12169     }
12170
12171   M (MPLS_ROUTE_DUMP, mp);
12172
12173   mp->table.mt_table_id = ntohl (table_id);
12174   S (mp);
12175
12176   /* Use a control ping for synchronization */
12177   MPING (CONTROL_PING, mp_ping);
12178   S (mp_ping);
12179
12180   W (ret);
12181   return ret;
12182 }
12183
12184 #define vl_api_ip_table_details_t_endian vl_noop_handler
12185 #define vl_api_ip_table_details_t_print vl_noop_handler
12186
12187 static void
12188 vl_api_ip_table_details_t_handler (vl_api_ip_table_details_t * mp)
12189 {
12190   vat_main_t *vam = &vat_main;
12191
12192   print (vam->ofp,
12193          "%s; table-id %d, prefix %U/%d",
12194          mp->table.name, ntohl (mp->table.table_id));
12195 }
12196
12197
12198 static void vl_api_ip_table_details_t_handler_json
12199   (vl_api_ip_table_details_t * mp)
12200 {
12201   vat_main_t *vam = &vat_main;
12202   vat_json_node_t *node = NULL;
12203
12204   if (VAT_JSON_ARRAY != vam->json_tree.type)
12205     {
12206       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12207       vat_json_init_array (&vam->json_tree);
12208     }
12209   node = vat_json_array_add (&vam->json_tree);
12210
12211   vat_json_init_object (node);
12212   vat_json_object_add_uint (node, "table", ntohl (mp->table.table_id));
12213 }
12214
12215 static int
12216 api_ip_table_dump (vat_main_t * vam)
12217 {
12218   vl_api_ip_table_dump_t *mp;
12219   vl_api_control_ping_t *mp_ping;
12220   int ret;
12221
12222   M (IP_TABLE_DUMP, mp);
12223   S (mp);
12224
12225   /* Use a control ping for synchronization */
12226   MPING (CONTROL_PING, mp_ping);
12227   S (mp_ping);
12228
12229   W (ret);
12230   return ret;
12231 }
12232
12233 static int
12234 api_ip_mtable_dump (vat_main_t * vam)
12235 {
12236   vl_api_ip_mtable_dump_t *mp;
12237   vl_api_control_ping_t *mp_ping;
12238   int ret;
12239
12240   M (IP_MTABLE_DUMP, mp);
12241   S (mp);
12242
12243   /* Use a control ping for synchronization */
12244   MPING (CONTROL_PING, mp_ping);
12245   S (mp_ping);
12246
12247   W (ret);
12248   return ret;
12249 }
12250
12251 static int
12252 api_ip_mroute_dump (vat_main_t * vam)
12253 {
12254   unformat_input_t *input = vam->input;
12255   vl_api_control_ping_t *mp_ping;
12256   vl_api_ip_mroute_dump_t *mp;
12257   int ret, is_ip6;
12258   u32 table_id;
12259
12260   is_ip6 = 0;
12261   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12262     {
12263       if (unformat (input, "table_id %d", &table_id))
12264         ;
12265       else if (unformat (input, "ip6"))
12266         is_ip6 = 1;
12267       else if (unformat (input, "ip4"))
12268         is_ip6 = 0;
12269       else
12270         break;
12271     }
12272   if (table_id == ~0)
12273     {
12274       errmsg ("missing table id");
12275       return -99;
12276     }
12277
12278   M (IP_MROUTE_DUMP, mp);
12279   mp->table.table_id = table_id;
12280   mp->table.is_ip6 = is_ip6;
12281   S (mp);
12282
12283   /* Use a control ping for synchronization */
12284   MPING (CONTROL_PING, mp_ping);
12285   S (mp_ping);
12286
12287   W (ret);
12288   return ret;
12289 }
12290
12291 #define vl_api_ip_route_details_t_endian vl_noop_handler
12292 #define vl_api_ip_route_details_t_print vl_noop_handler
12293
12294 static void
12295 vl_api_ip_route_details_t_handler (vl_api_ip_route_details_t * mp)
12296 {
12297   vat_main_t *vam = &vat_main;
12298   u8 count = mp->route.n_paths;
12299   vl_api_fib_path_t *fp;
12300   int i;
12301
12302   print (vam->ofp,
12303          "table-id %d, prefix %U/%d",
12304          ntohl (mp->route.table_id),
12305          format_ip46_address, mp->route.prefix.address, mp->route.prefix.len);
12306   for (i = 0; i < count; i++)
12307     {
12308       fp = &mp->route.paths[i];
12309
12310       vl_api_fib_path_print (vam, fp);
12311       fp++;
12312     }
12313 }
12314
12315 static void vl_api_ip_route_details_t_handler_json
12316   (vl_api_ip_route_details_t * mp)
12317 {
12318   vat_main_t *vam = &vat_main;
12319   u8 count = mp->route.n_paths;
12320   vat_json_node_t *node = NULL;
12321   struct in_addr ip4;
12322   struct in6_addr ip6;
12323   vl_api_fib_path_t *fp;
12324   int i;
12325
12326   if (VAT_JSON_ARRAY != vam->json_tree.type)
12327     {
12328       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12329       vat_json_init_array (&vam->json_tree);
12330     }
12331   node = vat_json_array_add (&vam->json_tree);
12332
12333   vat_json_init_object (node);
12334   vat_json_object_add_uint (node, "table", ntohl (mp->route.table_id));
12335   if (ADDRESS_IP6 == mp->route.prefix.address.af)
12336     {
12337       clib_memcpy (&ip6, &mp->route.prefix.address.un.ip6, sizeof (ip6));
12338       vat_json_object_add_ip6 (node, "prefix", ip6);
12339     }
12340   else
12341     {
12342       clib_memcpy (&ip4, &mp->route.prefix.address.un.ip4, sizeof (ip4));
12343       vat_json_object_add_ip4 (node, "prefix", ip4);
12344     }
12345   vat_json_object_add_uint (node, "mask_length", mp->route.prefix.len);
12346   vat_json_object_add_uint (node, "path_count", count);
12347   for (i = 0; i < count; i++)
12348     {
12349       fp = &mp->route.paths[i];
12350       vl_api_mpls_fib_path_json_print (node, fp);
12351     }
12352 }
12353
12354 static int
12355 api_ip_route_dump (vat_main_t * vam)
12356 {
12357   unformat_input_t *input = vam->input;
12358   vl_api_ip_route_dump_t *mp;
12359   vl_api_control_ping_t *mp_ping;
12360   u32 table_id;
12361   u8 is_ip6;
12362   int ret;
12363
12364   is_ip6 = 0;
12365   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12366     {
12367       if (unformat (input, "table_id %d", &table_id))
12368         ;
12369       else if (unformat (input, "ip6"))
12370         is_ip6 = 1;
12371       else if (unformat (input, "ip4"))
12372         is_ip6 = 0;
12373       else
12374         break;
12375     }
12376   if (table_id == ~0)
12377     {
12378       errmsg ("missing table id");
12379       return -99;
12380     }
12381
12382   M (IP_ROUTE_DUMP, mp);
12383
12384   mp->table.table_id = table_id;
12385   mp->table.is_ip6 = is_ip6;
12386
12387   S (mp);
12388
12389   /* Use a control ping for synchronization */
12390   MPING (CONTROL_PING, mp_ping);
12391   S (mp_ping);
12392
12393   W (ret);
12394   return ret;
12395 }
12396
12397 int
12398 api_classify_table_ids (vat_main_t * vam)
12399 {
12400   vl_api_classify_table_ids_t *mp;
12401   int ret;
12402
12403   /* Construct the API message */
12404   M (CLASSIFY_TABLE_IDS, mp);
12405   mp->context = 0;
12406
12407   S (mp);
12408   W (ret);
12409   return ret;
12410 }
12411
12412 int
12413 api_classify_table_by_interface (vat_main_t * vam)
12414 {
12415   unformat_input_t *input = vam->input;
12416   vl_api_classify_table_by_interface_t *mp;
12417
12418   u32 sw_if_index = ~0;
12419   int ret;
12420   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12421     {
12422       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12423         ;
12424       else if (unformat (input, "sw_if_index %d", &sw_if_index))
12425         ;
12426       else
12427         break;
12428     }
12429   if (sw_if_index == ~0)
12430     {
12431       errmsg ("missing interface name or sw_if_index");
12432       return -99;
12433     }
12434
12435   /* Construct the API message */
12436   M (CLASSIFY_TABLE_BY_INTERFACE, mp);
12437   mp->context = 0;
12438   mp->sw_if_index = ntohl (sw_if_index);
12439
12440   S (mp);
12441   W (ret);
12442   return ret;
12443 }
12444
12445 int
12446 api_classify_table_info (vat_main_t * vam)
12447 {
12448   unformat_input_t *input = vam->input;
12449   vl_api_classify_table_info_t *mp;
12450
12451   u32 table_id = ~0;
12452   int ret;
12453   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12454     {
12455       if (unformat (input, "table_id %d", &table_id))
12456         ;
12457       else
12458         break;
12459     }
12460   if (table_id == ~0)
12461     {
12462       errmsg ("missing table id");
12463       return -99;
12464     }
12465
12466   /* Construct the API message */
12467   M (CLASSIFY_TABLE_INFO, mp);
12468   mp->context = 0;
12469   mp->table_id = ntohl (table_id);
12470
12471   S (mp);
12472   W (ret);
12473   return ret;
12474 }
12475
12476 int
12477 api_classify_session_dump (vat_main_t * vam)
12478 {
12479   unformat_input_t *input = vam->input;
12480   vl_api_classify_session_dump_t *mp;
12481   vl_api_control_ping_t *mp_ping;
12482
12483   u32 table_id = ~0;
12484   int ret;
12485   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12486     {
12487       if (unformat (input, "table_id %d", &table_id))
12488         ;
12489       else
12490         break;
12491     }
12492   if (table_id == ~0)
12493     {
12494       errmsg ("missing table id");
12495       return -99;
12496     }
12497
12498   /* Construct the API message */
12499   M (CLASSIFY_SESSION_DUMP, mp);
12500   mp->context = 0;
12501   mp->table_id = ntohl (table_id);
12502   S (mp);
12503
12504   /* Use a control ping for synchronization */
12505   MPING (CONTROL_PING, mp_ping);
12506   S (mp_ping);
12507
12508   W (ret);
12509   return ret;
12510 }
12511
12512 static void
12513 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
12514 {
12515   vat_main_t *vam = &vat_main;
12516
12517   print (vam->ofp, "collector_address %U, collector_port %d, "
12518          "src_address %U, vrf_id %d, path_mtu %u, "
12519          "template_interval %u, udp_checksum %d",
12520          format_ip4_address, mp->collector_address,
12521          ntohs (mp->collector_port),
12522          format_ip4_address, mp->src_address,
12523          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
12524          ntohl (mp->template_interval), mp->udp_checksum);
12525
12526   vam->retval = 0;
12527   vam->result_ready = 1;
12528 }
12529
12530 static void
12531   vl_api_ipfix_exporter_details_t_handler_json
12532   (vl_api_ipfix_exporter_details_t * mp)
12533 {
12534   vat_main_t *vam = &vat_main;
12535   vat_json_node_t node;
12536   struct in_addr collector_address;
12537   struct in_addr src_address;
12538
12539   vat_json_init_object (&node);
12540   clib_memcpy (&collector_address, &mp->collector_address,
12541                sizeof (collector_address));
12542   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
12543   vat_json_object_add_uint (&node, "collector_port",
12544                             ntohs (mp->collector_port));
12545   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
12546   vat_json_object_add_ip4 (&node, "src_address", src_address);
12547   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
12548   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
12549   vat_json_object_add_uint (&node, "template_interval",
12550                             ntohl (mp->template_interval));
12551   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
12552
12553   vat_json_print (vam->ofp, &node);
12554   vat_json_free (&node);
12555   vam->retval = 0;
12556   vam->result_ready = 1;
12557 }
12558
12559 int
12560 api_ipfix_exporter_dump (vat_main_t * vam)
12561 {
12562   vl_api_ipfix_exporter_dump_t *mp;
12563   int ret;
12564
12565   /* Construct the API message */
12566   M (IPFIX_EXPORTER_DUMP, mp);
12567   mp->context = 0;
12568
12569   S (mp);
12570   W (ret);
12571   return ret;
12572 }
12573
12574 static int
12575 api_ipfix_classify_stream_dump (vat_main_t * vam)
12576 {
12577   vl_api_ipfix_classify_stream_dump_t *mp;
12578   int ret;
12579
12580   /* Construct the API message */
12581   M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
12582   mp->context = 0;
12583
12584   S (mp);
12585   W (ret);
12586   return ret;
12587   /* NOTREACHED */
12588   return 0;
12589 }
12590
12591 static void
12592   vl_api_ipfix_classify_stream_details_t_handler
12593   (vl_api_ipfix_classify_stream_details_t * mp)
12594 {
12595   vat_main_t *vam = &vat_main;
12596   print (vam->ofp, "domain_id %d, src_port %d",
12597          ntohl (mp->domain_id), ntohs (mp->src_port));
12598   vam->retval = 0;
12599   vam->result_ready = 1;
12600 }
12601
12602 static void
12603   vl_api_ipfix_classify_stream_details_t_handler_json
12604   (vl_api_ipfix_classify_stream_details_t * mp)
12605 {
12606   vat_main_t *vam = &vat_main;
12607   vat_json_node_t node;
12608
12609   vat_json_init_object (&node);
12610   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
12611   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
12612
12613   vat_json_print (vam->ofp, &node);
12614   vat_json_free (&node);
12615   vam->retval = 0;
12616   vam->result_ready = 1;
12617 }
12618
12619 static int
12620 api_ipfix_classify_table_dump (vat_main_t * vam)
12621 {
12622   vl_api_ipfix_classify_table_dump_t *mp;
12623   vl_api_control_ping_t *mp_ping;
12624   int ret;
12625
12626   if (!vam->json_output)
12627     {
12628       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
12629              "transport_protocol");
12630     }
12631
12632   /* Construct the API message */
12633   M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
12634
12635   /* send it... */
12636   S (mp);
12637
12638   /* Use a control ping for synchronization */
12639   MPING (CONTROL_PING, mp_ping);
12640   S (mp_ping);
12641
12642   W (ret);
12643   return ret;
12644 }
12645
12646 static void
12647   vl_api_ipfix_classify_table_details_t_handler
12648   (vl_api_ipfix_classify_table_details_t * mp)
12649 {
12650   vat_main_t *vam = &vat_main;
12651   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
12652          mp->transport_protocol);
12653 }
12654
12655 static void
12656   vl_api_ipfix_classify_table_details_t_handler_json
12657   (vl_api_ipfix_classify_table_details_t * mp)
12658 {
12659   vat_json_node_t *node = NULL;
12660   vat_main_t *vam = &vat_main;
12661
12662   if (VAT_JSON_ARRAY != vam->json_tree.type)
12663     {
12664       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12665       vat_json_init_array (&vam->json_tree);
12666     }
12667
12668   node = vat_json_array_add (&vam->json_tree);
12669   vat_json_init_object (node);
12670
12671   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
12672   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
12673   vat_json_object_add_uint (node, "transport_protocol",
12674                             mp->transport_protocol);
12675 }
12676
12677 static int
12678 api_sw_interface_span_enable_disable (vat_main_t * vam)
12679 {
12680   unformat_input_t *i = vam->input;
12681   vl_api_sw_interface_span_enable_disable_t *mp;
12682   u32 src_sw_if_index = ~0;
12683   u32 dst_sw_if_index = ~0;
12684   u8 state = 3;
12685   int ret;
12686   u8 is_l2 = 0;
12687
12688   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12689     {
12690       if (unformat
12691           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
12692         ;
12693       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
12694         ;
12695       else
12696         if (unformat
12697             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
12698         ;
12699       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
12700         ;
12701       else if (unformat (i, "disable"))
12702         state = 0;
12703       else if (unformat (i, "rx"))
12704         state = 1;
12705       else if (unformat (i, "tx"))
12706         state = 2;
12707       else if (unformat (i, "both"))
12708         state = 3;
12709       else if (unformat (i, "l2"))
12710         is_l2 = 1;
12711       else
12712         break;
12713     }
12714
12715   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
12716
12717   mp->sw_if_index_from = htonl (src_sw_if_index);
12718   mp->sw_if_index_to = htonl (dst_sw_if_index);
12719   mp->state = state;
12720   mp->is_l2 = is_l2;
12721
12722   S (mp);
12723   W (ret);
12724   return ret;
12725 }
12726
12727 static void
12728 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
12729                                             * mp)
12730 {
12731   vat_main_t *vam = &vat_main;
12732   u8 *sw_if_from_name = 0;
12733   u8 *sw_if_to_name = 0;
12734   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
12735   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
12736   char *states[] = { "none", "rx", "tx", "both" };
12737   hash_pair_t *p;
12738
12739   /* *INDENT-OFF* */
12740   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
12741   ({
12742     if ((u32) p->value[0] == sw_if_index_from)
12743       {
12744         sw_if_from_name = (u8 *)(p->key);
12745         if (sw_if_to_name)
12746           break;
12747       }
12748     if ((u32) p->value[0] == sw_if_index_to)
12749       {
12750         sw_if_to_name = (u8 *)(p->key);
12751         if (sw_if_from_name)
12752           break;
12753       }
12754   }));
12755   /* *INDENT-ON* */
12756   print (vam->ofp, "%20s => %20s (%s) %s",
12757          sw_if_from_name, sw_if_to_name, states[mp->state],
12758          mp->is_l2 ? "l2" : "device");
12759 }
12760
12761 static void
12762   vl_api_sw_interface_span_details_t_handler_json
12763   (vl_api_sw_interface_span_details_t * mp)
12764 {
12765   vat_main_t *vam = &vat_main;
12766   vat_json_node_t *node = NULL;
12767   u8 *sw_if_from_name = 0;
12768   u8 *sw_if_to_name = 0;
12769   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
12770   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
12771   hash_pair_t *p;
12772
12773   /* *INDENT-OFF* */
12774   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
12775   ({
12776     if ((u32) p->value[0] == sw_if_index_from)
12777       {
12778         sw_if_from_name = (u8 *)(p->key);
12779         if (sw_if_to_name)
12780           break;
12781       }
12782     if ((u32) p->value[0] == sw_if_index_to)
12783       {
12784         sw_if_to_name = (u8 *)(p->key);
12785         if (sw_if_from_name)
12786           break;
12787       }
12788   }));
12789   /* *INDENT-ON* */
12790
12791   if (VAT_JSON_ARRAY != vam->json_tree.type)
12792     {
12793       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12794       vat_json_init_array (&vam->json_tree);
12795     }
12796   node = vat_json_array_add (&vam->json_tree);
12797
12798   vat_json_init_object (node);
12799   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
12800   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
12801   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
12802   if (0 != sw_if_to_name)
12803     {
12804       vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
12805     }
12806   vat_json_object_add_uint (node, "state", mp->state);
12807   vat_json_object_add_uint (node, "is-l2", mp->is_l2);
12808 }
12809
12810 static int
12811 api_sw_interface_span_dump (vat_main_t * vam)
12812 {
12813   unformat_input_t *input = vam->input;
12814   vl_api_sw_interface_span_dump_t *mp;
12815   vl_api_control_ping_t *mp_ping;
12816   u8 is_l2 = 0;
12817   int ret;
12818
12819   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12820     {
12821       if (unformat (input, "l2"))
12822         is_l2 = 1;
12823       else
12824         break;
12825     }
12826
12827   M (SW_INTERFACE_SPAN_DUMP, mp);
12828   mp->is_l2 = is_l2;
12829   S (mp);
12830
12831   /* Use a control ping for synchronization */
12832   MPING (CONTROL_PING, mp_ping);
12833   S (mp_ping);
12834
12835   W (ret);
12836   return ret;
12837 }
12838
12839 int
12840 api_pg_create_interface (vat_main_t * vam)
12841 {
12842   unformat_input_t *input = vam->input;
12843   vl_api_pg_create_interface_t *mp;
12844
12845   u32 if_id = ~0, gso_size = 0;
12846   u8 gso_enabled = 0;
12847   int ret;
12848   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12849     {
12850       if (unformat (input, "if_id %d", &if_id))
12851         ;
12852       else if (unformat (input, "gso-enabled"))
12853         {
12854           gso_enabled = 1;
12855           if (unformat (input, "gso-size %u", &gso_size))
12856             ;
12857           else
12858             {
12859               errmsg ("missing gso-size");
12860               return -99;
12861             }
12862         }
12863       else
12864         break;
12865     }
12866   if (if_id == ~0)
12867     {
12868       errmsg ("missing pg interface index");
12869       return -99;
12870     }
12871
12872   /* Construct the API message */
12873   M (PG_CREATE_INTERFACE, mp);
12874   mp->context = 0;
12875   mp->interface_id = ntohl (if_id);
12876   mp->gso_enabled = gso_enabled;
12877
12878   S (mp);
12879   W (ret);
12880   return ret;
12881 }
12882
12883 int
12884 api_pg_capture (vat_main_t * vam)
12885 {
12886   unformat_input_t *input = vam->input;
12887   vl_api_pg_capture_t *mp;
12888
12889   u32 if_id = ~0;
12890   u8 enable = 1;
12891   u32 count = 1;
12892   u8 pcap_file_set = 0;
12893   u8 *pcap_file = 0;
12894   int ret;
12895   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12896     {
12897       if (unformat (input, "if_id %d", &if_id))
12898         ;
12899       else if (unformat (input, "pcap %s", &pcap_file))
12900         pcap_file_set = 1;
12901       else if (unformat (input, "count %d", &count))
12902         ;
12903       else if (unformat (input, "disable"))
12904         enable = 0;
12905       else
12906         break;
12907     }
12908   if (if_id == ~0)
12909     {
12910       errmsg ("missing pg interface index");
12911       return -99;
12912     }
12913   if (pcap_file_set > 0)
12914     {
12915       if (vec_len (pcap_file) > 255)
12916         {
12917           errmsg ("pcap file name is too long");
12918           return -99;
12919         }
12920     }
12921
12922   /* Construct the API message */
12923   M (PG_CAPTURE, mp);
12924   mp->context = 0;
12925   mp->interface_id = ntohl (if_id);
12926   mp->is_enabled = enable;
12927   mp->count = ntohl (count);
12928   if (pcap_file_set != 0)
12929     {
12930       vl_api_vec_to_api_string (pcap_file, &mp->pcap_file_name);
12931     }
12932   vec_free (pcap_file);
12933
12934   S (mp);
12935   W (ret);
12936   return ret;
12937 }
12938
12939 int
12940 api_pg_enable_disable (vat_main_t * vam)
12941 {
12942   unformat_input_t *input = vam->input;
12943   vl_api_pg_enable_disable_t *mp;
12944
12945   u8 enable = 1;
12946   u8 stream_name_set = 0;
12947   u8 *stream_name = 0;
12948   int ret;
12949   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12950     {
12951       if (unformat (input, "stream %s", &stream_name))
12952         stream_name_set = 1;
12953       else if (unformat (input, "disable"))
12954         enable = 0;
12955       else
12956         break;
12957     }
12958
12959   if (stream_name_set > 0)
12960     {
12961       if (vec_len (stream_name) > 255)
12962         {
12963           errmsg ("stream name too long");
12964           return -99;
12965         }
12966     }
12967
12968   /* Construct the API message */
12969   M (PG_ENABLE_DISABLE, mp);
12970   mp->context = 0;
12971   mp->is_enabled = enable;
12972   if (stream_name_set != 0)
12973     {
12974       vl_api_vec_to_api_string (stream_name, &mp->stream_name);
12975     }
12976   vec_free (stream_name);
12977
12978   S (mp);
12979   W (ret);
12980   return ret;
12981 }
12982
12983 int
12984 api_pg_interface_enable_disable_coalesce (vat_main_t * vam)
12985 {
12986   unformat_input_t *input = vam->input;
12987   vl_api_pg_interface_enable_disable_coalesce_t *mp;
12988
12989   u32 sw_if_index = ~0;
12990   u8 enable = 1;
12991   int ret;
12992   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12993     {
12994       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12995         ;
12996       else if (unformat (input, "sw_if_index %d", &sw_if_index))
12997         ;
12998       else if (unformat (input, "disable"))
12999         enable = 0;
13000       else
13001         break;
13002     }
13003
13004   if (sw_if_index == ~0)
13005     {
13006       errmsg ("Interface required but not specified");
13007       return -99;
13008     }
13009
13010   /* Construct the API message */
13011   M (PG_INTERFACE_ENABLE_DISABLE_COALESCE, mp);
13012   mp->context = 0;
13013   mp->coalesce_enabled = enable;
13014   mp->sw_if_index = htonl (sw_if_index);
13015
13016   S (mp);
13017   W (ret);
13018   return ret;
13019 }
13020
13021 int
13022 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
13023 {
13024   unformat_input_t *input = vam->input;
13025   vl_api_ip_source_and_port_range_check_add_del_t *mp;
13026
13027   u16 *low_ports = 0;
13028   u16 *high_ports = 0;
13029   u16 this_low;
13030   u16 this_hi;
13031   vl_api_prefix_t prefix;
13032   u32 tmp, tmp2;
13033   u8 prefix_set = 0;
13034   u32 vrf_id = ~0;
13035   u8 is_add = 1;
13036   int ret;
13037
13038   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13039     {
13040       if (unformat (input, "%U", unformat_vl_api_prefix, &prefix))
13041         prefix_set = 1;
13042       else if (unformat (input, "vrf %d", &vrf_id))
13043         ;
13044       else if (unformat (input, "del"))
13045         is_add = 0;
13046       else if (unformat (input, "port %d", &tmp))
13047         {
13048           if (tmp == 0 || tmp > 65535)
13049             {
13050               errmsg ("port %d out of range", tmp);
13051               return -99;
13052             }
13053           this_low = tmp;
13054           this_hi = this_low + 1;
13055           vec_add1 (low_ports, this_low);
13056           vec_add1 (high_ports, this_hi);
13057         }
13058       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
13059         {
13060           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
13061             {
13062               errmsg ("incorrect range parameters");
13063               return -99;
13064             }
13065           this_low = tmp;
13066           /* Note: in debug CLI +1 is added to high before
13067              passing to real fn that does "the work"
13068              (ip_source_and_port_range_check_add_del).
13069              This fn is a wrapper around the binary API fn a
13070              control plane will call, which expects this increment
13071              to have occurred. Hence letting the binary API control
13072              plane fn do the increment for consistency between VAT
13073              and other control planes.
13074            */
13075           this_hi = tmp2;
13076           vec_add1 (low_ports, this_low);
13077           vec_add1 (high_ports, this_hi);
13078         }
13079       else
13080         break;
13081     }
13082
13083   if (prefix_set == 0)
13084     {
13085       errmsg ("<address>/<mask> not specified");
13086       return -99;
13087     }
13088
13089   if (vrf_id == ~0)
13090     {
13091       errmsg ("VRF ID required, not specified");
13092       return -99;
13093     }
13094
13095   if (vrf_id == 0)
13096     {
13097       errmsg
13098         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
13099       return -99;
13100     }
13101
13102   if (vec_len (low_ports) == 0)
13103     {
13104       errmsg ("At least one port or port range required");
13105       return -99;
13106     }
13107
13108   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
13109
13110   mp->is_add = is_add;
13111
13112   clib_memcpy (&mp->prefix, &prefix, sizeof (prefix));
13113
13114   mp->number_of_ranges = vec_len (low_ports);
13115
13116   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
13117   vec_free (low_ports);
13118
13119   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
13120   vec_free (high_ports);
13121
13122   mp->vrf_id = ntohl (vrf_id);
13123
13124   S (mp);
13125   W (ret);
13126   return ret;
13127 }
13128
13129 int
13130 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
13131 {
13132   unformat_input_t *input = vam->input;
13133   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
13134   u32 sw_if_index = ~0;
13135   int vrf_set = 0;
13136   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
13137   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
13138   u8 is_add = 1;
13139   int ret;
13140
13141   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
13142     {
13143       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13144         ;
13145       else if (unformat (input, "sw_if_index %d", &sw_if_index))
13146         ;
13147       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
13148         vrf_set = 1;
13149       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
13150         vrf_set = 1;
13151       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
13152         vrf_set = 1;
13153       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
13154         vrf_set = 1;
13155       else if (unformat (input, "del"))
13156         is_add = 0;
13157       else
13158         break;
13159     }
13160
13161   if (sw_if_index == ~0)
13162     {
13163       errmsg ("Interface required but not specified");
13164       return -99;
13165     }
13166
13167   if (vrf_set == 0)
13168     {
13169       errmsg ("VRF ID required but not specified");
13170       return -99;
13171     }
13172
13173   if (tcp_out_vrf_id == 0
13174       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
13175     {
13176       errmsg
13177         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
13178       return -99;
13179     }
13180
13181   /* Construct the API message */
13182   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
13183
13184   mp->sw_if_index = ntohl (sw_if_index);
13185   mp->is_add = is_add;
13186   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
13187   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
13188   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
13189   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
13190
13191   /* send it... */
13192   S (mp);
13193
13194   /* Wait for a reply... */
13195   W (ret);
13196   return ret;
13197 }
13198
13199 static int
13200 api_set_punt (vat_main_t * vam)
13201 {
13202   unformat_input_t *i = vam->input;
13203   vl_api_address_family_t af;
13204   vl_api_set_punt_t *mp;
13205   u32 protocol = ~0;
13206   u32 port = ~0;
13207   int is_add = 1;
13208   int ret;
13209
13210   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13211     {
13212       if (unformat (i, "%U", unformat_vl_api_address_family, &af))
13213         ;
13214       else if (unformat (i, "protocol %d", &protocol))
13215         ;
13216       else if (unformat (i, "port %d", &port))
13217         ;
13218       else if (unformat (i, "del"))
13219         is_add = 0;
13220       else
13221         {
13222           clib_warning ("parse error '%U'", format_unformat_error, i);
13223           return -99;
13224         }
13225     }
13226
13227   M (SET_PUNT, mp);
13228
13229   mp->is_add = (u8) is_add;
13230   mp->punt.type = PUNT_API_TYPE_L4;
13231   mp->punt.punt.l4.af = af;
13232   mp->punt.punt.l4.protocol = (u8) protocol;
13233   mp->punt.punt.l4.port = htons ((u16) port);
13234
13235   S (mp);
13236   W (ret);
13237   return ret;
13238 }
13239
13240 static int
13241 api_delete_subif (vat_main_t * vam)
13242 {
13243   unformat_input_t *i = vam->input;
13244   vl_api_delete_subif_t *mp;
13245   u32 sw_if_index = ~0;
13246   int ret;
13247
13248   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13249     {
13250       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13251         ;
13252       if (unformat (i, "sw_if_index %d", &sw_if_index))
13253         ;
13254       else
13255         break;
13256     }
13257
13258   if (sw_if_index == ~0)
13259     {
13260       errmsg ("missing sw_if_index");
13261       return -99;
13262     }
13263
13264   /* Construct the API message */
13265   M (DELETE_SUBIF, mp);
13266   mp->sw_if_index = ntohl (sw_if_index);
13267
13268   S (mp);
13269   W (ret);
13270   return ret;
13271 }
13272
13273 #define foreach_pbb_vtr_op      \
13274 _("disable",  L2_VTR_DISABLED)  \
13275 _("pop",  L2_VTR_POP_2)         \
13276 _("push",  L2_VTR_PUSH_2)
13277
13278 static int
13279 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
13280 {
13281   unformat_input_t *i = vam->input;
13282   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
13283   u32 sw_if_index = ~0, vtr_op = ~0;
13284   u16 outer_tag = ~0;
13285   u8 dmac[6], smac[6];
13286   u8 dmac_set = 0, smac_set = 0;
13287   u16 vlanid = 0;
13288   u32 sid = ~0;
13289   u32 tmp;
13290   int ret;
13291
13292   /* Shut up coverity */
13293   clib_memset (dmac, 0, sizeof (dmac));
13294   clib_memset (smac, 0, sizeof (smac));
13295
13296   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13297     {
13298       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13299         ;
13300       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13301         ;
13302       else if (unformat (i, "vtr_op %d", &vtr_op))
13303         ;
13304 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
13305       foreach_pbb_vtr_op
13306 #undef _
13307         else if (unformat (i, "translate_pbb_stag"))
13308         {
13309           if (unformat (i, "%d", &tmp))
13310             {
13311               vtr_op = L2_VTR_TRANSLATE_2_1;
13312               outer_tag = tmp;
13313             }
13314           else
13315             {
13316               errmsg
13317                 ("translate_pbb_stag operation requires outer tag definition");
13318               return -99;
13319             }
13320         }
13321       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
13322         dmac_set++;
13323       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
13324         smac_set++;
13325       else if (unformat (i, "sid %d", &sid))
13326         ;
13327       else if (unformat (i, "vlanid %d", &tmp))
13328         vlanid = tmp;
13329       else
13330         {
13331           clib_warning ("parse error '%U'", format_unformat_error, i);
13332           return -99;
13333         }
13334     }
13335
13336   if ((sw_if_index == ~0) || (vtr_op == ~0))
13337     {
13338       errmsg ("missing sw_if_index or vtr operation");
13339       return -99;
13340     }
13341   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
13342       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
13343     {
13344       errmsg
13345         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
13346       return -99;
13347     }
13348
13349   M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
13350   mp->sw_if_index = ntohl (sw_if_index);
13351   mp->vtr_op = ntohl (vtr_op);
13352   mp->outer_tag = ntohs (outer_tag);
13353   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
13354   clib_memcpy (mp->b_smac, smac, sizeof (smac));
13355   mp->b_vlanid = ntohs (vlanid);
13356   mp->i_sid = ntohl (sid);
13357
13358   S (mp);
13359   W (ret);
13360   return ret;
13361 }
13362
13363 static int
13364 api_flow_classify_set_interface (vat_main_t * vam)
13365 {
13366   unformat_input_t *i = vam->input;
13367   vl_api_flow_classify_set_interface_t *mp;
13368   u32 sw_if_index;
13369   int sw_if_index_set;
13370   u32 ip4_table_index = ~0;
13371   u32 ip6_table_index = ~0;
13372   u8 is_add = 1;
13373   int ret;
13374
13375   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13376     {
13377       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13378         sw_if_index_set = 1;
13379       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13380         sw_if_index_set = 1;
13381       else if (unformat (i, "del"))
13382         is_add = 0;
13383       else if (unformat (i, "ip4-table %d", &ip4_table_index))
13384         ;
13385       else if (unformat (i, "ip6-table %d", &ip6_table_index))
13386         ;
13387       else
13388         {
13389           clib_warning ("parse error '%U'", format_unformat_error, i);
13390           return -99;
13391         }
13392     }
13393
13394   if (sw_if_index_set == 0)
13395     {
13396       errmsg ("missing interface name or sw_if_index");
13397       return -99;
13398     }
13399
13400   M (FLOW_CLASSIFY_SET_INTERFACE, mp);
13401
13402   mp->sw_if_index = ntohl (sw_if_index);
13403   mp->ip4_table_index = ntohl (ip4_table_index);
13404   mp->ip6_table_index = ntohl (ip6_table_index);
13405   mp->is_add = is_add;
13406
13407   S (mp);
13408   W (ret);
13409   return ret;
13410 }
13411
13412 static int
13413 api_flow_classify_dump (vat_main_t * vam)
13414 {
13415   unformat_input_t *i = vam->input;
13416   vl_api_flow_classify_dump_t *mp;
13417   vl_api_control_ping_t *mp_ping;
13418   u8 type = FLOW_CLASSIFY_N_TABLES;
13419   int ret;
13420
13421   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
13422     ;
13423   else
13424     {
13425       errmsg ("classify table type must be specified");
13426       return -99;
13427     }
13428
13429   if (!vam->json_output)
13430     {
13431       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
13432     }
13433
13434   M (FLOW_CLASSIFY_DUMP, mp);
13435   mp->type = type;
13436   /* send it... */
13437   S (mp);
13438
13439   /* Use a control ping for synchronization */
13440   MPING (CONTROL_PING, mp_ping);
13441   S (mp_ping);
13442
13443   /* Wait for a reply... */
13444   W (ret);
13445   return ret;
13446 }
13447
13448 static int
13449 api_feature_enable_disable (vat_main_t * vam)
13450 {
13451   unformat_input_t *i = vam->input;
13452   vl_api_feature_enable_disable_t *mp;
13453   u8 *arc_name = 0;
13454   u8 *feature_name = 0;
13455   u32 sw_if_index = ~0;
13456   u8 enable = 1;
13457   int ret;
13458
13459   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13460     {
13461       if (unformat (i, "arc_name %s", &arc_name))
13462         ;
13463       else if (unformat (i, "feature_name %s", &feature_name))
13464         ;
13465       else
13466         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13467         ;
13468       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13469         ;
13470       else if (unformat (i, "disable"))
13471         enable = 0;
13472       else
13473         break;
13474     }
13475
13476   if (arc_name == 0)
13477     {
13478       errmsg ("missing arc name");
13479       return -99;
13480     }
13481   if (vec_len (arc_name) > 63)
13482     {
13483       errmsg ("arc name too long");
13484     }
13485
13486   if (feature_name == 0)
13487     {
13488       errmsg ("missing feature name");
13489       return -99;
13490     }
13491   if (vec_len (feature_name) > 63)
13492     {
13493       errmsg ("feature name too long");
13494     }
13495
13496   if (sw_if_index == ~0)
13497     {
13498       errmsg ("missing interface name or sw_if_index");
13499       return -99;
13500     }
13501
13502   /* Construct the API message */
13503   M (FEATURE_ENABLE_DISABLE, mp);
13504   mp->sw_if_index = ntohl (sw_if_index);
13505   mp->enable = enable;
13506   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
13507   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
13508   vec_free (arc_name);
13509   vec_free (feature_name);
13510
13511   S (mp);
13512   W (ret);
13513   return ret;
13514 }
13515
13516 static int
13517 api_feature_gso_enable_disable (vat_main_t * vam)
13518 {
13519   unformat_input_t *i = vam->input;
13520   vl_api_feature_gso_enable_disable_t *mp;
13521   u32 sw_if_index = ~0;
13522   u8 enable = 1;
13523   int ret;
13524
13525   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13526     {
13527       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13528         ;
13529       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13530         ;
13531       else if (unformat (i, "enable"))
13532         enable = 1;
13533       else if (unformat (i, "disable"))
13534         enable = 0;
13535       else
13536         break;
13537     }
13538
13539   if (sw_if_index == ~0)
13540     {
13541       errmsg ("missing interface name or sw_if_index");
13542       return -99;
13543     }
13544
13545   /* Construct the API message */
13546   M (FEATURE_GSO_ENABLE_DISABLE, mp);
13547   mp->sw_if_index = ntohl (sw_if_index);
13548   mp->enable_disable = enable;
13549
13550   S (mp);
13551   W (ret);
13552   return ret;
13553 }
13554
13555 static int
13556 api_sw_interface_tag_add_del (vat_main_t * vam)
13557 {
13558   unformat_input_t *i = vam->input;
13559   vl_api_sw_interface_tag_add_del_t *mp;
13560   u32 sw_if_index = ~0;
13561   u8 *tag = 0;
13562   u8 enable = 1;
13563   int ret;
13564
13565   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13566     {
13567       if (unformat (i, "tag %s", &tag))
13568         ;
13569       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13570         ;
13571       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13572         ;
13573       else if (unformat (i, "del"))
13574         enable = 0;
13575       else
13576         break;
13577     }
13578
13579   if (sw_if_index == ~0)
13580     {
13581       errmsg ("missing interface name or sw_if_index");
13582       return -99;
13583     }
13584
13585   if (enable && (tag == 0))
13586     {
13587       errmsg ("no tag specified");
13588       return -99;
13589     }
13590
13591   /* Construct the API message */
13592   M (SW_INTERFACE_TAG_ADD_DEL, mp);
13593   mp->sw_if_index = ntohl (sw_if_index);
13594   mp->is_add = enable;
13595   if (enable)
13596     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
13597   vec_free (tag);
13598
13599   S (mp);
13600   W (ret);
13601   return ret;
13602 }
13603
13604 static int
13605 api_sw_interface_add_del_mac_address (vat_main_t * vam)
13606 {
13607   unformat_input_t *i = vam->input;
13608   vl_api_mac_address_t mac = { 0 };
13609   vl_api_sw_interface_add_del_mac_address_t *mp;
13610   u32 sw_if_index = ~0;
13611   u8 is_add = 1;
13612   u8 mac_set = 0;
13613   int ret;
13614
13615   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13616     {
13617       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13618         ;
13619       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13620         ;
13621       else if (unformat (i, "%U", unformat_vl_api_mac_address, &mac))
13622         mac_set++;
13623       else if (unformat (i, "del"))
13624         is_add = 0;
13625       else
13626         break;
13627     }
13628
13629   if (sw_if_index == ~0)
13630     {
13631       errmsg ("missing interface name or sw_if_index");
13632       return -99;
13633     }
13634
13635   if (!mac_set)
13636     {
13637       errmsg ("missing MAC address");
13638       return -99;
13639     }
13640
13641   /* Construct the API message */
13642   M (SW_INTERFACE_ADD_DEL_MAC_ADDRESS, mp);
13643   mp->sw_if_index = ntohl (sw_if_index);
13644   mp->is_add = is_add;
13645   clib_memcpy (&mp->addr, &mac, sizeof (mac));
13646
13647   S (mp);
13648   W (ret);
13649   return ret;
13650 }
13651
13652 static void vl_api_l2_xconnect_details_t_handler
13653   (vl_api_l2_xconnect_details_t * mp)
13654 {
13655   vat_main_t *vam = &vat_main;
13656
13657   print (vam->ofp, "%15d%15d",
13658          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
13659 }
13660
13661 static void vl_api_l2_xconnect_details_t_handler_json
13662   (vl_api_l2_xconnect_details_t * mp)
13663 {
13664   vat_main_t *vam = &vat_main;
13665   vat_json_node_t *node = NULL;
13666
13667   if (VAT_JSON_ARRAY != vam->json_tree.type)
13668     {
13669       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13670       vat_json_init_array (&vam->json_tree);
13671     }
13672   node = vat_json_array_add (&vam->json_tree);
13673
13674   vat_json_init_object (node);
13675   vat_json_object_add_uint (node, "rx_sw_if_index",
13676                             ntohl (mp->rx_sw_if_index));
13677   vat_json_object_add_uint (node, "tx_sw_if_index",
13678                             ntohl (mp->tx_sw_if_index));
13679 }
13680
13681 static int
13682 api_l2_xconnect_dump (vat_main_t * vam)
13683 {
13684   vl_api_l2_xconnect_dump_t *mp;
13685   vl_api_control_ping_t *mp_ping;
13686   int ret;
13687
13688   if (!vam->json_output)
13689     {
13690       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
13691     }
13692
13693   M (L2_XCONNECT_DUMP, mp);
13694
13695   S (mp);
13696
13697   /* Use a control ping for synchronization */
13698   MPING (CONTROL_PING, mp_ping);
13699   S (mp_ping);
13700
13701   W (ret);
13702   return ret;
13703 }
13704
13705 static int
13706 api_hw_interface_set_mtu (vat_main_t * vam)
13707 {
13708   unformat_input_t *i = vam->input;
13709   vl_api_hw_interface_set_mtu_t *mp;
13710   u32 sw_if_index = ~0;
13711   u32 mtu = 0;
13712   int ret;
13713
13714   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13715     {
13716       if (unformat (i, "mtu %d", &mtu))
13717         ;
13718       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13719         ;
13720       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13721         ;
13722       else
13723         break;
13724     }
13725
13726   if (sw_if_index == ~0)
13727     {
13728       errmsg ("missing interface name or sw_if_index");
13729       return -99;
13730     }
13731
13732   if (mtu == 0)
13733     {
13734       errmsg ("no mtu specified");
13735       return -99;
13736     }
13737
13738   /* Construct the API message */
13739   M (HW_INTERFACE_SET_MTU, mp);
13740   mp->sw_if_index = ntohl (sw_if_index);
13741   mp->mtu = ntohs ((u16) mtu);
13742
13743   S (mp);
13744   W (ret);
13745   return ret;
13746 }
13747
13748 static int
13749 api_p2p_ethernet_add (vat_main_t * vam)
13750 {
13751   unformat_input_t *i = vam->input;
13752   vl_api_p2p_ethernet_add_t *mp;
13753   u32 parent_if_index = ~0;
13754   u32 sub_id = ~0;
13755   u8 remote_mac[6];
13756   u8 mac_set = 0;
13757   int ret;
13758
13759   clib_memset (remote_mac, 0, sizeof (remote_mac));
13760   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13761     {
13762       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
13763         ;
13764       else if (unformat (i, "sw_if_index %d", &parent_if_index))
13765         ;
13766       else
13767         if (unformat
13768             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
13769         mac_set++;
13770       else if (unformat (i, "sub_id %d", &sub_id))
13771         ;
13772       else
13773         {
13774           clib_warning ("parse error '%U'", format_unformat_error, i);
13775           return -99;
13776         }
13777     }
13778
13779   if (parent_if_index == ~0)
13780     {
13781       errmsg ("missing interface name or sw_if_index");
13782       return -99;
13783     }
13784   if (mac_set == 0)
13785     {
13786       errmsg ("missing remote mac address");
13787       return -99;
13788     }
13789   if (sub_id == ~0)
13790     {
13791       errmsg ("missing sub-interface id");
13792       return -99;
13793     }
13794
13795   M (P2P_ETHERNET_ADD, mp);
13796   mp->parent_if_index = ntohl (parent_if_index);
13797   mp->subif_id = ntohl (sub_id);
13798   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
13799
13800   S (mp);
13801   W (ret);
13802   return ret;
13803 }
13804
13805 static int
13806 api_p2p_ethernet_del (vat_main_t * vam)
13807 {
13808   unformat_input_t *i = vam->input;
13809   vl_api_p2p_ethernet_del_t *mp;
13810   u32 parent_if_index = ~0;
13811   u8 remote_mac[6];
13812   u8 mac_set = 0;
13813   int ret;
13814
13815   clib_memset (remote_mac, 0, sizeof (remote_mac));
13816   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13817     {
13818       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
13819         ;
13820       else if (unformat (i, "sw_if_index %d", &parent_if_index))
13821         ;
13822       else
13823         if (unformat
13824             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
13825         mac_set++;
13826       else
13827         {
13828           clib_warning ("parse error '%U'", format_unformat_error, i);
13829           return -99;
13830         }
13831     }
13832
13833   if (parent_if_index == ~0)
13834     {
13835       errmsg ("missing interface name or sw_if_index");
13836       return -99;
13837     }
13838   if (mac_set == 0)
13839     {
13840       errmsg ("missing remote mac address");
13841       return -99;
13842     }
13843
13844   M (P2P_ETHERNET_DEL, mp);
13845   mp->parent_if_index = ntohl (parent_if_index);
13846   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
13847
13848   S (mp);
13849   W (ret);
13850   return ret;
13851 }
13852
13853 static int
13854 api_tcp_configure_src_addresses (vat_main_t * vam)
13855 {
13856   vl_api_tcp_configure_src_addresses_t *mp;
13857   unformat_input_t *i = vam->input;
13858   vl_api_address_t first, last;
13859   u8 range_set = 0;
13860   u32 vrf_id = 0;
13861   int ret;
13862
13863   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13864     {
13865       if (unformat (i, "%U - %U",
13866                     unformat_vl_api_address, &first,
13867                     unformat_vl_api_address, &last))
13868         {
13869           if (range_set)
13870             {
13871               errmsg ("one range per message (range already set)");
13872               return -99;
13873             }
13874           range_set = 1;
13875         }
13876       else if (unformat (i, "vrf %d", &vrf_id))
13877         ;
13878       else
13879         break;
13880     }
13881
13882   if (range_set == 0)
13883     {
13884       errmsg ("address range not set");
13885       return -99;
13886     }
13887
13888   M (TCP_CONFIGURE_SRC_ADDRESSES, mp);
13889
13890   mp->vrf_id = ntohl (vrf_id);
13891   clib_memcpy (&mp->first_address, &first, sizeof (first));
13892   clib_memcpy (&mp->last_address, &last, sizeof (last));
13893
13894   S (mp);
13895   W (ret);
13896   return ret;
13897 }
13898
13899 static void vl_api_app_namespace_add_del_reply_t_handler
13900   (vl_api_app_namespace_add_del_reply_t * mp)
13901 {
13902   vat_main_t *vam = &vat_main;
13903   i32 retval = ntohl (mp->retval);
13904   if (vam->async_mode)
13905     {
13906       vam->async_errors += (retval < 0);
13907     }
13908   else
13909     {
13910       vam->retval = retval;
13911       if (retval == 0)
13912         errmsg ("app ns index %d\n", ntohl (mp->appns_index));
13913       vam->result_ready = 1;
13914     }
13915 }
13916
13917 static void vl_api_app_namespace_add_del_reply_t_handler_json
13918   (vl_api_app_namespace_add_del_reply_t * mp)
13919 {
13920   vat_main_t *vam = &vat_main;
13921   vat_json_node_t node;
13922
13923   vat_json_init_object (&node);
13924   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
13925   vat_json_object_add_uint (&node, "appns_index", ntohl (mp->appns_index));
13926
13927   vat_json_print (vam->ofp, &node);
13928   vat_json_free (&node);
13929
13930   vam->retval = ntohl (mp->retval);
13931   vam->result_ready = 1;
13932 }
13933
13934 static int
13935 api_app_namespace_add_del (vat_main_t * vam)
13936 {
13937   vl_api_app_namespace_add_del_t *mp;
13938   unformat_input_t *i = vam->input;
13939   u8 *ns_id = 0, secret_set = 0, sw_if_index_set = 0;
13940   u32 sw_if_index, ip4_fib_id, ip6_fib_id;
13941   u64 secret;
13942   int ret;
13943
13944   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13945     {
13946       if (unformat (i, "id %_%v%_", &ns_id))
13947         ;
13948       else if (unformat (i, "secret %lu", &secret))
13949         secret_set = 1;
13950       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13951         sw_if_index_set = 1;
13952       else if (unformat (i, "ip4_fib_id %d", &ip4_fib_id))
13953         ;
13954       else if (unformat (i, "ip6_fib_id %d", &ip6_fib_id))
13955         ;
13956       else
13957         break;
13958     }
13959   if (!ns_id || !secret_set || !sw_if_index_set)
13960     {
13961       errmsg ("namespace id, secret and sw_if_index must be set");
13962       return -99;
13963     }
13964   if (vec_len (ns_id) > 64)
13965     {
13966       errmsg ("namespace id too long");
13967       return -99;
13968     }
13969   M (APP_NAMESPACE_ADD_DEL, mp);
13970
13971   vl_api_vec_to_api_string (ns_id, &mp->namespace_id);
13972   mp->secret = clib_host_to_net_u64 (secret);
13973   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
13974   mp->ip4_fib_id = clib_host_to_net_u32 (ip4_fib_id);
13975   mp->ip6_fib_id = clib_host_to_net_u32 (ip6_fib_id);
13976   vec_free (ns_id);
13977   S (mp);
13978   W (ret);
13979   return ret;
13980 }
13981
13982 static int
13983 api_sock_init_shm (vat_main_t * vam)
13984 {
13985 #if VPP_API_TEST_BUILTIN == 0
13986   unformat_input_t *i = vam->input;
13987   vl_api_shm_elem_config_t *config = 0;
13988   u64 size = 64 << 20;
13989   int rv;
13990
13991   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13992     {
13993       if (unformat (i, "size %U", unformat_memory_size, &size))
13994         ;
13995       else
13996         break;
13997     }
13998
13999   /*
14000    * Canned custom ring allocator config.
14001    * Should probably parse all of this
14002    */
14003   vec_validate (config, 6);
14004   config[0].type = VL_API_VLIB_RING;
14005   config[0].size = 256;
14006   config[0].count = 32;
14007
14008   config[1].type = VL_API_VLIB_RING;
14009   config[1].size = 1024;
14010   config[1].count = 16;
14011
14012   config[2].type = VL_API_VLIB_RING;
14013   config[2].size = 4096;
14014   config[2].count = 2;
14015
14016   config[3].type = VL_API_CLIENT_RING;
14017   config[3].size = 256;
14018   config[3].count = 32;
14019
14020   config[4].type = VL_API_CLIENT_RING;
14021   config[4].size = 1024;
14022   config[4].count = 16;
14023
14024   config[5].type = VL_API_CLIENT_RING;
14025   config[5].size = 4096;
14026   config[5].count = 2;
14027
14028   config[6].type = VL_API_QUEUE;
14029   config[6].count = 128;
14030   config[6].size = sizeof (uword);
14031
14032   rv = vl_socket_client_init_shm (config, 1 /* want_pthread */ );
14033   if (!rv)
14034     vam->client_index_invalid = 1;
14035   return rv;
14036 #else
14037   return -99;
14038 #endif
14039 }
14040
14041 static void
14042 vl_api_session_rules_details_t_handler (vl_api_session_rules_details_t * mp)
14043 {
14044   vat_main_t *vam = &vat_main;
14045   fib_prefix_t lcl, rmt;
14046
14047   ip_prefix_decode (&mp->lcl, &lcl);
14048   ip_prefix_decode (&mp->rmt, &rmt);
14049
14050   if (lcl.fp_proto == FIB_PROTOCOL_IP4)
14051     {
14052       print (vam->ofp,
14053              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
14054              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
14055              mp->scope, format_ip4_address, &lcl.fp_addr.ip4, lcl.fp_len,
14056              clib_net_to_host_u16 (mp->lcl_port), format_ip4_address,
14057              &rmt.fp_addr.ip4, rmt.fp_len,
14058              clib_net_to_host_u16 (mp->rmt_port),
14059              clib_net_to_host_u32 (mp->action_index), mp->tag);
14060     }
14061   else
14062     {
14063       print (vam->ofp,
14064              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
14065              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
14066              mp->scope, format_ip6_address, &lcl.fp_addr.ip6, lcl.fp_len,
14067              clib_net_to_host_u16 (mp->lcl_port), format_ip6_address,
14068              &rmt.fp_addr.ip6, rmt.fp_len,
14069              clib_net_to_host_u16 (mp->rmt_port),
14070              clib_net_to_host_u32 (mp->action_index), mp->tag);
14071     }
14072 }
14073
14074 static void
14075 vl_api_session_rules_details_t_handler_json (vl_api_session_rules_details_t *
14076                                              mp)
14077 {
14078   vat_main_t *vam = &vat_main;
14079   vat_json_node_t *node = NULL;
14080   struct in6_addr ip6;
14081   struct in_addr ip4;
14082
14083   fib_prefix_t lcl, rmt;
14084
14085   ip_prefix_decode (&mp->lcl, &lcl);
14086   ip_prefix_decode (&mp->rmt, &rmt);
14087
14088   if (VAT_JSON_ARRAY != vam->json_tree.type)
14089     {
14090       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14091       vat_json_init_array (&vam->json_tree);
14092     }
14093   node = vat_json_array_add (&vam->json_tree);
14094   vat_json_init_object (node);
14095
14096   vat_json_object_add_uint (node, "appns_index",
14097                             clib_net_to_host_u32 (mp->appns_index));
14098   vat_json_object_add_uint (node, "transport_proto", mp->transport_proto);
14099   vat_json_object_add_uint (node, "scope", mp->scope);
14100   vat_json_object_add_uint (node, "action_index",
14101                             clib_net_to_host_u32 (mp->action_index));
14102   vat_json_object_add_uint (node, "lcl_port",
14103                             clib_net_to_host_u16 (mp->lcl_port));
14104   vat_json_object_add_uint (node, "rmt_port",
14105                             clib_net_to_host_u16 (mp->rmt_port));
14106   vat_json_object_add_uint (node, "lcl_plen", lcl.fp_len);
14107   vat_json_object_add_uint (node, "rmt_plen", rmt.fp_len);
14108   vat_json_object_add_string_copy (node, "tag", mp->tag);
14109   if (lcl.fp_proto == FIB_PROTOCOL_IP4)
14110     {
14111       clib_memcpy (&ip4, &lcl.fp_addr.ip4, sizeof (ip4));
14112       vat_json_object_add_ip4 (node, "lcl_ip", ip4);
14113       clib_memcpy (&ip4, &rmt.fp_addr.ip4, sizeof (ip4));
14114       vat_json_object_add_ip4 (node, "rmt_ip", ip4);
14115     }
14116   else
14117     {
14118       clib_memcpy (&ip6, &lcl.fp_addr.ip6, sizeof (ip6));
14119       vat_json_object_add_ip6 (node, "lcl_ip", ip6);
14120       clib_memcpy (&ip6, &rmt.fp_addr.ip6, sizeof (ip6));
14121       vat_json_object_add_ip6 (node, "rmt_ip", ip6);
14122     }
14123 }
14124
14125 static int
14126 api_session_rule_add_del (vat_main_t * vam)
14127 {
14128   vl_api_session_rule_add_del_t *mp;
14129   unformat_input_t *i = vam->input;
14130   u32 proto = ~0, lcl_port, rmt_port, action = 0, lcl_plen, rmt_plen;
14131   u32 appns_index = 0, scope = 0;
14132   ip4_address_t lcl_ip4, rmt_ip4;
14133   ip6_address_t lcl_ip6, rmt_ip6;
14134   u8 is_ip4 = 1, conn_set = 0;
14135   u8 is_add = 1, *tag = 0;
14136   int ret;
14137   fib_prefix_t lcl, rmt;
14138
14139   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14140     {
14141       if (unformat (i, "del"))
14142         is_add = 0;
14143       else if (unformat (i, "add"))
14144         ;
14145       else if (unformat (i, "proto tcp"))
14146         proto = 0;
14147       else if (unformat (i, "proto udp"))
14148         proto = 1;
14149       else if (unformat (i, "appns %d", &appns_index))
14150         ;
14151       else if (unformat (i, "scope %d", &scope))
14152         ;
14153       else if (unformat (i, "tag %_%v%_", &tag))
14154         ;
14155       else
14156         if (unformat
14157             (i, "%U/%d %d %U/%d %d", unformat_ip4_address, &lcl_ip4,
14158              &lcl_plen, &lcl_port, unformat_ip4_address, &rmt_ip4, &rmt_plen,
14159              &rmt_port))
14160         {
14161           is_ip4 = 1;
14162           conn_set = 1;
14163         }
14164       else
14165         if (unformat
14166             (i, "%U/%d %d %U/%d %d", unformat_ip6_address, &lcl_ip6,
14167              &lcl_plen, &lcl_port, unformat_ip6_address, &rmt_ip6, &rmt_plen,
14168              &rmt_port))
14169         {
14170           is_ip4 = 0;
14171           conn_set = 1;
14172         }
14173       else if (unformat (i, "action %d", &action))
14174         ;
14175       else
14176         break;
14177     }
14178   if (proto == ~0 || !conn_set || action == ~0)
14179     {
14180       errmsg ("transport proto, connection and action must be set");
14181       return -99;
14182     }
14183
14184   if (scope > 3)
14185     {
14186       errmsg ("scope should be 0-3");
14187       return -99;
14188     }
14189
14190   M (SESSION_RULE_ADD_DEL, mp);
14191
14192   clib_memset (&lcl, 0, sizeof (lcl));
14193   clib_memset (&rmt, 0, sizeof (rmt));
14194   if (is_ip4)
14195     {
14196       ip_set (&lcl.fp_addr, &lcl_ip4, 1);
14197       ip_set (&rmt.fp_addr, &rmt_ip4, 1);
14198       lcl.fp_len = lcl_plen;
14199       rmt.fp_len = rmt_plen;
14200     }
14201   else
14202     {
14203       ip_set (&lcl.fp_addr, &lcl_ip6, 0);
14204       ip_set (&rmt.fp_addr, &rmt_ip6, 0);
14205       lcl.fp_len = lcl_plen;
14206       rmt.fp_len = rmt_plen;
14207     }
14208
14209
14210   ip_prefix_encode (&lcl, &mp->lcl);
14211   ip_prefix_encode (&rmt, &mp->rmt);
14212   mp->lcl_port = clib_host_to_net_u16 ((u16) lcl_port);
14213   mp->rmt_port = clib_host_to_net_u16 ((u16) rmt_port);
14214   mp->transport_proto =
14215     proto ? TRANSPORT_PROTO_API_UDP : TRANSPORT_PROTO_API_TCP;
14216   mp->action_index = clib_host_to_net_u32 (action);
14217   mp->appns_index = clib_host_to_net_u32 (appns_index);
14218   mp->scope = scope;
14219   mp->is_add = is_add;
14220   if (tag)
14221     {
14222       clib_memcpy (mp->tag, tag, vec_len (tag));
14223       vec_free (tag);
14224     }
14225
14226   S (mp);
14227   W (ret);
14228   return ret;
14229 }
14230
14231 static int
14232 api_session_rules_dump (vat_main_t * vam)
14233 {
14234   vl_api_session_rules_dump_t *mp;
14235   vl_api_control_ping_t *mp_ping;
14236   int ret;
14237
14238   if (!vam->json_output)
14239     {
14240       print (vam->ofp, "%=20s", "Session Rules");
14241     }
14242
14243   M (SESSION_RULES_DUMP, mp);
14244   /* send it... */
14245   S (mp);
14246
14247   /* Use a control ping for synchronization */
14248   MPING (CONTROL_PING, mp_ping);
14249   S (mp_ping);
14250
14251   /* Wait for a reply... */
14252   W (ret);
14253   return ret;
14254 }
14255
14256 static int
14257 api_ip_container_proxy_add_del (vat_main_t * vam)
14258 {
14259   vl_api_ip_container_proxy_add_del_t *mp;
14260   unformat_input_t *i = vam->input;
14261   u32 sw_if_index = ~0;
14262   vl_api_prefix_t pfx = { };
14263   u8 is_add = 1;
14264   int ret;
14265
14266   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14267     {
14268       if (unformat (i, "del"))
14269         is_add = 0;
14270       else if (unformat (i, "add"))
14271         ;
14272       if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
14273         ;
14274       else if (unformat (i, "sw_if_index %u", &sw_if_index))
14275         ;
14276       else
14277         break;
14278     }
14279   if (sw_if_index == ~0 || pfx.len == 0)
14280     {
14281       errmsg ("address and sw_if_index must be set");
14282       return -99;
14283     }
14284
14285   M (IP_CONTAINER_PROXY_ADD_DEL, mp);
14286
14287   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
14288   mp->is_add = is_add;
14289   clib_memcpy (&mp->pfx, &pfx, sizeof (pfx));
14290
14291   S (mp);
14292   W (ret);
14293   return ret;
14294 }
14295
14296 static int
14297 api_qos_record_enable_disable (vat_main_t * vam)
14298 {
14299   unformat_input_t *i = vam->input;
14300   vl_api_qos_record_enable_disable_t *mp;
14301   u32 sw_if_index, qs = 0xff;
14302   u8 sw_if_index_set = 0;
14303   u8 enable = 1;
14304   int ret;
14305
14306   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14307     {
14308       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14309         sw_if_index_set = 1;
14310       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14311         sw_if_index_set = 1;
14312       else if (unformat (i, "%U", unformat_qos_source, &qs))
14313         ;
14314       else if (unformat (i, "disable"))
14315         enable = 0;
14316       else
14317         {
14318           clib_warning ("parse error '%U'", format_unformat_error, i);
14319           return -99;
14320         }
14321     }
14322
14323   if (sw_if_index_set == 0)
14324     {
14325       errmsg ("missing interface name or sw_if_index");
14326       return -99;
14327     }
14328   if (qs == 0xff)
14329     {
14330       errmsg ("input location must be specified");
14331       return -99;
14332     }
14333
14334   M (QOS_RECORD_ENABLE_DISABLE, mp);
14335
14336   mp->record.sw_if_index = ntohl (sw_if_index);
14337   mp->record.input_source = qs;
14338   mp->enable = enable;
14339
14340   S (mp);
14341   W (ret);
14342   return ret;
14343 }
14344
14345
14346 static int
14347 q_or_quit (vat_main_t * vam)
14348 {
14349 #if VPP_API_TEST_BUILTIN == 0
14350   longjmp (vam->jump_buf, 1);
14351 #endif
14352   return 0;                     /* not so much */
14353 }
14354
14355 static int
14356 q (vat_main_t * vam)
14357 {
14358   return q_or_quit (vam);
14359 }
14360
14361 static int
14362 quit (vat_main_t * vam)
14363 {
14364   return q_or_quit (vam);
14365 }
14366
14367 static int
14368 comment (vat_main_t * vam)
14369 {
14370   return 0;
14371 }
14372
14373 static int
14374 elog_save (vat_main_t * vam)
14375 {
14376 #if VPP_API_TEST_BUILTIN == 0
14377   elog_main_t *em = &vam->elog_main;
14378   unformat_input_t *i = vam->input;
14379   char *file, *chroot_file;
14380   clib_error_t *error;
14381
14382   if (!unformat (i, "%s", &file))
14383     {
14384       errmsg ("expected file name, got `%U'", format_unformat_error, i);
14385       return 0;
14386     }
14387
14388   /* It's fairly hard to get "../oopsie" through unformat; just in case */
14389   if (strstr (file, "..") || index (file, '/'))
14390     {
14391       errmsg ("illegal characters in filename '%s'", file);
14392       return 0;
14393     }
14394
14395   chroot_file = (char *) format (0, "/tmp/%s%c", file, 0);
14396
14397   vec_free (file);
14398
14399   errmsg ("Saving %wd of %wd events to %s",
14400           elog_n_events_in_buffer (em),
14401           elog_buffer_capacity (em), chroot_file);
14402
14403   error = elog_write_file (em, chroot_file, 1 /* flush ring */ );
14404   vec_free (chroot_file);
14405
14406   if (error)
14407     clib_error_report (error);
14408 #else
14409   errmsg ("Use the vpp event loger...");
14410 #endif
14411
14412   return 0;
14413 }
14414
14415 static int
14416 elog_setup (vat_main_t * vam)
14417 {
14418 #if VPP_API_TEST_BUILTIN == 0
14419   elog_main_t *em = &vam->elog_main;
14420   unformat_input_t *i = vam->input;
14421   u32 nevents = 128 << 10;
14422
14423   (void) unformat (i, "nevents %d", &nevents);
14424
14425   elog_init (em, nevents);
14426   vl_api_set_elog_main (em);
14427   vl_api_set_elog_trace_api_messages (1);
14428   errmsg ("Event logger initialized with %u events", nevents);
14429 #else
14430   errmsg ("Use the vpp event loger...");
14431 #endif
14432   return 0;
14433 }
14434
14435 static int
14436 elog_enable (vat_main_t * vam)
14437 {
14438 #if VPP_API_TEST_BUILTIN == 0
14439   elog_main_t *em = &vam->elog_main;
14440
14441   elog_enable_disable (em, 1 /* enable */ );
14442   vl_api_set_elog_trace_api_messages (1);
14443   errmsg ("Event logger enabled...");
14444 #else
14445   errmsg ("Use the vpp event loger...");
14446 #endif
14447   return 0;
14448 }
14449
14450 static int
14451 elog_disable (vat_main_t * vam)
14452 {
14453 #if VPP_API_TEST_BUILTIN == 0
14454   elog_main_t *em = &vam->elog_main;
14455
14456   elog_enable_disable (em, 0 /* enable */ );
14457   vl_api_set_elog_trace_api_messages (1);
14458   errmsg ("Event logger disabled...");
14459 #else
14460   errmsg ("Use the vpp event loger...");
14461 #endif
14462   return 0;
14463 }
14464
14465 static int
14466 statseg (vat_main_t * vam)
14467 {
14468   ssvm_private_t *ssvmp = &vam->stat_segment;
14469   ssvm_shared_header_t *shared_header = ssvmp->sh;
14470   vlib_counter_t **counters;
14471   u64 thread0_index1_packets;
14472   u64 thread0_index1_bytes;
14473   f64 vector_rate, input_rate;
14474   uword *p;
14475
14476   uword *counter_vector_by_name;
14477   if (vam->stat_segment_lockp == 0)
14478     {
14479       errmsg ("Stat segment not mapped...");
14480       return -99;
14481     }
14482
14483   /* look up "/if/rx for sw_if_index 1 as a test */
14484
14485   clib_spinlock_lock (vam->stat_segment_lockp);
14486
14487   counter_vector_by_name = (uword *) shared_header->opaque[1];
14488
14489   p = hash_get_mem (counter_vector_by_name, "/if/rx");
14490   if (p == 0)
14491     {
14492       clib_spinlock_unlock (vam->stat_segment_lockp);
14493       errmsg ("/if/tx not found?");
14494       return -99;
14495     }
14496
14497   /* Fish per-thread vector of combined counters from shared memory */
14498   counters = (vlib_counter_t **) p[0];
14499
14500   if (vec_len (counters[0]) < 2)
14501     {
14502       clib_spinlock_unlock (vam->stat_segment_lockp);
14503       errmsg ("/if/tx vector length %d", vec_len (counters[0]));
14504       return -99;
14505     }
14506
14507   /* Read thread 0 sw_if_index 1 counter */
14508   thread0_index1_packets = counters[0][1].packets;
14509   thread0_index1_bytes = counters[0][1].bytes;
14510
14511   p = hash_get_mem (counter_vector_by_name, "vector_rate");
14512   if (p == 0)
14513     {
14514       clib_spinlock_unlock (vam->stat_segment_lockp);
14515       errmsg ("vector_rate not found?");
14516       return -99;
14517     }
14518
14519   vector_rate = *(f64 *) (p[0]);
14520   p = hash_get_mem (counter_vector_by_name, "input_rate");
14521   if (p == 0)
14522     {
14523       clib_spinlock_unlock (vam->stat_segment_lockp);
14524       errmsg ("input_rate not found?");
14525       return -99;
14526     }
14527   input_rate = *(f64 *) (p[0]);
14528
14529   clib_spinlock_unlock (vam->stat_segment_lockp);
14530
14531   print (vam->ofp, "vector_rate %.2f input_rate %.2f",
14532          vector_rate, input_rate);
14533   print (vam->ofp, "thread 0 sw_if_index 1 rx pkts %lld, bytes %lld",
14534          thread0_index1_packets, thread0_index1_bytes);
14535
14536   return 0;
14537 }
14538
14539 static int
14540 cmd_cmp (void *a1, void *a2)
14541 {
14542   u8 **c1 = a1;
14543   u8 **c2 = a2;
14544
14545   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
14546 }
14547
14548 static int
14549 help (vat_main_t * vam)
14550 {
14551   u8 **cmds = 0;
14552   u8 *name = 0;
14553   hash_pair_t *p;
14554   unformat_input_t *i = vam->input;
14555   int j;
14556
14557   if (unformat (i, "%s", &name))
14558     {
14559       uword *hs;
14560
14561       vec_add1 (name, 0);
14562
14563       hs = hash_get_mem (vam->help_by_name, name);
14564       if (hs)
14565         print (vam->ofp, "usage: %s %s", name, hs[0]);
14566       else
14567         print (vam->ofp, "No such msg / command '%s'", name);
14568       vec_free (name);
14569       return 0;
14570     }
14571
14572   print (vam->ofp, "Help is available for the following:");
14573
14574     /* *INDENT-OFF* */
14575     hash_foreach_pair (p, vam->function_by_name,
14576     ({
14577       vec_add1 (cmds, (u8 *)(p->key));
14578     }));
14579     /* *INDENT-ON* */
14580
14581   vec_sort_with_function (cmds, cmd_cmp);
14582
14583   for (j = 0; j < vec_len (cmds); j++)
14584     print (vam->ofp, "%s", cmds[j]);
14585
14586   vec_free (cmds);
14587   return 0;
14588 }
14589
14590 static int
14591 set (vat_main_t * vam)
14592 {
14593   u8 *name = 0, *value = 0;
14594   unformat_input_t *i = vam->input;
14595
14596   if (unformat (i, "%s", &name))
14597     {
14598       /* The input buffer is a vector, not a string. */
14599       value = vec_dup (i->buffer);
14600       vec_delete (value, i->index, 0);
14601       /* Almost certainly has a trailing newline */
14602       if (value[vec_len (value) - 1] == '\n')
14603         value[vec_len (value) - 1] = 0;
14604       /* Make sure it's a proper string, one way or the other */
14605       vec_add1 (value, 0);
14606       (void) clib_macro_set_value (&vam->macro_main,
14607                                    (char *) name, (char *) value);
14608     }
14609   else
14610     errmsg ("usage: set <name> <value>");
14611
14612   vec_free (name);
14613   vec_free (value);
14614   return 0;
14615 }
14616
14617 static int
14618 unset (vat_main_t * vam)
14619 {
14620   u8 *name = 0;
14621
14622   if (unformat (vam->input, "%s", &name))
14623     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
14624       errmsg ("unset: %s wasn't set", name);
14625   vec_free (name);
14626   return 0;
14627 }
14628
14629 typedef struct
14630 {
14631   u8 *name;
14632   u8 *value;
14633 } macro_sort_t;
14634
14635
14636 static int
14637 macro_sort_cmp (void *a1, void *a2)
14638 {
14639   macro_sort_t *s1 = a1;
14640   macro_sort_t *s2 = a2;
14641
14642   return strcmp ((char *) (s1->name), (char *) (s2->name));
14643 }
14644
14645 static int
14646 dump_macro_table (vat_main_t * vam)
14647 {
14648   macro_sort_t *sort_me = 0, *sm;
14649   int i;
14650   hash_pair_t *p;
14651
14652     /* *INDENT-OFF* */
14653     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
14654     ({
14655       vec_add2 (sort_me, sm, 1);
14656       sm->name = (u8 *)(p->key);
14657       sm->value = (u8 *) (p->value[0]);
14658     }));
14659     /* *INDENT-ON* */
14660
14661   vec_sort_with_function (sort_me, macro_sort_cmp);
14662
14663   if (vec_len (sort_me))
14664     print (vam->ofp, "%-15s%s", "Name", "Value");
14665   else
14666     print (vam->ofp, "The macro table is empty...");
14667
14668   for (i = 0; i < vec_len (sort_me); i++)
14669     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
14670   return 0;
14671 }
14672
14673 static int
14674 dump_node_table (vat_main_t * vam)
14675 {
14676   int i, j;
14677   vlib_node_t *node, *next_node;
14678
14679   if (vec_len (vam->graph_nodes) == 0)
14680     {
14681       print (vam->ofp, "Node table empty, issue get_node_graph...");
14682       return 0;
14683     }
14684
14685   for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
14686     {
14687       node = vam->graph_nodes[0][i];
14688       print (vam->ofp, "[%d] %s", i, node->name);
14689       for (j = 0; j < vec_len (node->next_nodes); j++)
14690         {
14691           if (node->next_nodes[j] != ~0)
14692             {
14693               next_node = vam->graph_nodes[0][node->next_nodes[j]];
14694               print (vam->ofp, "  [%d] %s", j, next_node->name);
14695             }
14696         }
14697     }
14698   return 0;
14699 }
14700
14701 static int
14702 value_sort_cmp (void *a1, void *a2)
14703 {
14704   name_sort_t *n1 = a1;
14705   name_sort_t *n2 = a2;
14706
14707   if (n1->value < n2->value)
14708     return -1;
14709   if (n1->value > n2->value)
14710     return 1;
14711   return 0;
14712 }
14713
14714
14715 static int
14716 dump_msg_api_table (vat_main_t * vam)
14717 {
14718   api_main_t *am = vlibapi_get_main ();
14719   name_sort_t *nses = 0, *ns;
14720   hash_pair_t *hp;
14721   int i;
14722
14723   /* *INDENT-OFF* */
14724   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
14725   ({
14726     vec_add2 (nses, ns, 1);
14727     ns->name = (u8 *)(hp->key);
14728     ns->value = (u32) hp->value[0];
14729   }));
14730   /* *INDENT-ON* */
14731
14732   vec_sort_with_function (nses, value_sort_cmp);
14733
14734   for (i = 0; i < vec_len (nses); i++)
14735     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
14736   vec_free (nses);
14737   return 0;
14738 }
14739
14740 static int
14741 get_msg_id (vat_main_t * vam)
14742 {
14743   u8 *name_and_crc;
14744   u32 message_index;
14745
14746   if (unformat (vam->input, "%s", &name_and_crc))
14747     {
14748       message_index = vl_msg_api_get_msg_index (name_and_crc);
14749       if (message_index == ~0)
14750         {
14751           print (vam->ofp, " '%s' not found", name_and_crc);
14752           return 0;
14753         }
14754       print (vam->ofp, " '%s' has message index %d",
14755              name_and_crc, message_index);
14756       return 0;
14757     }
14758   errmsg ("name_and_crc required...");
14759   return 0;
14760 }
14761
14762 static int
14763 search_node_table (vat_main_t * vam)
14764 {
14765   unformat_input_t *line_input = vam->input;
14766   u8 *node_to_find;
14767   int j;
14768   vlib_node_t *node, *next_node;
14769   uword *p;
14770
14771   if (vam->graph_node_index_by_name == 0)
14772     {
14773       print (vam->ofp, "Node table empty, issue get_node_graph...");
14774       return 0;
14775     }
14776
14777   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14778     {
14779       if (unformat (line_input, "%s", &node_to_find))
14780         {
14781           vec_add1 (node_to_find, 0);
14782           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
14783           if (p == 0)
14784             {
14785               print (vam->ofp, "%s not found...", node_to_find);
14786               goto out;
14787             }
14788           node = vam->graph_nodes[0][p[0]];
14789           print (vam->ofp, "[%d] %s", p[0], node->name);
14790           for (j = 0; j < vec_len (node->next_nodes); j++)
14791             {
14792               if (node->next_nodes[j] != ~0)
14793                 {
14794                   next_node = vam->graph_nodes[0][node->next_nodes[j]];
14795                   print (vam->ofp, "  [%d] %s", j, next_node->name);
14796                 }
14797             }
14798         }
14799
14800       else
14801         {
14802           clib_warning ("parse error '%U'", format_unformat_error,
14803                         line_input);
14804           return -99;
14805         }
14806
14807     out:
14808       vec_free (node_to_find);
14809
14810     }
14811
14812   return 0;
14813 }
14814
14815
14816 static int
14817 script (vat_main_t * vam)
14818 {
14819 #if (VPP_API_TEST_BUILTIN==0)
14820   u8 *s = 0;
14821   char *save_current_file;
14822   unformat_input_t save_input;
14823   jmp_buf save_jump_buf;
14824   u32 save_line_number;
14825
14826   FILE *new_fp, *save_ifp;
14827
14828   if (unformat (vam->input, "%s", &s))
14829     {
14830       new_fp = fopen ((char *) s, "r");
14831       if (new_fp == 0)
14832         {
14833           errmsg ("Couldn't open script file %s", s);
14834           vec_free (s);
14835           return -99;
14836         }
14837     }
14838   else
14839     {
14840       errmsg ("Missing script name");
14841       return -99;
14842     }
14843
14844   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
14845   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
14846   save_ifp = vam->ifp;
14847   save_line_number = vam->input_line_number;
14848   save_current_file = (char *) vam->current_file;
14849
14850   vam->input_line_number = 0;
14851   vam->ifp = new_fp;
14852   vam->current_file = s;
14853   do_one_file (vam);
14854
14855   clib_memcpy (&vam->input, &save_input, sizeof (save_input));
14856   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
14857   vam->ifp = save_ifp;
14858   vam->input_line_number = save_line_number;
14859   vam->current_file = (u8 *) save_current_file;
14860   vec_free (s);
14861
14862   return 0;
14863 #else
14864   clib_warning ("use the exec command...");
14865   return -99;
14866 #endif
14867 }
14868
14869 static int
14870 echo (vat_main_t * vam)
14871 {
14872   print (vam->ofp, "%v", vam->input->buffer);
14873   return 0;
14874 }
14875
14876 /* List of API message constructors, CLI names map to api_xxx */
14877 #define foreach_vpe_api_msg                                             \
14878 _(create_loopback,"[mac <mac-addr>] [instance <instance>]")             \
14879 _(sw_interface_dump,"")                                                 \
14880 _(sw_interface_set_flags,                                               \
14881   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
14882 _(sw_interface_add_del_address,                                         \
14883   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
14884 _(sw_interface_set_rx_mode,                                             \
14885   "<intfc> | sw_if_index <id> [queue <id>] <polling | interrupt | adaptive>") \
14886 _(sw_interface_set_rx_placement,                                        \
14887   "<intfc> | sw_if_index <id> [queue <id>] [worker <id> | main]")       \
14888 _(sw_interface_rx_placement_dump,                                       \
14889   "[<intfc> | sw_if_index <id>]")                                         \
14890 _(sw_interface_set_table,                                               \
14891   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
14892 _(sw_interface_set_mpls_enable,                                         \
14893   "<intfc> | sw_if_index [disable | dis]")                              \
14894 _(sw_interface_set_vpath,                                               \
14895   "<intfc> | sw_if_index <id> enable | disable")                        \
14896 _(sw_interface_set_vxlan_bypass,                                        \
14897   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
14898 _(sw_interface_set_l2_xconnect,                                         \
14899   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
14900   "enable | disable")                                                   \
14901 _(sw_interface_set_l2_bridge,                                           \
14902   "{<intfc> | sw_if_index <id>} bd_id <bridge-domain-id>\n"             \
14903   "[shg <split-horizon-group>] [bvi]\n"                                 \
14904   "enable | disable")                                                   \
14905 _(bridge_domain_set_mac_age, "bd_id <bridge-domain-id> mac-age 0-255")  \
14906 _(bridge_domain_add_del,                                                \
14907   "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") \
14908 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
14909 _(l2fib_add_del,                                                        \
14910   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
14911 _(l2fib_flush_bd, "bd_id <bridge-domain-id>")                           \
14912 _(l2fib_flush_int, "<intfc> | sw_if_index <id>")                        \
14913 _(l2_flags,                                                             \
14914   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
14915 _(bridge_flags,                                                         \
14916   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
14917 _(tap_create_v2,                                                        \
14918   "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]") \
14919 _(tap_delete_v2,                                                        \
14920   "<vpp-if-name> | sw_if_index <id>")                                   \
14921 _(sw_interface_tap_v2_dump, "")                                         \
14922 _(virtio_pci_create_v2,                                                    \
14923   "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]") \
14924 _(virtio_pci_delete,                                                    \
14925   "<vpp-if-name> | sw_if_index <id>")                                   \
14926 _(sw_interface_virtio_pci_dump, "")                                     \
14927 _(bond_create,                                                          \
14928   "[hw-addr <mac-addr>] {round-robin | active-backup | "                \
14929   "broadcast | {lacp | xor} [load-balance { l2 | l23 | l34 }]} "        \
14930   "[id <if-id>]")                                                       \
14931 _(bond_create2,                                                         \
14932   "[hw-addr <mac-addr>] {mode round-robin | active-backup | "           \
14933   "broadcast | {lacp | xor} [load-balance { l2 | l23 | l34 }]} "        \
14934   "[id <if-id>] [gso]")                                                 \
14935 _(bond_delete,                                                          \
14936   "<vpp-if-name> | sw_if_index <id>")                                   \
14937 _(bond_add_member,                                                      \
14938   "sw_if_index <n> bond <sw_if_index> [is_passive] [is_long_timeout]")  \
14939 _(bond_detach_member,                                                   \
14940   "sw_if_index <n>")                                                    \
14941  _(sw_interface_set_bond_weight, "<intfc> | sw_if_index <nn> weight <value>") \
14942  _(sw_bond_interface_dump, "<intfc> | sw_if_index <nn>")                \
14943  _(sw_member_interface_dump,                                            \
14944   "<vpp-if-name> | sw_if_index <id>")                                   \
14945 _(ip_table_add_del,                                                     \
14946   "table <n> [ipv6] [add | del]\n")                                     \
14947 _(ip_route_add_del,                                                     \
14948   "<addr>/<mask> via <<addr>|<intfc>|sw_if_index <id>|via-label <n>>\n" \
14949   "[table-id <n>] [<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"\
14950   "[weight <n>] [drop] [local] [classify <n>]  [out-label <n>]\n"       \
14951   "[multipath] [count <n>] [del]")                                      \
14952 _(ip_mroute_add_del,                                                    \
14953   "<src> <grp>/<mask> [table-id <n>]\n"                                 \
14954   "[<intfc> | sw_if_index <id>] [local] [del]")                         \
14955 _(mpls_table_add_del,                                                   \
14956   "table <n> [add | del]\n")                                            \
14957 _(mpls_route_add_del,                                                   \
14958   "<label> <eos> via <addr | next-hop-table <n> | via-label <n> |\n"    \
14959   "lookup-ip4-table <n> | lookup-in-ip6-table <n> |\n"                  \
14960   "l2-input-on <intfc> | l2-input-on sw_if_index <id>>\n"               \
14961   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>] [weight <n>]\n"  \
14962   "[drop] [local] [classify <n>] [out-label <n>] [multipath]\n"         \
14963   "[count <n>] [del]")                                                  \
14964 _(mpls_ip_bind_unbind,                                                  \
14965   "<label> <addr/len>")                                                 \
14966 _(mpls_tunnel_add_del,                                                  \
14967   "[add | del <intfc | sw_if_index <id>>] via <addr | via-label <n>>\n" \
14968   "[<intfc> | sw_if_index <id> | next-hop-table <id>]\n"                \
14969   "[l2-only]  [out-label <n>]")                                         \
14970 _(sr_mpls_policy_add,                                                   \
14971   "bsid <id> [weight <n>] [spray] next <sid> [next <sid>]")             \
14972 _(sr_mpls_policy_del,                                                   \
14973   "bsid <id>")                                                          \
14974 _(bier_table_add_del,                                                   \
14975   "<label> <sub-domain> <set> <bsl> [del]")                             \
14976 _(bier_route_add_del,                                                   \
14977   "<bit-position> <sub-domain> <set> <bsl> via <addr> [table-id <n>]\n" \
14978   "[<intfc> | sw_if_index <id>]"                                        \
14979   "[weight <n>] [del] [multipath]")                                     \
14980 _(sw_interface_set_unnumbered,                                          \
14981   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
14982 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
14983 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
14984   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
14985   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
14986   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
14987 _(ip_table_replace_begin, "table <n> [ipv6]")                           \
14988 _(ip_table_flush, "table <n> [ipv6]")                                   \
14989 _(ip_table_replace_end, "table <n> [ipv6]")                             \
14990 _(set_ip_flow_hash,                                                     \
14991   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
14992 _(sw_interface_ip6_enable_disable,                                      \
14993   "<intfc> | sw_if_index <id> enable | disable")                        \
14994 _(l2_patch_add_del,                                                     \
14995   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
14996   "enable | disable")                                                   \
14997 _(sr_localsid_add_del,                                                  \
14998   "(del) address <addr> next_hop <addr> behavior <beh>\n"               \
14999   "fib-table <num> (end.psp) sw_if_index <num>")                        \
15000 _(classify_add_del_table,                                               \
15001   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
15002   " [del] [del-chain] mask <mask-value>\n"                              \
15003   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
15004   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
15005 _(classify_add_del_session,                                             \
15006   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
15007   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
15008   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
15009   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
15010 _(classify_set_interface_ip_table,                                      \
15011   "<intfc> | sw_if_index <nn> table <nn>")                              \
15012 _(classify_set_interface_l2_tables,                                     \
15013   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
15014   "  [other-table <nn>]")                                               \
15015 _(get_node_index, "node <node-name")                                    \
15016 _(add_node_next, "node <node-name> next <next-node-name>")              \
15017 _(vxlan_offload_rx,                                                     \
15018   "hw { <interface name> | hw_if_index <nn>} "                          \
15019   "rx { <vxlan tunnel name> | sw_if_index <nn> } [del]")                \
15020 _(vxlan_add_del_tunnel,                                                 \
15021   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
15022   "{ <intfc> | mcast_sw_if_index <nn> } [instance <id>]}\n"             \
15023   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
15024 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
15025 _(l2_fib_clear_table, "")                                               \
15026 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
15027 _(l2_interface_vlan_tag_rewrite,                                        \
15028   "<intfc> | sw_if_index <nn> \n"                                       \
15029   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
15030   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
15031 _(create_vhost_user_if,                                                 \
15032         "socket <filename> [server] [renumber <dev_instance>] "         \
15033         "[disable_mrg_rxbuf] [disable_indirect_desc] [gso] "            \
15034         "[mac <mac_address>] [packed]")                                 \
15035 _(modify_vhost_user_if,                                                 \
15036         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
15037         "[server] [renumber <dev_instance>] [gso] [packed]")            \
15038 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
15039 _(sw_interface_vhost_user_dump, "<intfc> | sw_if_index <nn>")           \
15040 _(show_version, "")                                                     \
15041 _(show_threads, "")                                                     \
15042 _(vxlan_gpe_add_del_tunnel,                                             \
15043   "local <addr> remote <addr>  | group <mcast-ip-addr>\n"               \
15044   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
15045   "vni <nn> [encap-vrf-id <nn>] [decap-vrf-id <nn>]\n"                  \
15046   "[next-ip4][next-ip6][next-ethernet] [next-nsh] [del]\n")             \
15047 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
15048 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
15049 _(interface_name_renumber,                                              \
15050   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
15051 _(input_acl_set_interface,                                              \
15052   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
15053   "  [l2-table <nn>] [del]")                                            \
15054 _(want_l2_macs_events, "[disable] [learn-limit <n>] [scan-delay <n>] [max-entries <n>]") \
15055 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
15056 _(ip_dump, "ipv4 | ipv6")                                               \
15057 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
15058 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
15059   "  spid_id <n> ")                                                     \
15060 _(ipsec_sad_entry_add_del, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
15061   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
15062   "  integ_alg <alg> integ_key <hex>")                                  \
15063 _(ipsec_spd_entry_add_del, "spd_id <n> priority <n> action <action>\n"  \
15064   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
15065   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
15066   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
15067 _(ipsec_tunnel_if_add_del, "local_spi <n> remote_spi <n>\n"             \
15068   "  crypto_alg <alg> local_crypto_key <hex> remote_crypto_key <hex>\n" \
15069   "  integ_alg <alg> local_integ_key <hex> remote_integ_key <hex>\n"    \
15070   "  local_ip <addr> remote_ip <addr> [esn] [anti_replay] [del]\n"      \
15071   "  [instance <n>]")     \
15072 _(ipsec_sa_dump, "[sa_id <n>]")                                         \
15073 _(ipsec_tunnel_if_set_sa, "<intfc> sa_id <n> <inbound|outbound>\n")     \
15074 _(delete_loopback,"sw_if_index <nn>")                                   \
15075 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
15076 _(bd_ip_mac_flush, "bd_id <bridge-domain-id>")                          \
15077 _(bd_ip_mac_dump, "[bd_id] <bridge-domain-id>")                         \
15078 _(want_interface_events,  "enable|disable")                             \
15079 _(get_first_msg_id, "client <name>")                                    \
15080 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
15081 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
15082   "fib-id <nn> [ip4][ip6][default]")                                    \
15083 _(get_node_graph, " ")                                                  \
15084 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
15085 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
15086 _(ioam_disable, "")                                                     \
15087 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
15088 _(af_packet_delete, "name <host interface name>")                       \
15089 _(af_packet_dump, "")                                                   \
15090 _(policer_add_del, "name <policer name> <params> [del]")                \
15091 _(policer_dump, "[name <policer name>]")                                \
15092 _(policer_classify_set_interface,                                       \
15093   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
15094   "  [l2-table <nn>] [del]")                                            \
15095 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
15096 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
15097 _(mpls_table_dump, "")                                                  \
15098 _(mpls_route_dump, "table-id <ID>")                                     \
15099 _(classify_table_ids, "")                                               \
15100 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
15101 _(classify_table_info, "table_id <nn>")                                 \
15102 _(classify_session_dump, "table_id <nn>")                               \
15103 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
15104     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
15105     "[template_interval <nn>] [udp_checksum]")                          \
15106 _(ipfix_exporter_dump, "")                                              \
15107 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
15108 _(ipfix_classify_stream_dump, "")                                       \
15109 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
15110 _(ipfix_classify_table_dump, "")                                        \
15111 _(sw_interface_span_enable_disable, "[l2] [src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
15112 _(sw_interface_span_dump, "[l2]")                                           \
15113 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
15114 _(pg_create_interface, "if_id <nn> [gso-enabled gso-size <size>]")      \
15115 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
15116 _(pg_enable_disable, "[stream <id>] disable")                           \
15117 _(pg_interface_enable_disable_coalesce, "<intf> | sw_if_index <nn> enable | disable")  \
15118 _(ip_source_and_port_range_check_add_del,                               \
15119   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
15120 _(ip_source_and_port_range_check_interface_add_del,                     \
15121   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
15122   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
15123 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
15124 _(l2_interface_pbb_tag_rewrite,                                         \
15125   "<intfc> | sw_if_index <nn> \n"                                       \
15126   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
15127   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
15128 _(set_punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
15129 _(flow_classify_set_interface,                                          \
15130   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
15131 _(flow_classify_dump, "type [ip4|ip6]")                                 \
15132 _(ip_table_dump, "")                                                    \
15133 _(ip_route_dump, "table-id [ip4|ip6]")                                  \
15134 _(ip_mtable_dump, "")                                                   \
15135 _(ip_mroute_dump, "table-id [ip4|ip6]")                                 \
15136 _(feature_enable_disable, "arc_name <arc_name> "                        \
15137   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
15138 _(feature_gso_enable_disable, "<intfc> | sw_if_index <nn> "             \
15139   "[enable | disable] ")                                                \
15140 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
15141 "[disable]")                                                            \
15142 _(sw_interface_add_del_mac_address, "<intfc> | sw_if_index <nn> "       \
15143   "mac <mac-address> [del]")                                            \
15144 _(l2_xconnect_dump, "")                                                 \
15145 _(hw_interface_set_mtu, "<intfc> | hw_if_index <nn> mtu <nn>")        \
15146 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")          \
15147 _(p2p_ethernet_add, "<intfc> | sw_if_index <nn> remote_mac <mac-address> sub_id <id>") \
15148 _(p2p_ethernet_del, "<intfc> | sw_if_index <nn> remote_mac <mac-address>") \
15149 _(tcp_configure_src_addresses, "<ip4|6>first-<ip4|6>last [vrf <id>]")   \
15150 _(sock_init_shm, "size <nnn>")                                          \
15151 _(app_namespace_add_del, "[add] id <ns-id> secret <nn> sw_if_index <nn>")\
15152 _(session_rule_add_del, "[add|del] proto <tcp/udp> <lcl-ip>/<plen> "    \
15153   "<lcl-port> <rmt-ip>/<plen> <rmt-port> action <nn>")                  \
15154 _(session_rules_dump, "")                                               \
15155 _(ip_container_proxy_add_del, "[add|del] <address> <sw_if_index>")      \
15156 _(output_acl_set_interface,                                             \
15157   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
15158   "  [l2-table <nn>] [del]")                                            \
15159 _(qos_record_enable_disable, "<record-source> <intfc> | sw_if_index <id> [disable]")
15160
15161 /* List of command functions, CLI names map directly to functions */
15162 #define foreach_cli_function                                    \
15163 _(comment, "usage: comment <ignore-rest-of-line>")              \
15164 _(dump_interface_table, "usage: dump_interface_table")          \
15165 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
15166 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
15167 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
15168 _(dump_macro_table, "usage: dump_macro_table ")                 \
15169 _(dump_node_table, "usage: dump_node_table")                    \
15170 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
15171 _(elog_setup, "usage: elog_setup [nevents, default 128K]")      \
15172 _(elog_disable, "usage: elog_disable")                          \
15173 _(elog_enable, "usage: elog_enable")                            \
15174 _(elog_save, "usage: elog_save <filename>")                     \
15175 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
15176 _(echo, "usage: echo <message>")                                \
15177 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
15178 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
15179 _(help, "usage: help")                                          \
15180 _(q, "usage: quit")                                             \
15181 _(quit, "usage: quit")                                          \
15182 _(search_node_table, "usage: search_node_table <name>...")      \
15183 _(set, "usage: set <variable-name> <value>")                    \
15184 _(script, "usage: script <file-name>")                          \
15185 _(statseg, "usage: statseg")                                    \
15186 _(unset, "usage: unset <variable-name>")
15187
15188 #define _(N,n)                                  \
15189     static void vl_api_##n##_t_handler_uni      \
15190     (vl_api_##n##_t * mp)                       \
15191     {                                           \
15192         vat_main_t * vam = &vat_main;           \
15193         if (vam->json_output) {                 \
15194             vl_api_##n##_t_handler_json(mp);    \
15195         } else {                                \
15196             vl_api_##n##_t_handler(mp);         \
15197         }                                       \
15198     }
15199 foreach_vpe_api_reply_msg;
15200 #if VPP_API_TEST_BUILTIN == 0
15201 foreach_standalone_reply_msg;
15202 #endif
15203 #undef _
15204
15205 void
15206 vat_api_hookup (vat_main_t * vam)
15207 {
15208 #define _(N,n)                                                  \
15209     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
15210                            vl_api_##n##_t_handler_uni,          \
15211                            vl_noop_handler,                     \
15212                            vl_api_##n##_t_endian,               \
15213                            vl_api_##n##_t_print,                \
15214                            sizeof(vl_api_##n##_t), 1);
15215   foreach_vpe_api_reply_msg;
15216 #if VPP_API_TEST_BUILTIN == 0
15217   foreach_standalone_reply_msg;
15218 #endif
15219 #undef _
15220
15221 #if (VPP_API_TEST_BUILTIN==0)
15222   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
15223
15224   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
15225
15226   vam->function_by_name = hash_create_string (0, sizeof (uword));
15227
15228   vam->help_by_name = hash_create_string (0, sizeof (uword));
15229 #endif
15230
15231   /* API messages we can send */
15232 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
15233   foreach_vpe_api_msg;
15234 #undef _
15235
15236   /* Help strings */
15237 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
15238   foreach_vpe_api_msg;
15239 #undef _
15240
15241   /* CLI functions */
15242 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
15243   foreach_cli_function;
15244 #undef _
15245
15246   /* Help strings */
15247 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
15248   foreach_cli_function;
15249 #undef _
15250 }
15251
15252 #if VPP_API_TEST_BUILTIN
15253 static clib_error_t *
15254 vat_api_hookup_shim (vlib_main_t * vm)
15255 {
15256   vat_api_hookup (&vat_main);
15257   return 0;
15258 }
15259
15260 VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
15261 #endif
15262
15263 /*
15264  * fd.io coding-style-patch-verification: ON
15265  *
15266  * Local Variables:
15267  * eval: (c-set-style "gnu")
15268  * End:
15269  */