misc: remove cop API support (part 1)
[vpp.git] / src / vat / api_format.c
1 /*
2  *------------------------------------------------------------------
3  * api_format.c
4  *
5  * Copyright (c) 2014-2020 Cisco and/or its affiliates.
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at:
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *------------------------------------------------------------------
18  */
19
20 #include <vat/vat.h>
21 #include <vlib/pci/pci.h>
22 #include <vpp/api/types.h>
23 #include <vppinfra/socket.h>
24 #include <vlibapi/api.h>
25 #include <vlibmemory/api.h>
26 #include <vnet/ip/ip.h>
27 #include <vnet/ip-neighbor/ip_neighbor.h>
28 #include <vnet/ip/ip_types_api.h>
29 #include <vnet/l2/l2_input.h>
30 #include <vnet/vxlan/vxlan.h>
31 #include <vnet/vxlan-gpe/vxlan_gpe.h>
32 #include <vnet/udp/udp_local.h>
33
34 #include <vpp/api/vpe_msg_enum.h>
35 #include <vnet/l2/l2_classify.h>
36 #include <vnet/l2/l2_vtr.h>
37 #include <vnet/classify/in_out_acl.h>
38 #include <vnet/classify/policer_classify.h>
39 #include <vnet/classify/flow_classify.h>
40 #include <vnet/mpls/mpls.h>
41 #include <vnet/ipsec/ipsec.h>
42 #include <inttypes.h>
43 #include <vnet/ip/ip6_hop_by_hop.h>
44 #include <vnet/ip/ip_source_and_port_range_check.h>
45 #include <vnet/policer/xlate.h>
46 #include <vnet/span/span.h>
47 #include <vnet/policer/policer.h>
48 #include <vnet/policer/police.h>
49 #include <vnet/mfib/mfib_types.h>
50 #include <vnet/bonding/node.h>
51 #include <vnet/qos/qos_types.h>
52 #include <vnet/ethernet/ethernet_types_api.h>
53 #include <vnet/ip/ip_types_api.h>
54 #include "vat/json_format.h"
55 #include <vnet/ip/ip_types_api.h>
56 #include <vnet/ethernet/ethernet_types_api.h>
57
58 #include <inttypes.h>
59 #include <sys/stat.h>
60
61 #define vl_typedefs             /* define message structures */
62 #include <vpp/api/vpe_all_api_h.h>
63 #undef vl_typedefs
64
65 /* declare message handlers for each api */
66
67 #define vl_endianfun            /* define message structures */
68 #include <vpp/api/vpe_all_api_h.h>
69 #undef vl_endianfun
70
71 /* instantiate all the print functions we know about */
72 #if VPP_API_TEST_BUILTIN == 0
73 #define vl_print(handle, ...)
74 #else
75 #define vl_print(handle, ...) vlib_cli_output (handle, __VA_ARGS__)
76 #endif
77 #define vl_printfun
78 #include <vpp/api/vpe_all_api_h.h>
79 #undef vl_printfun
80
81 #define __plugin_msg_base 0
82 #include <vlibapi/vat_helper_macros.h>
83
84 #include <vnet/format_fns.h>
85
86 void vl_api_set_elog_main (elog_main_t * m);
87 int vl_api_set_elog_trace_api_messages (int enable);
88
89 #if VPP_API_TEST_BUILTIN == 0
90 #include <netdb.h>
91
92 u32
93 vl (void *p)
94 {
95   return vec_len (p);
96 }
97
98 int
99 vat_socket_connect (vat_main_t * vam)
100 {
101   int rv;
102   api_main_t *am = vlibapi_get_main ();
103   vam->socket_client_main = &socket_client_main;
104   if ((rv = vl_socket_client_connect ((char *) vam->socket_name,
105                                       "vpp_api_test",
106                                       0 /* default socket rx, tx buffer */ )))
107     return rv;
108
109   /* vpp expects the client index in network order */
110   vam->my_client_index = htonl (socket_client_main.client_index);
111   am->my_client_index = vam->my_client_index;
112   return 0;
113 }
114 #else /* vpp built-in case, we don't do sockets... */
115 int
116 vat_socket_connect (vat_main_t * vam)
117 {
118   return 0;
119 }
120
121 int
122 vl_socket_client_read (int wait)
123 {
124   return -1;
125 };
126
127 int
128 vl_socket_client_write ()
129 {
130   return -1;
131 };
132
133 void *
134 vl_socket_client_msg_alloc (int nbytes)
135 {
136   return 0;
137 }
138 #endif
139
140
141 f64
142 vat_time_now (vat_main_t * vam)
143 {
144 #if VPP_API_TEST_BUILTIN
145   return vlib_time_now (vam->vlib_main);
146 #else
147   return clib_time_now (&vam->clib_time);
148 #endif
149 }
150
151 void
152 errmsg (char *fmt, ...)
153 {
154   vat_main_t *vam = &vat_main;
155   va_list va;
156   u8 *s;
157
158   va_start (va, fmt);
159   s = va_format (0, fmt, &va);
160   va_end (va);
161
162   vec_add1 (s, 0);
163
164 #if VPP_API_TEST_BUILTIN
165   vlib_cli_output (vam->vlib_main, (char *) s);
166 #else
167   {
168     if (vam->ifp != stdin)
169       fformat (vam->ofp, "%s(%d): \n", vam->current_file,
170                vam->input_line_number);
171     else
172       fformat (vam->ofp, "%s\n", (char *) s);
173     fflush (vam->ofp);
174   }
175 #endif
176
177   vec_free (s);
178 }
179
180 #if VPP_API_TEST_BUILTIN == 0
181 static uword
182 api_unformat_sw_if_index (unformat_input_t * input, va_list * args)
183 {
184   vat_main_t *vam = va_arg (*args, vat_main_t *);
185   u32 *result = va_arg (*args, u32 *);
186   u8 *if_name;
187   uword *p;
188
189   if (!unformat (input, "%s", &if_name))
190     return 0;
191
192   p = hash_get_mem (vam->sw_if_index_by_interface_name, if_name);
193   if (p == 0)
194     return 0;
195   *result = p[0];
196   return 1;
197 }
198
199 static uword
200 api_unformat_hw_if_index (unformat_input_t * input, va_list * args)
201 {
202   return 0;
203 }
204
205 /* Parse an IP4 address %d.%d.%d.%d. */
206 uword
207 unformat_ip4_address (unformat_input_t * input, va_list * args)
208 {
209   u8 *result = va_arg (*args, u8 *);
210   unsigned a[4];
211
212   if (!unformat (input, "%d.%d.%d.%d", &a[0], &a[1], &a[2], &a[3]))
213     return 0;
214
215   if (a[0] >= 256 || a[1] >= 256 || a[2] >= 256 || a[3] >= 256)
216     return 0;
217
218   result[0] = a[0];
219   result[1] = a[1];
220   result[2] = a[2];
221   result[3] = a[3];
222
223   return 1;
224 }
225
226 uword
227 unformat_ethernet_address (unformat_input_t * input, va_list * args)
228 {
229   u8 *result = va_arg (*args, u8 *);
230   u32 i, a[6];
231
232   if (!unformat (input, "%_%x:%x:%x:%x:%x:%x%_",
233                  &a[0], &a[1], &a[2], &a[3], &a[4], &a[5]))
234     return 0;
235
236   /* Check range. */
237   for (i = 0; i < 6; i++)
238     if (a[i] >= (1 << 8))
239       return 0;
240
241   for (i = 0; i < 6; i++)
242     result[i] = a[i];
243
244   return 1;
245 }
246
247 /* Returns ethernet type as an int in host byte order. */
248 uword
249 unformat_ethernet_type_host_byte_order (unformat_input_t * input,
250                                         va_list * args)
251 {
252   u16 *result = va_arg (*args, u16 *);
253   int type;
254
255   /* Numeric type. */
256   if (unformat (input, "0x%x", &type) || unformat (input, "%d", &type))
257     {
258       if (type >= (1 << 16))
259         return 0;
260       *result = type;
261       return 1;
262     }
263   return 0;
264 }
265
266 /* Parse an IP46 address. */
267 uword
268 unformat_ip46_address (unformat_input_t * input, va_list * args)
269 {
270   ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
271   ip46_type_t type = va_arg (*args, ip46_type_t);
272   if ((type != IP46_TYPE_IP6) &&
273       unformat (input, "%U", unformat_ip4_address, &ip46->ip4))
274     {
275       ip46_address_mask_ip4 (ip46);
276       return 1;
277     }
278   else if ((type != IP46_TYPE_IP4) &&
279            unformat (input, "%U", unformat_ip6_address, &ip46->ip6))
280     {
281       return 1;
282     }
283   return 0;
284 }
285
286 /* Parse an IP6 address. */
287 uword
288 unformat_ip6_address (unformat_input_t * input, va_list * args)
289 {
290   ip6_address_t *result = va_arg (*args, ip6_address_t *);
291   u16 hex_quads[8];
292   uword hex_quad, n_hex_quads, hex_digit, n_hex_digits;
293   uword c, n_colon, double_colon_index;
294
295   n_hex_quads = hex_quad = n_hex_digits = n_colon = 0;
296   double_colon_index = ARRAY_LEN (hex_quads);
297   while ((c = unformat_get_input (input)) != UNFORMAT_END_OF_INPUT)
298     {
299       hex_digit = 16;
300       if (c >= '0' && c <= '9')
301         hex_digit = c - '0';
302       else if (c >= 'a' && c <= 'f')
303         hex_digit = c + 10 - 'a';
304       else if (c >= 'A' && c <= 'F')
305         hex_digit = c + 10 - 'A';
306       else if (c == ':' && n_colon < 2)
307         n_colon++;
308       else
309         {
310           unformat_put_input (input);
311           break;
312         }
313
314       /* Too many hex quads. */
315       if (n_hex_quads >= ARRAY_LEN (hex_quads))
316         return 0;
317
318       if (hex_digit < 16)
319         {
320           hex_quad = (hex_quad << 4) | hex_digit;
321
322           /* Hex quad must fit in 16 bits. */
323           if (n_hex_digits >= 4)
324             return 0;
325
326           n_colon = 0;
327           n_hex_digits++;
328         }
329
330       /* Save position of :: */
331       if (n_colon == 2)
332         {
333           /* More than one :: ? */
334           if (double_colon_index < ARRAY_LEN (hex_quads))
335             return 0;
336           double_colon_index = n_hex_quads;
337         }
338
339       if (n_colon > 0 && n_hex_digits > 0)
340         {
341           hex_quads[n_hex_quads++] = hex_quad;
342           hex_quad = 0;
343           n_hex_digits = 0;
344         }
345     }
346
347   if (n_hex_digits > 0)
348     hex_quads[n_hex_quads++] = hex_quad;
349
350   {
351     word i;
352
353     /* Expand :: to appropriate number of zero hex quads. */
354     if (double_colon_index < ARRAY_LEN (hex_quads))
355       {
356         word n_zero = ARRAY_LEN (hex_quads) - n_hex_quads;
357
358         for (i = n_hex_quads - 1; i >= (signed) double_colon_index; i--)
359           hex_quads[n_zero + i] = hex_quads[i];
360
361         for (i = 0; i < n_zero; i++)
362           hex_quads[double_colon_index + i] = 0;
363
364         n_hex_quads = ARRAY_LEN (hex_quads);
365       }
366
367     /* Too few hex quads given. */
368     if (n_hex_quads < ARRAY_LEN (hex_quads))
369       return 0;
370
371     for (i = 0; i < ARRAY_LEN (hex_quads); i++)
372       result->as_u16[i] = clib_host_to_net_u16 (hex_quads[i]);
373
374     return 1;
375   }
376 }
377
378 uword
379 unformat_ipsec_policy_action (unformat_input_t * input, va_list * args)
380 {
381   u32 *r = va_arg (*args, u32 *);
382
383   if (0);
384 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_POLICY_ACTION_##f;
385   foreach_ipsec_policy_action
386 #undef _
387     else
388     return 0;
389   return 1;
390 }
391
392 u8 *
393 format_ipsec_crypto_alg (u8 * s, va_list * args)
394 {
395   u32 i = va_arg (*args, u32);
396   u8 *t = 0;
397
398   switch (i)
399     {
400 #define _(v,f,str) case IPSEC_CRYPTO_ALG_##f: t = (u8 *) str; break;
401       foreach_ipsec_crypto_alg
402 #undef _
403     default:
404       return format (s, "unknown");
405     }
406   return format (s, "%s", t);
407 }
408
409 u8 *
410 format_ipsec_integ_alg (u8 * s, va_list * args)
411 {
412   u32 i = va_arg (*args, u32);
413   u8 *t = 0;
414
415   switch (i)
416     {
417 #define _(v,f,str) case IPSEC_INTEG_ALG_##f: t = (u8 *) str; break;
418       foreach_ipsec_integ_alg
419 #undef _
420     default:
421       return format (s, "unknown");
422     }
423   return format (s, "%s", t);
424 }
425
426 #else /* VPP_API_TEST_BUILTIN == 1 */
427 static uword
428 api_unformat_sw_if_index (unformat_input_t * input, va_list * args)
429 {
430   vat_main_t *vam __clib_unused = va_arg (*args, vat_main_t *);
431   vnet_main_t *vnm = vnet_get_main ();
432   u32 *result = va_arg (*args, u32 *);
433
434   return unformat (input, "%U", unformat_vnet_sw_interface, vnm, result);
435 }
436
437 static uword
438 api_unformat_hw_if_index (unformat_input_t * input, va_list * args)
439 {
440   vat_main_t *vam __clib_unused = va_arg (*args, vat_main_t *);
441   vnet_main_t *vnm = vnet_get_main ();
442   u32 *result = va_arg (*args, u32 *);
443
444   return unformat (input, "%U", unformat_vnet_hw_interface, vnm, result);
445 }
446
447 #endif /* VPP_API_TEST_BUILTIN */
448
449 uword
450 unformat_ipsec_api_crypto_alg (unformat_input_t * input, va_list * args)
451 {
452   u32 *r = va_arg (*args, u32 *);
453
454   if (0);
455 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_API_CRYPTO_ALG_##f;
456   foreach_ipsec_crypto_alg
457 #undef _
458     else
459     return 0;
460   return 1;
461 }
462
463 uword
464 unformat_ipsec_api_integ_alg (unformat_input_t * input, va_list * args)
465 {
466   u32 *r = va_arg (*args, u32 *);
467
468   if (0);
469 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_API_INTEG_ALG_##f;
470   foreach_ipsec_integ_alg
471 #undef _
472     else
473     return 0;
474   return 1;
475 }
476
477 static uword
478 unformat_policer_rate_type (unformat_input_t * input, va_list * args)
479 {
480   u8 *r = va_arg (*args, u8 *);
481
482   if (unformat (input, "kbps"))
483     *r = QOS_RATE_KBPS;
484   else if (unformat (input, "pps"))
485     *r = QOS_RATE_PPS;
486   else
487     return 0;
488   return 1;
489 }
490
491 static uword
492 unformat_policer_round_type (unformat_input_t * input, va_list * args)
493 {
494   u8 *r = va_arg (*args, u8 *);
495
496   if (unformat (input, "closest"))
497     *r = QOS_ROUND_TO_CLOSEST;
498   else if (unformat (input, "up"))
499     *r = QOS_ROUND_TO_UP;
500   else if (unformat (input, "down"))
501     *r = QOS_ROUND_TO_DOWN;
502   else
503     return 0;
504   return 1;
505 }
506
507 static uword
508 unformat_policer_type (unformat_input_t * input, va_list * args)
509 {
510   u8 *r = va_arg (*args, u8 *);
511
512   if (unformat (input, "1r2c"))
513     *r = QOS_POLICER_TYPE_1R2C;
514   else if (unformat (input, "1r3c"))
515     *r = QOS_POLICER_TYPE_1R3C_RFC_2697;
516   else if (unformat (input, "2r3c-2698"))
517     *r = QOS_POLICER_TYPE_2R3C_RFC_2698;
518   else if (unformat (input, "2r3c-4115"))
519     *r = QOS_POLICER_TYPE_2R3C_RFC_4115;
520   else if (unformat (input, "2r3c-mef5cf1"))
521     *r = QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1;
522   else
523     return 0;
524   return 1;
525 }
526
527 static uword
528 unformat_dscp (unformat_input_t * input, va_list * va)
529 {
530   u8 *r = va_arg (*va, u8 *);
531
532   if (0);
533 #define _(v, f) else if (unformat (input, #f)) *r = IP_DSCP_##f;
534   foreach_ip_dscp
535 #undef _
536     else return 0;
537   return 1;
538 }
539
540 static uword
541 unformat_policer_action_type (unformat_input_t * input, va_list * va)
542 {
543   qos_pol_action_params_st *a = va_arg (*va, qos_pol_action_params_st *);
544
545   if (unformat (input, "drop"))
546     a->action_type = QOS_ACTION_DROP;
547   else if (unformat (input, "transmit"))
548     a->action_type = QOS_ACTION_TRANSMIT;
549   else if (unformat (input, "mark-and-transmit %U", unformat_dscp, &a->dscp))
550     a->action_type = QOS_ACTION_MARK_AND_TRANSMIT;
551   else
552     return 0;
553   return 1;
554 }
555
556 static uword
557 unformat_policer_classify_table_type (unformat_input_t * input, va_list * va)
558 {
559   u32 *r = va_arg (*va, u32 *);
560   u32 tid;
561
562   if (unformat (input, "ip4"))
563     tid = POLICER_CLASSIFY_TABLE_IP4;
564   else if (unformat (input, "ip6"))
565     tid = POLICER_CLASSIFY_TABLE_IP6;
566   else if (unformat (input, "l2"))
567     tid = POLICER_CLASSIFY_TABLE_L2;
568   else
569     return 0;
570
571   *r = tid;
572   return 1;
573 }
574
575 static uword
576 unformat_flow_classify_table_type (unformat_input_t * input, va_list * va)
577 {
578   u32 *r = va_arg (*va, u32 *);
579   u32 tid;
580
581   if (unformat (input, "ip4"))
582     tid = FLOW_CLASSIFY_TABLE_IP4;
583   else if (unformat (input, "ip6"))
584     tid = FLOW_CLASSIFY_TABLE_IP6;
585   else
586     return 0;
587
588   *r = tid;
589   return 1;
590 }
591
592 #if (VPP_API_TEST_BUILTIN==0)
593
594 static const char *mfib_flag_names[] = MFIB_ENTRY_NAMES_SHORT;
595 static const char *mfib_flag_long_names[] = MFIB_ENTRY_NAMES_LONG;
596 static const char *mfib_itf_flag_long_names[] = MFIB_ITF_NAMES_LONG;
597 static const char *mfib_itf_flag_names[] = MFIB_ITF_NAMES_SHORT;
598
599 uword
600 unformat_mfib_itf_flags (unformat_input_t * input, va_list * args)
601 {
602   mfib_itf_flags_t old, *iflags = va_arg (*args, mfib_itf_flags_t *);
603   mfib_itf_attribute_t attr;
604
605   old = *iflags;
606   FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
607   {
608     if (unformat (input, mfib_itf_flag_long_names[attr]))
609       *iflags |= (1 << attr);
610   }
611   FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
612   {
613     if (unformat (input, mfib_itf_flag_names[attr]))
614       *iflags |= (1 << attr);
615   }
616
617   return (old == *iflags ? 0 : 1);
618 }
619
620 uword
621 unformat_mfib_entry_flags (unformat_input_t * input, va_list * args)
622 {
623   mfib_entry_flags_t old, *eflags = va_arg (*args, mfib_entry_flags_t *);
624   mfib_entry_attribute_t attr;
625
626   old = *eflags;
627   FOR_EACH_MFIB_ATTRIBUTE (attr)
628   {
629     if (unformat (input, mfib_flag_long_names[attr]))
630       *eflags |= (1 << attr);
631   }
632   FOR_EACH_MFIB_ATTRIBUTE (attr)
633   {
634     if (unformat (input, mfib_flag_names[attr]))
635       *eflags |= (1 << attr);
636   }
637
638   return (old == *eflags ? 0 : 1);
639 }
640
641 u8 *
642 format_ip4_address (u8 * s, va_list * args)
643 {
644   u8 *a = va_arg (*args, u8 *);
645   return format (s, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]);
646 }
647
648 u8 *
649 format_ip6_address (u8 * s, va_list * args)
650 {
651   ip6_address_t *a = va_arg (*args, ip6_address_t *);
652   u32 i, i_max_n_zero, max_n_zeros, i_first_zero, n_zeros, last_double_colon;
653
654   i_max_n_zero = ARRAY_LEN (a->as_u16);
655   max_n_zeros = 0;
656   i_first_zero = i_max_n_zero;
657   n_zeros = 0;
658   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
659     {
660       u32 is_zero = a->as_u16[i] == 0;
661       if (is_zero && i_first_zero >= ARRAY_LEN (a->as_u16))
662         {
663           i_first_zero = i;
664           n_zeros = 0;
665         }
666       n_zeros += is_zero;
667       if ((!is_zero && n_zeros > max_n_zeros)
668           || (i + 1 >= ARRAY_LEN (a->as_u16) && n_zeros > max_n_zeros))
669         {
670           i_max_n_zero = i_first_zero;
671           max_n_zeros = n_zeros;
672           i_first_zero = ARRAY_LEN (a->as_u16);
673           n_zeros = 0;
674         }
675     }
676
677   last_double_colon = 0;
678   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
679     {
680       if (i == i_max_n_zero && max_n_zeros > 1)
681         {
682           s = format (s, "::");
683           i += max_n_zeros - 1;
684           last_double_colon = 1;
685         }
686       else
687         {
688           s = format (s, "%s%x",
689                       (last_double_colon || i == 0) ? "" : ":",
690                       clib_net_to_host_u16 (a->as_u16[i]));
691           last_double_colon = 0;
692         }
693     }
694
695   return s;
696 }
697
698 /* Format an IP46 address. */
699 u8 *
700 format_ip46_address (u8 * s, va_list * args)
701 {
702   ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
703   ip46_type_t type = va_arg (*args, ip46_type_t);
704   int is_ip4 = 1;
705
706   switch (type)
707     {
708     case IP46_TYPE_ANY:
709       is_ip4 = ip46_address_is_ip4 (ip46);
710       break;
711     case IP46_TYPE_IP4:
712       is_ip4 = 1;
713       break;
714     case IP46_TYPE_IP6:
715       is_ip4 = 0;
716       break;
717     }
718
719   return is_ip4 ?
720     format (s, "%U", format_ip4_address, &ip46->ip4) :
721     format (s, "%U", format_ip6_address, &ip46->ip6);
722 }
723
724 u8 *
725 format_ethernet_address (u8 * s, va_list * args)
726 {
727   u8 *a = va_arg (*args, u8 *);
728
729   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
730                  a[0], a[1], a[2], a[3], a[4], a[5]);
731 }
732 #endif
733
734 static void
735 increment_v4_address (vl_api_ip4_address_t * i)
736 {
737   ip4_address_t *a = (ip4_address_t *) i;
738   u32 v;
739
740   v = ntohl (a->as_u32) + 1;
741   a->as_u32 = ntohl (v);
742 }
743
744 static void
745 increment_v6_address (vl_api_ip6_address_t * i)
746 {
747   ip6_address_t *a = (ip6_address_t *) i;
748   u64 v0, v1;
749
750   v0 = clib_net_to_host_u64 (a->as_u64[0]);
751   v1 = clib_net_to_host_u64 (a->as_u64[1]);
752
753   v1 += 1;
754   if (v1 == 0)
755     v0 += 1;
756   a->as_u64[0] = clib_net_to_host_u64 (v0);
757   a->as_u64[1] = clib_net_to_host_u64 (v1);
758 }
759
760 static void
761 increment_address (vl_api_address_t * a)
762 {
763   if (a->af == ADDRESS_IP4)
764     increment_v4_address (&a->un.ip4);
765   else if (a->af == ADDRESS_IP6)
766     increment_v6_address (&a->un.ip6);
767 }
768
769 static void
770 set_ip4_address (vl_api_address_t * a, u32 v)
771 {
772   if (a->af == ADDRESS_IP4)
773     {
774       ip4_address_t *i = (ip4_address_t *) & a->un.ip4;
775       i->as_u32 = v;
776     }
777 }
778
779 void
780 ip_set (ip46_address_t * dst, void *src, u8 is_ip4)
781 {
782   if (is_ip4)
783     dst->ip4.as_u32 = ((ip4_address_t *) src)->as_u32;
784   else
785     clib_memcpy_fast (&dst->ip6, (ip6_address_t *) src,
786                       sizeof (ip6_address_t));
787 }
788
789 static void
790 increment_mac_address (u8 * mac)
791 {
792   u64 tmp = *((u64 *) mac);
793   tmp = clib_net_to_host_u64 (tmp);
794   tmp += 1 << 16;               /* skip unused (least significant) octets */
795   tmp = clib_host_to_net_u64 (tmp);
796
797   clib_memcpy (mac, &tmp, 6);
798 }
799
800 static void
801 vat_json_object_add_address (vat_json_node_t * node,
802                              const char *str, const vl_api_address_t * addr)
803 {
804   if (ADDRESS_IP6 == addr->af)
805     {
806       struct in6_addr ip6;
807
808       clib_memcpy (&ip6, &addr->un.ip6, sizeof (ip6));
809       vat_json_object_add_ip6 (node, str, ip6);
810     }
811   else
812     {
813       struct in_addr ip4;
814
815       clib_memcpy (&ip4, &addr->un.ip4, sizeof (ip4));
816       vat_json_object_add_ip4 (node, str, ip4);
817     }
818 }
819
820 static void
821 vat_json_object_add_prefix (vat_json_node_t * node,
822                             const vl_api_prefix_t * prefix)
823 {
824   vat_json_object_add_uint (node, "len", prefix->len);
825   vat_json_object_add_address (node, "address", &prefix->address);
826 }
827
828 static void vl_api_create_loopback_reply_t_handler
829   (vl_api_create_loopback_reply_t * mp)
830 {
831   vat_main_t *vam = &vat_main;
832   i32 retval = ntohl (mp->retval);
833
834   vam->retval = retval;
835   vam->regenerate_interface_table = 1;
836   vam->sw_if_index = ntohl (mp->sw_if_index);
837   vam->result_ready = 1;
838 }
839
840 static void vl_api_create_loopback_reply_t_handler_json
841   (vl_api_create_loopback_reply_t * mp)
842 {
843   vat_main_t *vam = &vat_main;
844   vat_json_node_t node;
845
846   vat_json_init_object (&node);
847   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
848   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
849
850   vat_json_print (vam->ofp, &node);
851   vat_json_free (&node);
852   vam->retval = ntohl (mp->retval);
853   vam->result_ready = 1;
854 }
855
856 static void vl_api_create_loopback_instance_reply_t_handler
857   (vl_api_create_loopback_instance_reply_t * mp)
858 {
859   vat_main_t *vam = &vat_main;
860   i32 retval = ntohl (mp->retval);
861
862   vam->retval = retval;
863   vam->regenerate_interface_table = 1;
864   vam->sw_if_index = ntohl (mp->sw_if_index);
865   vam->result_ready = 1;
866 }
867
868 static void vl_api_create_loopback_instance_reply_t_handler_json
869   (vl_api_create_loopback_instance_reply_t * mp)
870 {
871   vat_main_t *vam = &vat_main;
872   vat_json_node_t node;
873
874   vat_json_init_object (&node);
875   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
876   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
877
878   vat_json_print (vam->ofp, &node);
879   vat_json_free (&node);
880   vam->retval = ntohl (mp->retval);
881   vam->result_ready = 1;
882 }
883
884 static void vl_api_af_packet_create_reply_t_handler
885   (vl_api_af_packet_create_reply_t * mp)
886 {
887   vat_main_t *vam = &vat_main;
888   i32 retval = ntohl (mp->retval);
889
890   vam->retval = retval;
891   vam->regenerate_interface_table = 1;
892   vam->sw_if_index = ntohl (mp->sw_if_index);
893   vam->result_ready = 1;
894 }
895
896 static void vl_api_af_packet_create_reply_t_handler_json
897   (vl_api_af_packet_create_reply_t * mp)
898 {
899   vat_main_t *vam = &vat_main;
900   vat_json_node_t node;
901
902   vat_json_init_object (&node);
903   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
904   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
905
906   vat_json_print (vam->ofp, &node);
907   vat_json_free (&node);
908
909   vam->retval = ntohl (mp->retval);
910   vam->result_ready = 1;
911 }
912
913 static void vl_api_create_vlan_subif_reply_t_handler
914   (vl_api_create_vlan_subif_reply_t * mp)
915 {
916   vat_main_t *vam = &vat_main;
917   i32 retval = ntohl (mp->retval);
918
919   vam->retval = retval;
920   vam->regenerate_interface_table = 1;
921   vam->sw_if_index = ntohl (mp->sw_if_index);
922   vam->result_ready = 1;
923 }
924
925 static void vl_api_create_vlan_subif_reply_t_handler_json
926   (vl_api_create_vlan_subif_reply_t * mp)
927 {
928   vat_main_t *vam = &vat_main;
929   vat_json_node_t node;
930
931   vat_json_init_object (&node);
932   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
933   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
934
935   vat_json_print (vam->ofp, &node);
936   vat_json_free (&node);
937
938   vam->retval = ntohl (mp->retval);
939   vam->result_ready = 1;
940 }
941
942 static void vl_api_create_subif_reply_t_handler
943   (vl_api_create_subif_reply_t * mp)
944 {
945   vat_main_t *vam = &vat_main;
946   i32 retval = ntohl (mp->retval);
947
948   vam->retval = retval;
949   vam->regenerate_interface_table = 1;
950   vam->sw_if_index = ntohl (mp->sw_if_index);
951   vam->result_ready = 1;
952 }
953
954 static void vl_api_create_subif_reply_t_handler_json
955   (vl_api_create_subif_reply_t * mp)
956 {
957   vat_main_t *vam = &vat_main;
958   vat_json_node_t node;
959
960   vat_json_init_object (&node);
961   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
962   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
963
964   vat_json_print (vam->ofp, &node);
965   vat_json_free (&node);
966
967   vam->retval = ntohl (mp->retval);
968   vam->result_ready = 1;
969 }
970
971 static void vl_api_interface_name_renumber_reply_t_handler
972   (vl_api_interface_name_renumber_reply_t * mp)
973 {
974   vat_main_t *vam = &vat_main;
975   i32 retval = ntohl (mp->retval);
976
977   vam->retval = retval;
978   vam->regenerate_interface_table = 1;
979   vam->result_ready = 1;
980 }
981
982 static void vl_api_interface_name_renumber_reply_t_handler_json
983   (vl_api_interface_name_renumber_reply_t * mp)
984 {
985   vat_main_t *vam = &vat_main;
986   vat_json_node_t node;
987
988   vat_json_init_object (&node);
989   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
990
991   vat_json_print (vam->ofp, &node);
992   vat_json_free (&node);
993
994   vam->retval = ntohl (mp->retval);
995   vam->result_ready = 1;
996 }
997
998 /*
999  * Special-case: build the interface table, maintain
1000  * the next loopback sw_if_index vbl.
1001  */
1002 static void vl_api_sw_interface_details_t_handler
1003   (vl_api_sw_interface_details_t * mp)
1004 {
1005   vat_main_t *vam = &vat_main;
1006   u8 *s = format (0, "%s%c", mp->interface_name, 0);
1007
1008   hash_set_mem (vam->sw_if_index_by_interface_name, s,
1009                 ntohl (mp->sw_if_index));
1010
1011   /* In sub interface case, fill the sub interface table entry */
1012   if (mp->sw_if_index != mp->sup_sw_if_index)
1013     {
1014       sw_interface_subif_t *sub = NULL;
1015
1016       vec_add2 (vam->sw_if_subif_table, sub, 1);
1017
1018       vec_validate (sub->interface_name, strlen ((char *) s) + 1);
1019       strncpy ((char *) sub->interface_name, (char *) s,
1020                vec_len (sub->interface_name));
1021       sub->sw_if_index = ntohl (mp->sw_if_index);
1022       sub->sub_id = ntohl (mp->sub_id);
1023
1024       sub->raw_flags = ntohl (mp->sub_if_flags & SUB_IF_API_FLAG_MASK_VNET);
1025
1026       sub->sub_number_of_tags = mp->sub_number_of_tags;
1027       sub->sub_outer_vlan_id = ntohs (mp->sub_outer_vlan_id);
1028       sub->sub_inner_vlan_id = ntohs (mp->sub_inner_vlan_id);
1029
1030       /* vlan tag rewrite */
1031       sub->vtr_op = ntohl (mp->vtr_op);
1032       sub->vtr_push_dot1q = ntohl (mp->vtr_push_dot1q);
1033       sub->vtr_tag1 = ntohl (mp->vtr_tag1);
1034       sub->vtr_tag2 = ntohl (mp->vtr_tag2);
1035     }
1036 }
1037
1038 static void vl_api_sw_interface_details_t_handler_json
1039   (vl_api_sw_interface_details_t * mp)
1040 {
1041   vat_main_t *vam = &vat_main;
1042   vat_json_node_t *node = NULL;
1043
1044   if (VAT_JSON_ARRAY != vam->json_tree.type)
1045     {
1046       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1047       vat_json_init_array (&vam->json_tree);
1048     }
1049   node = vat_json_array_add (&vam->json_tree);
1050
1051   vat_json_init_object (node);
1052   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
1053   vat_json_object_add_uint (node, "sup_sw_if_index",
1054                             ntohl (mp->sup_sw_if_index));
1055   vat_json_object_add_bytes (node, "l2_address", mp->l2_address,
1056                              sizeof (mp->l2_address));
1057   vat_json_object_add_string_copy (node, "interface_name",
1058                                    mp->interface_name);
1059   vat_json_object_add_string_copy (node, "interface_dev_type",
1060                                    mp->interface_dev_type);
1061   vat_json_object_add_uint (node, "flags", mp->flags);
1062   vat_json_object_add_uint (node, "link_duplex", mp->link_duplex);
1063   vat_json_object_add_uint (node, "link_speed", mp->link_speed);
1064   vat_json_object_add_uint (node, "mtu", ntohs (mp->link_mtu));
1065   vat_json_object_add_uint (node, "sub_id", ntohl (mp->sub_id));
1066   vat_json_object_add_uint (node, "sub_number_of_tags",
1067                             mp->sub_number_of_tags);
1068   vat_json_object_add_uint (node, "sub_outer_vlan_id",
1069                             ntohs (mp->sub_outer_vlan_id));
1070   vat_json_object_add_uint (node, "sub_inner_vlan_id",
1071                             ntohs (mp->sub_inner_vlan_id));
1072   vat_json_object_add_uint (node, "sub_if_flags", ntohl (mp->sub_if_flags));
1073   vat_json_object_add_uint (node, "vtr_op", ntohl (mp->vtr_op));
1074   vat_json_object_add_uint (node, "vtr_push_dot1q",
1075                             ntohl (mp->vtr_push_dot1q));
1076   vat_json_object_add_uint (node, "vtr_tag1", ntohl (mp->vtr_tag1));
1077   vat_json_object_add_uint (node, "vtr_tag2", ntohl (mp->vtr_tag2));
1078   if (ntohl (mp->sub_if_flags) & SUB_IF_API_FLAG_DOT1AH)
1079     {
1080       vat_json_object_add_string_copy (node, "pbb_vtr_dmac",
1081                                        format (0, "%U",
1082                                                format_ethernet_address,
1083                                                &mp->b_dmac));
1084       vat_json_object_add_string_copy (node, "pbb_vtr_smac",
1085                                        format (0, "%U",
1086                                                format_ethernet_address,
1087                                                &mp->b_smac));
1088       vat_json_object_add_uint (node, "pbb_vtr_b_vlanid", mp->b_vlanid);
1089       vat_json_object_add_uint (node, "pbb_vtr_i_sid", mp->i_sid);
1090     }
1091 }
1092
1093 #if VPP_API_TEST_BUILTIN == 0
1094 static void vl_api_sw_interface_event_t_handler
1095   (vl_api_sw_interface_event_t * mp)
1096 {
1097   vat_main_t *vam = &vat_main;
1098   if (vam->interface_event_display)
1099     errmsg ("interface flags: sw_if_index %d %s %s",
1100             ntohl (mp->sw_if_index),
1101             ((ntohl (mp->flags)) & IF_STATUS_API_FLAG_ADMIN_UP) ?
1102             "admin-up" : "admin-down",
1103             ((ntohl (mp->flags)) & IF_STATUS_API_FLAG_LINK_UP) ?
1104             "link-up" : "link-down");
1105 }
1106 #endif
1107
1108 __clib_unused static void
1109 vl_api_sw_interface_event_t_handler_json (vl_api_sw_interface_event_t * mp)
1110 {
1111   /* JSON output not supported */
1112 }
1113
1114 static void
1115 vl_api_cli_reply_t_handler (vl_api_cli_reply_t * mp)
1116 {
1117   vat_main_t *vam = &vat_main;
1118   i32 retval = ntohl (mp->retval);
1119
1120   vam->retval = retval;
1121   vam->shmem_result = uword_to_pointer (mp->reply_in_shmem, u8 *);
1122   vam->result_ready = 1;
1123 }
1124
1125 static void
1126 vl_api_cli_reply_t_handler_json (vl_api_cli_reply_t * mp)
1127 {
1128   vat_main_t *vam = &vat_main;
1129   vat_json_node_t node;
1130   void *oldheap;
1131   u8 *reply;
1132
1133   vat_json_init_object (&node);
1134   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1135   vat_json_object_add_uint (&node, "reply_in_shmem",
1136                             ntohl (mp->reply_in_shmem));
1137   /* Toss the shared-memory original... */
1138   oldheap = vl_msg_push_heap ();
1139
1140   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
1141   vec_free (reply);
1142
1143   vl_msg_pop_heap (oldheap);
1144
1145   vat_json_print (vam->ofp, &node);
1146   vat_json_free (&node);
1147
1148   vam->retval = ntohl (mp->retval);
1149   vam->result_ready = 1;
1150 }
1151
1152 static void
1153 vl_api_cli_inband_reply_t_handler (vl_api_cli_inband_reply_t * mp)
1154 {
1155   vat_main_t *vam = &vat_main;
1156   i32 retval = ntohl (mp->retval);
1157
1158   vec_reset_length (vam->cmd_reply);
1159
1160   vam->retval = retval;
1161   if (retval == 0)
1162     vam->cmd_reply = vl_api_from_api_to_new_vec (mp, &mp->reply);
1163   vam->result_ready = 1;
1164 }
1165
1166 static void
1167 vl_api_cli_inband_reply_t_handler_json (vl_api_cli_inband_reply_t * mp)
1168 {
1169   vat_main_t *vam = &vat_main;
1170   vat_json_node_t node;
1171   u8 *reply = 0;                /* reply vector */
1172
1173   reply = vl_api_from_api_to_new_vec (mp, &mp->reply);
1174   vec_reset_length (vam->cmd_reply);
1175
1176   vat_json_init_object (&node);
1177   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1178   vat_json_object_add_string_copy (&node, "reply", reply);
1179
1180   vat_json_print (vam->ofp, &node);
1181   vat_json_free (&node);
1182   vec_free (reply);
1183
1184   vam->retval = ntohl (mp->retval);
1185   vam->result_ready = 1;
1186 }
1187
1188 static void vl_api_classify_add_del_table_reply_t_handler
1189   (vl_api_classify_add_del_table_reply_t * mp)
1190 {
1191   vat_main_t *vam = &vat_main;
1192   i32 retval = ntohl (mp->retval);
1193   if (vam->async_mode)
1194     {
1195       vam->async_errors += (retval < 0);
1196     }
1197   else
1198     {
1199       vam->retval = retval;
1200       if (retval == 0 &&
1201           ((mp->new_table_index != 0xFFFFFFFF) ||
1202            (mp->skip_n_vectors != 0xFFFFFFFF) ||
1203            (mp->match_n_vectors != 0xFFFFFFFF)))
1204         /*
1205          * Note: this is just barely thread-safe, depends on
1206          * the main thread spinning waiting for an answer...
1207          */
1208         errmsg ("new index %d, skip_n_vectors %d, match_n_vectors %d",
1209                 ntohl (mp->new_table_index),
1210                 ntohl (mp->skip_n_vectors), ntohl (mp->match_n_vectors));
1211       vam->result_ready = 1;
1212     }
1213 }
1214
1215 static void vl_api_classify_add_del_table_reply_t_handler_json
1216   (vl_api_classify_add_del_table_reply_t * mp)
1217 {
1218   vat_main_t *vam = &vat_main;
1219   vat_json_node_t node;
1220
1221   vat_json_init_object (&node);
1222   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1223   vat_json_object_add_uint (&node, "new_table_index",
1224                             ntohl (mp->new_table_index));
1225   vat_json_object_add_uint (&node, "skip_n_vectors",
1226                             ntohl (mp->skip_n_vectors));
1227   vat_json_object_add_uint (&node, "match_n_vectors",
1228                             ntohl (mp->match_n_vectors));
1229
1230   vat_json_print (vam->ofp, &node);
1231   vat_json_free (&node);
1232
1233   vam->retval = ntohl (mp->retval);
1234   vam->result_ready = 1;
1235 }
1236
1237 static void vl_api_get_node_index_reply_t_handler
1238   (vl_api_get_node_index_reply_t * mp)
1239 {
1240   vat_main_t *vam = &vat_main;
1241   i32 retval = ntohl (mp->retval);
1242   if (vam->async_mode)
1243     {
1244       vam->async_errors += (retval < 0);
1245     }
1246   else
1247     {
1248       vam->retval = retval;
1249       if (retval == 0)
1250         errmsg ("node index %d", ntohl (mp->node_index));
1251       vam->result_ready = 1;
1252     }
1253 }
1254
1255 static void vl_api_get_node_index_reply_t_handler_json
1256   (vl_api_get_node_index_reply_t * mp)
1257 {
1258   vat_main_t *vam = &vat_main;
1259   vat_json_node_t node;
1260
1261   vat_json_init_object (&node);
1262   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1263   vat_json_object_add_uint (&node, "node_index", ntohl (mp->node_index));
1264
1265   vat_json_print (vam->ofp, &node);
1266   vat_json_free (&node);
1267
1268   vam->retval = ntohl (mp->retval);
1269   vam->result_ready = 1;
1270 }
1271
1272 static void vl_api_get_next_index_reply_t_handler
1273   (vl_api_get_next_index_reply_t * mp)
1274 {
1275   vat_main_t *vam = &vat_main;
1276   i32 retval = ntohl (mp->retval);
1277   if (vam->async_mode)
1278     {
1279       vam->async_errors += (retval < 0);
1280     }
1281   else
1282     {
1283       vam->retval = retval;
1284       if (retval == 0)
1285         errmsg ("next node index %d", ntohl (mp->next_index));
1286       vam->result_ready = 1;
1287     }
1288 }
1289
1290 static void vl_api_get_next_index_reply_t_handler_json
1291   (vl_api_get_next_index_reply_t * mp)
1292 {
1293   vat_main_t *vam = &vat_main;
1294   vat_json_node_t node;
1295
1296   vat_json_init_object (&node);
1297   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1298   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1299
1300   vat_json_print (vam->ofp, &node);
1301   vat_json_free (&node);
1302
1303   vam->retval = ntohl (mp->retval);
1304   vam->result_ready = 1;
1305 }
1306
1307 static void vl_api_add_node_next_reply_t_handler
1308   (vl_api_add_node_next_reply_t * mp)
1309 {
1310   vat_main_t *vam = &vat_main;
1311   i32 retval = ntohl (mp->retval);
1312   if (vam->async_mode)
1313     {
1314       vam->async_errors += (retval < 0);
1315     }
1316   else
1317     {
1318       vam->retval = retval;
1319       if (retval == 0)
1320         errmsg ("next index %d", ntohl (mp->next_index));
1321       vam->result_ready = 1;
1322     }
1323 }
1324
1325 static void vl_api_add_node_next_reply_t_handler_json
1326   (vl_api_add_node_next_reply_t * mp)
1327 {
1328   vat_main_t *vam = &vat_main;
1329   vat_json_node_t node;
1330
1331   vat_json_init_object (&node);
1332   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1333   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1334
1335   vat_json_print (vam->ofp, &node);
1336   vat_json_free (&node);
1337
1338   vam->retval = ntohl (mp->retval);
1339   vam->result_ready = 1;
1340 }
1341
1342 static void vl_api_show_version_reply_t_handler
1343   (vl_api_show_version_reply_t * mp)
1344 {
1345   vat_main_t *vam = &vat_main;
1346   i32 retval = ntohl (mp->retval);
1347
1348   if (retval >= 0)
1349     {
1350       errmsg ("        program: %s", mp->program);
1351       errmsg ("        version: %s", mp->version);
1352       errmsg ("     build date: %s", mp->build_date);
1353       errmsg ("build directory: %s", mp->build_directory);
1354     }
1355   vam->retval = retval;
1356   vam->result_ready = 1;
1357 }
1358
1359 static void vl_api_show_version_reply_t_handler_json
1360   (vl_api_show_version_reply_t * mp)
1361 {
1362   vat_main_t *vam = &vat_main;
1363   vat_json_node_t node;
1364
1365   vat_json_init_object (&node);
1366   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1367   vat_json_object_add_string_copy (&node, "program", mp->program);
1368   vat_json_object_add_string_copy (&node, "version", mp->version);
1369   vat_json_object_add_string_copy (&node, "build_date", mp->build_date);
1370   vat_json_object_add_string_copy (&node, "build_directory",
1371                                    mp->build_directory);
1372
1373   vat_json_print (vam->ofp, &node);
1374   vat_json_free (&node);
1375
1376   vam->retval = ntohl (mp->retval);
1377   vam->result_ready = 1;
1378 }
1379
1380 static void vl_api_show_threads_reply_t_handler
1381   (vl_api_show_threads_reply_t * mp)
1382 {
1383   vat_main_t *vam = &vat_main;
1384   i32 retval = ntohl (mp->retval);
1385   int i, count = 0;
1386
1387   if (retval >= 0)
1388     count = ntohl (mp->count);
1389
1390   for (i = 0; i < count; i++)
1391     print (vam->ofp,
1392            "\n%-2d %-11s %-11s %-5d %-6d %-4d %-6d",
1393            ntohl (mp->thread_data[i].id), mp->thread_data[i].name,
1394            mp->thread_data[i].type, ntohl (mp->thread_data[i].pid),
1395            ntohl (mp->thread_data[i].cpu_id), ntohl (mp->thread_data[i].core),
1396            ntohl (mp->thread_data[i].cpu_socket));
1397
1398   vam->retval = retval;
1399   vam->result_ready = 1;
1400 }
1401
1402 static void vl_api_show_threads_reply_t_handler_json
1403   (vl_api_show_threads_reply_t * mp)
1404 {
1405   vat_main_t *vam = &vat_main;
1406   vat_json_node_t node;
1407   vl_api_thread_data_t *td;
1408   i32 retval = ntohl (mp->retval);
1409   int i, count = 0;
1410
1411   if (retval >= 0)
1412     count = ntohl (mp->count);
1413
1414   vat_json_init_object (&node);
1415   vat_json_object_add_int (&node, "retval", retval);
1416   vat_json_object_add_uint (&node, "count", count);
1417
1418   for (i = 0; i < count; i++)
1419     {
1420       td = &mp->thread_data[i];
1421       vat_json_object_add_uint (&node, "id", ntohl (td->id));
1422       vat_json_object_add_string_copy (&node, "name", td->name);
1423       vat_json_object_add_string_copy (&node, "type", td->type);
1424       vat_json_object_add_uint (&node, "pid", ntohl (td->pid));
1425       vat_json_object_add_int (&node, "cpu_id", ntohl (td->cpu_id));
1426       vat_json_object_add_int (&node, "core", ntohl (td->id));
1427       vat_json_object_add_int (&node, "cpu_socket", ntohl (td->cpu_socket));
1428     }
1429
1430   vat_json_print (vam->ofp, &node);
1431   vat_json_free (&node);
1432
1433   vam->retval = retval;
1434   vam->result_ready = 1;
1435 }
1436
1437 static int
1438 api_show_threads (vat_main_t * vam)
1439 {
1440   vl_api_show_threads_t *mp;
1441   int ret;
1442
1443   print (vam->ofp,
1444          "\n%-2s %-11s %-11s %-5s %-6s %-4s %-6s",
1445          "ID", "Name", "Type", "LWP", "cpu_id", "Core", "Socket");
1446
1447   M (SHOW_THREADS, mp);
1448
1449   S (mp);
1450   W (ret);
1451   return ret;
1452 }
1453
1454 static void
1455 vl_api_l2_macs_event_t_handler (vl_api_l2_macs_event_t * mp)
1456 {
1457   u32 n_macs = ntohl (mp->n_macs);
1458   errmsg ("L2MAC event received with pid %d cl-idx %d for %d macs: \n",
1459           ntohl (mp->pid), mp->client_index, n_macs);
1460   int i;
1461   for (i = 0; i < n_macs; i++)
1462     {
1463       vl_api_mac_entry_t *mac = &mp->mac[i];
1464       errmsg (" [%d] sw_if_index %d  mac_addr %U  action %d \n",
1465               i + 1, ntohl (mac->sw_if_index),
1466               format_ethernet_address, mac->mac_addr, mac->action);
1467       if (i == 1000)
1468         break;
1469     }
1470 }
1471
1472 static void
1473 vl_api_l2_macs_event_t_handler_json (vl_api_l2_macs_event_t * mp)
1474 {
1475   /* JSON output not supported */
1476 }
1477
1478 #define vl_api_bridge_domain_details_t_endian vl_noop_handler
1479 #define vl_api_bridge_domain_details_t_print vl_noop_handler
1480
1481 /*
1482  * Special-case: build the bridge domain table, maintain
1483  * the next bd id vbl.
1484  */
1485 static void vl_api_bridge_domain_details_t_handler
1486   (vl_api_bridge_domain_details_t * mp)
1487 {
1488   vat_main_t *vam = &vat_main;
1489   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1490   int i;
1491
1492   print (vam->ofp, "\n%-3s %-3s %-3s %-3s %-3s %-6s %-3s",
1493          " ID", "LRN", "FWD", "FLD", "BVI", "UU-FWD", "#IF");
1494
1495   print (vam->ofp, "%3d %3d %3d %3d %3d %6d %3d",
1496          ntohl (mp->bd_id), mp->learn, mp->forward,
1497          mp->flood, ntohl (mp->bvi_sw_if_index),
1498          ntohl (mp->uu_fwd_sw_if_index), n_sw_ifs);
1499
1500   if (n_sw_ifs)
1501     {
1502       vl_api_bridge_domain_sw_if_t *sw_ifs;
1503       print (vam->ofp, "\n\n%s %s  %s", "sw_if_index", "SHG",
1504              "Interface Name");
1505
1506       sw_ifs = mp->sw_if_details;
1507       for (i = 0; i < n_sw_ifs; i++)
1508         {
1509           u8 *sw_if_name = 0;
1510           u32 sw_if_index;
1511           hash_pair_t *p;
1512
1513           sw_if_index = ntohl (sw_ifs->sw_if_index);
1514
1515           /* *INDENT-OFF* */
1516           hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
1517                              ({
1518                                if ((u32) p->value[0] == sw_if_index)
1519                                  {
1520                                    sw_if_name = (u8 *)(p->key);
1521                                    break;
1522                                  }
1523                              }));
1524           /* *INDENT-ON* */
1525           print (vam->ofp, "%7d     %3d  %s", sw_if_index,
1526                  sw_ifs->shg, sw_if_name ? (char *) sw_if_name :
1527                  "sw_if_index not found!");
1528
1529           sw_ifs++;
1530         }
1531     }
1532 }
1533
1534 static void vl_api_bridge_domain_details_t_handler_json
1535   (vl_api_bridge_domain_details_t * mp)
1536 {
1537   vat_main_t *vam = &vat_main;
1538   vat_json_node_t *node, *array = NULL;
1539   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1540
1541   if (VAT_JSON_ARRAY != vam->json_tree.type)
1542     {
1543       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1544       vat_json_init_array (&vam->json_tree);
1545     }
1546   node = vat_json_array_add (&vam->json_tree);
1547
1548   vat_json_init_object (node);
1549   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1550   vat_json_object_add_uint (node, "flood", mp->flood);
1551   vat_json_object_add_uint (node, "forward", mp->forward);
1552   vat_json_object_add_uint (node, "learn", mp->learn);
1553   vat_json_object_add_uint (node, "bvi_sw_if_index",
1554                             ntohl (mp->bvi_sw_if_index));
1555   vat_json_object_add_uint (node, "n_sw_ifs", n_sw_ifs);
1556   array = vat_json_object_add (node, "sw_if");
1557   vat_json_init_array (array);
1558
1559
1560
1561   if (n_sw_ifs)
1562     {
1563       vl_api_bridge_domain_sw_if_t *sw_ifs;
1564       int i;
1565
1566       sw_ifs = mp->sw_if_details;
1567       for (i = 0; i < n_sw_ifs; i++)
1568         {
1569           node = vat_json_array_add (array);
1570           vat_json_init_object (node);
1571           vat_json_object_add_uint (node, "sw_if_index",
1572                                     ntohl (sw_ifs->sw_if_index));
1573           vat_json_object_add_uint (node, "shg", sw_ifs->shg);
1574           sw_ifs++;
1575         }
1576     }
1577 }
1578
1579 static void vl_api_control_ping_reply_t_handler
1580   (vl_api_control_ping_reply_t * mp)
1581 {
1582   vat_main_t *vam = &vat_main;
1583   i32 retval = ntohl (mp->retval);
1584   if (vam->async_mode)
1585     {
1586       vam->async_errors += (retval < 0);
1587     }
1588   else
1589     {
1590       vam->retval = retval;
1591       vam->result_ready = 1;
1592     }
1593   if (vam->socket_client_main)
1594     vam->socket_client_main->control_pings_outstanding--;
1595 }
1596
1597 static void vl_api_control_ping_reply_t_handler_json
1598   (vl_api_control_ping_reply_t * mp)
1599 {
1600   vat_main_t *vam = &vat_main;
1601   i32 retval = ntohl (mp->retval);
1602
1603   if (VAT_JSON_NONE != vam->json_tree.type)
1604     {
1605       vat_json_print (vam->ofp, &vam->json_tree);
1606       vat_json_free (&vam->json_tree);
1607       vam->json_tree.type = VAT_JSON_NONE;
1608     }
1609   else
1610     {
1611       /* just print [] */
1612       vat_json_init_array (&vam->json_tree);
1613       vat_json_print (vam->ofp, &vam->json_tree);
1614       vam->json_tree.type = VAT_JSON_NONE;
1615     }
1616
1617   vam->retval = retval;
1618   vam->result_ready = 1;
1619 }
1620
1621 static void
1622   vl_api_bridge_domain_set_mac_age_reply_t_handler
1623   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1624 {
1625   vat_main_t *vam = &vat_main;
1626   i32 retval = ntohl (mp->retval);
1627   if (vam->async_mode)
1628     {
1629       vam->async_errors += (retval < 0);
1630     }
1631   else
1632     {
1633       vam->retval = retval;
1634       vam->result_ready = 1;
1635     }
1636 }
1637
1638 static void vl_api_bridge_domain_set_mac_age_reply_t_handler_json
1639   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1640 {
1641   vat_main_t *vam = &vat_main;
1642   vat_json_node_t node;
1643
1644   vat_json_init_object (&node);
1645   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1646
1647   vat_json_print (vam->ofp, &node);
1648   vat_json_free (&node);
1649
1650   vam->retval = ntohl (mp->retval);
1651   vam->result_ready = 1;
1652 }
1653
1654 static void
1655 vl_api_l2_flags_reply_t_handler (vl_api_l2_flags_reply_t * mp)
1656 {
1657   vat_main_t *vam = &vat_main;
1658   i32 retval = ntohl (mp->retval);
1659   if (vam->async_mode)
1660     {
1661       vam->async_errors += (retval < 0);
1662     }
1663   else
1664     {
1665       vam->retval = retval;
1666       vam->result_ready = 1;
1667     }
1668 }
1669
1670 static void vl_api_l2_flags_reply_t_handler_json
1671   (vl_api_l2_flags_reply_t * mp)
1672 {
1673   vat_main_t *vam = &vat_main;
1674   vat_json_node_t node;
1675
1676   vat_json_init_object (&node);
1677   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1678   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1679                             ntohl (mp->resulting_feature_bitmap));
1680
1681   vat_json_print (vam->ofp, &node);
1682   vat_json_free (&node);
1683
1684   vam->retval = ntohl (mp->retval);
1685   vam->result_ready = 1;
1686 }
1687
1688 static void vl_api_bridge_flags_reply_t_handler
1689   (vl_api_bridge_flags_reply_t * mp)
1690 {
1691   vat_main_t *vam = &vat_main;
1692   i32 retval = ntohl (mp->retval);
1693   if (vam->async_mode)
1694     {
1695       vam->async_errors += (retval < 0);
1696     }
1697   else
1698     {
1699       vam->retval = retval;
1700       vam->result_ready = 1;
1701     }
1702 }
1703
1704 static void vl_api_bridge_flags_reply_t_handler_json
1705   (vl_api_bridge_flags_reply_t * mp)
1706 {
1707   vat_main_t *vam = &vat_main;
1708   vat_json_node_t node;
1709
1710   vat_json_init_object (&node);
1711   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1712   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1713                             ntohl (mp->resulting_feature_bitmap));
1714
1715   vat_json_print (vam->ofp, &node);
1716   vat_json_free (&node);
1717
1718   vam->retval = ntohl (mp->retval);
1719   vam->result_ready = 1;
1720 }
1721
1722 static void
1723 vl_api_tap_create_v2_reply_t_handler (vl_api_tap_create_v2_reply_t * mp)
1724 {
1725   vat_main_t *vam = &vat_main;
1726   i32 retval = ntohl (mp->retval);
1727   if (vam->async_mode)
1728     {
1729       vam->async_errors += (retval < 0);
1730     }
1731   else
1732     {
1733       vam->retval = retval;
1734       vam->sw_if_index = ntohl (mp->sw_if_index);
1735       vam->result_ready = 1;
1736     }
1737
1738 }
1739
1740 static void vl_api_tap_create_v2_reply_t_handler_json
1741   (vl_api_tap_create_v2_reply_t * mp)
1742 {
1743   vat_main_t *vam = &vat_main;
1744   vat_json_node_t node;
1745
1746   vat_json_init_object (&node);
1747   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1748   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1749
1750   vat_json_print (vam->ofp, &node);
1751   vat_json_free (&node);
1752
1753   vam->retval = ntohl (mp->retval);
1754   vam->result_ready = 1;
1755
1756 }
1757
1758 static void
1759 vl_api_tap_delete_v2_reply_t_handler (vl_api_tap_delete_v2_reply_t * mp)
1760 {
1761   vat_main_t *vam = &vat_main;
1762   i32 retval = ntohl (mp->retval);
1763   if (vam->async_mode)
1764     {
1765       vam->async_errors += (retval < 0);
1766     }
1767   else
1768     {
1769       vam->retval = retval;
1770       vam->result_ready = 1;
1771     }
1772 }
1773
1774 static void vl_api_tap_delete_v2_reply_t_handler_json
1775   (vl_api_tap_delete_v2_reply_t * mp)
1776 {
1777   vat_main_t *vam = &vat_main;
1778   vat_json_node_t node;
1779
1780   vat_json_init_object (&node);
1781   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1782
1783   vat_json_print (vam->ofp, &node);
1784   vat_json_free (&node);
1785
1786   vam->retval = ntohl (mp->retval);
1787   vam->result_ready = 1;
1788 }
1789
1790 static void
1791 vl_api_virtio_pci_create_reply_t_handler (vl_api_virtio_pci_create_reply_t *
1792                                           mp)
1793 {
1794   vat_main_t *vam = &vat_main;
1795   i32 retval = ntohl (mp->retval);
1796   if (vam->async_mode)
1797     {
1798       vam->async_errors += (retval < 0);
1799     }
1800   else
1801     {
1802       vam->retval = retval;
1803       vam->sw_if_index = ntohl (mp->sw_if_index);
1804       vam->result_ready = 1;
1805     }
1806 }
1807
1808 static void vl_api_virtio_pci_create_reply_t_handler_json
1809   (vl_api_virtio_pci_create_reply_t * mp)
1810 {
1811   vat_main_t *vam = &vat_main;
1812   vat_json_node_t node;
1813
1814   vat_json_init_object (&node);
1815   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1816   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1817
1818   vat_json_print (vam->ofp, &node);
1819   vat_json_free (&node);
1820
1821   vam->retval = ntohl (mp->retval);
1822   vam->result_ready = 1;
1823
1824 }
1825
1826 static void
1827   vl_api_virtio_pci_create_v2_reply_t_handler
1828   (vl_api_virtio_pci_create_v2_reply_t * mp)
1829 {
1830   vat_main_t *vam = &vat_main;
1831   i32 retval = ntohl (mp->retval);
1832   if (vam->async_mode)
1833     {
1834       vam->async_errors += (retval < 0);
1835     }
1836   else
1837     {
1838       vam->retval = retval;
1839       vam->sw_if_index = ntohl (mp->sw_if_index);
1840       vam->result_ready = 1;
1841     }
1842 }
1843
1844 static void vl_api_virtio_pci_create_v2_reply_t_handler_json
1845   (vl_api_virtio_pci_create_v2_reply_t * mp)
1846 {
1847   vat_main_t *vam = &vat_main;
1848   vat_json_node_t node;
1849
1850   vat_json_init_object (&node);
1851   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1852   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1853
1854   vat_json_print (vam->ofp, &node);
1855   vat_json_free (&node);
1856
1857   vam->retval = ntohl (mp->retval);
1858   vam->result_ready = 1;
1859 }
1860
1861 static void
1862 vl_api_virtio_pci_delete_reply_t_handler (vl_api_virtio_pci_delete_reply_t *
1863                                           mp)
1864 {
1865   vat_main_t *vam = &vat_main;
1866   i32 retval = ntohl (mp->retval);
1867   if (vam->async_mode)
1868     {
1869       vam->async_errors += (retval < 0);
1870     }
1871   else
1872     {
1873       vam->retval = retval;
1874       vam->result_ready = 1;
1875     }
1876 }
1877
1878 static void vl_api_virtio_pci_delete_reply_t_handler_json
1879   (vl_api_virtio_pci_delete_reply_t * mp)
1880 {
1881   vat_main_t *vam = &vat_main;
1882   vat_json_node_t node;
1883
1884   vat_json_init_object (&node);
1885   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1886
1887   vat_json_print (vam->ofp, &node);
1888   vat_json_free (&node);
1889
1890   vam->retval = ntohl (mp->retval);
1891   vam->result_ready = 1;
1892 }
1893
1894 static void
1895 vl_api_bond_create_reply_t_handler (vl_api_bond_create_reply_t * mp)
1896 {
1897   vat_main_t *vam = &vat_main;
1898   i32 retval = ntohl (mp->retval);
1899
1900   if (vam->async_mode)
1901     {
1902       vam->async_errors += (retval < 0);
1903     }
1904   else
1905     {
1906       vam->retval = retval;
1907       vam->sw_if_index = ntohl (mp->sw_if_index);
1908       vam->result_ready = 1;
1909     }
1910 }
1911
1912 static void vl_api_bond_create_reply_t_handler_json
1913   (vl_api_bond_create_reply_t * mp)
1914 {
1915   vat_main_t *vam = &vat_main;
1916   vat_json_node_t node;
1917
1918   vat_json_init_object (&node);
1919   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1920   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1921
1922   vat_json_print (vam->ofp, &node);
1923   vat_json_free (&node);
1924
1925   vam->retval = ntohl (mp->retval);
1926   vam->result_ready = 1;
1927 }
1928
1929 static void
1930 vl_api_bond_create2_reply_t_handler (vl_api_bond_create2_reply_t * mp)
1931 {
1932   vat_main_t *vam = &vat_main;
1933   i32 retval = ntohl (mp->retval);
1934
1935   if (vam->async_mode)
1936     {
1937       vam->async_errors += (retval < 0);
1938     }
1939   else
1940     {
1941       vam->retval = retval;
1942       vam->sw_if_index = ntohl (mp->sw_if_index);
1943       vam->result_ready = 1;
1944     }
1945 }
1946
1947 static void vl_api_bond_create2_reply_t_handler_json
1948   (vl_api_bond_create2_reply_t * mp)
1949 {
1950   vat_main_t *vam = &vat_main;
1951   vat_json_node_t node;
1952
1953   vat_json_init_object (&node);
1954   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1955   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1956
1957   vat_json_print (vam->ofp, &node);
1958   vat_json_free (&node);
1959
1960   vam->retval = ntohl (mp->retval);
1961   vam->result_ready = 1;
1962 }
1963
1964 static void
1965 vl_api_bond_delete_reply_t_handler (vl_api_bond_delete_reply_t * mp)
1966 {
1967   vat_main_t *vam = &vat_main;
1968   i32 retval = ntohl (mp->retval);
1969
1970   if (vam->async_mode)
1971     {
1972       vam->async_errors += (retval < 0);
1973     }
1974   else
1975     {
1976       vam->retval = retval;
1977       vam->result_ready = 1;
1978     }
1979 }
1980
1981 static void vl_api_bond_delete_reply_t_handler_json
1982   (vl_api_bond_delete_reply_t * mp)
1983 {
1984   vat_main_t *vam = &vat_main;
1985   vat_json_node_t node;
1986
1987   vat_json_init_object (&node);
1988   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1989
1990   vat_json_print (vam->ofp, &node);
1991   vat_json_free (&node);
1992
1993   vam->retval = ntohl (mp->retval);
1994   vam->result_ready = 1;
1995 }
1996
1997 static void
1998 vl_api_bond_add_member_reply_t_handler (vl_api_bond_add_member_reply_t * mp)
1999 {
2000   vat_main_t *vam = &vat_main;
2001   i32 retval = ntohl (mp->retval);
2002
2003   if (vam->async_mode)
2004     {
2005       vam->async_errors += (retval < 0);
2006     }
2007   else
2008     {
2009       vam->retval = retval;
2010       vam->result_ready = 1;
2011     }
2012 }
2013
2014 static void vl_api_bond_add_member_reply_t_handler_json
2015   (vl_api_bond_add_member_reply_t * mp)
2016 {
2017   vat_main_t *vam = &vat_main;
2018   vat_json_node_t node;
2019
2020   vat_json_init_object (&node);
2021   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2022
2023   vat_json_print (vam->ofp, &node);
2024   vat_json_free (&node);
2025
2026   vam->retval = ntohl (mp->retval);
2027   vam->result_ready = 1;
2028 }
2029
2030 static void
2031 vl_api_bond_detach_member_reply_t_handler (vl_api_bond_detach_member_reply_t *
2032                                            mp)
2033 {
2034   vat_main_t *vam = &vat_main;
2035   i32 retval = ntohl (mp->retval);
2036
2037   if (vam->async_mode)
2038     {
2039       vam->async_errors += (retval < 0);
2040     }
2041   else
2042     {
2043       vam->retval = retval;
2044       vam->result_ready = 1;
2045     }
2046 }
2047
2048 static void vl_api_bond_detach_member_reply_t_handler_json
2049   (vl_api_bond_detach_member_reply_t * mp)
2050 {
2051   vat_main_t *vam = &vat_main;
2052   vat_json_node_t node;
2053
2054   vat_json_init_object (&node);
2055   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2056
2057   vat_json_print (vam->ofp, &node);
2058   vat_json_free (&node);
2059
2060   vam->retval = ntohl (mp->retval);
2061   vam->result_ready = 1;
2062 }
2063
2064 static int
2065 api_sw_interface_set_bond_weight (vat_main_t * vam)
2066 {
2067   unformat_input_t *i = vam->input;
2068   vl_api_sw_interface_set_bond_weight_t *mp;
2069   u32 sw_if_index = ~0;
2070   u32 weight = 0;
2071   u8 weight_enter = 0;
2072   int ret;
2073
2074   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2075     {
2076       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
2077         ;
2078       else if (unformat (i, "sw_if_index %d", &sw_if_index))
2079         ;
2080       else if (unformat (i, "weight %u", &weight))
2081         weight_enter = 1;
2082       else
2083         break;
2084     }
2085
2086   if (sw_if_index == ~0)
2087     {
2088       errmsg ("missing interface name or sw_if_index");
2089       return -99;
2090     }
2091   if (weight_enter == 0)
2092     {
2093       errmsg ("missing valid weight");
2094       return -99;
2095     }
2096
2097   /* Construct the API message */
2098   M (SW_INTERFACE_SET_BOND_WEIGHT, mp);
2099   mp->sw_if_index = ntohl (sw_if_index);
2100   mp->weight = ntohl (weight);
2101
2102   S (mp);
2103   W (ret);
2104   return ret;
2105 }
2106
2107 static void vl_api_sw_bond_interface_details_t_handler
2108   (vl_api_sw_bond_interface_details_t * mp)
2109 {
2110   vat_main_t *vam = &vat_main;
2111
2112   print (vam->ofp,
2113          "%-16s %-12d %-12U %-13U %-14u %-14u",
2114          mp->interface_name, ntohl (mp->sw_if_index),
2115          format_bond_mode, ntohl (mp->mode), format_bond_load_balance,
2116          ntohl (mp->lb), ntohl (mp->active_members), ntohl (mp->members));
2117 }
2118
2119 static void vl_api_sw_bond_interface_details_t_handler_json
2120   (vl_api_sw_bond_interface_details_t * mp)
2121 {
2122   vat_main_t *vam = &vat_main;
2123   vat_json_node_t *node = NULL;
2124
2125   if (VAT_JSON_ARRAY != vam->json_tree.type)
2126     {
2127       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2128       vat_json_init_array (&vam->json_tree);
2129     }
2130   node = vat_json_array_add (&vam->json_tree);
2131
2132   vat_json_init_object (node);
2133   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
2134   vat_json_object_add_string_copy (node, "interface_name",
2135                                    mp->interface_name);
2136   vat_json_object_add_uint (node, "mode", ntohl (mp->mode));
2137   vat_json_object_add_uint (node, "load_balance", ntohl (mp->lb));
2138   vat_json_object_add_uint (node, "active_members",
2139                             ntohl (mp->active_members));
2140   vat_json_object_add_uint (node, "members", ntohl (mp->members));
2141 }
2142
2143 static int
2144 api_sw_bond_interface_dump (vat_main_t * vam)
2145 {
2146   unformat_input_t *i = vam->input;
2147   vl_api_sw_bond_interface_dump_t *mp;
2148   vl_api_control_ping_t *mp_ping;
2149   int ret;
2150   u32 sw_if_index = ~0;
2151
2152   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2153     {
2154       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
2155         ;
2156       else if (unformat (i, "sw_if_index %d", &sw_if_index))
2157         ;
2158       else
2159         break;
2160     }
2161
2162   print (vam->ofp,
2163          "\n%-16s %-12s %-12s %-13s %-14s %-14s",
2164          "interface name", "sw_if_index", "mode", "load balance",
2165          "active members", "members");
2166
2167   /* Get list of bond interfaces */
2168   M (SW_BOND_INTERFACE_DUMP, mp);
2169   mp->sw_if_index = ntohl (sw_if_index);
2170   S (mp);
2171
2172   /* Use a control ping for synchronization */
2173   MPING (CONTROL_PING, mp_ping);
2174   S (mp_ping);
2175
2176   W (ret);
2177   return ret;
2178 }
2179
2180 static void vl_api_sw_member_interface_details_t_handler
2181   (vl_api_sw_member_interface_details_t * mp)
2182 {
2183   vat_main_t *vam = &vat_main;
2184
2185   print (vam->ofp,
2186          "%-25s %-12d %-7d %-12d %-10d %-10d", mp->interface_name,
2187          ntohl (mp->sw_if_index), mp->is_passive, mp->is_long_timeout,
2188          ntohl (mp->weight), mp->is_local_numa);
2189 }
2190
2191 static void vl_api_sw_member_interface_details_t_handler_json
2192   (vl_api_sw_member_interface_details_t * mp)
2193 {
2194   vat_main_t *vam = &vat_main;
2195   vat_json_node_t *node = NULL;
2196
2197   if (VAT_JSON_ARRAY != vam->json_tree.type)
2198     {
2199       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2200       vat_json_init_array (&vam->json_tree);
2201     }
2202   node = vat_json_array_add (&vam->json_tree);
2203
2204   vat_json_init_object (node);
2205   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
2206   vat_json_object_add_string_copy (node, "interface_name",
2207                                    mp->interface_name);
2208   vat_json_object_add_uint (node, "passive", mp->is_passive);
2209   vat_json_object_add_uint (node, "long_timeout", mp->is_long_timeout);
2210   vat_json_object_add_uint (node, "weight", ntohl (mp->weight));
2211   vat_json_object_add_uint (node, "is_local_numa", mp->is_local_numa);
2212 }
2213
2214 static int
2215 api_sw_member_interface_dump (vat_main_t * vam)
2216 {
2217   unformat_input_t *i = vam->input;
2218   vl_api_sw_member_interface_dump_t *mp;
2219   vl_api_control_ping_t *mp_ping;
2220   u32 sw_if_index = ~0;
2221   u8 sw_if_index_set = 0;
2222   int ret;
2223
2224   /* Parse args required to build the message */
2225   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2226     {
2227       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
2228         sw_if_index_set = 1;
2229       else if (unformat (i, "sw_if_index %d", &sw_if_index))
2230         sw_if_index_set = 1;
2231       else
2232         break;
2233     }
2234
2235   if (sw_if_index_set == 0)
2236     {
2237       errmsg ("missing vpp interface name. ");
2238       return -99;
2239     }
2240
2241   print (vam->ofp,
2242          "\n%-25s %-12s %-7s %-12s %-10s %-10s",
2243          "member interface name", "sw_if_index", "passive", "long_timeout",
2244          "weight", "local numa");
2245
2246   /* Get list of bond interfaces */
2247   M (SW_MEMBER_INTERFACE_DUMP, mp);
2248   mp->sw_if_index = ntohl (sw_if_index);
2249   S (mp);
2250
2251   /* Use a control ping for synchronization */
2252   MPING (CONTROL_PING, mp_ping);
2253   S (mp_ping);
2254
2255   W (ret);
2256   return ret;
2257 }
2258
2259 static void vl_api_mpls_tunnel_add_del_reply_t_handler
2260   (vl_api_mpls_tunnel_add_del_reply_t * mp)
2261 {
2262   vat_main_t *vam = &vat_main;
2263   i32 retval = ntohl (mp->retval);
2264   if (vam->async_mode)
2265     {
2266       vam->async_errors += (retval < 0);
2267     }
2268   else
2269     {
2270       vam->retval = retval;
2271       vam->sw_if_index = ntohl (mp->sw_if_index);
2272       vam->result_ready = 1;
2273     }
2274   vam->regenerate_interface_table = 1;
2275 }
2276
2277 static void vl_api_mpls_tunnel_add_del_reply_t_handler_json
2278   (vl_api_mpls_tunnel_add_del_reply_t * mp)
2279 {
2280   vat_main_t *vam = &vat_main;
2281   vat_json_node_t node;
2282
2283   vat_json_init_object (&node);
2284   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2285   vat_json_object_add_uint (&node, "tunnel_sw_if_index",
2286                             ntohl (mp->sw_if_index));
2287
2288   vat_json_print (vam->ofp, &node);
2289   vat_json_free (&node);
2290
2291   vam->retval = ntohl (mp->retval);
2292   vam->result_ready = 1;
2293 }
2294
2295 static void vl_api_vxlan_add_del_tunnel_reply_t_handler
2296   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
2297 {
2298   vat_main_t *vam = &vat_main;
2299   i32 retval = ntohl (mp->retval);
2300   if (vam->async_mode)
2301     {
2302       vam->async_errors += (retval < 0);
2303     }
2304   else
2305     {
2306       vam->retval = retval;
2307       vam->sw_if_index = ntohl (mp->sw_if_index);
2308       vam->result_ready = 1;
2309     }
2310   vam->regenerate_interface_table = 1;
2311 }
2312
2313 static void vl_api_vxlan_add_del_tunnel_reply_t_handler_json
2314   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
2315 {
2316   vat_main_t *vam = &vat_main;
2317   vat_json_node_t node;
2318
2319   vat_json_init_object (&node);
2320   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2321   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2322
2323   vat_json_print (vam->ofp, &node);
2324   vat_json_free (&node);
2325
2326   vam->retval = ntohl (mp->retval);
2327   vam->result_ready = 1;
2328 }
2329
2330 static void vl_api_vxlan_offload_rx_reply_t_handler
2331   (vl_api_vxlan_offload_rx_reply_t * mp)
2332 {
2333   vat_main_t *vam = &vat_main;
2334   i32 retval = ntohl (mp->retval);
2335   if (vam->async_mode)
2336     {
2337       vam->async_errors += (retval < 0);
2338     }
2339   else
2340     {
2341       vam->retval = retval;
2342       vam->result_ready = 1;
2343     }
2344 }
2345
2346 static void vl_api_vxlan_offload_rx_reply_t_handler_json
2347   (vl_api_vxlan_offload_rx_reply_t * mp)
2348 {
2349   vat_main_t *vam = &vat_main;
2350   vat_json_node_t node;
2351
2352   vat_json_init_object (&node);
2353   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2354
2355   vat_json_print (vam->ofp, &node);
2356   vat_json_free (&node);
2357
2358   vam->retval = ntohl (mp->retval);
2359   vam->result_ready = 1;
2360 }
2361
2362 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler
2363   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
2364 {
2365   vat_main_t *vam = &vat_main;
2366   i32 retval = ntohl (mp->retval);
2367   if (vam->async_mode)
2368     {
2369       vam->async_errors += (retval < 0);
2370     }
2371   else
2372     {
2373       vam->retval = retval;
2374       vam->sw_if_index = ntohl (mp->sw_if_index);
2375       vam->result_ready = 1;
2376     }
2377   vam->regenerate_interface_table = 1;
2378 }
2379
2380 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler_json
2381   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
2382 {
2383   vat_main_t *vam = &vat_main;
2384   vat_json_node_t node;
2385
2386   vat_json_init_object (&node);
2387   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2388   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2389
2390   vat_json_print (vam->ofp, &node);
2391   vat_json_free (&node);
2392
2393   vam->retval = ntohl (mp->retval);
2394   vam->result_ready = 1;
2395 }
2396
2397 static void vl_api_create_vhost_user_if_reply_t_handler
2398   (vl_api_create_vhost_user_if_reply_t * mp)
2399 {
2400   vat_main_t *vam = &vat_main;
2401   i32 retval = ntohl (mp->retval);
2402   if (vam->async_mode)
2403     {
2404       vam->async_errors += (retval < 0);
2405     }
2406   else
2407     {
2408       vam->retval = retval;
2409       vam->sw_if_index = ntohl (mp->sw_if_index);
2410       vam->result_ready = 1;
2411     }
2412   vam->regenerate_interface_table = 1;
2413 }
2414
2415 static void vl_api_create_vhost_user_if_reply_t_handler_json
2416   (vl_api_create_vhost_user_if_reply_t * mp)
2417 {
2418   vat_main_t *vam = &vat_main;
2419   vat_json_node_t node;
2420
2421   vat_json_init_object (&node);
2422   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2423   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2424
2425   vat_json_print (vam->ofp, &node);
2426   vat_json_free (&node);
2427
2428   vam->retval = ntohl (mp->retval);
2429   vam->result_ready = 1;
2430 }
2431
2432 static void vl_api_create_vhost_user_if_v2_reply_t_handler
2433   (vl_api_create_vhost_user_if_v2_reply_t * mp)
2434 {
2435   vat_main_t *vam = &vat_main;
2436   i32 retval = ntohl (mp->retval);
2437   if (vam->async_mode)
2438     {
2439       vam->async_errors += (retval < 0);
2440     }
2441   else
2442     {
2443       vam->retval = retval;
2444       vam->sw_if_index = ntohl (mp->sw_if_index);
2445       vam->result_ready = 1;
2446     }
2447   vam->regenerate_interface_table = 1;
2448 }
2449
2450 static void vl_api_create_vhost_user_if_v2_reply_t_handler_json
2451   (vl_api_create_vhost_user_if_v2_reply_t * mp)
2452 {
2453   vat_main_t *vam = &vat_main;
2454   vat_json_node_t node;
2455
2456   vat_json_init_object (&node);
2457   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2458   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2459
2460   vat_json_print (vam->ofp, &node);
2461   vat_json_free (&node);
2462
2463   vam->retval = ntohl (mp->retval);
2464   vam->result_ready = 1;
2465 }
2466
2467 static void vl_api_ip_address_details_t_handler
2468   (vl_api_ip_address_details_t * mp)
2469 {
2470   vat_main_t *vam = &vat_main;
2471   static ip_address_details_t empty_ip_address_details = { {0} };
2472   ip_address_details_t *address = NULL;
2473   ip_details_t *current_ip_details = NULL;
2474   ip_details_t *details = NULL;
2475
2476   details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
2477
2478   if (!details || vam->current_sw_if_index >= vec_len (details)
2479       || !details[vam->current_sw_if_index].present)
2480     {
2481       errmsg ("ip address details arrived but not stored");
2482       errmsg ("ip_dump should be called first");
2483       return;
2484     }
2485
2486   current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
2487
2488 #define addresses (current_ip_details->addr)
2489
2490   vec_validate_init_empty (addresses, vec_len (addresses),
2491                            empty_ip_address_details);
2492
2493   address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
2494
2495   clib_memcpy (&address->ip, &mp->prefix.address.un, sizeof (address->ip));
2496   address->prefix_length = mp->prefix.len;
2497 #undef addresses
2498 }
2499
2500 static void vl_api_ip_address_details_t_handler_json
2501   (vl_api_ip_address_details_t * mp)
2502 {
2503   vat_main_t *vam = &vat_main;
2504   vat_json_node_t *node = NULL;
2505
2506   if (VAT_JSON_ARRAY != vam->json_tree.type)
2507     {
2508       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2509       vat_json_init_array (&vam->json_tree);
2510     }
2511   node = vat_json_array_add (&vam->json_tree);
2512
2513   vat_json_init_object (node);
2514   vat_json_object_add_prefix (node, &mp->prefix);
2515 }
2516
2517 static void
2518 vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
2519 {
2520   vat_main_t *vam = &vat_main;
2521   static ip_details_t empty_ip_details = { 0 };
2522   ip_details_t *ip = NULL;
2523   u32 sw_if_index = ~0;
2524
2525   sw_if_index = ntohl (mp->sw_if_index);
2526
2527   vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2528                            sw_if_index, empty_ip_details);
2529
2530   ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2531                          sw_if_index);
2532
2533   ip->present = 1;
2534 }
2535
2536 static void
2537 vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
2538 {
2539   vat_main_t *vam = &vat_main;
2540
2541   if (VAT_JSON_ARRAY != vam->json_tree.type)
2542     {
2543       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2544       vat_json_init_array (&vam->json_tree);
2545     }
2546   vat_json_array_add_uint (&vam->json_tree,
2547                            clib_net_to_host_u32 (mp->sw_if_index));
2548 }
2549
2550 static void vl_api_get_first_msg_id_reply_t_handler
2551   (vl_api_get_first_msg_id_reply_t * mp)
2552 {
2553   vat_main_t *vam = &vat_main;
2554   i32 retval = ntohl (mp->retval);
2555
2556   if (vam->async_mode)
2557     {
2558       vam->async_errors += (retval < 0);
2559     }
2560   else
2561     {
2562       vam->retval = retval;
2563       vam->result_ready = 1;
2564     }
2565   if (retval >= 0)
2566     {
2567       errmsg ("first message id %d", ntohs (mp->first_msg_id));
2568     }
2569 }
2570
2571 static void vl_api_get_first_msg_id_reply_t_handler_json
2572   (vl_api_get_first_msg_id_reply_t * mp)
2573 {
2574   vat_main_t *vam = &vat_main;
2575   vat_json_node_t node;
2576
2577   vat_json_init_object (&node);
2578   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2579   vat_json_object_add_uint (&node, "first_msg_id",
2580                             (uint) ntohs (mp->first_msg_id));
2581
2582   vat_json_print (vam->ofp, &node);
2583   vat_json_free (&node);
2584
2585   vam->retval = ntohl (mp->retval);
2586   vam->result_ready = 1;
2587 }
2588
2589 static void vl_api_get_node_graph_reply_t_handler
2590   (vl_api_get_node_graph_reply_t * mp)
2591 {
2592   vat_main_t *vam = &vat_main;
2593   i32 retval = ntohl (mp->retval);
2594   u8 *pvt_copy, *reply;
2595   void *oldheap;
2596   vlib_node_t *node;
2597   int i;
2598
2599   if (vam->async_mode)
2600     {
2601       vam->async_errors += (retval < 0);
2602     }
2603   else
2604     {
2605       vam->retval = retval;
2606       vam->result_ready = 1;
2607     }
2608
2609   /* "Should never happen..." */
2610   if (retval != 0)
2611     return;
2612
2613   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2614   pvt_copy = vec_dup (reply);
2615
2616   /* Toss the shared-memory original... */
2617   oldheap = vl_msg_push_heap ();
2618
2619   vec_free (reply);
2620
2621   vl_msg_pop_heap (oldheap);
2622
2623   if (vam->graph_nodes)
2624     {
2625       hash_free (vam->graph_node_index_by_name);
2626
2627       for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
2628         {
2629           node = vam->graph_nodes[0][i];
2630           vec_free (node->name);
2631           vec_free (node->next_nodes);
2632           vec_free (node);
2633         }
2634       vec_free (vam->graph_nodes[0]);
2635       vec_free (vam->graph_nodes);
2636     }
2637
2638   vam->graph_node_index_by_name = hash_create_string (0, sizeof (uword));
2639   vam->graph_nodes = vlib_node_unserialize (pvt_copy);
2640   vec_free (pvt_copy);
2641
2642   for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
2643     {
2644       node = vam->graph_nodes[0][i];
2645       hash_set_mem (vam->graph_node_index_by_name, node->name, i);
2646     }
2647 }
2648
2649 static void vl_api_get_node_graph_reply_t_handler_json
2650   (vl_api_get_node_graph_reply_t * mp)
2651 {
2652   vat_main_t *vam = &vat_main;
2653   void *oldheap;
2654   vat_json_node_t node;
2655   u8 *reply;
2656
2657   /* $$$$ make this real? */
2658   vat_json_init_object (&node);
2659   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2660   vat_json_object_add_uint (&node, "reply_in_shmem", mp->reply_in_shmem);
2661
2662   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2663
2664   /* Toss the shared-memory original... */
2665   oldheap = vl_msg_push_heap ();
2666
2667   vec_free (reply);
2668
2669   vl_msg_pop_heap (oldheap);
2670
2671   vat_json_print (vam->ofp, &node);
2672   vat_json_free (&node);
2673
2674   vam->retval = ntohl (mp->retval);
2675   vam->result_ready = 1;
2676 }
2677
2678 static u8 *
2679 format_policer_type (u8 * s, va_list * va)
2680 {
2681   u32 i = va_arg (*va, u32);
2682
2683   if (i == QOS_POLICER_TYPE_1R2C)
2684     s = format (s, "1r2c");
2685   else if (i == QOS_POLICER_TYPE_1R3C_RFC_2697)
2686     s = format (s, "1r3c");
2687   else if (i == QOS_POLICER_TYPE_2R3C_RFC_2698)
2688     s = format (s, "2r3c-2698");
2689   else if (i == QOS_POLICER_TYPE_2R3C_RFC_4115)
2690     s = format (s, "2r3c-4115");
2691   else if (i == QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
2692     s = format (s, "2r3c-mef5cf1");
2693   else
2694     s = format (s, "ILLEGAL");
2695   return s;
2696 }
2697
2698 static u8 *
2699 format_policer_rate_type (u8 * s, va_list * va)
2700 {
2701   u32 i = va_arg (*va, u32);
2702
2703   if (i == QOS_RATE_KBPS)
2704     s = format (s, "kbps");
2705   else if (i == QOS_RATE_PPS)
2706     s = format (s, "pps");
2707   else
2708     s = format (s, "ILLEGAL");
2709   return s;
2710 }
2711
2712 static u8 *
2713 format_policer_round_type (u8 * s, va_list * va)
2714 {
2715   u32 i = va_arg (*va, u32);
2716
2717   if (i == QOS_ROUND_TO_CLOSEST)
2718     s = format (s, "closest");
2719   else if (i == QOS_ROUND_TO_UP)
2720     s = format (s, "up");
2721   else if (i == QOS_ROUND_TO_DOWN)
2722     s = format (s, "down");
2723   else
2724     s = format (s, "ILLEGAL");
2725   return s;
2726 }
2727
2728 static u8 *
2729 format_policer_action_type (u8 * s, va_list * va)
2730 {
2731   u32 i = va_arg (*va, u32);
2732
2733   if (i == QOS_ACTION_DROP)
2734     s = format (s, "drop");
2735   else if (i == QOS_ACTION_TRANSMIT)
2736     s = format (s, "transmit");
2737   else if (i == QOS_ACTION_MARK_AND_TRANSMIT)
2738     s = format (s, "mark-and-transmit");
2739   else
2740     s = format (s, "ILLEGAL");
2741   return s;
2742 }
2743
2744 static u8 *
2745 format_dscp (u8 * s, va_list * va)
2746 {
2747   u32 i = va_arg (*va, u32);
2748   char *t = 0;
2749
2750   switch (i)
2751     {
2752 #define _(v, f)                                                               \
2753   case IP_DSCP_##f:                                                           \
2754     return (format (s, "%s", #f));
2755       foreach_ip_dscp
2756 #undef _
2757     }
2758   s = format (s, "%s", t);
2759   return (format (s, "ILLEGAL"));
2760 }
2761
2762 static void
2763 vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
2764 {
2765   vat_main_t *vam = &vat_main;
2766   u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
2767
2768   if (mp->conform_action.type == SSE2_QOS_ACTION_API_MARK_AND_TRANSMIT)
2769     conform_dscp_str = format (0, "%U", format_dscp, mp->conform_action.dscp);
2770   else
2771     conform_dscp_str = format (0, "");
2772
2773   if (mp->exceed_action.type == SSE2_QOS_ACTION_API_MARK_AND_TRANSMIT)
2774     exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_action.dscp);
2775   else
2776     exceed_dscp_str = format (0, "");
2777
2778   if (mp->violate_action.type == SSE2_QOS_ACTION_API_MARK_AND_TRANSMIT)
2779     violate_dscp_str = format (0, "%U", format_dscp, mp->violate_action.dscp);
2780   else
2781     violate_dscp_str = format (0, "");
2782
2783   print (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
2784          "rate type %U, round type %U, %s rate, %s color-aware, "
2785          "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
2786          "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
2787          "conform action %U%s, exceed action %U%s, violate action %U%s",
2788          mp->name,
2789          format_policer_type, mp->type,
2790          ntohl (mp->cir),
2791          ntohl (mp->eir),
2792          clib_net_to_host_u64 (mp->cb),
2793          clib_net_to_host_u64 (mp->eb),
2794          format_policer_rate_type, mp->rate_type,
2795          format_policer_round_type, mp->round_type,
2796          mp->single_rate ? "single" : "dual",
2797          mp->color_aware ? "is" : "not",
2798          ntohl (mp->cir_tokens_per_period),
2799          ntohl (mp->pir_tokens_per_period),
2800          ntohl (mp->scale),
2801          ntohl (mp->current_limit),
2802          ntohl (mp->current_bucket),
2803          ntohl (mp->extended_limit),
2804          ntohl (mp->extended_bucket),
2805          clib_net_to_host_u64 (mp->last_update_time),
2806          format_policer_action_type, mp->conform_action.type,
2807          conform_dscp_str,
2808          format_policer_action_type, mp->exceed_action.type,
2809          exceed_dscp_str,
2810          format_policer_action_type, mp->violate_action.type,
2811          violate_dscp_str);
2812
2813   vec_free (conform_dscp_str);
2814   vec_free (exceed_dscp_str);
2815   vec_free (violate_dscp_str);
2816 }
2817
2818 static void vl_api_policer_details_t_handler_json
2819   (vl_api_policer_details_t * mp)
2820 {
2821   vat_main_t *vam = &vat_main;
2822   vat_json_node_t *node;
2823   u8 *rate_type_str, *round_type_str, *type_str;
2824   u8 *conform_action_str, *exceed_action_str, *violate_action_str;
2825
2826   rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
2827   round_type_str =
2828     format (0, "%U", format_policer_round_type, mp->round_type);
2829   type_str = format (0, "%U", format_policer_type, mp->type);
2830   conform_action_str = format (0, "%U", format_policer_action_type,
2831                                mp->conform_action.type);
2832   exceed_action_str = format (0, "%U", format_policer_action_type,
2833                               mp->exceed_action.type);
2834   violate_action_str = format (0, "%U", format_policer_action_type,
2835                                mp->violate_action.type);
2836
2837   if (VAT_JSON_ARRAY != vam->json_tree.type)
2838     {
2839       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2840       vat_json_init_array (&vam->json_tree);
2841     }
2842   node = vat_json_array_add (&vam->json_tree);
2843
2844   vat_json_init_object (node);
2845   vat_json_object_add_string_copy (node, "name", mp->name);
2846   vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
2847   vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
2848   vat_json_object_add_uint (node, "cb", clib_net_to_host_u64 (mp->cb));
2849   vat_json_object_add_uint (node, "eb", clib_net_to_host_u64 (mp->eb));
2850   vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
2851   vat_json_object_add_string_copy (node, "round_type", round_type_str);
2852   vat_json_object_add_string_copy (node, "type", type_str);
2853   vat_json_object_add_uint (node, "single_rate", mp->single_rate);
2854   vat_json_object_add_uint (node, "color_aware", mp->color_aware);
2855   vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
2856   vat_json_object_add_uint (node, "cir_tokens_per_period",
2857                             ntohl (mp->cir_tokens_per_period));
2858   vat_json_object_add_uint (node, "eir_tokens_per_period",
2859                             ntohl (mp->pir_tokens_per_period));
2860   vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
2861   vat_json_object_add_uint (node, "current_bucket",
2862                             ntohl (mp->current_bucket));
2863   vat_json_object_add_uint (node, "extended_limit",
2864                             ntohl (mp->extended_limit));
2865   vat_json_object_add_uint (node, "extended_bucket",
2866                             ntohl (mp->extended_bucket));
2867   vat_json_object_add_uint (node, "last_update_time",
2868                             ntohl (mp->last_update_time));
2869   vat_json_object_add_string_copy (node, "conform_action",
2870                                    conform_action_str);
2871   if (mp->conform_action.type == SSE2_QOS_ACTION_API_MARK_AND_TRANSMIT)
2872     {
2873       u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_action.dscp);
2874       vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
2875       vec_free (dscp_str);
2876     }
2877   vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
2878   if (mp->exceed_action.type == SSE2_QOS_ACTION_API_MARK_AND_TRANSMIT)
2879     {
2880       u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_action.dscp);
2881       vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
2882       vec_free (dscp_str);
2883     }
2884   vat_json_object_add_string_copy (node, "violate_action",
2885                                    violate_action_str);
2886   if (mp->violate_action.type == SSE2_QOS_ACTION_API_MARK_AND_TRANSMIT)
2887     {
2888       u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_action.dscp);
2889       vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
2890       vec_free (dscp_str);
2891     }
2892
2893   vec_free (rate_type_str);
2894   vec_free (round_type_str);
2895   vec_free (type_str);
2896   vec_free (conform_action_str);
2897   vec_free (exceed_action_str);
2898   vec_free (violate_action_str);
2899 }
2900
2901 static void
2902 vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
2903                                            mp)
2904 {
2905   vat_main_t *vam = &vat_main;
2906   int i, count = ntohl (mp->count);
2907
2908   if (count > 0)
2909     print (vam->ofp, "classify table ids (%d) : ", count);
2910   for (i = 0; i < count; i++)
2911     {
2912       print (vam->ofp, "%d", ntohl (mp->ids[i]));
2913       print (vam->ofp, (i < count - 1) ? "," : "");
2914     }
2915   vam->retval = ntohl (mp->retval);
2916   vam->result_ready = 1;
2917 }
2918
2919 static void
2920   vl_api_classify_table_ids_reply_t_handler_json
2921   (vl_api_classify_table_ids_reply_t * mp)
2922 {
2923   vat_main_t *vam = &vat_main;
2924   int i, count = ntohl (mp->count);
2925
2926   if (count > 0)
2927     {
2928       vat_json_node_t node;
2929
2930       vat_json_init_object (&node);
2931       for (i = 0; i < count; i++)
2932         {
2933           vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
2934         }
2935       vat_json_print (vam->ofp, &node);
2936       vat_json_free (&node);
2937     }
2938   vam->retval = ntohl (mp->retval);
2939   vam->result_ready = 1;
2940 }
2941
2942 static void
2943   vl_api_classify_table_by_interface_reply_t_handler
2944   (vl_api_classify_table_by_interface_reply_t * mp)
2945 {
2946   vat_main_t *vam = &vat_main;
2947   u32 table_id;
2948
2949   table_id = ntohl (mp->l2_table_id);
2950   if (table_id != ~0)
2951     print (vam->ofp, "l2 table id : %d", table_id);
2952   else
2953     print (vam->ofp, "l2 table id : No input ACL tables configured");
2954   table_id = ntohl (mp->ip4_table_id);
2955   if (table_id != ~0)
2956     print (vam->ofp, "ip4 table id : %d", table_id);
2957   else
2958     print (vam->ofp, "ip4 table id : No input ACL tables configured");
2959   table_id = ntohl (mp->ip6_table_id);
2960   if (table_id != ~0)
2961     print (vam->ofp, "ip6 table id : %d", table_id);
2962   else
2963     print (vam->ofp, "ip6 table id : No input ACL tables configured");
2964   vam->retval = ntohl (mp->retval);
2965   vam->result_ready = 1;
2966 }
2967
2968 static void
2969   vl_api_classify_table_by_interface_reply_t_handler_json
2970   (vl_api_classify_table_by_interface_reply_t * mp)
2971 {
2972   vat_main_t *vam = &vat_main;
2973   vat_json_node_t node;
2974
2975   vat_json_init_object (&node);
2976
2977   vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
2978   vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
2979   vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
2980
2981   vat_json_print (vam->ofp, &node);
2982   vat_json_free (&node);
2983
2984   vam->retval = ntohl (mp->retval);
2985   vam->result_ready = 1;
2986 }
2987
2988 static void vl_api_policer_add_del_reply_t_handler
2989   (vl_api_policer_add_del_reply_t * mp)
2990 {
2991   vat_main_t *vam = &vat_main;
2992   i32 retval = ntohl (mp->retval);
2993   if (vam->async_mode)
2994     {
2995       vam->async_errors += (retval < 0);
2996     }
2997   else
2998     {
2999       vam->retval = retval;
3000       vam->result_ready = 1;
3001       if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
3002         /*
3003          * Note: this is just barely thread-safe, depends on
3004          * the main thread spinning waiting for an answer...
3005          */
3006         errmsg ("policer index %d", ntohl (mp->policer_index));
3007     }
3008 }
3009
3010 static void vl_api_policer_add_del_reply_t_handler_json
3011   (vl_api_policer_add_del_reply_t * mp)
3012 {
3013   vat_main_t *vam = &vat_main;
3014   vat_json_node_t node;
3015
3016   vat_json_init_object (&node);
3017   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
3018   vat_json_object_add_uint (&node, "policer_index",
3019                             ntohl (mp->policer_index));
3020
3021   vat_json_print (vam->ofp, &node);
3022   vat_json_free (&node);
3023
3024   vam->retval = ntohl (mp->retval);
3025   vam->result_ready = 1;
3026 }
3027
3028 /* Format hex dump. */
3029 u8 *
3030 format_hex_bytes (u8 * s, va_list * va)
3031 {
3032   u8 *bytes = va_arg (*va, u8 *);
3033   int n_bytes = va_arg (*va, int);
3034   uword i;
3035
3036   /* Print short or long form depending on byte count. */
3037   uword short_form = n_bytes <= 32;
3038   u32 indent = format_get_indent (s);
3039
3040   if (n_bytes == 0)
3041     return s;
3042
3043   for (i = 0; i < n_bytes; i++)
3044     {
3045       if (!short_form && (i % 32) == 0)
3046         s = format (s, "%08x: ", i);
3047       s = format (s, "%02x", bytes[i]);
3048       if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
3049         s = format (s, "\n%U", format_white_space, indent);
3050     }
3051
3052   return s;
3053 }
3054
3055 static void
3056 vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
3057                                             * mp)
3058 {
3059   vat_main_t *vam = &vat_main;
3060   i32 retval = ntohl (mp->retval);
3061   if (retval == 0)
3062     {
3063       print (vam->ofp, "classify table info :");
3064       print (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d",
3065              ntohl (mp->active_sessions), ntohl (mp->next_table_index),
3066              ntohl (mp->miss_next_index));
3067       print (vam->ofp, "nbuckets: %d skip: %d match: %d",
3068              ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
3069              ntohl (mp->match_n_vectors));
3070       print (vam->ofp, "mask: %U", format_hex_bytes, mp->mask,
3071              ntohl (mp->mask_length));
3072     }
3073   vam->retval = retval;
3074   vam->result_ready = 1;
3075 }
3076
3077 static void
3078   vl_api_classify_table_info_reply_t_handler_json
3079   (vl_api_classify_table_info_reply_t * mp)
3080 {
3081   vat_main_t *vam = &vat_main;
3082   vat_json_node_t node;
3083
3084   i32 retval = ntohl (mp->retval);
3085   if (retval == 0)
3086     {
3087       vat_json_init_object (&node);
3088
3089       vat_json_object_add_int (&node, "sessions",
3090                                ntohl (mp->active_sessions));
3091       vat_json_object_add_int (&node, "nexttbl",
3092                                ntohl (mp->next_table_index));
3093       vat_json_object_add_int (&node, "nextnode",
3094                                ntohl (mp->miss_next_index));
3095       vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
3096       vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
3097       vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
3098       u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
3099                       ntohl (mp->mask_length), 0);
3100       vat_json_object_add_string_copy (&node, "mask", s);
3101
3102       vat_json_print (vam->ofp, &node);
3103       vat_json_free (&node);
3104     }
3105   vam->retval = ntohl (mp->retval);
3106   vam->result_ready = 1;
3107 }
3108
3109 static void
3110 vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
3111                                            mp)
3112 {
3113   vat_main_t *vam = &vat_main;
3114
3115   print (vam->ofp, "next_index: %d advance: %d opaque: %d ",
3116          ntohl (mp->hit_next_index), ntohl (mp->advance),
3117          ntohl (mp->opaque_index));
3118   print (vam->ofp, "mask: %U", format_hex_bytes, mp->match,
3119          ntohl (mp->match_length));
3120 }
3121
3122 static void
3123   vl_api_classify_session_details_t_handler_json
3124   (vl_api_classify_session_details_t * mp)
3125 {
3126   vat_main_t *vam = &vat_main;
3127   vat_json_node_t *node = NULL;
3128
3129   if (VAT_JSON_ARRAY != vam->json_tree.type)
3130     {
3131       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3132       vat_json_init_array (&vam->json_tree);
3133     }
3134   node = vat_json_array_add (&vam->json_tree);
3135
3136   vat_json_init_object (node);
3137   vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
3138   vat_json_object_add_int (node, "advance", ntohl (mp->advance));
3139   vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
3140   u8 *s =
3141     format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
3142             0);
3143   vat_json_object_add_string_copy (node, "match", s);
3144 }
3145
3146 static void vl_api_pg_create_interface_reply_t_handler
3147   (vl_api_pg_create_interface_reply_t * mp)
3148 {
3149   vat_main_t *vam = &vat_main;
3150
3151   vam->retval = ntohl (mp->retval);
3152   vam->result_ready = 1;
3153 }
3154
3155 static void vl_api_pg_create_interface_reply_t_handler_json
3156   (vl_api_pg_create_interface_reply_t * mp)
3157 {
3158   vat_main_t *vam = &vat_main;
3159   vat_json_node_t node;
3160
3161   i32 retval = ntohl (mp->retval);
3162   if (retval == 0)
3163     {
3164       vat_json_init_object (&node);
3165
3166       vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
3167
3168       vat_json_print (vam->ofp, &node);
3169       vat_json_free (&node);
3170     }
3171   vam->retval = ntohl (mp->retval);
3172   vam->result_ready = 1;
3173 }
3174
3175 static void vl_api_policer_classify_details_t_handler
3176   (vl_api_policer_classify_details_t * mp)
3177 {
3178   vat_main_t *vam = &vat_main;
3179
3180   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
3181          ntohl (mp->table_index));
3182 }
3183
3184 static void vl_api_policer_classify_details_t_handler_json
3185   (vl_api_policer_classify_details_t * mp)
3186 {
3187   vat_main_t *vam = &vat_main;
3188   vat_json_node_t *node;
3189
3190   if (VAT_JSON_ARRAY != vam->json_tree.type)
3191     {
3192       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3193       vat_json_init_array (&vam->json_tree);
3194     }
3195   node = vat_json_array_add (&vam->json_tree);
3196
3197   vat_json_init_object (node);
3198   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
3199   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
3200 }
3201
3202 static void vl_api_flow_classify_details_t_handler
3203   (vl_api_flow_classify_details_t * mp)
3204 {
3205   vat_main_t *vam = &vat_main;
3206
3207   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
3208          ntohl (mp->table_index));
3209 }
3210
3211 static void vl_api_flow_classify_details_t_handler_json
3212   (vl_api_flow_classify_details_t * mp)
3213 {
3214   vat_main_t *vam = &vat_main;
3215   vat_json_node_t *node;
3216
3217   if (VAT_JSON_ARRAY != vam->json_tree.type)
3218     {
3219       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3220       vat_json_init_array (&vam->json_tree);
3221     }
3222   node = vat_json_array_add (&vam->json_tree);
3223
3224   vat_json_init_object (node);
3225   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
3226   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
3227 }
3228
3229 /*
3230  * Generate boilerplate reply handlers, which
3231  * dig the return value out of the xxx_reply_t API message,
3232  * stick it into vam->retval, and set vam->result_ready
3233  *
3234  * Could also do this by pointing N message decode slots at
3235  * a single function, but that could break in subtle ways.
3236  */
3237
3238 #define foreach_standard_reply_retval_handler           \
3239 _(sw_interface_set_flags_reply)                         \
3240 _(sw_interface_add_del_address_reply)                   \
3241 _(sw_interface_set_rx_mode_reply)                       \
3242 _(sw_interface_set_rx_placement_reply)                  \
3243 _(sw_interface_set_table_reply)                         \
3244 _(sw_interface_set_mpls_enable_reply)                   \
3245 _(sw_interface_set_vpath_reply)                         \
3246 _(sw_interface_set_vxlan_bypass_reply)                  \
3247 _(sw_interface_set_vxlan_gpe_bypass_reply)              \
3248 _(sw_interface_set_l2_bridge_reply)                     \
3249 _(sw_interface_set_bond_weight_reply)                   \
3250 _(bridge_domain_add_del_reply)                          \
3251 _(sw_interface_set_l2_xconnect_reply)                   \
3252 _(l2fib_add_del_reply)                                  \
3253 _(l2fib_flush_int_reply)                                \
3254 _(l2fib_flush_bd_reply)                                 \
3255 _(ip_route_add_del_reply)                               \
3256 _(ip_table_add_del_reply)                               \
3257 _(ip_table_replace_begin_reply)                         \
3258 _(ip_table_flush_reply)                                 \
3259 _(ip_table_replace_end_reply)                           \
3260 _(ip_mroute_add_del_reply)                              \
3261 _(mpls_route_add_del_reply)                             \
3262 _(mpls_table_add_del_reply)                             \
3263 _(mpls_ip_bind_unbind_reply)                            \
3264 _(bier_route_add_del_reply)                             \
3265 _(bier_table_add_del_reply)                             \
3266 _(sw_interface_set_unnumbered_reply)                    \
3267 _(set_ip_flow_hash_reply)                               \
3268 _(sw_interface_ip6_enable_disable_reply)                \
3269 _(l2_patch_add_del_reply)                               \
3270 _(sr_mpls_policy_add_reply)                             \
3271 _(sr_mpls_policy_mod_reply)                             \
3272 _(sr_mpls_policy_del_reply)                             \
3273 _(sr_policy_add_reply)                                  \
3274 _(sr_policy_mod_reply)                                  \
3275 _(sr_policy_del_reply)                                  \
3276 _(sr_localsid_add_del_reply)                            \
3277 _(sr_steering_add_del_reply)                            \
3278 _(classify_add_del_session_reply)                       \
3279 _(classify_set_interface_ip_table_reply)                \
3280 _(classify_set_interface_l2_tables_reply)               \
3281 _(l2_fib_clear_table_reply)                             \
3282 _(l2_interface_efp_filter_reply)                        \
3283 _(l2_interface_vlan_tag_rewrite_reply)                  \
3284 _(modify_vhost_user_if_reply)                           \
3285 _(modify_vhost_user_if_v2_reply)                        \
3286 _(delete_vhost_user_if_reply)                           \
3287 _(want_l2_macs_events_reply)                            \
3288 _(input_acl_set_interface_reply)                        \
3289 _(ipsec_spd_add_del_reply)                              \
3290 _(ipsec_interface_add_del_spd_reply)                    \
3291 _(ipsec_spd_entry_add_del_reply)                        \
3292 _(ipsec_sad_entry_add_del_reply)                        \
3293 _(delete_loopback_reply)                                \
3294 _(bd_ip_mac_add_del_reply)                              \
3295 _(bd_ip_mac_flush_reply)                                \
3296 _(want_interface_events_reply)                          \
3297 _(sw_interface_clear_stats_reply)                       \
3298 _(ioam_enable_reply)                                    \
3299 _(ioam_disable_reply)                                   \
3300 _(af_packet_delete_reply)                               \
3301 _(policer_classify_set_interface_reply)                 \
3302 _(set_ipfix_exporter_reply)                             \
3303 _(set_ipfix_classify_stream_reply)                      \
3304 _(ipfix_classify_table_add_del_reply)                   \
3305 _(flow_classify_set_interface_reply)                    \
3306 _(sw_interface_span_enable_disable_reply)               \
3307 _(pg_capture_reply)                                     \
3308 _(pg_enable_disable_reply)                              \
3309 _(pg_interface_enable_disable_coalesce_reply)           \
3310 _(ip_source_and_port_range_check_add_del_reply)         \
3311 _(ip_source_and_port_range_check_interface_add_del_reply)\
3312 _(delete_subif_reply)                                   \
3313 _(l2_interface_pbb_tag_rewrite_reply)                   \
3314 _(set_punt_reply)                                       \
3315 _(feature_enable_disable_reply)                         \
3316 _(feature_gso_enable_disable_reply)                     \
3317 _(sw_interface_tag_add_del_reply)                       \
3318 _(sw_interface_add_del_mac_address_reply)               \
3319 _(hw_interface_set_mtu_reply)                           \
3320 _(p2p_ethernet_add_reply)                               \
3321 _(p2p_ethernet_del_reply)                               \
3322 _(tcp_configure_src_addresses_reply)                    \
3323 _(session_rule_add_del_reply)                           \
3324 _(ip_container_proxy_add_del_reply)                     \
3325 _(output_acl_set_interface_reply)                       \
3326 _(qos_record_enable_disable_reply)                      \
3327 _(flow_add_reply)
3328
3329 #define _(n)                                    \
3330     static void vl_api_##n##_t_handler          \
3331     (vl_api_##n##_t * mp)                       \
3332     {                                           \
3333         vat_main_t * vam = &vat_main;           \
3334         i32 retval = ntohl(mp->retval);         \
3335         if (vam->async_mode) {                  \
3336             vam->async_errors += (retval < 0);  \
3337         } else {                                \
3338             vam->retval = retval;               \
3339             vam->result_ready = 1;              \
3340         }                                       \
3341     }
3342 foreach_standard_reply_retval_handler;
3343 #undef _
3344
3345 #define _(n)                                    \
3346     static void vl_api_##n##_t_handler_json     \
3347     (vl_api_##n##_t * mp)                       \
3348     {                                           \
3349         vat_main_t * vam = &vat_main;           \
3350         vat_json_node_t node;                   \
3351         vat_json_init_object(&node);            \
3352         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
3353         vat_json_print(vam->ofp, &node);        \
3354         vam->retval = ntohl(mp->retval);        \
3355         vam->result_ready = 1;                  \
3356     }
3357 foreach_standard_reply_retval_handler;
3358 #undef _
3359
3360 /*
3361  * Table of message reply handlers, must include boilerplate handlers
3362  * we just generated
3363  */
3364
3365 #define foreach_vpe_api_reply_msg                                       \
3366 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
3367 _(CREATE_LOOPBACK_INSTANCE_REPLY, create_loopback_instance_reply)       \
3368 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
3369 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
3370 _(CONTROL_PING_REPLY, control_ping_reply)                               \
3371 _(CLI_REPLY, cli_reply)                                                 \
3372 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
3373 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
3374   sw_interface_add_del_address_reply)                                   \
3375 _(SW_INTERFACE_SET_RX_MODE_REPLY, sw_interface_set_rx_mode_reply)       \
3376 _(SW_INTERFACE_SET_RX_PLACEMENT_REPLY, sw_interface_set_rx_placement_reply)     \
3377 _(SW_INTERFACE_RX_PLACEMENT_DETAILS, sw_interface_rx_placement_details) \
3378 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
3379 _(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
3380 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
3381 _(SW_INTERFACE_SET_VXLAN_BYPASS_REPLY, sw_interface_set_vxlan_bypass_reply) \
3382 _(SW_INTERFACE_SET_VXLAN_GPE_BYPASS_REPLY, sw_interface_set_vxlan_gpe_bypass_reply) \
3383 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
3384   sw_interface_set_l2_xconnect_reply)                                   \
3385 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
3386   sw_interface_set_l2_bridge_reply)                                     \
3387 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
3388 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
3389 _(BRIDGE_DOMAIN_SET_MAC_AGE_REPLY, bridge_domain_set_mac_age_reply)     \
3390 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
3391 _(L2FIB_FLUSH_INT_REPLY, l2fib_flush_int_reply)                         \
3392 _(L2FIB_FLUSH_BD_REPLY, l2fib_flush_bd_reply)                           \
3393 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
3394 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
3395 _(TAP_CREATE_V2_REPLY, tap_create_v2_reply)                             \
3396 _(TAP_DELETE_V2_REPLY, tap_delete_v2_reply)                             \
3397 _(SW_INTERFACE_TAP_V2_DETAILS, sw_interface_tap_v2_details)             \
3398 _(VIRTIO_PCI_CREATE_REPLY, virtio_pci_create_reply)                     \
3399 _(VIRTIO_PCI_CREATE_V2_REPLY, virtio_pci_create_v2_reply)               \
3400 _(VIRTIO_PCI_DELETE_REPLY, virtio_pci_delete_reply)                     \
3401 _(SW_INTERFACE_VIRTIO_PCI_DETAILS, sw_interface_virtio_pci_details)     \
3402 _(BOND_CREATE_REPLY, bond_create_reply)                                 \
3403 _(BOND_CREATE2_REPLY, bond_create2_reply)                               \
3404 _(BOND_DELETE_REPLY, bond_delete_reply)                                 \
3405 _(BOND_ADD_MEMBER_REPLY, bond_add_member_reply)                         \
3406 _(BOND_DETACH_MEMBER_REPLY, bond_detach_member_reply)                   \
3407 _(SW_INTERFACE_SET_BOND_WEIGHT_REPLY, sw_interface_set_bond_weight_reply) \
3408 _(SW_BOND_INTERFACE_DETAILS, sw_bond_interface_details)                 \
3409 _(SW_MEMBER_INTERFACE_DETAILS, sw_member_interface_details)               \
3410 _(IP_ROUTE_ADD_DEL_REPLY, ip_route_add_del_reply)                       \
3411 _(IP_TABLE_ADD_DEL_REPLY, ip_table_add_del_reply)                       \
3412 _(IP_TABLE_REPLACE_BEGIN_REPLY, ip_table_replace_begin_reply)           \
3413 _(IP_TABLE_FLUSH_REPLY, ip_table_flush_reply)                           \
3414 _(IP_TABLE_REPLACE_END_REPLY, ip_table_replace_end_reply)               \
3415 _(IP_MROUTE_ADD_DEL_REPLY, ip_mroute_add_del_reply)                     \
3416 _(MPLS_TABLE_ADD_DEL_REPLY, mpls_table_add_del_reply)                   \
3417 _(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply)                   \
3418 _(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply)                 \
3419 _(BIER_ROUTE_ADD_DEL_REPLY, bier_route_add_del_reply)                   \
3420 _(BIER_TABLE_ADD_DEL_REPLY, bier_table_add_del_reply)                   \
3421 _(MPLS_TUNNEL_ADD_DEL_REPLY, mpls_tunnel_add_del_reply)                 \
3422 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
3423   sw_interface_set_unnumbered_reply)                                    \
3424 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
3425 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
3426 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
3427 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
3428   sw_interface_ip6_enable_disable_reply)                                \
3429 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
3430 _(SR_MPLS_POLICY_ADD_REPLY, sr_mpls_policy_add_reply)                   \
3431 _(SR_MPLS_POLICY_MOD_REPLY, sr_mpls_policy_mod_reply)                   \
3432 _(SR_MPLS_POLICY_DEL_REPLY, sr_mpls_policy_del_reply)                   \
3433 _(SR_POLICY_ADD_REPLY, sr_policy_add_reply)                             \
3434 _(SR_POLICY_MOD_REPLY, sr_policy_mod_reply)                             \
3435 _(SR_POLICY_DEL_REPLY, sr_policy_del_reply)                             \
3436 _(SR_LOCALSID_ADD_DEL_REPLY, sr_localsid_add_del_reply)                 \
3437 _(SR_STEERING_ADD_DEL_REPLY, sr_steering_add_del_reply)                 \
3438 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
3439 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
3440 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
3441 classify_set_interface_ip_table_reply)                                  \
3442 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
3443   classify_set_interface_l2_tables_reply)                               \
3444 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
3445 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
3446 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
3447 _(VXLAN_OFFLOAD_RX_REPLY, vxlan_offload_rx_reply)               \
3448 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
3449 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
3450 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
3451 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
3452 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
3453 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
3454 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
3455 _(CREATE_VHOST_USER_IF_V2_REPLY, create_vhost_user_if_v2_reply)         \
3456 _(MODIFY_VHOST_USER_IF_V2_REPLY, modify_vhost_user_if_v2_reply)         \
3457 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
3458 _(SHOW_VERSION_REPLY, show_version_reply)                               \
3459 _(SHOW_THREADS_REPLY, show_threads_reply)                               \
3460 _(L2_FIB_TABLE_DETAILS, l2_fib_table_details)                           \
3461 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)       \
3462 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
3463 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
3464 _(WANT_L2_MACS_EVENTS_REPLY, want_l2_macs_events_reply)                 \
3465 _(L2_MACS_EVENT, l2_macs_event)                                         \
3466 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
3467 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
3468 _(IP_DETAILS, ip_details)                                               \
3469 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
3470 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
3471 _(IPSEC_SPD_ENTRY_ADD_DEL_REPLY, ipsec_spd_entry_add_del_reply)         \
3472 _(IPSEC_SAD_ENTRY_ADD_DEL_REPLY, ipsec_sad_entry_add_del_reply)         \
3473 _(IPSEC_SA_DETAILS, ipsec_sa_details)                                   \
3474 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
3475 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
3476 _(BD_IP_MAC_FLUSH_REPLY, bd_ip_mac_flush_reply)                         \
3477 _(BD_IP_MAC_DETAILS, bd_ip_mac_details)                                 \
3478 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
3479 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
3480 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
3481 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
3482 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
3483 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
3484 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
3485 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
3486 _(AF_PACKET_DETAILS, af_packet_details)                                 \
3487 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
3488 _(POLICER_DETAILS, policer_details)                                     \
3489 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
3490 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
3491 _(MPLS_TUNNEL_DETAILS, mpls_tunnel_details)                             \
3492 _(MPLS_TABLE_DETAILS, mpls_table_details)                               \
3493 _(MPLS_ROUTE_DETAILS, mpls_route_details)                               \
3494 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
3495 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
3496 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
3497 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
3498 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
3499 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
3500 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
3501 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
3502 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
3503 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
3504 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
3505 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
3506 _(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
3507 _(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details)                 \
3508 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
3509 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
3510 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
3511 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
3512 _(PG_INTERFACE_ENABLE_DISABLE_COALESCE_REPLY, pg_interface_enable_disable_coalesce_reply) \
3513 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
3514  ip_source_and_port_range_check_add_del_reply)                          \
3515 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
3516  ip_source_and_port_range_check_interface_add_del_reply)                \
3517 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
3518 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
3519 _(SET_PUNT_REPLY, set_punt_reply)                                       \
3520 _(IP_TABLE_DETAILS, ip_table_details)                                   \
3521 _(IP_ROUTE_DETAILS, ip_route_details)                                   \
3522 _(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply)           \
3523 _(FEATURE_GSO_ENABLE_DISABLE_REPLY, feature_gso_enable_disable_reply)   \
3524 _(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply)       \
3525 _(SW_INTERFACE_ADD_DEL_MAC_ADDRESS_REPLY, sw_interface_add_del_mac_address_reply) \
3526 _(L2_XCONNECT_DETAILS, l2_xconnect_details)                             \
3527 _(HW_INTERFACE_SET_MTU_REPLY, hw_interface_set_mtu_reply)               \
3528 _(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply)           \
3529 _(P2P_ETHERNET_ADD_REPLY, p2p_ethernet_add_reply)                       \
3530 _(P2P_ETHERNET_DEL_REPLY, p2p_ethernet_del_reply)                       \
3531 _(TCP_CONFIGURE_SRC_ADDRESSES_REPLY, tcp_configure_src_addresses_reply) \
3532 _(APP_NAMESPACE_ADD_DEL_REPLY, app_namespace_add_del_reply)             \
3533 _(SESSION_RULE_ADD_DEL_REPLY, session_rule_add_del_reply)               \
3534 _(SESSION_RULES_DETAILS, session_rules_details)                         \
3535 _(IP_CONTAINER_PROXY_ADD_DEL_REPLY, ip_container_proxy_add_del_reply)   \
3536 _(OUTPUT_ACL_SET_INTERFACE_REPLY, output_acl_set_interface_reply)       \
3537 _(QOS_RECORD_ENABLE_DISABLE_REPLY, qos_record_enable_disable_reply)             \
3538 _(FLOW_ADD_REPLY, flow_add_reply)   \
3539
3540 #define foreach_standalone_reply_msg                                    \
3541 _(SW_INTERFACE_EVENT, sw_interface_event)
3542
3543 typedef struct
3544 {
3545   u8 *name;
3546   u32 value;
3547 } name_sort_t;
3548
3549 #define STR_VTR_OP_CASE(op)     \
3550     case L2_VTR_ ## op:         \
3551         return "" # op;
3552
3553 static const char *
3554 str_vtr_op (u32 vtr_op)
3555 {
3556   switch (vtr_op)
3557     {
3558       STR_VTR_OP_CASE (DISABLED);
3559       STR_VTR_OP_CASE (PUSH_1);
3560       STR_VTR_OP_CASE (PUSH_2);
3561       STR_VTR_OP_CASE (POP_1);
3562       STR_VTR_OP_CASE (POP_2);
3563       STR_VTR_OP_CASE (TRANSLATE_1_1);
3564       STR_VTR_OP_CASE (TRANSLATE_1_2);
3565       STR_VTR_OP_CASE (TRANSLATE_2_1);
3566       STR_VTR_OP_CASE (TRANSLATE_2_2);
3567     }
3568
3569   return "UNKNOWN";
3570 }
3571
3572 static int
3573 dump_sub_interface_table (vat_main_t * vam)
3574 {
3575   const sw_interface_subif_t *sub = NULL;
3576
3577   if (vam->json_output)
3578     {
3579       clib_warning
3580         ("JSON output supported only for VPE API calls and dump_stats_table");
3581       return -99;
3582     }
3583
3584   print (vam->ofp,
3585          "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
3586          "Interface", "sw_if_index",
3587          "sub id", "dot1ad", "tags", "outer id",
3588          "inner id", "exact", "default", "outer any", "inner any");
3589
3590   vec_foreach (sub, vam->sw_if_subif_table)
3591   {
3592     print (vam->ofp,
3593            "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
3594            sub->interface_name,
3595            sub->sw_if_index,
3596            sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
3597            sub->sub_number_of_tags, sub->sub_outer_vlan_id,
3598            sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
3599            sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
3600     if (sub->vtr_op != L2_VTR_DISABLED)
3601       {
3602         print (vam->ofp,
3603                "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
3604                "tag1: %d tag2: %d ]",
3605                str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
3606                sub->vtr_tag1, sub->vtr_tag2);
3607       }
3608   }
3609
3610   return 0;
3611 }
3612
3613 static int
3614 name_sort_cmp (void *a1, void *a2)
3615 {
3616   name_sort_t *n1 = a1;
3617   name_sort_t *n2 = a2;
3618
3619   return strcmp ((char *) n1->name, (char *) n2->name);
3620 }
3621
3622 static int
3623 dump_interface_table (vat_main_t * vam)
3624 {
3625   hash_pair_t *p;
3626   name_sort_t *nses = 0, *ns;
3627
3628   if (vam->json_output)
3629     {
3630       clib_warning
3631         ("JSON output supported only for VPE API calls and dump_stats_table");
3632       return -99;
3633     }
3634
3635   /* *INDENT-OFF* */
3636   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
3637   ({
3638     vec_add2 (nses, ns, 1);
3639     ns->name = (u8 *)(p->key);
3640     ns->value = (u32) p->value[0];
3641   }));
3642   /* *INDENT-ON* */
3643
3644   vec_sort_with_function (nses, name_sort_cmp);
3645
3646   print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
3647   vec_foreach (ns, nses)
3648   {
3649     print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
3650   }
3651   vec_free (nses);
3652   return 0;
3653 }
3654
3655 static int
3656 dump_ip_table (vat_main_t * vam, int is_ipv6)
3657 {
3658   const ip_details_t *det = NULL;
3659   const ip_address_details_t *address = NULL;
3660   u32 i = ~0;
3661
3662   print (vam->ofp, "%-12s", "sw_if_index");
3663
3664   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
3665   {
3666     i++;
3667     if (!det->present)
3668       {
3669         continue;
3670       }
3671     print (vam->ofp, "%-12d", i);
3672     print (vam->ofp, "            %-30s%-13s", "Address", "Prefix length");
3673     if (!det->addr)
3674       {
3675         continue;
3676       }
3677     vec_foreach (address, det->addr)
3678     {
3679       print (vam->ofp,
3680              "            %-30U%-13d",
3681              is_ipv6 ? format_ip6_address : format_ip4_address,
3682              address->ip, address->prefix_length);
3683     }
3684   }
3685
3686   return 0;
3687 }
3688
3689 static int
3690 dump_ipv4_table (vat_main_t * vam)
3691 {
3692   if (vam->json_output)
3693     {
3694       clib_warning
3695         ("JSON output supported only for VPE API calls and dump_stats_table");
3696       return -99;
3697     }
3698
3699   return dump_ip_table (vam, 0);
3700 }
3701
3702 static int
3703 dump_ipv6_table (vat_main_t * vam)
3704 {
3705   if (vam->json_output)
3706     {
3707       clib_warning
3708         ("JSON output supported only for VPE API calls and dump_stats_table");
3709       return -99;
3710     }
3711
3712   return dump_ip_table (vam, 1);
3713 }
3714
3715 /*
3716  * Pass CLI buffers directly in the CLI_INBAND API message,
3717  * instead of an additional shared memory area.
3718  */
3719 static int
3720 exec_inband (vat_main_t * vam)
3721 {
3722   vl_api_cli_inband_t *mp;
3723   unformat_input_t *i = vam->input;
3724   int ret;
3725
3726   if (vec_len (i->buffer) == 0)
3727     return -1;
3728
3729   if (vam->exec_mode == 0 && unformat (i, "mode"))
3730     {
3731       vam->exec_mode = 1;
3732       return 0;
3733     }
3734   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
3735     {
3736       vam->exec_mode = 0;
3737       return 0;
3738     }
3739
3740   /*
3741    * In order for the CLI command to work, it
3742    * must be a vector ending in \n, not a C-string ending
3743    * in \n\0.
3744    */
3745   M2 (CLI_INBAND, mp, vec_len (vam->input->buffer));
3746   vl_api_vec_to_api_string (vam->input->buffer, &mp->cmd);
3747
3748   S (mp);
3749   W (ret);
3750   /* json responses may or may not include a useful reply... */
3751   if (vec_len (vam->cmd_reply))
3752     print (vam->ofp, "%v", (char *) (vam->cmd_reply));
3753   return ret;
3754 }
3755
3756 int
3757 exec (vat_main_t * vam)
3758 {
3759   return exec_inband (vam);
3760 }
3761
3762 static int
3763 api_create_loopback (vat_main_t * vam)
3764 {
3765   unformat_input_t *i = vam->input;
3766   vl_api_create_loopback_t *mp;
3767   vl_api_create_loopback_instance_t *mp_lbi;
3768   u8 mac_address[6];
3769   u8 mac_set = 0;
3770   u8 is_specified = 0;
3771   u32 user_instance = 0;
3772   int ret;
3773
3774   clib_memset (mac_address, 0, sizeof (mac_address));
3775
3776   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
3777     {
3778       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
3779         mac_set = 1;
3780       if (unformat (i, "instance %d", &user_instance))
3781         is_specified = 1;
3782       else
3783         break;
3784     }
3785
3786   if (is_specified)
3787     {
3788       M (CREATE_LOOPBACK_INSTANCE, mp_lbi);
3789       mp_lbi->is_specified = is_specified;
3790       if (is_specified)
3791         mp_lbi->user_instance = htonl (user_instance);
3792       if (mac_set)
3793         clib_memcpy (mp_lbi->mac_address, mac_address, sizeof (mac_address));
3794       S (mp_lbi);
3795     }
3796   else
3797     {
3798       /* Construct the API message */
3799       M (CREATE_LOOPBACK, mp);
3800       if (mac_set)
3801         clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
3802       S (mp);
3803     }
3804
3805   W (ret);
3806   return ret;
3807 }
3808
3809 static int
3810 api_delete_loopback (vat_main_t * vam)
3811 {
3812   unformat_input_t *i = vam->input;
3813   vl_api_delete_loopback_t *mp;
3814   u32 sw_if_index = ~0;
3815   int ret;
3816
3817   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
3818     {
3819       if (unformat (i, "sw_if_index %d", &sw_if_index))
3820         ;
3821       else
3822         break;
3823     }
3824
3825   if (sw_if_index == ~0)
3826     {
3827       errmsg ("missing sw_if_index");
3828       return -99;
3829     }
3830
3831   /* Construct the API message */
3832   M (DELETE_LOOPBACK, mp);
3833   mp->sw_if_index = ntohl (sw_if_index);
3834
3835   S (mp);
3836   W (ret);
3837   return ret;
3838 }
3839
3840 static int
3841 api_want_interface_events (vat_main_t * vam)
3842 {
3843   unformat_input_t *i = vam->input;
3844   vl_api_want_interface_events_t *mp;
3845   int enable = -1;
3846   int ret;
3847
3848   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
3849     {
3850       if (unformat (i, "enable"))
3851         enable = 1;
3852       else if (unformat (i, "disable"))
3853         enable = 0;
3854       else
3855         break;
3856     }
3857
3858   if (enable == -1)
3859     {
3860       errmsg ("missing enable|disable");
3861       return -99;
3862     }
3863
3864   M (WANT_INTERFACE_EVENTS, mp);
3865   mp->enable_disable = enable;
3866
3867   vam->interface_event_display = enable;
3868
3869   S (mp);
3870   W (ret);
3871   return ret;
3872 }
3873
3874
3875 /* Note: non-static, called once to set up the initial intfc table */
3876 int
3877 api_sw_interface_dump (vat_main_t * vam)
3878 {
3879   vl_api_sw_interface_dump_t *mp;
3880   vl_api_control_ping_t *mp_ping;
3881   hash_pair_t *p;
3882   name_sort_t *nses = 0, *ns;
3883   sw_interface_subif_t *sub = NULL;
3884   int ret;
3885
3886   /* Toss the old name table */
3887   /* *INDENT-OFF* */
3888   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
3889   ({
3890     vec_add2 (nses, ns, 1);
3891     ns->name = (u8 *)(p->key);
3892     ns->value = (u32) p->value[0];
3893   }));
3894   /* *INDENT-ON* */
3895
3896   hash_free (vam->sw_if_index_by_interface_name);
3897
3898   vec_foreach (ns, nses) vec_free (ns->name);
3899
3900   vec_free (nses);
3901
3902   vec_foreach (sub, vam->sw_if_subif_table)
3903   {
3904     vec_free (sub->interface_name);
3905   }
3906   vec_free (vam->sw_if_subif_table);
3907
3908   /* recreate the interface name hash table */
3909   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
3910
3911   /*
3912    * Ask for all interface names. Otherwise, the epic catalog of
3913    * name filters becomes ridiculously long, and vat ends up needing
3914    * to be taught about new interface types.
3915    */
3916   M (SW_INTERFACE_DUMP, mp);
3917   S (mp);
3918
3919   /* Use a control ping for synchronization */
3920   MPING (CONTROL_PING, mp_ping);
3921   S (mp_ping);
3922
3923   W (ret);
3924   return ret;
3925 }
3926
3927 static int
3928 api_sw_interface_set_flags (vat_main_t * vam)
3929 {
3930   unformat_input_t *i = vam->input;
3931   vl_api_sw_interface_set_flags_t *mp;
3932   u32 sw_if_index;
3933   u8 sw_if_index_set = 0;
3934   u8 admin_up = 0;
3935   int ret;
3936
3937   /* Parse args required to build the message */
3938   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
3939     {
3940       if (unformat (i, "admin-up"))
3941         admin_up = 1;
3942       else if (unformat (i, "admin-down"))
3943         admin_up = 0;
3944       else
3945         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
3946         sw_if_index_set = 1;
3947       else if (unformat (i, "sw_if_index %d", &sw_if_index))
3948         sw_if_index_set = 1;
3949       else
3950         break;
3951     }
3952
3953   if (sw_if_index_set == 0)
3954     {
3955       errmsg ("missing interface name or sw_if_index");
3956       return -99;
3957     }
3958
3959   /* Construct the API message */
3960   M (SW_INTERFACE_SET_FLAGS, mp);
3961   mp->sw_if_index = ntohl (sw_if_index);
3962   mp->flags = ntohl ((admin_up) ? IF_STATUS_API_FLAG_ADMIN_UP : 0);
3963
3964   /* send it... */
3965   S (mp);
3966
3967   /* Wait for a reply, return the good/bad news... */
3968   W (ret);
3969   return ret;
3970 }
3971
3972 static int
3973 api_sw_interface_set_rx_mode (vat_main_t * vam)
3974 {
3975   unformat_input_t *i = vam->input;
3976   vl_api_sw_interface_set_rx_mode_t *mp;
3977   u32 sw_if_index;
3978   u8 sw_if_index_set = 0;
3979   int ret;
3980   u8 queue_id_valid = 0;
3981   u32 queue_id;
3982   vnet_hw_if_rx_mode mode = VNET_HW_IF_RX_MODE_UNKNOWN;
3983
3984   /* Parse args required to build the message */
3985   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
3986     {
3987       if (unformat (i, "queue %d", &queue_id))
3988         queue_id_valid = 1;
3989       else if (unformat (i, "polling"))
3990         mode = VNET_HW_IF_RX_MODE_POLLING;
3991       else if (unformat (i, "interrupt"))
3992         mode = VNET_HW_IF_RX_MODE_INTERRUPT;
3993       else if (unformat (i, "adaptive"))
3994         mode = VNET_HW_IF_RX_MODE_ADAPTIVE;
3995       else
3996         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
3997         sw_if_index_set = 1;
3998       else if (unformat (i, "sw_if_index %d", &sw_if_index))
3999         sw_if_index_set = 1;
4000       else
4001         break;
4002     }
4003
4004   if (sw_if_index_set == 0)
4005     {
4006       errmsg ("missing interface name or sw_if_index");
4007       return -99;
4008     }
4009   if (mode == VNET_HW_IF_RX_MODE_UNKNOWN)
4010     {
4011       errmsg ("missing rx-mode");
4012       return -99;
4013     }
4014
4015   /* Construct the API message */
4016   M (SW_INTERFACE_SET_RX_MODE, mp);
4017   mp->sw_if_index = ntohl (sw_if_index);
4018   mp->mode = (vl_api_rx_mode_t) mode;
4019   mp->queue_id_valid = queue_id_valid;
4020   mp->queue_id = queue_id_valid ? ntohl (queue_id) : ~0;
4021
4022   /* send it... */
4023   S (mp);
4024
4025   /* Wait for a reply, return the good/bad news... */
4026   W (ret);
4027   return ret;
4028 }
4029
4030 static int
4031 api_sw_interface_set_rx_placement (vat_main_t * vam)
4032 {
4033   unformat_input_t *i = vam->input;
4034   vl_api_sw_interface_set_rx_placement_t *mp;
4035   u32 sw_if_index;
4036   u8 sw_if_index_set = 0;
4037   int ret;
4038   u8 is_main = 0;
4039   u32 queue_id, thread_index;
4040
4041   /* Parse args required to build the message */
4042   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4043     {
4044       if (unformat (i, "queue %d", &queue_id))
4045         ;
4046       else if (unformat (i, "main"))
4047         is_main = 1;
4048       else if (unformat (i, "worker %d", &thread_index))
4049         ;
4050       else
4051         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
4052         sw_if_index_set = 1;
4053       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4054         sw_if_index_set = 1;
4055       else
4056         break;
4057     }
4058
4059   if (sw_if_index_set == 0)
4060     {
4061       errmsg ("missing interface name or sw_if_index");
4062       return -99;
4063     }
4064
4065   if (is_main)
4066     thread_index = 0;
4067   /* Construct the API message */
4068   M (SW_INTERFACE_SET_RX_PLACEMENT, mp);
4069   mp->sw_if_index = ntohl (sw_if_index);
4070   mp->worker_id = ntohl (thread_index);
4071   mp->queue_id = ntohl (queue_id);
4072   mp->is_main = is_main;
4073
4074   /* send it... */
4075   S (mp);
4076   /* Wait for a reply, return the good/bad news... */
4077   W (ret);
4078   return ret;
4079 }
4080
4081 static void vl_api_sw_interface_rx_placement_details_t_handler
4082   (vl_api_sw_interface_rx_placement_details_t * mp)
4083 {
4084   vat_main_t *vam = &vat_main;
4085   u32 worker_id = ntohl (mp->worker_id);
4086
4087   print (vam->ofp,
4088          "\n%-11d %-11s %-6d %-5d %-9s",
4089          ntohl (mp->sw_if_index), (worker_id == 0) ? "main" : "worker",
4090          worker_id, ntohl (mp->queue_id),
4091          (mp->mode ==
4092           1) ? "polling" : ((mp->mode == 2) ? "interrupt" : "adaptive"));
4093 }
4094
4095 static void vl_api_sw_interface_rx_placement_details_t_handler_json
4096   (vl_api_sw_interface_rx_placement_details_t * mp)
4097 {
4098   vat_main_t *vam = &vat_main;
4099   vat_json_node_t *node = NULL;
4100
4101   if (VAT_JSON_ARRAY != vam->json_tree.type)
4102     {
4103       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4104       vat_json_init_array (&vam->json_tree);
4105     }
4106   node = vat_json_array_add (&vam->json_tree);
4107
4108   vat_json_init_object (node);
4109   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
4110   vat_json_object_add_uint (node, "worker_id", ntohl (mp->worker_id));
4111   vat_json_object_add_uint (node, "queue_id", ntohl (mp->queue_id));
4112   vat_json_object_add_uint (node, "mode", mp->mode);
4113 }
4114
4115 static int
4116 api_sw_interface_rx_placement_dump (vat_main_t * vam)
4117 {
4118   unformat_input_t *i = vam->input;
4119   vl_api_sw_interface_rx_placement_dump_t *mp;
4120   vl_api_control_ping_t *mp_ping;
4121   int ret;
4122   u32 sw_if_index;
4123   u8 sw_if_index_set = 0;
4124
4125   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4126     {
4127       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
4128         sw_if_index_set++;
4129       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4130         sw_if_index_set++;
4131       else
4132         break;
4133     }
4134
4135   print (vam->ofp,
4136          "\n%-11s %-11s %-6s %-5s %-4s",
4137          "sw_if_index", "main/worker", "thread", "queue", "mode");
4138
4139   /* Dump Interface rx placement */
4140   M (SW_INTERFACE_RX_PLACEMENT_DUMP, mp);
4141
4142   if (sw_if_index_set)
4143     mp->sw_if_index = htonl (sw_if_index);
4144   else
4145     mp->sw_if_index = ~0;
4146
4147   S (mp);
4148
4149   /* Use a control ping for synchronization */
4150   MPING (CONTROL_PING, mp_ping);
4151   S (mp_ping);
4152
4153   W (ret);
4154   return ret;
4155 }
4156
4157 static int
4158 api_sw_interface_clear_stats (vat_main_t * vam)
4159 {
4160   unformat_input_t *i = vam->input;
4161   vl_api_sw_interface_clear_stats_t *mp;
4162   u32 sw_if_index;
4163   u8 sw_if_index_set = 0;
4164   int ret;
4165
4166   /* Parse args required to build the message */
4167   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4168     {
4169       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
4170         sw_if_index_set = 1;
4171       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4172         sw_if_index_set = 1;
4173       else
4174         break;
4175     }
4176
4177   /* Construct the API message */
4178   M (SW_INTERFACE_CLEAR_STATS, mp);
4179
4180   if (sw_if_index_set == 1)
4181     mp->sw_if_index = ntohl (sw_if_index);
4182   else
4183     mp->sw_if_index = ~0;
4184
4185   /* send it... */
4186   S (mp);
4187
4188   /* Wait for a reply, return the good/bad news... */
4189   W (ret);
4190   return ret;
4191 }
4192
4193 static int
4194 api_sw_interface_add_del_address (vat_main_t * vam)
4195 {
4196   unformat_input_t *i = vam->input;
4197   vl_api_sw_interface_add_del_address_t *mp;
4198   u32 sw_if_index;
4199   u8 sw_if_index_set = 0;
4200   u8 is_add = 1, del_all = 0;
4201   u32 address_length = 0;
4202   u8 v4_address_set = 0;
4203   u8 v6_address_set = 0;
4204   ip4_address_t v4address;
4205   ip6_address_t v6address;
4206   int ret;
4207
4208   /* Parse args required to build the message */
4209   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4210     {
4211       if (unformat (i, "del-all"))
4212         del_all = 1;
4213       else if (unformat (i, "del"))
4214         is_add = 0;
4215       else
4216         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
4217         sw_if_index_set = 1;
4218       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4219         sw_if_index_set = 1;
4220       else if (unformat (i, "%U/%d",
4221                          unformat_ip4_address, &v4address, &address_length))
4222         v4_address_set = 1;
4223       else if (unformat (i, "%U/%d",
4224                          unformat_ip6_address, &v6address, &address_length))
4225         v6_address_set = 1;
4226       else
4227         break;
4228     }
4229
4230   if (sw_if_index_set == 0)
4231     {
4232       errmsg ("missing interface name or sw_if_index");
4233       return -99;
4234     }
4235   if (v4_address_set && v6_address_set)
4236     {
4237       errmsg ("both v4 and v6 addresses set");
4238       return -99;
4239     }
4240   if (!v4_address_set && !v6_address_set && !del_all)
4241     {
4242       errmsg ("no addresses set");
4243       return -99;
4244     }
4245
4246   /* Construct the API message */
4247   M (SW_INTERFACE_ADD_DEL_ADDRESS, mp);
4248
4249   mp->sw_if_index = ntohl (sw_if_index);
4250   mp->is_add = is_add;
4251   mp->del_all = del_all;
4252   if (v6_address_set)
4253     {
4254       mp->prefix.address.af = ADDRESS_IP6;
4255       clib_memcpy (mp->prefix.address.un.ip6, &v6address, sizeof (v6address));
4256     }
4257   else
4258     {
4259       mp->prefix.address.af = ADDRESS_IP4;
4260       clib_memcpy (mp->prefix.address.un.ip4, &v4address, sizeof (v4address));
4261     }
4262   mp->prefix.len = address_length;
4263
4264   /* send it... */
4265   S (mp);
4266
4267   /* Wait for a reply, return good/bad news  */
4268   W (ret);
4269   return ret;
4270 }
4271
4272 static int
4273 api_sw_interface_set_mpls_enable (vat_main_t * vam)
4274 {
4275   unformat_input_t *i = vam->input;
4276   vl_api_sw_interface_set_mpls_enable_t *mp;
4277   u32 sw_if_index;
4278   u8 sw_if_index_set = 0;
4279   u8 enable = 1;
4280   int ret;
4281
4282   /* Parse args required to build the message */
4283   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4284     {
4285       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
4286         sw_if_index_set = 1;
4287       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4288         sw_if_index_set = 1;
4289       else if (unformat (i, "disable"))
4290         enable = 0;
4291       else if (unformat (i, "dis"))
4292         enable = 0;
4293       else
4294         break;
4295     }
4296
4297   if (sw_if_index_set == 0)
4298     {
4299       errmsg ("missing interface name or sw_if_index");
4300       return -99;
4301     }
4302
4303   /* Construct the API message */
4304   M (SW_INTERFACE_SET_MPLS_ENABLE, mp);
4305
4306   mp->sw_if_index = ntohl (sw_if_index);
4307   mp->enable = enable;
4308
4309   /* send it... */
4310   S (mp);
4311
4312   /* Wait for a reply... */
4313   W (ret);
4314   return ret;
4315 }
4316
4317 static int
4318 api_sw_interface_set_table (vat_main_t * vam)
4319 {
4320   unformat_input_t *i = vam->input;
4321   vl_api_sw_interface_set_table_t *mp;
4322   u32 sw_if_index, vrf_id = 0;
4323   u8 sw_if_index_set = 0;
4324   u8 is_ipv6 = 0;
4325   int ret;
4326
4327   /* Parse args required to build the message */
4328   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4329     {
4330       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
4331         sw_if_index_set = 1;
4332       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4333         sw_if_index_set = 1;
4334       else if (unformat (i, "vrf %d", &vrf_id))
4335         ;
4336       else if (unformat (i, "ipv6"))
4337         is_ipv6 = 1;
4338       else
4339         break;
4340     }
4341
4342   if (sw_if_index_set == 0)
4343     {
4344       errmsg ("missing interface name or sw_if_index");
4345       return -99;
4346     }
4347
4348   /* Construct the API message */
4349   M (SW_INTERFACE_SET_TABLE, mp);
4350
4351   mp->sw_if_index = ntohl (sw_if_index);
4352   mp->is_ipv6 = is_ipv6;
4353   mp->vrf_id = ntohl (vrf_id);
4354
4355   /* send it... */
4356   S (mp);
4357
4358   /* Wait for a reply... */
4359   W (ret);
4360   return ret;
4361 }
4362
4363 static void vl_api_sw_interface_get_table_reply_t_handler
4364   (vl_api_sw_interface_get_table_reply_t * mp)
4365 {
4366   vat_main_t *vam = &vat_main;
4367
4368   print (vam->ofp, "%d", ntohl (mp->vrf_id));
4369
4370   vam->retval = ntohl (mp->retval);
4371   vam->result_ready = 1;
4372
4373 }
4374
4375 static void vl_api_sw_interface_get_table_reply_t_handler_json
4376   (vl_api_sw_interface_get_table_reply_t * mp)
4377 {
4378   vat_main_t *vam = &vat_main;
4379   vat_json_node_t node;
4380
4381   vat_json_init_object (&node);
4382   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
4383   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
4384
4385   vat_json_print (vam->ofp, &node);
4386   vat_json_free (&node);
4387
4388   vam->retval = ntohl (mp->retval);
4389   vam->result_ready = 1;
4390 }
4391
4392 static int
4393 api_sw_interface_get_table (vat_main_t * vam)
4394 {
4395   unformat_input_t *i = vam->input;
4396   vl_api_sw_interface_get_table_t *mp;
4397   u32 sw_if_index;
4398   u8 sw_if_index_set = 0;
4399   u8 is_ipv6 = 0;
4400   int ret;
4401
4402   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4403     {
4404       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
4405         sw_if_index_set = 1;
4406       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4407         sw_if_index_set = 1;
4408       else if (unformat (i, "ipv6"))
4409         is_ipv6 = 1;
4410       else
4411         break;
4412     }
4413
4414   if (sw_if_index_set == 0)
4415     {
4416       errmsg ("missing interface name or sw_if_index");
4417       return -99;
4418     }
4419
4420   M (SW_INTERFACE_GET_TABLE, mp);
4421   mp->sw_if_index = htonl (sw_if_index);
4422   mp->is_ipv6 = is_ipv6;
4423
4424   S (mp);
4425   W (ret);
4426   return ret;
4427 }
4428
4429 static int
4430 api_sw_interface_set_vpath (vat_main_t * vam)
4431 {
4432   unformat_input_t *i = vam->input;
4433   vl_api_sw_interface_set_vpath_t *mp;
4434   u32 sw_if_index = 0;
4435   u8 sw_if_index_set = 0;
4436   u8 is_enable = 0;
4437   int ret;
4438
4439   /* Parse args required to build the message */
4440   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4441     {
4442       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
4443         sw_if_index_set = 1;
4444       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4445         sw_if_index_set = 1;
4446       else if (unformat (i, "enable"))
4447         is_enable = 1;
4448       else if (unformat (i, "disable"))
4449         is_enable = 0;
4450       else
4451         break;
4452     }
4453
4454   if (sw_if_index_set == 0)
4455     {
4456       errmsg ("missing interface name or sw_if_index");
4457       return -99;
4458     }
4459
4460   /* Construct the API message */
4461   M (SW_INTERFACE_SET_VPATH, mp);
4462
4463   mp->sw_if_index = ntohl (sw_if_index);
4464   mp->enable = is_enable;
4465
4466   /* send it... */
4467   S (mp);
4468
4469   /* Wait for a reply... */
4470   W (ret);
4471   return ret;
4472 }
4473
4474 static int
4475 api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
4476 {
4477   unformat_input_t *i = vam->input;
4478   vl_api_sw_interface_set_vxlan_bypass_t *mp;
4479   u32 sw_if_index = 0;
4480   u8 sw_if_index_set = 0;
4481   u8 is_enable = 1;
4482   u8 is_ipv6 = 0;
4483   int ret;
4484
4485   /* Parse args required to build the message */
4486   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4487     {
4488       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
4489         sw_if_index_set = 1;
4490       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4491         sw_if_index_set = 1;
4492       else if (unformat (i, "enable"))
4493         is_enable = 1;
4494       else if (unformat (i, "disable"))
4495         is_enable = 0;
4496       else if (unformat (i, "ip4"))
4497         is_ipv6 = 0;
4498       else if (unformat (i, "ip6"))
4499         is_ipv6 = 1;
4500       else
4501         break;
4502     }
4503
4504   if (sw_if_index_set == 0)
4505     {
4506       errmsg ("missing interface name or sw_if_index");
4507       return -99;
4508     }
4509
4510   /* Construct the API message */
4511   M (SW_INTERFACE_SET_VXLAN_BYPASS, mp);
4512
4513   mp->sw_if_index = ntohl (sw_if_index);
4514   mp->enable = is_enable;
4515   mp->is_ipv6 = is_ipv6;
4516
4517   /* send it... */
4518   S (mp);
4519
4520   /* Wait for a reply... */
4521   W (ret);
4522   return ret;
4523 }
4524
4525 static int
4526 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
4527 {
4528   unformat_input_t *i = vam->input;
4529   vl_api_sw_interface_set_l2_xconnect_t *mp;
4530   u32 rx_sw_if_index;
4531   u8 rx_sw_if_index_set = 0;
4532   u32 tx_sw_if_index;
4533   u8 tx_sw_if_index_set = 0;
4534   u8 enable = 1;
4535   int ret;
4536
4537   /* Parse args required to build the message */
4538   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4539     {
4540       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
4541         rx_sw_if_index_set = 1;
4542       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
4543         tx_sw_if_index_set = 1;
4544       else if (unformat (i, "rx"))
4545         {
4546           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4547             {
4548               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
4549                             &rx_sw_if_index))
4550                 rx_sw_if_index_set = 1;
4551             }
4552           else
4553             break;
4554         }
4555       else if (unformat (i, "tx"))
4556         {
4557           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4558             {
4559               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
4560                             &tx_sw_if_index))
4561                 tx_sw_if_index_set = 1;
4562             }
4563           else
4564             break;
4565         }
4566       else if (unformat (i, "enable"))
4567         enable = 1;
4568       else if (unformat (i, "disable"))
4569         enable = 0;
4570       else
4571         break;
4572     }
4573
4574   if (rx_sw_if_index_set == 0)
4575     {
4576       errmsg ("missing rx interface name or rx_sw_if_index");
4577       return -99;
4578     }
4579
4580   if (enable && (tx_sw_if_index_set == 0))
4581     {
4582       errmsg ("missing tx interface name or tx_sw_if_index");
4583       return -99;
4584     }
4585
4586   M (SW_INTERFACE_SET_L2_XCONNECT, mp);
4587
4588   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
4589   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
4590   mp->enable = enable;
4591
4592   S (mp);
4593   W (ret);
4594   return ret;
4595 }
4596
4597 static int
4598 api_sw_interface_set_l2_bridge (vat_main_t * vam)
4599 {
4600   unformat_input_t *i = vam->input;
4601   vl_api_sw_interface_set_l2_bridge_t *mp;
4602   vl_api_l2_port_type_t port_type;
4603   u32 rx_sw_if_index;
4604   u8 rx_sw_if_index_set = 0;
4605   u32 bd_id;
4606   u8 bd_id_set = 0;
4607   u32 shg = 0;
4608   u8 enable = 1;
4609   int ret;
4610
4611   port_type = L2_API_PORT_TYPE_NORMAL;
4612
4613   /* Parse args required to build the message */
4614   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4615     {
4616       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
4617         rx_sw_if_index_set = 1;
4618       else if (unformat (i, "bd_id %d", &bd_id))
4619         bd_id_set = 1;
4620       else
4621         if (unformat
4622             (i, "%U", api_unformat_sw_if_index, vam, &rx_sw_if_index))
4623         rx_sw_if_index_set = 1;
4624       else if (unformat (i, "shg %d", &shg))
4625         ;
4626       else if (unformat (i, "bvi"))
4627         port_type = L2_API_PORT_TYPE_BVI;
4628       else if (unformat (i, "uu-fwd"))
4629         port_type = L2_API_PORT_TYPE_UU_FWD;
4630       else if (unformat (i, "enable"))
4631         enable = 1;
4632       else if (unformat (i, "disable"))
4633         enable = 0;
4634       else
4635         break;
4636     }
4637
4638   if (rx_sw_if_index_set == 0)
4639     {
4640       errmsg ("missing rx interface name or sw_if_index");
4641       return -99;
4642     }
4643
4644   if (enable && (bd_id_set == 0))
4645     {
4646       errmsg ("missing bridge domain");
4647       return -99;
4648     }
4649
4650   M (SW_INTERFACE_SET_L2_BRIDGE, mp);
4651
4652   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
4653   mp->bd_id = ntohl (bd_id);
4654   mp->shg = (u8) shg;
4655   mp->port_type = ntohl (port_type);
4656   mp->enable = enable;
4657
4658   S (mp);
4659   W (ret);
4660   return ret;
4661 }
4662
4663 static int
4664 api_bridge_domain_dump (vat_main_t * vam)
4665 {
4666   unformat_input_t *i = vam->input;
4667   vl_api_bridge_domain_dump_t *mp;
4668   vl_api_control_ping_t *mp_ping;
4669   u32 bd_id = ~0;
4670   int ret;
4671
4672   /* Parse args required to build the message */
4673   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4674     {
4675       if (unformat (i, "bd_id %d", &bd_id))
4676         ;
4677       else
4678         break;
4679     }
4680
4681   M (BRIDGE_DOMAIN_DUMP, mp);
4682   mp->bd_id = ntohl (bd_id);
4683   S (mp);
4684
4685   /* Use a control ping for synchronization */
4686   MPING (CONTROL_PING, mp_ping);
4687   S (mp_ping);
4688
4689   W (ret);
4690   return ret;
4691 }
4692
4693 static int
4694 api_bridge_domain_add_del (vat_main_t * vam)
4695 {
4696   unformat_input_t *i = vam->input;
4697   vl_api_bridge_domain_add_del_t *mp;
4698   u32 bd_id = ~0;
4699   u8 is_add = 1;
4700   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
4701   u8 *bd_tag = NULL;
4702   u32 mac_age = 0;
4703   int ret;
4704
4705   /* Parse args required to build the message */
4706   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4707     {
4708       if (unformat (i, "bd_id %d", &bd_id))
4709         ;
4710       else if (unformat (i, "flood %d", &flood))
4711         ;
4712       else if (unformat (i, "uu-flood %d", &uu_flood))
4713         ;
4714       else if (unformat (i, "forward %d", &forward))
4715         ;
4716       else if (unformat (i, "learn %d", &learn))
4717         ;
4718       else if (unformat (i, "arp-term %d", &arp_term))
4719         ;
4720       else if (unformat (i, "mac-age %d", &mac_age))
4721         ;
4722       else if (unformat (i, "bd-tag %s", &bd_tag))
4723         ;
4724       else if (unformat (i, "del"))
4725         {
4726           is_add = 0;
4727           flood = uu_flood = forward = learn = 0;
4728         }
4729       else
4730         break;
4731     }
4732
4733   if (bd_id == ~0)
4734     {
4735       errmsg ("missing bridge domain");
4736       ret = -99;
4737       goto done;
4738     }
4739
4740   if (mac_age > 255)
4741     {
4742       errmsg ("mac age must be less than 256 ");
4743       ret = -99;
4744       goto done;
4745     }
4746
4747   if ((bd_tag) && (vec_len (bd_tag) > 63))
4748     {
4749       errmsg ("bd-tag cannot be longer than 63");
4750       ret = -99;
4751       goto done;
4752     }
4753
4754   M (BRIDGE_DOMAIN_ADD_DEL, mp);
4755
4756   mp->bd_id = ntohl (bd_id);
4757   mp->flood = flood;
4758   mp->uu_flood = uu_flood;
4759   mp->forward = forward;
4760   mp->learn = learn;
4761   mp->arp_term = arp_term;
4762   mp->is_add = is_add;
4763   mp->mac_age = (u8) mac_age;
4764   if (bd_tag)
4765     {
4766       clib_memcpy (mp->bd_tag, bd_tag, vec_len (bd_tag));
4767       mp->bd_tag[vec_len (bd_tag)] = 0;
4768     }
4769   S (mp);
4770   W (ret);
4771
4772 done:
4773   vec_free (bd_tag);
4774   return ret;
4775 }
4776
4777 static int
4778 api_l2fib_flush_bd (vat_main_t * vam)
4779 {
4780   unformat_input_t *i = vam->input;
4781   vl_api_l2fib_flush_bd_t *mp;
4782   u32 bd_id = ~0;
4783   int ret;
4784
4785   /* Parse args required to build the message */
4786   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4787     {
4788       if (unformat (i, "bd_id %d", &bd_id));
4789       else
4790         break;
4791     }
4792
4793   if (bd_id == ~0)
4794     {
4795       errmsg ("missing bridge domain");
4796       return -99;
4797     }
4798
4799   M (L2FIB_FLUSH_BD, mp);
4800
4801   mp->bd_id = htonl (bd_id);
4802
4803   S (mp);
4804   W (ret);
4805   return ret;
4806 }
4807
4808 static int
4809 api_l2fib_flush_int (vat_main_t * vam)
4810 {
4811   unformat_input_t *i = vam->input;
4812   vl_api_l2fib_flush_int_t *mp;
4813   u32 sw_if_index = ~0;
4814   int ret;
4815
4816   /* Parse args required to build the message */
4817   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4818     {
4819       if (unformat (i, "sw_if_index %d", &sw_if_index));
4820       else
4821         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index));
4822       else
4823         break;
4824     }
4825
4826   if (sw_if_index == ~0)
4827     {
4828       errmsg ("missing interface name or sw_if_index");
4829       return -99;
4830     }
4831
4832   M (L2FIB_FLUSH_INT, mp);
4833
4834   mp->sw_if_index = ntohl (sw_if_index);
4835
4836   S (mp);
4837   W (ret);
4838   return ret;
4839 }
4840
4841 static int
4842 api_l2fib_add_del (vat_main_t * vam)
4843 {
4844   unformat_input_t *i = vam->input;
4845   vl_api_l2fib_add_del_t *mp;
4846   f64 timeout;
4847   u8 mac[6] = { 0 };
4848   u8 mac_set = 0;
4849   u32 bd_id;
4850   u8 bd_id_set = 0;
4851   u32 sw_if_index = 0;
4852   u8 sw_if_index_set = 0;
4853   u8 is_add = 1;
4854   u8 static_mac = 0;
4855   u8 filter_mac = 0;
4856   u8 bvi_mac = 0;
4857   int count = 1;
4858   f64 before = 0;
4859   int j;
4860
4861   /* Parse args required to build the message */
4862   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4863     {
4864       if (unformat (i, "mac %U", unformat_ethernet_address, mac))
4865         mac_set = 1;
4866       else if (unformat (i, "bd_id %d", &bd_id))
4867         bd_id_set = 1;
4868       else if (unformat (i, "sw_if_index %d", &sw_if_index))
4869         sw_if_index_set = 1;
4870       else if (unformat (i, "sw_if"))
4871         {
4872           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
4873             {
4874               if (unformat
4875                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
4876                 sw_if_index_set = 1;
4877             }
4878           else
4879             break;
4880         }
4881       else if (unformat (i, "static"))
4882         static_mac = 1;
4883       else if (unformat (i, "filter"))
4884         {
4885           filter_mac = 1;
4886           static_mac = 1;
4887         }
4888       else if (unformat (i, "bvi"))
4889         {
4890           bvi_mac = 1;
4891           static_mac = 1;
4892         }
4893       else if (unformat (i, "del"))
4894         is_add = 0;
4895       else if (unformat (i, "count %d", &count))
4896         ;
4897       else
4898         break;
4899     }
4900
4901   if (mac_set == 0)
4902     {
4903       errmsg ("missing mac address");
4904       return -99;
4905     }
4906
4907   if (bd_id_set == 0)
4908     {
4909       errmsg ("missing bridge domain");
4910       return -99;
4911     }
4912
4913   if (is_add && sw_if_index_set == 0 && filter_mac == 0)
4914     {
4915       errmsg ("missing interface name or sw_if_index");
4916       return -99;
4917     }
4918
4919   if (count > 1)
4920     {
4921       /* Turn on async mode */
4922       vam->async_mode = 1;
4923       vam->async_errors = 0;
4924       before = vat_time_now (vam);
4925     }
4926
4927   for (j = 0; j < count; j++)
4928     {
4929       M (L2FIB_ADD_DEL, mp);
4930
4931       clib_memcpy (mp->mac, mac, 6);
4932       mp->bd_id = ntohl (bd_id);
4933       mp->is_add = is_add;
4934       mp->sw_if_index = ntohl (sw_if_index);
4935
4936       if (is_add)
4937         {
4938           mp->static_mac = static_mac;
4939           mp->filter_mac = filter_mac;
4940           mp->bvi_mac = bvi_mac;
4941         }
4942       increment_mac_address (mac);
4943       /* send it... */
4944       S (mp);
4945     }
4946
4947   if (count > 1)
4948     {
4949       vl_api_control_ping_t *mp_ping;
4950       f64 after;
4951
4952       /* Shut off async mode */
4953       vam->async_mode = 0;
4954
4955       MPING (CONTROL_PING, mp_ping);
4956       S (mp_ping);
4957
4958       timeout = vat_time_now (vam) + 1.0;
4959       while (vat_time_now (vam) < timeout)
4960         if (vam->result_ready == 1)
4961           goto out;
4962       vam->retval = -99;
4963
4964     out:
4965       if (vam->retval == -99)
4966         errmsg ("timeout");
4967
4968       if (vam->async_errors > 0)
4969         {
4970           errmsg ("%d asynchronous errors", vam->async_errors);
4971           vam->retval = -98;
4972         }
4973       vam->async_errors = 0;
4974       after = vat_time_now (vam);
4975
4976       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
4977              count, after - before, count / (after - before));
4978     }
4979   else
4980     {
4981       int ret;
4982
4983       /* Wait for a reply... */
4984       W (ret);
4985       return ret;
4986     }
4987   /* Return the good/bad news */
4988   return (vam->retval);
4989 }
4990
4991 static int
4992 api_bridge_domain_set_mac_age (vat_main_t * vam)
4993 {
4994   unformat_input_t *i = vam->input;
4995   vl_api_bridge_domain_set_mac_age_t *mp;
4996   u32 bd_id = ~0;
4997   u32 mac_age = 0;
4998   int ret;
4999
5000   /* Parse args required to build the message */
5001   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5002     {
5003       if (unformat (i, "bd_id %d", &bd_id));
5004       else if (unformat (i, "mac-age %d", &mac_age));
5005       else
5006         break;
5007     }
5008
5009   if (bd_id == ~0)
5010     {
5011       errmsg ("missing bridge domain");
5012       return -99;
5013     }
5014
5015   if (mac_age > 255)
5016     {
5017       errmsg ("mac age must be less than 256 ");
5018       return -99;
5019     }
5020
5021   M (BRIDGE_DOMAIN_SET_MAC_AGE, mp);
5022
5023   mp->bd_id = htonl (bd_id);
5024   mp->mac_age = (u8) mac_age;
5025
5026   S (mp);
5027   W (ret);
5028   return ret;
5029 }
5030
5031 static int
5032 api_l2_flags (vat_main_t * vam)
5033 {
5034   unformat_input_t *i = vam->input;
5035   vl_api_l2_flags_t *mp;
5036   u32 sw_if_index;
5037   u32 flags = 0;
5038   u8 sw_if_index_set = 0;
5039   u8 is_set = 0;
5040   int ret;
5041
5042   /* Parse args required to build the message */
5043   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5044     {
5045       if (unformat (i, "sw_if_index %d", &sw_if_index))
5046         sw_if_index_set = 1;
5047       else if (unformat (i, "sw_if"))
5048         {
5049           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5050             {
5051               if (unformat
5052                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5053                 sw_if_index_set = 1;
5054             }
5055           else
5056             break;
5057         }
5058       else if (unformat (i, "learn"))
5059         flags |= L2_LEARN;
5060       else if (unformat (i, "forward"))
5061         flags |= L2_FWD;
5062       else if (unformat (i, "flood"))
5063         flags |= L2_FLOOD;
5064       else if (unformat (i, "uu-flood"))
5065         flags |= L2_UU_FLOOD;
5066       else if (unformat (i, "arp-term"))
5067         flags |= L2_ARP_TERM;
5068       else if (unformat (i, "off"))
5069         is_set = 0;
5070       else if (unformat (i, "disable"))
5071         is_set = 0;
5072       else
5073         break;
5074     }
5075
5076   if (sw_if_index_set == 0)
5077     {
5078       errmsg ("missing interface name or sw_if_index");
5079       return -99;
5080     }
5081
5082   M (L2_FLAGS, mp);
5083
5084   mp->sw_if_index = ntohl (sw_if_index);
5085   mp->feature_bitmap = ntohl (flags);
5086   mp->is_set = is_set;
5087
5088   S (mp);
5089   W (ret);
5090   return ret;
5091 }
5092
5093 static int
5094 api_bridge_flags (vat_main_t * vam)
5095 {
5096   unformat_input_t *i = vam->input;
5097   vl_api_bridge_flags_t *mp;
5098   u32 bd_id;
5099   u8 bd_id_set = 0;
5100   u8 is_set = 1;
5101   bd_flags_t flags = 0;
5102   int ret;
5103
5104   /* Parse args required to build the message */
5105   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5106     {
5107       if (unformat (i, "bd_id %d", &bd_id))
5108         bd_id_set = 1;
5109       else if (unformat (i, "learn"))
5110         flags |= BRIDGE_API_FLAG_LEARN;
5111       else if (unformat (i, "forward"))
5112         flags |= BRIDGE_API_FLAG_FWD;
5113       else if (unformat (i, "flood"))
5114         flags |= BRIDGE_API_FLAG_FLOOD;
5115       else if (unformat (i, "uu-flood"))
5116         flags |= BRIDGE_API_FLAG_UU_FLOOD;
5117       else if (unformat (i, "arp-term"))
5118         flags |= BRIDGE_API_FLAG_ARP_TERM;
5119       else if (unformat (i, "off"))
5120         is_set = 0;
5121       else if (unformat (i, "disable"))
5122         is_set = 0;
5123       else
5124         break;
5125     }
5126
5127   if (bd_id_set == 0)
5128     {
5129       errmsg ("missing bridge domain");
5130       return -99;
5131     }
5132
5133   M (BRIDGE_FLAGS, mp);
5134
5135   mp->bd_id = ntohl (bd_id);
5136   mp->flags = ntohl (flags);
5137   mp->is_set = is_set;
5138
5139   S (mp);
5140   W (ret);
5141   return ret;
5142 }
5143
5144 static int
5145 api_bd_ip_mac_add_del (vat_main_t * vam)
5146 {
5147   vl_api_address_t ip = VL_API_ZERO_ADDRESS;
5148   vl_api_mac_address_t mac = { 0 };
5149   unformat_input_t *i = vam->input;
5150   vl_api_bd_ip_mac_add_del_t *mp;
5151   u32 bd_id;
5152   u8 is_add = 1;
5153   u8 bd_id_set = 0;
5154   u8 ip_set = 0;
5155   u8 mac_set = 0;
5156   int ret;
5157
5158
5159   /* Parse args required to build the message */
5160   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5161     {
5162       if (unformat (i, "bd_id %d", &bd_id))
5163         {
5164           bd_id_set++;
5165         }
5166       else if (unformat (i, "%U", unformat_vl_api_address, &ip))
5167         {
5168           ip_set++;
5169         }
5170       else if (unformat (i, "%U", unformat_vl_api_mac_address, &mac))
5171         {
5172           mac_set++;
5173         }
5174       else if (unformat (i, "del"))
5175         is_add = 0;
5176       else
5177         break;
5178     }
5179
5180   if (bd_id_set == 0)
5181     {
5182       errmsg ("missing bridge domain");
5183       return -99;
5184     }
5185   else if (ip_set == 0)
5186     {
5187       errmsg ("missing IP address");
5188       return -99;
5189     }
5190   else if (mac_set == 0)
5191     {
5192       errmsg ("missing MAC address");
5193       return -99;
5194     }
5195
5196   M (BD_IP_MAC_ADD_DEL, mp);
5197
5198   mp->entry.bd_id = ntohl (bd_id);
5199   mp->is_add = is_add;
5200
5201   clib_memcpy (&mp->entry.ip, &ip, sizeof (ip));
5202   clib_memcpy (&mp->entry.mac, &mac, sizeof (mac));
5203
5204   S (mp);
5205   W (ret);
5206   return ret;
5207 }
5208
5209 static int
5210 api_bd_ip_mac_flush (vat_main_t * vam)
5211 {
5212   unformat_input_t *i = vam->input;
5213   vl_api_bd_ip_mac_flush_t *mp;
5214   u32 bd_id;
5215   u8 bd_id_set = 0;
5216   int ret;
5217
5218   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5219     {
5220       if (unformat (i, "bd_id %d", &bd_id))
5221         {
5222           bd_id_set++;
5223         }
5224       else
5225         break;
5226     }
5227
5228   if (bd_id_set == 0)
5229     {
5230       errmsg ("missing bridge domain");
5231       return -99;
5232     }
5233
5234   M (BD_IP_MAC_FLUSH, mp);
5235
5236   mp->bd_id = ntohl (bd_id);
5237
5238   S (mp);
5239   W (ret);
5240   return ret;
5241 }
5242
5243 static void vl_api_bd_ip_mac_details_t_handler
5244   (vl_api_bd_ip_mac_details_t * mp)
5245 {
5246   vat_main_t *vam = &vat_main;
5247
5248   print (vam->ofp,
5249          "\n%-5d %U %U",
5250          ntohl (mp->entry.bd_id),
5251          format_vl_api_mac_address, mp->entry.mac,
5252          format_vl_api_address, &mp->entry.ip);
5253 }
5254
5255 static void vl_api_bd_ip_mac_details_t_handler_json
5256   (vl_api_bd_ip_mac_details_t * mp)
5257 {
5258   vat_main_t *vam = &vat_main;
5259   vat_json_node_t *node = NULL;
5260
5261   if (VAT_JSON_ARRAY != vam->json_tree.type)
5262     {
5263       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5264       vat_json_init_array (&vam->json_tree);
5265     }
5266   node = vat_json_array_add (&vam->json_tree);
5267
5268   vat_json_init_object (node);
5269   vat_json_object_add_uint (node, "bd_id", ntohl (mp->entry.bd_id));
5270   vat_json_object_add_string_copy (node, "mac_address",
5271                                    format (0, "%U", format_vl_api_mac_address,
5272                                            &mp->entry.mac));
5273   u8 *ip = 0;
5274
5275   ip = format (0, "%U", format_vl_api_address, &mp->entry.ip);
5276   vat_json_object_add_string_copy (node, "ip_address", ip);
5277   vec_free (ip);
5278 }
5279
5280 static int
5281 api_bd_ip_mac_dump (vat_main_t * vam)
5282 {
5283   unformat_input_t *i = vam->input;
5284   vl_api_bd_ip_mac_dump_t *mp;
5285   vl_api_control_ping_t *mp_ping;
5286   int ret;
5287   u32 bd_id;
5288   u8 bd_id_set = 0;
5289
5290   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5291     {
5292       if (unformat (i, "bd_id %d", &bd_id))
5293         {
5294           bd_id_set++;
5295         }
5296       else
5297         break;
5298     }
5299
5300   print (vam->ofp,
5301          "\n%-5s %-7s %-20s %-30s",
5302          "bd_id", "is_ipv6", "mac_address", "ip_address");
5303
5304   /* Dump Bridge Domain Ip to Mac entries */
5305   M (BD_IP_MAC_DUMP, mp);
5306
5307   if (bd_id_set)
5308     mp->bd_id = htonl (bd_id);
5309   else
5310     mp->bd_id = ~0;
5311
5312   S (mp);
5313
5314   /* Use a control ping for synchronization */
5315   MPING (CONTROL_PING, mp_ping);
5316   S (mp_ping);
5317
5318   W (ret);
5319   return ret;
5320 }
5321
5322 static int
5323 api_tap_create_v2 (vat_main_t * vam)
5324 {
5325   unformat_input_t *i = vam->input;
5326   vl_api_tap_create_v2_t *mp;
5327   u8 mac_address[6];
5328   u8 random_mac = 1;
5329   u32 id = ~0;
5330   u32 num_rx_queues = 0;
5331   u8 *host_if_name = 0;
5332   u8 host_if_name_set = 0;
5333   u8 *host_ns = 0;
5334   u8 host_ns_set = 0;
5335   u8 host_mac_addr[6];
5336   u8 host_mac_addr_set = 0;
5337   u8 *host_bridge = 0;
5338   u8 host_bridge_set = 0;
5339   u8 host_ip4_prefix_set = 0;
5340   u8 host_ip6_prefix_set = 0;
5341   ip4_address_t host_ip4_addr;
5342   ip4_address_t host_ip4_gw;
5343   u8 host_ip4_gw_set = 0;
5344   u32 host_ip4_prefix_len = 0;
5345   ip6_address_t host_ip6_addr;
5346   ip6_address_t host_ip6_gw;
5347   u8 host_ip6_gw_set = 0;
5348   u32 host_ip6_prefix_len = 0;
5349   u32 host_mtu_size = 0;
5350   u8 host_mtu_set = 0;
5351   u32 tap_flags = 0;
5352   int ret;
5353   u32 rx_ring_sz = 0, tx_ring_sz = 0;
5354
5355   clib_memset (mac_address, 0, sizeof (mac_address));
5356
5357   /* Parse args required to build the message */
5358   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5359     {
5360       if (unformat (i, "id %u", &id))
5361         ;
5362       else
5363         if (unformat
5364             (i, "hw-addr %U", unformat_ethernet_address, mac_address))
5365         random_mac = 0;
5366       else if (unformat (i, "host-if-name %s", &host_if_name))
5367         host_if_name_set = 1;
5368       else if (unformat (i, "num-rx-queues %u", &num_rx_queues))
5369         ;
5370       else if (unformat (i, "host-ns %s", &host_ns))
5371         host_ns_set = 1;
5372       else if (unformat (i, "host-mac-addr %U", unformat_ethernet_address,
5373                          host_mac_addr))
5374         host_mac_addr_set = 1;
5375       else if (unformat (i, "host-bridge %s", &host_bridge))
5376         host_bridge_set = 1;
5377       else if (unformat (i, "host-ip4-addr %U/%u", unformat_ip4_address,
5378                          &host_ip4_addr, &host_ip4_prefix_len))
5379         host_ip4_prefix_set = 1;
5380       else if (unformat (i, "host-ip6-addr %U/%u", unformat_ip6_address,
5381                          &host_ip6_addr, &host_ip6_prefix_len))
5382         host_ip6_prefix_set = 1;
5383       else if (unformat (i, "host-ip4-gw %U", unformat_ip4_address,
5384                          &host_ip4_gw))
5385         host_ip4_gw_set = 1;
5386       else if (unformat (i, "host-ip6-gw %U", unformat_ip6_address,
5387                          &host_ip6_gw))
5388         host_ip6_gw_set = 1;
5389       else if (unformat (i, "rx-ring-size %u", &rx_ring_sz))
5390         ;
5391       else if (unformat (i, "tx-ring-size %u", &tx_ring_sz))
5392         ;
5393       else if (unformat (i, "host-mtu-size %u", &host_mtu_size))
5394         host_mtu_set = 1;
5395       else if (unformat (i, "no-gso"))
5396         tap_flags &= ~TAP_API_FLAG_GSO;
5397       else if (unformat (i, "gso"))
5398         tap_flags |= TAP_API_FLAG_GSO;
5399       else if (unformat (i, "csum-offload"))
5400         tap_flags |= TAP_API_FLAG_CSUM_OFFLOAD;
5401       else if (unformat (i, "persist"))
5402         tap_flags |= TAP_API_FLAG_PERSIST;
5403       else if (unformat (i, "attach"))
5404         tap_flags |= TAP_API_FLAG_ATTACH;
5405       else if (unformat (i, "tun"))
5406         tap_flags |= TAP_API_FLAG_TUN;
5407       else if (unformat (i, "gro-coalesce"))
5408         tap_flags |= TAP_API_FLAG_GRO_COALESCE;
5409       else if (unformat (i, "packed"))
5410         tap_flags |= TAP_API_FLAG_PACKED;
5411       else if (unformat (i, "in-order"))
5412         tap_flags |= TAP_API_FLAG_IN_ORDER;
5413       else
5414         break;
5415     }
5416
5417   if (vec_len (host_if_name) > 63)
5418     {
5419       errmsg ("tap name too long. ");
5420       return -99;
5421     }
5422   if (vec_len (host_ns) > 63)
5423     {
5424       errmsg ("host name space too long. ");
5425       return -99;
5426     }
5427   if (vec_len (host_bridge) > 63)
5428     {
5429       errmsg ("host bridge name too long. ");
5430       return -99;
5431     }
5432   if (host_ip4_prefix_len > 32)
5433     {
5434       errmsg ("host ip4 prefix length not valid. ");
5435       return -99;
5436     }
5437   if (host_ip6_prefix_len > 128)
5438     {
5439       errmsg ("host ip6 prefix length not valid. ");
5440       return -99;
5441     }
5442   if (!is_pow2 (rx_ring_sz))
5443     {
5444       errmsg ("rx ring size must be power of 2. ");
5445       return -99;
5446     }
5447   if (rx_ring_sz > 32768)
5448     {
5449       errmsg ("rx ring size must be 32768 or lower. ");
5450       return -99;
5451     }
5452   if (!is_pow2 (tx_ring_sz))
5453     {
5454       errmsg ("tx ring size must be power of 2. ");
5455       return -99;
5456     }
5457   if (tx_ring_sz > 32768)
5458     {
5459       errmsg ("tx ring size must be 32768 or lower. ");
5460       return -99;
5461     }
5462   if (host_mtu_set && (host_mtu_size < 64 || host_mtu_size > 65355))
5463     {
5464       errmsg ("host MTU size must be in between 64 and 65355. ");
5465       return -99;
5466     }
5467
5468   /* Construct the API message */
5469   M (TAP_CREATE_V2, mp);
5470
5471   mp->id = ntohl (id);
5472   mp->use_random_mac = random_mac;
5473   mp->num_rx_queues = (u8) num_rx_queues;
5474   mp->tx_ring_sz = ntohs (tx_ring_sz);
5475   mp->rx_ring_sz = ntohs (rx_ring_sz);
5476   mp->host_mtu_set = host_mtu_set;
5477   mp->host_mtu_size = ntohl (host_mtu_size);
5478   mp->host_mac_addr_set = host_mac_addr_set;
5479   mp->host_ip4_prefix_set = host_ip4_prefix_set;
5480   mp->host_ip6_prefix_set = host_ip6_prefix_set;
5481   mp->host_ip4_gw_set = host_ip4_gw_set;
5482   mp->host_ip6_gw_set = host_ip6_gw_set;
5483   mp->tap_flags = ntohl (tap_flags);
5484   mp->host_namespace_set = host_ns_set;
5485   mp->host_if_name_set = host_if_name_set;
5486   mp->host_bridge_set = host_bridge_set;
5487
5488   if (random_mac == 0)
5489     clib_memcpy (mp->mac_address, mac_address, 6);
5490   if (host_mac_addr_set)
5491     clib_memcpy (mp->host_mac_addr, host_mac_addr, 6);
5492   if (host_if_name_set)
5493     clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
5494   if (host_ns_set)
5495     clib_memcpy (mp->host_namespace, host_ns, vec_len (host_ns));
5496   if (host_bridge_set)
5497     clib_memcpy (mp->host_bridge, host_bridge, vec_len (host_bridge));
5498   if (host_ip4_prefix_set)
5499     {
5500       clib_memcpy (mp->host_ip4_prefix.address, &host_ip4_addr, 4);
5501       mp->host_ip4_prefix.len = (u8) host_ip4_prefix_len;
5502     }
5503   if (host_ip6_prefix_set)
5504     {
5505       clib_memcpy (mp->host_ip6_prefix.address, &host_ip6_addr, 16);
5506       mp->host_ip6_prefix.len = (u8) host_ip6_prefix_len;
5507     }
5508   if (host_ip4_gw_set)
5509     clib_memcpy (mp->host_ip4_gw, &host_ip4_gw, 4);
5510   if (host_ip6_gw_set)
5511     clib_memcpy (mp->host_ip6_gw, &host_ip6_gw, 16);
5512
5513   vec_free (host_ns);
5514   vec_free (host_if_name);
5515   vec_free (host_bridge);
5516
5517   /* send it... */
5518   S (mp);
5519
5520   /* Wait for a reply... */
5521   W (ret);
5522   return ret;
5523 }
5524
5525 static int
5526 api_tap_delete_v2 (vat_main_t * vam)
5527 {
5528   unformat_input_t *i = vam->input;
5529   vl_api_tap_delete_v2_t *mp;
5530   u32 sw_if_index = ~0;
5531   u8 sw_if_index_set = 0;
5532   int ret;
5533
5534   /* Parse args required to build the message */
5535   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5536     {
5537       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5538         sw_if_index_set = 1;
5539       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5540         sw_if_index_set = 1;
5541       else
5542         break;
5543     }
5544
5545   if (sw_if_index_set == 0)
5546     {
5547       errmsg ("missing vpp interface name. ");
5548       return -99;
5549     }
5550
5551   /* Construct the API message */
5552   M (TAP_DELETE_V2, mp);
5553
5554   mp->sw_if_index = ntohl (sw_if_index);
5555
5556   /* send it... */
5557   S (mp);
5558
5559   /* Wait for a reply... */
5560   W (ret);
5561   return ret;
5562 }
5563
5564 uword
5565 unformat_vlib_pci_addr (unformat_input_t * input, va_list * args)
5566 {
5567   vlib_pci_addr_t *addr = va_arg (*args, vlib_pci_addr_t *);
5568   u32 x[4];
5569
5570   if (!unformat (input, "%x:%x:%x.%x", &x[0], &x[1], &x[2], &x[3]))
5571     return 0;
5572
5573   addr->domain = x[0];
5574   addr->bus = x[1];
5575   addr->slot = x[2];
5576   addr->function = x[3];
5577
5578   return 1;
5579 }
5580
5581 static int
5582 api_virtio_pci_create_v2 (vat_main_t * vam)
5583 {
5584   unformat_input_t *i = vam->input;
5585   vl_api_virtio_pci_create_v2_t *mp;
5586   u8 mac_address[6];
5587   u8 random_mac = 1;
5588   u32 pci_addr = 0;
5589   u64 features = (u64) ~ (0ULL);
5590   u32 virtio_flags = 0;
5591   int ret;
5592
5593   clib_memset (mac_address, 0, sizeof (mac_address));
5594
5595   /* Parse args required to build the message */
5596   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5597     {
5598       if (unformat (i, "hw-addr %U", unformat_ethernet_address, mac_address))
5599         {
5600           random_mac = 0;
5601         }
5602       else if (unformat (i, "pci-addr %U", unformat_vlib_pci_addr, &pci_addr))
5603         ;
5604       else if (unformat (i, "features 0x%llx", &features))
5605         ;
5606       else if (unformat (i, "gso-enabled"))
5607         virtio_flags |= VIRTIO_API_FLAG_GSO;
5608       else if (unformat (i, "csum-offload-enabled"))
5609         virtio_flags |= VIRTIO_API_FLAG_CSUM_OFFLOAD;
5610       else if (unformat (i, "gro-coalesce"))
5611         virtio_flags |= VIRTIO_API_FLAG_GRO_COALESCE;
5612       else if (unformat (i, "packed"))
5613         virtio_flags |= VIRTIO_API_FLAG_PACKED;
5614       else if (unformat (i, "in-order"))
5615         virtio_flags |= VIRTIO_API_FLAG_IN_ORDER;
5616       else if (unformat (i, "buffering"))
5617         virtio_flags |= VIRTIO_API_FLAG_BUFFERING;
5618       else
5619         break;
5620     }
5621
5622   if (pci_addr == 0)
5623     {
5624       errmsg ("pci address must be non zero. ");
5625       return -99;
5626     }
5627
5628   /* Construct the API message */
5629   M (VIRTIO_PCI_CREATE_V2, mp);
5630
5631   mp->use_random_mac = random_mac;
5632
5633   mp->pci_addr.domain = htons (((vlib_pci_addr_t) pci_addr).domain);
5634   mp->pci_addr.bus = ((vlib_pci_addr_t) pci_addr).bus;
5635   mp->pci_addr.slot = ((vlib_pci_addr_t) pci_addr).slot;
5636   mp->pci_addr.function = ((vlib_pci_addr_t) pci_addr).function;
5637
5638   mp->features = clib_host_to_net_u64 (features);
5639   mp->virtio_flags = clib_host_to_net_u32 (virtio_flags);
5640
5641   if (random_mac == 0)
5642     clib_memcpy (mp->mac_address, mac_address, 6);
5643
5644   /* send it... */
5645   S (mp);
5646
5647   /* Wait for a reply... */
5648   W (ret);
5649   return ret;
5650 }
5651
5652 static int
5653 api_virtio_pci_delete (vat_main_t * vam)
5654 {
5655   unformat_input_t *i = vam->input;
5656   vl_api_virtio_pci_delete_t *mp;
5657   u32 sw_if_index = ~0;
5658   u8 sw_if_index_set = 0;
5659   int ret;
5660
5661   /* Parse args required to build the message */
5662   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5663     {
5664       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5665         sw_if_index_set = 1;
5666       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5667         sw_if_index_set = 1;
5668       else
5669         break;
5670     }
5671
5672   if (sw_if_index_set == 0)
5673     {
5674       errmsg ("missing vpp interface name. ");
5675       return -99;
5676     }
5677
5678   /* Construct the API message */
5679   M (VIRTIO_PCI_DELETE, mp);
5680
5681   mp->sw_if_index = htonl (sw_if_index);
5682
5683   /* send it... */
5684   S (mp);
5685
5686   /* Wait for a reply... */
5687   W (ret);
5688   return ret;
5689 }
5690
5691 static int
5692 api_bond_create (vat_main_t * vam)
5693 {
5694   unformat_input_t *i = vam->input;
5695   vl_api_bond_create_t *mp;
5696   u8 mac_address[6];
5697   u8 custom_mac = 0;
5698   int ret;
5699   u8 mode;
5700   u8 lb;
5701   u8 mode_is_set = 0;
5702   u32 id = ~0;
5703   u8 numa_only = 0;
5704
5705   clib_memset (mac_address, 0, sizeof (mac_address));
5706   lb = BOND_LB_L2;
5707
5708   /* Parse args required to build the message */
5709   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5710     {
5711       if (unformat (i, "mode %U", unformat_bond_mode, &mode))
5712         mode_is_set = 1;
5713       else if (((mode == BOND_MODE_LACP) || (mode == BOND_MODE_XOR))
5714                && unformat (i, "lb %U", unformat_bond_load_balance, &lb))
5715         ;
5716       else if (unformat (i, "hw-addr %U", unformat_ethernet_address,
5717                          mac_address))
5718         custom_mac = 1;
5719       else if (unformat (i, "numa-only"))
5720         numa_only = 1;
5721       else if (unformat (i, "id %u", &id))
5722         ;
5723       else
5724         break;
5725     }
5726
5727   if (mode_is_set == 0)
5728     {
5729       errmsg ("Missing bond mode. ");
5730       return -99;
5731     }
5732
5733   /* Construct the API message */
5734   M (BOND_CREATE, mp);
5735
5736   mp->use_custom_mac = custom_mac;
5737
5738   mp->mode = htonl (mode);
5739   mp->lb = htonl (lb);
5740   mp->id = htonl (id);
5741   mp->numa_only = numa_only;
5742
5743   if (custom_mac)
5744     clib_memcpy (mp->mac_address, mac_address, 6);
5745
5746   /* send it... */
5747   S (mp);
5748
5749   /* Wait for a reply... */
5750   W (ret);
5751   return ret;
5752 }
5753
5754 static int
5755 api_bond_create2 (vat_main_t * vam)
5756 {
5757   unformat_input_t *i = vam->input;
5758   vl_api_bond_create2_t *mp;
5759   u8 mac_address[6];
5760   u8 custom_mac = 0;
5761   int ret;
5762   u8 mode;
5763   u8 lb;
5764   u8 mode_is_set = 0;
5765   u32 id = ~0;
5766   u8 numa_only = 0;
5767   u8 gso = 0;
5768
5769   clib_memset (mac_address, 0, sizeof (mac_address));
5770   lb = BOND_LB_L2;
5771
5772   /* Parse args required to build the message */
5773   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5774     {
5775       if (unformat (i, "mode %U", unformat_bond_mode, &mode))
5776         mode_is_set = 1;
5777       else if (((mode == BOND_MODE_LACP) || (mode == BOND_MODE_XOR))
5778                && unformat (i, "lb %U", unformat_bond_load_balance, &lb))
5779         ;
5780       else if (unformat (i, "hw-addr %U", unformat_ethernet_address,
5781                          mac_address))
5782         custom_mac = 1;
5783       else if (unformat (i, "numa-only"))
5784         numa_only = 1;
5785       else if (unformat (i, "gso"))
5786         gso = 1;
5787       else if (unformat (i, "id %u", &id))
5788         ;
5789       else
5790         break;
5791     }
5792
5793   if (mode_is_set == 0)
5794     {
5795       errmsg ("Missing bond mode. ");
5796       return -99;
5797     }
5798
5799   /* Construct the API message */
5800   M (BOND_CREATE2, mp);
5801
5802   mp->use_custom_mac = custom_mac;
5803
5804   mp->mode = htonl (mode);
5805   mp->lb = htonl (lb);
5806   mp->id = htonl (id);
5807   mp->numa_only = numa_only;
5808   mp->enable_gso = gso;
5809
5810   if (custom_mac)
5811     clib_memcpy (mp->mac_address, mac_address, 6);
5812
5813   /* send it... */
5814   S (mp);
5815
5816   /* Wait for a reply... */
5817   W (ret);
5818   return ret;
5819 }
5820
5821 static int
5822 api_bond_delete (vat_main_t * vam)
5823 {
5824   unformat_input_t *i = vam->input;
5825   vl_api_bond_delete_t *mp;
5826   u32 sw_if_index = ~0;
5827   u8 sw_if_index_set = 0;
5828   int ret;
5829
5830   /* Parse args required to build the message */
5831   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5832     {
5833       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5834         sw_if_index_set = 1;
5835       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5836         sw_if_index_set = 1;
5837       else
5838         break;
5839     }
5840
5841   if (sw_if_index_set == 0)
5842     {
5843       errmsg ("missing vpp interface name. ");
5844       return -99;
5845     }
5846
5847   /* Construct the API message */
5848   M (BOND_DELETE, mp);
5849
5850   mp->sw_if_index = ntohl (sw_if_index);
5851
5852   /* send it... */
5853   S (mp);
5854
5855   /* Wait for a reply... */
5856   W (ret);
5857   return ret;
5858 }
5859
5860 static int
5861 api_bond_add_member (vat_main_t * vam)
5862 {
5863   unformat_input_t *i = vam->input;
5864   vl_api_bond_add_member_t *mp;
5865   u32 bond_sw_if_index;
5866   int ret;
5867   u8 is_passive;
5868   u8 is_long_timeout;
5869   u32 bond_sw_if_index_is_set = 0;
5870   u32 sw_if_index;
5871   u8 sw_if_index_is_set = 0;
5872
5873   /* Parse args required to build the message */
5874   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5875     {
5876       if (unformat (i, "sw_if_index %d", &sw_if_index))
5877         sw_if_index_is_set = 1;
5878       else if (unformat (i, "bond %u", &bond_sw_if_index))
5879         bond_sw_if_index_is_set = 1;
5880       else if (unformat (i, "passive %d", &is_passive))
5881         ;
5882       else if (unformat (i, "long-timeout %d", &is_long_timeout))
5883         ;
5884       else
5885         break;
5886     }
5887
5888   if (bond_sw_if_index_is_set == 0)
5889     {
5890       errmsg ("Missing bond sw_if_index. ");
5891       return -99;
5892     }
5893   if (sw_if_index_is_set == 0)
5894     {
5895       errmsg ("Missing member sw_if_index. ");
5896       return -99;
5897     }
5898
5899   /* Construct the API message */
5900   M (BOND_ADD_MEMBER, mp);
5901
5902   mp->bond_sw_if_index = ntohl (bond_sw_if_index);
5903   mp->sw_if_index = ntohl (sw_if_index);
5904   mp->is_long_timeout = is_long_timeout;
5905   mp->is_passive = is_passive;
5906
5907   /* send it... */
5908   S (mp);
5909
5910   /* Wait for a reply... */
5911   W (ret);
5912   return ret;
5913 }
5914
5915 static int
5916 api_bond_detach_member (vat_main_t * vam)
5917 {
5918   unformat_input_t *i = vam->input;
5919   vl_api_bond_detach_member_t *mp;
5920   u32 sw_if_index = ~0;
5921   u8 sw_if_index_set = 0;
5922   int ret;
5923
5924   /* Parse args required to build the message */
5925   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5926     {
5927       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5928         sw_if_index_set = 1;
5929       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5930         sw_if_index_set = 1;
5931       else
5932         break;
5933     }
5934
5935   if (sw_if_index_set == 0)
5936     {
5937       errmsg ("missing vpp interface name. ");
5938       return -99;
5939     }
5940
5941   /* Construct the API message */
5942   M (BOND_DETACH_MEMBER, mp);
5943
5944   mp->sw_if_index = ntohl (sw_if_index);
5945
5946   /* send it... */
5947   S (mp);
5948
5949   /* Wait for a reply... */
5950   W (ret);
5951   return ret;
5952 }
5953
5954 static int
5955 api_ip_table_add_del (vat_main_t * vam)
5956 {
5957   unformat_input_t *i = vam->input;
5958   vl_api_ip_table_add_del_t *mp;
5959   u32 table_id = ~0;
5960   u8 is_ipv6 = 0;
5961   u8 is_add = 1;
5962   int ret = 0;
5963
5964   /* Parse args required to build the message */
5965   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5966     {
5967       if (unformat (i, "ipv6"))
5968         is_ipv6 = 1;
5969       else if (unformat (i, "del"))
5970         is_add = 0;
5971       else if (unformat (i, "add"))
5972         is_add = 1;
5973       else if (unformat (i, "table %d", &table_id))
5974         ;
5975       else
5976         {
5977           clib_warning ("parse error '%U'", format_unformat_error, i);
5978           return -99;
5979         }
5980     }
5981
5982   if (~0 == table_id)
5983     {
5984       errmsg ("missing table-ID");
5985       return -99;
5986     }
5987
5988   /* Construct the API message */
5989   M (IP_TABLE_ADD_DEL, mp);
5990
5991   mp->table.table_id = ntohl (table_id);
5992   mp->table.is_ip6 = is_ipv6;
5993   mp->is_add = is_add;
5994
5995   /* send it... */
5996   S (mp);
5997
5998   /* Wait for a reply... */
5999   W (ret);
6000
6001   return ret;
6002 }
6003
6004 uword
6005 unformat_fib_path (unformat_input_t * input, va_list * args)
6006 {
6007   vat_main_t *vam = va_arg (*args, vat_main_t *);
6008   vl_api_fib_path_t *path = va_arg (*args, vl_api_fib_path_t *);
6009   u32 weight, preference;
6010   mpls_label_t out_label;
6011
6012   clib_memset (path, 0, sizeof (*path));
6013   path->weight = 1;
6014   path->sw_if_index = ~0;
6015   path->rpf_id = ~0;
6016   path->n_labels = 0;
6017
6018   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
6019     {
6020       if (unformat (input, "%U %U",
6021                     unformat_vl_api_ip4_address,
6022                     &path->nh.address.ip4,
6023                     api_unformat_sw_if_index, vam, &path->sw_if_index))
6024         {
6025           path->proto = FIB_API_PATH_NH_PROTO_IP4;
6026         }
6027       else if (unformat (input, "%U %U",
6028                          unformat_vl_api_ip6_address,
6029                          &path->nh.address.ip6,
6030                          api_unformat_sw_if_index, vam, &path->sw_if_index))
6031         {
6032           path->proto = FIB_API_PATH_NH_PROTO_IP6;
6033         }
6034       else if (unformat (input, "weight %u", &weight))
6035         {
6036           path->weight = weight;
6037         }
6038       else if (unformat (input, "preference %u", &preference))
6039         {
6040           path->preference = preference;
6041         }
6042       else if (unformat (input, "%U next-hop-table %d",
6043                          unformat_vl_api_ip4_address,
6044                          &path->nh.address.ip4, &path->table_id))
6045         {
6046           path->proto = FIB_API_PATH_NH_PROTO_IP4;
6047         }
6048       else if (unformat (input, "%U next-hop-table %d",
6049                          unformat_vl_api_ip6_address,
6050                          &path->nh.address.ip6, &path->table_id))
6051         {
6052           path->proto = FIB_API_PATH_NH_PROTO_IP6;
6053         }
6054       else if (unformat (input, "%U",
6055                          unformat_vl_api_ip4_address, &path->nh.address.ip4))
6056         {
6057           /*
6058            * the recursive next-hops are by default in the default table
6059            */
6060           path->table_id = 0;
6061           path->sw_if_index = ~0;
6062           path->proto = FIB_API_PATH_NH_PROTO_IP4;
6063         }
6064       else if (unformat (input, "%U",
6065                          unformat_vl_api_ip6_address, &path->nh.address.ip6))
6066         {
6067           /*
6068            * the recursive next-hops are by default in the default table
6069            */
6070           path->table_id = 0;
6071           path->sw_if_index = ~0;
6072           path->proto = FIB_API_PATH_NH_PROTO_IP6;
6073         }
6074       else if (unformat (input, "resolve-via-host"))
6075         {
6076           path->flags |= FIB_API_PATH_FLAG_RESOLVE_VIA_HOST;
6077         }
6078       else if (unformat (input, "resolve-via-attached"))
6079         {
6080           path->flags |= FIB_API_PATH_FLAG_RESOLVE_VIA_ATTACHED;
6081         }
6082       else if (unformat (input, "ip4-lookup-in-table %d", &path->table_id))
6083         {
6084           path->type = FIB_API_PATH_TYPE_LOCAL;
6085           path->sw_if_index = ~0;
6086           path->proto = FIB_API_PATH_NH_PROTO_IP4;
6087         }
6088       else if (unformat (input, "ip6-lookup-in-table %d", &path->table_id))
6089         {
6090           path->type = FIB_API_PATH_TYPE_LOCAL;
6091           path->sw_if_index = ~0;
6092           path->proto = FIB_API_PATH_NH_PROTO_IP6;
6093         }
6094       else if (unformat (input, "sw_if_index %d", &path->sw_if_index))
6095         ;
6096       else if (unformat (input, "via-label %d", &path->nh.via_label))
6097         {
6098           path->proto = FIB_API_PATH_NH_PROTO_MPLS;
6099           path->sw_if_index = ~0;
6100         }
6101       else if (unformat (input, "l2-input-on %d", &path->sw_if_index))
6102         {
6103           path->proto = FIB_API_PATH_NH_PROTO_ETHERNET;
6104           path->type = FIB_API_PATH_TYPE_INTERFACE_RX;
6105         }
6106       else if (unformat (input, "local"))
6107         {
6108           path->type = FIB_API_PATH_TYPE_LOCAL;
6109         }
6110       else if (unformat (input, "out-labels"))
6111         {
6112           while (unformat (input, "%d", &out_label))
6113             {
6114               path->label_stack[path->n_labels].label = out_label;
6115               path->label_stack[path->n_labels].is_uniform = 0;
6116               path->label_stack[path->n_labels].ttl = 64;
6117               path->n_labels++;
6118             }
6119         }
6120       else if (unformat (input, "via"))
6121         {
6122           /* new path, back up and return */
6123           unformat_put_input (input);
6124           unformat_put_input (input);
6125           unformat_put_input (input);
6126           unformat_put_input (input);
6127           break;
6128         }
6129       else
6130         {
6131           return (0);
6132         }
6133     }
6134
6135   path->proto = ntohl (path->proto);
6136   path->type = ntohl (path->type);
6137   path->flags = ntohl (path->flags);
6138   path->table_id = ntohl (path->table_id);
6139   path->sw_if_index = ntohl (path->sw_if_index);
6140
6141   return (1);
6142 }
6143
6144 static int
6145 api_ip_route_add_del (vat_main_t * vam)
6146 {
6147   unformat_input_t *i = vam->input;
6148   vl_api_ip_route_add_del_t *mp;
6149   u32 vrf_id = 0;
6150   u8 is_add = 1;
6151   u8 is_multipath = 0;
6152   u8 prefix_set = 0;
6153   u8 path_count = 0;
6154   vl_api_prefix_t pfx = { };
6155   vl_api_fib_path_t paths[8];
6156   int count = 1;
6157   int j;
6158   f64 before = 0;
6159   u32 random_add_del = 0;
6160   u32 *random_vector = 0;
6161   u32 random_seed = 0xdeaddabe;
6162
6163   /* Parse args required to build the message */
6164   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6165     {
6166       if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
6167         prefix_set = 1;
6168       else if (unformat (i, "del"))
6169         is_add = 0;
6170       else if (unformat (i, "add"))
6171         is_add = 1;
6172       else if (unformat (i, "vrf %d", &vrf_id))
6173         ;
6174       else if (unformat (i, "count %d", &count))
6175         ;
6176       else if (unformat (i, "random"))
6177         random_add_del = 1;
6178       else if (unformat (i, "multipath"))
6179         is_multipath = 1;
6180       else if (unformat (i, "seed %d", &random_seed))
6181         ;
6182       else
6183         if (unformat
6184             (i, "via %U", unformat_fib_path, vam, &paths[path_count]))
6185         {
6186           path_count++;
6187           if (8 == path_count)
6188             {
6189               errmsg ("max 8 paths");
6190               return -99;
6191             }
6192         }
6193       else
6194         {
6195           clib_warning ("parse error '%U'", format_unformat_error, i);
6196           return -99;
6197         }
6198     }
6199
6200   if (!path_count)
6201     {
6202       errmsg ("specify a path; via ...");
6203       return -99;
6204     }
6205   if (prefix_set == 0)
6206     {
6207       errmsg ("missing prefix");
6208       return -99;
6209     }
6210
6211   /* Generate a pile of unique, random routes */
6212   if (random_add_del)
6213     {
6214       ip4_address_t *i = (ip4_address_t *) & paths[0].nh.address.ip4;
6215       u32 this_random_address;
6216       uword *random_hash;
6217
6218       random_hash = hash_create (count, sizeof (uword));
6219
6220       hash_set (random_hash, i->as_u32, 1);
6221       for (j = 0; j <= count; j++)
6222         {
6223           do
6224             {
6225               this_random_address = random_u32 (&random_seed);
6226               this_random_address =
6227                 clib_host_to_net_u32 (this_random_address);
6228             }
6229           while (hash_get (random_hash, this_random_address));
6230           vec_add1 (random_vector, this_random_address);
6231           hash_set (random_hash, this_random_address, 1);
6232         }
6233       hash_free (random_hash);
6234       set_ip4_address (&pfx.address, random_vector[0]);
6235     }
6236
6237   if (count > 1)
6238     {
6239       /* Turn on async mode */
6240       vam->async_mode = 1;
6241       vam->async_errors = 0;
6242       before = vat_time_now (vam);
6243     }
6244
6245   for (j = 0; j < count; j++)
6246     {
6247       /* Construct the API message */
6248       M2 (IP_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t) * path_count);
6249
6250       mp->is_add = is_add;
6251       mp->is_multipath = is_multipath;
6252
6253       clib_memcpy (&mp->route.prefix, &pfx, sizeof (pfx));
6254       mp->route.table_id = ntohl (vrf_id);
6255       mp->route.n_paths = path_count;
6256
6257       clib_memcpy (&mp->route.paths, &paths, sizeof (paths[0]) * path_count);
6258
6259       if (random_add_del)
6260         set_ip4_address (&pfx.address, random_vector[j + 1]);
6261       else
6262         increment_address (&pfx.address);
6263       /* send it... */
6264       S (mp);
6265       /* If we receive SIGTERM, stop now... */
6266       if (vam->do_exit)
6267         break;
6268     }
6269
6270   /* When testing multiple add/del ops, use a control-ping to sync */
6271   if (count > 1)
6272     {
6273       vl_api_control_ping_t *mp_ping;
6274       f64 after;
6275       f64 timeout;
6276
6277       /* Shut off async mode */
6278       vam->async_mode = 0;
6279
6280       MPING (CONTROL_PING, mp_ping);
6281       S (mp_ping);
6282
6283       timeout = vat_time_now (vam) + 1.0;
6284       while (vat_time_now (vam) < timeout)
6285         if (vam->result_ready == 1)
6286           goto out;
6287       vam->retval = -99;
6288
6289     out:
6290       if (vam->retval == -99)
6291         errmsg ("timeout");
6292
6293       if (vam->async_errors > 0)
6294         {
6295           errmsg ("%d asynchronous errors", vam->async_errors);
6296           vam->retval = -98;
6297         }
6298       vam->async_errors = 0;
6299       after = vat_time_now (vam);
6300
6301       /* slim chance, but we might have eaten SIGTERM on the first iteration */
6302       if (j > 0)
6303         count = j;
6304
6305       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
6306              count, after - before, count / (after - before));
6307     }
6308   else
6309     {
6310       int ret;
6311
6312       /* Wait for a reply... */
6313       W (ret);
6314       return ret;
6315     }
6316
6317   /* Return the good/bad news */
6318   return (vam->retval);
6319 }
6320
6321 static int
6322 api_ip_mroute_add_del (vat_main_t * vam)
6323 {
6324   unformat_input_t *i = vam->input;
6325   u8 path_set = 0, prefix_set = 0, is_add = 1;
6326   vl_api_ip_mroute_add_del_t *mp;
6327   mfib_entry_flags_t eflags = 0;
6328   vl_api_mfib_path_t path;
6329   vl_api_mprefix_t pfx = { };
6330   u32 vrf_id = 0;
6331   int ret;
6332
6333   /* Parse args required to build the message */
6334   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6335     {
6336       if (unformat (i, "%U", unformat_vl_api_mprefix, &pfx))
6337         {
6338           prefix_set = 1;
6339           pfx.grp_address_length = htons (pfx.grp_address_length);
6340         }
6341       else if (unformat (i, "del"))
6342         is_add = 0;
6343       else if (unformat (i, "add"))
6344         is_add = 1;
6345       else if (unformat (i, "vrf %d", &vrf_id))
6346         ;
6347       else if (unformat (i, "%U", unformat_mfib_itf_flags, &path.itf_flags))
6348         path.itf_flags = htonl (path.itf_flags);
6349       else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
6350         ;
6351       else if (unformat (i, "via %U", unformat_fib_path, vam, &path.path))
6352         path_set = 1;
6353       else
6354         {
6355           clib_warning ("parse error '%U'", format_unformat_error, i);
6356           return -99;
6357         }
6358     }
6359
6360   if (prefix_set == 0)
6361     {
6362       errmsg ("missing addresses\n");
6363       return -99;
6364     }
6365   if (path_set == 0)
6366     {
6367       errmsg ("missing path\n");
6368       return -99;
6369     }
6370
6371   /* Construct the API message */
6372   M (IP_MROUTE_ADD_DEL, mp);
6373
6374   mp->is_add = is_add;
6375   mp->is_multipath = 1;
6376
6377   clib_memcpy (&mp->route.prefix, &pfx, sizeof (pfx));
6378   mp->route.table_id = htonl (vrf_id);
6379   mp->route.n_paths = 1;
6380   mp->route.entry_flags = htonl (eflags);
6381
6382   clib_memcpy (&mp->route.paths, &path, sizeof (path));
6383
6384   /* send it... */
6385   S (mp);
6386   /* Wait for a reply... */
6387   W (ret);
6388   return ret;
6389 }
6390
6391 static int
6392 api_mpls_table_add_del (vat_main_t * vam)
6393 {
6394   unformat_input_t *i = vam->input;
6395   vl_api_mpls_table_add_del_t *mp;
6396   u32 table_id = ~0;
6397   u8 is_add = 1;
6398   int ret = 0;
6399
6400   /* Parse args required to build the message */
6401   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6402     {
6403       if (unformat (i, "table %d", &table_id))
6404         ;
6405       else if (unformat (i, "del"))
6406         is_add = 0;
6407       else if (unformat (i, "add"))
6408         is_add = 1;
6409       else
6410         {
6411           clib_warning ("parse error '%U'", format_unformat_error, i);
6412           return -99;
6413         }
6414     }
6415
6416   if (~0 == table_id)
6417     {
6418       errmsg ("missing table-ID");
6419       return -99;
6420     }
6421
6422   /* Construct the API message */
6423   M (MPLS_TABLE_ADD_DEL, mp);
6424
6425   mp->mt_table.mt_table_id = ntohl (table_id);
6426   mp->mt_is_add = is_add;
6427
6428   /* send it... */
6429   S (mp);
6430
6431   /* Wait for a reply... */
6432   W (ret);
6433
6434   return ret;
6435 }
6436
6437 static int
6438 api_mpls_route_add_del (vat_main_t * vam)
6439 {
6440   u8 is_add = 1, path_count = 0, is_multipath = 0, is_eos = 0;
6441   mpls_label_t local_label = MPLS_LABEL_INVALID;
6442   unformat_input_t *i = vam->input;
6443   vl_api_mpls_route_add_del_t *mp;
6444   vl_api_fib_path_t paths[8];
6445   int count = 1, j;
6446   f64 before = 0;
6447
6448   /* Parse args required to build the message */
6449   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6450     {
6451       if (unformat (i, "%d", &local_label))
6452         ;
6453       else if (unformat (i, "eos"))
6454         is_eos = 1;
6455       else if (unformat (i, "non-eos"))
6456         is_eos = 0;
6457       else if (unformat (i, "del"))
6458         is_add = 0;
6459       else if (unformat (i, "add"))
6460         is_add = 1;
6461       else if (unformat (i, "multipath"))
6462         is_multipath = 1;
6463       else if (unformat (i, "count %d", &count))
6464         ;
6465       else
6466         if (unformat
6467             (i, "via %U", unformat_fib_path, vam, &paths[path_count]))
6468         {
6469           path_count++;
6470           if (8 == path_count)
6471             {
6472               errmsg ("max 8 paths");
6473               return -99;
6474             }
6475         }
6476       else
6477         {
6478           clib_warning ("parse error '%U'", format_unformat_error, i);
6479           return -99;
6480         }
6481     }
6482
6483   if (!path_count)
6484     {
6485       errmsg ("specify a path; via ...");
6486       return -99;
6487     }
6488
6489   if (MPLS_LABEL_INVALID == local_label)
6490     {
6491       errmsg ("missing label");
6492       return -99;
6493     }
6494
6495   if (count > 1)
6496     {
6497       /* Turn on async mode */
6498       vam->async_mode = 1;
6499       vam->async_errors = 0;
6500       before = vat_time_now (vam);
6501     }
6502
6503   for (j = 0; j < count; j++)
6504     {
6505       /* Construct the API message */
6506       M2 (MPLS_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t) * path_count);
6507
6508       mp->mr_is_add = is_add;
6509       mp->mr_is_multipath = is_multipath;
6510
6511       mp->mr_route.mr_label = local_label;
6512       mp->mr_route.mr_eos = is_eos;
6513       mp->mr_route.mr_table_id = 0;
6514       mp->mr_route.mr_n_paths = path_count;
6515
6516       clib_memcpy (&mp->mr_route.mr_paths, paths,
6517                    sizeof (paths[0]) * path_count);
6518
6519       local_label++;
6520
6521       /* send it... */
6522       S (mp);
6523       /* If we receive SIGTERM, stop now... */
6524       if (vam->do_exit)
6525         break;
6526     }
6527
6528   /* When testing multiple add/del ops, use a control-ping to sync */
6529   if (count > 1)
6530     {
6531       vl_api_control_ping_t *mp_ping;
6532       f64 after;
6533       f64 timeout;
6534
6535       /* Shut off async mode */
6536       vam->async_mode = 0;
6537
6538       MPING (CONTROL_PING, mp_ping);
6539       S (mp_ping);
6540
6541       timeout = vat_time_now (vam) + 1.0;
6542       while (vat_time_now (vam) < timeout)
6543         if (vam->result_ready == 1)
6544           goto out;
6545       vam->retval = -99;
6546
6547     out:
6548       if (vam->retval == -99)
6549         errmsg ("timeout");
6550
6551       if (vam->async_errors > 0)
6552         {
6553           errmsg ("%d asynchronous errors", vam->async_errors);
6554           vam->retval = -98;
6555         }
6556       vam->async_errors = 0;
6557       after = vat_time_now (vam);
6558
6559       /* slim chance, but we might have eaten SIGTERM on the first iteration */
6560       if (j > 0)
6561         count = j;
6562
6563       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
6564              count, after - before, count / (after - before));
6565     }
6566   else
6567     {
6568       int ret;
6569
6570       /* Wait for a reply... */
6571       W (ret);
6572       return ret;
6573     }
6574
6575   /* Return the good/bad news */
6576   return (vam->retval);
6577   return (0);
6578 }
6579
6580 static int
6581 api_mpls_ip_bind_unbind (vat_main_t * vam)
6582 {
6583   unformat_input_t *i = vam->input;
6584   vl_api_mpls_ip_bind_unbind_t *mp;
6585   u32 ip_table_id = 0;
6586   u8 is_bind = 1;
6587   vl_api_prefix_t pfx;
6588   u8 prefix_set = 0;
6589   mpls_label_t local_label = MPLS_LABEL_INVALID;
6590   int ret;
6591
6592   /* Parse args required to build the message */
6593   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6594     {
6595       if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
6596         prefix_set = 1;
6597       else if (unformat (i, "%d", &local_label))
6598         ;
6599       else if (unformat (i, "table-id %d", &ip_table_id))
6600         ;
6601       else if (unformat (i, "unbind"))
6602         is_bind = 0;
6603       else if (unformat (i, "bind"))
6604         is_bind = 1;
6605       else
6606         {
6607           clib_warning ("parse error '%U'", format_unformat_error, i);
6608           return -99;
6609         }
6610     }
6611
6612   if (!prefix_set)
6613     {
6614       errmsg ("IP prefix not set");
6615       return -99;
6616     }
6617
6618   if (MPLS_LABEL_INVALID == local_label)
6619     {
6620       errmsg ("missing label");
6621       return -99;
6622     }
6623
6624   /* Construct the API message */
6625   M (MPLS_IP_BIND_UNBIND, mp);
6626
6627   mp->mb_is_bind = is_bind;
6628   mp->mb_ip_table_id = ntohl (ip_table_id);
6629   mp->mb_mpls_table_id = 0;
6630   mp->mb_label = ntohl (local_label);
6631   clib_memcpy (&mp->mb_prefix, &pfx, sizeof (pfx));
6632
6633   /* send it... */
6634   S (mp);
6635
6636   /* Wait for a reply... */
6637   W (ret);
6638   return ret;
6639   return (0);
6640 }
6641
6642 static int
6643 api_sr_mpls_policy_add (vat_main_t * vam)
6644 {
6645   unformat_input_t *i = vam->input;
6646   vl_api_sr_mpls_policy_add_t *mp;
6647   u32 bsid = 0;
6648   u32 weight = 1;
6649   u8 type = 0;
6650   u8 n_segments = 0;
6651   u32 sid;
6652   u32 *segments = NULL;
6653   int ret;
6654
6655   /* Parse args required to build the message */
6656   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6657     {
6658       if (unformat (i, "bsid %d", &bsid))
6659         ;
6660       else if (unformat (i, "weight %d", &weight))
6661         ;
6662       else if (unformat (i, "spray"))
6663         type = 1;
6664       else if (unformat (i, "next %d", &sid))
6665         {
6666           n_segments += 1;
6667           vec_add1 (segments, htonl (sid));
6668         }
6669       else
6670         {
6671           clib_warning ("parse error '%U'", format_unformat_error, i);
6672           return -99;
6673         }
6674     }
6675
6676   if (bsid == 0)
6677     {
6678       errmsg ("bsid not set");
6679       return -99;
6680     }
6681
6682   if (n_segments == 0)
6683     {
6684       errmsg ("no sid in segment stack");
6685       return -99;
6686     }
6687
6688   /* Construct the API message */
6689   M2 (SR_MPLS_POLICY_ADD, mp, sizeof (u32) * n_segments);
6690
6691   mp->bsid = htonl (bsid);
6692   mp->weight = htonl (weight);
6693   mp->is_spray = type;
6694   mp->n_segments = n_segments;
6695   memcpy (mp->segments, segments, sizeof (u32) * n_segments);
6696   vec_free (segments);
6697
6698   /* send it... */
6699   S (mp);
6700
6701   /* Wait for a reply... */
6702   W (ret);
6703   return ret;
6704 }
6705
6706 static int
6707 api_sr_mpls_policy_del (vat_main_t * vam)
6708 {
6709   unformat_input_t *i = vam->input;
6710   vl_api_sr_mpls_policy_del_t *mp;
6711   u32 bsid = 0;
6712   int ret;
6713
6714   /* Parse args required to build the message */
6715   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6716     {
6717       if (unformat (i, "bsid %d", &bsid))
6718         ;
6719       else
6720         {
6721           clib_warning ("parse error '%U'", format_unformat_error, i);
6722           return -99;
6723         }
6724     }
6725
6726   if (bsid == 0)
6727     {
6728       errmsg ("bsid not set");
6729       return -99;
6730     }
6731
6732   /* Construct the API message */
6733   M (SR_MPLS_POLICY_DEL, mp);
6734
6735   mp->bsid = htonl (bsid);
6736
6737   /* send it... */
6738   S (mp);
6739
6740   /* Wait for a reply... */
6741   W (ret);
6742   return ret;
6743 }
6744
6745 static int
6746 api_bier_table_add_del (vat_main_t * vam)
6747 {
6748   unformat_input_t *i = vam->input;
6749   vl_api_bier_table_add_del_t *mp;
6750   u8 is_add = 1;
6751   u32 set = 0, sub_domain = 0, hdr_len = 3;
6752   mpls_label_t local_label = MPLS_LABEL_INVALID;
6753   int ret;
6754
6755   /* Parse args required to build the message */
6756   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6757     {
6758       if (unformat (i, "sub-domain %d", &sub_domain))
6759         ;
6760       else if (unformat (i, "set %d", &set))
6761         ;
6762       else if (unformat (i, "label %d", &local_label))
6763         ;
6764       else if (unformat (i, "hdr-len %d", &hdr_len))
6765         ;
6766       else if (unformat (i, "add"))
6767         is_add = 1;
6768       else if (unformat (i, "del"))
6769         is_add = 0;
6770       else
6771         {
6772           clib_warning ("parse error '%U'", format_unformat_error, i);
6773           return -99;
6774         }
6775     }
6776
6777   if (MPLS_LABEL_INVALID == local_label)
6778     {
6779       errmsg ("missing label\n");
6780       return -99;
6781     }
6782
6783   /* Construct the API message */
6784   M (BIER_TABLE_ADD_DEL, mp);
6785
6786   mp->bt_is_add = is_add;
6787   mp->bt_label = ntohl (local_label);
6788   mp->bt_tbl_id.bt_set = set;
6789   mp->bt_tbl_id.bt_sub_domain = sub_domain;
6790   mp->bt_tbl_id.bt_hdr_len_id = hdr_len;
6791
6792   /* send it... */
6793   S (mp);
6794
6795   /* Wait for a reply... */
6796   W (ret);
6797
6798   return (ret);
6799 }
6800
6801 static int
6802 api_bier_route_add_del (vat_main_t * vam)
6803 {
6804   unformat_input_t *i = vam->input;
6805   vl_api_bier_route_add_del_t *mp;
6806   u8 is_add = 1;
6807   u32 set = 0, sub_domain = 0, hdr_len = 3, bp = 0;
6808   ip4_address_t v4_next_hop_address;
6809   ip6_address_t v6_next_hop_address;
6810   u8 next_hop_set = 0;
6811   u8 next_hop_proto_is_ip4 = 1;
6812   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
6813   int ret;
6814
6815   /* Parse args required to build the message */
6816   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6817     {
6818       if (unformat (i, "%U", unformat_ip4_address, &v4_next_hop_address))
6819         {
6820           next_hop_proto_is_ip4 = 1;
6821           next_hop_set = 1;
6822         }
6823       else if (unformat (i, "%U", unformat_ip6_address, &v6_next_hop_address))
6824         {
6825           next_hop_proto_is_ip4 = 0;
6826           next_hop_set = 1;
6827         }
6828       if (unformat (i, "sub-domain %d", &sub_domain))
6829         ;
6830       else if (unformat (i, "set %d", &set))
6831         ;
6832       else if (unformat (i, "hdr-len %d", &hdr_len))
6833         ;
6834       else if (unformat (i, "bp %d", &bp))
6835         ;
6836       else if (unformat (i, "add"))
6837         is_add = 1;
6838       else if (unformat (i, "del"))
6839         is_add = 0;
6840       else if (unformat (i, "out-label %d", &next_hop_out_label))
6841         ;
6842       else
6843         {
6844           clib_warning ("parse error '%U'", format_unformat_error, i);
6845           return -99;
6846         }
6847     }
6848
6849   if (!next_hop_set || (MPLS_LABEL_INVALID == next_hop_out_label))
6850     {
6851       errmsg ("next hop / label set\n");
6852       return -99;
6853     }
6854   if (0 == bp)
6855     {
6856       errmsg ("bit=position not set\n");
6857       return -99;
6858     }
6859
6860   /* Construct the API message */
6861   M2 (BIER_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t));
6862
6863   mp->br_is_add = is_add;
6864   mp->br_route.br_tbl_id.bt_set = set;
6865   mp->br_route.br_tbl_id.bt_sub_domain = sub_domain;
6866   mp->br_route.br_tbl_id.bt_hdr_len_id = hdr_len;
6867   mp->br_route.br_bp = ntohs (bp);
6868   mp->br_route.br_n_paths = 1;
6869   mp->br_route.br_paths[0].n_labels = 1;
6870   mp->br_route.br_paths[0].label_stack[0].label = ntohl (next_hop_out_label);
6871   mp->br_route.br_paths[0].proto = (next_hop_proto_is_ip4 ?
6872                                     FIB_API_PATH_NH_PROTO_IP4 :
6873                                     FIB_API_PATH_NH_PROTO_IP6);
6874
6875   if (next_hop_proto_is_ip4)
6876     {
6877       clib_memcpy (&mp->br_route.br_paths[0].nh.address.ip4,
6878                    &v4_next_hop_address, sizeof (v4_next_hop_address));
6879     }
6880   else
6881     {
6882       clib_memcpy (&mp->br_route.br_paths[0].nh.address.ip6,
6883                    &v6_next_hop_address, sizeof (v6_next_hop_address));
6884     }
6885
6886   /* send it... */
6887   S (mp);
6888
6889   /* Wait for a reply... */
6890   W (ret);
6891
6892   return (ret);
6893 }
6894
6895 static int
6896 api_mpls_tunnel_add_del (vat_main_t * vam)
6897 {
6898   unformat_input_t *i = vam->input;
6899   vl_api_mpls_tunnel_add_del_t *mp;
6900
6901   vl_api_fib_path_t paths[8];
6902   u32 sw_if_index = ~0;
6903   u8 path_count = 0;
6904   u8 l2_only = 0;
6905   u8 is_add = 1;
6906   int ret;
6907
6908   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6909     {
6910       if (unformat (i, "add"))
6911         is_add = 1;
6912       else
6913         if (unformat
6914             (i, "del %U", api_unformat_sw_if_index, vam, &sw_if_index))
6915         is_add = 0;
6916       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
6917         is_add = 0;
6918       else if (unformat (i, "l2-only"))
6919         l2_only = 1;
6920       else
6921         if (unformat
6922             (i, "via %U", unformat_fib_path, vam, &paths[path_count]))
6923         {
6924           path_count++;
6925           if (8 == path_count)
6926             {
6927               errmsg ("max 8 paths");
6928               return -99;
6929             }
6930         }
6931       else
6932         {
6933           clib_warning ("parse error '%U'", format_unformat_error, i);
6934           return -99;
6935         }
6936     }
6937
6938   M2 (MPLS_TUNNEL_ADD_DEL, mp, sizeof (vl_api_fib_path_t) * path_count);
6939
6940   mp->mt_is_add = is_add;
6941   mp->mt_tunnel.mt_sw_if_index = ntohl (sw_if_index);
6942   mp->mt_tunnel.mt_l2_only = l2_only;
6943   mp->mt_tunnel.mt_is_multicast = 0;
6944   mp->mt_tunnel.mt_n_paths = path_count;
6945
6946   clib_memcpy (&mp->mt_tunnel.mt_paths, &paths,
6947                sizeof (paths[0]) * path_count);
6948
6949   S (mp);
6950   W (ret);
6951   return ret;
6952 }
6953
6954 static int
6955 api_sw_interface_set_unnumbered (vat_main_t * vam)
6956 {
6957   unformat_input_t *i = vam->input;
6958   vl_api_sw_interface_set_unnumbered_t *mp;
6959   u32 sw_if_index;
6960   u32 unnum_sw_index = ~0;
6961   u8 is_add = 1;
6962   u8 sw_if_index_set = 0;
6963   int ret;
6964
6965   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6966     {
6967       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6968         sw_if_index_set = 1;
6969       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6970         sw_if_index_set = 1;
6971       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
6972         ;
6973       else if (unformat (i, "del"))
6974         is_add = 0;
6975       else
6976         {
6977           clib_warning ("parse error '%U'", format_unformat_error, i);
6978           return -99;
6979         }
6980     }
6981
6982   if (sw_if_index_set == 0)
6983     {
6984       errmsg ("missing interface name or sw_if_index");
6985       return -99;
6986     }
6987
6988   M (SW_INTERFACE_SET_UNNUMBERED, mp);
6989
6990   mp->sw_if_index = ntohl (sw_if_index);
6991   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
6992   mp->is_add = is_add;
6993
6994   S (mp);
6995   W (ret);
6996   return ret;
6997 }
6998
6999
7000 static int
7001 api_create_vlan_subif (vat_main_t * vam)
7002 {
7003   unformat_input_t *i = vam->input;
7004   vl_api_create_vlan_subif_t *mp;
7005   u32 sw_if_index;
7006   u8 sw_if_index_set = 0;
7007   u32 vlan_id;
7008   u8 vlan_id_set = 0;
7009   int ret;
7010
7011   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7012     {
7013       if (unformat (i, "sw_if_index %d", &sw_if_index))
7014         sw_if_index_set = 1;
7015       else
7016         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7017         sw_if_index_set = 1;
7018       else if (unformat (i, "vlan %d", &vlan_id))
7019         vlan_id_set = 1;
7020       else
7021         {
7022           clib_warning ("parse error '%U'", format_unformat_error, i);
7023           return -99;
7024         }
7025     }
7026
7027   if (sw_if_index_set == 0)
7028     {
7029       errmsg ("missing interface name or sw_if_index");
7030       return -99;
7031     }
7032
7033   if (vlan_id_set == 0)
7034     {
7035       errmsg ("missing vlan_id");
7036       return -99;
7037     }
7038   M (CREATE_VLAN_SUBIF, mp);
7039
7040   mp->sw_if_index = ntohl (sw_if_index);
7041   mp->vlan_id = ntohl (vlan_id);
7042
7043   S (mp);
7044   W (ret);
7045   return ret;
7046 }
7047
7048 #define foreach_create_subif_bit                \
7049 _(no_tags)                                      \
7050 _(one_tag)                                      \
7051 _(two_tags)                                     \
7052 _(dot1ad)                                       \
7053 _(exact_match)                                  \
7054 _(default_sub)                                  \
7055 _(outer_vlan_id_any)                            \
7056 _(inner_vlan_id_any)
7057
7058 #define foreach_create_subif_flag               \
7059 _(0, "no_tags")                                 \
7060 _(1, "one_tag")                                 \
7061 _(2, "two_tags")                                \
7062 _(3, "dot1ad")                                  \
7063 _(4, "exact_match")                             \
7064 _(5, "default_sub")                             \
7065 _(6, "outer_vlan_id_any")                       \
7066 _(7, "inner_vlan_id_any")
7067
7068 static int
7069 api_create_subif (vat_main_t * vam)
7070 {
7071   unformat_input_t *i = vam->input;
7072   vl_api_create_subif_t *mp;
7073   u32 sw_if_index;
7074   u8 sw_if_index_set = 0;
7075   u32 sub_id;
7076   u8 sub_id_set = 0;
7077   u32 __attribute__ ((unused)) no_tags = 0;
7078   u32 __attribute__ ((unused)) one_tag = 0;
7079   u32 __attribute__ ((unused)) two_tags = 0;
7080   u32 __attribute__ ((unused)) dot1ad = 0;
7081   u32 __attribute__ ((unused)) exact_match = 0;
7082   u32 __attribute__ ((unused)) default_sub = 0;
7083   u32 __attribute__ ((unused)) outer_vlan_id_any = 0;
7084   u32 __attribute__ ((unused)) inner_vlan_id_any = 0;
7085   u32 tmp;
7086   u16 outer_vlan_id = 0;
7087   u16 inner_vlan_id = 0;
7088   int ret;
7089
7090   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7091     {
7092       if (unformat (i, "sw_if_index %d", &sw_if_index))
7093         sw_if_index_set = 1;
7094       else
7095         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7096         sw_if_index_set = 1;
7097       else if (unformat (i, "sub_id %d", &sub_id))
7098         sub_id_set = 1;
7099       else if (unformat (i, "outer_vlan_id %d", &tmp))
7100         outer_vlan_id = tmp;
7101       else if (unformat (i, "inner_vlan_id %d", &tmp))
7102         inner_vlan_id = tmp;
7103
7104 #define _(a) else if (unformat (i, #a)) a = 1 ;
7105       foreach_create_subif_bit
7106 #undef _
7107         else
7108         {
7109           clib_warning ("parse error '%U'", format_unformat_error, i);
7110           return -99;
7111         }
7112     }
7113
7114   if (sw_if_index_set == 0)
7115     {
7116       errmsg ("missing interface name or sw_if_index");
7117       return -99;
7118     }
7119
7120   if (sub_id_set == 0)
7121     {
7122       errmsg ("missing sub_id");
7123       return -99;
7124     }
7125   M (CREATE_SUBIF, mp);
7126
7127   mp->sw_if_index = ntohl (sw_if_index);
7128   mp->sub_id = ntohl (sub_id);
7129
7130 #define _(a,b) mp->sub_if_flags |= (1 << a);
7131   foreach_create_subif_flag;
7132 #undef _
7133
7134   mp->outer_vlan_id = ntohs (outer_vlan_id);
7135   mp->inner_vlan_id = ntohs (inner_vlan_id);
7136
7137   S (mp);
7138   W (ret);
7139   return ret;
7140 }
7141
7142 static int
7143 api_ip_table_replace_begin (vat_main_t * vam)
7144 {
7145   unformat_input_t *i = vam->input;
7146   vl_api_ip_table_replace_begin_t *mp;
7147   u32 table_id = 0;
7148   u8 is_ipv6 = 0;
7149
7150   int ret;
7151   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7152     {
7153       if (unformat (i, "table %d", &table_id))
7154         ;
7155       else if (unformat (i, "ipv6"))
7156         is_ipv6 = 1;
7157       else
7158         {
7159           clib_warning ("parse error '%U'", format_unformat_error, i);
7160           return -99;
7161         }
7162     }
7163
7164   M (IP_TABLE_REPLACE_BEGIN, mp);
7165
7166   mp->table.table_id = ntohl (table_id);
7167   mp->table.is_ip6 = is_ipv6;
7168
7169   S (mp);
7170   W (ret);
7171   return ret;
7172 }
7173
7174 static int
7175 api_ip_table_flush (vat_main_t * vam)
7176 {
7177   unformat_input_t *i = vam->input;
7178   vl_api_ip_table_flush_t *mp;
7179   u32 table_id = 0;
7180   u8 is_ipv6 = 0;
7181
7182   int ret;
7183   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7184     {
7185       if (unformat (i, "table %d", &table_id))
7186         ;
7187       else if (unformat (i, "ipv6"))
7188         is_ipv6 = 1;
7189       else
7190         {
7191           clib_warning ("parse error '%U'", format_unformat_error, i);
7192           return -99;
7193         }
7194     }
7195
7196   M (IP_TABLE_FLUSH, mp);
7197
7198   mp->table.table_id = ntohl (table_id);
7199   mp->table.is_ip6 = is_ipv6;
7200
7201   S (mp);
7202   W (ret);
7203   return ret;
7204 }
7205
7206 static int
7207 api_ip_table_replace_end (vat_main_t * vam)
7208 {
7209   unformat_input_t *i = vam->input;
7210   vl_api_ip_table_replace_end_t *mp;
7211   u32 table_id = 0;
7212   u8 is_ipv6 = 0;
7213
7214   int ret;
7215   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7216     {
7217       if (unformat (i, "table %d", &table_id))
7218         ;
7219       else if (unformat (i, "ipv6"))
7220         is_ipv6 = 1;
7221       else
7222         {
7223           clib_warning ("parse error '%U'", format_unformat_error, i);
7224           return -99;
7225         }
7226     }
7227
7228   M (IP_TABLE_REPLACE_END, mp);
7229
7230   mp->table.table_id = ntohl (table_id);
7231   mp->table.is_ip6 = is_ipv6;
7232
7233   S (mp);
7234   W (ret);
7235   return ret;
7236 }
7237
7238 static int
7239 api_set_ip_flow_hash (vat_main_t * vam)
7240 {
7241   unformat_input_t *i = vam->input;
7242   vl_api_set_ip_flow_hash_t *mp;
7243   u32 vrf_id = 0;
7244   u8 is_ipv6 = 0;
7245   u8 vrf_id_set = 0;
7246   u8 src = 0;
7247   u8 dst = 0;
7248   u8 sport = 0;
7249   u8 dport = 0;
7250   u8 proto = 0;
7251   u8 reverse = 0;
7252   int ret;
7253
7254   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7255     {
7256       if (unformat (i, "vrf %d", &vrf_id))
7257         vrf_id_set = 1;
7258       else if (unformat (i, "ipv6"))
7259         is_ipv6 = 1;
7260       else if (unformat (i, "src"))
7261         src = 1;
7262       else if (unformat (i, "dst"))
7263         dst = 1;
7264       else if (unformat (i, "sport"))
7265         sport = 1;
7266       else if (unformat (i, "dport"))
7267         dport = 1;
7268       else if (unformat (i, "proto"))
7269         proto = 1;
7270       else if (unformat (i, "reverse"))
7271         reverse = 1;
7272
7273       else
7274         {
7275           clib_warning ("parse error '%U'", format_unformat_error, i);
7276           return -99;
7277         }
7278     }
7279
7280   if (vrf_id_set == 0)
7281     {
7282       errmsg ("missing vrf id");
7283       return -99;
7284     }
7285
7286   M (SET_IP_FLOW_HASH, mp);
7287   mp->src = src;
7288   mp->dst = dst;
7289   mp->sport = sport;
7290   mp->dport = dport;
7291   mp->proto = proto;
7292   mp->reverse = reverse;
7293   mp->vrf_id = ntohl (vrf_id);
7294   mp->is_ipv6 = is_ipv6;
7295
7296   S (mp);
7297   W (ret);
7298   return ret;
7299 }
7300
7301 static int
7302 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
7303 {
7304   unformat_input_t *i = vam->input;
7305   vl_api_sw_interface_ip6_enable_disable_t *mp;
7306   u32 sw_if_index;
7307   u8 sw_if_index_set = 0;
7308   u8 enable = 0;
7309   int ret;
7310
7311   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7312     {
7313       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7314         sw_if_index_set = 1;
7315       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7316         sw_if_index_set = 1;
7317       else if (unformat (i, "enable"))
7318         enable = 1;
7319       else if (unformat (i, "disable"))
7320         enable = 0;
7321       else
7322         {
7323           clib_warning ("parse error '%U'", format_unformat_error, i);
7324           return -99;
7325         }
7326     }
7327
7328   if (sw_if_index_set == 0)
7329     {
7330       errmsg ("missing interface name or sw_if_index");
7331       return -99;
7332     }
7333
7334   M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
7335
7336   mp->sw_if_index = ntohl (sw_if_index);
7337   mp->enable = enable;
7338
7339   S (mp);
7340   W (ret);
7341   return ret;
7342 }
7343
7344
7345 static int
7346 api_l2_patch_add_del (vat_main_t * vam)
7347 {
7348   unformat_input_t *i = vam->input;
7349   vl_api_l2_patch_add_del_t *mp;
7350   u32 rx_sw_if_index;
7351   u8 rx_sw_if_index_set = 0;
7352   u32 tx_sw_if_index;
7353   u8 tx_sw_if_index_set = 0;
7354   u8 is_add = 1;
7355   int ret;
7356
7357   /* Parse args required to build the message */
7358   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7359     {
7360       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
7361         rx_sw_if_index_set = 1;
7362       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
7363         tx_sw_if_index_set = 1;
7364       else if (unformat (i, "rx"))
7365         {
7366           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7367             {
7368               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
7369                             &rx_sw_if_index))
7370                 rx_sw_if_index_set = 1;
7371             }
7372           else
7373             break;
7374         }
7375       else if (unformat (i, "tx"))
7376         {
7377           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7378             {
7379               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
7380                             &tx_sw_if_index))
7381                 tx_sw_if_index_set = 1;
7382             }
7383           else
7384             break;
7385         }
7386       else if (unformat (i, "del"))
7387         is_add = 0;
7388       else
7389         break;
7390     }
7391
7392   if (rx_sw_if_index_set == 0)
7393     {
7394       errmsg ("missing rx interface name or rx_sw_if_index");
7395       return -99;
7396     }
7397
7398   if (tx_sw_if_index_set == 0)
7399     {
7400       errmsg ("missing tx interface name or tx_sw_if_index");
7401       return -99;
7402     }
7403
7404   M (L2_PATCH_ADD_DEL, mp);
7405
7406   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
7407   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
7408   mp->is_add = is_add;
7409
7410   S (mp);
7411   W (ret);
7412   return ret;
7413 }
7414
7415 u8 is_del;
7416 u8 localsid_addr[16];
7417 u8 end_psp;
7418 u8 behavior;
7419 u32 sw_if_index;
7420 u32 vlan_index;
7421 u32 fib_table;
7422 u8 nh_addr[16];
7423
7424 static int
7425 api_sr_localsid_add_del (vat_main_t * vam)
7426 {
7427   unformat_input_t *i = vam->input;
7428   vl_api_sr_localsid_add_del_t *mp;
7429
7430   u8 is_del;
7431   ip6_address_t localsid;
7432   u8 end_psp = 0;
7433   u8 behavior = ~0;
7434   u32 sw_if_index;
7435   u32 fib_table = ~(u32) 0;
7436   ip46_address_t nh_addr;
7437   clib_memset (&nh_addr, 0, sizeof (ip46_address_t));
7438
7439   bool nexthop_set = 0;
7440
7441   int ret;
7442
7443   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7444     {
7445       if (unformat (i, "del"))
7446         is_del = 1;
7447       else if (unformat (i, "address %U", unformat_ip6_address, &localsid));
7448       else if (unformat (i, "next-hop %U", unformat_ip46_address, &nh_addr))
7449         nexthop_set = 1;
7450       else if (unformat (i, "behavior %u", &behavior));
7451       else if (unformat (i, "sw_if_index %u", &sw_if_index));
7452       else if (unformat (i, "fib-table %u", &fib_table));
7453       else if (unformat (i, "end.psp %u", &behavior));
7454       else
7455         break;
7456     }
7457
7458   M (SR_LOCALSID_ADD_DEL, mp);
7459
7460   clib_memcpy (mp->localsid, &localsid, sizeof (mp->localsid));
7461
7462   if (nexthop_set)
7463     {
7464       clib_memcpy (&mp->nh_addr.un, &nh_addr, sizeof (mp->nh_addr.un));
7465     }
7466   mp->behavior = behavior;
7467   mp->sw_if_index = ntohl (sw_if_index);
7468   mp->fib_table = ntohl (fib_table);
7469   mp->end_psp = end_psp;
7470   mp->is_del = is_del;
7471
7472   S (mp);
7473   W (ret);
7474   return ret;
7475 }
7476
7477 static int
7478 api_ioam_enable (vat_main_t * vam)
7479 {
7480   unformat_input_t *input = vam->input;
7481   vl_api_ioam_enable_t *mp;
7482   u32 id = 0;
7483   int has_trace_option = 0;
7484   int has_pot_option = 0;
7485   int has_seqno_option = 0;
7486   int has_analyse_option = 0;
7487   int ret;
7488
7489   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7490     {
7491       if (unformat (input, "trace"))
7492         has_trace_option = 1;
7493       else if (unformat (input, "pot"))
7494         has_pot_option = 1;
7495       else if (unformat (input, "seqno"))
7496         has_seqno_option = 1;
7497       else if (unformat (input, "analyse"))
7498         has_analyse_option = 1;
7499       else
7500         break;
7501     }
7502   M (IOAM_ENABLE, mp);
7503   mp->id = htons (id);
7504   mp->seqno = has_seqno_option;
7505   mp->analyse = has_analyse_option;
7506   mp->pot_enable = has_pot_option;
7507   mp->trace_enable = has_trace_option;
7508
7509   S (mp);
7510   W (ret);
7511   return ret;
7512 }
7513
7514
7515 static int
7516 api_ioam_disable (vat_main_t * vam)
7517 {
7518   vl_api_ioam_disable_t *mp;
7519   int ret;
7520
7521   M (IOAM_DISABLE, mp);
7522   S (mp);
7523   W (ret);
7524   return ret;
7525 }
7526
7527 #define foreach_tcp_proto_field                 \
7528 _(src_port)                                     \
7529 _(dst_port)
7530
7531 #define foreach_udp_proto_field                 \
7532 _(src_port)                                     \
7533 _(dst_port)
7534
7535 #define foreach_ip4_proto_field                 \
7536 _(src_address)                                  \
7537 _(dst_address)                                  \
7538 _(tos)                                          \
7539 _(length)                                       \
7540 _(fragment_id)                                  \
7541 _(ttl)                                          \
7542 _(protocol)                                     \
7543 _(checksum)
7544
7545 typedef struct
7546 {
7547   u16 src_port, dst_port;
7548 } tcpudp_header_t;
7549
7550 #if VPP_API_TEST_BUILTIN == 0
7551 uword
7552 unformat_tcp_mask (unformat_input_t * input, va_list * args)
7553 {
7554   u8 **maskp = va_arg (*args, u8 **);
7555   u8 *mask = 0;
7556   u8 found_something = 0;
7557   tcp_header_t *tcp;
7558
7559 #define _(a) u8 a=0;
7560   foreach_tcp_proto_field;
7561 #undef _
7562
7563   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7564     {
7565       if (0);
7566 #define _(a) else if (unformat (input, #a)) a=1;
7567       foreach_tcp_proto_field
7568 #undef _
7569         else
7570         break;
7571     }
7572
7573 #define _(a) found_something += a;
7574   foreach_tcp_proto_field;
7575 #undef _
7576
7577   if (found_something == 0)
7578     return 0;
7579
7580   vec_validate (mask, sizeof (*tcp) - 1);
7581
7582   tcp = (tcp_header_t *) mask;
7583
7584 #define _(a) if (a) clib_memset (&tcp->a, 0xff, sizeof (tcp->a));
7585   foreach_tcp_proto_field;
7586 #undef _
7587
7588   *maskp = mask;
7589   return 1;
7590 }
7591
7592 uword
7593 unformat_udp_mask (unformat_input_t * input, va_list * args)
7594 {
7595   u8 **maskp = va_arg (*args, u8 **);
7596   u8 *mask = 0;
7597   u8 found_something = 0;
7598   udp_header_t *udp;
7599
7600 #define _(a) u8 a=0;
7601   foreach_udp_proto_field;
7602 #undef _
7603
7604   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7605     {
7606       if (0);
7607 #define _(a) else if (unformat (input, #a)) a=1;
7608       foreach_udp_proto_field
7609 #undef _
7610         else
7611         break;
7612     }
7613
7614 #define _(a) found_something += a;
7615   foreach_udp_proto_field;
7616 #undef _
7617
7618   if (found_something == 0)
7619     return 0;
7620
7621   vec_validate (mask, sizeof (*udp) - 1);
7622
7623   udp = (udp_header_t *) mask;
7624
7625 #define _(a) if (a) clib_memset (&udp->a, 0xff, sizeof (udp->a));
7626   foreach_udp_proto_field;
7627 #undef _
7628
7629   *maskp = mask;
7630   return 1;
7631 }
7632
7633 uword
7634 unformat_l4_mask (unformat_input_t * input, va_list * args)
7635 {
7636   u8 **maskp = va_arg (*args, u8 **);
7637   u16 src_port = 0, dst_port = 0;
7638   tcpudp_header_t *tcpudp;
7639
7640   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7641     {
7642       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
7643         return 1;
7644       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
7645         return 1;
7646       else if (unformat (input, "src_port"))
7647         src_port = 0xFFFF;
7648       else if (unformat (input, "dst_port"))
7649         dst_port = 0xFFFF;
7650       else
7651         return 0;
7652     }
7653
7654   if (!src_port && !dst_port)
7655     return 0;
7656
7657   u8 *mask = 0;
7658   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
7659
7660   tcpudp = (tcpudp_header_t *) mask;
7661   tcpudp->src_port = src_port;
7662   tcpudp->dst_port = dst_port;
7663
7664   *maskp = mask;
7665
7666   return 1;
7667 }
7668
7669 uword
7670 unformat_ip4_mask (unformat_input_t * input, va_list * args)
7671 {
7672   u8 **maskp = va_arg (*args, u8 **);
7673   u8 *mask = 0;
7674   u8 found_something = 0;
7675   ip4_header_t *ip;
7676
7677 #define _(a) u8 a=0;
7678   foreach_ip4_proto_field;
7679 #undef _
7680   u8 version = 0;
7681   u8 hdr_length = 0;
7682
7683
7684   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7685     {
7686       if (unformat (input, "version"))
7687         version = 1;
7688       else if (unformat (input, "hdr_length"))
7689         hdr_length = 1;
7690       else if (unformat (input, "src"))
7691         src_address = 1;
7692       else if (unformat (input, "dst"))
7693         dst_address = 1;
7694       else if (unformat (input, "proto"))
7695         protocol = 1;
7696
7697 #define _(a) else if (unformat (input, #a)) a=1;
7698       foreach_ip4_proto_field
7699 #undef _
7700         else
7701         break;
7702     }
7703
7704 #define _(a) found_something += a;
7705   foreach_ip4_proto_field;
7706 #undef _
7707
7708   if (found_something == 0)
7709     return 0;
7710
7711   vec_validate (mask, sizeof (*ip) - 1);
7712
7713   ip = (ip4_header_t *) mask;
7714
7715 #define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
7716   foreach_ip4_proto_field;
7717 #undef _
7718
7719   ip->ip_version_and_header_length = 0;
7720
7721   if (version)
7722     ip->ip_version_and_header_length |= 0xF0;
7723
7724   if (hdr_length)
7725     ip->ip_version_and_header_length |= 0x0F;
7726
7727   *maskp = mask;
7728   return 1;
7729 }
7730
7731 #define foreach_ip6_proto_field                 \
7732 _(src_address)                                  \
7733 _(dst_address)                                  \
7734 _(payload_length)                               \
7735 _(hop_limit)                                    \
7736 _(protocol)
7737
7738 uword
7739 unformat_ip6_mask (unformat_input_t * input, va_list * args)
7740 {
7741   u8 **maskp = va_arg (*args, u8 **);
7742   u8 *mask = 0;
7743   u8 found_something = 0;
7744   ip6_header_t *ip;
7745   u32 ip_version_traffic_class_and_flow_label;
7746
7747 #define _(a) u8 a=0;
7748   foreach_ip6_proto_field;
7749 #undef _
7750   u8 version = 0;
7751   u8 traffic_class = 0;
7752   u8 flow_label = 0;
7753
7754   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7755     {
7756       if (unformat (input, "version"))
7757         version = 1;
7758       else if (unformat (input, "traffic-class"))
7759         traffic_class = 1;
7760       else if (unformat (input, "flow-label"))
7761         flow_label = 1;
7762       else if (unformat (input, "src"))
7763         src_address = 1;
7764       else if (unformat (input, "dst"))
7765         dst_address = 1;
7766       else if (unformat (input, "proto"))
7767         protocol = 1;
7768
7769 #define _(a) else if (unformat (input, #a)) a=1;
7770       foreach_ip6_proto_field
7771 #undef _
7772         else
7773         break;
7774     }
7775
7776 #define _(a) found_something += a;
7777   foreach_ip6_proto_field;
7778 #undef _
7779
7780   if (found_something == 0)
7781     return 0;
7782
7783   vec_validate (mask, sizeof (*ip) - 1);
7784
7785   ip = (ip6_header_t *) mask;
7786
7787 #define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
7788   foreach_ip6_proto_field;
7789 #undef _
7790
7791   ip_version_traffic_class_and_flow_label = 0;
7792
7793   if (version)
7794     ip_version_traffic_class_and_flow_label |= 0xF0000000;
7795
7796   if (traffic_class)
7797     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
7798
7799   if (flow_label)
7800     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
7801
7802   ip->ip_version_traffic_class_and_flow_label =
7803     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
7804
7805   *maskp = mask;
7806   return 1;
7807 }
7808
7809 uword
7810 unformat_l3_mask (unformat_input_t * input, va_list * args)
7811 {
7812   u8 **maskp = va_arg (*args, u8 **);
7813
7814   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7815     {
7816       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
7817         return 1;
7818       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
7819         return 1;
7820       else
7821         break;
7822     }
7823   return 0;
7824 }
7825
7826 uword
7827 unformat_l2_mask (unformat_input_t * input, va_list * args)
7828 {
7829   u8 **maskp = va_arg (*args, u8 **);
7830   u8 *mask = 0;
7831   u8 src = 0;
7832   u8 dst = 0;
7833   u8 proto = 0;
7834   u8 tag1 = 0;
7835   u8 tag2 = 0;
7836   u8 ignore_tag1 = 0;
7837   u8 ignore_tag2 = 0;
7838   u8 cos1 = 0;
7839   u8 cos2 = 0;
7840   u8 dot1q = 0;
7841   u8 dot1ad = 0;
7842   int len = 14;
7843
7844   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7845     {
7846       if (unformat (input, "src"))
7847         src = 1;
7848       else if (unformat (input, "dst"))
7849         dst = 1;
7850       else if (unformat (input, "proto"))
7851         proto = 1;
7852       else if (unformat (input, "tag1"))
7853         tag1 = 1;
7854       else if (unformat (input, "tag2"))
7855         tag2 = 1;
7856       else if (unformat (input, "ignore-tag1"))
7857         ignore_tag1 = 1;
7858       else if (unformat (input, "ignore-tag2"))
7859         ignore_tag2 = 1;
7860       else if (unformat (input, "cos1"))
7861         cos1 = 1;
7862       else if (unformat (input, "cos2"))
7863         cos2 = 1;
7864       else if (unformat (input, "dot1q"))
7865         dot1q = 1;
7866       else if (unformat (input, "dot1ad"))
7867         dot1ad = 1;
7868       else
7869         break;
7870     }
7871   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
7872        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
7873     return 0;
7874
7875   if (tag1 || ignore_tag1 || cos1 || dot1q)
7876     len = 18;
7877   if (tag2 || ignore_tag2 || cos2 || dot1ad)
7878     len = 22;
7879
7880   vec_validate (mask, len - 1);
7881
7882   if (dst)
7883     clib_memset (mask, 0xff, 6);
7884
7885   if (src)
7886     clib_memset (mask + 6, 0xff, 6);
7887
7888   if (tag2 || dot1ad)
7889     {
7890       /* inner vlan tag */
7891       if (tag2)
7892         {
7893           mask[19] = 0xff;
7894           mask[18] = 0x0f;
7895         }
7896       if (cos2)
7897         mask[18] |= 0xe0;
7898       if (proto)
7899         mask[21] = mask[20] = 0xff;
7900       if (tag1)
7901         {
7902           mask[15] = 0xff;
7903           mask[14] = 0x0f;
7904         }
7905       if (cos1)
7906         mask[14] |= 0xe0;
7907       *maskp = mask;
7908       return 1;
7909     }
7910   if (tag1 | dot1q)
7911     {
7912       if (tag1)
7913         {
7914           mask[15] = 0xff;
7915           mask[14] = 0x0f;
7916         }
7917       if (cos1)
7918         mask[14] |= 0xe0;
7919       if (proto)
7920         mask[16] = mask[17] = 0xff;
7921
7922       *maskp = mask;
7923       return 1;
7924     }
7925   if (cos2)
7926     mask[18] |= 0xe0;
7927   if (cos1)
7928     mask[14] |= 0xe0;
7929   if (proto)
7930     mask[12] = mask[13] = 0xff;
7931
7932   *maskp = mask;
7933   return 1;
7934 }
7935
7936 uword
7937 unformat_classify_mask (unformat_input_t * input, va_list * args)
7938 {
7939   u8 **maskp = va_arg (*args, u8 **);
7940   u32 *skipp = va_arg (*args, u32 *);
7941   u32 *matchp = va_arg (*args, u32 *);
7942   u32 match;
7943   u8 *mask = 0;
7944   u8 *l2 = 0;
7945   u8 *l3 = 0;
7946   u8 *l4 = 0;
7947   int i;
7948
7949   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7950     {
7951       if (unformat (input, "hex %U", unformat_hex_string, &mask))
7952         ;
7953       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
7954         ;
7955       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
7956         ;
7957       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
7958         ;
7959       else
7960         break;
7961     }
7962
7963   if (l4 && !l3)
7964     {
7965       vec_free (mask);
7966       vec_free (l2);
7967       vec_free (l4);
7968       return 0;
7969     }
7970
7971   if (mask || l2 || l3 || l4)
7972     {
7973       if (l2 || l3 || l4)
7974         {
7975           /* "With a free Ethernet header in every package" */
7976           if (l2 == 0)
7977             vec_validate (l2, 13);
7978           mask = l2;
7979           if (vec_len (l3))
7980             {
7981               vec_append (mask, l3);
7982               vec_free (l3);
7983             }
7984           if (vec_len (l4))
7985             {
7986               vec_append (mask, l4);
7987               vec_free (l4);
7988             }
7989         }
7990
7991       /* Scan forward looking for the first significant mask octet */
7992       for (i = 0; i < vec_len (mask); i++)
7993         if (mask[i])
7994           break;
7995
7996       /* compute (skip, match) params */
7997       *skipp = i / sizeof (u32x4);
7998       vec_delete (mask, *skipp * sizeof (u32x4), 0);
7999
8000       /* Pad mask to an even multiple of the vector size */
8001       while (vec_len (mask) % sizeof (u32x4))
8002         vec_add1 (mask, 0);
8003
8004       match = vec_len (mask) / sizeof (u32x4);
8005
8006       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
8007         {
8008           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
8009           if (*tmp || *(tmp + 1))
8010             break;
8011           match--;
8012         }
8013       if (match == 0)
8014         clib_warning ("BUG: match 0");
8015
8016       _vec_len (mask) = match * sizeof (u32x4);
8017
8018       *matchp = match;
8019       *maskp = mask;
8020
8021       return 1;
8022     }
8023
8024   return 0;
8025 }
8026 #endif /* VPP_API_TEST_BUILTIN */
8027
8028 #define foreach_l2_next                         \
8029 _(drop, DROP)                                   \
8030 _(ethernet, ETHERNET_INPUT)                     \
8031 _(ip4, IP4_INPUT)                               \
8032 _(ip6, IP6_INPUT)
8033
8034 uword
8035 unformat_l2_next_index (unformat_input_t * input, va_list * args)
8036 {
8037   u32 *miss_next_indexp = va_arg (*args, u32 *);
8038   u32 next_index = 0;
8039   u32 tmp;
8040
8041 #define _(n,N) \
8042   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
8043   foreach_l2_next;
8044 #undef _
8045
8046   if (unformat (input, "%d", &tmp))
8047     {
8048       next_index = tmp;
8049       goto out;
8050     }
8051
8052   return 0;
8053
8054 out:
8055   *miss_next_indexp = next_index;
8056   return 1;
8057 }
8058
8059 #define foreach_ip_next                         \
8060 _(drop, DROP)                                   \
8061 _(local, LOCAL)                                 \
8062 _(rewrite, REWRITE)
8063
8064 uword
8065 api_unformat_ip_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 = IP_LOOKUP_NEXT_##N; goto out;}
8073   foreach_ip_next;
8074 #undef _
8075
8076   if (unformat (input, "%d", &tmp))
8077     {
8078       next_index = tmp;
8079       goto out;
8080     }
8081
8082   return 0;
8083
8084 out:
8085   *miss_next_indexp = next_index;
8086   return 1;
8087 }
8088
8089 #define foreach_acl_next                        \
8090 _(deny, DENY)
8091
8092 uword
8093 api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
8094 {
8095   u32 *miss_next_indexp = va_arg (*args, u32 *);
8096   u32 next_index = 0;
8097   u32 tmp;
8098
8099 #define _(n,N) \
8100   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
8101   foreach_acl_next;
8102 #undef _
8103
8104   if (unformat (input, "permit"))
8105     {
8106       next_index = ~0;
8107       goto out;
8108     }
8109   else if (unformat (input, "%d", &tmp))
8110     {
8111       next_index = tmp;
8112       goto out;
8113     }
8114
8115   return 0;
8116
8117 out:
8118   *miss_next_indexp = next_index;
8119   return 1;
8120 }
8121
8122 uword
8123 unformat_policer_precolor (unformat_input_t * input, va_list * args)
8124 {
8125   u32 *r = va_arg (*args, u32 *);
8126
8127   if (unformat (input, "conform-color"))
8128     *r = POLICE_CONFORM;
8129   else if (unformat (input, "exceed-color"))
8130     *r = POLICE_EXCEED;
8131   else
8132     return 0;
8133
8134   return 1;
8135 }
8136
8137 static int
8138 api_classify_add_del_table (vat_main_t * vam)
8139 {
8140   unformat_input_t *i = vam->input;
8141   vl_api_classify_add_del_table_t *mp;
8142
8143   u32 nbuckets = 2;
8144   u32 skip = ~0;
8145   u32 match = ~0;
8146   int is_add = 1;
8147   int del_chain = 0;
8148   u32 table_index = ~0;
8149   u32 next_table_index = ~0;
8150   u32 miss_next_index = ~0;
8151   u32 memory_size = 32 << 20;
8152   u8 *mask = 0;
8153   u32 current_data_flag = 0;
8154   int current_data_offset = 0;
8155   int ret;
8156
8157   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8158     {
8159       if (unformat (i, "del"))
8160         is_add = 0;
8161       else if (unformat (i, "del-chain"))
8162         {
8163           is_add = 0;
8164           del_chain = 1;
8165         }
8166       else if (unformat (i, "buckets %d", &nbuckets))
8167         ;
8168       else if (unformat (i, "memory_size %d", &memory_size))
8169         ;
8170       else if (unformat (i, "skip %d", &skip))
8171         ;
8172       else if (unformat (i, "match %d", &match))
8173         ;
8174       else if (unformat (i, "table %d", &table_index))
8175         ;
8176       else if (unformat (i, "mask %U", unformat_classify_mask,
8177                          &mask, &skip, &match))
8178         ;
8179       else if (unformat (i, "next-table %d", &next_table_index))
8180         ;
8181       else if (unformat (i, "miss-next %U", api_unformat_ip_next_index,
8182                          &miss_next_index))
8183         ;
8184       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
8185                          &miss_next_index))
8186         ;
8187       else if (unformat (i, "acl-miss-next %U", api_unformat_acl_next_index,
8188                          &miss_next_index))
8189         ;
8190       else if (unformat (i, "current-data-flag %d", &current_data_flag))
8191         ;
8192       else if (unformat (i, "current-data-offset %d", &current_data_offset))
8193         ;
8194       else
8195         break;
8196     }
8197
8198   if (is_add && mask == 0)
8199     {
8200       errmsg ("Mask required");
8201       return -99;
8202     }
8203
8204   if (is_add && skip == ~0)
8205     {
8206       errmsg ("skip count required");
8207       return -99;
8208     }
8209
8210   if (is_add && match == ~0)
8211     {
8212       errmsg ("match count required");
8213       return -99;
8214     }
8215
8216   if (!is_add && table_index == ~0)
8217     {
8218       errmsg ("table index required for delete");
8219       return -99;
8220     }
8221
8222   M2 (CLASSIFY_ADD_DEL_TABLE, mp, vec_len (mask));
8223
8224   mp->is_add = is_add;
8225   mp->del_chain = del_chain;
8226   mp->table_index = ntohl (table_index);
8227   mp->nbuckets = ntohl (nbuckets);
8228   mp->memory_size = ntohl (memory_size);
8229   mp->skip_n_vectors = ntohl (skip);
8230   mp->match_n_vectors = ntohl (match);
8231   mp->next_table_index = ntohl (next_table_index);
8232   mp->miss_next_index = ntohl (miss_next_index);
8233   mp->current_data_flag = ntohl (current_data_flag);
8234   mp->current_data_offset = ntohl (current_data_offset);
8235   mp->mask_len = ntohl (vec_len (mask));
8236   clib_memcpy (mp->mask, mask, vec_len (mask));
8237
8238   vec_free (mask);
8239
8240   S (mp);
8241   W (ret);
8242   return ret;
8243 }
8244
8245 #if VPP_API_TEST_BUILTIN == 0
8246 uword
8247 unformat_l4_match (unformat_input_t * input, va_list * args)
8248 {
8249   u8 **matchp = va_arg (*args, u8 **);
8250
8251   u8 *proto_header = 0;
8252   int src_port = 0;
8253   int dst_port = 0;
8254
8255   tcpudp_header_t h;
8256
8257   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8258     {
8259       if (unformat (input, "src_port %d", &src_port))
8260         ;
8261       else if (unformat (input, "dst_port %d", &dst_port))
8262         ;
8263       else
8264         return 0;
8265     }
8266
8267   h.src_port = clib_host_to_net_u16 (src_port);
8268   h.dst_port = clib_host_to_net_u16 (dst_port);
8269   vec_validate (proto_header, sizeof (h) - 1);
8270   memcpy (proto_header, &h, sizeof (h));
8271
8272   *matchp = proto_header;
8273
8274   return 1;
8275 }
8276
8277 uword
8278 unformat_ip4_match (unformat_input_t * input, va_list * args)
8279 {
8280   u8 **matchp = va_arg (*args, u8 **);
8281   u8 *match = 0;
8282   ip4_header_t *ip;
8283   int version = 0;
8284   u32 version_val;
8285   int hdr_length = 0;
8286   u32 hdr_length_val;
8287   int src = 0, dst = 0;
8288   ip4_address_t src_val, dst_val;
8289   int proto = 0;
8290   u32 proto_val;
8291   int tos = 0;
8292   u32 tos_val;
8293   int length = 0;
8294   u32 length_val;
8295   int fragment_id = 0;
8296   u32 fragment_id_val;
8297   int ttl = 0;
8298   int ttl_val;
8299   int checksum = 0;
8300   u32 checksum_val;
8301
8302   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8303     {
8304       if (unformat (input, "version %d", &version_val))
8305         version = 1;
8306       else if (unformat (input, "hdr_length %d", &hdr_length_val))
8307         hdr_length = 1;
8308       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
8309         src = 1;
8310       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
8311         dst = 1;
8312       else if (unformat (input, "proto %d", &proto_val))
8313         proto = 1;
8314       else if (unformat (input, "tos %d", &tos_val))
8315         tos = 1;
8316       else if (unformat (input, "length %d", &length_val))
8317         length = 1;
8318       else if (unformat (input, "fragment_id %d", &fragment_id_val))
8319         fragment_id = 1;
8320       else if (unformat (input, "ttl %d", &ttl_val))
8321         ttl = 1;
8322       else if (unformat (input, "checksum %d", &checksum_val))
8323         checksum = 1;
8324       else
8325         break;
8326     }
8327
8328   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
8329       + ttl + checksum == 0)
8330     return 0;
8331
8332   /*
8333    * Aligned because we use the real comparison functions
8334    */
8335   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
8336
8337   ip = (ip4_header_t *) match;
8338
8339   /* These are realistically matched in practice */
8340   if (src)
8341     ip->src_address.as_u32 = src_val.as_u32;
8342
8343   if (dst)
8344     ip->dst_address.as_u32 = dst_val.as_u32;
8345
8346   if (proto)
8347     ip->protocol = proto_val;
8348
8349
8350   /* These are not, but they're included for completeness */
8351   if (version)
8352     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
8353
8354   if (hdr_length)
8355     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
8356
8357   if (tos)
8358     ip->tos = tos_val;
8359
8360   if (length)
8361     ip->length = clib_host_to_net_u16 (length_val);
8362
8363   if (ttl)
8364     ip->ttl = ttl_val;
8365
8366   if (checksum)
8367     ip->checksum = clib_host_to_net_u16 (checksum_val);
8368
8369   *matchp = match;
8370   return 1;
8371 }
8372
8373 uword
8374 unformat_ip6_match (unformat_input_t * input, va_list * args)
8375 {
8376   u8 **matchp = va_arg (*args, u8 **);
8377   u8 *match = 0;
8378   ip6_header_t *ip;
8379   int version = 0;
8380   u32 version_val;
8381   u8 traffic_class = 0;
8382   u32 traffic_class_val = 0;
8383   u8 flow_label = 0;
8384   u8 flow_label_val;
8385   int src = 0, dst = 0;
8386   ip6_address_t src_val, dst_val;
8387   int proto = 0;
8388   u32 proto_val;
8389   int payload_length = 0;
8390   u32 payload_length_val;
8391   int hop_limit = 0;
8392   int hop_limit_val;
8393   u32 ip_version_traffic_class_and_flow_label;
8394
8395   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8396     {
8397       if (unformat (input, "version %d", &version_val))
8398         version = 1;
8399       else if (unformat (input, "traffic_class %d", &traffic_class_val))
8400         traffic_class = 1;
8401       else if (unformat (input, "flow_label %d", &flow_label_val))
8402         flow_label = 1;
8403       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
8404         src = 1;
8405       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
8406         dst = 1;
8407       else if (unformat (input, "proto %d", &proto_val))
8408         proto = 1;
8409       else if (unformat (input, "payload_length %d", &payload_length_val))
8410         payload_length = 1;
8411       else if (unformat (input, "hop_limit %d", &hop_limit_val))
8412         hop_limit = 1;
8413       else
8414         break;
8415     }
8416
8417   if (version + traffic_class + flow_label + src + dst + proto +
8418       payload_length + hop_limit == 0)
8419     return 0;
8420
8421   /*
8422    * Aligned because we use the real comparison functions
8423    */
8424   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
8425
8426   ip = (ip6_header_t *) match;
8427
8428   if (src)
8429     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
8430
8431   if (dst)
8432     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
8433
8434   if (proto)
8435     ip->protocol = proto_val;
8436
8437   ip_version_traffic_class_and_flow_label = 0;
8438
8439   if (version)
8440     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
8441
8442   if (traffic_class)
8443     ip_version_traffic_class_and_flow_label |=
8444       (traffic_class_val & 0xFF) << 20;
8445
8446   if (flow_label)
8447     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
8448
8449   ip->ip_version_traffic_class_and_flow_label =
8450     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
8451
8452   if (payload_length)
8453     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
8454
8455   if (hop_limit)
8456     ip->hop_limit = hop_limit_val;
8457
8458   *matchp = match;
8459   return 1;
8460 }
8461
8462 uword
8463 unformat_l3_match (unformat_input_t * input, va_list * args)
8464 {
8465   u8 **matchp = va_arg (*args, u8 **);
8466
8467   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8468     {
8469       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
8470         return 1;
8471       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
8472         return 1;
8473       else
8474         break;
8475     }
8476   return 0;
8477 }
8478
8479 uword
8480 unformat_vlan_tag (unformat_input_t * input, va_list * args)
8481 {
8482   u8 *tagp = va_arg (*args, u8 *);
8483   u32 tag;
8484
8485   if (unformat (input, "%d", &tag))
8486     {
8487       tagp[0] = (tag >> 8) & 0x0F;
8488       tagp[1] = tag & 0xFF;
8489       return 1;
8490     }
8491
8492   return 0;
8493 }
8494
8495 uword
8496 unformat_l2_match (unformat_input_t * input, va_list * args)
8497 {
8498   u8 **matchp = va_arg (*args, u8 **);
8499   u8 *match = 0;
8500   u8 src = 0;
8501   u8 src_val[6];
8502   u8 dst = 0;
8503   u8 dst_val[6];
8504   u8 proto = 0;
8505   u16 proto_val;
8506   u8 tag1 = 0;
8507   u8 tag1_val[2];
8508   u8 tag2 = 0;
8509   u8 tag2_val[2];
8510   int len = 14;
8511   u8 ignore_tag1 = 0;
8512   u8 ignore_tag2 = 0;
8513   u8 cos1 = 0;
8514   u8 cos2 = 0;
8515   u32 cos1_val = 0;
8516   u32 cos2_val = 0;
8517
8518   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8519     {
8520       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
8521         src = 1;
8522       else
8523         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
8524         dst = 1;
8525       else if (unformat (input, "proto %U",
8526                          unformat_ethernet_type_host_byte_order, &proto_val))
8527         proto = 1;
8528       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
8529         tag1 = 1;
8530       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
8531         tag2 = 1;
8532       else if (unformat (input, "ignore-tag1"))
8533         ignore_tag1 = 1;
8534       else if (unformat (input, "ignore-tag2"))
8535         ignore_tag2 = 1;
8536       else if (unformat (input, "cos1 %d", &cos1_val))
8537         cos1 = 1;
8538       else if (unformat (input, "cos2 %d", &cos2_val))
8539         cos2 = 1;
8540       else
8541         break;
8542     }
8543   if ((src + dst + proto + tag1 + tag2 +
8544        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
8545     return 0;
8546
8547   if (tag1 || ignore_tag1 || cos1)
8548     len = 18;
8549   if (tag2 || ignore_tag2 || cos2)
8550     len = 22;
8551
8552   vec_validate_aligned (match, len - 1, sizeof (u32x4));
8553
8554   if (dst)
8555     clib_memcpy (match, dst_val, 6);
8556
8557   if (src)
8558     clib_memcpy (match + 6, src_val, 6);
8559
8560   if (tag2)
8561     {
8562       /* inner vlan tag */
8563       match[19] = tag2_val[1];
8564       match[18] = tag2_val[0];
8565       if (cos2)
8566         match[18] |= (cos2_val & 0x7) << 5;
8567       if (proto)
8568         {
8569           match[21] = proto_val & 0xff;
8570           match[20] = proto_val >> 8;
8571         }
8572       if (tag1)
8573         {
8574           match[15] = tag1_val[1];
8575           match[14] = tag1_val[0];
8576         }
8577       if (cos1)
8578         match[14] |= (cos1_val & 0x7) << 5;
8579       *matchp = match;
8580       return 1;
8581     }
8582   if (tag1)
8583     {
8584       match[15] = tag1_val[1];
8585       match[14] = tag1_val[0];
8586       if (proto)
8587         {
8588           match[17] = proto_val & 0xff;
8589           match[16] = proto_val >> 8;
8590         }
8591       if (cos1)
8592         match[14] |= (cos1_val & 0x7) << 5;
8593
8594       *matchp = match;
8595       return 1;
8596     }
8597   if (cos2)
8598     match[18] |= (cos2_val & 0x7) << 5;
8599   if (cos1)
8600     match[14] |= (cos1_val & 0x7) << 5;
8601   if (proto)
8602     {
8603       match[13] = proto_val & 0xff;
8604       match[12] = proto_val >> 8;
8605     }
8606
8607   *matchp = match;
8608   return 1;
8609 }
8610
8611 uword
8612 unformat_qos_source (unformat_input_t * input, va_list * args)
8613 {
8614   int *qs = va_arg (*args, int *);
8615
8616   if (unformat (input, "ip"))
8617     *qs = QOS_SOURCE_IP;
8618   else if (unformat (input, "mpls"))
8619     *qs = QOS_SOURCE_MPLS;
8620   else if (unformat (input, "ext"))
8621     *qs = QOS_SOURCE_EXT;
8622   else if (unformat (input, "vlan"))
8623     *qs = QOS_SOURCE_VLAN;
8624   else
8625     return 0;
8626
8627   return 1;
8628 }
8629 #endif
8630
8631 uword
8632 api_unformat_classify_match (unformat_input_t * input, va_list * args)
8633 {
8634   u8 **matchp = va_arg (*args, u8 **);
8635   u32 skip_n_vectors = va_arg (*args, u32);
8636   u32 match_n_vectors = va_arg (*args, u32);
8637
8638   u8 *match = 0;
8639   u8 *l2 = 0;
8640   u8 *l3 = 0;
8641   u8 *l4 = 0;
8642
8643   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
8644     {
8645       if (unformat (input, "hex %U", unformat_hex_string, &match))
8646         ;
8647       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
8648         ;
8649       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
8650         ;
8651       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
8652         ;
8653       else
8654         break;
8655     }
8656
8657   if (l4 && !l3)
8658     {
8659       vec_free (match);
8660       vec_free (l2);
8661       vec_free (l4);
8662       return 0;
8663     }
8664
8665   if (match || l2 || l3 || l4)
8666     {
8667       if (l2 || l3 || l4)
8668         {
8669           /* "Win a free Ethernet header in every packet" */
8670           if (l2 == 0)
8671             vec_validate_aligned (l2, 13, sizeof (u32x4));
8672           match = l2;
8673           if (vec_len (l3))
8674             {
8675               vec_append_aligned (match, l3, sizeof (u32x4));
8676               vec_free (l3);
8677             }
8678           if (vec_len (l4))
8679             {
8680               vec_append_aligned (match, l4, sizeof (u32x4));
8681               vec_free (l4);
8682             }
8683         }
8684
8685       /* Make sure the vector is big enough even if key is all 0's */
8686       vec_validate_aligned
8687         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
8688          sizeof (u32x4));
8689
8690       /* Set size, include skipped vectors */
8691       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
8692
8693       *matchp = match;
8694
8695       return 1;
8696     }
8697
8698   return 0;
8699 }
8700
8701 static int
8702 api_classify_add_del_session (vat_main_t * vam)
8703 {
8704   unformat_input_t *i = vam->input;
8705   vl_api_classify_add_del_session_t *mp;
8706   int is_add = 1;
8707   u32 table_index = ~0;
8708   u32 hit_next_index = ~0;
8709   u32 opaque_index = ~0;
8710   u8 *match = 0;
8711   i32 advance = 0;
8712   u32 skip_n_vectors = 0;
8713   u32 match_n_vectors = 0;
8714   u32 action = 0;
8715   u32 metadata = 0;
8716   int ret;
8717
8718   /*
8719    * Warning: you have to supply skip_n and match_n
8720    * because the API client cant simply look at the classify
8721    * table object.
8722    */
8723
8724   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8725     {
8726       if (unformat (i, "del"))
8727         is_add = 0;
8728       else if (unformat (i, "hit-next %U", api_unformat_ip_next_index,
8729                          &hit_next_index))
8730         ;
8731       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
8732                          &hit_next_index))
8733         ;
8734       else if (unformat (i, "acl-hit-next %U", api_unformat_acl_next_index,
8735                          &hit_next_index))
8736         ;
8737       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
8738         ;
8739       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
8740         ;
8741       else if (unformat (i, "opaque-index %d", &opaque_index))
8742         ;
8743       else if (unformat (i, "skip_n %d", &skip_n_vectors))
8744         ;
8745       else if (unformat (i, "match_n %d", &match_n_vectors))
8746         ;
8747       else if (unformat (i, "match %U", api_unformat_classify_match,
8748                          &match, skip_n_vectors, match_n_vectors))
8749         ;
8750       else if (unformat (i, "advance %d", &advance))
8751         ;
8752       else if (unformat (i, "table-index %d", &table_index))
8753         ;
8754       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
8755         action = 1;
8756       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
8757         action = 2;
8758       else if (unformat (i, "action %d", &action))
8759         ;
8760       else if (unformat (i, "metadata %d", &metadata))
8761         ;
8762       else
8763         break;
8764     }
8765
8766   if (table_index == ~0)
8767     {
8768       errmsg ("Table index required");
8769       return -99;
8770     }
8771
8772   if (is_add && match == 0)
8773     {
8774       errmsg ("Match value required");
8775       return -99;
8776     }
8777
8778   M2 (CLASSIFY_ADD_DEL_SESSION, mp, vec_len (match));
8779
8780   mp->is_add = is_add;
8781   mp->table_index = ntohl (table_index);
8782   mp->hit_next_index = ntohl (hit_next_index);
8783   mp->opaque_index = ntohl (opaque_index);
8784   mp->advance = ntohl (advance);
8785   mp->action = action;
8786   mp->metadata = ntohl (metadata);
8787   mp->match_len = ntohl (vec_len (match));
8788   clib_memcpy (mp->match, match, vec_len (match));
8789   vec_free (match);
8790
8791   S (mp);
8792   W (ret);
8793   return ret;
8794 }
8795
8796 static int
8797 api_classify_set_interface_ip_table (vat_main_t * vam)
8798 {
8799   unformat_input_t *i = vam->input;
8800   vl_api_classify_set_interface_ip_table_t *mp;
8801   u32 sw_if_index;
8802   int sw_if_index_set;
8803   u32 table_index = ~0;
8804   u8 is_ipv6 = 0;
8805   int ret;
8806
8807   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8808     {
8809       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8810         sw_if_index_set = 1;
8811       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8812         sw_if_index_set = 1;
8813       else if (unformat (i, "table %d", &table_index))
8814         ;
8815       else
8816         {
8817           clib_warning ("parse error '%U'", format_unformat_error, i);
8818           return -99;
8819         }
8820     }
8821
8822   if (sw_if_index_set == 0)
8823     {
8824       errmsg ("missing interface name or sw_if_index");
8825       return -99;
8826     }
8827
8828
8829   M (CLASSIFY_SET_INTERFACE_IP_TABLE, mp);
8830
8831   mp->sw_if_index = ntohl (sw_if_index);
8832   mp->table_index = ntohl (table_index);
8833   mp->is_ipv6 = is_ipv6;
8834
8835   S (mp);
8836   W (ret);
8837   return ret;
8838 }
8839
8840 static int
8841 api_classify_set_interface_l2_tables (vat_main_t * vam)
8842 {
8843   unformat_input_t *i = vam->input;
8844   vl_api_classify_set_interface_l2_tables_t *mp;
8845   u32 sw_if_index;
8846   int sw_if_index_set;
8847   u32 ip4_table_index = ~0;
8848   u32 ip6_table_index = ~0;
8849   u32 other_table_index = ~0;
8850   u32 is_input = 1;
8851   int ret;
8852
8853   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8854     {
8855       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8856         sw_if_index_set = 1;
8857       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8858         sw_if_index_set = 1;
8859       else if (unformat (i, "ip4-table %d", &ip4_table_index))
8860         ;
8861       else if (unformat (i, "ip6-table %d", &ip6_table_index))
8862         ;
8863       else if (unformat (i, "other-table %d", &other_table_index))
8864         ;
8865       else if (unformat (i, "is-input %d", &is_input))
8866         ;
8867       else
8868         {
8869           clib_warning ("parse error '%U'", format_unformat_error, i);
8870           return -99;
8871         }
8872     }
8873
8874   if (sw_if_index_set == 0)
8875     {
8876       errmsg ("missing interface name or sw_if_index");
8877       return -99;
8878     }
8879
8880
8881   M (CLASSIFY_SET_INTERFACE_L2_TABLES, mp);
8882
8883   mp->sw_if_index = ntohl (sw_if_index);
8884   mp->ip4_table_index = ntohl (ip4_table_index);
8885   mp->ip6_table_index = ntohl (ip6_table_index);
8886   mp->other_table_index = ntohl (other_table_index);
8887   mp->is_input = (u8) is_input;
8888
8889   S (mp);
8890   W (ret);
8891   return ret;
8892 }
8893
8894 static int
8895 api_set_ipfix_exporter (vat_main_t * vam)
8896 {
8897   unformat_input_t *i = vam->input;
8898   vl_api_set_ipfix_exporter_t *mp;
8899   ip4_address_t collector_address;
8900   u8 collector_address_set = 0;
8901   u32 collector_port = ~0;
8902   ip4_address_t src_address;
8903   u8 src_address_set = 0;
8904   u32 vrf_id = ~0;
8905   u32 path_mtu = ~0;
8906   u32 template_interval = ~0;
8907   u8 udp_checksum = 0;
8908   int ret;
8909
8910   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8911     {
8912       if (unformat (i, "collector_address %U", unformat_ip4_address,
8913                     &collector_address))
8914         collector_address_set = 1;
8915       else if (unformat (i, "collector_port %d", &collector_port))
8916         ;
8917       else if (unformat (i, "src_address %U", unformat_ip4_address,
8918                          &src_address))
8919         src_address_set = 1;
8920       else if (unformat (i, "vrf_id %d", &vrf_id))
8921         ;
8922       else if (unformat (i, "path_mtu %d", &path_mtu))
8923         ;
8924       else if (unformat (i, "template_interval %d", &template_interval))
8925         ;
8926       else if (unformat (i, "udp_checksum"))
8927         udp_checksum = 1;
8928       else
8929         break;
8930     }
8931
8932   if (collector_address_set == 0)
8933     {
8934       errmsg ("collector_address required");
8935       return -99;
8936     }
8937
8938   if (src_address_set == 0)
8939     {
8940       errmsg ("src_address required");
8941       return -99;
8942     }
8943
8944   M (SET_IPFIX_EXPORTER, mp);
8945
8946   memcpy (mp->collector_address.un.ip4, collector_address.data,
8947           sizeof (collector_address.data));
8948   mp->collector_port = htons ((u16) collector_port);
8949   memcpy (mp->src_address.un.ip4, src_address.data,
8950           sizeof (src_address.data));
8951   mp->vrf_id = htonl (vrf_id);
8952   mp->path_mtu = htonl (path_mtu);
8953   mp->template_interval = htonl (template_interval);
8954   mp->udp_checksum = udp_checksum;
8955
8956   S (mp);
8957   W (ret);
8958   return ret;
8959 }
8960
8961 static int
8962 api_set_ipfix_classify_stream (vat_main_t * vam)
8963 {
8964   unformat_input_t *i = vam->input;
8965   vl_api_set_ipfix_classify_stream_t *mp;
8966   u32 domain_id = 0;
8967   u32 src_port = UDP_DST_PORT_ipfix;
8968   int ret;
8969
8970   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8971     {
8972       if (unformat (i, "domain %d", &domain_id))
8973         ;
8974       else if (unformat (i, "src_port %d", &src_port))
8975         ;
8976       else
8977         {
8978           errmsg ("unknown input `%U'", format_unformat_error, i);
8979           return -99;
8980         }
8981     }
8982
8983   M (SET_IPFIX_CLASSIFY_STREAM, mp);
8984
8985   mp->domain_id = htonl (domain_id);
8986   mp->src_port = htons ((u16) src_port);
8987
8988   S (mp);
8989   W (ret);
8990   return ret;
8991 }
8992
8993 static int
8994 api_ipfix_classify_table_add_del (vat_main_t * vam)
8995 {
8996   unformat_input_t *i = vam->input;
8997   vl_api_ipfix_classify_table_add_del_t *mp;
8998   int is_add = -1;
8999   u32 classify_table_index = ~0;
9000   u8 ip_version = 0;
9001   u8 transport_protocol = 255;
9002   int ret;
9003
9004   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9005     {
9006       if (unformat (i, "add"))
9007         is_add = 1;
9008       else if (unformat (i, "del"))
9009         is_add = 0;
9010       else if (unformat (i, "table %d", &classify_table_index))
9011         ;
9012       else if (unformat (i, "ip4"))
9013         ip_version = 4;
9014       else if (unformat (i, "ip6"))
9015         ip_version = 6;
9016       else if (unformat (i, "tcp"))
9017         transport_protocol = 6;
9018       else if (unformat (i, "udp"))
9019         transport_protocol = 17;
9020       else
9021         {
9022           errmsg ("unknown input `%U'", format_unformat_error, i);
9023           return -99;
9024         }
9025     }
9026
9027   if (is_add == -1)
9028     {
9029       errmsg ("expecting: add|del");
9030       return -99;
9031     }
9032   if (classify_table_index == ~0)
9033     {
9034       errmsg ("classifier table not specified");
9035       return -99;
9036     }
9037   if (ip_version == 0)
9038     {
9039       errmsg ("IP version not specified");
9040       return -99;
9041     }
9042
9043   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, mp);
9044
9045   mp->is_add = is_add;
9046   mp->table_id = htonl (classify_table_index);
9047   mp->ip_version = ip_version;
9048   mp->transport_protocol = transport_protocol;
9049
9050   S (mp);
9051   W (ret);
9052   return ret;
9053 }
9054
9055 static int
9056 api_get_node_index (vat_main_t * vam)
9057 {
9058   unformat_input_t *i = vam->input;
9059   vl_api_get_node_index_t *mp;
9060   u8 *name = 0;
9061   int ret;
9062
9063   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9064     {
9065       if (unformat (i, "node %s", &name))
9066         ;
9067       else
9068         break;
9069     }
9070   if (name == 0)
9071     {
9072       errmsg ("node name required");
9073       return -99;
9074     }
9075   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
9076     {
9077       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
9078       return -99;
9079     }
9080
9081   M (GET_NODE_INDEX, mp);
9082   clib_memcpy (mp->node_name, name, vec_len (name));
9083   vec_free (name);
9084
9085   S (mp);
9086   W (ret);
9087   return ret;
9088 }
9089
9090 static int
9091 api_get_next_index (vat_main_t * vam)
9092 {
9093   unformat_input_t *i = vam->input;
9094   vl_api_get_next_index_t *mp;
9095   u8 *node_name = 0, *next_node_name = 0;
9096   int ret;
9097
9098   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9099     {
9100       if (unformat (i, "node-name %s", &node_name))
9101         ;
9102       else if (unformat (i, "next-node-name %s", &next_node_name))
9103         break;
9104     }
9105
9106   if (node_name == 0)
9107     {
9108       errmsg ("node name required");
9109       return -99;
9110     }
9111   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
9112     {
9113       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
9114       return -99;
9115     }
9116
9117   if (next_node_name == 0)
9118     {
9119       errmsg ("next node name required");
9120       return -99;
9121     }
9122   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
9123     {
9124       errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
9125       return -99;
9126     }
9127
9128   M (GET_NEXT_INDEX, mp);
9129   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
9130   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
9131   vec_free (node_name);
9132   vec_free (next_node_name);
9133
9134   S (mp);
9135   W (ret);
9136   return ret;
9137 }
9138
9139 static int
9140 api_add_node_next (vat_main_t * vam)
9141 {
9142   unformat_input_t *i = vam->input;
9143   vl_api_add_node_next_t *mp;
9144   u8 *name = 0;
9145   u8 *next = 0;
9146   int ret;
9147
9148   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9149     {
9150       if (unformat (i, "node %s", &name))
9151         ;
9152       else if (unformat (i, "next %s", &next))
9153         ;
9154       else
9155         break;
9156     }
9157   if (name == 0)
9158     {
9159       errmsg ("node name required");
9160       return -99;
9161     }
9162   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
9163     {
9164       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
9165       return -99;
9166     }
9167   if (next == 0)
9168     {
9169       errmsg ("next node required");
9170       return -99;
9171     }
9172   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
9173     {
9174       errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
9175       return -99;
9176     }
9177
9178   M (ADD_NODE_NEXT, mp);
9179   clib_memcpy (mp->node_name, name, vec_len (name));
9180   clib_memcpy (mp->next_name, next, vec_len (next));
9181   vec_free (name);
9182   vec_free (next);
9183
9184   S (mp);
9185   W (ret);
9186   return ret;
9187 }
9188
9189 static void vl_api_sw_interface_tap_v2_details_t_handler
9190   (vl_api_sw_interface_tap_v2_details_t * mp)
9191 {
9192   vat_main_t *vam = &vat_main;
9193
9194   u8 *ip4 =
9195     format (0, "%U/%d", format_ip4_address, mp->host_ip4_prefix.address,
9196             mp->host_ip4_prefix.len);
9197   u8 *ip6 =
9198     format (0, "%U/%d", format_ip6_address, mp->host_ip6_prefix.address,
9199             mp->host_ip6_prefix.len);
9200
9201   print (vam->ofp,
9202          "\n%-16s %-12d %-5d %-12d %-12d %-14U %-30s %-20s %-20s %-30s 0x%-08x",
9203          mp->dev_name, ntohl (mp->sw_if_index), ntohl (mp->id),
9204          ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
9205          format_ethernet_address, mp->host_mac_addr, mp->host_namespace,
9206          mp->host_bridge, ip4, ip6, ntohl (mp->tap_flags));
9207
9208   vec_free (ip4);
9209   vec_free (ip6);
9210 }
9211
9212 static void vl_api_sw_interface_tap_v2_details_t_handler_json
9213   (vl_api_sw_interface_tap_v2_details_t * mp)
9214 {
9215   vat_main_t *vam = &vat_main;
9216   vat_json_node_t *node = NULL;
9217
9218   if (VAT_JSON_ARRAY != vam->json_tree.type)
9219     {
9220       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9221       vat_json_init_array (&vam->json_tree);
9222     }
9223   node = vat_json_array_add (&vam->json_tree);
9224
9225   vat_json_init_object (node);
9226   vat_json_object_add_uint (node, "id", ntohl (mp->id));
9227   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
9228   vat_json_object_add_uint (node, "tap_flags", ntohl (mp->tap_flags));
9229   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
9230   vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
9231   vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
9232   vat_json_object_add_string_copy (node, "host_mac_addr",
9233                                    format (0, "%U", format_ethernet_address,
9234                                            &mp->host_mac_addr));
9235   vat_json_object_add_string_copy (node, "host_namespace",
9236                                    mp->host_namespace);
9237   vat_json_object_add_string_copy (node, "host_bridge", mp->host_bridge);
9238   vat_json_object_add_string_copy (node, "host_ip4_addr",
9239                                    format (0, "%U/%d", format_ip4_address,
9240                                            mp->host_ip4_prefix.address,
9241                                            mp->host_ip4_prefix.len));
9242   vat_json_object_add_string_copy (node, "host_ip6_prefix",
9243                                    format (0, "%U/%d", format_ip6_address,
9244                                            mp->host_ip6_prefix.address,
9245                                            mp->host_ip6_prefix.len));
9246
9247 }
9248
9249 static int
9250 api_sw_interface_tap_v2_dump (vat_main_t * vam)
9251 {
9252   vl_api_sw_interface_tap_v2_dump_t *mp;
9253   vl_api_control_ping_t *mp_ping;
9254   int ret;
9255
9256   print (vam->ofp,
9257          "\n%-16s %-12s %-5s %-12s %-12s %-14s %-30s %-20s %-20s %-30s",
9258          "dev_name", "sw_if_index", "id", "rx_ring_sz", "tx_ring_sz",
9259          "host_mac_addr", "host_namespace", "host_bridge", "host_ip4_addr",
9260          "host_ip6_addr");
9261
9262   /* Get list of tap interfaces */
9263   M (SW_INTERFACE_TAP_V2_DUMP, mp);
9264   S (mp);
9265
9266   /* Use a control ping for synchronization */
9267   MPING (CONTROL_PING, mp_ping);
9268   S (mp_ping);
9269
9270   W (ret);
9271   return ret;
9272 }
9273
9274 static void vl_api_sw_interface_virtio_pci_details_t_handler
9275   (vl_api_sw_interface_virtio_pci_details_t * mp)
9276 {
9277   vat_main_t *vam = &vat_main;
9278
9279   typedef union
9280   {
9281     struct
9282     {
9283       u16 domain;
9284       u8 bus;
9285       u8 slot:5;
9286       u8 function:3;
9287     };
9288     u32 as_u32;
9289   } pci_addr_t;
9290   pci_addr_t addr;
9291
9292   addr.domain = ntohs (mp->pci_addr.domain);
9293   addr.bus = mp->pci_addr.bus;
9294   addr.slot = mp->pci_addr.slot;
9295   addr.function = mp->pci_addr.function;
9296
9297   u8 *pci_addr = format (0, "%04x:%02x:%02x.%x", addr.domain, addr.bus,
9298                          addr.slot, addr.function);
9299
9300   print (vam->ofp,
9301          "\n%-12s %-12d %-12d %-12d %-17U 0x%-08llx",
9302          pci_addr, ntohl (mp->sw_if_index),
9303          ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
9304          format_ethernet_address, mp->mac_addr,
9305          clib_net_to_host_u64 (mp->features));
9306   vec_free (pci_addr);
9307 }
9308
9309 static void vl_api_sw_interface_virtio_pci_details_t_handler_json
9310   (vl_api_sw_interface_virtio_pci_details_t * mp)
9311 {
9312   vat_main_t *vam = &vat_main;
9313   vat_json_node_t *node = NULL;
9314   vlib_pci_addr_t pci_addr;
9315
9316   if (VAT_JSON_ARRAY != vam->json_tree.type)
9317     {
9318       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9319       vat_json_init_array (&vam->json_tree);
9320     }
9321   node = vat_json_array_add (&vam->json_tree);
9322
9323   pci_addr.domain = ntohs (mp->pci_addr.domain);
9324   pci_addr.bus = mp->pci_addr.bus;
9325   pci_addr.slot = mp->pci_addr.slot;
9326   pci_addr.function = mp->pci_addr.function;
9327
9328   vat_json_init_object (node);
9329   vat_json_object_add_uint (node, "pci-addr", pci_addr.as_u32);
9330   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
9331   vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
9332   vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
9333   vat_json_object_add_uint (node, "features",
9334                             clib_net_to_host_u64 (mp->features));
9335   vat_json_object_add_string_copy (node, "mac_addr",
9336                                    format (0, "%U", format_ethernet_address,
9337                                            &mp->mac_addr));
9338 }
9339
9340 static int
9341 api_sw_interface_virtio_pci_dump (vat_main_t * vam)
9342 {
9343   vl_api_sw_interface_virtio_pci_dump_t *mp;
9344   vl_api_control_ping_t *mp_ping;
9345   int ret;
9346
9347   print (vam->ofp,
9348          "\n%-12s %-12s %-12s %-12s %-17s %-08s",
9349          "pci_addr", "sw_if_index", "rx_ring_sz", "tx_ring_sz",
9350          "mac_addr", "features");
9351
9352   /* Get list of tap interfaces */
9353   M (SW_INTERFACE_VIRTIO_PCI_DUMP, mp);
9354   S (mp);
9355
9356   /* Use a control ping for synchronization */
9357   MPING (CONTROL_PING, mp_ping);
9358   S (mp_ping);
9359
9360   W (ret);
9361   return ret;
9362 }
9363
9364 static int
9365 api_vxlan_offload_rx (vat_main_t * vam)
9366 {
9367   unformat_input_t *line_input = vam->input;
9368   vl_api_vxlan_offload_rx_t *mp;
9369   u32 hw_if_index = ~0, rx_if_index = ~0;
9370   u8 is_add = 1;
9371   int ret;
9372
9373   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
9374     {
9375       if (unformat (line_input, "del"))
9376         is_add = 0;
9377       else if (unformat (line_input, "hw %U", api_unformat_hw_if_index, vam,
9378                          &hw_if_index))
9379         ;
9380       else if (unformat (line_input, "hw hw_if_index %u", &hw_if_index))
9381         ;
9382       else if (unformat (line_input, "rx %U", api_unformat_sw_if_index, vam,
9383                          &rx_if_index))
9384         ;
9385       else if (unformat (line_input, "rx sw_if_index %u", &rx_if_index))
9386         ;
9387       else
9388         {
9389           errmsg ("parse error '%U'", format_unformat_error, line_input);
9390           return -99;
9391         }
9392     }
9393
9394   if (hw_if_index == ~0)
9395     {
9396       errmsg ("no hw interface");
9397       return -99;
9398     }
9399
9400   if (rx_if_index == ~0)
9401     {
9402       errmsg ("no rx tunnel");
9403       return -99;
9404     }
9405
9406   M (VXLAN_OFFLOAD_RX, mp);
9407
9408   mp->hw_if_index = ntohl (hw_if_index);
9409   mp->sw_if_index = ntohl (rx_if_index);
9410   mp->enable = is_add;
9411
9412   S (mp);
9413   W (ret);
9414   return ret;
9415 }
9416
9417 static uword unformat_vxlan_decap_next
9418   (unformat_input_t * input, va_list * args)
9419 {
9420   u32 *result = va_arg (*args, u32 *);
9421   u32 tmp;
9422
9423   if (unformat (input, "l2"))
9424     *result = VXLAN_INPUT_NEXT_L2_INPUT;
9425   else if (unformat (input, "%d", &tmp))
9426     *result = tmp;
9427   else
9428     return 0;
9429   return 1;
9430 }
9431
9432 static int
9433 api_vxlan_add_del_tunnel (vat_main_t * vam)
9434 {
9435   unformat_input_t *line_input = vam->input;
9436   vl_api_vxlan_add_del_tunnel_t *mp;
9437   ip46_address_t src, dst;
9438   u8 is_add = 1;
9439   u8 ipv4_set = 0, ipv6_set = 0;
9440   u8 src_set = 0;
9441   u8 dst_set = 0;
9442   u8 grp_set = 0;
9443   u32 instance = ~0;
9444   u32 mcast_sw_if_index = ~0;
9445   u32 encap_vrf_id = 0;
9446   u32 decap_next_index = ~0;
9447   u32 vni = 0;
9448   int ret;
9449
9450   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
9451   clib_memset (&src, 0, sizeof src);
9452   clib_memset (&dst, 0, sizeof dst);
9453
9454   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
9455     {
9456       if (unformat (line_input, "del"))
9457         is_add = 0;
9458       else if (unformat (line_input, "instance %d", &instance))
9459         ;
9460       else
9461         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
9462         {
9463           ipv4_set = 1;
9464           src_set = 1;
9465         }
9466       else
9467         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
9468         {
9469           ipv4_set = 1;
9470           dst_set = 1;
9471         }
9472       else
9473         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
9474         {
9475           ipv6_set = 1;
9476           src_set = 1;
9477         }
9478       else
9479         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
9480         {
9481           ipv6_set = 1;
9482           dst_set = 1;
9483         }
9484       else if (unformat (line_input, "group %U %U",
9485                          unformat_ip4_address, &dst.ip4,
9486                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
9487         {
9488           grp_set = dst_set = 1;
9489           ipv4_set = 1;
9490         }
9491       else if (unformat (line_input, "group %U",
9492                          unformat_ip4_address, &dst.ip4))
9493         {
9494           grp_set = dst_set = 1;
9495           ipv4_set = 1;
9496         }
9497       else if (unformat (line_input, "group %U %U",
9498                          unformat_ip6_address, &dst.ip6,
9499                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
9500         {
9501           grp_set = dst_set = 1;
9502           ipv6_set = 1;
9503         }
9504       else if (unformat (line_input, "group %U",
9505                          unformat_ip6_address, &dst.ip6))
9506         {
9507           grp_set = dst_set = 1;
9508           ipv6_set = 1;
9509         }
9510       else
9511         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
9512         ;
9513       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
9514         ;
9515       else if (unformat (line_input, "decap-next %U",
9516                          unformat_vxlan_decap_next, &decap_next_index))
9517         ;
9518       else if (unformat (line_input, "vni %d", &vni))
9519         ;
9520       else
9521         {
9522           errmsg ("parse error '%U'", format_unformat_error, line_input);
9523           return -99;
9524         }
9525     }
9526
9527   if (src_set == 0)
9528     {
9529       errmsg ("tunnel src address not specified");
9530       return -99;
9531     }
9532   if (dst_set == 0)
9533     {
9534       errmsg ("tunnel dst address not specified");
9535       return -99;
9536     }
9537
9538   if (grp_set && !ip46_address_is_multicast (&dst))
9539     {
9540       errmsg ("tunnel group address not multicast");
9541       return -99;
9542     }
9543   if (grp_set && mcast_sw_if_index == ~0)
9544     {
9545       errmsg ("tunnel nonexistent multicast device");
9546       return -99;
9547     }
9548   if (grp_set == 0 && ip46_address_is_multicast (&dst))
9549     {
9550       errmsg ("tunnel dst address must be unicast");
9551       return -99;
9552     }
9553
9554
9555   if (ipv4_set && ipv6_set)
9556     {
9557       errmsg ("both IPv4 and IPv6 addresses specified");
9558       return -99;
9559     }
9560
9561   if ((vni == 0) || (vni >> 24))
9562     {
9563       errmsg ("vni not specified or out of range");
9564       return -99;
9565     }
9566
9567   M (VXLAN_ADD_DEL_TUNNEL, mp);
9568
9569   if (ipv6_set)
9570     {
9571       clib_memcpy (mp->src_address.un.ip6, &src.ip6, sizeof (src.ip6));
9572       clib_memcpy (mp->dst_address.un.ip6, &dst.ip6, sizeof (dst.ip6));
9573     }
9574   else
9575     {
9576       clib_memcpy (mp->src_address.un.ip4, &src.ip4, sizeof (src.ip4));
9577       clib_memcpy (mp->dst_address.un.ip4, &dst.ip4, sizeof (dst.ip4));
9578     }
9579   mp->src_address.af = ipv6_set;
9580   mp->dst_address.af = ipv6_set;
9581
9582   mp->instance = htonl (instance);
9583   mp->encap_vrf_id = ntohl (encap_vrf_id);
9584   mp->decap_next_index = ntohl (decap_next_index);
9585   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
9586   mp->vni = ntohl (vni);
9587   mp->is_add = is_add;
9588
9589   S (mp);
9590   W (ret);
9591   return ret;
9592 }
9593
9594 static void vl_api_vxlan_tunnel_details_t_handler
9595   (vl_api_vxlan_tunnel_details_t * mp)
9596 {
9597   vat_main_t *vam = &vat_main;
9598   ip46_address_t src =
9599     to_ip46 (mp->dst_address.af, (u8 *) & mp->dst_address.un);
9600   ip46_address_t dst =
9601     to_ip46 (mp->dst_address.af, (u8 *) & mp->src_address.un);
9602
9603   print (vam->ofp, "%11d%11d%24U%24U%14d%18d%13d%19d",
9604          ntohl (mp->sw_if_index),
9605          ntohl (mp->instance),
9606          format_ip46_address, &src, IP46_TYPE_ANY,
9607          format_ip46_address, &dst, IP46_TYPE_ANY,
9608          ntohl (mp->encap_vrf_id),
9609          ntohl (mp->decap_next_index), ntohl (mp->vni),
9610          ntohl (mp->mcast_sw_if_index));
9611 }
9612
9613 static void vl_api_vxlan_tunnel_details_t_handler_json
9614   (vl_api_vxlan_tunnel_details_t * mp)
9615 {
9616   vat_main_t *vam = &vat_main;
9617   vat_json_node_t *node = NULL;
9618
9619   if (VAT_JSON_ARRAY != vam->json_tree.type)
9620     {
9621       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9622       vat_json_init_array (&vam->json_tree);
9623     }
9624   node = vat_json_array_add (&vam->json_tree);
9625
9626   vat_json_init_object (node);
9627   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
9628
9629   vat_json_object_add_uint (node, "instance", ntohl (mp->instance));
9630
9631   if (mp->src_address.af)
9632     {
9633       struct in6_addr ip6;
9634
9635       clib_memcpy (&ip6, mp->src_address.un.ip6, sizeof (ip6));
9636       vat_json_object_add_ip6 (node, "src_address", ip6);
9637       clib_memcpy (&ip6, mp->dst_address.un.ip6, sizeof (ip6));
9638       vat_json_object_add_ip6 (node, "dst_address", ip6);
9639     }
9640   else
9641     {
9642       struct in_addr ip4;
9643
9644       clib_memcpy (&ip4, mp->src_address.un.ip4, sizeof (ip4));
9645       vat_json_object_add_ip4 (node, "src_address", ip4);
9646       clib_memcpy (&ip4, mp->dst_address.un.ip4, sizeof (ip4));
9647       vat_json_object_add_ip4 (node, "dst_address", ip4);
9648     }
9649   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
9650   vat_json_object_add_uint (node, "decap_next_index",
9651                             ntohl (mp->decap_next_index));
9652   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
9653   vat_json_object_add_uint (node, "mcast_sw_if_index",
9654                             ntohl (mp->mcast_sw_if_index));
9655 }
9656
9657 static int
9658 api_vxlan_tunnel_dump (vat_main_t * vam)
9659 {
9660   unformat_input_t *i = vam->input;
9661   vl_api_vxlan_tunnel_dump_t *mp;
9662   vl_api_control_ping_t *mp_ping;
9663   u32 sw_if_index;
9664   u8 sw_if_index_set = 0;
9665   int ret;
9666
9667   /* Parse args required to build the message */
9668   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9669     {
9670       if (unformat (i, "sw_if_index %d", &sw_if_index))
9671         sw_if_index_set = 1;
9672       else
9673         break;
9674     }
9675
9676   if (sw_if_index_set == 0)
9677     {
9678       sw_if_index = ~0;
9679     }
9680
9681   if (!vam->json_output)
9682     {
9683       print (vam->ofp, "%11s%11s%24s%24s%14s%18s%13s%19s",
9684              "sw_if_index", "instance", "src_address", "dst_address",
9685              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
9686     }
9687
9688   /* Get list of vxlan-tunnel interfaces */
9689   M (VXLAN_TUNNEL_DUMP, mp);
9690
9691   mp->sw_if_index = htonl (sw_if_index);
9692
9693   S (mp);
9694
9695   /* Use a control ping for synchronization */
9696   MPING (CONTROL_PING, mp_ping);
9697   S (mp_ping);
9698
9699   W (ret);
9700   return ret;
9701 }
9702
9703 static int
9704 api_l2_fib_clear_table (vat_main_t * vam)
9705 {
9706 //  unformat_input_t * i = vam->input;
9707   vl_api_l2_fib_clear_table_t *mp;
9708   int ret;
9709
9710   M (L2_FIB_CLEAR_TABLE, mp);
9711
9712   S (mp);
9713   W (ret);
9714   return ret;
9715 }
9716
9717 static int
9718 api_l2_interface_efp_filter (vat_main_t * vam)
9719 {
9720   unformat_input_t *i = vam->input;
9721   vl_api_l2_interface_efp_filter_t *mp;
9722   u32 sw_if_index;
9723   u8 enable = 1;
9724   u8 sw_if_index_set = 0;
9725   int ret;
9726
9727   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9728     {
9729       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9730         sw_if_index_set = 1;
9731       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9732         sw_if_index_set = 1;
9733       else if (unformat (i, "enable"))
9734         enable = 1;
9735       else if (unformat (i, "disable"))
9736         enable = 0;
9737       else
9738         {
9739           clib_warning ("parse error '%U'", format_unformat_error, i);
9740           return -99;
9741         }
9742     }
9743
9744   if (sw_if_index_set == 0)
9745     {
9746       errmsg ("missing sw_if_index");
9747       return -99;
9748     }
9749
9750   M (L2_INTERFACE_EFP_FILTER, mp);
9751
9752   mp->sw_if_index = ntohl (sw_if_index);
9753   mp->enable_disable = enable;
9754
9755   S (mp);
9756   W (ret);
9757   return ret;
9758 }
9759
9760 #define foreach_vtr_op                          \
9761 _("disable",  L2_VTR_DISABLED)                  \
9762 _("push-1",  L2_VTR_PUSH_1)                     \
9763 _("push-2",  L2_VTR_PUSH_2)                     \
9764 _("pop-1",  L2_VTR_POP_1)                       \
9765 _("pop-2",  L2_VTR_POP_2)                       \
9766 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
9767 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
9768 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
9769 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
9770
9771 static int
9772 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
9773 {
9774   unformat_input_t *i = vam->input;
9775   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
9776   u32 sw_if_index;
9777   u8 sw_if_index_set = 0;
9778   u8 vtr_op_set = 0;
9779   u32 vtr_op = 0;
9780   u32 push_dot1q = 1;
9781   u32 tag1 = ~0;
9782   u32 tag2 = ~0;
9783   int ret;
9784
9785   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9786     {
9787       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9788         sw_if_index_set = 1;
9789       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9790         sw_if_index_set = 1;
9791       else if (unformat (i, "vtr_op %d", &vtr_op))
9792         vtr_op_set = 1;
9793 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
9794       foreach_vtr_op
9795 #undef _
9796         else if (unformat (i, "push_dot1q %d", &push_dot1q))
9797         ;
9798       else if (unformat (i, "tag1 %d", &tag1))
9799         ;
9800       else if (unformat (i, "tag2 %d", &tag2))
9801         ;
9802       else
9803         {
9804           clib_warning ("parse error '%U'", format_unformat_error, i);
9805           return -99;
9806         }
9807     }
9808
9809   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
9810     {
9811       errmsg ("missing vtr operation or sw_if_index");
9812       return -99;
9813     }
9814
9815   M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
9816   mp->sw_if_index = ntohl (sw_if_index);
9817   mp->vtr_op = ntohl (vtr_op);
9818   mp->push_dot1q = ntohl (push_dot1q);
9819   mp->tag1 = ntohl (tag1);
9820   mp->tag2 = ntohl (tag2);
9821
9822   S (mp);
9823   W (ret);
9824   return ret;
9825 }
9826
9827 static int
9828 api_create_vhost_user_if (vat_main_t * vam)
9829 {
9830   unformat_input_t *i = vam->input;
9831   vl_api_create_vhost_user_if_t *mp;
9832   u8 *file_name;
9833   u8 is_server = 0;
9834   u8 file_name_set = 0;
9835   u32 custom_dev_instance = ~0;
9836   u8 hwaddr[6];
9837   u8 use_custom_mac = 0;
9838   u8 disable_mrg_rxbuf = 0;
9839   u8 disable_indirect_desc = 0;
9840   u8 *tag = 0;
9841   u8 enable_gso = 0;
9842   u8 enable_packed = 0;
9843   int ret;
9844
9845   /* Shut up coverity */
9846   clib_memset (hwaddr, 0, sizeof (hwaddr));
9847
9848   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9849     {
9850       if (unformat (i, "socket %s", &file_name))
9851         {
9852           file_name_set = 1;
9853         }
9854       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
9855         ;
9856       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
9857         use_custom_mac = 1;
9858       else if (unformat (i, "server"))
9859         is_server = 1;
9860       else if (unformat (i, "disable_mrg_rxbuf"))
9861         disable_mrg_rxbuf = 1;
9862       else if (unformat (i, "disable_indirect_desc"))
9863         disable_indirect_desc = 1;
9864       else if (unformat (i, "gso"))
9865         enable_gso = 1;
9866       else if (unformat (i, "packed"))
9867         enable_packed = 1;
9868       else if (unformat (i, "tag %s", &tag))
9869         ;
9870       else
9871         break;
9872     }
9873
9874   if (file_name_set == 0)
9875     {
9876       errmsg ("missing socket file name");
9877       return -99;
9878     }
9879
9880   if (vec_len (file_name) > 255)
9881     {
9882       errmsg ("socket file name too long");
9883       return -99;
9884     }
9885   vec_add1 (file_name, 0);
9886
9887   M (CREATE_VHOST_USER_IF, mp);
9888
9889   mp->is_server = is_server;
9890   mp->disable_mrg_rxbuf = disable_mrg_rxbuf;
9891   mp->disable_indirect_desc = disable_indirect_desc;
9892   mp->enable_gso = enable_gso;
9893   mp->enable_packed = enable_packed;
9894   mp->custom_dev_instance = ntohl (custom_dev_instance);
9895   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
9896   vec_free (file_name);
9897   if (custom_dev_instance != ~0)
9898     mp->renumber = 1;
9899
9900   mp->use_custom_mac = use_custom_mac;
9901   clib_memcpy (mp->mac_address, hwaddr, 6);
9902   if (tag)
9903     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
9904   vec_free (tag);
9905
9906   S (mp);
9907   W (ret);
9908   return ret;
9909 }
9910
9911 static int
9912 api_modify_vhost_user_if (vat_main_t * vam)
9913 {
9914   unformat_input_t *i = vam->input;
9915   vl_api_modify_vhost_user_if_t *mp;
9916   u8 *file_name;
9917   u8 is_server = 0;
9918   u8 file_name_set = 0;
9919   u32 custom_dev_instance = ~0;
9920   u8 sw_if_index_set = 0;
9921   u32 sw_if_index = (u32) ~ 0;
9922   u8 enable_gso = 0;
9923   u8 enable_packed = 0;
9924   int ret;
9925
9926   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9927     {
9928       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9929         sw_if_index_set = 1;
9930       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9931         sw_if_index_set = 1;
9932       else if (unformat (i, "socket %s", &file_name))
9933         {
9934           file_name_set = 1;
9935         }
9936       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
9937         ;
9938       else if (unformat (i, "server"))
9939         is_server = 1;
9940       else if (unformat (i, "gso"))
9941         enable_gso = 1;
9942       else if (unformat (i, "packed"))
9943         enable_packed = 1;
9944       else
9945         break;
9946     }
9947
9948   if (sw_if_index_set == 0)
9949     {
9950       errmsg ("missing sw_if_index or interface name");
9951       return -99;
9952     }
9953
9954   if (file_name_set == 0)
9955     {
9956       errmsg ("missing socket file name");
9957       return -99;
9958     }
9959
9960   if (vec_len (file_name) > 255)
9961     {
9962       errmsg ("socket file name too long");
9963       return -99;
9964     }
9965   vec_add1 (file_name, 0);
9966
9967   M (MODIFY_VHOST_USER_IF, mp);
9968
9969   mp->sw_if_index = ntohl (sw_if_index);
9970   mp->is_server = is_server;
9971   mp->enable_gso = enable_gso;
9972   mp->enable_packed = enable_packed;
9973   mp->custom_dev_instance = ntohl (custom_dev_instance);
9974   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
9975   vec_free (file_name);
9976   if (custom_dev_instance != ~0)
9977     mp->renumber = 1;
9978
9979   S (mp);
9980   W (ret);
9981   return ret;
9982 }
9983
9984 static int
9985 api_create_vhost_user_if_v2 (vat_main_t * vam)
9986 {
9987   unformat_input_t *i = vam->input;
9988   vl_api_create_vhost_user_if_v2_t *mp;
9989   u8 *file_name;
9990   u8 is_server = 0;
9991   u8 file_name_set = 0;
9992   u32 custom_dev_instance = ~0;
9993   u8 hwaddr[6];
9994   u8 use_custom_mac = 0;
9995   u8 disable_mrg_rxbuf = 0;
9996   u8 disable_indirect_desc = 0;
9997   u8 *tag = 0;
9998   u8 enable_gso = 0;
9999   u8 enable_packed = 0;
10000   u8 enable_event_idx = 0;
10001   int ret;
10002
10003   /* Shut up coverity */
10004   clib_memset (hwaddr, 0, sizeof (hwaddr));
10005
10006   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10007     {
10008       if (unformat (i, "socket %s", &file_name))
10009         {
10010           file_name_set = 1;
10011         }
10012       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
10013         ;
10014       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
10015         use_custom_mac = 1;
10016       else if (unformat (i, "server"))
10017         is_server = 1;
10018       else if (unformat (i, "disable_mrg_rxbuf"))
10019         disable_mrg_rxbuf = 1;
10020       else if (unformat (i, "disable_indirect_desc"))
10021         disable_indirect_desc = 1;
10022       else if (unformat (i, "gso"))
10023         enable_gso = 1;
10024       else if (unformat (i, "packed"))
10025         enable_packed = 1;
10026       else if (unformat (i, "event-idx"))
10027         enable_event_idx = 1;
10028       else if (unformat (i, "tag %s", &tag))
10029         ;
10030       else
10031         break;
10032     }
10033
10034   if (file_name_set == 0)
10035     {
10036       errmsg ("missing socket file name");
10037       return -99;
10038     }
10039
10040   if (vec_len (file_name) > 255)
10041     {
10042       errmsg ("socket file name too long");
10043       return -99;
10044     }
10045   vec_add1 (file_name, 0);
10046
10047   M (CREATE_VHOST_USER_IF_V2, mp);
10048
10049   mp->is_server = is_server;
10050   mp->disable_mrg_rxbuf = disable_mrg_rxbuf;
10051   mp->disable_indirect_desc = disable_indirect_desc;
10052   mp->enable_gso = enable_gso;
10053   mp->enable_packed = enable_packed;
10054   mp->enable_event_idx = enable_event_idx;
10055   mp->custom_dev_instance = ntohl (custom_dev_instance);
10056   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
10057   vec_free (file_name);
10058   if (custom_dev_instance != ~0)
10059     mp->renumber = 1;
10060
10061   mp->use_custom_mac = use_custom_mac;
10062   clib_memcpy (mp->mac_address, hwaddr, 6);
10063   if (tag)
10064     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
10065   vec_free (tag);
10066
10067   S (mp);
10068   W (ret);
10069   return ret;
10070 }
10071
10072 static int
10073 api_modify_vhost_user_if_v2 (vat_main_t * vam)
10074 {
10075   unformat_input_t *i = vam->input;
10076   vl_api_modify_vhost_user_if_v2_t *mp;
10077   u8 *file_name;
10078   u8 is_server = 0;
10079   u8 file_name_set = 0;
10080   u32 custom_dev_instance = ~0;
10081   u8 sw_if_index_set = 0;
10082   u32 sw_if_index = (u32) ~ 0;
10083   u8 enable_gso = 0;
10084   u8 enable_packed = 0;
10085   u8 enable_event_idx = 0;
10086   int ret;
10087
10088   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10089     {
10090       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10091         sw_if_index_set = 1;
10092       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10093         sw_if_index_set = 1;
10094       else if (unformat (i, "socket %s", &file_name))
10095         {
10096           file_name_set = 1;
10097         }
10098       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
10099         ;
10100       else if (unformat (i, "server"))
10101         is_server = 1;
10102       else if (unformat (i, "gso"))
10103         enable_gso = 1;
10104       else if (unformat (i, "packed"))
10105         enable_packed = 1;
10106       else if (unformat (i, "event-idx"))
10107         enable_event_idx = 1;
10108       else
10109         break;
10110     }
10111
10112   if (sw_if_index_set == 0)
10113     {
10114       errmsg ("missing sw_if_index or interface name");
10115       return -99;
10116     }
10117
10118   if (file_name_set == 0)
10119     {
10120       errmsg ("missing socket file name");
10121       return -99;
10122     }
10123
10124   if (vec_len (file_name) > 255)
10125     {
10126       errmsg ("socket file name too long");
10127       return -99;
10128     }
10129   vec_add1 (file_name, 0);
10130
10131   M (MODIFY_VHOST_USER_IF_V2, mp);
10132
10133   mp->sw_if_index = ntohl (sw_if_index);
10134   mp->is_server = is_server;
10135   mp->enable_gso = enable_gso;
10136   mp->enable_packed = enable_packed;
10137   mp->enable_event_idx = enable_event_idx;
10138   mp->custom_dev_instance = ntohl (custom_dev_instance);
10139   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
10140   vec_free (file_name);
10141   if (custom_dev_instance != ~0)
10142     mp->renumber = 1;
10143
10144   S (mp);
10145   W (ret);
10146   return ret;
10147 }
10148
10149 static int
10150 api_delete_vhost_user_if (vat_main_t * vam)
10151 {
10152   unformat_input_t *i = vam->input;
10153   vl_api_delete_vhost_user_if_t *mp;
10154   u32 sw_if_index = ~0;
10155   u8 sw_if_index_set = 0;
10156   int ret;
10157
10158   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10159     {
10160       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10161         sw_if_index_set = 1;
10162       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10163         sw_if_index_set = 1;
10164       else
10165         break;
10166     }
10167
10168   if (sw_if_index_set == 0)
10169     {
10170       errmsg ("missing sw_if_index or interface name");
10171       return -99;
10172     }
10173
10174
10175   M (DELETE_VHOST_USER_IF, mp);
10176
10177   mp->sw_if_index = ntohl (sw_if_index);
10178
10179   S (mp);
10180   W (ret);
10181   return ret;
10182 }
10183
10184 static void vl_api_sw_interface_vhost_user_details_t_handler
10185   (vl_api_sw_interface_vhost_user_details_t * mp)
10186 {
10187   vat_main_t *vam = &vat_main;
10188   u64 features;
10189
10190   features =
10191     clib_net_to_host_u32 (mp->features_first_32) | ((u64)
10192                                                     clib_net_to_host_u32
10193                                                     (mp->features_last_32) <<
10194                                                     32);
10195
10196   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %16llx %6d %7d %s",
10197          (char *) mp->interface_name, ntohl (mp->sw_if_index),
10198          ntohl (mp->virtio_net_hdr_sz), features, mp->is_server,
10199          ntohl (mp->num_regions), (char *) mp->sock_filename);
10200   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
10201 }
10202
10203 static void vl_api_sw_interface_vhost_user_details_t_handler_json
10204   (vl_api_sw_interface_vhost_user_details_t * mp)
10205 {
10206   vat_main_t *vam = &vat_main;
10207   vat_json_node_t *node = NULL;
10208
10209   if (VAT_JSON_ARRAY != vam->json_tree.type)
10210     {
10211       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10212       vat_json_init_array (&vam->json_tree);
10213     }
10214   node = vat_json_array_add (&vam->json_tree);
10215
10216   vat_json_init_object (node);
10217   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10218   vat_json_object_add_string_copy (node, "interface_name",
10219                                    mp->interface_name);
10220   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
10221                             ntohl (mp->virtio_net_hdr_sz));
10222   vat_json_object_add_uint (node, "features_first_32",
10223                             clib_net_to_host_u32 (mp->features_first_32));
10224   vat_json_object_add_uint (node, "features_last_32",
10225                             clib_net_to_host_u32 (mp->features_last_32));
10226   vat_json_object_add_uint (node, "is_server", mp->is_server);
10227   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
10228   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
10229   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
10230 }
10231
10232 static int
10233 api_sw_interface_vhost_user_dump (vat_main_t * vam)
10234 {
10235   unformat_input_t *i = vam->input;
10236   vl_api_sw_interface_vhost_user_dump_t *mp;
10237   vl_api_control_ping_t *mp_ping;
10238   int ret;
10239   u32 sw_if_index = ~0;
10240
10241   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10242     {
10243       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10244         ;
10245       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10246         ;
10247       else
10248         break;
10249     }
10250
10251   print (vam->ofp, "Interface name            idx hdr_sz         features "
10252                    "server regions filename");
10253
10254   /* Get list of vhost-user interfaces */
10255   M (SW_INTERFACE_VHOST_USER_DUMP, mp);
10256   mp->sw_if_index = ntohl (sw_if_index);
10257   S (mp);
10258
10259   /* Use a control ping for synchronization */
10260   MPING (CONTROL_PING, mp_ping);
10261   S (mp_ping);
10262
10263   W (ret);
10264   return ret;
10265 }
10266
10267 static int
10268 api_show_version (vat_main_t * vam)
10269 {
10270   vl_api_show_version_t *mp;
10271   int ret;
10272
10273   M (SHOW_VERSION, mp);
10274
10275   S (mp);
10276   W (ret);
10277   return ret;
10278 }
10279
10280
10281 static int
10282 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
10283 {
10284   unformat_input_t *line_input = vam->input;
10285   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
10286   ip46_address_t local, remote;
10287   u8 is_add = 1;
10288   u8 local_set = 0;
10289   u8 remote_set = 0;
10290   u8 grp_set = 0;
10291   u32 mcast_sw_if_index = ~0;
10292   u32 encap_vrf_id = 0;
10293   u32 decap_vrf_id = 0;
10294   u8 protocol = ~0;
10295   u32 vni;
10296   u8 vni_set = 0;
10297   int ret;
10298
10299   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10300     {
10301       if (unformat (line_input, "del"))
10302         is_add = 0;
10303       else if (unformat (line_input, "local %U",
10304                          unformat_ip46_address, &local))
10305         {
10306           local_set = 1;
10307         }
10308       else if (unformat (line_input, "remote %U",
10309                          unformat_ip46_address, &remote))
10310         {
10311           remote_set = 1;
10312         }
10313       else if (unformat (line_input, "group %U %U",
10314                          unformat_ip46_address, &remote,
10315                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
10316         {
10317           grp_set = remote_set = 1;
10318         }
10319       else if (unformat (line_input, "group %U",
10320                          unformat_ip46_address, &remote))
10321         {
10322           grp_set = remote_set = 1;
10323         }
10324       else
10325         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
10326         ;
10327       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
10328         ;
10329       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
10330         ;
10331       else if (unformat (line_input, "vni %d", &vni))
10332         vni_set = 1;
10333       else if (unformat (line_input, "next-ip4"))
10334         protocol = 1;
10335       else if (unformat (line_input, "next-ip6"))
10336         protocol = 2;
10337       else if (unformat (line_input, "next-ethernet"))
10338         protocol = 3;
10339       else if (unformat (line_input, "next-nsh"))
10340         protocol = 4;
10341       else
10342         {
10343           errmsg ("parse error '%U'", format_unformat_error, line_input);
10344           return -99;
10345         }
10346     }
10347
10348   if (local_set == 0)
10349     {
10350       errmsg ("tunnel local address not specified");
10351       return -99;
10352     }
10353   if (remote_set == 0)
10354     {
10355       errmsg ("tunnel remote address not specified");
10356       return -99;
10357     }
10358   if (grp_set && mcast_sw_if_index == ~0)
10359     {
10360       errmsg ("tunnel nonexistent multicast device");
10361       return -99;
10362     }
10363   if (ip46_address_is_ip4 (&local) != ip46_address_is_ip4 (&remote))
10364     {
10365       errmsg ("both IPv4 and IPv6 addresses specified");
10366       return -99;
10367     }
10368
10369   if (vni_set == 0)
10370     {
10371       errmsg ("vni not specified");
10372       return -99;
10373     }
10374
10375   M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
10376
10377   ip_address_encode (&local,
10378                      ip46_address_is_ip4 (&local) ? IP46_TYPE_IP4 :
10379                      IP46_TYPE_IP6, &mp->local);
10380   ip_address_encode (&remote,
10381                      ip46_address_is_ip4 (&remote) ? IP46_TYPE_IP4 :
10382                      IP46_TYPE_IP6, &mp->remote);
10383
10384   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
10385   mp->encap_vrf_id = ntohl (encap_vrf_id);
10386   mp->decap_vrf_id = ntohl (decap_vrf_id);
10387   mp->protocol = protocol;
10388   mp->vni = ntohl (vni);
10389   mp->is_add = is_add;
10390
10391   S (mp);
10392   W (ret);
10393   return ret;
10394 }
10395
10396 static void vl_api_vxlan_gpe_tunnel_details_t_handler
10397   (vl_api_vxlan_gpe_tunnel_details_t * mp)
10398 {
10399   vat_main_t *vam = &vat_main;
10400   ip46_address_t local, remote;
10401
10402   ip_address_decode (&mp->local, &local);
10403   ip_address_decode (&mp->remote, &remote);
10404
10405   print (vam->ofp, "%11d%24U%24U%13d%12d%19d%14d%14d",
10406          ntohl (mp->sw_if_index),
10407          format_ip46_address, &local, IP46_TYPE_ANY,
10408          format_ip46_address, &remote, IP46_TYPE_ANY,
10409          ntohl (mp->vni), mp->protocol,
10410          ntohl (mp->mcast_sw_if_index),
10411          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
10412 }
10413
10414
10415 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
10416   (vl_api_vxlan_gpe_tunnel_details_t * mp)
10417 {
10418   vat_main_t *vam = &vat_main;
10419   vat_json_node_t *node = NULL;
10420   struct in_addr ip4;
10421   struct in6_addr ip6;
10422   ip46_address_t local, remote;
10423
10424   ip_address_decode (&mp->local, &local);
10425   ip_address_decode (&mp->remote, &remote);
10426
10427   if (VAT_JSON_ARRAY != vam->json_tree.type)
10428     {
10429       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10430       vat_json_init_array (&vam->json_tree);
10431     }
10432   node = vat_json_array_add (&vam->json_tree);
10433
10434   vat_json_init_object (node);
10435   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10436   if (ip46_address_is_ip4 (&local))
10437     {
10438       clib_memcpy (&ip4, &local.ip4, sizeof (ip4));
10439       vat_json_object_add_ip4 (node, "local", ip4);
10440       clib_memcpy (&ip4, &remote.ip4, sizeof (ip4));
10441       vat_json_object_add_ip4 (node, "remote", ip4);
10442     }
10443   else
10444     {
10445       clib_memcpy (&ip6, &local.ip6, sizeof (ip6));
10446       vat_json_object_add_ip6 (node, "local", ip6);
10447       clib_memcpy (&ip6, &remote.ip6, sizeof (ip6));
10448       vat_json_object_add_ip6 (node, "remote", ip6);
10449     }
10450   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
10451   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
10452   vat_json_object_add_uint (node, "mcast_sw_if_index",
10453                             ntohl (mp->mcast_sw_if_index));
10454   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
10455   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
10456   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
10457 }
10458
10459 static int
10460 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
10461 {
10462   unformat_input_t *i = vam->input;
10463   vl_api_vxlan_gpe_tunnel_dump_t *mp;
10464   vl_api_control_ping_t *mp_ping;
10465   u32 sw_if_index;
10466   u8 sw_if_index_set = 0;
10467   int ret;
10468
10469   /* Parse args required to build the message */
10470   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10471     {
10472       if (unformat (i, "sw_if_index %d", &sw_if_index))
10473         sw_if_index_set = 1;
10474       else
10475         break;
10476     }
10477
10478   if (sw_if_index_set == 0)
10479     {
10480       sw_if_index = ~0;
10481     }
10482
10483   if (!vam->json_output)
10484     {
10485       print (vam->ofp, "%11s%24s%24s%13s%15s%19s%14s%14s",
10486              "sw_if_index", "local", "remote", "vni",
10487              "protocol", "mcast_sw_if_index", "encap_vrf_id", "decap_vrf_id");
10488     }
10489
10490   /* Get list of vxlan-tunnel interfaces */
10491   M (VXLAN_GPE_TUNNEL_DUMP, mp);
10492
10493   mp->sw_if_index = htonl (sw_if_index);
10494
10495   S (mp);
10496
10497   /* Use a control ping for synchronization */
10498   MPING (CONTROL_PING, mp_ping);
10499   S (mp_ping);
10500
10501   W (ret);
10502   return ret;
10503 }
10504
10505 static void vl_api_l2_fib_table_details_t_handler
10506   (vl_api_l2_fib_table_details_t * mp)
10507 {
10508   vat_main_t *vam = &vat_main;
10509
10510   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
10511          "       %d       %d     %d",
10512          ntohl (mp->bd_id), format_ethernet_address, mp->mac,
10513          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
10514          mp->bvi_mac);
10515 }
10516
10517 static void vl_api_l2_fib_table_details_t_handler_json
10518   (vl_api_l2_fib_table_details_t * mp)
10519 {
10520   vat_main_t *vam = &vat_main;
10521   vat_json_node_t *node = NULL;
10522
10523   if (VAT_JSON_ARRAY != vam->json_tree.type)
10524     {
10525       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
10526       vat_json_init_array (&vam->json_tree);
10527     }
10528   node = vat_json_array_add (&vam->json_tree);
10529
10530   vat_json_init_object (node);
10531   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
10532   vat_json_object_add_bytes (node, "mac", mp->mac, 6);
10533   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
10534   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
10535   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
10536   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
10537 }
10538
10539 static int
10540 api_l2_fib_table_dump (vat_main_t * vam)
10541 {
10542   unformat_input_t *i = vam->input;
10543   vl_api_l2_fib_table_dump_t *mp;
10544   vl_api_control_ping_t *mp_ping;
10545   u32 bd_id;
10546   u8 bd_id_set = 0;
10547   int ret;
10548
10549   /* Parse args required to build the message */
10550   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10551     {
10552       if (unformat (i, "bd_id %d", &bd_id))
10553         bd_id_set = 1;
10554       else
10555         break;
10556     }
10557
10558   if (bd_id_set == 0)
10559     {
10560       errmsg ("missing bridge domain");
10561       return -99;
10562     }
10563
10564   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
10565
10566   /* Get list of l2 fib entries */
10567   M (L2_FIB_TABLE_DUMP, mp);
10568
10569   mp->bd_id = ntohl (bd_id);
10570   S (mp);
10571
10572   /* Use a control ping for synchronization */
10573   MPING (CONTROL_PING, mp_ping);
10574   S (mp_ping);
10575
10576   W (ret);
10577   return ret;
10578 }
10579
10580
10581 static int
10582 api_interface_name_renumber (vat_main_t * vam)
10583 {
10584   unformat_input_t *line_input = vam->input;
10585   vl_api_interface_name_renumber_t *mp;
10586   u32 sw_if_index = ~0;
10587   u32 new_show_dev_instance = ~0;
10588   int ret;
10589
10590   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10591     {
10592       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
10593                     &sw_if_index))
10594         ;
10595       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
10596         ;
10597       else if (unformat (line_input, "new_show_dev_instance %d",
10598                          &new_show_dev_instance))
10599         ;
10600       else
10601         break;
10602     }
10603
10604   if (sw_if_index == ~0)
10605     {
10606       errmsg ("missing interface name or sw_if_index");
10607       return -99;
10608     }
10609
10610   if (new_show_dev_instance == ~0)
10611     {
10612       errmsg ("missing new_show_dev_instance");
10613       return -99;
10614     }
10615
10616   M (INTERFACE_NAME_RENUMBER, mp);
10617
10618   mp->sw_if_index = ntohl (sw_if_index);
10619   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
10620
10621   S (mp);
10622   W (ret);
10623   return ret;
10624 }
10625
10626 static int
10627 api_want_l2_macs_events (vat_main_t * vam)
10628 {
10629   unformat_input_t *line_input = vam->input;
10630   vl_api_want_l2_macs_events_t *mp;
10631   u8 enable_disable = 1;
10632   u32 scan_delay = 0;
10633   u32 max_macs_in_event = 0;
10634   u32 learn_limit = 0;
10635   int ret;
10636
10637   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
10638     {
10639       if (unformat (line_input, "learn-limit %d", &learn_limit))
10640         ;
10641       else if (unformat (line_input, "scan-delay %d", &scan_delay))
10642         ;
10643       else if (unformat (line_input, "max-entries %d", &max_macs_in_event))
10644         ;
10645       else if (unformat (line_input, "disable"))
10646         enable_disable = 0;
10647       else
10648         break;
10649     }
10650
10651   M (WANT_L2_MACS_EVENTS, mp);
10652   mp->enable_disable = enable_disable;
10653   mp->pid = htonl (getpid ());
10654   mp->learn_limit = htonl (learn_limit);
10655   mp->scan_delay = (u8) scan_delay;
10656   mp->max_macs_in_event = (u8) (max_macs_in_event / 10);
10657   S (mp);
10658   W (ret);
10659   return ret;
10660 }
10661
10662 static int
10663 api_input_acl_set_interface (vat_main_t * vam)
10664 {
10665   unformat_input_t *i = vam->input;
10666   vl_api_input_acl_set_interface_t *mp;
10667   u32 sw_if_index;
10668   int sw_if_index_set;
10669   u32 ip4_table_index = ~0;
10670   u32 ip6_table_index = ~0;
10671   u32 l2_table_index = ~0;
10672   u8 is_add = 1;
10673   int ret;
10674
10675   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10676     {
10677       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10678         sw_if_index_set = 1;
10679       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10680         sw_if_index_set = 1;
10681       else if (unformat (i, "del"))
10682         is_add = 0;
10683       else if (unformat (i, "ip4-table %d", &ip4_table_index))
10684         ;
10685       else if (unformat (i, "ip6-table %d", &ip6_table_index))
10686         ;
10687       else if (unformat (i, "l2-table %d", &l2_table_index))
10688         ;
10689       else
10690         {
10691           clib_warning ("parse error '%U'", format_unformat_error, i);
10692           return -99;
10693         }
10694     }
10695
10696   if (sw_if_index_set == 0)
10697     {
10698       errmsg ("missing interface name or sw_if_index");
10699       return -99;
10700     }
10701
10702   M (INPUT_ACL_SET_INTERFACE, mp);
10703
10704   mp->sw_if_index = ntohl (sw_if_index);
10705   mp->ip4_table_index = ntohl (ip4_table_index);
10706   mp->ip6_table_index = ntohl (ip6_table_index);
10707   mp->l2_table_index = ntohl (l2_table_index);
10708   mp->is_add = is_add;
10709
10710   S (mp);
10711   W (ret);
10712   return ret;
10713 }
10714
10715 static int
10716 api_output_acl_set_interface (vat_main_t * vam)
10717 {
10718   unformat_input_t *i = vam->input;
10719   vl_api_output_acl_set_interface_t *mp;
10720   u32 sw_if_index;
10721   int sw_if_index_set;
10722   u32 ip4_table_index = ~0;
10723   u32 ip6_table_index = ~0;
10724   u32 l2_table_index = ~0;
10725   u8 is_add = 1;
10726   int ret;
10727
10728   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10729     {
10730       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10731         sw_if_index_set = 1;
10732       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10733         sw_if_index_set = 1;
10734       else if (unformat (i, "del"))
10735         is_add = 0;
10736       else if (unformat (i, "ip4-table %d", &ip4_table_index))
10737         ;
10738       else if (unformat (i, "ip6-table %d", &ip6_table_index))
10739         ;
10740       else if (unformat (i, "l2-table %d", &l2_table_index))
10741         ;
10742       else
10743         {
10744           clib_warning ("parse error '%U'", format_unformat_error, i);
10745           return -99;
10746         }
10747     }
10748
10749   if (sw_if_index_set == 0)
10750     {
10751       errmsg ("missing interface name or sw_if_index");
10752       return -99;
10753     }
10754
10755   M (OUTPUT_ACL_SET_INTERFACE, mp);
10756
10757   mp->sw_if_index = ntohl (sw_if_index);
10758   mp->ip4_table_index = ntohl (ip4_table_index);
10759   mp->ip6_table_index = ntohl (ip6_table_index);
10760   mp->l2_table_index = ntohl (l2_table_index);
10761   mp->is_add = is_add;
10762
10763   S (mp);
10764   W (ret);
10765   return ret;
10766 }
10767
10768 static int
10769 api_ip_address_dump (vat_main_t * vam)
10770 {
10771   unformat_input_t *i = vam->input;
10772   vl_api_ip_address_dump_t *mp;
10773   vl_api_control_ping_t *mp_ping;
10774   u32 sw_if_index = ~0;
10775   u8 sw_if_index_set = 0;
10776   u8 ipv4_set = 0;
10777   u8 ipv6_set = 0;
10778   int ret;
10779
10780   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10781     {
10782       if (unformat (i, "sw_if_index %d", &sw_if_index))
10783         sw_if_index_set = 1;
10784       else
10785         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10786         sw_if_index_set = 1;
10787       else if (unformat (i, "ipv4"))
10788         ipv4_set = 1;
10789       else if (unformat (i, "ipv6"))
10790         ipv6_set = 1;
10791       else
10792         break;
10793     }
10794
10795   if (ipv4_set && ipv6_set)
10796     {
10797       errmsg ("ipv4 and ipv6 flags cannot be both set");
10798       return -99;
10799     }
10800
10801   if ((!ipv4_set) && (!ipv6_set))
10802     {
10803       errmsg ("no ipv4 nor ipv6 flag set");
10804       return -99;
10805     }
10806
10807   if (sw_if_index_set == 0)
10808     {
10809       errmsg ("missing interface name or sw_if_index");
10810       return -99;
10811     }
10812
10813   vam->current_sw_if_index = sw_if_index;
10814   vam->is_ipv6 = ipv6_set;
10815
10816   M (IP_ADDRESS_DUMP, mp);
10817   mp->sw_if_index = ntohl (sw_if_index);
10818   mp->is_ipv6 = ipv6_set;
10819   S (mp);
10820
10821   /* Use a control ping for synchronization */
10822   MPING (CONTROL_PING, mp_ping);
10823   S (mp_ping);
10824
10825   W (ret);
10826   return ret;
10827 }
10828
10829 static int
10830 api_ip_dump (vat_main_t * vam)
10831 {
10832   vl_api_ip_dump_t *mp;
10833   vl_api_control_ping_t *mp_ping;
10834   unformat_input_t *in = vam->input;
10835   int ipv4_set = 0;
10836   int ipv6_set = 0;
10837   int is_ipv6;
10838   int i;
10839   int ret;
10840
10841   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
10842     {
10843       if (unformat (in, "ipv4"))
10844         ipv4_set = 1;
10845       else if (unformat (in, "ipv6"))
10846         ipv6_set = 1;
10847       else
10848         break;
10849     }
10850
10851   if (ipv4_set && ipv6_set)
10852     {
10853       errmsg ("ipv4 and ipv6 flags cannot be both set");
10854       return -99;
10855     }
10856
10857   if ((!ipv4_set) && (!ipv6_set))
10858     {
10859       errmsg ("no ipv4 nor ipv6 flag set");
10860       return -99;
10861     }
10862
10863   is_ipv6 = ipv6_set;
10864   vam->is_ipv6 = is_ipv6;
10865
10866   /* free old data */
10867   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
10868     {
10869       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
10870     }
10871   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
10872
10873   M (IP_DUMP, mp);
10874   mp->is_ipv6 = ipv6_set;
10875   S (mp);
10876
10877   /* Use a control ping for synchronization */
10878   MPING (CONTROL_PING, mp_ping);
10879   S (mp_ping);
10880
10881   W (ret);
10882   return ret;
10883 }
10884
10885 static int
10886 api_ipsec_spd_add_del (vat_main_t * vam)
10887 {
10888   unformat_input_t *i = vam->input;
10889   vl_api_ipsec_spd_add_del_t *mp;
10890   u32 spd_id = ~0;
10891   u8 is_add = 1;
10892   int ret;
10893
10894   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10895     {
10896       if (unformat (i, "spd_id %d", &spd_id))
10897         ;
10898       else if (unformat (i, "del"))
10899         is_add = 0;
10900       else
10901         {
10902           clib_warning ("parse error '%U'", format_unformat_error, i);
10903           return -99;
10904         }
10905     }
10906   if (spd_id == ~0)
10907     {
10908       errmsg ("spd_id must be set");
10909       return -99;
10910     }
10911
10912   M (IPSEC_SPD_ADD_DEL, mp);
10913
10914   mp->spd_id = ntohl (spd_id);
10915   mp->is_add = is_add;
10916
10917   S (mp);
10918   W (ret);
10919   return ret;
10920 }
10921
10922 static int
10923 api_ipsec_interface_add_del_spd (vat_main_t * vam)
10924 {
10925   unformat_input_t *i = vam->input;
10926   vl_api_ipsec_interface_add_del_spd_t *mp;
10927   u32 sw_if_index;
10928   u8 sw_if_index_set = 0;
10929   u32 spd_id = (u32) ~ 0;
10930   u8 is_add = 1;
10931   int ret;
10932
10933   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10934     {
10935       if (unformat (i, "del"))
10936         is_add = 0;
10937       else if (unformat (i, "spd_id %d", &spd_id))
10938         ;
10939       else
10940         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10941         sw_if_index_set = 1;
10942       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10943         sw_if_index_set = 1;
10944       else
10945         {
10946           clib_warning ("parse error '%U'", format_unformat_error, i);
10947           return -99;
10948         }
10949
10950     }
10951
10952   if (spd_id == (u32) ~ 0)
10953     {
10954       errmsg ("spd_id must be set");
10955       return -99;
10956     }
10957
10958   if (sw_if_index_set == 0)
10959     {
10960       errmsg ("missing interface name or sw_if_index");
10961       return -99;
10962     }
10963
10964   M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
10965
10966   mp->spd_id = ntohl (spd_id);
10967   mp->sw_if_index = ntohl (sw_if_index);
10968   mp->is_add = is_add;
10969
10970   S (mp);
10971   W (ret);
10972   return ret;
10973 }
10974
10975 static int
10976 api_ipsec_spd_entry_add_del (vat_main_t * vam)
10977 {
10978   unformat_input_t *i = vam->input;
10979   vl_api_ipsec_spd_entry_add_del_t *mp;
10980   u8 is_add = 1, is_outbound = 0;
10981   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
10982   i32 priority = 0;
10983   u32 rport_start = 0, rport_stop = (u32) ~ 0;
10984   u32 lport_start = 0, lport_stop = (u32) ~ 0;
10985   vl_api_address_t laddr_start = { }, laddr_stop =
10986   {
10987   }, raddr_start =
10988   {
10989   }, raddr_stop =
10990   {
10991   };
10992   int ret;
10993
10994   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10995     {
10996       if (unformat (i, "del"))
10997         is_add = 0;
10998       if (unformat (i, "outbound"))
10999         is_outbound = 1;
11000       if (unformat (i, "inbound"))
11001         is_outbound = 0;
11002       else if (unformat (i, "spd_id %d", &spd_id))
11003         ;
11004       else if (unformat (i, "sa_id %d", &sa_id))
11005         ;
11006       else if (unformat (i, "priority %d", &priority))
11007         ;
11008       else if (unformat (i, "protocol %d", &protocol))
11009         ;
11010       else if (unformat (i, "lport_start %d", &lport_start))
11011         ;
11012       else if (unformat (i, "lport_stop %d", &lport_stop))
11013         ;
11014       else if (unformat (i, "rport_start %d", &rport_start))
11015         ;
11016       else if (unformat (i, "rport_stop %d", &rport_stop))
11017         ;
11018       else if (unformat (i, "laddr_start %U",
11019                          unformat_vl_api_address, &laddr_start))
11020         ;
11021       else if (unformat (i, "laddr_stop %U", unformat_vl_api_address,
11022                          &laddr_stop))
11023         ;
11024       else if (unformat (i, "raddr_start %U", unformat_vl_api_address,
11025                          &raddr_start))
11026         ;
11027       else if (unformat (i, "raddr_stop %U", unformat_vl_api_address,
11028                          &raddr_stop))
11029         ;
11030       else
11031         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
11032         {
11033           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
11034             {
11035               clib_warning ("unsupported action: 'resolve'");
11036               return -99;
11037             }
11038         }
11039       else
11040         {
11041           clib_warning ("parse error '%U'", format_unformat_error, i);
11042           return -99;
11043         }
11044
11045     }
11046
11047   M (IPSEC_SPD_ENTRY_ADD_DEL, mp);
11048
11049   mp->is_add = is_add;
11050
11051   mp->entry.spd_id = ntohl (spd_id);
11052   mp->entry.priority = ntohl (priority);
11053   mp->entry.is_outbound = is_outbound;
11054
11055   clib_memcpy (&mp->entry.remote_address_start, &raddr_start,
11056                sizeof (vl_api_address_t));
11057   clib_memcpy (&mp->entry.remote_address_stop, &raddr_stop,
11058                sizeof (vl_api_address_t));
11059   clib_memcpy (&mp->entry.local_address_start, &laddr_start,
11060                sizeof (vl_api_address_t));
11061   clib_memcpy (&mp->entry.local_address_stop, &laddr_stop,
11062                sizeof (vl_api_address_t));
11063
11064   mp->entry.protocol = (u8) protocol;
11065   mp->entry.local_port_start = ntohs ((u16) lport_start);
11066   mp->entry.local_port_stop = ntohs ((u16) lport_stop);
11067   mp->entry.remote_port_start = ntohs ((u16) rport_start);
11068   mp->entry.remote_port_stop = ntohs ((u16) rport_stop);
11069   mp->entry.policy = (u8) policy;
11070   mp->entry.sa_id = ntohl (sa_id);
11071
11072   S (mp);
11073   W (ret);
11074   return ret;
11075 }
11076
11077 static int
11078 api_ipsec_sad_entry_add_del (vat_main_t * vam)
11079 {
11080   unformat_input_t *i = vam->input;
11081   vl_api_ipsec_sad_entry_add_del_t *mp;
11082   u32 sad_id = 0, spi = 0;
11083   u8 *ck = 0, *ik = 0;
11084   u8 is_add = 1;
11085
11086   vl_api_ipsec_crypto_alg_t crypto_alg = IPSEC_API_CRYPTO_ALG_NONE;
11087   vl_api_ipsec_integ_alg_t integ_alg = IPSEC_API_INTEG_ALG_NONE;
11088   vl_api_ipsec_sad_flags_t flags = IPSEC_API_SAD_FLAG_NONE;
11089   vl_api_ipsec_proto_t protocol = IPSEC_API_PROTO_AH;
11090   vl_api_address_t tun_src, tun_dst;
11091   int ret;
11092
11093   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11094     {
11095       if (unformat (i, "del"))
11096         is_add = 0;
11097       else if (unformat (i, "sad_id %d", &sad_id))
11098         ;
11099       else if (unformat (i, "spi %d", &spi))
11100         ;
11101       else if (unformat (i, "esp"))
11102         protocol = IPSEC_API_PROTO_ESP;
11103       else
11104         if (unformat (i, "tunnel_src %U", unformat_vl_api_address, &tun_src))
11105         {
11106           flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL;
11107           if (ADDRESS_IP6 == tun_src.af)
11108             flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL_V6;
11109         }
11110       else
11111         if (unformat (i, "tunnel_dst %U", unformat_vl_api_address, &tun_dst))
11112         {
11113           flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL;
11114           if (ADDRESS_IP6 == tun_src.af)
11115             flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL_V6;
11116         }
11117       else
11118         if (unformat (i, "crypto_alg %U",
11119                       unformat_ipsec_api_crypto_alg, &crypto_alg))
11120         ;
11121       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
11122         ;
11123       else if (unformat (i, "integ_alg %U",
11124                          unformat_ipsec_api_integ_alg, &integ_alg))
11125         ;
11126       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
11127         ;
11128       else
11129         {
11130           clib_warning ("parse error '%U'", format_unformat_error, i);
11131           return -99;
11132         }
11133
11134     }
11135
11136   M (IPSEC_SAD_ENTRY_ADD_DEL, mp);
11137
11138   mp->is_add = is_add;
11139   mp->entry.sad_id = ntohl (sad_id);
11140   mp->entry.protocol = protocol;
11141   mp->entry.spi = ntohl (spi);
11142   mp->entry.flags = flags;
11143
11144   mp->entry.crypto_algorithm = crypto_alg;
11145   mp->entry.integrity_algorithm = integ_alg;
11146   mp->entry.crypto_key.length = vec_len (ck);
11147   mp->entry.integrity_key.length = vec_len (ik);
11148
11149   if (mp->entry.crypto_key.length > sizeof (mp->entry.crypto_key.data))
11150     mp->entry.crypto_key.length = sizeof (mp->entry.crypto_key.data);
11151
11152   if (mp->entry.integrity_key.length > sizeof (mp->entry.integrity_key.data))
11153     mp->entry.integrity_key.length = sizeof (mp->entry.integrity_key.data);
11154
11155   if (ck)
11156     clib_memcpy (mp->entry.crypto_key.data, ck, mp->entry.crypto_key.length);
11157   if (ik)
11158     clib_memcpy (mp->entry.integrity_key.data, ik,
11159                  mp->entry.integrity_key.length);
11160
11161   if (flags & IPSEC_API_SAD_FLAG_IS_TUNNEL)
11162     {
11163       clib_memcpy (&mp->entry.tunnel_src, &tun_src,
11164                    sizeof (mp->entry.tunnel_src));
11165       clib_memcpy (&mp->entry.tunnel_dst, &tun_dst,
11166                    sizeof (mp->entry.tunnel_dst));
11167     }
11168
11169   S (mp);
11170   W (ret);
11171   return ret;
11172 }
11173
11174 static void
11175 vl_api_ipsec_sa_details_t_handler (vl_api_ipsec_sa_details_t * mp)
11176 {
11177   vat_main_t *vam = &vat_main;
11178
11179   print (vam->ofp, "sa_id %u sw_if_index %u spi %u proto %u crypto_alg %u "
11180          "crypto_key %U integ_alg %u integ_key %U flags %x "
11181          "tunnel_src_addr %U tunnel_dst_addr %U "
11182          "salt %u seq_outbound %lu last_seq_inbound %lu "
11183          "replay_window %lu stat_index %u\n",
11184          ntohl (mp->entry.sad_id),
11185          ntohl (mp->sw_if_index),
11186          ntohl (mp->entry.spi),
11187          ntohl (mp->entry.protocol),
11188          ntohl (mp->entry.crypto_algorithm),
11189          format_hex_bytes, mp->entry.crypto_key.data,
11190          mp->entry.crypto_key.length, ntohl (mp->entry.integrity_algorithm),
11191          format_hex_bytes, mp->entry.integrity_key.data,
11192          mp->entry.integrity_key.length, ntohl (mp->entry.flags),
11193          format_vl_api_address, &mp->entry.tunnel_src, format_vl_api_address,
11194          &mp->entry.tunnel_dst, ntohl (mp->salt),
11195          clib_net_to_host_u64 (mp->seq_outbound),
11196          clib_net_to_host_u64 (mp->last_seq_inbound),
11197          clib_net_to_host_u64 (mp->replay_window), ntohl (mp->stat_index));
11198 }
11199
11200 #define vl_api_ipsec_sa_details_t_endian vl_noop_handler
11201 #define vl_api_ipsec_sa_details_t_print vl_noop_handler
11202
11203 static void vl_api_ipsec_sa_details_t_handler_json
11204   (vl_api_ipsec_sa_details_t * mp)
11205 {
11206   vat_main_t *vam = &vat_main;
11207   vat_json_node_t *node = NULL;
11208   vl_api_ipsec_sad_flags_t flags;
11209
11210   if (VAT_JSON_ARRAY != vam->json_tree.type)
11211     {
11212       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11213       vat_json_init_array (&vam->json_tree);
11214     }
11215   node = vat_json_array_add (&vam->json_tree);
11216
11217   vat_json_init_object (node);
11218   vat_json_object_add_uint (node, "sa_id", ntohl (mp->entry.sad_id));
11219   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11220   vat_json_object_add_uint (node, "spi", ntohl (mp->entry.spi));
11221   vat_json_object_add_uint (node, "proto", ntohl (mp->entry.protocol));
11222   vat_json_object_add_uint (node, "crypto_alg",
11223                             ntohl (mp->entry.crypto_algorithm));
11224   vat_json_object_add_uint (node, "integ_alg",
11225                             ntohl (mp->entry.integrity_algorithm));
11226   flags = ntohl (mp->entry.flags);
11227   vat_json_object_add_uint (node, "use_esn",
11228                             ! !(flags & IPSEC_API_SAD_FLAG_USE_ESN));
11229   vat_json_object_add_uint (node, "use_anti_replay",
11230                             ! !(flags & IPSEC_API_SAD_FLAG_USE_ANTI_REPLAY));
11231   vat_json_object_add_uint (node, "is_tunnel",
11232                             ! !(flags & IPSEC_API_SAD_FLAG_IS_TUNNEL));
11233   vat_json_object_add_uint (node, "is_tunnel_ip6",
11234                             ! !(flags & IPSEC_API_SAD_FLAG_IS_TUNNEL_V6));
11235   vat_json_object_add_uint (node, "udp_encap",
11236                             ! !(flags & IPSEC_API_SAD_FLAG_UDP_ENCAP));
11237   vat_json_object_add_bytes (node, "crypto_key", mp->entry.crypto_key.data,
11238                              mp->entry.crypto_key.length);
11239   vat_json_object_add_bytes (node, "integ_key", mp->entry.integrity_key.data,
11240                              mp->entry.integrity_key.length);
11241   vat_json_object_add_address (node, "src", &mp->entry.tunnel_src);
11242   vat_json_object_add_address (node, "dst", &mp->entry.tunnel_dst);
11243   vat_json_object_add_uint (node, "replay_window",
11244                             clib_net_to_host_u64 (mp->replay_window));
11245   vat_json_object_add_uint (node, "stat_index", ntohl (mp->stat_index));
11246 }
11247
11248 static int
11249 api_ipsec_sa_dump (vat_main_t * vam)
11250 {
11251   unformat_input_t *i = vam->input;
11252   vl_api_ipsec_sa_dump_t *mp;
11253   vl_api_control_ping_t *mp_ping;
11254   u32 sa_id = ~0;
11255   int ret;
11256
11257   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11258     {
11259       if (unformat (i, "sa_id %d", &sa_id))
11260         ;
11261       else
11262         {
11263           clib_warning ("parse error '%U'", format_unformat_error, i);
11264           return -99;
11265         }
11266     }
11267
11268   M (IPSEC_SA_DUMP, mp);
11269
11270   mp->sa_id = ntohl (sa_id);
11271
11272   S (mp);
11273
11274   /* Use a control ping for synchronization */
11275   M (CONTROL_PING, mp_ping);
11276   S (mp_ping);
11277
11278   W (ret);
11279   return ret;
11280 }
11281
11282 static int
11283 api_get_first_msg_id (vat_main_t * vam)
11284 {
11285   vl_api_get_first_msg_id_t *mp;
11286   unformat_input_t *i = vam->input;
11287   u8 *name;
11288   u8 name_set = 0;
11289   int ret;
11290
11291   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11292     {
11293       if (unformat (i, "client %s", &name))
11294         name_set = 1;
11295       else
11296         break;
11297     }
11298
11299   if (name_set == 0)
11300     {
11301       errmsg ("missing client name");
11302       return -99;
11303     }
11304   vec_add1 (name, 0);
11305
11306   if (vec_len (name) > 63)
11307     {
11308       errmsg ("client name too long");
11309       return -99;
11310     }
11311
11312   M (GET_FIRST_MSG_ID, mp);
11313   clib_memcpy (mp->name, name, vec_len (name));
11314   S (mp);
11315   W (ret);
11316   return ret;
11317 }
11318
11319 static int
11320 api_get_node_graph (vat_main_t * vam)
11321 {
11322   vl_api_get_node_graph_t *mp;
11323   int ret;
11324
11325   M (GET_NODE_GRAPH, mp);
11326
11327   /* send it... */
11328   S (mp);
11329   /* Wait for the reply */
11330   W (ret);
11331   return ret;
11332 }
11333
11334 static int
11335 api_af_packet_create (vat_main_t * vam)
11336 {
11337   unformat_input_t *i = vam->input;
11338   vl_api_af_packet_create_t *mp;
11339   u8 *host_if_name = 0;
11340   u8 hw_addr[6];
11341   u8 random_hw_addr = 1;
11342   int ret;
11343
11344   clib_memset (hw_addr, 0, sizeof (hw_addr));
11345
11346   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11347     {
11348       if (unformat (i, "name %s", &host_if_name))
11349         vec_add1 (host_if_name, 0);
11350       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
11351         random_hw_addr = 0;
11352       else
11353         break;
11354     }
11355
11356   if (!vec_len (host_if_name))
11357     {
11358       errmsg ("host-interface name must be specified");
11359       return -99;
11360     }
11361
11362   if (vec_len (host_if_name) > 64)
11363     {
11364       errmsg ("host-interface name too long");
11365       return -99;
11366     }
11367
11368   M (AF_PACKET_CREATE, mp);
11369
11370   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
11371   clib_memcpy (mp->hw_addr, hw_addr, 6);
11372   mp->use_random_hw_addr = random_hw_addr;
11373   vec_free (host_if_name);
11374
11375   S (mp);
11376
11377   /* *INDENT-OFF* */
11378   W2 (ret,
11379       ({
11380         if (ret == 0)
11381           fprintf (vam->ofp ? vam->ofp : stderr,
11382                    " new sw_if_index = %d\n", vam->sw_if_index);
11383       }));
11384   /* *INDENT-ON* */
11385   return ret;
11386 }
11387
11388 static int
11389 api_af_packet_delete (vat_main_t * vam)
11390 {
11391   unformat_input_t *i = vam->input;
11392   vl_api_af_packet_delete_t *mp;
11393   u8 *host_if_name = 0;
11394   int ret;
11395
11396   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11397     {
11398       if (unformat (i, "name %s", &host_if_name))
11399         vec_add1 (host_if_name, 0);
11400       else
11401         break;
11402     }
11403
11404   if (!vec_len (host_if_name))
11405     {
11406       errmsg ("host-interface name must be specified");
11407       return -99;
11408     }
11409
11410   if (vec_len (host_if_name) > 64)
11411     {
11412       errmsg ("host-interface name too long");
11413       return -99;
11414     }
11415
11416   M (AF_PACKET_DELETE, mp);
11417
11418   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
11419   vec_free (host_if_name);
11420
11421   S (mp);
11422   W (ret);
11423   return ret;
11424 }
11425
11426 static void vl_api_af_packet_details_t_handler
11427   (vl_api_af_packet_details_t * mp)
11428 {
11429   vat_main_t *vam = &vat_main;
11430
11431   print (vam->ofp, "%-16s %d",
11432          mp->host_if_name, clib_net_to_host_u32 (mp->sw_if_index));
11433 }
11434
11435 static void vl_api_af_packet_details_t_handler_json
11436   (vl_api_af_packet_details_t * mp)
11437 {
11438   vat_main_t *vam = &vat_main;
11439   vat_json_node_t *node = NULL;
11440
11441   if (VAT_JSON_ARRAY != vam->json_tree.type)
11442     {
11443       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11444       vat_json_init_array (&vam->json_tree);
11445     }
11446   node = vat_json_array_add (&vam->json_tree);
11447
11448   vat_json_init_object (node);
11449   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11450   vat_json_object_add_string_copy (node, "dev_name", mp->host_if_name);
11451 }
11452
11453 static int
11454 api_af_packet_dump (vat_main_t * vam)
11455 {
11456   vl_api_af_packet_dump_t *mp;
11457   vl_api_control_ping_t *mp_ping;
11458   int ret;
11459
11460   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
11461   /* Get list of tap interfaces */
11462   M (AF_PACKET_DUMP, mp);
11463   S (mp);
11464
11465   /* Use a control ping for synchronization */
11466   MPING (CONTROL_PING, mp_ping);
11467   S (mp_ping);
11468
11469   W (ret);
11470   return ret;
11471 }
11472
11473 static int
11474 api_policer_add_del (vat_main_t * vam)
11475 {
11476   unformat_input_t *i = vam->input;
11477   vl_api_policer_add_del_t *mp;
11478   u8 is_add = 1;
11479   u8 *name = 0;
11480   u32 cir = 0;
11481   u32 eir = 0;
11482   u64 cb = 0;
11483   u64 eb = 0;
11484   u8 rate_type = 0;
11485   u8 round_type = 0;
11486   u8 type = 0;
11487   u8 color_aware = 0;
11488   qos_pol_action_params_st conform_action, exceed_action, violate_action;
11489   int ret;
11490
11491   conform_action.action_type = QOS_ACTION_TRANSMIT;
11492   conform_action.dscp = 0;
11493   exceed_action.action_type = QOS_ACTION_MARK_AND_TRANSMIT;
11494   exceed_action.dscp = 0;
11495   violate_action.action_type = QOS_ACTION_DROP;
11496   violate_action.dscp = 0;
11497
11498   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11499     {
11500       if (unformat (i, "del"))
11501         is_add = 0;
11502       else if (unformat (i, "name %s", &name))
11503         vec_add1 (name, 0);
11504       else if (unformat (i, "cir %u", &cir))
11505         ;
11506       else if (unformat (i, "eir %u", &eir))
11507         ;
11508       else if (unformat (i, "cb %u", &cb))
11509         ;
11510       else if (unformat (i, "eb %u", &eb))
11511         ;
11512       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
11513                          &rate_type))
11514         ;
11515       else if (unformat (i, "round_type %U", unformat_policer_round_type,
11516                          &round_type))
11517         ;
11518       else if (unformat (i, "type %U", unformat_policer_type, &type))
11519         ;
11520       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
11521                          &conform_action))
11522         ;
11523       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
11524                          &exceed_action))
11525         ;
11526       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
11527                          &violate_action))
11528         ;
11529       else if (unformat (i, "color-aware"))
11530         color_aware = 1;
11531       else
11532         break;
11533     }
11534
11535   if (!vec_len (name))
11536     {
11537       errmsg ("policer name must be specified");
11538       return -99;
11539     }
11540
11541   if (vec_len (name) > 64)
11542     {
11543       errmsg ("policer name too long");
11544       return -99;
11545     }
11546
11547   M (POLICER_ADD_DEL, mp);
11548
11549   clib_memcpy (mp->name, name, vec_len (name));
11550   vec_free (name);
11551   mp->is_add = is_add;
11552   mp->cir = ntohl (cir);
11553   mp->eir = ntohl (eir);
11554   mp->cb = clib_net_to_host_u64 (cb);
11555   mp->eb = clib_net_to_host_u64 (eb);
11556   mp->rate_type = rate_type;
11557   mp->round_type = round_type;
11558   mp->type = type;
11559   mp->conform_action.type =
11560     (vl_api_sse2_qos_action_type_t) conform_action.action_type;
11561   mp->conform_action.dscp = conform_action.dscp;
11562   mp->exceed_action.type =
11563     (vl_api_sse2_qos_action_type_t) exceed_action.action_type;
11564   mp->exceed_action.dscp = exceed_action.dscp;
11565   mp->violate_action.type =
11566     (vl_api_sse2_qos_action_type_t) violate_action.action_type;
11567   mp->violate_action.dscp = violate_action.dscp;
11568   mp->color_aware = color_aware;
11569
11570   S (mp);
11571   W (ret);
11572   return ret;
11573 }
11574
11575 static int
11576 api_policer_dump (vat_main_t * vam)
11577 {
11578   unformat_input_t *i = vam->input;
11579   vl_api_policer_dump_t *mp;
11580   vl_api_control_ping_t *mp_ping;
11581   u8 *match_name = 0;
11582   u8 match_name_valid = 0;
11583   int ret;
11584
11585   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11586     {
11587       if (unformat (i, "name %s", &match_name))
11588         {
11589           vec_add1 (match_name, 0);
11590           match_name_valid = 1;
11591         }
11592       else
11593         break;
11594     }
11595
11596   M (POLICER_DUMP, mp);
11597   mp->match_name_valid = match_name_valid;
11598   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
11599   vec_free (match_name);
11600   /* send it... */
11601   S (mp);
11602
11603   /* Use a control ping for synchronization */
11604   MPING (CONTROL_PING, mp_ping);
11605   S (mp_ping);
11606
11607   /* Wait for a reply... */
11608   W (ret);
11609   return ret;
11610 }
11611
11612 static int
11613 api_policer_classify_set_interface (vat_main_t * vam)
11614 {
11615   unformat_input_t *i = vam->input;
11616   vl_api_policer_classify_set_interface_t *mp;
11617   u32 sw_if_index;
11618   int sw_if_index_set;
11619   u32 ip4_table_index = ~0;
11620   u32 ip6_table_index = ~0;
11621   u32 l2_table_index = ~0;
11622   u8 is_add = 1;
11623   int ret;
11624
11625   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11626     {
11627       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11628         sw_if_index_set = 1;
11629       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11630         sw_if_index_set = 1;
11631       else if (unformat (i, "del"))
11632         is_add = 0;
11633       else if (unformat (i, "ip4-table %d", &ip4_table_index))
11634         ;
11635       else if (unformat (i, "ip6-table %d", &ip6_table_index))
11636         ;
11637       else if (unformat (i, "l2-table %d", &l2_table_index))
11638         ;
11639       else
11640         {
11641           clib_warning ("parse error '%U'", format_unformat_error, i);
11642           return -99;
11643         }
11644     }
11645
11646   if (sw_if_index_set == 0)
11647     {
11648       errmsg ("missing interface name or sw_if_index");
11649       return -99;
11650     }
11651
11652   M (POLICER_CLASSIFY_SET_INTERFACE, mp);
11653
11654   mp->sw_if_index = ntohl (sw_if_index);
11655   mp->ip4_table_index = ntohl (ip4_table_index);
11656   mp->ip6_table_index = ntohl (ip6_table_index);
11657   mp->l2_table_index = ntohl (l2_table_index);
11658   mp->is_add = is_add;
11659
11660   S (mp);
11661   W (ret);
11662   return ret;
11663 }
11664
11665 static int
11666 api_policer_classify_dump (vat_main_t * vam)
11667 {
11668   unformat_input_t *i = vam->input;
11669   vl_api_policer_classify_dump_t *mp;
11670   vl_api_control_ping_t *mp_ping;
11671   u8 type = POLICER_CLASSIFY_N_TABLES;
11672   int ret;
11673
11674   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
11675     ;
11676   else
11677     {
11678       errmsg ("classify table type must be specified");
11679       return -99;
11680     }
11681
11682   if (!vam->json_output)
11683     {
11684       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
11685     }
11686
11687   M (POLICER_CLASSIFY_DUMP, mp);
11688   mp->type = type;
11689   /* send it... */
11690   S (mp);
11691
11692   /* Use a control ping for synchronization */
11693   MPING (CONTROL_PING, mp_ping);
11694   S (mp_ping);
11695
11696   /* Wait for a reply... */
11697   W (ret);
11698   return ret;
11699 }
11700
11701 static u8 *
11702 format_fib_api_path_nh_proto (u8 * s, va_list * args)
11703 {
11704   vl_api_fib_path_nh_proto_t proto =
11705     va_arg (*args, vl_api_fib_path_nh_proto_t);
11706
11707   switch (proto)
11708     {
11709     case FIB_API_PATH_NH_PROTO_IP4:
11710       s = format (s, "ip4");
11711       break;
11712     case FIB_API_PATH_NH_PROTO_IP6:
11713       s = format (s, "ip6");
11714       break;
11715     case FIB_API_PATH_NH_PROTO_MPLS:
11716       s = format (s, "mpls");
11717       break;
11718     case FIB_API_PATH_NH_PROTO_BIER:
11719       s = format (s, "bier");
11720       break;
11721     case FIB_API_PATH_NH_PROTO_ETHERNET:
11722       s = format (s, "ethernet");
11723       break;
11724     }
11725
11726   return (s);
11727 }
11728
11729 static u8 *
11730 format_vl_api_ip_address_union (u8 * s, va_list * args)
11731 {
11732   vl_api_address_family_t af = va_arg (*args, int);
11733   const vl_api_address_union_t *u = va_arg (*args, vl_api_address_union_t *);
11734
11735   switch (af)
11736     {
11737     case ADDRESS_IP4:
11738       s = format (s, "%U", format_ip4_address, u->ip4);
11739       break;
11740     case ADDRESS_IP6:
11741       s = format (s, "%U", format_ip6_address, u->ip6);
11742       break;
11743     }
11744   return (s);
11745 }
11746
11747 static u8 *
11748 format_vl_api_fib_path_type (u8 * s, va_list * args)
11749 {
11750   vl_api_fib_path_type_t t = va_arg (*args, vl_api_fib_path_type_t);
11751
11752   switch (t)
11753     {
11754     case FIB_API_PATH_TYPE_NORMAL:
11755       s = format (s, "normal");
11756       break;
11757     case FIB_API_PATH_TYPE_LOCAL:
11758       s = format (s, "local");
11759       break;
11760     case FIB_API_PATH_TYPE_DROP:
11761       s = format (s, "drop");
11762       break;
11763     case FIB_API_PATH_TYPE_UDP_ENCAP:
11764       s = format (s, "udp-encap");
11765       break;
11766     case FIB_API_PATH_TYPE_BIER_IMP:
11767       s = format (s, "bier-imp");
11768       break;
11769     case FIB_API_PATH_TYPE_ICMP_UNREACH:
11770       s = format (s, "unreach");
11771       break;
11772     case FIB_API_PATH_TYPE_ICMP_PROHIBIT:
11773       s = format (s, "prohibit");
11774       break;
11775     case FIB_API_PATH_TYPE_SOURCE_LOOKUP:
11776       s = format (s, "src-lookup");
11777       break;
11778     case FIB_API_PATH_TYPE_DVR:
11779       s = format (s, "dvr");
11780       break;
11781     case FIB_API_PATH_TYPE_INTERFACE_RX:
11782       s = format (s, "interface-rx");
11783       break;
11784     case FIB_API_PATH_TYPE_CLASSIFY:
11785       s = format (s, "classify");
11786       break;
11787     }
11788
11789   return (s);
11790 }
11791
11792 static void
11793 vl_api_fib_path_print (vat_main_t * vam, vl_api_fib_path_t * fp)
11794 {
11795   print (vam->ofp,
11796          "  weight %d, sw_if_index %d, type %U, afi %U, next_hop %U",
11797          ntohl (fp->weight), ntohl (fp->sw_if_index),
11798          format_vl_api_fib_path_type, fp->type,
11799          format_fib_api_path_nh_proto, fp->proto,
11800          format_vl_api_ip_address_union, &fp->nh.address);
11801 }
11802
11803 static void
11804 vl_api_mpls_fib_path_json_print (vat_json_node_t * node,
11805                                  vl_api_fib_path_t * fp)
11806 {
11807   struct in_addr ip4;
11808   struct in6_addr ip6;
11809
11810   vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
11811   vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
11812   vat_json_object_add_uint (node, "type", fp->type);
11813   vat_json_object_add_uint (node, "next_hop_proto", fp->proto);
11814   if (fp->proto == FIB_API_PATH_NH_PROTO_IP4)
11815     {
11816       clib_memcpy (&ip4, &fp->nh.address.ip4, sizeof (ip4));
11817       vat_json_object_add_ip4 (node, "next_hop", ip4);
11818     }
11819   else if (fp->proto == FIB_API_PATH_NH_PROTO_IP6)
11820     {
11821       clib_memcpy (&ip6, &fp->nh.address.ip6, sizeof (ip6));
11822       vat_json_object_add_ip6 (node, "next_hop", ip6);
11823     }
11824 }
11825
11826 static void
11827 vl_api_mpls_tunnel_details_t_handler (vl_api_mpls_tunnel_details_t * mp)
11828 {
11829   vat_main_t *vam = &vat_main;
11830   int count = ntohl (mp->mt_tunnel.mt_n_paths);
11831   vl_api_fib_path_t *fp;
11832   i32 i;
11833
11834   print (vam->ofp, "sw_if_index %d via:",
11835          ntohl (mp->mt_tunnel.mt_sw_if_index));
11836   fp = mp->mt_tunnel.mt_paths;
11837   for (i = 0; i < count; i++)
11838     {
11839       vl_api_fib_path_print (vam, fp);
11840       fp++;
11841     }
11842
11843   print (vam->ofp, "");
11844 }
11845
11846 #define vl_api_mpls_tunnel_details_t_endian vl_noop_handler
11847 #define vl_api_mpls_tunnel_details_t_print vl_noop_handler
11848
11849 static void
11850 vl_api_mpls_tunnel_details_t_handler_json (vl_api_mpls_tunnel_details_t * mp)
11851 {
11852   vat_main_t *vam = &vat_main;
11853   vat_json_node_t *node = NULL;
11854   int count = ntohl (mp->mt_tunnel.mt_n_paths);
11855   vl_api_fib_path_t *fp;
11856   i32 i;
11857
11858   if (VAT_JSON_ARRAY != vam->json_tree.type)
11859     {
11860       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11861       vat_json_init_array (&vam->json_tree);
11862     }
11863   node = vat_json_array_add (&vam->json_tree);
11864
11865   vat_json_init_object (node);
11866   vat_json_object_add_uint (node, "sw_if_index",
11867                             ntohl (mp->mt_tunnel.mt_sw_if_index));
11868
11869   vat_json_object_add_uint (node, "l2_only", mp->mt_tunnel.mt_l2_only);
11870
11871   fp = mp->mt_tunnel.mt_paths;
11872   for (i = 0; i < count; i++)
11873     {
11874       vl_api_mpls_fib_path_json_print (node, fp);
11875       fp++;
11876     }
11877 }
11878
11879 static int
11880 api_mpls_tunnel_dump (vat_main_t * vam)
11881 {
11882   vl_api_mpls_tunnel_dump_t *mp;
11883   vl_api_control_ping_t *mp_ping;
11884   int ret;
11885
11886   M (MPLS_TUNNEL_DUMP, mp);
11887
11888   S (mp);
11889
11890   /* Use a control ping for synchronization */
11891   MPING (CONTROL_PING, mp_ping);
11892   S (mp_ping);
11893
11894   W (ret);
11895   return ret;
11896 }
11897
11898 #define vl_api_mpls_table_details_t_endian vl_noop_handler
11899 #define vl_api_mpls_table_details_t_print vl_noop_handler
11900
11901
11902 static void
11903 vl_api_mpls_table_details_t_handler (vl_api_mpls_table_details_t * mp)
11904 {
11905   vat_main_t *vam = &vat_main;
11906
11907   print (vam->ofp, "table-id %d,", ntohl (mp->mt_table.mt_table_id));
11908 }
11909
11910 static void vl_api_mpls_table_details_t_handler_json
11911   (vl_api_mpls_table_details_t * mp)
11912 {
11913   vat_main_t *vam = &vat_main;
11914   vat_json_node_t *node = NULL;
11915
11916   if (VAT_JSON_ARRAY != vam->json_tree.type)
11917     {
11918       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11919       vat_json_init_array (&vam->json_tree);
11920     }
11921   node = vat_json_array_add (&vam->json_tree);
11922
11923   vat_json_init_object (node);
11924   vat_json_object_add_uint (node, "table", ntohl (mp->mt_table.mt_table_id));
11925 }
11926
11927 static int
11928 api_mpls_table_dump (vat_main_t * vam)
11929 {
11930   vl_api_mpls_table_dump_t *mp;
11931   vl_api_control_ping_t *mp_ping;
11932   int ret;
11933
11934   M (MPLS_TABLE_DUMP, mp);
11935   S (mp);
11936
11937   /* Use a control ping for synchronization */
11938   MPING (CONTROL_PING, mp_ping);
11939   S (mp_ping);
11940
11941   W (ret);
11942   return ret;
11943 }
11944
11945 #define vl_api_mpls_route_details_t_endian vl_noop_handler
11946 #define vl_api_mpls_route_details_t_print vl_noop_handler
11947
11948 static void
11949 vl_api_mpls_route_details_t_handler (vl_api_mpls_route_details_t * mp)
11950 {
11951   vat_main_t *vam = &vat_main;
11952   int count = (int) clib_net_to_host_u32 (mp->mr_route.mr_n_paths);
11953   vl_api_fib_path_t *fp;
11954   int i;
11955
11956   print (vam->ofp,
11957          "table-id %d, label %u, ess_bit %u",
11958          ntohl (mp->mr_route.mr_table_id),
11959          ntohl (mp->mr_route.mr_label), mp->mr_route.mr_eos);
11960   fp = mp->mr_route.mr_paths;
11961   for (i = 0; i < count; i++)
11962     {
11963       vl_api_fib_path_print (vam, fp);
11964       fp++;
11965     }
11966 }
11967
11968 static void vl_api_mpls_route_details_t_handler_json
11969   (vl_api_mpls_route_details_t * mp)
11970 {
11971   vat_main_t *vam = &vat_main;
11972   int count = (int) clib_host_to_net_u32 (mp->mr_route.mr_n_paths);
11973   vat_json_node_t *node = NULL;
11974   vl_api_fib_path_t *fp;
11975   int i;
11976
11977   if (VAT_JSON_ARRAY != vam->json_tree.type)
11978     {
11979       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11980       vat_json_init_array (&vam->json_tree);
11981     }
11982   node = vat_json_array_add (&vam->json_tree);
11983
11984   vat_json_init_object (node);
11985   vat_json_object_add_uint (node, "table", ntohl (mp->mr_route.mr_table_id));
11986   vat_json_object_add_uint (node, "s_bit", mp->mr_route.mr_eos);
11987   vat_json_object_add_uint (node, "label", ntohl (mp->mr_route.mr_label));
11988   vat_json_object_add_uint (node, "path_count", count);
11989   fp = mp->mr_route.mr_paths;
11990   for (i = 0; i < count; i++)
11991     {
11992       vl_api_mpls_fib_path_json_print (node, fp);
11993       fp++;
11994     }
11995 }
11996
11997 static int
11998 api_mpls_route_dump (vat_main_t * vam)
11999 {
12000   unformat_input_t *input = vam->input;
12001   vl_api_mpls_route_dump_t *mp;
12002   vl_api_control_ping_t *mp_ping;
12003   u32 table_id;
12004   int ret;
12005
12006   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12007     {
12008       if (unformat (input, "table_id %d", &table_id))
12009         ;
12010       else
12011         break;
12012     }
12013   if (table_id == ~0)
12014     {
12015       errmsg ("missing table id");
12016       return -99;
12017     }
12018
12019   M (MPLS_ROUTE_DUMP, mp);
12020
12021   mp->table.mt_table_id = ntohl (table_id);
12022   S (mp);
12023
12024   /* Use a control ping for synchronization */
12025   MPING (CONTROL_PING, mp_ping);
12026   S (mp_ping);
12027
12028   W (ret);
12029   return ret;
12030 }
12031
12032 #define vl_api_ip_table_details_t_endian vl_noop_handler
12033 #define vl_api_ip_table_details_t_print vl_noop_handler
12034
12035 static void
12036 vl_api_ip_table_details_t_handler (vl_api_ip_table_details_t * mp)
12037 {
12038   vat_main_t *vam = &vat_main;
12039
12040   print (vam->ofp,
12041          "%s; table-id %d, prefix %U/%d",
12042          mp->table.name, ntohl (mp->table.table_id));
12043 }
12044
12045
12046 static void vl_api_ip_table_details_t_handler_json
12047   (vl_api_ip_table_details_t * mp)
12048 {
12049   vat_main_t *vam = &vat_main;
12050   vat_json_node_t *node = NULL;
12051
12052   if (VAT_JSON_ARRAY != vam->json_tree.type)
12053     {
12054       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12055       vat_json_init_array (&vam->json_tree);
12056     }
12057   node = vat_json_array_add (&vam->json_tree);
12058
12059   vat_json_init_object (node);
12060   vat_json_object_add_uint (node, "table", ntohl (mp->table.table_id));
12061 }
12062
12063 static int
12064 api_ip_table_dump (vat_main_t * vam)
12065 {
12066   vl_api_ip_table_dump_t *mp;
12067   vl_api_control_ping_t *mp_ping;
12068   int ret;
12069
12070   M (IP_TABLE_DUMP, mp);
12071   S (mp);
12072
12073   /* Use a control ping for synchronization */
12074   MPING (CONTROL_PING, mp_ping);
12075   S (mp_ping);
12076
12077   W (ret);
12078   return ret;
12079 }
12080
12081 static int
12082 api_ip_mtable_dump (vat_main_t * vam)
12083 {
12084   vl_api_ip_mtable_dump_t *mp;
12085   vl_api_control_ping_t *mp_ping;
12086   int ret;
12087
12088   M (IP_MTABLE_DUMP, mp);
12089   S (mp);
12090
12091   /* Use a control ping for synchronization */
12092   MPING (CONTROL_PING, mp_ping);
12093   S (mp_ping);
12094
12095   W (ret);
12096   return ret;
12097 }
12098
12099 static int
12100 api_ip_mroute_dump (vat_main_t * vam)
12101 {
12102   unformat_input_t *input = vam->input;
12103   vl_api_control_ping_t *mp_ping;
12104   vl_api_ip_mroute_dump_t *mp;
12105   int ret, is_ip6;
12106   u32 table_id;
12107
12108   is_ip6 = 0;
12109   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12110     {
12111       if (unformat (input, "table_id %d", &table_id))
12112         ;
12113       else if (unformat (input, "ip6"))
12114         is_ip6 = 1;
12115       else if (unformat (input, "ip4"))
12116         is_ip6 = 0;
12117       else
12118         break;
12119     }
12120   if (table_id == ~0)
12121     {
12122       errmsg ("missing table id");
12123       return -99;
12124     }
12125
12126   M (IP_MROUTE_DUMP, mp);
12127   mp->table.table_id = table_id;
12128   mp->table.is_ip6 = is_ip6;
12129   S (mp);
12130
12131   /* Use a control ping for synchronization */
12132   MPING (CONTROL_PING, mp_ping);
12133   S (mp_ping);
12134
12135   W (ret);
12136   return ret;
12137 }
12138
12139 #define vl_api_ip_route_details_t_endian vl_noop_handler
12140 #define vl_api_ip_route_details_t_print vl_noop_handler
12141
12142 static void
12143 vl_api_ip_route_details_t_handler (vl_api_ip_route_details_t * mp)
12144 {
12145   vat_main_t *vam = &vat_main;
12146   u8 count = mp->route.n_paths;
12147   vl_api_fib_path_t *fp;
12148   int i;
12149
12150   print (vam->ofp,
12151          "table-id %d, prefix %U/%d",
12152          ntohl (mp->route.table_id),
12153          format_ip46_address, mp->route.prefix.address, mp->route.prefix.len);
12154   for (i = 0; i < count; i++)
12155     {
12156       fp = &mp->route.paths[i];
12157
12158       vl_api_fib_path_print (vam, fp);
12159       fp++;
12160     }
12161 }
12162
12163 static void vl_api_ip_route_details_t_handler_json
12164   (vl_api_ip_route_details_t * mp)
12165 {
12166   vat_main_t *vam = &vat_main;
12167   u8 count = mp->route.n_paths;
12168   vat_json_node_t *node = NULL;
12169   struct in_addr ip4;
12170   struct in6_addr ip6;
12171   vl_api_fib_path_t *fp;
12172   int i;
12173
12174   if (VAT_JSON_ARRAY != vam->json_tree.type)
12175     {
12176       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12177       vat_json_init_array (&vam->json_tree);
12178     }
12179   node = vat_json_array_add (&vam->json_tree);
12180
12181   vat_json_init_object (node);
12182   vat_json_object_add_uint (node, "table", ntohl (mp->route.table_id));
12183   if (ADDRESS_IP6 == mp->route.prefix.address.af)
12184     {
12185       clib_memcpy (&ip6, &mp->route.prefix.address.un.ip6, sizeof (ip6));
12186       vat_json_object_add_ip6 (node, "prefix", ip6);
12187     }
12188   else
12189     {
12190       clib_memcpy (&ip4, &mp->route.prefix.address.un.ip4, sizeof (ip4));
12191       vat_json_object_add_ip4 (node, "prefix", ip4);
12192     }
12193   vat_json_object_add_uint (node, "mask_length", mp->route.prefix.len);
12194   vat_json_object_add_uint (node, "path_count", count);
12195   for (i = 0; i < count; i++)
12196     {
12197       fp = &mp->route.paths[i];
12198       vl_api_mpls_fib_path_json_print (node, fp);
12199     }
12200 }
12201
12202 static int
12203 api_ip_route_dump (vat_main_t * vam)
12204 {
12205   unformat_input_t *input = vam->input;
12206   vl_api_ip_route_dump_t *mp;
12207   vl_api_control_ping_t *mp_ping;
12208   u32 table_id;
12209   u8 is_ip6;
12210   int ret;
12211
12212   is_ip6 = 0;
12213   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12214     {
12215       if (unformat (input, "table_id %d", &table_id))
12216         ;
12217       else if (unformat (input, "ip6"))
12218         is_ip6 = 1;
12219       else if (unformat (input, "ip4"))
12220         is_ip6 = 0;
12221       else
12222         break;
12223     }
12224   if (table_id == ~0)
12225     {
12226       errmsg ("missing table id");
12227       return -99;
12228     }
12229
12230   M (IP_ROUTE_DUMP, mp);
12231
12232   mp->table.table_id = table_id;
12233   mp->table.is_ip6 = is_ip6;
12234
12235   S (mp);
12236
12237   /* Use a control ping for synchronization */
12238   MPING (CONTROL_PING, mp_ping);
12239   S (mp_ping);
12240
12241   W (ret);
12242   return ret;
12243 }
12244
12245 int
12246 api_classify_table_ids (vat_main_t * vam)
12247 {
12248   vl_api_classify_table_ids_t *mp;
12249   int ret;
12250
12251   /* Construct the API message */
12252   M (CLASSIFY_TABLE_IDS, mp);
12253   mp->context = 0;
12254
12255   S (mp);
12256   W (ret);
12257   return ret;
12258 }
12259
12260 int
12261 api_classify_table_by_interface (vat_main_t * vam)
12262 {
12263   unformat_input_t *input = vam->input;
12264   vl_api_classify_table_by_interface_t *mp;
12265
12266   u32 sw_if_index = ~0;
12267   int ret;
12268   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12269     {
12270       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12271         ;
12272       else if (unformat (input, "sw_if_index %d", &sw_if_index))
12273         ;
12274       else
12275         break;
12276     }
12277   if (sw_if_index == ~0)
12278     {
12279       errmsg ("missing interface name or sw_if_index");
12280       return -99;
12281     }
12282
12283   /* Construct the API message */
12284   M (CLASSIFY_TABLE_BY_INTERFACE, mp);
12285   mp->context = 0;
12286   mp->sw_if_index = ntohl (sw_if_index);
12287
12288   S (mp);
12289   W (ret);
12290   return ret;
12291 }
12292
12293 int
12294 api_classify_table_info (vat_main_t * vam)
12295 {
12296   unformat_input_t *input = vam->input;
12297   vl_api_classify_table_info_t *mp;
12298
12299   u32 table_id = ~0;
12300   int ret;
12301   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12302     {
12303       if (unformat (input, "table_id %d", &table_id))
12304         ;
12305       else
12306         break;
12307     }
12308   if (table_id == ~0)
12309     {
12310       errmsg ("missing table id");
12311       return -99;
12312     }
12313
12314   /* Construct the API message */
12315   M (CLASSIFY_TABLE_INFO, mp);
12316   mp->context = 0;
12317   mp->table_id = ntohl (table_id);
12318
12319   S (mp);
12320   W (ret);
12321   return ret;
12322 }
12323
12324 int
12325 api_classify_session_dump (vat_main_t * vam)
12326 {
12327   unformat_input_t *input = vam->input;
12328   vl_api_classify_session_dump_t *mp;
12329   vl_api_control_ping_t *mp_ping;
12330
12331   u32 table_id = ~0;
12332   int ret;
12333   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12334     {
12335       if (unformat (input, "table_id %d", &table_id))
12336         ;
12337       else
12338         break;
12339     }
12340   if (table_id == ~0)
12341     {
12342       errmsg ("missing table id");
12343       return -99;
12344     }
12345
12346   /* Construct the API message */
12347   M (CLASSIFY_SESSION_DUMP, mp);
12348   mp->context = 0;
12349   mp->table_id = ntohl (table_id);
12350   S (mp);
12351
12352   /* Use a control ping for synchronization */
12353   MPING (CONTROL_PING, mp_ping);
12354   S (mp_ping);
12355
12356   W (ret);
12357   return ret;
12358 }
12359
12360 static void
12361 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
12362 {
12363   vat_main_t *vam = &vat_main;
12364
12365   print (vam->ofp, "collector_address %U, collector_port %d, "
12366          "src_address %U, vrf_id %d, path_mtu %u, "
12367          "template_interval %u, udp_checksum %d",
12368          format_ip4_address, mp->collector_address,
12369          ntohs (mp->collector_port),
12370          format_ip4_address, mp->src_address,
12371          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
12372          ntohl (mp->template_interval), mp->udp_checksum);
12373
12374   vam->retval = 0;
12375   vam->result_ready = 1;
12376 }
12377
12378 static void
12379   vl_api_ipfix_exporter_details_t_handler_json
12380   (vl_api_ipfix_exporter_details_t * mp)
12381 {
12382   vat_main_t *vam = &vat_main;
12383   vat_json_node_t node;
12384   struct in_addr collector_address;
12385   struct in_addr src_address;
12386
12387   vat_json_init_object (&node);
12388   clib_memcpy (&collector_address, &mp->collector_address,
12389                sizeof (collector_address));
12390   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
12391   vat_json_object_add_uint (&node, "collector_port",
12392                             ntohs (mp->collector_port));
12393   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
12394   vat_json_object_add_ip4 (&node, "src_address", src_address);
12395   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
12396   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
12397   vat_json_object_add_uint (&node, "template_interval",
12398                             ntohl (mp->template_interval));
12399   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
12400
12401   vat_json_print (vam->ofp, &node);
12402   vat_json_free (&node);
12403   vam->retval = 0;
12404   vam->result_ready = 1;
12405 }
12406
12407 int
12408 api_ipfix_exporter_dump (vat_main_t * vam)
12409 {
12410   vl_api_ipfix_exporter_dump_t *mp;
12411   int ret;
12412
12413   /* Construct the API message */
12414   M (IPFIX_EXPORTER_DUMP, mp);
12415   mp->context = 0;
12416
12417   S (mp);
12418   W (ret);
12419   return ret;
12420 }
12421
12422 static int
12423 api_ipfix_classify_stream_dump (vat_main_t * vam)
12424 {
12425   vl_api_ipfix_classify_stream_dump_t *mp;
12426   int ret;
12427
12428   /* Construct the API message */
12429   M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
12430   mp->context = 0;
12431
12432   S (mp);
12433   W (ret);
12434   return ret;
12435   /* NOTREACHED */
12436   return 0;
12437 }
12438
12439 static void
12440   vl_api_ipfix_classify_stream_details_t_handler
12441   (vl_api_ipfix_classify_stream_details_t * mp)
12442 {
12443   vat_main_t *vam = &vat_main;
12444   print (vam->ofp, "domain_id %d, src_port %d",
12445          ntohl (mp->domain_id), ntohs (mp->src_port));
12446   vam->retval = 0;
12447   vam->result_ready = 1;
12448 }
12449
12450 static void
12451   vl_api_ipfix_classify_stream_details_t_handler_json
12452   (vl_api_ipfix_classify_stream_details_t * mp)
12453 {
12454   vat_main_t *vam = &vat_main;
12455   vat_json_node_t node;
12456
12457   vat_json_init_object (&node);
12458   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
12459   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
12460
12461   vat_json_print (vam->ofp, &node);
12462   vat_json_free (&node);
12463   vam->retval = 0;
12464   vam->result_ready = 1;
12465 }
12466
12467 static int
12468 api_ipfix_classify_table_dump (vat_main_t * vam)
12469 {
12470   vl_api_ipfix_classify_table_dump_t *mp;
12471   vl_api_control_ping_t *mp_ping;
12472   int ret;
12473
12474   if (!vam->json_output)
12475     {
12476       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
12477              "transport_protocol");
12478     }
12479
12480   /* Construct the API message */
12481   M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
12482
12483   /* send it... */
12484   S (mp);
12485
12486   /* Use a control ping for synchronization */
12487   MPING (CONTROL_PING, mp_ping);
12488   S (mp_ping);
12489
12490   W (ret);
12491   return ret;
12492 }
12493
12494 static void
12495   vl_api_ipfix_classify_table_details_t_handler
12496   (vl_api_ipfix_classify_table_details_t * mp)
12497 {
12498   vat_main_t *vam = &vat_main;
12499   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
12500          mp->transport_protocol);
12501 }
12502
12503 static void
12504   vl_api_ipfix_classify_table_details_t_handler_json
12505   (vl_api_ipfix_classify_table_details_t * mp)
12506 {
12507   vat_json_node_t *node = NULL;
12508   vat_main_t *vam = &vat_main;
12509
12510   if (VAT_JSON_ARRAY != vam->json_tree.type)
12511     {
12512       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12513       vat_json_init_array (&vam->json_tree);
12514     }
12515
12516   node = vat_json_array_add (&vam->json_tree);
12517   vat_json_init_object (node);
12518
12519   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
12520   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
12521   vat_json_object_add_uint (node, "transport_protocol",
12522                             mp->transport_protocol);
12523 }
12524
12525 static int
12526 api_sw_interface_span_enable_disable (vat_main_t * vam)
12527 {
12528   unformat_input_t *i = vam->input;
12529   vl_api_sw_interface_span_enable_disable_t *mp;
12530   u32 src_sw_if_index = ~0;
12531   u32 dst_sw_if_index = ~0;
12532   u8 state = 3;
12533   int ret;
12534   u8 is_l2 = 0;
12535
12536   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12537     {
12538       if (unformat
12539           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
12540         ;
12541       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
12542         ;
12543       else
12544         if (unformat
12545             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
12546         ;
12547       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
12548         ;
12549       else if (unformat (i, "disable"))
12550         state = 0;
12551       else if (unformat (i, "rx"))
12552         state = 1;
12553       else if (unformat (i, "tx"))
12554         state = 2;
12555       else if (unformat (i, "both"))
12556         state = 3;
12557       else if (unformat (i, "l2"))
12558         is_l2 = 1;
12559       else
12560         break;
12561     }
12562
12563   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
12564
12565   mp->sw_if_index_from = htonl (src_sw_if_index);
12566   mp->sw_if_index_to = htonl (dst_sw_if_index);
12567   mp->state = state;
12568   mp->is_l2 = is_l2;
12569
12570   S (mp);
12571   W (ret);
12572   return ret;
12573 }
12574
12575 static void
12576 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
12577                                             * mp)
12578 {
12579   vat_main_t *vam = &vat_main;
12580   u8 *sw_if_from_name = 0;
12581   u8 *sw_if_to_name = 0;
12582   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
12583   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
12584   char *states[] = { "none", "rx", "tx", "both" };
12585   hash_pair_t *p;
12586
12587   /* *INDENT-OFF* */
12588   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
12589   ({
12590     if ((u32) p->value[0] == sw_if_index_from)
12591       {
12592         sw_if_from_name = (u8 *)(p->key);
12593         if (sw_if_to_name)
12594           break;
12595       }
12596     if ((u32) p->value[0] == sw_if_index_to)
12597       {
12598         sw_if_to_name = (u8 *)(p->key);
12599         if (sw_if_from_name)
12600           break;
12601       }
12602   }));
12603   /* *INDENT-ON* */
12604   print (vam->ofp, "%20s => %20s (%s) %s",
12605          sw_if_from_name, sw_if_to_name, states[mp->state],
12606          mp->is_l2 ? "l2" : "device");
12607 }
12608
12609 static void
12610   vl_api_sw_interface_span_details_t_handler_json
12611   (vl_api_sw_interface_span_details_t * mp)
12612 {
12613   vat_main_t *vam = &vat_main;
12614   vat_json_node_t *node = NULL;
12615   u8 *sw_if_from_name = 0;
12616   u8 *sw_if_to_name = 0;
12617   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
12618   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
12619   hash_pair_t *p;
12620
12621   /* *INDENT-OFF* */
12622   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
12623   ({
12624     if ((u32) p->value[0] == sw_if_index_from)
12625       {
12626         sw_if_from_name = (u8 *)(p->key);
12627         if (sw_if_to_name)
12628           break;
12629       }
12630     if ((u32) p->value[0] == sw_if_index_to)
12631       {
12632         sw_if_to_name = (u8 *)(p->key);
12633         if (sw_if_from_name)
12634           break;
12635       }
12636   }));
12637   /* *INDENT-ON* */
12638
12639   if (VAT_JSON_ARRAY != vam->json_tree.type)
12640     {
12641       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12642       vat_json_init_array (&vam->json_tree);
12643     }
12644   node = vat_json_array_add (&vam->json_tree);
12645
12646   vat_json_init_object (node);
12647   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
12648   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
12649   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
12650   if (0 != sw_if_to_name)
12651     {
12652       vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
12653     }
12654   vat_json_object_add_uint (node, "state", mp->state);
12655   vat_json_object_add_uint (node, "is-l2", mp->is_l2);
12656 }
12657
12658 static int
12659 api_sw_interface_span_dump (vat_main_t * vam)
12660 {
12661   unformat_input_t *input = vam->input;
12662   vl_api_sw_interface_span_dump_t *mp;
12663   vl_api_control_ping_t *mp_ping;
12664   u8 is_l2 = 0;
12665   int ret;
12666
12667   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12668     {
12669       if (unformat (input, "l2"))
12670         is_l2 = 1;
12671       else
12672         break;
12673     }
12674
12675   M (SW_INTERFACE_SPAN_DUMP, mp);
12676   mp->is_l2 = is_l2;
12677   S (mp);
12678
12679   /* Use a control ping for synchronization */
12680   MPING (CONTROL_PING, mp_ping);
12681   S (mp_ping);
12682
12683   W (ret);
12684   return ret;
12685 }
12686
12687 int
12688 api_pg_create_interface (vat_main_t * vam)
12689 {
12690   unformat_input_t *input = vam->input;
12691   vl_api_pg_create_interface_t *mp;
12692
12693   u32 if_id = ~0, gso_size = 0;
12694   u8 gso_enabled = 0;
12695   int ret;
12696   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12697     {
12698       if (unformat (input, "if_id %d", &if_id))
12699         ;
12700       else if (unformat (input, "gso-enabled"))
12701         {
12702           gso_enabled = 1;
12703           if (unformat (input, "gso-size %u", &gso_size))
12704             ;
12705           else
12706             {
12707               errmsg ("missing gso-size");
12708               return -99;
12709             }
12710         }
12711       else
12712         break;
12713     }
12714   if (if_id == ~0)
12715     {
12716       errmsg ("missing pg interface index");
12717       return -99;
12718     }
12719
12720   /* Construct the API message */
12721   M (PG_CREATE_INTERFACE, mp);
12722   mp->context = 0;
12723   mp->interface_id = ntohl (if_id);
12724   mp->gso_enabled = gso_enabled;
12725
12726   S (mp);
12727   W (ret);
12728   return ret;
12729 }
12730
12731 int
12732 api_pg_capture (vat_main_t * vam)
12733 {
12734   unformat_input_t *input = vam->input;
12735   vl_api_pg_capture_t *mp;
12736
12737   u32 if_id = ~0;
12738   u8 enable = 1;
12739   u32 count = 1;
12740   u8 pcap_file_set = 0;
12741   u8 *pcap_file = 0;
12742   int ret;
12743   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12744     {
12745       if (unformat (input, "if_id %d", &if_id))
12746         ;
12747       else if (unformat (input, "pcap %s", &pcap_file))
12748         pcap_file_set = 1;
12749       else if (unformat (input, "count %d", &count))
12750         ;
12751       else if (unformat (input, "disable"))
12752         enable = 0;
12753       else
12754         break;
12755     }
12756   if (if_id == ~0)
12757     {
12758       errmsg ("missing pg interface index");
12759       return -99;
12760     }
12761   if (pcap_file_set > 0)
12762     {
12763       if (vec_len (pcap_file) > 255)
12764         {
12765           errmsg ("pcap file name is too long");
12766           return -99;
12767         }
12768     }
12769
12770   /* Construct the API message */
12771   M (PG_CAPTURE, mp);
12772   mp->context = 0;
12773   mp->interface_id = ntohl (if_id);
12774   mp->is_enabled = enable;
12775   mp->count = ntohl (count);
12776   if (pcap_file_set != 0)
12777     {
12778       vl_api_vec_to_api_string (pcap_file, &mp->pcap_file_name);
12779     }
12780   vec_free (pcap_file);
12781
12782   S (mp);
12783   W (ret);
12784   return ret;
12785 }
12786
12787 int
12788 api_pg_enable_disable (vat_main_t * vam)
12789 {
12790   unformat_input_t *input = vam->input;
12791   vl_api_pg_enable_disable_t *mp;
12792
12793   u8 enable = 1;
12794   u8 stream_name_set = 0;
12795   u8 *stream_name = 0;
12796   int ret;
12797   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12798     {
12799       if (unformat (input, "stream %s", &stream_name))
12800         stream_name_set = 1;
12801       else if (unformat (input, "disable"))
12802         enable = 0;
12803       else
12804         break;
12805     }
12806
12807   if (stream_name_set > 0)
12808     {
12809       if (vec_len (stream_name) > 255)
12810         {
12811           errmsg ("stream name too long");
12812           return -99;
12813         }
12814     }
12815
12816   /* Construct the API message */
12817   M (PG_ENABLE_DISABLE, mp);
12818   mp->context = 0;
12819   mp->is_enabled = enable;
12820   if (stream_name_set != 0)
12821     {
12822       vl_api_vec_to_api_string (stream_name, &mp->stream_name);
12823     }
12824   vec_free (stream_name);
12825
12826   S (mp);
12827   W (ret);
12828   return ret;
12829 }
12830
12831 int
12832 api_pg_interface_enable_disable_coalesce (vat_main_t * vam)
12833 {
12834   unformat_input_t *input = vam->input;
12835   vl_api_pg_interface_enable_disable_coalesce_t *mp;
12836
12837   u32 sw_if_index = ~0;
12838   u8 enable = 1;
12839   int ret;
12840   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12841     {
12842       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12843         ;
12844       else if (unformat (input, "sw_if_index %d", &sw_if_index))
12845         ;
12846       else if (unformat (input, "disable"))
12847         enable = 0;
12848       else
12849         break;
12850     }
12851
12852   if (sw_if_index == ~0)
12853     {
12854       errmsg ("Interface required but not specified");
12855       return -99;
12856     }
12857
12858   /* Construct the API message */
12859   M (PG_INTERFACE_ENABLE_DISABLE_COALESCE, mp);
12860   mp->context = 0;
12861   mp->coalesce_enabled = enable;
12862   mp->sw_if_index = htonl (sw_if_index);
12863
12864   S (mp);
12865   W (ret);
12866   return ret;
12867 }
12868
12869 int
12870 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
12871 {
12872   unformat_input_t *input = vam->input;
12873   vl_api_ip_source_and_port_range_check_add_del_t *mp;
12874
12875   u16 *low_ports = 0;
12876   u16 *high_ports = 0;
12877   u16 this_low;
12878   u16 this_hi;
12879   vl_api_prefix_t prefix;
12880   u32 tmp, tmp2;
12881   u8 prefix_set = 0;
12882   u32 vrf_id = ~0;
12883   u8 is_add = 1;
12884   int ret;
12885
12886   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12887     {
12888       if (unformat (input, "%U", unformat_vl_api_prefix, &prefix))
12889         prefix_set = 1;
12890       else if (unformat (input, "vrf %d", &vrf_id))
12891         ;
12892       else if (unformat (input, "del"))
12893         is_add = 0;
12894       else if (unformat (input, "port %d", &tmp))
12895         {
12896           if (tmp == 0 || tmp > 65535)
12897             {
12898               errmsg ("port %d out of range", tmp);
12899               return -99;
12900             }
12901           this_low = tmp;
12902           this_hi = this_low + 1;
12903           vec_add1 (low_ports, this_low);
12904           vec_add1 (high_ports, this_hi);
12905         }
12906       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
12907         {
12908           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
12909             {
12910               errmsg ("incorrect range parameters");
12911               return -99;
12912             }
12913           this_low = tmp;
12914           /* Note: in debug CLI +1 is added to high before
12915              passing to real fn that does "the work"
12916              (ip_source_and_port_range_check_add_del).
12917              This fn is a wrapper around the binary API fn a
12918              control plane will call, which expects this increment
12919              to have occurred. Hence letting the binary API control
12920              plane fn do the increment for consistency between VAT
12921              and other control planes.
12922            */
12923           this_hi = tmp2;
12924           vec_add1 (low_ports, this_low);
12925           vec_add1 (high_ports, this_hi);
12926         }
12927       else
12928         break;
12929     }
12930
12931   if (prefix_set == 0)
12932     {
12933       errmsg ("<address>/<mask> not specified");
12934       return -99;
12935     }
12936
12937   if (vrf_id == ~0)
12938     {
12939       errmsg ("VRF ID required, not specified");
12940       return -99;
12941     }
12942
12943   if (vrf_id == 0)
12944     {
12945       errmsg
12946         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
12947       return -99;
12948     }
12949
12950   if (vec_len (low_ports) == 0)
12951     {
12952       errmsg ("At least one port or port range required");
12953       return -99;
12954     }
12955
12956   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
12957
12958   mp->is_add = is_add;
12959
12960   clib_memcpy (&mp->prefix, &prefix, sizeof (prefix));
12961
12962   mp->number_of_ranges = vec_len (low_ports);
12963
12964   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
12965   vec_free (low_ports);
12966
12967   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
12968   vec_free (high_ports);
12969
12970   mp->vrf_id = ntohl (vrf_id);
12971
12972   S (mp);
12973   W (ret);
12974   return ret;
12975 }
12976
12977 int
12978 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
12979 {
12980   unformat_input_t *input = vam->input;
12981   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
12982   u32 sw_if_index = ~0;
12983   int vrf_set = 0;
12984   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
12985   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
12986   u8 is_add = 1;
12987   int ret;
12988
12989   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
12990     {
12991       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12992         ;
12993       else if (unformat (input, "sw_if_index %d", &sw_if_index))
12994         ;
12995       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
12996         vrf_set = 1;
12997       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
12998         vrf_set = 1;
12999       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
13000         vrf_set = 1;
13001       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
13002         vrf_set = 1;
13003       else if (unformat (input, "del"))
13004         is_add = 0;
13005       else
13006         break;
13007     }
13008
13009   if (sw_if_index == ~0)
13010     {
13011       errmsg ("Interface required but not specified");
13012       return -99;
13013     }
13014
13015   if (vrf_set == 0)
13016     {
13017       errmsg ("VRF ID required but not specified");
13018       return -99;
13019     }
13020
13021   if (tcp_out_vrf_id == 0
13022       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
13023     {
13024       errmsg
13025         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
13026       return -99;
13027     }
13028
13029   /* Construct the API message */
13030   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
13031
13032   mp->sw_if_index = ntohl (sw_if_index);
13033   mp->is_add = is_add;
13034   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
13035   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
13036   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
13037   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
13038
13039   /* send it... */
13040   S (mp);
13041
13042   /* Wait for a reply... */
13043   W (ret);
13044   return ret;
13045 }
13046
13047 static int
13048 api_set_punt (vat_main_t * vam)
13049 {
13050   unformat_input_t *i = vam->input;
13051   vl_api_address_family_t af;
13052   vl_api_set_punt_t *mp;
13053   u32 protocol = ~0;
13054   u32 port = ~0;
13055   int is_add = 1;
13056   int ret;
13057
13058   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13059     {
13060       if (unformat (i, "%U", unformat_vl_api_address_family, &af))
13061         ;
13062       else if (unformat (i, "protocol %d", &protocol))
13063         ;
13064       else if (unformat (i, "port %d", &port))
13065         ;
13066       else if (unformat (i, "del"))
13067         is_add = 0;
13068       else
13069         {
13070           clib_warning ("parse error '%U'", format_unformat_error, i);
13071           return -99;
13072         }
13073     }
13074
13075   M (SET_PUNT, mp);
13076
13077   mp->is_add = (u8) is_add;
13078   mp->punt.type = PUNT_API_TYPE_L4;
13079   mp->punt.punt.l4.af = af;
13080   mp->punt.punt.l4.protocol = (u8) protocol;
13081   mp->punt.punt.l4.port = htons ((u16) port);
13082
13083   S (mp);
13084   W (ret);
13085   return ret;
13086 }
13087
13088 static int
13089 api_delete_subif (vat_main_t * vam)
13090 {
13091   unformat_input_t *i = vam->input;
13092   vl_api_delete_subif_t *mp;
13093   u32 sw_if_index = ~0;
13094   int ret;
13095
13096   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13097     {
13098       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13099         ;
13100       if (unformat (i, "sw_if_index %d", &sw_if_index))
13101         ;
13102       else
13103         break;
13104     }
13105
13106   if (sw_if_index == ~0)
13107     {
13108       errmsg ("missing sw_if_index");
13109       return -99;
13110     }
13111
13112   /* Construct the API message */
13113   M (DELETE_SUBIF, mp);
13114   mp->sw_if_index = ntohl (sw_if_index);
13115
13116   S (mp);
13117   W (ret);
13118   return ret;
13119 }
13120
13121 #define foreach_pbb_vtr_op      \
13122 _("disable",  L2_VTR_DISABLED)  \
13123 _("pop",  L2_VTR_POP_2)         \
13124 _("push",  L2_VTR_PUSH_2)
13125
13126 static int
13127 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
13128 {
13129   unformat_input_t *i = vam->input;
13130   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
13131   u32 sw_if_index = ~0, vtr_op = ~0;
13132   u16 outer_tag = ~0;
13133   u8 dmac[6], smac[6];
13134   u8 dmac_set = 0, smac_set = 0;
13135   u16 vlanid = 0;
13136   u32 sid = ~0;
13137   u32 tmp;
13138   int ret;
13139
13140   /* Shut up coverity */
13141   clib_memset (dmac, 0, sizeof (dmac));
13142   clib_memset (smac, 0, sizeof (smac));
13143
13144   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13145     {
13146       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13147         ;
13148       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13149         ;
13150       else if (unformat (i, "vtr_op %d", &vtr_op))
13151         ;
13152 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
13153       foreach_pbb_vtr_op
13154 #undef _
13155         else if (unformat (i, "translate_pbb_stag"))
13156         {
13157           if (unformat (i, "%d", &tmp))
13158             {
13159               vtr_op = L2_VTR_TRANSLATE_2_1;
13160               outer_tag = tmp;
13161             }
13162           else
13163             {
13164               errmsg
13165                 ("translate_pbb_stag operation requires outer tag definition");
13166               return -99;
13167             }
13168         }
13169       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
13170         dmac_set++;
13171       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
13172         smac_set++;
13173       else if (unformat (i, "sid %d", &sid))
13174         ;
13175       else if (unformat (i, "vlanid %d", &tmp))
13176         vlanid = tmp;
13177       else
13178         {
13179           clib_warning ("parse error '%U'", format_unformat_error, i);
13180           return -99;
13181         }
13182     }
13183
13184   if ((sw_if_index == ~0) || (vtr_op == ~0))
13185     {
13186       errmsg ("missing sw_if_index or vtr operation");
13187       return -99;
13188     }
13189   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
13190       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
13191     {
13192       errmsg
13193         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
13194       return -99;
13195     }
13196
13197   M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
13198   mp->sw_if_index = ntohl (sw_if_index);
13199   mp->vtr_op = ntohl (vtr_op);
13200   mp->outer_tag = ntohs (outer_tag);
13201   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
13202   clib_memcpy (mp->b_smac, smac, sizeof (smac));
13203   mp->b_vlanid = ntohs (vlanid);
13204   mp->i_sid = ntohl (sid);
13205
13206   S (mp);
13207   W (ret);
13208   return ret;
13209 }
13210
13211 static int
13212 api_flow_classify_set_interface (vat_main_t * vam)
13213 {
13214   unformat_input_t *i = vam->input;
13215   vl_api_flow_classify_set_interface_t *mp;
13216   u32 sw_if_index;
13217   int sw_if_index_set;
13218   u32 ip4_table_index = ~0;
13219   u32 ip6_table_index = ~0;
13220   u8 is_add = 1;
13221   int ret;
13222
13223   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13224     {
13225       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13226         sw_if_index_set = 1;
13227       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13228         sw_if_index_set = 1;
13229       else if (unformat (i, "del"))
13230         is_add = 0;
13231       else if (unformat (i, "ip4-table %d", &ip4_table_index))
13232         ;
13233       else if (unformat (i, "ip6-table %d", &ip6_table_index))
13234         ;
13235       else
13236         {
13237           clib_warning ("parse error '%U'", format_unformat_error, i);
13238           return -99;
13239         }
13240     }
13241
13242   if (sw_if_index_set == 0)
13243     {
13244       errmsg ("missing interface name or sw_if_index");
13245       return -99;
13246     }
13247
13248   M (FLOW_CLASSIFY_SET_INTERFACE, mp);
13249
13250   mp->sw_if_index = ntohl (sw_if_index);
13251   mp->ip4_table_index = ntohl (ip4_table_index);
13252   mp->ip6_table_index = ntohl (ip6_table_index);
13253   mp->is_add = is_add;
13254
13255   S (mp);
13256   W (ret);
13257   return ret;
13258 }
13259
13260 static int
13261 api_flow_classify_dump (vat_main_t * vam)
13262 {
13263   unformat_input_t *i = vam->input;
13264   vl_api_flow_classify_dump_t *mp;
13265   vl_api_control_ping_t *mp_ping;
13266   u8 type = FLOW_CLASSIFY_N_TABLES;
13267   int ret;
13268
13269   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
13270     ;
13271   else
13272     {
13273       errmsg ("classify table type must be specified");
13274       return -99;
13275     }
13276
13277   if (!vam->json_output)
13278     {
13279       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
13280     }
13281
13282   M (FLOW_CLASSIFY_DUMP, mp);
13283   mp->type = type;
13284   /* send it... */
13285   S (mp);
13286
13287   /* Use a control ping for synchronization */
13288   MPING (CONTROL_PING, mp_ping);
13289   S (mp_ping);
13290
13291   /* Wait for a reply... */
13292   W (ret);
13293   return ret;
13294 }
13295
13296 static int
13297 api_feature_enable_disable (vat_main_t * vam)
13298 {
13299   unformat_input_t *i = vam->input;
13300   vl_api_feature_enable_disable_t *mp;
13301   u8 *arc_name = 0;
13302   u8 *feature_name = 0;
13303   u32 sw_if_index = ~0;
13304   u8 enable = 1;
13305   int ret;
13306
13307   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13308     {
13309       if (unformat (i, "arc_name %s", &arc_name))
13310         ;
13311       else if (unformat (i, "feature_name %s", &feature_name))
13312         ;
13313       else
13314         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13315         ;
13316       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13317         ;
13318       else if (unformat (i, "disable"))
13319         enable = 0;
13320       else
13321         break;
13322     }
13323
13324   if (arc_name == 0)
13325     {
13326       errmsg ("missing arc name");
13327       return -99;
13328     }
13329   if (vec_len (arc_name) > 63)
13330     {
13331       errmsg ("arc name too long");
13332     }
13333
13334   if (feature_name == 0)
13335     {
13336       errmsg ("missing feature name");
13337       return -99;
13338     }
13339   if (vec_len (feature_name) > 63)
13340     {
13341       errmsg ("feature name too long");
13342     }
13343
13344   if (sw_if_index == ~0)
13345     {
13346       errmsg ("missing interface name or sw_if_index");
13347       return -99;
13348     }
13349
13350   /* Construct the API message */
13351   M (FEATURE_ENABLE_DISABLE, mp);
13352   mp->sw_if_index = ntohl (sw_if_index);
13353   mp->enable = enable;
13354   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
13355   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
13356   vec_free (arc_name);
13357   vec_free (feature_name);
13358
13359   S (mp);
13360   W (ret);
13361   return ret;
13362 }
13363
13364 static int
13365 api_feature_gso_enable_disable (vat_main_t * vam)
13366 {
13367   unformat_input_t *i = vam->input;
13368   vl_api_feature_gso_enable_disable_t *mp;
13369   u32 sw_if_index = ~0;
13370   u8 enable = 1;
13371   int ret;
13372
13373   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13374     {
13375       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13376         ;
13377       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13378         ;
13379       else if (unformat (i, "enable"))
13380         enable = 1;
13381       else if (unformat (i, "disable"))
13382         enable = 0;
13383       else
13384         break;
13385     }
13386
13387   if (sw_if_index == ~0)
13388     {
13389       errmsg ("missing interface name or sw_if_index");
13390       return -99;
13391     }
13392
13393   /* Construct the API message */
13394   M (FEATURE_GSO_ENABLE_DISABLE, mp);
13395   mp->sw_if_index = ntohl (sw_if_index);
13396   mp->enable_disable = enable;
13397
13398   S (mp);
13399   W (ret);
13400   return ret;
13401 }
13402
13403 static int
13404 api_sw_interface_tag_add_del (vat_main_t * vam)
13405 {
13406   unformat_input_t *i = vam->input;
13407   vl_api_sw_interface_tag_add_del_t *mp;
13408   u32 sw_if_index = ~0;
13409   u8 *tag = 0;
13410   u8 enable = 1;
13411   int ret;
13412
13413   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13414     {
13415       if (unformat (i, "tag %s", &tag))
13416         ;
13417       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13418         ;
13419       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13420         ;
13421       else if (unformat (i, "del"))
13422         enable = 0;
13423       else
13424         break;
13425     }
13426
13427   if (sw_if_index == ~0)
13428     {
13429       errmsg ("missing interface name or sw_if_index");
13430       return -99;
13431     }
13432
13433   if (enable && (tag == 0))
13434     {
13435       errmsg ("no tag specified");
13436       return -99;
13437     }
13438
13439   /* Construct the API message */
13440   M (SW_INTERFACE_TAG_ADD_DEL, mp);
13441   mp->sw_if_index = ntohl (sw_if_index);
13442   mp->is_add = enable;
13443   if (enable)
13444     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
13445   vec_free (tag);
13446
13447   S (mp);
13448   W (ret);
13449   return ret;
13450 }
13451
13452 static int
13453 api_sw_interface_add_del_mac_address (vat_main_t * vam)
13454 {
13455   unformat_input_t *i = vam->input;
13456   vl_api_mac_address_t mac = { 0 };
13457   vl_api_sw_interface_add_del_mac_address_t *mp;
13458   u32 sw_if_index = ~0;
13459   u8 is_add = 1;
13460   u8 mac_set = 0;
13461   int ret;
13462
13463   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13464     {
13465       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13466         ;
13467       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13468         ;
13469       else if (unformat (i, "%U", unformat_vl_api_mac_address, &mac))
13470         mac_set++;
13471       else if (unformat (i, "del"))
13472         is_add = 0;
13473       else
13474         break;
13475     }
13476
13477   if (sw_if_index == ~0)
13478     {
13479       errmsg ("missing interface name or sw_if_index");
13480       return -99;
13481     }
13482
13483   if (!mac_set)
13484     {
13485       errmsg ("missing MAC address");
13486       return -99;
13487     }
13488
13489   /* Construct the API message */
13490   M (SW_INTERFACE_ADD_DEL_MAC_ADDRESS, mp);
13491   mp->sw_if_index = ntohl (sw_if_index);
13492   mp->is_add = is_add;
13493   clib_memcpy (&mp->addr, &mac, sizeof (mac));
13494
13495   S (mp);
13496   W (ret);
13497   return ret;
13498 }
13499
13500 static void vl_api_l2_xconnect_details_t_handler
13501   (vl_api_l2_xconnect_details_t * mp)
13502 {
13503   vat_main_t *vam = &vat_main;
13504
13505   print (vam->ofp, "%15d%15d",
13506          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
13507 }
13508
13509 static void vl_api_l2_xconnect_details_t_handler_json
13510   (vl_api_l2_xconnect_details_t * mp)
13511 {
13512   vat_main_t *vam = &vat_main;
13513   vat_json_node_t *node = NULL;
13514
13515   if (VAT_JSON_ARRAY != vam->json_tree.type)
13516     {
13517       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13518       vat_json_init_array (&vam->json_tree);
13519     }
13520   node = vat_json_array_add (&vam->json_tree);
13521
13522   vat_json_init_object (node);
13523   vat_json_object_add_uint (node, "rx_sw_if_index",
13524                             ntohl (mp->rx_sw_if_index));
13525   vat_json_object_add_uint (node, "tx_sw_if_index",
13526                             ntohl (mp->tx_sw_if_index));
13527 }
13528
13529 static int
13530 api_l2_xconnect_dump (vat_main_t * vam)
13531 {
13532   vl_api_l2_xconnect_dump_t *mp;
13533   vl_api_control_ping_t *mp_ping;
13534   int ret;
13535
13536   if (!vam->json_output)
13537     {
13538       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
13539     }
13540
13541   M (L2_XCONNECT_DUMP, mp);
13542
13543   S (mp);
13544
13545   /* Use a control ping for synchronization */
13546   MPING (CONTROL_PING, mp_ping);
13547   S (mp_ping);
13548
13549   W (ret);
13550   return ret;
13551 }
13552
13553 static int
13554 api_hw_interface_set_mtu (vat_main_t * vam)
13555 {
13556   unformat_input_t *i = vam->input;
13557   vl_api_hw_interface_set_mtu_t *mp;
13558   u32 sw_if_index = ~0;
13559   u32 mtu = 0;
13560   int ret;
13561
13562   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13563     {
13564       if (unformat (i, "mtu %d", &mtu))
13565         ;
13566       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13567         ;
13568       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13569         ;
13570       else
13571         break;
13572     }
13573
13574   if (sw_if_index == ~0)
13575     {
13576       errmsg ("missing interface name or sw_if_index");
13577       return -99;
13578     }
13579
13580   if (mtu == 0)
13581     {
13582       errmsg ("no mtu specified");
13583       return -99;
13584     }
13585
13586   /* Construct the API message */
13587   M (HW_INTERFACE_SET_MTU, mp);
13588   mp->sw_if_index = ntohl (sw_if_index);
13589   mp->mtu = ntohs ((u16) mtu);
13590
13591   S (mp);
13592   W (ret);
13593   return ret;
13594 }
13595
13596 static int
13597 api_p2p_ethernet_add (vat_main_t * vam)
13598 {
13599   unformat_input_t *i = vam->input;
13600   vl_api_p2p_ethernet_add_t *mp;
13601   u32 parent_if_index = ~0;
13602   u32 sub_id = ~0;
13603   u8 remote_mac[6];
13604   u8 mac_set = 0;
13605   int ret;
13606
13607   clib_memset (remote_mac, 0, sizeof (remote_mac));
13608   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13609     {
13610       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
13611         ;
13612       else if (unformat (i, "sw_if_index %d", &parent_if_index))
13613         ;
13614       else
13615         if (unformat
13616             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
13617         mac_set++;
13618       else if (unformat (i, "sub_id %d", &sub_id))
13619         ;
13620       else
13621         {
13622           clib_warning ("parse error '%U'", format_unformat_error, i);
13623           return -99;
13624         }
13625     }
13626
13627   if (parent_if_index == ~0)
13628     {
13629       errmsg ("missing interface name or sw_if_index");
13630       return -99;
13631     }
13632   if (mac_set == 0)
13633     {
13634       errmsg ("missing remote mac address");
13635       return -99;
13636     }
13637   if (sub_id == ~0)
13638     {
13639       errmsg ("missing sub-interface id");
13640       return -99;
13641     }
13642
13643   M (P2P_ETHERNET_ADD, mp);
13644   mp->parent_if_index = ntohl (parent_if_index);
13645   mp->subif_id = ntohl (sub_id);
13646   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
13647
13648   S (mp);
13649   W (ret);
13650   return ret;
13651 }
13652
13653 static int
13654 api_p2p_ethernet_del (vat_main_t * vam)
13655 {
13656   unformat_input_t *i = vam->input;
13657   vl_api_p2p_ethernet_del_t *mp;
13658   u32 parent_if_index = ~0;
13659   u8 remote_mac[6];
13660   u8 mac_set = 0;
13661   int ret;
13662
13663   clib_memset (remote_mac, 0, sizeof (remote_mac));
13664   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13665     {
13666       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
13667         ;
13668       else if (unformat (i, "sw_if_index %d", &parent_if_index))
13669         ;
13670       else
13671         if (unformat
13672             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
13673         mac_set++;
13674       else
13675         {
13676           clib_warning ("parse error '%U'", format_unformat_error, i);
13677           return -99;
13678         }
13679     }
13680
13681   if (parent_if_index == ~0)
13682     {
13683       errmsg ("missing interface name or sw_if_index");
13684       return -99;
13685     }
13686   if (mac_set == 0)
13687     {
13688       errmsg ("missing remote mac address");
13689       return -99;
13690     }
13691
13692   M (P2P_ETHERNET_DEL, mp);
13693   mp->parent_if_index = ntohl (parent_if_index);
13694   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
13695
13696   S (mp);
13697   W (ret);
13698   return ret;
13699 }
13700
13701 static int
13702 api_tcp_configure_src_addresses (vat_main_t * vam)
13703 {
13704   vl_api_tcp_configure_src_addresses_t *mp;
13705   unformat_input_t *i = vam->input;
13706   vl_api_address_t first, last;
13707   u8 range_set = 0;
13708   u32 vrf_id = 0;
13709   int ret;
13710
13711   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13712     {
13713       if (unformat (i, "%U - %U",
13714                     unformat_vl_api_address, &first,
13715                     unformat_vl_api_address, &last))
13716         {
13717           if (range_set)
13718             {
13719               errmsg ("one range per message (range already set)");
13720               return -99;
13721             }
13722           range_set = 1;
13723         }
13724       else if (unformat (i, "vrf %d", &vrf_id))
13725         ;
13726       else
13727         break;
13728     }
13729
13730   if (range_set == 0)
13731     {
13732       errmsg ("address range not set");
13733       return -99;
13734     }
13735
13736   M (TCP_CONFIGURE_SRC_ADDRESSES, mp);
13737
13738   mp->vrf_id = ntohl (vrf_id);
13739   clib_memcpy (&mp->first_address, &first, sizeof (first));
13740   clib_memcpy (&mp->last_address, &last, sizeof (last));
13741
13742   S (mp);
13743   W (ret);
13744   return ret;
13745 }
13746
13747 static void vl_api_app_namespace_add_del_reply_t_handler
13748   (vl_api_app_namespace_add_del_reply_t * mp)
13749 {
13750   vat_main_t *vam = &vat_main;
13751   i32 retval = ntohl (mp->retval);
13752   if (vam->async_mode)
13753     {
13754       vam->async_errors += (retval < 0);
13755     }
13756   else
13757     {
13758       vam->retval = retval;
13759       if (retval == 0)
13760         errmsg ("app ns index %d\n", ntohl (mp->appns_index));
13761       vam->result_ready = 1;
13762     }
13763 }
13764
13765 static void vl_api_app_namespace_add_del_reply_t_handler_json
13766   (vl_api_app_namespace_add_del_reply_t * mp)
13767 {
13768   vat_main_t *vam = &vat_main;
13769   vat_json_node_t node;
13770
13771   vat_json_init_object (&node);
13772   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
13773   vat_json_object_add_uint (&node, "appns_index", ntohl (mp->appns_index));
13774
13775   vat_json_print (vam->ofp, &node);
13776   vat_json_free (&node);
13777
13778   vam->retval = ntohl (mp->retval);
13779   vam->result_ready = 1;
13780 }
13781
13782 static int
13783 api_app_namespace_add_del (vat_main_t * vam)
13784 {
13785   vl_api_app_namespace_add_del_t *mp;
13786   unformat_input_t *i = vam->input;
13787   u8 *ns_id = 0, secret_set = 0, sw_if_index_set = 0;
13788   u32 sw_if_index, ip4_fib_id, ip6_fib_id;
13789   u64 secret;
13790   int ret;
13791
13792   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13793     {
13794       if (unformat (i, "id %_%v%_", &ns_id))
13795         ;
13796       else if (unformat (i, "secret %lu", &secret))
13797         secret_set = 1;
13798       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13799         sw_if_index_set = 1;
13800       else if (unformat (i, "ip4_fib_id %d", &ip4_fib_id))
13801         ;
13802       else if (unformat (i, "ip6_fib_id %d", &ip6_fib_id))
13803         ;
13804       else
13805         break;
13806     }
13807   if (!ns_id || !secret_set || !sw_if_index_set)
13808     {
13809       errmsg ("namespace id, secret and sw_if_index must be set");
13810       return -99;
13811     }
13812   if (vec_len (ns_id) > 64)
13813     {
13814       errmsg ("namespace id too long");
13815       return -99;
13816     }
13817   M (APP_NAMESPACE_ADD_DEL, mp);
13818
13819   vl_api_vec_to_api_string (ns_id, &mp->namespace_id);
13820   mp->secret = clib_host_to_net_u64 (secret);
13821   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
13822   mp->ip4_fib_id = clib_host_to_net_u32 (ip4_fib_id);
13823   mp->ip6_fib_id = clib_host_to_net_u32 (ip6_fib_id);
13824   vec_free (ns_id);
13825   S (mp);
13826   W (ret);
13827   return ret;
13828 }
13829
13830 static int
13831 api_sock_init_shm (vat_main_t * vam)
13832 {
13833 #if VPP_API_TEST_BUILTIN == 0
13834   unformat_input_t *i = vam->input;
13835   vl_api_shm_elem_config_t *config = 0;
13836   u64 size = 64 << 20;
13837   int rv;
13838
13839   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13840     {
13841       if (unformat (i, "size %U", unformat_memory_size, &size))
13842         ;
13843       else
13844         break;
13845     }
13846
13847   /*
13848    * Canned custom ring allocator config.
13849    * Should probably parse all of this
13850    */
13851   vec_validate (config, 6);
13852   config[0].type = VL_API_VLIB_RING;
13853   config[0].size = 256;
13854   config[0].count = 32;
13855
13856   config[1].type = VL_API_VLIB_RING;
13857   config[1].size = 1024;
13858   config[1].count = 16;
13859
13860   config[2].type = VL_API_VLIB_RING;
13861   config[2].size = 4096;
13862   config[2].count = 2;
13863
13864   config[3].type = VL_API_CLIENT_RING;
13865   config[3].size = 256;
13866   config[3].count = 32;
13867
13868   config[4].type = VL_API_CLIENT_RING;
13869   config[4].size = 1024;
13870   config[4].count = 16;
13871
13872   config[5].type = VL_API_CLIENT_RING;
13873   config[5].size = 4096;
13874   config[5].count = 2;
13875
13876   config[6].type = VL_API_QUEUE;
13877   config[6].count = 128;
13878   config[6].size = sizeof (uword);
13879
13880   rv = vl_socket_client_init_shm (config, 1 /* want_pthread */ );
13881   if (!rv)
13882     vam->client_index_invalid = 1;
13883   return rv;
13884 #else
13885   return -99;
13886 #endif
13887 }
13888
13889 static void
13890 vl_api_session_rules_details_t_handler (vl_api_session_rules_details_t * mp)
13891 {
13892   vat_main_t *vam = &vat_main;
13893   fib_prefix_t lcl, rmt;
13894
13895   ip_prefix_decode (&mp->lcl, &lcl);
13896   ip_prefix_decode (&mp->rmt, &rmt);
13897
13898   if (lcl.fp_proto == FIB_PROTOCOL_IP4)
13899     {
13900       print (vam->ofp,
13901              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
13902              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
13903              mp->scope, format_ip4_address, &lcl.fp_addr.ip4, lcl.fp_len,
13904              clib_net_to_host_u16 (mp->lcl_port), format_ip4_address,
13905              &rmt.fp_addr.ip4, rmt.fp_len,
13906              clib_net_to_host_u16 (mp->rmt_port),
13907              clib_net_to_host_u32 (mp->action_index), mp->tag);
13908     }
13909   else
13910     {
13911       print (vam->ofp,
13912              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
13913              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
13914              mp->scope, format_ip6_address, &lcl.fp_addr.ip6, lcl.fp_len,
13915              clib_net_to_host_u16 (mp->lcl_port), format_ip6_address,
13916              &rmt.fp_addr.ip6, rmt.fp_len,
13917              clib_net_to_host_u16 (mp->rmt_port),
13918              clib_net_to_host_u32 (mp->action_index), mp->tag);
13919     }
13920 }
13921
13922 static void
13923 vl_api_session_rules_details_t_handler_json (vl_api_session_rules_details_t *
13924                                              mp)
13925 {
13926   vat_main_t *vam = &vat_main;
13927   vat_json_node_t *node = NULL;
13928   struct in6_addr ip6;
13929   struct in_addr ip4;
13930
13931   fib_prefix_t lcl, rmt;
13932
13933   ip_prefix_decode (&mp->lcl, &lcl);
13934   ip_prefix_decode (&mp->rmt, &rmt);
13935
13936   if (VAT_JSON_ARRAY != vam->json_tree.type)
13937     {
13938       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13939       vat_json_init_array (&vam->json_tree);
13940     }
13941   node = vat_json_array_add (&vam->json_tree);
13942   vat_json_init_object (node);
13943
13944   vat_json_object_add_uint (node, "appns_index",
13945                             clib_net_to_host_u32 (mp->appns_index));
13946   vat_json_object_add_uint (node, "transport_proto", mp->transport_proto);
13947   vat_json_object_add_uint (node, "scope", mp->scope);
13948   vat_json_object_add_uint (node, "action_index",
13949                             clib_net_to_host_u32 (mp->action_index));
13950   vat_json_object_add_uint (node, "lcl_port",
13951                             clib_net_to_host_u16 (mp->lcl_port));
13952   vat_json_object_add_uint (node, "rmt_port",
13953                             clib_net_to_host_u16 (mp->rmt_port));
13954   vat_json_object_add_uint (node, "lcl_plen", lcl.fp_len);
13955   vat_json_object_add_uint (node, "rmt_plen", rmt.fp_len);
13956   vat_json_object_add_string_copy (node, "tag", mp->tag);
13957   if (lcl.fp_proto == FIB_PROTOCOL_IP4)
13958     {
13959       clib_memcpy (&ip4, &lcl.fp_addr.ip4, sizeof (ip4));
13960       vat_json_object_add_ip4 (node, "lcl_ip", ip4);
13961       clib_memcpy (&ip4, &rmt.fp_addr.ip4, sizeof (ip4));
13962       vat_json_object_add_ip4 (node, "rmt_ip", ip4);
13963     }
13964   else
13965     {
13966       clib_memcpy (&ip6, &lcl.fp_addr.ip6, sizeof (ip6));
13967       vat_json_object_add_ip6 (node, "lcl_ip", ip6);
13968       clib_memcpy (&ip6, &rmt.fp_addr.ip6, sizeof (ip6));
13969       vat_json_object_add_ip6 (node, "rmt_ip", ip6);
13970     }
13971 }
13972
13973 static int
13974 api_session_rule_add_del (vat_main_t * vam)
13975 {
13976   vl_api_session_rule_add_del_t *mp;
13977   unformat_input_t *i = vam->input;
13978   u32 proto = ~0, lcl_port, rmt_port, action = 0, lcl_plen, rmt_plen;
13979   u32 appns_index = 0, scope = 0;
13980   ip4_address_t lcl_ip4, rmt_ip4;
13981   ip6_address_t lcl_ip6, rmt_ip6;
13982   u8 is_ip4 = 1, conn_set = 0;
13983   u8 is_add = 1, *tag = 0;
13984   int ret;
13985   fib_prefix_t lcl, rmt;
13986
13987   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13988     {
13989       if (unformat (i, "del"))
13990         is_add = 0;
13991       else if (unformat (i, "add"))
13992         ;
13993       else if (unformat (i, "proto tcp"))
13994         proto = 0;
13995       else if (unformat (i, "proto udp"))
13996         proto = 1;
13997       else if (unformat (i, "appns %d", &appns_index))
13998         ;
13999       else if (unformat (i, "scope %d", &scope))
14000         ;
14001       else if (unformat (i, "tag %_%v%_", &tag))
14002         ;
14003       else
14004         if (unformat
14005             (i, "%U/%d %d %U/%d %d", unformat_ip4_address, &lcl_ip4,
14006              &lcl_plen, &lcl_port, unformat_ip4_address, &rmt_ip4, &rmt_plen,
14007              &rmt_port))
14008         {
14009           is_ip4 = 1;
14010           conn_set = 1;
14011         }
14012       else
14013         if (unformat
14014             (i, "%U/%d %d %U/%d %d", unformat_ip6_address, &lcl_ip6,
14015              &lcl_plen, &lcl_port, unformat_ip6_address, &rmt_ip6, &rmt_plen,
14016              &rmt_port))
14017         {
14018           is_ip4 = 0;
14019           conn_set = 1;
14020         }
14021       else if (unformat (i, "action %d", &action))
14022         ;
14023       else
14024         break;
14025     }
14026   if (proto == ~0 || !conn_set || action == ~0)
14027     {
14028       errmsg ("transport proto, connection and action must be set");
14029       return -99;
14030     }
14031
14032   if (scope > 3)
14033     {
14034       errmsg ("scope should be 0-3");
14035       return -99;
14036     }
14037
14038   M (SESSION_RULE_ADD_DEL, mp);
14039
14040   clib_memset (&lcl, 0, sizeof (lcl));
14041   clib_memset (&rmt, 0, sizeof (rmt));
14042   if (is_ip4)
14043     {
14044       ip_set (&lcl.fp_addr, &lcl_ip4, 1);
14045       ip_set (&rmt.fp_addr, &rmt_ip4, 1);
14046       lcl.fp_len = lcl_plen;
14047       rmt.fp_len = rmt_plen;
14048     }
14049   else
14050     {
14051       ip_set (&lcl.fp_addr, &lcl_ip6, 0);
14052       ip_set (&rmt.fp_addr, &rmt_ip6, 0);
14053       lcl.fp_len = lcl_plen;
14054       rmt.fp_len = rmt_plen;
14055     }
14056
14057
14058   ip_prefix_encode (&lcl, &mp->lcl);
14059   ip_prefix_encode (&rmt, &mp->rmt);
14060   mp->lcl_port = clib_host_to_net_u16 ((u16) lcl_port);
14061   mp->rmt_port = clib_host_to_net_u16 ((u16) rmt_port);
14062   mp->transport_proto =
14063     proto ? TRANSPORT_PROTO_API_UDP : TRANSPORT_PROTO_API_TCP;
14064   mp->action_index = clib_host_to_net_u32 (action);
14065   mp->appns_index = clib_host_to_net_u32 (appns_index);
14066   mp->scope = scope;
14067   mp->is_add = is_add;
14068   if (tag)
14069     {
14070       clib_memcpy (mp->tag, tag, vec_len (tag));
14071       vec_free (tag);
14072     }
14073
14074   S (mp);
14075   W (ret);
14076   return ret;
14077 }
14078
14079 static int
14080 api_session_rules_dump (vat_main_t * vam)
14081 {
14082   vl_api_session_rules_dump_t *mp;
14083   vl_api_control_ping_t *mp_ping;
14084   int ret;
14085
14086   if (!vam->json_output)
14087     {
14088       print (vam->ofp, "%=20s", "Session Rules");
14089     }
14090
14091   M (SESSION_RULES_DUMP, mp);
14092   /* send it... */
14093   S (mp);
14094
14095   /* Use a control ping for synchronization */
14096   MPING (CONTROL_PING, mp_ping);
14097   S (mp_ping);
14098
14099   /* Wait for a reply... */
14100   W (ret);
14101   return ret;
14102 }
14103
14104 static int
14105 api_ip_container_proxy_add_del (vat_main_t * vam)
14106 {
14107   vl_api_ip_container_proxy_add_del_t *mp;
14108   unformat_input_t *i = vam->input;
14109   u32 sw_if_index = ~0;
14110   vl_api_prefix_t pfx = { };
14111   u8 is_add = 1;
14112   int ret;
14113
14114   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14115     {
14116       if (unformat (i, "del"))
14117         is_add = 0;
14118       else if (unformat (i, "add"))
14119         ;
14120       if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
14121         ;
14122       else if (unformat (i, "sw_if_index %u", &sw_if_index))
14123         ;
14124       else
14125         break;
14126     }
14127   if (sw_if_index == ~0 || pfx.len == 0)
14128     {
14129       errmsg ("address and sw_if_index must be set");
14130       return -99;
14131     }
14132
14133   M (IP_CONTAINER_PROXY_ADD_DEL, mp);
14134
14135   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
14136   mp->is_add = is_add;
14137   clib_memcpy (&mp->pfx, &pfx, sizeof (pfx));
14138
14139   S (mp);
14140   W (ret);
14141   return ret;
14142 }
14143
14144 static int
14145 api_qos_record_enable_disable (vat_main_t * vam)
14146 {
14147   unformat_input_t *i = vam->input;
14148   vl_api_qos_record_enable_disable_t *mp;
14149   u32 sw_if_index, qs = 0xff;
14150   u8 sw_if_index_set = 0;
14151   u8 enable = 1;
14152   int ret;
14153
14154   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14155     {
14156       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14157         sw_if_index_set = 1;
14158       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14159         sw_if_index_set = 1;
14160       else if (unformat (i, "%U", unformat_qos_source, &qs))
14161         ;
14162       else if (unformat (i, "disable"))
14163         enable = 0;
14164       else
14165         {
14166           clib_warning ("parse error '%U'", format_unformat_error, i);
14167           return -99;
14168         }
14169     }
14170
14171   if (sw_if_index_set == 0)
14172     {
14173       errmsg ("missing interface name or sw_if_index");
14174       return -99;
14175     }
14176   if (qs == 0xff)
14177     {
14178       errmsg ("input location must be specified");
14179       return -99;
14180     }
14181
14182   M (QOS_RECORD_ENABLE_DISABLE, mp);
14183
14184   mp->record.sw_if_index = ntohl (sw_if_index);
14185   mp->record.input_source = qs;
14186   mp->enable = enable;
14187
14188   S (mp);
14189   W (ret);
14190   return ret;
14191 }
14192
14193
14194 static int
14195 q_or_quit (vat_main_t * vam)
14196 {
14197 #if VPP_API_TEST_BUILTIN == 0
14198   longjmp (vam->jump_buf, 1);
14199 #endif
14200   return 0;                     /* not so much */
14201 }
14202
14203 static int
14204 q (vat_main_t * vam)
14205 {
14206   return q_or_quit (vam);
14207 }
14208
14209 static int
14210 quit (vat_main_t * vam)
14211 {
14212   return q_or_quit (vam);
14213 }
14214
14215 static int
14216 comment (vat_main_t * vam)
14217 {
14218   return 0;
14219 }
14220
14221 static int
14222 elog_save (vat_main_t * vam)
14223 {
14224 #if VPP_API_TEST_BUILTIN == 0
14225   elog_main_t *em = &vam->elog_main;
14226   unformat_input_t *i = vam->input;
14227   char *file, *chroot_file;
14228   clib_error_t *error;
14229
14230   if (!unformat (i, "%s", &file))
14231     {
14232       errmsg ("expected file name, got `%U'", format_unformat_error, i);
14233       return 0;
14234     }
14235
14236   /* It's fairly hard to get "../oopsie" through unformat; just in case */
14237   if (strstr (file, "..") || index (file, '/'))
14238     {
14239       errmsg ("illegal characters in filename '%s'", file);
14240       return 0;
14241     }
14242
14243   chroot_file = (char *) format (0, "/tmp/%s%c", file, 0);
14244
14245   vec_free (file);
14246
14247   errmsg ("Saving %wd of %wd events to %s",
14248           elog_n_events_in_buffer (em),
14249           elog_buffer_capacity (em), chroot_file);
14250
14251   error = elog_write_file (em, chroot_file, 1 /* flush ring */ );
14252   vec_free (chroot_file);
14253
14254   if (error)
14255     clib_error_report (error);
14256 #else
14257   errmsg ("Use the vpp event loger...");
14258 #endif
14259
14260   return 0;
14261 }
14262
14263 static int
14264 elog_setup (vat_main_t * vam)
14265 {
14266 #if VPP_API_TEST_BUILTIN == 0
14267   elog_main_t *em = &vam->elog_main;
14268   unformat_input_t *i = vam->input;
14269   u32 nevents = 128 << 10;
14270
14271   (void) unformat (i, "nevents %d", &nevents);
14272
14273   elog_init (em, nevents);
14274   vl_api_set_elog_main (em);
14275   vl_api_set_elog_trace_api_messages (1);
14276   errmsg ("Event logger initialized with %u events", nevents);
14277 #else
14278   errmsg ("Use the vpp event loger...");
14279 #endif
14280   return 0;
14281 }
14282
14283 static int
14284 elog_enable (vat_main_t * vam)
14285 {
14286 #if VPP_API_TEST_BUILTIN == 0
14287   elog_main_t *em = &vam->elog_main;
14288
14289   elog_enable_disable (em, 1 /* enable */ );
14290   vl_api_set_elog_trace_api_messages (1);
14291   errmsg ("Event logger enabled...");
14292 #else
14293   errmsg ("Use the vpp event loger...");
14294 #endif
14295   return 0;
14296 }
14297
14298 static int
14299 elog_disable (vat_main_t * vam)
14300 {
14301 #if VPP_API_TEST_BUILTIN == 0
14302   elog_main_t *em = &vam->elog_main;
14303
14304   elog_enable_disable (em, 0 /* enable */ );
14305   vl_api_set_elog_trace_api_messages (1);
14306   errmsg ("Event logger disabled...");
14307 #else
14308   errmsg ("Use the vpp event loger...");
14309 #endif
14310   return 0;
14311 }
14312
14313 static int
14314 statseg (vat_main_t * vam)
14315 {
14316   ssvm_private_t *ssvmp = &vam->stat_segment;
14317   ssvm_shared_header_t *shared_header = ssvmp->sh;
14318   vlib_counter_t **counters;
14319   u64 thread0_index1_packets;
14320   u64 thread0_index1_bytes;
14321   f64 vector_rate, input_rate;
14322   uword *p;
14323
14324   uword *counter_vector_by_name;
14325   if (vam->stat_segment_lockp == 0)
14326     {
14327       errmsg ("Stat segment not mapped...");
14328       return -99;
14329     }
14330
14331   /* look up "/if/rx for sw_if_index 1 as a test */
14332
14333   clib_spinlock_lock (vam->stat_segment_lockp);
14334
14335   counter_vector_by_name = (uword *) shared_header->opaque[1];
14336
14337   p = hash_get_mem (counter_vector_by_name, "/if/rx");
14338   if (p == 0)
14339     {
14340       clib_spinlock_unlock (vam->stat_segment_lockp);
14341       errmsg ("/if/tx not found?");
14342       return -99;
14343     }
14344
14345   /* Fish per-thread vector of combined counters from shared memory */
14346   counters = (vlib_counter_t **) p[0];
14347
14348   if (vec_len (counters[0]) < 2)
14349     {
14350       clib_spinlock_unlock (vam->stat_segment_lockp);
14351       errmsg ("/if/tx vector length %d", vec_len (counters[0]));
14352       return -99;
14353     }
14354
14355   /* Read thread 0 sw_if_index 1 counter */
14356   thread0_index1_packets = counters[0][1].packets;
14357   thread0_index1_bytes = counters[0][1].bytes;
14358
14359   p = hash_get_mem (counter_vector_by_name, "vector_rate");
14360   if (p == 0)
14361     {
14362       clib_spinlock_unlock (vam->stat_segment_lockp);
14363       errmsg ("vector_rate not found?");
14364       return -99;
14365     }
14366
14367   vector_rate = *(f64 *) (p[0]);
14368   p = hash_get_mem (counter_vector_by_name, "input_rate");
14369   if (p == 0)
14370     {
14371       clib_spinlock_unlock (vam->stat_segment_lockp);
14372       errmsg ("input_rate not found?");
14373       return -99;
14374     }
14375   input_rate = *(f64 *) (p[0]);
14376
14377   clib_spinlock_unlock (vam->stat_segment_lockp);
14378
14379   print (vam->ofp, "vector_rate %.2f input_rate %.2f",
14380          vector_rate, input_rate);
14381   print (vam->ofp, "thread 0 sw_if_index 1 rx pkts %lld, bytes %lld",
14382          thread0_index1_packets, thread0_index1_bytes);
14383
14384   return 0;
14385 }
14386
14387 static int
14388 cmd_cmp (void *a1, void *a2)
14389 {
14390   u8 **c1 = a1;
14391   u8 **c2 = a2;
14392
14393   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
14394 }
14395
14396 static int
14397 help (vat_main_t * vam)
14398 {
14399   u8 **cmds = 0;
14400   u8 *name = 0;
14401   hash_pair_t *p;
14402   unformat_input_t *i = vam->input;
14403   int j;
14404
14405   if (unformat (i, "%s", &name))
14406     {
14407       uword *hs;
14408
14409       vec_add1 (name, 0);
14410
14411       hs = hash_get_mem (vam->help_by_name, name);
14412       if (hs)
14413         print (vam->ofp, "usage: %s %s", name, hs[0]);
14414       else
14415         print (vam->ofp, "No such msg / command '%s'", name);
14416       vec_free (name);
14417       return 0;
14418     }
14419
14420   print (vam->ofp, "Help is available for the following:");
14421
14422     /* *INDENT-OFF* */
14423     hash_foreach_pair (p, vam->function_by_name,
14424     ({
14425       vec_add1 (cmds, (u8 *)(p->key));
14426     }));
14427     /* *INDENT-ON* */
14428
14429   vec_sort_with_function (cmds, cmd_cmp);
14430
14431   for (j = 0; j < vec_len (cmds); j++)
14432     print (vam->ofp, "%s", cmds[j]);
14433
14434   vec_free (cmds);
14435   return 0;
14436 }
14437
14438 static int
14439 set (vat_main_t * vam)
14440 {
14441   u8 *name = 0, *value = 0;
14442   unformat_input_t *i = vam->input;
14443
14444   if (unformat (i, "%s", &name))
14445     {
14446       /* The input buffer is a vector, not a string. */
14447       value = vec_dup (i->buffer);
14448       vec_delete (value, i->index, 0);
14449       /* Almost certainly has a trailing newline */
14450       if (value[vec_len (value) - 1] == '\n')
14451         value[vec_len (value) - 1] = 0;
14452       /* Make sure it's a proper string, one way or the other */
14453       vec_add1 (value, 0);
14454       (void) clib_macro_set_value (&vam->macro_main,
14455                                    (char *) name, (char *) value);
14456     }
14457   else
14458     errmsg ("usage: set <name> <value>");
14459
14460   vec_free (name);
14461   vec_free (value);
14462   return 0;
14463 }
14464
14465 static int
14466 unset (vat_main_t * vam)
14467 {
14468   u8 *name = 0;
14469
14470   if (unformat (vam->input, "%s", &name))
14471     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
14472       errmsg ("unset: %s wasn't set", name);
14473   vec_free (name);
14474   return 0;
14475 }
14476
14477 typedef struct
14478 {
14479   u8 *name;
14480   u8 *value;
14481 } macro_sort_t;
14482
14483
14484 static int
14485 macro_sort_cmp (void *a1, void *a2)
14486 {
14487   macro_sort_t *s1 = a1;
14488   macro_sort_t *s2 = a2;
14489
14490   return strcmp ((char *) (s1->name), (char *) (s2->name));
14491 }
14492
14493 static int
14494 dump_macro_table (vat_main_t * vam)
14495 {
14496   macro_sort_t *sort_me = 0, *sm;
14497   int i;
14498   hash_pair_t *p;
14499
14500     /* *INDENT-OFF* */
14501     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
14502     ({
14503       vec_add2 (sort_me, sm, 1);
14504       sm->name = (u8 *)(p->key);
14505       sm->value = (u8 *) (p->value[0]);
14506     }));
14507     /* *INDENT-ON* */
14508
14509   vec_sort_with_function (sort_me, macro_sort_cmp);
14510
14511   if (vec_len (sort_me))
14512     print (vam->ofp, "%-15s%s", "Name", "Value");
14513   else
14514     print (vam->ofp, "The macro table is empty...");
14515
14516   for (i = 0; i < vec_len (sort_me); i++)
14517     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
14518   return 0;
14519 }
14520
14521 static int
14522 dump_node_table (vat_main_t * vam)
14523 {
14524   int i, j;
14525   vlib_node_t *node, *next_node;
14526
14527   if (vec_len (vam->graph_nodes) == 0)
14528     {
14529       print (vam->ofp, "Node table empty, issue get_node_graph...");
14530       return 0;
14531     }
14532
14533   for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
14534     {
14535       node = vam->graph_nodes[0][i];
14536       print (vam->ofp, "[%d] %s", i, node->name);
14537       for (j = 0; j < vec_len (node->next_nodes); j++)
14538         {
14539           if (node->next_nodes[j] != ~0)
14540             {
14541               next_node = vam->graph_nodes[0][node->next_nodes[j]];
14542               print (vam->ofp, "  [%d] %s", j, next_node->name);
14543             }
14544         }
14545     }
14546   return 0;
14547 }
14548
14549 static int
14550 value_sort_cmp (void *a1, void *a2)
14551 {
14552   name_sort_t *n1 = a1;
14553   name_sort_t *n2 = a2;
14554
14555   if (n1->value < n2->value)
14556     return -1;
14557   if (n1->value > n2->value)
14558     return 1;
14559   return 0;
14560 }
14561
14562
14563 static int
14564 dump_msg_api_table (vat_main_t * vam)
14565 {
14566   api_main_t *am = vlibapi_get_main ();
14567   name_sort_t *nses = 0, *ns;
14568   hash_pair_t *hp;
14569   int i;
14570
14571   /* *INDENT-OFF* */
14572   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
14573   ({
14574     vec_add2 (nses, ns, 1);
14575     ns->name = (u8 *)(hp->key);
14576     ns->value = (u32) hp->value[0];
14577   }));
14578   /* *INDENT-ON* */
14579
14580   vec_sort_with_function (nses, value_sort_cmp);
14581
14582   for (i = 0; i < vec_len (nses); i++)
14583     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
14584   vec_free (nses);
14585   return 0;
14586 }
14587
14588 static int
14589 get_msg_id (vat_main_t * vam)
14590 {
14591   u8 *name_and_crc;
14592   u32 message_index;
14593
14594   if (unformat (vam->input, "%s", &name_and_crc))
14595     {
14596       message_index = vl_msg_api_get_msg_index (name_and_crc);
14597       if (message_index == ~0)
14598         {
14599           print (vam->ofp, " '%s' not found", name_and_crc);
14600           return 0;
14601         }
14602       print (vam->ofp, " '%s' has message index %d",
14603              name_and_crc, message_index);
14604       return 0;
14605     }
14606   errmsg ("name_and_crc required...");
14607   return 0;
14608 }
14609
14610 static int
14611 search_node_table (vat_main_t * vam)
14612 {
14613   unformat_input_t *line_input = vam->input;
14614   u8 *node_to_find;
14615   int j;
14616   vlib_node_t *node, *next_node;
14617   uword *p;
14618
14619   if (vam->graph_node_index_by_name == 0)
14620     {
14621       print (vam->ofp, "Node table empty, issue get_node_graph...");
14622       return 0;
14623     }
14624
14625   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14626     {
14627       if (unformat (line_input, "%s", &node_to_find))
14628         {
14629           vec_add1 (node_to_find, 0);
14630           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
14631           if (p == 0)
14632             {
14633               print (vam->ofp, "%s not found...", node_to_find);
14634               goto out;
14635             }
14636           node = vam->graph_nodes[0][p[0]];
14637           print (vam->ofp, "[%d] %s", p[0], node->name);
14638           for (j = 0; j < vec_len (node->next_nodes); j++)
14639             {
14640               if (node->next_nodes[j] != ~0)
14641                 {
14642                   next_node = vam->graph_nodes[0][node->next_nodes[j]];
14643                   print (vam->ofp, "  [%d] %s", j, next_node->name);
14644                 }
14645             }
14646         }
14647
14648       else
14649         {
14650           clib_warning ("parse error '%U'", format_unformat_error,
14651                         line_input);
14652           return -99;
14653         }
14654
14655     out:
14656       vec_free (node_to_find);
14657
14658     }
14659
14660   return 0;
14661 }
14662
14663
14664 static int
14665 script (vat_main_t * vam)
14666 {
14667 #if (VPP_API_TEST_BUILTIN==0)
14668   u8 *s = 0;
14669   char *save_current_file;
14670   unformat_input_t save_input;
14671   jmp_buf save_jump_buf;
14672   u32 save_line_number;
14673
14674   FILE *new_fp, *save_ifp;
14675
14676   if (unformat (vam->input, "%s", &s))
14677     {
14678       new_fp = fopen ((char *) s, "r");
14679       if (new_fp == 0)
14680         {
14681           errmsg ("Couldn't open script file %s", s);
14682           vec_free (s);
14683           return -99;
14684         }
14685     }
14686   else
14687     {
14688       errmsg ("Missing script name");
14689       return -99;
14690     }
14691
14692   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
14693   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
14694   save_ifp = vam->ifp;
14695   save_line_number = vam->input_line_number;
14696   save_current_file = (char *) vam->current_file;
14697
14698   vam->input_line_number = 0;
14699   vam->ifp = new_fp;
14700   vam->current_file = s;
14701   do_one_file (vam);
14702
14703   clib_memcpy (&vam->input, &save_input, sizeof (save_input));
14704   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
14705   vam->ifp = save_ifp;
14706   vam->input_line_number = save_line_number;
14707   vam->current_file = (u8 *) save_current_file;
14708   vec_free (s);
14709
14710   return 0;
14711 #else
14712   clib_warning ("use the exec command...");
14713   return -99;
14714 #endif
14715 }
14716
14717 static int
14718 echo (vat_main_t * vam)
14719 {
14720   print (vam->ofp, "%v", vam->input->buffer);
14721   return 0;
14722 }
14723
14724 /* List of API message constructors, CLI names map to api_xxx */
14725 #define foreach_vpe_api_msg                                             \
14726 _(create_loopback,"[mac <mac-addr>] [instance <instance>]")             \
14727 _(sw_interface_dump,"")                                                 \
14728 _(sw_interface_set_flags,                                               \
14729   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
14730 _(sw_interface_add_del_address,                                         \
14731   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
14732 _(sw_interface_set_rx_mode,                                             \
14733   "<intfc> | sw_if_index <id> [queue <id>] <polling | interrupt | adaptive>") \
14734 _(sw_interface_set_rx_placement,                                        \
14735   "<intfc> | sw_if_index <id> [queue <id>] [worker <id> | main]")       \
14736 _(sw_interface_rx_placement_dump,                                       \
14737   "[<intfc> | sw_if_index <id>]")                                         \
14738 _(sw_interface_set_table,                                               \
14739   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
14740 _(sw_interface_set_mpls_enable,                                         \
14741   "<intfc> | sw_if_index [disable | dis]")                              \
14742 _(sw_interface_set_vpath,                                               \
14743   "<intfc> | sw_if_index <id> enable | disable")                        \
14744 _(sw_interface_set_vxlan_bypass,                                        \
14745   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
14746 _(sw_interface_set_l2_xconnect,                                         \
14747   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
14748   "enable | disable")                                                   \
14749 _(sw_interface_set_l2_bridge,                                           \
14750   "{<intfc> | sw_if_index <id>} bd_id <bridge-domain-id>\n"             \
14751   "[shg <split-horizon-group>] [bvi]\n"                                 \
14752   "enable | disable")                                                   \
14753 _(bridge_domain_set_mac_age, "bd_id <bridge-domain-id> mac-age 0-255")  \
14754 _(bridge_domain_add_del,                                                \
14755   "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") \
14756 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
14757 _(l2fib_add_del,                                                        \
14758   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
14759 _(l2fib_flush_bd, "bd_id <bridge-domain-id>")                           \
14760 _(l2fib_flush_int, "<intfc> | sw_if_index <id>")                        \
14761 _(l2_flags,                                                             \
14762   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
14763 _(bridge_flags,                                                         \
14764   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
14765 _(tap_create_v2,                                                        \
14766   "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]") \
14767 _(tap_delete_v2,                                                        \
14768   "<vpp-if-name> | sw_if_index <id>")                                   \
14769 _(sw_interface_tap_v2_dump, "")                                         \
14770 _(virtio_pci_create_v2,                                                    \
14771   "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]") \
14772 _(virtio_pci_delete,                                                    \
14773   "<vpp-if-name> | sw_if_index <id>")                                   \
14774 _(sw_interface_virtio_pci_dump, "")                                     \
14775 _(bond_create,                                                          \
14776   "[hw-addr <mac-addr>] {round-robin | active-backup | "                \
14777   "broadcast | {lacp | xor} [load-balance { l2 | l23 | l34 }]} "        \
14778   "[id <if-id>]")                                                       \
14779 _(bond_create2,                                                         \
14780   "[hw-addr <mac-addr>] {mode round-robin | active-backup | "           \
14781   "broadcast | {lacp | xor} [load-balance { l2 | l23 | l34 }]} "        \
14782   "[id <if-id>] [gso]")                                                 \
14783 _(bond_delete,                                                          \
14784   "<vpp-if-name> | sw_if_index <id>")                                   \
14785 _(bond_add_member,                                                      \
14786   "sw_if_index <n> bond <sw_if_index> [is_passive] [is_long_timeout]")  \
14787 _(bond_detach_member,                                                   \
14788   "sw_if_index <n>")                                                    \
14789  _(sw_interface_set_bond_weight, "<intfc> | sw_if_index <nn> weight <value>") \
14790  _(sw_bond_interface_dump, "<intfc> | sw_if_index <nn>")                \
14791  _(sw_member_interface_dump,                                            \
14792   "<vpp-if-name> | sw_if_index <id>")                                   \
14793 _(ip_table_add_del,                                                     \
14794   "table <n> [ipv6] [add | del]\n")                                     \
14795 _(ip_route_add_del,                                                     \
14796   "<addr>/<mask> via <<addr>|<intfc>|sw_if_index <id>|via-label <n>>\n" \
14797   "[table-id <n>] [<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"\
14798   "[weight <n>] [drop] [local] [classify <n>]  [out-label <n>]\n"       \
14799   "[multipath] [count <n>] [del]")                                      \
14800 _(ip_mroute_add_del,                                                    \
14801   "<src> <grp>/<mask> [table-id <n>]\n"                                 \
14802   "[<intfc> | sw_if_index <id>] [local] [del]")                         \
14803 _(mpls_table_add_del,                                                   \
14804   "table <n> [add | del]\n")                                            \
14805 _(mpls_route_add_del,                                                   \
14806   "<label> <eos> via <addr | next-hop-table <n> | via-label <n> |\n"    \
14807   "lookup-ip4-table <n> | lookup-in-ip6-table <n> |\n"                  \
14808   "l2-input-on <intfc> | l2-input-on sw_if_index <id>>\n"               \
14809   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>] [weight <n>]\n"  \
14810   "[drop] [local] [classify <n>] [out-label <n>] [multipath]\n"         \
14811   "[count <n>] [del]")                                                  \
14812 _(mpls_ip_bind_unbind,                                                  \
14813   "<label> <addr/len>")                                                 \
14814 _(mpls_tunnel_add_del,                                                  \
14815   "[add | del <intfc | sw_if_index <id>>] via <addr | via-label <n>>\n" \
14816   "[<intfc> | sw_if_index <id> | next-hop-table <id>]\n"                \
14817   "[l2-only]  [out-label <n>]")                                         \
14818 _(sr_mpls_policy_add,                                                   \
14819   "bsid <id> [weight <n>] [spray] next <sid> [next <sid>]")             \
14820 _(sr_mpls_policy_del,                                                   \
14821   "bsid <id>")                                                          \
14822 _(bier_table_add_del,                                                   \
14823   "<label> <sub-domain> <set> <bsl> [del]")                             \
14824 _(bier_route_add_del,                                                   \
14825   "<bit-position> <sub-domain> <set> <bsl> via <addr> [table-id <n>]\n" \
14826   "[<intfc> | sw_if_index <id>]"                                        \
14827   "[weight <n>] [del] [multipath]")                                     \
14828 _(sw_interface_set_unnumbered,                                          \
14829   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
14830 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
14831 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
14832   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
14833   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
14834   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
14835 _(ip_table_replace_begin, "table <n> [ipv6]")                           \
14836 _(ip_table_flush, "table <n> [ipv6]")                                   \
14837 _(ip_table_replace_end, "table <n> [ipv6]")                             \
14838 _(set_ip_flow_hash,                                                     \
14839   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
14840 _(sw_interface_ip6_enable_disable,                                      \
14841   "<intfc> | sw_if_index <id> enable | disable")                        \
14842 _(l2_patch_add_del,                                                     \
14843   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
14844   "enable | disable")                                                   \
14845 _(sr_localsid_add_del,                                                  \
14846   "(del) address <addr> next_hop <addr> behavior <beh>\n"               \
14847   "fib-table <num> (end.psp) sw_if_index <num>")                        \
14848 _(classify_add_del_table,                                               \
14849   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
14850   " [del] [del-chain] mask <mask-value>\n"                              \
14851   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
14852   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
14853 _(classify_add_del_session,                                             \
14854   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
14855   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
14856   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
14857   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
14858 _(classify_set_interface_ip_table,                                      \
14859   "<intfc> | sw_if_index <nn> table <nn>")                              \
14860 _(classify_set_interface_l2_tables,                                     \
14861   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
14862   "  [other-table <nn>]")                                               \
14863 _(get_node_index, "node <node-name")                                    \
14864 _(add_node_next, "node <node-name> next <next-node-name>")              \
14865 _(vxlan_offload_rx,                                                     \
14866   "hw { <interface name> | hw_if_index <nn>} "                          \
14867   "rx { <vxlan tunnel name> | sw_if_index <nn> } [del]")                \
14868 _(vxlan_add_del_tunnel,                                                 \
14869   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
14870   "{ <intfc> | mcast_sw_if_index <nn> } [instance <id>]}\n"             \
14871   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
14872 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
14873 _(l2_fib_clear_table, "")                                               \
14874 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
14875 _(l2_interface_vlan_tag_rewrite,                                        \
14876   "<intfc> | sw_if_index <nn> \n"                                       \
14877   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
14878   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
14879 _(create_vhost_user_if,                                                 \
14880         "socket <filename> [server] [renumber <dev_instance>] "         \
14881         "[disable_mrg_rxbuf] [disable_indirect_desc] [gso] "            \
14882         "[mac <mac_address>] [packed]")                                 \
14883 _(modify_vhost_user_if,                                                 \
14884         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
14885         "[server] [renumber <dev_instance>] [gso] [packed]")            \
14886 _(create_vhost_user_if_v2,                                              \
14887         "socket <filename> [server] [renumber <dev_instance>] "         \
14888         "[disable_mrg_rxbuf] [disable_indirect_desc] [gso] "            \
14889         "[mac <mac_address>] [packed] [event-idx]")                     \
14890 _(modify_vhost_user_if_v2,                                              \
14891         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
14892         "[server] [renumber <dev_instance>] [gso] [packed] [event-idx]")\
14893 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
14894 _(sw_interface_vhost_user_dump, "<intfc> | sw_if_index <nn>")           \
14895 _(show_version, "")                                                     \
14896 _(show_threads, "")                                                     \
14897 _(vxlan_gpe_add_del_tunnel,                                             \
14898   "local <addr> remote <addr>  | group <mcast-ip-addr>\n"               \
14899   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
14900   "vni <nn> [encap-vrf-id <nn>] [decap-vrf-id <nn>]\n"                  \
14901   "[next-ip4][next-ip6][next-ethernet] [next-nsh] [del]\n")             \
14902 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
14903 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
14904 _(interface_name_renumber,                                              \
14905   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
14906 _(input_acl_set_interface,                                              \
14907   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
14908   "  [l2-table <nn>] [del]")                                            \
14909 _(want_l2_macs_events, "[disable] [learn-limit <n>] [scan-delay <n>] [max-entries <n>]") \
14910 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
14911 _(ip_dump, "ipv4 | ipv6")                                               \
14912 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
14913 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
14914   "  spid_id <n> ")                                                     \
14915 _(ipsec_sad_entry_add_del, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
14916   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
14917   "  integ_alg <alg> integ_key <hex>")                                  \
14918 _(ipsec_spd_entry_add_del, "spd_id <n> priority <n> action <action>\n"  \
14919   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
14920   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
14921   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
14922 _(ipsec_sa_dump, "[sa_id <n>]")                                         \
14923 _(delete_loopback,"sw_if_index <nn>")                                   \
14924 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
14925 _(bd_ip_mac_flush, "bd_id <bridge-domain-id>")                          \
14926 _(bd_ip_mac_dump, "[bd_id] <bridge-domain-id>")                         \
14927 _(want_interface_events,  "enable|disable")                             \
14928 _(get_first_msg_id, "client <name>")                                    \
14929 _(get_node_graph, " ")                                                  \
14930 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
14931 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
14932 _(ioam_disable, "")                                                     \
14933 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
14934 _(af_packet_delete, "name <host interface name>")                       \
14935 _(af_packet_dump, "")                                                   \
14936 _(policer_add_del, "name <policer name> <params> [del]")                \
14937 _(policer_dump, "[name <policer name>]")                                \
14938 _(policer_classify_set_interface,                                       \
14939   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
14940   "  [l2-table <nn>] [del]")                                            \
14941 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
14942 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
14943 _(mpls_table_dump, "")                                                  \
14944 _(mpls_route_dump, "table-id <ID>")                                     \
14945 _(classify_table_ids, "")                                               \
14946 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
14947 _(classify_table_info, "table_id <nn>")                                 \
14948 _(classify_session_dump, "table_id <nn>")                               \
14949 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
14950     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
14951     "[template_interval <nn>] [udp_checksum]")                          \
14952 _(ipfix_exporter_dump, "")                                              \
14953 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
14954 _(ipfix_classify_stream_dump, "")                                       \
14955 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
14956 _(ipfix_classify_table_dump, "")                                        \
14957 _(sw_interface_span_enable_disable, "[l2] [src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
14958 _(sw_interface_span_dump, "[l2]")                                           \
14959 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
14960 _(pg_create_interface, "if_id <nn> [gso-enabled gso-size <size>]")      \
14961 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
14962 _(pg_enable_disable, "[stream <id>] disable")                           \
14963 _(pg_interface_enable_disable_coalesce, "<intf> | sw_if_index <nn> enable | disable")  \
14964 _(ip_source_and_port_range_check_add_del,                               \
14965   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
14966 _(ip_source_and_port_range_check_interface_add_del,                     \
14967   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
14968   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
14969 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
14970 _(l2_interface_pbb_tag_rewrite,                                         \
14971   "<intfc> | sw_if_index <nn> \n"                                       \
14972   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
14973   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
14974 _(set_punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
14975 _(flow_classify_set_interface,                                          \
14976   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
14977 _(flow_classify_dump, "type [ip4|ip6]")                                 \
14978 _(ip_table_dump, "")                                                    \
14979 _(ip_route_dump, "table-id [ip4|ip6]")                                  \
14980 _(ip_mtable_dump, "")                                                   \
14981 _(ip_mroute_dump, "table-id [ip4|ip6]")                                 \
14982 _(feature_enable_disable, "arc_name <arc_name> "                        \
14983   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
14984 _(feature_gso_enable_disable, "<intfc> | sw_if_index <nn> "             \
14985   "[enable | disable] ")                                                \
14986 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
14987 "[disable]")                                                            \
14988 _(sw_interface_add_del_mac_address, "<intfc> | sw_if_index <nn> "       \
14989   "mac <mac-address> [del]")                                            \
14990 _(l2_xconnect_dump, "")                                                 \
14991 _(hw_interface_set_mtu, "<intfc> | hw_if_index <nn> mtu <nn>")        \
14992 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")          \
14993 _(p2p_ethernet_add, "<intfc> | sw_if_index <nn> remote_mac <mac-address> sub_id <id>") \
14994 _(p2p_ethernet_del, "<intfc> | sw_if_index <nn> remote_mac <mac-address>") \
14995 _(tcp_configure_src_addresses, "<ip4|6>first-<ip4|6>last [vrf <id>]")   \
14996 _(sock_init_shm, "size <nnn>")                                          \
14997 _(app_namespace_add_del, "[add] id <ns-id> secret <nn> sw_if_index <nn>")\
14998 _(session_rule_add_del, "[add|del] proto <tcp/udp> <lcl-ip>/<plen> "    \
14999   "<lcl-port> <rmt-ip>/<plen> <rmt-port> action <nn>")                  \
15000 _(session_rules_dump, "")                                               \
15001 _(ip_container_proxy_add_del, "[add|del] <address> <sw_if_index>")      \
15002 _(output_acl_set_interface,                                             \
15003   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
15004   "  [l2-table <nn>] [del]")                                            \
15005 _(qos_record_enable_disable, "<record-source> <intfc> | sw_if_index <id> [disable]")
15006
15007 /* List of command functions, CLI names map directly to functions */
15008 #define foreach_cli_function                                    \
15009 _(comment, "usage: comment <ignore-rest-of-line>")              \
15010 _(dump_interface_table, "usage: dump_interface_table")          \
15011 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
15012 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
15013 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
15014 _(dump_macro_table, "usage: dump_macro_table ")                 \
15015 _(dump_node_table, "usage: dump_node_table")                    \
15016 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
15017 _(elog_setup, "usage: elog_setup [nevents, default 128K]")      \
15018 _(elog_disable, "usage: elog_disable")                          \
15019 _(elog_enable, "usage: elog_enable")                            \
15020 _(elog_save, "usage: elog_save <filename>")                     \
15021 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
15022 _(echo, "usage: echo <message>")                                \
15023 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
15024 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
15025 _(help, "usage: help")                                          \
15026 _(q, "usage: quit")                                             \
15027 _(quit, "usage: quit")                                          \
15028 _(search_node_table, "usage: search_node_table <name>...")      \
15029 _(set, "usage: set <variable-name> <value>")                    \
15030 _(script, "usage: script <file-name>")                          \
15031 _(statseg, "usage: statseg")                                    \
15032 _(unset, "usage: unset <variable-name>")
15033
15034 #define _(N,n)                                  \
15035     static void vl_api_##n##_t_handler_uni      \
15036     (vl_api_##n##_t * mp)                       \
15037     {                                           \
15038         vat_main_t * vam = &vat_main;           \
15039         if (vam->json_output) {                 \
15040             vl_api_##n##_t_handler_json(mp);    \
15041         } else {                                \
15042             vl_api_##n##_t_handler(mp);         \
15043         }                                       \
15044     }
15045 foreach_vpe_api_reply_msg;
15046 #if VPP_API_TEST_BUILTIN == 0
15047 foreach_standalone_reply_msg;
15048 #endif
15049 #undef _
15050
15051 void
15052 vat_api_hookup (vat_main_t * vam)
15053 {
15054 #define _(N,n)                                                  \
15055     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
15056                            vl_api_##n##_t_handler_uni,          \
15057                            vl_noop_handler,                     \
15058                            vl_api_##n##_t_endian,               \
15059                            vl_api_##n##_t_print,                \
15060                            sizeof(vl_api_##n##_t), 1);
15061   foreach_vpe_api_reply_msg;
15062 #if VPP_API_TEST_BUILTIN == 0
15063   foreach_standalone_reply_msg;
15064 #endif
15065 #undef _
15066
15067 #if (VPP_API_TEST_BUILTIN==0)
15068   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
15069
15070   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
15071
15072   vam->function_by_name = hash_create_string (0, sizeof (uword));
15073
15074   vam->help_by_name = hash_create_string (0, sizeof (uword));
15075 #endif
15076
15077   /* API messages we can send */
15078 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
15079   foreach_vpe_api_msg;
15080 #undef _
15081
15082   /* Help strings */
15083 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
15084   foreach_vpe_api_msg;
15085 #undef _
15086
15087   /* CLI functions */
15088 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
15089   foreach_cli_function;
15090 #undef _
15091
15092   /* Help strings */
15093 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
15094   foreach_cli_function;
15095 #undef _
15096 }
15097
15098 #if VPP_API_TEST_BUILTIN
15099 static clib_error_t *
15100 vat_api_hookup_shim (vlib_main_t * vm)
15101 {
15102   vat_api_hookup (&vat_main);
15103   return 0;
15104 }
15105
15106 VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
15107 #endif
15108
15109 /*
15110  * fd.io coding-style-patch-verification: ON
15111  *
15112  * Local Variables:
15113  * eval: (c-set-style "gnu")
15114  * End:
15115  */