tap: fix the default parameter for num_rx_queues
[vpp.git] / src / vat / api_format.c
1 /*
2  *------------------------------------------------------------------
3  * api_format.c
4  *
5  * Copyright (c) 2014-2016 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/l2tp/l2tp.h>
31 #include <vnet/vxlan/vxlan.h>
32 #include <vnet/geneve/geneve.h>
33 #include <vnet/gre/gre.h>
34 #include <vnet/vxlan-gpe/vxlan_gpe.h>
35 #include <vnet/lisp-gpe/lisp_gpe.h>
36
37 #include <vpp/api/vpe_msg_enum.h>
38 #include <vnet/l2/l2_classify.h>
39 #include <vnet/l2/l2_vtr.h>
40 #include <vnet/classify/in_out_acl.h>
41 #include <vnet/classify/policer_classify.h>
42 #include <vnet/classify/flow_classify.h>
43 #include <vnet/mpls/mpls.h>
44 #include <vnet/ipsec/ipsec.h>
45 #include <inttypes.h>
46 #include <vnet/cop/cop.h>
47 #include <vnet/ip/ip6_hop_by_hop.h>
48 #include <vnet/ip/ip_source_and_port_range_check.h>
49 #include <vnet/policer/xlate.h>
50 #include <vnet/span/span.h>
51 #include <vnet/policer/policer.h>
52 #include <vnet/policer/police.h>
53 #include <vnet/mfib/mfib_types.h>
54 #include <vnet/bonding/node.h>
55 #include <vnet/qos/qos_types.h>
56 #include <vnet/ethernet/ethernet_types_api.h>
57 #include <vnet/ip/ip_types_api.h>
58 #include "vat/json_format.h"
59 #include <vnet/ip/ip_types_api.h>
60 #include <vnet/ethernet/ethernet_types_api.h>
61
62 #include <inttypes.h>
63 #include <sys/stat.h>
64
65 #define vl_typedefs             /* define message structures */
66 #include <vpp/api/vpe_all_api_h.h>
67 #undef vl_typedefs
68
69 /* declare message handlers for each api */
70
71 #define vl_endianfun            /* define message structures */
72 #include <vpp/api/vpe_all_api_h.h>
73 #undef vl_endianfun
74
75 /* instantiate all the print functions we know about */
76 #if VPP_API_TEST_BUILTIN == 0
77 #define vl_print(handle, ...)
78 #else
79 #define vl_print(handle, ...) vlib_cli_output (handle, __VA_ARGS__)
80 #endif
81 #define vl_printfun
82 #include <vpp/api/vpe_all_api_h.h>
83 #undef vl_printfun
84
85 #define __plugin_msg_base 0
86 #include <vlibapi/vat_helper_macros.h>
87
88 #include <vnet/format_fns.h>
89
90 void vl_api_set_elog_main (elog_main_t * m);
91 int vl_api_set_elog_trace_api_messages (int enable);
92
93 #if VPP_API_TEST_BUILTIN == 0
94 #include <netdb.h>
95
96 u32
97 vl (void *p)
98 {
99   return vec_len (p);
100 }
101
102 int
103 vat_socket_connect (vat_main_t * vam)
104 {
105   int rv;
106   vam->socket_client_main = &socket_client_main;
107   if ((rv = vl_socket_client_connect ((char *) vam->socket_name,
108                                       "vpp_api_test",
109                                       0 /* default socket rx, tx buffer */ )))
110     return rv;
111   /* vpp expects the client index in network order */
112   vam->my_client_index = htonl (socket_client_main.client_index);
113   return 0;
114 }
115 #else /* vpp built-in case, we don't do sockets... */
116 int
117 vat_socket_connect (vat_main_t * vam)
118 {
119   return 0;
120 }
121
122 int
123 vl_socket_client_read (int wait)
124 {
125   return -1;
126 };
127
128 int
129 vl_socket_client_write ()
130 {
131   return -1;
132 };
133
134 void *
135 vl_socket_client_msg_alloc (int nbytes)
136 {
137   return 0;
138 }
139 #endif
140
141
142 f64
143 vat_time_now (vat_main_t * vam)
144 {
145 #if VPP_API_TEST_BUILTIN
146   return vlib_time_now (vam->vlib_main);
147 #else
148   return clib_time_now (&vam->clib_time);
149 #endif
150 }
151
152 void
153 errmsg (char *fmt, ...)
154 {
155   vat_main_t *vam = &vat_main;
156   va_list va;
157   u8 *s;
158
159   va_start (va, fmt);
160   s = va_format (0, fmt, &va);
161   va_end (va);
162
163   vec_add1 (s, 0);
164
165 #if VPP_API_TEST_BUILTIN
166   vlib_cli_output (vam->vlib_main, (char *) s);
167 #else
168   {
169     if (vam->ifp != stdin)
170       fformat (vam->ofp, "%s(%d): \n", vam->current_file,
171                vam->input_line_number);
172     else
173       fformat (vam->ofp, "%s\n", (char *) s);
174     fflush (vam->ofp);
175   }
176 #endif
177
178   vec_free (s);
179 }
180
181 #if VPP_API_TEST_BUILTIN == 0
182 static uword
183 api_unformat_sw_if_index (unformat_input_t * input, va_list * args)
184 {
185   vat_main_t *vam = va_arg (*args, vat_main_t *);
186   u32 *result = va_arg (*args, u32 *);
187   u8 *if_name;
188   uword *p;
189
190   if (!unformat (input, "%s", &if_name))
191     return 0;
192
193   p = hash_get_mem (vam->sw_if_index_by_interface_name, if_name);
194   if (p == 0)
195     return 0;
196   *result = p[0];
197   return 1;
198 }
199
200 static uword
201 api_unformat_hw_if_index (unformat_input_t * input, va_list * args)
202 {
203   return 0;
204 }
205
206 /* Parse an IP4 address %d.%d.%d.%d. */
207 uword
208 unformat_ip4_address (unformat_input_t * input, va_list * args)
209 {
210   u8 *result = va_arg (*args, u8 *);
211   unsigned a[4];
212
213   if (!unformat (input, "%d.%d.%d.%d", &a[0], &a[1], &a[2], &a[3]))
214     return 0;
215
216   if (a[0] >= 256 || a[1] >= 256 || a[2] >= 256 || a[3] >= 256)
217     return 0;
218
219   result[0] = a[0];
220   result[1] = a[1];
221   result[2] = a[2];
222   result[3] = a[3];
223
224   return 1;
225 }
226
227 uword
228 unformat_ethernet_address (unformat_input_t * input, va_list * args)
229 {
230   u8 *result = va_arg (*args, u8 *);
231   u32 i, a[6];
232
233   if (!unformat (input, "%_%x:%x:%x:%x:%x:%x%_",
234                  &a[0], &a[1], &a[2], &a[3], &a[4], &a[5]))
235     return 0;
236
237   /* Check range. */
238   for (i = 0; i < 6; i++)
239     if (a[i] >= (1 << 8))
240       return 0;
241
242   for (i = 0; i < 6; i++)
243     result[i] = a[i];
244
245   return 1;
246 }
247
248 /* Returns ethernet type as an int in host byte order. */
249 uword
250 unformat_ethernet_type_host_byte_order (unformat_input_t * input,
251                                         va_list * args)
252 {
253   u16 *result = va_arg (*args, u16 *);
254   int type;
255
256   /* Numeric type. */
257   if (unformat (input, "0x%x", &type) || unformat (input, "%d", &type))
258     {
259       if (type >= (1 << 16))
260         return 0;
261       *result = type;
262       return 1;
263     }
264   return 0;
265 }
266
267 /* Parse an IP6 address. */
268 uword
269 unformat_ip6_address (unformat_input_t * input, va_list * args)
270 {
271   ip6_address_t *result = va_arg (*args, ip6_address_t *);
272   u16 hex_quads[8];
273   uword hex_quad, n_hex_quads, hex_digit, n_hex_digits;
274   uword c, n_colon, double_colon_index;
275
276   n_hex_quads = hex_quad = n_hex_digits = n_colon = 0;
277   double_colon_index = ARRAY_LEN (hex_quads);
278   while ((c = unformat_get_input (input)) != UNFORMAT_END_OF_INPUT)
279     {
280       hex_digit = 16;
281       if (c >= '0' && c <= '9')
282         hex_digit = c - '0';
283       else if (c >= 'a' && c <= 'f')
284         hex_digit = c + 10 - 'a';
285       else if (c >= 'A' && c <= 'F')
286         hex_digit = c + 10 - 'A';
287       else if (c == ':' && n_colon < 2)
288         n_colon++;
289       else
290         {
291           unformat_put_input (input);
292           break;
293         }
294
295       /* Too many hex quads. */
296       if (n_hex_quads >= ARRAY_LEN (hex_quads))
297         return 0;
298
299       if (hex_digit < 16)
300         {
301           hex_quad = (hex_quad << 4) | hex_digit;
302
303           /* Hex quad must fit in 16 bits. */
304           if (n_hex_digits >= 4)
305             return 0;
306
307           n_colon = 0;
308           n_hex_digits++;
309         }
310
311       /* Save position of :: */
312       if (n_colon == 2)
313         {
314           /* More than one :: ? */
315           if (double_colon_index < ARRAY_LEN (hex_quads))
316             return 0;
317           double_colon_index = n_hex_quads;
318         }
319
320       if (n_colon > 0 && n_hex_digits > 0)
321         {
322           hex_quads[n_hex_quads++] = hex_quad;
323           hex_quad = 0;
324           n_hex_digits = 0;
325         }
326     }
327
328   if (n_hex_digits > 0)
329     hex_quads[n_hex_quads++] = hex_quad;
330
331   {
332     word i;
333
334     /* Expand :: to appropriate number of zero hex quads. */
335     if (double_colon_index < ARRAY_LEN (hex_quads))
336       {
337         word n_zero = ARRAY_LEN (hex_quads) - n_hex_quads;
338
339         for (i = n_hex_quads - 1; i >= (signed) double_colon_index; i--)
340           hex_quads[n_zero + i] = hex_quads[i];
341
342         for (i = 0; i < n_zero; i++)
343           hex_quads[double_colon_index + i] = 0;
344
345         n_hex_quads = ARRAY_LEN (hex_quads);
346       }
347
348     /* Too few hex quads given. */
349     if (n_hex_quads < ARRAY_LEN (hex_quads))
350       return 0;
351
352     for (i = 0; i < ARRAY_LEN (hex_quads); i++)
353       result->as_u16[i] = clib_host_to_net_u16 (hex_quads[i]);
354
355     return 1;
356   }
357 }
358
359 uword
360 unformat_ipsec_policy_action (unformat_input_t * input, va_list * args)
361 {
362   u32 *r = va_arg (*args, u32 *);
363
364   if (0);
365 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_POLICY_ACTION_##f;
366   foreach_ipsec_policy_action
367 #undef _
368     else
369     return 0;
370   return 1;
371 }
372
373 u8 *
374 format_ipsec_crypto_alg (u8 * s, va_list * args)
375 {
376   u32 i = va_arg (*args, u32);
377   u8 *t = 0;
378
379   switch (i)
380     {
381 #define _(v,f,str) case IPSEC_CRYPTO_ALG_##f: t = (u8 *) str; break;
382       foreach_ipsec_crypto_alg
383 #undef _
384     default:
385       return format (s, "unknown");
386     }
387   return format (s, "%s", t);
388 }
389
390 u8 *
391 format_ipsec_integ_alg (u8 * s, va_list * args)
392 {
393   u32 i = va_arg (*args, u32);
394   u8 *t = 0;
395
396   switch (i)
397     {
398 #define _(v,f,str) case IPSEC_INTEG_ALG_##f: t = (u8 *) str; break;
399       foreach_ipsec_integ_alg
400 #undef _
401     default:
402       return format (s, "unknown");
403     }
404   return format (s, "%s", t);
405 }
406
407 #else /* VPP_API_TEST_BUILTIN == 1 */
408 static uword
409 api_unformat_sw_if_index (unformat_input_t * input, va_list * args)
410 {
411   vat_main_t *vam __clib_unused = va_arg (*args, vat_main_t *);
412   vnet_main_t *vnm = vnet_get_main ();
413   u32 *result = va_arg (*args, u32 *);
414
415   return unformat (input, "%U", unformat_vnet_sw_interface, vnm, result);
416 }
417
418 static uword
419 api_unformat_hw_if_index (unformat_input_t * input, va_list * args)
420 {
421   vat_main_t *vam __clib_unused = va_arg (*args, vat_main_t *);
422   vnet_main_t *vnm = vnet_get_main ();
423   u32 *result = va_arg (*args, u32 *);
424
425   return unformat (input, "%U", unformat_vnet_hw_interface, vnm, result);
426 }
427
428 #endif /* VPP_API_TEST_BUILTIN */
429
430 uword
431 unformat_ipsec_api_crypto_alg (unformat_input_t * input, va_list * args)
432 {
433   u32 *r = va_arg (*args, u32 *);
434
435   if (0);
436 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_API_CRYPTO_ALG_##f;
437   foreach_ipsec_crypto_alg
438 #undef _
439     else
440     return 0;
441   return 1;
442 }
443
444 uword
445 unformat_ipsec_api_integ_alg (unformat_input_t * input, va_list * args)
446 {
447   u32 *r = va_arg (*args, u32 *);
448
449   if (0);
450 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_API_INTEG_ALG_##f;
451   foreach_ipsec_integ_alg
452 #undef _
453     else
454     return 0;
455   return 1;
456 }
457
458 static uword
459 unformat_policer_rate_type (unformat_input_t * input, va_list * args)
460 {
461   u8 *r = va_arg (*args, u8 *);
462
463   if (unformat (input, "kbps"))
464     *r = SSE2_QOS_RATE_KBPS;
465   else if (unformat (input, "pps"))
466     *r = SSE2_QOS_RATE_PPS;
467   else
468     return 0;
469   return 1;
470 }
471
472 static uword
473 unformat_policer_round_type (unformat_input_t * input, va_list * args)
474 {
475   u8 *r = va_arg (*args, u8 *);
476
477   if (unformat (input, "closest"))
478     *r = SSE2_QOS_ROUND_TO_CLOSEST;
479   else if (unformat (input, "up"))
480     *r = SSE2_QOS_ROUND_TO_UP;
481   else if (unformat (input, "down"))
482     *r = SSE2_QOS_ROUND_TO_DOWN;
483   else
484     return 0;
485   return 1;
486 }
487
488 static uword
489 unformat_policer_type (unformat_input_t * input, va_list * args)
490 {
491   u8 *r = va_arg (*args, u8 *);
492
493   if (unformat (input, "1r2c"))
494     *r = SSE2_QOS_POLICER_TYPE_1R2C;
495   else if (unformat (input, "1r3c"))
496     *r = SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697;
497   else if (unformat (input, "2r3c-2698"))
498     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698;
499   else if (unformat (input, "2r3c-4115"))
500     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115;
501   else if (unformat (input, "2r3c-mef5cf1"))
502     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1;
503   else
504     return 0;
505   return 1;
506 }
507
508 static uword
509 unformat_dscp (unformat_input_t * input, va_list * va)
510 {
511   u8 *r = va_arg (*va, u8 *);
512
513   if (0);
514 #define _(v,f,str) else if (unformat (input, str)) *r = VNET_DSCP_##f;
515   foreach_vnet_dscp
516 #undef _
517     else
518     return 0;
519   return 1;
520 }
521
522 static uword
523 unformat_policer_action_type (unformat_input_t * input, va_list * va)
524 {
525   sse2_qos_pol_action_params_st *a
526     = va_arg (*va, sse2_qos_pol_action_params_st *);
527
528   if (unformat (input, "drop"))
529     a->action_type = SSE2_QOS_ACTION_DROP;
530   else if (unformat (input, "transmit"))
531     a->action_type = SSE2_QOS_ACTION_TRANSMIT;
532   else if (unformat (input, "mark-and-transmit %U", unformat_dscp, &a->dscp))
533     a->action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
534   else
535     return 0;
536   return 1;
537 }
538
539 static uword
540 unformat_policer_classify_table_type (unformat_input_t * input, va_list * va)
541 {
542   u32 *r = va_arg (*va, u32 *);
543   u32 tid;
544
545   if (unformat (input, "ip4"))
546     tid = POLICER_CLASSIFY_TABLE_IP4;
547   else if (unformat (input, "ip6"))
548     tid = POLICER_CLASSIFY_TABLE_IP6;
549   else if (unformat (input, "l2"))
550     tid = POLICER_CLASSIFY_TABLE_L2;
551   else
552     return 0;
553
554   *r = tid;
555   return 1;
556 }
557
558 static uword
559 unformat_flow_classify_table_type (unformat_input_t * input, va_list * va)
560 {
561   u32 *r = va_arg (*va, u32 *);
562   u32 tid;
563
564   if (unformat (input, "ip4"))
565     tid = FLOW_CLASSIFY_TABLE_IP4;
566   else if (unformat (input, "ip6"))
567     tid = FLOW_CLASSIFY_TABLE_IP6;
568   else
569     return 0;
570
571   *r = tid;
572   return 1;
573 }
574
575 #if (VPP_API_TEST_BUILTIN==0)
576
577 static const char *mfib_flag_names[] = MFIB_ENTRY_NAMES_SHORT;
578 static const char *mfib_flag_long_names[] = MFIB_ENTRY_NAMES_LONG;
579 static const char *mfib_itf_flag_long_names[] = MFIB_ITF_NAMES_LONG;
580 static const char *mfib_itf_flag_names[] = MFIB_ITF_NAMES_SHORT;
581
582 uword
583 unformat_mfib_itf_flags (unformat_input_t * input, va_list * args)
584 {
585   mfib_itf_flags_t old, *iflags = va_arg (*args, mfib_itf_flags_t *);
586   mfib_itf_attribute_t attr;
587
588   old = *iflags;
589   FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
590   {
591     if (unformat (input, mfib_itf_flag_long_names[attr]))
592       *iflags |= (1 << attr);
593   }
594   FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
595   {
596     if (unformat (input, mfib_itf_flag_names[attr]))
597       *iflags |= (1 << attr);
598   }
599
600   return (old == *iflags ? 0 : 1);
601 }
602
603 uword
604 unformat_mfib_entry_flags (unformat_input_t * input, va_list * args)
605 {
606   mfib_entry_flags_t old, *eflags = va_arg (*args, mfib_entry_flags_t *);
607   mfib_entry_attribute_t attr;
608
609   old = *eflags;
610   FOR_EACH_MFIB_ATTRIBUTE (attr)
611   {
612     if (unformat (input, mfib_flag_long_names[attr]))
613       *eflags |= (1 << attr);
614   }
615   FOR_EACH_MFIB_ATTRIBUTE (attr)
616   {
617     if (unformat (input, mfib_flag_names[attr]))
618       *eflags |= (1 << attr);
619   }
620
621   return (old == *eflags ? 0 : 1);
622 }
623
624 u8 *
625 format_ip4_address (u8 * s, va_list * args)
626 {
627   u8 *a = va_arg (*args, u8 *);
628   return format (s, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]);
629 }
630
631 u8 *
632 format_ip6_address (u8 * s, va_list * args)
633 {
634   ip6_address_t *a = va_arg (*args, ip6_address_t *);
635   u32 i, i_max_n_zero, max_n_zeros, i_first_zero, n_zeros, last_double_colon;
636
637   i_max_n_zero = ARRAY_LEN (a->as_u16);
638   max_n_zeros = 0;
639   i_first_zero = i_max_n_zero;
640   n_zeros = 0;
641   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
642     {
643       u32 is_zero = a->as_u16[i] == 0;
644       if (is_zero && i_first_zero >= ARRAY_LEN (a->as_u16))
645         {
646           i_first_zero = i;
647           n_zeros = 0;
648         }
649       n_zeros += is_zero;
650       if ((!is_zero && n_zeros > max_n_zeros)
651           || (i + 1 >= ARRAY_LEN (a->as_u16) && n_zeros > max_n_zeros))
652         {
653           i_max_n_zero = i_first_zero;
654           max_n_zeros = n_zeros;
655           i_first_zero = ARRAY_LEN (a->as_u16);
656           n_zeros = 0;
657         }
658     }
659
660   last_double_colon = 0;
661   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
662     {
663       if (i == i_max_n_zero && max_n_zeros > 1)
664         {
665           s = format (s, "::");
666           i += max_n_zeros - 1;
667           last_double_colon = 1;
668         }
669       else
670         {
671           s = format (s, "%s%x",
672                       (last_double_colon || i == 0) ? "" : ":",
673                       clib_net_to_host_u16 (a->as_u16[i]));
674           last_double_colon = 0;
675         }
676     }
677
678   return s;
679 }
680
681 /* Format an IP46 address. */
682 u8 *
683 format_ip46_address (u8 * s, va_list * args)
684 {
685   ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
686   ip46_type_t type = va_arg (*args, ip46_type_t);
687   int is_ip4 = 1;
688
689   switch (type)
690     {
691     case IP46_TYPE_ANY:
692       is_ip4 = ip46_address_is_ip4 (ip46);
693       break;
694     case IP46_TYPE_IP4:
695       is_ip4 = 1;
696       break;
697     case IP46_TYPE_IP6:
698       is_ip4 = 0;
699       break;
700     }
701
702   return is_ip4 ?
703     format (s, "%U", format_ip4_address, &ip46->ip4) :
704     format (s, "%U", format_ip6_address, &ip46->ip6);
705 }
706
707 u8 *
708 format_ethernet_address (u8 * s, va_list * args)
709 {
710   u8 *a = va_arg (*args, u8 *);
711
712   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
713                  a[0], a[1], a[2], a[3], a[4], a[5]);
714 }
715 #endif
716
717 static void
718 increment_v4_address (vl_api_ip4_address_t * i)
719 {
720   ip4_address_t *a = (ip4_address_t *) i;
721   u32 v;
722
723   v = ntohl (a->as_u32) + 1;
724   a->as_u32 = ntohl (v);
725 }
726
727 static void
728 increment_v6_address (vl_api_ip6_address_t * i)
729 {
730   ip6_address_t *a = (ip6_address_t *) i;
731   u64 v0, v1;
732
733   v0 = clib_net_to_host_u64 (a->as_u64[0]);
734   v1 = clib_net_to_host_u64 (a->as_u64[1]);
735
736   v1 += 1;
737   if (v1 == 0)
738     v0 += 1;
739   a->as_u64[0] = clib_net_to_host_u64 (v0);
740   a->as_u64[1] = clib_net_to_host_u64 (v1);
741 }
742
743 static void
744 increment_address (vl_api_address_t * a)
745 {
746   if (clib_net_to_host_u32 (a->af) == ADDRESS_IP4)
747     increment_v4_address (&a->un.ip4);
748   else if (clib_net_to_host_u32 (a->af) == ADDRESS_IP6)
749     increment_v6_address (&a->un.ip6);
750 }
751
752 static void
753 set_ip4_address (vl_api_address_t * a, u32 v)
754 {
755   if (a->af == ADDRESS_IP4)
756     {
757       ip4_address_t *i = (ip4_address_t *) & a->un.ip4;
758       i->as_u32 = v;
759     }
760 }
761
762 static void
763 increment_mac_address (u8 * mac)
764 {
765   u64 tmp = *((u64 *) mac);
766   tmp = clib_net_to_host_u64 (tmp);
767   tmp += 1 << 16;               /* skip unused (least significant) octets */
768   tmp = clib_host_to_net_u64 (tmp);
769
770   clib_memcpy (mac, &tmp, 6);
771 }
772
773 static void
774 vat_json_object_add_address (vat_json_node_t * node,
775                              const char *str, const vl_api_address_t * addr)
776 {
777   if (ADDRESS_IP6 == addr->af)
778     {
779       struct in6_addr ip6;
780
781       clib_memcpy (&ip6, &addr->un.ip6, sizeof (ip6));
782       vat_json_object_add_ip6 (node, str, ip6);
783     }
784   else
785     {
786       struct in_addr ip4;
787
788       clib_memcpy (&ip4, &addr->un.ip4, sizeof (ip4));
789       vat_json_object_add_ip4 (node, str, ip4);
790     }
791 }
792
793 static void
794 vat_json_object_add_prefix (vat_json_node_t * node,
795                             const vl_api_prefix_t * prefix)
796 {
797   vat_json_object_add_uint (node, "len", prefix->len);
798   vat_json_object_add_address (node, "address", &prefix->address);
799 }
800
801 static void vl_api_create_loopback_reply_t_handler
802   (vl_api_create_loopback_reply_t * mp)
803 {
804   vat_main_t *vam = &vat_main;
805   i32 retval = ntohl (mp->retval);
806
807   vam->retval = retval;
808   vam->regenerate_interface_table = 1;
809   vam->sw_if_index = ntohl (mp->sw_if_index);
810   vam->result_ready = 1;
811 }
812
813 static void vl_api_create_loopback_reply_t_handler_json
814   (vl_api_create_loopback_reply_t * mp)
815 {
816   vat_main_t *vam = &vat_main;
817   vat_json_node_t node;
818
819   vat_json_init_object (&node);
820   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
821   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
822
823   vat_json_print (vam->ofp, &node);
824   vat_json_free (&node);
825   vam->retval = ntohl (mp->retval);
826   vam->result_ready = 1;
827 }
828
829 static void vl_api_create_loopback_instance_reply_t_handler
830   (vl_api_create_loopback_instance_reply_t * mp)
831 {
832   vat_main_t *vam = &vat_main;
833   i32 retval = ntohl (mp->retval);
834
835   vam->retval = retval;
836   vam->regenerate_interface_table = 1;
837   vam->sw_if_index = ntohl (mp->sw_if_index);
838   vam->result_ready = 1;
839 }
840
841 static void vl_api_create_loopback_instance_reply_t_handler_json
842   (vl_api_create_loopback_instance_reply_t * mp)
843 {
844   vat_main_t *vam = &vat_main;
845   vat_json_node_t node;
846
847   vat_json_init_object (&node);
848   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
849   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
850
851   vat_json_print (vam->ofp, &node);
852   vat_json_free (&node);
853   vam->retval = ntohl (mp->retval);
854   vam->result_ready = 1;
855 }
856
857 static void vl_api_af_packet_create_reply_t_handler
858   (vl_api_af_packet_create_reply_t * mp)
859 {
860   vat_main_t *vam = &vat_main;
861   i32 retval = ntohl (mp->retval);
862
863   vam->retval = retval;
864   vam->regenerate_interface_table = 1;
865   vam->sw_if_index = ntohl (mp->sw_if_index);
866   vam->result_ready = 1;
867 }
868
869 static void vl_api_af_packet_create_reply_t_handler_json
870   (vl_api_af_packet_create_reply_t * mp)
871 {
872   vat_main_t *vam = &vat_main;
873   vat_json_node_t node;
874
875   vat_json_init_object (&node);
876   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
877   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
878
879   vat_json_print (vam->ofp, &node);
880   vat_json_free (&node);
881
882   vam->retval = ntohl (mp->retval);
883   vam->result_ready = 1;
884 }
885
886 static void vl_api_create_vlan_subif_reply_t_handler
887   (vl_api_create_vlan_subif_reply_t * mp)
888 {
889   vat_main_t *vam = &vat_main;
890   i32 retval = ntohl (mp->retval);
891
892   vam->retval = retval;
893   vam->regenerate_interface_table = 1;
894   vam->sw_if_index = ntohl (mp->sw_if_index);
895   vam->result_ready = 1;
896 }
897
898 static void vl_api_create_vlan_subif_reply_t_handler_json
899   (vl_api_create_vlan_subif_reply_t * mp)
900 {
901   vat_main_t *vam = &vat_main;
902   vat_json_node_t node;
903
904   vat_json_init_object (&node);
905   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
906   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
907
908   vat_json_print (vam->ofp, &node);
909   vat_json_free (&node);
910
911   vam->retval = ntohl (mp->retval);
912   vam->result_ready = 1;
913 }
914
915 static void vl_api_create_subif_reply_t_handler
916   (vl_api_create_subif_reply_t * mp)
917 {
918   vat_main_t *vam = &vat_main;
919   i32 retval = ntohl (mp->retval);
920
921   vam->retval = retval;
922   vam->regenerate_interface_table = 1;
923   vam->sw_if_index = ntohl (mp->sw_if_index);
924   vam->result_ready = 1;
925 }
926
927 static void vl_api_create_subif_reply_t_handler_json
928   (vl_api_create_subif_reply_t * mp)
929 {
930   vat_main_t *vam = &vat_main;
931   vat_json_node_t node;
932
933   vat_json_init_object (&node);
934   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
935   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
936
937   vat_json_print (vam->ofp, &node);
938   vat_json_free (&node);
939
940   vam->retval = ntohl (mp->retval);
941   vam->result_ready = 1;
942 }
943
944 static void vl_api_interface_name_renumber_reply_t_handler
945   (vl_api_interface_name_renumber_reply_t * mp)
946 {
947   vat_main_t *vam = &vat_main;
948   i32 retval = ntohl (mp->retval);
949
950   vam->retval = retval;
951   vam->regenerate_interface_table = 1;
952   vam->result_ready = 1;
953 }
954
955 static void vl_api_interface_name_renumber_reply_t_handler_json
956   (vl_api_interface_name_renumber_reply_t * mp)
957 {
958   vat_main_t *vam = &vat_main;
959   vat_json_node_t node;
960
961   vat_json_init_object (&node);
962   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
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 /*
972  * Special-case: build the interface table, maintain
973  * the next loopback sw_if_index vbl.
974  */
975 static void vl_api_sw_interface_details_t_handler
976   (vl_api_sw_interface_details_t * mp)
977 {
978   vat_main_t *vam = &vat_main;
979   u8 *s = format (0, "%s%c", mp->interface_name, 0);
980
981   hash_set_mem (vam->sw_if_index_by_interface_name, s,
982                 ntohl (mp->sw_if_index));
983
984   /* In sub interface case, fill the sub interface table entry */
985   if (mp->sw_if_index != mp->sup_sw_if_index)
986     {
987       sw_interface_subif_t *sub = NULL;
988
989       vec_add2 (vam->sw_if_subif_table, sub, 1);
990
991       vec_validate (sub->interface_name, strlen ((char *) s) + 1);
992       strncpy ((char *) sub->interface_name, (char *) s,
993                vec_len (sub->interface_name));
994       sub->sw_if_index = ntohl (mp->sw_if_index);
995       sub->sub_id = ntohl (mp->sub_id);
996
997       sub->raw_flags = ntohl (mp->sub_if_flags & SUB_IF_API_FLAG_MASK_VNET);
998
999       sub->sub_number_of_tags = mp->sub_number_of_tags;
1000       sub->sub_outer_vlan_id = ntohs (mp->sub_outer_vlan_id);
1001       sub->sub_inner_vlan_id = ntohs (mp->sub_inner_vlan_id);
1002
1003       /* vlan tag rewrite */
1004       sub->vtr_op = ntohl (mp->vtr_op);
1005       sub->vtr_push_dot1q = ntohl (mp->vtr_push_dot1q);
1006       sub->vtr_tag1 = ntohl (mp->vtr_tag1);
1007       sub->vtr_tag2 = ntohl (mp->vtr_tag2);
1008     }
1009 }
1010
1011 static void vl_api_sw_interface_details_t_handler_json
1012   (vl_api_sw_interface_details_t * mp)
1013 {
1014   vat_main_t *vam = &vat_main;
1015   vat_json_node_t *node = NULL;
1016
1017   if (VAT_JSON_ARRAY != vam->json_tree.type)
1018     {
1019       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1020       vat_json_init_array (&vam->json_tree);
1021     }
1022   node = vat_json_array_add (&vam->json_tree);
1023
1024   vat_json_init_object (node);
1025   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
1026   vat_json_object_add_uint (node, "sup_sw_if_index",
1027                             ntohl (mp->sup_sw_if_index));
1028   vat_json_object_add_bytes (node, "l2_address", mp->l2_address,
1029                              sizeof (mp->l2_address));
1030   vat_json_object_add_string_copy (node, "interface_name",
1031                                    mp->interface_name);
1032   vat_json_object_add_string_copy (node, "interface_dev_type",
1033                                    mp->interface_dev_type);
1034   vat_json_object_add_uint (node, "flags", mp->flags);
1035   vat_json_object_add_uint (node, "link_duplex", mp->link_duplex);
1036   vat_json_object_add_uint (node, "link_speed", mp->link_speed);
1037   vat_json_object_add_uint (node, "mtu", ntohs (mp->link_mtu));
1038   vat_json_object_add_uint (node, "sub_id", ntohl (mp->sub_id));
1039   vat_json_object_add_uint (node, "sub_number_of_tags",
1040                             mp->sub_number_of_tags);
1041   vat_json_object_add_uint (node, "sub_outer_vlan_id",
1042                             ntohs (mp->sub_outer_vlan_id));
1043   vat_json_object_add_uint (node, "sub_inner_vlan_id",
1044                             ntohs (mp->sub_inner_vlan_id));
1045   vat_json_object_add_uint (node, "sub_if_flags", ntohl (mp->sub_if_flags));
1046   vat_json_object_add_uint (node, "vtr_op", ntohl (mp->vtr_op));
1047   vat_json_object_add_uint (node, "vtr_push_dot1q",
1048                             ntohl (mp->vtr_push_dot1q));
1049   vat_json_object_add_uint (node, "vtr_tag1", ntohl (mp->vtr_tag1));
1050   vat_json_object_add_uint (node, "vtr_tag2", ntohl (mp->vtr_tag2));
1051   if (ntohl (mp->sub_if_flags) & SUB_IF_API_FLAG_DOT1AH)
1052     {
1053       vat_json_object_add_string_copy (node, "pbb_vtr_dmac",
1054                                        format (0, "%U",
1055                                                format_ethernet_address,
1056                                                &mp->b_dmac));
1057       vat_json_object_add_string_copy (node, "pbb_vtr_smac",
1058                                        format (0, "%U",
1059                                                format_ethernet_address,
1060                                                &mp->b_smac));
1061       vat_json_object_add_uint (node, "pbb_vtr_b_vlanid", mp->b_vlanid);
1062       vat_json_object_add_uint (node, "pbb_vtr_i_sid", mp->i_sid);
1063     }
1064 }
1065
1066 #if VPP_API_TEST_BUILTIN == 0
1067 static void vl_api_sw_interface_event_t_handler
1068   (vl_api_sw_interface_event_t * mp)
1069 {
1070   vat_main_t *vam = &vat_main;
1071   if (vam->interface_event_display)
1072     errmsg ("interface flags: sw_if_index %d %s %s",
1073             ntohl (mp->sw_if_index),
1074             ((ntohl (mp->flags)) & IF_STATUS_API_FLAG_ADMIN_UP) ?
1075             "admin-up" : "admin-down",
1076             ((ntohl (mp->flags)) & IF_STATUS_API_FLAG_LINK_UP) ?
1077             "link-up" : "link-down");
1078 }
1079 #endif
1080
1081 __clib_unused static void
1082 vl_api_sw_interface_event_t_handler_json (vl_api_sw_interface_event_t * mp)
1083 {
1084   /* JSON output not supported */
1085 }
1086
1087 static void
1088 vl_api_cli_reply_t_handler (vl_api_cli_reply_t * mp)
1089 {
1090   vat_main_t *vam = &vat_main;
1091   i32 retval = ntohl (mp->retval);
1092
1093   vam->retval = retval;
1094   vam->shmem_result = uword_to_pointer (mp->reply_in_shmem, u8 *);
1095   vam->result_ready = 1;
1096 }
1097
1098 static void
1099 vl_api_cli_reply_t_handler_json (vl_api_cli_reply_t * mp)
1100 {
1101   vat_main_t *vam = &vat_main;
1102   vat_json_node_t node;
1103   void *oldheap;
1104   u8 *reply;
1105
1106   vat_json_init_object (&node);
1107   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1108   vat_json_object_add_uint (&node, "reply_in_shmem",
1109                             ntohl (mp->reply_in_shmem));
1110   /* Toss the shared-memory original... */
1111   oldheap = vl_msg_push_heap ();
1112
1113   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
1114   vec_free (reply);
1115
1116   vl_msg_pop_heap (oldheap);
1117
1118   vat_json_print (vam->ofp, &node);
1119   vat_json_free (&node);
1120
1121   vam->retval = ntohl (mp->retval);
1122   vam->result_ready = 1;
1123 }
1124
1125 static void
1126 vl_api_cli_inband_reply_t_handler (vl_api_cli_inband_reply_t * mp)
1127 {
1128   vat_main_t *vam = &vat_main;
1129   i32 retval = ntohl (mp->retval);
1130   u32 length = vl_api_string_len (&mp->reply);
1131
1132   vec_reset_length (vam->cmd_reply);
1133
1134   vam->retval = retval;
1135   if (retval == 0)
1136     {
1137       vec_validate (vam->cmd_reply, length);
1138       clib_memcpy ((char *) (vam->cmd_reply),
1139                    vl_api_from_api_string (&mp->reply), length);
1140       vam->cmd_reply[length] = 0;
1141     }
1142   vam->result_ready = 1;
1143 }
1144
1145 static void
1146 vl_api_cli_inband_reply_t_handler_json (vl_api_cli_inband_reply_t * mp)
1147 {
1148   vat_main_t *vam = &vat_main;
1149   vat_json_node_t node;
1150
1151   vec_reset_length (vam->cmd_reply);
1152
1153   vat_json_init_object (&node);
1154   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1155   vat_json_object_add_string_copy (&node, "reply",
1156                                    vl_api_from_api_string (&mp->reply));
1157
1158   vat_json_print (vam->ofp, &node);
1159   vat_json_free (&node);
1160
1161   vam->retval = ntohl (mp->retval);
1162   vam->result_ready = 1;
1163 }
1164
1165 static void vl_api_classify_add_del_table_reply_t_handler
1166   (vl_api_classify_add_del_table_reply_t * mp)
1167 {
1168   vat_main_t *vam = &vat_main;
1169   i32 retval = ntohl (mp->retval);
1170   if (vam->async_mode)
1171     {
1172       vam->async_errors += (retval < 0);
1173     }
1174   else
1175     {
1176       vam->retval = retval;
1177       if (retval == 0 &&
1178           ((mp->new_table_index != 0xFFFFFFFF) ||
1179            (mp->skip_n_vectors != 0xFFFFFFFF) ||
1180            (mp->match_n_vectors != 0xFFFFFFFF)))
1181         /*
1182          * Note: this is just barely thread-safe, depends on
1183          * the main thread spinning waiting for an answer...
1184          */
1185         errmsg ("new index %d, skip_n_vectors %d, match_n_vectors %d",
1186                 ntohl (mp->new_table_index),
1187                 ntohl (mp->skip_n_vectors), ntohl (mp->match_n_vectors));
1188       vam->result_ready = 1;
1189     }
1190 }
1191
1192 static void vl_api_classify_add_del_table_reply_t_handler_json
1193   (vl_api_classify_add_del_table_reply_t * mp)
1194 {
1195   vat_main_t *vam = &vat_main;
1196   vat_json_node_t node;
1197
1198   vat_json_init_object (&node);
1199   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1200   vat_json_object_add_uint (&node, "new_table_index",
1201                             ntohl (mp->new_table_index));
1202   vat_json_object_add_uint (&node, "skip_n_vectors",
1203                             ntohl (mp->skip_n_vectors));
1204   vat_json_object_add_uint (&node, "match_n_vectors",
1205                             ntohl (mp->match_n_vectors));
1206
1207   vat_json_print (vam->ofp, &node);
1208   vat_json_free (&node);
1209
1210   vam->retval = ntohl (mp->retval);
1211   vam->result_ready = 1;
1212 }
1213
1214 static void vl_api_get_node_index_reply_t_handler
1215   (vl_api_get_node_index_reply_t * mp)
1216 {
1217   vat_main_t *vam = &vat_main;
1218   i32 retval = ntohl (mp->retval);
1219   if (vam->async_mode)
1220     {
1221       vam->async_errors += (retval < 0);
1222     }
1223   else
1224     {
1225       vam->retval = retval;
1226       if (retval == 0)
1227         errmsg ("node index %d", ntohl (mp->node_index));
1228       vam->result_ready = 1;
1229     }
1230 }
1231
1232 static void vl_api_get_node_index_reply_t_handler_json
1233   (vl_api_get_node_index_reply_t * mp)
1234 {
1235   vat_main_t *vam = &vat_main;
1236   vat_json_node_t node;
1237
1238   vat_json_init_object (&node);
1239   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1240   vat_json_object_add_uint (&node, "node_index", ntohl (mp->node_index));
1241
1242   vat_json_print (vam->ofp, &node);
1243   vat_json_free (&node);
1244
1245   vam->retval = ntohl (mp->retval);
1246   vam->result_ready = 1;
1247 }
1248
1249 static void vl_api_get_next_index_reply_t_handler
1250   (vl_api_get_next_index_reply_t * mp)
1251 {
1252   vat_main_t *vam = &vat_main;
1253   i32 retval = ntohl (mp->retval);
1254   if (vam->async_mode)
1255     {
1256       vam->async_errors += (retval < 0);
1257     }
1258   else
1259     {
1260       vam->retval = retval;
1261       if (retval == 0)
1262         errmsg ("next node index %d", ntohl (mp->next_index));
1263       vam->result_ready = 1;
1264     }
1265 }
1266
1267 static void vl_api_get_next_index_reply_t_handler_json
1268   (vl_api_get_next_index_reply_t * mp)
1269 {
1270   vat_main_t *vam = &vat_main;
1271   vat_json_node_t node;
1272
1273   vat_json_init_object (&node);
1274   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1275   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1276
1277   vat_json_print (vam->ofp, &node);
1278   vat_json_free (&node);
1279
1280   vam->retval = ntohl (mp->retval);
1281   vam->result_ready = 1;
1282 }
1283
1284 static void vl_api_add_node_next_reply_t_handler
1285   (vl_api_add_node_next_reply_t * mp)
1286 {
1287   vat_main_t *vam = &vat_main;
1288   i32 retval = ntohl (mp->retval);
1289   if (vam->async_mode)
1290     {
1291       vam->async_errors += (retval < 0);
1292     }
1293   else
1294     {
1295       vam->retval = retval;
1296       if (retval == 0)
1297         errmsg ("next index %d", ntohl (mp->next_index));
1298       vam->result_ready = 1;
1299     }
1300 }
1301
1302 static void vl_api_add_node_next_reply_t_handler_json
1303   (vl_api_add_node_next_reply_t * mp)
1304 {
1305   vat_main_t *vam = &vat_main;
1306   vat_json_node_t node;
1307
1308   vat_json_init_object (&node);
1309   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1310   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1311
1312   vat_json_print (vam->ofp, &node);
1313   vat_json_free (&node);
1314
1315   vam->retval = ntohl (mp->retval);
1316   vam->result_ready = 1;
1317 }
1318
1319 static void vl_api_show_version_reply_t_handler
1320   (vl_api_show_version_reply_t * mp)
1321 {
1322   vat_main_t *vam = &vat_main;
1323   i32 retval = ntohl (mp->retval);
1324
1325   if (retval >= 0)
1326     {
1327       errmsg ("        program: %s", mp->program);
1328       errmsg ("        version: %s", mp->version);
1329       errmsg ("     build date: %s", mp->build_date);
1330       errmsg ("build directory: %s", mp->build_directory);
1331     }
1332   vam->retval = retval;
1333   vam->result_ready = 1;
1334 }
1335
1336 static void vl_api_show_version_reply_t_handler_json
1337   (vl_api_show_version_reply_t * mp)
1338 {
1339   vat_main_t *vam = &vat_main;
1340   vat_json_node_t node;
1341
1342   vat_json_init_object (&node);
1343   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1344   vat_json_object_add_string_copy (&node, "program", mp->program);
1345   vat_json_object_add_string_copy (&node, "version", mp->version);
1346   vat_json_object_add_string_copy (&node, "build_date", mp->build_date);
1347   vat_json_object_add_string_copy (&node, "build_directory",
1348                                    mp->build_directory);
1349
1350   vat_json_print (vam->ofp, &node);
1351   vat_json_free (&node);
1352
1353   vam->retval = ntohl (mp->retval);
1354   vam->result_ready = 1;
1355 }
1356
1357 static void vl_api_show_threads_reply_t_handler
1358   (vl_api_show_threads_reply_t * mp)
1359 {
1360   vat_main_t *vam = &vat_main;
1361   i32 retval = ntohl (mp->retval);
1362   int i, count = 0;
1363
1364   if (retval >= 0)
1365     count = ntohl (mp->count);
1366
1367   for (i = 0; i < count; i++)
1368     print (vam->ofp,
1369            "\n%-2d %-11s %-11s %-5d %-6d %-4d %-6d",
1370            ntohl (mp->thread_data[i].id), mp->thread_data[i].name,
1371            mp->thread_data[i].type, ntohl (mp->thread_data[i].pid),
1372            ntohl (mp->thread_data[i].cpu_id), ntohl (mp->thread_data[i].core),
1373            ntohl (mp->thread_data[i].cpu_socket));
1374
1375   vam->retval = retval;
1376   vam->result_ready = 1;
1377 }
1378
1379 static void vl_api_show_threads_reply_t_handler_json
1380   (vl_api_show_threads_reply_t * mp)
1381 {
1382   vat_main_t *vam = &vat_main;
1383   vat_json_node_t node;
1384   vl_api_thread_data_t *td;
1385   i32 retval = ntohl (mp->retval);
1386   int i, count = 0;
1387
1388   if (retval >= 0)
1389     count = ntohl (mp->count);
1390
1391   vat_json_init_object (&node);
1392   vat_json_object_add_int (&node, "retval", retval);
1393   vat_json_object_add_uint (&node, "count", count);
1394
1395   for (i = 0; i < count; i++)
1396     {
1397       td = &mp->thread_data[i];
1398       vat_json_object_add_uint (&node, "id", ntohl (td->id));
1399       vat_json_object_add_string_copy (&node, "name", td->name);
1400       vat_json_object_add_string_copy (&node, "type", td->type);
1401       vat_json_object_add_uint (&node, "pid", ntohl (td->pid));
1402       vat_json_object_add_int (&node, "cpu_id", ntohl (td->cpu_id));
1403       vat_json_object_add_int (&node, "core", ntohl (td->id));
1404       vat_json_object_add_int (&node, "cpu_socket", ntohl (td->cpu_socket));
1405     }
1406
1407   vat_json_print (vam->ofp, &node);
1408   vat_json_free (&node);
1409
1410   vam->retval = retval;
1411   vam->result_ready = 1;
1412 }
1413
1414 static int
1415 api_show_threads (vat_main_t * vam)
1416 {
1417   vl_api_show_threads_t *mp;
1418   int ret;
1419
1420   print (vam->ofp,
1421          "\n%-2s %-11s %-11s %-5s %-6s %-4s %-6s",
1422          "ID", "Name", "Type", "LWP", "cpu_id", "Core", "Socket");
1423
1424   M (SHOW_THREADS, mp);
1425
1426   S (mp);
1427   W (ret);
1428   return ret;
1429 }
1430
1431 static void
1432 vl_api_l2_macs_event_t_handler (vl_api_l2_macs_event_t * mp)
1433 {
1434   u32 n_macs = ntohl (mp->n_macs);
1435   errmsg ("L2MAC event received with pid %d cl-idx %d for %d macs: \n",
1436           ntohl (mp->pid), mp->client_index, n_macs);
1437   int i;
1438   for (i = 0; i < n_macs; i++)
1439     {
1440       vl_api_mac_entry_t *mac = &mp->mac[i];
1441       errmsg (" [%d] sw_if_index %d  mac_addr %U  action %d \n",
1442               i + 1, ntohl (mac->sw_if_index),
1443               format_ethernet_address, mac->mac_addr, mac->action);
1444       if (i == 1000)
1445         break;
1446     }
1447 }
1448
1449 static void
1450 vl_api_l2_macs_event_t_handler_json (vl_api_l2_macs_event_t * mp)
1451 {
1452   /* JSON output not supported */
1453 }
1454
1455 #define vl_api_bridge_domain_details_t_endian vl_noop_handler
1456 #define vl_api_bridge_domain_details_t_print vl_noop_handler
1457
1458 /*
1459  * Special-case: build the bridge domain table, maintain
1460  * the next bd id vbl.
1461  */
1462 static void vl_api_bridge_domain_details_t_handler
1463   (vl_api_bridge_domain_details_t * mp)
1464 {
1465   vat_main_t *vam = &vat_main;
1466   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1467   int i;
1468
1469   print (vam->ofp, "\n%-3s %-3s %-3s %-3s %-3s %-6s %-3s",
1470          " ID", "LRN", "FWD", "FLD", "BVI", "UU-FWD", "#IF");
1471
1472   print (vam->ofp, "%3d %3d %3d %3d %3d %6d %3d",
1473          ntohl (mp->bd_id), mp->learn, mp->forward,
1474          mp->flood, ntohl (mp->bvi_sw_if_index),
1475          ntohl (mp->uu_fwd_sw_if_index), n_sw_ifs);
1476
1477   if (n_sw_ifs)
1478     {
1479       vl_api_bridge_domain_sw_if_t *sw_ifs;
1480       print (vam->ofp, "\n\n%s %s  %s", "sw_if_index", "SHG",
1481              "Interface Name");
1482
1483       sw_ifs = mp->sw_if_details;
1484       for (i = 0; i < n_sw_ifs; i++)
1485         {
1486           u8 *sw_if_name = 0;
1487           u32 sw_if_index;
1488           hash_pair_t *p;
1489
1490           sw_if_index = ntohl (sw_ifs->sw_if_index);
1491
1492           /* *INDENT-OFF* */
1493           hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
1494                              ({
1495                                if ((u32) p->value[0] == sw_if_index)
1496                                  {
1497                                    sw_if_name = (u8 *)(p->key);
1498                                    break;
1499                                  }
1500                              }));
1501           /* *INDENT-ON* */
1502           print (vam->ofp, "%7d     %3d  %s", sw_if_index,
1503                  sw_ifs->shg, sw_if_name ? (char *) sw_if_name :
1504                  "sw_if_index not found!");
1505
1506           sw_ifs++;
1507         }
1508     }
1509 }
1510
1511 static void vl_api_bridge_domain_details_t_handler_json
1512   (vl_api_bridge_domain_details_t * mp)
1513 {
1514   vat_main_t *vam = &vat_main;
1515   vat_json_node_t *node, *array = NULL;
1516   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1517
1518   if (VAT_JSON_ARRAY != vam->json_tree.type)
1519     {
1520       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1521       vat_json_init_array (&vam->json_tree);
1522     }
1523   node = vat_json_array_add (&vam->json_tree);
1524
1525   vat_json_init_object (node);
1526   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1527   vat_json_object_add_uint (node, "flood", mp->flood);
1528   vat_json_object_add_uint (node, "forward", mp->forward);
1529   vat_json_object_add_uint (node, "learn", mp->learn);
1530   vat_json_object_add_uint (node, "bvi_sw_if_index",
1531                             ntohl (mp->bvi_sw_if_index));
1532   vat_json_object_add_uint (node, "n_sw_ifs", n_sw_ifs);
1533   array = vat_json_object_add (node, "sw_if");
1534   vat_json_init_array (array);
1535
1536
1537
1538   if (n_sw_ifs)
1539     {
1540       vl_api_bridge_domain_sw_if_t *sw_ifs;
1541       int i;
1542
1543       sw_ifs = mp->sw_if_details;
1544       for (i = 0; i < n_sw_ifs; i++)
1545         {
1546           node = vat_json_array_add (array);
1547           vat_json_init_object (node);
1548           vat_json_object_add_uint (node, "sw_if_index",
1549                                     ntohl (sw_ifs->sw_if_index));
1550           vat_json_object_add_uint (node, "shg", sw_ifs->shg);
1551           sw_ifs++;
1552         }
1553     }
1554 }
1555
1556 static void vl_api_control_ping_reply_t_handler
1557   (vl_api_control_ping_reply_t * mp)
1558 {
1559   vat_main_t *vam = &vat_main;
1560   i32 retval = ntohl (mp->retval);
1561   if (vam->async_mode)
1562     {
1563       vam->async_errors += (retval < 0);
1564     }
1565   else
1566     {
1567       vam->retval = retval;
1568       vam->result_ready = 1;
1569     }
1570   if (vam->socket_client_main)
1571     vam->socket_client_main->control_pings_outstanding--;
1572 }
1573
1574 static void vl_api_control_ping_reply_t_handler_json
1575   (vl_api_control_ping_reply_t * mp)
1576 {
1577   vat_main_t *vam = &vat_main;
1578   i32 retval = ntohl (mp->retval);
1579
1580   if (VAT_JSON_NONE != vam->json_tree.type)
1581     {
1582       vat_json_print (vam->ofp, &vam->json_tree);
1583       vat_json_free (&vam->json_tree);
1584       vam->json_tree.type = VAT_JSON_NONE;
1585     }
1586   else
1587     {
1588       /* just print [] */
1589       vat_json_init_array (&vam->json_tree);
1590       vat_json_print (vam->ofp, &vam->json_tree);
1591       vam->json_tree.type = VAT_JSON_NONE;
1592     }
1593
1594   vam->retval = retval;
1595   vam->result_ready = 1;
1596 }
1597
1598 static void
1599   vl_api_bridge_domain_set_mac_age_reply_t_handler
1600   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1601 {
1602   vat_main_t *vam = &vat_main;
1603   i32 retval = ntohl (mp->retval);
1604   if (vam->async_mode)
1605     {
1606       vam->async_errors += (retval < 0);
1607     }
1608   else
1609     {
1610       vam->retval = retval;
1611       vam->result_ready = 1;
1612     }
1613 }
1614
1615 static void vl_api_bridge_domain_set_mac_age_reply_t_handler_json
1616   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1617 {
1618   vat_main_t *vam = &vat_main;
1619   vat_json_node_t node;
1620
1621   vat_json_init_object (&node);
1622   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1623
1624   vat_json_print (vam->ofp, &node);
1625   vat_json_free (&node);
1626
1627   vam->retval = ntohl (mp->retval);
1628   vam->result_ready = 1;
1629 }
1630
1631 static void
1632 vl_api_l2_flags_reply_t_handler (vl_api_l2_flags_reply_t * mp)
1633 {
1634   vat_main_t *vam = &vat_main;
1635   i32 retval = ntohl (mp->retval);
1636   if (vam->async_mode)
1637     {
1638       vam->async_errors += (retval < 0);
1639     }
1640   else
1641     {
1642       vam->retval = retval;
1643       vam->result_ready = 1;
1644     }
1645 }
1646
1647 static void vl_api_l2_flags_reply_t_handler_json
1648   (vl_api_l2_flags_reply_t * mp)
1649 {
1650   vat_main_t *vam = &vat_main;
1651   vat_json_node_t node;
1652
1653   vat_json_init_object (&node);
1654   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1655   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1656                             ntohl (mp->resulting_feature_bitmap));
1657
1658   vat_json_print (vam->ofp, &node);
1659   vat_json_free (&node);
1660
1661   vam->retval = ntohl (mp->retval);
1662   vam->result_ready = 1;
1663 }
1664
1665 static void vl_api_bridge_flags_reply_t_handler
1666   (vl_api_bridge_flags_reply_t * mp)
1667 {
1668   vat_main_t *vam = &vat_main;
1669   i32 retval = ntohl (mp->retval);
1670   if (vam->async_mode)
1671     {
1672       vam->async_errors += (retval < 0);
1673     }
1674   else
1675     {
1676       vam->retval = retval;
1677       vam->result_ready = 1;
1678     }
1679 }
1680
1681 static void vl_api_bridge_flags_reply_t_handler_json
1682   (vl_api_bridge_flags_reply_t * mp)
1683 {
1684   vat_main_t *vam = &vat_main;
1685   vat_json_node_t node;
1686
1687   vat_json_init_object (&node);
1688   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1689   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1690                             ntohl (mp->resulting_feature_bitmap));
1691
1692   vat_json_print (vam->ofp, &node);
1693   vat_json_free (&node);
1694
1695   vam->retval = ntohl (mp->retval);
1696   vam->result_ready = 1;
1697 }
1698
1699 static void
1700 vl_api_tap_create_v2_reply_t_handler (vl_api_tap_create_v2_reply_t * mp)
1701 {
1702   vat_main_t *vam = &vat_main;
1703   i32 retval = ntohl (mp->retval);
1704   if (vam->async_mode)
1705     {
1706       vam->async_errors += (retval < 0);
1707     }
1708   else
1709     {
1710       vam->retval = retval;
1711       vam->sw_if_index = ntohl (mp->sw_if_index);
1712       vam->result_ready = 1;
1713     }
1714
1715 }
1716
1717 static void vl_api_tap_create_v2_reply_t_handler_json
1718   (vl_api_tap_create_v2_reply_t * mp)
1719 {
1720   vat_main_t *vam = &vat_main;
1721   vat_json_node_t node;
1722
1723   vat_json_init_object (&node);
1724   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1725   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1726
1727   vat_json_print (vam->ofp, &node);
1728   vat_json_free (&node);
1729
1730   vam->retval = ntohl (mp->retval);
1731   vam->result_ready = 1;
1732
1733 }
1734
1735 static void
1736 vl_api_tap_delete_v2_reply_t_handler (vl_api_tap_delete_v2_reply_t * mp)
1737 {
1738   vat_main_t *vam = &vat_main;
1739   i32 retval = ntohl (mp->retval);
1740   if (vam->async_mode)
1741     {
1742       vam->async_errors += (retval < 0);
1743     }
1744   else
1745     {
1746       vam->retval = retval;
1747       vam->result_ready = 1;
1748     }
1749 }
1750
1751 static void vl_api_tap_delete_v2_reply_t_handler_json
1752   (vl_api_tap_delete_v2_reply_t * mp)
1753 {
1754   vat_main_t *vam = &vat_main;
1755   vat_json_node_t node;
1756
1757   vat_json_init_object (&node);
1758   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1759
1760   vat_json_print (vam->ofp, &node);
1761   vat_json_free (&node);
1762
1763   vam->retval = ntohl (mp->retval);
1764   vam->result_ready = 1;
1765 }
1766
1767 static void
1768 vl_api_virtio_pci_create_reply_t_handler (vl_api_virtio_pci_create_reply_t *
1769                                           mp)
1770 {
1771   vat_main_t *vam = &vat_main;
1772   i32 retval = ntohl (mp->retval);
1773   if (vam->async_mode)
1774     {
1775       vam->async_errors += (retval < 0);
1776     }
1777   else
1778     {
1779       vam->retval = retval;
1780       vam->sw_if_index = ntohl (mp->sw_if_index);
1781       vam->result_ready = 1;
1782     }
1783 }
1784
1785 static void vl_api_virtio_pci_create_reply_t_handler_json
1786   (vl_api_virtio_pci_create_reply_t * mp)
1787 {
1788   vat_main_t *vam = &vat_main;
1789   vat_json_node_t node;
1790
1791   vat_json_init_object (&node);
1792   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1793   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1794
1795   vat_json_print (vam->ofp, &node);
1796   vat_json_free (&node);
1797
1798   vam->retval = ntohl (mp->retval);
1799   vam->result_ready = 1;
1800
1801 }
1802
1803 static void
1804 vl_api_virtio_pci_delete_reply_t_handler (vl_api_virtio_pci_delete_reply_t *
1805                                           mp)
1806 {
1807   vat_main_t *vam = &vat_main;
1808   i32 retval = ntohl (mp->retval);
1809   if (vam->async_mode)
1810     {
1811       vam->async_errors += (retval < 0);
1812     }
1813   else
1814     {
1815       vam->retval = retval;
1816       vam->result_ready = 1;
1817     }
1818 }
1819
1820 static void vl_api_virtio_pci_delete_reply_t_handler_json
1821   (vl_api_virtio_pci_delete_reply_t * mp)
1822 {
1823   vat_main_t *vam = &vat_main;
1824   vat_json_node_t node;
1825
1826   vat_json_init_object (&node);
1827   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1828
1829   vat_json_print (vam->ofp, &node);
1830   vat_json_free (&node);
1831
1832   vam->retval = ntohl (mp->retval);
1833   vam->result_ready = 1;
1834 }
1835
1836 static void
1837 vl_api_bond_create_reply_t_handler (vl_api_bond_create_reply_t * mp)
1838 {
1839   vat_main_t *vam = &vat_main;
1840   i32 retval = ntohl (mp->retval);
1841
1842   if (vam->async_mode)
1843     {
1844       vam->async_errors += (retval < 0);
1845     }
1846   else
1847     {
1848       vam->retval = retval;
1849       vam->sw_if_index = ntohl (mp->sw_if_index);
1850       vam->result_ready = 1;
1851     }
1852 }
1853
1854 static void vl_api_bond_create_reply_t_handler_json
1855   (vl_api_bond_create_reply_t * mp)
1856 {
1857   vat_main_t *vam = &vat_main;
1858   vat_json_node_t node;
1859
1860   vat_json_init_object (&node);
1861   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1862   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1863
1864   vat_json_print (vam->ofp, &node);
1865   vat_json_free (&node);
1866
1867   vam->retval = ntohl (mp->retval);
1868   vam->result_ready = 1;
1869 }
1870
1871 static void
1872 vl_api_bond_delete_reply_t_handler (vl_api_bond_delete_reply_t * mp)
1873 {
1874   vat_main_t *vam = &vat_main;
1875   i32 retval = ntohl (mp->retval);
1876
1877   if (vam->async_mode)
1878     {
1879       vam->async_errors += (retval < 0);
1880     }
1881   else
1882     {
1883       vam->retval = retval;
1884       vam->result_ready = 1;
1885     }
1886 }
1887
1888 static void vl_api_bond_delete_reply_t_handler_json
1889   (vl_api_bond_delete_reply_t * mp)
1890 {
1891   vat_main_t *vam = &vat_main;
1892   vat_json_node_t node;
1893
1894   vat_json_init_object (&node);
1895   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1896
1897   vat_json_print (vam->ofp, &node);
1898   vat_json_free (&node);
1899
1900   vam->retval = ntohl (mp->retval);
1901   vam->result_ready = 1;
1902 }
1903
1904 static void
1905 vl_api_bond_enslave_reply_t_handler (vl_api_bond_enslave_reply_t * mp)
1906 {
1907   vat_main_t *vam = &vat_main;
1908   i32 retval = ntohl (mp->retval);
1909
1910   if (vam->async_mode)
1911     {
1912       vam->async_errors += (retval < 0);
1913     }
1914   else
1915     {
1916       vam->retval = retval;
1917       vam->result_ready = 1;
1918     }
1919 }
1920
1921 static void vl_api_bond_enslave_reply_t_handler_json
1922   (vl_api_bond_enslave_reply_t * mp)
1923 {
1924   vat_main_t *vam = &vat_main;
1925   vat_json_node_t node;
1926
1927   vat_json_init_object (&node);
1928   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1929
1930   vat_json_print (vam->ofp, &node);
1931   vat_json_free (&node);
1932
1933   vam->retval = ntohl (mp->retval);
1934   vam->result_ready = 1;
1935 }
1936
1937 static void
1938 vl_api_bond_detach_slave_reply_t_handler (vl_api_bond_detach_slave_reply_t *
1939                                           mp)
1940 {
1941   vat_main_t *vam = &vat_main;
1942   i32 retval = ntohl (mp->retval);
1943
1944   if (vam->async_mode)
1945     {
1946       vam->async_errors += (retval < 0);
1947     }
1948   else
1949     {
1950       vam->retval = retval;
1951       vam->result_ready = 1;
1952     }
1953 }
1954
1955 static void vl_api_bond_detach_slave_reply_t_handler_json
1956   (vl_api_bond_detach_slave_reply_t * mp)
1957 {
1958   vat_main_t *vam = &vat_main;
1959   vat_json_node_t node;
1960
1961   vat_json_init_object (&node);
1962   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1963
1964   vat_json_print (vam->ofp, &node);
1965   vat_json_free (&node);
1966
1967   vam->retval = ntohl (mp->retval);
1968   vam->result_ready = 1;
1969 }
1970
1971 static int
1972 api_sw_interface_set_bond_weight (vat_main_t * vam)
1973 {
1974   unformat_input_t *i = vam->input;
1975   vl_api_sw_interface_set_bond_weight_t *mp;
1976   u32 sw_if_index = ~0;
1977   u32 weight = 0;
1978   u8 weight_enter = 0;
1979   int ret;
1980
1981   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
1982     {
1983       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
1984         ;
1985       else if (unformat (i, "sw_if_index %d", &sw_if_index))
1986         ;
1987       else if (unformat (i, "weight %u", &weight))
1988         weight_enter = 1;
1989       else
1990         break;
1991     }
1992
1993   if (sw_if_index == ~0)
1994     {
1995       errmsg ("missing interface name or sw_if_index");
1996       return -99;
1997     }
1998   if (weight_enter == 0)
1999     {
2000       errmsg ("missing valid weight");
2001       return -99;
2002     }
2003
2004   /* Construct the API message */
2005   M (SW_INTERFACE_SET_BOND_WEIGHT, mp);
2006   mp->sw_if_index = ntohl (sw_if_index);
2007   mp->weight = ntohl (weight);
2008
2009   S (mp);
2010   W (ret);
2011   return ret;
2012 }
2013
2014 static void vl_api_sw_interface_bond_details_t_handler
2015   (vl_api_sw_interface_bond_details_t * mp)
2016 {
2017   vat_main_t *vam = &vat_main;
2018
2019   print (vam->ofp,
2020          "%-16s %-12d %-12U %-13U %-14u %-14u",
2021          mp->interface_name, ntohl (mp->sw_if_index),
2022          format_bond_mode, ntohl (mp->mode), format_bond_load_balance,
2023          ntohl (mp->lb), ntohl (mp->active_slaves), ntohl (mp->slaves));
2024 }
2025
2026 static void vl_api_sw_interface_bond_details_t_handler_json
2027   (vl_api_sw_interface_bond_details_t * mp)
2028 {
2029   vat_main_t *vam = &vat_main;
2030   vat_json_node_t *node = NULL;
2031
2032   if (VAT_JSON_ARRAY != vam->json_tree.type)
2033     {
2034       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2035       vat_json_init_array (&vam->json_tree);
2036     }
2037   node = vat_json_array_add (&vam->json_tree);
2038
2039   vat_json_init_object (node);
2040   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
2041   vat_json_object_add_string_copy (node, "interface_name",
2042                                    mp->interface_name);
2043   vat_json_object_add_uint (node, "mode", ntohl (mp->mode));
2044   vat_json_object_add_uint (node, "load_balance", ntohl (mp->lb));
2045   vat_json_object_add_uint (node, "active_slaves", ntohl (mp->active_slaves));
2046   vat_json_object_add_uint (node, "slaves", ntohl (mp->slaves));
2047 }
2048
2049 static int
2050 api_sw_interface_bond_dump (vat_main_t * vam)
2051 {
2052   vl_api_sw_interface_bond_dump_t *mp;
2053   vl_api_control_ping_t *mp_ping;
2054   int ret;
2055
2056   print (vam->ofp,
2057          "\n%-16s %-12s %-12s %-13s %-14s %-14s",
2058          "interface name", "sw_if_index", "mode", "load balance",
2059          "active slaves", "slaves");
2060
2061   /* Get list of bond interfaces */
2062   M (SW_INTERFACE_BOND_DUMP, mp);
2063   S (mp);
2064
2065   /* Use a control ping for synchronization */
2066   MPING (CONTROL_PING, mp_ping);
2067   S (mp_ping);
2068
2069   W (ret);
2070   return ret;
2071 }
2072
2073 static void vl_api_sw_interface_slave_details_t_handler
2074   (vl_api_sw_interface_slave_details_t * mp)
2075 {
2076   vat_main_t *vam = &vat_main;
2077
2078   print (vam->ofp,
2079          "%-25s %-12d %-7d %-12d %-10d %-10d", mp->interface_name,
2080          ntohl (mp->sw_if_index), mp->is_passive, mp->is_long_timeout,
2081          ntohl (mp->weight), mp->is_local_numa);
2082 }
2083
2084 static void vl_api_sw_interface_slave_details_t_handler_json
2085   (vl_api_sw_interface_slave_details_t * mp)
2086 {
2087   vat_main_t *vam = &vat_main;
2088   vat_json_node_t *node = NULL;
2089
2090   if (VAT_JSON_ARRAY != vam->json_tree.type)
2091     {
2092       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2093       vat_json_init_array (&vam->json_tree);
2094     }
2095   node = vat_json_array_add (&vam->json_tree);
2096
2097   vat_json_init_object (node);
2098   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
2099   vat_json_object_add_string_copy (node, "interface_name",
2100                                    mp->interface_name);
2101   vat_json_object_add_uint (node, "passive", mp->is_passive);
2102   vat_json_object_add_uint (node, "long_timeout", mp->is_long_timeout);
2103   vat_json_object_add_uint (node, "weight", ntohl (mp->weight));
2104   vat_json_object_add_uint (node, "is_local_numa", mp->is_local_numa);
2105 }
2106
2107 static int
2108 api_sw_interface_slave_dump (vat_main_t * vam)
2109 {
2110   unformat_input_t *i = vam->input;
2111   vl_api_sw_interface_slave_dump_t *mp;
2112   vl_api_control_ping_t *mp_ping;
2113   u32 sw_if_index = ~0;
2114   u8 sw_if_index_set = 0;
2115   int ret;
2116
2117   /* Parse args required to build the message */
2118   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2119     {
2120       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
2121         sw_if_index_set = 1;
2122       else if (unformat (i, "sw_if_index %d", &sw_if_index))
2123         sw_if_index_set = 1;
2124       else
2125         break;
2126     }
2127
2128   if (sw_if_index_set == 0)
2129     {
2130       errmsg ("missing vpp interface name. ");
2131       return -99;
2132     }
2133
2134   print (vam->ofp,
2135          "\n%-25s %-12s %-7s %-12s %-10s %-10s",
2136          "slave interface name", "sw_if_index", "passive", "long_timeout",
2137          "weight", "local numa");
2138
2139   /* Get list of bond interfaces */
2140   M (SW_INTERFACE_SLAVE_DUMP, mp);
2141   mp->sw_if_index = ntohl (sw_if_index);
2142   S (mp);
2143
2144   /* Use a control ping for synchronization */
2145   MPING (CONTROL_PING, mp_ping);
2146   S (mp_ping);
2147
2148   W (ret);
2149   return ret;
2150 }
2151
2152 static void vl_api_mpls_tunnel_add_del_reply_t_handler
2153   (vl_api_mpls_tunnel_add_del_reply_t * mp)
2154 {
2155   vat_main_t *vam = &vat_main;
2156   i32 retval = ntohl (mp->retval);
2157   if (vam->async_mode)
2158     {
2159       vam->async_errors += (retval < 0);
2160     }
2161   else
2162     {
2163       vam->retval = retval;
2164       vam->sw_if_index = ntohl (mp->sw_if_index);
2165       vam->result_ready = 1;
2166     }
2167   vam->regenerate_interface_table = 1;
2168 }
2169
2170 static void vl_api_mpls_tunnel_add_del_reply_t_handler_json
2171   (vl_api_mpls_tunnel_add_del_reply_t * mp)
2172 {
2173   vat_main_t *vam = &vat_main;
2174   vat_json_node_t node;
2175
2176   vat_json_init_object (&node);
2177   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2178   vat_json_object_add_uint (&node, "tunnel_sw_if_index",
2179                             ntohl (mp->sw_if_index));
2180
2181   vat_json_print (vam->ofp, &node);
2182   vat_json_free (&node);
2183
2184   vam->retval = ntohl (mp->retval);
2185   vam->result_ready = 1;
2186 }
2187
2188 static void vl_api_l2tpv3_create_tunnel_reply_t_handler
2189   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
2190 {
2191   vat_main_t *vam = &vat_main;
2192   i32 retval = ntohl (mp->retval);
2193   if (vam->async_mode)
2194     {
2195       vam->async_errors += (retval < 0);
2196     }
2197   else
2198     {
2199       vam->retval = retval;
2200       vam->sw_if_index = ntohl (mp->sw_if_index);
2201       vam->result_ready = 1;
2202     }
2203 }
2204
2205 static void vl_api_l2tpv3_create_tunnel_reply_t_handler_json
2206   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
2207 {
2208   vat_main_t *vam = &vat_main;
2209   vat_json_node_t node;
2210
2211   vat_json_init_object (&node);
2212   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2213   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2214
2215   vat_json_print (vam->ofp, &node);
2216   vat_json_free (&node);
2217
2218   vam->retval = ntohl (mp->retval);
2219   vam->result_ready = 1;
2220 }
2221
2222 static void vl_api_gpe_add_del_fwd_entry_reply_t_handler
2223   (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
2224 {
2225   vat_main_t *vam = &vat_main;
2226   i32 retval = ntohl (mp->retval);
2227   if (vam->async_mode)
2228     {
2229       vam->async_errors += (retval < 0);
2230     }
2231   else
2232     {
2233       vam->retval = retval;
2234       vam->result_ready = 1;
2235     }
2236 }
2237
2238 static void vl_api_gpe_add_del_fwd_entry_reply_t_handler_json
2239   (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
2240 {
2241   vat_main_t *vam = &vat_main;
2242   vat_json_node_t node;
2243
2244   vat_json_init_object (&node);
2245   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2246   vat_json_object_add_uint (&node, "fwd_entry_index",
2247                             clib_net_to_host_u32 (mp->fwd_entry_index));
2248
2249   vat_json_print (vam->ofp, &node);
2250   vat_json_free (&node);
2251
2252   vam->retval = ntohl (mp->retval);
2253   vam->result_ready = 1;
2254 }
2255
2256 u8 *
2257 format_lisp_transport_protocol (u8 * s, va_list * args)
2258 {
2259   u32 proto = va_arg (*args, u32);
2260
2261   switch (proto)
2262     {
2263     case 1:
2264       return format (s, "udp");
2265     case 2:
2266       return format (s, "api");
2267     default:
2268       return 0;
2269     }
2270   return 0;
2271 }
2272
2273 static void vl_api_one_get_transport_protocol_reply_t_handler
2274   (vl_api_one_get_transport_protocol_reply_t * mp)
2275 {
2276   vat_main_t *vam = &vat_main;
2277   i32 retval = ntohl (mp->retval);
2278   if (vam->async_mode)
2279     {
2280       vam->async_errors += (retval < 0);
2281     }
2282   else
2283     {
2284       u32 proto = mp->protocol;
2285       print (vam->ofp, "Transport protocol: %U",
2286              format_lisp_transport_protocol, proto);
2287       vam->retval = retval;
2288       vam->result_ready = 1;
2289     }
2290 }
2291
2292 static void vl_api_one_get_transport_protocol_reply_t_handler_json
2293   (vl_api_one_get_transport_protocol_reply_t * mp)
2294 {
2295   vat_main_t *vam = &vat_main;
2296   vat_json_node_t node;
2297   u8 *s;
2298
2299   s = format (0, "%U", format_lisp_transport_protocol, mp->protocol);
2300   vec_add1 (s, 0);
2301
2302   vat_json_init_object (&node);
2303   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2304   vat_json_object_add_string_copy (&node, "transport-protocol", s);
2305
2306   vec_free (s);
2307   vat_json_print (vam->ofp, &node);
2308   vat_json_free (&node);
2309
2310   vam->retval = ntohl (mp->retval);
2311   vam->result_ready = 1;
2312 }
2313
2314 static void vl_api_one_add_del_locator_set_reply_t_handler
2315   (vl_api_one_add_del_locator_set_reply_t * mp)
2316 {
2317   vat_main_t *vam = &vat_main;
2318   i32 retval = ntohl (mp->retval);
2319   if (vam->async_mode)
2320     {
2321       vam->async_errors += (retval < 0);
2322     }
2323   else
2324     {
2325       vam->retval = retval;
2326       vam->result_ready = 1;
2327     }
2328 }
2329
2330 static void vl_api_one_add_del_locator_set_reply_t_handler_json
2331   (vl_api_one_add_del_locator_set_reply_t * mp)
2332 {
2333   vat_main_t *vam = &vat_main;
2334   vat_json_node_t node;
2335
2336   vat_json_init_object (&node);
2337   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2338   vat_json_object_add_uint (&node, "locator_set_index", ntohl (mp->ls_index));
2339
2340   vat_json_print (vam->ofp, &node);
2341   vat_json_free (&node);
2342
2343   vam->retval = ntohl (mp->retval);
2344   vam->result_ready = 1;
2345 }
2346
2347 static void vl_api_vxlan_add_del_tunnel_reply_t_handler
2348   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
2349 {
2350   vat_main_t *vam = &vat_main;
2351   i32 retval = ntohl (mp->retval);
2352   if (vam->async_mode)
2353     {
2354       vam->async_errors += (retval < 0);
2355     }
2356   else
2357     {
2358       vam->retval = retval;
2359       vam->sw_if_index = ntohl (mp->sw_if_index);
2360       vam->result_ready = 1;
2361     }
2362   vam->regenerate_interface_table = 1;
2363 }
2364
2365 static void vl_api_vxlan_add_del_tunnel_reply_t_handler_json
2366   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
2367 {
2368   vat_main_t *vam = &vat_main;
2369   vat_json_node_t node;
2370
2371   vat_json_init_object (&node);
2372   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2373   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2374
2375   vat_json_print (vam->ofp, &node);
2376   vat_json_free (&node);
2377
2378   vam->retval = ntohl (mp->retval);
2379   vam->result_ready = 1;
2380 }
2381
2382 static void vl_api_vxlan_offload_rx_reply_t_handler
2383   (vl_api_vxlan_offload_rx_reply_t * mp)
2384 {
2385   vat_main_t *vam = &vat_main;
2386   i32 retval = ntohl (mp->retval);
2387   if (vam->async_mode)
2388     {
2389       vam->async_errors += (retval < 0);
2390     }
2391   else
2392     {
2393       vam->retval = retval;
2394       vam->result_ready = 1;
2395     }
2396 }
2397
2398 static void vl_api_vxlan_offload_rx_reply_t_handler_json
2399   (vl_api_vxlan_offload_rx_reply_t * mp)
2400 {
2401   vat_main_t *vam = &vat_main;
2402   vat_json_node_t node;
2403
2404   vat_json_init_object (&node);
2405   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2406
2407   vat_json_print (vam->ofp, &node);
2408   vat_json_free (&node);
2409
2410   vam->retval = ntohl (mp->retval);
2411   vam->result_ready = 1;
2412 }
2413
2414 static void vl_api_geneve_add_del_tunnel_reply_t_handler
2415   (vl_api_geneve_add_del_tunnel_reply_t * mp)
2416 {
2417   vat_main_t *vam = &vat_main;
2418   i32 retval = ntohl (mp->retval);
2419   if (vam->async_mode)
2420     {
2421       vam->async_errors += (retval < 0);
2422     }
2423   else
2424     {
2425       vam->retval = retval;
2426       vam->sw_if_index = ntohl (mp->sw_if_index);
2427       vam->result_ready = 1;
2428     }
2429 }
2430
2431 static void vl_api_geneve_add_del_tunnel_reply_t_handler_json
2432   (vl_api_geneve_add_del_tunnel_reply_t * mp)
2433 {
2434   vat_main_t *vam = &vat_main;
2435   vat_json_node_t node;
2436
2437   vat_json_init_object (&node);
2438   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2439   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2440
2441   vat_json_print (vam->ofp, &node);
2442   vat_json_free (&node);
2443
2444   vam->retval = ntohl (mp->retval);
2445   vam->result_ready = 1;
2446 }
2447
2448 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler
2449   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
2450 {
2451   vat_main_t *vam = &vat_main;
2452   i32 retval = ntohl (mp->retval);
2453   if (vam->async_mode)
2454     {
2455       vam->async_errors += (retval < 0);
2456     }
2457   else
2458     {
2459       vam->retval = retval;
2460       vam->sw_if_index = ntohl (mp->sw_if_index);
2461       vam->result_ready = 1;
2462     }
2463   vam->regenerate_interface_table = 1;
2464 }
2465
2466 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler_json
2467   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
2468 {
2469   vat_main_t *vam = &vat_main;
2470   vat_json_node_t node;
2471
2472   vat_json_init_object (&node);
2473   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2474   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2475
2476   vat_json_print (vam->ofp, &node);
2477   vat_json_free (&node);
2478
2479   vam->retval = ntohl (mp->retval);
2480   vam->result_ready = 1;
2481 }
2482
2483 static void vl_api_gre_tunnel_add_del_reply_t_handler
2484   (vl_api_gre_tunnel_add_del_reply_t * mp)
2485 {
2486   vat_main_t *vam = &vat_main;
2487   i32 retval = ntohl (mp->retval);
2488   if (vam->async_mode)
2489     {
2490       vam->async_errors += (retval < 0);
2491     }
2492   else
2493     {
2494       vam->retval = retval;
2495       vam->sw_if_index = ntohl (mp->sw_if_index);
2496       vam->result_ready = 1;
2497     }
2498 }
2499
2500 static void vl_api_gre_tunnel_add_del_reply_t_handler_json
2501   (vl_api_gre_tunnel_add_del_reply_t * mp)
2502 {
2503   vat_main_t *vam = &vat_main;
2504   vat_json_node_t node;
2505
2506   vat_json_init_object (&node);
2507   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2508   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2509
2510   vat_json_print (vam->ofp, &node);
2511   vat_json_free (&node);
2512
2513   vam->retval = ntohl (mp->retval);
2514   vam->result_ready = 1;
2515 }
2516
2517 static void vl_api_create_vhost_user_if_reply_t_handler
2518   (vl_api_create_vhost_user_if_reply_t * mp)
2519 {
2520   vat_main_t *vam = &vat_main;
2521   i32 retval = ntohl (mp->retval);
2522   if (vam->async_mode)
2523     {
2524       vam->async_errors += (retval < 0);
2525     }
2526   else
2527     {
2528       vam->retval = retval;
2529       vam->sw_if_index = ntohl (mp->sw_if_index);
2530       vam->result_ready = 1;
2531     }
2532   vam->regenerate_interface_table = 1;
2533 }
2534
2535 static void vl_api_create_vhost_user_if_reply_t_handler_json
2536   (vl_api_create_vhost_user_if_reply_t * mp)
2537 {
2538   vat_main_t *vam = &vat_main;
2539   vat_json_node_t node;
2540
2541   vat_json_init_object (&node);
2542   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2543   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2544
2545   vat_json_print (vam->ofp, &node);
2546   vat_json_free (&node);
2547
2548   vam->retval = ntohl (mp->retval);
2549   vam->result_ready = 1;
2550 }
2551
2552 static void vl_api_ip_address_details_t_handler
2553   (vl_api_ip_address_details_t * mp)
2554 {
2555   vat_main_t *vam = &vat_main;
2556   static ip_address_details_t empty_ip_address_details = { {0} };
2557   ip_address_details_t *address = NULL;
2558   ip_details_t *current_ip_details = NULL;
2559   ip_details_t *details = NULL;
2560
2561   details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
2562
2563   if (!details || vam->current_sw_if_index >= vec_len (details)
2564       || !details[vam->current_sw_if_index].present)
2565     {
2566       errmsg ("ip address details arrived but not stored");
2567       errmsg ("ip_dump should be called first");
2568       return;
2569     }
2570
2571   current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
2572
2573 #define addresses (current_ip_details->addr)
2574
2575   vec_validate_init_empty (addresses, vec_len (addresses),
2576                            empty_ip_address_details);
2577
2578   address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
2579
2580   clib_memcpy (&address->ip, &mp->prefix.address.un, sizeof (address->ip));
2581   address->prefix_length = mp->prefix.len;
2582 #undef addresses
2583 }
2584
2585 static void vl_api_ip_address_details_t_handler_json
2586   (vl_api_ip_address_details_t * mp)
2587 {
2588   vat_main_t *vam = &vat_main;
2589   vat_json_node_t *node = NULL;
2590
2591   if (VAT_JSON_ARRAY != vam->json_tree.type)
2592     {
2593       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2594       vat_json_init_array (&vam->json_tree);
2595     }
2596   node = vat_json_array_add (&vam->json_tree);
2597
2598   vat_json_init_object (node);
2599   vat_json_object_add_prefix (node, &mp->prefix);
2600 }
2601
2602 static void
2603 vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
2604 {
2605   vat_main_t *vam = &vat_main;
2606   static ip_details_t empty_ip_details = { 0 };
2607   ip_details_t *ip = NULL;
2608   u32 sw_if_index = ~0;
2609
2610   sw_if_index = ntohl (mp->sw_if_index);
2611
2612   vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2613                            sw_if_index, empty_ip_details);
2614
2615   ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2616                          sw_if_index);
2617
2618   ip->present = 1;
2619 }
2620
2621 static void
2622 vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
2623 {
2624   vat_main_t *vam = &vat_main;
2625
2626   if (VAT_JSON_ARRAY != vam->json_tree.type)
2627     {
2628       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2629       vat_json_init_array (&vam->json_tree);
2630     }
2631   vat_json_array_add_uint (&vam->json_tree,
2632                            clib_net_to_host_u32 (mp->sw_if_index));
2633 }
2634
2635 static void vl_api_get_first_msg_id_reply_t_handler
2636   (vl_api_get_first_msg_id_reply_t * mp)
2637 {
2638   vat_main_t *vam = &vat_main;
2639   i32 retval = ntohl (mp->retval);
2640
2641   if (vam->async_mode)
2642     {
2643       vam->async_errors += (retval < 0);
2644     }
2645   else
2646     {
2647       vam->retval = retval;
2648       vam->result_ready = 1;
2649     }
2650   if (retval >= 0)
2651     {
2652       errmsg ("first message id %d", ntohs (mp->first_msg_id));
2653     }
2654 }
2655
2656 static void vl_api_get_first_msg_id_reply_t_handler_json
2657   (vl_api_get_first_msg_id_reply_t * mp)
2658 {
2659   vat_main_t *vam = &vat_main;
2660   vat_json_node_t node;
2661
2662   vat_json_init_object (&node);
2663   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2664   vat_json_object_add_uint (&node, "first_msg_id",
2665                             (uint) ntohs (mp->first_msg_id));
2666
2667   vat_json_print (vam->ofp, &node);
2668   vat_json_free (&node);
2669
2670   vam->retval = ntohl (mp->retval);
2671   vam->result_ready = 1;
2672 }
2673
2674 static void vl_api_get_node_graph_reply_t_handler
2675   (vl_api_get_node_graph_reply_t * mp)
2676 {
2677   vat_main_t *vam = &vat_main;
2678   i32 retval = ntohl (mp->retval);
2679   u8 *pvt_copy, *reply;
2680   void *oldheap;
2681   vlib_node_t *node;
2682   int i;
2683
2684   if (vam->async_mode)
2685     {
2686       vam->async_errors += (retval < 0);
2687     }
2688   else
2689     {
2690       vam->retval = retval;
2691       vam->result_ready = 1;
2692     }
2693
2694   /* "Should never happen..." */
2695   if (retval != 0)
2696     return;
2697
2698   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2699   pvt_copy = vec_dup (reply);
2700
2701   /* Toss the shared-memory original... */
2702   oldheap = vl_msg_push_heap ();
2703
2704   vec_free (reply);
2705
2706   vl_msg_pop_heap (oldheap);
2707
2708   if (vam->graph_nodes)
2709     {
2710       hash_free (vam->graph_node_index_by_name);
2711
2712       for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
2713         {
2714           node = vam->graph_nodes[0][i];
2715           vec_free (node->name);
2716           vec_free (node->next_nodes);
2717           vec_free (node);
2718         }
2719       vec_free (vam->graph_nodes[0]);
2720       vec_free (vam->graph_nodes);
2721     }
2722
2723   vam->graph_node_index_by_name = hash_create_string (0, sizeof (uword));
2724   vam->graph_nodes = vlib_node_unserialize (pvt_copy);
2725   vec_free (pvt_copy);
2726
2727   for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
2728     {
2729       node = vam->graph_nodes[0][i];
2730       hash_set_mem (vam->graph_node_index_by_name, node->name, i);
2731     }
2732 }
2733
2734 static void vl_api_get_node_graph_reply_t_handler_json
2735   (vl_api_get_node_graph_reply_t * mp)
2736 {
2737   vat_main_t *vam = &vat_main;
2738   void *oldheap;
2739   vat_json_node_t node;
2740   u8 *reply;
2741
2742   /* $$$$ make this real? */
2743   vat_json_init_object (&node);
2744   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2745   vat_json_object_add_uint (&node, "reply_in_shmem", mp->reply_in_shmem);
2746
2747   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2748
2749   /* Toss the shared-memory original... */
2750   oldheap = vl_msg_push_heap ();
2751
2752   vec_free (reply);
2753
2754   vl_msg_pop_heap (oldheap);
2755
2756   vat_json_print (vam->ofp, &node);
2757   vat_json_free (&node);
2758
2759   vam->retval = ntohl (mp->retval);
2760   vam->result_ready = 1;
2761 }
2762
2763 static void
2764 vl_api_one_locator_details_t_handler (vl_api_one_locator_details_t * mp)
2765 {
2766   vat_main_t *vam = &vat_main;
2767   u8 *s = 0;
2768
2769   if (mp->local)
2770     {
2771       s = format (s, "%=16d%=16d%=16d",
2772                   ntohl (mp->sw_if_index), mp->priority, mp->weight);
2773     }
2774   else
2775     {
2776       s = format (s, "%=16U%=16d%=16d",
2777                   mp->is_ipv6 ? format_ip6_address :
2778                   format_ip4_address,
2779                   mp->ip_address, mp->priority, mp->weight);
2780     }
2781
2782   print (vam->ofp, "%v", s);
2783   vec_free (s);
2784 }
2785
2786 static void
2787 vl_api_one_locator_details_t_handler_json (vl_api_one_locator_details_t * mp)
2788 {
2789   vat_main_t *vam = &vat_main;
2790   vat_json_node_t *node = NULL;
2791   struct in6_addr ip6;
2792   struct in_addr ip4;
2793
2794   if (VAT_JSON_ARRAY != vam->json_tree.type)
2795     {
2796       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2797       vat_json_init_array (&vam->json_tree);
2798     }
2799   node = vat_json_array_add (&vam->json_tree);
2800   vat_json_init_object (node);
2801
2802   vat_json_object_add_uint (node, "local", mp->local ? 1 : 0);
2803   vat_json_object_add_uint (node, "priority", mp->priority);
2804   vat_json_object_add_uint (node, "weight", mp->weight);
2805
2806   if (mp->local)
2807     vat_json_object_add_uint (node, "sw_if_index",
2808                               clib_net_to_host_u32 (mp->sw_if_index));
2809   else
2810     {
2811       if (mp->is_ipv6)
2812         {
2813           clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2814           vat_json_object_add_ip6 (node, "address", ip6);
2815         }
2816       else
2817         {
2818           clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2819           vat_json_object_add_ip4 (node, "address", ip4);
2820         }
2821     }
2822 }
2823
2824 static void
2825 vl_api_one_locator_set_details_t_handler (vl_api_one_locator_set_details_t *
2826                                           mp)
2827 {
2828   vat_main_t *vam = &vat_main;
2829   u8 *ls_name = 0;
2830
2831   ls_name = format (0, "%s", mp->ls_name);
2832
2833   print (vam->ofp, "%=10d%=15v", clib_net_to_host_u32 (mp->ls_index),
2834          ls_name);
2835   vec_free (ls_name);
2836 }
2837
2838 static void
2839   vl_api_one_locator_set_details_t_handler_json
2840   (vl_api_one_locator_set_details_t * mp)
2841 {
2842   vat_main_t *vam = &vat_main;
2843   vat_json_node_t *node = 0;
2844   u8 *ls_name = 0;
2845
2846   ls_name = format (0, "%s", mp->ls_name);
2847   vec_add1 (ls_name, 0);
2848
2849   if (VAT_JSON_ARRAY != vam->json_tree.type)
2850     {
2851       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2852       vat_json_init_array (&vam->json_tree);
2853     }
2854   node = vat_json_array_add (&vam->json_tree);
2855
2856   vat_json_init_object (node);
2857   vat_json_object_add_string_copy (node, "ls_name", ls_name);
2858   vat_json_object_add_uint (node, "ls_index",
2859                             clib_net_to_host_u32 (mp->ls_index));
2860   vec_free (ls_name);
2861 }
2862
2863 typedef struct
2864 {
2865   u32 spi;
2866   u8 si;
2867 } __attribute__ ((__packed__)) lisp_nsh_api_t;
2868
2869 uword
2870 unformat_nsh_address (unformat_input_t * input, va_list * args)
2871 {
2872   lisp_nsh_api_t *nsh = va_arg (*args, lisp_nsh_api_t *);
2873   return unformat (input, "SPI:%d SI:%d", &nsh->spi, &nsh->si);
2874 }
2875
2876 u8 *
2877 format_nsh_address_vat (u8 * s, va_list * args)
2878 {
2879   nsh_t *a = va_arg (*args, nsh_t *);
2880   return format (s, "SPI:%d SI:%d", clib_net_to_host_u32 (a->spi), a->si);
2881 }
2882
2883 static u8 *
2884 format_lisp_flat_eid (u8 * s, va_list * args)
2885 {
2886   u32 type = va_arg (*args, u32);
2887   u8 *eid = va_arg (*args, u8 *);
2888   u32 eid_len = va_arg (*args, u32);
2889
2890   switch (type)
2891     {
2892     case 0:
2893       return format (s, "%U/%d", format_ip4_address, eid, eid_len);
2894     case 1:
2895       return format (s, "%U/%d", format_ip6_address, eid, eid_len);
2896     case 2:
2897       return format (s, "%U", format_ethernet_address, eid);
2898     case 3:
2899       return format (s, "%U", format_nsh_address_vat, eid);
2900     }
2901   return 0;
2902 }
2903
2904 static u8 *
2905 format_lisp_eid_vat (u8 * s, va_list * args)
2906 {
2907   u32 type = va_arg (*args, u32);
2908   u8 *eid = va_arg (*args, u8 *);
2909   u32 eid_len = va_arg (*args, u32);
2910   u8 *seid = va_arg (*args, u8 *);
2911   u32 seid_len = va_arg (*args, u32);
2912   u32 is_src_dst = va_arg (*args, u32);
2913
2914   if (is_src_dst)
2915     s = format (s, "%U|", format_lisp_flat_eid, type, seid, seid_len);
2916
2917   s = format (s, "%U", format_lisp_flat_eid, type, eid, eid_len);
2918
2919   return s;
2920 }
2921
2922 static void
2923 vl_api_one_eid_table_details_t_handler (vl_api_one_eid_table_details_t * mp)
2924 {
2925   vat_main_t *vam = &vat_main;
2926   u8 *s = 0, *eid = 0;
2927
2928   if (~0 == mp->locator_set_index)
2929     s = format (0, "action: %d", mp->action);
2930   else
2931     s = format (0, "%d", clib_net_to_host_u32 (mp->locator_set_index));
2932
2933   eid = format (0, "%U", format_lisp_eid_vat,
2934                 mp->eid_type,
2935                 mp->eid,
2936                 mp->eid_prefix_len,
2937                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
2938   vec_add1 (eid, 0);
2939
2940   print (vam->ofp, "[%d] %-35s%-20s%-30s%-20d%-20d%-10d%-20s",
2941          clib_net_to_host_u32 (mp->vni),
2942          eid,
2943          mp->is_local ? "local" : "remote",
2944          s, clib_net_to_host_u32 (mp->ttl), mp->authoritative,
2945          clib_net_to_host_u16 (mp->key_id), mp->key);
2946
2947   vec_free (s);
2948   vec_free (eid);
2949 }
2950
2951 static void
2952 vl_api_one_eid_table_details_t_handler_json (vl_api_one_eid_table_details_t
2953                                              * mp)
2954 {
2955   vat_main_t *vam = &vat_main;
2956   vat_json_node_t *node = 0;
2957   u8 *eid = 0;
2958
2959   if (VAT_JSON_ARRAY != vam->json_tree.type)
2960     {
2961       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2962       vat_json_init_array (&vam->json_tree);
2963     }
2964   node = vat_json_array_add (&vam->json_tree);
2965
2966   vat_json_init_object (node);
2967   if (~0 == mp->locator_set_index)
2968     vat_json_object_add_uint (node, "action", mp->action);
2969   else
2970     vat_json_object_add_uint (node, "locator_set_index",
2971                               clib_net_to_host_u32 (mp->locator_set_index));
2972
2973   vat_json_object_add_uint (node, "is_local", mp->is_local ? 1 : 0);
2974   if (mp->eid_type == 3)
2975     {
2976       vat_json_node_t *nsh_json = vat_json_object_add (node, "eid");
2977       vat_json_init_object (nsh_json);
2978       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) mp->eid;
2979       vat_json_object_add_uint (nsh_json, "spi",
2980                                 clib_net_to_host_u32 (nsh->spi));
2981       vat_json_object_add_uint (nsh_json, "si", nsh->si);
2982     }
2983   else
2984     {
2985       eid = format (0, "%U", format_lisp_eid_vat,
2986                     mp->eid_type,
2987                     mp->eid,
2988                     mp->eid_prefix_len,
2989                     mp->seid, mp->seid_prefix_len, mp->is_src_dst);
2990       vec_add1 (eid, 0);
2991       vat_json_object_add_string_copy (node, "eid", eid);
2992       vec_free (eid);
2993     }
2994   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2995   vat_json_object_add_uint (node, "ttl", clib_net_to_host_u32 (mp->ttl));
2996   vat_json_object_add_uint (node, "authoritative", (mp->authoritative));
2997
2998   if (mp->key_id)
2999     {
3000       vat_json_object_add_uint (node, "key_id",
3001                                 clib_net_to_host_u16 (mp->key_id));
3002       vat_json_object_add_string_copy (node, "key", mp->key);
3003     }
3004 }
3005
3006 static void
3007 vl_api_one_stats_details_t_handler (vl_api_one_stats_details_t * mp)
3008 {
3009   vat_main_t *vam = &vat_main;
3010   u8 *seid = 0, *deid = 0;
3011   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3012
3013   deid = format (0, "%U", format_lisp_eid_vat,
3014                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
3015
3016   seid = format (0, "%U", format_lisp_eid_vat,
3017                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
3018
3019   vec_add1 (deid, 0);
3020   vec_add1 (seid, 0);
3021
3022   if (mp->is_ip4)
3023     format_ip_address_fcn = format_ip4_address;
3024   else
3025     format_ip_address_fcn = format_ip6_address;
3026
3027
3028   print (vam->ofp, "([%d] %s %s) (%U %U) %u %u",
3029          clib_net_to_host_u32 (mp->vni),
3030          seid, deid,
3031          format_ip_address_fcn, mp->lloc,
3032          format_ip_address_fcn, mp->rloc,
3033          clib_net_to_host_u32 (mp->pkt_count),
3034          clib_net_to_host_u32 (mp->bytes));
3035
3036   vec_free (deid);
3037   vec_free (seid);
3038 }
3039
3040 static void
3041 vl_api_one_stats_details_t_handler_json (vl_api_one_stats_details_t * mp)
3042 {
3043   struct in6_addr ip6;
3044   struct in_addr ip4;
3045   vat_main_t *vam = &vat_main;
3046   vat_json_node_t *node = 0;
3047   u8 *deid = 0, *seid = 0;
3048
3049   if (VAT_JSON_ARRAY != vam->json_tree.type)
3050     {
3051       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3052       vat_json_init_array (&vam->json_tree);
3053     }
3054   node = vat_json_array_add (&vam->json_tree);
3055
3056   vat_json_init_object (node);
3057   deid = format (0, "%U", format_lisp_eid_vat,
3058                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
3059
3060   seid = format (0, "%U", format_lisp_eid_vat,
3061                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
3062
3063   vec_add1 (deid, 0);
3064   vec_add1 (seid, 0);
3065
3066   vat_json_object_add_string_copy (node, "seid", seid);
3067   vat_json_object_add_string_copy (node, "deid", deid);
3068   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3069
3070   if (mp->is_ip4)
3071     {
3072       clib_memcpy (&ip4, mp->lloc, sizeof (ip4));
3073       vat_json_object_add_ip4 (node, "lloc", ip4);
3074       clib_memcpy (&ip4, mp->rloc, sizeof (ip4));
3075       vat_json_object_add_ip4 (node, "rloc", ip4);
3076     }
3077   else
3078     {
3079       clib_memcpy (&ip6, mp->lloc, sizeof (ip6));
3080       vat_json_object_add_ip6 (node, "lloc", ip6);
3081       clib_memcpy (&ip6, mp->rloc, sizeof (ip6));
3082       vat_json_object_add_ip6 (node, "rloc", ip6);
3083     }
3084   vat_json_object_add_uint (node, "pkt_count",
3085                             clib_net_to_host_u32 (mp->pkt_count));
3086   vat_json_object_add_uint (node, "bytes", clib_net_to_host_u32 (mp->bytes));
3087
3088   vec_free (deid);
3089   vec_free (seid);
3090 }
3091
3092 static void
3093   vl_api_one_eid_table_map_details_t_handler
3094   (vl_api_one_eid_table_map_details_t * mp)
3095 {
3096   vat_main_t *vam = &vat_main;
3097
3098   u8 *line = format (0, "%=10d%=10d",
3099                      clib_net_to_host_u32 (mp->vni),
3100                      clib_net_to_host_u32 (mp->dp_table));
3101   print (vam->ofp, "%v", line);
3102   vec_free (line);
3103 }
3104
3105 static void
3106   vl_api_one_eid_table_map_details_t_handler_json
3107   (vl_api_one_eid_table_map_details_t * mp)
3108 {
3109   vat_main_t *vam = &vat_main;
3110   vat_json_node_t *node = NULL;
3111
3112   if (VAT_JSON_ARRAY != vam->json_tree.type)
3113     {
3114       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3115       vat_json_init_array (&vam->json_tree);
3116     }
3117   node = vat_json_array_add (&vam->json_tree);
3118   vat_json_init_object (node);
3119   vat_json_object_add_uint (node, "dp_table",
3120                             clib_net_to_host_u32 (mp->dp_table));
3121   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3122 }
3123
3124 static void
3125   vl_api_one_eid_table_vni_details_t_handler
3126   (vl_api_one_eid_table_vni_details_t * mp)
3127 {
3128   vat_main_t *vam = &vat_main;
3129
3130   u8 *line = format (0, "%d", clib_net_to_host_u32 (mp->vni));
3131   print (vam->ofp, "%v", line);
3132   vec_free (line);
3133 }
3134
3135 static void
3136   vl_api_one_eid_table_vni_details_t_handler_json
3137   (vl_api_one_eid_table_vni_details_t * mp)
3138 {
3139   vat_main_t *vam = &vat_main;
3140   vat_json_node_t *node = NULL;
3141
3142   if (VAT_JSON_ARRAY != vam->json_tree.type)
3143     {
3144       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3145       vat_json_init_array (&vam->json_tree);
3146     }
3147   node = vat_json_array_add (&vam->json_tree);
3148   vat_json_init_object (node);
3149   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3150 }
3151
3152 static void
3153   vl_api_show_one_map_register_fallback_threshold_reply_t_handler
3154   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
3155 {
3156   vat_main_t *vam = &vat_main;
3157   int retval = clib_net_to_host_u32 (mp->retval);
3158
3159   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
3160   print (vam->ofp, "fallback threshold value: %d", mp->value);
3161
3162   vam->retval = retval;
3163   vam->result_ready = 1;
3164 }
3165
3166 static void
3167   vl_api_show_one_map_register_fallback_threshold_reply_t_handler_json
3168   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
3169 {
3170   vat_main_t *vam = &vat_main;
3171   vat_json_node_t _node, *node = &_node;
3172   int retval = clib_net_to_host_u32 (mp->retval);
3173
3174   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
3175   vat_json_init_object (node);
3176   vat_json_object_add_uint (node, "value", mp->value);
3177
3178   vat_json_print (vam->ofp, node);
3179   vat_json_free (node);
3180
3181   vam->retval = retval;
3182   vam->result_ready = 1;
3183 }
3184
3185 static void
3186   vl_api_show_one_map_register_state_reply_t_handler
3187   (vl_api_show_one_map_register_state_reply_t * mp)
3188 {
3189   vat_main_t *vam = &vat_main;
3190   int retval = clib_net_to_host_u32 (mp->retval);
3191
3192   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
3193
3194   vam->retval = retval;
3195   vam->result_ready = 1;
3196 }
3197
3198 static void
3199   vl_api_show_one_map_register_state_reply_t_handler_json
3200   (vl_api_show_one_map_register_state_reply_t * mp)
3201 {
3202   vat_main_t *vam = &vat_main;
3203   vat_json_node_t _node, *node = &_node;
3204   int retval = clib_net_to_host_u32 (mp->retval);
3205
3206   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
3207
3208   vat_json_init_object (node);
3209   vat_json_object_add_string_copy (node, "state", s);
3210
3211   vat_json_print (vam->ofp, node);
3212   vat_json_free (node);
3213
3214   vam->retval = retval;
3215   vam->result_ready = 1;
3216   vec_free (s);
3217 }
3218
3219 static void
3220   vl_api_show_one_rloc_probe_state_reply_t_handler
3221   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3222 {
3223   vat_main_t *vam = &vat_main;
3224   int retval = clib_net_to_host_u32 (mp->retval);
3225
3226   if (retval)
3227     goto end;
3228
3229   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
3230 end:
3231   vam->retval = retval;
3232   vam->result_ready = 1;
3233 }
3234
3235 static void
3236   vl_api_show_one_rloc_probe_state_reply_t_handler_json
3237   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3238 {
3239   vat_main_t *vam = &vat_main;
3240   vat_json_node_t _node, *node = &_node;
3241   int retval = clib_net_to_host_u32 (mp->retval);
3242
3243   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
3244   vat_json_init_object (node);
3245   vat_json_object_add_string_copy (node, "state", s);
3246
3247   vat_json_print (vam->ofp, node);
3248   vat_json_free (node);
3249
3250   vam->retval = retval;
3251   vam->result_ready = 1;
3252   vec_free (s);
3253 }
3254
3255 static void
3256   vl_api_show_one_stats_enable_disable_reply_t_handler
3257   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3258 {
3259   vat_main_t *vam = &vat_main;
3260   int retval = clib_net_to_host_u32 (mp->retval);
3261
3262   if (retval)
3263     goto end;
3264
3265   print (vam->ofp, "%s", mp->is_en ? "enabled" : "disabled");
3266 end:
3267   vam->retval = retval;
3268   vam->result_ready = 1;
3269 }
3270
3271 static void
3272   vl_api_show_one_stats_enable_disable_reply_t_handler_json
3273   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3274 {
3275   vat_main_t *vam = &vat_main;
3276   vat_json_node_t _node, *node = &_node;
3277   int retval = clib_net_to_host_u32 (mp->retval);
3278
3279   u8 *s = format (0, "%s", mp->is_en ? "enabled" : "disabled");
3280   vat_json_init_object (node);
3281   vat_json_object_add_string_copy (node, "state", s);
3282
3283   vat_json_print (vam->ofp, node);
3284   vat_json_free (node);
3285
3286   vam->retval = retval;
3287   vam->result_ready = 1;
3288   vec_free (s);
3289 }
3290
3291 static void
3292 api_gpe_fwd_entry_net_to_host (vl_api_gpe_fwd_entry_t * e)
3293 {
3294   e->dp_table = clib_net_to_host_u32 (e->dp_table);
3295   e->fwd_entry_index = clib_net_to_host_u32 (e->fwd_entry_index);
3296   e->vni = clib_net_to_host_u32 (e->vni);
3297 }
3298
3299 static void
3300   gpe_fwd_entries_get_reply_t_net_to_host
3301   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3302 {
3303   u32 i;
3304
3305   mp->count = clib_net_to_host_u32 (mp->count);
3306   for (i = 0; i < mp->count; i++)
3307     {
3308       api_gpe_fwd_entry_net_to_host (&mp->entries[i]);
3309     }
3310 }
3311
3312 static u8 *
3313 format_gpe_encap_mode (u8 * s, va_list * args)
3314 {
3315   u32 mode = va_arg (*args, u32);
3316
3317   switch (mode)
3318     {
3319     case 0:
3320       return format (s, "lisp");
3321     case 1:
3322       return format (s, "vxlan");
3323     }
3324   return 0;
3325 }
3326
3327 static void
3328   vl_api_gpe_get_encap_mode_reply_t_handler
3329   (vl_api_gpe_get_encap_mode_reply_t * mp)
3330 {
3331   vat_main_t *vam = &vat_main;
3332
3333   print (vam->ofp, "gpe mode: %U", format_gpe_encap_mode, mp->encap_mode);
3334   vam->retval = ntohl (mp->retval);
3335   vam->result_ready = 1;
3336 }
3337
3338 static void
3339   vl_api_gpe_get_encap_mode_reply_t_handler_json
3340   (vl_api_gpe_get_encap_mode_reply_t * mp)
3341 {
3342   vat_main_t *vam = &vat_main;
3343   vat_json_node_t node;
3344
3345   u8 *encap_mode = format (0, "%U", format_gpe_encap_mode, mp->encap_mode);
3346   vec_add1 (encap_mode, 0);
3347
3348   vat_json_init_object (&node);
3349   vat_json_object_add_string_copy (&node, "gpe_mode", encap_mode);
3350
3351   vec_free (encap_mode);
3352   vat_json_print (vam->ofp, &node);
3353   vat_json_free (&node);
3354
3355   vam->retval = ntohl (mp->retval);
3356   vam->result_ready = 1;
3357 }
3358
3359 static void
3360   vl_api_gpe_fwd_entry_path_details_t_handler
3361   (vl_api_gpe_fwd_entry_path_details_t * mp)
3362 {
3363   vat_main_t *vam = &vat_main;
3364   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3365
3366   if (mp->lcl_loc.is_ip4)
3367     format_ip_address_fcn = format_ip4_address;
3368   else
3369     format_ip_address_fcn = format_ip6_address;
3370
3371   print (vam->ofp, "w:%d %30U %30U", mp->rmt_loc.weight,
3372          format_ip_address_fcn, &mp->lcl_loc,
3373          format_ip_address_fcn, &mp->rmt_loc);
3374 }
3375
3376 static void
3377 lisp_fill_locator_node (vat_json_node_t * n, vl_api_gpe_locator_t * loc)
3378 {
3379   struct in6_addr ip6;
3380   struct in_addr ip4;
3381
3382   if (loc->is_ip4)
3383     {
3384       clib_memcpy (&ip4, loc->addr, sizeof (ip4));
3385       vat_json_object_add_ip4 (n, "address", ip4);
3386     }
3387   else
3388     {
3389       clib_memcpy (&ip6, loc->addr, sizeof (ip6));
3390       vat_json_object_add_ip6 (n, "address", ip6);
3391     }
3392   vat_json_object_add_uint (n, "weight", loc->weight);
3393 }
3394
3395 static void
3396   vl_api_gpe_fwd_entry_path_details_t_handler_json
3397   (vl_api_gpe_fwd_entry_path_details_t * mp)
3398 {
3399   vat_main_t *vam = &vat_main;
3400   vat_json_node_t *node = NULL;
3401   vat_json_node_t *loc_node;
3402
3403   if (VAT_JSON_ARRAY != vam->json_tree.type)
3404     {
3405       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3406       vat_json_init_array (&vam->json_tree);
3407     }
3408   node = vat_json_array_add (&vam->json_tree);
3409   vat_json_init_object (node);
3410
3411   loc_node = vat_json_object_add (node, "local_locator");
3412   vat_json_init_object (loc_node);
3413   lisp_fill_locator_node (loc_node, &mp->lcl_loc);
3414
3415   loc_node = vat_json_object_add (node, "remote_locator");
3416   vat_json_init_object (loc_node);
3417   lisp_fill_locator_node (loc_node, &mp->rmt_loc);
3418 }
3419
3420 static void
3421   vl_api_gpe_fwd_entries_get_reply_t_handler
3422   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3423 {
3424   vat_main_t *vam = &vat_main;
3425   u32 i;
3426   int retval = clib_net_to_host_u32 (mp->retval);
3427   vl_api_gpe_fwd_entry_t *e;
3428
3429   if (retval)
3430     goto end;
3431
3432   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3433
3434   for (i = 0; i < mp->count; i++)
3435     {
3436       e = &mp->entries[i];
3437       print (vam->ofp, "%10d %10d %U %40U", e->fwd_entry_index, e->dp_table,
3438              format_lisp_flat_eid, e->eid_type, e->leid, e->leid_prefix_len,
3439              format_lisp_flat_eid, e->eid_type, e->reid, e->reid_prefix_len);
3440     }
3441
3442 end:
3443   vam->retval = retval;
3444   vam->result_ready = 1;
3445 }
3446
3447 static void
3448   vl_api_gpe_fwd_entries_get_reply_t_handler_json
3449   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3450 {
3451   u8 *s = 0;
3452   vat_main_t *vam = &vat_main;
3453   vat_json_node_t *e = 0, root;
3454   u32 i;
3455   int retval = clib_net_to_host_u32 (mp->retval);
3456   vl_api_gpe_fwd_entry_t *fwd;
3457
3458   if (retval)
3459     goto end;
3460
3461   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3462   vat_json_init_array (&root);
3463
3464   for (i = 0; i < mp->count; i++)
3465     {
3466       e = vat_json_array_add (&root);
3467       fwd = &mp->entries[i];
3468
3469       vat_json_init_object (e);
3470       vat_json_object_add_int (e, "fwd_entry_index", fwd->fwd_entry_index);
3471       vat_json_object_add_int (e, "dp_table", fwd->dp_table);
3472       vat_json_object_add_int (e, "vni", fwd->vni);
3473       vat_json_object_add_int (e, "action", fwd->action);
3474
3475       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->leid,
3476                   fwd->leid_prefix_len);
3477       vec_add1 (s, 0);
3478       vat_json_object_add_string_copy (e, "leid", s);
3479       vec_free (s);
3480
3481       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->reid,
3482                   fwd->reid_prefix_len);
3483       vec_add1 (s, 0);
3484       vat_json_object_add_string_copy (e, "reid", s);
3485       vec_free (s);
3486     }
3487
3488   vat_json_print (vam->ofp, &root);
3489   vat_json_free (&root);
3490
3491 end:
3492   vam->retval = retval;
3493   vam->result_ready = 1;
3494 }
3495
3496 static void
3497   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler
3498   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3499 {
3500   vat_main_t *vam = &vat_main;
3501   u32 i, n;
3502   int retval = clib_net_to_host_u32 (mp->retval);
3503   vl_api_gpe_native_fwd_rpath_t *r;
3504
3505   if (retval)
3506     goto end;
3507
3508   n = clib_net_to_host_u32 (mp->count);
3509
3510   for (i = 0; i < n; i++)
3511     {
3512       r = &mp->entries[i];
3513       print (vam->ofp, "fib_index: %d sw_if_index %d nh %U",
3514              clib_net_to_host_u32 (r->fib_index),
3515              clib_net_to_host_u32 (r->nh_sw_if_index),
3516              r->is_ip4 ? format_ip4_address : format_ip6_address, r->nh_addr);
3517     }
3518
3519 end:
3520   vam->retval = retval;
3521   vam->result_ready = 1;
3522 }
3523
3524 static void
3525   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler_json
3526   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3527 {
3528   vat_main_t *vam = &vat_main;
3529   vat_json_node_t root, *e;
3530   u32 i, n;
3531   int retval = clib_net_to_host_u32 (mp->retval);
3532   vl_api_gpe_native_fwd_rpath_t *r;
3533   u8 *s;
3534
3535   if (retval)
3536     goto end;
3537
3538   n = clib_net_to_host_u32 (mp->count);
3539   vat_json_init_array (&root);
3540
3541   for (i = 0; i < n; i++)
3542     {
3543       e = vat_json_array_add (&root);
3544       vat_json_init_object (e);
3545       r = &mp->entries[i];
3546       s =
3547         format (0, "%U", r->is_ip4 ? format_ip4_address : format_ip6_address,
3548                 r->nh_addr);
3549       vec_add1 (s, 0);
3550       vat_json_object_add_string_copy (e, "ip4", s);
3551       vec_free (s);
3552
3553       vat_json_object_add_uint (e, "fib_index",
3554                                 clib_net_to_host_u32 (r->fib_index));
3555       vat_json_object_add_uint (e, "nh_sw_if_index",
3556                                 clib_net_to_host_u32 (r->nh_sw_if_index));
3557     }
3558
3559   vat_json_print (vam->ofp, &root);
3560   vat_json_free (&root);
3561
3562 end:
3563   vam->retval = retval;
3564   vam->result_ready = 1;
3565 }
3566
3567 static void
3568   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler
3569   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3570 {
3571   vat_main_t *vam = &vat_main;
3572   u32 i, n;
3573   int retval = clib_net_to_host_u32 (mp->retval);
3574
3575   if (retval)
3576     goto end;
3577
3578   n = clib_net_to_host_u32 (mp->count);
3579
3580   for (i = 0; i < n; i++)
3581     print (vam->ofp, "%d", clib_net_to_host_u32 (mp->vnis[i]));
3582
3583 end:
3584   vam->retval = retval;
3585   vam->result_ready = 1;
3586 }
3587
3588 static void
3589   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler_json
3590   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3591 {
3592   vat_main_t *vam = &vat_main;
3593   vat_json_node_t root;
3594   u32 i, n;
3595   int retval = clib_net_to_host_u32 (mp->retval);
3596
3597   if (retval)
3598     goto end;
3599
3600   n = clib_net_to_host_u32 (mp->count);
3601   vat_json_init_array (&root);
3602
3603   for (i = 0; i < n; i++)
3604     vat_json_array_add_uint (&root, clib_net_to_host_u32 (mp->vnis[i]));
3605
3606   vat_json_print (vam->ofp, &root);
3607   vat_json_free (&root);
3608
3609 end:
3610   vam->retval = retval;
3611   vam->result_ready = 1;
3612 }
3613
3614 static void
3615   vl_api_one_ndp_entries_get_reply_t_handler
3616   (vl_api_one_ndp_entries_get_reply_t * mp)
3617 {
3618   vat_main_t *vam = &vat_main;
3619   u32 i, n;
3620   int retval = clib_net_to_host_u32 (mp->retval);
3621
3622   if (retval)
3623     goto end;
3624
3625   n = clib_net_to_host_u32 (mp->count);
3626
3627   for (i = 0; i < n; i++)
3628     print (vam->ofp, "%U -> %U", format_ip6_address, &mp->entries[i].ip6,
3629            format_ethernet_address, mp->entries[i].mac);
3630
3631 end:
3632   vam->retval = retval;
3633   vam->result_ready = 1;
3634 }
3635
3636 static void
3637   vl_api_one_ndp_entries_get_reply_t_handler_json
3638   (vl_api_one_ndp_entries_get_reply_t * mp)
3639 {
3640   u8 *s = 0;
3641   vat_main_t *vam = &vat_main;
3642   vat_json_node_t *e = 0, root;
3643   u32 i, n;
3644   int retval = clib_net_to_host_u32 (mp->retval);
3645   vl_api_one_ndp_entry_t *arp_entry;
3646
3647   if (retval)
3648     goto end;
3649
3650   n = clib_net_to_host_u32 (mp->count);
3651   vat_json_init_array (&root);
3652
3653   for (i = 0; i < n; i++)
3654     {
3655       e = vat_json_array_add (&root);
3656       arp_entry = &mp->entries[i];
3657
3658       vat_json_init_object (e);
3659       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
3660       vec_add1 (s, 0);
3661
3662       vat_json_object_add_string_copy (e, "mac", s);
3663       vec_free (s);
3664
3665       s = format (0, "%U", format_ip6_address, &arp_entry->ip6);
3666       vec_add1 (s, 0);
3667       vat_json_object_add_string_copy (e, "ip6", s);
3668       vec_free (s);
3669     }
3670
3671   vat_json_print (vam->ofp, &root);
3672   vat_json_free (&root);
3673
3674 end:
3675   vam->retval = retval;
3676   vam->result_ready = 1;
3677 }
3678
3679 static void
3680   vl_api_one_l2_arp_entries_get_reply_t_handler
3681   (vl_api_one_l2_arp_entries_get_reply_t * mp)
3682 {
3683   vat_main_t *vam = &vat_main;
3684   u32 i, n;
3685   int retval = clib_net_to_host_u32 (mp->retval);
3686
3687   if (retval)
3688     goto end;
3689
3690   n = clib_net_to_host_u32 (mp->count);
3691
3692   for (i = 0; i < n; i++)
3693     print (vam->ofp, "%U -> %U", format_ip4_address, &mp->entries[i].ip4,
3694            format_ethernet_address, mp->entries[i].mac);
3695
3696 end:
3697   vam->retval = retval;
3698   vam->result_ready = 1;
3699 }
3700
3701 static void
3702   vl_api_one_l2_arp_entries_get_reply_t_handler_json
3703   (vl_api_one_l2_arp_entries_get_reply_t * mp)
3704 {
3705   u8 *s = 0;
3706   vat_main_t *vam = &vat_main;
3707   vat_json_node_t *e = 0, root;
3708   u32 i, n;
3709   int retval = clib_net_to_host_u32 (mp->retval);
3710   vl_api_one_l2_arp_entry_t *arp_entry;
3711
3712   if (retval)
3713     goto end;
3714
3715   n = clib_net_to_host_u32 (mp->count);
3716   vat_json_init_array (&root);
3717
3718   for (i = 0; i < n; i++)
3719     {
3720       e = vat_json_array_add (&root);
3721       arp_entry = &mp->entries[i];
3722
3723       vat_json_init_object (e);
3724       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
3725       vec_add1 (s, 0);
3726
3727       vat_json_object_add_string_copy (e, "mac", s);
3728       vec_free (s);
3729
3730       s = format (0, "%U", format_ip4_address, &arp_entry->ip4);
3731       vec_add1 (s, 0);
3732       vat_json_object_add_string_copy (e, "ip4", s);
3733       vec_free (s);
3734     }
3735
3736   vat_json_print (vam->ofp, &root);
3737   vat_json_free (&root);
3738
3739 end:
3740   vam->retval = retval;
3741   vam->result_ready = 1;
3742 }
3743
3744 static void
3745 vl_api_one_ndp_bd_get_reply_t_handler (vl_api_one_ndp_bd_get_reply_t * mp)
3746 {
3747   vat_main_t *vam = &vat_main;
3748   u32 i, n;
3749   int retval = clib_net_to_host_u32 (mp->retval);
3750
3751   if (retval)
3752     goto end;
3753
3754   n = clib_net_to_host_u32 (mp->count);
3755
3756   for (i = 0; i < n; i++)
3757     {
3758       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
3759     }
3760
3761 end:
3762   vam->retval = retval;
3763   vam->result_ready = 1;
3764 }
3765
3766 static void
3767   vl_api_one_ndp_bd_get_reply_t_handler_json
3768   (vl_api_one_ndp_bd_get_reply_t * mp)
3769 {
3770   vat_main_t *vam = &vat_main;
3771   vat_json_node_t root;
3772   u32 i, n;
3773   int retval = clib_net_to_host_u32 (mp->retval);
3774
3775   if (retval)
3776     goto end;
3777
3778   n = clib_net_to_host_u32 (mp->count);
3779   vat_json_init_array (&root);
3780
3781   for (i = 0; i < n; i++)
3782     {
3783       vat_json_array_add_uint (&root,
3784                                clib_net_to_host_u32 (mp->bridge_domains[i]));
3785     }
3786
3787   vat_json_print (vam->ofp, &root);
3788   vat_json_free (&root);
3789
3790 end:
3791   vam->retval = retval;
3792   vam->result_ready = 1;
3793 }
3794
3795 static void
3796   vl_api_one_l2_arp_bd_get_reply_t_handler
3797   (vl_api_one_l2_arp_bd_get_reply_t * mp)
3798 {
3799   vat_main_t *vam = &vat_main;
3800   u32 i, n;
3801   int retval = clib_net_to_host_u32 (mp->retval);
3802
3803   if (retval)
3804     goto end;
3805
3806   n = clib_net_to_host_u32 (mp->count);
3807
3808   for (i = 0; i < n; i++)
3809     {
3810       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
3811     }
3812
3813 end:
3814   vam->retval = retval;
3815   vam->result_ready = 1;
3816 }
3817
3818 static void
3819   vl_api_one_l2_arp_bd_get_reply_t_handler_json
3820   (vl_api_one_l2_arp_bd_get_reply_t * mp)
3821 {
3822   vat_main_t *vam = &vat_main;
3823   vat_json_node_t root;
3824   u32 i, n;
3825   int retval = clib_net_to_host_u32 (mp->retval);
3826
3827   if (retval)
3828     goto end;
3829
3830   n = clib_net_to_host_u32 (mp->count);
3831   vat_json_init_array (&root);
3832
3833   for (i = 0; i < n; i++)
3834     {
3835       vat_json_array_add_uint (&root,
3836                                clib_net_to_host_u32 (mp->bridge_domains[i]));
3837     }
3838
3839   vat_json_print (vam->ofp, &root);
3840   vat_json_free (&root);
3841
3842 end:
3843   vam->retval = retval;
3844   vam->result_ready = 1;
3845 }
3846
3847 static void
3848   vl_api_one_adjacencies_get_reply_t_handler
3849   (vl_api_one_adjacencies_get_reply_t * mp)
3850 {
3851   vat_main_t *vam = &vat_main;
3852   u32 i, n;
3853   int retval = clib_net_to_host_u32 (mp->retval);
3854   vl_api_one_adjacency_t *a;
3855
3856   if (retval)
3857     goto end;
3858
3859   n = clib_net_to_host_u32 (mp->count);
3860
3861   for (i = 0; i < n; i++)
3862     {
3863       a = &mp->adjacencies[i];
3864       print (vam->ofp, "%U %40U",
3865              format_lisp_flat_eid, a->eid_type, a->leid, a->leid_prefix_len,
3866              format_lisp_flat_eid, a->eid_type, a->reid, a->reid_prefix_len);
3867     }
3868
3869 end:
3870   vam->retval = retval;
3871   vam->result_ready = 1;
3872 }
3873
3874 static void
3875   vl_api_one_adjacencies_get_reply_t_handler_json
3876   (vl_api_one_adjacencies_get_reply_t * mp)
3877 {
3878   u8 *s = 0;
3879   vat_main_t *vam = &vat_main;
3880   vat_json_node_t *e = 0, root;
3881   u32 i, n;
3882   int retval = clib_net_to_host_u32 (mp->retval);
3883   vl_api_one_adjacency_t *a;
3884
3885   if (retval)
3886     goto end;
3887
3888   n = clib_net_to_host_u32 (mp->count);
3889   vat_json_init_array (&root);
3890
3891   for (i = 0; i < n; i++)
3892     {
3893       e = vat_json_array_add (&root);
3894       a = &mp->adjacencies[i];
3895
3896       vat_json_init_object (e);
3897       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->leid,
3898                   a->leid_prefix_len);
3899       vec_add1 (s, 0);
3900       vat_json_object_add_string_copy (e, "leid", s);
3901       vec_free (s);
3902
3903       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->reid,
3904                   a->reid_prefix_len);
3905       vec_add1 (s, 0);
3906       vat_json_object_add_string_copy (e, "reid", s);
3907       vec_free (s);
3908     }
3909
3910   vat_json_print (vam->ofp, &root);
3911   vat_json_free (&root);
3912
3913 end:
3914   vam->retval = retval;
3915   vam->result_ready = 1;
3916 }
3917
3918 static void
3919 vl_api_one_map_server_details_t_handler (vl_api_one_map_server_details_t * mp)
3920 {
3921   vat_main_t *vam = &vat_main;
3922
3923   print (vam->ofp, "%=20U",
3924          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
3925          mp->ip_address);
3926 }
3927
3928 static void
3929   vl_api_one_map_server_details_t_handler_json
3930   (vl_api_one_map_server_details_t * mp)
3931 {
3932   vat_main_t *vam = &vat_main;
3933   vat_json_node_t *node = NULL;
3934   struct in6_addr ip6;
3935   struct in_addr ip4;
3936
3937   if (VAT_JSON_ARRAY != vam->json_tree.type)
3938     {
3939       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3940       vat_json_init_array (&vam->json_tree);
3941     }
3942   node = vat_json_array_add (&vam->json_tree);
3943
3944   vat_json_init_object (node);
3945   if (mp->is_ipv6)
3946     {
3947       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
3948       vat_json_object_add_ip6 (node, "map-server", ip6);
3949     }
3950   else
3951     {
3952       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
3953       vat_json_object_add_ip4 (node, "map-server", ip4);
3954     }
3955 }
3956
3957 static void
3958 vl_api_one_map_resolver_details_t_handler (vl_api_one_map_resolver_details_t
3959                                            * mp)
3960 {
3961   vat_main_t *vam = &vat_main;
3962
3963   print (vam->ofp, "%=20U",
3964          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
3965          mp->ip_address);
3966 }
3967
3968 static void
3969   vl_api_one_map_resolver_details_t_handler_json
3970   (vl_api_one_map_resolver_details_t * mp)
3971 {
3972   vat_main_t *vam = &vat_main;
3973   vat_json_node_t *node = NULL;
3974   struct in6_addr ip6;
3975   struct in_addr ip4;
3976
3977   if (VAT_JSON_ARRAY != vam->json_tree.type)
3978     {
3979       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3980       vat_json_init_array (&vam->json_tree);
3981     }
3982   node = vat_json_array_add (&vam->json_tree);
3983
3984   vat_json_init_object (node);
3985   if (mp->is_ipv6)
3986     {
3987       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
3988       vat_json_object_add_ip6 (node, "map resolver", ip6);
3989     }
3990   else
3991     {
3992       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
3993       vat_json_object_add_ip4 (node, "map resolver", ip4);
3994     }
3995 }
3996
3997 static void
3998 vl_api_show_one_status_reply_t_handler (vl_api_show_one_status_reply_t * mp)
3999 {
4000   vat_main_t *vam = &vat_main;
4001   i32 retval = ntohl (mp->retval);
4002
4003   if (0 <= retval)
4004     {
4005       print (vam->ofp, "feature: %s\ngpe: %s",
4006              mp->feature_status ? "enabled" : "disabled",
4007              mp->gpe_status ? "enabled" : "disabled");
4008     }
4009
4010   vam->retval = retval;
4011   vam->result_ready = 1;
4012 }
4013
4014 static void
4015   vl_api_show_one_status_reply_t_handler_json
4016   (vl_api_show_one_status_reply_t * mp)
4017 {
4018   vat_main_t *vam = &vat_main;
4019   vat_json_node_t node;
4020   u8 *gpe_status = NULL;
4021   u8 *feature_status = NULL;
4022
4023   gpe_status = format (0, "%s", mp->gpe_status ? "enabled" : "disabled");
4024   feature_status = format (0, "%s",
4025                            mp->feature_status ? "enabled" : "disabled");
4026   vec_add1 (gpe_status, 0);
4027   vec_add1 (feature_status, 0);
4028
4029   vat_json_init_object (&node);
4030   vat_json_object_add_string_copy (&node, "gpe_status", gpe_status);
4031   vat_json_object_add_string_copy (&node, "feature_status", feature_status);
4032
4033   vec_free (gpe_status);
4034   vec_free (feature_status);
4035
4036   vat_json_print (vam->ofp, &node);
4037   vat_json_free (&node);
4038
4039   vam->retval = ntohl (mp->retval);
4040   vam->result_ready = 1;
4041 }
4042
4043 static void
4044   vl_api_one_get_map_request_itr_rlocs_reply_t_handler
4045   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
4046 {
4047   vat_main_t *vam = &vat_main;
4048   i32 retval = ntohl (mp->retval);
4049
4050   if (retval >= 0)
4051     {
4052       print (vam->ofp, "%=20s", mp->locator_set_name);
4053     }
4054
4055   vam->retval = retval;
4056   vam->result_ready = 1;
4057 }
4058
4059 static void
4060   vl_api_one_get_map_request_itr_rlocs_reply_t_handler_json
4061   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
4062 {
4063   vat_main_t *vam = &vat_main;
4064   vat_json_node_t *node = NULL;
4065
4066   if (VAT_JSON_ARRAY != vam->json_tree.type)
4067     {
4068       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4069       vat_json_init_array (&vam->json_tree);
4070     }
4071   node = vat_json_array_add (&vam->json_tree);
4072
4073   vat_json_init_object (node);
4074   vat_json_object_add_string_copy (node, "itr-rlocs", mp->locator_set_name);
4075
4076   vat_json_print (vam->ofp, node);
4077   vat_json_free (node);
4078
4079   vam->retval = ntohl (mp->retval);
4080   vam->result_ready = 1;
4081 }
4082
4083 static u8 *
4084 format_lisp_map_request_mode (u8 * s, va_list * args)
4085 {
4086   u32 mode = va_arg (*args, u32);
4087
4088   switch (mode)
4089     {
4090     case 0:
4091       return format (0, "dst-only");
4092     case 1:
4093       return format (0, "src-dst");
4094     }
4095   return 0;
4096 }
4097
4098 static void
4099   vl_api_show_one_map_request_mode_reply_t_handler
4100   (vl_api_show_one_map_request_mode_reply_t * mp)
4101 {
4102   vat_main_t *vam = &vat_main;
4103   i32 retval = ntohl (mp->retval);
4104
4105   if (0 <= retval)
4106     {
4107       u32 mode = mp->mode;
4108       print (vam->ofp, "map_request_mode: %U",
4109              format_lisp_map_request_mode, mode);
4110     }
4111
4112   vam->retval = retval;
4113   vam->result_ready = 1;
4114 }
4115
4116 static void
4117   vl_api_show_one_map_request_mode_reply_t_handler_json
4118   (vl_api_show_one_map_request_mode_reply_t * mp)
4119 {
4120   vat_main_t *vam = &vat_main;
4121   vat_json_node_t node;
4122   u8 *s = 0;
4123   u32 mode;
4124
4125   mode = mp->mode;
4126   s = format (0, "%U", format_lisp_map_request_mode, mode);
4127   vec_add1 (s, 0);
4128
4129   vat_json_init_object (&node);
4130   vat_json_object_add_string_copy (&node, "map_request_mode", s);
4131   vat_json_print (vam->ofp, &node);
4132   vat_json_free (&node);
4133
4134   vec_free (s);
4135   vam->retval = ntohl (mp->retval);
4136   vam->result_ready = 1;
4137 }
4138
4139 static void
4140   vl_api_one_show_xtr_mode_reply_t_handler
4141   (vl_api_one_show_xtr_mode_reply_t * mp)
4142 {
4143   vat_main_t *vam = &vat_main;
4144   i32 retval = ntohl (mp->retval);
4145
4146   if (0 <= retval)
4147     {
4148       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4149     }
4150
4151   vam->retval = retval;
4152   vam->result_ready = 1;
4153 }
4154
4155 static void
4156   vl_api_one_show_xtr_mode_reply_t_handler_json
4157   (vl_api_one_show_xtr_mode_reply_t * mp)
4158 {
4159   vat_main_t *vam = &vat_main;
4160   vat_json_node_t node;
4161   u8 *status = 0;
4162
4163   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4164   vec_add1 (status, 0);
4165
4166   vat_json_init_object (&node);
4167   vat_json_object_add_string_copy (&node, "status", status);
4168
4169   vec_free (status);
4170
4171   vat_json_print (vam->ofp, &node);
4172   vat_json_free (&node);
4173
4174   vam->retval = ntohl (mp->retval);
4175   vam->result_ready = 1;
4176 }
4177
4178 static void
4179   vl_api_one_show_pitr_mode_reply_t_handler
4180   (vl_api_one_show_pitr_mode_reply_t * mp)
4181 {
4182   vat_main_t *vam = &vat_main;
4183   i32 retval = ntohl (mp->retval);
4184
4185   if (0 <= retval)
4186     {
4187       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4188     }
4189
4190   vam->retval = retval;
4191   vam->result_ready = 1;
4192 }
4193
4194 static void
4195   vl_api_one_show_pitr_mode_reply_t_handler_json
4196   (vl_api_one_show_pitr_mode_reply_t * mp)
4197 {
4198   vat_main_t *vam = &vat_main;
4199   vat_json_node_t node;
4200   u8 *status = 0;
4201
4202   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4203   vec_add1 (status, 0);
4204
4205   vat_json_init_object (&node);
4206   vat_json_object_add_string_copy (&node, "status", status);
4207
4208   vec_free (status);
4209
4210   vat_json_print (vam->ofp, &node);
4211   vat_json_free (&node);
4212
4213   vam->retval = ntohl (mp->retval);
4214   vam->result_ready = 1;
4215 }
4216
4217 static void
4218   vl_api_one_show_petr_mode_reply_t_handler
4219   (vl_api_one_show_petr_mode_reply_t * mp)
4220 {
4221   vat_main_t *vam = &vat_main;
4222   i32 retval = ntohl (mp->retval);
4223
4224   if (0 <= retval)
4225     {
4226       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4227     }
4228
4229   vam->retval = retval;
4230   vam->result_ready = 1;
4231 }
4232
4233 static void
4234   vl_api_one_show_petr_mode_reply_t_handler_json
4235   (vl_api_one_show_petr_mode_reply_t * mp)
4236 {
4237   vat_main_t *vam = &vat_main;
4238   vat_json_node_t node;
4239   u8 *status = 0;
4240
4241   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4242   vec_add1 (status, 0);
4243
4244   vat_json_init_object (&node);
4245   vat_json_object_add_string_copy (&node, "status", status);
4246
4247   vec_free (status);
4248
4249   vat_json_print (vam->ofp, &node);
4250   vat_json_free (&node);
4251
4252   vam->retval = ntohl (mp->retval);
4253   vam->result_ready = 1;
4254 }
4255
4256 static void
4257   vl_api_show_one_use_petr_reply_t_handler
4258   (vl_api_show_one_use_petr_reply_t * mp)
4259 {
4260   vat_main_t *vam = &vat_main;
4261   i32 retval = ntohl (mp->retval);
4262
4263   if (0 <= retval)
4264     {
4265       print (vam->ofp, "%s\n", mp->status ? "enabled" : "disabled");
4266       if (mp->status)
4267         {
4268           print (vam->ofp, "Proxy-ETR address; %U",
4269                  mp->is_ip4 ? format_ip4_address : format_ip6_address,
4270                  mp->address);
4271         }
4272     }
4273
4274   vam->retval = retval;
4275   vam->result_ready = 1;
4276 }
4277
4278 static void
4279   vl_api_show_one_use_petr_reply_t_handler_json
4280   (vl_api_show_one_use_petr_reply_t * mp)
4281 {
4282   vat_main_t *vam = &vat_main;
4283   vat_json_node_t node;
4284   u8 *status = 0;
4285   struct in_addr ip4;
4286   struct in6_addr ip6;
4287
4288   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4289   vec_add1 (status, 0);
4290
4291   vat_json_init_object (&node);
4292   vat_json_object_add_string_copy (&node, "status", status);
4293   if (mp->status)
4294     {
4295       if (mp->is_ip4)
4296         {
4297           clib_memcpy (&ip6, mp->address, sizeof (ip6));
4298           vat_json_object_add_ip6 (&node, "address", ip6);
4299         }
4300       else
4301         {
4302           clib_memcpy (&ip4, mp->address, sizeof (ip4));
4303           vat_json_object_add_ip4 (&node, "address", ip4);
4304         }
4305     }
4306
4307   vec_free (status);
4308
4309   vat_json_print (vam->ofp, &node);
4310   vat_json_free (&node);
4311
4312   vam->retval = ntohl (mp->retval);
4313   vam->result_ready = 1;
4314 }
4315
4316 static void
4317   vl_api_show_one_nsh_mapping_reply_t_handler
4318   (vl_api_show_one_nsh_mapping_reply_t * mp)
4319 {
4320   vat_main_t *vam = &vat_main;
4321   i32 retval = ntohl (mp->retval);
4322
4323   if (0 <= retval)
4324     {
4325       print (vam->ofp, "%-20s%-16s",
4326              mp->is_set ? "set" : "not-set",
4327              mp->is_set ? (char *) mp->locator_set_name : "");
4328     }
4329
4330   vam->retval = retval;
4331   vam->result_ready = 1;
4332 }
4333
4334 static void
4335   vl_api_show_one_nsh_mapping_reply_t_handler_json
4336   (vl_api_show_one_nsh_mapping_reply_t * mp)
4337 {
4338   vat_main_t *vam = &vat_main;
4339   vat_json_node_t node;
4340   u8 *status = 0;
4341
4342   status = format (0, "%s", mp->is_set ? "yes" : "no");
4343   vec_add1 (status, 0);
4344
4345   vat_json_init_object (&node);
4346   vat_json_object_add_string_copy (&node, "is_set", status);
4347   if (mp->is_set)
4348     {
4349       vat_json_object_add_string_copy (&node, "locator_set",
4350                                        mp->locator_set_name);
4351     }
4352
4353   vec_free (status);
4354
4355   vat_json_print (vam->ofp, &node);
4356   vat_json_free (&node);
4357
4358   vam->retval = ntohl (mp->retval);
4359   vam->result_ready = 1;
4360 }
4361
4362 static void
4363   vl_api_show_one_map_register_ttl_reply_t_handler
4364   (vl_api_show_one_map_register_ttl_reply_t * mp)
4365 {
4366   vat_main_t *vam = &vat_main;
4367   i32 retval = ntohl (mp->retval);
4368
4369   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4370
4371   if (0 <= retval)
4372     {
4373       print (vam->ofp, "ttl: %u", mp->ttl);
4374     }
4375
4376   vam->retval = retval;
4377   vam->result_ready = 1;
4378 }
4379
4380 static void
4381   vl_api_show_one_map_register_ttl_reply_t_handler_json
4382   (vl_api_show_one_map_register_ttl_reply_t * mp)
4383 {
4384   vat_main_t *vam = &vat_main;
4385   vat_json_node_t node;
4386
4387   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4388   vat_json_init_object (&node);
4389   vat_json_object_add_uint (&node, "ttl", mp->ttl);
4390
4391   vat_json_print (vam->ofp, &node);
4392   vat_json_free (&node);
4393
4394   vam->retval = ntohl (mp->retval);
4395   vam->result_ready = 1;
4396 }
4397
4398 static void
4399 vl_api_show_one_pitr_reply_t_handler (vl_api_show_one_pitr_reply_t * mp)
4400 {
4401   vat_main_t *vam = &vat_main;
4402   i32 retval = ntohl (mp->retval);
4403
4404   if (0 <= retval)
4405     {
4406       print (vam->ofp, "%-20s%-16s",
4407              mp->status ? "enabled" : "disabled",
4408              mp->status ? (char *) mp->locator_set_name : "");
4409     }
4410
4411   vam->retval = retval;
4412   vam->result_ready = 1;
4413 }
4414
4415 static void
4416 vl_api_show_one_pitr_reply_t_handler_json (vl_api_show_one_pitr_reply_t * mp)
4417 {
4418   vat_main_t *vam = &vat_main;
4419   vat_json_node_t node;
4420   u8 *status = 0;
4421
4422   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4423   vec_add1 (status, 0);
4424
4425   vat_json_init_object (&node);
4426   vat_json_object_add_string_copy (&node, "status", status);
4427   if (mp->status)
4428     {
4429       vat_json_object_add_string_copy (&node, "locator_set",
4430                                        mp->locator_set_name);
4431     }
4432
4433   vec_free (status);
4434
4435   vat_json_print (vam->ofp, &node);
4436   vat_json_free (&node);
4437
4438   vam->retval = ntohl (mp->retval);
4439   vam->result_ready = 1;
4440 }
4441
4442 static u8 *
4443 format_policer_type (u8 * s, va_list * va)
4444 {
4445   u32 i = va_arg (*va, u32);
4446
4447   if (i == SSE2_QOS_POLICER_TYPE_1R2C)
4448     s = format (s, "1r2c");
4449   else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
4450     s = format (s, "1r3c");
4451   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
4452     s = format (s, "2r3c-2698");
4453   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
4454     s = format (s, "2r3c-4115");
4455   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
4456     s = format (s, "2r3c-mef5cf1");
4457   else
4458     s = format (s, "ILLEGAL");
4459   return s;
4460 }
4461
4462 static u8 *
4463 format_policer_rate_type (u8 * s, va_list * va)
4464 {
4465   u32 i = va_arg (*va, u32);
4466
4467   if (i == SSE2_QOS_RATE_KBPS)
4468     s = format (s, "kbps");
4469   else if (i == SSE2_QOS_RATE_PPS)
4470     s = format (s, "pps");
4471   else
4472     s = format (s, "ILLEGAL");
4473   return s;
4474 }
4475
4476 static u8 *
4477 format_policer_round_type (u8 * s, va_list * va)
4478 {
4479   u32 i = va_arg (*va, u32);
4480
4481   if (i == SSE2_QOS_ROUND_TO_CLOSEST)
4482     s = format (s, "closest");
4483   else if (i == SSE2_QOS_ROUND_TO_UP)
4484     s = format (s, "up");
4485   else if (i == SSE2_QOS_ROUND_TO_DOWN)
4486     s = format (s, "down");
4487   else
4488     s = format (s, "ILLEGAL");
4489   return s;
4490 }
4491
4492 static u8 *
4493 format_policer_action_type (u8 * s, va_list * va)
4494 {
4495   u32 i = va_arg (*va, u32);
4496
4497   if (i == SSE2_QOS_ACTION_DROP)
4498     s = format (s, "drop");
4499   else if (i == SSE2_QOS_ACTION_TRANSMIT)
4500     s = format (s, "transmit");
4501   else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4502     s = format (s, "mark-and-transmit");
4503   else
4504     s = format (s, "ILLEGAL");
4505   return s;
4506 }
4507
4508 static u8 *
4509 format_dscp (u8 * s, va_list * va)
4510 {
4511   u32 i = va_arg (*va, u32);
4512   char *t = 0;
4513
4514   switch (i)
4515     {
4516 #define _(v,f,str) case VNET_DSCP_##f: t = str; break;
4517       foreach_vnet_dscp
4518 #undef _
4519     default:
4520       return format (s, "ILLEGAL");
4521     }
4522   s = format (s, "%s", t);
4523   return s;
4524 }
4525
4526 static void
4527 vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
4528 {
4529   vat_main_t *vam = &vat_main;
4530   u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
4531
4532   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4533     conform_dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
4534   else
4535     conform_dscp_str = format (0, "");
4536
4537   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4538     exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
4539   else
4540     exceed_dscp_str = format (0, "");
4541
4542   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4543     violate_dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
4544   else
4545     violate_dscp_str = format (0, "");
4546
4547   print (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
4548          "rate type %U, round type %U, %s rate, %s color-aware, "
4549          "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
4550          "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
4551          "conform action %U%s, exceed action %U%s, violate action %U%s",
4552          mp->name,
4553          format_policer_type, mp->type,
4554          ntohl (mp->cir),
4555          ntohl (mp->eir),
4556          clib_net_to_host_u64 (mp->cb),
4557          clib_net_to_host_u64 (mp->eb),
4558          format_policer_rate_type, mp->rate_type,
4559          format_policer_round_type, mp->round_type,
4560          mp->single_rate ? "single" : "dual",
4561          mp->color_aware ? "is" : "not",
4562          ntohl (mp->cir_tokens_per_period),
4563          ntohl (mp->pir_tokens_per_period),
4564          ntohl (mp->scale),
4565          ntohl (mp->current_limit),
4566          ntohl (mp->current_bucket),
4567          ntohl (mp->extended_limit),
4568          ntohl (mp->extended_bucket),
4569          clib_net_to_host_u64 (mp->last_update_time),
4570          format_policer_action_type, mp->conform_action_type,
4571          conform_dscp_str,
4572          format_policer_action_type, mp->exceed_action_type,
4573          exceed_dscp_str,
4574          format_policer_action_type, mp->violate_action_type,
4575          violate_dscp_str);
4576
4577   vec_free (conform_dscp_str);
4578   vec_free (exceed_dscp_str);
4579   vec_free (violate_dscp_str);
4580 }
4581
4582 static void vl_api_policer_details_t_handler_json
4583   (vl_api_policer_details_t * mp)
4584 {
4585   vat_main_t *vam = &vat_main;
4586   vat_json_node_t *node;
4587   u8 *rate_type_str, *round_type_str, *type_str;
4588   u8 *conform_action_str, *exceed_action_str, *violate_action_str;
4589
4590   rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
4591   round_type_str =
4592     format (0, "%U", format_policer_round_type, mp->round_type);
4593   type_str = format (0, "%U", format_policer_type, mp->type);
4594   conform_action_str = format (0, "%U", format_policer_action_type,
4595                                mp->conform_action_type);
4596   exceed_action_str = format (0, "%U", format_policer_action_type,
4597                               mp->exceed_action_type);
4598   violate_action_str = format (0, "%U", format_policer_action_type,
4599                                mp->violate_action_type);
4600
4601   if (VAT_JSON_ARRAY != vam->json_tree.type)
4602     {
4603       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4604       vat_json_init_array (&vam->json_tree);
4605     }
4606   node = vat_json_array_add (&vam->json_tree);
4607
4608   vat_json_init_object (node);
4609   vat_json_object_add_string_copy (node, "name", mp->name);
4610   vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
4611   vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
4612   vat_json_object_add_uint (node, "cb", clib_net_to_host_u64 (mp->cb));
4613   vat_json_object_add_uint (node, "eb", clib_net_to_host_u64 (mp->eb));
4614   vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
4615   vat_json_object_add_string_copy (node, "round_type", round_type_str);
4616   vat_json_object_add_string_copy (node, "type", type_str);
4617   vat_json_object_add_uint (node, "single_rate", mp->single_rate);
4618   vat_json_object_add_uint (node, "color_aware", mp->color_aware);
4619   vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
4620   vat_json_object_add_uint (node, "cir_tokens_per_period",
4621                             ntohl (mp->cir_tokens_per_period));
4622   vat_json_object_add_uint (node, "eir_tokens_per_period",
4623                             ntohl (mp->pir_tokens_per_period));
4624   vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
4625   vat_json_object_add_uint (node, "current_bucket",
4626                             ntohl (mp->current_bucket));
4627   vat_json_object_add_uint (node, "extended_limit",
4628                             ntohl (mp->extended_limit));
4629   vat_json_object_add_uint (node, "extended_bucket",
4630                             ntohl (mp->extended_bucket));
4631   vat_json_object_add_uint (node, "last_update_time",
4632                             ntohl (mp->last_update_time));
4633   vat_json_object_add_string_copy (node, "conform_action",
4634                                    conform_action_str);
4635   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4636     {
4637       u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
4638       vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
4639       vec_free (dscp_str);
4640     }
4641   vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
4642   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4643     {
4644       u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
4645       vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
4646       vec_free (dscp_str);
4647     }
4648   vat_json_object_add_string_copy (node, "violate_action",
4649                                    violate_action_str);
4650   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4651     {
4652       u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
4653       vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
4654       vec_free (dscp_str);
4655     }
4656
4657   vec_free (rate_type_str);
4658   vec_free (round_type_str);
4659   vec_free (type_str);
4660   vec_free (conform_action_str);
4661   vec_free (exceed_action_str);
4662   vec_free (violate_action_str);
4663 }
4664
4665 static void
4666 vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
4667                                            mp)
4668 {
4669   vat_main_t *vam = &vat_main;
4670   int i, count = ntohl (mp->count);
4671
4672   if (count > 0)
4673     print (vam->ofp, "classify table ids (%d) : ", count);
4674   for (i = 0; i < count; i++)
4675     {
4676       print (vam->ofp, "%d", ntohl (mp->ids[i]));
4677       print (vam->ofp, (i < count - 1) ? "," : "");
4678     }
4679   vam->retval = ntohl (mp->retval);
4680   vam->result_ready = 1;
4681 }
4682
4683 static void
4684   vl_api_classify_table_ids_reply_t_handler_json
4685   (vl_api_classify_table_ids_reply_t * mp)
4686 {
4687   vat_main_t *vam = &vat_main;
4688   int i, count = ntohl (mp->count);
4689
4690   if (count > 0)
4691     {
4692       vat_json_node_t node;
4693
4694       vat_json_init_object (&node);
4695       for (i = 0; i < count; i++)
4696         {
4697           vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
4698         }
4699       vat_json_print (vam->ofp, &node);
4700       vat_json_free (&node);
4701     }
4702   vam->retval = ntohl (mp->retval);
4703   vam->result_ready = 1;
4704 }
4705
4706 static void
4707   vl_api_classify_table_by_interface_reply_t_handler
4708   (vl_api_classify_table_by_interface_reply_t * mp)
4709 {
4710   vat_main_t *vam = &vat_main;
4711   u32 table_id;
4712
4713   table_id = ntohl (mp->l2_table_id);
4714   if (table_id != ~0)
4715     print (vam->ofp, "l2 table id : %d", table_id);
4716   else
4717     print (vam->ofp, "l2 table id : No input ACL tables configured");
4718   table_id = ntohl (mp->ip4_table_id);
4719   if (table_id != ~0)
4720     print (vam->ofp, "ip4 table id : %d", table_id);
4721   else
4722     print (vam->ofp, "ip4 table id : No input ACL tables configured");
4723   table_id = ntohl (mp->ip6_table_id);
4724   if (table_id != ~0)
4725     print (vam->ofp, "ip6 table id : %d", table_id);
4726   else
4727     print (vam->ofp, "ip6 table id : No input ACL tables configured");
4728   vam->retval = ntohl (mp->retval);
4729   vam->result_ready = 1;
4730 }
4731
4732 static void
4733   vl_api_classify_table_by_interface_reply_t_handler_json
4734   (vl_api_classify_table_by_interface_reply_t * mp)
4735 {
4736   vat_main_t *vam = &vat_main;
4737   vat_json_node_t node;
4738
4739   vat_json_init_object (&node);
4740
4741   vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
4742   vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
4743   vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
4744
4745   vat_json_print (vam->ofp, &node);
4746   vat_json_free (&node);
4747
4748   vam->retval = ntohl (mp->retval);
4749   vam->result_ready = 1;
4750 }
4751
4752 static void vl_api_policer_add_del_reply_t_handler
4753   (vl_api_policer_add_del_reply_t * mp)
4754 {
4755   vat_main_t *vam = &vat_main;
4756   i32 retval = ntohl (mp->retval);
4757   if (vam->async_mode)
4758     {
4759       vam->async_errors += (retval < 0);
4760     }
4761   else
4762     {
4763       vam->retval = retval;
4764       vam->result_ready = 1;
4765       if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
4766         /*
4767          * Note: this is just barely thread-safe, depends on
4768          * the main thread spinning waiting for an answer...
4769          */
4770         errmsg ("policer index %d", ntohl (mp->policer_index));
4771     }
4772 }
4773
4774 static void vl_api_policer_add_del_reply_t_handler_json
4775   (vl_api_policer_add_del_reply_t * mp)
4776 {
4777   vat_main_t *vam = &vat_main;
4778   vat_json_node_t node;
4779
4780   vat_json_init_object (&node);
4781   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
4782   vat_json_object_add_uint (&node, "policer_index",
4783                             ntohl (mp->policer_index));
4784
4785   vat_json_print (vam->ofp, &node);
4786   vat_json_free (&node);
4787
4788   vam->retval = ntohl (mp->retval);
4789   vam->result_ready = 1;
4790 }
4791
4792 /* Format hex dump. */
4793 u8 *
4794 format_hex_bytes (u8 * s, va_list * va)
4795 {
4796   u8 *bytes = va_arg (*va, u8 *);
4797   int n_bytes = va_arg (*va, int);
4798   uword i;
4799
4800   /* Print short or long form depending on byte count. */
4801   uword short_form = n_bytes <= 32;
4802   u32 indent = format_get_indent (s);
4803
4804   if (n_bytes == 0)
4805     return s;
4806
4807   for (i = 0; i < n_bytes; i++)
4808     {
4809       if (!short_form && (i % 32) == 0)
4810         s = format (s, "%08x: ", i);
4811       s = format (s, "%02x", bytes[i]);
4812       if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
4813         s = format (s, "\n%U", format_white_space, indent);
4814     }
4815
4816   return s;
4817 }
4818
4819 static void
4820 vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
4821                                             * mp)
4822 {
4823   vat_main_t *vam = &vat_main;
4824   i32 retval = ntohl (mp->retval);
4825   if (retval == 0)
4826     {
4827       print (vam->ofp, "classify table info :");
4828       print (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d",
4829              ntohl (mp->active_sessions), ntohl (mp->next_table_index),
4830              ntohl (mp->miss_next_index));
4831       print (vam->ofp, "nbuckets: %d skip: %d match: %d",
4832              ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
4833              ntohl (mp->match_n_vectors));
4834       print (vam->ofp, "mask: %U", format_hex_bytes, mp->mask,
4835              ntohl (mp->mask_length));
4836     }
4837   vam->retval = retval;
4838   vam->result_ready = 1;
4839 }
4840
4841 static void
4842   vl_api_classify_table_info_reply_t_handler_json
4843   (vl_api_classify_table_info_reply_t * mp)
4844 {
4845   vat_main_t *vam = &vat_main;
4846   vat_json_node_t node;
4847
4848   i32 retval = ntohl (mp->retval);
4849   if (retval == 0)
4850     {
4851       vat_json_init_object (&node);
4852
4853       vat_json_object_add_int (&node, "sessions",
4854                                ntohl (mp->active_sessions));
4855       vat_json_object_add_int (&node, "nexttbl",
4856                                ntohl (mp->next_table_index));
4857       vat_json_object_add_int (&node, "nextnode",
4858                                ntohl (mp->miss_next_index));
4859       vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
4860       vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
4861       vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
4862       u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
4863                       ntohl (mp->mask_length), 0);
4864       vat_json_object_add_string_copy (&node, "mask", s);
4865
4866       vat_json_print (vam->ofp, &node);
4867       vat_json_free (&node);
4868     }
4869   vam->retval = ntohl (mp->retval);
4870   vam->result_ready = 1;
4871 }
4872
4873 static void
4874 vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
4875                                            mp)
4876 {
4877   vat_main_t *vam = &vat_main;
4878
4879   print (vam->ofp, "next_index: %d advance: %d opaque: %d ",
4880          ntohl (mp->hit_next_index), ntohl (mp->advance),
4881          ntohl (mp->opaque_index));
4882   print (vam->ofp, "mask: %U", format_hex_bytes, mp->match,
4883          ntohl (mp->match_length));
4884 }
4885
4886 static void
4887   vl_api_classify_session_details_t_handler_json
4888   (vl_api_classify_session_details_t * mp)
4889 {
4890   vat_main_t *vam = &vat_main;
4891   vat_json_node_t *node = NULL;
4892
4893   if (VAT_JSON_ARRAY != vam->json_tree.type)
4894     {
4895       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4896       vat_json_init_array (&vam->json_tree);
4897     }
4898   node = vat_json_array_add (&vam->json_tree);
4899
4900   vat_json_init_object (node);
4901   vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
4902   vat_json_object_add_int (node, "advance", ntohl (mp->advance));
4903   vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
4904   u8 *s =
4905     format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
4906             0);
4907   vat_json_object_add_string_copy (node, "match", s);
4908 }
4909
4910 static void vl_api_pg_create_interface_reply_t_handler
4911   (vl_api_pg_create_interface_reply_t * mp)
4912 {
4913   vat_main_t *vam = &vat_main;
4914
4915   vam->retval = ntohl (mp->retval);
4916   vam->result_ready = 1;
4917 }
4918
4919 static void vl_api_pg_create_interface_reply_t_handler_json
4920   (vl_api_pg_create_interface_reply_t * mp)
4921 {
4922   vat_main_t *vam = &vat_main;
4923   vat_json_node_t node;
4924
4925   i32 retval = ntohl (mp->retval);
4926   if (retval == 0)
4927     {
4928       vat_json_init_object (&node);
4929
4930       vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
4931
4932       vat_json_print (vam->ofp, &node);
4933       vat_json_free (&node);
4934     }
4935   vam->retval = ntohl (mp->retval);
4936   vam->result_ready = 1;
4937 }
4938
4939 static void vl_api_policer_classify_details_t_handler
4940   (vl_api_policer_classify_details_t * mp)
4941 {
4942   vat_main_t *vam = &vat_main;
4943
4944   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
4945          ntohl (mp->table_index));
4946 }
4947
4948 static void vl_api_policer_classify_details_t_handler_json
4949   (vl_api_policer_classify_details_t * mp)
4950 {
4951   vat_main_t *vam = &vat_main;
4952   vat_json_node_t *node;
4953
4954   if (VAT_JSON_ARRAY != vam->json_tree.type)
4955     {
4956       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4957       vat_json_init_array (&vam->json_tree);
4958     }
4959   node = vat_json_array_add (&vam->json_tree);
4960
4961   vat_json_init_object (node);
4962   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
4963   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
4964 }
4965
4966 static void vl_api_flow_classify_details_t_handler
4967   (vl_api_flow_classify_details_t * mp)
4968 {
4969   vat_main_t *vam = &vat_main;
4970
4971   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
4972          ntohl (mp->table_index));
4973 }
4974
4975 static void vl_api_flow_classify_details_t_handler_json
4976   (vl_api_flow_classify_details_t * mp)
4977 {
4978   vat_main_t *vam = &vat_main;
4979   vat_json_node_t *node;
4980
4981   if (VAT_JSON_ARRAY != vam->json_tree.type)
4982     {
4983       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4984       vat_json_init_array (&vam->json_tree);
4985     }
4986   node = vat_json_array_add (&vam->json_tree);
4987
4988   vat_json_init_object (node);
4989   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
4990   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
4991 }
4992
4993 #define vl_api_one_adjacencies_get_reply_t_endian vl_noop_handler
4994 #define vl_api_one_adjacencies_get_reply_t_print vl_noop_handler
4995 #define vl_api_one_l2_arp_bd_get_reply_t_print vl_noop_handler
4996 #define vl_api_one_l2_arp_entries_get_reply_t_endian vl_noop_handler
4997 #define vl_api_one_l2_arp_entries_get_reply_t_print vl_noop_handler
4998 #define vl_api_one_l2_arp_bd_get_reply_t_endian vl_noop_handler
4999 #define vl_api_one_ndp_bd_get_reply_t_endian vl_noop_handler
5000 #define vl_api_one_ndp_bd_get_reply_t_print vl_noop_handler
5001 #define vl_api_one_ndp_entries_get_reply_t_print vl_noop_handler
5002 #define vl_api_one_ndp_entries_get_reply_t_endian vl_noop_handler
5003
5004 /*
5005  * Generate boilerplate reply handlers, which
5006  * dig the return value out of the xxx_reply_t API message,
5007  * stick it into vam->retval, and set vam->result_ready
5008  *
5009  * Could also do this by pointing N message decode slots at
5010  * a single function, but that could break in subtle ways.
5011  */
5012
5013 #define foreach_standard_reply_retval_handler           \
5014 _(sw_interface_set_flags_reply)                         \
5015 _(sw_interface_add_del_address_reply)                   \
5016 _(sw_interface_set_rx_mode_reply)                       \
5017 _(sw_interface_set_rx_placement_reply)                  \
5018 _(sw_interface_set_table_reply)                         \
5019 _(sw_interface_set_mpls_enable_reply)                   \
5020 _(sw_interface_set_vpath_reply)                         \
5021 _(sw_interface_set_vxlan_bypass_reply)                  \
5022 _(sw_interface_set_geneve_bypass_reply)                 \
5023 _(sw_interface_set_vxlan_gpe_bypass_reply)              \
5024 _(sw_interface_set_l2_bridge_reply)                     \
5025 _(sw_interface_set_bond_weight_reply)                   \
5026 _(bridge_domain_add_del_reply)                          \
5027 _(sw_interface_set_l2_xconnect_reply)                   \
5028 _(l2fib_add_del_reply)                                  \
5029 _(l2fib_flush_int_reply)                                \
5030 _(l2fib_flush_bd_reply)                                 \
5031 _(ip_route_add_del_reply)                               \
5032 _(ip_table_add_del_reply)                               \
5033 _(ip_table_replace_begin_reply)                         \
5034 _(ip_table_flush_reply)                                 \
5035 _(ip_table_replace_end_reply)                           \
5036 _(ip_mroute_add_del_reply)                              \
5037 _(mpls_route_add_del_reply)                             \
5038 _(mpls_table_add_del_reply)                             \
5039 _(mpls_ip_bind_unbind_reply)                            \
5040 _(bier_route_add_del_reply)                             \
5041 _(bier_table_add_del_reply)                             \
5042 _(sw_interface_set_unnumbered_reply)                    \
5043 _(set_ip_flow_hash_reply)                               \
5044 _(sw_interface_ip6_enable_disable_reply)                \
5045 _(l2_patch_add_del_reply)                               \
5046 _(sr_mpls_policy_add_reply)                             \
5047 _(sr_mpls_policy_mod_reply)                             \
5048 _(sr_mpls_policy_del_reply)                             \
5049 _(sr_policy_add_reply)                                  \
5050 _(sr_policy_mod_reply)                                  \
5051 _(sr_policy_del_reply)                                  \
5052 _(sr_localsid_add_del_reply)                            \
5053 _(sr_steering_add_del_reply)                            \
5054 _(classify_add_del_session_reply)                       \
5055 _(classify_set_interface_ip_table_reply)                \
5056 _(classify_set_interface_l2_tables_reply)               \
5057 _(l2tpv3_set_tunnel_cookies_reply)                      \
5058 _(l2tpv3_interface_enable_disable_reply)                \
5059 _(l2tpv3_set_lookup_key_reply)                          \
5060 _(l2_fib_clear_table_reply)                             \
5061 _(l2_interface_efp_filter_reply)                        \
5062 _(l2_interface_vlan_tag_rewrite_reply)                  \
5063 _(modify_vhost_user_if_reply)                           \
5064 _(delete_vhost_user_if_reply)                           \
5065 _(want_l2_macs_events_reply)                            \
5066 _(input_acl_set_interface_reply)                        \
5067 _(ipsec_spd_add_del_reply)                              \
5068 _(ipsec_interface_add_del_spd_reply)                    \
5069 _(ipsec_spd_entry_add_del_reply)                        \
5070 _(ipsec_sad_entry_add_del_reply)                        \
5071 _(ipsec_tunnel_if_add_del_reply)                        \
5072 _(ipsec_tunnel_if_set_sa_reply)                         \
5073 _(delete_loopback_reply)                                \
5074 _(bd_ip_mac_add_del_reply)                              \
5075 _(bd_ip_mac_flush_reply)                                \
5076 _(want_interface_events_reply)                          \
5077 _(cop_interface_enable_disable_reply)                   \
5078 _(cop_whitelist_enable_disable_reply)                   \
5079 _(sw_interface_clear_stats_reply)                       \
5080 _(ioam_enable_reply)                                    \
5081 _(ioam_disable_reply)                                   \
5082 _(one_add_del_locator_reply)                            \
5083 _(one_add_del_local_eid_reply)                          \
5084 _(one_add_del_remote_mapping_reply)                     \
5085 _(one_add_del_adjacency_reply)                          \
5086 _(one_add_del_map_resolver_reply)                       \
5087 _(one_add_del_map_server_reply)                         \
5088 _(one_enable_disable_reply)                             \
5089 _(one_rloc_probe_enable_disable_reply)                  \
5090 _(one_map_register_enable_disable_reply)                \
5091 _(one_map_register_set_ttl_reply)                       \
5092 _(one_set_transport_protocol_reply)                     \
5093 _(one_map_register_fallback_threshold_reply)            \
5094 _(one_pitr_set_locator_set_reply)                       \
5095 _(one_map_request_mode_reply)                           \
5096 _(one_add_del_map_request_itr_rlocs_reply)              \
5097 _(one_eid_table_add_del_map_reply)                      \
5098 _(one_use_petr_reply)                                   \
5099 _(one_stats_enable_disable_reply)                       \
5100 _(one_add_del_l2_arp_entry_reply)                       \
5101 _(one_add_del_ndp_entry_reply)                          \
5102 _(one_stats_flush_reply)                                \
5103 _(one_enable_disable_xtr_mode_reply)                    \
5104 _(one_enable_disable_pitr_mode_reply)                   \
5105 _(one_enable_disable_petr_mode_reply)                   \
5106 _(gpe_enable_disable_reply)                             \
5107 _(gpe_set_encap_mode_reply)                             \
5108 _(gpe_add_del_iface_reply)                              \
5109 _(gpe_add_del_native_fwd_rpath_reply)                   \
5110 _(af_packet_delete_reply)                               \
5111 _(policer_classify_set_interface_reply)                 \
5112 _(set_ipfix_exporter_reply)                             \
5113 _(set_ipfix_classify_stream_reply)                      \
5114 _(ipfix_classify_table_add_del_reply)                   \
5115 _(flow_classify_set_interface_reply)                    \
5116 _(sw_interface_span_enable_disable_reply)               \
5117 _(pg_capture_reply)                                     \
5118 _(pg_enable_disable_reply)                              \
5119 _(ip_source_and_port_range_check_add_del_reply)         \
5120 _(ip_source_and_port_range_check_interface_add_del_reply)\
5121 _(delete_subif_reply)                                   \
5122 _(l2_interface_pbb_tag_rewrite_reply)                   \
5123 _(set_punt_reply)                                       \
5124 _(feature_enable_disable_reply)                         \
5125 _(feature_gso_enable_disable_reply)                     \
5126 _(sw_interface_tag_add_del_reply)                       \
5127 _(sw_interface_add_del_mac_address_reply)               \
5128 _(hw_interface_set_mtu_reply)                           \
5129 _(p2p_ethernet_add_reply)                               \
5130 _(p2p_ethernet_del_reply)                               \
5131 _(lldp_config_reply)                                    \
5132 _(sw_interface_set_lldp_reply)                          \
5133 _(tcp_configure_src_addresses_reply)                    \
5134 _(session_rule_add_del_reply)                           \
5135 _(ip_container_proxy_add_del_reply)                     \
5136 _(output_acl_set_interface_reply)                       \
5137 _(qos_record_enable_disable_reply)
5138
5139 #define _(n)                                    \
5140     static void vl_api_##n##_t_handler          \
5141     (vl_api_##n##_t * mp)                       \
5142     {                                           \
5143         vat_main_t * vam = &vat_main;           \
5144         i32 retval = ntohl(mp->retval);         \
5145         if (vam->async_mode) {                  \
5146             vam->async_errors += (retval < 0);  \
5147         } else {                                \
5148             vam->retval = retval;               \
5149             vam->result_ready = 1;              \
5150         }                                       \
5151     }
5152 foreach_standard_reply_retval_handler;
5153 #undef _
5154
5155 #define _(n)                                    \
5156     static void vl_api_##n##_t_handler_json     \
5157     (vl_api_##n##_t * mp)                       \
5158     {                                           \
5159         vat_main_t * vam = &vat_main;           \
5160         vat_json_node_t node;                   \
5161         vat_json_init_object(&node);            \
5162         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
5163         vat_json_print(vam->ofp, &node);        \
5164         vam->retval = ntohl(mp->retval);        \
5165         vam->result_ready = 1;                  \
5166     }
5167 foreach_standard_reply_retval_handler;
5168 #undef _
5169
5170 /*
5171  * Table of message reply handlers, must include boilerplate handlers
5172  * we just generated
5173  */
5174
5175 #define foreach_vpe_api_reply_msg                                       \
5176 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
5177 _(CREATE_LOOPBACK_INSTANCE_REPLY, create_loopback_instance_reply)       \
5178 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
5179 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
5180 _(CONTROL_PING_REPLY, control_ping_reply)                               \
5181 _(CLI_REPLY, cli_reply)                                                 \
5182 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
5183 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
5184   sw_interface_add_del_address_reply)                                   \
5185 _(SW_INTERFACE_SET_RX_MODE_REPLY, sw_interface_set_rx_mode_reply)       \
5186 _(SW_INTERFACE_SET_RX_PLACEMENT_REPLY, sw_interface_set_rx_placement_reply)     \
5187 _(SW_INTERFACE_RX_PLACEMENT_DETAILS, sw_interface_rx_placement_details) \
5188 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
5189 _(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
5190 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
5191 _(SW_INTERFACE_SET_VXLAN_BYPASS_REPLY, sw_interface_set_vxlan_bypass_reply) \
5192 _(SW_INTERFACE_SET_GENEVE_BYPASS_REPLY, sw_interface_set_geneve_bypass_reply) \
5193 _(SW_INTERFACE_SET_VXLAN_GPE_BYPASS_REPLY, sw_interface_set_vxlan_gpe_bypass_reply) \
5194 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
5195   sw_interface_set_l2_xconnect_reply)                                   \
5196 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
5197   sw_interface_set_l2_bridge_reply)                                     \
5198 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
5199 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
5200 _(BRIDGE_DOMAIN_SET_MAC_AGE_REPLY, bridge_domain_set_mac_age_reply)     \
5201 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
5202 _(L2FIB_FLUSH_INT_REPLY, l2fib_flush_int_reply)                         \
5203 _(L2FIB_FLUSH_BD_REPLY, l2fib_flush_bd_reply)                           \
5204 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
5205 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
5206 _(TAP_CREATE_V2_REPLY, tap_create_v2_reply)                             \
5207 _(TAP_DELETE_V2_REPLY, tap_delete_v2_reply)                             \
5208 _(SW_INTERFACE_TAP_V2_DETAILS, sw_interface_tap_v2_details)             \
5209 _(VIRTIO_PCI_CREATE_REPLY, virtio_pci_create_reply)                     \
5210 _(VIRTIO_PCI_DELETE_REPLY, virtio_pci_delete_reply)                     \
5211 _(SW_INTERFACE_VIRTIO_PCI_DETAILS, sw_interface_virtio_pci_details)     \
5212 _(BOND_CREATE_REPLY, bond_create_reply)                                 \
5213 _(BOND_DELETE_REPLY, bond_delete_reply)                                 \
5214 _(BOND_ENSLAVE_REPLY, bond_enslave_reply)                               \
5215 _(BOND_DETACH_SLAVE_REPLY, bond_detach_slave_reply)                     \
5216 _(SW_INTERFACE_SET_BOND_WEIGHT_REPLY, sw_interface_set_bond_weight_reply) \
5217 _(SW_INTERFACE_BOND_DETAILS, sw_interface_bond_details)                 \
5218 _(SW_INTERFACE_SLAVE_DETAILS, sw_interface_slave_details)               \
5219 _(IP_ROUTE_ADD_DEL_REPLY, ip_route_add_del_reply)                       \
5220 _(IP_TABLE_ADD_DEL_REPLY, ip_table_add_del_reply)                       \
5221 _(IP_TABLE_REPLACE_BEGIN_REPLY, ip_table_replace_begin_reply)           \
5222 _(IP_TABLE_FLUSH_REPLY, ip_table_flush_reply)                           \
5223 _(IP_TABLE_REPLACE_END_REPLY, ip_table_replace_end_reply)               \
5224 _(IP_MROUTE_ADD_DEL_REPLY, ip_mroute_add_del_reply)                     \
5225 _(MPLS_TABLE_ADD_DEL_REPLY, mpls_table_add_del_reply)                   \
5226 _(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply)                   \
5227 _(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply)                 \
5228 _(BIER_ROUTE_ADD_DEL_REPLY, bier_route_add_del_reply)                   \
5229 _(BIER_TABLE_ADD_DEL_REPLY, bier_table_add_del_reply)                   \
5230 _(MPLS_TUNNEL_ADD_DEL_REPLY, mpls_tunnel_add_del_reply)                 \
5231 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
5232   sw_interface_set_unnumbered_reply)                                    \
5233 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
5234 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
5235 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
5236 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
5237   sw_interface_ip6_enable_disable_reply)                                \
5238 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
5239 _(SR_MPLS_POLICY_ADD_REPLY, sr_mpls_policy_add_reply)                   \
5240 _(SR_MPLS_POLICY_MOD_REPLY, sr_mpls_policy_mod_reply)                   \
5241 _(SR_MPLS_POLICY_DEL_REPLY, sr_mpls_policy_del_reply)                   \
5242 _(SR_POLICY_ADD_REPLY, sr_policy_add_reply)                             \
5243 _(SR_POLICY_MOD_REPLY, sr_policy_mod_reply)                             \
5244 _(SR_POLICY_DEL_REPLY, sr_policy_del_reply)                             \
5245 _(SR_LOCALSID_ADD_DEL_REPLY, sr_localsid_add_del_reply)                 \
5246 _(SR_STEERING_ADD_DEL_REPLY, sr_steering_add_del_reply)                 \
5247 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
5248 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
5249 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
5250 classify_set_interface_ip_table_reply)                                  \
5251 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
5252   classify_set_interface_l2_tables_reply)                               \
5253 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
5254 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
5255 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
5256 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
5257 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
5258   l2tpv3_interface_enable_disable_reply)                                \
5259 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
5260 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
5261 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
5262 _(VXLAN_OFFLOAD_RX_REPLY, vxlan_offload_rx_reply)               \
5263 _(GENEVE_ADD_DEL_TUNNEL_REPLY, geneve_add_del_tunnel_reply)             \
5264 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
5265 _(GENEVE_TUNNEL_DETAILS, geneve_tunnel_details)                         \
5266 _(GRE_TUNNEL_ADD_DEL_REPLY, gre_tunnel_add_del_reply)                   \
5267 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
5268 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
5269 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
5270 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
5271 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
5272 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
5273 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
5274 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
5275 _(SHOW_VERSION_REPLY, show_version_reply)                               \
5276 _(SHOW_THREADS_REPLY, show_threads_reply)                               \
5277 _(L2_FIB_TABLE_DETAILS, l2_fib_table_details)                           \
5278 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)       \
5279 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
5280 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
5281 _(WANT_L2_MACS_EVENTS_REPLY, want_l2_macs_events_reply)                 \
5282 _(L2_MACS_EVENT, l2_macs_event)                                         \
5283 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
5284 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
5285 _(IP_DETAILS, ip_details)                                               \
5286 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
5287 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
5288 _(IPSEC_SPD_ENTRY_ADD_DEL_REPLY, ipsec_spd_entry_add_del_reply)         \
5289 _(IPSEC_SAD_ENTRY_ADD_DEL_REPLY, ipsec_sad_entry_add_del_reply)         \
5290 _(IPSEC_SA_DETAILS, ipsec_sa_details)                                   \
5291 _(IPSEC_TUNNEL_IF_ADD_DEL_REPLY, ipsec_tunnel_if_add_del_reply)         \
5292 _(IPSEC_TUNNEL_IF_SET_SA_REPLY, ipsec_tunnel_if_set_sa_reply)           \
5293 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
5294 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
5295 _(BD_IP_MAC_FLUSH_REPLY, bd_ip_mac_flush_reply)                         \
5296 _(BD_IP_MAC_DETAILS, bd_ip_mac_details)                                 \
5297 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
5298 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
5299 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
5300 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
5301 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
5302 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
5303 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
5304 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
5305 _(ONE_ADD_DEL_LOCATOR_SET_REPLY, one_add_del_locator_set_reply)         \
5306 _(ONE_ADD_DEL_LOCATOR_REPLY, one_add_del_locator_reply)                 \
5307 _(ONE_ADD_DEL_LOCAL_EID_REPLY, one_add_del_local_eid_reply)             \
5308 _(ONE_ADD_DEL_REMOTE_MAPPING_REPLY, one_add_del_remote_mapping_reply)   \
5309 _(ONE_ADD_DEL_ADJACENCY_REPLY, one_add_del_adjacency_reply)             \
5310 _(ONE_ADD_DEL_MAP_RESOLVER_REPLY, one_add_del_map_resolver_reply)       \
5311 _(ONE_ADD_DEL_MAP_SERVER_REPLY, one_add_del_map_server_reply)           \
5312 _(ONE_ENABLE_DISABLE_REPLY, one_enable_disable_reply)                   \
5313 _(ONE_MAP_REGISTER_ENABLE_DISABLE_REPLY,                                \
5314   one_map_register_enable_disable_reply)                                \
5315 _(ONE_MAP_REGISTER_SET_TTL_REPLY, one_map_register_set_ttl_reply)       \
5316 _(ONE_SET_TRANSPORT_PROTOCOL_REPLY, one_set_transport_protocol_reply)   \
5317 _(ONE_GET_TRANSPORT_PROTOCOL_REPLY, one_get_transport_protocol_reply)   \
5318 _(ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                            \
5319   one_map_register_fallback_threshold_reply)                            \
5320 _(ONE_RLOC_PROBE_ENABLE_DISABLE_REPLY,                                  \
5321   one_rloc_probe_enable_disable_reply)                                  \
5322 _(ONE_PITR_SET_LOCATOR_SET_REPLY, one_pitr_set_locator_set_reply)       \
5323 _(ONE_USE_PETR_REPLY, one_use_petr_reply)                               \
5324 _(ONE_MAP_REQUEST_MODE_REPLY, one_map_request_mode_reply)               \
5325 _(ONE_EID_TABLE_ADD_DEL_MAP_REPLY, one_eid_table_add_del_map_reply)     \
5326 _(ONE_LOCATOR_SET_DETAILS, one_locator_set_details)                     \
5327 _(ONE_LOCATOR_DETAILS, one_locator_details)                             \
5328 _(ONE_EID_TABLE_DETAILS, one_eid_table_details)                         \
5329 _(ONE_EID_TABLE_MAP_DETAILS, one_eid_table_map_details)                 \
5330 _(ONE_EID_TABLE_VNI_DETAILS, one_eid_table_vni_details)                 \
5331 _(ONE_MAP_RESOLVER_DETAILS, one_map_resolver_details)                   \
5332 _(ONE_MAP_SERVER_DETAILS, one_map_server_details)                       \
5333 _(ONE_ADJACENCIES_GET_REPLY, one_adjacencies_get_reply)                 \
5334 _(ONE_STATS_DETAILS, one_stats_details)                                 \
5335 _(ONE_STATS_FLUSH_REPLY, one_stats_flush_reply)                         \
5336 _(ONE_STATS_ENABLE_DISABLE_REPLY, one_stats_enable_disable_reply)       \
5337 _(SHOW_ONE_STATS_ENABLE_DISABLE_REPLY,                                  \
5338   show_one_stats_enable_disable_reply)                                  \
5339 _(ONE_ADD_DEL_NDP_ENTRY_REPLY, one_add_del_ndp_entry_reply)             \
5340 _(ONE_NDP_BD_GET_REPLY, one_ndp_bd_get_reply)                           \
5341 _(ONE_NDP_ENTRIES_GET_REPLY, one_ndp_entries_get_reply)                 \
5342 _(ONE_ADD_DEL_L2_ARP_ENTRY_REPLY, one_add_del_l2_arp_entry_reply)       \
5343 _(ONE_L2_ARP_BD_GET_REPLY, one_l2_arp_bd_get_reply)                     \
5344 _(ONE_L2_ARP_ENTRIES_GET_REPLY, one_l2_arp_entries_get_reply)           \
5345 _(ONE_ENABLE_DISABLE_XTR_MODE_REPLY, one_enable_disable_xtr_mode_reply) \
5346 _(ONE_ENABLE_DISABLE_PITR_MODE_REPLY,                                   \
5347   one_enable_disable_pitr_mode_reply)                                   \
5348 _(ONE_ENABLE_DISABLE_PETR_MODE_REPLY,                                   \
5349   one_enable_disable_petr_mode_reply)                                   \
5350 _(ONE_SHOW_XTR_MODE_REPLY, one_show_xtr_mode_reply)                     \
5351 _(ONE_SHOW_PITR_MODE_REPLY, one_show_pitr_mode_reply)                   \
5352 _(ONE_SHOW_PETR_MODE_REPLY, one_show_petr_mode_reply)                   \
5353 _(GPE_SET_ENCAP_MODE_REPLY, gpe_set_encap_mode_reply)                   \
5354 _(GPE_GET_ENCAP_MODE_REPLY, gpe_get_encap_mode_reply)                   \
5355 _(GPE_ADD_DEL_IFACE_REPLY, gpe_add_del_iface_reply)                     \
5356 _(GPE_ENABLE_DISABLE_REPLY, gpe_enable_disable_reply)                   \
5357 _(GPE_ADD_DEL_FWD_ENTRY_REPLY, gpe_add_del_fwd_entry_reply)             \
5358 _(GPE_FWD_ENTRY_VNIS_GET_REPLY, gpe_fwd_entry_vnis_get_reply)           \
5359 _(GPE_FWD_ENTRIES_GET_REPLY, gpe_fwd_entries_get_reply)                 \
5360 _(GPE_NATIVE_FWD_RPATHS_GET_REPLY, gpe_native_fwd_rpaths_get_reply)     \
5361 _(GPE_ADD_DEL_NATIVE_FWD_RPATH_REPLY,                                   \
5362   gpe_add_del_native_fwd_rpath_reply)                                   \
5363 _(GPE_FWD_ENTRY_PATH_DETAILS,                                           \
5364   gpe_fwd_entry_path_details)                                           \
5365 _(SHOW_ONE_STATUS_REPLY, show_one_status_reply)                         \
5366 _(ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                              \
5367   one_add_del_map_request_itr_rlocs_reply)                              \
5368 _(ONE_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                  \
5369   one_get_map_request_itr_rlocs_reply)                                  \
5370 _(SHOW_ONE_NSH_MAPPING_REPLY, show_one_nsh_mapping_reply)               \
5371 _(SHOW_ONE_PITR_REPLY, show_one_pitr_reply)                             \
5372 _(SHOW_ONE_USE_PETR_REPLY, show_one_use_petr_reply)                     \
5373 _(SHOW_ONE_MAP_REQUEST_MODE_REPLY, show_one_map_request_mode_reply)     \
5374 _(SHOW_ONE_RLOC_PROBE_STATE_REPLY, show_one_rloc_probe_state_reply)     \
5375 _(SHOW_ONE_MAP_REGISTER_STATE_REPLY,                                    \
5376   show_one_map_register_state_reply)                                    \
5377 _(SHOW_ONE_MAP_REGISTER_TTL_REPLY, show_one_map_register_ttl_reply)     \
5378 _(SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                       \
5379   show_one_map_register_fallback_threshold_reply)                       \
5380 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
5381 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
5382 _(AF_PACKET_DETAILS, af_packet_details)                                 \
5383 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
5384 _(POLICER_DETAILS, policer_details)                                     \
5385 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
5386 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
5387 _(MPLS_TUNNEL_DETAILS, mpls_tunnel_details)                             \
5388 _(MPLS_TABLE_DETAILS, mpls_table_details)                               \
5389 _(MPLS_ROUTE_DETAILS, mpls_route_details)                               \
5390 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
5391 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
5392 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
5393 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
5394 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
5395 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
5396 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
5397 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
5398 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
5399 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
5400 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
5401 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
5402 _(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
5403 _(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details)                 \
5404 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
5405 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
5406 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
5407 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
5408 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
5409  ip_source_and_port_range_check_add_del_reply)                          \
5410 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
5411  ip_source_and_port_range_check_interface_add_del_reply)                \
5412 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
5413 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
5414 _(SET_PUNT_REPLY, set_punt_reply)                                       \
5415 _(IP_TABLE_DETAILS, ip_table_details)                                   \
5416 _(IP_ROUTE_DETAILS, ip_route_details)                                   \
5417 _(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply)           \
5418 _(FEATURE_GSO_ENABLE_DISABLE_REPLY, feature_gso_enable_disable_reply)   \
5419 _(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply)       \
5420 _(SW_INTERFACE_ADD_DEL_MAC_ADDRESS_REPLY, sw_interface_add_del_mac_address_reply) \
5421 _(L2_XCONNECT_DETAILS, l2_xconnect_details)                             \
5422 _(HW_INTERFACE_SET_MTU_REPLY, hw_interface_set_mtu_reply)               \
5423 _(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply)           \
5424 _(P2P_ETHERNET_ADD_REPLY, p2p_ethernet_add_reply)                       \
5425 _(P2P_ETHERNET_DEL_REPLY, p2p_ethernet_del_reply)                       \
5426 _(LLDP_CONFIG_REPLY, lldp_config_reply)                                 \
5427 _(SW_INTERFACE_SET_LLDP_REPLY, sw_interface_set_lldp_reply)             \
5428 _(TCP_CONFIGURE_SRC_ADDRESSES_REPLY, tcp_configure_src_addresses_reply) \
5429 _(APP_NAMESPACE_ADD_DEL_REPLY, app_namespace_add_del_reply)             \
5430 _(SESSION_RULE_ADD_DEL_REPLY, session_rule_add_del_reply)               \
5431 _(SESSION_RULES_DETAILS, session_rules_details)                         \
5432 _(IP_CONTAINER_PROXY_ADD_DEL_REPLY, ip_container_proxy_add_del_reply)   \
5433 _(OUTPUT_ACL_SET_INTERFACE_REPLY, output_acl_set_interface_reply)       \
5434 _(QOS_RECORD_ENABLE_DISABLE_REPLY, qos_record_enable_disable_reply)
5435
5436 #define foreach_standalone_reply_msg                                    \
5437 _(SW_INTERFACE_EVENT, sw_interface_event)
5438
5439 typedef struct
5440 {
5441   u8 *name;
5442   u32 value;
5443 } name_sort_t;
5444
5445 #define STR_VTR_OP_CASE(op)     \
5446     case L2_VTR_ ## op:         \
5447         return "" # op;
5448
5449 static const char *
5450 str_vtr_op (u32 vtr_op)
5451 {
5452   switch (vtr_op)
5453     {
5454       STR_VTR_OP_CASE (DISABLED);
5455       STR_VTR_OP_CASE (PUSH_1);
5456       STR_VTR_OP_CASE (PUSH_2);
5457       STR_VTR_OP_CASE (POP_1);
5458       STR_VTR_OP_CASE (POP_2);
5459       STR_VTR_OP_CASE (TRANSLATE_1_1);
5460       STR_VTR_OP_CASE (TRANSLATE_1_2);
5461       STR_VTR_OP_CASE (TRANSLATE_2_1);
5462       STR_VTR_OP_CASE (TRANSLATE_2_2);
5463     }
5464
5465   return "UNKNOWN";
5466 }
5467
5468 static int
5469 dump_sub_interface_table (vat_main_t * vam)
5470 {
5471   const sw_interface_subif_t *sub = NULL;
5472
5473   if (vam->json_output)
5474     {
5475       clib_warning
5476         ("JSON output supported only for VPE API calls and dump_stats_table");
5477       return -99;
5478     }
5479
5480   print (vam->ofp,
5481          "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
5482          "Interface", "sw_if_index",
5483          "sub id", "dot1ad", "tags", "outer id",
5484          "inner id", "exact", "default", "outer any", "inner any");
5485
5486   vec_foreach (sub, vam->sw_if_subif_table)
5487   {
5488     print (vam->ofp,
5489            "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
5490            sub->interface_name,
5491            sub->sw_if_index,
5492            sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
5493            sub->sub_number_of_tags, sub->sub_outer_vlan_id,
5494            sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
5495            sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
5496     if (sub->vtr_op != L2_VTR_DISABLED)
5497       {
5498         print (vam->ofp,
5499                "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
5500                "tag1: %d tag2: %d ]",
5501                str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
5502                sub->vtr_tag1, sub->vtr_tag2);
5503       }
5504   }
5505
5506   return 0;
5507 }
5508
5509 static int
5510 name_sort_cmp (void *a1, void *a2)
5511 {
5512   name_sort_t *n1 = a1;
5513   name_sort_t *n2 = a2;
5514
5515   return strcmp ((char *) n1->name, (char *) n2->name);
5516 }
5517
5518 static int
5519 dump_interface_table (vat_main_t * vam)
5520 {
5521   hash_pair_t *p;
5522   name_sort_t *nses = 0, *ns;
5523
5524   if (vam->json_output)
5525     {
5526       clib_warning
5527         ("JSON output supported only for VPE API calls and dump_stats_table");
5528       return -99;
5529     }
5530
5531   /* *INDENT-OFF* */
5532   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5533   ({
5534     vec_add2 (nses, ns, 1);
5535     ns->name = (u8 *)(p->key);
5536     ns->value = (u32) p->value[0];
5537   }));
5538   /* *INDENT-ON* */
5539
5540   vec_sort_with_function (nses, name_sort_cmp);
5541
5542   print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
5543   vec_foreach (ns, nses)
5544   {
5545     print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
5546   }
5547   vec_free (nses);
5548   return 0;
5549 }
5550
5551 static int
5552 dump_ip_table (vat_main_t * vam, int is_ipv6)
5553 {
5554   const ip_details_t *det = NULL;
5555   const ip_address_details_t *address = NULL;
5556   u32 i = ~0;
5557
5558   print (vam->ofp, "%-12s", "sw_if_index");
5559
5560   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
5561   {
5562     i++;
5563     if (!det->present)
5564       {
5565         continue;
5566       }
5567     print (vam->ofp, "%-12d", i);
5568     print (vam->ofp, "            %-30s%-13s", "Address", "Prefix length");
5569     if (!det->addr)
5570       {
5571         continue;
5572       }
5573     vec_foreach (address, det->addr)
5574     {
5575       print (vam->ofp,
5576              "            %-30U%-13d",
5577              is_ipv6 ? format_ip6_address : format_ip4_address,
5578              address->ip, address->prefix_length);
5579     }
5580   }
5581
5582   return 0;
5583 }
5584
5585 static int
5586 dump_ipv4_table (vat_main_t * vam)
5587 {
5588   if (vam->json_output)
5589     {
5590       clib_warning
5591         ("JSON output supported only for VPE API calls and dump_stats_table");
5592       return -99;
5593     }
5594
5595   return dump_ip_table (vam, 0);
5596 }
5597
5598 static int
5599 dump_ipv6_table (vat_main_t * vam)
5600 {
5601   if (vam->json_output)
5602     {
5603       clib_warning
5604         ("JSON output supported only for VPE API calls and dump_stats_table");
5605       return -99;
5606     }
5607
5608   return dump_ip_table (vam, 1);
5609 }
5610
5611 /*
5612  * Pass CLI buffers directly in the CLI_INBAND API message,
5613  * instead of an additional shared memory area.
5614  */
5615 static int
5616 exec_inband (vat_main_t * vam)
5617 {
5618   vl_api_cli_inband_t *mp;
5619   unformat_input_t *i = vam->input;
5620   int ret;
5621
5622   if (vec_len (i->buffer) == 0)
5623     return -1;
5624
5625   if (vam->exec_mode == 0 && unformat (i, "mode"))
5626     {
5627       vam->exec_mode = 1;
5628       return 0;
5629     }
5630   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
5631     {
5632       vam->exec_mode = 0;
5633       return 0;
5634     }
5635
5636   /*
5637    * In order for the CLI command to work, it
5638    * must be a vector ending in \n, not a C-string ending
5639    * in \n\0.
5640    */
5641   u32 len = vec_len (vam->input->buffer);
5642   M2 (CLI_INBAND, mp, len);
5643   vl_api_to_api_string (len - 1, (const char *) vam->input->buffer, &mp->cmd);
5644
5645   S (mp);
5646   W (ret);
5647   /* json responses may or may not include a useful reply... */
5648   if (vec_len (vam->cmd_reply))
5649     print (vam->ofp, "%v", (char *) (vam->cmd_reply));
5650   return ret;
5651 }
5652
5653 int
5654 exec (vat_main_t * vam)
5655 {
5656   return exec_inband (vam);
5657 }
5658
5659 static int
5660 api_create_loopback (vat_main_t * vam)
5661 {
5662   unformat_input_t *i = vam->input;
5663   vl_api_create_loopback_t *mp;
5664   vl_api_create_loopback_instance_t *mp_lbi;
5665   u8 mac_address[6];
5666   u8 mac_set = 0;
5667   u8 is_specified = 0;
5668   u32 user_instance = 0;
5669   int ret;
5670
5671   clib_memset (mac_address, 0, sizeof (mac_address));
5672
5673   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5674     {
5675       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5676         mac_set = 1;
5677       if (unformat (i, "instance %d", &user_instance))
5678         is_specified = 1;
5679       else
5680         break;
5681     }
5682
5683   if (is_specified)
5684     {
5685       M (CREATE_LOOPBACK_INSTANCE, mp_lbi);
5686       mp_lbi->is_specified = is_specified;
5687       if (is_specified)
5688         mp_lbi->user_instance = htonl (user_instance);
5689       if (mac_set)
5690         clib_memcpy (mp_lbi->mac_address, mac_address, sizeof (mac_address));
5691       S (mp_lbi);
5692     }
5693   else
5694     {
5695       /* Construct the API message */
5696       M (CREATE_LOOPBACK, mp);
5697       if (mac_set)
5698         clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
5699       S (mp);
5700     }
5701
5702   W (ret);
5703   return ret;
5704 }
5705
5706 static int
5707 api_delete_loopback (vat_main_t * vam)
5708 {
5709   unformat_input_t *i = vam->input;
5710   vl_api_delete_loopback_t *mp;
5711   u32 sw_if_index = ~0;
5712   int ret;
5713
5714   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5715     {
5716       if (unformat (i, "sw_if_index %d", &sw_if_index))
5717         ;
5718       else
5719         break;
5720     }
5721
5722   if (sw_if_index == ~0)
5723     {
5724       errmsg ("missing sw_if_index");
5725       return -99;
5726     }
5727
5728   /* Construct the API message */
5729   M (DELETE_LOOPBACK, mp);
5730   mp->sw_if_index = ntohl (sw_if_index);
5731
5732   S (mp);
5733   W (ret);
5734   return ret;
5735 }
5736
5737 static int
5738 api_want_interface_events (vat_main_t * vam)
5739 {
5740   unformat_input_t *i = vam->input;
5741   vl_api_want_interface_events_t *mp;
5742   int enable = -1;
5743   int ret;
5744
5745   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5746     {
5747       if (unformat (i, "enable"))
5748         enable = 1;
5749       else if (unformat (i, "disable"))
5750         enable = 0;
5751       else
5752         break;
5753     }
5754
5755   if (enable == -1)
5756     {
5757       errmsg ("missing enable|disable");
5758       return -99;
5759     }
5760
5761   M (WANT_INTERFACE_EVENTS, mp);
5762   mp->enable_disable = enable;
5763
5764   vam->interface_event_display = enable;
5765
5766   S (mp);
5767   W (ret);
5768   return ret;
5769 }
5770
5771
5772 /* Note: non-static, called once to set up the initial intfc table */
5773 int
5774 api_sw_interface_dump (vat_main_t * vam)
5775 {
5776   vl_api_sw_interface_dump_t *mp;
5777   vl_api_control_ping_t *mp_ping;
5778   hash_pair_t *p;
5779   name_sort_t *nses = 0, *ns;
5780   sw_interface_subif_t *sub = NULL;
5781   int ret;
5782
5783   /* Toss the old name table */
5784   /* *INDENT-OFF* */
5785   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5786   ({
5787     vec_add2 (nses, ns, 1);
5788     ns->name = (u8 *)(p->key);
5789     ns->value = (u32) p->value[0];
5790   }));
5791   /* *INDENT-ON* */
5792
5793   hash_free (vam->sw_if_index_by_interface_name);
5794
5795   vec_foreach (ns, nses) vec_free (ns->name);
5796
5797   vec_free (nses);
5798
5799   vec_foreach (sub, vam->sw_if_subif_table)
5800   {
5801     vec_free (sub->interface_name);
5802   }
5803   vec_free (vam->sw_if_subif_table);
5804
5805   /* recreate the interface name hash table */
5806   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
5807
5808   /*
5809    * Ask for all interface names. Otherwise, the epic catalog of
5810    * name filters becomes ridiculously long, and vat ends up needing
5811    * to be taught about new interface types.
5812    */
5813   M (SW_INTERFACE_DUMP, mp);
5814   S (mp);
5815
5816   /* Use a control ping for synchronization */
5817   MPING (CONTROL_PING, mp_ping);
5818   S (mp_ping);
5819
5820   W (ret);
5821   return ret;
5822 }
5823
5824 static int
5825 api_sw_interface_set_flags (vat_main_t * vam)
5826 {
5827   unformat_input_t *i = vam->input;
5828   vl_api_sw_interface_set_flags_t *mp;
5829   u32 sw_if_index;
5830   u8 sw_if_index_set = 0;
5831   u8 admin_up = 0;
5832   int ret;
5833
5834   /* Parse args required to build the message */
5835   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5836     {
5837       if (unformat (i, "admin-up"))
5838         admin_up = 1;
5839       else if (unformat (i, "admin-down"))
5840         admin_up = 0;
5841       else
5842         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5843         sw_if_index_set = 1;
5844       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5845         sw_if_index_set = 1;
5846       else
5847         break;
5848     }
5849
5850   if (sw_if_index_set == 0)
5851     {
5852       errmsg ("missing interface name or sw_if_index");
5853       return -99;
5854     }
5855
5856   /* Construct the API message */
5857   M (SW_INTERFACE_SET_FLAGS, mp);
5858   mp->sw_if_index = ntohl (sw_if_index);
5859   mp->flags = ntohl ((admin_up) ? IF_STATUS_API_FLAG_ADMIN_UP : 0);
5860
5861   /* send it... */
5862   S (mp);
5863
5864   /* Wait for a reply, return the good/bad news... */
5865   W (ret);
5866   return ret;
5867 }
5868
5869 static int
5870 api_sw_interface_set_rx_mode (vat_main_t * vam)
5871 {
5872   unformat_input_t *i = vam->input;
5873   vl_api_sw_interface_set_rx_mode_t *mp;
5874   u32 sw_if_index;
5875   u8 sw_if_index_set = 0;
5876   int ret;
5877   u8 queue_id_valid = 0;
5878   u32 queue_id;
5879   vnet_hw_interface_rx_mode mode = VNET_HW_INTERFACE_RX_MODE_UNKNOWN;
5880
5881   /* Parse args required to build the message */
5882   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5883     {
5884       if (unformat (i, "queue %d", &queue_id))
5885         queue_id_valid = 1;
5886       else if (unformat (i, "polling"))
5887         mode = VNET_HW_INTERFACE_RX_MODE_POLLING;
5888       else if (unformat (i, "interrupt"))
5889         mode = VNET_HW_INTERFACE_RX_MODE_INTERRUPT;
5890       else if (unformat (i, "adaptive"))
5891         mode = VNET_HW_INTERFACE_RX_MODE_ADAPTIVE;
5892       else
5893         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5894         sw_if_index_set = 1;
5895       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5896         sw_if_index_set = 1;
5897       else
5898         break;
5899     }
5900
5901   if (sw_if_index_set == 0)
5902     {
5903       errmsg ("missing interface name or sw_if_index");
5904       return -99;
5905     }
5906   if (mode == VNET_HW_INTERFACE_RX_MODE_UNKNOWN)
5907     {
5908       errmsg ("missing rx-mode");
5909       return -99;
5910     }
5911
5912   /* Construct the API message */
5913   M (SW_INTERFACE_SET_RX_MODE, mp);
5914   mp->sw_if_index = ntohl (sw_if_index);
5915   mp->mode = (vl_api_rx_mode_t) mode;
5916   mp->queue_id_valid = queue_id_valid;
5917   mp->queue_id = queue_id_valid ? ntohl (queue_id) : ~0;
5918
5919   /* send it... */
5920   S (mp);
5921
5922   /* Wait for a reply, return the good/bad news... */
5923   W (ret);
5924   return ret;
5925 }
5926
5927 static int
5928 api_sw_interface_set_rx_placement (vat_main_t * vam)
5929 {
5930   unformat_input_t *i = vam->input;
5931   vl_api_sw_interface_set_rx_placement_t *mp;
5932   u32 sw_if_index;
5933   u8 sw_if_index_set = 0;
5934   int ret;
5935   u8 is_main = 0;
5936   u32 queue_id, thread_index;
5937
5938   /* Parse args required to build the message */
5939   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5940     {
5941       if (unformat (i, "queue %d", &queue_id))
5942         ;
5943       else if (unformat (i, "main"))
5944         is_main = 1;
5945       else if (unformat (i, "worker %d", &thread_index))
5946         ;
5947       else
5948         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5949         sw_if_index_set = 1;
5950       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5951         sw_if_index_set = 1;
5952       else
5953         break;
5954     }
5955
5956   if (sw_if_index_set == 0)
5957     {
5958       errmsg ("missing interface name or sw_if_index");
5959       return -99;
5960     }
5961
5962   if (is_main)
5963     thread_index = 0;
5964   /* Construct the API message */
5965   M (SW_INTERFACE_SET_RX_PLACEMENT, mp);
5966   mp->sw_if_index = ntohl (sw_if_index);
5967   mp->worker_id = ntohl (thread_index);
5968   mp->queue_id = ntohl (queue_id);
5969   mp->is_main = is_main;
5970
5971   /* send it... */
5972   S (mp);
5973   /* Wait for a reply, return the good/bad news... */
5974   W (ret);
5975   return ret;
5976 }
5977
5978 static void vl_api_sw_interface_rx_placement_details_t_handler
5979   (vl_api_sw_interface_rx_placement_details_t * mp)
5980 {
5981   vat_main_t *vam = &vat_main;
5982   u32 worker_id = ntohl (mp->worker_id);
5983
5984   print (vam->ofp,
5985          "\n%-11d %-11s %-6d %-5d %-9s",
5986          ntohl (mp->sw_if_index), (worker_id == 0) ? "main" : "worker",
5987          worker_id, ntohl (mp->queue_id),
5988          (mp->mode ==
5989           1) ? "polling" : ((mp->mode == 2) ? "interrupt" : "adaptive"));
5990 }
5991
5992 static void vl_api_sw_interface_rx_placement_details_t_handler_json
5993   (vl_api_sw_interface_rx_placement_details_t * mp)
5994 {
5995   vat_main_t *vam = &vat_main;
5996   vat_json_node_t *node = NULL;
5997
5998   if (VAT_JSON_ARRAY != vam->json_tree.type)
5999     {
6000       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
6001       vat_json_init_array (&vam->json_tree);
6002     }
6003   node = vat_json_array_add (&vam->json_tree);
6004
6005   vat_json_init_object (node);
6006   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
6007   vat_json_object_add_uint (node, "worker_id", ntohl (mp->worker_id));
6008   vat_json_object_add_uint (node, "queue_id", ntohl (mp->queue_id));
6009   vat_json_object_add_uint (node, "mode", mp->mode);
6010 }
6011
6012 static int
6013 api_sw_interface_rx_placement_dump (vat_main_t * vam)
6014 {
6015   unformat_input_t *i = vam->input;
6016   vl_api_sw_interface_rx_placement_dump_t *mp;
6017   vl_api_control_ping_t *mp_ping;
6018   int ret;
6019   u32 sw_if_index;
6020   u8 sw_if_index_set = 0;
6021
6022   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6023     {
6024       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6025         sw_if_index_set++;
6026       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6027         sw_if_index_set++;
6028       else
6029         break;
6030     }
6031
6032   print (vam->ofp,
6033          "\n%-11s %-11s %-6s %-5s %-4s",
6034          "sw_if_index", "main/worker", "thread", "queue", "mode");
6035
6036   /* Dump Interface rx placement */
6037   M (SW_INTERFACE_RX_PLACEMENT_DUMP, mp);
6038
6039   if (sw_if_index_set)
6040     mp->sw_if_index = htonl (sw_if_index);
6041   else
6042     mp->sw_if_index = ~0;
6043
6044   S (mp);
6045
6046   /* Use a control ping for synchronization */
6047   MPING (CONTROL_PING, mp_ping);
6048   S (mp_ping);
6049
6050   W (ret);
6051   return ret;
6052 }
6053
6054 static int
6055 api_sw_interface_clear_stats (vat_main_t * vam)
6056 {
6057   unformat_input_t *i = vam->input;
6058   vl_api_sw_interface_clear_stats_t *mp;
6059   u32 sw_if_index;
6060   u8 sw_if_index_set = 0;
6061   int ret;
6062
6063   /* Parse args required to build the message */
6064   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6065     {
6066       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6067         sw_if_index_set = 1;
6068       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6069         sw_if_index_set = 1;
6070       else
6071         break;
6072     }
6073
6074   /* Construct the API message */
6075   M (SW_INTERFACE_CLEAR_STATS, mp);
6076
6077   if (sw_if_index_set == 1)
6078     mp->sw_if_index = ntohl (sw_if_index);
6079   else
6080     mp->sw_if_index = ~0;
6081
6082   /* send it... */
6083   S (mp);
6084
6085   /* Wait for a reply, return the good/bad news... */
6086   W (ret);
6087   return ret;
6088 }
6089
6090 static int
6091 api_sw_interface_add_del_address (vat_main_t * vam)
6092 {
6093   unformat_input_t *i = vam->input;
6094   vl_api_sw_interface_add_del_address_t *mp;
6095   u32 sw_if_index;
6096   u8 sw_if_index_set = 0;
6097   u8 is_add = 1, del_all = 0;
6098   u32 address_length = 0;
6099   u8 v4_address_set = 0;
6100   u8 v6_address_set = 0;
6101   ip4_address_t v4address;
6102   ip6_address_t v6address;
6103   int ret;
6104
6105   /* Parse args required to build the message */
6106   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6107     {
6108       if (unformat (i, "del-all"))
6109         del_all = 1;
6110       else if (unformat (i, "del"))
6111         is_add = 0;
6112       else
6113         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6114         sw_if_index_set = 1;
6115       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6116         sw_if_index_set = 1;
6117       else if (unformat (i, "%U/%d",
6118                          unformat_ip4_address, &v4address, &address_length))
6119         v4_address_set = 1;
6120       else if (unformat (i, "%U/%d",
6121                          unformat_ip6_address, &v6address, &address_length))
6122         v6_address_set = 1;
6123       else
6124         break;
6125     }
6126
6127   if (sw_if_index_set == 0)
6128     {
6129       errmsg ("missing interface name or sw_if_index");
6130       return -99;
6131     }
6132   if (v4_address_set && v6_address_set)
6133     {
6134       errmsg ("both v4 and v6 addresses set");
6135       return -99;
6136     }
6137   if (!v4_address_set && !v6_address_set && !del_all)
6138     {
6139       errmsg ("no addresses set");
6140       return -99;
6141     }
6142
6143   /* Construct the API message */
6144   M (SW_INTERFACE_ADD_DEL_ADDRESS, mp);
6145
6146   mp->sw_if_index = ntohl (sw_if_index);
6147   mp->is_add = is_add;
6148   mp->del_all = del_all;
6149   if (v6_address_set)
6150     {
6151       mp->prefix.address.af = ADDRESS_IP6;
6152       clib_memcpy (mp->prefix.address.un.ip6, &v6address, sizeof (v6address));
6153     }
6154   else
6155     {
6156       mp->prefix.address.af = ADDRESS_IP4;
6157       clib_memcpy (mp->prefix.address.un.ip4, &v4address, sizeof (v4address));
6158     }
6159   mp->prefix.len = address_length;
6160
6161   /* send it... */
6162   S (mp);
6163
6164   /* Wait for a reply, return good/bad news  */
6165   W (ret);
6166   return ret;
6167 }
6168
6169 static int
6170 api_sw_interface_set_mpls_enable (vat_main_t * vam)
6171 {
6172   unformat_input_t *i = vam->input;
6173   vl_api_sw_interface_set_mpls_enable_t *mp;
6174   u32 sw_if_index;
6175   u8 sw_if_index_set = 0;
6176   u8 enable = 1;
6177   int ret;
6178
6179   /* Parse args required to build the message */
6180   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6181     {
6182       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6183         sw_if_index_set = 1;
6184       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6185         sw_if_index_set = 1;
6186       else if (unformat (i, "disable"))
6187         enable = 0;
6188       else if (unformat (i, "dis"))
6189         enable = 0;
6190       else
6191         break;
6192     }
6193
6194   if (sw_if_index_set == 0)
6195     {
6196       errmsg ("missing interface name or sw_if_index");
6197       return -99;
6198     }
6199
6200   /* Construct the API message */
6201   M (SW_INTERFACE_SET_MPLS_ENABLE, mp);
6202
6203   mp->sw_if_index = ntohl (sw_if_index);
6204   mp->enable = enable;
6205
6206   /* send it... */
6207   S (mp);
6208
6209   /* Wait for a reply... */
6210   W (ret);
6211   return ret;
6212 }
6213
6214 static int
6215 api_sw_interface_set_table (vat_main_t * vam)
6216 {
6217   unformat_input_t *i = vam->input;
6218   vl_api_sw_interface_set_table_t *mp;
6219   u32 sw_if_index, vrf_id = 0;
6220   u8 sw_if_index_set = 0;
6221   u8 is_ipv6 = 0;
6222   int ret;
6223
6224   /* Parse args required to build the message */
6225   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6226     {
6227       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6228         sw_if_index_set = 1;
6229       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6230         sw_if_index_set = 1;
6231       else if (unformat (i, "vrf %d", &vrf_id))
6232         ;
6233       else if (unformat (i, "ipv6"))
6234         is_ipv6 = 1;
6235       else
6236         break;
6237     }
6238
6239   if (sw_if_index_set == 0)
6240     {
6241       errmsg ("missing interface name or sw_if_index");
6242       return -99;
6243     }
6244
6245   /* Construct the API message */
6246   M (SW_INTERFACE_SET_TABLE, mp);
6247
6248   mp->sw_if_index = ntohl (sw_if_index);
6249   mp->is_ipv6 = is_ipv6;
6250   mp->vrf_id = ntohl (vrf_id);
6251
6252   /* send it... */
6253   S (mp);
6254
6255   /* Wait for a reply... */
6256   W (ret);
6257   return ret;
6258 }
6259
6260 static void vl_api_sw_interface_get_table_reply_t_handler
6261   (vl_api_sw_interface_get_table_reply_t * mp)
6262 {
6263   vat_main_t *vam = &vat_main;
6264
6265   print (vam->ofp, "%d", ntohl (mp->vrf_id));
6266
6267   vam->retval = ntohl (mp->retval);
6268   vam->result_ready = 1;
6269
6270 }
6271
6272 static void vl_api_sw_interface_get_table_reply_t_handler_json
6273   (vl_api_sw_interface_get_table_reply_t * mp)
6274 {
6275   vat_main_t *vam = &vat_main;
6276   vat_json_node_t node;
6277
6278   vat_json_init_object (&node);
6279   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
6280   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
6281
6282   vat_json_print (vam->ofp, &node);
6283   vat_json_free (&node);
6284
6285   vam->retval = ntohl (mp->retval);
6286   vam->result_ready = 1;
6287 }
6288
6289 static int
6290 api_sw_interface_get_table (vat_main_t * vam)
6291 {
6292   unformat_input_t *i = vam->input;
6293   vl_api_sw_interface_get_table_t *mp;
6294   u32 sw_if_index;
6295   u8 sw_if_index_set = 0;
6296   u8 is_ipv6 = 0;
6297   int ret;
6298
6299   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6300     {
6301       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6302         sw_if_index_set = 1;
6303       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6304         sw_if_index_set = 1;
6305       else if (unformat (i, "ipv6"))
6306         is_ipv6 = 1;
6307       else
6308         break;
6309     }
6310
6311   if (sw_if_index_set == 0)
6312     {
6313       errmsg ("missing interface name or sw_if_index");
6314       return -99;
6315     }
6316
6317   M (SW_INTERFACE_GET_TABLE, mp);
6318   mp->sw_if_index = htonl (sw_if_index);
6319   mp->is_ipv6 = is_ipv6;
6320
6321   S (mp);
6322   W (ret);
6323   return ret;
6324 }
6325
6326 static int
6327 api_sw_interface_set_vpath (vat_main_t * vam)
6328 {
6329   unformat_input_t *i = vam->input;
6330   vl_api_sw_interface_set_vpath_t *mp;
6331   u32 sw_if_index = 0;
6332   u8 sw_if_index_set = 0;
6333   u8 is_enable = 0;
6334   int ret;
6335
6336   /* Parse args required to build the message */
6337   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6338     {
6339       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6340         sw_if_index_set = 1;
6341       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6342         sw_if_index_set = 1;
6343       else if (unformat (i, "enable"))
6344         is_enable = 1;
6345       else if (unformat (i, "disable"))
6346         is_enable = 0;
6347       else
6348         break;
6349     }
6350
6351   if (sw_if_index_set == 0)
6352     {
6353       errmsg ("missing interface name or sw_if_index");
6354       return -99;
6355     }
6356
6357   /* Construct the API message */
6358   M (SW_INTERFACE_SET_VPATH, mp);
6359
6360   mp->sw_if_index = ntohl (sw_if_index);
6361   mp->enable = is_enable;
6362
6363   /* send it... */
6364   S (mp);
6365
6366   /* Wait for a reply... */
6367   W (ret);
6368   return ret;
6369 }
6370
6371 static int
6372 api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
6373 {
6374   unformat_input_t *i = vam->input;
6375   vl_api_sw_interface_set_vxlan_bypass_t *mp;
6376   u32 sw_if_index = 0;
6377   u8 sw_if_index_set = 0;
6378   u8 is_enable = 1;
6379   u8 is_ipv6 = 0;
6380   int ret;
6381
6382   /* Parse args required to build the message */
6383   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6384     {
6385       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6386         sw_if_index_set = 1;
6387       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6388         sw_if_index_set = 1;
6389       else if (unformat (i, "enable"))
6390         is_enable = 1;
6391       else if (unformat (i, "disable"))
6392         is_enable = 0;
6393       else if (unformat (i, "ip4"))
6394         is_ipv6 = 0;
6395       else if (unformat (i, "ip6"))
6396         is_ipv6 = 1;
6397       else
6398         break;
6399     }
6400
6401   if (sw_if_index_set == 0)
6402     {
6403       errmsg ("missing interface name or sw_if_index");
6404       return -99;
6405     }
6406
6407   /* Construct the API message */
6408   M (SW_INTERFACE_SET_VXLAN_BYPASS, mp);
6409
6410   mp->sw_if_index = ntohl (sw_if_index);
6411   mp->enable = is_enable;
6412   mp->is_ipv6 = is_ipv6;
6413
6414   /* send it... */
6415   S (mp);
6416
6417   /* Wait for a reply... */
6418   W (ret);
6419   return ret;
6420 }
6421
6422 static int
6423 api_sw_interface_set_geneve_bypass (vat_main_t * vam)
6424 {
6425   unformat_input_t *i = vam->input;
6426   vl_api_sw_interface_set_geneve_bypass_t *mp;
6427   u32 sw_if_index = 0;
6428   u8 sw_if_index_set = 0;
6429   u8 is_enable = 1;
6430   u8 is_ipv6 = 0;
6431   int ret;
6432
6433   /* Parse args required to build the message */
6434   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6435     {
6436       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6437         sw_if_index_set = 1;
6438       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6439         sw_if_index_set = 1;
6440       else if (unformat (i, "enable"))
6441         is_enable = 1;
6442       else if (unformat (i, "disable"))
6443         is_enable = 0;
6444       else if (unformat (i, "ip4"))
6445         is_ipv6 = 0;
6446       else if (unformat (i, "ip6"))
6447         is_ipv6 = 1;
6448       else
6449         break;
6450     }
6451
6452   if (sw_if_index_set == 0)
6453     {
6454       errmsg ("missing interface name or sw_if_index");
6455       return -99;
6456     }
6457
6458   /* Construct the API message */
6459   M (SW_INTERFACE_SET_GENEVE_BYPASS, mp);
6460
6461   mp->sw_if_index = ntohl (sw_if_index);
6462   mp->enable = is_enable;
6463   mp->is_ipv6 = is_ipv6;
6464
6465   /* send it... */
6466   S (mp);
6467
6468   /* Wait for a reply... */
6469   W (ret);
6470   return ret;
6471 }
6472
6473 static int
6474 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
6475 {
6476   unformat_input_t *i = vam->input;
6477   vl_api_sw_interface_set_l2_xconnect_t *mp;
6478   u32 rx_sw_if_index;
6479   u8 rx_sw_if_index_set = 0;
6480   u32 tx_sw_if_index;
6481   u8 tx_sw_if_index_set = 0;
6482   u8 enable = 1;
6483   int ret;
6484
6485   /* Parse args required to build the message */
6486   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6487     {
6488       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
6489         rx_sw_if_index_set = 1;
6490       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
6491         tx_sw_if_index_set = 1;
6492       else if (unformat (i, "rx"))
6493         {
6494           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6495             {
6496               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6497                             &rx_sw_if_index))
6498                 rx_sw_if_index_set = 1;
6499             }
6500           else
6501             break;
6502         }
6503       else if (unformat (i, "tx"))
6504         {
6505           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6506             {
6507               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6508                             &tx_sw_if_index))
6509                 tx_sw_if_index_set = 1;
6510             }
6511           else
6512             break;
6513         }
6514       else if (unformat (i, "enable"))
6515         enable = 1;
6516       else if (unformat (i, "disable"))
6517         enable = 0;
6518       else
6519         break;
6520     }
6521
6522   if (rx_sw_if_index_set == 0)
6523     {
6524       errmsg ("missing rx interface name or rx_sw_if_index");
6525       return -99;
6526     }
6527
6528   if (enable && (tx_sw_if_index_set == 0))
6529     {
6530       errmsg ("missing tx interface name or tx_sw_if_index");
6531       return -99;
6532     }
6533
6534   M (SW_INTERFACE_SET_L2_XCONNECT, mp);
6535
6536   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6537   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
6538   mp->enable = enable;
6539
6540   S (mp);
6541   W (ret);
6542   return ret;
6543 }
6544
6545 static int
6546 api_sw_interface_set_l2_bridge (vat_main_t * vam)
6547 {
6548   unformat_input_t *i = vam->input;
6549   vl_api_sw_interface_set_l2_bridge_t *mp;
6550   vl_api_l2_port_type_t port_type;
6551   u32 rx_sw_if_index;
6552   u8 rx_sw_if_index_set = 0;
6553   u32 bd_id;
6554   u8 bd_id_set = 0;
6555   u32 shg = 0;
6556   u8 enable = 1;
6557   int ret;
6558
6559   port_type = L2_API_PORT_TYPE_NORMAL;
6560
6561   /* Parse args required to build the message */
6562   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6563     {
6564       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
6565         rx_sw_if_index_set = 1;
6566       else if (unformat (i, "bd_id %d", &bd_id))
6567         bd_id_set = 1;
6568       else
6569         if (unformat
6570             (i, "%U", api_unformat_sw_if_index, vam, &rx_sw_if_index))
6571         rx_sw_if_index_set = 1;
6572       else if (unformat (i, "shg %d", &shg))
6573         ;
6574       else if (unformat (i, "bvi"))
6575         port_type = L2_API_PORT_TYPE_BVI;
6576       else if (unformat (i, "uu-fwd"))
6577         port_type = L2_API_PORT_TYPE_UU_FWD;
6578       else if (unformat (i, "enable"))
6579         enable = 1;
6580       else if (unformat (i, "disable"))
6581         enable = 0;
6582       else
6583         break;
6584     }
6585
6586   if (rx_sw_if_index_set == 0)
6587     {
6588       errmsg ("missing rx interface name or sw_if_index");
6589       return -99;
6590     }
6591
6592   if (enable && (bd_id_set == 0))
6593     {
6594       errmsg ("missing bridge domain");
6595       return -99;
6596     }
6597
6598   M (SW_INTERFACE_SET_L2_BRIDGE, mp);
6599
6600   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6601   mp->bd_id = ntohl (bd_id);
6602   mp->shg = (u8) shg;
6603   mp->port_type = ntohl (port_type);
6604   mp->enable = enable;
6605
6606   S (mp);
6607   W (ret);
6608   return ret;
6609 }
6610
6611 static int
6612 api_bridge_domain_dump (vat_main_t * vam)
6613 {
6614   unformat_input_t *i = vam->input;
6615   vl_api_bridge_domain_dump_t *mp;
6616   vl_api_control_ping_t *mp_ping;
6617   u32 bd_id = ~0;
6618   int ret;
6619
6620   /* Parse args required to build the message */
6621   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6622     {
6623       if (unformat (i, "bd_id %d", &bd_id))
6624         ;
6625       else
6626         break;
6627     }
6628
6629   M (BRIDGE_DOMAIN_DUMP, mp);
6630   mp->bd_id = ntohl (bd_id);
6631   S (mp);
6632
6633   /* Use a control ping for synchronization */
6634   MPING (CONTROL_PING, mp_ping);
6635   S (mp_ping);
6636
6637   W (ret);
6638   return ret;
6639 }
6640
6641 static int
6642 api_bridge_domain_add_del (vat_main_t * vam)
6643 {
6644   unformat_input_t *i = vam->input;
6645   vl_api_bridge_domain_add_del_t *mp;
6646   u32 bd_id = ~0;
6647   u8 is_add = 1;
6648   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
6649   u8 *bd_tag = NULL;
6650   u32 mac_age = 0;
6651   int ret;
6652
6653   /* Parse args required to build the message */
6654   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6655     {
6656       if (unformat (i, "bd_id %d", &bd_id))
6657         ;
6658       else if (unformat (i, "flood %d", &flood))
6659         ;
6660       else if (unformat (i, "uu-flood %d", &uu_flood))
6661         ;
6662       else if (unformat (i, "forward %d", &forward))
6663         ;
6664       else if (unformat (i, "learn %d", &learn))
6665         ;
6666       else if (unformat (i, "arp-term %d", &arp_term))
6667         ;
6668       else if (unformat (i, "mac-age %d", &mac_age))
6669         ;
6670       else if (unformat (i, "bd-tag %s", &bd_tag))
6671         ;
6672       else if (unformat (i, "del"))
6673         {
6674           is_add = 0;
6675           flood = uu_flood = forward = learn = 0;
6676         }
6677       else
6678         break;
6679     }
6680
6681   if (bd_id == ~0)
6682     {
6683       errmsg ("missing bridge domain");
6684       ret = -99;
6685       goto done;
6686     }
6687
6688   if (mac_age > 255)
6689     {
6690       errmsg ("mac age must be less than 256 ");
6691       ret = -99;
6692       goto done;
6693     }
6694
6695   if ((bd_tag) && (vec_len (bd_tag) > 63))
6696     {
6697       errmsg ("bd-tag cannot be longer than 63");
6698       ret = -99;
6699       goto done;
6700     }
6701
6702   M (BRIDGE_DOMAIN_ADD_DEL, mp);
6703
6704   mp->bd_id = ntohl (bd_id);
6705   mp->flood = flood;
6706   mp->uu_flood = uu_flood;
6707   mp->forward = forward;
6708   mp->learn = learn;
6709   mp->arp_term = arp_term;
6710   mp->is_add = is_add;
6711   mp->mac_age = (u8) mac_age;
6712   if (bd_tag)
6713     {
6714       clib_memcpy (mp->bd_tag, bd_tag, vec_len (bd_tag));
6715       mp->bd_tag[vec_len (bd_tag)] = 0;
6716     }
6717   S (mp);
6718   W (ret);
6719
6720 done:
6721   vec_free (bd_tag);
6722   return ret;
6723 }
6724
6725 static int
6726 api_l2fib_flush_bd (vat_main_t * vam)
6727 {
6728   unformat_input_t *i = vam->input;
6729   vl_api_l2fib_flush_bd_t *mp;
6730   u32 bd_id = ~0;
6731   int ret;
6732
6733   /* Parse args required to build the message */
6734   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6735     {
6736       if (unformat (i, "bd_id %d", &bd_id));
6737       else
6738         break;
6739     }
6740
6741   if (bd_id == ~0)
6742     {
6743       errmsg ("missing bridge domain");
6744       return -99;
6745     }
6746
6747   M (L2FIB_FLUSH_BD, mp);
6748
6749   mp->bd_id = htonl (bd_id);
6750
6751   S (mp);
6752   W (ret);
6753   return ret;
6754 }
6755
6756 static int
6757 api_l2fib_flush_int (vat_main_t * vam)
6758 {
6759   unformat_input_t *i = vam->input;
6760   vl_api_l2fib_flush_int_t *mp;
6761   u32 sw_if_index = ~0;
6762   int ret;
6763
6764   /* Parse args required to build the message */
6765   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6766     {
6767       if (unformat (i, "sw_if_index %d", &sw_if_index));
6768       else
6769         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index));
6770       else
6771         break;
6772     }
6773
6774   if (sw_if_index == ~0)
6775     {
6776       errmsg ("missing interface name or sw_if_index");
6777       return -99;
6778     }
6779
6780   M (L2FIB_FLUSH_INT, mp);
6781
6782   mp->sw_if_index = ntohl (sw_if_index);
6783
6784   S (mp);
6785   W (ret);
6786   return ret;
6787 }
6788
6789 static int
6790 api_l2fib_add_del (vat_main_t * vam)
6791 {
6792   unformat_input_t *i = vam->input;
6793   vl_api_l2fib_add_del_t *mp;
6794   f64 timeout;
6795   u8 mac[6] = { 0 };
6796   u8 mac_set = 0;
6797   u32 bd_id;
6798   u8 bd_id_set = 0;
6799   u32 sw_if_index = 0;
6800   u8 sw_if_index_set = 0;
6801   u8 is_add = 1;
6802   u8 static_mac = 0;
6803   u8 filter_mac = 0;
6804   u8 bvi_mac = 0;
6805   int count = 1;
6806   f64 before = 0;
6807   int j;
6808
6809   /* Parse args required to build the message */
6810   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6811     {
6812       if (unformat (i, "mac %U", unformat_ethernet_address, mac))
6813         mac_set = 1;
6814       else if (unformat (i, "bd_id %d", &bd_id))
6815         bd_id_set = 1;
6816       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6817         sw_if_index_set = 1;
6818       else if (unformat (i, "sw_if"))
6819         {
6820           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6821             {
6822               if (unformat
6823                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6824                 sw_if_index_set = 1;
6825             }
6826           else
6827             break;
6828         }
6829       else if (unformat (i, "static"))
6830         static_mac = 1;
6831       else if (unformat (i, "filter"))
6832         {
6833           filter_mac = 1;
6834           static_mac = 1;
6835         }
6836       else if (unformat (i, "bvi"))
6837         {
6838           bvi_mac = 1;
6839           static_mac = 1;
6840         }
6841       else if (unformat (i, "del"))
6842         is_add = 0;
6843       else if (unformat (i, "count %d", &count))
6844         ;
6845       else
6846         break;
6847     }
6848
6849   if (mac_set == 0)
6850     {
6851       errmsg ("missing mac address");
6852       return -99;
6853     }
6854
6855   if (bd_id_set == 0)
6856     {
6857       errmsg ("missing bridge domain");
6858       return -99;
6859     }
6860
6861   if (is_add && sw_if_index_set == 0 && filter_mac == 0)
6862     {
6863       errmsg ("missing interface name or sw_if_index");
6864       return -99;
6865     }
6866
6867   if (count > 1)
6868     {
6869       /* Turn on async mode */
6870       vam->async_mode = 1;
6871       vam->async_errors = 0;
6872       before = vat_time_now (vam);
6873     }
6874
6875   for (j = 0; j < count; j++)
6876     {
6877       M (L2FIB_ADD_DEL, mp);
6878
6879       clib_memcpy (mp->mac, mac, 6);
6880       mp->bd_id = ntohl (bd_id);
6881       mp->is_add = is_add;
6882       mp->sw_if_index = ntohl (sw_if_index);
6883
6884       if (is_add)
6885         {
6886           mp->static_mac = static_mac;
6887           mp->filter_mac = filter_mac;
6888           mp->bvi_mac = bvi_mac;
6889         }
6890       increment_mac_address (mac);
6891       /* send it... */
6892       S (mp);
6893     }
6894
6895   if (count > 1)
6896     {
6897       vl_api_control_ping_t *mp_ping;
6898       f64 after;
6899
6900       /* Shut off async mode */
6901       vam->async_mode = 0;
6902
6903       MPING (CONTROL_PING, mp_ping);
6904       S (mp_ping);
6905
6906       timeout = vat_time_now (vam) + 1.0;
6907       while (vat_time_now (vam) < timeout)
6908         if (vam->result_ready == 1)
6909           goto out;
6910       vam->retval = -99;
6911
6912     out:
6913       if (vam->retval == -99)
6914         errmsg ("timeout");
6915
6916       if (vam->async_errors > 0)
6917         {
6918           errmsg ("%d asynchronous errors", vam->async_errors);
6919           vam->retval = -98;
6920         }
6921       vam->async_errors = 0;
6922       after = vat_time_now (vam);
6923
6924       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
6925              count, after - before, count / (after - before));
6926     }
6927   else
6928     {
6929       int ret;
6930
6931       /* Wait for a reply... */
6932       W (ret);
6933       return ret;
6934     }
6935   /* Return the good/bad news */
6936   return (vam->retval);
6937 }
6938
6939 static int
6940 api_bridge_domain_set_mac_age (vat_main_t * vam)
6941 {
6942   unformat_input_t *i = vam->input;
6943   vl_api_bridge_domain_set_mac_age_t *mp;
6944   u32 bd_id = ~0;
6945   u32 mac_age = 0;
6946   int ret;
6947
6948   /* Parse args required to build the message */
6949   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6950     {
6951       if (unformat (i, "bd_id %d", &bd_id));
6952       else if (unformat (i, "mac-age %d", &mac_age));
6953       else
6954         break;
6955     }
6956
6957   if (bd_id == ~0)
6958     {
6959       errmsg ("missing bridge domain");
6960       return -99;
6961     }
6962
6963   if (mac_age > 255)
6964     {
6965       errmsg ("mac age must be less than 256 ");
6966       return -99;
6967     }
6968
6969   M (BRIDGE_DOMAIN_SET_MAC_AGE, mp);
6970
6971   mp->bd_id = htonl (bd_id);
6972   mp->mac_age = (u8) mac_age;
6973
6974   S (mp);
6975   W (ret);
6976   return ret;
6977 }
6978
6979 static int
6980 api_l2_flags (vat_main_t * vam)
6981 {
6982   unformat_input_t *i = vam->input;
6983   vl_api_l2_flags_t *mp;
6984   u32 sw_if_index;
6985   u32 flags = 0;
6986   u8 sw_if_index_set = 0;
6987   u8 is_set = 0;
6988   int ret;
6989
6990   /* Parse args required to build the message */
6991   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6992     {
6993       if (unformat (i, "sw_if_index %d", &sw_if_index))
6994         sw_if_index_set = 1;
6995       else if (unformat (i, "sw_if"))
6996         {
6997           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6998             {
6999               if (unformat
7000                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7001                 sw_if_index_set = 1;
7002             }
7003           else
7004             break;
7005         }
7006       else if (unformat (i, "learn"))
7007         flags |= L2_LEARN;
7008       else if (unformat (i, "forward"))
7009         flags |= L2_FWD;
7010       else if (unformat (i, "flood"))
7011         flags |= L2_FLOOD;
7012       else if (unformat (i, "uu-flood"))
7013         flags |= L2_UU_FLOOD;
7014       else if (unformat (i, "arp-term"))
7015         flags |= L2_ARP_TERM;
7016       else if (unformat (i, "off"))
7017         is_set = 0;
7018       else if (unformat (i, "disable"))
7019         is_set = 0;
7020       else
7021         break;
7022     }
7023
7024   if (sw_if_index_set == 0)
7025     {
7026       errmsg ("missing interface name or sw_if_index");
7027       return -99;
7028     }
7029
7030   M (L2_FLAGS, mp);
7031
7032   mp->sw_if_index = ntohl (sw_if_index);
7033   mp->feature_bitmap = ntohl (flags);
7034   mp->is_set = is_set;
7035
7036   S (mp);
7037   W (ret);
7038   return ret;
7039 }
7040
7041 static int
7042 api_bridge_flags (vat_main_t * vam)
7043 {
7044   unformat_input_t *i = vam->input;
7045   vl_api_bridge_flags_t *mp;
7046   u32 bd_id;
7047   u8 bd_id_set = 0;
7048   u8 is_set = 1;
7049   bd_flags_t flags = 0;
7050   int ret;
7051
7052   /* Parse args required to build the message */
7053   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7054     {
7055       if (unformat (i, "bd_id %d", &bd_id))
7056         bd_id_set = 1;
7057       else if (unformat (i, "learn"))
7058         flags |= BRIDGE_API_FLAG_LEARN;
7059       else if (unformat (i, "forward"))
7060         flags |= BRIDGE_API_FLAG_FWD;
7061       else if (unformat (i, "flood"))
7062         flags |= BRIDGE_API_FLAG_FLOOD;
7063       else if (unformat (i, "uu-flood"))
7064         flags |= BRIDGE_API_FLAG_UU_FLOOD;
7065       else if (unformat (i, "arp-term"))
7066         flags |= BRIDGE_API_FLAG_ARP_TERM;
7067       else if (unformat (i, "off"))
7068         is_set = 0;
7069       else if (unformat (i, "disable"))
7070         is_set = 0;
7071       else
7072         break;
7073     }
7074
7075   if (bd_id_set == 0)
7076     {
7077       errmsg ("missing bridge domain");
7078       return -99;
7079     }
7080
7081   M (BRIDGE_FLAGS, mp);
7082
7083   mp->bd_id = ntohl (bd_id);
7084   mp->flags = ntohl (flags);
7085   mp->is_set = is_set;
7086
7087   S (mp);
7088   W (ret);
7089   return ret;
7090 }
7091
7092 static int
7093 api_bd_ip_mac_add_del (vat_main_t * vam)
7094 {
7095   vl_api_address_t ip = VL_API_ZERO_ADDRESS;
7096   vl_api_mac_address_t mac = { 0 };
7097   unformat_input_t *i = vam->input;
7098   vl_api_bd_ip_mac_add_del_t *mp;
7099   u32 bd_id;
7100   u8 is_add = 1;
7101   u8 bd_id_set = 0;
7102   u8 ip_set = 0;
7103   u8 mac_set = 0;
7104   int ret;
7105
7106
7107   /* Parse args required to build the message */
7108   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7109     {
7110       if (unformat (i, "bd_id %d", &bd_id))
7111         {
7112           bd_id_set++;
7113         }
7114       else if (unformat (i, "%U", unformat_vl_api_address, &ip))
7115         {
7116           ip_set++;
7117         }
7118       else if (unformat (i, "%U", unformat_vl_api_mac_address, &mac))
7119         {
7120           mac_set++;
7121         }
7122       else if (unformat (i, "del"))
7123         is_add = 0;
7124       else
7125         break;
7126     }
7127
7128   if (bd_id_set == 0)
7129     {
7130       errmsg ("missing bridge domain");
7131       return -99;
7132     }
7133   else if (ip_set == 0)
7134     {
7135       errmsg ("missing IP address");
7136       return -99;
7137     }
7138   else if (mac_set == 0)
7139     {
7140       errmsg ("missing MAC address");
7141       return -99;
7142     }
7143
7144   M (BD_IP_MAC_ADD_DEL, mp);
7145
7146   mp->entry.bd_id = ntohl (bd_id);
7147   mp->is_add = is_add;
7148
7149   clib_memcpy (&mp->entry.ip, &ip, sizeof (ip));
7150   clib_memcpy (&mp->entry.mac, &mac, sizeof (mac));
7151
7152   S (mp);
7153   W (ret);
7154   return ret;
7155 }
7156
7157 static int
7158 api_bd_ip_mac_flush (vat_main_t * vam)
7159 {
7160   unformat_input_t *i = vam->input;
7161   vl_api_bd_ip_mac_flush_t *mp;
7162   u32 bd_id;
7163   u8 bd_id_set = 0;
7164   int ret;
7165
7166   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7167     {
7168       if (unformat (i, "bd_id %d", &bd_id))
7169         {
7170           bd_id_set++;
7171         }
7172       else
7173         break;
7174     }
7175
7176   if (bd_id_set == 0)
7177     {
7178       errmsg ("missing bridge domain");
7179       return -99;
7180     }
7181
7182   M (BD_IP_MAC_FLUSH, mp);
7183
7184   mp->bd_id = ntohl (bd_id);
7185
7186   S (mp);
7187   W (ret);
7188   return ret;
7189 }
7190
7191 static void vl_api_bd_ip_mac_details_t_handler
7192   (vl_api_bd_ip_mac_details_t * mp)
7193 {
7194   vat_main_t *vam = &vat_main;
7195
7196   print (vam->ofp,
7197          "\n%-5d %U %U",
7198          ntohl (mp->entry.bd_id),
7199          format_vl_api_mac_address, mp->entry.mac,
7200          format_vl_api_address, &mp->entry.ip);
7201 }
7202
7203 static void vl_api_bd_ip_mac_details_t_handler_json
7204   (vl_api_bd_ip_mac_details_t * mp)
7205 {
7206   vat_main_t *vam = &vat_main;
7207   vat_json_node_t *node = NULL;
7208
7209   if (VAT_JSON_ARRAY != vam->json_tree.type)
7210     {
7211       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
7212       vat_json_init_array (&vam->json_tree);
7213     }
7214   node = vat_json_array_add (&vam->json_tree);
7215
7216   vat_json_init_object (node);
7217   vat_json_object_add_uint (node, "bd_id", ntohl (mp->entry.bd_id));
7218   vat_json_object_add_string_copy (node, "mac_address",
7219                                    format (0, "%U", format_vl_api_mac_address,
7220                                            &mp->entry.mac));
7221   u8 *ip = 0;
7222
7223   ip = format (0, "%U", format_vl_api_address, &mp->entry.ip);
7224   vat_json_object_add_string_copy (node, "ip_address", ip);
7225   vec_free (ip);
7226 }
7227
7228 static int
7229 api_bd_ip_mac_dump (vat_main_t * vam)
7230 {
7231   unformat_input_t *i = vam->input;
7232   vl_api_bd_ip_mac_dump_t *mp;
7233   vl_api_control_ping_t *mp_ping;
7234   int ret;
7235   u32 bd_id;
7236   u8 bd_id_set = 0;
7237
7238   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7239     {
7240       if (unformat (i, "bd_id %d", &bd_id))
7241         {
7242           bd_id_set++;
7243         }
7244       else
7245         break;
7246     }
7247
7248   print (vam->ofp,
7249          "\n%-5s %-7s %-20s %-30s",
7250          "bd_id", "is_ipv6", "mac_address", "ip_address");
7251
7252   /* Dump Bridge Domain Ip to Mac entries */
7253   M (BD_IP_MAC_DUMP, mp);
7254
7255   if (bd_id_set)
7256     mp->bd_id = htonl (bd_id);
7257   else
7258     mp->bd_id = ~0;
7259
7260   S (mp);
7261
7262   /* Use a control ping for synchronization */
7263   MPING (CONTROL_PING, mp_ping);
7264   S (mp_ping);
7265
7266   W (ret);
7267   return ret;
7268 }
7269
7270 static int
7271 api_tap_create_v2 (vat_main_t * vam)
7272 {
7273   unformat_input_t *i = vam->input;
7274   vl_api_tap_create_v2_t *mp;
7275   u8 mac_address[6];
7276   u8 random_mac = 1;
7277   u32 id = ~0;
7278   u32 num_rx_queues = 0;
7279   u8 *host_if_name = 0;
7280   u8 host_if_name_set = 0;
7281   u8 *host_ns = 0;
7282   u8 host_ns_set = 0;
7283   u8 host_mac_addr[6];
7284   u8 host_mac_addr_set = 0;
7285   u8 *host_bridge = 0;
7286   u8 host_bridge_set = 0;
7287   u8 host_ip4_prefix_set = 0;
7288   u8 host_ip6_prefix_set = 0;
7289   ip4_address_t host_ip4_addr;
7290   ip4_address_t host_ip4_gw;
7291   u8 host_ip4_gw_set = 0;
7292   u32 host_ip4_prefix_len = 0;
7293   ip6_address_t host_ip6_addr;
7294   ip6_address_t host_ip6_gw;
7295   u8 host_ip6_gw_set = 0;
7296   u32 host_ip6_prefix_len = 0;
7297   u32 host_mtu_size = 0;
7298   u8 host_mtu_set = 0;
7299   u32 tap_flags = 0;
7300   int ret;
7301   u32 rx_ring_sz = 0, tx_ring_sz = 0;
7302
7303   clib_memset (mac_address, 0, sizeof (mac_address));
7304
7305   /* Parse args required to build the message */
7306   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7307     {
7308       if (unformat (i, "id %u", &id))
7309         ;
7310       else
7311         if (unformat
7312             (i, "hw-addr %U", unformat_ethernet_address, mac_address))
7313         random_mac = 0;
7314       else if (unformat (i, "host-if-name %s", &host_if_name))
7315         host_if_name_set = 1;
7316       else if (unformat (i, "num-rx-queues %u", &num_rx_queues))
7317         ;
7318       else if (unformat (i, "host-ns %s", &host_ns))
7319         host_ns_set = 1;
7320       else if (unformat (i, "host-mac-addr %U", unformat_ethernet_address,
7321                          host_mac_addr))
7322         host_mac_addr_set = 1;
7323       else if (unformat (i, "host-bridge %s", &host_bridge))
7324         host_bridge_set = 1;
7325       else if (unformat (i, "host-ip4-addr %U/%u", unformat_ip4_address,
7326                          &host_ip4_addr, &host_ip4_prefix_len))
7327         host_ip4_prefix_set = 1;
7328       else if (unformat (i, "host-ip6-addr %U/%u", unformat_ip6_address,
7329                          &host_ip6_addr, &host_ip6_prefix_len))
7330         host_ip6_prefix_set = 1;
7331       else if (unformat (i, "host-ip4-gw %U", unformat_ip4_address,
7332                          &host_ip4_gw))
7333         host_ip4_gw_set = 1;
7334       else if (unformat (i, "host-ip6-gw %U", unformat_ip6_address,
7335                          &host_ip6_gw))
7336         host_ip6_gw_set = 1;
7337       else if (unformat (i, "rx-ring-size %u", &rx_ring_sz))
7338         ;
7339       else if (unformat (i, "tx-ring-size %u", &tx_ring_sz))
7340         ;
7341       else if (unformat (i, "host-mtu-size %u", &host_mtu_size))
7342         host_mtu_set = 1;
7343       else if (unformat (i, "no-gso"))
7344         tap_flags &= ~TAP_FLAG_GSO;
7345       else if (unformat (i, "gso"))
7346         tap_flags |= TAP_FLAG_GSO;
7347       else if (unformat (i, "csum-offload"))
7348         tap_flags |= TAP_FLAG_CSUM_OFFLOAD;
7349       else
7350         break;
7351     }
7352
7353   if (vec_len (host_if_name) > 63)
7354     {
7355       errmsg ("tap name too long. ");
7356       return -99;
7357     }
7358   if (vec_len (host_ns) > 63)
7359     {
7360       errmsg ("host name space too long. ");
7361       return -99;
7362     }
7363   if (vec_len (host_bridge) > 63)
7364     {
7365       errmsg ("host bridge name too long. ");
7366       return -99;
7367     }
7368   if (host_ip4_prefix_len > 32)
7369     {
7370       errmsg ("host ip4 prefix length not valid. ");
7371       return -99;
7372     }
7373   if (host_ip6_prefix_len > 128)
7374     {
7375       errmsg ("host ip6 prefix length not valid. ");
7376       return -99;
7377     }
7378   if (!is_pow2 (rx_ring_sz))
7379     {
7380       errmsg ("rx ring size must be power of 2. ");
7381       return -99;
7382     }
7383   if (rx_ring_sz > 32768)
7384     {
7385       errmsg ("rx ring size must be 32768 or lower. ");
7386       return -99;
7387     }
7388   if (!is_pow2 (tx_ring_sz))
7389     {
7390       errmsg ("tx ring size must be power of 2. ");
7391       return -99;
7392     }
7393   if (tx_ring_sz > 32768)
7394     {
7395       errmsg ("tx ring size must be 32768 or lower. ");
7396       return -99;
7397     }
7398   if (host_mtu_set && (host_mtu_size < 64 || host_mtu_size > 65355))
7399     {
7400       errmsg ("host MTU size must be in between 64 and 65355. ");
7401       return -99;
7402     }
7403
7404   /* Construct the API message */
7405   M (TAP_CREATE_V2, mp);
7406
7407   mp->id = ntohl (id);
7408   mp->use_random_mac = random_mac;
7409   mp->num_rx_queues = (u8) num_rx_queues;
7410   mp->tx_ring_sz = ntohs (tx_ring_sz);
7411   mp->rx_ring_sz = ntohs (rx_ring_sz);
7412   mp->host_mtu_set = host_mtu_set;
7413   mp->host_mtu_size = ntohl (host_mtu_size);
7414   mp->host_mac_addr_set = host_mac_addr_set;
7415   mp->host_ip4_prefix_set = host_ip4_prefix_set;
7416   mp->host_ip6_prefix_set = host_ip6_prefix_set;
7417   mp->host_ip4_gw_set = host_ip4_gw_set;
7418   mp->host_ip6_gw_set = host_ip6_gw_set;
7419   mp->tap_flags = ntohl (tap_flags);
7420   mp->host_namespace_set = host_ns_set;
7421   mp->host_if_name_set = host_if_name_set;
7422   mp->host_bridge_set = host_bridge_set;
7423
7424   if (random_mac == 0)
7425     clib_memcpy (mp->mac_address, mac_address, 6);
7426   if (host_mac_addr_set)
7427     clib_memcpy (mp->host_mac_addr, host_mac_addr, 6);
7428   if (host_if_name_set)
7429     clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
7430   if (host_ns_set)
7431     clib_memcpy (mp->host_namespace, host_ns, vec_len (host_ns));
7432   if (host_bridge_set)
7433     clib_memcpy (mp->host_bridge, host_bridge, vec_len (host_bridge));
7434   if (host_ip4_prefix_set)
7435     {
7436       clib_memcpy (mp->host_ip4_prefix.address, &host_ip4_addr, 4);
7437       mp->host_ip4_prefix.len = (u8) host_ip4_prefix_len;
7438     }
7439   if (host_ip6_prefix_set)
7440     {
7441       clib_memcpy (mp->host_ip6_prefix.address, &host_ip6_addr, 16);
7442       mp->host_ip6_prefix.len = (u8) host_ip6_prefix_len;
7443     }
7444   if (host_ip4_gw_set)
7445     clib_memcpy (mp->host_ip4_gw, &host_ip4_gw, 4);
7446   if (host_ip6_gw_set)
7447     clib_memcpy (mp->host_ip6_gw, &host_ip6_gw, 16);
7448
7449   vec_free (host_ns);
7450   vec_free (host_if_name);
7451   vec_free (host_bridge);
7452
7453   /* send it... */
7454   S (mp);
7455
7456   /* Wait for a reply... */
7457   W (ret);
7458   return ret;
7459 }
7460
7461 static int
7462 api_tap_delete_v2 (vat_main_t * vam)
7463 {
7464   unformat_input_t *i = vam->input;
7465   vl_api_tap_delete_v2_t *mp;
7466   u32 sw_if_index = ~0;
7467   u8 sw_if_index_set = 0;
7468   int ret;
7469
7470   /* Parse args required to build the message */
7471   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7472     {
7473       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7474         sw_if_index_set = 1;
7475       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7476         sw_if_index_set = 1;
7477       else
7478         break;
7479     }
7480
7481   if (sw_if_index_set == 0)
7482     {
7483       errmsg ("missing vpp interface name. ");
7484       return -99;
7485     }
7486
7487   /* Construct the API message */
7488   M (TAP_DELETE_V2, mp);
7489
7490   mp->sw_if_index = ntohl (sw_if_index);
7491
7492   /* send it... */
7493   S (mp);
7494
7495   /* Wait for a reply... */
7496   W (ret);
7497   return ret;
7498 }
7499
7500 uword
7501 unformat_vlib_pci_addr (unformat_input_t * input, va_list * args)
7502 {
7503   vlib_pci_addr_t *addr = va_arg (*args, vlib_pci_addr_t *);
7504   u32 x[4];
7505
7506   if (!unformat (input, "%x:%x:%x.%x", &x[0], &x[1], &x[2], &x[3]))
7507     return 0;
7508
7509   addr->domain = x[0];
7510   addr->bus = x[1];
7511   addr->slot = x[2];
7512   addr->function = x[3];
7513
7514   return 1;
7515 }
7516
7517 static int
7518 api_virtio_pci_create (vat_main_t * vam)
7519 {
7520   unformat_input_t *i = vam->input;
7521   vl_api_virtio_pci_create_t *mp;
7522   u8 mac_address[6];
7523   u8 random_mac = 1;
7524   u8 gso_enabled = 0;
7525   u8 checksum_offload_enabled = 0;
7526   u32 pci_addr = 0;
7527   u64 features = (u64) ~ (0ULL);
7528   int ret;
7529
7530   clib_memset (mac_address, 0, sizeof (mac_address));
7531
7532   /* Parse args required to build the message */
7533   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7534     {
7535       if (unformat (i, "hw-addr %U", unformat_ethernet_address, mac_address))
7536         {
7537           random_mac = 0;
7538         }
7539       else if (unformat (i, "pci-addr %U", unformat_vlib_pci_addr, &pci_addr))
7540         ;
7541       else if (unformat (i, "features 0x%llx", &features))
7542         ;
7543       else if (unformat (i, "gso-enabled"))
7544         gso_enabled = 1;
7545       else if (unformat (i, "csum-offload-enabled"))
7546         checksum_offload_enabled = 1;
7547       else
7548         break;
7549     }
7550
7551   if (pci_addr == 0)
7552     {
7553       errmsg ("pci address must be non zero. ");
7554       return -99;
7555     }
7556
7557   /* Construct the API message */
7558   M (VIRTIO_PCI_CREATE, mp);
7559
7560   mp->use_random_mac = random_mac;
7561
7562   mp->pci_addr.domain = htons (((vlib_pci_addr_t) pci_addr).domain);
7563   mp->pci_addr.bus = ((vlib_pci_addr_t) pci_addr).bus;
7564   mp->pci_addr.slot = ((vlib_pci_addr_t) pci_addr).slot;
7565   mp->pci_addr.function = ((vlib_pci_addr_t) pci_addr).function;
7566
7567   mp->features = clib_host_to_net_u64 (features);
7568   mp->gso_enabled = gso_enabled;
7569   mp->checksum_offload_enabled = checksum_offload_enabled;
7570
7571   if (random_mac == 0)
7572     clib_memcpy (mp->mac_address, mac_address, 6);
7573
7574   /* send it... */
7575   S (mp);
7576
7577   /* Wait for a reply... */
7578   W (ret);
7579   return ret;
7580 }
7581
7582 static int
7583 api_virtio_pci_delete (vat_main_t * vam)
7584 {
7585   unformat_input_t *i = vam->input;
7586   vl_api_virtio_pci_delete_t *mp;
7587   u32 sw_if_index = ~0;
7588   u8 sw_if_index_set = 0;
7589   int ret;
7590
7591   /* Parse args required to build the message */
7592   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7593     {
7594       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7595         sw_if_index_set = 1;
7596       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7597         sw_if_index_set = 1;
7598       else
7599         break;
7600     }
7601
7602   if (sw_if_index_set == 0)
7603     {
7604       errmsg ("missing vpp interface name. ");
7605       return -99;
7606     }
7607
7608   /* Construct the API message */
7609   M (VIRTIO_PCI_DELETE, mp);
7610
7611   mp->sw_if_index = htonl (sw_if_index);
7612
7613   /* send it... */
7614   S (mp);
7615
7616   /* Wait for a reply... */
7617   W (ret);
7618   return ret;
7619 }
7620
7621 static int
7622 api_bond_create (vat_main_t * vam)
7623 {
7624   unformat_input_t *i = vam->input;
7625   vl_api_bond_create_t *mp;
7626   u8 mac_address[6];
7627   u8 custom_mac = 0;
7628   int ret;
7629   u8 mode;
7630   u8 lb;
7631   u8 mode_is_set = 0;
7632   u32 id = ~0;
7633   u8 numa_only = 0;
7634
7635   clib_memset (mac_address, 0, sizeof (mac_address));
7636   lb = BOND_LB_L2;
7637
7638   /* Parse args required to build the message */
7639   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7640     {
7641       if (unformat (i, "mode %U", unformat_bond_mode, &mode))
7642         mode_is_set = 1;
7643       else if (((mode == BOND_MODE_LACP) || (mode == BOND_MODE_XOR))
7644                && unformat (i, "lb %U", unformat_bond_load_balance, &lb))
7645         ;
7646       else if (unformat (i, "hw-addr %U", unformat_ethernet_address,
7647                          mac_address))
7648         custom_mac = 1;
7649       else if (unformat (i, "numa-only"))
7650         numa_only = 1;
7651       else if (unformat (i, "id %u", &id))
7652         ;
7653       else
7654         break;
7655     }
7656
7657   if (mode_is_set == 0)
7658     {
7659       errmsg ("Missing bond mode. ");
7660       return -99;
7661     }
7662
7663   /* Construct the API message */
7664   M (BOND_CREATE, mp);
7665
7666   mp->use_custom_mac = custom_mac;
7667
7668   mp->mode = htonl (mode);
7669   mp->lb = htonl (lb);
7670   mp->id = htonl (id);
7671   mp->numa_only = numa_only;
7672
7673   if (custom_mac)
7674     clib_memcpy (mp->mac_address, mac_address, 6);
7675
7676   /* send it... */
7677   S (mp);
7678
7679   /* Wait for a reply... */
7680   W (ret);
7681   return ret;
7682 }
7683
7684 static int
7685 api_bond_delete (vat_main_t * vam)
7686 {
7687   unformat_input_t *i = vam->input;
7688   vl_api_bond_delete_t *mp;
7689   u32 sw_if_index = ~0;
7690   u8 sw_if_index_set = 0;
7691   int ret;
7692
7693   /* Parse args required to build the message */
7694   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7695     {
7696       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7697         sw_if_index_set = 1;
7698       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7699         sw_if_index_set = 1;
7700       else
7701         break;
7702     }
7703
7704   if (sw_if_index_set == 0)
7705     {
7706       errmsg ("missing vpp interface name. ");
7707       return -99;
7708     }
7709
7710   /* Construct the API message */
7711   M (BOND_DELETE, mp);
7712
7713   mp->sw_if_index = ntohl (sw_if_index);
7714
7715   /* send it... */
7716   S (mp);
7717
7718   /* Wait for a reply... */
7719   W (ret);
7720   return ret;
7721 }
7722
7723 static int
7724 api_bond_enslave (vat_main_t * vam)
7725 {
7726   unformat_input_t *i = vam->input;
7727   vl_api_bond_enslave_t *mp;
7728   u32 bond_sw_if_index;
7729   int ret;
7730   u8 is_passive;
7731   u8 is_long_timeout;
7732   u32 bond_sw_if_index_is_set = 0;
7733   u32 sw_if_index;
7734   u8 sw_if_index_is_set = 0;
7735
7736   /* Parse args required to build the message */
7737   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7738     {
7739       if (unformat (i, "sw_if_index %d", &sw_if_index))
7740         sw_if_index_is_set = 1;
7741       else if (unformat (i, "bond %u", &bond_sw_if_index))
7742         bond_sw_if_index_is_set = 1;
7743       else if (unformat (i, "passive %d", &is_passive))
7744         ;
7745       else if (unformat (i, "long-timeout %d", &is_long_timeout))
7746         ;
7747       else
7748         break;
7749     }
7750
7751   if (bond_sw_if_index_is_set == 0)
7752     {
7753       errmsg ("Missing bond sw_if_index. ");
7754       return -99;
7755     }
7756   if (sw_if_index_is_set == 0)
7757     {
7758       errmsg ("Missing slave sw_if_index. ");
7759       return -99;
7760     }
7761
7762   /* Construct the API message */
7763   M (BOND_ENSLAVE, mp);
7764
7765   mp->bond_sw_if_index = ntohl (bond_sw_if_index);
7766   mp->sw_if_index = ntohl (sw_if_index);
7767   mp->is_long_timeout = is_long_timeout;
7768   mp->is_passive = is_passive;
7769
7770   /* send it... */
7771   S (mp);
7772
7773   /* Wait for a reply... */
7774   W (ret);
7775   return ret;
7776 }
7777
7778 static int
7779 api_bond_detach_slave (vat_main_t * vam)
7780 {
7781   unformat_input_t *i = vam->input;
7782   vl_api_bond_detach_slave_t *mp;
7783   u32 sw_if_index = ~0;
7784   u8 sw_if_index_set = 0;
7785   int ret;
7786
7787   /* Parse args required to build the message */
7788   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7789     {
7790       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7791         sw_if_index_set = 1;
7792       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7793         sw_if_index_set = 1;
7794       else
7795         break;
7796     }
7797
7798   if (sw_if_index_set == 0)
7799     {
7800       errmsg ("missing vpp interface name. ");
7801       return -99;
7802     }
7803
7804   /* Construct the API message */
7805   M (BOND_DETACH_SLAVE, mp);
7806
7807   mp->sw_if_index = ntohl (sw_if_index);
7808
7809   /* send it... */
7810   S (mp);
7811
7812   /* Wait for a reply... */
7813   W (ret);
7814   return ret;
7815 }
7816
7817 static int
7818 api_ip_table_add_del (vat_main_t * vam)
7819 {
7820   unformat_input_t *i = vam->input;
7821   vl_api_ip_table_add_del_t *mp;
7822   u32 table_id = ~0;
7823   u8 is_ipv6 = 0;
7824   u8 is_add = 1;
7825   int ret = 0;
7826
7827   /* Parse args required to build the message */
7828   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7829     {
7830       if (unformat (i, "ipv6"))
7831         is_ipv6 = 1;
7832       else if (unformat (i, "del"))
7833         is_add = 0;
7834       else if (unformat (i, "add"))
7835         is_add = 1;
7836       else if (unformat (i, "table %d", &table_id))
7837         ;
7838       else
7839         {
7840           clib_warning ("parse error '%U'", format_unformat_error, i);
7841           return -99;
7842         }
7843     }
7844
7845   if (~0 == table_id)
7846     {
7847       errmsg ("missing table-ID");
7848       return -99;
7849     }
7850
7851   /* Construct the API message */
7852   M (IP_TABLE_ADD_DEL, mp);
7853
7854   mp->table.table_id = ntohl (table_id);
7855   mp->table.is_ip6 = is_ipv6;
7856   mp->is_add = is_add;
7857
7858   /* send it... */
7859   S (mp);
7860
7861   /* Wait for a reply... */
7862   W (ret);
7863
7864   return ret;
7865 }
7866
7867 uword
7868 unformat_fib_path (unformat_input_t * input, va_list * args)
7869 {
7870   vat_main_t *vam = va_arg (*args, vat_main_t *);
7871   vl_api_fib_path_t *path = va_arg (*args, vl_api_fib_path_t *);
7872   u32 weight, preference;
7873   mpls_label_t out_label;
7874
7875   clib_memset (path, 0, sizeof (*path));
7876   path->weight = 1;
7877   path->sw_if_index = ~0;
7878   path->rpf_id = ~0;
7879   path->n_labels = 0;
7880
7881   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7882     {
7883       if (unformat (input, "%U %U",
7884                     unformat_vl_api_ip4_address,
7885                     &path->nh.address.ip4,
7886                     api_unformat_sw_if_index, vam, &path->sw_if_index))
7887         {
7888           path->proto = FIB_API_PATH_NH_PROTO_IP4;
7889         }
7890       else if (unformat (input, "%U %U",
7891                          unformat_vl_api_ip6_address,
7892                          &path->nh.address.ip6,
7893                          api_unformat_sw_if_index, vam, &path->sw_if_index))
7894         {
7895           path->proto = FIB_API_PATH_NH_PROTO_IP6;
7896         }
7897       else if (unformat (input, "weight %u", &weight))
7898         {
7899           path->weight = weight;
7900         }
7901       else if (unformat (input, "preference %u", &preference))
7902         {
7903           path->preference = preference;
7904         }
7905       else if (unformat (input, "%U next-hop-table %d",
7906                          unformat_vl_api_ip4_address,
7907                          &path->nh.address.ip4, &path->table_id))
7908         {
7909           path->proto = FIB_API_PATH_NH_PROTO_IP4;
7910         }
7911       else if (unformat (input, "%U next-hop-table %d",
7912                          unformat_vl_api_ip6_address,
7913                          &path->nh.address.ip6, &path->table_id))
7914         {
7915           path->proto = FIB_API_PATH_NH_PROTO_IP6;
7916         }
7917       else if (unformat (input, "%U",
7918                          unformat_vl_api_ip4_address, &path->nh.address.ip4))
7919         {
7920           /*
7921            * the recursive next-hops are by default in the default table
7922            */
7923           path->table_id = 0;
7924           path->sw_if_index = ~0;
7925           path->proto = FIB_API_PATH_NH_PROTO_IP4;
7926         }
7927       else if (unformat (input, "%U",
7928                          unformat_vl_api_ip6_address, &path->nh.address.ip6))
7929         {
7930           /*
7931            * the recursive next-hops are by default in the default table
7932            */
7933           path->table_id = 0;
7934           path->sw_if_index = ~0;
7935           path->proto = FIB_API_PATH_NH_PROTO_IP6;
7936         }
7937       else if (unformat (input, "resolve-via-host"))
7938         {
7939           path->flags |= FIB_API_PATH_FLAG_RESOLVE_VIA_HOST;
7940         }
7941       else if (unformat (input, "resolve-via-attached"))
7942         {
7943           path->flags |= FIB_API_PATH_FLAG_RESOLVE_VIA_ATTACHED;
7944         }
7945       else if (unformat (input, "ip4-lookup-in-table %d", &path->table_id))
7946         {
7947           path->type = FIB_API_PATH_TYPE_LOCAL;
7948           path->sw_if_index = ~0;
7949           path->proto = FIB_API_PATH_NH_PROTO_IP4;
7950         }
7951       else if (unformat (input, "ip6-lookup-in-table %d", &path->table_id))
7952         {
7953           path->type = FIB_API_PATH_TYPE_LOCAL;
7954           path->sw_if_index = ~0;
7955           path->proto = FIB_API_PATH_NH_PROTO_IP6;
7956         }
7957       else if (unformat (input, "sw_if_index %d", &path->sw_if_index))
7958         ;
7959       else if (unformat (input, "via-label %d", &path->nh.via_label))
7960         {
7961           path->proto = FIB_API_PATH_NH_PROTO_MPLS;
7962           path->sw_if_index = ~0;
7963         }
7964       else if (unformat (input, "l2-input-on %d", &path->sw_if_index))
7965         {
7966           path->proto = FIB_API_PATH_NH_PROTO_ETHERNET;
7967           path->type = FIB_API_PATH_TYPE_INTERFACE_RX;
7968         }
7969       else if (unformat (input, "local"))
7970         {
7971           path->type = FIB_API_PATH_TYPE_LOCAL;
7972         }
7973       else if (unformat (input, "out-labels"))
7974         {
7975           while (unformat (input, "%d", &out_label))
7976             {
7977               path->label_stack[path->n_labels].label = out_label;
7978               path->label_stack[path->n_labels].is_uniform = 0;
7979               path->label_stack[path->n_labels].ttl = 64;
7980               path->n_labels++;
7981             }
7982         }
7983       else if (unformat (input, "via"))
7984         {
7985           /* new path, back up and return */
7986           unformat_put_input (input);
7987           unformat_put_input (input);
7988           unformat_put_input (input);
7989           unformat_put_input (input);
7990           break;
7991         }
7992       else
7993         {
7994           return (0);
7995         }
7996     }
7997
7998   path->proto = ntohl (path->proto);
7999   path->type = ntohl (path->type);
8000   path->flags = ntohl (path->flags);
8001   path->table_id = ntohl (path->table_id);
8002   path->sw_if_index = ntohl (path->sw_if_index);
8003
8004   return (1);
8005 }
8006
8007 static int
8008 api_ip_route_add_del (vat_main_t * vam)
8009 {
8010   unformat_input_t *i = vam->input;
8011   vl_api_ip_route_add_del_t *mp;
8012   u32 vrf_id = 0;
8013   u8 is_add = 1;
8014   u8 is_multipath = 0;
8015   u8 prefix_set = 0;
8016   u8 path_count = 0;
8017   vl_api_prefix_t pfx = { };
8018   vl_api_fib_path_t paths[8];
8019   int count = 1;
8020   int j;
8021   f64 before = 0;
8022   u32 random_add_del = 0;
8023   u32 *random_vector = 0;
8024   u32 random_seed = 0xdeaddabe;
8025
8026   /* Parse args required to build the message */
8027   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8028     {
8029       if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
8030         prefix_set = 1;
8031       else if (unformat (i, "del"))
8032         is_add = 0;
8033       else if (unformat (i, "add"))
8034         is_add = 1;
8035       else if (unformat (i, "vrf %d", &vrf_id))
8036         ;
8037       else if (unformat (i, "count %d", &count))
8038         ;
8039       else if (unformat (i, "random"))
8040         random_add_del = 1;
8041       else if (unformat (i, "multipath"))
8042         is_multipath = 1;
8043       else if (unformat (i, "seed %d", &random_seed))
8044         ;
8045       else
8046         if (unformat
8047             (i, "via %U", unformat_fib_path, vam, &paths[path_count]))
8048         {
8049           path_count++;
8050           if (8 == path_count)
8051             {
8052               errmsg ("max 8 paths");
8053               return -99;
8054             }
8055         }
8056       else
8057         {
8058           clib_warning ("parse error '%U'", format_unformat_error, i);
8059           return -99;
8060         }
8061     }
8062
8063   if (!path_count)
8064     {
8065       errmsg ("specify a path; via ...");
8066       return -99;
8067     }
8068   if (prefix_set == 0)
8069     {
8070       errmsg ("missing prefix");
8071       return -99;
8072     }
8073
8074   /* Generate a pile of unique, random routes */
8075   if (random_add_del)
8076     {
8077       ip4_address_t *i = (ip4_address_t *) & paths[0].nh.address.ip4;
8078       u32 this_random_address;
8079       uword *random_hash;
8080
8081       random_hash = hash_create (count, sizeof (uword));
8082
8083       hash_set (random_hash, i->as_u32, 1);
8084       for (j = 0; j <= count; j++)
8085         {
8086           do
8087             {
8088               this_random_address = random_u32 (&random_seed);
8089               this_random_address =
8090                 clib_host_to_net_u32 (this_random_address);
8091             }
8092           while (hash_get (random_hash, this_random_address));
8093           vec_add1 (random_vector, this_random_address);
8094           hash_set (random_hash, this_random_address, 1);
8095         }
8096       hash_free (random_hash);
8097       set_ip4_address (&pfx.address, random_vector[0]);
8098     }
8099
8100   if (count > 1)
8101     {
8102       /* Turn on async mode */
8103       vam->async_mode = 1;
8104       vam->async_errors = 0;
8105       before = vat_time_now (vam);
8106     }
8107
8108   for (j = 0; j < count; j++)
8109     {
8110       /* Construct the API message */
8111       M2 (IP_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t) * path_count);
8112
8113       mp->is_add = is_add;
8114       mp->is_multipath = is_multipath;
8115
8116       clib_memcpy (&mp->route.prefix, &pfx, sizeof (pfx));
8117       mp->route.table_id = ntohl (vrf_id);
8118       mp->route.n_paths = path_count;
8119
8120       clib_memcpy (&mp->route.paths, &paths, sizeof (paths[0]) * path_count);
8121
8122       if (random_add_del)
8123         set_ip4_address (&pfx.address, random_vector[j + 1]);
8124       else
8125         increment_address (&pfx.address);
8126       /* send it... */
8127       S (mp);
8128       /* If we receive SIGTERM, stop now... */
8129       if (vam->do_exit)
8130         break;
8131     }
8132
8133   /* When testing multiple add/del ops, use a control-ping to sync */
8134   if (count > 1)
8135     {
8136       vl_api_control_ping_t *mp_ping;
8137       f64 after;
8138       f64 timeout;
8139
8140       /* Shut off async mode */
8141       vam->async_mode = 0;
8142
8143       MPING (CONTROL_PING, mp_ping);
8144       S (mp_ping);
8145
8146       timeout = vat_time_now (vam) + 1.0;
8147       while (vat_time_now (vam) < timeout)
8148         if (vam->result_ready == 1)
8149           goto out;
8150       vam->retval = -99;
8151
8152     out:
8153       if (vam->retval == -99)
8154         errmsg ("timeout");
8155
8156       if (vam->async_errors > 0)
8157         {
8158           errmsg ("%d asynchronous errors", vam->async_errors);
8159           vam->retval = -98;
8160         }
8161       vam->async_errors = 0;
8162       after = vat_time_now (vam);
8163
8164       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8165       if (j > 0)
8166         count = j;
8167
8168       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8169              count, after - before, count / (after - before));
8170     }
8171   else
8172     {
8173       int ret;
8174
8175       /* Wait for a reply... */
8176       W (ret);
8177       return ret;
8178     }
8179
8180   /* Return the good/bad news */
8181   return (vam->retval);
8182 }
8183
8184 static int
8185 api_ip_mroute_add_del (vat_main_t * vam)
8186 {
8187   unformat_input_t *i = vam->input;
8188   u8 path_set = 0, prefix_set = 0, is_add = 1;
8189   vl_api_ip_mroute_add_del_t *mp;
8190   mfib_entry_flags_t eflags = 0;
8191   vl_api_mfib_path_t path;
8192   vl_api_mprefix_t pfx = { };
8193   u32 vrf_id = 0;
8194   int ret;
8195
8196   /* Parse args required to build the message */
8197   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8198     {
8199       if (unformat (i, "%U", unformat_vl_api_mprefix, &pfx))
8200         {
8201           prefix_set = 1;
8202           pfx.grp_address_length = htons (pfx.grp_address_length);
8203         }
8204       else if (unformat (i, "del"))
8205         is_add = 0;
8206       else if (unformat (i, "add"))
8207         is_add = 1;
8208       else if (unformat (i, "vrf %d", &vrf_id))
8209         ;
8210       else if (unformat (i, "%U", unformat_mfib_itf_flags, &path.itf_flags))
8211         path.itf_flags = htonl (path.itf_flags);
8212       else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
8213         ;
8214       else if (unformat (i, "via %U", unformat_fib_path, vam, &path.path))
8215         path_set = 1;
8216       else
8217         {
8218           clib_warning ("parse error '%U'", format_unformat_error, i);
8219           return -99;
8220         }
8221     }
8222
8223   if (prefix_set == 0)
8224     {
8225       errmsg ("missing addresses\n");
8226       return -99;
8227     }
8228   if (path_set == 0)
8229     {
8230       errmsg ("missing path\n");
8231       return -99;
8232     }
8233
8234   /* Construct the API message */
8235   M (IP_MROUTE_ADD_DEL, mp);
8236
8237   mp->is_add = is_add;
8238   mp->is_multipath = 1;
8239
8240   clib_memcpy (&mp->route.prefix, &pfx, sizeof (pfx));
8241   mp->route.table_id = htonl (vrf_id);
8242   mp->route.n_paths = 1;
8243   mp->route.entry_flags = htonl (eflags);
8244
8245   clib_memcpy (&mp->route.paths, &path, sizeof (path));
8246
8247   /* send it... */
8248   S (mp);
8249   /* Wait for a reply... */
8250   W (ret);
8251   return ret;
8252 }
8253
8254 static int
8255 api_mpls_table_add_del (vat_main_t * vam)
8256 {
8257   unformat_input_t *i = vam->input;
8258   vl_api_mpls_table_add_del_t *mp;
8259   u32 table_id = ~0;
8260   u8 is_add = 1;
8261   int ret = 0;
8262
8263   /* Parse args required to build the message */
8264   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8265     {
8266       if (unformat (i, "table %d", &table_id))
8267         ;
8268       else if (unformat (i, "del"))
8269         is_add = 0;
8270       else if (unformat (i, "add"))
8271         is_add = 1;
8272       else
8273         {
8274           clib_warning ("parse error '%U'", format_unformat_error, i);
8275           return -99;
8276         }
8277     }
8278
8279   if (~0 == table_id)
8280     {
8281       errmsg ("missing table-ID");
8282       return -99;
8283     }
8284
8285   /* Construct the API message */
8286   M (MPLS_TABLE_ADD_DEL, mp);
8287
8288   mp->mt_table.mt_table_id = ntohl (table_id);
8289   mp->mt_is_add = is_add;
8290
8291   /* send it... */
8292   S (mp);
8293
8294   /* Wait for a reply... */
8295   W (ret);
8296
8297   return ret;
8298 }
8299
8300 static int
8301 api_mpls_route_add_del (vat_main_t * vam)
8302 {
8303   u8 is_add = 1, path_count = 0, is_multipath = 0, is_eos = 0;
8304   mpls_label_t local_label = MPLS_LABEL_INVALID;
8305   unformat_input_t *i = vam->input;
8306   vl_api_mpls_route_add_del_t *mp;
8307   vl_api_fib_path_t paths[8];
8308   int count = 1, j;
8309   f64 before = 0;
8310
8311   /* Parse args required to build the message */
8312   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8313     {
8314       if (unformat (i, "%d", &local_label))
8315         ;
8316       else if (unformat (i, "eos"))
8317         is_eos = 1;
8318       else if (unformat (i, "non-eos"))
8319         is_eos = 0;
8320       else if (unformat (i, "del"))
8321         is_add = 0;
8322       else if (unformat (i, "add"))
8323         is_add = 1;
8324       else if (unformat (i, "multipath"))
8325         is_multipath = 1;
8326       else if (unformat (i, "count %d", &count))
8327         ;
8328       else
8329         if (unformat
8330             (i, "via %U", unformat_fib_path, vam, &paths[path_count]))
8331         {
8332           path_count++;
8333           if (8 == path_count)
8334             {
8335               errmsg ("max 8 paths");
8336               return -99;
8337             }
8338         }
8339       else
8340         {
8341           clib_warning ("parse error '%U'", format_unformat_error, i);
8342           return -99;
8343         }
8344     }
8345
8346   if (!path_count)
8347     {
8348       errmsg ("specify a path; via ...");
8349       return -99;
8350     }
8351
8352   if (MPLS_LABEL_INVALID == local_label)
8353     {
8354       errmsg ("missing label");
8355       return -99;
8356     }
8357
8358   if (count > 1)
8359     {
8360       /* Turn on async mode */
8361       vam->async_mode = 1;
8362       vam->async_errors = 0;
8363       before = vat_time_now (vam);
8364     }
8365
8366   for (j = 0; j < count; j++)
8367     {
8368       /* Construct the API message */
8369       M2 (MPLS_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t) * path_count);
8370
8371       mp->mr_is_add = is_add;
8372       mp->mr_is_multipath = is_multipath;
8373
8374       mp->mr_route.mr_label = local_label;
8375       mp->mr_route.mr_eos = is_eos;
8376       mp->mr_route.mr_table_id = 0;
8377       mp->mr_route.mr_n_paths = path_count;
8378
8379       clib_memcpy (&mp->mr_route.mr_paths, paths,
8380                    sizeof (paths[0]) * path_count);
8381
8382       local_label++;
8383
8384       /* send it... */
8385       S (mp);
8386       /* If we receive SIGTERM, stop now... */
8387       if (vam->do_exit)
8388         break;
8389     }
8390
8391   /* When testing multiple add/del ops, use a control-ping to sync */
8392   if (count > 1)
8393     {
8394       vl_api_control_ping_t *mp_ping;
8395       f64 after;
8396       f64 timeout;
8397
8398       /* Shut off async mode */
8399       vam->async_mode = 0;
8400
8401       MPING (CONTROL_PING, mp_ping);
8402       S (mp_ping);
8403
8404       timeout = vat_time_now (vam) + 1.0;
8405       while (vat_time_now (vam) < timeout)
8406         if (vam->result_ready == 1)
8407           goto out;
8408       vam->retval = -99;
8409
8410     out:
8411       if (vam->retval == -99)
8412         errmsg ("timeout");
8413
8414       if (vam->async_errors > 0)
8415         {
8416           errmsg ("%d asynchronous errors", vam->async_errors);
8417           vam->retval = -98;
8418         }
8419       vam->async_errors = 0;
8420       after = vat_time_now (vam);
8421
8422       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8423       if (j > 0)
8424         count = j;
8425
8426       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8427              count, after - before, count / (after - before));
8428     }
8429   else
8430     {
8431       int ret;
8432
8433       /* Wait for a reply... */
8434       W (ret);
8435       return ret;
8436     }
8437
8438   /* Return the good/bad news */
8439   return (vam->retval);
8440   return (0);
8441 }
8442
8443 static int
8444 api_mpls_ip_bind_unbind (vat_main_t * vam)
8445 {
8446   unformat_input_t *i = vam->input;
8447   vl_api_mpls_ip_bind_unbind_t *mp;
8448   u32 ip_table_id = 0;
8449   u8 is_bind = 1;
8450   vl_api_prefix_t pfx;
8451   u8 prefix_set = 0;
8452   mpls_label_t local_label = MPLS_LABEL_INVALID;
8453   int ret;
8454
8455   /* Parse args required to build the message */
8456   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8457     {
8458       if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
8459         prefix_set = 1;
8460       else if (unformat (i, "%d", &local_label))
8461         ;
8462       else if (unformat (i, "table-id %d", &ip_table_id))
8463         ;
8464       else if (unformat (i, "unbind"))
8465         is_bind = 0;
8466       else if (unformat (i, "bind"))
8467         is_bind = 1;
8468       else
8469         {
8470           clib_warning ("parse error '%U'", format_unformat_error, i);
8471           return -99;
8472         }
8473     }
8474
8475   if (!prefix_set)
8476     {
8477       errmsg ("IP prefix not set");
8478       return -99;
8479     }
8480
8481   if (MPLS_LABEL_INVALID == local_label)
8482     {
8483       errmsg ("missing label");
8484       return -99;
8485     }
8486
8487   /* Construct the API message */
8488   M (MPLS_IP_BIND_UNBIND, mp);
8489
8490   mp->mb_is_bind = is_bind;
8491   mp->mb_ip_table_id = ntohl (ip_table_id);
8492   mp->mb_mpls_table_id = 0;
8493   mp->mb_label = ntohl (local_label);
8494   clib_memcpy (&mp->mb_prefix, &pfx, sizeof (pfx));
8495
8496   /* send it... */
8497   S (mp);
8498
8499   /* Wait for a reply... */
8500   W (ret);
8501   return ret;
8502   return (0);
8503 }
8504
8505 static int
8506 api_sr_mpls_policy_add (vat_main_t * vam)
8507 {
8508   unformat_input_t *i = vam->input;
8509   vl_api_sr_mpls_policy_add_t *mp;
8510   u32 bsid = 0;
8511   u32 weight = 1;
8512   u8 type = 0;
8513   u8 n_segments = 0;
8514   u32 sid;
8515   u32 *segments = NULL;
8516   int ret;
8517
8518   /* Parse args required to build the message */
8519   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8520     {
8521       if (unformat (i, "bsid %d", &bsid))
8522         ;
8523       else if (unformat (i, "weight %d", &weight))
8524         ;
8525       else if (unformat (i, "spray"))
8526         type = 1;
8527       else if (unformat (i, "next %d", &sid))
8528         {
8529           n_segments += 1;
8530           vec_add1 (segments, htonl (sid));
8531         }
8532       else
8533         {
8534           clib_warning ("parse error '%U'", format_unformat_error, i);
8535           return -99;
8536         }
8537     }
8538
8539   if (bsid == 0)
8540     {
8541       errmsg ("bsid not set");
8542       return -99;
8543     }
8544
8545   if (n_segments == 0)
8546     {
8547       errmsg ("no sid in segment stack");
8548       return -99;
8549     }
8550
8551   /* Construct the API message */
8552   M2 (SR_MPLS_POLICY_ADD, mp, sizeof (u32) * n_segments);
8553
8554   mp->bsid = htonl (bsid);
8555   mp->weight = htonl (weight);
8556   mp->type = type;
8557   mp->n_segments = n_segments;
8558   memcpy (mp->segments, segments, sizeof (u32) * n_segments);
8559   vec_free (segments);
8560
8561   /* send it... */
8562   S (mp);
8563
8564   /* Wait for a reply... */
8565   W (ret);
8566   return ret;
8567 }
8568
8569 static int
8570 api_sr_mpls_policy_del (vat_main_t * vam)
8571 {
8572   unformat_input_t *i = vam->input;
8573   vl_api_sr_mpls_policy_del_t *mp;
8574   u32 bsid = 0;
8575   int ret;
8576
8577   /* Parse args required to build the message */
8578   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8579     {
8580       if (unformat (i, "bsid %d", &bsid))
8581         ;
8582       else
8583         {
8584           clib_warning ("parse error '%U'", format_unformat_error, i);
8585           return -99;
8586         }
8587     }
8588
8589   if (bsid == 0)
8590     {
8591       errmsg ("bsid not set");
8592       return -99;
8593     }
8594
8595   /* Construct the API message */
8596   M (SR_MPLS_POLICY_DEL, mp);
8597
8598   mp->bsid = htonl (bsid);
8599
8600   /* send it... */
8601   S (mp);
8602
8603   /* Wait for a reply... */
8604   W (ret);
8605   return ret;
8606 }
8607
8608 static int
8609 api_bier_table_add_del (vat_main_t * vam)
8610 {
8611   unformat_input_t *i = vam->input;
8612   vl_api_bier_table_add_del_t *mp;
8613   u8 is_add = 1;
8614   u32 set = 0, sub_domain = 0, hdr_len = 3;
8615   mpls_label_t local_label = MPLS_LABEL_INVALID;
8616   int ret;
8617
8618   /* Parse args required to build the message */
8619   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8620     {
8621       if (unformat (i, "sub-domain %d", &sub_domain))
8622         ;
8623       else if (unformat (i, "set %d", &set))
8624         ;
8625       else if (unformat (i, "label %d", &local_label))
8626         ;
8627       else if (unformat (i, "hdr-len %d", &hdr_len))
8628         ;
8629       else if (unformat (i, "add"))
8630         is_add = 1;
8631       else if (unformat (i, "del"))
8632         is_add = 0;
8633       else
8634         {
8635           clib_warning ("parse error '%U'", format_unformat_error, i);
8636           return -99;
8637         }
8638     }
8639
8640   if (MPLS_LABEL_INVALID == local_label)
8641     {
8642       errmsg ("missing label\n");
8643       return -99;
8644     }
8645
8646   /* Construct the API message */
8647   M (BIER_TABLE_ADD_DEL, mp);
8648
8649   mp->bt_is_add = is_add;
8650   mp->bt_label = ntohl (local_label);
8651   mp->bt_tbl_id.bt_set = set;
8652   mp->bt_tbl_id.bt_sub_domain = sub_domain;
8653   mp->bt_tbl_id.bt_hdr_len_id = hdr_len;
8654
8655   /* send it... */
8656   S (mp);
8657
8658   /* Wait for a reply... */
8659   W (ret);
8660
8661   return (ret);
8662 }
8663
8664 static int
8665 api_bier_route_add_del (vat_main_t * vam)
8666 {
8667   unformat_input_t *i = vam->input;
8668   vl_api_bier_route_add_del_t *mp;
8669   u8 is_add = 1;
8670   u32 set = 0, sub_domain = 0, hdr_len = 3, bp = 0;
8671   ip4_address_t v4_next_hop_address;
8672   ip6_address_t v6_next_hop_address;
8673   u8 next_hop_set = 0;
8674   u8 next_hop_proto_is_ip4 = 1;
8675   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8676   int ret;
8677
8678   /* Parse args required to build the message */
8679   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8680     {
8681       if (unformat (i, "%U", unformat_ip4_address, &v4_next_hop_address))
8682         {
8683           next_hop_proto_is_ip4 = 1;
8684           next_hop_set = 1;
8685         }
8686       else if (unformat (i, "%U", unformat_ip6_address, &v6_next_hop_address))
8687         {
8688           next_hop_proto_is_ip4 = 0;
8689           next_hop_set = 1;
8690         }
8691       if (unformat (i, "sub-domain %d", &sub_domain))
8692         ;
8693       else if (unformat (i, "set %d", &set))
8694         ;
8695       else if (unformat (i, "hdr-len %d", &hdr_len))
8696         ;
8697       else if (unformat (i, "bp %d", &bp))
8698         ;
8699       else if (unformat (i, "add"))
8700         is_add = 1;
8701       else if (unformat (i, "del"))
8702         is_add = 0;
8703       else if (unformat (i, "out-label %d", &next_hop_out_label))
8704         ;
8705       else
8706         {
8707           clib_warning ("parse error '%U'", format_unformat_error, i);
8708           return -99;
8709         }
8710     }
8711
8712   if (!next_hop_set || (MPLS_LABEL_INVALID == next_hop_out_label))
8713     {
8714       errmsg ("next hop / label set\n");
8715       return -99;
8716     }
8717   if (0 == bp)
8718     {
8719       errmsg ("bit=position not set\n");
8720       return -99;
8721     }
8722
8723   /* Construct the API message */
8724   M2 (BIER_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t));
8725
8726   mp->br_is_add = is_add;
8727   mp->br_route.br_tbl_id.bt_set = set;
8728   mp->br_route.br_tbl_id.bt_sub_domain = sub_domain;
8729   mp->br_route.br_tbl_id.bt_hdr_len_id = hdr_len;
8730   mp->br_route.br_bp = ntohs (bp);
8731   mp->br_route.br_n_paths = 1;
8732   mp->br_route.br_paths[0].n_labels = 1;
8733   mp->br_route.br_paths[0].label_stack[0].label = ntohl (next_hop_out_label);
8734   mp->br_route.br_paths[0].proto = (next_hop_proto_is_ip4 ?
8735                                     FIB_API_PATH_NH_PROTO_IP4 :
8736                                     FIB_API_PATH_NH_PROTO_IP6);
8737
8738   if (next_hop_proto_is_ip4)
8739     {
8740       clib_memcpy (&mp->br_route.br_paths[0].nh.address.ip4,
8741                    &v4_next_hop_address, sizeof (v4_next_hop_address));
8742     }
8743   else
8744     {
8745       clib_memcpy (&mp->br_route.br_paths[0].nh.address.ip6,
8746                    &v6_next_hop_address, sizeof (v6_next_hop_address));
8747     }
8748
8749   /* send it... */
8750   S (mp);
8751
8752   /* Wait for a reply... */
8753   W (ret);
8754
8755   return (ret);
8756 }
8757
8758 static int
8759 api_mpls_tunnel_add_del (vat_main_t * vam)
8760 {
8761   unformat_input_t *i = vam->input;
8762   vl_api_mpls_tunnel_add_del_t *mp;
8763
8764   vl_api_fib_path_t paths[8];
8765   u32 sw_if_index = ~0;
8766   u8 path_count = 0;
8767   u8 l2_only = 0;
8768   u8 is_add = 1;
8769   int ret;
8770
8771   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8772     {
8773       if (unformat (i, "add"))
8774         is_add = 1;
8775       else
8776         if (unformat
8777             (i, "del %U", api_unformat_sw_if_index, vam, &sw_if_index))
8778         is_add = 0;
8779       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
8780         is_add = 0;
8781       else if (unformat (i, "l2-only"))
8782         l2_only = 1;
8783       else
8784         if (unformat
8785             (i, "via %U", unformat_fib_path, vam, &paths[path_count]))
8786         {
8787           path_count++;
8788           if (8 == path_count)
8789             {
8790               errmsg ("max 8 paths");
8791               return -99;
8792             }
8793         }
8794       else
8795         {
8796           clib_warning ("parse error '%U'", format_unformat_error, i);
8797           return -99;
8798         }
8799     }
8800
8801   M2 (MPLS_TUNNEL_ADD_DEL, mp, sizeof (vl_api_fib_path_t) * path_count);
8802
8803   mp->mt_is_add = is_add;
8804   mp->mt_tunnel.mt_sw_if_index = ntohl (sw_if_index);
8805   mp->mt_tunnel.mt_l2_only = l2_only;
8806   mp->mt_tunnel.mt_is_multicast = 0;
8807   mp->mt_tunnel.mt_n_paths = path_count;
8808
8809   clib_memcpy (&mp->mt_tunnel.mt_paths, &paths,
8810                sizeof (paths[0]) * path_count);
8811
8812   S (mp);
8813   W (ret);
8814   return ret;
8815 }
8816
8817 static int
8818 api_sw_interface_set_unnumbered (vat_main_t * vam)
8819 {
8820   unformat_input_t *i = vam->input;
8821   vl_api_sw_interface_set_unnumbered_t *mp;
8822   u32 sw_if_index;
8823   u32 unnum_sw_index = ~0;
8824   u8 is_add = 1;
8825   u8 sw_if_index_set = 0;
8826   int ret;
8827
8828   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8829     {
8830       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8831         sw_if_index_set = 1;
8832       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8833         sw_if_index_set = 1;
8834       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
8835         ;
8836       else if (unformat (i, "del"))
8837         is_add = 0;
8838       else
8839         {
8840           clib_warning ("parse error '%U'", format_unformat_error, i);
8841           return -99;
8842         }
8843     }
8844
8845   if (sw_if_index_set == 0)
8846     {
8847       errmsg ("missing interface name or sw_if_index");
8848       return -99;
8849     }
8850
8851   M (SW_INTERFACE_SET_UNNUMBERED, mp);
8852
8853   mp->sw_if_index = ntohl (sw_if_index);
8854   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
8855   mp->is_add = is_add;
8856
8857   S (mp);
8858   W (ret);
8859   return ret;
8860 }
8861
8862
8863 static int
8864 api_create_vlan_subif (vat_main_t * vam)
8865 {
8866   unformat_input_t *i = vam->input;
8867   vl_api_create_vlan_subif_t *mp;
8868   u32 sw_if_index;
8869   u8 sw_if_index_set = 0;
8870   u32 vlan_id;
8871   u8 vlan_id_set = 0;
8872   int ret;
8873
8874   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8875     {
8876       if (unformat (i, "sw_if_index %d", &sw_if_index))
8877         sw_if_index_set = 1;
8878       else
8879         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8880         sw_if_index_set = 1;
8881       else if (unformat (i, "vlan %d", &vlan_id))
8882         vlan_id_set = 1;
8883       else
8884         {
8885           clib_warning ("parse error '%U'", format_unformat_error, i);
8886           return -99;
8887         }
8888     }
8889
8890   if (sw_if_index_set == 0)
8891     {
8892       errmsg ("missing interface name or sw_if_index");
8893       return -99;
8894     }
8895
8896   if (vlan_id_set == 0)
8897     {
8898       errmsg ("missing vlan_id");
8899       return -99;
8900     }
8901   M (CREATE_VLAN_SUBIF, mp);
8902
8903   mp->sw_if_index = ntohl (sw_if_index);
8904   mp->vlan_id = ntohl (vlan_id);
8905
8906   S (mp);
8907   W (ret);
8908   return ret;
8909 }
8910
8911 #define foreach_create_subif_bit                \
8912 _(no_tags)                                      \
8913 _(one_tag)                                      \
8914 _(two_tags)                                     \
8915 _(dot1ad)                                       \
8916 _(exact_match)                                  \
8917 _(default_sub)                                  \
8918 _(outer_vlan_id_any)                            \
8919 _(inner_vlan_id_any)
8920
8921 #define foreach_create_subif_flag               \
8922 _(0, "no_tags")                                 \
8923 _(1, "one_tag")                                 \
8924 _(2, "two_tags")                                \
8925 _(3, "dot1ad")                                  \
8926 _(4, "exact_match")                             \
8927 _(5, "default_sub")                             \
8928 _(6, "outer_vlan_id_any")                       \
8929 _(7, "inner_vlan_id_any")
8930
8931 static int
8932 api_create_subif (vat_main_t * vam)
8933 {
8934   unformat_input_t *i = vam->input;
8935   vl_api_create_subif_t *mp;
8936   u32 sw_if_index;
8937   u8 sw_if_index_set = 0;
8938   u32 sub_id;
8939   u8 sub_id_set = 0;
8940   u32 __attribute__ ((unused)) no_tags = 0;
8941   u32 __attribute__ ((unused)) one_tag = 0;
8942   u32 __attribute__ ((unused)) two_tags = 0;
8943   u32 __attribute__ ((unused)) dot1ad = 0;
8944   u32 __attribute__ ((unused)) exact_match = 0;
8945   u32 __attribute__ ((unused)) default_sub = 0;
8946   u32 __attribute__ ((unused)) outer_vlan_id_any = 0;
8947   u32 __attribute__ ((unused)) inner_vlan_id_any = 0;
8948   u32 tmp;
8949   u16 outer_vlan_id = 0;
8950   u16 inner_vlan_id = 0;
8951   int ret;
8952
8953   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8954     {
8955       if (unformat (i, "sw_if_index %d", &sw_if_index))
8956         sw_if_index_set = 1;
8957       else
8958         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8959         sw_if_index_set = 1;
8960       else if (unformat (i, "sub_id %d", &sub_id))
8961         sub_id_set = 1;
8962       else if (unformat (i, "outer_vlan_id %d", &tmp))
8963         outer_vlan_id = tmp;
8964       else if (unformat (i, "inner_vlan_id %d", &tmp))
8965         inner_vlan_id = tmp;
8966
8967 #define _(a) else if (unformat (i, #a)) a = 1 ;
8968       foreach_create_subif_bit
8969 #undef _
8970         else
8971         {
8972           clib_warning ("parse error '%U'", format_unformat_error, i);
8973           return -99;
8974         }
8975     }
8976
8977   if (sw_if_index_set == 0)
8978     {
8979       errmsg ("missing interface name or sw_if_index");
8980       return -99;
8981     }
8982
8983   if (sub_id_set == 0)
8984     {
8985       errmsg ("missing sub_id");
8986       return -99;
8987     }
8988   M (CREATE_SUBIF, mp);
8989
8990   mp->sw_if_index = ntohl (sw_if_index);
8991   mp->sub_id = ntohl (sub_id);
8992
8993 #define _(a,b) mp->sub_if_flags |= (1 << a);
8994   foreach_create_subif_flag;
8995 #undef _
8996
8997   mp->outer_vlan_id = ntohs (outer_vlan_id);
8998   mp->inner_vlan_id = ntohs (inner_vlan_id);
8999
9000   S (mp);
9001   W (ret);
9002   return ret;
9003 }
9004
9005 static int
9006 api_ip_table_replace_begin (vat_main_t * vam)
9007 {
9008   unformat_input_t *i = vam->input;
9009   vl_api_ip_table_replace_begin_t *mp;
9010   u32 table_id = 0;
9011   u8 is_ipv6 = 0;
9012
9013   int ret;
9014   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9015     {
9016       if (unformat (i, "table %d", &table_id))
9017         ;
9018       else if (unformat (i, "ipv6"))
9019         is_ipv6 = 1;
9020       else
9021         {
9022           clib_warning ("parse error '%U'", format_unformat_error, i);
9023           return -99;
9024         }
9025     }
9026
9027   M (IP_TABLE_REPLACE_BEGIN, mp);
9028
9029   mp->table.table_id = ntohl (table_id);
9030   mp->table.is_ip6 = is_ipv6;
9031
9032   S (mp);
9033   W (ret);
9034   return ret;
9035 }
9036
9037 static int
9038 api_ip_table_flush (vat_main_t * vam)
9039 {
9040   unformat_input_t *i = vam->input;
9041   vl_api_ip_table_flush_t *mp;
9042   u32 table_id = 0;
9043   u8 is_ipv6 = 0;
9044
9045   int ret;
9046   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9047     {
9048       if (unformat (i, "table %d", &table_id))
9049         ;
9050       else if (unformat (i, "ipv6"))
9051         is_ipv6 = 1;
9052       else
9053         {
9054           clib_warning ("parse error '%U'", format_unformat_error, i);
9055           return -99;
9056         }
9057     }
9058
9059   M (IP_TABLE_FLUSH, mp);
9060
9061   mp->table.table_id = ntohl (table_id);
9062   mp->table.is_ip6 = is_ipv6;
9063
9064   S (mp);
9065   W (ret);
9066   return ret;
9067 }
9068
9069 static int
9070 api_ip_table_replace_end (vat_main_t * vam)
9071 {
9072   unformat_input_t *i = vam->input;
9073   vl_api_ip_table_replace_end_t *mp;
9074   u32 table_id = 0;
9075   u8 is_ipv6 = 0;
9076
9077   int ret;
9078   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9079     {
9080       if (unformat (i, "table %d", &table_id))
9081         ;
9082       else if (unformat (i, "ipv6"))
9083         is_ipv6 = 1;
9084       else
9085         {
9086           clib_warning ("parse error '%U'", format_unformat_error, i);
9087           return -99;
9088         }
9089     }
9090
9091   M (IP_TABLE_REPLACE_END, mp);
9092
9093   mp->table.table_id = ntohl (table_id);
9094   mp->table.is_ip6 = is_ipv6;
9095
9096   S (mp);
9097   W (ret);
9098   return ret;
9099 }
9100
9101 static int
9102 api_set_ip_flow_hash (vat_main_t * vam)
9103 {
9104   unformat_input_t *i = vam->input;
9105   vl_api_set_ip_flow_hash_t *mp;
9106   u32 vrf_id = 0;
9107   u8 is_ipv6 = 0;
9108   u8 vrf_id_set = 0;
9109   u8 src = 0;
9110   u8 dst = 0;
9111   u8 sport = 0;
9112   u8 dport = 0;
9113   u8 proto = 0;
9114   u8 reverse = 0;
9115   int ret;
9116
9117   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9118     {
9119       if (unformat (i, "vrf %d", &vrf_id))
9120         vrf_id_set = 1;
9121       else if (unformat (i, "ipv6"))
9122         is_ipv6 = 1;
9123       else if (unformat (i, "src"))
9124         src = 1;
9125       else if (unformat (i, "dst"))
9126         dst = 1;
9127       else if (unformat (i, "sport"))
9128         sport = 1;
9129       else if (unformat (i, "dport"))
9130         dport = 1;
9131       else if (unformat (i, "proto"))
9132         proto = 1;
9133       else if (unformat (i, "reverse"))
9134         reverse = 1;
9135
9136       else
9137         {
9138           clib_warning ("parse error '%U'", format_unformat_error, i);
9139           return -99;
9140         }
9141     }
9142
9143   if (vrf_id_set == 0)
9144     {
9145       errmsg ("missing vrf id");
9146       return -99;
9147     }
9148
9149   M (SET_IP_FLOW_HASH, mp);
9150   mp->src = src;
9151   mp->dst = dst;
9152   mp->sport = sport;
9153   mp->dport = dport;
9154   mp->proto = proto;
9155   mp->reverse = reverse;
9156   mp->vrf_id = ntohl (vrf_id);
9157   mp->is_ipv6 = is_ipv6;
9158
9159   S (mp);
9160   W (ret);
9161   return ret;
9162 }
9163
9164 static int
9165 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
9166 {
9167   unformat_input_t *i = vam->input;
9168   vl_api_sw_interface_ip6_enable_disable_t *mp;
9169   u32 sw_if_index;
9170   u8 sw_if_index_set = 0;
9171   u8 enable = 0;
9172   int ret;
9173
9174   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9175     {
9176       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9177         sw_if_index_set = 1;
9178       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9179         sw_if_index_set = 1;
9180       else if (unformat (i, "enable"))
9181         enable = 1;
9182       else if (unformat (i, "disable"))
9183         enable = 0;
9184       else
9185         {
9186           clib_warning ("parse error '%U'", format_unformat_error, i);
9187           return -99;
9188         }
9189     }
9190
9191   if (sw_if_index_set == 0)
9192     {
9193       errmsg ("missing interface name or sw_if_index");
9194       return -99;
9195     }
9196
9197   M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
9198
9199   mp->sw_if_index = ntohl (sw_if_index);
9200   mp->enable = enable;
9201
9202   S (mp);
9203   W (ret);
9204   return ret;
9205 }
9206
9207
9208 static int
9209 api_l2_patch_add_del (vat_main_t * vam)
9210 {
9211   unformat_input_t *i = vam->input;
9212   vl_api_l2_patch_add_del_t *mp;
9213   u32 rx_sw_if_index;
9214   u8 rx_sw_if_index_set = 0;
9215   u32 tx_sw_if_index;
9216   u8 tx_sw_if_index_set = 0;
9217   u8 is_add = 1;
9218   int ret;
9219
9220   /* Parse args required to build the message */
9221   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9222     {
9223       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
9224         rx_sw_if_index_set = 1;
9225       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
9226         tx_sw_if_index_set = 1;
9227       else if (unformat (i, "rx"))
9228         {
9229           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9230             {
9231               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
9232                             &rx_sw_if_index))
9233                 rx_sw_if_index_set = 1;
9234             }
9235           else
9236             break;
9237         }
9238       else if (unformat (i, "tx"))
9239         {
9240           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9241             {
9242               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
9243                             &tx_sw_if_index))
9244                 tx_sw_if_index_set = 1;
9245             }
9246           else
9247             break;
9248         }
9249       else if (unformat (i, "del"))
9250         is_add = 0;
9251       else
9252         break;
9253     }
9254
9255   if (rx_sw_if_index_set == 0)
9256     {
9257       errmsg ("missing rx interface name or rx_sw_if_index");
9258       return -99;
9259     }
9260
9261   if (tx_sw_if_index_set == 0)
9262     {
9263       errmsg ("missing tx interface name or tx_sw_if_index");
9264       return -99;
9265     }
9266
9267   M (L2_PATCH_ADD_DEL, mp);
9268
9269   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
9270   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
9271   mp->is_add = is_add;
9272
9273   S (mp);
9274   W (ret);
9275   return ret;
9276 }
9277
9278 u8 is_del;
9279 u8 localsid_addr[16];
9280 u8 end_psp;
9281 u8 behavior;
9282 u32 sw_if_index;
9283 u32 vlan_index;
9284 u32 fib_table;
9285 u8 nh_addr[16];
9286
9287 static int
9288 api_sr_localsid_add_del (vat_main_t * vam)
9289 {
9290   unformat_input_t *i = vam->input;
9291   vl_api_sr_localsid_add_del_t *mp;
9292
9293   u8 is_del;
9294   ip6_address_t localsid;
9295   u8 end_psp = 0;
9296   u8 behavior = ~0;
9297   u32 sw_if_index;
9298   u32 fib_table = ~(u32) 0;
9299   ip6_address_t nh_addr6;
9300   ip4_address_t nh_addr4;
9301   clib_memset (&nh_addr6, 0, sizeof (ip6_address_t));
9302   clib_memset (&nh_addr4, 0, sizeof (ip4_address_t));
9303
9304   bool nexthop_set = 0;
9305
9306   int ret;
9307
9308   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9309     {
9310       if (unformat (i, "del"))
9311         is_del = 1;
9312       else if (unformat (i, "address %U", unformat_ip6_address, &localsid));
9313       else if (unformat (i, "next-hop %U", unformat_ip4_address, &nh_addr4))
9314         nexthop_set = 1;
9315       else if (unformat (i, "next-hop %U", unformat_ip6_address, &nh_addr6))
9316         nexthop_set = 1;
9317       else if (unformat (i, "behavior %u", &behavior));
9318       else if (unformat (i, "sw_if_index %u", &sw_if_index));
9319       else if (unformat (i, "fib-table %u", &fib_table));
9320       else if (unformat (i, "end.psp %u", &behavior));
9321       else
9322         break;
9323     }
9324
9325   M (SR_LOCALSID_ADD_DEL, mp);
9326
9327   clib_memcpy (mp->localsid.addr, &localsid, sizeof (mp->localsid));
9328
9329   if (nexthop_set)
9330     {
9331       clib_memcpy (mp->nh_addr6, &nh_addr6, sizeof (mp->nh_addr6));
9332       clib_memcpy (mp->nh_addr4, &nh_addr4, sizeof (mp->nh_addr4));
9333     }
9334   mp->behavior = behavior;
9335   mp->sw_if_index = ntohl (sw_if_index);
9336   mp->fib_table = ntohl (fib_table);
9337   mp->end_psp = end_psp;
9338   mp->is_del = is_del;
9339
9340   S (mp);
9341   W (ret);
9342   return ret;
9343 }
9344
9345 static int
9346 api_ioam_enable (vat_main_t * vam)
9347 {
9348   unformat_input_t *input = vam->input;
9349   vl_api_ioam_enable_t *mp;
9350   u32 id = 0;
9351   int has_trace_option = 0;
9352   int has_pot_option = 0;
9353   int has_seqno_option = 0;
9354   int has_analyse_option = 0;
9355   int ret;
9356
9357   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9358     {
9359       if (unformat (input, "trace"))
9360         has_trace_option = 1;
9361       else if (unformat (input, "pot"))
9362         has_pot_option = 1;
9363       else if (unformat (input, "seqno"))
9364         has_seqno_option = 1;
9365       else if (unformat (input, "analyse"))
9366         has_analyse_option = 1;
9367       else
9368         break;
9369     }
9370   M (IOAM_ENABLE, mp);
9371   mp->id = htons (id);
9372   mp->seqno = has_seqno_option;
9373   mp->analyse = has_analyse_option;
9374   mp->pot_enable = has_pot_option;
9375   mp->trace_enable = has_trace_option;
9376
9377   S (mp);
9378   W (ret);
9379   return ret;
9380 }
9381
9382
9383 static int
9384 api_ioam_disable (vat_main_t * vam)
9385 {
9386   vl_api_ioam_disable_t *mp;
9387   int ret;
9388
9389   M (IOAM_DISABLE, mp);
9390   S (mp);
9391   W (ret);
9392   return ret;
9393 }
9394
9395 #define foreach_tcp_proto_field                 \
9396 _(src_port)                                     \
9397 _(dst_port)
9398
9399 #define foreach_udp_proto_field                 \
9400 _(src_port)                                     \
9401 _(dst_port)
9402
9403 #define foreach_ip4_proto_field                 \
9404 _(src_address)                                  \
9405 _(dst_address)                                  \
9406 _(tos)                                          \
9407 _(length)                                       \
9408 _(fragment_id)                                  \
9409 _(ttl)                                          \
9410 _(protocol)                                     \
9411 _(checksum)
9412
9413 typedef struct
9414 {
9415   u16 src_port, dst_port;
9416 } tcpudp_header_t;
9417
9418 #if VPP_API_TEST_BUILTIN == 0
9419 uword
9420 unformat_tcp_mask (unformat_input_t * input, va_list * args)
9421 {
9422   u8 **maskp = va_arg (*args, u8 **);
9423   u8 *mask = 0;
9424   u8 found_something = 0;
9425   tcp_header_t *tcp;
9426
9427 #define _(a) u8 a=0;
9428   foreach_tcp_proto_field;
9429 #undef _
9430
9431   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9432     {
9433       if (0);
9434 #define _(a) else if (unformat (input, #a)) a=1;
9435       foreach_tcp_proto_field
9436 #undef _
9437         else
9438         break;
9439     }
9440
9441 #define _(a) found_something += a;
9442   foreach_tcp_proto_field;
9443 #undef _
9444
9445   if (found_something == 0)
9446     return 0;
9447
9448   vec_validate (mask, sizeof (*tcp) - 1);
9449
9450   tcp = (tcp_header_t *) mask;
9451
9452 #define _(a) if (a) clib_memset (&tcp->a, 0xff, sizeof (tcp->a));
9453   foreach_tcp_proto_field;
9454 #undef _
9455
9456   *maskp = mask;
9457   return 1;
9458 }
9459
9460 uword
9461 unformat_udp_mask (unformat_input_t * input, va_list * args)
9462 {
9463   u8 **maskp = va_arg (*args, u8 **);
9464   u8 *mask = 0;
9465   u8 found_something = 0;
9466   udp_header_t *udp;
9467
9468 #define _(a) u8 a=0;
9469   foreach_udp_proto_field;
9470 #undef _
9471
9472   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9473     {
9474       if (0);
9475 #define _(a) else if (unformat (input, #a)) a=1;
9476       foreach_udp_proto_field
9477 #undef _
9478         else
9479         break;
9480     }
9481
9482 #define _(a) found_something += a;
9483   foreach_udp_proto_field;
9484 #undef _
9485
9486   if (found_something == 0)
9487     return 0;
9488
9489   vec_validate (mask, sizeof (*udp) - 1);
9490
9491   udp = (udp_header_t *) mask;
9492
9493 #define _(a) if (a) clib_memset (&udp->a, 0xff, sizeof (udp->a));
9494   foreach_udp_proto_field;
9495 #undef _
9496
9497   *maskp = mask;
9498   return 1;
9499 }
9500
9501 uword
9502 unformat_l4_mask (unformat_input_t * input, va_list * args)
9503 {
9504   u8 **maskp = va_arg (*args, u8 **);
9505   u16 src_port = 0, dst_port = 0;
9506   tcpudp_header_t *tcpudp;
9507
9508   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9509     {
9510       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
9511         return 1;
9512       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
9513         return 1;
9514       else if (unformat (input, "src_port"))
9515         src_port = 0xFFFF;
9516       else if (unformat (input, "dst_port"))
9517         dst_port = 0xFFFF;
9518       else
9519         return 0;
9520     }
9521
9522   if (!src_port && !dst_port)
9523     return 0;
9524
9525   u8 *mask = 0;
9526   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
9527
9528   tcpudp = (tcpudp_header_t *) mask;
9529   tcpudp->src_port = src_port;
9530   tcpudp->dst_port = dst_port;
9531
9532   *maskp = mask;
9533
9534   return 1;
9535 }
9536
9537 uword
9538 unformat_ip4_mask (unformat_input_t * input, va_list * args)
9539 {
9540   u8 **maskp = va_arg (*args, u8 **);
9541   u8 *mask = 0;
9542   u8 found_something = 0;
9543   ip4_header_t *ip;
9544
9545 #define _(a) u8 a=0;
9546   foreach_ip4_proto_field;
9547 #undef _
9548   u8 version = 0;
9549   u8 hdr_length = 0;
9550
9551
9552   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9553     {
9554       if (unformat (input, "version"))
9555         version = 1;
9556       else if (unformat (input, "hdr_length"))
9557         hdr_length = 1;
9558       else if (unformat (input, "src"))
9559         src_address = 1;
9560       else if (unformat (input, "dst"))
9561         dst_address = 1;
9562       else if (unformat (input, "proto"))
9563         protocol = 1;
9564
9565 #define _(a) else if (unformat (input, #a)) a=1;
9566       foreach_ip4_proto_field
9567 #undef _
9568         else
9569         break;
9570     }
9571
9572 #define _(a) found_something += a;
9573   foreach_ip4_proto_field;
9574 #undef _
9575
9576   if (found_something == 0)
9577     return 0;
9578
9579   vec_validate (mask, sizeof (*ip) - 1);
9580
9581   ip = (ip4_header_t *) mask;
9582
9583 #define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
9584   foreach_ip4_proto_field;
9585 #undef _
9586
9587   ip->ip_version_and_header_length = 0;
9588
9589   if (version)
9590     ip->ip_version_and_header_length |= 0xF0;
9591
9592   if (hdr_length)
9593     ip->ip_version_and_header_length |= 0x0F;
9594
9595   *maskp = mask;
9596   return 1;
9597 }
9598
9599 #define foreach_ip6_proto_field                 \
9600 _(src_address)                                  \
9601 _(dst_address)                                  \
9602 _(payload_length)                               \
9603 _(hop_limit)                                    \
9604 _(protocol)
9605
9606 uword
9607 unformat_ip6_mask (unformat_input_t * input, va_list * args)
9608 {
9609   u8 **maskp = va_arg (*args, u8 **);
9610   u8 *mask = 0;
9611   u8 found_something = 0;
9612   ip6_header_t *ip;
9613   u32 ip_version_traffic_class_and_flow_label;
9614
9615 #define _(a) u8 a=0;
9616   foreach_ip6_proto_field;
9617 #undef _
9618   u8 version = 0;
9619   u8 traffic_class = 0;
9620   u8 flow_label = 0;
9621
9622   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9623     {
9624       if (unformat (input, "version"))
9625         version = 1;
9626       else if (unformat (input, "traffic-class"))
9627         traffic_class = 1;
9628       else if (unformat (input, "flow-label"))
9629         flow_label = 1;
9630       else if (unformat (input, "src"))
9631         src_address = 1;
9632       else if (unformat (input, "dst"))
9633         dst_address = 1;
9634       else if (unformat (input, "proto"))
9635         protocol = 1;
9636
9637 #define _(a) else if (unformat (input, #a)) a=1;
9638       foreach_ip6_proto_field
9639 #undef _
9640         else
9641         break;
9642     }
9643
9644 #define _(a) found_something += a;
9645   foreach_ip6_proto_field;
9646 #undef _
9647
9648   if (found_something == 0)
9649     return 0;
9650
9651   vec_validate (mask, sizeof (*ip) - 1);
9652
9653   ip = (ip6_header_t *) mask;
9654
9655 #define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
9656   foreach_ip6_proto_field;
9657 #undef _
9658
9659   ip_version_traffic_class_and_flow_label = 0;
9660
9661   if (version)
9662     ip_version_traffic_class_and_flow_label |= 0xF0000000;
9663
9664   if (traffic_class)
9665     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
9666
9667   if (flow_label)
9668     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
9669
9670   ip->ip_version_traffic_class_and_flow_label =
9671     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
9672
9673   *maskp = mask;
9674   return 1;
9675 }
9676
9677 uword
9678 unformat_l3_mask (unformat_input_t * input, va_list * args)
9679 {
9680   u8 **maskp = va_arg (*args, u8 **);
9681
9682   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9683     {
9684       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
9685         return 1;
9686       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
9687         return 1;
9688       else
9689         break;
9690     }
9691   return 0;
9692 }
9693
9694 uword
9695 unformat_l2_mask (unformat_input_t * input, va_list * args)
9696 {
9697   u8 **maskp = va_arg (*args, u8 **);
9698   u8 *mask = 0;
9699   u8 src = 0;
9700   u8 dst = 0;
9701   u8 proto = 0;
9702   u8 tag1 = 0;
9703   u8 tag2 = 0;
9704   u8 ignore_tag1 = 0;
9705   u8 ignore_tag2 = 0;
9706   u8 cos1 = 0;
9707   u8 cos2 = 0;
9708   u8 dot1q = 0;
9709   u8 dot1ad = 0;
9710   int len = 14;
9711
9712   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9713     {
9714       if (unformat (input, "src"))
9715         src = 1;
9716       else if (unformat (input, "dst"))
9717         dst = 1;
9718       else if (unformat (input, "proto"))
9719         proto = 1;
9720       else if (unformat (input, "tag1"))
9721         tag1 = 1;
9722       else if (unformat (input, "tag2"))
9723         tag2 = 1;
9724       else if (unformat (input, "ignore-tag1"))
9725         ignore_tag1 = 1;
9726       else if (unformat (input, "ignore-tag2"))
9727         ignore_tag2 = 1;
9728       else if (unformat (input, "cos1"))
9729         cos1 = 1;
9730       else if (unformat (input, "cos2"))
9731         cos2 = 1;
9732       else if (unformat (input, "dot1q"))
9733         dot1q = 1;
9734       else if (unformat (input, "dot1ad"))
9735         dot1ad = 1;
9736       else
9737         break;
9738     }
9739   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
9740        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
9741     return 0;
9742
9743   if (tag1 || ignore_tag1 || cos1 || dot1q)
9744     len = 18;
9745   if (tag2 || ignore_tag2 || cos2 || dot1ad)
9746     len = 22;
9747
9748   vec_validate (mask, len - 1);
9749
9750   if (dst)
9751     clib_memset (mask, 0xff, 6);
9752
9753   if (src)
9754     clib_memset (mask + 6, 0xff, 6);
9755
9756   if (tag2 || dot1ad)
9757     {
9758       /* inner vlan tag */
9759       if (tag2)
9760         {
9761           mask[19] = 0xff;
9762           mask[18] = 0x0f;
9763         }
9764       if (cos2)
9765         mask[18] |= 0xe0;
9766       if (proto)
9767         mask[21] = mask[20] = 0xff;
9768       if (tag1)
9769         {
9770           mask[15] = 0xff;
9771           mask[14] = 0x0f;
9772         }
9773       if (cos1)
9774         mask[14] |= 0xe0;
9775       *maskp = mask;
9776       return 1;
9777     }
9778   if (tag1 | dot1q)
9779     {
9780       if (tag1)
9781         {
9782           mask[15] = 0xff;
9783           mask[14] = 0x0f;
9784         }
9785       if (cos1)
9786         mask[14] |= 0xe0;
9787       if (proto)
9788         mask[16] = mask[17] = 0xff;
9789
9790       *maskp = mask;
9791       return 1;
9792     }
9793   if (cos2)
9794     mask[18] |= 0xe0;
9795   if (cos1)
9796     mask[14] |= 0xe0;
9797   if (proto)
9798     mask[12] = mask[13] = 0xff;
9799
9800   *maskp = mask;
9801   return 1;
9802 }
9803
9804 uword
9805 unformat_classify_mask (unformat_input_t * input, va_list * args)
9806 {
9807   u8 **maskp = va_arg (*args, u8 **);
9808   u32 *skipp = va_arg (*args, u32 *);
9809   u32 *matchp = va_arg (*args, u32 *);
9810   u32 match;
9811   u8 *mask = 0;
9812   u8 *l2 = 0;
9813   u8 *l3 = 0;
9814   u8 *l4 = 0;
9815   int i;
9816
9817   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9818     {
9819       if (unformat (input, "hex %U", unformat_hex_string, &mask))
9820         ;
9821       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
9822         ;
9823       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
9824         ;
9825       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
9826         ;
9827       else
9828         break;
9829     }
9830
9831   if (l4 && !l3)
9832     {
9833       vec_free (mask);
9834       vec_free (l2);
9835       vec_free (l4);
9836       return 0;
9837     }
9838
9839   if (mask || l2 || l3 || l4)
9840     {
9841       if (l2 || l3 || l4)
9842         {
9843           /* "With a free Ethernet header in every package" */
9844           if (l2 == 0)
9845             vec_validate (l2, 13);
9846           mask = l2;
9847           if (vec_len (l3))
9848             {
9849               vec_append (mask, l3);
9850               vec_free (l3);
9851             }
9852           if (vec_len (l4))
9853             {
9854               vec_append (mask, l4);
9855               vec_free (l4);
9856             }
9857         }
9858
9859       /* Scan forward looking for the first significant mask octet */
9860       for (i = 0; i < vec_len (mask); i++)
9861         if (mask[i])
9862           break;
9863
9864       /* compute (skip, match) params */
9865       *skipp = i / sizeof (u32x4);
9866       vec_delete (mask, *skipp * sizeof (u32x4), 0);
9867
9868       /* Pad mask to an even multiple of the vector size */
9869       while (vec_len (mask) % sizeof (u32x4))
9870         vec_add1 (mask, 0);
9871
9872       match = vec_len (mask) / sizeof (u32x4);
9873
9874       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
9875         {
9876           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
9877           if (*tmp || *(tmp + 1))
9878             break;
9879           match--;
9880         }
9881       if (match == 0)
9882         clib_warning ("BUG: match 0");
9883
9884       _vec_len (mask) = match * sizeof (u32x4);
9885
9886       *matchp = match;
9887       *maskp = mask;
9888
9889       return 1;
9890     }
9891
9892   return 0;
9893 }
9894 #endif /* VPP_API_TEST_BUILTIN */
9895
9896 #define foreach_l2_next                         \
9897 _(drop, DROP)                                   \
9898 _(ethernet, ETHERNET_INPUT)                     \
9899 _(ip4, IP4_INPUT)                               \
9900 _(ip6, IP6_INPUT)
9901
9902 uword
9903 unformat_l2_next_index (unformat_input_t * input, va_list * args)
9904 {
9905   u32 *miss_next_indexp = va_arg (*args, u32 *);
9906   u32 next_index = 0;
9907   u32 tmp;
9908
9909 #define _(n,N) \
9910   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
9911   foreach_l2_next;
9912 #undef _
9913
9914   if (unformat (input, "%d", &tmp))
9915     {
9916       next_index = tmp;
9917       goto out;
9918     }
9919
9920   return 0;
9921
9922 out:
9923   *miss_next_indexp = next_index;
9924   return 1;
9925 }
9926
9927 #define foreach_ip_next                         \
9928 _(drop, DROP)                                   \
9929 _(local, LOCAL)                                 \
9930 _(rewrite, REWRITE)
9931
9932 uword
9933 api_unformat_ip_next_index (unformat_input_t * input, va_list * args)
9934 {
9935   u32 *miss_next_indexp = va_arg (*args, u32 *);
9936   u32 next_index = 0;
9937   u32 tmp;
9938
9939 #define _(n,N) \
9940   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
9941   foreach_ip_next;
9942 #undef _
9943
9944   if (unformat (input, "%d", &tmp))
9945     {
9946       next_index = tmp;
9947       goto out;
9948     }
9949
9950   return 0;
9951
9952 out:
9953   *miss_next_indexp = next_index;
9954   return 1;
9955 }
9956
9957 #define foreach_acl_next                        \
9958 _(deny, DENY)
9959
9960 uword
9961 api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
9962 {
9963   u32 *miss_next_indexp = va_arg (*args, u32 *);
9964   u32 next_index = 0;
9965   u32 tmp;
9966
9967 #define _(n,N) \
9968   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
9969   foreach_acl_next;
9970 #undef _
9971
9972   if (unformat (input, "permit"))
9973     {
9974       next_index = ~0;
9975       goto out;
9976     }
9977   else if (unformat (input, "%d", &tmp))
9978     {
9979       next_index = tmp;
9980       goto out;
9981     }
9982
9983   return 0;
9984
9985 out:
9986   *miss_next_indexp = next_index;
9987   return 1;
9988 }
9989
9990 uword
9991 unformat_policer_precolor (unformat_input_t * input, va_list * args)
9992 {
9993   u32 *r = va_arg (*args, u32 *);
9994
9995   if (unformat (input, "conform-color"))
9996     *r = POLICE_CONFORM;
9997   else if (unformat (input, "exceed-color"))
9998     *r = POLICE_EXCEED;
9999   else
10000     return 0;
10001
10002   return 1;
10003 }
10004
10005 static int
10006 api_classify_add_del_table (vat_main_t * vam)
10007 {
10008   unformat_input_t *i = vam->input;
10009   vl_api_classify_add_del_table_t *mp;
10010
10011   u32 nbuckets = 2;
10012   u32 skip = ~0;
10013   u32 match = ~0;
10014   int is_add = 1;
10015   int del_chain = 0;
10016   u32 table_index = ~0;
10017   u32 next_table_index = ~0;
10018   u32 miss_next_index = ~0;
10019   u32 memory_size = 32 << 20;
10020   u8 *mask = 0;
10021   u32 current_data_flag = 0;
10022   int current_data_offset = 0;
10023   int ret;
10024
10025   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10026     {
10027       if (unformat (i, "del"))
10028         is_add = 0;
10029       else if (unformat (i, "del-chain"))
10030         {
10031           is_add = 0;
10032           del_chain = 1;
10033         }
10034       else if (unformat (i, "buckets %d", &nbuckets))
10035         ;
10036       else if (unformat (i, "memory_size %d", &memory_size))
10037         ;
10038       else if (unformat (i, "skip %d", &skip))
10039         ;
10040       else if (unformat (i, "match %d", &match))
10041         ;
10042       else if (unformat (i, "table %d", &table_index))
10043         ;
10044       else if (unformat (i, "mask %U", unformat_classify_mask,
10045                          &mask, &skip, &match))
10046         ;
10047       else if (unformat (i, "next-table %d", &next_table_index))
10048         ;
10049       else if (unformat (i, "miss-next %U", api_unformat_ip_next_index,
10050                          &miss_next_index))
10051         ;
10052       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
10053                          &miss_next_index))
10054         ;
10055       else if (unformat (i, "acl-miss-next %U", api_unformat_acl_next_index,
10056                          &miss_next_index))
10057         ;
10058       else if (unformat (i, "current-data-flag %d", &current_data_flag))
10059         ;
10060       else if (unformat (i, "current-data-offset %d", &current_data_offset))
10061         ;
10062       else
10063         break;
10064     }
10065
10066   if (is_add && mask == 0)
10067     {
10068       errmsg ("Mask required");
10069       return -99;
10070     }
10071
10072   if (is_add && skip == ~0)
10073     {
10074       errmsg ("skip count required");
10075       return -99;
10076     }
10077
10078   if (is_add && match == ~0)
10079     {
10080       errmsg ("match count required");
10081       return -99;
10082     }
10083
10084   if (!is_add && table_index == ~0)
10085     {
10086       errmsg ("table index required for delete");
10087       return -99;
10088     }
10089
10090   M2 (CLASSIFY_ADD_DEL_TABLE, mp, vec_len (mask));
10091
10092   mp->is_add = is_add;
10093   mp->del_chain = del_chain;
10094   mp->table_index = ntohl (table_index);
10095   mp->nbuckets = ntohl (nbuckets);
10096   mp->memory_size = ntohl (memory_size);
10097   mp->skip_n_vectors = ntohl (skip);
10098   mp->match_n_vectors = ntohl (match);
10099   mp->next_table_index = ntohl (next_table_index);
10100   mp->miss_next_index = ntohl (miss_next_index);
10101   mp->current_data_flag = ntohl (current_data_flag);
10102   mp->current_data_offset = ntohl (current_data_offset);
10103   mp->mask_len = ntohl (vec_len (mask));
10104   clib_memcpy (mp->mask, mask, vec_len (mask));
10105
10106   vec_free (mask);
10107
10108   S (mp);
10109   W (ret);
10110   return ret;
10111 }
10112
10113 #if VPP_API_TEST_BUILTIN == 0
10114 uword
10115 unformat_l4_match (unformat_input_t * input, va_list * args)
10116 {
10117   u8 **matchp = va_arg (*args, u8 **);
10118
10119   u8 *proto_header = 0;
10120   int src_port = 0;
10121   int dst_port = 0;
10122
10123   tcpudp_header_t h;
10124
10125   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10126     {
10127       if (unformat (input, "src_port %d", &src_port))
10128         ;
10129       else if (unformat (input, "dst_port %d", &dst_port))
10130         ;
10131       else
10132         return 0;
10133     }
10134
10135   h.src_port = clib_host_to_net_u16 (src_port);
10136   h.dst_port = clib_host_to_net_u16 (dst_port);
10137   vec_validate (proto_header, sizeof (h) - 1);
10138   memcpy (proto_header, &h, sizeof (h));
10139
10140   *matchp = proto_header;
10141
10142   return 1;
10143 }
10144
10145 uword
10146 unformat_ip4_match (unformat_input_t * input, va_list * args)
10147 {
10148   u8 **matchp = va_arg (*args, u8 **);
10149   u8 *match = 0;
10150   ip4_header_t *ip;
10151   int version = 0;
10152   u32 version_val;
10153   int hdr_length = 0;
10154   u32 hdr_length_val;
10155   int src = 0, dst = 0;
10156   ip4_address_t src_val, dst_val;
10157   int proto = 0;
10158   u32 proto_val;
10159   int tos = 0;
10160   u32 tos_val;
10161   int length = 0;
10162   u32 length_val;
10163   int fragment_id = 0;
10164   u32 fragment_id_val;
10165   int ttl = 0;
10166   int ttl_val;
10167   int checksum = 0;
10168   u32 checksum_val;
10169
10170   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10171     {
10172       if (unformat (input, "version %d", &version_val))
10173         version = 1;
10174       else if (unformat (input, "hdr_length %d", &hdr_length_val))
10175         hdr_length = 1;
10176       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
10177         src = 1;
10178       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
10179         dst = 1;
10180       else if (unformat (input, "proto %d", &proto_val))
10181         proto = 1;
10182       else if (unformat (input, "tos %d", &tos_val))
10183         tos = 1;
10184       else if (unformat (input, "length %d", &length_val))
10185         length = 1;
10186       else if (unformat (input, "fragment_id %d", &fragment_id_val))
10187         fragment_id = 1;
10188       else if (unformat (input, "ttl %d", &ttl_val))
10189         ttl = 1;
10190       else if (unformat (input, "checksum %d", &checksum_val))
10191         checksum = 1;
10192       else
10193         break;
10194     }
10195
10196   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
10197       + ttl + checksum == 0)
10198     return 0;
10199
10200   /*
10201    * Aligned because we use the real comparison functions
10202    */
10203   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
10204
10205   ip = (ip4_header_t *) match;
10206
10207   /* These are realistically matched in practice */
10208   if (src)
10209     ip->src_address.as_u32 = src_val.as_u32;
10210
10211   if (dst)
10212     ip->dst_address.as_u32 = dst_val.as_u32;
10213
10214   if (proto)
10215     ip->protocol = proto_val;
10216
10217
10218   /* These are not, but they're included for completeness */
10219   if (version)
10220     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
10221
10222   if (hdr_length)
10223     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
10224
10225   if (tos)
10226     ip->tos = tos_val;
10227
10228   if (length)
10229     ip->length = clib_host_to_net_u16 (length_val);
10230
10231   if (ttl)
10232     ip->ttl = ttl_val;
10233
10234   if (checksum)
10235     ip->checksum = clib_host_to_net_u16 (checksum_val);
10236
10237   *matchp = match;
10238   return 1;
10239 }
10240
10241 uword
10242 unformat_ip6_match (unformat_input_t * input, va_list * args)
10243 {
10244   u8 **matchp = va_arg (*args, u8 **);
10245   u8 *match = 0;
10246   ip6_header_t *ip;
10247   int version = 0;
10248   u32 version_val;
10249   u8 traffic_class = 0;
10250   u32 traffic_class_val = 0;
10251   u8 flow_label = 0;
10252   u8 flow_label_val;
10253   int src = 0, dst = 0;
10254   ip6_address_t src_val, dst_val;
10255   int proto = 0;
10256   u32 proto_val;
10257   int payload_length = 0;
10258   u32 payload_length_val;
10259   int hop_limit = 0;
10260   int hop_limit_val;
10261   u32 ip_version_traffic_class_and_flow_label;
10262
10263   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10264     {
10265       if (unformat (input, "version %d", &version_val))
10266         version = 1;
10267       else if (unformat (input, "traffic_class %d", &traffic_class_val))
10268         traffic_class = 1;
10269       else if (unformat (input, "flow_label %d", &flow_label_val))
10270         flow_label = 1;
10271       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
10272         src = 1;
10273       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
10274         dst = 1;
10275       else if (unformat (input, "proto %d", &proto_val))
10276         proto = 1;
10277       else if (unformat (input, "payload_length %d", &payload_length_val))
10278         payload_length = 1;
10279       else if (unformat (input, "hop_limit %d", &hop_limit_val))
10280         hop_limit = 1;
10281       else
10282         break;
10283     }
10284
10285   if (version + traffic_class + flow_label + src + dst + proto +
10286       payload_length + hop_limit == 0)
10287     return 0;
10288
10289   /*
10290    * Aligned because we use the real comparison functions
10291    */
10292   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
10293
10294   ip = (ip6_header_t *) match;
10295
10296   if (src)
10297     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
10298
10299   if (dst)
10300     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
10301
10302   if (proto)
10303     ip->protocol = proto_val;
10304
10305   ip_version_traffic_class_and_flow_label = 0;
10306
10307   if (version)
10308     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
10309
10310   if (traffic_class)
10311     ip_version_traffic_class_and_flow_label |=
10312       (traffic_class_val & 0xFF) << 20;
10313
10314   if (flow_label)
10315     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
10316
10317   ip->ip_version_traffic_class_and_flow_label =
10318     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
10319
10320   if (payload_length)
10321     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
10322
10323   if (hop_limit)
10324     ip->hop_limit = hop_limit_val;
10325
10326   *matchp = match;
10327   return 1;
10328 }
10329
10330 uword
10331 unformat_l3_match (unformat_input_t * input, va_list * args)
10332 {
10333   u8 **matchp = va_arg (*args, u8 **);
10334
10335   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10336     {
10337       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
10338         return 1;
10339       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
10340         return 1;
10341       else
10342         break;
10343     }
10344   return 0;
10345 }
10346
10347 uword
10348 unformat_vlan_tag (unformat_input_t * input, va_list * args)
10349 {
10350   u8 *tagp = va_arg (*args, u8 *);
10351   u32 tag;
10352
10353   if (unformat (input, "%d", &tag))
10354     {
10355       tagp[0] = (tag >> 8) & 0x0F;
10356       tagp[1] = tag & 0xFF;
10357       return 1;
10358     }
10359
10360   return 0;
10361 }
10362
10363 uword
10364 unformat_l2_match (unformat_input_t * input, va_list * args)
10365 {
10366   u8 **matchp = va_arg (*args, u8 **);
10367   u8 *match = 0;
10368   u8 src = 0;
10369   u8 src_val[6];
10370   u8 dst = 0;
10371   u8 dst_val[6];
10372   u8 proto = 0;
10373   u16 proto_val;
10374   u8 tag1 = 0;
10375   u8 tag1_val[2];
10376   u8 tag2 = 0;
10377   u8 tag2_val[2];
10378   int len = 14;
10379   u8 ignore_tag1 = 0;
10380   u8 ignore_tag2 = 0;
10381   u8 cos1 = 0;
10382   u8 cos2 = 0;
10383   u32 cos1_val = 0;
10384   u32 cos2_val = 0;
10385
10386   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10387     {
10388       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
10389         src = 1;
10390       else
10391         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
10392         dst = 1;
10393       else if (unformat (input, "proto %U",
10394                          unformat_ethernet_type_host_byte_order, &proto_val))
10395         proto = 1;
10396       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
10397         tag1 = 1;
10398       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
10399         tag2 = 1;
10400       else if (unformat (input, "ignore-tag1"))
10401         ignore_tag1 = 1;
10402       else if (unformat (input, "ignore-tag2"))
10403         ignore_tag2 = 1;
10404       else if (unformat (input, "cos1 %d", &cos1_val))
10405         cos1 = 1;
10406       else if (unformat (input, "cos2 %d", &cos2_val))
10407         cos2 = 1;
10408       else
10409         break;
10410     }
10411   if ((src + dst + proto + tag1 + tag2 +
10412        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
10413     return 0;
10414
10415   if (tag1 || ignore_tag1 || cos1)
10416     len = 18;
10417   if (tag2 || ignore_tag2 || cos2)
10418     len = 22;
10419
10420   vec_validate_aligned (match, len - 1, sizeof (u32x4));
10421
10422   if (dst)
10423     clib_memcpy (match, dst_val, 6);
10424
10425   if (src)
10426     clib_memcpy (match + 6, src_val, 6);
10427
10428   if (tag2)
10429     {
10430       /* inner vlan tag */
10431       match[19] = tag2_val[1];
10432       match[18] = tag2_val[0];
10433       if (cos2)
10434         match[18] |= (cos2_val & 0x7) << 5;
10435       if (proto)
10436         {
10437           match[21] = proto_val & 0xff;
10438           match[20] = proto_val >> 8;
10439         }
10440       if (tag1)
10441         {
10442           match[15] = tag1_val[1];
10443           match[14] = tag1_val[0];
10444         }
10445       if (cos1)
10446         match[14] |= (cos1_val & 0x7) << 5;
10447       *matchp = match;
10448       return 1;
10449     }
10450   if (tag1)
10451     {
10452       match[15] = tag1_val[1];
10453       match[14] = tag1_val[0];
10454       if (proto)
10455         {
10456           match[17] = proto_val & 0xff;
10457           match[16] = proto_val >> 8;
10458         }
10459       if (cos1)
10460         match[14] |= (cos1_val & 0x7) << 5;
10461
10462       *matchp = match;
10463       return 1;
10464     }
10465   if (cos2)
10466     match[18] |= (cos2_val & 0x7) << 5;
10467   if (cos1)
10468     match[14] |= (cos1_val & 0x7) << 5;
10469   if (proto)
10470     {
10471       match[13] = proto_val & 0xff;
10472       match[12] = proto_val >> 8;
10473     }
10474
10475   *matchp = match;
10476   return 1;
10477 }
10478
10479 uword
10480 unformat_qos_source (unformat_input_t * input, va_list * args)
10481 {
10482   int *qs = va_arg (*args, int *);
10483
10484   if (unformat (input, "ip"))
10485     *qs = QOS_SOURCE_IP;
10486   else if (unformat (input, "mpls"))
10487     *qs = QOS_SOURCE_MPLS;
10488   else if (unformat (input, "ext"))
10489     *qs = QOS_SOURCE_EXT;
10490   else if (unformat (input, "vlan"))
10491     *qs = QOS_SOURCE_VLAN;
10492   else
10493     return 0;
10494
10495   return 1;
10496 }
10497 #endif
10498
10499 uword
10500 api_unformat_classify_match (unformat_input_t * input, va_list * args)
10501 {
10502   u8 **matchp = va_arg (*args, u8 **);
10503   u32 skip_n_vectors = va_arg (*args, u32);
10504   u32 match_n_vectors = va_arg (*args, u32);
10505
10506   u8 *match = 0;
10507   u8 *l2 = 0;
10508   u8 *l3 = 0;
10509   u8 *l4 = 0;
10510
10511   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10512     {
10513       if (unformat (input, "hex %U", unformat_hex_string, &match))
10514         ;
10515       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
10516         ;
10517       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
10518         ;
10519       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
10520         ;
10521       else
10522         break;
10523     }
10524
10525   if (l4 && !l3)
10526     {
10527       vec_free (match);
10528       vec_free (l2);
10529       vec_free (l4);
10530       return 0;
10531     }
10532
10533   if (match || l2 || l3 || l4)
10534     {
10535       if (l2 || l3 || l4)
10536         {
10537           /* "Win a free Ethernet header in every packet" */
10538           if (l2 == 0)
10539             vec_validate_aligned (l2, 13, sizeof (u32x4));
10540           match = l2;
10541           if (vec_len (l3))
10542             {
10543               vec_append_aligned (match, l3, sizeof (u32x4));
10544               vec_free (l3);
10545             }
10546           if (vec_len (l4))
10547             {
10548               vec_append_aligned (match, l4, sizeof (u32x4));
10549               vec_free (l4);
10550             }
10551         }
10552
10553       /* Make sure the vector is big enough even if key is all 0's */
10554       vec_validate_aligned
10555         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
10556          sizeof (u32x4));
10557
10558       /* Set size, include skipped vectors */
10559       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
10560
10561       *matchp = match;
10562
10563       return 1;
10564     }
10565
10566   return 0;
10567 }
10568
10569 static int
10570 api_classify_add_del_session (vat_main_t * vam)
10571 {
10572   unformat_input_t *i = vam->input;
10573   vl_api_classify_add_del_session_t *mp;
10574   int is_add = 1;
10575   u32 table_index = ~0;
10576   u32 hit_next_index = ~0;
10577   u32 opaque_index = ~0;
10578   u8 *match = 0;
10579   i32 advance = 0;
10580   u32 skip_n_vectors = 0;
10581   u32 match_n_vectors = 0;
10582   u32 action = 0;
10583   u32 metadata = 0;
10584   int ret;
10585
10586   /*
10587    * Warning: you have to supply skip_n and match_n
10588    * because the API client cant simply look at the classify
10589    * table object.
10590    */
10591
10592   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10593     {
10594       if (unformat (i, "del"))
10595         is_add = 0;
10596       else if (unformat (i, "hit-next %U", api_unformat_ip_next_index,
10597                          &hit_next_index))
10598         ;
10599       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
10600                          &hit_next_index))
10601         ;
10602       else if (unformat (i, "acl-hit-next %U", api_unformat_acl_next_index,
10603                          &hit_next_index))
10604         ;
10605       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
10606         ;
10607       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
10608         ;
10609       else if (unformat (i, "opaque-index %d", &opaque_index))
10610         ;
10611       else if (unformat (i, "skip_n %d", &skip_n_vectors))
10612         ;
10613       else if (unformat (i, "match_n %d", &match_n_vectors))
10614         ;
10615       else if (unformat (i, "match %U", api_unformat_classify_match,
10616                          &match, skip_n_vectors, match_n_vectors))
10617         ;
10618       else if (unformat (i, "advance %d", &advance))
10619         ;
10620       else if (unformat (i, "table-index %d", &table_index))
10621         ;
10622       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
10623         action = 1;
10624       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
10625         action = 2;
10626       else if (unformat (i, "action %d", &action))
10627         ;
10628       else if (unformat (i, "metadata %d", &metadata))
10629         ;
10630       else
10631         break;
10632     }
10633
10634   if (table_index == ~0)
10635     {
10636       errmsg ("Table index required");
10637       return -99;
10638     }
10639
10640   if (is_add && match == 0)
10641     {
10642       errmsg ("Match value required");
10643       return -99;
10644     }
10645
10646   M2 (CLASSIFY_ADD_DEL_SESSION, mp, vec_len (match));
10647
10648   mp->is_add = is_add;
10649   mp->table_index = ntohl (table_index);
10650   mp->hit_next_index = ntohl (hit_next_index);
10651   mp->opaque_index = ntohl (opaque_index);
10652   mp->advance = ntohl (advance);
10653   mp->action = action;
10654   mp->metadata = ntohl (metadata);
10655   mp->match_len = ntohl (vec_len (match));
10656   clib_memcpy (mp->match, match, vec_len (match));
10657   vec_free (match);
10658
10659   S (mp);
10660   W (ret);
10661   return ret;
10662 }
10663
10664 static int
10665 api_classify_set_interface_ip_table (vat_main_t * vam)
10666 {
10667   unformat_input_t *i = vam->input;
10668   vl_api_classify_set_interface_ip_table_t *mp;
10669   u32 sw_if_index;
10670   int sw_if_index_set;
10671   u32 table_index = ~0;
10672   u8 is_ipv6 = 0;
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, "table %d", &table_index))
10682         ;
10683       else
10684         {
10685           clib_warning ("parse error '%U'", format_unformat_error, i);
10686           return -99;
10687         }
10688     }
10689
10690   if (sw_if_index_set == 0)
10691     {
10692       errmsg ("missing interface name or sw_if_index");
10693       return -99;
10694     }
10695
10696
10697   M (CLASSIFY_SET_INTERFACE_IP_TABLE, mp);
10698
10699   mp->sw_if_index = ntohl (sw_if_index);
10700   mp->table_index = ntohl (table_index);
10701   mp->is_ipv6 = is_ipv6;
10702
10703   S (mp);
10704   W (ret);
10705   return ret;
10706 }
10707
10708 static int
10709 api_classify_set_interface_l2_tables (vat_main_t * vam)
10710 {
10711   unformat_input_t *i = vam->input;
10712   vl_api_classify_set_interface_l2_tables_t *mp;
10713   u32 sw_if_index;
10714   int sw_if_index_set;
10715   u32 ip4_table_index = ~0;
10716   u32 ip6_table_index = ~0;
10717   u32 other_table_index = ~0;
10718   u32 is_input = 1;
10719   int ret;
10720
10721   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10722     {
10723       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10724         sw_if_index_set = 1;
10725       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10726         sw_if_index_set = 1;
10727       else if (unformat (i, "ip4-table %d", &ip4_table_index))
10728         ;
10729       else if (unformat (i, "ip6-table %d", &ip6_table_index))
10730         ;
10731       else if (unformat (i, "other-table %d", &other_table_index))
10732         ;
10733       else if (unformat (i, "is-input %d", &is_input))
10734         ;
10735       else
10736         {
10737           clib_warning ("parse error '%U'", format_unformat_error, i);
10738           return -99;
10739         }
10740     }
10741
10742   if (sw_if_index_set == 0)
10743     {
10744       errmsg ("missing interface name or sw_if_index");
10745       return -99;
10746     }
10747
10748
10749   M (CLASSIFY_SET_INTERFACE_L2_TABLES, mp);
10750
10751   mp->sw_if_index = ntohl (sw_if_index);
10752   mp->ip4_table_index = ntohl (ip4_table_index);
10753   mp->ip6_table_index = ntohl (ip6_table_index);
10754   mp->other_table_index = ntohl (other_table_index);
10755   mp->is_input = (u8) is_input;
10756
10757   S (mp);
10758   W (ret);
10759   return ret;
10760 }
10761
10762 static int
10763 api_set_ipfix_exporter (vat_main_t * vam)
10764 {
10765   unformat_input_t *i = vam->input;
10766   vl_api_set_ipfix_exporter_t *mp;
10767   ip4_address_t collector_address;
10768   u8 collector_address_set = 0;
10769   u32 collector_port = ~0;
10770   ip4_address_t src_address;
10771   u8 src_address_set = 0;
10772   u32 vrf_id = ~0;
10773   u32 path_mtu = ~0;
10774   u32 template_interval = ~0;
10775   u8 udp_checksum = 0;
10776   int ret;
10777
10778   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10779     {
10780       if (unformat (i, "collector_address %U", unformat_ip4_address,
10781                     &collector_address))
10782         collector_address_set = 1;
10783       else if (unformat (i, "collector_port %d", &collector_port))
10784         ;
10785       else if (unformat (i, "src_address %U", unformat_ip4_address,
10786                          &src_address))
10787         src_address_set = 1;
10788       else if (unformat (i, "vrf_id %d", &vrf_id))
10789         ;
10790       else if (unformat (i, "path_mtu %d", &path_mtu))
10791         ;
10792       else if (unformat (i, "template_interval %d", &template_interval))
10793         ;
10794       else if (unformat (i, "udp_checksum"))
10795         udp_checksum = 1;
10796       else
10797         break;
10798     }
10799
10800   if (collector_address_set == 0)
10801     {
10802       errmsg ("collector_address required");
10803       return -99;
10804     }
10805
10806   if (src_address_set == 0)
10807     {
10808       errmsg ("src_address required");
10809       return -99;
10810     }
10811
10812   M (SET_IPFIX_EXPORTER, mp);
10813
10814   memcpy (mp->collector_address.un.ip4, collector_address.data,
10815           sizeof (collector_address.data));
10816   mp->collector_port = htons ((u16) collector_port);
10817   memcpy (mp->src_address.un.ip4, src_address.data,
10818           sizeof (src_address.data));
10819   mp->vrf_id = htonl (vrf_id);
10820   mp->path_mtu = htonl (path_mtu);
10821   mp->template_interval = htonl (template_interval);
10822   mp->udp_checksum = udp_checksum;
10823
10824   S (mp);
10825   W (ret);
10826   return ret;
10827 }
10828
10829 static int
10830 api_set_ipfix_classify_stream (vat_main_t * vam)
10831 {
10832   unformat_input_t *i = vam->input;
10833   vl_api_set_ipfix_classify_stream_t *mp;
10834   u32 domain_id = 0;
10835   u32 src_port = UDP_DST_PORT_ipfix;
10836   int ret;
10837
10838   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10839     {
10840       if (unformat (i, "domain %d", &domain_id))
10841         ;
10842       else if (unformat (i, "src_port %d", &src_port))
10843         ;
10844       else
10845         {
10846           errmsg ("unknown input `%U'", format_unformat_error, i);
10847           return -99;
10848         }
10849     }
10850
10851   M (SET_IPFIX_CLASSIFY_STREAM, mp);
10852
10853   mp->domain_id = htonl (domain_id);
10854   mp->src_port = htons ((u16) src_port);
10855
10856   S (mp);
10857   W (ret);
10858   return ret;
10859 }
10860
10861 static int
10862 api_ipfix_classify_table_add_del (vat_main_t * vam)
10863 {
10864   unformat_input_t *i = vam->input;
10865   vl_api_ipfix_classify_table_add_del_t *mp;
10866   int is_add = -1;
10867   u32 classify_table_index = ~0;
10868   u8 ip_version = 0;
10869   u8 transport_protocol = 255;
10870   int ret;
10871
10872   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10873     {
10874       if (unformat (i, "add"))
10875         is_add = 1;
10876       else if (unformat (i, "del"))
10877         is_add = 0;
10878       else if (unformat (i, "table %d", &classify_table_index))
10879         ;
10880       else if (unformat (i, "ip4"))
10881         ip_version = 4;
10882       else if (unformat (i, "ip6"))
10883         ip_version = 6;
10884       else if (unformat (i, "tcp"))
10885         transport_protocol = 6;
10886       else if (unformat (i, "udp"))
10887         transport_protocol = 17;
10888       else
10889         {
10890           errmsg ("unknown input `%U'", format_unformat_error, i);
10891           return -99;
10892         }
10893     }
10894
10895   if (is_add == -1)
10896     {
10897       errmsg ("expecting: add|del");
10898       return -99;
10899     }
10900   if (classify_table_index == ~0)
10901     {
10902       errmsg ("classifier table not specified");
10903       return -99;
10904     }
10905   if (ip_version == 0)
10906     {
10907       errmsg ("IP version not specified");
10908       return -99;
10909     }
10910
10911   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, mp);
10912
10913   mp->is_add = is_add;
10914   mp->table_id = htonl (classify_table_index);
10915   mp->ip_version = ip_version;
10916   mp->transport_protocol = transport_protocol;
10917
10918   S (mp);
10919   W (ret);
10920   return ret;
10921 }
10922
10923 static int
10924 api_get_node_index (vat_main_t * vam)
10925 {
10926   unformat_input_t *i = vam->input;
10927   vl_api_get_node_index_t *mp;
10928   u8 *name = 0;
10929   int ret;
10930
10931   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10932     {
10933       if (unformat (i, "node %s", &name))
10934         ;
10935       else
10936         break;
10937     }
10938   if (name == 0)
10939     {
10940       errmsg ("node name required");
10941       return -99;
10942     }
10943   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
10944     {
10945       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
10946       return -99;
10947     }
10948
10949   M (GET_NODE_INDEX, mp);
10950   clib_memcpy (mp->node_name, name, vec_len (name));
10951   vec_free (name);
10952
10953   S (mp);
10954   W (ret);
10955   return ret;
10956 }
10957
10958 static int
10959 api_get_next_index (vat_main_t * vam)
10960 {
10961   unformat_input_t *i = vam->input;
10962   vl_api_get_next_index_t *mp;
10963   u8 *node_name = 0, *next_node_name = 0;
10964   int ret;
10965
10966   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10967     {
10968       if (unformat (i, "node-name %s", &node_name))
10969         ;
10970       else if (unformat (i, "next-node-name %s", &next_node_name))
10971         break;
10972     }
10973
10974   if (node_name == 0)
10975     {
10976       errmsg ("node name required");
10977       return -99;
10978     }
10979   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
10980     {
10981       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
10982       return -99;
10983     }
10984
10985   if (next_node_name == 0)
10986     {
10987       errmsg ("next node name required");
10988       return -99;
10989     }
10990   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
10991     {
10992       errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
10993       return -99;
10994     }
10995
10996   M (GET_NEXT_INDEX, mp);
10997   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
10998   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
10999   vec_free (node_name);
11000   vec_free (next_node_name);
11001
11002   S (mp);
11003   W (ret);
11004   return ret;
11005 }
11006
11007 static int
11008 api_add_node_next (vat_main_t * vam)
11009 {
11010   unformat_input_t *i = vam->input;
11011   vl_api_add_node_next_t *mp;
11012   u8 *name = 0;
11013   u8 *next = 0;
11014   int ret;
11015
11016   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11017     {
11018       if (unformat (i, "node %s", &name))
11019         ;
11020       else if (unformat (i, "next %s", &next))
11021         ;
11022       else
11023         break;
11024     }
11025   if (name == 0)
11026     {
11027       errmsg ("node name required");
11028       return -99;
11029     }
11030   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
11031     {
11032       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11033       return -99;
11034     }
11035   if (next == 0)
11036     {
11037       errmsg ("next node required");
11038       return -99;
11039     }
11040   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
11041     {
11042       errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
11043       return -99;
11044     }
11045
11046   M (ADD_NODE_NEXT, mp);
11047   clib_memcpy (mp->node_name, name, vec_len (name));
11048   clib_memcpy (mp->next_name, next, vec_len (next));
11049   vec_free (name);
11050   vec_free (next);
11051
11052   S (mp);
11053   W (ret);
11054   return ret;
11055 }
11056
11057 static int
11058 api_l2tpv3_create_tunnel (vat_main_t * vam)
11059 {
11060   unformat_input_t *i = vam->input;
11061   ip6_address_t client_address, our_address;
11062   int client_address_set = 0;
11063   int our_address_set = 0;
11064   u32 local_session_id = 0;
11065   u32 remote_session_id = 0;
11066   u64 local_cookie = 0;
11067   u64 remote_cookie = 0;
11068   u8 l2_sublayer_present = 0;
11069   vl_api_l2tpv3_create_tunnel_t *mp;
11070   int ret;
11071
11072   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11073     {
11074       if (unformat (i, "client_address %U", unformat_ip6_address,
11075                     &client_address))
11076         client_address_set = 1;
11077       else if (unformat (i, "our_address %U", unformat_ip6_address,
11078                          &our_address))
11079         our_address_set = 1;
11080       else if (unformat (i, "local_session_id %d", &local_session_id))
11081         ;
11082       else if (unformat (i, "remote_session_id %d", &remote_session_id))
11083         ;
11084       else if (unformat (i, "local_cookie %lld", &local_cookie))
11085         ;
11086       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
11087         ;
11088       else if (unformat (i, "l2-sublayer-present"))
11089         l2_sublayer_present = 1;
11090       else
11091         break;
11092     }
11093
11094   if (client_address_set == 0)
11095     {
11096       errmsg ("client_address required");
11097       return -99;
11098     }
11099
11100   if (our_address_set == 0)
11101     {
11102       errmsg ("our_address required");
11103       return -99;
11104     }
11105
11106   M (L2TPV3_CREATE_TUNNEL, mp);
11107
11108   clib_memcpy (mp->client_address.un.ip6, client_address.as_u8,
11109                sizeof (ip6_address_t));
11110
11111   clib_memcpy (mp->our_address.un.ip6, our_address.as_u8,
11112                sizeof (ip6_address_t));
11113
11114   mp->local_session_id = ntohl (local_session_id);
11115   mp->remote_session_id = ntohl (remote_session_id);
11116   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
11117   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
11118   mp->l2_sublayer_present = l2_sublayer_present;
11119
11120   S (mp);
11121   W (ret);
11122   return ret;
11123 }
11124
11125 static int
11126 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
11127 {
11128   unformat_input_t *i = vam->input;
11129   u32 sw_if_index;
11130   u8 sw_if_index_set = 0;
11131   u64 new_local_cookie = 0;
11132   u64 new_remote_cookie = 0;
11133   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
11134   int ret;
11135
11136   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11137     {
11138       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11139         sw_if_index_set = 1;
11140       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11141         sw_if_index_set = 1;
11142       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
11143         ;
11144       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
11145         ;
11146       else
11147         break;
11148     }
11149
11150   if (sw_if_index_set == 0)
11151     {
11152       errmsg ("missing interface name or sw_if_index");
11153       return -99;
11154     }
11155
11156   M (L2TPV3_SET_TUNNEL_COOKIES, mp);
11157
11158   mp->sw_if_index = ntohl (sw_if_index);
11159   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
11160   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
11161
11162   S (mp);
11163   W (ret);
11164   return ret;
11165 }
11166
11167 static int
11168 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
11169 {
11170   unformat_input_t *i = vam->input;
11171   vl_api_l2tpv3_interface_enable_disable_t *mp;
11172   u32 sw_if_index;
11173   u8 sw_if_index_set = 0;
11174   u8 enable_disable = 1;
11175   int ret;
11176
11177   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11178     {
11179       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11180         sw_if_index_set = 1;
11181       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11182         sw_if_index_set = 1;
11183       else if (unformat (i, "enable"))
11184         enable_disable = 1;
11185       else if (unformat (i, "disable"))
11186         enable_disable = 0;
11187       else
11188         break;
11189     }
11190
11191   if (sw_if_index_set == 0)
11192     {
11193       errmsg ("missing interface name or sw_if_index");
11194       return -99;
11195     }
11196
11197   M (L2TPV3_INTERFACE_ENABLE_DISABLE, mp);
11198
11199   mp->sw_if_index = ntohl (sw_if_index);
11200   mp->enable_disable = enable_disable;
11201
11202   S (mp);
11203   W (ret);
11204   return ret;
11205 }
11206
11207 static int
11208 api_l2tpv3_set_lookup_key (vat_main_t * vam)
11209 {
11210   unformat_input_t *i = vam->input;
11211   vl_api_l2tpv3_set_lookup_key_t *mp;
11212   u8 key = ~0;
11213   int ret;
11214
11215   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11216     {
11217       if (unformat (i, "lookup_v6_src"))
11218         key = L2T_LOOKUP_SRC_ADDRESS;
11219       else if (unformat (i, "lookup_v6_dst"))
11220         key = L2T_LOOKUP_DST_ADDRESS;
11221       else if (unformat (i, "lookup_session_id"))
11222         key = L2T_LOOKUP_SESSION_ID;
11223       else
11224         break;
11225     }
11226
11227   if (key == (u8) ~ 0)
11228     {
11229       errmsg ("l2tp session lookup key unset");
11230       return -99;
11231     }
11232
11233   M (L2TPV3_SET_LOOKUP_KEY, mp);
11234
11235   mp->key = key;
11236
11237   S (mp);
11238   W (ret);
11239   return ret;
11240 }
11241
11242 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
11243   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
11244 {
11245   vat_main_t *vam = &vat_main;
11246
11247   print (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)",
11248          format_ip6_address, mp->our_address,
11249          format_ip6_address, mp->client_address,
11250          clib_net_to_host_u32 (mp->sw_if_index));
11251
11252   print (vam->ofp,
11253          "   local cookies %016llx %016llx remote cookie %016llx",
11254          clib_net_to_host_u64 (mp->local_cookie[0]),
11255          clib_net_to_host_u64 (mp->local_cookie[1]),
11256          clib_net_to_host_u64 (mp->remote_cookie));
11257
11258   print (vam->ofp, "   local session-id %d remote session-id %d",
11259          clib_net_to_host_u32 (mp->local_session_id),
11260          clib_net_to_host_u32 (mp->remote_session_id));
11261
11262   print (vam->ofp, "   l2 specific sublayer %s\n",
11263          mp->l2_sublayer_present ? "preset" : "absent");
11264
11265 }
11266
11267 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
11268   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
11269 {
11270   vat_main_t *vam = &vat_main;
11271   vat_json_node_t *node = NULL;
11272   struct in6_addr addr;
11273
11274   if (VAT_JSON_ARRAY != vam->json_tree.type)
11275     {
11276       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11277       vat_json_init_array (&vam->json_tree);
11278     }
11279   node = vat_json_array_add (&vam->json_tree);
11280
11281   vat_json_init_object (node);
11282
11283   clib_memcpy (&addr, mp->our_address.un.ip6, sizeof (addr));
11284   vat_json_object_add_ip6 (node, "our_address", addr);
11285   clib_memcpy (&addr, mp->client_address.un.ip6, sizeof (addr));
11286   vat_json_object_add_ip6 (node, "client_address", addr);
11287
11288   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
11289   vat_json_init_array (lc);
11290   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
11291   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
11292   vat_json_object_add_uint (node, "remote_cookie",
11293                             clib_net_to_host_u64 (mp->remote_cookie));
11294
11295   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
11296   vat_json_object_add_uint (node, "local_session_id",
11297                             clib_net_to_host_u32 (mp->local_session_id));
11298   vat_json_object_add_uint (node, "remote_session_id",
11299                             clib_net_to_host_u32 (mp->remote_session_id));
11300   vat_json_object_add_string_copy (node, "l2_sublayer",
11301                                    mp->l2_sublayer_present ? (u8 *) "present"
11302                                    : (u8 *) "absent");
11303 }
11304
11305 static int
11306 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
11307 {
11308   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
11309   vl_api_control_ping_t *mp_ping;
11310   int ret;
11311
11312   /* Get list of l2tpv3-tunnel interfaces */
11313   M (SW_IF_L2TPV3_TUNNEL_DUMP, mp);
11314   S (mp);
11315
11316   /* Use a control ping for synchronization */
11317   MPING (CONTROL_PING, mp_ping);
11318   S (mp_ping);
11319
11320   W (ret);
11321   return ret;
11322 }
11323
11324
11325 static void vl_api_sw_interface_tap_v2_details_t_handler
11326   (vl_api_sw_interface_tap_v2_details_t * mp)
11327 {
11328   vat_main_t *vam = &vat_main;
11329
11330   u8 *ip4 =
11331     format (0, "%U/%d", format_ip4_address, mp->host_ip4_prefix.address,
11332             mp->host_ip4_prefix.len);
11333   u8 *ip6 =
11334     format (0, "%U/%d", format_ip6_address, mp->host_ip6_prefix.address,
11335             mp->host_ip6_prefix.len);
11336
11337   print (vam->ofp,
11338          "\n%-16s %-12d %-5d %-12d %-12d %-14U %-30s %-20s %-20s %-30s 0x%-08x",
11339          mp->dev_name, ntohl (mp->sw_if_index), ntohl (mp->id),
11340          ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
11341          format_ethernet_address, mp->host_mac_addr, mp->host_namespace,
11342          mp->host_bridge, ip4, ip6, ntohl (mp->tap_flags));
11343
11344   vec_free (ip4);
11345   vec_free (ip6);
11346 }
11347
11348 static void vl_api_sw_interface_tap_v2_details_t_handler_json
11349   (vl_api_sw_interface_tap_v2_details_t * mp)
11350 {
11351   vat_main_t *vam = &vat_main;
11352   vat_json_node_t *node = NULL;
11353
11354   if (VAT_JSON_ARRAY != vam->json_tree.type)
11355     {
11356       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11357       vat_json_init_array (&vam->json_tree);
11358     }
11359   node = vat_json_array_add (&vam->json_tree);
11360
11361   vat_json_init_object (node);
11362   vat_json_object_add_uint (node, "id", ntohl (mp->id));
11363   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11364   vat_json_object_add_uint (node, "tap_flags", ntohl (mp->tap_flags));
11365   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
11366   vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
11367   vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
11368   vat_json_object_add_string_copy (node, "host_mac_addr",
11369                                    format (0, "%U", format_ethernet_address,
11370                                            &mp->host_mac_addr));
11371   vat_json_object_add_string_copy (node, "host_namespace",
11372                                    mp->host_namespace);
11373   vat_json_object_add_string_copy (node, "host_bridge", mp->host_bridge);
11374   vat_json_object_add_string_copy (node, "host_ip4_addr",
11375                                    format (0, "%U/%d", format_ip4_address,
11376                                            mp->host_ip4_prefix.address,
11377                                            mp->host_ip4_prefix.len));
11378   vat_json_object_add_string_copy (node, "host_ip6_prefix",
11379                                    format (0, "%U/%d", format_ip6_address,
11380                                            mp->host_ip6_prefix.address,
11381                                            mp->host_ip6_prefix.len));
11382
11383 }
11384
11385 static int
11386 api_sw_interface_tap_v2_dump (vat_main_t * vam)
11387 {
11388   vl_api_sw_interface_tap_v2_dump_t *mp;
11389   vl_api_control_ping_t *mp_ping;
11390   int ret;
11391
11392   print (vam->ofp,
11393          "\n%-16s %-12s %-5s %-12s %-12s %-14s %-30s %-20s %-20s %-30s",
11394          "dev_name", "sw_if_index", "id", "rx_ring_sz", "tx_ring_sz",
11395          "host_mac_addr", "host_namespace", "host_bridge", "host_ip4_addr",
11396          "host_ip6_addr");
11397
11398   /* Get list of tap interfaces */
11399   M (SW_INTERFACE_TAP_V2_DUMP, mp);
11400   S (mp);
11401
11402   /* Use a control ping for synchronization */
11403   MPING (CONTROL_PING, mp_ping);
11404   S (mp_ping);
11405
11406   W (ret);
11407   return ret;
11408 }
11409
11410 static void vl_api_sw_interface_virtio_pci_details_t_handler
11411   (vl_api_sw_interface_virtio_pci_details_t * mp)
11412 {
11413   vat_main_t *vam = &vat_main;
11414
11415   typedef union
11416   {
11417     struct
11418     {
11419       u16 domain;
11420       u8 bus;
11421       u8 slot:5;
11422       u8 function:3;
11423     };
11424     u32 as_u32;
11425   } pci_addr_t;
11426   pci_addr_t addr;
11427
11428   addr.domain = ntohs (mp->pci_addr.domain);
11429   addr.bus = mp->pci_addr.bus;
11430   addr.slot = mp->pci_addr.slot;
11431   addr.function = mp->pci_addr.function;
11432
11433   u8 *pci_addr = format (0, "%04x:%02x:%02x.%x", addr.domain, addr.bus,
11434                          addr.slot, addr.function);
11435
11436   print (vam->ofp,
11437          "\n%-12s %-12d %-12d %-12d %-17U 0x%-08llx",
11438          pci_addr, ntohl (mp->sw_if_index),
11439          ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
11440          format_ethernet_address, mp->mac_addr,
11441          clib_net_to_host_u64 (mp->features));
11442   vec_free (pci_addr);
11443 }
11444
11445 static void vl_api_sw_interface_virtio_pci_details_t_handler_json
11446   (vl_api_sw_interface_virtio_pci_details_t * mp)
11447 {
11448   vat_main_t *vam = &vat_main;
11449   vat_json_node_t *node = NULL;
11450   vlib_pci_addr_t pci_addr;
11451
11452   if (VAT_JSON_ARRAY != vam->json_tree.type)
11453     {
11454       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11455       vat_json_init_array (&vam->json_tree);
11456     }
11457   node = vat_json_array_add (&vam->json_tree);
11458
11459   pci_addr.domain = ntohs (mp->pci_addr.domain);
11460   pci_addr.bus = mp->pci_addr.bus;
11461   pci_addr.slot = mp->pci_addr.slot;
11462   pci_addr.function = mp->pci_addr.function;
11463
11464   vat_json_init_object (node);
11465   vat_json_object_add_uint (node, "pci-addr", pci_addr.as_u32);
11466   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11467   vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
11468   vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
11469   vat_json_object_add_uint (node, "features",
11470                             clib_net_to_host_u64 (mp->features));
11471   vat_json_object_add_string_copy (node, "mac_addr",
11472                                    format (0, "%U", format_ethernet_address,
11473                                            &mp->mac_addr));
11474 }
11475
11476 static int
11477 api_sw_interface_virtio_pci_dump (vat_main_t * vam)
11478 {
11479   vl_api_sw_interface_virtio_pci_dump_t *mp;
11480   vl_api_control_ping_t *mp_ping;
11481   int ret;
11482
11483   print (vam->ofp,
11484          "\n%-12s %-12s %-12s %-12s %-17s %-08s",
11485          "pci_addr", "sw_if_index", "rx_ring_sz", "tx_ring_sz",
11486          "mac_addr", "features");
11487
11488   /* Get list of tap interfaces */
11489   M (SW_INTERFACE_VIRTIO_PCI_DUMP, mp);
11490   S (mp);
11491
11492   /* Use a control ping for synchronization */
11493   MPING (CONTROL_PING, mp_ping);
11494   S (mp_ping);
11495
11496   W (ret);
11497   return ret;
11498 }
11499
11500 static int
11501 api_vxlan_offload_rx (vat_main_t * vam)
11502 {
11503   unformat_input_t *line_input = vam->input;
11504   vl_api_vxlan_offload_rx_t *mp;
11505   u32 hw_if_index = ~0, rx_if_index = ~0;
11506   u8 is_add = 1;
11507   int ret;
11508
11509   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11510     {
11511       if (unformat (line_input, "del"))
11512         is_add = 0;
11513       else if (unformat (line_input, "hw %U", api_unformat_hw_if_index, vam,
11514                          &hw_if_index))
11515         ;
11516       else if (unformat (line_input, "hw hw_if_index %u", &hw_if_index))
11517         ;
11518       else if (unformat (line_input, "rx %U", api_unformat_sw_if_index, vam,
11519                          &rx_if_index))
11520         ;
11521       else if (unformat (line_input, "rx sw_if_index %u", &rx_if_index))
11522         ;
11523       else
11524         {
11525           errmsg ("parse error '%U'", format_unformat_error, line_input);
11526           return -99;
11527         }
11528     }
11529
11530   if (hw_if_index == ~0)
11531     {
11532       errmsg ("no hw interface");
11533       return -99;
11534     }
11535
11536   if (rx_if_index == ~0)
11537     {
11538       errmsg ("no rx tunnel");
11539       return -99;
11540     }
11541
11542   M (VXLAN_OFFLOAD_RX, mp);
11543
11544   mp->hw_if_index = ntohl (hw_if_index);
11545   mp->sw_if_index = ntohl (rx_if_index);
11546   mp->enable = is_add;
11547
11548   S (mp);
11549   W (ret);
11550   return ret;
11551 }
11552
11553 static uword unformat_vxlan_decap_next
11554   (unformat_input_t * input, va_list * args)
11555 {
11556   u32 *result = va_arg (*args, u32 *);
11557   u32 tmp;
11558
11559   if (unformat (input, "l2"))
11560     *result = VXLAN_INPUT_NEXT_L2_INPUT;
11561   else if (unformat (input, "%d", &tmp))
11562     *result = tmp;
11563   else
11564     return 0;
11565   return 1;
11566 }
11567
11568 static int
11569 api_vxlan_add_del_tunnel (vat_main_t * vam)
11570 {
11571   unformat_input_t *line_input = vam->input;
11572   vl_api_vxlan_add_del_tunnel_t *mp;
11573   ip46_address_t src, dst;
11574   u8 is_add = 1;
11575   u8 ipv4_set = 0, ipv6_set = 0;
11576   u8 src_set = 0;
11577   u8 dst_set = 0;
11578   u8 grp_set = 0;
11579   u32 instance = ~0;
11580   u32 mcast_sw_if_index = ~0;
11581   u32 encap_vrf_id = 0;
11582   u32 decap_next_index = ~0;
11583   u32 vni = 0;
11584   int ret;
11585
11586   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
11587   clib_memset (&src, 0, sizeof src);
11588   clib_memset (&dst, 0, sizeof dst);
11589
11590   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11591     {
11592       if (unformat (line_input, "del"))
11593         is_add = 0;
11594       else if (unformat (line_input, "instance %d", &instance))
11595         ;
11596       else
11597         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
11598         {
11599           ipv4_set = 1;
11600           src_set = 1;
11601         }
11602       else
11603         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
11604         {
11605           ipv4_set = 1;
11606           dst_set = 1;
11607         }
11608       else
11609         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
11610         {
11611           ipv6_set = 1;
11612           src_set = 1;
11613         }
11614       else
11615         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
11616         {
11617           ipv6_set = 1;
11618           dst_set = 1;
11619         }
11620       else if (unformat (line_input, "group %U %U",
11621                          unformat_ip4_address, &dst.ip4,
11622                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
11623         {
11624           grp_set = dst_set = 1;
11625           ipv4_set = 1;
11626         }
11627       else if (unformat (line_input, "group %U",
11628                          unformat_ip4_address, &dst.ip4))
11629         {
11630           grp_set = dst_set = 1;
11631           ipv4_set = 1;
11632         }
11633       else if (unformat (line_input, "group %U %U",
11634                          unformat_ip6_address, &dst.ip6,
11635                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
11636         {
11637           grp_set = dst_set = 1;
11638           ipv6_set = 1;
11639         }
11640       else if (unformat (line_input, "group %U",
11641                          unformat_ip6_address, &dst.ip6))
11642         {
11643           grp_set = dst_set = 1;
11644           ipv6_set = 1;
11645         }
11646       else
11647         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
11648         ;
11649       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
11650         ;
11651       else if (unformat (line_input, "decap-next %U",
11652                          unformat_vxlan_decap_next, &decap_next_index))
11653         ;
11654       else if (unformat (line_input, "vni %d", &vni))
11655         ;
11656       else
11657         {
11658           errmsg ("parse error '%U'", format_unformat_error, line_input);
11659           return -99;
11660         }
11661     }
11662
11663   if (src_set == 0)
11664     {
11665       errmsg ("tunnel src address not specified");
11666       return -99;
11667     }
11668   if (dst_set == 0)
11669     {
11670       errmsg ("tunnel dst address not specified");
11671       return -99;
11672     }
11673
11674   if (grp_set && !ip46_address_is_multicast (&dst))
11675     {
11676       errmsg ("tunnel group address not multicast");
11677       return -99;
11678     }
11679   if (grp_set && mcast_sw_if_index == ~0)
11680     {
11681       errmsg ("tunnel nonexistent multicast device");
11682       return -99;
11683     }
11684   if (grp_set == 0 && ip46_address_is_multicast (&dst))
11685     {
11686       errmsg ("tunnel dst address must be unicast");
11687       return -99;
11688     }
11689
11690
11691   if (ipv4_set && ipv6_set)
11692     {
11693       errmsg ("both IPv4 and IPv6 addresses specified");
11694       return -99;
11695     }
11696
11697   if ((vni == 0) || (vni >> 24))
11698     {
11699       errmsg ("vni not specified or out of range");
11700       return -99;
11701     }
11702
11703   M (VXLAN_ADD_DEL_TUNNEL, mp);
11704
11705   if (ipv6_set)
11706     {
11707       clib_memcpy (mp->src_address, &src.ip6, sizeof (src.ip6));
11708       clib_memcpy (mp->dst_address, &dst.ip6, sizeof (dst.ip6));
11709     }
11710   else
11711     {
11712       clib_memcpy (mp->src_address, &src.ip4, sizeof (src.ip4));
11713       clib_memcpy (mp->dst_address, &dst.ip4, sizeof (dst.ip4));
11714     }
11715
11716   mp->instance = htonl (instance);
11717   mp->encap_vrf_id = ntohl (encap_vrf_id);
11718   mp->decap_next_index = ntohl (decap_next_index);
11719   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
11720   mp->vni = ntohl (vni);
11721   mp->is_add = is_add;
11722   mp->is_ipv6 = ipv6_set;
11723
11724   S (mp);
11725   W (ret);
11726   return ret;
11727 }
11728
11729 static void vl_api_vxlan_tunnel_details_t_handler
11730   (vl_api_vxlan_tunnel_details_t * mp)
11731 {
11732   vat_main_t *vam = &vat_main;
11733   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
11734   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
11735
11736   print (vam->ofp, "%11d%11d%24U%24U%14d%18d%13d%19d",
11737          ntohl (mp->sw_if_index),
11738          ntohl (mp->instance),
11739          format_ip46_address, &src, IP46_TYPE_ANY,
11740          format_ip46_address, &dst, IP46_TYPE_ANY,
11741          ntohl (mp->encap_vrf_id),
11742          ntohl (mp->decap_next_index), ntohl (mp->vni),
11743          ntohl (mp->mcast_sw_if_index));
11744 }
11745
11746 static void vl_api_vxlan_tunnel_details_t_handler_json
11747   (vl_api_vxlan_tunnel_details_t * mp)
11748 {
11749   vat_main_t *vam = &vat_main;
11750   vat_json_node_t *node = NULL;
11751
11752   if (VAT_JSON_ARRAY != vam->json_tree.type)
11753     {
11754       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11755       vat_json_init_array (&vam->json_tree);
11756     }
11757   node = vat_json_array_add (&vam->json_tree);
11758
11759   vat_json_init_object (node);
11760   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11761
11762   vat_json_object_add_uint (node, "instance", ntohl (mp->instance));
11763
11764   if (mp->is_ipv6)
11765     {
11766       struct in6_addr ip6;
11767
11768       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
11769       vat_json_object_add_ip6 (node, "src_address", ip6);
11770       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
11771       vat_json_object_add_ip6 (node, "dst_address", ip6);
11772     }
11773   else
11774     {
11775       struct in_addr ip4;
11776
11777       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
11778       vat_json_object_add_ip4 (node, "src_address", ip4);
11779       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
11780       vat_json_object_add_ip4 (node, "dst_address", ip4);
11781     }
11782   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
11783   vat_json_object_add_uint (node, "decap_next_index",
11784                             ntohl (mp->decap_next_index));
11785   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
11786   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
11787   vat_json_object_add_uint (node, "mcast_sw_if_index",
11788                             ntohl (mp->mcast_sw_if_index));
11789 }
11790
11791 static int
11792 api_vxlan_tunnel_dump (vat_main_t * vam)
11793 {
11794   unformat_input_t *i = vam->input;
11795   vl_api_vxlan_tunnel_dump_t *mp;
11796   vl_api_control_ping_t *mp_ping;
11797   u32 sw_if_index;
11798   u8 sw_if_index_set = 0;
11799   int ret;
11800
11801   /* Parse args required to build the message */
11802   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11803     {
11804       if (unformat (i, "sw_if_index %d", &sw_if_index))
11805         sw_if_index_set = 1;
11806       else
11807         break;
11808     }
11809
11810   if (sw_if_index_set == 0)
11811     {
11812       sw_if_index = ~0;
11813     }
11814
11815   if (!vam->json_output)
11816     {
11817       print (vam->ofp, "%11s%11s%24s%24s%14s%18s%13s%19s",
11818              "sw_if_index", "instance", "src_address", "dst_address",
11819              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
11820     }
11821
11822   /* Get list of vxlan-tunnel interfaces */
11823   M (VXLAN_TUNNEL_DUMP, mp);
11824
11825   mp->sw_if_index = htonl (sw_if_index);
11826
11827   S (mp);
11828
11829   /* Use a control ping for synchronization */
11830   MPING (CONTROL_PING, mp_ping);
11831   S (mp_ping);
11832
11833   W (ret);
11834   return ret;
11835 }
11836
11837 static uword unformat_geneve_decap_next
11838   (unformat_input_t * input, va_list * args)
11839 {
11840   u32 *result = va_arg (*args, u32 *);
11841   u32 tmp;
11842
11843   if (unformat (input, "l2"))
11844     *result = GENEVE_INPUT_NEXT_L2_INPUT;
11845   else if (unformat (input, "%d", &tmp))
11846     *result = tmp;
11847   else
11848     return 0;
11849   return 1;
11850 }
11851
11852 static int
11853 api_geneve_add_del_tunnel (vat_main_t * vam)
11854 {
11855   unformat_input_t *line_input = vam->input;
11856   vl_api_geneve_add_del_tunnel_t *mp;
11857   ip46_address_t src, dst;
11858   u8 is_add = 1;
11859   u8 ipv4_set = 0, ipv6_set = 0;
11860   u8 src_set = 0;
11861   u8 dst_set = 0;
11862   u8 grp_set = 0;
11863   u32 mcast_sw_if_index = ~0;
11864   u32 encap_vrf_id = 0;
11865   u32 decap_next_index = ~0;
11866   u32 vni = 0;
11867   int ret;
11868
11869   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
11870   clib_memset (&src, 0, sizeof src);
11871   clib_memset (&dst, 0, sizeof dst);
11872
11873   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11874     {
11875       if (unformat (line_input, "del"))
11876         is_add = 0;
11877       else
11878         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
11879         {
11880           ipv4_set = 1;
11881           src_set = 1;
11882         }
11883       else
11884         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
11885         {
11886           ipv4_set = 1;
11887           dst_set = 1;
11888         }
11889       else
11890         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
11891         {
11892           ipv6_set = 1;
11893           src_set = 1;
11894         }
11895       else
11896         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
11897         {
11898           ipv6_set = 1;
11899           dst_set = 1;
11900         }
11901       else if (unformat (line_input, "group %U %U",
11902                          unformat_ip4_address, &dst.ip4,
11903                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
11904         {
11905           grp_set = dst_set = 1;
11906           ipv4_set = 1;
11907         }
11908       else if (unformat (line_input, "group %U",
11909                          unformat_ip4_address, &dst.ip4))
11910         {
11911           grp_set = dst_set = 1;
11912           ipv4_set = 1;
11913         }
11914       else if (unformat (line_input, "group %U %U",
11915                          unformat_ip6_address, &dst.ip6,
11916                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
11917         {
11918           grp_set = dst_set = 1;
11919           ipv6_set = 1;
11920         }
11921       else if (unformat (line_input, "group %U",
11922                          unformat_ip6_address, &dst.ip6))
11923         {
11924           grp_set = dst_set = 1;
11925           ipv6_set = 1;
11926         }
11927       else
11928         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
11929         ;
11930       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
11931         ;
11932       else if (unformat (line_input, "decap-next %U",
11933                          unformat_geneve_decap_next, &decap_next_index))
11934         ;
11935       else if (unformat (line_input, "vni %d", &vni))
11936         ;
11937       else
11938         {
11939           errmsg ("parse error '%U'", format_unformat_error, line_input);
11940           return -99;
11941         }
11942     }
11943
11944   if (src_set == 0)
11945     {
11946       errmsg ("tunnel src address not specified");
11947       return -99;
11948     }
11949   if (dst_set == 0)
11950     {
11951       errmsg ("tunnel dst address not specified");
11952       return -99;
11953     }
11954
11955   if (grp_set && !ip46_address_is_multicast (&dst))
11956     {
11957       errmsg ("tunnel group address not multicast");
11958       return -99;
11959     }
11960   if (grp_set && mcast_sw_if_index == ~0)
11961     {
11962       errmsg ("tunnel nonexistent multicast device");
11963       return -99;
11964     }
11965   if (grp_set == 0 && ip46_address_is_multicast (&dst))
11966     {
11967       errmsg ("tunnel dst address must be unicast");
11968       return -99;
11969     }
11970
11971
11972   if (ipv4_set && ipv6_set)
11973     {
11974       errmsg ("both IPv4 and IPv6 addresses specified");
11975       return -99;
11976     }
11977
11978   if ((vni == 0) || (vni >> 24))
11979     {
11980       errmsg ("vni not specified or out of range");
11981       return -99;
11982     }
11983
11984   M (GENEVE_ADD_DEL_TUNNEL, mp);
11985
11986   if (ipv6_set)
11987     {
11988       clib_memcpy (&mp->local_address.un.ip6, &src.ip6, sizeof (src.ip6));
11989       clib_memcpy (&mp->remote_address.un.ip6, &dst.ip6, sizeof (dst.ip6));
11990     }
11991   else
11992     {
11993       clib_memcpy (&mp->local_address.un.ip4, &src.ip4, sizeof (src.ip4));
11994       clib_memcpy (&mp->remote_address.un.ip4, &dst.ip4, sizeof (dst.ip4));
11995     }
11996   mp->encap_vrf_id = ntohl (encap_vrf_id);
11997   mp->decap_next_index = ntohl (decap_next_index);
11998   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
11999   mp->vni = ntohl (vni);
12000   mp->is_add = is_add;
12001
12002   S (mp);
12003   W (ret);
12004   return ret;
12005 }
12006
12007 static void vl_api_geneve_tunnel_details_t_handler
12008   (vl_api_geneve_tunnel_details_t * mp)
12009 {
12010   vat_main_t *vam = &vat_main;
12011   ip46_address_t src = {.as_u64[0] = 0,.as_u64[1] = 0 };
12012   ip46_address_t dst = {.as_u64[0] = 0,.as_u64[1] = 0 };
12013
12014   if (mp->src_address.af == ADDRESS_IP6)
12015     {
12016       clib_memcpy (&src.ip6, &mp->src_address.un.ip6, sizeof (ip6_address_t));
12017       clib_memcpy (&dst.ip6, &mp->dst_address.un.ip6, sizeof (ip6_address_t));
12018     }
12019   else
12020     {
12021       clib_memcpy (&src.ip4, &mp->src_address.un.ip4, sizeof (ip4_address_t));
12022       clib_memcpy (&dst.ip4, &mp->dst_address.un.ip4, sizeof (ip4_address_t));
12023     }
12024
12025   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
12026          ntohl (mp->sw_if_index),
12027          format_ip46_address, &src, IP46_TYPE_ANY,
12028          format_ip46_address, &dst, IP46_TYPE_ANY,
12029          ntohl (mp->encap_vrf_id),
12030          ntohl (mp->decap_next_index), ntohl (mp->vni),
12031          ntohl (mp->mcast_sw_if_index));
12032 }
12033
12034 static void vl_api_geneve_tunnel_details_t_handler_json
12035   (vl_api_geneve_tunnel_details_t * mp)
12036 {
12037   vat_main_t *vam = &vat_main;
12038   vat_json_node_t *node = NULL;
12039   bool is_ipv6;
12040
12041   if (VAT_JSON_ARRAY != vam->json_tree.type)
12042     {
12043       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12044       vat_json_init_array (&vam->json_tree);
12045     }
12046   node = vat_json_array_add (&vam->json_tree);
12047
12048   vat_json_init_object (node);
12049   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12050   is_ipv6 = mp->src_address.af == ADDRESS_IP6;
12051   if (is_ipv6)
12052     {
12053       struct in6_addr ip6;
12054
12055       clib_memcpy (&ip6, &mp->src_address.un.ip6, sizeof (ip6));
12056       vat_json_object_add_ip6 (node, "src_address", ip6);
12057       clib_memcpy (&ip6, &mp->dst_address.un.ip6, sizeof (ip6));
12058       vat_json_object_add_ip6 (node, "dst_address", ip6);
12059     }
12060   else
12061     {
12062       struct in_addr ip4;
12063
12064       clib_memcpy (&ip4, &mp->src_address.un.ip4, sizeof (ip4));
12065       vat_json_object_add_ip4 (node, "src_address", ip4);
12066       clib_memcpy (&ip4, &mp->dst_address.un.ip4, sizeof (ip4));
12067       vat_json_object_add_ip4 (node, "dst_address", ip4);
12068     }
12069   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
12070   vat_json_object_add_uint (node, "decap_next_index",
12071                             ntohl (mp->decap_next_index));
12072   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
12073   vat_json_object_add_uint (node, "mcast_sw_if_index",
12074                             ntohl (mp->mcast_sw_if_index));
12075 }
12076
12077 static int
12078 api_geneve_tunnel_dump (vat_main_t * vam)
12079 {
12080   unformat_input_t *i = vam->input;
12081   vl_api_geneve_tunnel_dump_t *mp;
12082   vl_api_control_ping_t *mp_ping;
12083   u32 sw_if_index;
12084   u8 sw_if_index_set = 0;
12085   int ret;
12086
12087   /* Parse args required to build the message */
12088   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12089     {
12090       if (unformat (i, "sw_if_index %d", &sw_if_index))
12091         sw_if_index_set = 1;
12092       else
12093         break;
12094     }
12095
12096   if (sw_if_index_set == 0)
12097     {
12098       sw_if_index = ~0;
12099     }
12100
12101   if (!vam->json_output)
12102     {
12103       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
12104              "sw_if_index", "local_address", "remote_address",
12105              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
12106     }
12107
12108   /* Get list of geneve-tunnel interfaces */
12109   M (GENEVE_TUNNEL_DUMP, mp);
12110
12111   mp->sw_if_index = htonl (sw_if_index);
12112
12113   S (mp);
12114
12115   /* Use a control ping for synchronization */
12116   M (CONTROL_PING, mp_ping);
12117   S (mp_ping);
12118
12119   W (ret);
12120   return ret;
12121 }
12122
12123 static int
12124 api_gre_tunnel_add_del (vat_main_t * vam)
12125 {
12126   unformat_input_t *line_input = vam->input;
12127   vl_api_address_t src = { }, dst =
12128   {
12129   };
12130   vl_api_gre_tunnel_add_del_t *mp;
12131   vl_api_gre_tunnel_type_t t_type;
12132   u8 is_add = 1;
12133   u8 src_set = 0;
12134   u8 dst_set = 0;
12135   u32 outer_table_id = 0;
12136   u32 session_id = 0;
12137   u32 instance = ~0;
12138   int ret;
12139
12140   t_type = GRE_API_TUNNEL_TYPE_L3;
12141
12142   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12143     {
12144       if (unformat (line_input, "del"))
12145         is_add = 0;
12146       else if (unformat (line_input, "instance %d", &instance))
12147         ;
12148       else if (unformat (line_input, "src %U", unformat_vl_api_address, &src))
12149         {
12150           src_set = 1;
12151         }
12152       else if (unformat (line_input, "dst %U", unformat_vl_api_address, &dst))
12153         {
12154           dst_set = 1;
12155         }
12156       else if (unformat (line_input, "outer-table-id %d", &outer_table_id))
12157         ;
12158       else if (unformat (line_input, "teb"))
12159         t_type = GRE_API_TUNNEL_TYPE_TEB;
12160       else if (unformat (line_input, "erspan %d", &session_id))
12161         t_type = GRE_API_TUNNEL_TYPE_ERSPAN;
12162       else
12163         {
12164           errmsg ("parse error '%U'", format_unformat_error, line_input);
12165           return -99;
12166         }
12167     }
12168
12169   if (src_set == 0)
12170     {
12171       errmsg ("tunnel src address not specified");
12172       return -99;
12173     }
12174   if (dst_set == 0)
12175     {
12176       errmsg ("tunnel dst address not specified");
12177       return -99;
12178     }
12179
12180   M (GRE_TUNNEL_ADD_DEL, mp);
12181
12182   clib_memcpy (&mp->tunnel.src, &src, sizeof (mp->tunnel.src));
12183   clib_memcpy (&mp->tunnel.dst, &dst, sizeof (mp->tunnel.dst));
12184
12185   mp->tunnel.instance = htonl (instance);
12186   mp->tunnel.outer_table_id = htonl (outer_table_id);
12187   mp->is_add = is_add;
12188   mp->tunnel.session_id = htons ((u16) session_id);
12189   mp->tunnel.type = htonl (t_type);
12190
12191   S (mp);
12192   W (ret);
12193   return ret;
12194 }
12195
12196 static void vl_api_gre_tunnel_details_t_handler
12197   (vl_api_gre_tunnel_details_t * mp)
12198 {
12199   vat_main_t *vam = &vat_main;
12200
12201   print (vam->ofp, "%11d%11d%24U%24U%13d%14d%12d",
12202          ntohl (mp->tunnel.sw_if_index),
12203          ntohl (mp->tunnel.instance),
12204          format_vl_api_address, &mp->tunnel.src,
12205          format_vl_api_address, &mp->tunnel.dst,
12206          mp->tunnel.type, ntohl (mp->tunnel.outer_table_id),
12207          ntohl (mp->tunnel.session_id));
12208 }
12209
12210 static void vl_api_gre_tunnel_details_t_handler_json
12211   (vl_api_gre_tunnel_details_t * mp)
12212 {
12213   vat_main_t *vam = &vat_main;
12214   vat_json_node_t *node = NULL;
12215
12216   if (VAT_JSON_ARRAY != vam->json_tree.type)
12217     {
12218       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12219       vat_json_init_array (&vam->json_tree);
12220     }
12221   node = vat_json_array_add (&vam->json_tree);
12222
12223   vat_json_init_object (node);
12224   vat_json_object_add_uint (node, "sw_if_index",
12225                             ntohl (mp->tunnel.sw_if_index));
12226   vat_json_object_add_uint (node, "instance", ntohl (mp->tunnel.instance));
12227
12228   vat_json_object_add_address (node, "src", &mp->tunnel.src);
12229   vat_json_object_add_address (node, "dst", &mp->tunnel.dst);
12230   vat_json_object_add_uint (node, "tunnel_type", mp->tunnel.type);
12231   vat_json_object_add_uint (node, "outer_table_id",
12232                             ntohl (mp->tunnel.outer_table_id));
12233   vat_json_object_add_uint (node, "session_id", mp->tunnel.session_id);
12234 }
12235
12236 static int
12237 api_gre_tunnel_dump (vat_main_t * vam)
12238 {
12239   unformat_input_t *i = vam->input;
12240   vl_api_gre_tunnel_dump_t *mp;
12241   vl_api_control_ping_t *mp_ping;
12242   u32 sw_if_index;
12243   u8 sw_if_index_set = 0;
12244   int ret;
12245
12246   /* Parse args required to build the message */
12247   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12248     {
12249       if (unformat (i, "sw_if_index %d", &sw_if_index))
12250         sw_if_index_set = 1;
12251       else
12252         break;
12253     }
12254
12255   if (sw_if_index_set == 0)
12256     {
12257       sw_if_index = ~0;
12258     }
12259
12260   if (!vam->json_output)
12261     {
12262       print (vam->ofp, "%11s%11s%24s%24s%13s%14s%12s",
12263              "sw_if_index", "instance", "src_address", "dst_address",
12264              "tunnel_type", "outer_fib_id", "session_id");
12265     }
12266
12267   /* Get list of gre-tunnel interfaces */
12268   M (GRE_TUNNEL_DUMP, mp);
12269
12270   mp->sw_if_index = htonl (sw_if_index);
12271
12272   S (mp);
12273
12274   /* Use a control ping for synchronization */
12275   MPING (CONTROL_PING, mp_ping);
12276   S (mp_ping);
12277
12278   W (ret);
12279   return ret;
12280 }
12281
12282 static int
12283 api_l2_fib_clear_table (vat_main_t * vam)
12284 {
12285 //  unformat_input_t * i = vam->input;
12286   vl_api_l2_fib_clear_table_t *mp;
12287   int ret;
12288
12289   M (L2_FIB_CLEAR_TABLE, mp);
12290
12291   S (mp);
12292   W (ret);
12293   return ret;
12294 }
12295
12296 static int
12297 api_l2_interface_efp_filter (vat_main_t * vam)
12298 {
12299   unformat_input_t *i = vam->input;
12300   vl_api_l2_interface_efp_filter_t *mp;
12301   u32 sw_if_index;
12302   u8 enable = 1;
12303   u8 sw_if_index_set = 0;
12304   int ret;
12305
12306   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12307     {
12308       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12309         sw_if_index_set = 1;
12310       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12311         sw_if_index_set = 1;
12312       else if (unformat (i, "enable"))
12313         enable = 1;
12314       else if (unformat (i, "disable"))
12315         enable = 0;
12316       else
12317         {
12318           clib_warning ("parse error '%U'", format_unformat_error, i);
12319           return -99;
12320         }
12321     }
12322
12323   if (sw_if_index_set == 0)
12324     {
12325       errmsg ("missing sw_if_index");
12326       return -99;
12327     }
12328
12329   M (L2_INTERFACE_EFP_FILTER, mp);
12330
12331   mp->sw_if_index = ntohl (sw_if_index);
12332   mp->enable_disable = enable;
12333
12334   S (mp);
12335   W (ret);
12336   return ret;
12337 }
12338
12339 #define foreach_vtr_op                          \
12340 _("disable",  L2_VTR_DISABLED)                  \
12341 _("push-1",  L2_VTR_PUSH_1)                     \
12342 _("push-2",  L2_VTR_PUSH_2)                     \
12343 _("pop-1",  L2_VTR_POP_1)                       \
12344 _("pop-2",  L2_VTR_POP_2)                       \
12345 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
12346 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
12347 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
12348 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
12349
12350 static int
12351 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
12352 {
12353   unformat_input_t *i = vam->input;
12354   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
12355   u32 sw_if_index;
12356   u8 sw_if_index_set = 0;
12357   u8 vtr_op_set = 0;
12358   u32 vtr_op = 0;
12359   u32 push_dot1q = 1;
12360   u32 tag1 = ~0;
12361   u32 tag2 = ~0;
12362   int ret;
12363
12364   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12365     {
12366       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12367         sw_if_index_set = 1;
12368       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12369         sw_if_index_set = 1;
12370       else if (unformat (i, "vtr_op %d", &vtr_op))
12371         vtr_op_set = 1;
12372 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
12373       foreach_vtr_op
12374 #undef _
12375         else if (unformat (i, "push_dot1q %d", &push_dot1q))
12376         ;
12377       else if (unformat (i, "tag1 %d", &tag1))
12378         ;
12379       else if (unformat (i, "tag2 %d", &tag2))
12380         ;
12381       else
12382         {
12383           clib_warning ("parse error '%U'", format_unformat_error, i);
12384           return -99;
12385         }
12386     }
12387
12388   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
12389     {
12390       errmsg ("missing vtr operation or sw_if_index");
12391       return -99;
12392     }
12393
12394   M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
12395   mp->sw_if_index = ntohl (sw_if_index);
12396   mp->vtr_op = ntohl (vtr_op);
12397   mp->push_dot1q = ntohl (push_dot1q);
12398   mp->tag1 = ntohl (tag1);
12399   mp->tag2 = ntohl (tag2);
12400
12401   S (mp);
12402   W (ret);
12403   return ret;
12404 }
12405
12406 static int
12407 api_create_vhost_user_if (vat_main_t * vam)
12408 {
12409   unformat_input_t *i = vam->input;
12410   vl_api_create_vhost_user_if_t *mp;
12411   u8 *file_name;
12412   u8 is_server = 0;
12413   u8 file_name_set = 0;
12414   u32 custom_dev_instance = ~0;
12415   u8 hwaddr[6];
12416   u8 use_custom_mac = 0;
12417   u8 disable_mrg_rxbuf = 0;
12418   u8 disable_indirect_desc = 0;
12419   u8 *tag = 0;
12420   u8 enable_gso = 0;
12421   int ret;
12422
12423   /* Shut up coverity */
12424   clib_memset (hwaddr, 0, sizeof (hwaddr));
12425
12426   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12427     {
12428       if (unformat (i, "socket %s", &file_name))
12429         {
12430           file_name_set = 1;
12431         }
12432       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
12433         ;
12434       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
12435         use_custom_mac = 1;
12436       else if (unformat (i, "server"))
12437         is_server = 1;
12438       else if (unformat (i, "disable_mrg_rxbuf"))
12439         disable_mrg_rxbuf = 1;
12440       else if (unformat (i, "disable_indirect_desc"))
12441         disable_indirect_desc = 1;
12442       else if (unformat (i, "gso"))
12443         enable_gso = 1;
12444       else if (unformat (i, "tag %s", &tag))
12445         ;
12446       else
12447         break;
12448     }
12449
12450   if (file_name_set == 0)
12451     {
12452       errmsg ("missing socket file name");
12453       return -99;
12454     }
12455
12456   if (vec_len (file_name) > 255)
12457     {
12458       errmsg ("socket file name too long");
12459       return -99;
12460     }
12461   vec_add1 (file_name, 0);
12462
12463   M (CREATE_VHOST_USER_IF, mp);
12464
12465   mp->is_server = is_server;
12466   mp->disable_mrg_rxbuf = disable_mrg_rxbuf;
12467   mp->disable_indirect_desc = disable_indirect_desc;
12468   mp->enable_gso = enable_gso;
12469   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
12470   vec_free (file_name);
12471   if (custom_dev_instance != ~0)
12472     {
12473       mp->renumber = 1;
12474       mp->custom_dev_instance = ntohl (custom_dev_instance);
12475     }
12476
12477   mp->use_custom_mac = use_custom_mac;
12478   clib_memcpy (mp->mac_address, hwaddr, 6);
12479   if (tag)
12480     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
12481   vec_free (tag);
12482
12483   S (mp);
12484   W (ret);
12485   return ret;
12486 }
12487
12488 static int
12489 api_modify_vhost_user_if (vat_main_t * vam)
12490 {
12491   unformat_input_t *i = vam->input;
12492   vl_api_modify_vhost_user_if_t *mp;
12493   u8 *file_name;
12494   u8 is_server = 0;
12495   u8 file_name_set = 0;
12496   u32 custom_dev_instance = ~0;
12497   u8 sw_if_index_set = 0;
12498   u32 sw_if_index = (u32) ~ 0;
12499   u8 enable_gso = 0;
12500   int ret;
12501
12502   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12503     {
12504       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12505         sw_if_index_set = 1;
12506       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12507         sw_if_index_set = 1;
12508       else if (unformat (i, "socket %s", &file_name))
12509         {
12510           file_name_set = 1;
12511         }
12512       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
12513         ;
12514       else if (unformat (i, "server"))
12515         is_server = 1;
12516       else if (unformat (i, "gso"))
12517         enable_gso = 1;
12518       else
12519         break;
12520     }
12521
12522   if (sw_if_index_set == 0)
12523     {
12524       errmsg ("missing sw_if_index or interface name");
12525       return -99;
12526     }
12527
12528   if (file_name_set == 0)
12529     {
12530       errmsg ("missing socket file name");
12531       return -99;
12532     }
12533
12534   if (vec_len (file_name) > 255)
12535     {
12536       errmsg ("socket file name too long");
12537       return -99;
12538     }
12539   vec_add1 (file_name, 0);
12540
12541   M (MODIFY_VHOST_USER_IF, mp);
12542
12543   mp->sw_if_index = ntohl (sw_if_index);
12544   mp->is_server = is_server;
12545   mp->enable_gso = enable_gso;
12546   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
12547   vec_free (file_name);
12548   if (custom_dev_instance != ~0)
12549     {
12550       mp->renumber = 1;
12551       mp->custom_dev_instance = ntohl (custom_dev_instance);
12552     }
12553
12554   S (mp);
12555   W (ret);
12556   return ret;
12557 }
12558
12559 static int
12560 api_delete_vhost_user_if (vat_main_t * vam)
12561 {
12562   unformat_input_t *i = vam->input;
12563   vl_api_delete_vhost_user_if_t *mp;
12564   u32 sw_if_index = ~0;
12565   u8 sw_if_index_set = 0;
12566   int ret;
12567
12568   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12569     {
12570       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12571         sw_if_index_set = 1;
12572       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12573         sw_if_index_set = 1;
12574       else
12575         break;
12576     }
12577
12578   if (sw_if_index_set == 0)
12579     {
12580       errmsg ("missing sw_if_index or interface name");
12581       return -99;
12582     }
12583
12584
12585   M (DELETE_VHOST_USER_IF, mp);
12586
12587   mp->sw_if_index = ntohl (sw_if_index);
12588
12589   S (mp);
12590   W (ret);
12591   return ret;
12592 }
12593
12594 static void vl_api_sw_interface_vhost_user_details_t_handler
12595   (vl_api_sw_interface_vhost_user_details_t * mp)
12596 {
12597   vat_main_t *vam = &vat_main;
12598   u64 features;
12599
12600   features =
12601     clib_net_to_host_u32 (mp->features_first_32) | ((u64)
12602                                                     clib_net_to_host_u32
12603                                                     (mp->features_last_32) <<
12604                                                     32);
12605
12606   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s",
12607          (char *) mp->interface_name,
12608          ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
12609          features, mp->is_server,
12610          ntohl (mp->num_regions), (char *) mp->sock_filename);
12611   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
12612 }
12613
12614 static void vl_api_sw_interface_vhost_user_details_t_handler_json
12615   (vl_api_sw_interface_vhost_user_details_t * mp)
12616 {
12617   vat_main_t *vam = &vat_main;
12618   vat_json_node_t *node = NULL;
12619
12620   if (VAT_JSON_ARRAY != vam->json_tree.type)
12621     {
12622       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12623       vat_json_init_array (&vam->json_tree);
12624     }
12625   node = vat_json_array_add (&vam->json_tree);
12626
12627   vat_json_init_object (node);
12628   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12629   vat_json_object_add_string_copy (node, "interface_name",
12630                                    mp->interface_name);
12631   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
12632                             ntohl (mp->virtio_net_hdr_sz));
12633   vat_json_object_add_uint (node, "features_first_32",
12634                             clib_net_to_host_u32 (mp->features_first_32));
12635   vat_json_object_add_uint (node, "features_last_32",
12636                             clib_net_to_host_u32 (mp->features_last_32));
12637   vat_json_object_add_uint (node, "is_server", mp->is_server);
12638   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
12639   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
12640   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
12641 }
12642
12643 static int
12644 api_sw_interface_vhost_user_dump (vat_main_t * vam)
12645 {
12646   vl_api_sw_interface_vhost_user_dump_t *mp;
12647   vl_api_control_ping_t *mp_ping;
12648   int ret;
12649   print (vam->ofp,
12650          "Interface name            idx hdr_sz features server regions filename");
12651
12652   /* Get list of vhost-user interfaces */
12653   M (SW_INTERFACE_VHOST_USER_DUMP, mp);
12654   mp->sw_if_index = ntohl (~0);
12655   S (mp);
12656
12657   /* Use a control ping for synchronization */
12658   MPING (CONTROL_PING, mp_ping);
12659   S (mp_ping);
12660
12661   W (ret);
12662   return ret;
12663 }
12664
12665 static int
12666 api_show_version (vat_main_t * vam)
12667 {
12668   vl_api_show_version_t *mp;
12669   int ret;
12670
12671   M (SHOW_VERSION, mp);
12672
12673   S (mp);
12674   W (ret);
12675   return ret;
12676 }
12677
12678
12679 static int
12680 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
12681 {
12682   unformat_input_t *line_input = vam->input;
12683   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
12684   ip4_address_t local4, remote4;
12685   ip6_address_t local6, remote6;
12686   u8 is_add = 1;
12687   u8 ipv4_set = 0, ipv6_set = 0;
12688   u8 local_set = 0;
12689   u8 remote_set = 0;
12690   u8 grp_set = 0;
12691   u32 mcast_sw_if_index = ~0;
12692   u32 encap_vrf_id = 0;
12693   u32 decap_vrf_id = 0;
12694   u8 protocol = ~0;
12695   u32 vni;
12696   u8 vni_set = 0;
12697   int ret;
12698
12699   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
12700   clib_memset (&local4, 0, sizeof local4);
12701   clib_memset (&remote4, 0, sizeof remote4);
12702   clib_memset (&local6, 0, sizeof local6);
12703   clib_memset (&remote6, 0, sizeof remote6);
12704
12705   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12706     {
12707       if (unformat (line_input, "del"))
12708         is_add = 0;
12709       else if (unformat (line_input, "local %U",
12710                          unformat_ip4_address, &local4))
12711         {
12712           local_set = 1;
12713           ipv4_set = 1;
12714         }
12715       else if (unformat (line_input, "remote %U",
12716                          unformat_ip4_address, &remote4))
12717         {
12718           remote_set = 1;
12719           ipv4_set = 1;
12720         }
12721       else if (unformat (line_input, "local %U",
12722                          unformat_ip6_address, &local6))
12723         {
12724           local_set = 1;
12725           ipv6_set = 1;
12726         }
12727       else if (unformat (line_input, "remote %U",
12728                          unformat_ip6_address, &remote6))
12729         {
12730           remote_set = 1;
12731           ipv6_set = 1;
12732         }
12733       else if (unformat (line_input, "group %U %U",
12734                          unformat_ip4_address, &remote4,
12735                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12736         {
12737           grp_set = remote_set = 1;
12738           ipv4_set = 1;
12739         }
12740       else if (unformat (line_input, "group %U",
12741                          unformat_ip4_address, &remote4))
12742         {
12743           grp_set = remote_set = 1;
12744           ipv4_set = 1;
12745         }
12746       else if (unformat (line_input, "group %U %U",
12747                          unformat_ip6_address, &remote6,
12748                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12749         {
12750           grp_set = remote_set = 1;
12751           ipv6_set = 1;
12752         }
12753       else if (unformat (line_input, "group %U",
12754                          unformat_ip6_address, &remote6))
12755         {
12756           grp_set = remote_set = 1;
12757           ipv6_set = 1;
12758         }
12759       else
12760         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
12761         ;
12762       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
12763         ;
12764       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
12765         ;
12766       else if (unformat (line_input, "vni %d", &vni))
12767         vni_set = 1;
12768       else if (unformat (line_input, "next-ip4"))
12769         protocol = 1;
12770       else if (unformat (line_input, "next-ip6"))
12771         protocol = 2;
12772       else if (unformat (line_input, "next-ethernet"))
12773         protocol = 3;
12774       else if (unformat (line_input, "next-nsh"))
12775         protocol = 4;
12776       else
12777         {
12778           errmsg ("parse error '%U'", format_unformat_error, line_input);
12779           return -99;
12780         }
12781     }
12782
12783   if (local_set == 0)
12784     {
12785       errmsg ("tunnel local address not specified");
12786       return -99;
12787     }
12788   if (remote_set == 0)
12789     {
12790       errmsg ("tunnel remote address not specified");
12791       return -99;
12792     }
12793   if (grp_set && mcast_sw_if_index == ~0)
12794     {
12795       errmsg ("tunnel nonexistent multicast device");
12796       return -99;
12797     }
12798   if (ipv4_set && ipv6_set)
12799     {
12800       errmsg ("both IPv4 and IPv6 addresses specified");
12801       return -99;
12802     }
12803
12804   if (vni_set == 0)
12805     {
12806       errmsg ("vni not specified");
12807       return -99;
12808     }
12809
12810   M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
12811
12812
12813   if (ipv6_set)
12814     {
12815       clib_memcpy (&mp->local, &local6, sizeof (local6));
12816       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
12817     }
12818   else
12819     {
12820       clib_memcpy (&mp->local, &local4, sizeof (local4));
12821       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
12822     }
12823
12824   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
12825   mp->encap_vrf_id = ntohl (encap_vrf_id);
12826   mp->decap_vrf_id = ntohl (decap_vrf_id);
12827   mp->protocol = protocol;
12828   mp->vni = ntohl (vni);
12829   mp->is_add = is_add;
12830   mp->is_ipv6 = ipv6_set;
12831
12832   S (mp);
12833   W (ret);
12834   return ret;
12835 }
12836
12837 static void vl_api_vxlan_gpe_tunnel_details_t_handler
12838   (vl_api_vxlan_gpe_tunnel_details_t * mp)
12839 {
12840   vat_main_t *vam = &vat_main;
12841   ip46_address_t local = to_ip46 (mp->is_ipv6, mp->local);
12842   ip46_address_t remote = to_ip46 (mp->is_ipv6, mp->remote);
12843
12844   print (vam->ofp, "%11d%24U%24U%13d%12d%19d%14d%14d",
12845          ntohl (mp->sw_if_index),
12846          format_ip46_address, &local, IP46_TYPE_ANY,
12847          format_ip46_address, &remote, IP46_TYPE_ANY,
12848          ntohl (mp->vni), mp->protocol,
12849          ntohl (mp->mcast_sw_if_index),
12850          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
12851 }
12852
12853
12854 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
12855   (vl_api_vxlan_gpe_tunnel_details_t * mp)
12856 {
12857   vat_main_t *vam = &vat_main;
12858   vat_json_node_t *node = NULL;
12859   struct in_addr ip4;
12860   struct in6_addr ip6;
12861
12862   if (VAT_JSON_ARRAY != vam->json_tree.type)
12863     {
12864       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12865       vat_json_init_array (&vam->json_tree);
12866     }
12867   node = vat_json_array_add (&vam->json_tree);
12868
12869   vat_json_init_object (node);
12870   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12871   if (mp->is_ipv6)
12872     {
12873       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
12874       vat_json_object_add_ip6 (node, "local", ip6);
12875       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
12876       vat_json_object_add_ip6 (node, "remote", ip6);
12877     }
12878   else
12879     {
12880       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
12881       vat_json_object_add_ip4 (node, "local", ip4);
12882       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
12883       vat_json_object_add_ip4 (node, "remote", ip4);
12884     }
12885   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
12886   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
12887   vat_json_object_add_uint (node, "mcast_sw_if_index",
12888                             ntohl (mp->mcast_sw_if_index));
12889   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
12890   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
12891   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
12892 }
12893
12894 static int
12895 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
12896 {
12897   unformat_input_t *i = vam->input;
12898   vl_api_vxlan_gpe_tunnel_dump_t *mp;
12899   vl_api_control_ping_t *mp_ping;
12900   u32 sw_if_index;
12901   u8 sw_if_index_set = 0;
12902   int ret;
12903
12904   /* Parse args required to build the message */
12905   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12906     {
12907       if (unformat (i, "sw_if_index %d", &sw_if_index))
12908         sw_if_index_set = 1;
12909       else
12910         break;
12911     }
12912
12913   if (sw_if_index_set == 0)
12914     {
12915       sw_if_index = ~0;
12916     }
12917
12918   if (!vam->json_output)
12919     {
12920       print (vam->ofp, "%11s%24s%24s%13s%15s%19s%14s%14s",
12921              "sw_if_index", "local", "remote", "vni",
12922              "protocol", "mcast_sw_if_index", "encap_vrf_id", "decap_vrf_id");
12923     }
12924
12925   /* Get list of vxlan-tunnel interfaces */
12926   M (VXLAN_GPE_TUNNEL_DUMP, mp);
12927
12928   mp->sw_if_index = htonl (sw_if_index);
12929
12930   S (mp);
12931
12932   /* Use a control ping for synchronization */
12933   MPING (CONTROL_PING, mp_ping);
12934   S (mp_ping);
12935
12936   W (ret);
12937   return ret;
12938 }
12939
12940 static void vl_api_l2_fib_table_details_t_handler
12941   (vl_api_l2_fib_table_details_t * mp)
12942 {
12943   vat_main_t *vam = &vat_main;
12944
12945   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
12946          "       %d       %d     %d",
12947          ntohl (mp->bd_id), format_ethernet_address, mp->mac,
12948          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
12949          mp->bvi_mac);
12950 }
12951
12952 static void vl_api_l2_fib_table_details_t_handler_json
12953   (vl_api_l2_fib_table_details_t * mp)
12954 {
12955   vat_main_t *vam = &vat_main;
12956   vat_json_node_t *node = NULL;
12957
12958   if (VAT_JSON_ARRAY != vam->json_tree.type)
12959     {
12960       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12961       vat_json_init_array (&vam->json_tree);
12962     }
12963   node = vat_json_array_add (&vam->json_tree);
12964
12965   vat_json_init_object (node);
12966   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
12967   vat_json_object_add_bytes (node, "mac", mp->mac, 6);
12968   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12969   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
12970   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
12971   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
12972 }
12973
12974 static int
12975 api_l2_fib_table_dump (vat_main_t * vam)
12976 {
12977   unformat_input_t *i = vam->input;
12978   vl_api_l2_fib_table_dump_t *mp;
12979   vl_api_control_ping_t *mp_ping;
12980   u32 bd_id;
12981   u8 bd_id_set = 0;
12982   int ret;
12983
12984   /* Parse args required to build the message */
12985   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12986     {
12987       if (unformat (i, "bd_id %d", &bd_id))
12988         bd_id_set = 1;
12989       else
12990         break;
12991     }
12992
12993   if (bd_id_set == 0)
12994     {
12995       errmsg ("missing bridge domain");
12996       return -99;
12997     }
12998
12999   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
13000
13001   /* Get list of l2 fib entries */
13002   M (L2_FIB_TABLE_DUMP, mp);
13003
13004   mp->bd_id = ntohl (bd_id);
13005   S (mp);
13006
13007   /* Use a control ping for synchronization */
13008   MPING (CONTROL_PING, mp_ping);
13009   S (mp_ping);
13010
13011   W (ret);
13012   return ret;
13013 }
13014
13015
13016 static int
13017 api_interface_name_renumber (vat_main_t * vam)
13018 {
13019   unformat_input_t *line_input = vam->input;
13020   vl_api_interface_name_renumber_t *mp;
13021   u32 sw_if_index = ~0;
13022   u32 new_show_dev_instance = ~0;
13023   int ret;
13024
13025   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13026     {
13027       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
13028                     &sw_if_index))
13029         ;
13030       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
13031         ;
13032       else if (unformat (line_input, "new_show_dev_instance %d",
13033                          &new_show_dev_instance))
13034         ;
13035       else
13036         break;
13037     }
13038
13039   if (sw_if_index == ~0)
13040     {
13041       errmsg ("missing interface name or sw_if_index");
13042       return -99;
13043     }
13044
13045   if (new_show_dev_instance == ~0)
13046     {
13047       errmsg ("missing new_show_dev_instance");
13048       return -99;
13049     }
13050
13051   M (INTERFACE_NAME_RENUMBER, mp);
13052
13053   mp->sw_if_index = ntohl (sw_if_index);
13054   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
13055
13056   S (mp);
13057   W (ret);
13058   return ret;
13059 }
13060
13061 static int
13062 api_want_l2_macs_events (vat_main_t * vam)
13063 {
13064   unformat_input_t *line_input = vam->input;
13065   vl_api_want_l2_macs_events_t *mp;
13066   u8 enable_disable = 1;
13067   u32 scan_delay = 0;
13068   u32 max_macs_in_event = 0;
13069   u32 learn_limit = 0;
13070   int ret;
13071
13072   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13073     {
13074       if (unformat (line_input, "learn-limit %d", &learn_limit))
13075         ;
13076       else if (unformat (line_input, "scan-delay %d", &scan_delay))
13077         ;
13078       else if (unformat (line_input, "max-entries %d", &max_macs_in_event))
13079         ;
13080       else if (unformat (line_input, "disable"))
13081         enable_disable = 0;
13082       else
13083         break;
13084     }
13085
13086   M (WANT_L2_MACS_EVENTS, mp);
13087   mp->enable_disable = enable_disable;
13088   mp->pid = htonl (getpid ());
13089   mp->learn_limit = htonl (learn_limit);
13090   mp->scan_delay = (u8) scan_delay;
13091   mp->max_macs_in_event = (u8) (max_macs_in_event / 10);
13092   S (mp);
13093   W (ret);
13094   return ret;
13095 }
13096
13097 static int
13098 api_input_acl_set_interface (vat_main_t * vam)
13099 {
13100   unformat_input_t *i = vam->input;
13101   vl_api_input_acl_set_interface_t *mp;
13102   u32 sw_if_index;
13103   int sw_if_index_set;
13104   u32 ip4_table_index = ~0;
13105   u32 ip6_table_index = ~0;
13106   u32 l2_table_index = ~0;
13107   u8 is_add = 1;
13108   int ret;
13109
13110   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13111     {
13112       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13113         sw_if_index_set = 1;
13114       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13115         sw_if_index_set = 1;
13116       else if (unformat (i, "del"))
13117         is_add = 0;
13118       else if (unformat (i, "ip4-table %d", &ip4_table_index))
13119         ;
13120       else if (unformat (i, "ip6-table %d", &ip6_table_index))
13121         ;
13122       else if (unformat (i, "l2-table %d", &l2_table_index))
13123         ;
13124       else
13125         {
13126           clib_warning ("parse error '%U'", format_unformat_error, i);
13127           return -99;
13128         }
13129     }
13130
13131   if (sw_if_index_set == 0)
13132     {
13133       errmsg ("missing interface name or sw_if_index");
13134       return -99;
13135     }
13136
13137   M (INPUT_ACL_SET_INTERFACE, mp);
13138
13139   mp->sw_if_index = ntohl (sw_if_index);
13140   mp->ip4_table_index = ntohl (ip4_table_index);
13141   mp->ip6_table_index = ntohl (ip6_table_index);
13142   mp->l2_table_index = ntohl (l2_table_index);
13143   mp->is_add = is_add;
13144
13145   S (mp);
13146   W (ret);
13147   return ret;
13148 }
13149
13150 static int
13151 api_output_acl_set_interface (vat_main_t * vam)
13152 {
13153   unformat_input_t *i = vam->input;
13154   vl_api_output_acl_set_interface_t *mp;
13155   u32 sw_if_index;
13156   int sw_if_index_set;
13157   u32 ip4_table_index = ~0;
13158   u32 ip6_table_index = ~0;
13159   u32 l2_table_index = ~0;
13160   u8 is_add = 1;
13161   int ret;
13162
13163   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13164     {
13165       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13166         sw_if_index_set = 1;
13167       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13168         sw_if_index_set = 1;
13169       else if (unformat (i, "del"))
13170         is_add = 0;
13171       else if (unformat (i, "ip4-table %d", &ip4_table_index))
13172         ;
13173       else if (unformat (i, "ip6-table %d", &ip6_table_index))
13174         ;
13175       else if (unformat (i, "l2-table %d", &l2_table_index))
13176         ;
13177       else
13178         {
13179           clib_warning ("parse error '%U'", format_unformat_error, i);
13180           return -99;
13181         }
13182     }
13183
13184   if (sw_if_index_set == 0)
13185     {
13186       errmsg ("missing interface name or sw_if_index");
13187       return -99;
13188     }
13189
13190   M (OUTPUT_ACL_SET_INTERFACE, mp);
13191
13192   mp->sw_if_index = ntohl (sw_if_index);
13193   mp->ip4_table_index = ntohl (ip4_table_index);
13194   mp->ip6_table_index = ntohl (ip6_table_index);
13195   mp->l2_table_index = ntohl (l2_table_index);
13196   mp->is_add = is_add;
13197
13198   S (mp);
13199   W (ret);
13200   return ret;
13201 }
13202
13203 static int
13204 api_ip_address_dump (vat_main_t * vam)
13205 {
13206   unformat_input_t *i = vam->input;
13207   vl_api_ip_address_dump_t *mp;
13208   vl_api_control_ping_t *mp_ping;
13209   u32 sw_if_index = ~0;
13210   u8 sw_if_index_set = 0;
13211   u8 ipv4_set = 0;
13212   u8 ipv6_set = 0;
13213   int ret;
13214
13215   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13216     {
13217       if (unformat (i, "sw_if_index %d", &sw_if_index))
13218         sw_if_index_set = 1;
13219       else
13220         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13221         sw_if_index_set = 1;
13222       else if (unformat (i, "ipv4"))
13223         ipv4_set = 1;
13224       else if (unformat (i, "ipv6"))
13225         ipv6_set = 1;
13226       else
13227         break;
13228     }
13229
13230   if (ipv4_set && ipv6_set)
13231     {
13232       errmsg ("ipv4 and ipv6 flags cannot be both set");
13233       return -99;
13234     }
13235
13236   if ((!ipv4_set) && (!ipv6_set))
13237     {
13238       errmsg ("no ipv4 nor ipv6 flag set");
13239       return -99;
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   vam->current_sw_if_index = sw_if_index;
13249   vam->is_ipv6 = ipv6_set;
13250
13251   M (IP_ADDRESS_DUMP, mp);
13252   mp->sw_if_index = ntohl (sw_if_index);
13253   mp->is_ipv6 = ipv6_set;
13254   S (mp);
13255
13256   /* Use a control ping for synchronization */
13257   MPING (CONTROL_PING, mp_ping);
13258   S (mp_ping);
13259
13260   W (ret);
13261   return ret;
13262 }
13263
13264 static int
13265 api_ip_dump (vat_main_t * vam)
13266 {
13267   vl_api_ip_dump_t *mp;
13268   vl_api_control_ping_t *mp_ping;
13269   unformat_input_t *in = vam->input;
13270   int ipv4_set = 0;
13271   int ipv6_set = 0;
13272   int is_ipv6;
13273   int i;
13274   int ret;
13275
13276   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
13277     {
13278       if (unformat (in, "ipv4"))
13279         ipv4_set = 1;
13280       else if (unformat (in, "ipv6"))
13281         ipv6_set = 1;
13282       else
13283         break;
13284     }
13285
13286   if (ipv4_set && ipv6_set)
13287     {
13288       errmsg ("ipv4 and ipv6 flags cannot be both set");
13289       return -99;
13290     }
13291
13292   if ((!ipv4_set) && (!ipv6_set))
13293     {
13294       errmsg ("no ipv4 nor ipv6 flag set");
13295       return -99;
13296     }
13297
13298   is_ipv6 = ipv6_set;
13299   vam->is_ipv6 = is_ipv6;
13300
13301   /* free old data */
13302   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
13303     {
13304       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
13305     }
13306   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
13307
13308   M (IP_DUMP, mp);
13309   mp->is_ipv6 = ipv6_set;
13310   S (mp);
13311
13312   /* Use a control ping for synchronization */
13313   MPING (CONTROL_PING, mp_ping);
13314   S (mp_ping);
13315
13316   W (ret);
13317   return ret;
13318 }
13319
13320 static int
13321 api_ipsec_spd_add_del (vat_main_t * vam)
13322 {
13323   unformat_input_t *i = vam->input;
13324   vl_api_ipsec_spd_add_del_t *mp;
13325   u32 spd_id = ~0;
13326   u8 is_add = 1;
13327   int ret;
13328
13329   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13330     {
13331       if (unformat (i, "spd_id %d", &spd_id))
13332         ;
13333       else if (unformat (i, "del"))
13334         is_add = 0;
13335       else
13336         {
13337           clib_warning ("parse error '%U'", format_unformat_error, i);
13338           return -99;
13339         }
13340     }
13341   if (spd_id == ~0)
13342     {
13343       errmsg ("spd_id must be set");
13344       return -99;
13345     }
13346
13347   M (IPSEC_SPD_ADD_DEL, mp);
13348
13349   mp->spd_id = ntohl (spd_id);
13350   mp->is_add = is_add;
13351
13352   S (mp);
13353   W (ret);
13354   return ret;
13355 }
13356
13357 static int
13358 api_ipsec_interface_add_del_spd (vat_main_t * vam)
13359 {
13360   unformat_input_t *i = vam->input;
13361   vl_api_ipsec_interface_add_del_spd_t *mp;
13362   u32 sw_if_index;
13363   u8 sw_if_index_set = 0;
13364   u32 spd_id = (u32) ~ 0;
13365   u8 is_add = 1;
13366   int ret;
13367
13368   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13369     {
13370       if (unformat (i, "del"))
13371         is_add = 0;
13372       else if (unformat (i, "spd_id %d", &spd_id))
13373         ;
13374       else
13375         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13376         sw_if_index_set = 1;
13377       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13378         sw_if_index_set = 1;
13379       else
13380         {
13381           clib_warning ("parse error '%U'", format_unformat_error, i);
13382           return -99;
13383         }
13384
13385     }
13386
13387   if (spd_id == (u32) ~ 0)
13388     {
13389       errmsg ("spd_id must be set");
13390       return -99;
13391     }
13392
13393   if (sw_if_index_set == 0)
13394     {
13395       errmsg ("missing interface name or sw_if_index");
13396       return -99;
13397     }
13398
13399   M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
13400
13401   mp->spd_id = ntohl (spd_id);
13402   mp->sw_if_index = ntohl (sw_if_index);
13403   mp->is_add = is_add;
13404
13405   S (mp);
13406   W (ret);
13407   return ret;
13408 }
13409
13410 static int
13411 api_ipsec_spd_entry_add_del (vat_main_t * vam)
13412 {
13413   unformat_input_t *i = vam->input;
13414   vl_api_ipsec_spd_entry_add_del_t *mp;
13415   u8 is_add = 1, is_outbound = 0;
13416   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
13417   i32 priority = 0;
13418   u32 rport_start = 0, rport_stop = (u32) ~ 0;
13419   u32 lport_start = 0, lport_stop = (u32) ~ 0;
13420   vl_api_address_t laddr_start = { }, laddr_stop =
13421   {
13422   }, raddr_start =
13423   {
13424   }, raddr_stop =
13425   {
13426   };
13427   int ret;
13428
13429   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13430     {
13431       if (unformat (i, "del"))
13432         is_add = 0;
13433       if (unformat (i, "outbound"))
13434         is_outbound = 1;
13435       if (unformat (i, "inbound"))
13436         is_outbound = 0;
13437       else if (unformat (i, "spd_id %d", &spd_id))
13438         ;
13439       else if (unformat (i, "sa_id %d", &sa_id))
13440         ;
13441       else if (unformat (i, "priority %d", &priority))
13442         ;
13443       else if (unformat (i, "protocol %d", &protocol))
13444         ;
13445       else if (unformat (i, "lport_start %d", &lport_start))
13446         ;
13447       else if (unformat (i, "lport_stop %d", &lport_stop))
13448         ;
13449       else if (unformat (i, "rport_start %d", &rport_start))
13450         ;
13451       else if (unformat (i, "rport_stop %d", &rport_stop))
13452         ;
13453       else if (unformat (i, "laddr_start %U",
13454                          unformat_vl_api_address, &laddr_start))
13455         ;
13456       else if (unformat (i, "laddr_stop %U", unformat_vl_api_address,
13457                          &laddr_stop))
13458         ;
13459       else if (unformat (i, "raddr_start %U", unformat_vl_api_address,
13460                          &raddr_start))
13461         ;
13462       else if (unformat (i, "raddr_stop %U", unformat_vl_api_address,
13463                          &raddr_stop))
13464         ;
13465       else
13466         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
13467         {
13468           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
13469             {
13470               clib_warning ("unsupported action: 'resolve'");
13471               return -99;
13472             }
13473         }
13474       else
13475         {
13476           clib_warning ("parse error '%U'", format_unformat_error, i);
13477           return -99;
13478         }
13479
13480     }
13481
13482   M (IPSEC_SPD_ENTRY_ADD_DEL, mp);
13483
13484   mp->is_add = is_add;
13485
13486   mp->entry.spd_id = ntohl (spd_id);
13487   mp->entry.priority = ntohl (priority);
13488   mp->entry.is_outbound = is_outbound;
13489
13490   clib_memcpy (&mp->entry.remote_address_start, &raddr_start,
13491                sizeof (vl_api_address_t));
13492   clib_memcpy (&mp->entry.remote_address_stop, &raddr_stop,
13493                sizeof (vl_api_address_t));
13494   clib_memcpy (&mp->entry.local_address_start, &laddr_start,
13495                sizeof (vl_api_address_t));
13496   clib_memcpy (&mp->entry.local_address_stop, &laddr_stop,
13497                sizeof (vl_api_address_t));
13498
13499   mp->entry.protocol = (u8) protocol;
13500   mp->entry.local_port_start = ntohs ((u16) lport_start);
13501   mp->entry.local_port_stop = ntohs ((u16) lport_stop);
13502   mp->entry.remote_port_start = ntohs ((u16) rport_start);
13503   mp->entry.remote_port_stop = ntohs ((u16) rport_stop);
13504   mp->entry.policy = (u8) policy;
13505   mp->entry.sa_id = ntohl (sa_id);
13506
13507   S (mp);
13508   W (ret);
13509   return ret;
13510 }
13511
13512 static int
13513 api_ipsec_sad_entry_add_del (vat_main_t * vam)
13514 {
13515   unformat_input_t *i = vam->input;
13516   vl_api_ipsec_sad_entry_add_del_t *mp;
13517   u32 sad_id = 0, spi = 0;
13518   u8 *ck = 0, *ik = 0;
13519   u8 is_add = 1;
13520
13521   vl_api_ipsec_crypto_alg_t crypto_alg = IPSEC_API_CRYPTO_ALG_NONE;
13522   vl_api_ipsec_integ_alg_t integ_alg = IPSEC_API_INTEG_ALG_NONE;
13523   vl_api_ipsec_sad_flags_t flags = IPSEC_API_SAD_FLAG_NONE;
13524   vl_api_ipsec_proto_t protocol = IPSEC_API_PROTO_AH;
13525   vl_api_address_t tun_src, tun_dst;
13526   int ret;
13527
13528   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13529     {
13530       if (unformat (i, "del"))
13531         is_add = 0;
13532       else if (unformat (i, "sad_id %d", &sad_id))
13533         ;
13534       else if (unformat (i, "spi %d", &spi))
13535         ;
13536       else if (unformat (i, "esp"))
13537         protocol = IPSEC_API_PROTO_ESP;
13538       else
13539         if (unformat (i, "tunnel_src %U", unformat_vl_api_address, &tun_src))
13540         {
13541           flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL;
13542           if (ADDRESS_IP6 == tun_src.af)
13543             flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL_V6;
13544         }
13545       else
13546         if (unformat (i, "tunnel_dst %U", unformat_vl_api_address, &tun_dst))
13547         {
13548           flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL;
13549           if (ADDRESS_IP6 == tun_src.af)
13550             flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL_V6;
13551         }
13552       else
13553         if (unformat (i, "crypto_alg %U",
13554                       unformat_ipsec_api_crypto_alg, &crypto_alg))
13555         ;
13556       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
13557         ;
13558       else if (unformat (i, "integ_alg %U",
13559                          unformat_ipsec_api_integ_alg, &integ_alg))
13560         ;
13561       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
13562         ;
13563       else
13564         {
13565           clib_warning ("parse error '%U'", format_unformat_error, i);
13566           return -99;
13567         }
13568
13569     }
13570
13571   M (IPSEC_SAD_ENTRY_ADD_DEL, mp);
13572
13573   mp->is_add = is_add;
13574   mp->entry.sad_id = ntohl (sad_id);
13575   mp->entry.protocol = protocol;
13576   mp->entry.spi = ntohl (spi);
13577   mp->entry.flags = flags;
13578
13579   mp->entry.crypto_algorithm = crypto_alg;
13580   mp->entry.integrity_algorithm = integ_alg;
13581   mp->entry.crypto_key.length = vec_len (ck);
13582   mp->entry.integrity_key.length = vec_len (ik);
13583
13584   if (mp->entry.crypto_key.length > sizeof (mp->entry.crypto_key.data))
13585     mp->entry.crypto_key.length = sizeof (mp->entry.crypto_key.data);
13586
13587   if (mp->entry.integrity_key.length > sizeof (mp->entry.integrity_key.data))
13588     mp->entry.integrity_key.length = sizeof (mp->entry.integrity_key.data);
13589
13590   if (ck)
13591     clib_memcpy (mp->entry.crypto_key.data, ck, mp->entry.crypto_key.length);
13592   if (ik)
13593     clib_memcpy (mp->entry.integrity_key.data, ik,
13594                  mp->entry.integrity_key.length);
13595
13596   if (flags & IPSEC_API_SAD_FLAG_IS_TUNNEL)
13597     {
13598       clib_memcpy (&mp->entry.tunnel_src, &tun_src,
13599                    sizeof (mp->entry.tunnel_src));
13600       clib_memcpy (&mp->entry.tunnel_dst, &tun_dst,
13601                    sizeof (mp->entry.tunnel_dst));
13602     }
13603
13604   S (mp);
13605   W (ret);
13606   return ret;
13607 }
13608
13609 static int
13610 api_ipsec_tunnel_if_add_del (vat_main_t * vam)
13611 {
13612   unformat_input_t *i = vam->input;
13613   vl_api_ipsec_tunnel_if_add_del_t *mp;
13614   u32 local_spi = 0, remote_spi = 0;
13615   u32 crypto_alg = 0, integ_alg = 0;
13616   u8 *lck = NULL, *rck = NULL;
13617   u8 *lik = NULL, *rik = NULL;
13618   vl_api_address_t local_ip = { 0 };
13619   vl_api_address_t remote_ip = { 0 };
13620   f64 before = 0;
13621   u8 is_add = 1;
13622   u8 esn = 0;
13623   u8 anti_replay = 0;
13624   u8 renumber = 0;
13625   u32 instance = ~0;
13626   u32 count = 1, jj;
13627   int ret = -1;
13628
13629   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13630     {
13631       if (unformat (i, "del"))
13632         is_add = 0;
13633       else if (unformat (i, "esn"))
13634         esn = 1;
13635       else if (unformat (i, "anti-replay"))
13636         anti_replay = 1;
13637       else if (unformat (i, "count %d", &count))
13638         ;
13639       else if (unformat (i, "local_spi %d", &local_spi))
13640         ;
13641       else if (unformat (i, "remote_spi %d", &remote_spi))
13642         ;
13643       else
13644         if (unformat (i, "local_ip %U", unformat_vl_api_address, &local_ip))
13645         ;
13646       else
13647         if (unformat (i, "remote_ip %U", unformat_vl_api_address, &remote_ip))
13648         ;
13649       else if (unformat (i, "local_crypto_key %U", unformat_hex_string, &lck))
13650         ;
13651       else
13652         if (unformat (i, "remote_crypto_key %U", unformat_hex_string, &rck))
13653         ;
13654       else if (unformat (i, "local_integ_key %U", unformat_hex_string, &lik))
13655         ;
13656       else if (unformat (i, "remote_integ_key %U", unformat_hex_string, &rik))
13657         ;
13658       else
13659         if (unformat
13660             (i, "crypto_alg %U", unformat_ipsec_api_crypto_alg, &crypto_alg))
13661         {
13662           if (crypto_alg >= IPSEC_CRYPTO_N_ALG)
13663             {
13664               errmsg ("unsupported crypto-alg: '%U'\n",
13665                       format_ipsec_crypto_alg, crypto_alg);
13666               return -99;
13667             }
13668         }
13669       else
13670         if (unformat
13671             (i, "integ_alg %U", unformat_ipsec_api_integ_alg, &integ_alg))
13672         {
13673           if (integ_alg >= IPSEC_INTEG_N_ALG)
13674             {
13675               errmsg ("unsupported integ-alg: '%U'\n",
13676                       format_ipsec_integ_alg, integ_alg);
13677               return -99;
13678             }
13679         }
13680       else if (unformat (i, "instance %u", &instance))
13681         renumber = 1;
13682       else
13683         {
13684           errmsg ("parse error '%U'\n", format_unformat_error, i);
13685           return -99;
13686         }
13687     }
13688
13689   if (count > 1)
13690     {
13691       /* Turn on async mode */
13692       vam->async_mode = 1;
13693       vam->async_errors = 0;
13694       before = vat_time_now (vam);
13695     }
13696
13697   for (jj = 0; jj < count; jj++)
13698     {
13699       M (IPSEC_TUNNEL_IF_ADD_DEL, mp);
13700
13701       mp->is_add = is_add;
13702       mp->esn = esn;
13703       mp->anti_replay = anti_replay;
13704
13705       if (jj > 0)
13706         increment_address (&remote_ip);
13707
13708       clib_memcpy (&mp->local_ip, &local_ip, sizeof (local_ip));
13709       clib_memcpy (&mp->remote_ip, &remote_ip, sizeof (remote_ip));
13710
13711       mp->local_spi = htonl (local_spi + jj);
13712       mp->remote_spi = htonl (remote_spi + jj);
13713       mp->crypto_alg = (u8) crypto_alg;
13714
13715       mp->local_crypto_key_len = 0;
13716       if (lck)
13717         {
13718           mp->local_crypto_key_len = vec_len (lck);
13719           if (mp->local_crypto_key_len > sizeof (mp->local_crypto_key))
13720             mp->local_crypto_key_len = sizeof (mp->local_crypto_key);
13721           clib_memcpy (mp->local_crypto_key, lck, mp->local_crypto_key_len);
13722         }
13723
13724       mp->remote_crypto_key_len = 0;
13725       if (rck)
13726         {
13727           mp->remote_crypto_key_len = vec_len (rck);
13728           if (mp->remote_crypto_key_len > sizeof (mp->remote_crypto_key))
13729             mp->remote_crypto_key_len = sizeof (mp->remote_crypto_key);
13730           clib_memcpy (mp->remote_crypto_key, rck, mp->remote_crypto_key_len);
13731         }
13732
13733       mp->integ_alg = (u8) integ_alg;
13734
13735       mp->local_integ_key_len = 0;
13736       if (lik)
13737         {
13738           mp->local_integ_key_len = vec_len (lik);
13739           if (mp->local_integ_key_len > sizeof (mp->local_integ_key))
13740             mp->local_integ_key_len = sizeof (mp->local_integ_key);
13741           clib_memcpy (mp->local_integ_key, lik, mp->local_integ_key_len);
13742         }
13743
13744       mp->remote_integ_key_len = 0;
13745       if (rik)
13746         {
13747           mp->remote_integ_key_len = vec_len (rik);
13748           if (mp->remote_integ_key_len > sizeof (mp->remote_integ_key))
13749             mp->remote_integ_key_len = sizeof (mp->remote_integ_key);
13750           clib_memcpy (mp->remote_integ_key, rik, mp->remote_integ_key_len);
13751         }
13752
13753       if (renumber)
13754         {
13755           mp->renumber = renumber;
13756           mp->show_instance = ntohl (instance);
13757         }
13758       S (mp);
13759     }
13760
13761   /* When testing multiple add/del ops, use a control-ping to sync */
13762   if (count > 1)
13763     {
13764       vl_api_control_ping_t *mp_ping;
13765       f64 after;
13766       f64 timeout;
13767
13768       /* Shut off async mode */
13769       vam->async_mode = 0;
13770
13771       MPING (CONTROL_PING, mp_ping);
13772       S (mp_ping);
13773
13774       timeout = vat_time_now (vam) + 1.0;
13775       while (vat_time_now (vam) < timeout)
13776         if (vam->result_ready == 1)
13777           goto out;
13778       vam->retval = -99;
13779
13780     out:
13781       if (vam->retval == -99)
13782         errmsg ("timeout");
13783
13784       if (vam->async_errors > 0)
13785         {
13786           errmsg ("%d asynchronous errors", vam->async_errors);
13787           vam->retval = -98;
13788         }
13789       vam->async_errors = 0;
13790       after = vat_time_now (vam);
13791
13792       /* slim chance, but we might have eaten SIGTERM on the first iteration */
13793       if (jj > 0)
13794         count = jj;
13795
13796       print (vam->ofp, "%d tunnels in %.6f secs, %.2f tunnels/sec",
13797              count, after - before, count / (after - before));
13798     }
13799   else
13800     {
13801       /* Wait for a reply... */
13802       W (ret);
13803       return ret;
13804     }
13805
13806   return ret;
13807 }
13808
13809 static void
13810 vl_api_ipsec_sa_details_t_handler (vl_api_ipsec_sa_details_t * mp)
13811 {
13812   vat_main_t *vam = &vat_main;
13813
13814   print (vam->ofp, "sa_id %u sw_if_index %u spi %u proto %u crypto_alg %u "
13815          "crypto_key %U integ_alg %u integ_key %U flags %x "
13816          "tunnel_src_addr %U tunnel_dst_addr %U "
13817          "salt %u seq_outbound %lu last_seq_inbound %lu "
13818          "replay_window %lu\n",
13819          ntohl (mp->entry.sad_id),
13820          ntohl (mp->sw_if_index),
13821          ntohl (mp->entry.spi),
13822          ntohl (mp->entry.protocol),
13823          ntohl (mp->entry.crypto_algorithm),
13824          format_hex_bytes, mp->entry.crypto_key.data,
13825          mp->entry.crypto_key.length, ntohl (mp->entry.integrity_algorithm),
13826          format_hex_bytes, mp->entry.integrity_key.data,
13827          mp->entry.integrity_key.length, ntohl (mp->entry.flags),
13828          format_vl_api_address, &mp->entry.tunnel_src, format_vl_api_address,
13829          &mp->entry.tunnel_dst, ntohl (mp->salt),
13830          clib_net_to_host_u64 (mp->seq_outbound),
13831          clib_net_to_host_u64 (mp->last_seq_inbound),
13832          clib_net_to_host_u64 (mp->replay_window));
13833 }
13834
13835 #define vl_api_ipsec_sa_details_t_endian vl_noop_handler
13836 #define vl_api_ipsec_sa_details_t_print vl_noop_handler
13837
13838 static void vl_api_ipsec_sa_details_t_handler_json
13839   (vl_api_ipsec_sa_details_t * mp)
13840 {
13841   vat_main_t *vam = &vat_main;
13842   vat_json_node_t *node = NULL;
13843   vl_api_ipsec_sad_flags_t flags;
13844
13845   if (VAT_JSON_ARRAY != vam->json_tree.type)
13846     {
13847       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13848       vat_json_init_array (&vam->json_tree);
13849     }
13850   node = vat_json_array_add (&vam->json_tree);
13851
13852   vat_json_init_object (node);
13853   vat_json_object_add_uint (node, "sa_id", ntohl (mp->entry.sad_id));
13854   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13855   vat_json_object_add_uint (node, "spi", ntohl (mp->entry.spi));
13856   vat_json_object_add_uint (node, "proto", ntohl (mp->entry.protocol));
13857   vat_json_object_add_uint (node, "crypto_alg",
13858                             ntohl (mp->entry.crypto_algorithm));
13859   vat_json_object_add_uint (node, "integ_alg",
13860                             ntohl (mp->entry.integrity_algorithm));
13861   flags = ntohl (mp->entry.flags);
13862   vat_json_object_add_uint (node, "use_esn",
13863                             ! !(flags & IPSEC_API_SAD_FLAG_USE_ESN));
13864   vat_json_object_add_uint (node, "use_anti_replay",
13865                             ! !(flags & IPSEC_API_SAD_FLAG_USE_ANTI_REPLAY));
13866   vat_json_object_add_uint (node, "is_tunnel",
13867                             ! !(flags & IPSEC_API_SAD_FLAG_IS_TUNNEL));
13868   vat_json_object_add_uint (node, "is_tunnel_ip6",
13869                             ! !(flags & IPSEC_API_SAD_FLAG_IS_TUNNEL_V6));
13870   vat_json_object_add_uint (node, "udp_encap",
13871                             ! !(flags & IPSEC_API_SAD_FLAG_UDP_ENCAP));
13872   vat_json_object_add_bytes (node, "crypto_key", mp->entry.crypto_key.data,
13873                              mp->entry.crypto_key.length);
13874   vat_json_object_add_bytes (node, "integ_key", mp->entry.integrity_key.data,
13875                              mp->entry.integrity_key.length);
13876   vat_json_object_add_address (node, "src", &mp->entry.tunnel_src);
13877   vat_json_object_add_address (node, "dst", &mp->entry.tunnel_dst);
13878   vat_json_object_add_uint (node, "replay_window",
13879                             clib_net_to_host_u64 (mp->replay_window));
13880 }
13881
13882 static int
13883 api_ipsec_sa_dump (vat_main_t * vam)
13884 {
13885   unformat_input_t *i = vam->input;
13886   vl_api_ipsec_sa_dump_t *mp;
13887   vl_api_control_ping_t *mp_ping;
13888   u32 sa_id = ~0;
13889   int ret;
13890
13891   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13892     {
13893       if (unformat (i, "sa_id %d", &sa_id))
13894         ;
13895       else
13896         {
13897           clib_warning ("parse error '%U'", format_unformat_error, i);
13898           return -99;
13899         }
13900     }
13901
13902   M (IPSEC_SA_DUMP, mp);
13903
13904   mp->sa_id = ntohl (sa_id);
13905
13906   S (mp);
13907
13908   /* Use a control ping for synchronization */
13909   M (CONTROL_PING, mp_ping);
13910   S (mp_ping);
13911
13912   W (ret);
13913   return ret;
13914 }
13915
13916 static int
13917 api_ipsec_tunnel_if_set_sa (vat_main_t * vam)
13918 {
13919   unformat_input_t *i = vam->input;
13920   vl_api_ipsec_tunnel_if_set_sa_t *mp;
13921   u32 sw_if_index = ~0;
13922   u32 sa_id = ~0;
13923   u8 is_outbound = (u8) ~ 0;
13924   int ret;
13925
13926   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13927     {
13928       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13929         ;
13930       else if (unformat (i, "sa_id %d", &sa_id))
13931         ;
13932       else if (unformat (i, "outbound"))
13933         is_outbound = 1;
13934       else if (unformat (i, "inbound"))
13935         is_outbound = 0;
13936       else
13937         {
13938           clib_warning ("parse error '%U'", format_unformat_error, i);
13939           return -99;
13940         }
13941     }
13942
13943   if (sw_if_index == ~0)
13944     {
13945       errmsg ("interface must be specified");
13946       return -99;
13947     }
13948
13949   if (sa_id == ~0)
13950     {
13951       errmsg ("SA ID must be specified");
13952       return -99;
13953     }
13954
13955   M (IPSEC_TUNNEL_IF_SET_SA, mp);
13956
13957   mp->sw_if_index = htonl (sw_if_index);
13958   mp->sa_id = htonl (sa_id);
13959   mp->is_outbound = is_outbound;
13960
13961   S (mp);
13962   W (ret);
13963
13964   return ret;
13965 }
13966
13967 static int
13968 api_get_first_msg_id (vat_main_t * vam)
13969 {
13970   vl_api_get_first_msg_id_t *mp;
13971   unformat_input_t *i = vam->input;
13972   u8 *name;
13973   u8 name_set = 0;
13974   int ret;
13975
13976   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13977     {
13978       if (unformat (i, "client %s", &name))
13979         name_set = 1;
13980       else
13981         break;
13982     }
13983
13984   if (name_set == 0)
13985     {
13986       errmsg ("missing client name");
13987       return -99;
13988     }
13989   vec_add1 (name, 0);
13990
13991   if (vec_len (name) > 63)
13992     {
13993       errmsg ("client name too long");
13994       return -99;
13995     }
13996
13997   M (GET_FIRST_MSG_ID, mp);
13998   clib_memcpy (mp->name, name, vec_len (name));
13999   S (mp);
14000   W (ret);
14001   return ret;
14002 }
14003
14004 static int
14005 api_cop_interface_enable_disable (vat_main_t * vam)
14006 {
14007   unformat_input_t *line_input = vam->input;
14008   vl_api_cop_interface_enable_disable_t *mp;
14009   u32 sw_if_index = ~0;
14010   u8 enable_disable = 1;
14011   int ret;
14012
14013   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14014     {
14015       if (unformat (line_input, "disable"))
14016         enable_disable = 0;
14017       if (unformat (line_input, "enable"))
14018         enable_disable = 1;
14019       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
14020                          vam, &sw_if_index))
14021         ;
14022       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
14023         ;
14024       else
14025         break;
14026     }
14027
14028   if (sw_if_index == ~0)
14029     {
14030       errmsg ("missing interface name or sw_if_index");
14031       return -99;
14032     }
14033
14034   /* Construct the API message */
14035   M (COP_INTERFACE_ENABLE_DISABLE, mp);
14036   mp->sw_if_index = ntohl (sw_if_index);
14037   mp->enable_disable = enable_disable;
14038
14039   /* send it... */
14040   S (mp);
14041   /* Wait for the reply */
14042   W (ret);
14043   return ret;
14044 }
14045
14046 static int
14047 api_cop_whitelist_enable_disable (vat_main_t * vam)
14048 {
14049   unformat_input_t *line_input = vam->input;
14050   vl_api_cop_whitelist_enable_disable_t *mp;
14051   u32 sw_if_index = ~0;
14052   u8 ip4 = 0, ip6 = 0, default_cop = 0;
14053   u32 fib_id = 0;
14054   int ret;
14055
14056   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14057     {
14058       if (unformat (line_input, "ip4"))
14059         ip4 = 1;
14060       else if (unformat (line_input, "ip6"))
14061         ip6 = 1;
14062       else if (unformat (line_input, "default"))
14063         default_cop = 1;
14064       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
14065                          vam, &sw_if_index))
14066         ;
14067       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
14068         ;
14069       else if (unformat (line_input, "fib-id %d", &fib_id))
14070         ;
14071       else
14072         break;
14073     }
14074
14075   if (sw_if_index == ~0)
14076     {
14077       errmsg ("missing interface name or sw_if_index");
14078       return -99;
14079     }
14080
14081   /* Construct the API message */
14082   M (COP_WHITELIST_ENABLE_DISABLE, mp);
14083   mp->sw_if_index = ntohl (sw_if_index);
14084   mp->fib_id = ntohl (fib_id);
14085   mp->ip4 = ip4;
14086   mp->ip6 = ip6;
14087   mp->default_cop = default_cop;
14088
14089   /* send it... */
14090   S (mp);
14091   /* Wait for the reply */
14092   W (ret);
14093   return ret;
14094 }
14095
14096 static int
14097 api_get_node_graph (vat_main_t * vam)
14098 {
14099   vl_api_get_node_graph_t *mp;
14100   int ret;
14101
14102   M (GET_NODE_GRAPH, mp);
14103
14104   /* send it... */
14105   S (mp);
14106   /* Wait for the reply */
14107   W (ret);
14108   return ret;
14109 }
14110
14111 /* *INDENT-OFF* */
14112 /** Used for parsing LISP eids */
14113 typedef CLIB_PACKED(struct{
14114   u8 addr[16];   /**< eid address */
14115   u32 len;       /**< prefix length if IP */
14116   u8 type;      /**< type of eid */
14117 }) lisp_eid_vat_t;
14118 /* *INDENT-ON* */
14119
14120 static uword
14121 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
14122 {
14123   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
14124
14125   clib_memset (a, 0, sizeof (a[0]));
14126
14127   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
14128     {
14129       a->type = 0;              /* ipv4 type */
14130     }
14131   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
14132     {
14133       a->type = 1;              /* ipv6 type */
14134     }
14135   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
14136     {
14137       a->type = 2;              /* mac type */
14138     }
14139   else if (unformat (input, "%U", unformat_nsh_address, a->addr))
14140     {
14141       a->type = 3;              /* NSH type */
14142       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) a->addr;
14143       nsh->spi = clib_host_to_net_u32 (nsh->spi);
14144     }
14145   else
14146     {
14147       return 0;
14148     }
14149
14150   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
14151     {
14152       return 0;
14153     }
14154
14155   return 1;
14156 }
14157
14158 static int
14159 lisp_eid_size_vat (u8 type)
14160 {
14161   switch (type)
14162     {
14163     case 0:
14164       return 4;
14165     case 1:
14166       return 16;
14167     case 2:
14168       return 6;
14169     case 3:
14170       return 5;
14171     }
14172   return 0;
14173 }
14174
14175 static void
14176 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
14177 {
14178   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
14179 }
14180
14181 static int
14182 api_one_add_del_locator_set (vat_main_t * vam)
14183 {
14184   unformat_input_t *input = vam->input;
14185   vl_api_one_add_del_locator_set_t *mp;
14186   u8 is_add = 1;
14187   u8 *locator_set_name = NULL;
14188   u8 locator_set_name_set = 0;
14189   vl_api_local_locator_t locator, *locators = 0;
14190   u32 sw_if_index, priority, weight;
14191   u32 data_len = 0;
14192
14193   int ret;
14194   /* Parse args required to build the message */
14195   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14196     {
14197       if (unformat (input, "del"))
14198         {
14199           is_add = 0;
14200         }
14201       else if (unformat (input, "locator-set %s", &locator_set_name))
14202         {
14203           locator_set_name_set = 1;
14204         }
14205       else if (unformat (input, "sw_if_index %u p %u w %u",
14206                          &sw_if_index, &priority, &weight))
14207         {
14208           locator.sw_if_index = htonl (sw_if_index);
14209           locator.priority = priority;
14210           locator.weight = weight;
14211           vec_add1 (locators, locator);
14212         }
14213       else
14214         if (unformat
14215             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
14216              &sw_if_index, &priority, &weight))
14217         {
14218           locator.sw_if_index = htonl (sw_if_index);
14219           locator.priority = priority;
14220           locator.weight = weight;
14221           vec_add1 (locators, locator);
14222         }
14223       else
14224         break;
14225     }
14226
14227   if (locator_set_name_set == 0)
14228     {
14229       errmsg ("missing locator-set name");
14230       vec_free (locators);
14231       return -99;
14232     }
14233
14234   if (vec_len (locator_set_name) > 64)
14235     {
14236       errmsg ("locator-set name too long");
14237       vec_free (locator_set_name);
14238       vec_free (locators);
14239       return -99;
14240     }
14241   vec_add1 (locator_set_name, 0);
14242
14243   data_len = sizeof (vl_api_local_locator_t) * vec_len (locators);
14244
14245   /* Construct the API message */
14246   M2 (ONE_ADD_DEL_LOCATOR_SET, mp, data_len);
14247
14248   mp->is_add = is_add;
14249   clib_memcpy (mp->locator_set_name, locator_set_name,
14250                vec_len (locator_set_name));
14251   vec_free (locator_set_name);
14252
14253   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
14254   if (locators)
14255     clib_memcpy (mp->locators, locators, data_len);
14256   vec_free (locators);
14257
14258   /* send it... */
14259   S (mp);
14260
14261   /* Wait for a reply... */
14262   W (ret);
14263   return ret;
14264 }
14265
14266 #define api_lisp_add_del_locator_set api_one_add_del_locator_set
14267
14268 static int
14269 api_one_add_del_locator (vat_main_t * vam)
14270 {
14271   unformat_input_t *input = vam->input;
14272   vl_api_one_add_del_locator_t *mp;
14273   u32 tmp_if_index = ~0;
14274   u32 sw_if_index = ~0;
14275   u8 sw_if_index_set = 0;
14276   u8 sw_if_index_if_name_set = 0;
14277   u32 priority = ~0;
14278   u8 priority_set = 0;
14279   u32 weight = ~0;
14280   u8 weight_set = 0;
14281   u8 is_add = 1;
14282   u8 *locator_set_name = NULL;
14283   u8 locator_set_name_set = 0;
14284   int ret;
14285
14286   /* Parse args required to build the message */
14287   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14288     {
14289       if (unformat (input, "del"))
14290         {
14291           is_add = 0;
14292         }
14293       else if (unformat (input, "locator-set %s", &locator_set_name))
14294         {
14295           locator_set_name_set = 1;
14296         }
14297       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
14298                          &tmp_if_index))
14299         {
14300           sw_if_index_if_name_set = 1;
14301           sw_if_index = tmp_if_index;
14302         }
14303       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
14304         {
14305           sw_if_index_set = 1;
14306           sw_if_index = tmp_if_index;
14307         }
14308       else if (unformat (input, "p %d", &priority))
14309         {
14310           priority_set = 1;
14311         }
14312       else if (unformat (input, "w %d", &weight))
14313         {
14314           weight_set = 1;
14315         }
14316       else
14317         break;
14318     }
14319
14320   if (locator_set_name_set == 0)
14321     {
14322       errmsg ("missing locator-set name");
14323       return -99;
14324     }
14325
14326   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
14327     {
14328       errmsg ("missing sw_if_index");
14329       vec_free (locator_set_name);
14330       return -99;
14331     }
14332
14333   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
14334     {
14335       errmsg ("cannot use both params interface name and sw_if_index");
14336       vec_free (locator_set_name);
14337       return -99;
14338     }
14339
14340   if (priority_set == 0)
14341     {
14342       errmsg ("missing locator-set priority");
14343       vec_free (locator_set_name);
14344       return -99;
14345     }
14346
14347   if (weight_set == 0)
14348     {
14349       errmsg ("missing locator-set weight");
14350       vec_free (locator_set_name);
14351       return -99;
14352     }
14353
14354   if (vec_len (locator_set_name) > 64)
14355     {
14356       errmsg ("locator-set name too long");
14357       vec_free (locator_set_name);
14358       return -99;
14359     }
14360   vec_add1 (locator_set_name, 0);
14361
14362   /* Construct the API message */
14363   M (ONE_ADD_DEL_LOCATOR, mp);
14364
14365   mp->is_add = is_add;
14366   mp->sw_if_index = ntohl (sw_if_index);
14367   mp->priority = priority;
14368   mp->weight = weight;
14369   clib_memcpy (mp->locator_set_name, locator_set_name,
14370                vec_len (locator_set_name));
14371   vec_free (locator_set_name);
14372
14373   /* send it... */
14374   S (mp);
14375
14376   /* Wait for a reply... */
14377   W (ret);
14378   return ret;
14379 }
14380
14381 #define api_lisp_add_del_locator api_one_add_del_locator
14382
14383 uword
14384 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
14385 {
14386   u32 *key_id = va_arg (*args, u32 *);
14387   u8 *s = 0;
14388
14389   if (unformat (input, "%s", &s))
14390     {
14391       if (!strcmp ((char *) s, "sha1"))
14392         key_id[0] = HMAC_SHA_1_96;
14393       else if (!strcmp ((char *) s, "sha256"))
14394         key_id[0] = HMAC_SHA_256_128;
14395       else
14396         {
14397           clib_warning ("invalid key_id: '%s'", s);
14398           key_id[0] = HMAC_NO_KEY;
14399         }
14400     }
14401   else
14402     return 0;
14403
14404   vec_free (s);
14405   return 1;
14406 }
14407
14408 static int
14409 api_one_add_del_local_eid (vat_main_t * vam)
14410 {
14411   unformat_input_t *input = vam->input;
14412   vl_api_one_add_del_local_eid_t *mp;
14413   u8 is_add = 1;
14414   u8 eid_set = 0;
14415   lisp_eid_vat_t _eid, *eid = &_eid;
14416   u8 *locator_set_name = 0;
14417   u8 locator_set_name_set = 0;
14418   u32 vni = 0;
14419   u16 key_id = 0;
14420   u8 *key = 0;
14421   int ret;
14422
14423   /* Parse args required to build the message */
14424   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14425     {
14426       if (unformat (input, "del"))
14427         {
14428           is_add = 0;
14429         }
14430       else if (unformat (input, "vni %d", &vni))
14431         {
14432           ;
14433         }
14434       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
14435         {
14436           eid_set = 1;
14437         }
14438       else if (unformat (input, "locator-set %s", &locator_set_name))
14439         {
14440           locator_set_name_set = 1;
14441         }
14442       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
14443         ;
14444       else if (unformat (input, "secret-key %_%v%_", &key))
14445         ;
14446       else
14447         break;
14448     }
14449
14450   if (locator_set_name_set == 0)
14451     {
14452       errmsg ("missing locator-set name");
14453       return -99;
14454     }
14455
14456   if (0 == eid_set)
14457     {
14458       errmsg ("EID address not set!");
14459       vec_free (locator_set_name);
14460       return -99;
14461     }
14462
14463   if (key && (0 == key_id))
14464     {
14465       errmsg ("invalid key_id!");
14466       return -99;
14467     }
14468
14469   if (vec_len (key) > 64)
14470     {
14471       errmsg ("key too long");
14472       vec_free (key);
14473       return -99;
14474     }
14475
14476   if (vec_len (locator_set_name) > 64)
14477     {
14478       errmsg ("locator-set name too long");
14479       vec_free (locator_set_name);
14480       return -99;
14481     }
14482   vec_add1 (locator_set_name, 0);
14483
14484   /* Construct the API message */
14485   M (ONE_ADD_DEL_LOCAL_EID, mp);
14486
14487   mp->is_add = is_add;
14488   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
14489   mp->eid_type = eid->type;
14490   mp->prefix_len = eid->len;
14491   mp->vni = clib_host_to_net_u32 (vni);
14492   mp->key_id = clib_host_to_net_u16 (key_id);
14493   clib_memcpy (mp->locator_set_name, locator_set_name,
14494                vec_len (locator_set_name));
14495   clib_memcpy (mp->key, key, vec_len (key));
14496
14497   vec_free (locator_set_name);
14498   vec_free (key);
14499
14500   /* send it... */
14501   S (mp);
14502
14503   /* Wait for a reply... */
14504   W (ret);
14505   return ret;
14506 }
14507
14508 #define api_lisp_add_del_local_eid api_one_add_del_local_eid
14509
14510 static int
14511 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
14512 {
14513   u32 dp_table = 0, vni = 0;;
14514   unformat_input_t *input = vam->input;
14515   vl_api_gpe_add_del_fwd_entry_t *mp;
14516   u8 is_add = 1;
14517   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
14518   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
14519   u8 rmt_eid_set = 0, lcl_eid_set = 0;
14520   u32 action = ~0, w;
14521   ip4_address_t rmt_rloc4, lcl_rloc4;
14522   ip6_address_t rmt_rloc6, lcl_rloc6;
14523   vl_api_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
14524   int ret;
14525
14526   clib_memset (&rloc, 0, sizeof (rloc));
14527
14528   /* Parse args required to build the message */
14529   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14530     {
14531       if (unformat (input, "del"))
14532         is_add = 0;
14533       else if (unformat (input, "add"))
14534         is_add = 1;
14535       else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
14536         {
14537           rmt_eid_set = 1;
14538         }
14539       else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
14540         {
14541           lcl_eid_set = 1;
14542         }
14543       else if (unformat (input, "vrf %d", &dp_table))
14544         ;
14545       else if (unformat (input, "bd %d", &dp_table))
14546         ;
14547       else if (unformat (input, "vni %d", &vni))
14548         ;
14549       else if (unformat (input, "w %d", &w))
14550         {
14551           if (!curr_rloc)
14552             {
14553               errmsg ("No RLOC configured for setting priority/weight!");
14554               return -99;
14555             }
14556           curr_rloc->weight = w;
14557         }
14558       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
14559                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
14560         {
14561           rloc.is_ip4 = 1;
14562
14563           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
14564           rloc.weight = 0;
14565           vec_add1 (lcl_locs, rloc);
14566
14567           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
14568           vec_add1 (rmt_locs, rloc);
14569           /* weight saved in rmt loc */
14570           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
14571         }
14572       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
14573                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
14574         {
14575           rloc.is_ip4 = 0;
14576           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
14577           rloc.weight = 0;
14578           vec_add1 (lcl_locs, rloc);
14579
14580           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
14581           vec_add1 (rmt_locs, rloc);
14582           /* weight saved in rmt loc */
14583           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
14584         }
14585       else if (unformat (input, "action %d", &action))
14586         {
14587           ;
14588         }
14589       else
14590         {
14591           clib_warning ("parse error '%U'", format_unformat_error, input);
14592           return -99;
14593         }
14594     }
14595
14596   if (!rmt_eid_set)
14597     {
14598       errmsg ("remote eid addresses not set");
14599       return -99;
14600     }
14601
14602   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
14603     {
14604       errmsg ("eid types don't match");
14605       return -99;
14606     }
14607
14608   if (0 == rmt_locs && (u32) ~ 0 == action)
14609     {
14610       errmsg ("action not set for negative mapping");
14611       return -99;
14612     }
14613
14614   /* Construct the API message */
14615   M2 (GPE_ADD_DEL_FWD_ENTRY, mp,
14616       sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs) * 2);
14617
14618   mp->is_add = is_add;
14619   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
14620   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
14621   mp->eid_type = rmt_eid->type;
14622   mp->dp_table = clib_host_to_net_u32 (dp_table);
14623   mp->vni = clib_host_to_net_u32 (vni);
14624   mp->rmt_len = rmt_eid->len;
14625   mp->lcl_len = lcl_eid->len;
14626   mp->action = action;
14627
14628   if (0 != rmt_locs && 0 != lcl_locs)
14629     {
14630       mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
14631       clib_memcpy (mp->locs, lcl_locs,
14632                    (sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs)));
14633
14634       u32 offset = sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs);
14635       clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
14636                    (sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs)));
14637     }
14638   vec_free (lcl_locs);
14639   vec_free (rmt_locs);
14640
14641   /* send it... */
14642   S (mp);
14643
14644   /* Wait for a reply... */
14645   W (ret);
14646   return ret;
14647 }
14648
14649 static int
14650 api_one_add_del_map_server (vat_main_t * vam)
14651 {
14652   unformat_input_t *input = vam->input;
14653   vl_api_one_add_del_map_server_t *mp;
14654   u8 is_add = 1;
14655   u8 ipv4_set = 0;
14656   u8 ipv6_set = 0;
14657   ip4_address_t ipv4;
14658   ip6_address_t ipv6;
14659   int ret;
14660
14661   /* Parse args required to build the message */
14662   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14663     {
14664       if (unformat (input, "del"))
14665         {
14666           is_add = 0;
14667         }
14668       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
14669         {
14670           ipv4_set = 1;
14671         }
14672       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
14673         {
14674           ipv6_set = 1;
14675         }
14676       else
14677         break;
14678     }
14679
14680   if (ipv4_set && ipv6_set)
14681     {
14682       errmsg ("both eid v4 and v6 addresses set");
14683       return -99;
14684     }
14685
14686   if (!ipv4_set && !ipv6_set)
14687     {
14688       errmsg ("eid addresses not set");
14689       return -99;
14690     }
14691
14692   /* Construct the API message */
14693   M (ONE_ADD_DEL_MAP_SERVER, mp);
14694
14695   mp->is_add = is_add;
14696   if (ipv6_set)
14697     {
14698       mp->is_ipv6 = 1;
14699       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
14700     }
14701   else
14702     {
14703       mp->is_ipv6 = 0;
14704       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
14705     }
14706
14707   /* send it... */
14708   S (mp);
14709
14710   /* Wait for a reply... */
14711   W (ret);
14712   return ret;
14713 }
14714
14715 #define api_lisp_add_del_map_server api_one_add_del_map_server
14716
14717 static int
14718 api_one_add_del_map_resolver (vat_main_t * vam)
14719 {
14720   unformat_input_t *input = vam->input;
14721   vl_api_one_add_del_map_resolver_t *mp;
14722   u8 is_add = 1;
14723   u8 ipv4_set = 0;
14724   u8 ipv6_set = 0;
14725   ip4_address_t ipv4;
14726   ip6_address_t ipv6;
14727   int ret;
14728
14729   /* Parse args required to build the message */
14730   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14731     {
14732       if (unformat (input, "del"))
14733         {
14734           is_add = 0;
14735         }
14736       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
14737         {
14738           ipv4_set = 1;
14739         }
14740       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
14741         {
14742           ipv6_set = 1;
14743         }
14744       else
14745         break;
14746     }
14747
14748   if (ipv4_set && ipv6_set)
14749     {
14750       errmsg ("both eid v4 and v6 addresses set");
14751       return -99;
14752     }
14753
14754   if (!ipv4_set && !ipv6_set)
14755     {
14756       errmsg ("eid addresses not set");
14757       return -99;
14758     }
14759
14760   /* Construct the API message */
14761   M (ONE_ADD_DEL_MAP_RESOLVER, mp);
14762
14763   mp->is_add = is_add;
14764   if (ipv6_set)
14765     {
14766       mp->is_ipv6 = 1;
14767       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
14768     }
14769   else
14770     {
14771       mp->is_ipv6 = 0;
14772       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
14773     }
14774
14775   /* send it... */
14776   S (mp);
14777
14778   /* Wait for a reply... */
14779   W (ret);
14780   return ret;
14781 }
14782
14783 #define api_lisp_add_del_map_resolver api_one_add_del_map_resolver
14784
14785 static int
14786 api_lisp_gpe_enable_disable (vat_main_t * vam)
14787 {
14788   unformat_input_t *input = vam->input;
14789   vl_api_gpe_enable_disable_t *mp;
14790   u8 is_set = 0;
14791   u8 is_en = 1;
14792   int ret;
14793
14794   /* Parse args required to build the message */
14795   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14796     {
14797       if (unformat (input, "enable"))
14798         {
14799           is_set = 1;
14800           is_en = 1;
14801         }
14802       else if (unformat (input, "disable"))
14803         {
14804           is_set = 1;
14805           is_en = 0;
14806         }
14807       else
14808         break;
14809     }
14810
14811   if (is_set == 0)
14812     {
14813       errmsg ("Value not set");
14814       return -99;
14815     }
14816
14817   /* Construct the API message */
14818   M (GPE_ENABLE_DISABLE, mp);
14819
14820   mp->is_en = is_en;
14821
14822   /* send it... */
14823   S (mp);
14824
14825   /* Wait for a reply... */
14826   W (ret);
14827   return ret;
14828 }
14829
14830 static int
14831 api_one_rloc_probe_enable_disable (vat_main_t * vam)
14832 {
14833   unformat_input_t *input = vam->input;
14834   vl_api_one_rloc_probe_enable_disable_t *mp;
14835   u8 is_set = 0;
14836   u8 is_en = 0;
14837   int ret;
14838
14839   /* Parse args required to build the message */
14840   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14841     {
14842       if (unformat (input, "enable"))
14843         {
14844           is_set = 1;
14845           is_en = 1;
14846         }
14847       else if (unformat (input, "disable"))
14848         is_set = 1;
14849       else
14850         break;
14851     }
14852
14853   if (!is_set)
14854     {
14855       errmsg ("Value not set");
14856       return -99;
14857     }
14858
14859   /* Construct the API message */
14860   M (ONE_RLOC_PROBE_ENABLE_DISABLE, mp);
14861
14862   mp->is_enabled = is_en;
14863
14864   /* send it... */
14865   S (mp);
14866
14867   /* Wait for a reply... */
14868   W (ret);
14869   return ret;
14870 }
14871
14872 #define api_lisp_rloc_probe_enable_disable api_one_rloc_probe_enable_disable
14873
14874 static int
14875 api_one_map_register_enable_disable (vat_main_t * vam)
14876 {
14877   unformat_input_t *input = vam->input;
14878   vl_api_one_map_register_enable_disable_t *mp;
14879   u8 is_set = 0;
14880   u8 is_en = 0;
14881   int ret;
14882
14883   /* Parse args required to build the message */
14884   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14885     {
14886       if (unformat (input, "enable"))
14887         {
14888           is_set = 1;
14889           is_en = 1;
14890         }
14891       else if (unformat (input, "disable"))
14892         is_set = 1;
14893       else
14894         break;
14895     }
14896
14897   if (!is_set)
14898     {
14899       errmsg ("Value not set");
14900       return -99;
14901     }
14902
14903   /* Construct the API message */
14904   M (ONE_MAP_REGISTER_ENABLE_DISABLE, mp);
14905
14906   mp->is_enabled = is_en;
14907
14908   /* send it... */
14909   S (mp);
14910
14911   /* Wait for a reply... */
14912   W (ret);
14913   return ret;
14914 }
14915
14916 #define api_lisp_map_register_enable_disable api_one_map_register_enable_disable
14917
14918 static int
14919 api_one_enable_disable (vat_main_t * vam)
14920 {
14921   unformat_input_t *input = vam->input;
14922   vl_api_one_enable_disable_t *mp;
14923   u8 is_set = 0;
14924   u8 is_en = 0;
14925   int ret;
14926
14927   /* Parse args required to build the message */
14928   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14929     {
14930       if (unformat (input, "enable"))
14931         {
14932           is_set = 1;
14933           is_en = 1;
14934         }
14935       else if (unformat (input, "disable"))
14936         {
14937           is_set = 1;
14938         }
14939       else
14940         break;
14941     }
14942
14943   if (!is_set)
14944     {
14945       errmsg ("Value not set");
14946       return -99;
14947     }
14948
14949   /* Construct the API message */
14950   M (ONE_ENABLE_DISABLE, mp);
14951
14952   mp->is_en = is_en;
14953
14954   /* send it... */
14955   S (mp);
14956
14957   /* Wait for a reply... */
14958   W (ret);
14959   return ret;
14960 }
14961
14962 #define api_lisp_enable_disable api_one_enable_disable
14963
14964 static int
14965 api_one_enable_disable_xtr_mode (vat_main_t * vam)
14966 {
14967   unformat_input_t *input = vam->input;
14968   vl_api_one_enable_disable_xtr_mode_t *mp;
14969   u8 is_set = 0;
14970   u8 is_en = 0;
14971   int ret;
14972
14973   /* Parse args required to build the message */
14974   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14975     {
14976       if (unformat (input, "enable"))
14977         {
14978           is_set = 1;
14979           is_en = 1;
14980         }
14981       else if (unformat (input, "disable"))
14982         {
14983           is_set = 1;
14984         }
14985       else
14986         break;
14987     }
14988
14989   if (!is_set)
14990     {
14991       errmsg ("Value not set");
14992       return -99;
14993     }
14994
14995   /* Construct the API message */
14996   M (ONE_ENABLE_DISABLE_XTR_MODE, mp);
14997
14998   mp->is_en = is_en;
14999
15000   /* send it... */
15001   S (mp);
15002
15003   /* Wait for a reply... */
15004   W (ret);
15005   return ret;
15006 }
15007
15008 static int
15009 api_one_show_xtr_mode (vat_main_t * vam)
15010 {
15011   vl_api_one_show_xtr_mode_t *mp;
15012   int ret;
15013
15014   /* Construct the API message */
15015   M (ONE_SHOW_XTR_MODE, mp);
15016
15017   /* send it... */
15018   S (mp);
15019
15020   /* Wait for a reply... */
15021   W (ret);
15022   return ret;
15023 }
15024
15025 static int
15026 api_one_enable_disable_pitr_mode (vat_main_t * vam)
15027 {
15028   unformat_input_t *input = vam->input;
15029   vl_api_one_enable_disable_pitr_mode_t *mp;
15030   u8 is_set = 0;
15031   u8 is_en = 0;
15032   int ret;
15033
15034   /* Parse args required to build the message */
15035   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15036     {
15037       if (unformat (input, "enable"))
15038         {
15039           is_set = 1;
15040           is_en = 1;
15041         }
15042       else if (unformat (input, "disable"))
15043         {
15044           is_set = 1;
15045         }
15046       else
15047         break;
15048     }
15049
15050   if (!is_set)
15051     {
15052       errmsg ("Value not set");
15053       return -99;
15054     }
15055
15056   /* Construct the API message */
15057   M (ONE_ENABLE_DISABLE_PITR_MODE, mp);
15058
15059   mp->is_en = is_en;
15060
15061   /* send it... */
15062   S (mp);
15063
15064   /* Wait for a reply... */
15065   W (ret);
15066   return ret;
15067 }
15068
15069 static int
15070 api_one_show_pitr_mode (vat_main_t * vam)
15071 {
15072   vl_api_one_show_pitr_mode_t *mp;
15073   int ret;
15074
15075   /* Construct the API message */
15076   M (ONE_SHOW_PITR_MODE, mp);
15077
15078   /* send it... */
15079   S (mp);
15080
15081   /* Wait for a reply... */
15082   W (ret);
15083   return ret;
15084 }
15085
15086 static int
15087 api_one_enable_disable_petr_mode (vat_main_t * vam)
15088 {
15089   unformat_input_t *input = vam->input;
15090   vl_api_one_enable_disable_petr_mode_t *mp;
15091   u8 is_set = 0;
15092   u8 is_en = 0;
15093   int ret;
15094
15095   /* Parse args required to build the message */
15096   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15097     {
15098       if (unformat (input, "enable"))
15099         {
15100           is_set = 1;
15101           is_en = 1;
15102         }
15103       else if (unformat (input, "disable"))
15104         {
15105           is_set = 1;
15106         }
15107       else
15108         break;
15109     }
15110
15111   if (!is_set)
15112     {
15113       errmsg ("Value not set");
15114       return -99;
15115     }
15116
15117   /* Construct the API message */
15118   M (ONE_ENABLE_DISABLE_PETR_MODE, mp);
15119
15120   mp->is_en = is_en;
15121
15122   /* send it... */
15123   S (mp);
15124
15125   /* Wait for a reply... */
15126   W (ret);
15127   return ret;
15128 }
15129
15130 static int
15131 api_one_show_petr_mode (vat_main_t * vam)
15132 {
15133   vl_api_one_show_petr_mode_t *mp;
15134   int ret;
15135
15136   /* Construct the API message */
15137   M (ONE_SHOW_PETR_MODE, mp);
15138
15139   /* send it... */
15140   S (mp);
15141
15142   /* Wait for a reply... */
15143   W (ret);
15144   return ret;
15145 }
15146
15147 static int
15148 api_show_one_map_register_state (vat_main_t * vam)
15149 {
15150   vl_api_show_one_map_register_state_t *mp;
15151   int ret;
15152
15153   M (SHOW_ONE_MAP_REGISTER_STATE, mp);
15154
15155   /* send */
15156   S (mp);
15157
15158   /* wait for reply */
15159   W (ret);
15160   return ret;
15161 }
15162
15163 #define api_show_lisp_map_register_state api_show_one_map_register_state
15164
15165 static int
15166 api_show_one_rloc_probe_state (vat_main_t * vam)
15167 {
15168   vl_api_show_one_rloc_probe_state_t *mp;
15169   int ret;
15170
15171   M (SHOW_ONE_RLOC_PROBE_STATE, mp);
15172
15173   /* send */
15174   S (mp);
15175
15176   /* wait for reply */
15177   W (ret);
15178   return ret;
15179 }
15180
15181 #define api_show_lisp_rloc_probe_state api_show_one_rloc_probe_state
15182
15183 static int
15184 api_one_add_del_ndp_entry (vat_main_t * vam)
15185 {
15186   vl_api_one_add_del_ndp_entry_t *mp;
15187   unformat_input_t *input = vam->input;
15188   u8 is_add = 1;
15189   u8 mac_set = 0;
15190   u8 bd_set = 0;
15191   u8 ip_set = 0;
15192   u8 mac[6] = { 0, };
15193   u8 ip6[16] = { 0, };
15194   u32 bd = ~0;
15195   int ret;
15196
15197   /* Parse args required to build the message */
15198   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15199     {
15200       if (unformat (input, "del"))
15201         is_add = 0;
15202       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
15203         mac_set = 1;
15204       else if (unformat (input, "ip %U", unformat_ip6_address, ip6))
15205         ip_set = 1;
15206       else if (unformat (input, "bd %d", &bd))
15207         bd_set = 1;
15208       else
15209         {
15210           errmsg ("parse error '%U'", format_unformat_error, input);
15211           return -99;
15212         }
15213     }
15214
15215   if (!bd_set || !ip_set || (!mac_set && is_add))
15216     {
15217       errmsg ("Missing BD, IP or MAC!");
15218       return -99;
15219     }
15220
15221   M (ONE_ADD_DEL_NDP_ENTRY, mp);
15222   mp->is_add = is_add;
15223   clib_memcpy (mp->mac, mac, 6);
15224   mp->bd = clib_host_to_net_u32 (bd);
15225   clib_memcpy (mp->ip6, ip6, sizeof (mp->ip6));
15226
15227   /* send */
15228   S (mp);
15229
15230   /* wait for reply */
15231   W (ret);
15232   return ret;
15233 }
15234
15235 static int
15236 api_one_add_del_l2_arp_entry (vat_main_t * vam)
15237 {
15238   vl_api_one_add_del_l2_arp_entry_t *mp;
15239   unformat_input_t *input = vam->input;
15240   u8 is_add = 1;
15241   u8 mac_set = 0;
15242   u8 bd_set = 0;
15243   u8 ip_set = 0;
15244   u8 mac[6] = { 0, };
15245   u32 ip4 = 0, bd = ~0;
15246   int ret;
15247
15248   /* Parse args required to build the message */
15249   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15250     {
15251       if (unformat (input, "del"))
15252         is_add = 0;
15253       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
15254         mac_set = 1;
15255       else if (unformat (input, "ip %U", unformat_ip4_address, &ip4))
15256         ip_set = 1;
15257       else if (unformat (input, "bd %d", &bd))
15258         bd_set = 1;
15259       else
15260         {
15261           errmsg ("parse error '%U'", format_unformat_error, input);
15262           return -99;
15263         }
15264     }
15265
15266   if (!bd_set || !ip_set || (!mac_set && is_add))
15267     {
15268       errmsg ("Missing BD, IP or MAC!");
15269       return -99;
15270     }
15271
15272   M (ONE_ADD_DEL_L2_ARP_ENTRY, mp);
15273   mp->is_add = is_add;
15274   clib_memcpy (mp->mac, mac, 6);
15275   mp->bd = clib_host_to_net_u32 (bd);
15276   mp->ip4 = ip4;
15277
15278   /* send */
15279   S (mp);
15280
15281   /* wait for reply */
15282   W (ret);
15283   return ret;
15284 }
15285
15286 static int
15287 api_one_ndp_bd_get (vat_main_t * vam)
15288 {
15289   vl_api_one_ndp_bd_get_t *mp;
15290   int ret;
15291
15292   M (ONE_NDP_BD_GET, mp);
15293
15294   /* send */
15295   S (mp);
15296
15297   /* wait for reply */
15298   W (ret);
15299   return ret;
15300 }
15301
15302 static int
15303 api_one_ndp_entries_get (vat_main_t * vam)
15304 {
15305   vl_api_one_ndp_entries_get_t *mp;
15306   unformat_input_t *input = vam->input;
15307   u8 bd_set = 0;
15308   u32 bd = ~0;
15309   int ret;
15310
15311   /* Parse args required to build the message */
15312   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15313     {
15314       if (unformat (input, "bd %d", &bd))
15315         bd_set = 1;
15316       else
15317         {
15318           errmsg ("parse error '%U'", format_unformat_error, input);
15319           return -99;
15320         }
15321     }
15322
15323   if (!bd_set)
15324     {
15325       errmsg ("Expected bridge domain!");
15326       return -99;
15327     }
15328
15329   M (ONE_NDP_ENTRIES_GET, mp);
15330   mp->bd = clib_host_to_net_u32 (bd);
15331
15332   /* send */
15333   S (mp);
15334
15335   /* wait for reply */
15336   W (ret);
15337   return ret;
15338 }
15339
15340 static int
15341 api_one_l2_arp_bd_get (vat_main_t * vam)
15342 {
15343   vl_api_one_l2_arp_bd_get_t *mp;
15344   int ret;
15345
15346   M (ONE_L2_ARP_BD_GET, mp);
15347
15348   /* send */
15349   S (mp);
15350
15351   /* wait for reply */
15352   W (ret);
15353   return ret;
15354 }
15355
15356 static int
15357 api_one_l2_arp_entries_get (vat_main_t * vam)
15358 {
15359   vl_api_one_l2_arp_entries_get_t *mp;
15360   unformat_input_t *input = vam->input;
15361   u8 bd_set = 0;
15362   u32 bd = ~0;
15363   int ret;
15364
15365   /* Parse args required to build the message */
15366   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15367     {
15368       if (unformat (input, "bd %d", &bd))
15369         bd_set = 1;
15370       else
15371         {
15372           errmsg ("parse error '%U'", format_unformat_error, input);
15373           return -99;
15374         }
15375     }
15376
15377   if (!bd_set)
15378     {
15379       errmsg ("Expected bridge domain!");
15380       return -99;
15381     }
15382
15383   M (ONE_L2_ARP_ENTRIES_GET, mp);
15384   mp->bd = clib_host_to_net_u32 (bd);
15385
15386   /* send */
15387   S (mp);
15388
15389   /* wait for reply */
15390   W (ret);
15391   return ret;
15392 }
15393
15394 static int
15395 api_one_stats_enable_disable (vat_main_t * vam)
15396 {
15397   vl_api_one_stats_enable_disable_t *mp;
15398   unformat_input_t *input = vam->input;
15399   u8 is_set = 0;
15400   u8 is_en = 0;
15401   int ret;
15402
15403   /* Parse args required to build the message */
15404   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15405     {
15406       if (unformat (input, "enable"))
15407         {
15408           is_set = 1;
15409           is_en = 1;
15410         }
15411       else if (unformat (input, "disable"))
15412         {
15413           is_set = 1;
15414         }
15415       else
15416         break;
15417     }
15418
15419   if (!is_set)
15420     {
15421       errmsg ("Value not set");
15422       return -99;
15423     }
15424
15425   M (ONE_STATS_ENABLE_DISABLE, mp);
15426   mp->is_en = is_en;
15427
15428   /* send */
15429   S (mp);
15430
15431   /* wait for reply */
15432   W (ret);
15433   return ret;
15434 }
15435
15436 static int
15437 api_show_one_stats_enable_disable (vat_main_t * vam)
15438 {
15439   vl_api_show_one_stats_enable_disable_t *mp;
15440   int ret;
15441
15442   M (SHOW_ONE_STATS_ENABLE_DISABLE, mp);
15443
15444   /* send */
15445   S (mp);
15446
15447   /* wait for reply */
15448   W (ret);
15449   return ret;
15450 }
15451
15452 static int
15453 api_show_one_map_request_mode (vat_main_t * vam)
15454 {
15455   vl_api_show_one_map_request_mode_t *mp;
15456   int ret;
15457
15458   M (SHOW_ONE_MAP_REQUEST_MODE, mp);
15459
15460   /* send */
15461   S (mp);
15462
15463   /* wait for reply */
15464   W (ret);
15465   return ret;
15466 }
15467
15468 #define api_show_lisp_map_request_mode api_show_one_map_request_mode
15469
15470 static int
15471 api_one_map_request_mode (vat_main_t * vam)
15472 {
15473   unformat_input_t *input = vam->input;
15474   vl_api_one_map_request_mode_t *mp;
15475   u8 mode = 0;
15476   int ret;
15477
15478   /* Parse args required to build the message */
15479   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15480     {
15481       if (unformat (input, "dst-only"))
15482         mode = 0;
15483       else if (unformat (input, "src-dst"))
15484         mode = 1;
15485       else
15486         {
15487           errmsg ("parse error '%U'", format_unformat_error, input);
15488           return -99;
15489         }
15490     }
15491
15492   M (ONE_MAP_REQUEST_MODE, mp);
15493
15494   mp->mode = mode;
15495
15496   /* send */
15497   S (mp);
15498
15499   /* wait for reply */
15500   W (ret);
15501   return ret;
15502 }
15503
15504 #define api_lisp_map_request_mode api_one_map_request_mode
15505
15506 /**
15507  * Enable/disable ONE proxy ITR.
15508  *
15509  * @param vam vpp API test context
15510  * @return return code
15511  */
15512 static int
15513 api_one_pitr_set_locator_set (vat_main_t * vam)
15514 {
15515   u8 ls_name_set = 0;
15516   unformat_input_t *input = vam->input;
15517   vl_api_one_pitr_set_locator_set_t *mp;
15518   u8 is_add = 1;
15519   u8 *ls_name = 0;
15520   int ret;
15521
15522   /* Parse args required to build the message */
15523   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15524     {
15525       if (unformat (input, "del"))
15526         is_add = 0;
15527       else if (unformat (input, "locator-set %s", &ls_name))
15528         ls_name_set = 1;
15529       else
15530         {
15531           errmsg ("parse error '%U'", format_unformat_error, input);
15532           return -99;
15533         }
15534     }
15535
15536   if (!ls_name_set)
15537     {
15538       errmsg ("locator-set name not set!");
15539       return -99;
15540     }
15541
15542   M (ONE_PITR_SET_LOCATOR_SET, mp);
15543
15544   mp->is_add = is_add;
15545   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
15546   vec_free (ls_name);
15547
15548   /* send */
15549   S (mp);
15550
15551   /* wait for reply */
15552   W (ret);
15553   return ret;
15554 }
15555
15556 #define api_lisp_pitr_set_locator_set api_one_pitr_set_locator_set
15557
15558 static int
15559 api_one_nsh_set_locator_set (vat_main_t * vam)
15560 {
15561   u8 ls_name_set = 0;
15562   unformat_input_t *input = vam->input;
15563   vl_api_one_nsh_set_locator_set_t *mp;
15564   u8 is_add = 1;
15565   u8 *ls_name = 0;
15566   int ret;
15567
15568   /* Parse args required to build the message */
15569   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15570     {
15571       if (unformat (input, "del"))
15572         is_add = 0;
15573       else if (unformat (input, "ls %s", &ls_name))
15574         ls_name_set = 1;
15575       else
15576         {
15577           errmsg ("parse error '%U'", format_unformat_error, input);
15578           return -99;
15579         }
15580     }
15581
15582   if (!ls_name_set && is_add)
15583     {
15584       errmsg ("locator-set name not set!");
15585       return -99;
15586     }
15587
15588   M (ONE_NSH_SET_LOCATOR_SET, mp);
15589
15590   mp->is_add = is_add;
15591   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
15592   vec_free (ls_name);
15593
15594   /* send */
15595   S (mp);
15596
15597   /* wait for reply */
15598   W (ret);
15599   return ret;
15600 }
15601
15602 static int
15603 api_show_one_pitr (vat_main_t * vam)
15604 {
15605   vl_api_show_one_pitr_t *mp;
15606   int ret;
15607
15608   if (!vam->json_output)
15609     {
15610       print (vam->ofp, "%=20s", "lisp status:");
15611     }
15612
15613   M (SHOW_ONE_PITR, mp);
15614   /* send it... */
15615   S (mp);
15616
15617   /* Wait for a reply... */
15618   W (ret);
15619   return ret;
15620 }
15621
15622 #define api_show_lisp_pitr api_show_one_pitr
15623
15624 static int
15625 api_one_use_petr (vat_main_t * vam)
15626 {
15627   unformat_input_t *input = vam->input;
15628   vl_api_one_use_petr_t *mp;
15629   u8 is_add = 0;
15630   ip_address_t ip;
15631   int ret;
15632
15633   clib_memset (&ip, 0, sizeof (ip));
15634
15635   /* Parse args required to build the message */
15636   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15637     {
15638       if (unformat (input, "disable"))
15639         is_add = 0;
15640       else
15641         if (unformat (input, "%U", unformat_ip4_address, &ip_addr_v4 (&ip)))
15642         {
15643           is_add = 1;
15644           ip_addr_version (&ip) = AF_IP4;
15645         }
15646       else
15647         if (unformat (input, "%U", unformat_ip6_address, &ip_addr_v6 (&ip)))
15648         {
15649           is_add = 1;
15650           ip_addr_version (&ip) = AF_IP6;
15651         }
15652       else
15653         {
15654           errmsg ("parse error '%U'", format_unformat_error, input);
15655           return -99;
15656         }
15657     }
15658
15659   M (ONE_USE_PETR, mp);
15660
15661   mp->is_add = is_add;
15662   if (is_add)
15663     {
15664       mp->is_ip4 = ip_addr_version (&ip) == AF_IP4 ? 1 : 0;
15665       if (mp->is_ip4)
15666         clib_memcpy (mp->address, &ip, 4);
15667       else
15668         clib_memcpy (mp->address, &ip, 16);
15669     }
15670
15671   /* send */
15672   S (mp);
15673
15674   /* wait for reply */
15675   W (ret);
15676   return ret;
15677 }
15678
15679 #define api_lisp_use_petr api_one_use_petr
15680
15681 static int
15682 api_show_one_nsh_mapping (vat_main_t * vam)
15683 {
15684   vl_api_show_one_use_petr_t *mp;
15685   int ret;
15686
15687   if (!vam->json_output)
15688     {
15689       print (vam->ofp, "%=20s", "local ONE NSH mapping:");
15690     }
15691
15692   M (SHOW_ONE_NSH_MAPPING, mp);
15693   /* send it... */
15694   S (mp);
15695
15696   /* Wait for a reply... */
15697   W (ret);
15698   return ret;
15699 }
15700
15701 static int
15702 api_show_one_use_petr (vat_main_t * vam)
15703 {
15704   vl_api_show_one_use_petr_t *mp;
15705   int ret;
15706
15707   if (!vam->json_output)
15708     {
15709       print (vam->ofp, "%=20s", "Proxy-ETR status:");
15710     }
15711
15712   M (SHOW_ONE_USE_PETR, mp);
15713   /* send it... */
15714   S (mp);
15715
15716   /* Wait for a reply... */
15717   W (ret);
15718   return ret;
15719 }
15720
15721 #define api_show_lisp_use_petr api_show_one_use_petr
15722
15723 /**
15724  * Add/delete mapping between vni and vrf
15725  */
15726 static int
15727 api_one_eid_table_add_del_map (vat_main_t * vam)
15728 {
15729   unformat_input_t *input = vam->input;
15730   vl_api_one_eid_table_add_del_map_t *mp;
15731   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
15732   u32 vni, vrf, bd_index;
15733   int ret;
15734
15735   /* Parse args required to build the message */
15736   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15737     {
15738       if (unformat (input, "del"))
15739         is_add = 0;
15740       else if (unformat (input, "vrf %d", &vrf))
15741         vrf_set = 1;
15742       else if (unformat (input, "bd_index %d", &bd_index))
15743         bd_index_set = 1;
15744       else if (unformat (input, "vni %d", &vni))
15745         vni_set = 1;
15746       else
15747         break;
15748     }
15749
15750   if (!vni_set || (!vrf_set && !bd_index_set))
15751     {
15752       errmsg ("missing arguments!");
15753       return -99;
15754     }
15755
15756   if (vrf_set && bd_index_set)
15757     {
15758       errmsg ("error: both vrf and bd entered!");
15759       return -99;
15760     }
15761
15762   M (ONE_EID_TABLE_ADD_DEL_MAP, mp);
15763
15764   mp->is_add = is_add;
15765   mp->vni = htonl (vni);
15766   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
15767   mp->is_l2 = bd_index_set;
15768
15769   /* send */
15770   S (mp);
15771
15772   /* wait for reply */
15773   W (ret);
15774   return ret;
15775 }
15776
15777 #define api_lisp_eid_table_add_del_map api_one_eid_table_add_del_map
15778
15779 uword
15780 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
15781 {
15782   u32 *action = va_arg (*args, u32 *);
15783   u8 *s = 0;
15784
15785   if (unformat (input, "%s", &s))
15786     {
15787       if (!strcmp ((char *) s, "no-action"))
15788         action[0] = 0;
15789       else if (!strcmp ((char *) s, "natively-forward"))
15790         action[0] = 1;
15791       else if (!strcmp ((char *) s, "send-map-request"))
15792         action[0] = 2;
15793       else if (!strcmp ((char *) s, "drop"))
15794         action[0] = 3;
15795       else
15796         {
15797           clib_warning ("invalid action: '%s'", s);
15798           action[0] = 3;
15799         }
15800     }
15801   else
15802     return 0;
15803
15804   vec_free (s);
15805   return 1;
15806 }
15807
15808 /**
15809  * Add/del remote mapping to/from ONE control plane
15810  *
15811  * @param vam vpp API test context
15812  * @return return code
15813  */
15814 static int
15815 api_one_add_del_remote_mapping (vat_main_t * vam)
15816 {
15817   unformat_input_t *input = vam->input;
15818   vl_api_one_add_del_remote_mapping_t *mp;
15819   u32 vni = 0;
15820   lisp_eid_vat_t _eid, *eid = &_eid;
15821   lisp_eid_vat_t _seid, *seid = &_seid;
15822   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
15823   u32 action = ~0, p, w, data_len;
15824   ip4_address_t rloc4;
15825   ip6_address_t rloc6;
15826   vl_api_remote_locator_t *rlocs = 0, rloc, *curr_rloc = 0;
15827   int ret;
15828
15829   clib_memset (&rloc, 0, sizeof (rloc));
15830
15831   /* Parse args required to build the message */
15832   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15833     {
15834       if (unformat (input, "del-all"))
15835         {
15836           del_all = 1;
15837         }
15838       else if (unformat (input, "del"))
15839         {
15840           is_add = 0;
15841         }
15842       else if (unformat (input, "add"))
15843         {
15844           is_add = 1;
15845         }
15846       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
15847         {
15848           eid_set = 1;
15849         }
15850       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
15851         {
15852           seid_set = 1;
15853         }
15854       else if (unformat (input, "vni %d", &vni))
15855         {
15856           ;
15857         }
15858       else if (unformat (input, "p %d w %d", &p, &w))
15859         {
15860           if (!curr_rloc)
15861             {
15862               errmsg ("No RLOC configured for setting priority/weight!");
15863               return -99;
15864             }
15865           curr_rloc->priority = p;
15866           curr_rloc->weight = w;
15867         }
15868       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
15869         {
15870           rloc.is_ip4 = 1;
15871           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
15872           vec_add1 (rlocs, rloc);
15873           curr_rloc = &rlocs[vec_len (rlocs) - 1];
15874         }
15875       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
15876         {
15877           rloc.is_ip4 = 0;
15878           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
15879           vec_add1 (rlocs, rloc);
15880           curr_rloc = &rlocs[vec_len (rlocs) - 1];
15881         }
15882       else if (unformat (input, "action %U",
15883                          unformat_negative_mapping_action, &action))
15884         {
15885           ;
15886         }
15887       else
15888         {
15889           clib_warning ("parse error '%U'", format_unformat_error, input);
15890           return -99;
15891         }
15892     }
15893
15894   if (0 == eid_set)
15895     {
15896       errmsg ("missing params!");
15897       return -99;
15898     }
15899
15900   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
15901     {
15902       errmsg ("no action set for negative map-reply!");
15903       return -99;
15904     }
15905
15906   data_len = vec_len (rlocs) * sizeof (vl_api_remote_locator_t);
15907
15908   M2 (ONE_ADD_DEL_REMOTE_MAPPING, mp, data_len);
15909   mp->is_add = is_add;
15910   mp->vni = htonl (vni);
15911   mp->action = (u8) action;
15912   mp->is_src_dst = seid_set;
15913   mp->eid_len = eid->len;
15914   mp->seid_len = seid->len;
15915   mp->del_all = del_all;
15916   mp->eid_type = eid->type;
15917   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
15918   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
15919
15920   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
15921   clib_memcpy (mp->rlocs, rlocs, data_len);
15922   vec_free (rlocs);
15923
15924   /* send it... */
15925   S (mp);
15926
15927   /* Wait for a reply... */
15928   W (ret);
15929   return ret;
15930 }
15931
15932 #define api_lisp_add_del_remote_mapping api_one_add_del_remote_mapping
15933
15934 /**
15935  * Add/del ONE adjacency. Saves mapping in ONE control plane and updates
15936  * forwarding entries in data-plane accordingly.
15937  *
15938  * @param vam vpp API test context
15939  * @return return code
15940  */
15941 static int
15942 api_one_add_del_adjacency (vat_main_t * vam)
15943 {
15944   unformat_input_t *input = vam->input;
15945   vl_api_one_add_del_adjacency_t *mp;
15946   u32 vni = 0;
15947   ip4_address_t leid4, reid4;
15948   ip6_address_t leid6, reid6;
15949   u8 reid_mac[6] = { 0 };
15950   u8 leid_mac[6] = { 0 };
15951   u8 reid_type, leid_type;
15952   u32 leid_len = 0, reid_len = 0, len;
15953   u8 is_add = 1;
15954   int ret;
15955
15956   leid_type = reid_type = (u8) ~ 0;
15957
15958   /* Parse args required to build the message */
15959   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15960     {
15961       if (unformat (input, "del"))
15962         {
15963           is_add = 0;
15964         }
15965       else if (unformat (input, "add"))
15966         {
15967           is_add = 1;
15968         }
15969       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
15970                          &reid4, &len))
15971         {
15972           reid_type = 0;        /* ipv4 */
15973           reid_len = len;
15974         }
15975       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
15976                          &reid6, &len))
15977         {
15978           reid_type = 1;        /* ipv6 */
15979           reid_len = len;
15980         }
15981       else if (unformat (input, "reid %U", unformat_ethernet_address,
15982                          reid_mac))
15983         {
15984           reid_type = 2;        /* mac */
15985         }
15986       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
15987                          &leid4, &len))
15988         {
15989           leid_type = 0;        /* ipv4 */
15990           leid_len = len;
15991         }
15992       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
15993                          &leid6, &len))
15994         {
15995           leid_type = 1;        /* ipv6 */
15996           leid_len = len;
15997         }
15998       else if (unformat (input, "leid %U", unformat_ethernet_address,
15999                          leid_mac))
16000         {
16001           leid_type = 2;        /* mac */
16002         }
16003       else if (unformat (input, "vni %d", &vni))
16004         {
16005           ;
16006         }
16007       else
16008         {
16009           errmsg ("parse error '%U'", format_unformat_error, input);
16010           return -99;
16011         }
16012     }
16013
16014   if ((u8) ~ 0 == reid_type)
16015     {
16016       errmsg ("missing params!");
16017       return -99;
16018     }
16019
16020   if (leid_type != reid_type)
16021     {
16022       errmsg ("remote and local EIDs are of different types!");
16023       return -99;
16024     }
16025
16026   M (ONE_ADD_DEL_ADJACENCY, mp);
16027   mp->is_add = is_add;
16028   mp->vni = htonl (vni);
16029   mp->leid_len = leid_len;
16030   mp->reid_len = reid_len;
16031   mp->eid_type = reid_type;
16032
16033   switch (mp->eid_type)
16034     {
16035     case 0:
16036       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
16037       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
16038       break;
16039     case 1:
16040       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
16041       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
16042       break;
16043     case 2:
16044       clib_memcpy (mp->leid, leid_mac, 6);
16045       clib_memcpy (mp->reid, reid_mac, 6);
16046       break;
16047     default:
16048       errmsg ("unknown EID type %d!", mp->eid_type);
16049       return 0;
16050     }
16051
16052   /* send it... */
16053   S (mp);
16054
16055   /* Wait for a reply... */
16056   W (ret);
16057   return ret;
16058 }
16059
16060 #define api_lisp_add_del_adjacency api_one_add_del_adjacency
16061
16062 uword
16063 unformat_gpe_encap_mode (unformat_input_t * input, va_list * args)
16064 {
16065   u32 *mode = va_arg (*args, u32 *);
16066
16067   if (unformat (input, "lisp"))
16068     *mode = 0;
16069   else if (unformat (input, "vxlan"))
16070     *mode = 1;
16071   else
16072     return 0;
16073
16074   return 1;
16075 }
16076
16077 static int
16078 api_gpe_get_encap_mode (vat_main_t * vam)
16079 {
16080   vl_api_gpe_get_encap_mode_t *mp;
16081   int ret;
16082
16083   /* Construct the API message */
16084   M (GPE_GET_ENCAP_MODE, mp);
16085
16086   /* send it... */
16087   S (mp);
16088
16089   /* Wait for a reply... */
16090   W (ret);
16091   return ret;
16092 }
16093
16094 static int
16095 api_gpe_set_encap_mode (vat_main_t * vam)
16096 {
16097   unformat_input_t *input = vam->input;
16098   vl_api_gpe_set_encap_mode_t *mp;
16099   int ret;
16100   u32 mode = 0;
16101
16102   /* Parse args required to build the message */
16103   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16104     {
16105       if (unformat (input, "%U", unformat_gpe_encap_mode, &mode))
16106         ;
16107       else
16108         break;
16109     }
16110
16111   /* Construct the API message */
16112   M (GPE_SET_ENCAP_MODE, mp);
16113
16114   mp->mode = mode;
16115
16116   /* send it... */
16117   S (mp);
16118
16119   /* Wait for a reply... */
16120   W (ret);
16121   return ret;
16122 }
16123
16124 static int
16125 api_lisp_gpe_add_del_iface (vat_main_t * vam)
16126 {
16127   unformat_input_t *input = vam->input;
16128   vl_api_gpe_add_del_iface_t *mp;
16129   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
16130   u32 dp_table = 0, vni = 0;
16131   int ret;
16132
16133   /* Parse args required to build the message */
16134   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16135     {
16136       if (unformat (input, "up"))
16137         {
16138           action_set = 1;
16139           is_add = 1;
16140         }
16141       else if (unformat (input, "down"))
16142         {
16143           action_set = 1;
16144           is_add = 0;
16145         }
16146       else if (unformat (input, "table_id %d", &dp_table))
16147         {
16148           dp_table_set = 1;
16149         }
16150       else if (unformat (input, "bd_id %d", &dp_table))
16151         {
16152           dp_table_set = 1;
16153           is_l2 = 1;
16154         }
16155       else if (unformat (input, "vni %d", &vni))
16156         {
16157           vni_set = 1;
16158         }
16159       else
16160         break;
16161     }
16162
16163   if (action_set == 0)
16164     {
16165       errmsg ("Action not set");
16166       return -99;
16167     }
16168   if (dp_table_set == 0 || vni_set == 0)
16169     {
16170       errmsg ("vni and dp_table must be set");
16171       return -99;
16172     }
16173
16174   /* Construct the API message */
16175   M (GPE_ADD_DEL_IFACE, mp);
16176
16177   mp->is_add = is_add;
16178   mp->dp_table = clib_host_to_net_u32 (dp_table);
16179   mp->is_l2 = is_l2;
16180   mp->vni = clib_host_to_net_u32 (vni);
16181
16182   /* send it... */
16183   S (mp);
16184
16185   /* Wait for a reply... */
16186   W (ret);
16187   return ret;
16188 }
16189
16190 static int
16191 api_one_map_register_fallback_threshold (vat_main_t * vam)
16192 {
16193   unformat_input_t *input = vam->input;
16194   vl_api_one_map_register_fallback_threshold_t *mp;
16195   u32 value = 0;
16196   u8 is_set = 0;
16197   int ret;
16198
16199   /* Parse args required to build the message */
16200   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16201     {
16202       if (unformat (input, "%u", &value))
16203         is_set = 1;
16204       else
16205         {
16206           clib_warning ("parse error '%U'", format_unformat_error, input);
16207           return -99;
16208         }
16209     }
16210
16211   if (!is_set)
16212     {
16213       errmsg ("fallback threshold value is missing!");
16214       return -99;
16215     }
16216
16217   M (ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
16218   mp->value = clib_host_to_net_u32 (value);
16219
16220   /* send it... */
16221   S (mp);
16222
16223   /* Wait for a reply... */
16224   W (ret);
16225   return ret;
16226 }
16227
16228 static int
16229 api_show_one_map_register_fallback_threshold (vat_main_t * vam)
16230 {
16231   vl_api_show_one_map_register_fallback_threshold_t *mp;
16232   int ret;
16233
16234   M (SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
16235
16236   /* send it... */
16237   S (mp);
16238
16239   /* Wait for a reply... */
16240   W (ret);
16241   return ret;
16242 }
16243
16244 uword
16245 unformat_lisp_transport_protocol (unformat_input_t * input, va_list * args)
16246 {
16247   u32 *proto = va_arg (*args, u32 *);
16248
16249   if (unformat (input, "udp"))
16250     *proto = 1;
16251   else if (unformat (input, "api"))
16252     *proto = 2;
16253   else
16254     return 0;
16255
16256   return 1;
16257 }
16258
16259 static int
16260 api_one_set_transport_protocol (vat_main_t * vam)
16261 {
16262   unformat_input_t *input = vam->input;
16263   vl_api_one_set_transport_protocol_t *mp;
16264   u8 is_set = 0;
16265   u32 protocol = 0;
16266   int ret;
16267
16268   /* Parse args required to build the message */
16269   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16270     {
16271       if (unformat (input, "%U", unformat_lisp_transport_protocol, &protocol))
16272         is_set = 1;
16273       else
16274         {
16275           clib_warning ("parse error '%U'", format_unformat_error, input);
16276           return -99;
16277         }
16278     }
16279
16280   if (!is_set)
16281     {
16282       errmsg ("Transport protocol missing!");
16283       return -99;
16284     }
16285
16286   M (ONE_SET_TRANSPORT_PROTOCOL, mp);
16287   mp->protocol = (u8) protocol;
16288
16289   /* send it... */
16290   S (mp);
16291
16292   /* Wait for a reply... */
16293   W (ret);
16294   return ret;
16295 }
16296
16297 static int
16298 api_one_get_transport_protocol (vat_main_t * vam)
16299 {
16300   vl_api_one_get_transport_protocol_t *mp;
16301   int ret;
16302
16303   M (ONE_GET_TRANSPORT_PROTOCOL, mp);
16304
16305   /* send it... */
16306   S (mp);
16307
16308   /* Wait for a reply... */
16309   W (ret);
16310   return ret;
16311 }
16312
16313 static int
16314 api_one_map_register_set_ttl (vat_main_t * vam)
16315 {
16316   unformat_input_t *input = vam->input;
16317   vl_api_one_map_register_set_ttl_t *mp;
16318   u32 ttl = 0;
16319   u8 is_set = 0;
16320   int ret;
16321
16322   /* Parse args required to build the message */
16323   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16324     {
16325       if (unformat (input, "%u", &ttl))
16326         is_set = 1;
16327       else
16328         {
16329           clib_warning ("parse error '%U'", format_unformat_error, input);
16330           return -99;
16331         }
16332     }
16333
16334   if (!is_set)
16335     {
16336       errmsg ("TTL value missing!");
16337       return -99;
16338     }
16339
16340   M (ONE_MAP_REGISTER_SET_TTL, mp);
16341   mp->ttl = clib_host_to_net_u32 (ttl);
16342
16343   /* send it... */
16344   S (mp);
16345
16346   /* Wait for a reply... */
16347   W (ret);
16348   return ret;
16349 }
16350
16351 static int
16352 api_show_one_map_register_ttl (vat_main_t * vam)
16353 {
16354   vl_api_show_one_map_register_ttl_t *mp;
16355   int ret;
16356
16357   M (SHOW_ONE_MAP_REGISTER_TTL, mp);
16358
16359   /* send it... */
16360   S (mp);
16361
16362   /* Wait for a reply... */
16363   W (ret);
16364   return ret;
16365 }
16366
16367 /**
16368  * Add/del map request itr rlocs from ONE control plane and updates
16369  *
16370  * @param vam vpp API test context
16371  * @return return code
16372  */
16373 static int
16374 api_one_add_del_map_request_itr_rlocs (vat_main_t * vam)
16375 {
16376   unformat_input_t *input = vam->input;
16377   vl_api_one_add_del_map_request_itr_rlocs_t *mp;
16378   u8 *locator_set_name = 0;
16379   u8 locator_set_name_set = 0;
16380   u8 is_add = 1;
16381   int ret;
16382
16383   /* Parse args required to build the message */
16384   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16385     {
16386       if (unformat (input, "del"))
16387         {
16388           is_add = 0;
16389         }
16390       else if (unformat (input, "%_%v%_", &locator_set_name))
16391         {
16392           locator_set_name_set = 1;
16393         }
16394       else
16395         {
16396           clib_warning ("parse error '%U'", format_unformat_error, input);
16397           return -99;
16398         }
16399     }
16400
16401   if (is_add && !locator_set_name_set)
16402     {
16403       errmsg ("itr-rloc is not set!");
16404       return -99;
16405     }
16406
16407   if (is_add && vec_len (locator_set_name) > 64)
16408     {
16409       errmsg ("itr-rloc locator-set name too long");
16410       vec_free (locator_set_name);
16411       return -99;
16412     }
16413
16414   M (ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS, mp);
16415   mp->is_add = is_add;
16416   if (is_add)
16417     {
16418       clib_memcpy (mp->locator_set_name, locator_set_name,
16419                    vec_len (locator_set_name));
16420     }
16421   else
16422     {
16423       clib_memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
16424     }
16425   vec_free (locator_set_name);
16426
16427   /* send it... */
16428   S (mp);
16429
16430   /* Wait for a reply... */
16431   W (ret);
16432   return ret;
16433 }
16434
16435 #define api_lisp_add_del_map_request_itr_rlocs api_one_add_del_map_request_itr_rlocs
16436
16437 static int
16438 api_one_locator_dump (vat_main_t * vam)
16439 {
16440   unformat_input_t *input = vam->input;
16441   vl_api_one_locator_dump_t *mp;
16442   vl_api_control_ping_t *mp_ping;
16443   u8 is_index_set = 0, is_name_set = 0;
16444   u8 *ls_name = 0;
16445   u32 ls_index = ~0;
16446   int ret;
16447
16448   /* Parse args required to build the message */
16449   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16450     {
16451       if (unformat (input, "ls_name %_%v%_", &ls_name))
16452         {
16453           is_name_set = 1;
16454         }
16455       else if (unformat (input, "ls_index %d", &ls_index))
16456         {
16457           is_index_set = 1;
16458         }
16459       else
16460         {
16461           errmsg ("parse error '%U'", format_unformat_error, input);
16462           return -99;
16463         }
16464     }
16465
16466   if (!is_index_set && !is_name_set)
16467     {
16468       errmsg ("error: expected one of index or name!");
16469       return -99;
16470     }
16471
16472   if (is_index_set && is_name_set)
16473     {
16474       errmsg ("error: only one param expected!");
16475       return -99;
16476     }
16477
16478   if (vec_len (ls_name) > 62)
16479     {
16480       errmsg ("error: locator set name too long!");
16481       return -99;
16482     }
16483
16484   if (!vam->json_output)
16485     {
16486       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
16487     }
16488
16489   M (ONE_LOCATOR_DUMP, mp);
16490   mp->is_index_set = is_index_set;
16491
16492   if (is_index_set)
16493     mp->ls_index = clib_host_to_net_u32 (ls_index);
16494   else
16495     {
16496       vec_add1 (ls_name, 0);
16497       strncpy ((char *) mp->ls_name, (char *) ls_name,
16498                sizeof (mp->ls_name) - 1);
16499     }
16500
16501   /* send it... */
16502   S (mp);
16503
16504   /* Use a control ping for synchronization */
16505   MPING (CONTROL_PING, mp_ping);
16506   S (mp_ping);
16507
16508   /* Wait for a reply... */
16509   W (ret);
16510   return ret;
16511 }
16512
16513 #define api_lisp_locator_dump api_one_locator_dump
16514
16515 static int
16516 api_one_locator_set_dump (vat_main_t * vam)
16517 {
16518   vl_api_one_locator_set_dump_t *mp;
16519   vl_api_control_ping_t *mp_ping;
16520   unformat_input_t *input = vam->input;
16521   u8 filter = 0;
16522   int ret;
16523
16524   /* Parse args required to build the message */
16525   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16526     {
16527       if (unformat (input, "local"))
16528         {
16529           filter = 1;
16530         }
16531       else if (unformat (input, "remote"))
16532         {
16533           filter = 2;
16534         }
16535       else
16536         {
16537           errmsg ("parse error '%U'", format_unformat_error, input);
16538           return -99;
16539         }
16540     }
16541
16542   if (!vam->json_output)
16543     {
16544       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
16545     }
16546
16547   M (ONE_LOCATOR_SET_DUMP, mp);
16548
16549   mp->filter = filter;
16550
16551   /* send it... */
16552   S (mp);
16553
16554   /* Use a control ping for synchronization */
16555   MPING (CONTROL_PING, mp_ping);
16556   S (mp_ping);
16557
16558   /* Wait for a reply... */
16559   W (ret);
16560   return ret;
16561 }
16562
16563 #define api_lisp_locator_set_dump api_one_locator_set_dump
16564
16565 static int
16566 api_one_eid_table_map_dump (vat_main_t * vam)
16567 {
16568   u8 is_l2 = 0;
16569   u8 mode_set = 0;
16570   unformat_input_t *input = vam->input;
16571   vl_api_one_eid_table_map_dump_t *mp;
16572   vl_api_control_ping_t *mp_ping;
16573   int ret;
16574
16575   /* Parse args required to build the message */
16576   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16577     {
16578       if (unformat (input, "l2"))
16579         {
16580           is_l2 = 1;
16581           mode_set = 1;
16582         }
16583       else if (unformat (input, "l3"))
16584         {
16585           is_l2 = 0;
16586           mode_set = 1;
16587         }
16588       else
16589         {
16590           errmsg ("parse error '%U'", format_unformat_error, input);
16591           return -99;
16592         }
16593     }
16594
16595   if (!mode_set)
16596     {
16597       errmsg ("expected one of 'l2' or 'l3' parameter!");
16598       return -99;
16599     }
16600
16601   if (!vam->json_output)
16602     {
16603       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
16604     }
16605
16606   M (ONE_EID_TABLE_MAP_DUMP, mp);
16607   mp->is_l2 = is_l2;
16608
16609   /* send it... */
16610   S (mp);
16611
16612   /* Use a control ping for synchronization */
16613   MPING (CONTROL_PING, mp_ping);
16614   S (mp_ping);
16615
16616   /* Wait for a reply... */
16617   W (ret);
16618   return ret;
16619 }
16620
16621 #define api_lisp_eid_table_map_dump api_one_eid_table_map_dump
16622
16623 static int
16624 api_one_eid_table_vni_dump (vat_main_t * vam)
16625 {
16626   vl_api_one_eid_table_vni_dump_t *mp;
16627   vl_api_control_ping_t *mp_ping;
16628   int ret;
16629
16630   if (!vam->json_output)
16631     {
16632       print (vam->ofp, "VNI");
16633     }
16634
16635   M (ONE_EID_TABLE_VNI_DUMP, mp);
16636
16637   /* send it... */
16638   S (mp);
16639
16640   /* Use a control ping for synchronization */
16641   MPING (CONTROL_PING, mp_ping);
16642   S (mp_ping);
16643
16644   /* Wait for a reply... */
16645   W (ret);
16646   return ret;
16647 }
16648
16649 #define api_lisp_eid_table_vni_dump api_one_eid_table_vni_dump
16650
16651 static int
16652 api_one_eid_table_dump (vat_main_t * vam)
16653 {
16654   unformat_input_t *i = vam->input;
16655   vl_api_one_eid_table_dump_t *mp;
16656   vl_api_control_ping_t *mp_ping;
16657   struct in_addr ip4;
16658   struct in6_addr ip6;
16659   u8 mac[6];
16660   u8 eid_type = ~0, eid_set = 0;
16661   u32 prefix_length = ~0, t, vni = 0;
16662   u8 filter = 0;
16663   int ret;
16664   lisp_nsh_api_t nsh;
16665
16666   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16667     {
16668       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
16669         {
16670           eid_set = 1;
16671           eid_type = 0;
16672           prefix_length = t;
16673         }
16674       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
16675         {
16676           eid_set = 1;
16677           eid_type = 1;
16678           prefix_length = t;
16679         }
16680       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
16681         {
16682           eid_set = 1;
16683           eid_type = 2;
16684         }
16685       else if (unformat (i, "eid %U", unformat_nsh_address, &nsh))
16686         {
16687           eid_set = 1;
16688           eid_type = 3;
16689         }
16690       else if (unformat (i, "vni %d", &t))
16691         {
16692           vni = t;
16693         }
16694       else if (unformat (i, "local"))
16695         {
16696           filter = 1;
16697         }
16698       else if (unformat (i, "remote"))
16699         {
16700           filter = 2;
16701         }
16702       else
16703         {
16704           errmsg ("parse error '%U'", format_unformat_error, i);
16705           return -99;
16706         }
16707     }
16708
16709   if (!vam->json_output)
16710     {
16711       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
16712              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
16713     }
16714
16715   M (ONE_EID_TABLE_DUMP, mp);
16716
16717   mp->filter = filter;
16718   if (eid_set)
16719     {
16720       mp->eid_set = 1;
16721       mp->vni = htonl (vni);
16722       mp->eid_type = eid_type;
16723       switch (eid_type)
16724         {
16725         case 0:
16726           mp->prefix_length = prefix_length;
16727           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
16728           break;
16729         case 1:
16730           mp->prefix_length = prefix_length;
16731           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
16732           break;
16733         case 2:
16734           clib_memcpy (mp->eid, mac, sizeof (mac));
16735           break;
16736         case 3:
16737           clib_memcpy (mp->eid, &nsh, sizeof (nsh));
16738           break;
16739         default:
16740           errmsg ("unknown EID type %d!", eid_type);
16741           return -99;
16742         }
16743     }
16744
16745   /* send it... */
16746   S (mp);
16747
16748   /* Use a control ping for synchronization */
16749   MPING (CONTROL_PING, mp_ping);
16750   S (mp_ping);
16751
16752   /* Wait for a reply... */
16753   W (ret);
16754   return ret;
16755 }
16756
16757 #define api_lisp_eid_table_dump api_one_eid_table_dump
16758
16759 static int
16760 api_lisp_gpe_fwd_entries_get (vat_main_t * vam)
16761 {
16762   unformat_input_t *i = vam->input;
16763   vl_api_gpe_fwd_entries_get_t *mp;
16764   u8 vni_set = 0;
16765   u32 vni = ~0;
16766   int ret;
16767
16768   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16769     {
16770       if (unformat (i, "vni %d", &vni))
16771         {
16772           vni_set = 1;
16773         }
16774       else
16775         {
16776           errmsg ("parse error '%U'", format_unformat_error, i);
16777           return -99;
16778         }
16779     }
16780
16781   if (!vni_set)
16782     {
16783       errmsg ("vni not set!");
16784       return -99;
16785     }
16786
16787   if (!vam->json_output)
16788     {
16789       print (vam->ofp, "%10s %10s %s %40s", "fwd_index", "dp_table",
16790              "leid", "reid");
16791     }
16792
16793   M (GPE_FWD_ENTRIES_GET, mp);
16794   mp->vni = clib_host_to_net_u32 (vni);
16795
16796   /* send it... */
16797   S (mp);
16798
16799   /* Wait for a reply... */
16800   W (ret);
16801   return ret;
16802 }
16803
16804 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_endian vl_noop_handler
16805 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_print vl_noop_handler
16806 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_endian vl_noop_handler
16807 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_print vl_noop_handler
16808 #define vl_api_gpe_fwd_entries_get_reply_t_endian vl_noop_handler
16809 #define vl_api_gpe_fwd_entries_get_reply_t_print vl_noop_handler
16810 #define vl_api_gpe_fwd_entry_path_details_t_endian vl_noop_handler
16811 #define vl_api_gpe_fwd_entry_path_details_t_print vl_noop_handler
16812
16813 static int
16814 api_one_adjacencies_get (vat_main_t * vam)
16815 {
16816   unformat_input_t *i = vam->input;
16817   vl_api_one_adjacencies_get_t *mp;
16818   u8 vni_set = 0;
16819   u32 vni = ~0;
16820   int ret;
16821
16822   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16823     {
16824       if (unformat (i, "vni %d", &vni))
16825         {
16826           vni_set = 1;
16827         }
16828       else
16829         {
16830           errmsg ("parse error '%U'", format_unformat_error, i);
16831           return -99;
16832         }
16833     }
16834
16835   if (!vni_set)
16836     {
16837       errmsg ("vni not set!");
16838       return -99;
16839     }
16840
16841   if (!vam->json_output)
16842     {
16843       print (vam->ofp, "%s %40s", "leid", "reid");
16844     }
16845
16846   M (ONE_ADJACENCIES_GET, mp);
16847   mp->vni = clib_host_to_net_u32 (vni);
16848
16849   /* send it... */
16850   S (mp);
16851
16852   /* Wait for a reply... */
16853   W (ret);
16854   return ret;
16855 }
16856
16857 #define api_lisp_adjacencies_get api_one_adjacencies_get
16858
16859 static int
16860 api_gpe_native_fwd_rpaths_get (vat_main_t * vam)
16861 {
16862   unformat_input_t *i = vam->input;
16863   vl_api_gpe_native_fwd_rpaths_get_t *mp;
16864   int ret;
16865   u8 ip_family_set = 0, is_ip4 = 1;
16866
16867   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16868     {
16869       if (unformat (i, "ip4"))
16870         {
16871           ip_family_set = 1;
16872           is_ip4 = 1;
16873         }
16874       else if (unformat (i, "ip6"))
16875         {
16876           ip_family_set = 1;
16877           is_ip4 = 0;
16878         }
16879       else
16880         {
16881           errmsg ("parse error '%U'", format_unformat_error, i);
16882           return -99;
16883         }
16884     }
16885
16886   if (!ip_family_set)
16887     {
16888       errmsg ("ip family not set!");
16889       return -99;
16890     }
16891
16892   M (GPE_NATIVE_FWD_RPATHS_GET, mp);
16893   mp->is_ip4 = is_ip4;
16894
16895   /* send it... */
16896   S (mp);
16897
16898   /* Wait for a reply... */
16899   W (ret);
16900   return ret;
16901 }
16902
16903 static int
16904 api_gpe_fwd_entry_vnis_get (vat_main_t * vam)
16905 {
16906   vl_api_gpe_fwd_entry_vnis_get_t *mp;
16907   int ret;
16908
16909   if (!vam->json_output)
16910     {
16911       print (vam->ofp, "VNIs");
16912     }
16913
16914   M (GPE_FWD_ENTRY_VNIS_GET, mp);
16915
16916   /* send it... */
16917   S (mp);
16918
16919   /* Wait for a reply... */
16920   W (ret);
16921   return ret;
16922 }
16923
16924 static int
16925 api_gpe_add_del_native_fwd_rpath (vat_main_t * vam)
16926 {
16927   unformat_input_t *i = vam->input;
16928   vl_api_gpe_add_del_native_fwd_rpath_t *mp;
16929   int ret = 0;
16930   u8 is_add = 1, ip_set = 0, is_ip4 = 1;
16931   struct in_addr ip4;
16932   struct in6_addr ip6;
16933   u32 table_id = 0, nh_sw_if_index = ~0;
16934
16935   clib_memset (&ip4, 0, sizeof (ip4));
16936   clib_memset (&ip6, 0, sizeof (ip6));
16937
16938   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16939     {
16940       if (unformat (i, "del"))
16941         is_add = 0;
16942       else if (unformat (i, "via %U %U", unformat_ip4_address, &ip4,
16943                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
16944         {
16945           ip_set = 1;
16946           is_ip4 = 1;
16947         }
16948       else if (unformat (i, "via %U %U", unformat_ip6_address, &ip6,
16949                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
16950         {
16951           ip_set = 1;
16952           is_ip4 = 0;
16953         }
16954       else if (unformat (i, "via %U", unformat_ip4_address, &ip4))
16955         {
16956           ip_set = 1;
16957           is_ip4 = 1;
16958           nh_sw_if_index = ~0;
16959         }
16960       else if (unformat (i, "via %U", unformat_ip6_address, &ip6))
16961         {
16962           ip_set = 1;
16963           is_ip4 = 0;
16964           nh_sw_if_index = ~0;
16965         }
16966       else if (unformat (i, "table %d", &table_id))
16967         ;
16968       else
16969         {
16970           errmsg ("parse error '%U'", format_unformat_error, i);
16971           return -99;
16972         }
16973     }
16974
16975   if (!ip_set)
16976     {
16977       errmsg ("nh addr not set!");
16978       return -99;
16979     }
16980
16981   M (GPE_ADD_DEL_NATIVE_FWD_RPATH, mp);
16982   mp->is_add = is_add;
16983   mp->table_id = clib_host_to_net_u32 (table_id);
16984   mp->nh_sw_if_index = clib_host_to_net_u32 (nh_sw_if_index);
16985   mp->is_ip4 = is_ip4;
16986   if (is_ip4)
16987     clib_memcpy (mp->nh_addr, &ip4, sizeof (ip4));
16988   else
16989     clib_memcpy (mp->nh_addr, &ip6, sizeof (ip6));
16990
16991   /* send it... */
16992   S (mp);
16993
16994   /* Wait for a reply... */
16995   W (ret);
16996   return ret;
16997 }
16998
16999 static int
17000 api_one_map_server_dump (vat_main_t * vam)
17001 {
17002   vl_api_one_map_server_dump_t *mp;
17003   vl_api_control_ping_t *mp_ping;
17004   int ret;
17005
17006   if (!vam->json_output)
17007     {
17008       print (vam->ofp, "%=20s", "Map server");
17009     }
17010
17011   M (ONE_MAP_SERVER_DUMP, mp);
17012   /* send it... */
17013   S (mp);
17014
17015   /* Use a control ping for synchronization */
17016   MPING (CONTROL_PING, mp_ping);
17017   S (mp_ping);
17018
17019   /* Wait for a reply... */
17020   W (ret);
17021   return ret;
17022 }
17023
17024 #define api_lisp_map_server_dump api_one_map_server_dump
17025
17026 static int
17027 api_one_map_resolver_dump (vat_main_t * vam)
17028 {
17029   vl_api_one_map_resolver_dump_t *mp;
17030   vl_api_control_ping_t *mp_ping;
17031   int ret;
17032
17033   if (!vam->json_output)
17034     {
17035       print (vam->ofp, "%=20s", "Map resolver");
17036     }
17037
17038   M (ONE_MAP_RESOLVER_DUMP, mp);
17039   /* send it... */
17040   S (mp);
17041
17042   /* Use a control ping for synchronization */
17043   MPING (CONTROL_PING, mp_ping);
17044   S (mp_ping);
17045
17046   /* Wait for a reply... */
17047   W (ret);
17048   return ret;
17049 }
17050
17051 #define api_lisp_map_resolver_dump api_one_map_resolver_dump
17052
17053 static int
17054 api_one_stats_flush (vat_main_t * vam)
17055 {
17056   vl_api_one_stats_flush_t *mp;
17057   int ret = 0;
17058
17059   M (ONE_STATS_FLUSH, mp);
17060   S (mp);
17061   W (ret);
17062   return ret;
17063 }
17064
17065 static int
17066 api_one_stats_dump (vat_main_t * vam)
17067 {
17068   vl_api_one_stats_dump_t *mp;
17069   vl_api_control_ping_t *mp_ping;
17070   int ret;
17071
17072   M (ONE_STATS_DUMP, mp);
17073   /* send it... */
17074   S (mp);
17075
17076   /* Use a control ping for synchronization */
17077   MPING (CONTROL_PING, mp_ping);
17078   S (mp_ping);
17079
17080   /* Wait for a reply... */
17081   W (ret);
17082   return ret;
17083 }
17084
17085 static int
17086 api_show_one_status (vat_main_t * vam)
17087 {
17088   vl_api_show_one_status_t *mp;
17089   int ret;
17090
17091   if (!vam->json_output)
17092     {
17093       print (vam->ofp, "%-20s%-16s", "ONE status", "locator-set");
17094     }
17095
17096   M (SHOW_ONE_STATUS, mp);
17097   /* send it... */
17098   S (mp);
17099   /* Wait for a reply... */
17100   W (ret);
17101   return ret;
17102 }
17103
17104 #define api_show_lisp_status api_show_one_status
17105
17106 static int
17107 api_lisp_gpe_fwd_entry_path_dump (vat_main_t * vam)
17108 {
17109   vl_api_gpe_fwd_entry_path_dump_t *mp;
17110   vl_api_control_ping_t *mp_ping;
17111   unformat_input_t *i = vam->input;
17112   u32 fwd_entry_index = ~0;
17113   int ret;
17114
17115   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17116     {
17117       if (unformat (i, "index %d", &fwd_entry_index))
17118         ;
17119       else
17120         break;
17121     }
17122
17123   if (~0 == fwd_entry_index)
17124     {
17125       errmsg ("no index specified!");
17126       return -99;
17127     }
17128
17129   if (!vam->json_output)
17130     {
17131       print (vam->ofp, "first line");
17132     }
17133
17134   M (GPE_FWD_ENTRY_PATH_DUMP, mp);
17135
17136   /* send it... */
17137   S (mp);
17138   /* Use a control ping for synchronization */
17139   MPING (CONTROL_PING, mp_ping);
17140   S (mp_ping);
17141
17142   /* Wait for a reply... */
17143   W (ret);
17144   return ret;
17145 }
17146
17147 static int
17148 api_one_get_map_request_itr_rlocs (vat_main_t * vam)
17149 {
17150   vl_api_one_get_map_request_itr_rlocs_t *mp;
17151   int ret;
17152
17153   if (!vam->json_output)
17154     {
17155       print (vam->ofp, "%=20s", "itr-rlocs:");
17156     }
17157
17158   M (ONE_GET_MAP_REQUEST_ITR_RLOCS, mp);
17159   /* send it... */
17160   S (mp);
17161   /* Wait for a reply... */
17162   W (ret);
17163   return ret;
17164 }
17165
17166 #define api_lisp_get_map_request_itr_rlocs api_one_get_map_request_itr_rlocs
17167
17168 static int
17169 api_af_packet_create (vat_main_t * vam)
17170 {
17171   unformat_input_t *i = vam->input;
17172   vl_api_af_packet_create_t *mp;
17173   u8 *host_if_name = 0;
17174   u8 hw_addr[6];
17175   u8 random_hw_addr = 1;
17176   int ret;
17177
17178   clib_memset (hw_addr, 0, sizeof (hw_addr));
17179
17180   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17181     {
17182       if (unformat (i, "name %s", &host_if_name))
17183         vec_add1 (host_if_name, 0);
17184       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
17185         random_hw_addr = 0;
17186       else
17187         break;
17188     }
17189
17190   if (!vec_len (host_if_name))
17191     {
17192       errmsg ("host-interface name must be specified");
17193       return -99;
17194     }
17195
17196   if (vec_len (host_if_name) > 64)
17197     {
17198       errmsg ("host-interface name too long");
17199       return -99;
17200     }
17201
17202   M (AF_PACKET_CREATE, mp);
17203
17204   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
17205   clib_memcpy (mp->hw_addr, hw_addr, 6);
17206   mp->use_random_hw_addr = random_hw_addr;
17207   vec_free (host_if_name);
17208
17209   S (mp);
17210
17211   /* *INDENT-OFF* */
17212   W2 (ret,
17213       ({
17214         if (ret == 0)
17215           fprintf (vam->ofp ? vam->ofp : stderr,
17216                    " new sw_if_index = %d\n", vam->sw_if_index);
17217       }));
17218   /* *INDENT-ON* */
17219   return ret;
17220 }
17221
17222 static int
17223 api_af_packet_delete (vat_main_t * vam)
17224 {
17225   unformat_input_t *i = vam->input;
17226   vl_api_af_packet_delete_t *mp;
17227   u8 *host_if_name = 0;
17228   int ret;
17229
17230   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17231     {
17232       if (unformat (i, "name %s", &host_if_name))
17233         vec_add1 (host_if_name, 0);
17234       else
17235         break;
17236     }
17237
17238   if (!vec_len (host_if_name))
17239     {
17240       errmsg ("host-interface name must be specified");
17241       return -99;
17242     }
17243
17244   if (vec_len (host_if_name) > 64)
17245     {
17246       errmsg ("host-interface name too long");
17247       return -99;
17248     }
17249
17250   M (AF_PACKET_DELETE, mp);
17251
17252   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
17253   vec_free (host_if_name);
17254
17255   S (mp);
17256   W (ret);
17257   return ret;
17258 }
17259
17260 static void vl_api_af_packet_details_t_handler
17261   (vl_api_af_packet_details_t * mp)
17262 {
17263   vat_main_t *vam = &vat_main;
17264
17265   print (vam->ofp, "%-16s %d",
17266          mp->host_if_name, clib_net_to_host_u32 (mp->sw_if_index));
17267 }
17268
17269 static void vl_api_af_packet_details_t_handler_json
17270   (vl_api_af_packet_details_t * mp)
17271 {
17272   vat_main_t *vam = &vat_main;
17273   vat_json_node_t *node = NULL;
17274
17275   if (VAT_JSON_ARRAY != vam->json_tree.type)
17276     {
17277       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17278       vat_json_init_array (&vam->json_tree);
17279     }
17280   node = vat_json_array_add (&vam->json_tree);
17281
17282   vat_json_init_object (node);
17283   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
17284   vat_json_object_add_string_copy (node, "dev_name", mp->host_if_name);
17285 }
17286
17287 static int
17288 api_af_packet_dump (vat_main_t * vam)
17289 {
17290   vl_api_af_packet_dump_t *mp;
17291   vl_api_control_ping_t *mp_ping;
17292   int ret;
17293
17294   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
17295   /* Get list of tap interfaces */
17296   M (AF_PACKET_DUMP, mp);
17297   S (mp);
17298
17299   /* Use a control ping for synchronization */
17300   MPING (CONTROL_PING, mp_ping);
17301   S (mp_ping);
17302
17303   W (ret);
17304   return ret;
17305 }
17306
17307 static int
17308 api_policer_add_del (vat_main_t * vam)
17309 {
17310   unformat_input_t *i = vam->input;
17311   vl_api_policer_add_del_t *mp;
17312   u8 is_add = 1;
17313   u8 *name = 0;
17314   u32 cir = 0;
17315   u32 eir = 0;
17316   u64 cb = 0;
17317   u64 eb = 0;
17318   u8 rate_type = 0;
17319   u8 round_type = 0;
17320   u8 type = 0;
17321   u8 color_aware = 0;
17322   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
17323   int ret;
17324
17325   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
17326   conform_action.dscp = 0;
17327   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
17328   exceed_action.dscp = 0;
17329   violate_action.action_type = SSE2_QOS_ACTION_DROP;
17330   violate_action.dscp = 0;
17331
17332   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17333     {
17334       if (unformat (i, "del"))
17335         is_add = 0;
17336       else if (unformat (i, "name %s", &name))
17337         vec_add1 (name, 0);
17338       else if (unformat (i, "cir %u", &cir))
17339         ;
17340       else if (unformat (i, "eir %u", &eir))
17341         ;
17342       else if (unformat (i, "cb %u", &cb))
17343         ;
17344       else if (unformat (i, "eb %u", &eb))
17345         ;
17346       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
17347                          &rate_type))
17348         ;
17349       else if (unformat (i, "round_type %U", unformat_policer_round_type,
17350                          &round_type))
17351         ;
17352       else if (unformat (i, "type %U", unformat_policer_type, &type))
17353         ;
17354       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
17355                          &conform_action))
17356         ;
17357       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
17358                          &exceed_action))
17359         ;
17360       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
17361                          &violate_action))
17362         ;
17363       else if (unformat (i, "color-aware"))
17364         color_aware = 1;
17365       else
17366         break;
17367     }
17368
17369   if (!vec_len (name))
17370     {
17371       errmsg ("policer name must be specified");
17372       return -99;
17373     }
17374
17375   if (vec_len (name) > 64)
17376     {
17377       errmsg ("policer name too long");
17378       return -99;
17379     }
17380
17381   M (POLICER_ADD_DEL, mp);
17382
17383   clib_memcpy (mp->name, name, vec_len (name));
17384   vec_free (name);
17385   mp->is_add = is_add;
17386   mp->cir = ntohl (cir);
17387   mp->eir = ntohl (eir);
17388   mp->cb = clib_net_to_host_u64 (cb);
17389   mp->eb = clib_net_to_host_u64 (eb);
17390   mp->rate_type = rate_type;
17391   mp->round_type = round_type;
17392   mp->type = type;
17393   mp->conform_action_type = conform_action.action_type;
17394   mp->conform_dscp = conform_action.dscp;
17395   mp->exceed_action_type = exceed_action.action_type;
17396   mp->exceed_dscp = exceed_action.dscp;
17397   mp->violate_action_type = violate_action.action_type;
17398   mp->violate_dscp = violate_action.dscp;
17399   mp->color_aware = color_aware;
17400
17401   S (mp);
17402   W (ret);
17403   return ret;
17404 }
17405
17406 static int
17407 api_policer_dump (vat_main_t * vam)
17408 {
17409   unformat_input_t *i = vam->input;
17410   vl_api_policer_dump_t *mp;
17411   vl_api_control_ping_t *mp_ping;
17412   u8 *match_name = 0;
17413   u8 match_name_valid = 0;
17414   int ret;
17415
17416   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17417     {
17418       if (unformat (i, "name %s", &match_name))
17419         {
17420           vec_add1 (match_name, 0);
17421           match_name_valid = 1;
17422         }
17423       else
17424         break;
17425     }
17426
17427   M (POLICER_DUMP, mp);
17428   mp->match_name_valid = match_name_valid;
17429   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
17430   vec_free (match_name);
17431   /* send it... */
17432   S (mp);
17433
17434   /* Use a control ping for synchronization */
17435   MPING (CONTROL_PING, mp_ping);
17436   S (mp_ping);
17437
17438   /* Wait for a reply... */
17439   W (ret);
17440   return ret;
17441 }
17442
17443 static int
17444 api_policer_classify_set_interface (vat_main_t * vam)
17445 {
17446   unformat_input_t *i = vam->input;
17447   vl_api_policer_classify_set_interface_t *mp;
17448   u32 sw_if_index;
17449   int sw_if_index_set;
17450   u32 ip4_table_index = ~0;
17451   u32 ip6_table_index = ~0;
17452   u32 l2_table_index = ~0;
17453   u8 is_add = 1;
17454   int ret;
17455
17456   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17457     {
17458       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17459         sw_if_index_set = 1;
17460       else if (unformat (i, "sw_if_index %d", &sw_if_index))
17461         sw_if_index_set = 1;
17462       else if (unformat (i, "del"))
17463         is_add = 0;
17464       else if (unformat (i, "ip4-table %d", &ip4_table_index))
17465         ;
17466       else if (unformat (i, "ip6-table %d", &ip6_table_index))
17467         ;
17468       else if (unformat (i, "l2-table %d", &l2_table_index))
17469         ;
17470       else
17471         {
17472           clib_warning ("parse error '%U'", format_unformat_error, i);
17473           return -99;
17474         }
17475     }
17476
17477   if (sw_if_index_set == 0)
17478     {
17479       errmsg ("missing interface name or sw_if_index");
17480       return -99;
17481     }
17482
17483   M (POLICER_CLASSIFY_SET_INTERFACE, mp);
17484
17485   mp->sw_if_index = ntohl (sw_if_index);
17486   mp->ip4_table_index = ntohl (ip4_table_index);
17487   mp->ip6_table_index = ntohl (ip6_table_index);
17488   mp->l2_table_index = ntohl (l2_table_index);
17489   mp->is_add = is_add;
17490
17491   S (mp);
17492   W (ret);
17493   return ret;
17494 }
17495
17496 static int
17497 api_policer_classify_dump (vat_main_t * vam)
17498 {
17499   unformat_input_t *i = vam->input;
17500   vl_api_policer_classify_dump_t *mp;
17501   vl_api_control_ping_t *mp_ping;
17502   u8 type = POLICER_CLASSIFY_N_TABLES;
17503   int ret;
17504
17505   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
17506     ;
17507   else
17508     {
17509       errmsg ("classify table type must be specified");
17510       return -99;
17511     }
17512
17513   if (!vam->json_output)
17514     {
17515       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
17516     }
17517
17518   M (POLICER_CLASSIFY_DUMP, mp);
17519   mp->type = type;
17520   /* send it... */
17521   S (mp);
17522
17523   /* Use a control ping for synchronization */
17524   MPING (CONTROL_PING, mp_ping);
17525   S (mp_ping);
17526
17527   /* Wait for a reply... */
17528   W (ret);
17529   return ret;
17530 }
17531
17532 static u8 *
17533 format_fib_api_path_nh_proto (u8 * s, va_list * args)
17534 {
17535   vl_api_fib_path_nh_proto_t proto =
17536     va_arg (*args, vl_api_fib_path_nh_proto_t);
17537
17538   switch (proto)
17539     {
17540     case FIB_API_PATH_NH_PROTO_IP4:
17541       s = format (s, "ip4");
17542       break;
17543     case FIB_API_PATH_NH_PROTO_IP6:
17544       s = format (s, "ip6");
17545       break;
17546     case FIB_API_PATH_NH_PROTO_MPLS:
17547       s = format (s, "mpls");
17548       break;
17549     case FIB_API_PATH_NH_PROTO_BIER:
17550       s = format (s, "bier");
17551       break;
17552     case FIB_API_PATH_NH_PROTO_ETHERNET:
17553       s = format (s, "ethernet");
17554       break;
17555     }
17556
17557   return (s);
17558 }
17559
17560 static u8 *
17561 format_vl_api_ip_address_union (u8 * s, va_list * args)
17562 {
17563   vl_api_address_family_t af = va_arg (*args, vl_api_address_family_t);
17564   const vl_api_address_union_t *u = va_arg (*args, vl_api_address_union_t *);
17565
17566   switch (af)
17567     {
17568     case ADDRESS_IP4:
17569       s = format (s, "%U", format_ip4_address, u->ip4);
17570       break;
17571     case ADDRESS_IP6:
17572       s = format (s, "%U", format_ip6_address, u->ip6);
17573       break;
17574     }
17575   return (s);
17576 }
17577
17578 static u8 *
17579 format_vl_api_fib_path_type (u8 * s, va_list * args)
17580 {
17581   vl_api_fib_path_type_t t = va_arg (*args, vl_api_fib_path_type_t);
17582
17583   switch (t)
17584     {
17585     case FIB_API_PATH_TYPE_NORMAL:
17586       s = format (s, "normal");
17587       break;
17588     case FIB_API_PATH_TYPE_LOCAL:
17589       s = format (s, "local");
17590       break;
17591     case FIB_API_PATH_TYPE_DROP:
17592       s = format (s, "drop");
17593       break;
17594     case FIB_API_PATH_TYPE_UDP_ENCAP:
17595       s = format (s, "udp-encap");
17596       break;
17597     case FIB_API_PATH_TYPE_BIER_IMP:
17598       s = format (s, "bier-imp");
17599       break;
17600     case FIB_API_PATH_TYPE_ICMP_UNREACH:
17601       s = format (s, "unreach");
17602       break;
17603     case FIB_API_PATH_TYPE_ICMP_PROHIBIT:
17604       s = format (s, "prohibit");
17605       break;
17606     case FIB_API_PATH_TYPE_SOURCE_LOOKUP:
17607       s = format (s, "src-lookup");
17608       break;
17609     case FIB_API_PATH_TYPE_DVR:
17610       s = format (s, "dvr");
17611       break;
17612     case FIB_API_PATH_TYPE_INTERFACE_RX:
17613       s = format (s, "interface-rx");
17614       break;
17615     case FIB_API_PATH_TYPE_CLASSIFY:
17616       s = format (s, "classify");
17617       break;
17618     }
17619
17620   return (s);
17621 }
17622
17623 static void
17624 vl_api_fib_path_print (vat_main_t * vam, vl_api_fib_path_t * fp)
17625 {
17626   print (vam->ofp,
17627          "  weight %d, sw_if_index %d, type %U, afi %U, next_hop %U",
17628          ntohl (fp->weight), ntohl (fp->sw_if_index),
17629          format_vl_api_fib_path_type, fp->type,
17630          format_fib_api_path_nh_proto, fp->proto,
17631          format_vl_api_ip_address_union, &fp->nh.address);
17632 }
17633
17634 static void
17635 vl_api_mpls_fib_path_json_print (vat_json_node_t * node,
17636                                  vl_api_fib_path_t * fp)
17637 {
17638   struct in_addr ip4;
17639   struct in6_addr ip6;
17640
17641   vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
17642   vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
17643   vat_json_object_add_uint (node, "type", fp->type);
17644   vat_json_object_add_uint (node, "next_hop_proto", fp->proto);
17645   if (fp->proto == FIB_API_PATH_NH_PROTO_IP4)
17646     {
17647       clib_memcpy (&ip4, &fp->nh.address.ip4, sizeof (ip4));
17648       vat_json_object_add_ip4 (node, "next_hop", ip4);
17649     }
17650   else if (fp->proto == FIB_API_PATH_NH_PROTO_IP4)
17651     {
17652       clib_memcpy (&ip6, &fp->nh.address.ip6, sizeof (ip6));
17653       vat_json_object_add_ip6 (node, "next_hop", ip6);
17654     }
17655 }
17656
17657 static void
17658 vl_api_mpls_tunnel_details_t_handler (vl_api_mpls_tunnel_details_t * mp)
17659 {
17660   vat_main_t *vam = &vat_main;
17661   int count = ntohl (mp->mt_tunnel.mt_n_paths);
17662   vl_api_fib_path_t *fp;
17663   i32 i;
17664
17665   print (vam->ofp, "sw_if_index %d via:",
17666          ntohl (mp->mt_tunnel.mt_sw_if_index));
17667   fp = mp->mt_tunnel.mt_paths;
17668   for (i = 0; i < count; i++)
17669     {
17670       vl_api_fib_path_print (vam, fp);
17671       fp++;
17672     }
17673
17674   print (vam->ofp, "");
17675 }
17676
17677 #define vl_api_mpls_tunnel_details_t_endian vl_noop_handler
17678 #define vl_api_mpls_tunnel_details_t_print vl_noop_handler
17679
17680 static void
17681 vl_api_mpls_tunnel_details_t_handler_json (vl_api_mpls_tunnel_details_t * mp)
17682 {
17683   vat_main_t *vam = &vat_main;
17684   vat_json_node_t *node = NULL;
17685   int count = ntohl (mp->mt_tunnel.mt_n_paths);
17686   vl_api_fib_path_t *fp;
17687   i32 i;
17688
17689   if (VAT_JSON_ARRAY != vam->json_tree.type)
17690     {
17691       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17692       vat_json_init_array (&vam->json_tree);
17693     }
17694   node = vat_json_array_add (&vam->json_tree);
17695
17696   vat_json_init_object (node);
17697   vat_json_object_add_uint (node, "sw_if_index",
17698                             ntohl (mp->mt_tunnel.mt_sw_if_index));
17699
17700   vat_json_object_add_uint (node, "l2_only", mp->mt_tunnel.mt_l2_only);
17701
17702   fp = mp->mt_tunnel.mt_paths;
17703   for (i = 0; i < count; i++)
17704     {
17705       vl_api_mpls_fib_path_json_print (node, fp);
17706       fp++;
17707     }
17708 }
17709
17710 static int
17711 api_mpls_tunnel_dump (vat_main_t * vam)
17712 {
17713   vl_api_mpls_tunnel_dump_t *mp;
17714   vl_api_control_ping_t *mp_ping;
17715   int ret;
17716
17717   M (MPLS_TUNNEL_DUMP, mp);
17718
17719   S (mp);
17720
17721   /* Use a control ping for synchronization */
17722   MPING (CONTROL_PING, mp_ping);
17723   S (mp_ping);
17724
17725   W (ret);
17726   return ret;
17727 }
17728
17729 #define vl_api_mpls_table_details_t_endian vl_noop_handler
17730 #define vl_api_mpls_table_details_t_print vl_noop_handler
17731
17732
17733 static void
17734 vl_api_mpls_table_details_t_handler (vl_api_mpls_table_details_t * mp)
17735 {
17736   vat_main_t *vam = &vat_main;
17737
17738   print (vam->ofp, "table-id %d,", ntohl (mp->mt_table.mt_table_id));
17739 }
17740
17741 static void vl_api_mpls_table_details_t_handler_json
17742   (vl_api_mpls_table_details_t * mp)
17743 {
17744   vat_main_t *vam = &vat_main;
17745   vat_json_node_t *node = NULL;
17746
17747   if (VAT_JSON_ARRAY != vam->json_tree.type)
17748     {
17749       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17750       vat_json_init_array (&vam->json_tree);
17751     }
17752   node = vat_json_array_add (&vam->json_tree);
17753
17754   vat_json_init_object (node);
17755   vat_json_object_add_uint (node, "table", ntohl (mp->mt_table.mt_table_id));
17756 }
17757
17758 static int
17759 api_mpls_table_dump (vat_main_t * vam)
17760 {
17761   vl_api_mpls_table_dump_t *mp;
17762   vl_api_control_ping_t *mp_ping;
17763   int ret;
17764
17765   M (MPLS_TABLE_DUMP, mp);
17766   S (mp);
17767
17768   /* Use a control ping for synchronization */
17769   MPING (CONTROL_PING, mp_ping);
17770   S (mp_ping);
17771
17772   W (ret);
17773   return ret;
17774 }
17775
17776 #define vl_api_mpls_route_details_t_endian vl_noop_handler
17777 #define vl_api_mpls_route_details_t_print vl_noop_handler
17778
17779 static void
17780 vl_api_mpls_route_details_t_handler (vl_api_mpls_route_details_t * mp)
17781 {
17782   vat_main_t *vam = &vat_main;
17783   int count = (int) clib_net_to_host_u32 (mp->mr_route.mr_n_paths);
17784   vl_api_fib_path_t *fp;
17785   int i;
17786
17787   print (vam->ofp,
17788          "table-id %d, label %u, ess_bit %u",
17789          ntohl (mp->mr_route.mr_table_id),
17790          ntohl (mp->mr_route.mr_label), mp->mr_route.mr_eos);
17791   fp = mp->mr_route.mr_paths;
17792   for (i = 0; i < count; i++)
17793     {
17794       vl_api_fib_path_print (vam, fp);
17795       fp++;
17796     }
17797 }
17798
17799 static void vl_api_mpls_route_details_t_handler_json
17800   (vl_api_mpls_route_details_t * mp)
17801 {
17802   vat_main_t *vam = &vat_main;
17803   int count = (int) clib_host_to_net_u32 (mp->mr_route.mr_n_paths);
17804   vat_json_node_t *node = NULL;
17805   vl_api_fib_path_t *fp;
17806   int i;
17807
17808   if (VAT_JSON_ARRAY != vam->json_tree.type)
17809     {
17810       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17811       vat_json_init_array (&vam->json_tree);
17812     }
17813   node = vat_json_array_add (&vam->json_tree);
17814
17815   vat_json_init_object (node);
17816   vat_json_object_add_uint (node, "table", ntohl (mp->mr_route.mr_table_id));
17817   vat_json_object_add_uint (node, "s_bit", mp->mr_route.mr_eos);
17818   vat_json_object_add_uint (node, "label", ntohl (mp->mr_route.mr_label));
17819   vat_json_object_add_uint (node, "path_count", count);
17820   fp = mp->mr_route.mr_paths;
17821   for (i = 0; i < count; i++)
17822     {
17823       vl_api_mpls_fib_path_json_print (node, fp);
17824       fp++;
17825     }
17826 }
17827
17828 static int
17829 api_mpls_route_dump (vat_main_t * vam)
17830 {
17831   unformat_input_t *input = vam->input;
17832   vl_api_mpls_route_dump_t *mp;
17833   vl_api_control_ping_t *mp_ping;
17834   u32 table_id;
17835   int ret;
17836
17837   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17838     {
17839       if (unformat (input, "table_id %d", &table_id))
17840         ;
17841       else
17842         break;
17843     }
17844   if (table_id == ~0)
17845     {
17846       errmsg ("missing table id");
17847       return -99;
17848     }
17849
17850   M (MPLS_ROUTE_DUMP, mp);
17851
17852   mp->table.mt_table_id = ntohl (table_id);
17853   S (mp);
17854
17855   /* Use a control ping for synchronization */
17856   MPING (CONTROL_PING, mp_ping);
17857   S (mp_ping);
17858
17859   W (ret);
17860   return ret;
17861 }
17862
17863 #define vl_api_ip_table_details_t_endian vl_noop_handler
17864 #define vl_api_ip_table_details_t_print vl_noop_handler
17865
17866 static void
17867 vl_api_ip_table_details_t_handler (vl_api_ip_table_details_t * mp)
17868 {
17869   vat_main_t *vam = &vat_main;
17870
17871   print (vam->ofp,
17872          "%s; table-id %d, prefix %U/%d",
17873          mp->table.name, ntohl (mp->table.table_id));
17874 }
17875
17876
17877 static void vl_api_ip_table_details_t_handler_json
17878   (vl_api_ip_table_details_t * mp)
17879 {
17880   vat_main_t *vam = &vat_main;
17881   vat_json_node_t *node = NULL;
17882
17883   if (VAT_JSON_ARRAY != vam->json_tree.type)
17884     {
17885       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17886       vat_json_init_array (&vam->json_tree);
17887     }
17888   node = vat_json_array_add (&vam->json_tree);
17889
17890   vat_json_init_object (node);
17891   vat_json_object_add_uint (node, "table", ntohl (mp->table.table_id));
17892 }
17893
17894 static int
17895 api_ip_table_dump (vat_main_t * vam)
17896 {
17897   vl_api_ip_table_dump_t *mp;
17898   vl_api_control_ping_t *mp_ping;
17899   int ret;
17900
17901   M (IP_TABLE_DUMP, mp);
17902   S (mp);
17903
17904   /* Use a control ping for synchronization */
17905   MPING (CONTROL_PING, mp_ping);
17906   S (mp_ping);
17907
17908   W (ret);
17909   return ret;
17910 }
17911
17912 static int
17913 api_ip_mtable_dump (vat_main_t * vam)
17914 {
17915   vl_api_ip_mtable_dump_t *mp;
17916   vl_api_control_ping_t *mp_ping;
17917   int ret;
17918
17919   M (IP_MTABLE_DUMP, mp);
17920   S (mp);
17921
17922   /* Use a control ping for synchronization */
17923   MPING (CONTROL_PING, mp_ping);
17924   S (mp_ping);
17925
17926   W (ret);
17927   return ret;
17928 }
17929
17930 static int
17931 api_ip_mroute_dump (vat_main_t * vam)
17932 {
17933   unformat_input_t *input = vam->input;
17934   vl_api_control_ping_t *mp_ping;
17935   vl_api_ip_mroute_dump_t *mp;
17936   int ret, is_ip6;
17937   u32 table_id;
17938
17939   is_ip6 = 0;
17940   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17941     {
17942       if (unformat (input, "table_id %d", &table_id))
17943         ;
17944       else if (unformat (input, "ip6"))
17945         is_ip6 = 1;
17946       else if (unformat (input, "ip4"))
17947         is_ip6 = 0;
17948       else
17949         break;
17950     }
17951   if (table_id == ~0)
17952     {
17953       errmsg ("missing table id");
17954       return -99;
17955     }
17956
17957   M (IP_MROUTE_DUMP, mp);
17958   mp->table.table_id = table_id;
17959   mp->table.is_ip6 = is_ip6;
17960   S (mp);
17961
17962   /* Use a control ping for synchronization */
17963   MPING (CONTROL_PING, mp_ping);
17964   S (mp_ping);
17965
17966   W (ret);
17967   return ret;
17968 }
17969
17970 #define vl_api_ip_route_details_t_endian vl_noop_handler
17971 #define vl_api_ip_route_details_t_print vl_noop_handler
17972
17973 static void
17974 vl_api_ip_route_details_t_handler (vl_api_ip_route_details_t * mp)
17975 {
17976   vat_main_t *vam = &vat_main;
17977   u8 count = mp->route.n_paths;
17978   vl_api_fib_path_t *fp;
17979   int i;
17980
17981   print (vam->ofp,
17982          "table-id %d, prefix %U/%d",
17983          ntohl (mp->route.table_id),
17984          format_ip46_address, mp->route.prefix.address, mp->route.prefix.len);
17985   for (i = 0; i < count; i++)
17986     {
17987       fp = &mp->route.paths[i];
17988
17989       vl_api_fib_path_print (vam, fp);
17990       fp++;
17991     }
17992 }
17993
17994 static void vl_api_ip_route_details_t_handler_json
17995   (vl_api_ip_route_details_t * mp)
17996 {
17997   vat_main_t *vam = &vat_main;
17998   u8 count = mp->route.n_paths;
17999   vat_json_node_t *node = NULL;
18000   struct in_addr ip4;
18001   struct in6_addr ip6;
18002   vl_api_fib_path_t *fp;
18003   int i;
18004
18005   if (VAT_JSON_ARRAY != vam->json_tree.type)
18006     {
18007       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18008       vat_json_init_array (&vam->json_tree);
18009     }
18010   node = vat_json_array_add (&vam->json_tree);
18011
18012   vat_json_init_object (node);
18013   vat_json_object_add_uint (node, "table", ntohl (mp->route.table_id));
18014   if (ADDRESS_IP6 == mp->route.prefix.address.af)
18015     {
18016       clib_memcpy (&ip6, &mp->route.prefix.address.un.ip6, sizeof (ip6));
18017       vat_json_object_add_ip6 (node, "prefix", ip6);
18018     }
18019   else
18020     {
18021       clib_memcpy (&ip4, &mp->route.prefix.address.un.ip4, sizeof (ip4));
18022       vat_json_object_add_ip4 (node, "prefix", ip4);
18023     }
18024   vat_json_object_add_uint (node, "mask_length", mp->route.prefix.len);
18025   vat_json_object_add_uint (node, "path_count", count);
18026   for (i = 0; i < count; i++)
18027     {
18028       fp = &mp->route.paths[i];
18029       vl_api_mpls_fib_path_json_print (node, fp);
18030     }
18031 }
18032
18033 static int
18034 api_ip_route_dump (vat_main_t * vam)
18035 {
18036   unformat_input_t *input = vam->input;
18037   vl_api_ip_route_dump_t *mp;
18038   vl_api_control_ping_t *mp_ping;
18039   u32 table_id;
18040   u8 is_ip6;
18041   int ret;
18042
18043   is_ip6 = 0;
18044   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18045     {
18046       if (unformat (input, "table_id %d", &table_id))
18047         ;
18048       else if (unformat (input, "ip6"))
18049         is_ip6 = 1;
18050       else if (unformat (input, "ip4"))
18051         is_ip6 = 0;
18052       else
18053         break;
18054     }
18055   if (table_id == ~0)
18056     {
18057       errmsg ("missing table id");
18058       return -99;
18059     }
18060
18061   M (IP_ROUTE_DUMP, mp);
18062
18063   mp->table.table_id = table_id;
18064   mp->table.is_ip6 = is_ip6;
18065
18066   S (mp);
18067
18068   /* Use a control ping for synchronization */
18069   MPING (CONTROL_PING, mp_ping);
18070   S (mp_ping);
18071
18072   W (ret);
18073   return ret;
18074 }
18075
18076 int
18077 api_classify_table_ids (vat_main_t * vam)
18078 {
18079   vl_api_classify_table_ids_t *mp;
18080   int ret;
18081
18082   /* Construct the API message */
18083   M (CLASSIFY_TABLE_IDS, mp);
18084   mp->context = 0;
18085
18086   S (mp);
18087   W (ret);
18088   return ret;
18089 }
18090
18091 int
18092 api_classify_table_by_interface (vat_main_t * vam)
18093 {
18094   unformat_input_t *input = vam->input;
18095   vl_api_classify_table_by_interface_t *mp;
18096
18097   u32 sw_if_index = ~0;
18098   int ret;
18099   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18100     {
18101       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18102         ;
18103       else if (unformat (input, "sw_if_index %d", &sw_if_index))
18104         ;
18105       else
18106         break;
18107     }
18108   if (sw_if_index == ~0)
18109     {
18110       errmsg ("missing interface name or sw_if_index");
18111       return -99;
18112     }
18113
18114   /* Construct the API message */
18115   M (CLASSIFY_TABLE_BY_INTERFACE, mp);
18116   mp->context = 0;
18117   mp->sw_if_index = ntohl (sw_if_index);
18118
18119   S (mp);
18120   W (ret);
18121   return ret;
18122 }
18123
18124 int
18125 api_classify_table_info (vat_main_t * vam)
18126 {
18127   unformat_input_t *input = vam->input;
18128   vl_api_classify_table_info_t *mp;
18129
18130   u32 table_id = ~0;
18131   int ret;
18132   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18133     {
18134       if (unformat (input, "table_id %d", &table_id))
18135         ;
18136       else
18137         break;
18138     }
18139   if (table_id == ~0)
18140     {
18141       errmsg ("missing table id");
18142       return -99;
18143     }
18144
18145   /* Construct the API message */
18146   M (CLASSIFY_TABLE_INFO, mp);
18147   mp->context = 0;
18148   mp->table_id = ntohl (table_id);
18149
18150   S (mp);
18151   W (ret);
18152   return ret;
18153 }
18154
18155 int
18156 api_classify_session_dump (vat_main_t * vam)
18157 {
18158   unformat_input_t *input = vam->input;
18159   vl_api_classify_session_dump_t *mp;
18160   vl_api_control_ping_t *mp_ping;
18161
18162   u32 table_id = ~0;
18163   int ret;
18164   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18165     {
18166       if (unformat (input, "table_id %d", &table_id))
18167         ;
18168       else
18169         break;
18170     }
18171   if (table_id == ~0)
18172     {
18173       errmsg ("missing table id");
18174       return -99;
18175     }
18176
18177   /* Construct the API message */
18178   M (CLASSIFY_SESSION_DUMP, mp);
18179   mp->context = 0;
18180   mp->table_id = ntohl (table_id);
18181   S (mp);
18182
18183   /* Use a control ping for synchronization */
18184   MPING (CONTROL_PING, mp_ping);
18185   S (mp_ping);
18186
18187   W (ret);
18188   return ret;
18189 }
18190
18191 static void
18192 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
18193 {
18194   vat_main_t *vam = &vat_main;
18195
18196   print (vam->ofp, "collector_address %U, collector_port %d, "
18197          "src_address %U, vrf_id %d, path_mtu %u, "
18198          "template_interval %u, udp_checksum %d",
18199          format_ip4_address, mp->collector_address,
18200          ntohs (mp->collector_port),
18201          format_ip4_address, mp->src_address,
18202          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
18203          ntohl (mp->template_interval), mp->udp_checksum);
18204
18205   vam->retval = 0;
18206   vam->result_ready = 1;
18207 }
18208
18209 static void
18210   vl_api_ipfix_exporter_details_t_handler_json
18211   (vl_api_ipfix_exporter_details_t * mp)
18212 {
18213   vat_main_t *vam = &vat_main;
18214   vat_json_node_t node;
18215   struct in_addr collector_address;
18216   struct in_addr src_address;
18217
18218   vat_json_init_object (&node);
18219   clib_memcpy (&collector_address, &mp->collector_address,
18220                sizeof (collector_address));
18221   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
18222   vat_json_object_add_uint (&node, "collector_port",
18223                             ntohs (mp->collector_port));
18224   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
18225   vat_json_object_add_ip4 (&node, "src_address", src_address);
18226   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
18227   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
18228   vat_json_object_add_uint (&node, "template_interval",
18229                             ntohl (mp->template_interval));
18230   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
18231
18232   vat_json_print (vam->ofp, &node);
18233   vat_json_free (&node);
18234   vam->retval = 0;
18235   vam->result_ready = 1;
18236 }
18237
18238 int
18239 api_ipfix_exporter_dump (vat_main_t * vam)
18240 {
18241   vl_api_ipfix_exporter_dump_t *mp;
18242   int ret;
18243
18244   /* Construct the API message */
18245   M (IPFIX_EXPORTER_DUMP, mp);
18246   mp->context = 0;
18247
18248   S (mp);
18249   W (ret);
18250   return ret;
18251 }
18252
18253 static int
18254 api_ipfix_classify_stream_dump (vat_main_t * vam)
18255 {
18256   vl_api_ipfix_classify_stream_dump_t *mp;
18257   int ret;
18258
18259   /* Construct the API message */
18260   M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
18261   mp->context = 0;
18262
18263   S (mp);
18264   W (ret);
18265   return ret;
18266   /* NOTREACHED */
18267   return 0;
18268 }
18269
18270 static void
18271   vl_api_ipfix_classify_stream_details_t_handler
18272   (vl_api_ipfix_classify_stream_details_t * mp)
18273 {
18274   vat_main_t *vam = &vat_main;
18275   print (vam->ofp, "domain_id %d, src_port %d",
18276          ntohl (mp->domain_id), ntohs (mp->src_port));
18277   vam->retval = 0;
18278   vam->result_ready = 1;
18279 }
18280
18281 static void
18282   vl_api_ipfix_classify_stream_details_t_handler_json
18283   (vl_api_ipfix_classify_stream_details_t * mp)
18284 {
18285   vat_main_t *vam = &vat_main;
18286   vat_json_node_t node;
18287
18288   vat_json_init_object (&node);
18289   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
18290   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
18291
18292   vat_json_print (vam->ofp, &node);
18293   vat_json_free (&node);
18294   vam->retval = 0;
18295   vam->result_ready = 1;
18296 }
18297
18298 static int
18299 api_ipfix_classify_table_dump (vat_main_t * vam)
18300 {
18301   vl_api_ipfix_classify_table_dump_t *mp;
18302   vl_api_control_ping_t *mp_ping;
18303   int ret;
18304
18305   if (!vam->json_output)
18306     {
18307       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
18308              "transport_protocol");
18309     }
18310
18311   /* Construct the API message */
18312   M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
18313
18314   /* send it... */
18315   S (mp);
18316
18317   /* Use a control ping for synchronization */
18318   MPING (CONTROL_PING, mp_ping);
18319   S (mp_ping);
18320
18321   W (ret);
18322   return ret;
18323 }
18324
18325 static void
18326   vl_api_ipfix_classify_table_details_t_handler
18327   (vl_api_ipfix_classify_table_details_t * mp)
18328 {
18329   vat_main_t *vam = &vat_main;
18330   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
18331          mp->transport_protocol);
18332 }
18333
18334 static void
18335   vl_api_ipfix_classify_table_details_t_handler_json
18336   (vl_api_ipfix_classify_table_details_t * mp)
18337 {
18338   vat_json_node_t *node = NULL;
18339   vat_main_t *vam = &vat_main;
18340
18341   if (VAT_JSON_ARRAY != vam->json_tree.type)
18342     {
18343       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18344       vat_json_init_array (&vam->json_tree);
18345     }
18346
18347   node = vat_json_array_add (&vam->json_tree);
18348   vat_json_init_object (node);
18349
18350   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
18351   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
18352   vat_json_object_add_uint (node, "transport_protocol",
18353                             mp->transport_protocol);
18354 }
18355
18356 static int
18357 api_sw_interface_span_enable_disable (vat_main_t * vam)
18358 {
18359   unformat_input_t *i = vam->input;
18360   vl_api_sw_interface_span_enable_disable_t *mp;
18361   u32 src_sw_if_index = ~0;
18362   u32 dst_sw_if_index = ~0;
18363   u8 state = 3;
18364   int ret;
18365   u8 is_l2 = 0;
18366
18367   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18368     {
18369       if (unformat
18370           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
18371         ;
18372       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
18373         ;
18374       else
18375         if (unformat
18376             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
18377         ;
18378       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
18379         ;
18380       else if (unformat (i, "disable"))
18381         state = 0;
18382       else if (unformat (i, "rx"))
18383         state = 1;
18384       else if (unformat (i, "tx"))
18385         state = 2;
18386       else if (unformat (i, "both"))
18387         state = 3;
18388       else if (unformat (i, "l2"))
18389         is_l2 = 1;
18390       else
18391         break;
18392     }
18393
18394   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
18395
18396   mp->sw_if_index_from = htonl (src_sw_if_index);
18397   mp->sw_if_index_to = htonl (dst_sw_if_index);
18398   mp->state = state;
18399   mp->is_l2 = is_l2;
18400
18401   S (mp);
18402   W (ret);
18403   return ret;
18404 }
18405
18406 static void
18407 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
18408                                             * mp)
18409 {
18410   vat_main_t *vam = &vat_main;
18411   u8 *sw_if_from_name = 0;
18412   u8 *sw_if_to_name = 0;
18413   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
18414   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
18415   char *states[] = { "none", "rx", "tx", "both" };
18416   hash_pair_t *p;
18417
18418   /* *INDENT-OFF* */
18419   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
18420   ({
18421     if ((u32) p->value[0] == sw_if_index_from)
18422       {
18423         sw_if_from_name = (u8 *)(p->key);
18424         if (sw_if_to_name)
18425           break;
18426       }
18427     if ((u32) p->value[0] == sw_if_index_to)
18428       {
18429         sw_if_to_name = (u8 *)(p->key);
18430         if (sw_if_from_name)
18431           break;
18432       }
18433   }));
18434   /* *INDENT-ON* */
18435   print (vam->ofp, "%20s => %20s (%s) %s",
18436          sw_if_from_name, sw_if_to_name, states[mp->state],
18437          mp->is_l2 ? "l2" : "device");
18438 }
18439
18440 static void
18441   vl_api_sw_interface_span_details_t_handler_json
18442   (vl_api_sw_interface_span_details_t * mp)
18443 {
18444   vat_main_t *vam = &vat_main;
18445   vat_json_node_t *node = NULL;
18446   u8 *sw_if_from_name = 0;
18447   u8 *sw_if_to_name = 0;
18448   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
18449   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
18450   hash_pair_t *p;
18451
18452   /* *INDENT-OFF* */
18453   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
18454   ({
18455     if ((u32) p->value[0] == sw_if_index_from)
18456       {
18457         sw_if_from_name = (u8 *)(p->key);
18458         if (sw_if_to_name)
18459           break;
18460       }
18461     if ((u32) p->value[0] == sw_if_index_to)
18462       {
18463         sw_if_to_name = (u8 *)(p->key);
18464         if (sw_if_from_name)
18465           break;
18466       }
18467   }));
18468   /* *INDENT-ON* */
18469
18470   if (VAT_JSON_ARRAY != vam->json_tree.type)
18471     {
18472       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18473       vat_json_init_array (&vam->json_tree);
18474     }
18475   node = vat_json_array_add (&vam->json_tree);
18476
18477   vat_json_init_object (node);
18478   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
18479   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
18480   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
18481   if (0 != sw_if_to_name)
18482     {
18483       vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
18484     }
18485   vat_json_object_add_uint (node, "state", mp->state);
18486   vat_json_object_add_uint (node, "is-l2", mp->is_l2);
18487 }
18488
18489 static int
18490 api_sw_interface_span_dump (vat_main_t * vam)
18491 {
18492   unformat_input_t *input = vam->input;
18493   vl_api_sw_interface_span_dump_t *mp;
18494   vl_api_control_ping_t *mp_ping;
18495   u8 is_l2 = 0;
18496   int ret;
18497
18498   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18499     {
18500       if (unformat (input, "l2"))
18501         is_l2 = 1;
18502       else
18503         break;
18504     }
18505
18506   M (SW_INTERFACE_SPAN_DUMP, mp);
18507   mp->is_l2 = is_l2;
18508   S (mp);
18509
18510   /* Use a control ping for synchronization */
18511   MPING (CONTROL_PING, mp_ping);
18512   S (mp_ping);
18513
18514   W (ret);
18515   return ret;
18516 }
18517
18518 int
18519 api_pg_create_interface (vat_main_t * vam)
18520 {
18521   unformat_input_t *input = vam->input;
18522   vl_api_pg_create_interface_t *mp;
18523
18524   u32 if_id = ~0, gso_size = 0;
18525   u8 gso_enabled = 0;
18526   int ret;
18527   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18528     {
18529       if (unformat (input, "if_id %d", &if_id))
18530         ;
18531       else if (unformat (input, "gso-enabled"))
18532         {
18533           gso_enabled = 1;
18534           if (unformat (input, "gso-size %u", &gso_size))
18535             ;
18536           else
18537             {
18538               errmsg ("missing gso-size");
18539               return -99;
18540             }
18541         }
18542       else
18543         break;
18544     }
18545   if (if_id == ~0)
18546     {
18547       errmsg ("missing pg interface index");
18548       return -99;
18549     }
18550
18551   /* Construct the API message */
18552   M (PG_CREATE_INTERFACE, mp);
18553   mp->context = 0;
18554   mp->interface_id = ntohl (if_id);
18555   mp->gso_enabled = gso_enabled;
18556
18557   S (mp);
18558   W (ret);
18559   return ret;
18560 }
18561
18562 int
18563 api_pg_capture (vat_main_t * vam)
18564 {
18565   unformat_input_t *input = vam->input;
18566   vl_api_pg_capture_t *mp;
18567
18568   u32 if_id = ~0;
18569   u8 enable = 1;
18570   u32 count = 1;
18571   u8 pcap_file_set = 0;
18572   u8 *pcap_file = 0;
18573   int ret;
18574   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18575     {
18576       if (unformat (input, "if_id %d", &if_id))
18577         ;
18578       else if (unformat (input, "pcap %s", &pcap_file))
18579         pcap_file_set = 1;
18580       else if (unformat (input, "count %d", &count))
18581         ;
18582       else if (unformat (input, "disable"))
18583         enable = 0;
18584       else
18585         break;
18586     }
18587   if (if_id == ~0)
18588     {
18589       errmsg ("missing pg interface index");
18590       return -99;
18591     }
18592   if (pcap_file_set > 0)
18593     {
18594       if (vec_len (pcap_file) > 255)
18595         {
18596           errmsg ("pcap file name is too long");
18597           return -99;
18598         }
18599     }
18600
18601   u32 name_len = vec_len (pcap_file);
18602   /* Construct the API message */
18603   M (PG_CAPTURE, mp);
18604   mp->context = 0;
18605   mp->interface_id = ntohl (if_id);
18606   mp->is_enabled = enable;
18607   mp->count = ntohl (count);
18608   mp->pcap_name_length = ntohl (name_len);
18609   if (pcap_file_set != 0)
18610     {
18611       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
18612     }
18613   vec_free (pcap_file);
18614
18615   S (mp);
18616   W (ret);
18617   return ret;
18618 }
18619
18620 int
18621 api_pg_enable_disable (vat_main_t * vam)
18622 {
18623   unformat_input_t *input = vam->input;
18624   vl_api_pg_enable_disable_t *mp;
18625
18626   u8 enable = 1;
18627   u8 stream_name_set = 0;
18628   u8 *stream_name = 0;
18629   int ret;
18630   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18631     {
18632       if (unformat (input, "stream %s", &stream_name))
18633         stream_name_set = 1;
18634       else if (unformat (input, "disable"))
18635         enable = 0;
18636       else
18637         break;
18638     }
18639
18640   if (stream_name_set > 0)
18641     {
18642       if (vec_len (stream_name) > 255)
18643         {
18644           errmsg ("stream name too long");
18645           return -99;
18646         }
18647     }
18648
18649   u32 name_len = vec_len (stream_name);
18650   /* Construct the API message */
18651   M (PG_ENABLE_DISABLE, mp);
18652   mp->context = 0;
18653   mp->is_enabled = enable;
18654   if (stream_name_set != 0)
18655     {
18656       mp->stream_name_length = ntohl (name_len);
18657       clib_memcpy (mp->stream_name, stream_name, name_len);
18658     }
18659   vec_free (stream_name);
18660
18661   S (mp);
18662   W (ret);
18663   return ret;
18664 }
18665
18666 int
18667 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
18668 {
18669   unformat_input_t *input = vam->input;
18670   vl_api_ip_source_and_port_range_check_add_del_t *mp;
18671
18672   u16 *low_ports = 0;
18673   u16 *high_ports = 0;
18674   u16 this_low;
18675   u16 this_hi;
18676   vl_api_prefix_t prefix;
18677   u32 tmp, tmp2;
18678   u8 prefix_set = 0;
18679   u32 vrf_id = ~0;
18680   u8 is_add = 1;
18681   int ret;
18682
18683   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18684     {
18685       if (unformat (input, "%U", unformat_vl_api_prefix, &prefix))
18686         prefix_set = 1;
18687       else if (unformat (input, "vrf %d", &vrf_id))
18688         ;
18689       else if (unformat (input, "del"))
18690         is_add = 0;
18691       else if (unformat (input, "port %d", &tmp))
18692         {
18693           if (tmp == 0 || tmp > 65535)
18694             {
18695               errmsg ("port %d out of range", tmp);
18696               return -99;
18697             }
18698           this_low = tmp;
18699           this_hi = this_low + 1;
18700           vec_add1 (low_ports, this_low);
18701           vec_add1 (high_ports, this_hi);
18702         }
18703       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
18704         {
18705           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
18706             {
18707               errmsg ("incorrect range parameters");
18708               return -99;
18709             }
18710           this_low = tmp;
18711           /* Note: in debug CLI +1 is added to high before
18712              passing to real fn that does "the work"
18713              (ip_source_and_port_range_check_add_del).
18714              This fn is a wrapper around the binary API fn a
18715              control plane will call, which expects this increment
18716              to have occurred. Hence letting the binary API control
18717              plane fn do the increment for consistency between VAT
18718              and other control planes.
18719            */
18720           this_hi = tmp2;
18721           vec_add1 (low_ports, this_low);
18722           vec_add1 (high_ports, this_hi);
18723         }
18724       else
18725         break;
18726     }
18727
18728   if (prefix_set == 0)
18729     {
18730       errmsg ("<address>/<mask> not specified");
18731       return -99;
18732     }
18733
18734   if (vrf_id == ~0)
18735     {
18736       errmsg ("VRF ID required, not specified");
18737       return -99;
18738     }
18739
18740   if (vrf_id == 0)
18741     {
18742       errmsg
18743         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
18744       return -99;
18745     }
18746
18747   if (vec_len (low_ports) == 0)
18748     {
18749       errmsg ("At least one port or port range required");
18750       return -99;
18751     }
18752
18753   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
18754
18755   mp->is_add = is_add;
18756
18757   clib_memcpy (&mp->prefix, &prefix, sizeof (prefix));
18758
18759   mp->number_of_ranges = vec_len (low_ports);
18760
18761   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
18762   vec_free (low_ports);
18763
18764   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
18765   vec_free (high_ports);
18766
18767   mp->vrf_id = ntohl (vrf_id);
18768
18769   S (mp);
18770   W (ret);
18771   return ret;
18772 }
18773
18774 int
18775 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
18776 {
18777   unformat_input_t *input = vam->input;
18778   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
18779   u32 sw_if_index = ~0;
18780   int vrf_set = 0;
18781   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
18782   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
18783   u8 is_add = 1;
18784   int ret;
18785
18786   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18787     {
18788       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18789         ;
18790       else if (unformat (input, "sw_if_index %d", &sw_if_index))
18791         ;
18792       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
18793         vrf_set = 1;
18794       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
18795         vrf_set = 1;
18796       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
18797         vrf_set = 1;
18798       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
18799         vrf_set = 1;
18800       else if (unformat (input, "del"))
18801         is_add = 0;
18802       else
18803         break;
18804     }
18805
18806   if (sw_if_index == ~0)
18807     {
18808       errmsg ("Interface required but not specified");
18809       return -99;
18810     }
18811
18812   if (vrf_set == 0)
18813     {
18814       errmsg ("VRF ID required but not specified");
18815       return -99;
18816     }
18817
18818   if (tcp_out_vrf_id == 0
18819       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
18820     {
18821       errmsg
18822         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
18823       return -99;
18824     }
18825
18826   /* Construct the API message */
18827   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
18828
18829   mp->sw_if_index = ntohl (sw_if_index);
18830   mp->is_add = is_add;
18831   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
18832   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
18833   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
18834   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
18835
18836   /* send it... */
18837   S (mp);
18838
18839   /* Wait for a reply... */
18840   W (ret);
18841   return ret;
18842 }
18843
18844 static int
18845 api_set_punt (vat_main_t * vam)
18846 {
18847   unformat_input_t *i = vam->input;
18848   vl_api_address_family_t af;
18849   vl_api_set_punt_t *mp;
18850   u32 protocol = ~0;
18851   u32 port = ~0;
18852   int is_add = 1;
18853   int ret;
18854
18855   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18856     {
18857       if (unformat (i, "%U", unformat_vl_api_address_family, &af))
18858         ;
18859       else if (unformat (i, "protocol %d", &protocol))
18860         ;
18861       else if (unformat (i, "port %d", &port))
18862         ;
18863       else if (unformat (i, "del"))
18864         is_add = 0;
18865       else
18866         {
18867           clib_warning ("parse error '%U'", format_unformat_error, i);
18868           return -99;
18869         }
18870     }
18871
18872   M (SET_PUNT, mp);
18873
18874   mp->is_add = (u8) is_add;
18875   mp->punt.type = PUNT_API_TYPE_L4;
18876   mp->punt.punt.l4.af = af;
18877   mp->punt.punt.l4.protocol = (u8) protocol;
18878   mp->punt.punt.l4.port = htons ((u16) port);
18879
18880   S (mp);
18881   W (ret);
18882   return ret;
18883 }
18884
18885 static int
18886 api_delete_subif (vat_main_t * vam)
18887 {
18888   unformat_input_t *i = vam->input;
18889   vl_api_delete_subif_t *mp;
18890   u32 sw_if_index = ~0;
18891   int ret;
18892
18893   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18894     {
18895       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18896         ;
18897       if (unformat (i, "sw_if_index %d", &sw_if_index))
18898         ;
18899       else
18900         break;
18901     }
18902
18903   if (sw_if_index == ~0)
18904     {
18905       errmsg ("missing sw_if_index");
18906       return -99;
18907     }
18908
18909   /* Construct the API message */
18910   M (DELETE_SUBIF, mp);
18911   mp->sw_if_index = ntohl (sw_if_index);
18912
18913   S (mp);
18914   W (ret);
18915   return ret;
18916 }
18917
18918 #define foreach_pbb_vtr_op      \
18919 _("disable",  L2_VTR_DISABLED)  \
18920 _("pop",  L2_VTR_POP_2)         \
18921 _("push",  L2_VTR_PUSH_2)
18922
18923 static int
18924 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
18925 {
18926   unformat_input_t *i = vam->input;
18927   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
18928   u32 sw_if_index = ~0, vtr_op = ~0;
18929   u16 outer_tag = ~0;
18930   u8 dmac[6], smac[6];
18931   u8 dmac_set = 0, smac_set = 0;
18932   u16 vlanid = 0;
18933   u32 sid = ~0;
18934   u32 tmp;
18935   int ret;
18936
18937   /* Shut up coverity */
18938   clib_memset (dmac, 0, sizeof (dmac));
18939   clib_memset (smac, 0, sizeof (smac));
18940
18941   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18942     {
18943       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18944         ;
18945       else if (unformat (i, "sw_if_index %d", &sw_if_index))
18946         ;
18947       else if (unformat (i, "vtr_op %d", &vtr_op))
18948         ;
18949 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
18950       foreach_pbb_vtr_op
18951 #undef _
18952         else if (unformat (i, "translate_pbb_stag"))
18953         {
18954           if (unformat (i, "%d", &tmp))
18955             {
18956               vtr_op = L2_VTR_TRANSLATE_2_1;
18957               outer_tag = tmp;
18958             }
18959           else
18960             {
18961               errmsg
18962                 ("translate_pbb_stag operation requires outer tag definition");
18963               return -99;
18964             }
18965         }
18966       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
18967         dmac_set++;
18968       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
18969         smac_set++;
18970       else if (unformat (i, "sid %d", &sid))
18971         ;
18972       else if (unformat (i, "vlanid %d", &tmp))
18973         vlanid = tmp;
18974       else
18975         {
18976           clib_warning ("parse error '%U'", format_unformat_error, i);
18977           return -99;
18978         }
18979     }
18980
18981   if ((sw_if_index == ~0) || (vtr_op == ~0))
18982     {
18983       errmsg ("missing sw_if_index or vtr operation");
18984       return -99;
18985     }
18986   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
18987       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
18988     {
18989       errmsg
18990         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
18991       return -99;
18992     }
18993
18994   M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
18995   mp->sw_if_index = ntohl (sw_if_index);
18996   mp->vtr_op = ntohl (vtr_op);
18997   mp->outer_tag = ntohs (outer_tag);
18998   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
18999   clib_memcpy (mp->b_smac, smac, sizeof (smac));
19000   mp->b_vlanid = ntohs (vlanid);
19001   mp->i_sid = ntohl (sid);
19002
19003   S (mp);
19004   W (ret);
19005   return ret;
19006 }
19007
19008 static int
19009 api_flow_classify_set_interface (vat_main_t * vam)
19010 {
19011   unformat_input_t *i = vam->input;
19012   vl_api_flow_classify_set_interface_t *mp;
19013   u32 sw_if_index;
19014   int sw_if_index_set;
19015   u32 ip4_table_index = ~0;
19016   u32 ip6_table_index = ~0;
19017   u8 is_add = 1;
19018   int ret;
19019
19020   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19021     {
19022       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19023         sw_if_index_set = 1;
19024       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19025         sw_if_index_set = 1;
19026       else if (unformat (i, "del"))
19027         is_add = 0;
19028       else if (unformat (i, "ip4-table %d", &ip4_table_index))
19029         ;
19030       else if (unformat (i, "ip6-table %d", &ip6_table_index))
19031         ;
19032       else
19033         {
19034           clib_warning ("parse error '%U'", format_unformat_error, i);
19035           return -99;
19036         }
19037     }
19038
19039   if (sw_if_index_set == 0)
19040     {
19041       errmsg ("missing interface name or sw_if_index");
19042       return -99;
19043     }
19044
19045   M (FLOW_CLASSIFY_SET_INTERFACE, mp);
19046
19047   mp->sw_if_index = ntohl (sw_if_index);
19048   mp->ip4_table_index = ntohl (ip4_table_index);
19049   mp->ip6_table_index = ntohl (ip6_table_index);
19050   mp->is_add = is_add;
19051
19052   S (mp);
19053   W (ret);
19054   return ret;
19055 }
19056
19057 static int
19058 api_flow_classify_dump (vat_main_t * vam)
19059 {
19060   unformat_input_t *i = vam->input;
19061   vl_api_flow_classify_dump_t *mp;
19062   vl_api_control_ping_t *mp_ping;
19063   u8 type = FLOW_CLASSIFY_N_TABLES;
19064   int ret;
19065
19066   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
19067     ;
19068   else
19069     {
19070       errmsg ("classify table type must be specified");
19071       return -99;
19072     }
19073
19074   if (!vam->json_output)
19075     {
19076       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
19077     }
19078
19079   M (FLOW_CLASSIFY_DUMP, mp);
19080   mp->type = type;
19081   /* send it... */
19082   S (mp);
19083
19084   /* Use a control ping for synchronization */
19085   MPING (CONTROL_PING, mp_ping);
19086   S (mp_ping);
19087
19088   /* Wait for a reply... */
19089   W (ret);
19090   return ret;
19091 }
19092
19093 static int
19094 api_feature_enable_disable (vat_main_t * vam)
19095 {
19096   unformat_input_t *i = vam->input;
19097   vl_api_feature_enable_disable_t *mp;
19098   u8 *arc_name = 0;
19099   u8 *feature_name = 0;
19100   u32 sw_if_index = ~0;
19101   u8 enable = 1;
19102   int ret;
19103
19104   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19105     {
19106       if (unformat (i, "arc_name %s", &arc_name))
19107         ;
19108       else if (unformat (i, "feature_name %s", &feature_name))
19109         ;
19110       else
19111         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19112         ;
19113       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19114         ;
19115       else if (unformat (i, "disable"))
19116         enable = 0;
19117       else
19118         break;
19119     }
19120
19121   if (arc_name == 0)
19122     {
19123       errmsg ("missing arc name");
19124       return -99;
19125     }
19126   if (vec_len (arc_name) > 63)
19127     {
19128       errmsg ("arc name too long");
19129     }
19130
19131   if (feature_name == 0)
19132     {
19133       errmsg ("missing feature name");
19134       return -99;
19135     }
19136   if (vec_len (feature_name) > 63)
19137     {
19138       errmsg ("feature name too long");
19139     }
19140
19141   if (sw_if_index == ~0)
19142     {
19143       errmsg ("missing interface name or sw_if_index");
19144       return -99;
19145     }
19146
19147   /* Construct the API message */
19148   M (FEATURE_ENABLE_DISABLE, mp);
19149   mp->sw_if_index = ntohl (sw_if_index);
19150   mp->enable = enable;
19151   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
19152   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
19153   vec_free (arc_name);
19154   vec_free (feature_name);
19155
19156   S (mp);
19157   W (ret);
19158   return ret;
19159 }
19160
19161 static int
19162 api_feature_gso_enable_disable (vat_main_t * vam)
19163 {
19164   unformat_input_t *i = vam->input;
19165   vl_api_feature_gso_enable_disable_t *mp;
19166   u32 sw_if_index = ~0;
19167   u8 enable = 1;
19168   int ret;
19169
19170   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19171     {
19172       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19173         ;
19174       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19175         ;
19176       else if (unformat (i, "enable"))
19177         enable = 1;
19178       else if (unformat (i, "disable"))
19179         enable = 0;
19180       else
19181         break;
19182     }
19183
19184   if (sw_if_index == ~0)
19185     {
19186       errmsg ("missing interface name or sw_if_index");
19187       return -99;
19188     }
19189
19190   /* Construct the API message */
19191   M (FEATURE_GSO_ENABLE_DISABLE, mp);
19192   mp->sw_if_index = ntohl (sw_if_index);
19193   mp->enable_disable = enable;
19194
19195   S (mp);
19196   W (ret);
19197   return ret;
19198 }
19199
19200 static int
19201 api_sw_interface_tag_add_del (vat_main_t * vam)
19202 {
19203   unformat_input_t *i = vam->input;
19204   vl_api_sw_interface_tag_add_del_t *mp;
19205   u32 sw_if_index = ~0;
19206   u8 *tag = 0;
19207   u8 enable = 1;
19208   int ret;
19209
19210   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19211     {
19212       if (unformat (i, "tag %s", &tag))
19213         ;
19214       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19215         ;
19216       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19217         ;
19218       else if (unformat (i, "del"))
19219         enable = 0;
19220       else
19221         break;
19222     }
19223
19224   if (sw_if_index == ~0)
19225     {
19226       errmsg ("missing interface name or sw_if_index");
19227       return -99;
19228     }
19229
19230   if (enable && (tag == 0))
19231     {
19232       errmsg ("no tag specified");
19233       return -99;
19234     }
19235
19236   /* Construct the API message */
19237   M (SW_INTERFACE_TAG_ADD_DEL, mp);
19238   mp->sw_if_index = ntohl (sw_if_index);
19239   mp->is_add = enable;
19240   if (enable)
19241     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
19242   vec_free (tag);
19243
19244   S (mp);
19245   W (ret);
19246   return ret;
19247 }
19248
19249 static int
19250 api_sw_interface_add_del_mac_address (vat_main_t * vam)
19251 {
19252   unformat_input_t *i = vam->input;
19253   vl_api_mac_address_t mac = { 0 };
19254   vl_api_sw_interface_add_del_mac_address_t *mp;
19255   u32 sw_if_index = ~0;
19256   u8 is_add = 1;
19257   u8 mac_set = 0;
19258   int ret;
19259
19260   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19261     {
19262       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19263         ;
19264       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19265         ;
19266       else if (unformat (i, "%U", unformat_vl_api_mac_address, &mac))
19267         mac_set++;
19268       else if (unformat (i, "del"))
19269         is_add = 0;
19270       else
19271         break;
19272     }
19273
19274   if (sw_if_index == ~0)
19275     {
19276       errmsg ("missing interface name or sw_if_index");
19277       return -99;
19278     }
19279
19280   if (!mac_set)
19281     {
19282       errmsg ("missing MAC address");
19283       return -99;
19284     }
19285
19286   /* Construct the API message */
19287   M (SW_INTERFACE_ADD_DEL_MAC_ADDRESS, mp);
19288   mp->sw_if_index = ntohl (sw_if_index);
19289   mp->is_add = is_add;
19290   clib_memcpy (&mp->addr, &mac, sizeof (mac));
19291
19292   S (mp);
19293   W (ret);
19294   return ret;
19295 }
19296
19297 static void vl_api_l2_xconnect_details_t_handler
19298   (vl_api_l2_xconnect_details_t * mp)
19299 {
19300   vat_main_t *vam = &vat_main;
19301
19302   print (vam->ofp, "%15d%15d",
19303          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
19304 }
19305
19306 static void vl_api_l2_xconnect_details_t_handler_json
19307   (vl_api_l2_xconnect_details_t * mp)
19308 {
19309   vat_main_t *vam = &vat_main;
19310   vat_json_node_t *node = NULL;
19311
19312   if (VAT_JSON_ARRAY != vam->json_tree.type)
19313     {
19314       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19315       vat_json_init_array (&vam->json_tree);
19316     }
19317   node = vat_json_array_add (&vam->json_tree);
19318
19319   vat_json_init_object (node);
19320   vat_json_object_add_uint (node, "rx_sw_if_index",
19321                             ntohl (mp->rx_sw_if_index));
19322   vat_json_object_add_uint (node, "tx_sw_if_index",
19323                             ntohl (mp->tx_sw_if_index));
19324 }
19325
19326 static int
19327 api_l2_xconnect_dump (vat_main_t * vam)
19328 {
19329   vl_api_l2_xconnect_dump_t *mp;
19330   vl_api_control_ping_t *mp_ping;
19331   int ret;
19332
19333   if (!vam->json_output)
19334     {
19335       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
19336     }
19337
19338   M (L2_XCONNECT_DUMP, mp);
19339
19340   S (mp);
19341
19342   /* Use a control ping for synchronization */
19343   MPING (CONTROL_PING, mp_ping);
19344   S (mp_ping);
19345
19346   W (ret);
19347   return ret;
19348 }
19349
19350 static int
19351 api_hw_interface_set_mtu (vat_main_t * vam)
19352 {
19353   unformat_input_t *i = vam->input;
19354   vl_api_hw_interface_set_mtu_t *mp;
19355   u32 sw_if_index = ~0;
19356   u32 mtu = 0;
19357   int ret;
19358
19359   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19360     {
19361       if (unformat (i, "mtu %d", &mtu))
19362         ;
19363       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19364         ;
19365       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19366         ;
19367       else
19368         break;
19369     }
19370
19371   if (sw_if_index == ~0)
19372     {
19373       errmsg ("missing interface name or sw_if_index");
19374       return -99;
19375     }
19376
19377   if (mtu == 0)
19378     {
19379       errmsg ("no mtu specified");
19380       return -99;
19381     }
19382
19383   /* Construct the API message */
19384   M (HW_INTERFACE_SET_MTU, mp);
19385   mp->sw_if_index = ntohl (sw_if_index);
19386   mp->mtu = ntohs ((u16) mtu);
19387
19388   S (mp);
19389   W (ret);
19390   return ret;
19391 }
19392
19393 static int
19394 api_p2p_ethernet_add (vat_main_t * vam)
19395 {
19396   unformat_input_t *i = vam->input;
19397   vl_api_p2p_ethernet_add_t *mp;
19398   u32 parent_if_index = ~0;
19399   u32 sub_id = ~0;
19400   u8 remote_mac[6];
19401   u8 mac_set = 0;
19402   int ret;
19403
19404   clib_memset (remote_mac, 0, sizeof (remote_mac));
19405   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19406     {
19407       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
19408         ;
19409       else if (unformat (i, "sw_if_index %d", &parent_if_index))
19410         ;
19411       else
19412         if (unformat
19413             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
19414         mac_set++;
19415       else if (unformat (i, "sub_id %d", &sub_id))
19416         ;
19417       else
19418         {
19419           clib_warning ("parse error '%U'", format_unformat_error, i);
19420           return -99;
19421         }
19422     }
19423
19424   if (parent_if_index == ~0)
19425     {
19426       errmsg ("missing interface name or sw_if_index");
19427       return -99;
19428     }
19429   if (mac_set == 0)
19430     {
19431       errmsg ("missing remote mac address");
19432       return -99;
19433     }
19434   if (sub_id == ~0)
19435     {
19436       errmsg ("missing sub-interface id");
19437       return -99;
19438     }
19439
19440   M (P2P_ETHERNET_ADD, mp);
19441   mp->parent_if_index = ntohl (parent_if_index);
19442   mp->subif_id = ntohl (sub_id);
19443   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
19444
19445   S (mp);
19446   W (ret);
19447   return ret;
19448 }
19449
19450 static int
19451 api_p2p_ethernet_del (vat_main_t * vam)
19452 {
19453   unformat_input_t *i = vam->input;
19454   vl_api_p2p_ethernet_del_t *mp;
19455   u32 parent_if_index = ~0;
19456   u8 remote_mac[6];
19457   u8 mac_set = 0;
19458   int ret;
19459
19460   clib_memset (remote_mac, 0, sizeof (remote_mac));
19461   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19462     {
19463       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
19464         ;
19465       else if (unformat (i, "sw_if_index %d", &parent_if_index))
19466         ;
19467       else
19468         if (unformat
19469             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
19470         mac_set++;
19471       else
19472         {
19473           clib_warning ("parse error '%U'", format_unformat_error, i);
19474           return -99;
19475         }
19476     }
19477
19478   if (parent_if_index == ~0)
19479     {
19480       errmsg ("missing interface name or sw_if_index");
19481       return -99;
19482     }
19483   if (mac_set == 0)
19484     {
19485       errmsg ("missing remote mac address");
19486       return -99;
19487     }
19488
19489   M (P2P_ETHERNET_DEL, mp);
19490   mp->parent_if_index = ntohl (parent_if_index);
19491   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
19492
19493   S (mp);
19494   W (ret);
19495   return ret;
19496 }
19497
19498 static int
19499 api_lldp_config (vat_main_t * vam)
19500 {
19501   unformat_input_t *i = vam->input;
19502   vl_api_lldp_config_t *mp;
19503   int tx_hold = 0;
19504   int tx_interval = 0;
19505   u8 *sys_name = NULL;
19506   int ret;
19507
19508   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19509     {
19510       if (unformat (i, "system-name %s", &sys_name))
19511         ;
19512       else if (unformat (i, "tx-hold %d", &tx_hold))
19513         ;
19514       else if (unformat (i, "tx-interval %d", &tx_interval))
19515         ;
19516       else
19517         {
19518           clib_warning ("parse error '%U'", format_unformat_error, i);
19519           return -99;
19520         }
19521     }
19522
19523   vec_add1 (sys_name, 0);
19524
19525   M (LLDP_CONFIG, mp);
19526   mp->tx_hold = htonl (tx_hold);
19527   mp->tx_interval = htonl (tx_interval);
19528   clib_memcpy (mp->system_name, sys_name, vec_len (sys_name));
19529   vec_free (sys_name);
19530
19531   S (mp);
19532   W (ret);
19533   return ret;
19534 }
19535
19536 static int
19537 api_sw_interface_set_lldp (vat_main_t * vam)
19538 {
19539   unformat_input_t *i = vam->input;
19540   vl_api_sw_interface_set_lldp_t *mp;
19541   u32 sw_if_index = ~0;
19542   u32 enable = 1;
19543   u8 *port_desc = NULL, *mgmt_oid = NULL;
19544   ip4_address_t ip4_addr;
19545   ip6_address_t ip6_addr;
19546   int ret;
19547
19548   clib_memset (&ip4_addr, 0, sizeof (ip4_addr));
19549   clib_memset (&ip6_addr, 0, sizeof (ip6_addr));
19550
19551   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19552     {
19553       if (unformat (i, "disable"))
19554         enable = 0;
19555       else
19556         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19557         ;
19558       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19559         ;
19560       else if (unformat (i, "port-desc %s", &port_desc))
19561         ;
19562       else if (unformat (i, "mgmt-ip4 %U", unformat_ip4_address, &ip4_addr))
19563         ;
19564       else if (unformat (i, "mgmt-ip6 %U", unformat_ip6_address, &ip6_addr))
19565         ;
19566       else if (unformat (i, "mgmt-oid %s", &mgmt_oid))
19567         ;
19568       else
19569         break;
19570     }
19571
19572   if (sw_if_index == ~0)
19573     {
19574       errmsg ("missing interface name or sw_if_index");
19575       return -99;
19576     }
19577
19578   /* Construct the API message */
19579   vec_add1 (port_desc, 0);
19580   vec_add1 (mgmt_oid, 0);
19581   M (SW_INTERFACE_SET_LLDP, mp);
19582   mp->sw_if_index = ntohl (sw_if_index);
19583   mp->enable = enable;
19584   clib_memcpy (mp->port_desc, port_desc, vec_len (port_desc));
19585   clib_memcpy (mp->mgmt_oid, mgmt_oid, vec_len (mgmt_oid));
19586   clib_memcpy (mp->mgmt_ip4, &ip4_addr, sizeof (ip4_addr));
19587   clib_memcpy (mp->mgmt_ip6, &ip6_addr, sizeof (ip6_addr));
19588   vec_free (port_desc);
19589   vec_free (mgmt_oid);
19590
19591   S (mp);
19592   W (ret);
19593   return ret;
19594 }
19595
19596 static int
19597 api_tcp_configure_src_addresses (vat_main_t * vam)
19598 {
19599   vl_api_tcp_configure_src_addresses_t *mp;
19600   unformat_input_t *i = vam->input;
19601   vl_api_address_t first, last;
19602   u8 range_set = 0;
19603   u32 vrf_id = 0;
19604   int ret;
19605
19606   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19607     {
19608       if (unformat (i, "%U - %U",
19609                     unformat_vl_api_address, &first,
19610                     unformat_vl_api_address, &last))
19611         {
19612           if (range_set)
19613             {
19614               errmsg ("one range per message (range already set)");
19615               return -99;
19616             }
19617           range_set = 1;
19618         }
19619       else if (unformat (i, "vrf %d", &vrf_id))
19620         ;
19621       else
19622         break;
19623     }
19624
19625   if (range_set == 0)
19626     {
19627       errmsg ("address range not set");
19628       return -99;
19629     }
19630
19631   M (TCP_CONFIGURE_SRC_ADDRESSES, mp);
19632
19633   mp->vrf_id = ntohl (vrf_id);
19634   clib_memcpy (&mp->first_address, &first, sizeof (first));
19635   clib_memcpy (&mp->last_address, &last, sizeof (last));
19636
19637   S (mp);
19638   W (ret);
19639   return ret;
19640 }
19641
19642 static void vl_api_app_namespace_add_del_reply_t_handler
19643   (vl_api_app_namespace_add_del_reply_t * mp)
19644 {
19645   vat_main_t *vam = &vat_main;
19646   i32 retval = ntohl (mp->retval);
19647   if (vam->async_mode)
19648     {
19649       vam->async_errors += (retval < 0);
19650     }
19651   else
19652     {
19653       vam->retval = retval;
19654       if (retval == 0)
19655         errmsg ("app ns index %d\n", ntohl (mp->appns_index));
19656       vam->result_ready = 1;
19657     }
19658 }
19659
19660 static void vl_api_app_namespace_add_del_reply_t_handler_json
19661   (vl_api_app_namespace_add_del_reply_t * mp)
19662 {
19663   vat_main_t *vam = &vat_main;
19664   vat_json_node_t node;
19665
19666   vat_json_init_object (&node);
19667   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
19668   vat_json_object_add_uint (&node, "appns_index", ntohl (mp->appns_index));
19669
19670   vat_json_print (vam->ofp, &node);
19671   vat_json_free (&node);
19672
19673   vam->retval = ntohl (mp->retval);
19674   vam->result_ready = 1;
19675 }
19676
19677 static int
19678 api_app_namespace_add_del (vat_main_t * vam)
19679 {
19680   vl_api_app_namespace_add_del_t *mp;
19681   unformat_input_t *i = vam->input;
19682   u8 *ns_id = 0, secret_set = 0, sw_if_index_set = 0;
19683   u32 sw_if_index, ip4_fib_id, ip6_fib_id;
19684   u64 secret;
19685   int ret;
19686
19687   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19688     {
19689       if (unformat (i, "id %_%v%_", &ns_id))
19690         ;
19691       else if (unformat (i, "secret %lu", &secret))
19692         secret_set = 1;
19693       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19694         sw_if_index_set = 1;
19695       else if (unformat (i, "ip4_fib_id %d", &ip4_fib_id))
19696         ;
19697       else if (unformat (i, "ip6_fib_id %d", &ip6_fib_id))
19698         ;
19699       else
19700         break;
19701     }
19702   if (!ns_id || !secret_set || !sw_if_index_set)
19703     {
19704       errmsg ("namespace id, secret and sw_if_index must be set");
19705       return -99;
19706     }
19707   if (vec_len (ns_id) > 64)
19708     {
19709       errmsg ("namespace id too long");
19710       return -99;
19711     }
19712   M (APP_NAMESPACE_ADD_DEL, mp);
19713
19714   clib_memcpy (mp->namespace_id, ns_id, vec_len (ns_id));
19715   mp->namespace_id_len = vec_len (ns_id);
19716   mp->secret = clib_host_to_net_u64 (secret);
19717   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
19718   mp->ip4_fib_id = clib_host_to_net_u32 (ip4_fib_id);
19719   mp->ip6_fib_id = clib_host_to_net_u32 (ip6_fib_id);
19720   vec_free (ns_id);
19721   S (mp);
19722   W (ret);
19723   return ret;
19724 }
19725
19726 static int
19727 api_sock_init_shm (vat_main_t * vam)
19728 {
19729 #if VPP_API_TEST_BUILTIN == 0
19730   unformat_input_t *i = vam->input;
19731   vl_api_shm_elem_config_t *config = 0;
19732   u64 size = 64 << 20;
19733   int rv;
19734
19735   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19736     {
19737       if (unformat (i, "size %U", unformat_memory_size, &size))
19738         ;
19739       else
19740         break;
19741     }
19742
19743   /*
19744    * Canned custom ring allocator config.
19745    * Should probably parse all of this
19746    */
19747   vec_validate (config, 6);
19748   config[0].type = VL_API_VLIB_RING;
19749   config[0].size = 256;
19750   config[0].count = 32;
19751
19752   config[1].type = VL_API_VLIB_RING;
19753   config[1].size = 1024;
19754   config[1].count = 16;
19755
19756   config[2].type = VL_API_VLIB_RING;
19757   config[2].size = 4096;
19758   config[2].count = 2;
19759
19760   config[3].type = VL_API_CLIENT_RING;
19761   config[3].size = 256;
19762   config[3].count = 32;
19763
19764   config[4].type = VL_API_CLIENT_RING;
19765   config[4].size = 1024;
19766   config[4].count = 16;
19767
19768   config[5].type = VL_API_CLIENT_RING;
19769   config[5].size = 4096;
19770   config[5].count = 2;
19771
19772   config[6].type = VL_API_QUEUE;
19773   config[6].count = 128;
19774   config[6].size = sizeof (uword);
19775
19776   rv = vl_socket_client_init_shm (config, 1 /* want_pthread */ );
19777   if (!rv)
19778     vam->client_index_invalid = 1;
19779   return rv;
19780 #else
19781   return -99;
19782 #endif
19783 }
19784
19785 static void
19786 vl_api_session_rules_details_t_handler (vl_api_session_rules_details_t * mp)
19787 {
19788   vat_main_t *vam = &vat_main;
19789
19790   if (mp->is_ip4)
19791     {
19792       print (vam->ofp,
19793              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
19794              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
19795              mp->scope, format_ip4_address, &mp->lcl_ip, mp->lcl_plen,
19796              clib_net_to_host_u16 (mp->lcl_port), format_ip4_address,
19797              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
19798              clib_net_to_host_u32 (mp->action_index), mp->tag);
19799     }
19800   else
19801     {
19802       print (vam->ofp,
19803              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
19804              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
19805              mp->scope, format_ip6_address, &mp->lcl_ip, mp->lcl_plen,
19806              clib_net_to_host_u16 (mp->lcl_port), format_ip6_address,
19807              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
19808              clib_net_to_host_u32 (mp->action_index), mp->tag);
19809     }
19810 }
19811
19812 static void
19813 vl_api_session_rules_details_t_handler_json (vl_api_session_rules_details_t *
19814                                              mp)
19815 {
19816   vat_main_t *vam = &vat_main;
19817   vat_json_node_t *node = NULL;
19818   struct in6_addr ip6;
19819   struct in_addr ip4;
19820
19821   if (VAT_JSON_ARRAY != vam->json_tree.type)
19822     {
19823       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19824       vat_json_init_array (&vam->json_tree);
19825     }
19826   node = vat_json_array_add (&vam->json_tree);
19827   vat_json_init_object (node);
19828
19829   vat_json_object_add_uint (node, "is_ip4", mp->is_ip4 ? 1 : 0);
19830   vat_json_object_add_uint (node, "appns_index",
19831                             clib_net_to_host_u32 (mp->appns_index));
19832   vat_json_object_add_uint (node, "transport_proto", mp->transport_proto);
19833   vat_json_object_add_uint (node, "scope", mp->scope);
19834   vat_json_object_add_uint (node, "action_index",
19835                             clib_net_to_host_u32 (mp->action_index));
19836   vat_json_object_add_uint (node, "lcl_port",
19837                             clib_net_to_host_u16 (mp->lcl_port));
19838   vat_json_object_add_uint (node, "rmt_port",
19839                             clib_net_to_host_u16 (mp->rmt_port));
19840   vat_json_object_add_uint (node, "lcl_plen", mp->lcl_plen);
19841   vat_json_object_add_uint (node, "rmt_plen", mp->rmt_plen);
19842   vat_json_object_add_string_copy (node, "tag", mp->tag);
19843   if (mp->is_ip4)
19844     {
19845       clib_memcpy (&ip4, mp->lcl_ip, sizeof (ip4));
19846       vat_json_object_add_ip4 (node, "lcl_ip", ip4);
19847       clib_memcpy (&ip4, mp->rmt_ip, sizeof (ip4));
19848       vat_json_object_add_ip4 (node, "rmt_ip", ip4);
19849     }
19850   else
19851     {
19852       clib_memcpy (&ip6, mp->lcl_ip, sizeof (ip6));
19853       vat_json_object_add_ip6 (node, "lcl_ip", ip6);
19854       clib_memcpy (&ip6, mp->rmt_ip, sizeof (ip6));
19855       vat_json_object_add_ip6 (node, "rmt_ip", ip6);
19856     }
19857 }
19858
19859 static int
19860 api_session_rule_add_del (vat_main_t * vam)
19861 {
19862   vl_api_session_rule_add_del_t *mp;
19863   unformat_input_t *i = vam->input;
19864   u32 proto = ~0, lcl_port, rmt_port, action = 0, lcl_plen, rmt_plen;
19865   u32 appns_index = 0, scope = 0;
19866   ip4_address_t lcl_ip4, rmt_ip4;
19867   ip6_address_t lcl_ip6, rmt_ip6;
19868   u8 is_ip4 = 1, conn_set = 0;
19869   u8 is_add = 1, *tag = 0;
19870   int ret;
19871
19872   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19873     {
19874       if (unformat (i, "del"))
19875         is_add = 0;
19876       else if (unformat (i, "add"))
19877         ;
19878       else if (unformat (i, "proto tcp"))
19879         proto = 0;
19880       else if (unformat (i, "proto udp"))
19881         proto = 1;
19882       else if (unformat (i, "appns %d", &appns_index))
19883         ;
19884       else if (unformat (i, "scope %d", &scope))
19885         ;
19886       else if (unformat (i, "tag %_%v%_", &tag))
19887         ;
19888       else
19889         if (unformat
19890             (i, "%U/%d %d %U/%d %d", unformat_ip4_address, &lcl_ip4,
19891              &lcl_plen, &lcl_port, unformat_ip4_address, &rmt_ip4, &rmt_plen,
19892              &rmt_port))
19893         {
19894           is_ip4 = 1;
19895           conn_set = 1;
19896         }
19897       else
19898         if (unformat
19899             (i, "%U/%d %d %U/%d %d", unformat_ip6_address, &lcl_ip6,
19900              &lcl_plen, &lcl_port, unformat_ip6_address, &rmt_ip6, &rmt_plen,
19901              &rmt_port))
19902         {
19903           is_ip4 = 0;
19904           conn_set = 1;
19905         }
19906       else if (unformat (i, "action %d", &action))
19907         ;
19908       else
19909         break;
19910     }
19911   if (proto == ~0 || !conn_set || action == ~0)
19912     {
19913       errmsg ("transport proto, connection and action must be set");
19914       return -99;
19915     }
19916
19917   if (scope > 3)
19918     {
19919       errmsg ("scope should be 0-3");
19920       return -99;
19921     }
19922
19923   M (SESSION_RULE_ADD_DEL, mp);
19924
19925   mp->is_ip4 = is_ip4;
19926   mp->transport_proto = proto;
19927   mp->lcl_port = clib_host_to_net_u16 ((u16) lcl_port);
19928   mp->rmt_port = clib_host_to_net_u16 ((u16) rmt_port);
19929   mp->lcl_plen = lcl_plen;
19930   mp->rmt_plen = rmt_plen;
19931   mp->action_index = clib_host_to_net_u32 (action);
19932   mp->appns_index = clib_host_to_net_u32 (appns_index);
19933   mp->scope = scope;
19934   mp->is_add = is_add;
19935   if (is_ip4)
19936     {
19937       clib_memcpy (mp->lcl_ip, &lcl_ip4, sizeof (lcl_ip4));
19938       clib_memcpy (mp->rmt_ip, &rmt_ip4, sizeof (rmt_ip4));
19939     }
19940   else
19941     {
19942       clib_memcpy (mp->lcl_ip, &lcl_ip6, sizeof (lcl_ip6));
19943       clib_memcpy (mp->rmt_ip, &rmt_ip6, sizeof (rmt_ip6));
19944     }
19945   if (tag)
19946     {
19947       clib_memcpy (mp->tag, tag, vec_len (tag));
19948       vec_free (tag);
19949     }
19950
19951   S (mp);
19952   W (ret);
19953   return ret;
19954 }
19955
19956 static int
19957 api_session_rules_dump (vat_main_t * vam)
19958 {
19959   vl_api_session_rules_dump_t *mp;
19960   vl_api_control_ping_t *mp_ping;
19961   int ret;
19962
19963   if (!vam->json_output)
19964     {
19965       print (vam->ofp, "%=20s", "Session Rules");
19966     }
19967
19968   M (SESSION_RULES_DUMP, mp);
19969   /* send it... */
19970   S (mp);
19971
19972   /* Use a control ping for synchronization */
19973   MPING (CONTROL_PING, mp_ping);
19974   S (mp_ping);
19975
19976   /* Wait for a reply... */
19977   W (ret);
19978   return ret;
19979 }
19980
19981 static int
19982 api_ip_container_proxy_add_del (vat_main_t * vam)
19983 {
19984   vl_api_ip_container_proxy_add_del_t *mp;
19985   unformat_input_t *i = vam->input;
19986   u32 sw_if_index = ~0;
19987   vl_api_prefix_t pfx = { };
19988   u8 is_add = 1;
19989   int ret;
19990
19991   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19992     {
19993       if (unformat (i, "del"))
19994         is_add = 0;
19995       else if (unformat (i, "add"))
19996         ;
19997       if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
19998         ;
19999       else if (unformat (i, "sw_if_index %u", &sw_if_index))
20000         ;
20001       else
20002         break;
20003     }
20004   if (sw_if_index == ~0 || pfx.len == 0)
20005     {
20006       errmsg ("address and sw_if_index must be set");
20007       return -99;
20008     }
20009
20010   M (IP_CONTAINER_PROXY_ADD_DEL, mp);
20011
20012   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
20013   mp->is_add = is_add;
20014   clib_memcpy (&mp->pfx, &pfx, sizeof (pfx));
20015
20016   S (mp);
20017   W (ret);
20018   return ret;
20019 }
20020
20021 static int
20022 api_qos_record_enable_disable (vat_main_t * vam)
20023 {
20024   unformat_input_t *i = vam->input;
20025   vl_api_qos_record_enable_disable_t *mp;
20026   u32 sw_if_index, qs = 0xff;
20027   u8 sw_if_index_set = 0;
20028   u8 enable = 1;
20029   int ret;
20030
20031   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20032     {
20033       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20034         sw_if_index_set = 1;
20035       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20036         sw_if_index_set = 1;
20037       else if (unformat (i, "%U", unformat_qos_source, &qs))
20038         ;
20039       else if (unformat (i, "disable"))
20040         enable = 0;
20041       else
20042         {
20043           clib_warning ("parse error '%U'", format_unformat_error, i);
20044           return -99;
20045         }
20046     }
20047
20048   if (sw_if_index_set == 0)
20049     {
20050       errmsg ("missing interface name or sw_if_index");
20051       return -99;
20052     }
20053   if (qs == 0xff)
20054     {
20055       errmsg ("input location must be specified");
20056       return -99;
20057     }
20058
20059   M (QOS_RECORD_ENABLE_DISABLE, mp);
20060
20061   mp->record.sw_if_index = ntohl (sw_if_index);
20062   mp->record.input_source = qs;
20063   mp->enable = enable;
20064
20065   S (mp);
20066   W (ret);
20067   return ret;
20068 }
20069
20070
20071 static int
20072 q_or_quit (vat_main_t * vam)
20073 {
20074 #if VPP_API_TEST_BUILTIN == 0
20075   longjmp (vam->jump_buf, 1);
20076 #endif
20077   return 0;                     /* not so much */
20078 }
20079
20080 static int
20081 q (vat_main_t * vam)
20082 {
20083   return q_or_quit (vam);
20084 }
20085
20086 static int
20087 quit (vat_main_t * vam)
20088 {
20089   return q_or_quit (vam);
20090 }
20091
20092 static int
20093 comment (vat_main_t * vam)
20094 {
20095   return 0;
20096 }
20097
20098 static int
20099 elog_save (vat_main_t * vam)
20100 {
20101 #if VPP_API_TEST_BUILTIN == 0
20102   elog_main_t *em = &vam->elog_main;
20103   unformat_input_t *i = vam->input;
20104   char *file, *chroot_file;
20105   clib_error_t *error;
20106
20107   if (!unformat (i, "%s", &file))
20108     {
20109       errmsg ("expected file name, got `%U'", format_unformat_error, i);
20110       return 0;
20111     }
20112
20113   /* It's fairly hard to get "../oopsie" through unformat; just in case */
20114   if (strstr (file, "..") || index (file, '/'))
20115     {
20116       errmsg ("illegal characters in filename '%s'", file);
20117       return 0;
20118     }
20119
20120   chroot_file = (char *) format (0, "/tmp/%s%c", file, 0);
20121
20122   vec_free (file);
20123
20124   errmsg ("Saving %wd of %wd events to %s",
20125           elog_n_events_in_buffer (em),
20126           elog_buffer_capacity (em), chroot_file);
20127
20128   error = elog_write_file (em, chroot_file, 1 /* flush ring */ );
20129   vec_free (chroot_file);
20130
20131   if (error)
20132     clib_error_report (error);
20133 #else
20134   errmsg ("Use the vpp event loger...");
20135 #endif
20136
20137   return 0;
20138 }
20139
20140 static int
20141 elog_setup (vat_main_t * vam)
20142 {
20143 #if VPP_API_TEST_BUILTIN == 0
20144   elog_main_t *em = &vam->elog_main;
20145   unformat_input_t *i = vam->input;
20146   u32 nevents = 128 << 10;
20147
20148   (void) unformat (i, "nevents %d", &nevents);
20149
20150   elog_init (em, nevents);
20151   vl_api_set_elog_main (em);
20152   vl_api_set_elog_trace_api_messages (1);
20153   errmsg ("Event logger initialized with %u events", nevents);
20154 #else
20155   errmsg ("Use the vpp event loger...");
20156 #endif
20157   return 0;
20158 }
20159
20160 static int
20161 elog_enable (vat_main_t * vam)
20162 {
20163 #if VPP_API_TEST_BUILTIN == 0
20164   elog_main_t *em = &vam->elog_main;
20165
20166   elog_enable_disable (em, 1 /* enable */ );
20167   vl_api_set_elog_trace_api_messages (1);
20168   errmsg ("Event logger enabled...");
20169 #else
20170   errmsg ("Use the vpp event loger...");
20171 #endif
20172   return 0;
20173 }
20174
20175 static int
20176 elog_disable (vat_main_t * vam)
20177 {
20178 #if VPP_API_TEST_BUILTIN == 0
20179   elog_main_t *em = &vam->elog_main;
20180
20181   elog_enable_disable (em, 0 /* enable */ );
20182   vl_api_set_elog_trace_api_messages (1);
20183   errmsg ("Event logger disabled...");
20184 #else
20185   errmsg ("Use the vpp event loger...");
20186 #endif
20187   return 0;
20188 }
20189
20190 static int
20191 statseg (vat_main_t * vam)
20192 {
20193   ssvm_private_t *ssvmp = &vam->stat_segment;
20194   ssvm_shared_header_t *shared_header = ssvmp->sh;
20195   vlib_counter_t **counters;
20196   u64 thread0_index1_packets;
20197   u64 thread0_index1_bytes;
20198   f64 vector_rate, input_rate;
20199   uword *p;
20200
20201   uword *counter_vector_by_name;
20202   if (vam->stat_segment_lockp == 0)
20203     {
20204       errmsg ("Stat segment not mapped...");
20205       return -99;
20206     }
20207
20208   /* look up "/if/rx for sw_if_index 1 as a test */
20209
20210   clib_spinlock_lock (vam->stat_segment_lockp);
20211
20212   counter_vector_by_name = (uword *) shared_header->opaque[1];
20213
20214   p = hash_get_mem (counter_vector_by_name, "/if/rx");
20215   if (p == 0)
20216     {
20217       clib_spinlock_unlock (vam->stat_segment_lockp);
20218       errmsg ("/if/tx not found?");
20219       return -99;
20220     }
20221
20222   /* Fish per-thread vector of combined counters from shared memory */
20223   counters = (vlib_counter_t **) p[0];
20224
20225   if (vec_len (counters[0]) < 2)
20226     {
20227       clib_spinlock_unlock (vam->stat_segment_lockp);
20228       errmsg ("/if/tx vector length %d", vec_len (counters[0]));
20229       return -99;
20230     }
20231
20232   /* Read thread 0 sw_if_index 1 counter */
20233   thread0_index1_packets = counters[0][1].packets;
20234   thread0_index1_bytes = counters[0][1].bytes;
20235
20236   p = hash_get_mem (counter_vector_by_name, "vector_rate");
20237   if (p == 0)
20238     {
20239       clib_spinlock_unlock (vam->stat_segment_lockp);
20240       errmsg ("vector_rate not found?");
20241       return -99;
20242     }
20243
20244   vector_rate = *(f64 *) (p[0]);
20245   p = hash_get_mem (counter_vector_by_name, "input_rate");
20246   if (p == 0)
20247     {
20248       clib_spinlock_unlock (vam->stat_segment_lockp);
20249       errmsg ("input_rate not found?");
20250       return -99;
20251     }
20252   input_rate = *(f64 *) (p[0]);
20253
20254   clib_spinlock_unlock (vam->stat_segment_lockp);
20255
20256   print (vam->ofp, "vector_rate %.2f input_rate %.2f",
20257          vector_rate, input_rate);
20258   print (vam->ofp, "thread 0 sw_if_index 1 rx pkts %lld, bytes %lld",
20259          thread0_index1_packets, thread0_index1_bytes);
20260
20261   return 0;
20262 }
20263
20264 static int
20265 cmd_cmp (void *a1, void *a2)
20266 {
20267   u8 **c1 = a1;
20268   u8 **c2 = a2;
20269
20270   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
20271 }
20272
20273 static int
20274 help (vat_main_t * vam)
20275 {
20276   u8 **cmds = 0;
20277   u8 *name = 0;
20278   hash_pair_t *p;
20279   unformat_input_t *i = vam->input;
20280   int j;
20281
20282   if (unformat (i, "%s", &name))
20283     {
20284       uword *hs;
20285
20286       vec_add1 (name, 0);
20287
20288       hs = hash_get_mem (vam->help_by_name, name);
20289       if (hs)
20290         print (vam->ofp, "usage: %s %s", name, hs[0]);
20291       else
20292         print (vam->ofp, "No such msg / command '%s'", name);
20293       vec_free (name);
20294       return 0;
20295     }
20296
20297   print (vam->ofp, "Help is available for the following:");
20298
20299     /* *INDENT-OFF* */
20300     hash_foreach_pair (p, vam->function_by_name,
20301     ({
20302       vec_add1 (cmds, (u8 *)(p->key));
20303     }));
20304     /* *INDENT-ON* */
20305
20306   vec_sort_with_function (cmds, cmd_cmp);
20307
20308   for (j = 0; j < vec_len (cmds); j++)
20309     print (vam->ofp, "%s", cmds[j]);
20310
20311   vec_free (cmds);
20312   return 0;
20313 }
20314
20315 static int
20316 set (vat_main_t * vam)
20317 {
20318   u8 *name = 0, *value = 0;
20319   unformat_input_t *i = vam->input;
20320
20321   if (unformat (i, "%s", &name))
20322     {
20323       /* The input buffer is a vector, not a string. */
20324       value = vec_dup (i->buffer);
20325       vec_delete (value, i->index, 0);
20326       /* Almost certainly has a trailing newline */
20327       if (value[vec_len (value) - 1] == '\n')
20328         value[vec_len (value) - 1] = 0;
20329       /* Make sure it's a proper string, one way or the other */
20330       vec_add1 (value, 0);
20331       (void) clib_macro_set_value (&vam->macro_main,
20332                                    (char *) name, (char *) value);
20333     }
20334   else
20335     errmsg ("usage: set <name> <value>");
20336
20337   vec_free (name);
20338   vec_free (value);
20339   return 0;
20340 }
20341
20342 static int
20343 unset (vat_main_t * vam)
20344 {
20345   u8 *name = 0;
20346
20347   if (unformat (vam->input, "%s", &name))
20348     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
20349       errmsg ("unset: %s wasn't set", name);
20350   vec_free (name);
20351   return 0;
20352 }
20353
20354 typedef struct
20355 {
20356   u8 *name;
20357   u8 *value;
20358 } macro_sort_t;
20359
20360
20361 static int
20362 macro_sort_cmp (void *a1, void *a2)
20363 {
20364   macro_sort_t *s1 = a1;
20365   macro_sort_t *s2 = a2;
20366
20367   return strcmp ((char *) (s1->name), (char *) (s2->name));
20368 }
20369
20370 static int
20371 dump_macro_table (vat_main_t * vam)
20372 {
20373   macro_sort_t *sort_me = 0, *sm;
20374   int i;
20375   hash_pair_t *p;
20376
20377     /* *INDENT-OFF* */
20378     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
20379     ({
20380       vec_add2 (sort_me, sm, 1);
20381       sm->name = (u8 *)(p->key);
20382       sm->value = (u8 *) (p->value[0]);
20383     }));
20384     /* *INDENT-ON* */
20385
20386   vec_sort_with_function (sort_me, macro_sort_cmp);
20387
20388   if (vec_len (sort_me))
20389     print (vam->ofp, "%-15s%s", "Name", "Value");
20390   else
20391     print (vam->ofp, "The macro table is empty...");
20392
20393   for (i = 0; i < vec_len (sort_me); i++)
20394     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
20395   return 0;
20396 }
20397
20398 static int
20399 dump_node_table (vat_main_t * vam)
20400 {
20401   int i, j;
20402   vlib_node_t *node, *next_node;
20403
20404   if (vec_len (vam->graph_nodes) == 0)
20405     {
20406       print (vam->ofp, "Node table empty, issue get_node_graph...");
20407       return 0;
20408     }
20409
20410   for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
20411     {
20412       node = vam->graph_nodes[0][i];
20413       print (vam->ofp, "[%d] %s", i, node->name);
20414       for (j = 0; j < vec_len (node->next_nodes); j++)
20415         {
20416           if (node->next_nodes[j] != ~0)
20417             {
20418               next_node = vam->graph_nodes[0][node->next_nodes[j]];
20419               print (vam->ofp, "  [%d] %s", j, next_node->name);
20420             }
20421         }
20422     }
20423   return 0;
20424 }
20425
20426 static int
20427 value_sort_cmp (void *a1, void *a2)
20428 {
20429   name_sort_t *n1 = a1;
20430   name_sort_t *n2 = a2;
20431
20432   if (n1->value < n2->value)
20433     return -1;
20434   if (n1->value > n2->value)
20435     return 1;
20436   return 0;
20437 }
20438
20439
20440 static int
20441 dump_msg_api_table (vat_main_t * vam)
20442 {
20443   api_main_t *am = vlibapi_get_main ();
20444   name_sort_t *nses = 0, *ns;
20445   hash_pair_t *hp;
20446   int i;
20447
20448   /* *INDENT-OFF* */
20449   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
20450   ({
20451     vec_add2 (nses, ns, 1);
20452     ns->name = (u8 *)(hp->key);
20453     ns->value = (u32) hp->value[0];
20454   }));
20455   /* *INDENT-ON* */
20456
20457   vec_sort_with_function (nses, value_sort_cmp);
20458
20459   for (i = 0; i < vec_len (nses); i++)
20460     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
20461   vec_free (nses);
20462   return 0;
20463 }
20464
20465 static int
20466 get_msg_id (vat_main_t * vam)
20467 {
20468   u8 *name_and_crc;
20469   u32 message_index;
20470
20471   if (unformat (vam->input, "%s", &name_and_crc))
20472     {
20473       message_index = vl_msg_api_get_msg_index (name_and_crc);
20474       if (message_index == ~0)
20475         {
20476           print (vam->ofp, " '%s' not found", name_and_crc);
20477           return 0;
20478         }
20479       print (vam->ofp, " '%s' has message index %d",
20480              name_and_crc, message_index);
20481       return 0;
20482     }
20483   errmsg ("name_and_crc required...");
20484   return 0;
20485 }
20486
20487 static int
20488 search_node_table (vat_main_t * vam)
20489 {
20490   unformat_input_t *line_input = vam->input;
20491   u8 *node_to_find;
20492   int j;
20493   vlib_node_t *node, *next_node;
20494   uword *p;
20495
20496   if (vam->graph_node_index_by_name == 0)
20497     {
20498       print (vam->ofp, "Node table empty, issue get_node_graph...");
20499       return 0;
20500     }
20501
20502   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
20503     {
20504       if (unformat (line_input, "%s", &node_to_find))
20505         {
20506           vec_add1 (node_to_find, 0);
20507           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
20508           if (p == 0)
20509             {
20510               print (vam->ofp, "%s not found...", node_to_find);
20511               goto out;
20512             }
20513           node = vam->graph_nodes[0][p[0]];
20514           print (vam->ofp, "[%d] %s", p[0], node->name);
20515           for (j = 0; j < vec_len (node->next_nodes); j++)
20516             {
20517               if (node->next_nodes[j] != ~0)
20518                 {
20519                   next_node = vam->graph_nodes[0][node->next_nodes[j]];
20520                   print (vam->ofp, "  [%d] %s", j, next_node->name);
20521                 }
20522             }
20523         }
20524
20525       else
20526         {
20527           clib_warning ("parse error '%U'", format_unformat_error,
20528                         line_input);
20529           return -99;
20530         }
20531
20532     out:
20533       vec_free (node_to_find);
20534
20535     }
20536
20537   return 0;
20538 }
20539
20540
20541 static int
20542 script (vat_main_t * vam)
20543 {
20544 #if (VPP_API_TEST_BUILTIN==0)
20545   u8 *s = 0;
20546   char *save_current_file;
20547   unformat_input_t save_input;
20548   jmp_buf save_jump_buf;
20549   u32 save_line_number;
20550
20551   FILE *new_fp, *save_ifp;
20552
20553   if (unformat (vam->input, "%s", &s))
20554     {
20555       new_fp = fopen ((char *) s, "r");
20556       if (new_fp == 0)
20557         {
20558           errmsg ("Couldn't open script file %s", s);
20559           vec_free (s);
20560           return -99;
20561         }
20562     }
20563   else
20564     {
20565       errmsg ("Missing script name");
20566       return -99;
20567     }
20568
20569   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
20570   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
20571   save_ifp = vam->ifp;
20572   save_line_number = vam->input_line_number;
20573   save_current_file = (char *) vam->current_file;
20574
20575   vam->input_line_number = 0;
20576   vam->ifp = new_fp;
20577   vam->current_file = s;
20578   do_one_file (vam);
20579
20580   clib_memcpy (&vam->input, &save_input, sizeof (save_input));
20581   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
20582   vam->ifp = save_ifp;
20583   vam->input_line_number = save_line_number;
20584   vam->current_file = (u8 *) save_current_file;
20585   vec_free (s);
20586
20587   return 0;
20588 #else
20589   clib_warning ("use the exec command...");
20590   return -99;
20591 #endif
20592 }
20593
20594 static int
20595 echo (vat_main_t * vam)
20596 {
20597   print (vam->ofp, "%v", vam->input->buffer);
20598   return 0;
20599 }
20600
20601 /* List of API message constructors, CLI names map to api_xxx */
20602 #define foreach_vpe_api_msg                                             \
20603 _(create_loopback,"[mac <mac-addr>] [instance <instance>]")             \
20604 _(sw_interface_dump,"")                                                 \
20605 _(sw_interface_set_flags,                                               \
20606   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
20607 _(sw_interface_add_del_address,                                         \
20608   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
20609 _(sw_interface_set_rx_mode,                                             \
20610   "<intfc> | sw_if_index <id> [queue <id>] <polling | interrupt | adaptive>") \
20611 _(sw_interface_set_rx_placement,                                        \
20612   "<intfc> | sw_if_index <id> [queue <id>] [worker <id> | main]")       \
20613 _(sw_interface_rx_placement_dump,                                       \
20614   "[<intfc> | sw_if_index <id>]")                                         \
20615 _(sw_interface_set_table,                                               \
20616   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
20617 _(sw_interface_set_mpls_enable,                                         \
20618   "<intfc> | sw_if_index [disable | dis]")                              \
20619 _(sw_interface_set_vpath,                                               \
20620   "<intfc> | sw_if_index <id> enable | disable")                        \
20621 _(sw_interface_set_vxlan_bypass,                                        \
20622   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
20623 _(sw_interface_set_geneve_bypass,                                       \
20624   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
20625 _(sw_interface_set_l2_xconnect,                                         \
20626   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
20627   "enable | disable")                                                   \
20628 _(sw_interface_set_l2_bridge,                                           \
20629   "{<intfc> | sw_if_index <id>} bd_id <bridge-domain-id>\n"             \
20630   "[shg <split-horizon-group>] [bvi]\n"                                 \
20631   "enable | disable")                                                   \
20632 _(bridge_domain_set_mac_age, "bd_id <bridge-domain-id> mac-age 0-255")  \
20633 _(bridge_domain_add_del,                                                \
20634   "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") \
20635 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
20636 _(l2fib_add_del,                                                        \
20637   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
20638 _(l2fib_flush_bd, "bd_id <bridge-domain-id>")                           \
20639 _(l2fib_flush_int, "<intfc> | sw_if_index <id>")                        \
20640 _(l2_flags,                                                             \
20641   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
20642 _(bridge_flags,                                                         \
20643   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
20644 _(tap_create_v2,                                                        \
20645   "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]") \
20646 _(tap_delete_v2,                                                        \
20647   "<vpp-if-name> | sw_if_index <id>")                                   \
20648 _(sw_interface_tap_v2_dump, "")                                         \
20649 _(virtio_pci_create,                                                    \
20650   "pci-addr <pci-address> [use_random_mac | hw-addr <mac-addr>] [features <hex-value>] [gso-enabled | csum-offload-enabled]") \
20651 _(virtio_pci_delete,                                                    \
20652   "<vpp-if-name> | sw_if_index <id>")                                   \
20653 _(sw_interface_virtio_pci_dump, "")                                     \
20654 _(bond_create,                                                          \
20655   "[hw-addr <mac-addr>] {round-robin | active-backup | "                \
20656   "broadcast | {lacp | xor} [load-balance { l2 | l23 | l34 }]} "        \
20657   "[id <if-id>]")                                                       \
20658 _(bond_delete,                                                          \
20659   "<vpp-if-name> | sw_if_index <id>")                                   \
20660 _(bond_enslave,                                                         \
20661   "sw_if_index <n> bond <sw_if_index> [is_passive] [is_long_timeout]")  \
20662 _(bond_detach_slave,                                                    \
20663   "sw_if_index <n>")                                                    \
20664  _(sw_interface_set_bond_weight, "<intfc> | sw_if_index <nn> weight <value>") \
20665 _(sw_interface_bond_dump, "")                                           \
20666 _(sw_interface_slave_dump,                                              \
20667   "<vpp-if-name> | sw_if_index <id>")                                   \
20668 _(ip_table_add_del,                                                     \
20669   "table <n> [ipv6] [add | del]\n")                                     \
20670 _(ip_route_add_del,                                                     \
20671   "<addr>/<mask> via <<addr>|<intfc>|sw_if_index <id>|via-label <n>>\n" \
20672   "[table-id <n>] [<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"\
20673   "[weight <n>] [drop] [local] [classify <n>]  [out-label <n>]\n"       \
20674   "[multipath] [count <n>] [del]")                                      \
20675 _(ip_mroute_add_del,                                                    \
20676   "<src> <grp>/<mask> [table-id <n>]\n"                                 \
20677   "[<intfc> | sw_if_index <id>] [local] [del]")                         \
20678 _(mpls_table_add_del,                                                   \
20679   "table <n> [add | del]\n")                                            \
20680 _(mpls_route_add_del,                                                   \
20681   "<label> <eos> via <addr | next-hop-table <n> | via-label <n> |\n"    \
20682   "lookup-ip4-table <n> | lookup-in-ip6-table <n> |\n"                  \
20683   "l2-input-on <intfc> | l2-input-on sw_if_index <id>>\n"               \
20684   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>] [weight <n>]\n"  \
20685   "[drop] [local] [classify <n>] [out-label <n>] [multipath]\n"         \
20686   "[count <n>] [del]")                                                  \
20687 _(mpls_ip_bind_unbind,                                                  \
20688   "<label> <addr/len>")                                                 \
20689 _(mpls_tunnel_add_del,                                                  \
20690   "[add | del <intfc | sw_if_index <id>>] via <addr | via-label <n>>\n" \
20691   "[<intfc> | sw_if_index <id> | next-hop-table <id>]\n"                \
20692   "[l2-only]  [out-label <n>]")                                         \
20693 _(sr_mpls_policy_add,                                                   \
20694   "bsid <id> [weight <n>] [spray] next <sid> [next <sid>]")             \
20695 _(sr_mpls_policy_del,                                                   \
20696   "bsid <id>")                                                          \
20697 _(bier_table_add_del,                                                   \
20698   "<label> <sub-domain> <set> <bsl> [del]")                             \
20699 _(bier_route_add_del,                                                   \
20700   "<bit-position> <sub-domain> <set> <bsl> via <addr> [table-id <n>]\n" \
20701   "[<intfc> | sw_if_index <id>]"                                        \
20702   "[weight <n>] [del] [multipath]")                                     \
20703 _(sw_interface_set_unnumbered,                                          \
20704   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
20705 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
20706 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
20707   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
20708   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
20709   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
20710 _(ip_table_replace_begin, "table <n> [ipv6]")                           \
20711 _(ip_table_flush, "table <n> [ipv6]")                                   \
20712 _(ip_table_replace_end, "table <n> [ipv6]")                             \
20713 _(set_ip_flow_hash,                                                     \
20714   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
20715 _(sw_interface_ip6_enable_disable,                                      \
20716   "<intfc> | sw_if_index <id> enable | disable")                        \
20717 _(l2_patch_add_del,                                                     \
20718   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
20719   "enable | disable")                                                   \
20720 _(sr_localsid_add_del,                                                  \
20721   "(del) address <addr> next_hop <addr> behavior <beh>\n"               \
20722   "fib-table <num> (end.psp) sw_if_index <num>")                        \
20723 _(classify_add_del_table,                                               \
20724   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
20725   " [del] [del-chain] mask <mask-value>\n"                              \
20726   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
20727   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
20728 _(classify_add_del_session,                                             \
20729   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
20730   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
20731   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
20732   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
20733 _(classify_set_interface_ip_table,                                      \
20734   "<intfc> | sw_if_index <nn> table <nn>")                              \
20735 _(classify_set_interface_l2_tables,                                     \
20736   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
20737   "  [other-table <nn>]")                                               \
20738 _(get_node_index, "node <node-name")                                    \
20739 _(add_node_next, "node <node-name> next <next-node-name>")              \
20740 _(l2tpv3_create_tunnel,                                                 \
20741   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
20742   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
20743   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
20744 _(l2tpv3_set_tunnel_cookies,                                            \
20745   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
20746   "[new_remote_cookie <nn>]\n")                                         \
20747 _(l2tpv3_interface_enable_disable,                                      \
20748   "<intfc> | sw_if_index <nn> enable | disable")                        \
20749 _(l2tpv3_set_lookup_key,                                                \
20750   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
20751 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
20752 _(vxlan_offload_rx,                                                     \
20753   "hw { <interface name> | hw_if_index <nn>} "                          \
20754   "rx { <vxlan tunnel name> | sw_if_index <nn> } [del]")                \
20755 _(vxlan_add_del_tunnel,                                                 \
20756   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
20757   "{ <intfc> | mcast_sw_if_index <nn> } [instance <id>]}\n"             \
20758   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
20759 _(geneve_add_del_tunnel,                                                \
20760   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
20761   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
20762   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
20763 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
20764 _(geneve_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                   \
20765 _(gre_tunnel_add_del,                                                   \
20766   "src <ip-addr> dst <ip-addr> [outer-fib-id <nn>] [instance <n>]\n"    \
20767   "[teb | erspan <session-id>] [del]")                                  \
20768 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
20769 _(l2_fib_clear_table, "")                                               \
20770 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
20771 _(l2_interface_vlan_tag_rewrite,                                        \
20772   "<intfc> | sw_if_index <nn> \n"                                       \
20773   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
20774   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
20775 _(create_vhost_user_if,                                                 \
20776         "socket <filename> [server] [renumber <dev_instance>] "         \
20777         "[disable_mrg_rxbuf] [disable_indirect_desc] [gso] "            \
20778         "[mac <mac_address>]")                                          \
20779 _(modify_vhost_user_if,                                                 \
20780         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
20781         "[server] [renumber <dev_instance>] [gso]")                     \
20782 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
20783 _(sw_interface_vhost_user_dump, "")                                     \
20784 _(show_version, "")                                                     \
20785 _(show_threads, "")                                                     \
20786 _(vxlan_gpe_add_del_tunnel,                                             \
20787   "local <addr> remote <addr>  | group <mcast-ip-addr>\n"               \
20788   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
20789   "vni <nn> [encap-vrf-id <nn>] [decap-vrf-id <nn>]\n"                  \
20790   "[next-ip4][next-ip6][next-ethernet] [next-nsh] [del]\n")             \
20791 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
20792 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
20793 _(interface_name_renumber,                                              \
20794   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
20795 _(input_acl_set_interface,                                              \
20796   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
20797   "  [l2-table <nn>] [del]")                                            \
20798 _(want_l2_macs_events, "[disable] [learn-limit <n>] [scan-delay <n>] [max-entries <n>]") \
20799 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
20800 _(ip_dump, "ipv4 | ipv6")                                               \
20801 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
20802 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
20803   "  spid_id <n> ")                                                     \
20804 _(ipsec_sad_entry_add_del, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
20805   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
20806   "  integ_alg <alg> integ_key <hex>")                                  \
20807 _(ipsec_spd_entry_add_del, "spd_id <n> priority <n> action <action>\n"  \
20808   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
20809   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
20810   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
20811 _(ipsec_tunnel_if_add_del, "local_spi <n> remote_spi <n>\n"             \
20812   "  crypto_alg <alg> local_crypto_key <hex> remote_crypto_key <hex>\n" \
20813   "  integ_alg <alg> local_integ_key <hex> remote_integ_key <hex>\n"    \
20814   "  local_ip <addr> remote_ip <addr> [esn] [anti_replay] [del]\n"      \
20815   "  [instance <n>]")     \
20816 _(ipsec_sa_dump, "[sa_id <n>]")                                         \
20817 _(ipsec_tunnel_if_set_sa, "<intfc> sa_id <n> <inbound|outbound>\n")     \
20818 _(delete_loopback,"sw_if_index <nn>")                                   \
20819 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
20820 _(bd_ip_mac_flush, "bd_id <bridge-domain-id>")                          \
20821 _(bd_ip_mac_dump, "[bd_id] <bridge-domain-id>")                         \
20822 _(want_interface_events,  "enable|disable")                             \
20823 _(get_first_msg_id, "client <name>")                                    \
20824 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
20825 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
20826   "fib-id <nn> [ip4][ip6][default]")                                    \
20827 _(get_node_graph, " ")                                                  \
20828 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
20829 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
20830 _(ioam_disable, "")                                                     \
20831 _(one_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
20832                             " sw_if_index <sw_if_index> p <priority> "  \
20833                             "w <weight>] [del]")                        \
20834 _(one_add_del_locator, "locator-set <locator_name> "                    \
20835                         "iface <intf> | sw_if_index <sw_if_index> "     \
20836                         "p <priority> w <weight> [del]")                \
20837 _(one_add_del_local_eid,"vni <vni> eid "                                \
20838                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
20839                          "locator-set <locator_name> [del]"             \
20840                          "[key-id sha1|sha256 secret-key <secret-key>]")\
20841 _(one_add_del_map_resolver, "<ip4|6-addr> [del]")                       \
20842 _(one_add_del_map_server, "<ip4|6-addr> [del]")                         \
20843 _(one_enable_disable, "enable|disable")                                 \
20844 _(one_map_register_enable_disable, "enable|disable")                    \
20845 _(one_map_register_fallback_threshold, "<value>")                       \
20846 _(one_rloc_probe_enable_disable, "enable|disable")                      \
20847 _(one_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "       \
20848                                "[seid <seid>] "                         \
20849                                "rloc <locator> p <prio> "               \
20850                                "w <weight> [rloc <loc> ... ] "          \
20851                                "action <action> [del-all]")             \
20852 _(one_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "    \
20853                           "<local-eid>")                                \
20854 _(one_pitr_set_locator_set, "locator-set <loc-set-name> | del")         \
20855 _(one_use_petr, "ip-address> | disable")                                \
20856 _(one_map_request_mode, "src-dst|dst-only")                             \
20857 _(one_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")            \
20858 _(one_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")               \
20859 _(one_locator_set_dump, "[local | remote]")                             \
20860 _(one_locator_dump, "ls_index <index> | ls_name <name>")                \
20861 _(one_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "       \
20862                        "[local] | [remote]")                            \
20863 _(one_add_del_ndp_entry, "[del] mac <mac> bd <bd> ip6 <ip6>")           \
20864 _(one_ndp_bd_get, "")                                                   \
20865 _(one_ndp_entries_get, "bd <bridge-domain>")                            \
20866 _(one_add_del_l2_arp_entry, "[del] mac <mac> bd <bd> ip4 <ip4>")        \
20867 _(one_l2_arp_bd_get, "")                                                \
20868 _(one_l2_arp_entries_get, "bd <bridge-domain>")                         \
20869 _(one_stats_enable_disable, "enable|disable")                           \
20870 _(show_one_stats_enable_disable, "")                                    \
20871 _(one_eid_table_vni_dump, "")                                           \
20872 _(one_eid_table_map_dump, "l2|l3")                                      \
20873 _(one_map_resolver_dump, "")                                            \
20874 _(one_map_server_dump, "")                                              \
20875 _(one_adjacencies_get, "vni <vni>")                                     \
20876 _(one_nsh_set_locator_set, "[del] ls <locator-set-name>")               \
20877 _(show_one_rloc_probe_state, "")                                        \
20878 _(show_one_map_register_state, "")                                      \
20879 _(show_one_status, "")                                                  \
20880 _(one_stats_dump, "")                                                   \
20881 _(one_stats_flush, "")                                                  \
20882 _(one_get_map_request_itr_rlocs, "")                                    \
20883 _(one_map_register_set_ttl, "<ttl>")                                    \
20884 _(one_set_transport_protocol, "udp|api")                                \
20885 _(one_get_transport_protocol, "")                                       \
20886 _(one_enable_disable_xtr_mode, "enable|disable")                        \
20887 _(one_show_xtr_mode, "")                                                \
20888 _(one_enable_disable_pitr_mode, "enable|disable")                       \
20889 _(one_show_pitr_mode, "")                                               \
20890 _(one_enable_disable_petr_mode, "enable|disable")                       \
20891 _(one_show_petr_mode, "")                                               \
20892 _(show_one_nsh_mapping, "")                                             \
20893 _(show_one_pitr, "")                                                    \
20894 _(show_one_use_petr, "")                                                \
20895 _(show_one_map_request_mode, "")                                        \
20896 _(show_one_map_register_ttl, "")                                        \
20897 _(show_one_map_register_fallback_threshold, "")                         \
20898 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
20899                             " sw_if_index <sw_if_index> p <priority> "  \
20900                             "w <weight>] [del]")                        \
20901 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
20902                         "iface <intf> | sw_if_index <sw_if_index> "     \
20903                         "p <priority> w <weight> [del]")                \
20904 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
20905                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
20906                          "locator-set <locator_name> [del]"             \
20907                          "[key-id sha1|sha256 secret-key <secret-key>]") \
20908 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
20909 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
20910 _(lisp_enable_disable, "enable|disable")                                \
20911 _(lisp_map_register_enable_disable, "enable|disable")                   \
20912 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
20913 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
20914                                "[seid <seid>] "                         \
20915                                "rloc <locator> p <prio> "               \
20916                                "w <weight> [rloc <loc> ... ] "          \
20917                                "action <action> [del-all]")             \
20918 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
20919                           "<local-eid>")                                \
20920 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
20921 _(lisp_use_petr, "<ip-address> | disable")                              \
20922 _(lisp_map_request_mode, "src-dst|dst-only")                            \
20923 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
20924 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
20925 _(lisp_locator_set_dump, "[local | remote]")                            \
20926 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
20927 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
20928                        "[local] | [remote]")                            \
20929 _(lisp_eid_table_vni_dump, "")                                          \
20930 _(lisp_eid_table_map_dump, "l2|l3")                                     \
20931 _(lisp_map_resolver_dump, "")                                           \
20932 _(lisp_map_server_dump, "")                                             \
20933 _(lisp_adjacencies_get, "vni <vni>")                                    \
20934 _(gpe_fwd_entry_vnis_get, "")                                           \
20935 _(gpe_native_fwd_rpaths_get, "ip4 | ip6")                               \
20936 _(gpe_add_del_native_fwd_rpath, "[del] via <nh-ip-addr> [iface] "       \
20937                                 "[table <table-id>]")                   \
20938 _(lisp_gpe_fwd_entries_get, "vni <vni>")                                \
20939 _(lisp_gpe_fwd_entry_path_dump, "index <fwd_entry_index>")              \
20940 _(gpe_set_encap_mode, "lisp|vxlan")                                     \
20941 _(gpe_get_encap_mode, "")                                               \
20942 _(lisp_gpe_add_del_iface, "up|down")                                    \
20943 _(lisp_gpe_enable_disable, "enable|disable")                            \
20944 _(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>"       \
20945   "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
20946 _(show_lisp_rloc_probe_state, "")                                       \
20947 _(show_lisp_map_register_state, "")                                     \
20948 _(show_lisp_status, "")                                                 \
20949 _(lisp_get_map_request_itr_rlocs, "")                                   \
20950 _(show_lisp_pitr, "")                                                   \
20951 _(show_lisp_use_petr, "")                                               \
20952 _(show_lisp_map_request_mode, "")                                       \
20953 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
20954 _(af_packet_delete, "name <host interface name>")                       \
20955 _(af_packet_dump, "")                                                   \
20956 _(policer_add_del, "name <policer name> <params> [del]")                \
20957 _(policer_dump, "[name <policer name>]")                                \
20958 _(policer_classify_set_interface,                                       \
20959   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
20960   "  [l2-table <nn>] [del]")                                            \
20961 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
20962 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
20963 _(mpls_table_dump, "")                                                  \
20964 _(mpls_route_dump, "table-id <ID>")                                     \
20965 _(classify_table_ids, "")                                               \
20966 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
20967 _(classify_table_info, "table_id <nn>")                                 \
20968 _(classify_session_dump, "table_id <nn>")                               \
20969 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
20970     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
20971     "[template_interval <nn>] [udp_checksum]")                          \
20972 _(ipfix_exporter_dump, "")                                              \
20973 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
20974 _(ipfix_classify_stream_dump, "")                                       \
20975 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
20976 _(ipfix_classify_table_dump, "")                                        \
20977 _(sw_interface_span_enable_disable, "[l2] [src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
20978 _(sw_interface_span_dump, "[l2]")                                           \
20979 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
20980 _(pg_create_interface, "if_id <nn> [gso-enabled gso-size <size>]")      \
20981 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
20982 _(pg_enable_disable, "[stream <id>] disable")                           \
20983 _(ip_source_and_port_range_check_add_del,                               \
20984   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
20985 _(ip_source_and_port_range_check_interface_add_del,                     \
20986   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
20987   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
20988 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
20989 _(l2_interface_pbb_tag_rewrite,                                         \
20990   "<intfc> | sw_if_index <nn> \n"                                       \
20991   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
20992   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
20993 _(set_punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
20994 _(flow_classify_set_interface,                                          \
20995   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
20996 _(flow_classify_dump, "type [ip4|ip6]")                                 \
20997 _(ip_table_dump, "")                                                    \
20998 _(ip_route_dump, "table-id [ip4|ip6]")                                  \
20999 _(ip_mtable_dump, "")                                                   \
21000 _(ip_mroute_dump, "table-id [ip4|ip6]")                                 \
21001 _(feature_enable_disable, "arc_name <arc_name> "                        \
21002   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
21003 _(feature_gso_enable_disable, "<intfc> | sw_if_index <nn> "             \
21004   "[enable | disable] ")                                                \
21005 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
21006 "[disable]")                                                            \
21007 _(sw_interface_add_del_mac_address, "<intfc> | sw_if_index <nn> "       \
21008   "mac <mac-address> [del]")                                            \
21009 _(l2_xconnect_dump, "")                                                 \
21010 _(hw_interface_set_mtu, "<intfc> | hw_if_index <nn> mtu <nn>")        \
21011 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")          \
21012 _(p2p_ethernet_add, "<intfc> | sw_if_index <nn> remote_mac <mac-address> sub_id <id>") \
21013 _(p2p_ethernet_del, "<intfc> | sw_if_index <nn> remote_mac <mac-address>") \
21014 _(lldp_config, "system-name <name> tx-hold <nn> tx-interval <nn>") \
21015 _(sw_interface_set_lldp, "<intfc> | sw_if_index <nn> [port-desc <description>]\n" \
21016   " [mgmt-ip4 <ip4>] [mgmt-ip6 <ip6>] [mgmt-oid <object id>] [disable]") \
21017 _(tcp_configure_src_addresses, "<ip4|6>first-<ip4|6>last [vrf <id>]")   \
21018 _(sock_init_shm, "size <nnn>")                                          \
21019 _(app_namespace_add_del, "[add] id <ns-id> secret <nn> sw_if_index <nn>")\
21020 _(session_rule_add_del, "[add|del] proto <tcp/udp> <lcl-ip>/<plen> "    \
21021   "<lcl-port> <rmt-ip>/<plen> <rmt-port> action <nn>")                  \
21022 _(session_rules_dump, "")                                               \
21023 _(ip_container_proxy_add_del, "[add|del] <address> <sw_if_index>")      \
21024 _(output_acl_set_interface,                                             \
21025   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
21026   "  [l2-table <nn>] [del]")                                            \
21027 _(qos_record_enable_disable, "<record-source> <intfc> | sw_if_index <id> [disable]")
21028
21029 /* List of command functions, CLI names map directly to functions */
21030 #define foreach_cli_function                                    \
21031 _(comment, "usage: comment <ignore-rest-of-line>")              \
21032 _(dump_interface_table, "usage: dump_interface_table")          \
21033 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
21034 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
21035 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
21036 _(dump_macro_table, "usage: dump_macro_table ")                 \
21037 _(dump_node_table, "usage: dump_node_table")                    \
21038 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
21039 _(elog_setup, "usage: elog_setup [nevents, default 128K]")      \
21040 _(elog_disable, "usage: elog_disable")                          \
21041 _(elog_enable, "usage: elog_enable")                            \
21042 _(elog_save, "usage: elog_save <filename>")                     \
21043 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
21044 _(echo, "usage: echo <message>")                                \
21045 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
21046 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
21047 _(help, "usage: help")                                          \
21048 _(q, "usage: quit")                                             \
21049 _(quit, "usage: quit")                                          \
21050 _(search_node_table, "usage: search_node_table <name>...")      \
21051 _(set, "usage: set <variable-name> <value>")                    \
21052 _(script, "usage: script <file-name>")                          \
21053 _(statseg, "usage: statseg")                                    \
21054 _(unset, "usage: unset <variable-name>")
21055
21056 #define _(N,n)                                  \
21057     static void vl_api_##n##_t_handler_uni      \
21058     (vl_api_##n##_t * mp)                       \
21059     {                                           \
21060         vat_main_t * vam = &vat_main;           \
21061         if (vam->json_output) {                 \
21062             vl_api_##n##_t_handler_json(mp);    \
21063         } else {                                \
21064             vl_api_##n##_t_handler(mp);         \
21065         }                                       \
21066     }
21067 foreach_vpe_api_reply_msg;
21068 #if VPP_API_TEST_BUILTIN == 0
21069 foreach_standalone_reply_msg;
21070 #endif
21071 #undef _
21072
21073 void
21074 vat_api_hookup (vat_main_t * vam)
21075 {
21076 #define _(N,n)                                                  \
21077     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
21078                            vl_api_##n##_t_handler_uni,          \
21079                            vl_noop_handler,                     \
21080                            vl_api_##n##_t_endian,               \
21081                            vl_api_##n##_t_print,                \
21082                            sizeof(vl_api_##n##_t), 1);
21083   foreach_vpe_api_reply_msg;
21084 #if VPP_API_TEST_BUILTIN == 0
21085   foreach_standalone_reply_msg;
21086 #endif
21087 #undef _
21088
21089 #if (VPP_API_TEST_BUILTIN==0)
21090   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
21091
21092   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
21093
21094   vam->function_by_name = hash_create_string (0, sizeof (uword));
21095
21096   vam->help_by_name = hash_create_string (0, sizeof (uword));
21097 #endif
21098
21099   /* API messages we can send */
21100 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
21101   foreach_vpe_api_msg;
21102 #undef _
21103
21104   /* Help strings */
21105 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
21106   foreach_vpe_api_msg;
21107 #undef _
21108
21109   /* CLI functions */
21110 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
21111   foreach_cli_function;
21112 #undef _
21113
21114   /* Help strings */
21115 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
21116   foreach_cli_function;
21117 #undef _
21118 }
21119
21120 #if VPP_API_TEST_BUILTIN
21121 static clib_error_t *
21122 vat_api_hookup_shim (vlib_main_t * vm)
21123 {
21124   vat_api_hookup (&vat_main);
21125   return 0;
21126 }
21127
21128 VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
21129 #endif
21130
21131 /*
21132  * fd.io coding-style-patch-verification: ON
21133  *
21134  * Local Variables:
21135  * eval: (c-set-style "gnu")
21136  * End:
21137  */