devices: virtio API cleanup
[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 _(netmap_create_reply)                                  \
5113 _(netmap_delete_reply)                                  \
5114 _(set_ipfix_exporter_reply)                             \
5115 _(set_ipfix_classify_stream_reply)                      \
5116 _(ipfix_classify_table_add_del_reply)                   \
5117 _(flow_classify_set_interface_reply)                    \
5118 _(sw_interface_span_enable_disable_reply)               \
5119 _(pg_capture_reply)                                     \
5120 _(pg_enable_disable_reply)                              \
5121 _(ip_source_and_port_range_check_add_del_reply)         \
5122 _(ip_source_and_port_range_check_interface_add_del_reply)\
5123 _(delete_subif_reply)                                   \
5124 _(l2_interface_pbb_tag_rewrite_reply)                   \
5125 _(set_punt_reply)                                       \
5126 _(feature_enable_disable_reply)                         \
5127 _(feature_gso_enable_disable_reply)                     \
5128 _(sw_interface_tag_add_del_reply)                       \
5129 _(sw_interface_add_del_mac_address_reply)               \
5130 _(hw_interface_set_mtu_reply)                           \
5131 _(p2p_ethernet_add_reply)                               \
5132 _(p2p_ethernet_del_reply)                               \
5133 _(lldp_config_reply)                                    \
5134 _(sw_interface_set_lldp_reply)                          \
5135 _(tcp_configure_src_addresses_reply)                    \
5136 _(session_rule_add_del_reply)                           \
5137 _(ip_container_proxy_add_del_reply)                     \
5138 _(output_acl_set_interface_reply)                       \
5139 _(qos_record_enable_disable_reply)
5140
5141 #define _(n)                                    \
5142     static void vl_api_##n##_t_handler          \
5143     (vl_api_##n##_t * mp)                       \
5144     {                                           \
5145         vat_main_t * vam = &vat_main;           \
5146         i32 retval = ntohl(mp->retval);         \
5147         if (vam->async_mode) {                  \
5148             vam->async_errors += (retval < 0);  \
5149         } else {                                \
5150             vam->retval = retval;               \
5151             vam->result_ready = 1;              \
5152         }                                       \
5153     }
5154 foreach_standard_reply_retval_handler;
5155 #undef _
5156
5157 #define _(n)                                    \
5158     static void vl_api_##n##_t_handler_json     \
5159     (vl_api_##n##_t * mp)                       \
5160     {                                           \
5161         vat_main_t * vam = &vat_main;           \
5162         vat_json_node_t node;                   \
5163         vat_json_init_object(&node);            \
5164         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
5165         vat_json_print(vam->ofp, &node);        \
5166         vam->retval = ntohl(mp->retval);        \
5167         vam->result_ready = 1;                  \
5168     }
5169 foreach_standard_reply_retval_handler;
5170 #undef _
5171
5172 /*
5173  * Table of message reply handlers, must include boilerplate handlers
5174  * we just generated
5175  */
5176
5177 #define foreach_vpe_api_reply_msg                                       \
5178 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
5179 _(CREATE_LOOPBACK_INSTANCE_REPLY, create_loopback_instance_reply)       \
5180 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
5181 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
5182 _(CONTROL_PING_REPLY, control_ping_reply)                               \
5183 _(CLI_REPLY, cli_reply)                                                 \
5184 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
5185 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
5186   sw_interface_add_del_address_reply)                                   \
5187 _(SW_INTERFACE_SET_RX_MODE_REPLY, sw_interface_set_rx_mode_reply)       \
5188 _(SW_INTERFACE_SET_RX_PLACEMENT_REPLY, sw_interface_set_rx_placement_reply)     \
5189 _(SW_INTERFACE_RX_PLACEMENT_DETAILS, sw_interface_rx_placement_details) \
5190 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
5191 _(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
5192 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
5193 _(SW_INTERFACE_SET_VXLAN_BYPASS_REPLY, sw_interface_set_vxlan_bypass_reply) \
5194 _(SW_INTERFACE_SET_GENEVE_BYPASS_REPLY, sw_interface_set_geneve_bypass_reply) \
5195 _(SW_INTERFACE_SET_VXLAN_GPE_BYPASS_REPLY, sw_interface_set_vxlan_gpe_bypass_reply) \
5196 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
5197   sw_interface_set_l2_xconnect_reply)                                   \
5198 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
5199   sw_interface_set_l2_bridge_reply)                                     \
5200 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
5201 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
5202 _(BRIDGE_DOMAIN_SET_MAC_AGE_REPLY, bridge_domain_set_mac_age_reply)     \
5203 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
5204 _(L2FIB_FLUSH_INT_REPLY, l2fib_flush_int_reply)                         \
5205 _(L2FIB_FLUSH_BD_REPLY, l2fib_flush_bd_reply)                           \
5206 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
5207 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
5208 _(TAP_CREATE_V2_REPLY, tap_create_v2_reply)                             \
5209 _(TAP_DELETE_V2_REPLY, tap_delete_v2_reply)                             \
5210 _(SW_INTERFACE_TAP_V2_DETAILS, sw_interface_tap_v2_details)             \
5211 _(VIRTIO_PCI_CREATE_REPLY, virtio_pci_create_reply)                     \
5212 _(VIRTIO_PCI_DELETE_REPLY, virtio_pci_delete_reply)                     \
5213 _(SW_INTERFACE_VIRTIO_PCI_DETAILS, sw_interface_virtio_pci_details)     \
5214 _(BOND_CREATE_REPLY, bond_create_reply)                                 \
5215 _(BOND_DELETE_REPLY, bond_delete_reply)                                 \
5216 _(BOND_ENSLAVE_REPLY, bond_enslave_reply)                               \
5217 _(BOND_DETACH_SLAVE_REPLY, bond_detach_slave_reply)                     \
5218 _(SW_INTERFACE_SET_BOND_WEIGHT_REPLY, sw_interface_set_bond_weight_reply) \
5219 _(SW_INTERFACE_BOND_DETAILS, sw_interface_bond_details)                 \
5220 _(SW_INTERFACE_SLAVE_DETAILS, sw_interface_slave_details)               \
5221 _(IP_ROUTE_ADD_DEL_REPLY, ip_route_add_del_reply)                       \
5222 _(IP_TABLE_ADD_DEL_REPLY, ip_table_add_del_reply)                       \
5223 _(IP_TABLE_REPLACE_BEGIN_REPLY, ip_table_replace_begin_reply)           \
5224 _(IP_TABLE_FLUSH_REPLY, ip_table_flush_reply)                           \
5225 _(IP_TABLE_REPLACE_END_REPLY, ip_table_replace_end_reply)               \
5226 _(IP_MROUTE_ADD_DEL_REPLY, ip_mroute_add_del_reply)                     \
5227 _(MPLS_TABLE_ADD_DEL_REPLY, mpls_table_add_del_reply)                   \
5228 _(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply)                   \
5229 _(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply)                 \
5230 _(BIER_ROUTE_ADD_DEL_REPLY, bier_route_add_del_reply)                   \
5231 _(BIER_TABLE_ADD_DEL_REPLY, bier_table_add_del_reply)                   \
5232 _(MPLS_TUNNEL_ADD_DEL_REPLY, mpls_tunnel_add_del_reply)                 \
5233 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
5234   sw_interface_set_unnumbered_reply)                                    \
5235 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
5236 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
5237 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
5238 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
5239   sw_interface_ip6_enable_disable_reply)                                \
5240 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
5241 _(SR_MPLS_POLICY_ADD_REPLY, sr_mpls_policy_add_reply)                   \
5242 _(SR_MPLS_POLICY_MOD_REPLY, sr_mpls_policy_mod_reply)                   \
5243 _(SR_MPLS_POLICY_DEL_REPLY, sr_mpls_policy_del_reply)                   \
5244 _(SR_POLICY_ADD_REPLY, sr_policy_add_reply)                             \
5245 _(SR_POLICY_MOD_REPLY, sr_policy_mod_reply)                             \
5246 _(SR_POLICY_DEL_REPLY, sr_policy_del_reply)                             \
5247 _(SR_LOCALSID_ADD_DEL_REPLY, sr_localsid_add_del_reply)                 \
5248 _(SR_STEERING_ADD_DEL_REPLY, sr_steering_add_del_reply)                 \
5249 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
5250 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
5251 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
5252 classify_set_interface_ip_table_reply)                                  \
5253 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
5254   classify_set_interface_l2_tables_reply)                               \
5255 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
5256 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
5257 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
5258 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
5259 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
5260   l2tpv3_interface_enable_disable_reply)                                \
5261 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
5262 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
5263 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
5264 _(VXLAN_OFFLOAD_RX_REPLY, vxlan_offload_rx_reply)               \
5265 _(GENEVE_ADD_DEL_TUNNEL_REPLY, geneve_add_del_tunnel_reply)             \
5266 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
5267 _(GENEVE_TUNNEL_DETAILS, geneve_tunnel_details)                         \
5268 _(GRE_TUNNEL_ADD_DEL_REPLY, gre_tunnel_add_del_reply)                   \
5269 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
5270 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
5271 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
5272 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
5273 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
5274 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
5275 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
5276 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
5277 _(SHOW_VERSION_REPLY, show_version_reply)                               \
5278 _(SHOW_THREADS_REPLY, show_threads_reply)                               \
5279 _(L2_FIB_TABLE_DETAILS, l2_fib_table_details)                           \
5280 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)       \
5281 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
5282 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
5283 _(WANT_L2_MACS_EVENTS_REPLY, want_l2_macs_events_reply)                 \
5284 _(L2_MACS_EVENT, l2_macs_event)                                         \
5285 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
5286 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
5287 _(IP_DETAILS, ip_details)                                               \
5288 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
5289 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
5290 _(IPSEC_SPD_ENTRY_ADD_DEL_REPLY, ipsec_spd_entry_add_del_reply)         \
5291 _(IPSEC_SAD_ENTRY_ADD_DEL_REPLY, ipsec_sad_entry_add_del_reply)         \
5292 _(IPSEC_SA_DETAILS, ipsec_sa_details)                                   \
5293 _(IPSEC_TUNNEL_IF_ADD_DEL_REPLY, ipsec_tunnel_if_add_del_reply)         \
5294 _(IPSEC_TUNNEL_IF_SET_SA_REPLY, ipsec_tunnel_if_set_sa_reply)           \
5295 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
5296 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
5297 _(BD_IP_MAC_FLUSH_REPLY, bd_ip_mac_flush_reply)                         \
5298 _(BD_IP_MAC_DETAILS, bd_ip_mac_details)                                 \
5299 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
5300 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
5301 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
5302 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
5303 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
5304 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
5305 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
5306 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
5307 _(ONE_ADD_DEL_LOCATOR_SET_REPLY, one_add_del_locator_set_reply)         \
5308 _(ONE_ADD_DEL_LOCATOR_REPLY, one_add_del_locator_reply)                 \
5309 _(ONE_ADD_DEL_LOCAL_EID_REPLY, one_add_del_local_eid_reply)             \
5310 _(ONE_ADD_DEL_REMOTE_MAPPING_REPLY, one_add_del_remote_mapping_reply)   \
5311 _(ONE_ADD_DEL_ADJACENCY_REPLY, one_add_del_adjacency_reply)             \
5312 _(ONE_ADD_DEL_MAP_RESOLVER_REPLY, one_add_del_map_resolver_reply)       \
5313 _(ONE_ADD_DEL_MAP_SERVER_REPLY, one_add_del_map_server_reply)           \
5314 _(ONE_ENABLE_DISABLE_REPLY, one_enable_disable_reply)                   \
5315 _(ONE_MAP_REGISTER_ENABLE_DISABLE_REPLY,                                \
5316   one_map_register_enable_disable_reply)                                \
5317 _(ONE_MAP_REGISTER_SET_TTL_REPLY, one_map_register_set_ttl_reply)       \
5318 _(ONE_SET_TRANSPORT_PROTOCOL_REPLY, one_set_transport_protocol_reply)   \
5319 _(ONE_GET_TRANSPORT_PROTOCOL_REPLY, one_get_transport_protocol_reply)   \
5320 _(ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                            \
5321   one_map_register_fallback_threshold_reply)                            \
5322 _(ONE_RLOC_PROBE_ENABLE_DISABLE_REPLY,                                  \
5323   one_rloc_probe_enable_disable_reply)                                  \
5324 _(ONE_PITR_SET_LOCATOR_SET_REPLY, one_pitr_set_locator_set_reply)       \
5325 _(ONE_USE_PETR_REPLY, one_use_petr_reply)                               \
5326 _(ONE_MAP_REQUEST_MODE_REPLY, one_map_request_mode_reply)               \
5327 _(ONE_EID_TABLE_ADD_DEL_MAP_REPLY, one_eid_table_add_del_map_reply)     \
5328 _(ONE_LOCATOR_SET_DETAILS, one_locator_set_details)                     \
5329 _(ONE_LOCATOR_DETAILS, one_locator_details)                             \
5330 _(ONE_EID_TABLE_DETAILS, one_eid_table_details)                         \
5331 _(ONE_EID_TABLE_MAP_DETAILS, one_eid_table_map_details)                 \
5332 _(ONE_EID_TABLE_VNI_DETAILS, one_eid_table_vni_details)                 \
5333 _(ONE_MAP_RESOLVER_DETAILS, one_map_resolver_details)                   \
5334 _(ONE_MAP_SERVER_DETAILS, one_map_server_details)                       \
5335 _(ONE_ADJACENCIES_GET_REPLY, one_adjacencies_get_reply)                 \
5336 _(ONE_STATS_DETAILS, one_stats_details)                                 \
5337 _(ONE_STATS_FLUSH_REPLY, one_stats_flush_reply)                         \
5338 _(ONE_STATS_ENABLE_DISABLE_REPLY, one_stats_enable_disable_reply)       \
5339 _(SHOW_ONE_STATS_ENABLE_DISABLE_REPLY,                                  \
5340   show_one_stats_enable_disable_reply)                                  \
5341 _(ONE_ADD_DEL_NDP_ENTRY_REPLY, one_add_del_ndp_entry_reply)             \
5342 _(ONE_NDP_BD_GET_REPLY, one_ndp_bd_get_reply)                           \
5343 _(ONE_NDP_ENTRIES_GET_REPLY, one_ndp_entries_get_reply)                 \
5344 _(ONE_ADD_DEL_L2_ARP_ENTRY_REPLY, one_add_del_l2_arp_entry_reply)       \
5345 _(ONE_L2_ARP_BD_GET_REPLY, one_l2_arp_bd_get_reply)                     \
5346 _(ONE_L2_ARP_ENTRIES_GET_REPLY, one_l2_arp_entries_get_reply)           \
5347 _(ONE_ENABLE_DISABLE_XTR_MODE_REPLY, one_enable_disable_xtr_mode_reply) \
5348 _(ONE_ENABLE_DISABLE_PITR_MODE_REPLY,                                   \
5349   one_enable_disable_pitr_mode_reply)                                   \
5350 _(ONE_ENABLE_DISABLE_PETR_MODE_REPLY,                                   \
5351   one_enable_disable_petr_mode_reply)                                   \
5352 _(ONE_SHOW_XTR_MODE_REPLY, one_show_xtr_mode_reply)                     \
5353 _(ONE_SHOW_PITR_MODE_REPLY, one_show_pitr_mode_reply)                   \
5354 _(ONE_SHOW_PETR_MODE_REPLY, one_show_petr_mode_reply)                   \
5355 _(GPE_SET_ENCAP_MODE_REPLY, gpe_set_encap_mode_reply)                   \
5356 _(GPE_GET_ENCAP_MODE_REPLY, gpe_get_encap_mode_reply)                   \
5357 _(GPE_ADD_DEL_IFACE_REPLY, gpe_add_del_iface_reply)                     \
5358 _(GPE_ENABLE_DISABLE_REPLY, gpe_enable_disable_reply)                   \
5359 _(GPE_ADD_DEL_FWD_ENTRY_REPLY, gpe_add_del_fwd_entry_reply)             \
5360 _(GPE_FWD_ENTRY_VNIS_GET_REPLY, gpe_fwd_entry_vnis_get_reply)           \
5361 _(GPE_FWD_ENTRIES_GET_REPLY, gpe_fwd_entries_get_reply)                 \
5362 _(GPE_NATIVE_FWD_RPATHS_GET_REPLY, gpe_native_fwd_rpaths_get_reply)     \
5363 _(GPE_ADD_DEL_NATIVE_FWD_RPATH_REPLY,                                   \
5364   gpe_add_del_native_fwd_rpath_reply)                                   \
5365 _(GPE_FWD_ENTRY_PATH_DETAILS,                                           \
5366   gpe_fwd_entry_path_details)                                           \
5367 _(SHOW_ONE_STATUS_REPLY, show_one_status_reply)                         \
5368 _(ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                              \
5369   one_add_del_map_request_itr_rlocs_reply)                              \
5370 _(ONE_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                  \
5371   one_get_map_request_itr_rlocs_reply)                                  \
5372 _(SHOW_ONE_NSH_MAPPING_REPLY, show_one_nsh_mapping_reply)               \
5373 _(SHOW_ONE_PITR_REPLY, show_one_pitr_reply)                             \
5374 _(SHOW_ONE_USE_PETR_REPLY, show_one_use_petr_reply)                     \
5375 _(SHOW_ONE_MAP_REQUEST_MODE_REPLY, show_one_map_request_mode_reply)     \
5376 _(SHOW_ONE_RLOC_PROBE_STATE_REPLY, show_one_rloc_probe_state_reply)     \
5377 _(SHOW_ONE_MAP_REGISTER_STATE_REPLY,                                    \
5378   show_one_map_register_state_reply)                                    \
5379 _(SHOW_ONE_MAP_REGISTER_TTL_REPLY, show_one_map_register_ttl_reply)     \
5380 _(SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                       \
5381   show_one_map_register_fallback_threshold_reply)                       \
5382 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
5383 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
5384 _(AF_PACKET_DETAILS, af_packet_details)                                 \
5385 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
5386 _(POLICER_DETAILS, policer_details)                                     \
5387 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
5388 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
5389 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
5390 _(NETMAP_DELETE_REPLY, netmap_delete_reply)                             \
5391 _(MPLS_TUNNEL_DETAILS, mpls_tunnel_details)                             \
5392 _(MPLS_TABLE_DETAILS, mpls_table_details)                               \
5393 _(MPLS_ROUTE_DETAILS, mpls_route_details)                               \
5394 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
5395 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
5396 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
5397 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
5398 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
5399 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
5400 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
5401 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
5402 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
5403 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
5404 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
5405 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
5406 _(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
5407 _(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details)                 \
5408 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
5409 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
5410 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
5411 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
5412 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
5413  ip_source_and_port_range_check_add_del_reply)                          \
5414 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
5415  ip_source_and_port_range_check_interface_add_del_reply)                \
5416 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
5417 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
5418 _(SET_PUNT_REPLY, set_punt_reply)                                       \
5419 _(IP_TABLE_DETAILS, ip_table_details)                                   \
5420 _(IP_ROUTE_DETAILS, ip_route_details)                                   \
5421 _(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply)           \
5422 _(FEATURE_GSO_ENABLE_DISABLE_REPLY, feature_gso_enable_disable_reply)   \
5423 _(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply)       \
5424 _(SW_INTERFACE_ADD_DEL_MAC_ADDRESS_REPLY, sw_interface_add_del_mac_address_reply) \
5425 _(L2_XCONNECT_DETAILS, l2_xconnect_details)                             \
5426 _(HW_INTERFACE_SET_MTU_REPLY, hw_interface_set_mtu_reply)               \
5427 _(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply)           \
5428 _(P2P_ETHERNET_ADD_REPLY, p2p_ethernet_add_reply)                       \
5429 _(P2P_ETHERNET_DEL_REPLY, p2p_ethernet_del_reply)                       \
5430 _(LLDP_CONFIG_REPLY, lldp_config_reply)                                 \
5431 _(SW_INTERFACE_SET_LLDP_REPLY, sw_interface_set_lldp_reply)             \
5432 _(TCP_CONFIGURE_SRC_ADDRESSES_REPLY, tcp_configure_src_addresses_reply) \
5433 _(APP_NAMESPACE_ADD_DEL_REPLY, app_namespace_add_del_reply)             \
5434 _(SESSION_RULE_ADD_DEL_REPLY, session_rule_add_del_reply)               \
5435 _(SESSION_RULES_DETAILS, session_rules_details)                         \
5436 _(IP_CONTAINER_PROXY_ADD_DEL_REPLY, ip_container_proxy_add_del_reply)   \
5437 _(OUTPUT_ACL_SET_INTERFACE_REPLY, output_acl_set_interface_reply)       \
5438 _(QOS_RECORD_ENABLE_DISABLE_REPLY, qos_record_enable_disable_reply)
5439
5440 #define foreach_standalone_reply_msg                                    \
5441 _(SW_INTERFACE_EVENT, sw_interface_event)
5442
5443 typedef struct
5444 {
5445   u8 *name;
5446   u32 value;
5447 } name_sort_t;
5448
5449 #define STR_VTR_OP_CASE(op)     \
5450     case L2_VTR_ ## op:         \
5451         return "" # op;
5452
5453 static const char *
5454 str_vtr_op (u32 vtr_op)
5455 {
5456   switch (vtr_op)
5457     {
5458       STR_VTR_OP_CASE (DISABLED);
5459       STR_VTR_OP_CASE (PUSH_1);
5460       STR_VTR_OP_CASE (PUSH_2);
5461       STR_VTR_OP_CASE (POP_1);
5462       STR_VTR_OP_CASE (POP_2);
5463       STR_VTR_OP_CASE (TRANSLATE_1_1);
5464       STR_VTR_OP_CASE (TRANSLATE_1_2);
5465       STR_VTR_OP_CASE (TRANSLATE_2_1);
5466       STR_VTR_OP_CASE (TRANSLATE_2_2);
5467     }
5468
5469   return "UNKNOWN";
5470 }
5471
5472 static int
5473 dump_sub_interface_table (vat_main_t * vam)
5474 {
5475   const sw_interface_subif_t *sub = NULL;
5476
5477   if (vam->json_output)
5478     {
5479       clib_warning
5480         ("JSON output supported only for VPE API calls and dump_stats_table");
5481       return -99;
5482     }
5483
5484   print (vam->ofp,
5485          "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
5486          "Interface", "sw_if_index",
5487          "sub id", "dot1ad", "tags", "outer id",
5488          "inner id", "exact", "default", "outer any", "inner any");
5489
5490   vec_foreach (sub, vam->sw_if_subif_table)
5491   {
5492     print (vam->ofp,
5493            "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
5494            sub->interface_name,
5495            sub->sw_if_index,
5496            sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
5497            sub->sub_number_of_tags, sub->sub_outer_vlan_id,
5498            sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
5499            sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
5500     if (sub->vtr_op != L2_VTR_DISABLED)
5501       {
5502         print (vam->ofp,
5503                "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
5504                "tag1: %d tag2: %d ]",
5505                str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
5506                sub->vtr_tag1, sub->vtr_tag2);
5507       }
5508   }
5509
5510   return 0;
5511 }
5512
5513 static int
5514 name_sort_cmp (void *a1, void *a2)
5515 {
5516   name_sort_t *n1 = a1;
5517   name_sort_t *n2 = a2;
5518
5519   return strcmp ((char *) n1->name, (char *) n2->name);
5520 }
5521
5522 static int
5523 dump_interface_table (vat_main_t * vam)
5524 {
5525   hash_pair_t *p;
5526   name_sort_t *nses = 0, *ns;
5527
5528   if (vam->json_output)
5529     {
5530       clib_warning
5531         ("JSON output supported only for VPE API calls and dump_stats_table");
5532       return -99;
5533     }
5534
5535   /* *INDENT-OFF* */
5536   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5537   ({
5538     vec_add2 (nses, ns, 1);
5539     ns->name = (u8 *)(p->key);
5540     ns->value = (u32) p->value[0];
5541   }));
5542   /* *INDENT-ON* */
5543
5544   vec_sort_with_function (nses, name_sort_cmp);
5545
5546   print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
5547   vec_foreach (ns, nses)
5548   {
5549     print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
5550   }
5551   vec_free (nses);
5552   return 0;
5553 }
5554
5555 static int
5556 dump_ip_table (vat_main_t * vam, int is_ipv6)
5557 {
5558   const ip_details_t *det = NULL;
5559   const ip_address_details_t *address = NULL;
5560   u32 i = ~0;
5561
5562   print (vam->ofp, "%-12s", "sw_if_index");
5563
5564   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
5565   {
5566     i++;
5567     if (!det->present)
5568       {
5569         continue;
5570       }
5571     print (vam->ofp, "%-12d", i);
5572     print (vam->ofp, "            %-30s%-13s", "Address", "Prefix length");
5573     if (!det->addr)
5574       {
5575         continue;
5576       }
5577     vec_foreach (address, det->addr)
5578     {
5579       print (vam->ofp,
5580              "            %-30U%-13d",
5581              is_ipv6 ? format_ip6_address : format_ip4_address,
5582              address->ip, address->prefix_length);
5583     }
5584   }
5585
5586   return 0;
5587 }
5588
5589 static int
5590 dump_ipv4_table (vat_main_t * vam)
5591 {
5592   if (vam->json_output)
5593     {
5594       clib_warning
5595         ("JSON output supported only for VPE API calls and dump_stats_table");
5596       return -99;
5597     }
5598
5599   return dump_ip_table (vam, 0);
5600 }
5601
5602 static int
5603 dump_ipv6_table (vat_main_t * vam)
5604 {
5605   if (vam->json_output)
5606     {
5607       clib_warning
5608         ("JSON output supported only for VPE API calls and dump_stats_table");
5609       return -99;
5610     }
5611
5612   return dump_ip_table (vam, 1);
5613 }
5614
5615 /*
5616  * Pass CLI buffers directly in the CLI_INBAND API message,
5617  * instead of an additional shared memory area.
5618  */
5619 static int
5620 exec_inband (vat_main_t * vam)
5621 {
5622   vl_api_cli_inband_t *mp;
5623   unformat_input_t *i = vam->input;
5624   int ret;
5625
5626   if (vec_len (i->buffer) == 0)
5627     return -1;
5628
5629   if (vam->exec_mode == 0 && unformat (i, "mode"))
5630     {
5631       vam->exec_mode = 1;
5632       return 0;
5633     }
5634   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
5635     {
5636       vam->exec_mode = 0;
5637       return 0;
5638     }
5639
5640   /*
5641    * In order for the CLI command to work, it
5642    * must be a vector ending in \n, not a C-string ending
5643    * in \n\0.
5644    */
5645   u32 len = vec_len (vam->input->buffer);
5646   M2 (CLI_INBAND, mp, len);
5647   vl_api_to_api_string (len - 1, (const char *) vam->input->buffer, &mp->cmd);
5648
5649   S (mp);
5650   W (ret);
5651   /* json responses may or may not include a useful reply... */
5652   if (vec_len (vam->cmd_reply))
5653     print (vam->ofp, "%v", (char *) (vam->cmd_reply));
5654   return ret;
5655 }
5656
5657 int
5658 exec (vat_main_t * vam)
5659 {
5660   return exec_inband (vam);
5661 }
5662
5663 static int
5664 api_create_loopback (vat_main_t * vam)
5665 {
5666   unformat_input_t *i = vam->input;
5667   vl_api_create_loopback_t *mp;
5668   vl_api_create_loopback_instance_t *mp_lbi;
5669   u8 mac_address[6];
5670   u8 mac_set = 0;
5671   u8 is_specified = 0;
5672   u32 user_instance = 0;
5673   int ret;
5674
5675   clib_memset (mac_address, 0, sizeof (mac_address));
5676
5677   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5678     {
5679       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5680         mac_set = 1;
5681       if (unformat (i, "instance %d", &user_instance))
5682         is_specified = 1;
5683       else
5684         break;
5685     }
5686
5687   if (is_specified)
5688     {
5689       M (CREATE_LOOPBACK_INSTANCE, mp_lbi);
5690       mp_lbi->is_specified = is_specified;
5691       if (is_specified)
5692         mp_lbi->user_instance = htonl (user_instance);
5693       if (mac_set)
5694         clib_memcpy (mp_lbi->mac_address, mac_address, sizeof (mac_address));
5695       S (mp_lbi);
5696     }
5697   else
5698     {
5699       /* Construct the API message */
5700       M (CREATE_LOOPBACK, mp);
5701       if (mac_set)
5702         clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
5703       S (mp);
5704     }
5705
5706   W (ret);
5707   return ret;
5708 }
5709
5710 static int
5711 api_delete_loopback (vat_main_t * vam)
5712 {
5713   unformat_input_t *i = vam->input;
5714   vl_api_delete_loopback_t *mp;
5715   u32 sw_if_index = ~0;
5716   int ret;
5717
5718   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5719     {
5720       if (unformat (i, "sw_if_index %d", &sw_if_index))
5721         ;
5722       else
5723         break;
5724     }
5725
5726   if (sw_if_index == ~0)
5727     {
5728       errmsg ("missing sw_if_index");
5729       return -99;
5730     }
5731
5732   /* Construct the API message */
5733   M (DELETE_LOOPBACK, mp);
5734   mp->sw_if_index = ntohl (sw_if_index);
5735
5736   S (mp);
5737   W (ret);
5738   return ret;
5739 }
5740
5741 static int
5742 api_want_interface_events (vat_main_t * vam)
5743 {
5744   unformat_input_t *i = vam->input;
5745   vl_api_want_interface_events_t *mp;
5746   int enable = -1;
5747   int ret;
5748
5749   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5750     {
5751       if (unformat (i, "enable"))
5752         enable = 1;
5753       else if (unformat (i, "disable"))
5754         enable = 0;
5755       else
5756         break;
5757     }
5758
5759   if (enable == -1)
5760     {
5761       errmsg ("missing enable|disable");
5762       return -99;
5763     }
5764
5765   M (WANT_INTERFACE_EVENTS, mp);
5766   mp->enable_disable = enable;
5767
5768   vam->interface_event_display = enable;
5769
5770   S (mp);
5771   W (ret);
5772   return ret;
5773 }
5774
5775
5776 /* Note: non-static, called once to set up the initial intfc table */
5777 int
5778 api_sw_interface_dump (vat_main_t * vam)
5779 {
5780   vl_api_sw_interface_dump_t *mp;
5781   vl_api_control_ping_t *mp_ping;
5782   hash_pair_t *p;
5783   name_sort_t *nses = 0, *ns;
5784   sw_interface_subif_t *sub = NULL;
5785   int ret;
5786
5787   /* Toss the old name table */
5788   /* *INDENT-OFF* */
5789   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5790   ({
5791     vec_add2 (nses, ns, 1);
5792     ns->name = (u8 *)(p->key);
5793     ns->value = (u32) p->value[0];
5794   }));
5795   /* *INDENT-ON* */
5796
5797   hash_free (vam->sw_if_index_by_interface_name);
5798
5799   vec_foreach (ns, nses) vec_free (ns->name);
5800
5801   vec_free (nses);
5802
5803   vec_foreach (sub, vam->sw_if_subif_table)
5804   {
5805     vec_free (sub->interface_name);
5806   }
5807   vec_free (vam->sw_if_subif_table);
5808
5809   /* recreate the interface name hash table */
5810   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
5811
5812   /*
5813    * Ask for all interface names. Otherwise, the epic catalog of
5814    * name filters becomes ridiculously long, and vat ends up needing
5815    * to be taught about new interface types.
5816    */
5817   M (SW_INTERFACE_DUMP, mp);
5818   S (mp);
5819
5820   /* Use a control ping for synchronization */
5821   MPING (CONTROL_PING, mp_ping);
5822   S (mp_ping);
5823
5824   W (ret);
5825   return ret;
5826 }
5827
5828 static int
5829 api_sw_interface_set_flags (vat_main_t * vam)
5830 {
5831   unformat_input_t *i = vam->input;
5832   vl_api_sw_interface_set_flags_t *mp;
5833   u32 sw_if_index;
5834   u8 sw_if_index_set = 0;
5835   u8 admin_up = 0;
5836   int ret;
5837
5838   /* Parse args required to build the message */
5839   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5840     {
5841       if (unformat (i, "admin-up"))
5842         admin_up = 1;
5843       else if (unformat (i, "admin-down"))
5844         admin_up = 0;
5845       else
5846         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5847         sw_if_index_set = 1;
5848       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5849         sw_if_index_set = 1;
5850       else
5851         break;
5852     }
5853
5854   if (sw_if_index_set == 0)
5855     {
5856       errmsg ("missing interface name or sw_if_index");
5857       return -99;
5858     }
5859
5860   /* Construct the API message */
5861   M (SW_INTERFACE_SET_FLAGS, mp);
5862   mp->sw_if_index = ntohl (sw_if_index);
5863   mp->flags = ntohl ((admin_up) ? IF_STATUS_API_FLAG_ADMIN_UP : 0);
5864
5865   /* send it... */
5866   S (mp);
5867
5868   /* Wait for a reply, return the good/bad news... */
5869   W (ret);
5870   return ret;
5871 }
5872
5873 static int
5874 api_sw_interface_set_rx_mode (vat_main_t * vam)
5875 {
5876   unformat_input_t *i = vam->input;
5877   vl_api_sw_interface_set_rx_mode_t *mp;
5878   u32 sw_if_index;
5879   u8 sw_if_index_set = 0;
5880   int ret;
5881   u8 queue_id_valid = 0;
5882   u32 queue_id;
5883   vnet_hw_interface_rx_mode mode = VNET_HW_INTERFACE_RX_MODE_UNKNOWN;
5884
5885   /* Parse args required to build the message */
5886   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5887     {
5888       if (unformat (i, "queue %d", &queue_id))
5889         queue_id_valid = 1;
5890       else if (unformat (i, "polling"))
5891         mode = VNET_HW_INTERFACE_RX_MODE_POLLING;
5892       else if (unformat (i, "interrupt"))
5893         mode = VNET_HW_INTERFACE_RX_MODE_INTERRUPT;
5894       else if (unformat (i, "adaptive"))
5895         mode = VNET_HW_INTERFACE_RX_MODE_ADAPTIVE;
5896       else
5897         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5898         sw_if_index_set = 1;
5899       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5900         sw_if_index_set = 1;
5901       else
5902         break;
5903     }
5904
5905   if (sw_if_index_set == 0)
5906     {
5907       errmsg ("missing interface name or sw_if_index");
5908       return -99;
5909     }
5910   if (mode == VNET_HW_INTERFACE_RX_MODE_UNKNOWN)
5911     {
5912       errmsg ("missing rx-mode");
5913       return -99;
5914     }
5915
5916   /* Construct the API message */
5917   M (SW_INTERFACE_SET_RX_MODE, mp);
5918   mp->sw_if_index = ntohl (sw_if_index);
5919   mp->mode = (vl_api_rx_mode_t) mode;
5920   mp->queue_id_valid = queue_id_valid;
5921   mp->queue_id = queue_id_valid ? ntohl (queue_id) : ~0;
5922
5923   /* send it... */
5924   S (mp);
5925
5926   /* Wait for a reply, return the good/bad news... */
5927   W (ret);
5928   return ret;
5929 }
5930
5931 static int
5932 api_sw_interface_set_rx_placement (vat_main_t * vam)
5933 {
5934   unformat_input_t *i = vam->input;
5935   vl_api_sw_interface_set_rx_placement_t *mp;
5936   u32 sw_if_index;
5937   u8 sw_if_index_set = 0;
5938   int ret;
5939   u8 is_main = 0;
5940   u32 queue_id, thread_index;
5941
5942   /* Parse args required to build the message */
5943   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5944     {
5945       if (unformat (i, "queue %d", &queue_id))
5946         ;
5947       else if (unformat (i, "main"))
5948         is_main = 1;
5949       else if (unformat (i, "worker %d", &thread_index))
5950         ;
5951       else
5952         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5953         sw_if_index_set = 1;
5954       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5955         sw_if_index_set = 1;
5956       else
5957         break;
5958     }
5959
5960   if (sw_if_index_set == 0)
5961     {
5962       errmsg ("missing interface name or sw_if_index");
5963       return -99;
5964     }
5965
5966   if (is_main)
5967     thread_index = 0;
5968   /* Construct the API message */
5969   M (SW_INTERFACE_SET_RX_PLACEMENT, mp);
5970   mp->sw_if_index = ntohl (sw_if_index);
5971   mp->worker_id = ntohl (thread_index);
5972   mp->queue_id = ntohl (queue_id);
5973   mp->is_main = is_main;
5974
5975   /* send it... */
5976   S (mp);
5977   /* Wait for a reply, return the good/bad news... */
5978   W (ret);
5979   return ret;
5980 }
5981
5982 static void vl_api_sw_interface_rx_placement_details_t_handler
5983   (vl_api_sw_interface_rx_placement_details_t * mp)
5984 {
5985   vat_main_t *vam = &vat_main;
5986   u32 worker_id = ntohl (mp->worker_id);
5987
5988   print (vam->ofp,
5989          "\n%-11d %-11s %-6d %-5d %-9s",
5990          ntohl (mp->sw_if_index), (worker_id == 0) ? "main" : "worker",
5991          worker_id, ntohl (mp->queue_id),
5992          (mp->mode ==
5993           1) ? "polling" : ((mp->mode == 2) ? "interrupt" : "adaptive"));
5994 }
5995
5996 static void vl_api_sw_interface_rx_placement_details_t_handler_json
5997   (vl_api_sw_interface_rx_placement_details_t * mp)
5998 {
5999   vat_main_t *vam = &vat_main;
6000   vat_json_node_t *node = NULL;
6001
6002   if (VAT_JSON_ARRAY != vam->json_tree.type)
6003     {
6004       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
6005       vat_json_init_array (&vam->json_tree);
6006     }
6007   node = vat_json_array_add (&vam->json_tree);
6008
6009   vat_json_init_object (node);
6010   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
6011   vat_json_object_add_uint (node, "worker_id", ntohl (mp->worker_id));
6012   vat_json_object_add_uint (node, "queue_id", ntohl (mp->queue_id));
6013   vat_json_object_add_uint (node, "mode", mp->mode);
6014 }
6015
6016 static int
6017 api_sw_interface_rx_placement_dump (vat_main_t * vam)
6018 {
6019   unformat_input_t *i = vam->input;
6020   vl_api_sw_interface_rx_placement_dump_t *mp;
6021   vl_api_control_ping_t *mp_ping;
6022   int ret;
6023   u32 sw_if_index;
6024   u8 sw_if_index_set = 0;
6025
6026   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6027     {
6028       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6029         sw_if_index_set++;
6030       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6031         sw_if_index_set++;
6032       else
6033         break;
6034     }
6035
6036   print (vam->ofp,
6037          "\n%-11s %-11s %-6s %-5s %-4s",
6038          "sw_if_index", "main/worker", "thread", "queue", "mode");
6039
6040   /* Dump Interface rx placement */
6041   M (SW_INTERFACE_RX_PLACEMENT_DUMP, mp);
6042
6043   if (sw_if_index_set)
6044     mp->sw_if_index = htonl (sw_if_index);
6045   else
6046     mp->sw_if_index = ~0;
6047
6048   S (mp);
6049
6050   /* Use a control ping for synchronization */
6051   MPING (CONTROL_PING, mp_ping);
6052   S (mp_ping);
6053
6054   W (ret);
6055   return ret;
6056 }
6057
6058 static int
6059 api_sw_interface_clear_stats (vat_main_t * vam)
6060 {
6061   unformat_input_t *i = vam->input;
6062   vl_api_sw_interface_clear_stats_t *mp;
6063   u32 sw_if_index;
6064   u8 sw_if_index_set = 0;
6065   int ret;
6066
6067   /* Parse args required to build the message */
6068   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6069     {
6070       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6071         sw_if_index_set = 1;
6072       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6073         sw_if_index_set = 1;
6074       else
6075         break;
6076     }
6077
6078   /* Construct the API message */
6079   M (SW_INTERFACE_CLEAR_STATS, mp);
6080
6081   if (sw_if_index_set == 1)
6082     mp->sw_if_index = ntohl (sw_if_index);
6083   else
6084     mp->sw_if_index = ~0;
6085
6086   /* send it... */
6087   S (mp);
6088
6089   /* Wait for a reply, return the good/bad news... */
6090   W (ret);
6091   return ret;
6092 }
6093
6094 static int
6095 api_sw_interface_add_del_address (vat_main_t * vam)
6096 {
6097   unformat_input_t *i = vam->input;
6098   vl_api_sw_interface_add_del_address_t *mp;
6099   u32 sw_if_index;
6100   u8 sw_if_index_set = 0;
6101   u8 is_add = 1, del_all = 0;
6102   u32 address_length = 0;
6103   u8 v4_address_set = 0;
6104   u8 v6_address_set = 0;
6105   ip4_address_t v4address;
6106   ip6_address_t v6address;
6107   int ret;
6108
6109   /* Parse args required to build the message */
6110   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6111     {
6112       if (unformat (i, "del-all"))
6113         del_all = 1;
6114       else if (unformat (i, "del"))
6115         is_add = 0;
6116       else
6117         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6118         sw_if_index_set = 1;
6119       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6120         sw_if_index_set = 1;
6121       else if (unformat (i, "%U/%d",
6122                          unformat_ip4_address, &v4address, &address_length))
6123         v4_address_set = 1;
6124       else if (unformat (i, "%U/%d",
6125                          unformat_ip6_address, &v6address, &address_length))
6126         v6_address_set = 1;
6127       else
6128         break;
6129     }
6130
6131   if (sw_if_index_set == 0)
6132     {
6133       errmsg ("missing interface name or sw_if_index");
6134       return -99;
6135     }
6136   if (v4_address_set && v6_address_set)
6137     {
6138       errmsg ("both v4 and v6 addresses set");
6139       return -99;
6140     }
6141   if (!v4_address_set && !v6_address_set && !del_all)
6142     {
6143       errmsg ("no addresses set");
6144       return -99;
6145     }
6146
6147   /* Construct the API message */
6148   M (SW_INTERFACE_ADD_DEL_ADDRESS, mp);
6149
6150   mp->sw_if_index = ntohl (sw_if_index);
6151   mp->is_add = is_add;
6152   mp->del_all = del_all;
6153   if (v6_address_set)
6154     {
6155       mp->prefix.address.af = ADDRESS_IP6;
6156       clib_memcpy (mp->prefix.address.un.ip6, &v6address, sizeof (v6address));
6157     }
6158   else
6159     {
6160       mp->prefix.address.af = ADDRESS_IP4;
6161       clib_memcpy (mp->prefix.address.un.ip4, &v4address, sizeof (v4address));
6162     }
6163   mp->prefix.len = address_length;
6164
6165   /* send it... */
6166   S (mp);
6167
6168   /* Wait for a reply, return good/bad news  */
6169   W (ret);
6170   return ret;
6171 }
6172
6173 static int
6174 api_sw_interface_set_mpls_enable (vat_main_t * vam)
6175 {
6176   unformat_input_t *i = vam->input;
6177   vl_api_sw_interface_set_mpls_enable_t *mp;
6178   u32 sw_if_index;
6179   u8 sw_if_index_set = 0;
6180   u8 enable = 1;
6181   int ret;
6182
6183   /* Parse args required to build the message */
6184   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6185     {
6186       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6187         sw_if_index_set = 1;
6188       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6189         sw_if_index_set = 1;
6190       else if (unformat (i, "disable"))
6191         enable = 0;
6192       else if (unformat (i, "dis"))
6193         enable = 0;
6194       else
6195         break;
6196     }
6197
6198   if (sw_if_index_set == 0)
6199     {
6200       errmsg ("missing interface name or sw_if_index");
6201       return -99;
6202     }
6203
6204   /* Construct the API message */
6205   M (SW_INTERFACE_SET_MPLS_ENABLE, mp);
6206
6207   mp->sw_if_index = ntohl (sw_if_index);
6208   mp->enable = enable;
6209
6210   /* send it... */
6211   S (mp);
6212
6213   /* Wait for a reply... */
6214   W (ret);
6215   return ret;
6216 }
6217
6218 static int
6219 api_sw_interface_set_table (vat_main_t * vam)
6220 {
6221   unformat_input_t *i = vam->input;
6222   vl_api_sw_interface_set_table_t *mp;
6223   u32 sw_if_index, vrf_id = 0;
6224   u8 sw_if_index_set = 0;
6225   u8 is_ipv6 = 0;
6226   int ret;
6227
6228   /* Parse args required to build the message */
6229   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6230     {
6231       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6232         sw_if_index_set = 1;
6233       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6234         sw_if_index_set = 1;
6235       else if (unformat (i, "vrf %d", &vrf_id))
6236         ;
6237       else if (unformat (i, "ipv6"))
6238         is_ipv6 = 1;
6239       else
6240         break;
6241     }
6242
6243   if (sw_if_index_set == 0)
6244     {
6245       errmsg ("missing interface name or sw_if_index");
6246       return -99;
6247     }
6248
6249   /* Construct the API message */
6250   M (SW_INTERFACE_SET_TABLE, mp);
6251
6252   mp->sw_if_index = ntohl (sw_if_index);
6253   mp->is_ipv6 = is_ipv6;
6254   mp->vrf_id = ntohl (vrf_id);
6255
6256   /* send it... */
6257   S (mp);
6258
6259   /* Wait for a reply... */
6260   W (ret);
6261   return ret;
6262 }
6263
6264 static void vl_api_sw_interface_get_table_reply_t_handler
6265   (vl_api_sw_interface_get_table_reply_t * mp)
6266 {
6267   vat_main_t *vam = &vat_main;
6268
6269   print (vam->ofp, "%d", ntohl (mp->vrf_id));
6270
6271   vam->retval = ntohl (mp->retval);
6272   vam->result_ready = 1;
6273
6274 }
6275
6276 static void vl_api_sw_interface_get_table_reply_t_handler_json
6277   (vl_api_sw_interface_get_table_reply_t * mp)
6278 {
6279   vat_main_t *vam = &vat_main;
6280   vat_json_node_t node;
6281
6282   vat_json_init_object (&node);
6283   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
6284   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
6285
6286   vat_json_print (vam->ofp, &node);
6287   vat_json_free (&node);
6288
6289   vam->retval = ntohl (mp->retval);
6290   vam->result_ready = 1;
6291 }
6292
6293 static int
6294 api_sw_interface_get_table (vat_main_t * vam)
6295 {
6296   unformat_input_t *i = vam->input;
6297   vl_api_sw_interface_get_table_t *mp;
6298   u32 sw_if_index;
6299   u8 sw_if_index_set = 0;
6300   u8 is_ipv6 = 0;
6301   int ret;
6302
6303   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6304     {
6305       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6306         sw_if_index_set = 1;
6307       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6308         sw_if_index_set = 1;
6309       else if (unformat (i, "ipv6"))
6310         is_ipv6 = 1;
6311       else
6312         break;
6313     }
6314
6315   if (sw_if_index_set == 0)
6316     {
6317       errmsg ("missing interface name or sw_if_index");
6318       return -99;
6319     }
6320
6321   M (SW_INTERFACE_GET_TABLE, mp);
6322   mp->sw_if_index = htonl (sw_if_index);
6323   mp->is_ipv6 = is_ipv6;
6324
6325   S (mp);
6326   W (ret);
6327   return ret;
6328 }
6329
6330 static int
6331 api_sw_interface_set_vpath (vat_main_t * vam)
6332 {
6333   unformat_input_t *i = vam->input;
6334   vl_api_sw_interface_set_vpath_t *mp;
6335   u32 sw_if_index = 0;
6336   u8 sw_if_index_set = 0;
6337   u8 is_enable = 0;
6338   int ret;
6339
6340   /* Parse args required to build the message */
6341   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6342     {
6343       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6344         sw_if_index_set = 1;
6345       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6346         sw_if_index_set = 1;
6347       else if (unformat (i, "enable"))
6348         is_enable = 1;
6349       else if (unformat (i, "disable"))
6350         is_enable = 0;
6351       else
6352         break;
6353     }
6354
6355   if (sw_if_index_set == 0)
6356     {
6357       errmsg ("missing interface name or sw_if_index");
6358       return -99;
6359     }
6360
6361   /* Construct the API message */
6362   M (SW_INTERFACE_SET_VPATH, mp);
6363
6364   mp->sw_if_index = ntohl (sw_if_index);
6365   mp->enable = is_enable;
6366
6367   /* send it... */
6368   S (mp);
6369
6370   /* Wait for a reply... */
6371   W (ret);
6372   return ret;
6373 }
6374
6375 static int
6376 api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
6377 {
6378   unformat_input_t *i = vam->input;
6379   vl_api_sw_interface_set_vxlan_bypass_t *mp;
6380   u32 sw_if_index = 0;
6381   u8 sw_if_index_set = 0;
6382   u8 is_enable = 1;
6383   u8 is_ipv6 = 0;
6384   int ret;
6385
6386   /* Parse args required to build the message */
6387   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6388     {
6389       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6390         sw_if_index_set = 1;
6391       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6392         sw_if_index_set = 1;
6393       else if (unformat (i, "enable"))
6394         is_enable = 1;
6395       else if (unformat (i, "disable"))
6396         is_enable = 0;
6397       else if (unformat (i, "ip4"))
6398         is_ipv6 = 0;
6399       else if (unformat (i, "ip6"))
6400         is_ipv6 = 1;
6401       else
6402         break;
6403     }
6404
6405   if (sw_if_index_set == 0)
6406     {
6407       errmsg ("missing interface name or sw_if_index");
6408       return -99;
6409     }
6410
6411   /* Construct the API message */
6412   M (SW_INTERFACE_SET_VXLAN_BYPASS, mp);
6413
6414   mp->sw_if_index = ntohl (sw_if_index);
6415   mp->enable = is_enable;
6416   mp->is_ipv6 = is_ipv6;
6417
6418   /* send it... */
6419   S (mp);
6420
6421   /* Wait for a reply... */
6422   W (ret);
6423   return ret;
6424 }
6425
6426 static int
6427 api_sw_interface_set_geneve_bypass (vat_main_t * vam)
6428 {
6429   unformat_input_t *i = vam->input;
6430   vl_api_sw_interface_set_geneve_bypass_t *mp;
6431   u32 sw_if_index = 0;
6432   u8 sw_if_index_set = 0;
6433   u8 is_enable = 1;
6434   u8 is_ipv6 = 0;
6435   int ret;
6436
6437   /* Parse args required to build the message */
6438   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6439     {
6440       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6441         sw_if_index_set = 1;
6442       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6443         sw_if_index_set = 1;
6444       else if (unformat (i, "enable"))
6445         is_enable = 1;
6446       else if (unformat (i, "disable"))
6447         is_enable = 0;
6448       else if (unformat (i, "ip4"))
6449         is_ipv6 = 0;
6450       else if (unformat (i, "ip6"))
6451         is_ipv6 = 1;
6452       else
6453         break;
6454     }
6455
6456   if (sw_if_index_set == 0)
6457     {
6458       errmsg ("missing interface name or sw_if_index");
6459       return -99;
6460     }
6461
6462   /* Construct the API message */
6463   M (SW_INTERFACE_SET_GENEVE_BYPASS, mp);
6464
6465   mp->sw_if_index = ntohl (sw_if_index);
6466   mp->enable = is_enable;
6467   mp->is_ipv6 = is_ipv6;
6468
6469   /* send it... */
6470   S (mp);
6471
6472   /* Wait for a reply... */
6473   W (ret);
6474   return ret;
6475 }
6476
6477 static int
6478 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
6479 {
6480   unformat_input_t *i = vam->input;
6481   vl_api_sw_interface_set_l2_xconnect_t *mp;
6482   u32 rx_sw_if_index;
6483   u8 rx_sw_if_index_set = 0;
6484   u32 tx_sw_if_index;
6485   u8 tx_sw_if_index_set = 0;
6486   u8 enable = 1;
6487   int ret;
6488
6489   /* Parse args required to build the message */
6490   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6491     {
6492       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
6493         rx_sw_if_index_set = 1;
6494       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
6495         tx_sw_if_index_set = 1;
6496       else if (unformat (i, "rx"))
6497         {
6498           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6499             {
6500               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6501                             &rx_sw_if_index))
6502                 rx_sw_if_index_set = 1;
6503             }
6504           else
6505             break;
6506         }
6507       else if (unformat (i, "tx"))
6508         {
6509           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6510             {
6511               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6512                             &tx_sw_if_index))
6513                 tx_sw_if_index_set = 1;
6514             }
6515           else
6516             break;
6517         }
6518       else if (unformat (i, "enable"))
6519         enable = 1;
6520       else if (unformat (i, "disable"))
6521         enable = 0;
6522       else
6523         break;
6524     }
6525
6526   if (rx_sw_if_index_set == 0)
6527     {
6528       errmsg ("missing rx interface name or rx_sw_if_index");
6529       return -99;
6530     }
6531
6532   if (enable && (tx_sw_if_index_set == 0))
6533     {
6534       errmsg ("missing tx interface name or tx_sw_if_index");
6535       return -99;
6536     }
6537
6538   M (SW_INTERFACE_SET_L2_XCONNECT, mp);
6539
6540   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6541   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
6542   mp->enable = enable;
6543
6544   S (mp);
6545   W (ret);
6546   return ret;
6547 }
6548
6549 static int
6550 api_sw_interface_set_l2_bridge (vat_main_t * vam)
6551 {
6552   unformat_input_t *i = vam->input;
6553   vl_api_sw_interface_set_l2_bridge_t *mp;
6554   vl_api_l2_port_type_t port_type;
6555   u32 rx_sw_if_index;
6556   u8 rx_sw_if_index_set = 0;
6557   u32 bd_id;
6558   u8 bd_id_set = 0;
6559   u32 shg = 0;
6560   u8 enable = 1;
6561   int ret;
6562
6563   port_type = L2_API_PORT_TYPE_NORMAL;
6564
6565   /* Parse args required to build the message */
6566   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6567     {
6568       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
6569         rx_sw_if_index_set = 1;
6570       else if (unformat (i, "bd_id %d", &bd_id))
6571         bd_id_set = 1;
6572       else
6573         if (unformat
6574             (i, "%U", api_unformat_sw_if_index, vam, &rx_sw_if_index))
6575         rx_sw_if_index_set = 1;
6576       else if (unformat (i, "shg %d", &shg))
6577         ;
6578       else if (unformat (i, "bvi"))
6579         port_type = L2_API_PORT_TYPE_BVI;
6580       else if (unformat (i, "uu-fwd"))
6581         port_type = L2_API_PORT_TYPE_UU_FWD;
6582       else if (unformat (i, "enable"))
6583         enable = 1;
6584       else if (unformat (i, "disable"))
6585         enable = 0;
6586       else
6587         break;
6588     }
6589
6590   if (rx_sw_if_index_set == 0)
6591     {
6592       errmsg ("missing rx interface name or sw_if_index");
6593       return -99;
6594     }
6595
6596   if (enable && (bd_id_set == 0))
6597     {
6598       errmsg ("missing bridge domain");
6599       return -99;
6600     }
6601
6602   M (SW_INTERFACE_SET_L2_BRIDGE, mp);
6603
6604   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6605   mp->bd_id = ntohl (bd_id);
6606   mp->shg = (u8) shg;
6607   mp->port_type = ntohl (port_type);
6608   mp->enable = enable;
6609
6610   S (mp);
6611   W (ret);
6612   return ret;
6613 }
6614
6615 static int
6616 api_bridge_domain_dump (vat_main_t * vam)
6617 {
6618   unformat_input_t *i = vam->input;
6619   vl_api_bridge_domain_dump_t *mp;
6620   vl_api_control_ping_t *mp_ping;
6621   u32 bd_id = ~0;
6622   int ret;
6623
6624   /* Parse args required to build the message */
6625   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6626     {
6627       if (unformat (i, "bd_id %d", &bd_id))
6628         ;
6629       else
6630         break;
6631     }
6632
6633   M (BRIDGE_DOMAIN_DUMP, mp);
6634   mp->bd_id = ntohl (bd_id);
6635   S (mp);
6636
6637   /* Use a control ping for synchronization */
6638   MPING (CONTROL_PING, mp_ping);
6639   S (mp_ping);
6640
6641   W (ret);
6642   return ret;
6643 }
6644
6645 static int
6646 api_bridge_domain_add_del (vat_main_t * vam)
6647 {
6648   unformat_input_t *i = vam->input;
6649   vl_api_bridge_domain_add_del_t *mp;
6650   u32 bd_id = ~0;
6651   u8 is_add = 1;
6652   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
6653   u8 *bd_tag = NULL;
6654   u32 mac_age = 0;
6655   int ret;
6656
6657   /* Parse args required to build the message */
6658   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6659     {
6660       if (unformat (i, "bd_id %d", &bd_id))
6661         ;
6662       else if (unformat (i, "flood %d", &flood))
6663         ;
6664       else if (unformat (i, "uu-flood %d", &uu_flood))
6665         ;
6666       else if (unformat (i, "forward %d", &forward))
6667         ;
6668       else if (unformat (i, "learn %d", &learn))
6669         ;
6670       else if (unformat (i, "arp-term %d", &arp_term))
6671         ;
6672       else if (unformat (i, "mac-age %d", &mac_age))
6673         ;
6674       else if (unformat (i, "bd-tag %s", &bd_tag))
6675         ;
6676       else if (unformat (i, "del"))
6677         {
6678           is_add = 0;
6679           flood = uu_flood = forward = learn = 0;
6680         }
6681       else
6682         break;
6683     }
6684
6685   if (bd_id == ~0)
6686     {
6687       errmsg ("missing bridge domain");
6688       ret = -99;
6689       goto done;
6690     }
6691
6692   if (mac_age > 255)
6693     {
6694       errmsg ("mac age must be less than 256 ");
6695       ret = -99;
6696       goto done;
6697     }
6698
6699   if ((bd_tag) && (vec_len (bd_tag) > 63))
6700     {
6701       errmsg ("bd-tag cannot be longer than 63");
6702       ret = -99;
6703       goto done;
6704     }
6705
6706   M (BRIDGE_DOMAIN_ADD_DEL, mp);
6707
6708   mp->bd_id = ntohl (bd_id);
6709   mp->flood = flood;
6710   mp->uu_flood = uu_flood;
6711   mp->forward = forward;
6712   mp->learn = learn;
6713   mp->arp_term = arp_term;
6714   mp->is_add = is_add;
6715   mp->mac_age = (u8) mac_age;
6716   if (bd_tag)
6717     {
6718       clib_memcpy (mp->bd_tag, bd_tag, vec_len (bd_tag));
6719       mp->bd_tag[vec_len (bd_tag)] = 0;
6720     }
6721   S (mp);
6722   W (ret);
6723
6724 done:
6725   vec_free (bd_tag);
6726   return ret;
6727 }
6728
6729 static int
6730 api_l2fib_flush_bd (vat_main_t * vam)
6731 {
6732   unformat_input_t *i = vam->input;
6733   vl_api_l2fib_flush_bd_t *mp;
6734   u32 bd_id = ~0;
6735   int ret;
6736
6737   /* Parse args required to build the message */
6738   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6739     {
6740       if (unformat (i, "bd_id %d", &bd_id));
6741       else
6742         break;
6743     }
6744
6745   if (bd_id == ~0)
6746     {
6747       errmsg ("missing bridge domain");
6748       return -99;
6749     }
6750
6751   M (L2FIB_FLUSH_BD, mp);
6752
6753   mp->bd_id = htonl (bd_id);
6754
6755   S (mp);
6756   W (ret);
6757   return ret;
6758 }
6759
6760 static int
6761 api_l2fib_flush_int (vat_main_t * vam)
6762 {
6763   unformat_input_t *i = vam->input;
6764   vl_api_l2fib_flush_int_t *mp;
6765   u32 sw_if_index = ~0;
6766   int ret;
6767
6768   /* Parse args required to build the message */
6769   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6770     {
6771       if (unformat (i, "sw_if_index %d", &sw_if_index));
6772       else
6773         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index));
6774       else
6775         break;
6776     }
6777
6778   if (sw_if_index == ~0)
6779     {
6780       errmsg ("missing interface name or sw_if_index");
6781       return -99;
6782     }
6783
6784   M (L2FIB_FLUSH_INT, mp);
6785
6786   mp->sw_if_index = ntohl (sw_if_index);
6787
6788   S (mp);
6789   W (ret);
6790   return ret;
6791 }
6792
6793 static int
6794 api_l2fib_add_del (vat_main_t * vam)
6795 {
6796   unformat_input_t *i = vam->input;
6797   vl_api_l2fib_add_del_t *mp;
6798   f64 timeout;
6799   u8 mac[6] = { 0 };
6800   u8 mac_set = 0;
6801   u32 bd_id;
6802   u8 bd_id_set = 0;
6803   u32 sw_if_index = 0;
6804   u8 sw_if_index_set = 0;
6805   u8 is_add = 1;
6806   u8 static_mac = 0;
6807   u8 filter_mac = 0;
6808   u8 bvi_mac = 0;
6809   int count = 1;
6810   f64 before = 0;
6811   int j;
6812
6813   /* Parse args required to build the message */
6814   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6815     {
6816       if (unformat (i, "mac %U", unformat_ethernet_address, mac))
6817         mac_set = 1;
6818       else if (unformat (i, "bd_id %d", &bd_id))
6819         bd_id_set = 1;
6820       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6821         sw_if_index_set = 1;
6822       else if (unformat (i, "sw_if"))
6823         {
6824           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6825             {
6826               if (unformat
6827                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6828                 sw_if_index_set = 1;
6829             }
6830           else
6831             break;
6832         }
6833       else if (unformat (i, "static"))
6834         static_mac = 1;
6835       else if (unformat (i, "filter"))
6836         {
6837           filter_mac = 1;
6838           static_mac = 1;
6839         }
6840       else if (unformat (i, "bvi"))
6841         {
6842           bvi_mac = 1;
6843           static_mac = 1;
6844         }
6845       else if (unformat (i, "del"))
6846         is_add = 0;
6847       else if (unformat (i, "count %d", &count))
6848         ;
6849       else
6850         break;
6851     }
6852
6853   if (mac_set == 0)
6854     {
6855       errmsg ("missing mac address");
6856       return -99;
6857     }
6858
6859   if (bd_id_set == 0)
6860     {
6861       errmsg ("missing bridge domain");
6862       return -99;
6863     }
6864
6865   if (is_add && sw_if_index_set == 0 && filter_mac == 0)
6866     {
6867       errmsg ("missing interface name or sw_if_index");
6868       return -99;
6869     }
6870
6871   if (count > 1)
6872     {
6873       /* Turn on async mode */
6874       vam->async_mode = 1;
6875       vam->async_errors = 0;
6876       before = vat_time_now (vam);
6877     }
6878
6879   for (j = 0; j < count; j++)
6880     {
6881       M (L2FIB_ADD_DEL, mp);
6882
6883       clib_memcpy (mp->mac, mac, 6);
6884       mp->bd_id = ntohl (bd_id);
6885       mp->is_add = is_add;
6886       mp->sw_if_index = ntohl (sw_if_index);
6887
6888       if (is_add)
6889         {
6890           mp->static_mac = static_mac;
6891           mp->filter_mac = filter_mac;
6892           mp->bvi_mac = bvi_mac;
6893         }
6894       increment_mac_address (mac);
6895       /* send it... */
6896       S (mp);
6897     }
6898
6899   if (count > 1)
6900     {
6901       vl_api_control_ping_t *mp_ping;
6902       f64 after;
6903
6904       /* Shut off async mode */
6905       vam->async_mode = 0;
6906
6907       MPING (CONTROL_PING, mp_ping);
6908       S (mp_ping);
6909
6910       timeout = vat_time_now (vam) + 1.0;
6911       while (vat_time_now (vam) < timeout)
6912         if (vam->result_ready == 1)
6913           goto out;
6914       vam->retval = -99;
6915
6916     out:
6917       if (vam->retval == -99)
6918         errmsg ("timeout");
6919
6920       if (vam->async_errors > 0)
6921         {
6922           errmsg ("%d asynchronous errors", vam->async_errors);
6923           vam->retval = -98;
6924         }
6925       vam->async_errors = 0;
6926       after = vat_time_now (vam);
6927
6928       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
6929              count, after - before, count / (after - before));
6930     }
6931   else
6932     {
6933       int ret;
6934
6935       /* Wait for a reply... */
6936       W (ret);
6937       return ret;
6938     }
6939   /* Return the good/bad news */
6940   return (vam->retval);
6941 }
6942
6943 static int
6944 api_bridge_domain_set_mac_age (vat_main_t * vam)
6945 {
6946   unformat_input_t *i = vam->input;
6947   vl_api_bridge_domain_set_mac_age_t *mp;
6948   u32 bd_id = ~0;
6949   u32 mac_age = 0;
6950   int ret;
6951
6952   /* Parse args required to build the message */
6953   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6954     {
6955       if (unformat (i, "bd_id %d", &bd_id));
6956       else if (unformat (i, "mac-age %d", &mac_age));
6957       else
6958         break;
6959     }
6960
6961   if (bd_id == ~0)
6962     {
6963       errmsg ("missing bridge domain");
6964       return -99;
6965     }
6966
6967   if (mac_age > 255)
6968     {
6969       errmsg ("mac age must be less than 256 ");
6970       return -99;
6971     }
6972
6973   M (BRIDGE_DOMAIN_SET_MAC_AGE, mp);
6974
6975   mp->bd_id = htonl (bd_id);
6976   mp->mac_age = (u8) mac_age;
6977
6978   S (mp);
6979   W (ret);
6980   return ret;
6981 }
6982
6983 static int
6984 api_l2_flags (vat_main_t * vam)
6985 {
6986   unformat_input_t *i = vam->input;
6987   vl_api_l2_flags_t *mp;
6988   u32 sw_if_index;
6989   u32 flags = 0;
6990   u8 sw_if_index_set = 0;
6991   u8 is_set = 0;
6992   int ret;
6993
6994   /* Parse args required to build the message */
6995   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6996     {
6997       if (unformat (i, "sw_if_index %d", &sw_if_index))
6998         sw_if_index_set = 1;
6999       else if (unformat (i, "sw_if"))
7000         {
7001           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7002             {
7003               if (unformat
7004                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7005                 sw_if_index_set = 1;
7006             }
7007           else
7008             break;
7009         }
7010       else if (unformat (i, "learn"))
7011         flags |= L2_LEARN;
7012       else if (unformat (i, "forward"))
7013         flags |= L2_FWD;
7014       else if (unformat (i, "flood"))
7015         flags |= L2_FLOOD;
7016       else if (unformat (i, "uu-flood"))
7017         flags |= L2_UU_FLOOD;
7018       else if (unformat (i, "arp-term"))
7019         flags |= L2_ARP_TERM;
7020       else if (unformat (i, "off"))
7021         is_set = 0;
7022       else if (unformat (i, "disable"))
7023         is_set = 0;
7024       else
7025         break;
7026     }
7027
7028   if (sw_if_index_set == 0)
7029     {
7030       errmsg ("missing interface name or sw_if_index");
7031       return -99;
7032     }
7033
7034   M (L2_FLAGS, mp);
7035
7036   mp->sw_if_index = ntohl (sw_if_index);
7037   mp->feature_bitmap = ntohl (flags);
7038   mp->is_set = is_set;
7039
7040   S (mp);
7041   W (ret);
7042   return ret;
7043 }
7044
7045 static int
7046 api_bridge_flags (vat_main_t * vam)
7047 {
7048   unformat_input_t *i = vam->input;
7049   vl_api_bridge_flags_t *mp;
7050   u32 bd_id;
7051   u8 bd_id_set = 0;
7052   u8 is_set = 1;
7053   bd_flags_t flags = 0;
7054   int ret;
7055
7056   /* Parse args required to build the message */
7057   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7058     {
7059       if (unformat (i, "bd_id %d", &bd_id))
7060         bd_id_set = 1;
7061       else if (unformat (i, "learn"))
7062         flags |= BRIDGE_API_FLAG_LEARN;
7063       else if (unformat (i, "forward"))
7064         flags |= BRIDGE_API_FLAG_FWD;
7065       else if (unformat (i, "flood"))
7066         flags |= BRIDGE_API_FLAG_FLOOD;
7067       else if (unformat (i, "uu-flood"))
7068         flags |= BRIDGE_API_FLAG_UU_FLOOD;
7069       else if (unformat (i, "arp-term"))
7070         flags |= BRIDGE_API_FLAG_ARP_TERM;
7071       else if (unformat (i, "off"))
7072         is_set = 0;
7073       else if (unformat (i, "disable"))
7074         is_set = 0;
7075       else
7076         break;
7077     }
7078
7079   if (bd_id_set == 0)
7080     {
7081       errmsg ("missing bridge domain");
7082       return -99;
7083     }
7084
7085   M (BRIDGE_FLAGS, mp);
7086
7087   mp->bd_id = ntohl (bd_id);
7088   mp->flags = ntohl (flags);
7089   mp->is_set = is_set;
7090
7091   S (mp);
7092   W (ret);
7093   return ret;
7094 }
7095
7096 static int
7097 api_bd_ip_mac_add_del (vat_main_t * vam)
7098 {
7099   vl_api_address_t ip = VL_API_ZERO_ADDRESS;
7100   vl_api_mac_address_t mac = { 0 };
7101   unformat_input_t *i = vam->input;
7102   vl_api_bd_ip_mac_add_del_t *mp;
7103   u32 bd_id;
7104   u8 is_add = 1;
7105   u8 bd_id_set = 0;
7106   u8 ip_set = 0;
7107   u8 mac_set = 0;
7108   int ret;
7109
7110
7111   /* Parse args required to build the message */
7112   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7113     {
7114       if (unformat (i, "bd_id %d", &bd_id))
7115         {
7116           bd_id_set++;
7117         }
7118       else if (unformat (i, "%U", unformat_vl_api_address, &ip))
7119         {
7120           ip_set++;
7121         }
7122       else if (unformat (i, "%U", unformat_vl_api_mac_address, &mac))
7123         {
7124           mac_set++;
7125         }
7126       else if (unformat (i, "del"))
7127         is_add = 0;
7128       else
7129         break;
7130     }
7131
7132   if (bd_id_set == 0)
7133     {
7134       errmsg ("missing bridge domain");
7135       return -99;
7136     }
7137   else if (ip_set == 0)
7138     {
7139       errmsg ("missing IP address");
7140       return -99;
7141     }
7142   else if (mac_set == 0)
7143     {
7144       errmsg ("missing MAC address");
7145       return -99;
7146     }
7147
7148   M (BD_IP_MAC_ADD_DEL, mp);
7149
7150   mp->entry.bd_id = ntohl (bd_id);
7151   mp->is_add = is_add;
7152
7153   clib_memcpy (&mp->entry.ip, &ip, sizeof (ip));
7154   clib_memcpy (&mp->entry.mac, &mac, sizeof (mac));
7155
7156   S (mp);
7157   W (ret);
7158   return ret;
7159 }
7160
7161 static int
7162 api_bd_ip_mac_flush (vat_main_t * vam)
7163 {
7164   unformat_input_t *i = vam->input;
7165   vl_api_bd_ip_mac_flush_t *mp;
7166   u32 bd_id;
7167   u8 bd_id_set = 0;
7168   int ret;
7169
7170   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7171     {
7172       if (unformat (i, "bd_id %d", &bd_id))
7173         {
7174           bd_id_set++;
7175         }
7176       else
7177         break;
7178     }
7179
7180   if (bd_id_set == 0)
7181     {
7182       errmsg ("missing bridge domain");
7183       return -99;
7184     }
7185
7186   M (BD_IP_MAC_FLUSH, mp);
7187
7188   mp->bd_id = ntohl (bd_id);
7189
7190   S (mp);
7191   W (ret);
7192   return ret;
7193 }
7194
7195 static void vl_api_bd_ip_mac_details_t_handler
7196   (vl_api_bd_ip_mac_details_t * mp)
7197 {
7198   vat_main_t *vam = &vat_main;
7199
7200   print (vam->ofp,
7201          "\n%-5d %U %U",
7202          ntohl (mp->entry.bd_id),
7203          format_vl_api_mac_address, mp->entry.mac,
7204          format_vl_api_address, &mp->entry.ip);
7205 }
7206
7207 static void vl_api_bd_ip_mac_details_t_handler_json
7208   (vl_api_bd_ip_mac_details_t * mp)
7209 {
7210   vat_main_t *vam = &vat_main;
7211   vat_json_node_t *node = NULL;
7212
7213   if (VAT_JSON_ARRAY != vam->json_tree.type)
7214     {
7215       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
7216       vat_json_init_array (&vam->json_tree);
7217     }
7218   node = vat_json_array_add (&vam->json_tree);
7219
7220   vat_json_init_object (node);
7221   vat_json_object_add_uint (node, "bd_id", ntohl (mp->entry.bd_id));
7222   vat_json_object_add_string_copy (node, "mac_address",
7223                                    format (0, "%U", format_vl_api_mac_address,
7224                                            &mp->entry.mac));
7225   u8 *ip = 0;
7226
7227   ip = format (0, "%U", format_vl_api_address, &mp->entry.ip);
7228   vat_json_object_add_string_copy (node, "ip_address", ip);
7229   vec_free (ip);
7230 }
7231
7232 static int
7233 api_bd_ip_mac_dump (vat_main_t * vam)
7234 {
7235   unformat_input_t *i = vam->input;
7236   vl_api_bd_ip_mac_dump_t *mp;
7237   vl_api_control_ping_t *mp_ping;
7238   int ret;
7239   u32 bd_id;
7240   u8 bd_id_set = 0;
7241
7242   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7243     {
7244       if (unformat (i, "bd_id %d", &bd_id))
7245         {
7246           bd_id_set++;
7247         }
7248       else
7249         break;
7250     }
7251
7252   print (vam->ofp,
7253          "\n%-5s %-7s %-20s %-30s",
7254          "bd_id", "is_ipv6", "mac_address", "ip_address");
7255
7256   /* Dump Bridge Domain Ip to Mac entries */
7257   M (BD_IP_MAC_DUMP, mp);
7258
7259   if (bd_id_set)
7260     mp->bd_id = htonl (bd_id);
7261   else
7262     mp->bd_id = ~0;
7263
7264   S (mp);
7265
7266   /* Use a control ping for synchronization */
7267   MPING (CONTROL_PING, mp_ping);
7268   S (mp_ping);
7269
7270   W (ret);
7271   return ret;
7272 }
7273
7274 static int
7275 api_tap_create_v2 (vat_main_t * vam)
7276 {
7277   unformat_input_t *i = vam->input;
7278   vl_api_tap_create_v2_t *mp;
7279 #define TAP_FLAG_GSO (1 << 0)
7280   u8 mac_address[6];
7281   u8 random_mac = 1;
7282   u32 id = ~0;
7283   u8 *host_if_name = 0;
7284   u8 *host_ns = 0;
7285   u8 host_mac_addr[6];
7286   u8 host_mac_addr_set = 0;
7287   u8 *host_bridge = 0;
7288   ip4_address_t host_ip4_addr;
7289   ip4_address_t host_ip4_gw;
7290   u8 host_ip4_gw_set = 0;
7291   u32 host_ip4_prefix_len = 0;
7292   ip6_address_t host_ip6_addr;
7293   ip6_address_t host_ip6_gw;
7294   u8 host_ip6_gw_set = 0;
7295   u32 host_ip6_prefix_len = 0;
7296   u8 host_mtu_set = 0;
7297   u32 host_mtu_size = 0;
7298   u32 tap_flags = 0;
7299   int ret;
7300   u32 rx_ring_sz = 0, tx_ring_sz = 0;
7301
7302   clib_memset (mac_address, 0, sizeof (mac_address));
7303
7304   /* Parse args required to build the message */
7305   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7306     {
7307       if (unformat (i, "hw-addr %U", unformat_ethernet_address, mac_address))
7308         {
7309           random_mac = 0;
7310         }
7311       else if (unformat (i, "id %u", &id))
7312         ;
7313       else if (unformat (i, "host-if-name %s", &host_if_name))
7314         ;
7315       else if (unformat (i, "host-ns %s", &host_ns))
7316         ;
7317       else if (unformat (i, "host-mac-addr %U", unformat_ethernet_address,
7318                          host_mac_addr))
7319         host_mac_addr_set = 1;
7320       else if (unformat (i, "host-bridge %s", &host_bridge))
7321         ;
7322       else if (unformat (i, "host-ip4-addr %U/%d", unformat_ip4_address,
7323                          &host_ip4_addr, &host_ip4_prefix_len))
7324         ;
7325       else if (unformat (i, "host-ip6-addr %U/%d", unformat_ip6_address,
7326                          &host_ip6_addr, &host_ip6_prefix_len))
7327         ;
7328       else if (unformat (i, "host-ip4-gw %U", unformat_ip4_address,
7329                          &host_ip4_gw))
7330         host_ip4_gw_set = 1;
7331       else if (unformat (i, "host-ip6-gw %U", unformat_ip6_address,
7332                          &host_ip6_gw))
7333         host_ip6_gw_set = 1;
7334       else if (unformat (i, "rx-ring-size %d", &rx_ring_sz))
7335         ;
7336       else if (unformat (i, "tx-ring-size %d", &tx_ring_sz))
7337         ;
7338       else if (unformat (i, "host-mtu-size %d", &host_mtu_size))
7339         host_mtu_set = 1;
7340       else if (unformat (i, "no-gso"))
7341         tap_flags &= ~TAP_FLAG_GSO;
7342       else if (unformat (i, "gso"))
7343         tap_flags |= TAP_FLAG_GSO;
7344       else
7345         break;
7346     }
7347
7348   if (vec_len (host_if_name) > 63)
7349     {
7350       errmsg ("tap name too long. ");
7351       return -99;
7352     }
7353   if (vec_len (host_ns) > 63)
7354     {
7355       errmsg ("host name space too long. ");
7356       return -99;
7357     }
7358   if (vec_len (host_bridge) > 63)
7359     {
7360       errmsg ("host bridge name too long. ");
7361       return -99;
7362     }
7363   if (host_ip4_prefix_len > 32)
7364     {
7365       errmsg ("host ip4 prefix length not valid. ");
7366       return -99;
7367     }
7368   if (host_ip6_prefix_len > 128)
7369     {
7370       errmsg ("host ip6 prefix length not valid. ");
7371       return -99;
7372     }
7373   if (!is_pow2 (rx_ring_sz))
7374     {
7375       errmsg ("rx ring size must be power of 2. ");
7376       return -99;
7377     }
7378   if (rx_ring_sz > 32768)
7379     {
7380       errmsg ("rx ring size must be 32768 or lower. ");
7381       return -99;
7382     }
7383   if (!is_pow2 (tx_ring_sz))
7384     {
7385       errmsg ("tx ring size must be power of 2. ");
7386       return -99;
7387     }
7388   if (tx_ring_sz > 32768)
7389     {
7390       errmsg ("tx ring size must be 32768 or lower. ");
7391       return -99;
7392     }
7393   if (host_mtu_set && (host_mtu_size < 64 || host_mtu_size > 65355))
7394     {
7395       errmsg ("host MTU size must be in between 64 and 65355. ");
7396       return -99;
7397     }
7398
7399   /* Construct the API message */
7400   M (TAP_CREATE_V2, mp);
7401
7402   mp->use_random_mac = random_mac;
7403
7404   mp->id = ntohl (id);
7405   mp->host_namespace_set = host_ns != 0;
7406   mp->host_bridge_set = host_bridge != 0;
7407   mp->host_ip4_prefix_set = host_ip4_prefix_len != 0;
7408   mp->host_ip6_prefix_set = host_ip6_prefix_len != 0;
7409   mp->rx_ring_sz = ntohs (rx_ring_sz);
7410   mp->tx_ring_sz = ntohs (tx_ring_sz);
7411   mp->host_mtu_set = host_mtu_set;
7412   mp->host_mtu_size = ntohl (host_mtu_size);
7413   mp->tap_flags = ntohl (tap_flags);
7414
7415   if (random_mac == 0)
7416     clib_memcpy (mp->mac_address, mac_address, 6);
7417   if (host_mac_addr_set)
7418     clib_memcpy (mp->host_mac_addr, host_mac_addr, 6);
7419   if (host_if_name)
7420     clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
7421   if (host_ns)
7422     clib_memcpy (mp->host_namespace, host_ns, vec_len (host_ns));
7423   if (host_bridge)
7424     clib_memcpy (mp->host_bridge, host_bridge, vec_len (host_bridge));
7425   if (host_ip4_prefix_len)
7426     clib_memcpy (mp->host_ip4_prefix.address, &host_ip4_addr, 4);
7427   if (host_ip6_prefix_len)
7428     clib_memcpy (mp->host_ip6_prefix.address, &host_ip6_addr, 16);
7429   if (host_ip4_gw_set)
7430     clib_memcpy (mp->host_ip4_gw, &host_ip4_gw, 4);
7431   if (host_ip6_gw_set)
7432     clib_memcpy (mp->host_ip6_gw, &host_ip6_gw, 16);
7433
7434   vec_free (host_ns);
7435   vec_free (host_if_name);
7436   vec_free (host_bridge);
7437
7438   /* send it... */
7439   S (mp);
7440
7441   /* Wait for a reply... */
7442   W (ret);
7443   return ret;
7444 }
7445
7446 static int
7447 api_tap_delete_v2 (vat_main_t * vam)
7448 {
7449   unformat_input_t *i = vam->input;
7450   vl_api_tap_delete_v2_t *mp;
7451   u32 sw_if_index = ~0;
7452   u8 sw_if_index_set = 0;
7453   int ret;
7454
7455   /* Parse args required to build the message */
7456   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7457     {
7458       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7459         sw_if_index_set = 1;
7460       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7461         sw_if_index_set = 1;
7462       else
7463         break;
7464     }
7465
7466   if (sw_if_index_set == 0)
7467     {
7468       errmsg ("missing vpp interface name. ");
7469       return -99;
7470     }
7471
7472   /* Construct the API message */
7473   M (TAP_DELETE_V2, mp);
7474
7475   mp->sw_if_index = ntohl (sw_if_index);
7476
7477   /* send it... */
7478   S (mp);
7479
7480   /* Wait for a reply... */
7481   W (ret);
7482   return ret;
7483 }
7484
7485 uword
7486 unformat_vlib_pci_addr (unformat_input_t * input, va_list * args)
7487 {
7488   vlib_pci_addr_t *addr = va_arg (*args, vlib_pci_addr_t *);
7489   u32 x[4];
7490
7491   if (!unformat (input, "%x:%x:%x.%x", &x[0], &x[1], &x[2], &x[3]))
7492     return 0;
7493
7494   addr->domain = x[0];
7495   addr->bus = x[1];
7496   addr->slot = x[2];
7497   addr->function = x[3];
7498
7499   return 1;
7500 }
7501
7502 static int
7503 api_virtio_pci_create (vat_main_t * vam)
7504 {
7505   unformat_input_t *i = vam->input;
7506   vl_api_virtio_pci_create_t *mp;
7507   u8 mac_address[6];
7508   u8 random_mac = 1;
7509   u8 gso_enabled = 0;
7510   u32 pci_addr = 0;
7511   u64 features = (u64) ~ (0ULL);
7512   int ret;
7513
7514   clib_memset (mac_address, 0, sizeof (mac_address));
7515
7516   /* Parse args required to build the message */
7517   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7518     {
7519       if (unformat (i, "hw-addr %U", unformat_ethernet_address, mac_address))
7520         {
7521           random_mac = 0;
7522         }
7523       else if (unformat (i, "pci-addr %U", unformat_vlib_pci_addr, &pci_addr))
7524         ;
7525       else if (unformat (i, "features 0x%llx", &features))
7526         ;
7527       else if (unformat (i, "gso-enabled"))
7528         gso_enabled = 1;
7529       else
7530         break;
7531     }
7532
7533   if (pci_addr == 0)
7534     {
7535       errmsg ("pci address must be non zero. ");
7536       return -99;
7537     }
7538
7539   /* Construct the API message */
7540   M (VIRTIO_PCI_CREATE, mp);
7541
7542   mp->use_random_mac = random_mac;
7543
7544   mp->pci_addr.domain = htons (((vlib_pci_addr_t) pci_addr).domain);
7545   mp->pci_addr.bus = ((vlib_pci_addr_t) pci_addr).bus;
7546   mp->pci_addr.slot = ((vlib_pci_addr_t) pci_addr).slot;
7547   mp->pci_addr.function = ((vlib_pci_addr_t) pci_addr).function;
7548
7549   mp->features = clib_host_to_net_u64 (features);
7550   mp->gso_enabled = gso_enabled;
7551
7552   if (random_mac == 0)
7553     clib_memcpy (mp->mac_address, mac_address, 6);
7554
7555   /* send it... */
7556   S (mp);
7557
7558   /* Wait for a reply... */
7559   W (ret);
7560   return ret;
7561 }
7562
7563 static int
7564 api_virtio_pci_delete (vat_main_t * vam)
7565 {
7566   unformat_input_t *i = vam->input;
7567   vl_api_virtio_pci_delete_t *mp;
7568   u32 sw_if_index = ~0;
7569   u8 sw_if_index_set = 0;
7570   int ret;
7571
7572   /* Parse args required to build the message */
7573   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7574     {
7575       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7576         sw_if_index_set = 1;
7577       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7578         sw_if_index_set = 1;
7579       else
7580         break;
7581     }
7582
7583   if (sw_if_index_set == 0)
7584     {
7585       errmsg ("missing vpp interface name. ");
7586       return -99;
7587     }
7588
7589   /* Construct the API message */
7590   M (VIRTIO_PCI_DELETE, mp);
7591
7592   mp->sw_if_index = htonl (sw_if_index);
7593
7594   /* send it... */
7595   S (mp);
7596
7597   /* Wait for a reply... */
7598   W (ret);
7599   return ret;
7600 }
7601
7602 static int
7603 api_bond_create (vat_main_t * vam)
7604 {
7605   unformat_input_t *i = vam->input;
7606   vl_api_bond_create_t *mp;
7607   u8 mac_address[6];
7608   u8 custom_mac = 0;
7609   int ret;
7610   u8 mode;
7611   u8 lb;
7612   u8 mode_is_set = 0;
7613   u32 id = ~0;
7614   u8 numa_only = 0;
7615
7616   clib_memset (mac_address, 0, sizeof (mac_address));
7617   lb = BOND_LB_L2;
7618
7619   /* Parse args required to build the message */
7620   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7621     {
7622       if (unformat (i, "mode %U", unformat_bond_mode, &mode))
7623         mode_is_set = 1;
7624       else if (((mode == BOND_MODE_LACP) || (mode == BOND_MODE_XOR))
7625                && unformat (i, "lb %U", unformat_bond_load_balance, &lb))
7626         ;
7627       else if (unformat (i, "hw-addr %U", unformat_ethernet_address,
7628                          mac_address))
7629         custom_mac = 1;
7630       else if (unformat (i, "numa-only"))
7631         numa_only = 1;
7632       else if (unformat (i, "id %u", &id))
7633         ;
7634       else
7635         break;
7636     }
7637
7638   if (mode_is_set == 0)
7639     {
7640       errmsg ("Missing bond mode. ");
7641       return -99;
7642     }
7643
7644   /* Construct the API message */
7645   M (BOND_CREATE, mp);
7646
7647   mp->use_custom_mac = custom_mac;
7648
7649   mp->mode = htonl (mode);
7650   mp->lb = htonl (lb);
7651   mp->id = htonl (id);
7652   mp->numa_only = numa_only;
7653
7654   if (custom_mac)
7655     clib_memcpy (mp->mac_address, mac_address, 6);
7656
7657   /* send it... */
7658   S (mp);
7659
7660   /* Wait for a reply... */
7661   W (ret);
7662   return ret;
7663 }
7664
7665 static int
7666 api_bond_delete (vat_main_t * vam)
7667 {
7668   unformat_input_t *i = vam->input;
7669   vl_api_bond_delete_t *mp;
7670   u32 sw_if_index = ~0;
7671   u8 sw_if_index_set = 0;
7672   int ret;
7673
7674   /* Parse args required to build the message */
7675   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7676     {
7677       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7678         sw_if_index_set = 1;
7679       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7680         sw_if_index_set = 1;
7681       else
7682         break;
7683     }
7684
7685   if (sw_if_index_set == 0)
7686     {
7687       errmsg ("missing vpp interface name. ");
7688       return -99;
7689     }
7690
7691   /* Construct the API message */
7692   M (BOND_DELETE, mp);
7693
7694   mp->sw_if_index = ntohl (sw_if_index);
7695
7696   /* send it... */
7697   S (mp);
7698
7699   /* Wait for a reply... */
7700   W (ret);
7701   return ret;
7702 }
7703
7704 static int
7705 api_bond_enslave (vat_main_t * vam)
7706 {
7707   unformat_input_t *i = vam->input;
7708   vl_api_bond_enslave_t *mp;
7709   u32 bond_sw_if_index;
7710   int ret;
7711   u8 is_passive;
7712   u8 is_long_timeout;
7713   u32 bond_sw_if_index_is_set = 0;
7714   u32 sw_if_index;
7715   u8 sw_if_index_is_set = 0;
7716
7717   /* Parse args required to build the message */
7718   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7719     {
7720       if (unformat (i, "sw_if_index %d", &sw_if_index))
7721         sw_if_index_is_set = 1;
7722       else if (unformat (i, "bond %u", &bond_sw_if_index))
7723         bond_sw_if_index_is_set = 1;
7724       else if (unformat (i, "passive %d", &is_passive))
7725         ;
7726       else if (unformat (i, "long-timeout %d", &is_long_timeout))
7727         ;
7728       else
7729         break;
7730     }
7731
7732   if (bond_sw_if_index_is_set == 0)
7733     {
7734       errmsg ("Missing bond sw_if_index. ");
7735       return -99;
7736     }
7737   if (sw_if_index_is_set == 0)
7738     {
7739       errmsg ("Missing slave sw_if_index. ");
7740       return -99;
7741     }
7742
7743   /* Construct the API message */
7744   M (BOND_ENSLAVE, mp);
7745
7746   mp->bond_sw_if_index = ntohl (bond_sw_if_index);
7747   mp->sw_if_index = ntohl (sw_if_index);
7748   mp->is_long_timeout = is_long_timeout;
7749   mp->is_passive = is_passive;
7750
7751   /* send it... */
7752   S (mp);
7753
7754   /* Wait for a reply... */
7755   W (ret);
7756   return ret;
7757 }
7758
7759 static int
7760 api_bond_detach_slave (vat_main_t * vam)
7761 {
7762   unformat_input_t *i = vam->input;
7763   vl_api_bond_detach_slave_t *mp;
7764   u32 sw_if_index = ~0;
7765   u8 sw_if_index_set = 0;
7766   int ret;
7767
7768   /* Parse args required to build the message */
7769   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7770     {
7771       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7772         sw_if_index_set = 1;
7773       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7774         sw_if_index_set = 1;
7775       else
7776         break;
7777     }
7778
7779   if (sw_if_index_set == 0)
7780     {
7781       errmsg ("missing vpp interface name. ");
7782       return -99;
7783     }
7784
7785   /* Construct the API message */
7786   M (BOND_DETACH_SLAVE, mp);
7787
7788   mp->sw_if_index = ntohl (sw_if_index);
7789
7790   /* send it... */
7791   S (mp);
7792
7793   /* Wait for a reply... */
7794   W (ret);
7795   return ret;
7796 }
7797
7798 static int
7799 api_ip_table_add_del (vat_main_t * vam)
7800 {
7801   unformat_input_t *i = vam->input;
7802   vl_api_ip_table_add_del_t *mp;
7803   u32 table_id = ~0;
7804   u8 is_ipv6 = 0;
7805   u8 is_add = 1;
7806   int ret = 0;
7807
7808   /* Parse args required to build the message */
7809   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7810     {
7811       if (unformat (i, "ipv6"))
7812         is_ipv6 = 1;
7813       else if (unformat (i, "del"))
7814         is_add = 0;
7815       else if (unformat (i, "add"))
7816         is_add = 1;
7817       else if (unformat (i, "table %d", &table_id))
7818         ;
7819       else
7820         {
7821           clib_warning ("parse error '%U'", format_unformat_error, i);
7822           return -99;
7823         }
7824     }
7825
7826   if (~0 == table_id)
7827     {
7828       errmsg ("missing table-ID");
7829       return -99;
7830     }
7831
7832   /* Construct the API message */
7833   M (IP_TABLE_ADD_DEL, mp);
7834
7835   mp->table.table_id = ntohl (table_id);
7836   mp->table.is_ip6 = is_ipv6;
7837   mp->is_add = is_add;
7838
7839   /* send it... */
7840   S (mp);
7841
7842   /* Wait for a reply... */
7843   W (ret);
7844
7845   return ret;
7846 }
7847
7848 uword
7849 unformat_fib_path (unformat_input_t * input, va_list * args)
7850 {
7851   vat_main_t *vam = va_arg (*args, vat_main_t *);
7852   vl_api_fib_path_t *path = va_arg (*args, vl_api_fib_path_t *);
7853   u32 weight, preference;
7854   mpls_label_t out_label;
7855
7856   clib_memset (path, 0, sizeof (*path));
7857   path->weight = 1;
7858   path->sw_if_index = ~0;
7859   path->rpf_id = ~0;
7860   path->n_labels = 0;
7861
7862   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7863     {
7864       if (unformat (input, "%U %U",
7865                     unformat_vl_api_ip4_address,
7866                     &path->nh.address.ip4,
7867                     api_unformat_sw_if_index, vam, &path->sw_if_index))
7868         {
7869           path->proto = FIB_API_PATH_NH_PROTO_IP4;
7870         }
7871       else if (unformat (input, "%U %U",
7872                          unformat_vl_api_ip6_address,
7873                          &path->nh.address.ip6,
7874                          api_unformat_sw_if_index, vam, &path->sw_if_index))
7875         {
7876           path->proto = FIB_API_PATH_NH_PROTO_IP6;
7877         }
7878       else if (unformat (input, "weight %u", &weight))
7879         {
7880           path->weight = weight;
7881         }
7882       else if (unformat (input, "preference %u", &preference))
7883         {
7884           path->preference = preference;
7885         }
7886       else if (unformat (input, "%U next-hop-table %d",
7887                          unformat_vl_api_ip4_address,
7888                          &path->nh.address.ip4, &path->table_id))
7889         {
7890           path->proto = FIB_API_PATH_NH_PROTO_IP4;
7891         }
7892       else if (unformat (input, "%U next-hop-table %d",
7893                          unformat_vl_api_ip6_address,
7894                          &path->nh.address.ip6, &path->table_id))
7895         {
7896           path->proto = FIB_API_PATH_NH_PROTO_IP6;
7897         }
7898       else if (unformat (input, "%U",
7899                          unformat_vl_api_ip4_address, &path->nh.address.ip4))
7900         {
7901           /*
7902            * the recursive next-hops are by default in the default table
7903            */
7904           path->table_id = 0;
7905           path->sw_if_index = ~0;
7906           path->proto = FIB_API_PATH_NH_PROTO_IP4;
7907         }
7908       else if (unformat (input, "%U",
7909                          unformat_vl_api_ip6_address, &path->nh.address.ip6))
7910         {
7911           /*
7912            * the recursive next-hops are by default in the default table
7913            */
7914           path->table_id = 0;
7915           path->sw_if_index = ~0;
7916           path->proto = FIB_API_PATH_NH_PROTO_IP6;
7917         }
7918       else if (unformat (input, "resolve-via-host"))
7919         {
7920           path->flags |= FIB_API_PATH_FLAG_RESOLVE_VIA_HOST;
7921         }
7922       else if (unformat (input, "resolve-via-attached"))
7923         {
7924           path->flags |= FIB_API_PATH_FLAG_RESOLVE_VIA_ATTACHED;
7925         }
7926       else if (unformat (input, "ip4-lookup-in-table %d", &path->table_id))
7927         {
7928           path->type = FIB_API_PATH_TYPE_LOCAL;
7929           path->sw_if_index = ~0;
7930           path->proto = FIB_API_PATH_NH_PROTO_IP4;
7931         }
7932       else if (unformat (input, "ip6-lookup-in-table %d", &path->table_id))
7933         {
7934           path->type = FIB_API_PATH_TYPE_LOCAL;
7935           path->sw_if_index = ~0;
7936           path->proto = FIB_API_PATH_NH_PROTO_IP6;
7937         }
7938       else if (unformat (input, "sw_if_index %d", &path->sw_if_index))
7939         ;
7940       else if (unformat (input, "via-label %d", &path->nh.via_label))
7941         {
7942           path->proto = FIB_API_PATH_NH_PROTO_MPLS;
7943           path->sw_if_index = ~0;
7944         }
7945       else if (unformat (input, "l2-input-on %d", &path->sw_if_index))
7946         {
7947           path->proto = FIB_API_PATH_NH_PROTO_ETHERNET;
7948           path->type = FIB_API_PATH_TYPE_INTERFACE_RX;
7949         }
7950       else if (unformat (input, "local"))
7951         {
7952           path->type = FIB_API_PATH_TYPE_LOCAL;
7953         }
7954       else if (unformat (input, "out-labels"))
7955         {
7956           while (unformat (input, "%d", &out_label))
7957             {
7958               path->label_stack[path->n_labels].label = out_label;
7959               path->label_stack[path->n_labels].is_uniform = 0;
7960               path->label_stack[path->n_labels].ttl = 64;
7961               path->n_labels++;
7962             }
7963         }
7964       else if (unformat (input, "via"))
7965         {
7966           /* new path, back up and return */
7967           unformat_put_input (input);
7968           unformat_put_input (input);
7969           unformat_put_input (input);
7970           unformat_put_input (input);
7971           break;
7972         }
7973       else
7974         {
7975           return (0);
7976         }
7977     }
7978
7979   path->proto = ntohl (path->proto);
7980   path->type = ntohl (path->type);
7981   path->flags = ntohl (path->flags);
7982   path->table_id = ntohl (path->table_id);
7983   path->sw_if_index = ntohl (path->sw_if_index);
7984
7985   return (1);
7986 }
7987
7988 static int
7989 api_ip_route_add_del (vat_main_t * vam)
7990 {
7991   unformat_input_t *i = vam->input;
7992   vl_api_ip_route_add_del_t *mp;
7993   u32 vrf_id = 0;
7994   u8 is_add = 1;
7995   u8 is_multipath = 0;
7996   u8 prefix_set = 0;
7997   u8 path_count = 0;
7998   vl_api_prefix_t pfx = { };
7999   vl_api_fib_path_t paths[8];
8000   int count = 1;
8001   int j;
8002   f64 before = 0;
8003   u32 random_add_del = 0;
8004   u32 *random_vector = 0;
8005   u32 random_seed = 0xdeaddabe;
8006
8007   /* Parse args required to build the message */
8008   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8009     {
8010       if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
8011         prefix_set = 1;
8012       else if (unformat (i, "del"))
8013         is_add = 0;
8014       else if (unformat (i, "add"))
8015         is_add = 1;
8016       else if (unformat (i, "vrf %d", &vrf_id))
8017         ;
8018       else if (unformat (i, "count %d", &count))
8019         ;
8020       else if (unformat (i, "random"))
8021         random_add_del = 1;
8022       else if (unformat (i, "multipath"))
8023         is_multipath = 1;
8024       else if (unformat (i, "seed %d", &random_seed))
8025         ;
8026       else
8027         if (unformat
8028             (i, "via %U", unformat_fib_path, vam, &paths[path_count]))
8029         {
8030           path_count++;
8031           if (8 == path_count)
8032             {
8033               errmsg ("max 8 paths");
8034               return -99;
8035             }
8036         }
8037       else
8038         {
8039           clib_warning ("parse error '%U'", format_unformat_error, i);
8040           return -99;
8041         }
8042     }
8043
8044   if (!path_count)
8045     {
8046       errmsg ("specify a path; via ...");
8047       return -99;
8048     }
8049   if (prefix_set == 0)
8050     {
8051       errmsg ("missing prefix");
8052       return -99;
8053     }
8054
8055   /* Generate a pile of unique, random routes */
8056   if (random_add_del)
8057     {
8058       ip4_address_t *i = (ip4_address_t *) & paths[0].nh.address.ip4;
8059       u32 this_random_address;
8060       uword *random_hash;
8061
8062       random_hash = hash_create (count, sizeof (uword));
8063
8064       hash_set (random_hash, i->as_u32, 1);
8065       for (j = 0; j <= count; j++)
8066         {
8067           do
8068             {
8069               this_random_address = random_u32 (&random_seed);
8070               this_random_address =
8071                 clib_host_to_net_u32 (this_random_address);
8072             }
8073           while (hash_get (random_hash, this_random_address));
8074           vec_add1 (random_vector, this_random_address);
8075           hash_set (random_hash, this_random_address, 1);
8076         }
8077       hash_free (random_hash);
8078       set_ip4_address (&pfx.address, random_vector[0]);
8079     }
8080
8081   if (count > 1)
8082     {
8083       /* Turn on async mode */
8084       vam->async_mode = 1;
8085       vam->async_errors = 0;
8086       before = vat_time_now (vam);
8087     }
8088
8089   for (j = 0; j < count; j++)
8090     {
8091       /* Construct the API message */
8092       M2 (IP_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t) * path_count);
8093
8094       mp->is_add = is_add;
8095       mp->is_multipath = is_multipath;
8096
8097       clib_memcpy (&mp->route.prefix, &pfx, sizeof (pfx));
8098       mp->route.table_id = ntohl (vrf_id);
8099       mp->route.n_paths = path_count;
8100
8101       clib_memcpy (&mp->route.paths, &paths, sizeof (paths[0]) * path_count);
8102
8103       if (random_add_del)
8104         set_ip4_address (&pfx.address, random_vector[j + 1]);
8105       else
8106         increment_address (&pfx.address);
8107       /* send it... */
8108       S (mp);
8109       /* If we receive SIGTERM, stop now... */
8110       if (vam->do_exit)
8111         break;
8112     }
8113
8114   /* When testing multiple add/del ops, use a control-ping to sync */
8115   if (count > 1)
8116     {
8117       vl_api_control_ping_t *mp_ping;
8118       f64 after;
8119       f64 timeout;
8120
8121       /* Shut off async mode */
8122       vam->async_mode = 0;
8123
8124       MPING (CONTROL_PING, mp_ping);
8125       S (mp_ping);
8126
8127       timeout = vat_time_now (vam) + 1.0;
8128       while (vat_time_now (vam) < timeout)
8129         if (vam->result_ready == 1)
8130           goto out;
8131       vam->retval = -99;
8132
8133     out:
8134       if (vam->retval == -99)
8135         errmsg ("timeout");
8136
8137       if (vam->async_errors > 0)
8138         {
8139           errmsg ("%d asynchronous errors", vam->async_errors);
8140           vam->retval = -98;
8141         }
8142       vam->async_errors = 0;
8143       after = vat_time_now (vam);
8144
8145       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8146       if (j > 0)
8147         count = j;
8148
8149       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8150              count, after - before, count / (after - before));
8151     }
8152   else
8153     {
8154       int ret;
8155
8156       /* Wait for a reply... */
8157       W (ret);
8158       return ret;
8159     }
8160
8161   /* Return the good/bad news */
8162   return (vam->retval);
8163 }
8164
8165 static int
8166 api_ip_mroute_add_del (vat_main_t * vam)
8167 {
8168   unformat_input_t *i = vam->input;
8169   u8 path_set = 0, prefix_set = 0, is_add = 1;
8170   vl_api_ip_mroute_add_del_t *mp;
8171   mfib_entry_flags_t eflags = 0;
8172   vl_api_mfib_path_t path;
8173   vl_api_mprefix_t pfx = { };
8174   u32 vrf_id = 0;
8175   int ret;
8176
8177   /* Parse args required to build the message */
8178   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8179     {
8180       if (unformat (i, "%U", unformat_vl_api_mprefix, &pfx))
8181         {
8182           prefix_set = 1;
8183           pfx.grp_address_length = htons (pfx.grp_address_length);
8184         }
8185       else if (unformat (i, "del"))
8186         is_add = 0;
8187       else if (unformat (i, "add"))
8188         is_add = 1;
8189       else if (unformat (i, "vrf %d", &vrf_id))
8190         ;
8191       else if (unformat (i, "%U", unformat_mfib_itf_flags, &path.itf_flags))
8192         path.itf_flags = htonl (path.itf_flags);
8193       else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
8194         ;
8195       else if (unformat (i, "via %U", unformat_fib_path, vam, &path.path))
8196         path_set = 1;
8197       else
8198         {
8199           clib_warning ("parse error '%U'", format_unformat_error, i);
8200           return -99;
8201         }
8202     }
8203
8204   if (prefix_set == 0)
8205     {
8206       errmsg ("missing addresses\n");
8207       return -99;
8208     }
8209   if (path_set == 0)
8210     {
8211       errmsg ("missing path\n");
8212       return -99;
8213     }
8214
8215   /* Construct the API message */
8216   M (IP_MROUTE_ADD_DEL, mp);
8217
8218   mp->is_add = is_add;
8219   mp->is_multipath = 1;
8220
8221   clib_memcpy (&mp->route.prefix, &pfx, sizeof (pfx));
8222   mp->route.table_id = htonl (vrf_id);
8223   mp->route.n_paths = 1;
8224   mp->route.entry_flags = htonl (eflags);
8225
8226   clib_memcpy (&mp->route.paths, &path, sizeof (path));
8227
8228   /* send it... */
8229   S (mp);
8230   /* Wait for a reply... */
8231   W (ret);
8232   return ret;
8233 }
8234
8235 static int
8236 api_mpls_table_add_del (vat_main_t * vam)
8237 {
8238   unformat_input_t *i = vam->input;
8239   vl_api_mpls_table_add_del_t *mp;
8240   u32 table_id = ~0;
8241   u8 is_add = 1;
8242   int ret = 0;
8243
8244   /* Parse args required to build the message */
8245   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8246     {
8247       if (unformat (i, "table %d", &table_id))
8248         ;
8249       else if (unformat (i, "del"))
8250         is_add = 0;
8251       else if (unformat (i, "add"))
8252         is_add = 1;
8253       else
8254         {
8255           clib_warning ("parse error '%U'", format_unformat_error, i);
8256           return -99;
8257         }
8258     }
8259
8260   if (~0 == table_id)
8261     {
8262       errmsg ("missing table-ID");
8263       return -99;
8264     }
8265
8266   /* Construct the API message */
8267   M (MPLS_TABLE_ADD_DEL, mp);
8268
8269   mp->mt_table.mt_table_id = ntohl (table_id);
8270   mp->mt_is_add = is_add;
8271
8272   /* send it... */
8273   S (mp);
8274
8275   /* Wait for a reply... */
8276   W (ret);
8277
8278   return ret;
8279 }
8280
8281 static int
8282 api_mpls_route_add_del (vat_main_t * vam)
8283 {
8284   u8 is_add = 1, path_count = 0, is_multipath = 0, is_eos = 0;
8285   mpls_label_t local_label = MPLS_LABEL_INVALID;
8286   unformat_input_t *i = vam->input;
8287   vl_api_mpls_route_add_del_t *mp;
8288   vl_api_fib_path_t paths[8];
8289   int count = 1, j;
8290   f64 before = 0;
8291
8292   /* Parse args required to build the message */
8293   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8294     {
8295       if (unformat (i, "%d", &local_label))
8296         ;
8297       else if (unformat (i, "eos"))
8298         is_eos = 1;
8299       else if (unformat (i, "non-eos"))
8300         is_eos = 0;
8301       else if (unformat (i, "del"))
8302         is_add = 0;
8303       else if (unformat (i, "add"))
8304         is_add = 1;
8305       else if (unformat (i, "multipath"))
8306         is_multipath = 1;
8307       else if (unformat (i, "count %d", &count))
8308         ;
8309       else
8310         if (unformat
8311             (i, "via %U", unformat_fib_path, vam, &paths[path_count]))
8312         {
8313           path_count++;
8314           if (8 == path_count)
8315             {
8316               errmsg ("max 8 paths");
8317               return -99;
8318             }
8319         }
8320       else
8321         {
8322           clib_warning ("parse error '%U'", format_unformat_error, i);
8323           return -99;
8324         }
8325     }
8326
8327   if (!path_count)
8328     {
8329       errmsg ("specify a path; via ...");
8330       return -99;
8331     }
8332
8333   if (MPLS_LABEL_INVALID == local_label)
8334     {
8335       errmsg ("missing label");
8336       return -99;
8337     }
8338
8339   if (count > 1)
8340     {
8341       /* Turn on async mode */
8342       vam->async_mode = 1;
8343       vam->async_errors = 0;
8344       before = vat_time_now (vam);
8345     }
8346
8347   for (j = 0; j < count; j++)
8348     {
8349       /* Construct the API message */
8350       M2 (MPLS_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t) * path_count);
8351
8352       mp->mr_is_add = is_add;
8353       mp->mr_is_multipath = is_multipath;
8354
8355       mp->mr_route.mr_label = local_label;
8356       mp->mr_route.mr_eos = is_eos;
8357       mp->mr_route.mr_table_id = 0;
8358       mp->mr_route.mr_n_paths = path_count;
8359
8360       clib_memcpy (&mp->mr_route.mr_paths, paths,
8361                    sizeof (paths[0]) * path_count);
8362
8363       local_label++;
8364
8365       /* send it... */
8366       S (mp);
8367       /* If we receive SIGTERM, stop now... */
8368       if (vam->do_exit)
8369         break;
8370     }
8371
8372   /* When testing multiple add/del ops, use a control-ping to sync */
8373   if (count > 1)
8374     {
8375       vl_api_control_ping_t *mp_ping;
8376       f64 after;
8377       f64 timeout;
8378
8379       /* Shut off async mode */
8380       vam->async_mode = 0;
8381
8382       MPING (CONTROL_PING, mp_ping);
8383       S (mp_ping);
8384
8385       timeout = vat_time_now (vam) + 1.0;
8386       while (vat_time_now (vam) < timeout)
8387         if (vam->result_ready == 1)
8388           goto out;
8389       vam->retval = -99;
8390
8391     out:
8392       if (vam->retval == -99)
8393         errmsg ("timeout");
8394
8395       if (vam->async_errors > 0)
8396         {
8397           errmsg ("%d asynchronous errors", vam->async_errors);
8398           vam->retval = -98;
8399         }
8400       vam->async_errors = 0;
8401       after = vat_time_now (vam);
8402
8403       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8404       if (j > 0)
8405         count = j;
8406
8407       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8408              count, after - before, count / (after - before));
8409     }
8410   else
8411     {
8412       int ret;
8413
8414       /* Wait for a reply... */
8415       W (ret);
8416       return ret;
8417     }
8418
8419   /* Return the good/bad news */
8420   return (vam->retval);
8421   return (0);
8422 }
8423
8424 static int
8425 api_mpls_ip_bind_unbind (vat_main_t * vam)
8426 {
8427   unformat_input_t *i = vam->input;
8428   vl_api_mpls_ip_bind_unbind_t *mp;
8429   u32 ip_table_id = 0;
8430   u8 is_bind = 1;
8431   vl_api_prefix_t pfx;
8432   u8 prefix_set = 0;
8433   mpls_label_t local_label = MPLS_LABEL_INVALID;
8434   int ret;
8435
8436   /* Parse args required to build the message */
8437   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8438     {
8439       if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
8440         prefix_set = 1;
8441       else if (unformat (i, "%d", &local_label))
8442         ;
8443       else if (unformat (i, "table-id %d", &ip_table_id))
8444         ;
8445       else if (unformat (i, "unbind"))
8446         is_bind = 0;
8447       else if (unformat (i, "bind"))
8448         is_bind = 1;
8449       else
8450         {
8451           clib_warning ("parse error '%U'", format_unformat_error, i);
8452           return -99;
8453         }
8454     }
8455
8456   if (!prefix_set)
8457     {
8458       errmsg ("IP prefix not set");
8459       return -99;
8460     }
8461
8462   if (MPLS_LABEL_INVALID == local_label)
8463     {
8464       errmsg ("missing label");
8465       return -99;
8466     }
8467
8468   /* Construct the API message */
8469   M (MPLS_IP_BIND_UNBIND, mp);
8470
8471   mp->mb_is_bind = is_bind;
8472   mp->mb_ip_table_id = ntohl (ip_table_id);
8473   mp->mb_mpls_table_id = 0;
8474   mp->mb_label = ntohl (local_label);
8475   clib_memcpy (&mp->mb_prefix, &pfx, sizeof (pfx));
8476
8477   /* send it... */
8478   S (mp);
8479
8480   /* Wait for a reply... */
8481   W (ret);
8482   return ret;
8483   return (0);
8484 }
8485
8486 static int
8487 api_sr_mpls_policy_add (vat_main_t * vam)
8488 {
8489   unformat_input_t *i = vam->input;
8490   vl_api_sr_mpls_policy_add_t *mp;
8491   u32 bsid = 0;
8492   u32 weight = 1;
8493   u8 type = 0;
8494   u8 n_segments = 0;
8495   u32 sid;
8496   u32 *segments = NULL;
8497   int ret;
8498
8499   /* Parse args required to build the message */
8500   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8501     {
8502       if (unformat (i, "bsid %d", &bsid))
8503         ;
8504       else if (unformat (i, "weight %d", &weight))
8505         ;
8506       else if (unformat (i, "spray"))
8507         type = 1;
8508       else if (unformat (i, "next %d", &sid))
8509         {
8510           n_segments += 1;
8511           vec_add1 (segments, htonl (sid));
8512         }
8513       else
8514         {
8515           clib_warning ("parse error '%U'", format_unformat_error, i);
8516           return -99;
8517         }
8518     }
8519
8520   if (bsid == 0)
8521     {
8522       errmsg ("bsid not set");
8523       return -99;
8524     }
8525
8526   if (n_segments == 0)
8527     {
8528       errmsg ("no sid in segment stack");
8529       return -99;
8530     }
8531
8532   /* Construct the API message */
8533   M2 (SR_MPLS_POLICY_ADD, mp, sizeof (u32) * n_segments);
8534
8535   mp->bsid = htonl (bsid);
8536   mp->weight = htonl (weight);
8537   mp->type = type;
8538   mp->n_segments = n_segments;
8539   memcpy (mp->segments, segments, sizeof (u32) * n_segments);
8540   vec_free (segments);
8541
8542   /* send it... */
8543   S (mp);
8544
8545   /* Wait for a reply... */
8546   W (ret);
8547   return ret;
8548 }
8549
8550 static int
8551 api_sr_mpls_policy_del (vat_main_t * vam)
8552 {
8553   unformat_input_t *i = vam->input;
8554   vl_api_sr_mpls_policy_del_t *mp;
8555   u32 bsid = 0;
8556   int ret;
8557
8558   /* Parse args required to build the message */
8559   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8560     {
8561       if (unformat (i, "bsid %d", &bsid))
8562         ;
8563       else
8564         {
8565           clib_warning ("parse error '%U'", format_unformat_error, i);
8566           return -99;
8567         }
8568     }
8569
8570   if (bsid == 0)
8571     {
8572       errmsg ("bsid not set");
8573       return -99;
8574     }
8575
8576   /* Construct the API message */
8577   M (SR_MPLS_POLICY_DEL, mp);
8578
8579   mp->bsid = htonl (bsid);
8580
8581   /* send it... */
8582   S (mp);
8583
8584   /* Wait for a reply... */
8585   W (ret);
8586   return ret;
8587 }
8588
8589 static int
8590 api_bier_table_add_del (vat_main_t * vam)
8591 {
8592   unformat_input_t *i = vam->input;
8593   vl_api_bier_table_add_del_t *mp;
8594   u8 is_add = 1;
8595   u32 set = 0, sub_domain = 0, hdr_len = 3;
8596   mpls_label_t local_label = MPLS_LABEL_INVALID;
8597   int ret;
8598
8599   /* Parse args required to build the message */
8600   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8601     {
8602       if (unformat (i, "sub-domain %d", &sub_domain))
8603         ;
8604       else if (unformat (i, "set %d", &set))
8605         ;
8606       else if (unformat (i, "label %d", &local_label))
8607         ;
8608       else if (unformat (i, "hdr-len %d", &hdr_len))
8609         ;
8610       else if (unformat (i, "add"))
8611         is_add = 1;
8612       else if (unformat (i, "del"))
8613         is_add = 0;
8614       else
8615         {
8616           clib_warning ("parse error '%U'", format_unformat_error, i);
8617           return -99;
8618         }
8619     }
8620
8621   if (MPLS_LABEL_INVALID == local_label)
8622     {
8623       errmsg ("missing label\n");
8624       return -99;
8625     }
8626
8627   /* Construct the API message */
8628   M (BIER_TABLE_ADD_DEL, mp);
8629
8630   mp->bt_is_add = is_add;
8631   mp->bt_label = ntohl (local_label);
8632   mp->bt_tbl_id.bt_set = set;
8633   mp->bt_tbl_id.bt_sub_domain = sub_domain;
8634   mp->bt_tbl_id.bt_hdr_len_id = hdr_len;
8635
8636   /* send it... */
8637   S (mp);
8638
8639   /* Wait for a reply... */
8640   W (ret);
8641
8642   return (ret);
8643 }
8644
8645 static int
8646 api_bier_route_add_del (vat_main_t * vam)
8647 {
8648   unformat_input_t *i = vam->input;
8649   vl_api_bier_route_add_del_t *mp;
8650   u8 is_add = 1;
8651   u32 set = 0, sub_domain = 0, hdr_len = 3, bp = 0;
8652   ip4_address_t v4_next_hop_address;
8653   ip6_address_t v6_next_hop_address;
8654   u8 next_hop_set = 0;
8655   u8 next_hop_proto_is_ip4 = 1;
8656   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8657   int ret;
8658
8659   /* Parse args required to build the message */
8660   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8661     {
8662       if (unformat (i, "%U", unformat_ip4_address, &v4_next_hop_address))
8663         {
8664           next_hop_proto_is_ip4 = 1;
8665           next_hop_set = 1;
8666         }
8667       else if (unformat (i, "%U", unformat_ip6_address, &v6_next_hop_address))
8668         {
8669           next_hop_proto_is_ip4 = 0;
8670           next_hop_set = 1;
8671         }
8672       if (unformat (i, "sub-domain %d", &sub_domain))
8673         ;
8674       else if (unformat (i, "set %d", &set))
8675         ;
8676       else if (unformat (i, "hdr-len %d", &hdr_len))
8677         ;
8678       else if (unformat (i, "bp %d", &bp))
8679         ;
8680       else if (unformat (i, "add"))
8681         is_add = 1;
8682       else if (unformat (i, "del"))
8683         is_add = 0;
8684       else if (unformat (i, "out-label %d", &next_hop_out_label))
8685         ;
8686       else
8687         {
8688           clib_warning ("parse error '%U'", format_unformat_error, i);
8689           return -99;
8690         }
8691     }
8692
8693   if (!next_hop_set || (MPLS_LABEL_INVALID == next_hop_out_label))
8694     {
8695       errmsg ("next hop / label set\n");
8696       return -99;
8697     }
8698   if (0 == bp)
8699     {
8700       errmsg ("bit=position not set\n");
8701       return -99;
8702     }
8703
8704   /* Construct the API message */
8705   M2 (BIER_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t));
8706
8707   mp->br_is_add = is_add;
8708   mp->br_route.br_tbl_id.bt_set = set;
8709   mp->br_route.br_tbl_id.bt_sub_domain = sub_domain;
8710   mp->br_route.br_tbl_id.bt_hdr_len_id = hdr_len;
8711   mp->br_route.br_bp = ntohs (bp);
8712   mp->br_route.br_n_paths = 1;
8713   mp->br_route.br_paths[0].n_labels = 1;
8714   mp->br_route.br_paths[0].label_stack[0].label = ntohl (next_hop_out_label);
8715   mp->br_route.br_paths[0].proto = (next_hop_proto_is_ip4 ?
8716                                     FIB_API_PATH_NH_PROTO_IP4 :
8717                                     FIB_API_PATH_NH_PROTO_IP6);
8718
8719   if (next_hop_proto_is_ip4)
8720     {
8721       clib_memcpy (&mp->br_route.br_paths[0].nh.address.ip4,
8722                    &v4_next_hop_address, sizeof (v4_next_hop_address));
8723     }
8724   else
8725     {
8726       clib_memcpy (&mp->br_route.br_paths[0].nh.address.ip6,
8727                    &v6_next_hop_address, sizeof (v6_next_hop_address));
8728     }
8729
8730   /* send it... */
8731   S (mp);
8732
8733   /* Wait for a reply... */
8734   W (ret);
8735
8736   return (ret);
8737 }
8738
8739 static int
8740 api_mpls_tunnel_add_del (vat_main_t * vam)
8741 {
8742   unformat_input_t *i = vam->input;
8743   vl_api_mpls_tunnel_add_del_t *mp;
8744
8745   vl_api_fib_path_t paths[8];
8746   u32 sw_if_index = ~0;
8747   u8 path_count = 0;
8748   u8 l2_only = 0;
8749   u8 is_add = 1;
8750   int ret;
8751
8752   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8753     {
8754       if (unformat (i, "add"))
8755         is_add = 1;
8756       else
8757         if (unformat
8758             (i, "del %U", api_unformat_sw_if_index, vam, &sw_if_index))
8759         is_add = 0;
8760       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
8761         is_add = 0;
8762       else if (unformat (i, "l2-only"))
8763         l2_only = 1;
8764       else
8765         if (unformat
8766             (i, "via %U", unformat_fib_path, vam, &paths[path_count]))
8767         {
8768           path_count++;
8769           if (8 == path_count)
8770             {
8771               errmsg ("max 8 paths");
8772               return -99;
8773             }
8774         }
8775       else
8776         {
8777           clib_warning ("parse error '%U'", format_unformat_error, i);
8778           return -99;
8779         }
8780     }
8781
8782   M2 (MPLS_TUNNEL_ADD_DEL, mp, sizeof (vl_api_fib_path_t) * path_count);
8783
8784   mp->mt_is_add = is_add;
8785   mp->mt_tunnel.mt_sw_if_index = ntohl (sw_if_index);
8786   mp->mt_tunnel.mt_l2_only = l2_only;
8787   mp->mt_tunnel.mt_is_multicast = 0;
8788   mp->mt_tunnel.mt_n_paths = path_count;
8789
8790   clib_memcpy (&mp->mt_tunnel.mt_paths, &paths,
8791                sizeof (paths[0]) * path_count);
8792
8793   S (mp);
8794   W (ret);
8795   return ret;
8796 }
8797
8798 static int
8799 api_sw_interface_set_unnumbered (vat_main_t * vam)
8800 {
8801   unformat_input_t *i = vam->input;
8802   vl_api_sw_interface_set_unnumbered_t *mp;
8803   u32 sw_if_index;
8804   u32 unnum_sw_index = ~0;
8805   u8 is_add = 1;
8806   u8 sw_if_index_set = 0;
8807   int ret;
8808
8809   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8810     {
8811       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8812         sw_if_index_set = 1;
8813       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8814         sw_if_index_set = 1;
8815       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
8816         ;
8817       else if (unformat (i, "del"))
8818         is_add = 0;
8819       else
8820         {
8821           clib_warning ("parse error '%U'", format_unformat_error, i);
8822           return -99;
8823         }
8824     }
8825
8826   if (sw_if_index_set == 0)
8827     {
8828       errmsg ("missing interface name or sw_if_index");
8829       return -99;
8830     }
8831
8832   M (SW_INTERFACE_SET_UNNUMBERED, mp);
8833
8834   mp->sw_if_index = ntohl (sw_if_index);
8835   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
8836   mp->is_add = is_add;
8837
8838   S (mp);
8839   W (ret);
8840   return ret;
8841 }
8842
8843
8844 static int
8845 api_create_vlan_subif (vat_main_t * vam)
8846 {
8847   unformat_input_t *i = vam->input;
8848   vl_api_create_vlan_subif_t *mp;
8849   u32 sw_if_index;
8850   u8 sw_if_index_set = 0;
8851   u32 vlan_id;
8852   u8 vlan_id_set = 0;
8853   int ret;
8854
8855   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8856     {
8857       if (unformat (i, "sw_if_index %d", &sw_if_index))
8858         sw_if_index_set = 1;
8859       else
8860         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8861         sw_if_index_set = 1;
8862       else if (unformat (i, "vlan %d", &vlan_id))
8863         vlan_id_set = 1;
8864       else
8865         {
8866           clib_warning ("parse error '%U'", format_unformat_error, i);
8867           return -99;
8868         }
8869     }
8870
8871   if (sw_if_index_set == 0)
8872     {
8873       errmsg ("missing interface name or sw_if_index");
8874       return -99;
8875     }
8876
8877   if (vlan_id_set == 0)
8878     {
8879       errmsg ("missing vlan_id");
8880       return -99;
8881     }
8882   M (CREATE_VLAN_SUBIF, mp);
8883
8884   mp->sw_if_index = ntohl (sw_if_index);
8885   mp->vlan_id = ntohl (vlan_id);
8886
8887   S (mp);
8888   W (ret);
8889   return ret;
8890 }
8891
8892 #define foreach_create_subif_bit                \
8893 _(no_tags)                                      \
8894 _(one_tag)                                      \
8895 _(two_tags)                                     \
8896 _(dot1ad)                                       \
8897 _(exact_match)                                  \
8898 _(default_sub)                                  \
8899 _(outer_vlan_id_any)                            \
8900 _(inner_vlan_id_any)
8901
8902 #define foreach_create_subif_flag               \
8903 _(0, "no_tags")                                 \
8904 _(1, "one_tag")                                 \
8905 _(2, "two_tags")                                \
8906 _(3, "dot1ad")                                  \
8907 _(4, "exact_match")                             \
8908 _(5, "default_sub")                             \
8909 _(6, "outer_vlan_id_any")                       \
8910 _(7, "inner_vlan_id_any")
8911
8912 static int
8913 api_create_subif (vat_main_t * vam)
8914 {
8915   unformat_input_t *i = vam->input;
8916   vl_api_create_subif_t *mp;
8917   u32 sw_if_index;
8918   u8 sw_if_index_set = 0;
8919   u32 sub_id;
8920   u8 sub_id_set = 0;
8921   u32 __attribute__ ((unused)) no_tags = 0;
8922   u32 __attribute__ ((unused)) one_tag = 0;
8923   u32 __attribute__ ((unused)) two_tags = 0;
8924   u32 __attribute__ ((unused)) dot1ad = 0;
8925   u32 __attribute__ ((unused)) exact_match = 0;
8926   u32 __attribute__ ((unused)) default_sub = 0;
8927   u32 __attribute__ ((unused)) outer_vlan_id_any = 0;
8928   u32 __attribute__ ((unused)) inner_vlan_id_any = 0;
8929   u32 tmp;
8930   u16 outer_vlan_id = 0;
8931   u16 inner_vlan_id = 0;
8932   int ret;
8933
8934   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8935     {
8936       if (unformat (i, "sw_if_index %d", &sw_if_index))
8937         sw_if_index_set = 1;
8938       else
8939         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8940         sw_if_index_set = 1;
8941       else if (unformat (i, "sub_id %d", &sub_id))
8942         sub_id_set = 1;
8943       else if (unformat (i, "outer_vlan_id %d", &tmp))
8944         outer_vlan_id = tmp;
8945       else if (unformat (i, "inner_vlan_id %d", &tmp))
8946         inner_vlan_id = tmp;
8947
8948 #define _(a) else if (unformat (i, #a)) a = 1 ;
8949       foreach_create_subif_bit
8950 #undef _
8951         else
8952         {
8953           clib_warning ("parse error '%U'", format_unformat_error, i);
8954           return -99;
8955         }
8956     }
8957
8958   if (sw_if_index_set == 0)
8959     {
8960       errmsg ("missing interface name or sw_if_index");
8961       return -99;
8962     }
8963
8964   if (sub_id_set == 0)
8965     {
8966       errmsg ("missing sub_id");
8967       return -99;
8968     }
8969   M (CREATE_SUBIF, mp);
8970
8971   mp->sw_if_index = ntohl (sw_if_index);
8972   mp->sub_id = ntohl (sub_id);
8973
8974 #define _(a,b) mp->sub_if_flags |= (1 << a);
8975   foreach_create_subif_flag;
8976 #undef _
8977
8978   mp->outer_vlan_id = ntohs (outer_vlan_id);
8979   mp->inner_vlan_id = ntohs (inner_vlan_id);
8980
8981   S (mp);
8982   W (ret);
8983   return ret;
8984 }
8985
8986 static int
8987 api_ip_table_replace_begin (vat_main_t * vam)
8988 {
8989   unformat_input_t *i = vam->input;
8990   vl_api_ip_table_replace_begin_t *mp;
8991   u32 table_id = 0;
8992   u8 is_ipv6 = 0;
8993
8994   int ret;
8995   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8996     {
8997       if (unformat (i, "table %d", &table_id))
8998         ;
8999       else if (unformat (i, "ipv6"))
9000         is_ipv6 = 1;
9001       else
9002         {
9003           clib_warning ("parse error '%U'", format_unformat_error, i);
9004           return -99;
9005         }
9006     }
9007
9008   M (IP_TABLE_REPLACE_BEGIN, mp);
9009
9010   mp->table.table_id = ntohl (table_id);
9011   mp->table.is_ip6 = is_ipv6;
9012
9013   S (mp);
9014   W (ret);
9015   return ret;
9016 }
9017
9018 static int
9019 api_ip_table_flush (vat_main_t * vam)
9020 {
9021   unformat_input_t *i = vam->input;
9022   vl_api_ip_table_flush_t *mp;
9023   u32 table_id = 0;
9024   u8 is_ipv6 = 0;
9025
9026   int ret;
9027   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9028     {
9029       if (unformat (i, "table %d", &table_id))
9030         ;
9031       else if (unformat (i, "ipv6"))
9032         is_ipv6 = 1;
9033       else
9034         {
9035           clib_warning ("parse error '%U'", format_unformat_error, i);
9036           return -99;
9037         }
9038     }
9039
9040   M (IP_TABLE_FLUSH, mp);
9041
9042   mp->table.table_id = ntohl (table_id);
9043   mp->table.is_ip6 = is_ipv6;
9044
9045   S (mp);
9046   W (ret);
9047   return ret;
9048 }
9049
9050 static int
9051 api_ip_table_replace_end (vat_main_t * vam)
9052 {
9053   unformat_input_t *i = vam->input;
9054   vl_api_ip_table_replace_end_t *mp;
9055   u32 table_id = 0;
9056   u8 is_ipv6 = 0;
9057
9058   int ret;
9059   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9060     {
9061       if (unformat (i, "table %d", &table_id))
9062         ;
9063       else if (unformat (i, "ipv6"))
9064         is_ipv6 = 1;
9065       else
9066         {
9067           clib_warning ("parse error '%U'", format_unformat_error, i);
9068           return -99;
9069         }
9070     }
9071
9072   M (IP_TABLE_REPLACE_END, mp);
9073
9074   mp->table.table_id = ntohl (table_id);
9075   mp->table.is_ip6 = is_ipv6;
9076
9077   S (mp);
9078   W (ret);
9079   return ret;
9080 }
9081
9082 static int
9083 api_set_ip_flow_hash (vat_main_t * vam)
9084 {
9085   unformat_input_t *i = vam->input;
9086   vl_api_set_ip_flow_hash_t *mp;
9087   u32 vrf_id = 0;
9088   u8 is_ipv6 = 0;
9089   u8 vrf_id_set = 0;
9090   u8 src = 0;
9091   u8 dst = 0;
9092   u8 sport = 0;
9093   u8 dport = 0;
9094   u8 proto = 0;
9095   u8 reverse = 0;
9096   int ret;
9097
9098   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9099     {
9100       if (unformat (i, "vrf %d", &vrf_id))
9101         vrf_id_set = 1;
9102       else if (unformat (i, "ipv6"))
9103         is_ipv6 = 1;
9104       else if (unformat (i, "src"))
9105         src = 1;
9106       else if (unformat (i, "dst"))
9107         dst = 1;
9108       else if (unformat (i, "sport"))
9109         sport = 1;
9110       else if (unformat (i, "dport"))
9111         dport = 1;
9112       else if (unformat (i, "proto"))
9113         proto = 1;
9114       else if (unformat (i, "reverse"))
9115         reverse = 1;
9116
9117       else
9118         {
9119           clib_warning ("parse error '%U'", format_unformat_error, i);
9120           return -99;
9121         }
9122     }
9123
9124   if (vrf_id_set == 0)
9125     {
9126       errmsg ("missing vrf id");
9127       return -99;
9128     }
9129
9130   M (SET_IP_FLOW_HASH, mp);
9131   mp->src = src;
9132   mp->dst = dst;
9133   mp->sport = sport;
9134   mp->dport = dport;
9135   mp->proto = proto;
9136   mp->reverse = reverse;
9137   mp->vrf_id = ntohl (vrf_id);
9138   mp->is_ipv6 = is_ipv6;
9139
9140   S (mp);
9141   W (ret);
9142   return ret;
9143 }
9144
9145 static int
9146 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
9147 {
9148   unformat_input_t *i = vam->input;
9149   vl_api_sw_interface_ip6_enable_disable_t *mp;
9150   u32 sw_if_index;
9151   u8 sw_if_index_set = 0;
9152   u8 enable = 0;
9153   int ret;
9154
9155   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9156     {
9157       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9158         sw_if_index_set = 1;
9159       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9160         sw_if_index_set = 1;
9161       else if (unformat (i, "enable"))
9162         enable = 1;
9163       else if (unformat (i, "disable"))
9164         enable = 0;
9165       else
9166         {
9167           clib_warning ("parse error '%U'", format_unformat_error, i);
9168           return -99;
9169         }
9170     }
9171
9172   if (sw_if_index_set == 0)
9173     {
9174       errmsg ("missing interface name or sw_if_index");
9175       return -99;
9176     }
9177
9178   M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
9179
9180   mp->sw_if_index = ntohl (sw_if_index);
9181   mp->enable = enable;
9182
9183   S (mp);
9184   W (ret);
9185   return ret;
9186 }
9187
9188
9189 static int
9190 api_l2_patch_add_del (vat_main_t * vam)
9191 {
9192   unformat_input_t *i = vam->input;
9193   vl_api_l2_patch_add_del_t *mp;
9194   u32 rx_sw_if_index;
9195   u8 rx_sw_if_index_set = 0;
9196   u32 tx_sw_if_index;
9197   u8 tx_sw_if_index_set = 0;
9198   u8 is_add = 1;
9199   int ret;
9200
9201   /* Parse args required to build the message */
9202   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9203     {
9204       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
9205         rx_sw_if_index_set = 1;
9206       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
9207         tx_sw_if_index_set = 1;
9208       else if (unformat (i, "rx"))
9209         {
9210           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9211             {
9212               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
9213                             &rx_sw_if_index))
9214                 rx_sw_if_index_set = 1;
9215             }
9216           else
9217             break;
9218         }
9219       else if (unformat (i, "tx"))
9220         {
9221           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9222             {
9223               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
9224                             &tx_sw_if_index))
9225                 tx_sw_if_index_set = 1;
9226             }
9227           else
9228             break;
9229         }
9230       else if (unformat (i, "del"))
9231         is_add = 0;
9232       else
9233         break;
9234     }
9235
9236   if (rx_sw_if_index_set == 0)
9237     {
9238       errmsg ("missing rx interface name or rx_sw_if_index");
9239       return -99;
9240     }
9241
9242   if (tx_sw_if_index_set == 0)
9243     {
9244       errmsg ("missing tx interface name or tx_sw_if_index");
9245       return -99;
9246     }
9247
9248   M (L2_PATCH_ADD_DEL, mp);
9249
9250   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
9251   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
9252   mp->is_add = is_add;
9253
9254   S (mp);
9255   W (ret);
9256   return ret;
9257 }
9258
9259 u8 is_del;
9260 u8 localsid_addr[16];
9261 u8 end_psp;
9262 u8 behavior;
9263 u32 sw_if_index;
9264 u32 vlan_index;
9265 u32 fib_table;
9266 u8 nh_addr[16];
9267
9268 static int
9269 api_sr_localsid_add_del (vat_main_t * vam)
9270 {
9271   unformat_input_t *i = vam->input;
9272   vl_api_sr_localsid_add_del_t *mp;
9273
9274   u8 is_del;
9275   ip6_address_t localsid;
9276   u8 end_psp = 0;
9277   u8 behavior = ~0;
9278   u32 sw_if_index;
9279   u32 fib_table = ~(u32) 0;
9280   ip6_address_t nh_addr6;
9281   ip4_address_t nh_addr4;
9282   clib_memset (&nh_addr6, 0, sizeof (ip6_address_t));
9283   clib_memset (&nh_addr4, 0, sizeof (ip4_address_t));
9284
9285   bool nexthop_set = 0;
9286
9287   int ret;
9288
9289   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9290     {
9291       if (unformat (i, "del"))
9292         is_del = 1;
9293       else if (unformat (i, "address %U", unformat_ip6_address, &localsid));
9294       else if (unformat (i, "next-hop %U", unformat_ip4_address, &nh_addr4))
9295         nexthop_set = 1;
9296       else if (unformat (i, "next-hop %U", unformat_ip6_address, &nh_addr6))
9297         nexthop_set = 1;
9298       else if (unformat (i, "behavior %u", &behavior));
9299       else if (unformat (i, "sw_if_index %u", &sw_if_index));
9300       else if (unformat (i, "fib-table %u", &fib_table));
9301       else if (unformat (i, "end.psp %u", &behavior));
9302       else
9303         break;
9304     }
9305
9306   M (SR_LOCALSID_ADD_DEL, mp);
9307
9308   clib_memcpy (mp->localsid.addr, &localsid, sizeof (mp->localsid));
9309
9310   if (nexthop_set)
9311     {
9312       clib_memcpy (mp->nh_addr6, &nh_addr6, sizeof (mp->nh_addr6));
9313       clib_memcpy (mp->nh_addr4, &nh_addr4, sizeof (mp->nh_addr4));
9314     }
9315   mp->behavior = behavior;
9316   mp->sw_if_index = ntohl (sw_if_index);
9317   mp->fib_table = ntohl (fib_table);
9318   mp->end_psp = end_psp;
9319   mp->is_del = is_del;
9320
9321   S (mp);
9322   W (ret);
9323   return ret;
9324 }
9325
9326 static int
9327 api_ioam_enable (vat_main_t * vam)
9328 {
9329   unformat_input_t *input = vam->input;
9330   vl_api_ioam_enable_t *mp;
9331   u32 id = 0;
9332   int has_trace_option = 0;
9333   int has_pot_option = 0;
9334   int has_seqno_option = 0;
9335   int has_analyse_option = 0;
9336   int ret;
9337
9338   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9339     {
9340       if (unformat (input, "trace"))
9341         has_trace_option = 1;
9342       else if (unformat (input, "pot"))
9343         has_pot_option = 1;
9344       else if (unformat (input, "seqno"))
9345         has_seqno_option = 1;
9346       else if (unformat (input, "analyse"))
9347         has_analyse_option = 1;
9348       else
9349         break;
9350     }
9351   M (IOAM_ENABLE, mp);
9352   mp->id = htons (id);
9353   mp->seqno = has_seqno_option;
9354   mp->analyse = has_analyse_option;
9355   mp->pot_enable = has_pot_option;
9356   mp->trace_enable = has_trace_option;
9357
9358   S (mp);
9359   W (ret);
9360   return ret;
9361 }
9362
9363
9364 static int
9365 api_ioam_disable (vat_main_t * vam)
9366 {
9367   vl_api_ioam_disable_t *mp;
9368   int ret;
9369
9370   M (IOAM_DISABLE, mp);
9371   S (mp);
9372   W (ret);
9373   return ret;
9374 }
9375
9376 #define foreach_tcp_proto_field                 \
9377 _(src_port)                                     \
9378 _(dst_port)
9379
9380 #define foreach_udp_proto_field                 \
9381 _(src_port)                                     \
9382 _(dst_port)
9383
9384 #define foreach_ip4_proto_field                 \
9385 _(src_address)                                  \
9386 _(dst_address)                                  \
9387 _(tos)                                          \
9388 _(length)                                       \
9389 _(fragment_id)                                  \
9390 _(ttl)                                          \
9391 _(protocol)                                     \
9392 _(checksum)
9393
9394 typedef struct
9395 {
9396   u16 src_port, dst_port;
9397 } tcpudp_header_t;
9398
9399 #if VPP_API_TEST_BUILTIN == 0
9400 uword
9401 unformat_tcp_mask (unformat_input_t * input, va_list * args)
9402 {
9403   u8 **maskp = va_arg (*args, u8 **);
9404   u8 *mask = 0;
9405   u8 found_something = 0;
9406   tcp_header_t *tcp;
9407
9408 #define _(a) u8 a=0;
9409   foreach_tcp_proto_field;
9410 #undef _
9411
9412   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9413     {
9414       if (0);
9415 #define _(a) else if (unformat (input, #a)) a=1;
9416       foreach_tcp_proto_field
9417 #undef _
9418         else
9419         break;
9420     }
9421
9422 #define _(a) found_something += a;
9423   foreach_tcp_proto_field;
9424 #undef _
9425
9426   if (found_something == 0)
9427     return 0;
9428
9429   vec_validate (mask, sizeof (*tcp) - 1);
9430
9431   tcp = (tcp_header_t *) mask;
9432
9433 #define _(a) if (a) clib_memset (&tcp->a, 0xff, sizeof (tcp->a));
9434   foreach_tcp_proto_field;
9435 #undef _
9436
9437   *maskp = mask;
9438   return 1;
9439 }
9440
9441 uword
9442 unformat_udp_mask (unformat_input_t * input, va_list * args)
9443 {
9444   u8 **maskp = va_arg (*args, u8 **);
9445   u8 *mask = 0;
9446   u8 found_something = 0;
9447   udp_header_t *udp;
9448
9449 #define _(a) u8 a=0;
9450   foreach_udp_proto_field;
9451 #undef _
9452
9453   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9454     {
9455       if (0);
9456 #define _(a) else if (unformat (input, #a)) a=1;
9457       foreach_udp_proto_field
9458 #undef _
9459         else
9460         break;
9461     }
9462
9463 #define _(a) found_something += a;
9464   foreach_udp_proto_field;
9465 #undef _
9466
9467   if (found_something == 0)
9468     return 0;
9469
9470   vec_validate (mask, sizeof (*udp) - 1);
9471
9472   udp = (udp_header_t *) mask;
9473
9474 #define _(a) if (a) clib_memset (&udp->a, 0xff, sizeof (udp->a));
9475   foreach_udp_proto_field;
9476 #undef _
9477
9478   *maskp = mask;
9479   return 1;
9480 }
9481
9482 uword
9483 unformat_l4_mask (unformat_input_t * input, va_list * args)
9484 {
9485   u8 **maskp = va_arg (*args, u8 **);
9486   u16 src_port = 0, dst_port = 0;
9487   tcpudp_header_t *tcpudp;
9488
9489   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9490     {
9491       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
9492         return 1;
9493       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
9494         return 1;
9495       else if (unformat (input, "src_port"))
9496         src_port = 0xFFFF;
9497       else if (unformat (input, "dst_port"))
9498         dst_port = 0xFFFF;
9499       else
9500         return 0;
9501     }
9502
9503   if (!src_port && !dst_port)
9504     return 0;
9505
9506   u8 *mask = 0;
9507   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
9508
9509   tcpudp = (tcpudp_header_t *) mask;
9510   tcpudp->src_port = src_port;
9511   tcpudp->dst_port = dst_port;
9512
9513   *maskp = mask;
9514
9515   return 1;
9516 }
9517
9518 uword
9519 unformat_ip4_mask (unformat_input_t * input, va_list * args)
9520 {
9521   u8 **maskp = va_arg (*args, u8 **);
9522   u8 *mask = 0;
9523   u8 found_something = 0;
9524   ip4_header_t *ip;
9525
9526 #define _(a) u8 a=0;
9527   foreach_ip4_proto_field;
9528 #undef _
9529   u8 version = 0;
9530   u8 hdr_length = 0;
9531
9532
9533   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9534     {
9535       if (unformat (input, "version"))
9536         version = 1;
9537       else if (unformat (input, "hdr_length"))
9538         hdr_length = 1;
9539       else if (unformat (input, "src"))
9540         src_address = 1;
9541       else if (unformat (input, "dst"))
9542         dst_address = 1;
9543       else if (unformat (input, "proto"))
9544         protocol = 1;
9545
9546 #define _(a) else if (unformat (input, #a)) a=1;
9547       foreach_ip4_proto_field
9548 #undef _
9549         else
9550         break;
9551     }
9552
9553 #define _(a) found_something += a;
9554   foreach_ip4_proto_field;
9555 #undef _
9556
9557   if (found_something == 0)
9558     return 0;
9559
9560   vec_validate (mask, sizeof (*ip) - 1);
9561
9562   ip = (ip4_header_t *) mask;
9563
9564 #define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
9565   foreach_ip4_proto_field;
9566 #undef _
9567
9568   ip->ip_version_and_header_length = 0;
9569
9570   if (version)
9571     ip->ip_version_and_header_length |= 0xF0;
9572
9573   if (hdr_length)
9574     ip->ip_version_and_header_length |= 0x0F;
9575
9576   *maskp = mask;
9577   return 1;
9578 }
9579
9580 #define foreach_ip6_proto_field                 \
9581 _(src_address)                                  \
9582 _(dst_address)                                  \
9583 _(payload_length)                               \
9584 _(hop_limit)                                    \
9585 _(protocol)
9586
9587 uword
9588 unformat_ip6_mask (unformat_input_t * input, va_list * args)
9589 {
9590   u8 **maskp = va_arg (*args, u8 **);
9591   u8 *mask = 0;
9592   u8 found_something = 0;
9593   ip6_header_t *ip;
9594   u32 ip_version_traffic_class_and_flow_label;
9595
9596 #define _(a) u8 a=0;
9597   foreach_ip6_proto_field;
9598 #undef _
9599   u8 version = 0;
9600   u8 traffic_class = 0;
9601   u8 flow_label = 0;
9602
9603   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9604     {
9605       if (unformat (input, "version"))
9606         version = 1;
9607       else if (unformat (input, "traffic-class"))
9608         traffic_class = 1;
9609       else if (unformat (input, "flow-label"))
9610         flow_label = 1;
9611       else if (unformat (input, "src"))
9612         src_address = 1;
9613       else if (unformat (input, "dst"))
9614         dst_address = 1;
9615       else if (unformat (input, "proto"))
9616         protocol = 1;
9617
9618 #define _(a) else if (unformat (input, #a)) a=1;
9619       foreach_ip6_proto_field
9620 #undef _
9621         else
9622         break;
9623     }
9624
9625 #define _(a) found_something += a;
9626   foreach_ip6_proto_field;
9627 #undef _
9628
9629   if (found_something == 0)
9630     return 0;
9631
9632   vec_validate (mask, sizeof (*ip) - 1);
9633
9634   ip = (ip6_header_t *) mask;
9635
9636 #define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
9637   foreach_ip6_proto_field;
9638 #undef _
9639
9640   ip_version_traffic_class_and_flow_label = 0;
9641
9642   if (version)
9643     ip_version_traffic_class_and_flow_label |= 0xF0000000;
9644
9645   if (traffic_class)
9646     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
9647
9648   if (flow_label)
9649     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
9650
9651   ip->ip_version_traffic_class_and_flow_label =
9652     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
9653
9654   *maskp = mask;
9655   return 1;
9656 }
9657
9658 uword
9659 unformat_l3_mask (unformat_input_t * input, va_list * args)
9660 {
9661   u8 **maskp = va_arg (*args, u8 **);
9662
9663   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9664     {
9665       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
9666         return 1;
9667       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
9668         return 1;
9669       else
9670         break;
9671     }
9672   return 0;
9673 }
9674
9675 uword
9676 unformat_l2_mask (unformat_input_t * input, va_list * args)
9677 {
9678   u8 **maskp = va_arg (*args, u8 **);
9679   u8 *mask = 0;
9680   u8 src = 0;
9681   u8 dst = 0;
9682   u8 proto = 0;
9683   u8 tag1 = 0;
9684   u8 tag2 = 0;
9685   u8 ignore_tag1 = 0;
9686   u8 ignore_tag2 = 0;
9687   u8 cos1 = 0;
9688   u8 cos2 = 0;
9689   u8 dot1q = 0;
9690   u8 dot1ad = 0;
9691   int len = 14;
9692
9693   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9694     {
9695       if (unformat (input, "src"))
9696         src = 1;
9697       else if (unformat (input, "dst"))
9698         dst = 1;
9699       else if (unformat (input, "proto"))
9700         proto = 1;
9701       else if (unformat (input, "tag1"))
9702         tag1 = 1;
9703       else if (unformat (input, "tag2"))
9704         tag2 = 1;
9705       else if (unformat (input, "ignore-tag1"))
9706         ignore_tag1 = 1;
9707       else if (unformat (input, "ignore-tag2"))
9708         ignore_tag2 = 1;
9709       else if (unformat (input, "cos1"))
9710         cos1 = 1;
9711       else if (unformat (input, "cos2"))
9712         cos2 = 1;
9713       else if (unformat (input, "dot1q"))
9714         dot1q = 1;
9715       else if (unformat (input, "dot1ad"))
9716         dot1ad = 1;
9717       else
9718         break;
9719     }
9720   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
9721        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
9722     return 0;
9723
9724   if (tag1 || ignore_tag1 || cos1 || dot1q)
9725     len = 18;
9726   if (tag2 || ignore_tag2 || cos2 || dot1ad)
9727     len = 22;
9728
9729   vec_validate (mask, len - 1);
9730
9731   if (dst)
9732     clib_memset (mask, 0xff, 6);
9733
9734   if (src)
9735     clib_memset (mask + 6, 0xff, 6);
9736
9737   if (tag2 || dot1ad)
9738     {
9739       /* inner vlan tag */
9740       if (tag2)
9741         {
9742           mask[19] = 0xff;
9743           mask[18] = 0x0f;
9744         }
9745       if (cos2)
9746         mask[18] |= 0xe0;
9747       if (proto)
9748         mask[21] = mask[20] = 0xff;
9749       if (tag1)
9750         {
9751           mask[15] = 0xff;
9752           mask[14] = 0x0f;
9753         }
9754       if (cos1)
9755         mask[14] |= 0xe0;
9756       *maskp = mask;
9757       return 1;
9758     }
9759   if (tag1 | dot1q)
9760     {
9761       if (tag1)
9762         {
9763           mask[15] = 0xff;
9764           mask[14] = 0x0f;
9765         }
9766       if (cos1)
9767         mask[14] |= 0xe0;
9768       if (proto)
9769         mask[16] = mask[17] = 0xff;
9770
9771       *maskp = mask;
9772       return 1;
9773     }
9774   if (cos2)
9775     mask[18] |= 0xe0;
9776   if (cos1)
9777     mask[14] |= 0xe0;
9778   if (proto)
9779     mask[12] = mask[13] = 0xff;
9780
9781   *maskp = mask;
9782   return 1;
9783 }
9784
9785 uword
9786 unformat_classify_mask (unformat_input_t * input, va_list * args)
9787 {
9788   u8 **maskp = va_arg (*args, u8 **);
9789   u32 *skipp = va_arg (*args, u32 *);
9790   u32 *matchp = va_arg (*args, u32 *);
9791   u32 match;
9792   u8 *mask = 0;
9793   u8 *l2 = 0;
9794   u8 *l3 = 0;
9795   u8 *l4 = 0;
9796   int i;
9797
9798   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9799     {
9800       if (unformat (input, "hex %U", unformat_hex_string, &mask))
9801         ;
9802       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
9803         ;
9804       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
9805         ;
9806       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
9807         ;
9808       else
9809         break;
9810     }
9811
9812   if (l4 && !l3)
9813     {
9814       vec_free (mask);
9815       vec_free (l2);
9816       vec_free (l4);
9817       return 0;
9818     }
9819
9820   if (mask || l2 || l3 || l4)
9821     {
9822       if (l2 || l3 || l4)
9823         {
9824           /* "With a free Ethernet header in every package" */
9825           if (l2 == 0)
9826             vec_validate (l2, 13);
9827           mask = l2;
9828           if (vec_len (l3))
9829             {
9830               vec_append (mask, l3);
9831               vec_free (l3);
9832             }
9833           if (vec_len (l4))
9834             {
9835               vec_append (mask, l4);
9836               vec_free (l4);
9837             }
9838         }
9839
9840       /* Scan forward looking for the first significant mask octet */
9841       for (i = 0; i < vec_len (mask); i++)
9842         if (mask[i])
9843           break;
9844
9845       /* compute (skip, match) params */
9846       *skipp = i / sizeof (u32x4);
9847       vec_delete (mask, *skipp * sizeof (u32x4), 0);
9848
9849       /* Pad mask to an even multiple of the vector size */
9850       while (vec_len (mask) % sizeof (u32x4))
9851         vec_add1 (mask, 0);
9852
9853       match = vec_len (mask) / sizeof (u32x4);
9854
9855       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
9856         {
9857           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
9858           if (*tmp || *(tmp + 1))
9859             break;
9860           match--;
9861         }
9862       if (match == 0)
9863         clib_warning ("BUG: match 0");
9864
9865       _vec_len (mask) = match * sizeof (u32x4);
9866
9867       *matchp = match;
9868       *maskp = mask;
9869
9870       return 1;
9871     }
9872
9873   return 0;
9874 }
9875 #endif /* VPP_API_TEST_BUILTIN */
9876
9877 #define foreach_l2_next                         \
9878 _(drop, DROP)                                   \
9879 _(ethernet, ETHERNET_INPUT)                     \
9880 _(ip4, IP4_INPUT)                               \
9881 _(ip6, IP6_INPUT)
9882
9883 uword
9884 unformat_l2_next_index (unformat_input_t * input, va_list * args)
9885 {
9886   u32 *miss_next_indexp = va_arg (*args, u32 *);
9887   u32 next_index = 0;
9888   u32 tmp;
9889
9890 #define _(n,N) \
9891   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
9892   foreach_l2_next;
9893 #undef _
9894
9895   if (unformat (input, "%d", &tmp))
9896     {
9897       next_index = tmp;
9898       goto out;
9899     }
9900
9901   return 0;
9902
9903 out:
9904   *miss_next_indexp = next_index;
9905   return 1;
9906 }
9907
9908 #define foreach_ip_next                         \
9909 _(drop, DROP)                                   \
9910 _(local, LOCAL)                                 \
9911 _(rewrite, REWRITE)
9912
9913 uword
9914 api_unformat_ip_next_index (unformat_input_t * input, va_list * args)
9915 {
9916   u32 *miss_next_indexp = va_arg (*args, u32 *);
9917   u32 next_index = 0;
9918   u32 tmp;
9919
9920 #define _(n,N) \
9921   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
9922   foreach_ip_next;
9923 #undef _
9924
9925   if (unformat (input, "%d", &tmp))
9926     {
9927       next_index = tmp;
9928       goto out;
9929     }
9930
9931   return 0;
9932
9933 out:
9934   *miss_next_indexp = next_index;
9935   return 1;
9936 }
9937
9938 #define foreach_acl_next                        \
9939 _(deny, DENY)
9940
9941 uword
9942 api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
9943 {
9944   u32 *miss_next_indexp = va_arg (*args, u32 *);
9945   u32 next_index = 0;
9946   u32 tmp;
9947
9948 #define _(n,N) \
9949   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
9950   foreach_acl_next;
9951 #undef _
9952
9953   if (unformat (input, "permit"))
9954     {
9955       next_index = ~0;
9956       goto out;
9957     }
9958   else if (unformat (input, "%d", &tmp))
9959     {
9960       next_index = tmp;
9961       goto out;
9962     }
9963
9964   return 0;
9965
9966 out:
9967   *miss_next_indexp = next_index;
9968   return 1;
9969 }
9970
9971 uword
9972 unformat_policer_precolor (unformat_input_t * input, va_list * args)
9973 {
9974   u32 *r = va_arg (*args, u32 *);
9975
9976   if (unformat (input, "conform-color"))
9977     *r = POLICE_CONFORM;
9978   else if (unformat (input, "exceed-color"))
9979     *r = POLICE_EXCEED;
9980   else
9981     return 0;
9982
9983   return 1;
9984 }
9985
9986 static int
9987 api_classify_add_del_table (vat_main_t * vam)
9988 {
9989   unformat_input_t *i = vam->input;
9990   vl_api_classify_add_del_table_t *mp;
9991
9992   u32 nbuckets = 2;
9993   u32 skip = ~0;
9994   u32 match = ~0;
9995   int is_add = 1;
9996   int del_chain = 0;
9997   u32 table_index = ~0;
9998   u32 next_table_index = ~0;
9999   u32 miss_next_index = ~0;
10000   u32 memory_size = 32 << 20;
10001   u8 *mask = 0;
10002   u32 current_data_flag = 0;
10003   int current_data_offset = 0;
10004   int ret;
10005
10006   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10007     {
10008       if (unformat (i, "del"))
10009         is_add = 0;
10010       else if (unformat (i, "del-chain"))
10011         {
10012           is_add = 0;
10013           del_chain = 1;
10014         }
10015       else if (unformat (i, "buckets %d", &nbuckets))
10016         ;
10017       else if (unformat (i, "memory_size %d", &memory_size))
10018         ;
10019       else if (unformat (i, "skip %d", &skip))
10020         ;
10021       else if (unformat (i, "match %d", &match))
10022         ;
10023       else if (unformat (i, "table %d", &table_index))
10024         ;
10025       else if (unformat (i, "mask %U", unformat_classify_mask,
10026                          &mask, &skip, &match))
10027         ;
10028       else if (unformat (i, "next-table %d", &next_table_index))
10029         ;
10030       else if (unformat (i, "miss-next %U", api_unformat_ip_next_index,
10031                          &miss_next_index))
10032         ;
10033       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
10034                          &miss_next_index))
10035         ;
10036       else if (unformat (i, "acl-miss-next %U", api_unformat_acl_next_index,
10037                          &miss_next_index))
10038         ;
10039       else if (unformat (i, "current-data-flag %d", &current_data_flag))
10040         ;
10041       else if (unformat (i, "current-data-offset %d", &current_data_offset))
10042         ;
10043       else
10044         break;
10045     }
10046
10047   if (is_add && mask == 0)
10048     {
10049       errmsg ("Mask required");
10050       return -99;
10051     }
10052
10053   if (is_add && skip == ~0)
10054     {
10055       errmsg ("skip count required");
10056       return -99;
10057     }
10058
10059   if (is_add && match == ~0)
10060     {
10061       errmsg ("match count required");
10062       return -99;
10063     }
10064
10065   if (!is_add && table_index == ~0)
10066     {
10067       errmsg ("table index required for delete");
10068       return -99;
10069     }
10070
10071   M2 (CLASSIFY_ADD_DEL_TABLE, mp, vec_len (mask));
10072
10073   mp->is_add = is_add;
10074   mp->del_chain = del_chain;
10075   mp->table_index = ntohl (table_index);
10076   mp->nbuckets = ntohl (nbuckets);
10077   mp->memory_size = ntohl (memory_size);
10078   mp->skip_n_vectors = ntohl (skip);
10079   mp->match_n_vectors = ntohl (match);
10080   mp->next_table_index = ntohl (next_table_index);
10081   mp->miss_next_index = ntohl (miss_next_index);
10082   mp->current_data_flag = ntohl (current_data_flag);
10083   mp->current_data_offset = ntohl (current_data_offset);
10084   mp->mask_len = ntohl (vec_len (mask));
10085   clib_memcpy (mp->mask, mask, vec_len (mask));
10086
10087   vec_free (mask);
10088
10089   S (mp);
10090   W (ret);
10091   return ret;
10092 }
10093
10094 #if VPP_API_TEST_BUILTIN == 0
10095 uword
10096 unformat_l4_match (unformat_input_t * input, va_list * args)
10097 {
10098   u8 **matchp = va_arg (*args, u8 **);
10099
10100   u8 *proto_header = 0;
10101   int src_port = 0;
10102   int dst_port = 0;
10103
10104   tcpudp_header_t h;
10105
10106   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10107     {
10108       if (unformat (input, "src_port %d", &src_port))
10109         ;
10110       else if (unformat (input, "dst_port %d", &dst_port))
10111         ;
10112       else
10113         return 0;
10114     }
10115
10116   h.src_port = clib_host_to_net_u16 (src_port);
10117   h.dst_port = clib_host_to_net_u16 (dst_port);
10118   vec_validate (proto_header, sizeof (h) - 1);
10119   memcpy (proto_header, &h, sizeof (h));
10120
10121   *matchp = proto_header;
10122
10123   return 1;
10124 }
10125
10126 uword
10127 unformat_ip4_match (unformat_input_t * input, va_list * args)
10128 {
10129   u8 **matchp = va_arg (*args, u8 **);
10130   u8 *match = 0;
10131   ip4_header_t *ip;
10132   int version = 0;
10133   u32 version_val;
10134   int hdr_length = 0;
10135   u32 hdr_length_val;
10136   int src = 0, dst = 0;
10137   ip4_address_t src_val, dst_val;
10138   int proto = 0;
10139   u32 proto_val;
10140   int tos = 0;
10141   u32 tos_val;
10142   int length = 0;
10143   u32 length_val;
10144   int fragment_id = 0;
10145   u32 fragment_id_val;
10146   int ttl = 0;
10147   int ttl_val;
10148   int checksum = 0;
10149   u32 checksum_val;
10150
10151   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10152     {
10153       if (unformat (input, "version %d", &version_val))
10154         version = 1;
10155       else if (unformat (input, "hdr_length %d", &hdr_length_val))
10156         hdr_length = 1;
10157       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
10158         src = 1;
10159       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
10160         dst = 1;
10161       else if (unformat (input, "proto %d", &proto_val))
10162         proto = 1;
10163       else if (unformat (input, "tos %d", &tos_val))
10164         tos = 1;
10165       else if (unformat (input, "length %d", &length_val))
10166         length = 1;
10167       else if (unformat (input, "fragment_id %d", &fragment_id_val))
10168         fragment_id = 1;
10169       else if (unformat (input, "ttl %d", &ttl_val))
10170         ttl = 1;
10171       else if (unformat (input, "checksum %d", &checksum_val))
10172         checksum = 1;
10173       else
10174         break;
10175     }
10176
10177   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
10178       + ttl + checksum == 0)
10179     return 0;
10180
10181   /*
10182    * Aligned because we use the real comparison functions
10183    */
10184   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
10185
10186   ip = (ip4_header_t *) match;
10187
10188   /* These are realistically matched in practice */
10189   if (src)
10190     ip->src_address.as_u32 = src_val.as_u32;
10191
10192   if (dst)
10193     ip->dst_address.as_u32 = dst_val.as_u32;
10194
10195   if (proto)
10196     ip->protocol = proto_val;
10197
10198
10199   /* These are not, but they're included for completeness */
10200   if (version)
10201     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
10202
10203   if (hdr_length)
10204     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
10205
10206   if (tos)
10207     ip->tos = tos_val;
10208
10209   if (length)
10210     ip->length = clib_host_to_net_u16 (length_val);
10211
10212   if (ttl)
10213     ip->ttl = ttl_val;
10214
10215   if (checksum)
10216     ip->checksum = clib_host_to_net_u16 (checksum_val);
10217
10218   *matchp = match;
10219   return 1;
10220 }
10221
10222 uword
10223 unformat_ip6_match (unformat_input_t * input, va_list * args)
10224 {
10225   u8 **matchp = va_arg (*args, u8 **);
10226   u8 *match = 0;
10227   ip6_header_t *ip;
10228   int version = 0;
10229   u32 version_val;
10230   u8 traffic_class = 0;
10231   u32 traffic_class_val = 0;
10232   u8 flow_label = 0;
10233   u8 flow_label_val;
10234   int src = 0, dst = 0;
10235   ip6_address_t src_val, dst_val;
10236   int proto = 0;
10237   u32 proto_val;
10238   int payload_length = 0;
10239   u32 payload_length_val;
10240   int hop_limit = 0;
10241   int hop_limit_val;
10242   u32 ip_version_traffic_class_and_flow_label;
10243
10244   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10245     {
10246       if (unformat (input, "version %d", &version_val))
10247         version = 1;
10248       else if (unformat (input, "traffic_class %d", &traffic_class_val))
10249         traffic_class = 1;
10250       else if (unformat (input, "flow_label %d", &flow_label_val))
10251         flow_label = 1;
10252       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
10253         src = 1;
10254       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
10255         dst = 1;
10256       else if (unformat (input, "proto %d", &proto_val))
10257         proto = 1;
10258       else if (unformat (input, "payload_length %d", &payload_length_val))
10259         payload_length = 1;
10260       else if (unformat (input, "hop_limit %d", &hop_limit_val))
10261         hop_limit = 1;
10262       else
10263         break;
10264     }
10265
10266   if (version + traffic_class + flow_label + src + dst + proto +
10267       payload_length + hop_limit == 0)
10268     return 0;
10269
10270   /*
10271    * Aligned because we use the real comparison functions
10272    */
10273   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
10274
10275   ip = (ip6_header_t *) match;
10276
10277   if (src)
10278     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
10279
10280   if (dst)
10281     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
10282
10283   if (proto)
10284     ip->protocol = proto_val;
10285
10286   ip_version_traffic_class_and_flow_label = 0;
10287
10288   if (version)
10289     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
10290
10291   if (traffic_class)
10292     ip_version_traffic_class_and_flow_label |=
10293       (traffic_class_val & 0xFF) << 20;
10294
10295   if (flow_label)
10296     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
10297
10298   ip->ip_version_traffic_class_and_flow_label =
10299     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
10300
10301   if (payload_length)
10302     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
10303
10304   if (hop_limit)
10305     ip->hop_limit = hop_limit_val;
10306
10307   *matchp = match;
10308   return 1;
10309 }
10310
10311 uword
10312 unformat_l3_match (unformat_input_t * input, va_list * args)
10313 {
10314   u8 **matchp = va_arg (*args, u8 **);
10315
10316   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10317     {
10318       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
10319         return 1;
10320       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
10321         return 1;
10322       else
10323         break;
10324     }
10325   return 0;
10326 }
10327
10328 uword
10329 unformat_vlan_tag (unformat_input_t * input, va_list * args)
10330 {
10331   u8 *tagp = va_arg (*args, u8 *);
10332   u32 tag;
10333
10334   if (unformat (input, "%d", &tag))
10335     {
10336       tagp[0] = (tag >> 8) & 0x0F;
10337       tagp[1] = tag & 0xFF;
10338       return 1;
10339     }
10340
10341   return 0;
10342 }
10343
10344 uword
10345 unformat_l2_match (unformat_input_t * input, va_list * args)
10346 {
10347   u8 **matchp = va_arg (*args, u8 **);
10348   u8 *match = 0;
10349   u8 src = 0;
10350   u8 src_val[6];
10351   u8 dst = 0;
10352   u8 dst_val[6];
10353   u8 proto = 0;
10354   u16 proto_val;
10355   u8 tag1 = 0;
10356   u8 tag1_val[2];
10357   u8 tag2 = 0;
10358   u8 tag2_val[2];
10359   int len = 14;
10360   u8 ignore_tag1 = 0;
10361   u8 ignore_tag2 = 0;
10362   u8 cos1 = 0;
10363   u8 cos2 = 0;
10364   u32 cos1_val = 0;
10365   u32 cos2_val = 0;
10366
10367   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10368     {
10369       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
10370         src = 1;
10371       else
10372         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
10373         dst = 1;
10374       else if (unformat (input, "proto %U",
10375                          unformat_ethernet_type_host_byte_order, &proto_val))
10376         proto = 1;
10377       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
10378         tag1 = 1;
10379       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
10380         tag2 = 1;
10381       else if (unformat (input, "ignore-tag1"))
10382         ignore_tag1 = 1;
10383       else if (unformat (input, "ignore-tag2"))
10384         ignore_tag2 = 1;
10385       else if (unformat (input, "cos1 %d", &cos1_val))
10386         cos1 = 1;
10387       else if (unformat (input, "cos2 %d", &cos2_val))
10388         cos2 = 1;
10389       else
10390         break;
10391     }
10392   if ((src + dst + proto + tag1 + tag2 +
10393        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
10394     return 0;
10395
10396   if (tag1 || ignore_tag1 || cos1)
10397     len = 18;
10398   if (tag2 || ignore_tag2 || cos2)
10399     len = 22;
10400
10401   vec_validate_aligned (match, len - 1, sizeof (u32x4));
10402
10403   if (dst)
10404     clib_memcpy (match, dst_val, 6);
10405
10406   if (src)
10407     clib_memcpy (match + 6, src_val, 6);
10408
10409   if (tag2)
10410     {
10411       /* inner vlan tag */
10412       match[19] = tag2_val[1];
10413       match[18] = tag2_val[0];
10414       if (cos2)
10415         match[18] |= (cos2_val & 0x7) << 5;
10416       if (proto)
10417         {
10418           match[21] = proto_val & 0xff;
10419           match[20] = proto_val >> 8;
10420         }
10421       if (tag1)
10422         {
10423           match[15] = tag1_val[1];
10424           match[14] = tag1_val[0];
10425         }
10426       if (cos1)
10427         match[14] |= (cos1_val & 0x7) << 5;
10428       *matchp = match;
10429       return 1;
10430     }
10431   if (tag1)
10432     {
10433       match[15] = tag1_val[1];
10434       match[14] = tag1_val[0];
10435       if (proto)
10436         {
10437           match[17] = proto_val & 0xff;
10438           match[16] = proto_val >> 8;
10439         }
10440       if (cos1)
10441         match[14] |= (cos1_val & 0x7) << 5;
10442
10443       *matchp = match;
10444       return 1;
10445     }
10446   if (cos2)
10447     match[18] |= (cos2_val & 0x7) << 5;
10448   if (cos1)
10449     match[14] |= (cos1_val & 0x7) << 5;
10450   if (proto)
10451     {
10452       match[13] = proto_val & 0xff;
10453       match[12] = proto_val >> 8;
10454     }
10455
10456   *matchp = match;
10457   return 1;
10458 }
10459
10460 uword
10461 unformat_qos_source (unformat_input_t * input, va_list * args)
10462 {
10463   int *qs = va_arg (*args, int *);
10464
10465   if (unformat (input, "ip"))
10466     *qs = QOS_SOURCE_IP;
10467   else if (unformat (input, "mpls"))
10468     *qs = QOS_SOURCE_MPLS;
10469   else if (unformat (input, "ext"))
10470     *qs = QOS_SOURCE_EXT;
10471   else if (unformat (input, "vlan"))
10472     *qs = QOS_SOURCE_VLAN;
10473   else
10474     return 0;
10475
10476   return 1;
10477 }
10478 #endif
10479
10480 uword
10481 api_unformat_classify_match (unformat_input_t * input, va_list * args)
10482 {
10483   u8 **matchp = va_arg (*args, u8 **);
10484   u32 skip_n_vectors = va_arg (*args, u32);
10485   u32 match_n_vectors = va_arg (*args, u32);
10486
10487   u8 *match = 0;
10488   u8 *l2 = 0;
10489   u8 *l3 = 0;
10490   u8 *l4 = 0;
10491
10492   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10493     {
10494       if (unformat (input, "hex %U", unformat_hex_string, &match))
10495         ;
10496       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
10497         ;
10498       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
10499         ;
10500       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
10501         ;
10502       else
10503         break;
10504     }
10505
10506   if (l4 && !l3)
10507     {
10508       vec_free (match);
10509       vec_free (l2);
10510       vec_free (l4);
10511       return 0;
10512     }
10513
10514   if (match || l2 || l3 || l4)
10515     {
10516       if (l2 || l3 || l4)
10517         {
10518           /* "Win a free Ethernet header in every packet" */
10519           if (l2 == 0)
10520             vec_validate_aligned (l2, 13, sizeof (u32x4));
10521           match = l2;
10522           if (vec_len (l3))
10523             {
10524               vec_append_aligned (match, l3, sizeof (u32x4));
10525               vec_free (l3);
10526             }
10527           if (vec_len (l4))
10528             {
10529               vec_append_aligned (match, l4, sizeof (u32x4));
10530               vec_free (l4);
10531             }
10532         }
10533
10534       /* Make sure the vector is big enough even if key is all 0's */
10535       vec_validate_aligned
10536         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
10537          sizeof (u32x4));
10538
10539       /* Set size, include skipped vectors */
10540       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
10541
10542       *matchp = match;
10543
10544       return 1;
10545     }
10546
10547   return 0;
10548 }
10549
10550 static int
10551 api_classify_add_del_session (vat_main_t * vam)
10552 {
10553   unformat_input_t *i = vam->input;
10554   vl_api_classify_add_del_session_t *mp;
10555   int is_add = 1;
10556   u32 table_index = ~0;
10557   u32 hit_next_index = ~0;
10558   u32 opaque_index = ~0;
10559   u8 *match = 0;
10560   i32 advance = 0;
10561   u32 skip_n_vectors = 0;
10562   u32 match_n_vectors = 0;
10563   u32 action = 0;
10564   u32 metadata = 0;
10565   int ret;
10566
10567   /*
10568    * Warning: you have to supply skip_n and match_n
10569    * because the API client cant simply look at the classify
10570    * table object.
10571    */
10572
10573   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10574     {
10575       if (unformat (i, "del"))
10576         is_add = 0;
10577       else if (unformat (i, "hit-next %U", api_unformat_ip_next_index,
10578                          &hit_next_index))
10579         ;
10580       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
10581                          &hit_next_index))
10582         ;
10583       else if (unformat (i, "acl-hit-next %U", api_unformat_acl_next_index,
10584                          &hit_next_index))
10585         ;
10586       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
10587         ;
10588       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
10589         ;
10590       else if (unformat (i, "opaque-index %d", &opaque_index))
10591         ;
10592       else if (unformat (i, "skip_n %d", &skip_n_vectors))
10593         ;
10594       else if (unformat (i, "match_n %d", &match_n_vectors))
10595         ;
10596       else if (unformat (i, "match %U", api_unformat_classify_match,
10597                          &match, skip_n_vectors, match_n_vectors))
10598         ;
10599       else if (unformat (i, "advance %d", &advance))
10600         ;
10601       else if (unformat (i, "table-index %d", &table_index))
10602         ;
10603       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
10604         action = 1;
10605       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
10606         action = 2;
10607       else if (unformat (i, "action %d", &action))
10608         ;
10609       else if (unformat (i, "metadata %d", &metadata))
10610         ;
10611       else
10612         break;
10613     }
10614
10615   if (table_index == ~0)
10616     {
10617       errmsg ("Table index required");
10618       return -99;
10619     }
10620
10621   if (is_add && match == 0)
10622     {
10623       errmsg ("Match value required");
10624       return -99;
10625     }
10626
10627   M2 (CLASSIFY_ADD_DEL_SESSION, mp, vec_len (match));
10628
10629   mp->is_add = is_add;
10630   mp->table_index = ntohl (table_index);
10631   mp->hit_next_index = ntohl (hit_next_index);
10632   mp->opaque_index = ntohl (opaque_index);
10633   mp->advance = ntohl (advance);
10634   mp->action = action;
10635   mp->metadata = ntohl (metadata);
10636   mp->match_len = ntohl (vec_len (match));
10637   clib_memcpy (mp->match, match, vec_len (match));
10638   vec_free (match);
10639
10640   S (mp);
10641   W (ret);
10642   return ret;
10643 }
10644
10645 static int
10646 api_classify_set_interface_ip_table (vat_main_t * vam)
10647 {
10648   unformat_input_t *i = vam->input;
10649   vl_api_classify_set_interface_ip_table_t *mp;
10650   u32 sw_if_index;
10651   int sw_if_index_set;
10652   u32 table_index = ~0;
10653   u8 is_ipv6 = 0;
10654   int ret;
10655
10656   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10657     {
10658       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10659         sw_if_index_set = 1;
10660       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10661         sw_if_index_set = 1;
10662       else if (unformat (i, "table %d", &table_index))
10663         ;
10664       else
10665         {
10666           clib_warning ("parse error '%U'", format_unformat_error, i);
10667           return -99;
10668         }
10669     }
10670
10671   if (sw_if_index_set == 0)
10672     {
10673       errmsg ("missing interface name or sw_if_index");
10674       return -99;
10675     }
10676
10677
10678   M (CLASSIFY_SET_INTERFACE_IP_TABLE, mp);
10679
10680   mp->sw_if_index = ntohl (sw_if_index);
10681   mp->table_index = ntohl (table_index);
10682   mp->is_ipv6 = is_ipv6;
10683
10684   S (mp);
10685   W (ret);
10686   return ret;
10687 }
10688
10689 static int
10690 api_classify_set_interface_l2_tables (vat_main_t * vam)
10691 {
10692   unformat_input_t *i = vam->input;
10693   vl_api_classify_set_interface_l2_tables_t *mp;
10694   u32 sw_if_index;
10695   int sw_if_index_set;
10696   u32 ip4_table_index = ~0;
10697   u32 ip6_table_index = ~0;
10698   u32 other_table_index = ~0;
10699   u32 is_input = 1;
10700   int ret;
10701
10702   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10703     {
10704       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10705         sw_if_index_set = 1;
10706       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10707         sw_if_index_set = 1;
10708       else if (unformat (i, "ip4-table %d", &ip4_table_index))
10709         ;
10710       else if (unformat (i, "ip6-table %d", &ip6_table_index))
10711         ;
10712       else if (unformat (i, "other-table %d", &other_table_index))
10713         ;
10714       else if (unformat (i, "is-input %d", &is_input))
10715         ;
10716       else
10717         {
10718           clib_warning ("parse error '%U'", format_unformat_error, i);
10719           return -99;
10720         }
10721     }
10722
10723   if (sw_if_index_set == 0)
10724     {
10725       errmsg ("missing interface name or sw_if_index");
10726       return -99;
10727     }
10728
10729
10730   M (CLASSIFY_SET_INTERFACE_L2_TABLES, mp);
10731
10732   mp->sw_if_index = ntohl (sw_if_index);
10733   mp->ip4_table_index = ntohl (ip4_table_index);
10734   mp->ip6_table_index = ntohl (ip6_table_index);
10735   mp->other_table_index = ntohl (other_table_index);
10736   mp->is_input = (u8) is_input;
10737
10738   S (mp);
10739   W (ret);
10740   return ret;
10741 }
10742
10743 static int
10744 api_set_ipfix_exporter (vat_main_t * vam)
10745 {
10746   unformat_input_t *i = vam->input;
10747   vl_api_set_ipfix_exporter_t *mp;
10748   ip4_address_t collector_address;
10749   u8 collector_address_set = 0;
10750   u32 collector_port = ~0;
10751   ip4_address_t src_address;
10752   u8 src_address_set = 0;
10753   u32 vrf_id = ~0;
10754   u32 path_mtu = ~0;
10755   u32 template_interval = ~0;
10756   u8 udp_checksum = 0;
10757   int ret;
10758
10759   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10760     {
10761       if (unformat (i, "collector_address %U", unformat_ip4_address,
10762                     &collector_address))
10763         collector_address_set = 1;
10764       else if (unformat (i, "collector_port %d", &collector_port))
10765         ;
10766       else if (unformat (i, "src_address %U", unformat_ip4_address,
10767                          &src_address))
10768         src_address_set = 1;
10769       else if (unformat (i, "vrf_id %d", &vrf_id))
10770         ;
10771       else if (unformat (i, "path_mtu %d", &path_mtu))
10772         ;
10773       else if (unformat (i, "template_interval %d", &template_interval))
10774         ;
10775       else if (unformat (i, "udp_checksum"))
10776         udp_checksum = 1;
10777       else
10778         break;
10779     }
10780
10781   if (collector_address_set == 0)
10782     {
10783       errmsg ("collector_address required");
10784       return -99;
10785     }
10786
10787   if (src_address_set == 0)
10788     {
10789       errmsg ("src_address required");
10790       return -99;
10791     }
10792
10793   M (SET_IPFIX_EXPORTER, mp);
10794
10795   memcpy (mp->collector_address.un.ip4, collector_address.data,
10796           sizeof (collector_address.data));
10797   mp->collector_port = htons ((u16) collector_port);
10798   memcpy (mp->src_address.un.ip4, src_address.data,
10799           sizeof (src_address.data));
10800   mp->vrf_id = htonl (vrf_id);
10801   mp->path_mtu = htonl (path_mtu);
10802   mp->template_interval = htonl (template_interval);
10803   mp->udp_checksum = udp_checksum;
10804
10805   S (mp);
10806   W (ret);
10807   return ret;
10808 }
10809
10810 static int
10811 api_set_ipfix_classify_stream (vat_main_t * vam)
10812 {
10813   unformat_input_t *i = vam->input;
10814   vl_api_set_ipfix_classify_stream_t *mp;
10815   u32 domain_id = 0;
10816   u32 src_port = UDP_DST_PORT_ipfix;
10817   int ret;
10818
10819   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10820     {
10821       if (unformat (i, "domain %d", &domain_id))
10822         ;
10823       else if (unformat (i, "src_port %d", &src_port))
10824         ;
10825       else
10826         {
10827           errmsg ("unknown input `%U'", format_unformat_error, i);
10828           return -99;
10829         }
10830     }
10831
10832   M (SET_IPFIX_CLASSIFY_STREAM, mp);
10833
10834   mp->domain_id = htonl (domain_id);
10835   mp->src_port = htons ((u16) src_port);
10836
10837   S (mp);
10838   W (ret);
10839   return ret;
10840 }
10841
10842 static int
10843 api_ipfix_classify_table_add_del (vat_main_t * vam)
10844 {
10845   unformat_input_t *i = vam->input;
10846   vl_api_ipfix_classify_table_add_del_t *mp;
10847   int is_add = -1;
10848   u32 classify_table_index = ~0;
10849   u8 ip_version = 0;
10850   u8 transport_protocol = 255;
10851   int ret;
10852
10853   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10854     {
10855       if (unformat (i, "add"))
10856         is_add = 1;
10857       else if (unformat (i, "del"))
10858         is_add = 0;
10859       else if (unformat (i, "table %d", &classify_table_index))
10860         ;
10861       else if (unformat (i, "ip4"))
10862         ip_version = 4;
10863       else if (unformat (i, "ip6"))
10864         ip_version = 6;
10865       else if (unformat (i, "tcp"))
10866         transport_protocol = 6;
10867       else if (unformat (i, "udp"))
10868         transport_protocol = 17;
10869       else
10870         {
10871           errmsg ("unknown input `%U'", format_unformat_error, i);
10872           return -99;
10873         }
10874     }
10875
10876   if (is_add == -1)
10877     {
10878       errmsg ("expecting: add|del");
10879       return -99;
10880     }
10881   if (classify_table_index == ~0)
10882     {
10883       errmsg ("classifier table not specified");
10884       return -99;
10885     }
10886   if (ip_version == 0)
10887     {
10888       errmsg ("IP version not specified");
10889       return -99;
10890     }
10891
10892   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, mp);
10893
10894   mp->is_add = is_add;
10895   mp->table_id = htonl (classify_table_index);
10896   mp->ip_version = ip_version;
10897   mp->transport_protocol = transport_protocol;
10898
10899   S (mp);
10900   W (ret);
10901   return ret;
10902 }
10903
10904 static int
10905 api_get_node_index (vat_main_t * vam)
10906 {
10907   unformat_input_t *i = vam->input;
10908   vl_api_get_node_index_t *mp;
10909   u8 *name = 0;
10910   int ret;
10911
10912   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10913     {
10914       if (unformat (i, "node %s", &name))
10915         ;
10916       else
10917         break;
10918     }
10919   if (name == 0)
10920     {
10921       errmsg ("node name required");
10922       return -99;
10923     }
10924   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
10925     {
10926       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
10927       return -99;
10928     }
10929
10930   M (GET_NODE_INDEX, mp);
10931   clib_memcpy (mp->node_name, name, vec_len (name));
10932   vec_free (name);
10933
10934   S (mp);
10935   W (ret);
10936   return ret;
10937 }
10938
10939 static int
10940 api_get_next_index (vat_main_t * vam)
10941 {
10942   unformat_input_t *i = vam->input;
10943   vl_api_get_next_index_t *mp;
10944   u8 *node_name = 0, *next_node_name = 0;
10945   int ret;
10946
10947   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10948     {
10949       if (unformat (i, "node-name %s", &node_name))
10950         ;
10951       else if (unformat (i, "next-node-name %s", &next_node_name))
10952         break;
10953     }
10954
10955   if (node_name == 0)
10956     {
10957       errmsg ("node name required");
10958       return -99;
10959     }
10960   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
10961     {
10962       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
10963       return -99;
10964     }
10965
10966   if (next_node_name == 0)
10967     {
10968       errmsg ("next node name required");
10969       return -99;
10970     }
10971   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
10972     {
10973       errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
10974       return -99;
10975     }
10976
10977   M (GET_NEXT_INDEX, mp);
10978   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
10979   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
10980   vec_free (node_name);
10981   vec_free (next_node_name);
10982
10983   S (mp);
10984   W (ret);
10985   return ret;
10986 }
10987
10988 static int
10989 api_add_node_next (vat_main_t * vam)
10990 {
10991   unformat_input_t *i = vam->input;
10992   vl_api_add_node_next_t *mp;
10993   u8 *name = 0;
10994   u8 *next = 0;
10995   int ret;
10996
10997   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10998     {
10999       if (unformat (i, "node %s", &name))
11000         ;
11001       else if (unformat (i, "next %s", &next))
11002         ;
11003       else
11004         break;
11005     }
11006   if (name == 0)
11007     {
11008       errmsg ("node name required");
11009       return -99;
11010     }
11011   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
11012     {
11013       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11014       return -99;
11015     }
11016   if (next == 0)
11017     {
11018       errmsg ("next node required");
11019       return -99;
11020     }
11021   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
11022     {
11023       errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
11024       return -99;
11025     }
11026
11027   M (ADD_NODE_NEXT, mp);
11028   clib_memcpy (mp->node_name, name, vec_len (name));
11029   clib_memcpy (mp->next_name, next, vec_len (next));
11030   vec_free (name);
11031   vec_free (next);
11032
11033   S (mp);
11034   W (ret);
11035   return ret;
11036 }
11037
11038 static int
11039 api_l2tpv3_create_tunnel (vat_main_t * vam)
11040 {
11041   unformat_input_t *i = vam->input;
11042   ip6_address_t client_address, our_address;
11043   int client_address_set = 0;
11044   int our_address_set = 0;
11045   u32 local_session_id = 0;
11046   u32 remote_session_id = 0;
11047   u64 local_cookie = 0;
11048   u64 remote_cookie = 0;
11049   u8 l2_sublayer_present = 0;
11050   vl_api_l2tpv3_create_tunnel_t *mp;
11051   int ret;
11052
11053   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11054     {
11055       if (unformat (i, "client_address %U", unformat_ip6_address,
11056                     &client_address))
11057         client_address_set = 1;
11058       else if (unformat (i, "our_address %U", unformat_ip6_address,
11059                          &our_address))
11060         our_address_set = 1;
11061       else if (unformat (i, "local_session_id %d", &local_session_id))
11062         ;
11063       else if (unformat (i, "remote_session_id %d", &remote_session_id))
11064         ;
11065       else if (unformat (i, "local_cookie %lld", &local_cookie))
11066         ;
11067       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
11068         ;
11069       else if (unformat (i, "l2-sublayer-present"))
11070         l2_sublayer_present = 1;
11071       else
11072         break;
11073     }
11074
11075   if (client_address_set == 0)
11076     {
11077       errmsg ("client_address required");
11078       return -99;
11079     }
11080
11081   if (our_address_set == 0)
11082     {
11083       errmsg ("our_address required");
11084       return -99;
11085     }
11086
11087   M (L2TPV3_CREATE_TUNNEL, mp);
11088
11089   clib_memcpy (mp->client_address.un.ip6, client_address.as_u8,
11090                sizeof (ip6_address_t));
11091
11092   clib_memcpy (mp->our_address.un.ip6, our_address.as_u8,
11093                sizeof (ip6_address_t));
11094
11095   mp->local_session_id = ntohl (local_session_id);
11096   mp->remote_session_id = ntohl (remote_session_id);
11097   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
11098   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
11099   mp->l2_sublayer_present = l2_sublayer_present;
11100
11101   S (mp);
11102   W (ret);
11103   return ret;
11104 }
11105
11106 static int
11107 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
11108 {
11109   unformat_input_t *i = vam->input;
11110   u32 sw_if_index;
11111   u8 sw_if_index_set = 0;
11112   u64 new_local_cookie = 0;
11113   u64 new_remote_cookie = 0;
11114   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
11115   int ret;
11116
11117   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11118     {
11119       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11120         sw_if_index_set = 1;
11121       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11122         sw_if_index_set = 1;
11123       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
11124         ;
11125       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
11126         ;
11127       else
11128         break;
11129     }
11130
11131   if (sw_if_index_set == 0)
11132     {
11133       errmsg ("missing interface name or sw_if_index");
11134       return -99;
11135     }
11136
11137   M (L2TPV3_SET_TUNNEL_COOKIES, mp);
11138
11139   mp->sw_if_index = ntohl (sw_if_index);
11140   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
11141   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
11142
11143   S (mp);
11144   W (ret);
11145   return ret;
11146 }
11147
11148 static int
11149 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
11150 {
11151   unformat_input_t *i = vam->input;
11152   vl_api_l2tpv3_interface_enable_disable_t *mp;
11153   u32 sw_if_index;
11154   u8 sw_if_index_set = 0;
11155   u8 enable_disable = 1;
11156   int ret;
11157
11158   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11159     {
11160       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11161         sw_if_index_set = 1;
11162       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11163         sw_if_index_set = 1;
11164       else if (unformat (i, "enable"))
11165         enable_disable = 1;
11166       else if (unformat (i, "disable"))
11167         enable_disable = 0;
11168       else
11169         break;
11170     }
11171
11172   if (sw_if_index_set == 0)
11173     {
11174       errmsg ("missing interface name or sw_if_index");
11175       return -99;
11176     }
11177
11178   M (L2TPV3_INTERFACE_ENABLE_DISABLE, mp);
11179
11180   mp->sw_if_index = ntohl (sw_if_index);
11181   mp->enable_disable = enable_disable;
11182
11183   S (mp);
11184   W (ret);
11185   return ret;
11186 }
11187
11188 static int
11189 api_l2tpv3_set_lookup_key (vat_main_t * vam)
11190 {
11191   unformat_input_t *i = vam->input;
11192   vl_api_l2tpv3_set_lookup_key_t *mp;
11193   u8 key = ~0;
11194   int ret;
11195
11196   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11197     {
11198       if (unformat (i, "lookup_v6_src"))
11199         key = L2T_LOOKUP_SRC_ADDRESS;
11200       else if (unformat (i, "lookup_v6_dst"))
11201         key = L2T_LOOKUP_DST_ADDRESS;
11202       else if (unformat (i, "lookup_session_id"))
11203         key = L2T_LOOKUP_SESSION_ID;
11204       else
11205         break;
11206     }
11207
11208   if (key == (u8) ~ 0)
11209     {
11210       errmsg ("l2tp session lookup key unset");
11211       return -99;
11212     }
11213
11214   M (L2TPV3_SET_LOOKUP_KEY, mp);
11215
11216   mp->key = key;
11217
11218   S (mp);
11219   W (ret);
11220   return ret;
11221 }
11222
11223 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
11224   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
11225 {
11226   vat_main_t *vam = &vat_main;
11227
11228   print (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)",
11229          format_ip6_address, mp->our_address,
11230          format_ip6_address, mp->client_address,
11231          clib_net_to_host_u32 (mp->sw_if_index));
11232
11233   print (vam->ofp,
11234          "   local cookies %016llx %016llx remote cookie %016llx",
11235          clib_net_to_host_u64 (mp->local_cookie[0]),
11236          clib_net_to_host_u64 (mp->local_cookie[1]),
11237          clib_net_to_host_u64 (mp->remote_cookie));
11238
11239   print (vam->ofp, "   local session-id %d remote session-id %d",
11240          clib_net_to_host_u32 (mp->local_session_id),
11241          clib_net_to_host_u32 (mp->remote_session_id));
11242
11243   print (vam->ofp, "   l2 specific sublayer %s\n",
11244          mp->l2_sublayer_present ? "preset" : "absent");
11245
11246 }
11247
11248 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
11249   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
11250 {
11251   vat_main_t *vam = &vat_main;
11252   vat_json_node_t *node = NULL;
11253   struct in6_addr addr;
11254
11255   if (VAT_JSON_ARRAY != vam->json_tree.type)
11256     {
11257       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11258       vat_json_init_array (&vam->json_tree);
11259     }
11260   node = vat_json_array_add (&vam->json_tree);
11261
11262   vat_json_init_object (node);
11263
11264   clib_memcpy (&addr, mp->our_address.un.ip6, sizeof (addr));
11265   vat_json_object_add_ip6 (node, "our_address", addr);
11266   clib_memcpy (&addr, mp->client_address.un.ip6, sizeof (addr));
11267   vat_json_object_add_ip6 (node, "client_address", addr);
11268
11269   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
11270   vat_json_init_array (lc);
11271   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
11272   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
11273   vat_json_object_add_uint (node, "remote_cookie",
11274                             clib_net_to_host_u64 (mp->remote_cookie));
11275
11276   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
11277   vat_json_object_add_uint (node, "local_session_id",
11278                             clib_net_to_host_u32 (mp->local_session_id));
11279   vat_json_object_add_uint (node, "remote_session_id",
11280                             clib_net_to_host_u32 (mp->remote_session_id));
11281   vat_json_object_add_string_copy (node, "l2_sublayer",
11282                                    mp->l2_sublayer_present ? (u8 *) "present"
11283                                    : (u8 *) "absent");
11284 }
11285
11286 static int
11287 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
11288 {
11289   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
11290   vl_api_control_ping_t *mp_ping;
11291   int ret;
11292
11293   /* Get list of l2tpv3-tunnel interfaces */
11294   M (SW_IF_L2TPV3_TUNNEL_DUMP, mp);
11295   S (mp);
11296
11297   /* Use a control ping for synchronization */
11298   MPING (CONTROL_PING, mp_ping);
11299   S (mp_ping);
11300
11301   W (ret);
11302   return ret;
11303 }
11304
11305
11306 static void vl_api_sw_interface_tap_v2_details_t_handler
11307   (vl_api_sw_interface_tap_v2_details_t * mp)
11308 {
11309   vat_main_t *vam = &vat_main;
11310
11311   u8 *ip4 =
11312     format (0, "%U/%d", format_ip4_address, mp->host_ip4_prefix.address,
11313             mp->host_ip4_prefix.len);
11314   u8 *ip6 =
11315     format (0, "%U/%d", format_ip6_address, mp->host_ip6_prefix.address,
11316             mp->host_ip6_prefix.len);
11317
11318   print (vam->ofp,
11319          "\n%-16s %-12d %-5d %-12d %-12d %-14U %-30s %-20s %-20s %-30s 0x%-08x",
11320          mp->dev_name, ntohl (mp->sw_if_index), ntohl (mp->id),
11321          ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
11322          format_ethernet_address, mp->host_mac_addr, mp->host_namespace,
11323          mp->host_bridge, ip4, ip6, ntohl (mp->tap_flags));
11324
11325   vec_free (ip4);
11326   vec_free (ip6);
11327 }
11328
11329 static void vl_api_sw_interface_tap_v2_details_t_handler_json
11330   (vl_api_sw_interface_tap_v2_details_t * mp)
11331 {
11332   vat_main_t *vam = &vat_main;
11333   vat_json_node_t *node = NULL;
11334
11335   if (VAT_JSON_ARRAY != vam->json_tree.type)
11336     {
11337       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11338       vat_json_init_array (&vam->json_tree);
11339     }
11340   node = vat_json_array_add (&vam->json_tree);
11341
11342   vat_json_init_object (node);
11343   vat_json_object_add_uint (node, "id", ntohl (mp->id));
11344   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11345   vat_json_object_add_uint (node, "tap_flags", ntohl (mp->tap_flags));
11346   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
11347   vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
11348   vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
11349   vat_json_object_add_string_copy (node, "host_mac_addr",
11350                                    format (0, "%U", format_ethernet_address,
11351                                            &mp->host_mac_addr));
11352   vat_json_object_add_string_copy (node, "host_namespace",
11353                                    mp->host_namespace);
11354   vat_json_object_add_string_copy (node, "host_bridge", mp->host_bridge);
11355   vat_json_object_add_string_copy (node, "host_ip4_addr",
11356                                    format (0, "%U/%d", format_ip4_address,
11357                                            mp->host_ip4_prefix.address,
11358                                            mp->host_ip4_prefix.len));
11359   vat_json_object_add_string_copy (node, "host_ip6_prefix",
11360                                    format (0, "%U/%d", format_ip6_address,
11361                                            mp->host_ip6_prefix.address,
11362                                            mp->host_ip6_prefix.len));
11363
11364 }
11365
11366 static int
11367 api_sw_interface_tap_v2_dump (vat_main_t * vam)
11368 {
11369   vl_api_sw_interface_tap_v2_dump_t *mp;
11370   vl_api_control_ping_t *mp_ping;
11371   int ret;
11372
11373   print (vam->ofp,
11374          "\n%-16s %-12s %-5s %-12s %-12s %-14s %-30s %-20s %-20s %-30s",
11375          "dev_name", "sw_if_index", "id", "rx_ring_sz", "tx_ring_sz",
11376          "host_mac_addr", "host_namespace", "host_bridge", "host_ip4_addr",
11377          "host_ip6_addr");
11378
11379   /* Get list of tap interfaces */
11380   M (SW_INTERFACE_TAP_V2_DUMP, mp);
11381   S (mp);
11382
11383   /* Use a control ping for synchronization */
11384   MPING (CONTROL_PING, mp_ping);
11385   S (mp_ping);
11386
11387   W (ret);
11388   return ret;
11389 }
11390
11391 static void vl_api_sw_interface_virtio_pci_details_t_handler
11392   (vl_api_sw_interface_virtio_pci_details_t * mp)
11393 {
11394   vat_main_t *vam = &vat_main;
11395
11396   typedef union
11397   {
11398     struct
11399     {
11400       u16 domain;
11401       u8 bus;
11402       u8 slot:5;
11403       u8 function:3;
11404     };
11405     u32 as_u32;
11406   } pci_addr_t;
11407   pci_addr_t addr;
11408
11409   addr.domain = ntohs (mp->pci_addr.domain);
11410   addr.bus = mp->pci_addr.bus;
11411   addr.slot = mp->pci_addr.slot;
11412   addr.function = mp->pci_addr.function;
11413
11414   u8 *pci_addr = format (0, "%04x:%02x:%02x.%x", addr.domain, addr.bus,
11415                          addr.slot, addr.function);
11416
11417   print (vam->ofp,
11418          "\n%-12s %-12d %-12d %-12d %-17U 0x%-08llx",
11419          pci_addr, ntohl (mp->sw_if_index),
11420          ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
11421          format_ethernet_address, mp->mac_addr,
11422          clib_net_to_host_u64 (mp->features));
11423   vec_free (pci_addr);
11424 }
11425
11426 static void vl_api_sw_interface_virtio_pci_details_t_handler_json
11427   (vl_api_sw_interface_virtio_pci_details_t * mp)
11428 {
11429   vat_main_t *vam = &vat_main;
11430   vat_json_node_t *node = NULL;
11431   vlib_pci_addr_t pci_addr;
11432
11433   if (VAT_JSON_ARRAY != vam->json_tree.type)
11434     {
11435       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11436       vat_json_init_array (&vam->json_tree);
11437     }
11438   node = vat_json_array_add (&vam->json_tree);
11439
11440   pci_addr.domain = ntohs (mp->pci_addr.domain);
11441   pci_addr.bus = mp->pci_addr.bus;
11442   pci_addr.slot = mp->pci_addr.slot;
11443   pci_addr.function = mp->pci_addr.function;
11444
11445   vat_json_init_object (node);
11446   vat_json_object_add_uint (node, "pci-addr", pci_addr.as_u32);
11447   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11448   vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
11449   vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
11450   vat_json_object_add_uint (node, "features",
11451                             clib_net_to_host_u64 (mp->features));
11452   vat_json_object_add_string_copy (node, "mac_addr",
11453                                    format (0, "%U", format_ethernet_address,
11454                                            &mp->mac_addr));
11455 }
11456
11457 static int
11458 api_sw_interface_virtio_pci_dump (vat_main_t * vam)
11459 {
11460   vl_api_sw_interface_virtio_pci_dump_t *mp;
11461   vl_api_control_ping_t *mp_ping;
11462   int ret;
11463
11464   print (vam->ofp,
11465          "\n%-12s %-12s %-12s %-12s %-17s %-08s",
11466          "pci_addr", "sw_if_index", "rx_ring_sz", "tx_ring_sz",
11467          "mac_addr", "features");
11468
11469   /* Get list of tap interfaces */
11470   M (SW_INTERFACE_VIRTIO_PCI_DUMP, mp);
11471   S (mp);
11472
11473   /* Use a control ping for synchronization */
11474   MPING (CONTROL_PING, mp_ping);
11475   S (mp_ping);
11476
11477   W (ret);
11478   return ret;
11479 }
11480
11481 static int
11482 api_vxlan_offload_rx (vat_main_t * vam)
11483 {
11484   unformat_input_t *line_input = vam->input;
11485   vl_api_vxlan_offload_rx_t *mp;
11486   u32 hw_if_index = ~0, rx_if_index = ~0;
11487   u8 is_add = 1;
11488   int ret;
11489
11490   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11491     {
11492       if (unformat (line_input, "del"))
11493         is_add = 0;
11494       else if (unformat (line_input, "hw %U", api_unformat_hw_if_index, vam,
11495                          &hw_if_index))
11496         ;
11497       else if (unformat (line_input, "hw hw_if_index %u", &hw_if_index))
11498         ;
11499       else if (unformat (line_input, "rx %U", api_unformat_sw_if_index, vam,
11500                          &rx_if_index))
11501         ;
11502       else if (unformat (line_input, "rx sw_if_index %u", &rx_if_index))
11503         ;
11504       else
11505         {
11506           errmsg ("parse error '%U'", format_unformat_error, line_input);
11507           return -99;
11508         }
11509     }
11510
11511   if (hw_if_index == ~0)
11512     {
11513       errmsg ("no hw interface");
11514       return -99;
11515     }
11516
11517   if (rx_if_index == ~0)
11518     {
11519       errmsg ("no rx tunnel");
11520       return -99;
11521     }
11522
11523   M (VXLAN_OFFLOAD_RX, mp);
11524
11525   mp->hw_if_index = ntohl (hw_if_index);
11526   mp->sw_if_index = ntohl (rx_if_index);
11527   mp->enable = is_add;
11528
11529   S (mp);
11530   W (ret);
11531   return ret;
11532 }
11533
11534 static uword unformat_vxlan_decap_next
11535   (unformat_input_t * input, va_list * args)
11536 {
11537   u32 *result = va_arg (*args, u32 *);
11538   u32 tmp;
11539
11540   if (unformat (input, "l2"))
11541     *result = VXLAN_INPUT_NEXT_L2_INPUT;
11542   else if (unformat (input, "%d", &tmp))
11543     *result = tmp;
11544   else
11545     return 0;
11546   return 1;
11547 }
11548
11549 static int
11550 api_vxlan_add_del_tunnel (vat_main_t * vam)
11551 {
11552   unformat_input_t *line_input = vam->input;
11553   vl_api_vxlan_add_del_tunnel_t *mp;
11554   ip46_address_t src, dst;
11555   u8 is_add = 1;
11556   u8 ipv4_set = 0, ipv6_set = 0;
11557   u8 src_set = 0;
11558   u8 dst_set = 0;
11559   u8 grp_set = 0;
11560   u32 instance = ~0;
11561   u32 mcast_sw_if_index = ~0;
11562   u32 encap_vrf_id = 0;
11563   u32 decap_next_index = ~0;
11564   u32 vni = 0;
11565   int ret;
11566
11567   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
11568   clib_memset (&src, 0, sizeof src);
11569   clib_memset (&dst, 0, sizeof dst);
11570
11571   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11572     {
11573       if (unformat (line_input, "del"))
11574         is_add = 0;
11575       else if (unformat (line_input, "instance %d", &instance))
11576         ;
11577       else
11578         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
11579         {
11580           ipv4_set = 1;
11581           src_set = 1;
11582         }
11583       else
11584         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
11585         {
11586           ipv4_set = 1;
11587           dst_set = 1;
11588         }
11589       else
11590         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
11591         {
11592           ipv6_set = 1;
11593           src_set = 1;
11594         }
11595       else
11596         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
11597         {
11598           ipv6_set = 1;
11599           dst_set = 1;
11600         }
11601       else if (unformat (line_input, "group %U %U",
11602                          unformat_ip4_address, &dst.ip4,
11603                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
11604         {
11605           grp_set = dst_set = 1;
11606           ipv4_set = 1;
11607         }
11608       else if (unformat (line_input, "group %U",
11609                          unformat_ip4_address, &dst.ip4))
11610         {
11611           grp_set = dst_set = 1;
11612           ipv4_set = 1;
11613         }
11614       else if (unformat (line_input, "group %U %U",
11615                          unformat_ip6_address, &dst.ip6,
11616                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
11617         {
11618           grp_set = dst_set = 1;
11619           ipv6_set = 1;
11620         }
11621       else if (unformat (line_input, "group %U",
11622                          unformat_ip6_address, &dst.ip6))
11623         {
11624           grp_set = dst_set = 1;
11625           ipv6_set = 1;
11626         }
11627       else
11628         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
11629         ;
11630       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
11631         ;
11632       else if (unformat (line_input, "decap-next %U",
11633                          unformat_vxlan_decap_next, &decap_next_index))
11634         ;
11635       else if (unformat (line_input, "vni %d", &vni))
11636         ;
11637       else
11638         {
11639           errmsg ("parse error '%U'", format_unformat_error, line_input);
11640           return -99;
11641         }
11642     }
11643
11644   if (src_set == 0)
11645     {
11646       errmsg ("tunnel src address not specified");
11647       return -99;
11648     }
11649   if (dst_set == 0)
11650     {
11651       errmsg ("tunnel dst address not specified");
11652       return -99;
11653     }
11654
11655   if (grp_set && !ip46_address_is_multicast (&dst))
11656     {
11657       errmsg ("tunnel group address not multicast");
11658       return -99;
11659     }
11660   if (grp_set && mcast_sw_if_index == ~0)
11661     {
11662       errmsg ("tunnel nonexistent multicast device");
11663       return -99;
11664     }
11665   if (grp_set == 0 && ip46_address_is_multicast (&dst))
11666     {
11667       errmsg ("tunnel dst address must be unicast");
11668       return -99;
11669     }
11670
11671
11672   if (ipv4_set && ipv6_set)
11673     {
11674       errmsg ("both IPv4 and IPv6 addresses specified");
11675       return -99;
11676     }
11677
11678   if ((vni == 0) || (vni >> 24))
11679     {
11680       errmsg ("vni not specified or out of range");
11681       return -99;
11682     }
11683
11684   M (VXLAN_ADD_DEL_TUNNEL, mp);
11685
11686   if (ipv6_set)
11687     {
11688       clib_memcpy (mp->src_address, &src.ip6, sizeof (src.ip6));
11689       clib_memcpy (mp->dst_address, &dst.ip6, sizeof (dst.ip6));
11690     }
11691   else
11692     {
11693       clib_memcpy (mp->src_address, &src.ip4, sizeof (src.ip4));
11694       clib_memcpy (mp->dst_address, &dst.ip4, sizeof (dst.ip4));
11695     }
11696
11697   mp->instance = htonl (instance);
11698   mp->encap_vrf_id = ntohl (encap_vrf_id);
11699   mp->decap_next_index = ntohl (decap_next_index);
11700   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
11701   mp->vni = ntohl (vni);
11702   mp->is_add = is_add;
11703   mp->is_ipv6 = ipv6_set;
11704
11705   S (mp);
11706   W (ret);
11707   return ret;
11708 }
11709
11710 static void vl_api_vxlan_tunnel_details_t_handler
11711   (vl_api_vxlan_tunnel_details_t * mp)
11712 {
11713   vat_main_t *vam = &vat_main;
11714   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
11715   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
11716
11717   print (vam->ofp, "%11d%11d%24U%24U%14d%18d%13d%19d",
11718          ntohl (mp->sw_if_index),
11719          ntohl (mp->instance),
11720          format_ip46_address, &src, IP46_TYPE_ANY,
11721          format_ip46_address, &dst, IP46_TYPE_ANY,
11722          ntohl (mp->encap_vrf_id),
11723          ntohl (mp->decap_next_index), ntohl (mp->vni),
11724          ntohl (mp->mcast_sw_if_index));
11725 }
11726
11727 static void vl_api_vxlan_tunnel_details_t_handler_json
11728   (vl_api_vxlan_tunnel_details_t * mp)
11729 {
11730   vat_main_t *vam = &vat_main;
11731   vat_json_node_t *node = NULL;
11732
11733   if (VAT_JSON_ARRAY != vam->json_tree.type)
11734     {
11735       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11736       vat_json_init_array (&vam->json_tree);
11737     }
11738   node = vat_json_array_add (&vam->json_tree);
11739
11740   vat_json_init_object (node);
11741   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11742
11743   vat_json_object_add_uint (node, "instance", ntohl (mp->instance));
11744
11745   if (mp->is_ipv6)
11746     {
11747       struct in6_addr ip6;
11748
11749       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
11750       vat_json_object_add_ip6 (node, "src_address", ip6);
11751       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
11752       vat_json_object_add_ip6 (node, "dst_address", ip6);
11753     }
11754   else
11755     {
11756       struct in_addr ip4;
11757
11758       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
11759       vat_json_object_add_ip4 (node, "src_address", ip4);
11760       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
11761       vat_json_object_add_ip4 (node, "dst_address", ip4);
11762     }
11763   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
11764   vat_json_object_add_uint (node, "decap_next_index",
11765                             ntohl (mp->decap_next_index));
11766   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
11767   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
11768   vat_json_object_add_uint (node, "mcast_sw_if_index",
11769                             ntohl (mp->mcast_sw_if_index));
11770 }
11771
11772 static int
11773 api_vxlan_tunnel_dump (vat_main_t * vam)
11774 {
11775   unformat_input_t *i = vam->input;
11776   vl_api_vxlan_tunnel_dump_t *mp;
11777   vl_api_control_ping_t *mp_ping;
11778   u32 sw_if_index;
11779   u8 sw_if_index_set = 0;
11780   int ret;
11781
11782   /* Parse args required to build the message */
11783   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11784     {
11785       if (unformat (i, "sw_if_index %d", &sw_if_index))
11786         sw_if_index_set = 1;
11787       else
11788         break;
11789     }
11790
11791   if (sw_if_index_set == 0)
11792     {
11793       sw_if_index = ~0;
11794     }
11795
11796   if (!vam->json_output)
11797     {
11798       print (vam->ofp, "%11s%11s%24s%24s%14s%18s%13s%19s",
11799              "sw_if_index", "instance", "src_address", "dst_address",
11800              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
11801     }
11802
11803   /* Get list of vxlan-tunnel interfaces */
11804   M (VXLAN_TUNNEL_DUMP, mp);
11805
11806   mp->sw_if_index = htonl (sw_if_index);
11807
11808   S (mp);
11809
11810   /* Use a control ping for synchronization */
11811   MPING (CONTROL_PING, mp_ping);
11812   S (mp_ping);
11813
11814   W (ret);
11815   return ret;
11816 }
11817
11818 static uword unformat_geneve_decap_next
11819   (unformat_input_t * input, va_list * args)
11820 {
11821   u32 *result = va_arg (*args, u32 *);
11822   u32 tmp;
11823
11824   if (unformat (input, "l2"))
11825     *result = GENEVE_INPUT_NEXT_L2_INPUT;
11826   else if (unformat (input, "%d", &tmp))
11827     *result = tmp;
11828   else
11829     return 0;
11830   return 1;
11831 }
11832
11833 static int
11834 api_geneve_add_del_tunnel (vat_main_t * vam)
11835 {
11836   unformat_input_t *line_input = vam->input;
11837   vl_api_geneve_add_del_tunnel_t *mp;
11838   ip46_address_t src, dst;
11839   u8 is_add = 1;
11840   u8 ipv4_set = 0, ipv6_set = 0;
11841   u8 src_set = 0;
11842   u8 dst_set = 0;
11843   u8 grp_set = 0;
11844   u32 mcast_sw_if_index = ~0;
11845   u32 encap_vrf_id = 0;
11846   u32 decap_next_index = ~0;
11847   u32 vni = 0;
11848   int ret;
11849
11850   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
11851   clib_memset (&src, 0, sizeof src);
11852   clib_memset (&dst, 0, sizeof dst);
11853
11854   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11855     {
11856       if (unformat (line_input, "del"))
11857         is_add = 0;
11858       else
11859         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
11860         {
11861           ipv4_set = 1;
11862           src_set = 1;
11863         }
11864       else
11865         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
11866         {
11867           ipv4_set = 1;
11868           dst_set = 1;
11869         }
11870       else
11871         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
11872         {
11873           ipv6_set = 1;
11874           src_set = 1;
11875         }
11876       else
11877         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
11878         {
11879           ipv6_set = 1;
11880           dst_set = 1;
11881         }
11882       else if (unformat (line_input, "group %U %U",
11883                          unformat_ip4_address, &dst.ip4,
11884                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
11885         {
11886           grp_set = dst_set = 1;
11887           ipv4_set = 1;
11888         }
11889       else if (unformat (line_input, "group %U",
11890                          unformat_ip4_address, &dst.ip4))
11891         {
11892           grp_set = dst_set = 1;
11893           ipv4_set = 1;
11894         }
11895       else if (unformat (line_input, "group %U %U",
11896                          unformat_ip6_address, &dst.ip6,
11897                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
11898         {
11899           grp_set = dst_set = 1;
11900           ipv6_set = 1;
11901         }
11902       else if (unformat (line_input, "group %U",
11903                          unformat_ip6_address, &dst.ip6))
11904         {
11905           grp_set = dst_set = 1;
11906           ipv6_set = 1;
11907         }
11908       else
11909         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
11910         ;
11911       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
11912         ;
11913       else if (unformat (line_input, "decap-next %U",
11914                          unformat_geneve_decap_next, &decap_next_index))
11915         ;
11916       else if (unformat (line_input, "vni %d", &vni))
11917         ;
11918       else
11919         {
11920           errmsg ("parse error '%U'", format_unformat_error, line_input);
11921           return -99;
11922         }
11923     }
11924
11925   if (src_set == 0)
11926     {
11927       errmsg ("tunnel src address not specified");
11928       return -99;
11929     }
11930   if (dst_set == 0)
11931     {
11932       errmsg ("tunnel dst address not specified");
11933       return -99;
11934     }
11935
11936   if (grp_set && !ip46_address_is_multicast (&dst))
11937     {
11938       errmsg ("tunnel group address not multicast");
11939       return -99;
11940     }
11941   if (grp_set && mcast_sw_if_index == ~0)
11942     {
11943       errmsg ("tunnel nonexistent multicast device");
11944       return -99;
11945     }
11946   if (grp_set == 0 && ip46_address_is_multicast (&dst))
11947     {
11948       errmsg ("tunnel dst address must be unicast");
11949       return -99;
11950     }
11951
11952
11953   if (ipv4_set && ipv6_set)
11954     {
11955       errmsg ("both IPv4 and IPv6 addresses specified");
11956       return -99;
11957     }
11958
11959   if ((vni == 0) || (vni >> 24))
11960     {
11961       errmsg ("vni not specified or out of range");
11962       return -99;
11963     }
11964
11965   M (GENEVE_ADD_DEL_TUNNEL, mp);
11966
11967   if (ipv6_set)
11968     {
11969       clib_memcpy (&mp->local_address.un.ip6, &src.ip6, sizeof (src.ip6));
11970       clib_memcpy (&mp->remote_address.un.ip6, &dst.ip6, sizeof (dst.ip6));
11971     }
11972   else
11973     {
11974       clib_memcpy (&mp->local_address.un.ip4, &src.ip4, sizeof (src.ip4));
11975       clib_memcpy (&mp->remote_address.un.ip4, &dst.ip4, sizeof (dst.ip4));
11976     }
11977   mp->encap_vrf_id = ntohl (encap_vrf_id);
11978   mp->decap_next_index = ntohl (decap_next_index);
11979   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
11980   mp->vni = ntohl (vni);
11981   mp->is_add = is_add;
11982
11983   S (mp);
11984   W (ret);
11985   return ret;
11986 }
11987
11988 static void vl_api_geneve_tunnel_details_t_handler
11989   (vl_api_geneve_tunnel_details_t * mp)
11990 {
11991   vat_main_t *vam = &vat_main;
11992   ip46_address_t src = {.as_u64[0] = 0,.as_u64[1] = 0 };
11993   ip46_address_t dst = {.as_u64[0] = 0,.as_u64[1] = 0 };
11994
11995   if (mp->src_address.af == ADDRESS_IP6)
11996     {
11997       clib_memcpy (&src.ip6, &mp->src_address.un.ip6, sizeof (ip6_address_t));
11998       clib_memcpy (&dst.ip6, &mp->dst_address.un.ip6, sizeof (ip6_address_t));
11999     }
12000   else
12001     {
12002       clib_memcpy (&src.ip4, &mp->src_address.un.ip4, sizeof (ip4_address_t));
12003       clib_memcpy (&dst.ip4, &mp->dst_address.un.ip4, sizeof (ip4_address_t));
12004     }
12005
12006   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
12007          ntohl (mp->sw_if_index),
12008          format_ip46_address, &src, IP46_TYPE_ANY,
12009          format_ip46_address, &dst, IP46_TYPE_ANY,
12010          ntohl (mp->encap_vrf_id),
12011          ntohl (mp->decap_next_index), ntohl (mp->vni),
12012          ntohl (mp->mcast_sw_if_index));
12013 }
12014
12015 static void vl_api_geneve_tunnel_details_t_handler_json
12016   (vl_api_geneve_tunnel_details_t * mp)
12017 {
12018   vat_main_t *vam = &vat_main;
12019   vat_json_node_t *node = NULL;
12020   bool is_ipv6;
12021
12022   if (VAT_JSON_ARRAY != vam->json_tree.type)
12023     {
12024       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12025       vat_json_init_array (&vam->json_tree);
12026     }
12027   node = vat_json_array_add (&vam->json_tree);
12028
12029   vat_json_init_object (node);
12030   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12031   is_ipv6 = mp->src_address.af == ADDRESS_IP6;
12032   if (is_ipv6)
12033     {
12034       struct in6_addr ip6;
12035
12036       clib_memcpy (&ip6, &mp->src_address.un.ip6, sizeof (ip6));
12037       vat_json_object_add_ip6 (node, "src_address", ip6);
12038       clib_memcpy (&ip6, &mp->dst_address.un.ip6, sizeof (ip6));
12039       vat_json_object_add_ip6 (node, "dst_address", ip6);
12040     }
12041   else
12042     {
12043       struct in_addr ip4;
12044
12045       clib_memcpy (&ip4, &mp->src_address.un.ip4, sizeof (ip4));
12046       vat_json_object_add_ip4 (node, "src_address", ip4);
12047       clib_memcpy (&ip4, &mp->dst_address.un.ip4, sizeof (ip4));
12048       vat_json_object_add_ip4 (node, "dst_address", ip4);
12049     }
12050   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
12051   vat_json_object_add_uint (node, "decap_next_index",
12052                             ntohl (mp->decap_next_index));
12053   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
12054   vat_json_object_add_uint (node, "mcast_sw_if_index",
12055                             ntohl (mp->mcast_sw_if_index));
12056 }
12057
12058 static int
12059 api_geneve_tunnel_dump (vat_main_t * vam)
12060 {
12061   unformat_input_t *i = vam->input;
12062   vl_api_geneve_tunnel_dump_t *mp;
12063   vl_api_control_ping_t *mp_ping;
12064   u32 sw_if_index;
12065   u8 sw_if_index_set = 0;
12066   int ret;
12067
12068   /* Parse args required to build the message */
12069   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12070     {
12071       if (unformat (i, "sw_if_index %d", &sw_if_index))
12072         sw_if_index_set = 1;
12073       else
12074         break;
12075     }
12076
12077   if (sw_if_index_set == 0)
12078     {
12079       sw_if_index = ~0;
12080     }
12081
12082   if (!vam->json_output)
12083     {
12084       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
12085              "sw_if_index", "local_address", "remote_address",
12086              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
12087     }
12088
12089   /* Get list of geneve-tunnel interfaces */
12090   M (GENEVE_TUNNEL_DUMP, mp);
12091
12092   mp->sw_if_index = htonl (sw_if_index);
12093
12094   S (mp);
12095
12096   /* Use a control ping for synchronization */
12097   M (CONTROL_PING, mp_ping);
12098   S (mp_ping);
12099
12100   W (ret);
12101   return ret;
12102 }
12103
12104 static int
12105 api_gre_tunnel_add_del (vat_main_t * vam)
12106 {
12107   unformat_input_t *line_input = vam->input;
12108   vl_api_address_t src = { }, dst =
12109   {
12110   };
12111   vl_api_gre_tunnel_add_del_t *mp;
12112   vl_api_gre_tunnel_type_t t_type;
12113   u8 is_add = 1;
12114   u8 src_set = 0;
12115   u8 dst_set = 0;
12116   u32 outer_table_id = 0;
12117   u32 session_id = 0;
12118   u32 instance = ~0;
12119   int ret;
12120
12121   t_type = GRE_API_TUNNEL_TYPE_L3;
12122
12123   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12124     {
12125       if (unformat (line_input, "del"))
12126         is_add = 0;
12127       else if (unformat (line_input, "instance %d", &instance))
12128         ;
12129       else if (unformat (line_input, "src %U", unformat_vl_api_address, &src))
12130         {
12131           src_set = 1;
12132         }
12133       else if (unformat (line_input, "dst %U", unformat_vl_api_address, &dst))
12134         {
12135           dst_set = 1;
12136         }
12137       else if (unformat (line_input, "outer-table-id %d", &outer_table_id))
12138         ;
12139       else if (unformat (line_input, "teb"))
12140         t_type = GRE_API_TUNNEL_TYPE_TEB;
12141       else if (unformat (line_input, "erspan %d", &session_id))
12142         t_type = GRE_API_TUNNEL_TYPE_ERSPAN;
12143       else
12144         {
12145           errmsg ("parse error '%U'", format_unformat_error, line_input);
12146           return -99;
12147         }
12148     }
12149
12150   if (src_set == 0)
12151     {
12152       errmsg ("tunnel src address not specified");
12153       return -99;
12154     }
12155   if (dst_set == 0)
12156     {
12157       errmsg ("tunnel dst address not specified");
12158       return -99;
12159     }
12160
12161   M (GRE_TUNNEL_ADD_DEL, mp);
12162
12163   clib_memcpy (&mp->tunnel.src, &src, sizeof (mp->tunnel.src));
12164   clib_memcpy (&mp->tunnel.dst, &dst, sizeof (mp->tunnel.dst));
12165
12166   mp->tunnel.instance = htonl (instance);
12167   mp->tunnel.outer_table_id = htonl (outer_table_id);
12168   mp->is_add = is_add;
12169   mp->tunnel.session_id = htons ((u16) session_id);
12170   mp->tunnel.type = htonl (t_type);
12171
12172   S (mp);
12173   W (ret);
12174   return ret;
12175 }
12176
12177 static void vl_api_gre_tunnel_details_t_handler
12178   (vl_api_gre_tunnel_details_t * mp)
12179 {
12180   vat_main_t *vam = &vat_main;
12181
12182   print (vam->ofp, "%11d%11d%24U%24U%13d%14d%12d",
12183          ntohl (mp->tunnel.sw_if_index),
12184          ntohl (mp->tunnel.instance),
12185          format_vl_api_address, &mp->tunnel.src,
12186          format_vl_api_address, &mp->tunnel.dst,
12187          mp->tunnel.type, ntohl (mp->tunnel.outer_table_id),
12188          ntohl (mp->tunnel.session_id));
12189 }
12190
12191 static void vl_api_gre_tunnel_details_t_handler_json
12192   (vl_api_gre_tunnel_details_t * mp)
12193 {
12194   vat_main_t *vam = &vat_main;
12195   vat_json_node_t *node = NULL;
12196
12197   if (VAT_JSON_ARRAY != vam->json_tree.type)
12198     {
12199       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12200       vat_json_init_array (&vam->json_tree);
12201     }
12202   node = vat_json_array_add (&vam->json_tree);
12203
12204   vat_json_init_object (node);
12205   vat_json_object_add_uint (node, "sw_if_index",
12206                             ntohl (mp->tunnel.sw_if_index));
12207   vat_json_object_add_uint (node, "instance", ntohl (mp->tunnel.instance));
12208
12209   vat_json_object_add_address (node, "src", &mp->tunnel.src);
12210   vat_json_object_add_address (node, "dst", &mp->tunnel.dst);
12211   vat_json_object_add_uint (node, "tunnel_type", mp->tunnel.type);
12212   vat_json_object_add_uint (node, "outer_table_id",
12213                             ntohl (mp->tunnel.outer_table_id));
12214   vat_json_object_add_uint (node, "session_id", mp->tunnel.session_id);
12215 }
12216
12217 static int
12218 api_gre_tunnel_dump (vat_main_t * vam)
12219 {
12220   unformat_input_t *i = vam->input;
12221   vl_api_gre_tunnel_dump_t *mp;
12222   vl_api_control_ping_t *mp_ping;
12223   u32 sw_if_index;
12224   u8 sw_if_index_set = 0;
12225   int ret;
12226
12227   /* Parse args required to build the message */
12228   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12229     {
12230       if (unformat (i, "sw_if_index %d", &sw_if_index))
12231         sw_if_index_set = 1;
12232       else
12233         break;
12234     }
12235
12236   if (sw_if_index_set == 0)
12237     {
12238       sw_if_index = ~0;
12239     }
12240
12241   if (!vam->json_output)
12242     {
12243       print (vam->ofp, "%11s%11s%24s%24s%13s%14s%12s",
12244              "sw_if_index", "instance", "src_address", "dst_address",
12245              "tunnel_type", "outer_fib_id", "session_id");
12246     }
12247
12248   /* Get list of gre-tunnel interfaces */
12249   M (GRE_TUNNEL_DUMP, mp);
12250
12251   mp->sw_if_index = htonl (sw_if_index);
12252
12253   S (mp);
12254
12255   /* Use a control ping for synchronization */
12256   MPING (CONTROL_PING, mp_ping);
12257   S (mp_ping);
12258
12259   W (ret);
12260   return ret;
12261 }
12262
12263 static int
12264 api_l2_fib_clear_table (vat_main_t * vam)
12265 {
12266 //  unformat_input_t * i = vam->input;
12267   vl_api_l2_fib_clear_table_t *mp;
12268   int ret;
12269
12270   M (L2_FIB_CLEAR_TABLE, mp);
12271
12272   S (mp);
12273   W (ret);
12274   return ret;
12275 }
12276
12277 static int
12278 api_l2_interface_efp_filter (vat_main_t * vam)
12279 {
12280   unformat_input_t *i = vam->input;
12281   vl_api_l2_interface_efp_filter_t *mp;
12282   u32 sw_if_index;
12283   u8 enable = 1;
12284   u8 sw_if_index_set = 0;
12285   int ret;
12286
12287   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12288     {
12289       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12290         sw_if_index_set = 1;
12291       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12292         sw_if_index_set = 1;
12293       else if (unformat (i, "enable"))
12294         enable = 1;
12295       else if (unformat (i, "disable"))
12296         enable = 0;
12297       else
12298         {
12299           clib_warning ("parse error '%U'", format_unformat_error, i);
12300           return -99;
12301         }
12302     }
12303
12304   if (sw_if_index_set == 0)
12305     {
12306       errmsg ("missing sw_if_index");
12307       return -99;
12308     }
12309
12310   M (L2_INTERFACE_EFP_FILTER, mp);
12311
12312   mp->sw_if_index = ntohl (sw_if_index);
12313   mp->enable_disable = enable;
12314
12315   S (mp);
12316   W (ret);
12317   return ret;
12318 }
12319
12320 #define foreach_vtr_op                          \
12321 _("disable",  L2_VTR_DISABLED)                  \
12322 _("push-1",  L2_VTR_PUSH_1)                     \
12323 _("push-2",  L2_VTR_PUSH_2)                     \
12324 _("pop-1",  L2_VTR_POP_1)                       \
12325 _("pop-2",  L2_VTR_POP_2)                       \
12326 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
12327 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
12328 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
12329 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
12330
12331 static int
12332 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
12333 {
12334   unformat_input_t *i = vam->input;
12335   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
12336   u32 sw_if_index;
12337   u8 sw_if_index_set = 0;
12338   u8 vtr_op_set = 0;
12339   u32 vtr_op = 0;
12340   u32 push_dot1q = 1;
12341   u32 tag1 = ~0;
12342   u32 tag2 = ~0;
12343   int ret;
12344
12345   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12346     {
12347       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12348         sw_if_index_set = 1;
12349       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12350         sw_if_index_set = 1;
12351       else if (unformat (i, "vtr_op %d", &vtr_op))
12352         vtr_op_set = 1;
12353 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
12354       foreach_vtr_op
12355 #undef _
12356         else if (unformat (i, "push_dot1q %d", &push_dot1q))
12357         ;
12358       else if (unformat (i, "tag1 %d", &tag1))
12359         ;
12360       else if (unformat (i, "tag2 %d", &tag2))
12361         ;
12362       else
12363         {
12364           clib_warning ("parse error '%U'", format_unformat_error, i);
12365           return -99;
12366         }
12367     }
12368
12369   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
12370     {
12371       errmsg ("missing vtr operation or sw_if_index");
12372       return -99;
12373     }
12374
12375   M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
12376   mp->sw_if_index = ntohl (sw_if_index);
12377   mp->vtr_op = ntohl (vtr_op);
12378   mp->push_dot1q = ntohl (push_dot1q);
12379   mp->tag1 = ntohl (tag1);
12380   mp->tag2 = ntohl (tag2);
12381
12382   S (mp);
12383   W (ret);
12384   return ret;
12385 }
12386
12387 static int
12388 api_create_vhost_user_if (vat_main_t * vam)
12389 {
12390   unformat_input_t *i = vam->input;
12391   vl_api_create_vhost_user_if_t *mp;
12392   u8 *file_name;
12393   u8 is_server = 0;
12394   u8 file_name_set = 0;
12395   u32 custom_dev_instance = ~0;
12396   u8 hwaddr[6];
12397   u8 use_custom_mac = 0;
12398   u8 disable_mrg_rxbuf = 0;
12399   u8 disable_indirect_desc = 0;
12400   u8 *tag = 0;
12401   u8 enable_gso = 0;
12402   int ret;
12403
12404   /* Shut up coverity */
12405   clib_memset (hwaddr, 0, sizeof (hwaddr));
12406
12407   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12408     {
12409       if (unformat (i, "socket %s", &file_name))
12410         {
12411           file_name_set = 1;
12412         }
12413       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
12414         ;
12415       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
12416         use_custom_mac = 1;
12417       else if (unformat (i, "server"))
12418         is_server = 1;
12419       else if (unformat (i, "disable_mrg_rxbuf"))
12420         disable_mrg_rxbuf = 1;
12421       else if (unformat (i, "disable_indirect_desc"))
12422         disable_indirect_desc = 1;
12423       else if (unformat (i, "gso"))
12424         enable_gso = 1;
12425       else if (unformat (i, "tag %s", &tag))
12426         ;
12427       else
12428         break;
12429     }
12430
12431   if (file_name_set == 0)
12432     {
12433       errmsg ("missing socket file name");
12434       return -99;
12435     }
12436
12437   if (vec_len (file_name) > 255)
12438     {
12439       errmsg ("socket file name too long");
12440       return -99;
12441     }
12442   vec_add1 (file_name, 0);
12443
12444   M (CREATE_VHOST_USER_IF, mp);
12445
12446   mp->is_server = is_server;
12447   mp->disable_mrg_rxbuf = disable_mrg_rxbuf;
12448   mp->disable_indirect_desc = disable_indirect_desc;
12449   mp->enable_gso = enable_gso;
12450   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
12451   vec_free (file_name);
12452   if (custom_dev_instance != ~0)
12453     {
12454       mp->renumber = 1;
12455       mp->custom_dev_instance = ntohl (custom_dev_instance);
12456     }
12457
12458   mp->use_custom_mac = use_custom_mac;
12459   clib_memcpy (mp->mac_address, hwaddr, 6);
12460   if (tag)
12461     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
12462   vec_free (tag);
12463
12464   S (mp);
12465   W (ret);
12466   return ret;
12467 }
12468
12469 static int
12470 api_modify_vhost_user_if (vat_main_t * vam)
12471 {
12472   unformat_input_t *i = vam->input;
12473   vl_api_modify_vhost_user_if_t *mp;
12474   u8 *file_name;
12475   u8 is_server = 0;
12476   u8 file_name_set = 0;
12477   u32 custom_dev_instance = ~0;
12478   u8 sw_if_index_set = 0;
12479   u32 sw_if_index = (u32) ~ 0;
12480   u8 enable_gso = 0;
12481   int ret;
12482
12483   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12484     {
12485       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12486         sw_if_index_set = 1;
12487       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12488         sw_if_index_set = 1;
12489       else if (unformat (i, "socket %s", &file_name))
12490         {
12491           file_name_set = 1;
12492         }
12493       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
12494         ;
12495       else if (unformat (i, "server"))
12496         is_server = 1;
12497       else if (unformat (i, "gso"))
12498         enable_gso = 1;
12499       else
12500         break;
12501     }
12502
12503   if (sw_if_index_set == 0)
12504     {
12505       errmsg ("missing sw_if_index or interface name");
12506       return -99;
12507     }
12508
12509   if (file_name_set == 0)
12510     {
12511       errmsg ("missing socket file name");
12512       return -99;
12513     }
12514
12515   if (vec_len (file_name) > 255)
12516     {
12517       errmsg ("socket file name too long");
12518       return -99;
12519     }
12520   vec_add1 (file_name, 0);
12521
12522   M (MODIFY_VHOST_USER_IF, mp);
12523
12524   mp->sw_if_index = ntohl (sw_if_index);
12525   mp->is_server = is_server;
12526   mp->enable_gso = enable_gso;
12527   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
12528   vec_free (file_name);
12529   if (custom_dev_instance != ~0)
12530     {
12531       mp->renumber = 1;
12532       mp->custom_dev_instance = ntohl (custom_dev_instance);
12533     }
12534
12535   S (mp);
12536   W (ret);
12537   return ret;
12538 }
12539
12540 static int
12541 api_delete_vhost_user_if (vat_main_t * vam)
12542 {
12543   unformat_input_t *i = vam->input;
12544   vl_api_delete_vhost_user_if_t *mp;
12545   u32 sw_if_index = ~0;
12546   u8 sw_if_index_set = 0;
12547   int ret;
12548
12549   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12550     {
12551       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12552         sw_if_index_set = 1;
12553       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12554         sw_if_index_set = 1;
12555       else
12556         break;
12557     }
12558
12559   if (sw_if_index_set == 0)
12560     {
12561       errmsg ("missing sw_if_index or interface name");
12562       return -99;
12563     }
12564
12565
12566   M (DELETE_VHOST_USER_IF, mp);
12567
12568   mp->sw_if_index = ntohl (sw_if_index);
12569
12570   S (mp);
12571   W (ret);
12572   return ret;
12573 }
12574
12575 static void vl_api_sw_interface_vhost_user_details_t_handler
12576   (vl_api_sw_interface_vhost_user_details_t * mp)
12577 {
12578   vat_main_t *vam = &vat_main;
12579   u64 features;
12580
12581   features =
12582     clib_net_to_host_u32 (mp->features_first_32) | ((u64)
12583                                                     clib_net_to_host_u32
12584                                                     (mp->features_last_32) <<
12585                                                     32);
12586
12587   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s",
12588          (char *) mp->interface_name,
12589          ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
12590          features, mp->is_server,
12591          ntohl (mp->num_regions), (char *) mp->sock_filename);
12592   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
12593 }
12594
12595 static void vl_api_sw_interface_vhost_user_details_t_handler_json
12596   (vl_api_sw_interface_vhost_user_details_t * mp)
12597 {
12598   vat_main_t *vam = &vat_main;
12599   vat_json_node_t *node = NULL;
12600
12601   if (VAT_JSON_ARRAY != vam->json_tree.type)
12602     {
12603       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12604       vat_json_init_array (&vam->json_tree);
12605     }
12606   node = vat_json_array_add (&vam->json_tree);
12607
12608   vat_json_init_object (node);
12609   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12610   vat_json_object_add_string_copy (node, "interface_name",
12611                                    mp->interface_name);
12612   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
12613                             ntohl (mp->virtio_net_hdr_sz));
12614   vat_json_object_add_uint (node, "features_first_32",
12615                             clib_net_to_host_u32 (mp->features_first_32));
12616   vat_json_object_add_uint (node, "features_last_32",
12617                             clib_net_to_host_u32 (mp->features_last_32));
12618   vat_json_object_add_uint (node, "is_server", mp->is_server);
12619   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
12620   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
12621   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
12622 }
12623
12624 static int
12625 api_sw_interface_vhost_user_dump (vat_main_t * vam)
12626 {
12627   vl_api_sw_interface_vhost_user_dump_t *mp;
12628   vl_api_control_ping_t *mp_ping;
12629   int ret;
12630   print (vam->ofp,
12631          "Interface name            idx hdr_sz features server regions filename");
12632
12633   /* Get list of vhost-user interfaces */
12634   M (SW_INTERFACE_VHOST_USER_DUMP, mp);
12635   S (mp);
12636
12637   /* Use a control ping for synchronization */
12638   MPING (CONTROL_PING, mp_ping);
12639   S (mp_ping);
12640
12641   W (ret);
12642   return ret;
12643 }
12644
12645 static int
12646 api_show_version (vat_main_t * vam)
12647 {
12648   vl_api_show_version_t *mp;
12649   int ret;
12650
12651   M (SHOW_VERSION, mp);
12652
12653   S (mp);
12654   W (ret);
12655   return ret;
12656 }
12657
12658
12659 static int
12660 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
12661 {
12662   unformat_input_t *line_input = vam->input;
12663   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
12664   ip4_address_t local4, remote4;
12665   ip6_address_t local6, remote6;
12666   u8 is_add = 1;
12667   u8 ipv4_set = 0, ipv6_set = 0;
12668   u8 local_set = 0;
12669   u8 remote_set = 0;
12670   u8 grp_set = 0;
12671   u32 mcast_sw_if_index = ~0;
12672   u32 encap_vrf_id = 0;
12673   u32 decap_vrf_id = 0;
12674   u8 protocol = ~0;
12675   u32 vni;
12676   u8 vni_set = 0;
12677   int ret;
12678
12679   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
12680   clib_memset (&local4, 0, sizeof local4);
12681   clib_memset (&remote4, 0, sizeof remote4);
12682   clib_memset (&local6, 0, sizeof local6);
12683   clib_memset (&remote6, 0, sizeof remote6);
12684
12685   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12686     {
12687       if (unformat (line_input, "del"))
12688         is_add = 0;
12689       else if (unformat (line_input, "local %U",
12690                          unformat_ip4_address, &local4))
12691         {
12692           local_set = 1;
12693           ipv4_set = 1;
12694         }
12695       else if (unformat (line_input, "remote %U",
12696                          unformat_ip4_address, &remote4))
12697         {
12698           remote_set = 1;
12699           ipv4_set = 1;
12700         }
12701       else if (unformat (line_input, "local %U",
12702                          unformat_ip6_address, &local6))
12703         {
12704           local_set = 1;
12705           ipv6_set = 1;
12706         }
12707       else if (unformat (line_input, "remote %U",
12708                          unformat_ip6_address, &remote6))
12709         {
12710           remote_set = 1;
12711           ipv6_set = 1;
12712         }
12713       else if (unformat (line_input, "group %U %U",
12714                          unformat_ip4_address, &remote4,
12715                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12716         {
12717           grp_set = remote_set = 1;
12718           ipv4_set = 1;
12719         }
12720       else if (unformat (line_input, "group %U",
12721                          unformat_ip4_address, &remote4))
12722         {
12723           grp_set = remote_set = 1;
12724           ipv4_set = 1;
12725         }
12726       else if (unformat (line_input, "group %U %U",
12727                          unformat_ip6_address, &remote6,
12728                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12729         {
12730           grp_set = remote_set = 1;
12731           ipv6_set = 1;
12732         }
12733       else if (unformat (line_input, "group %U",
12734                          unformat_ip6_address, &remote6))
12735         {
12736           grp_set = remote_set = 1;
12737           ipv6_set = 1;
12738         }
12739       else
12740         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
12741         ;
12742       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
12743         ;
12744       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
12745         ;
12746       else if (unformat (line_input, "vni %d", &vni))
12747         vni_set = 1;
12748       else if (unformat (line_input, "next-ip4"))
12749         protocol = 1;
12750       else if (unformat (line_input, "next-ip6"))
12751         protocol = 2;
12752       else if (unformat (line_input, "next-ethernet"))
12753         protocol = 3;
12754       else if (unformat (line_input, "next-nsh"))
12755         protocol = 4;
12756       else
12757         {
12758           errmsg ("parse error '%U'", format_unformat_error, line_input);
12759           return -99;
12760         }
12761     }
12762
12763   if (local_set == 0)
12764     {
12765       errmsg ("tunnel local address not specified");
12766       return -99;
12767     }
12768   if (remote_set == 0)
12769     {
12770       errmsg ("tunnel remote address not specified");
12771       return -99;
12772     }
12773   if (grp_set && mcast_sw_if_index == ~0)
12774     {
12775       errmsg ("tunnel nonexistent multicast device");
12776       return -99;
12777     }
12778   if (ipv4_set && ipv6_set)
12779     {
12780       errmsg ("both IPv4 and IPv6 addresses specified");
12781       return -99;
12782     }
12783
12784   if (vni_set == 0)
12785     {
12786       errmsg ("vni not specified");
12787       return -99;
12788     }
12789
12790   M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
12791
12792
12793   if (ipv6_set)
12794     {
12795       clib_memcpy (&mp->local, &local6, sizeof (local6));
12796       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
12797     }
12798   else
12799     {
12800       clib_memcpy (&mp->local, &local4, sizeof (local4));
12801       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
12802     }
12803
12804   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
12805   mp->encap_vrf_id = ntohl (encap_vrf_id);
12806   mp->decap_vrf_id = ntohl (decap_vrf_id);
12807   mp->protocol = protocol;
12808   mp->vni = ntohl (vni);
12809   mp->is_add = is_add;
12810   mp->is_ipv6 = ipv6_set;
12811
12812   S (mp);
12813   W (ret);
12814   return ret;
12815 }
12816
12817 static void vl_api_vxlan_gpe_tunnel_details_t_handler
12818   (vl_api_vxlan_gpe_tunnel_details_t * mp)
12819 {
12820   vat_main_t *vam = &vat_main;
12821   ip46_address_t local = to_ip46 (mp->is_ipv6, mp->local);
12822   ip46_address_t remote = to_ip46 (mp->is_ipv6, mp->remote);
12823
12824   print (vam->ofp, "%11d%24U%24U%13d%12d%19d%14d%14d",
12825          ntohl (mp->sw_if_index),
12826          format_ip46_address, &local, IP46_TYPE_ANY,
12827          format_ip46_address, &remote, IP46_TYPE_ANY,
12828          ntohl (mp->vni), mp->protocol,
12829          ntohl (mp->mcast_sw_if_index),
12830          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
12831 }
12832
12833
12834 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
12835   (vl_api_vxlan_gpe_tunnel_details_t * mp)
12836 {
12837   vat_main_t *vam = &vat_main;
12838   vat_json_node_t *node = NULL;
12839   struct in_addr ip4;
12840   struct in6_addr ip6;
12841
12842   if (VAT_JSON_ARRAY != vam->json_tree.type)
12843     {
12844       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12845       vat_json_init_array (&vam->json_tree);
12846     }
12847   node = vat_json_array_add (&vam->json_tree);
12848
12849   vat_json_init_object (node);
12850   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12851   if (mp->is_ipv6)
12852     {
12853       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
12854       vat_json_object_add_ip6 (node, "local", ip6);
12855       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
12856       vat_json_object_add_ip6 (node, "remote", ip6);
12857     }
12858   else
12859     {
12860       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
12861       vat_json_object_add_ip4 (node, "local", ip4);
12862       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
12863       vat_json_object_add_ip4 (node, "remote", ip4);
12864     }
12865   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
12866   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
12867   vat_json_object_add_uint (node, "mcast_sw_if_index",
12868                             ntohl (mp->mcast_sw_if_index));
12869   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
12870   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
12871   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
12872 }
12873
12874 static int
12875 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
12876 {
12877   unformat_input_t *i = vam->input;
12878   vl_api_vxlan_gpe_tunnel_dump_t *mp;
12879   vl_api_control_ping_t *mp_ping;
12880   u32 sw_if_index;
12881   u8 sw_if_index_set = 0;
12882   int ret;
12883
12884   /* Parse args required to build the message */
12885   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12886     {
12887       if (unformat (i, "sw_if_index %d", &sw_if_index))
12888         sw_if_index_set = 1;
12889       else
12890         break;
12891     }
12892
12893   if (sw_if_index_set == 0)
12894     {
12895       sw_if_index = ~0;
12896     }
12897
12898   if (!vam->json_output)
12899     {
12900       print (vam->ofp, "%11s%24s%24s%13s%15s%19s%14s%14s",
12901              "sw_if_index", "local", "remote", "vni",
12902              "protocol", "mcast_sw_if_index", "encap_vrf_id", "decap_vrf_id");
12903     }
12904
12905   /* Get list of vxlan-tunnel interfaces */
12906   M (VXLAN_GPE_TUNNEL_DUMP, mp);
12907
12908   mp->sw_if_index = htonl (sw_if_index);
12909
12910   S (mp);
12911
12912   /* Use a control ping for synchronization */
12913   MPING (CONTROL_PING, mp_ping);
12914   S (mp_ping);
12915
12916   W (ret);
12917   return ret;
12918 }
12919
12920 static void vl_api_l2_fib_table_details_t_handler
12921   (vl_api_l2_fib_table_details_t * mp)
12922 {
12923   vat_main_t *vam = &vat_main;
12924
12925   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
12926          "       %d       %d     %d",
12927          ntohl (mp->bd_id), format_ethernet_address, mp->mac,
12928          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
12929          mp->bvi_mac);
12930 }
12931
12932 static void vl_api_l2_fib_table_details_t_handler_json
12933   (vl_api_l2_fib_table_details_t * mp)
12934 {
12935   vat_main_t *vam = &vat_main;
12936   vat_json_node_t *node = NULL;
12937
12938   if (VAT_JSON_ARRAY != vam->json_tree.type)
12939     {
12940       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12941       vat_json_init_array (&vam->json_tree);
12942     }
12943   node = vat_json_array_add (&vam->json_tree);
12944
12945   vat_json_init_object (node);
12946   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
12947   vat_json_object_add_bytes (node, "mac", mp->mac, 6);
12948   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12949   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
12950   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
12951   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
12952 }
12953
12954 static int
12955 api_l2_fib_table_dump (vat_main_t * vam)
12956 {
12957   unformat_input_t *i = vam->input;
12958   vl_api_l2_fib_table_dump_t *mp;
12959   vl_api_control_ping_t *mp_ping;
12960   u32 bd_id;
12961   u8 bd_id_set = 0;
12962   int ret;
12963
12964   /* Parse args required to build the message */
12965   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12966     {
12967       if (unformat (i, "bd_id %d", &bd_id))
12968         bd_id_set = 1;
12969       else
12970         break;
12971     }
12972
12973   if (bd_id_set == 0)
12974     {
12975       errmsg ("missing bridge domain");
12976       return -99;
12977     }
12978
12979   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
12980
12981   /* Get list of l2 fib entries */
12982   M (L2_FIB_TABLE_DUMP, mp);
12983
12984   mp->bd_id = ntohl (bd_id);
12985   S (mp);
12986
12987   /* Use a control ping for synchronization */
12988   MPING (CONTROL_PING, mp_ping);
12989   S (mp_ping);
12990
12991   W (ret);
12992   return ret;
12993 }
12994
12995
12996 static int
12997 api_interface_name_renumber (vat_main_t * vam)
12998 {
12999   unformat_input_t *line_input = vam->input;
13000   vl_api_interface_name_renumber_t *mp;
13001   u32 sw_if_index = ~0;
13002   u32 new_show_dev_instance = ~0;
13003   int ret;
13004
13005   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13006     {
13007       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
13008                     &sw_if_index))
13009         ;
13010       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
13011         ;
13012       else if (unformat (line_input, "new_show_dev_instance %d",
13013                          &new_show_dev_instance))
13014         ;
13015       else
13016         break;
13017     }
13018
13019   if (sw_if_index == ~0)
13020     {
13021       errmsg ("missing interface name or sw_if_index");
13022       return -99;
13023     }
13024
13025   if (new_show_dev_instance == ~0)
13026     {
13027       errmsg ("missing new_show_dev_instance");
13028       return -99;
13029     }
13030
13031   M (INTERFACE_NAME_RENUMBER, mp);
13032
13033   mp->sw_if_index = ntohl (sw_if_index);
13034   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
13035
13036   S (mp);
13037   W (ret);
13038   return ret;
13039 }
13040
13041 static int
13042 api_want_l2_macs_events (vat_main_t * vam)
13043 {
13044   unformat_input_t *line_input = vam->input;
13045   vl_api_want_l2_macs_events_t *mp;
13046   u8 enable_disable = 1;
13047   u32 scan_delay = 0;
13048   u32 max_macs_in_event = 0;
13049   u32 learn_limit = 0;
13050   int ret;
13051
13052   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13053     {
13054       if (unformat (line_input, "learn-limit %d", &learn_limit))
13055         ;
13056       else if (unformat (line_input, "scan-delay %d", &scan_delay))
13057         ;
13058       else if (unformat (line_input, "max-entries %d", &max_macs_in_event))
13059         ;
13060       else if (unformat (line_input, "disable"))
13061         enable_disable = 0;
13062       else
13063         break;
13064     }
13065
13066   M (WANT_L2_MACS_EVENTS, mp);
13067   mp->enable_disable = enable_disable;
13068   mp->pid = htonl (getpid ());
13069   mp->learn_limit = htonl (learn_limit);
13070   mp->scan_delay = (u8) scan_delay;
13071   mp->max_macs_in_event = (u8) (max_macs_in_event / 10);
13072   S (mp);
13073   W (ret);
13074   return ret;
13075 }
13076
13077 static int
13078 api_input_acl_set_interface (vat_main_t * vam)
13079 {
13080   unformat_input_t *i = vam->input;
13081   vl_api_input_acl_set_interface_t *mp;
13082   u32 sw_if_index;
13083   int sw_if_index_set;
13084   u32 ip4_table_index = ~0;
13085   u32 ip6_table_index = ~0;
13086   u32 l2_table_index = ~0;
13087   u8 is_add = 1;
13088   int ret;
13089
13090   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13091     {
13092       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13093         sw_if_index_set = 1;
13094       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13095         sw_if_index_set = 1;
13096       else if (unformat (i, "del"))
13097         is_add = 0;
13098       else if (unformat (i, "ip4-table %d", &ip4_table_index))
13099         ;
13100       else if (unformat (i, "ip6-table %d", &ip6_table_index))
13101         ;
13102       else if (unformat (i, "l2-table %d", &l2_table_index))
13103         ;
13104       else
13105         {
13106           clib_warning ("parse error '%U'", format_unformat_error, i);
13107           return -99;
13108         }
13109     }
13110
13111   if (sw_if_index_set == 0)
13112     {
13113       errmsg ("missing interface name or sw_if_index");
13114       return -99;
13115     }
13116
13117   M (INPUT_ACL_SET_INTERFACE, mp);
13118
13119   mp->sw_if_index = ntohl (sw_if_index);
13120   mp->ip4_table_index = ntohl (ip4_table_index);
13121   mp->ip6_table_index = ntohl (ip6_table_index);
13122   mp->l2_table_index = ntohl (l2_table_index);
13123   mp->is_add = is_add;
13124
13125   S (mp);
13126   W (ret);
13127   return ret;
13128 }
13129
13130 static int
13131 api_output_acl_set_interface (vat_main_t * vam)
13132 {
13133   unformat_input_t *i = vam->input;
13134   vl_api_output_acl_set_interface_t *mp;
13135   u32 sw_if_index;
13136   int sw_if_index_set;
13137   u32 ip4_table_index = ~0;
13138   u32 ip6_table_index = ~0;
13139   u32 l2_table_index = ~0;
13140   u8 is_add = 1;
13141   int ret;
13142
13143   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13144     {
13145       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13146         sw_if_index_set = 1;
13147       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13148         sw_if_index_set = 1;
13149       else if (unformat (i, "del"))
13150         is_add = 0;
13151       else if (unformat (i, "ip4-table %d", &ip4_table_index))
13152         ;
13153       else if (unformat (i, "ip6-table %d", &ip6_table_index))
13154         ;
13155       else if (unformat (i, "l2-table %d", &l2_table_index))
13156         ;
13157       else
13158         {
13159           clib_warning ("parse error '%U'", format_unformat_error, i);
13160           return -99;
13161         }
13162     }
13163
13164   if (sw_if_index_set == 0)
13165     {
13166       errmsg ("missing interface name or sw_if_index");
13167       return -99;
13168     }
13169
13170   M (OUTPUT_ACL_SET_INTERFACE, mp);
13171
13172   mp->sw_if_index = ntohl (sw_if_index);
13173   mp->ip4_table_index = ntohl (ip4_table_index);
13174   mp->ip6_table_index = ntohl (ip6_table_index);
13175   mp->l2_table_index = ntohl (l2_table_index);
13176   mp->is_add = is_add;
13177
13178   S (mp);
13179   W (ret);
13180   return ret;
13181 }
13182
13183 static int
13184 api_ip_address_dump (vat_main_t * vam)
13185 {
13186   unformat_input_t *i = vam->input;
13187   vl_api_ip_address_dump_t *mp;
13188   vl_api_control_ping_t *mp_ping;
13189   u32 sw_if_index = ~0;
13190   u8 sw_if_index_set = 0;
13191   u8 ipv4_set = 0;
13192   u8 ipv6_set = 0;
13193   int ret;
13194
13195   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13196     {
13197       if (unformat (i, "sw_if_index %d", &sw_if_index))
13198         sw_if_index_set = 1;
13199       else
13200         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13201         sw_if_index_set = 1;
13202       else if (unformat (i, "ipv4"))
13203         ipv4_set = 1;
13204       else if (unformat (i, "ipv6"))
13205         ipv6_set = 1;
13206       else
13207         break;
13208     }
13209
13210   if (ipv4_set && ipv6_set)
13211     {
13212       errmsg ("ipv4 and ipv6 flags cannot be both set");
13213       return -99;
13214     }
13215
13216   if ((!ipv4_set) && (!ipv6_set))
13217     {
13218       errmsg ("no ipv4 nor ipv6 flag set");
13219       return -99;
13220     }
13221
13222   if (sw_if_index_set == 0)
13223     {
13224       errmsg ("missing interface name or sw_if_index");
13225       return -99;
13226     }
13227
13228   vam->current_sw_if_index = sw_if_index;
13229   vam->is_ipv6 = ipv6_set;
13230
13231   M (IP_ADDRESS_DUMP, mp);
13232   mp->sw_if_index = ntohl (sw_if_index);
13233   mp->is_ipv6 = ipv6_set;
13234   S (mp);
13235
13236   /* Use a control ping for synchronization */
13237   MPING (CONTROL_PING, mp_ping);
13238   S (mp_ping);
13239
13240   W (ret);
13241   return ret;
13242 }
13243
13244 static int
13245 api_ip_dump (vat_main_t * vam)
13246 {
13247   vl_api_ip_dump_t *mp;
13248   vl_api_control_ping_t *mp_ping;
13249   unformat_input_t *in = vam->input;
13250   int ipv4_set = 0;
13251   int ipv6_set = 0;
13252   int is_ipv6;
13253   int i;
13254   int ret;
13255
13256   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
13257     {
13258       if (unformat (in, "ipv4"))
13259         ipv4_set = 1;
13260       else if (unformat (in, "ipv6"))
13261         ipv6_set = 1;
13262       else
13263         break;
13264     }
13265
13266   if (ipv4_set && ipv6_set)
13267     {
13268       errmsg ("ipv4 and ipv6 flags cannot be both set");
13269       return -99;
13270     }
13271
13272   if ((!ipv4_set) && (!ipv6_set))
13273     {
13274       errmsg ("no ipv4 nor ipv6 flag set");
13275       return -99;
13276     }
13277
13278   is_ipv6 = ipv6_set;
13279   vam->is_ipv6 = is_ipv6;
13280
13281   /* free old data */
13282   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
13283     {
13284       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
13285     }
13286   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
13287
13288   M (IP_DUMP, mp);
13289   mp->is_ipv6 = ipv6_set;
13290   S (mp);
13291
13292   /* Use a control ping for synchronization */
13293   MPING (CONTROL_PING, mp_ping);
13294   S (mp_ping);
13295
13296   W (ret);
13297   return ret;
13298 }
13299
13300 static int
13301 api_ipsec_spd_add_del (vat_main_t * vam)
13302 {
13303   unformat_input_t *i = vam->input;
13304   vl_api_ipsec_spd_add_del_t *mp;
13305   u32 spd_id = ~0;
13306   u8 is_add = 1;
13307   int ret;
13308
13309   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13310     {
13311       if (unformat (i, "spd_id %d", &spd_id))
13312         ;
13313       else if (unformat (i, "del"))
13314         is_add = 0;
13315       else
13316         {
13317           clib_warning ("parse error '%U'", format_unformat_error, i);
13318           return -99;
13319         }
13320     }
13321   if (spd_id == ~0)
13322     {
13323       errmsg ("spd_id must be set");
13324       return -99;
13325     }
13326
13327   M (IPSEC_SPD_ADD_DEL, mp);
13328
13329   mp->spd_id = ntohl (spd_id);
13330   mp->is_add = is_add;
13331
13332   S (mp);
13333   W (ret);
13334   return ret;
13335 }
13336
13337 static int
13338 api_ipsec_interface_add_del_spd (vat_main_t * vam)
13339 {
13340   unformat_input_t *i = vam->input;
13341   vl_api_ipsec_interface_add_del_spd_t *mp;
13342   u32 sw_if_index;
13343   u8 sw_if_index_set = 0;
13344   u32 spd_id = (u32) ~ 0;
13345   u8 is_add = 1;
13346   int ret;
13347
13348   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13349     {
13350       if (unformat (i, "del"))
13351         is_add = 0;
13352       else if (unformat (i, "spd_id %d", &spd_id))
13353         ;
13354       else
13355         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13356         sw_if_index_set = 1;
13357       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13358         sw_if_index_set = 1;
13359       else
13360         {
13361           clib_warning ("parse error '%U'", format_unformat_error, i);
13362           return -99;
13363         }
13364
13365     }
13366
13367   if (spd_id == (u32) ~ 0)
13368     {
13369       errmsg ("spd_id must be set");
13370       return -99;
13371     }
13372
13373   if (sw_if_index_set == 0)
13374     {
13375       errmsg ("missing interface name or sw_if_index");
13376       return -99;
13377     }
13378
13379   M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
13380
13381   mp->spd_id = ntohl (spd_id);
13382   mp->sw_if_index = ntohl (sw_if_index);
13383   mp->is_add = is_add;
13384
13385   S (mp);
13386   W (ret);
13387   return ret;
13388 }
13389
13390 static int
13391 api_ipsec_spd_entry_add_del (vat_main_t * vam)
13392 {
13393   unformat_input_t *i = vam->input;
13394   vl_api_ipsec_spd_entry_add_del_t *mp;
13395   u8 is_add = 1, is_outbound = 0;
13396   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
13397   i32 priority = 0;
13398   u32 rport_start = 0, rport_stop = (u32) ~ 0;
13399   u32 lport_start = 0, lport_stop = (u32) ~ 0;
13400   vl_api_address_t laddr_start = { }, laddr_stop =
13401   {
13402   }, raddr_start =
13403   {
13404   }, raddr_stop =
13405   {
13406   };
13407   int ret;
13408
13409   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13410     {
13411       if (unformat (i, "del"))
13412         is_add = 0;
13413       if (unformat (i, "outbound"))
13414         is_outbound = 1;
13415       if (unformat (i, "inbound"))
13416         is_outbound = 0;
13417       else if (unformat (i, "spd_id %d", &spd_id))
13418         ;
13419       else if (unformat (i, "sa_id %d", &sa_id))
13420         ;
13421       else if (unformat (i, "priority %d", &priority))
13422         ;
13423       else if (unformat (i, "protocol %d", &protocol))
13424         ;
13425       else if (unformat (i, "lport_start %d", &lport_start))
13426         ;
13427       else if (unformat (i, "lport_stop %d", &lport_stop))
13428         ;
13429       else if (unformat (i, "rport_start %d", &rport_start))
13430         ;
13431       else if (unformat (i, "rport_stop %d", &rport_stop))
13432         ;
13433       else if (unformat (i, "laddr_start %U",
13434                          unformat_vl_api_address, &laddr_start))
13435         ;
13436       else if (unformat (i, "laddr_stop %U", unformat_vl_api_address,
13437                          &laddr_stop))
13438         ;
13439       else if (unformat (i, "raddr_start %U", unformat_vl_api_address,
13440                          &raddr_start))
13441         ;
13442       else if (unformat (i, "raddr_stop %U", unformat_vl_api_address,
13443                          &raddr_stop))
13444         ;
13445       else
13446         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
13447         {
13448           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
13449             {
13450               clib_warning ("unsupported action: 'resolve'");
13451               return -99;
13452             }
13453         }
13454       else
13455         {
13456           clib_warning ("parse error '%U'", format_unformat_error, i);
13457           return -99;
13458         }
13459
13460     }
13461
13462   M (IPSEC_SPD_ENTRY_ADD_DEL, mp);
13463
13464   mp->is_add = is_add;
13465
13466   mp->entry.spd_id = ntohl (spd_id);
13467   mp->entry.priority = ntohl (priority);
13468   mp->entry.is_outbound = is_outbound;
13469
13470   clib_memcpy (&mp->entry.remote_address_start, &raddr_start,
13471                sizeof (vl_api_address_t));
13472   clib_memcpy (&mp->entry.remote_address_stop, &raddr_stop,
13473                sizeof (vl_api_address_t));
13474   clib_memcpy (&mp->entry.local_address_start, &laddr_start,
13475                sizeof (vl_api_address_t));
13476   clib_memcpy (&mp->entry.local_address_stop, &laddr_stop,
13477                sizeof (vl_api_address_t));
13478
13479   mp->entry.protocol = (u8) protocol;
13480   mp->entry.local_port_start = ntohs ((u16) lport_start);
13481   mp->entry.local_port_stop = ntohs ((u16) lport_stop);
13482   mp->entry.remote_port_start = ntohs ((u16) rport_start);
13483   mp->entry.remote_port_stop = ntohs ((u16) rport_stop);
13484   mp->entry.policy = (u8) policy;
13485   mp->entry.sa_id = ntohl (sa_id);
13486
13487   S (mp);
13488   W (ret);
13489   return ret;
13490 }
13491
13492 static int
13493 api_ipsec_sad_entry_add_del (vat_main_t * vam)
13494 {
13495   unformat_input_t *i = vam->input;
13496   vl_api_ipsec_sad_entry_add_del_t *mp;
13497   u32 sad_id = 0, spi = 0;
13498   u8 *ck = 0, *ik = 0;
13499   u8 is_add = 1;
13500
13501   vl_api_ipsec_crypto_alg_t crypto_alg = IPSEC_API_CRYPTO_ALG_NONE;
13502   vl_api_ipsec_integ_alg_t integ_alg = IPSEC_API_INTEG_ALG_NONE;
13503   vl_api_ipsec_sad_flags_t flags = IPSEC_API_SAD_FLAG_NONE;
13504   vl_api_ipsec_proto_t protocol = IPSEC_API_PROTO_AH;
13505   vl_api_address_t tun_src, tun_dst;
13506   int ret;
13507
13508   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13509     {
13510       if (unformat (i, "del"))
13511         is_add = 0;
13512       else if (unformat (i, "sad_id %d", &sad_id))
13513         ;
13514       else if (unformat (i, "spi %d", &spi))
13515         ;
13516       else if (unformat (i, "esp"))
13517         protocol = IPSEC_API_PROTO_ESP;
13518       else
13519         if (unformat (i, "tunnel_src %U", unformat_vl_api_address, &tun_src))
13520         {
13521           flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL;
13522           if (ADDRESS_IP6 == tun_src.af)
13523             flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL_V6;
13524         }
13525       else
13526         if (unformat (i, "tunnel_dst %U", unformat_vl_api_address, &tun_dst))
13527         {
13528           flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL;
13529           if (ADDRESS_IP6 == tun_src.af)
13530             flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL_V6;
13531         }
13532       else
13533         if (unformat (i, "crypto_alg %U",
13534                       unformat_ipsec_api_crypto_alg, &crypto_alg))
13535         ;
13536       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
13537         ;
13538       else if (unformat (i, "integ_alg %U",
13539                          unformat_ipsec_api_integ_alg, &integ_alg))
13540         ;
13541       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
13542         ;
13543       else
13544         {
13545           clib_warning ("parse error '%U'", format_unformat_error, i);
13546           return -99;
13547         }
13548
13549     }
13550
13551   M (IPSEC_SAD_ENTRY_ADD_DEL, mp);
13552
13553   mp->is_add = is_add;
13554   mp->entry.sad_id = ntohl (sad_id);
13555   mp->entry.protocol = protocol;
13556   mp->entry.spi = ntohl (spi);
13557   mp->entry.flags = flags;
13558
13559   mp->entry.crypto_algorithm = crypto_alg;
13560   mp->entry.integrity_algorithm = integ_alg;
13561   mp->entry.crypto_key.length = vec_len (ck);
13562   mp->entry.integrity_key.length = vec_len (ik);
13563
13564   if (mp->entry.crypto_key.length > sizeof (mp->entry.crypto_key.data))
13565     mp->entry.crypto_key.length = sizeof (mp->entry.crypto_key.data);
13566
13567   if (mp->entry.integrity_key.length > sizeof (mp->entry.integrity_key.data))
13568     mp->entry.integrity_key.length = sizeof (mp->entry.integrity_key.data);
13569
13570   if (ck)
13571     clib_memcpy (mp->entry.crypto_key.data, ck, mp->entry.crypto_key.length);
13572   if (ik)
13573     clib_memcpy (mp->entry.integrity_key.data, ik,
13574                  mp->entry.integrity_key.length);
13575
13576   if (flags & IPSEC_API_SAD_FLAG_IS_TUNNEL)
13577     {
13578       clib_memcpy (&mp->entry.tunnel_src, &tun_src,
13579                    sizeof (mp->entry.tunnel_src));
13580       clib_memcpy (&mp->entry.tunnel_dst, &tun_dst,
13581                    sizeof (mp->entry.tunnel_dst));
13582     }
13583
13584   S (mp);
13585   W (ret);
13586   return ret;
13587 }
13588
13589 static int
13590 api_ipsec_tunnel_if_add_del (vat_main_t * vam)
13591 {
13592   unformat_input_t *i = vam->input;
13593   vl_api_ipsec_tunnel_if_add_del_t *mp;
13594   u32 local_spi = 0, remote_spi = 0;
13595   u32 crypto_alg = 0, integ_alg = 0;
13596   u8 *lck = NULL, *rck = NULL;
13597   u8 *lik = NULL, *rik = NULL;
13598   vl_api_address_t local_ip = { 0 };
13599   vl_api_address_t remote_ip = { 0 };
13600   f64 before = 0;
13601   u8 is_add = 1;
13602   u8 esn = 0;
13603   u8 anti_replay = 0;
13604   u8 renumber = 0;
13605   u32 instance = ~0;
13606   u32 count = 1, jj;
13607   int ret = -1;
13608
13609   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13610     {
13611       if (unformat (i, "del"))
13612         is_add = 0;
13613       else if (unformat (i, "esn"))
13614         esn = 1;
13615       else if (unformat (i, "anti-replay"))
13616         anti_replay = 1;
13617       else if (unformat (i, "count %d", &count))
13618         ;
13619       else if (unformat (i, "local_spi %d", &local_spi))
13620         ;
13621       else if (unformat (i, "remote_spi %d", &remote_spi))
13622         ;
13623       else
13624         if (unformat (i, "local_ip %U", unformat_vl_api_address, &local_ip))
13625         ;
13626       else
13627         if (unformat (i, "remote_ip %U", unformat_vl_api_address, &remote_ip))
13628         ;
13629       else if (unformat (i, "local_crypto_key %U", unformat_hex_string, &lck))
13630         ;
13631       else
13632         if (unformat (i, "remote_crypto_key %U", unformat_hex_string, &rck))
13633         ;
13634       else if (unformat (i, "local_integ_key %U", unformat_hex_string, &lik))
13635         ;
13636       else if (unformat (i, "remote_integ_key %U", unformat_hex_string, &rik))
13637         ;
13638       else
13639         if (unformat
13640             (i, "crypto_alg %U", unformat_ipsec_api_crypto_alg, &crypto_alg))
13641         {
13642           if (crypto_alg >= IPSEC_CRYPTO_N_ALG)
13643             {
13644               errmsg ("unsupported crypto-alg: '%U'\n",
13645                       format_ipsec_crypto_alg, crypto_alg);
13646               return -99;
13647             }
13648         }
13649       else
13650         if (unformat
13651             (i, "integ_alg %U", unformat_ipsec_api_integ_alg, &integ_alg))
13652         {
13653           if (integ_alg >= IPSEC_INTEG_N_ALG)
13654             {
13655               errmsg ("unsupported integ-alg: '%U'\n",
13656                       format_ipsec_integ_alg, integ_alg);
13657               return -99;
13658             }
13659         }
13660       else if (unformat (i, "instance %u", &instance))
13661         renumber = 1;
13662       else
13663         {
13664           errmsg ("parse error '%U'\n", format_unformat_error, i);
13665           return -99;
13666         }
13667     }
13668
13669   if (count > 1)
13670     {
13671       /* Turn on async mode */
13672       vam->async_mode = 1;
13673       vam->async_errors = 0;
13674       before = vat_time_now (vam);
13675     }
13676
13677   for (jj = 0; jj < count; jj++)
13678     {
13679       M (IPSEC_TUNNEL_IF_ADD_DEL, mp);
13680
13681       mp->is_add = is_add;
13682       mp->esn = esn;
13683       mp->anti_replay = anti_replay;
13684
13685       if (jj > 0)
13686         increment_address (&remote_ip);
13687
13688       clib_memcpy (&mp->local_ip, &local_ip, sizeof (local_ip));
13689       clib_memcpy (&mp->remote_ip, &remote_ip, sizeof (remote_ip));
13690
13691       mp->local_spi = htonl (local_spi + jj);
13692       mp->remote_spi = htonl (remote_spi + jj);
13693       mp->crypto_alg = (u8) crypto_alg;
13694
13695       mp->local_crypto_key_len = 0;
13696       if (lck)
13697         {
13698           mp->local_crypto_key_len = vec_len (lck);
13699           if (mp->local_crypto_key_len > sizeof (mp->local_crypto_key))
13700             mp->local_crypto_key_len = sizeof (mp->local_crypto_key);
13701           clib_memcpy (mp->local_crypto_key, lck, mp->local_crypto_key_len);
13702         }
13703
13704       mp->remote_crypto_key_len = 0;
13705       if (rck)
13706         {
13707           mp->remote_crypto_key_len = vec_len (rck);
13708           if (mp->remote_crypto_key_len > sizeof (mp->remote_crypto_key))
13709             mp->remote_crypto_key_len = sizeof (mp->remote_crypto_key);
13710           clib_memcpy (mp->remote_crypto_key, rck, mp->remote_crypto_key_len);
13711         }
13712
13713       mp->integ_alg = (u8) integ_alg;
13714
13715       mp->local_integ_key_len = 0;
13716       if (lik)
13717         {
13718           mp->local_integ_key_len = vec_len (lik);
13719           if (mp->local_integ_key_len > sizeof (mp->local_integ_key))
13720             mp->local_integ_key_len = sizeof (mp->local_integ_key);
13721           clib_memcpy (mp->local_integ_key, lik, mp->local_integ_key_len);
13722         }
13723
13724       mp->remote_integ_key_len = 0;
13725       if (rik)
13726         {
13727           mp->remote_integ_key_len = vec_len (rik);
13728           if (mp->remote_integ_key_len > sizeof (mp->remote_integ_key))
13729             mp->remote_integ_key_len = sizeof (mp->remote_integ_key);
13730           clib_memcpy (mp->remote_integ_key, rik, mp->remote_integ_key_len);
13731         }
13732
13733       if (renumber)
13734         {
13735           mp->renumber = renumber;
13736           mp->show_instance = ntohl (instance);
13737         }
13738       S (mp);
13739     }
13740
13741   /* When testing multiple add/del ops, use a control-ping to sync */
13742   if (count > 1)
13743     {
13744       vl_api_control_ping_t *mp_ping;
13745       f64 after;
13746       f64 timeout;
13747
13748       /* Shut off async mode */
13749       vam->async_mode = 0;
13750
13751       MPING (CONTROL_PING, mp_ping);
13752       S (mp_ping);
13753
13754       timeout = vat_time_now (vam) + 1.0;
13755       while (vat_time_now (vam) < timeout)
13756         if (vam->result_ready == 1)
13757           goto out;
13758       vam->retval = -99;
13759
13760     out:
13761       if (vam->retval == -99)
13762         errmsg ("timeout");
13763
13764       if (vam->async_errors > 0)
13765         {
13766           errmsg ("%d asynchronous errors", vam->async_errors);
13767           vam->retval = -98;
13768         }
13769       vam->async_errors = 0;
13770       after = vat_time_now (vam);
13771
13772       /* slim chance, but we might have eaten SIGTERM on the first iteration */
13773       if (jj > 0)
13774         count = jj;
13775
13776       print (vam->ofp, "%d tunnels in %.6f secs, %.2f tunnels/sec",
13777              count, after - before, count / (after - before));
13778     }
13779   else
13780     {
13781       /* Wait for a reply... */
13782       W (ret);
13783       return ret;
13784     }
13785
13786   return ret;
13787 }
13788
13789 static void
13790 vl_api_ipsec_sa_details_t_handler (vl_api_ipsec_sa_details_t * mp)
13791 {
13792   vat_main_t *vam = &vat_main;
13793
13794   print (vam->ofp, "sa_id %u sw_if_index %u spi %u proto %u crypto_alg %u "
13795          "crypto_key %U integ_alg %u integ_key %U flags %x "
13796          "tunnel_src_addr %U tunnel_dst_addr %U "
13797          "salt %u seq_outbound %lu last_seq_inbound %lu "
13798          "replay_window %lu\n",
13799          ntohl (mp->entry.sad_id),
13800          ntohl (mp->sw_if_index),
13801          ntohl (mp->entry.spi),
13802          ntohl (mp->entry.protocol),
13803          ntohl (mp->entry.crypto_algorithm),
13804          format_hex_bytes, mp->entry.crypto_key.data,
13805          mp->entry.crypto_key.length, ntohl (mp->entry.integrity_algorithm),
13806          format_hex_bytes, mp->entry.integrity_key.data,
13807          mp->entry.integrity_key.length, ntohl (mp->entry.flags),
13808          format_vl_api_address, &mp->entry.tunnel_src, format_vl_api_address,
13809          &mp->entry.tunnel_dst, ntohl (mp->salt),
13810          clib_net_to_host_u64 (mp->seq_outbound),
13811          clib_net_to_host_u64 (mp->last_seq_inbound),
13812          clib_net_to_host_u64 (mp->replay_window));
13813 }
13814
13815 #define vl_api_ipsec_sa_details_t_endian vl_noop_handler
13816 #define vl_api_ipsec_sa_details_t_print vl_noop_handler
13817
13818 static void vl_api_ipsec_sa_details_t_handler_json
13819   (vl_api_ipsec_sa_details_t * mp)
13820 {
13821   vat_main_t *vam = &vat_main;
13822   vat_json_node_t *node = NULL;
13823   vl_api_ipsec_sad_flags_t flags;
13824
13825   if (VAT_JSON_ARRAY != vam->json_tree.type)
13826     {
13827       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13828       vat_json_init_array (&vam->json_tree);
13829     }
13830   node = vat_json_array_add (&vam->json_tree);
13831
13832   vat_json_init_object (node);
13833   vat_json_object_add_uint (node, "sa_id", ntohl (mp->entry.sad_id));
13834   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13835   vat_json_object_add_uint (node, "spi", ntohl (mp->entry.spi));
13836   vat_json_object_add_uint (node, "proto", ntohl (mp->entry.protocol));
13837   vat_json_object_add_uint (node, "crypto_alg",
13838                             ntohl (mp->entry.crypto_algorithm));
13839   vat_json_object_add_uint (node, "integ_alg",
13840                             ntohl (mp->entry.integrity_algorithm));
13841   flags = ntohl (mp->entry.flags);
13842   vat_json_object_add_uint (node, "use_esn",
13843                             ! !(flags & IPSEC_API_SAD_FLAG_USE_ESN));
13844   vat_json_object_add_uint (node, "use_anti_replay",
13845                             ! !(flags & IPSEC_API_SAD_FLAG_USE_ANTI_REPLAY));
13846   vat_json_object_add_uint (node, "is_tunnel",
13847                             ! !(flags & IPSEC_API_SAD_FLAG_IS_TUNNEL));
13848   vat_json_object_add_uint (node, "is_tunnel_ip6",
13849                             ! !(flags & IPSEC_API_SAD_FLAG_IS_TUNNEL_V6));
13850   vat_json_object_add_uint (node, "udp_encap",
13851                             ! !(flags & IPSEC_API_SAD_FLAG_UDP_ENCAP));
13852   vat_json_object_add_bytes (node, "crypto_key", mp->entry.crypto_key.data,
13853                              mp->entry.crypto_key.length);
13854   vat_json_object_add_bytes (node, "integ_key", mp->entry.integrity_key.data,
13855                              mp->entry.integrity_key.length);
13856   vat_json_object_add_address (node, "src", &mp->entry.tunnel_src);
13857   vat_json_object_add_address (node, "dst", &mp->entry.tunnel_dst);
13858   vat_json_object_add_uint (node, "replay_window",
13859                             clib_net_to_host_u64 (mp->replay_window));
13860 }
13861
13862 static int
13863 api_ipsec_sa_dump (vat_main_t * vam)
13864 {
13865   unformat_input_t *i = vam->input;
13866   vl_api_ipsec_sa_dump_t *mp;
13867   vl_api_control_ping_t *mp_ping;
13868   u32 sa_id = ~0;
13869   int ret;
13870
13871   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13872     {
13873       if (unformat (i, "sa_id %d", &sa_id))
13874         ;
13875       else
13876         {
13877           clib_warning ("parse error '%U'", format_unformat_error, i);
13878           return -99;
13879         }
13880     }
13881
13882   M (IPSEC_SA_DUMP, mp);
13883
13884   mp->sa_id = ntohl (sa_id);
13885
13886   S (mp);
13887
13888   /* Use a control ping for synchronization */
13889   M (CONTROL_PING, mp_ping);
13890   S (mp_ping);
13891
13892   W (ret);
13893   return ret;
13894 }
13895
13896 static int
13897 api_ipsec_tunnel_if_set_sa (vat_main_t * vam)
13898 {
13899   unformat_input_t *i = vam->input;
13900   vl_api_ipsec_tunnel_if_set_sa_t *mp;
13901   u32 sw_if_index = ~0;
13902   u32 sa_id = ~0;
13903   u8 is_outbound = (u8) ~ 0;
13904   int ret;
13905
13906   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13907     {
13908       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13909         ;
13910       else if (unformat (i, "sa_id %d", &sa_id))
13911         ;
13912       else if (unformat (i, "outbound"))
13913         is_outbound = 1;
13914       else if (unformat (i, "inbound"))
13915         is_outbound = 0;
13916       else
13917         {
13918           clib_warning ("parse error '%U'", format_unformat_error, i);
13919           return -99;
13920         }
13921     }
13922
13923   if (sw_if_index == ~0)
13924     {
13925       errmsg ("interface must be specified");
13926       return -99;
13927     }
13928
13929   if (sa_id == ~0)
13930     {
13931       errmsg ("SA ID must be specified");
13932       return -99;
13933     }
13934
13935   M (IPSEC_TUNNEL_IF_SET_SA, mp);
13936
13937   mp->sw_if_index = htonl (sw_if_index);
13938   mp->sa_id = htonl (sa_id);
13939   mp->is_outbound = is_outbound;
13940
13941   S (mp);
13942   W (ret);
13943
13944   return ret;
13945 }
13946
13947 static int
13948 api_get_first_msg_id (vat_main_t * vam)
13949 {
13950   vl_api_get_first_msg_id_t *mp;
13951   unformat_input_t *i = vam->input;
13952   u8 *name;
13953   u8 name_set = 0;
13954   int ret;
13955
13956   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13957     {
13958       if (unformat (i, "client %s", &name))
13959         name_set = 1;
13960       else
13961         break;
13962     }
13963
13964   if (name_set == 0)
13965     {
13966       errmsg ("missing client name");
13967       return -99;
13968     }
13969   vec_add1 (name, 0);
13970
13971   if (vec_len (name) > 63)
13972     {
13973       errmsg ("client name too long");
13974       return -99;
13975     }
13976
13977   M (GET_FIRST_MSG_ID, mp);
13978   clib_memcpy (mp->name, name, vec_len (name));
13979   S (mp);
13980   W (ret);
13981   return ret;
13982 }
13983
13984 static int
13985 api_cop_interface_enable_disable (vat_main_t * vam)
13986 {
13987   unformat_input_t *line_input = vam->input;
13988   vl_api_cop_interface_enable_disable_t *mp;
13989   u32 sw_if_index = ~0;
13990   u8 enable_disable = 1;
13991   int ret;
13992
13993   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13994     {
13995       if (unformat (line_input, "disable"))
13996         enable_disable = 0;
13997       if (unformat (line_input, "enable"))
13998         enable_disable = 1;
13999       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
14000                          vam, &sw_if_index))
14001         ;
14002       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
14003         ;
14004       else
14005         break;
14006     }
14007
14008   if (sw_if_index == ~0)
14009     {
14010       errmsg ("missing interface name or sw_if_index");
14011       return -99;
14012     }
14013
14014   /* Construct the API message */
14015   M (COP_INTERFACE_ENABLE_DISABLE, mp);
14016   mp->sw_if_index = ntohl (sw_if_index);
14017   mp->enable_disable = enable_disable;
14018
14019   /* send it... */
14020   S (mp);
14021   /* Wait for the reply */
14022   W (ret);
14023   return ret;
14024 }
14025
14026 static int
14027 api_cop_whitelist_enable_disable (vat_main_t * vam)
14028 {
14029   unformat_input_t *line_input = vam->input;
14030   vl_api_cop_whitelist_enable_disable_t *mp;
14031   u32 sw_if_index = ~0;
14032   u8 ip4 = 0, ip6 = 0, default_cop = 0;
14033   u32 fib_id = 0;
14034   int ret;
14035
14036   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14037     {
14038       if (unformat (line_input, "ip4"))
14039         ip4 = 1;
14040       else if (unformat (line_input, "ip6"))
14041         ip6 = 1;
14042       else if (unformat (line_input, "default"))
14043         default_cop = 1;
14044       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
14045                          vam, &sw_if_index))
14046         ;
14047       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
14048         ;
14049       else if (unformat (line_input, "fib-id %d", &fib_id))
14050         ;
14051       else
14052         break;
14053     }
14054
14055   if (sw_if_index == ~0)
14056     {
14057       errmsg ("missing interface name or sw_if_index");
14058       return -99;
14059     }
14060
14061   /* Construct the API message */
14062   M (COP_WHITELIST_ENABLE_DISABLE, mp);
14063   mp->sw_if_index = ntohl (sw_if_index);
14064   mp->fib_id = ntohl (fib_id);
14065   mp->ip4 = ip4;
14066   mp->ip6 = ip6;
14067   mp->default_cop = default_cop;
14068
14069   /* send it... */
14070   S (mp);
14071   /* Wait for the reply */
14072   W (ret);
14073   return ret;
14074 }
14075
14076 static int
14077 api_get_node_graph (vat_main_t * vam)
14078 {
14079   vl_api_get_node_graph_t *mp;
14080   int ret;
14081
14082   M (GET_NODE_GRAPH, mp);
14083
14084   /* send it... */
14085   S (mp);
14086   /* Wait for the reply */
14087   W (ret);
14088   return ret;
14089 }
14090
14091 /* *INDENT-OFF* */
14092 /** Used for parsing LISP eids */
14093 typedef CLIB_PACKED(struct{
14094   u8 addr[16];   /**< eid address */
14095   u32 len;       /**< prefix length if IP */
14096   u8 type;      /**< type of eid */
14097 }) lisp_eid_vat_t;
14098 /* *INDENT-ON* */
14099
14100 static uword
14101 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
14102 {
14103   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
14104
14105   clib_memset (a, 0, sizeof (a[0]));
14106
14107   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
14108     {
14109       a->type = 0;              /* ipv4 type */
14110     }
14111   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
14112     {
14113       a->type = 1;              /* ipv6 type */
14114     }
14115   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
14116     {
14117       a->type = 2;              /* mac type */
14118     }
14119   else if (unformat (input, "%U", unformat_nsh_address, a->addr))
14120     {
14121       a->type = 3;              /* NSH type */
14122       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) a->addr;
14123       nsh->spi = clib_host_to_net_u32 (nsh->spi);
14124     }
14125   else
14126     {
14127       return 0;
14128     }
14129
14130   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
14131     {
14132       return 0;
14133     }
14134
14135   return 1;
14136 }
14137
14138 static int
14139 lisp_eid_size_vat (u8 type)
14140 {
14141   switch (type)
14142     {
14143     case 0:
14144       return 4;
14145     case 1:
14146       return 16;
14147     case 2:
14148       return 6;
14149     case 3:
14150       return 5;
14151     }
14152   return 0;
14153 }
14154
14155 static void
14156 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
14157 {
14158   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
14159 }
14160
14161 static int
14162 api_one_add_del_locator_set (vat_main_t * vam)
14163 {
14164   unformat_input_t *input = vam->input;
14165   vl_api_one_add_del_locator_set_t *mp;
14166   u8 is_add = 1;
14167   u8 *locator_set_name = NULL;
14168   u8 locator_set_name_set = 0;
14169   vl_api_local_locator_t locator, *locators = 0;
14170   u32 sw_if_index, priority, weight;
14171   u32 data_len = 0;
14172
14173   int ret;
14174   /* Parse args required to build the message */
14175   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14176     {
14177       if (unformat (input, "del"))
14178         {
14179           is_add = 0;
14180         }
14181       else if (unformat (input, "locator-set %s", &locator_set_name))
14182         {
14183           locator_set_name_set = 1;
14184         }
14185       else if (unformat (input, "sw_if_index %u p %u w %u",
14186                          &sw_if_index, &priority, &weight))
14187         {
14188           locator.sw_if_index = htonl (sw_if_index);
14189           locator.priority = priority;
14190           locator.weight = weight;
14191           vec_add1 (locators, locator);
14192         }
14193       else
14194         if (unformat
14195             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
14196              &sw_if_index, &priority, &weight))
14197         {
14198           locator.sw_if_index = htonl (sw_if_index);
14199           locator.priority = priority;
14200           locator.weight = weight;
14201           vec_add1 (locators, locator);
14202         }
14203       else
14204         break;
14205     }
14206
14207   if (locator_set_name_set == 0)
14208     {
14209       errmsg ("missing locator-set name");
14210       vec_free (locators);
14211       return -99;
14212     }
14213
14214   if (vec_len (locator_set_name) > 64)
14215     {
14216       errmsg ("locator-set name too long");
14217       vec_free (locator_set_name);
14218       vec_free (locators);
14219       return -99;
14220     }
14221   vec_add1 (locator_set_name, 0);
14222
14223   data_len = sizeof (vl_api_local_locator_t) * vec_len (locators);
14224
14225   /* Construct the API message */
14226   M2 (ONE_ADD_DEL_LOCATOR_SET, mp, data_len);
14227
14228   mp->is_add = is_add;
14229   clib_memcpy (mp->locator_set_name, locator_set_name,
14230                vec_len (locator_set_name));
14231   vec_free (locator_set_name);
14232
14233   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
14234   if (locators)
14235     clib_memcpy (mp->locators, locators, data_len);
14236   vec_free (locators);
14237
14238   /* send it... */
14239   S (mp);
14240
14241   /* Wait for a reply... */
14242   W (ret);
14243   return ret;
14244 }
14245
14246 #define api_lisp_add_del_locator_set api_one_add_del_locator_set
14247
14248 static int
14249 api_one_add_del_locator (vat_main_t * vam)
14250 {
14251   unformat_input_t *input = vam->input;
14252   vl_api_one_add_del_locator_t *mp;
14253   u32 tmp_if_index = ~0;
14254   u32 sw_if_index = ~0;
14255   u8 sw_if_index_set = 0;
14256   u8 sw_if_index_if_name_set = 0;
14257   u32 priority = ~0;
14258   u8 priority_set = 0;
14259   u32 weight = ~0;
14260   u8 weight_set = 0;
14261   u8 is_add = 1;
14262   u8 *locator_set_name = NULL;
14263   u8 locator_set_name_set = 0;
14264   int ret;
14265
14266   /* Parse args required to build the message */
14267   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14268     {
14269       if (unformat (input, "del"))
14270         {
14271           is_add = 0;
14272         }
14273       else if (unformat (input, "locator-set %s", &locator_set_name))
14274         {
14275           locator_set_name_set = 1;
14276         }
14277       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
14278                          &tmp_if_index))
14279         {
14280           sw_if_index_if_name_set = 1;
14281           sw_if_index = tmp_if_index;
14282         }
14283       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
14284         {
14285           sw_if_index_set = 1;
14286           sw_if_index = tmp_if_index;
14287         }
14288       else if (unformat (input, "p %d", &priority))
14289         {
14290           priority_set = 1;
14291         }
14292       else if (unformat (input, "w %d", &weight))
14293         {
14294           weight_set = 1;
14295         }
14296       else
14297         break;
14298     }
14299
14300   if (locator_set_name_set == 0)
14301     {
14302       errmsg ("missing locator-set name");
14303       return -99;
14304     }
14305
14306   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
14307     {
14308       errmsg ("missing sw_if_index");
14309       vec_free (locator_set_name);
14310       return -99;
14311     }
14312
14313   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
14314     {
14315       errmsg ("cannot use both params interface name and sw_if_index");
14316       vec_free (locator_set_name);
14317       return -99;
14318     }
14319
14320   if (priority_set == 0)
14321     {
14322       errmsg ("missing locator-set priority");
14323       vec_free (locator_set_name);
14324       return -99;
14325     }
14326
14327   if (weight_set == 0)
14328     {
14329       errmsg ("missing locator-set weight");
14330       vec_free (locator_set_name);
14331       return -99;
14332     }
14333
14334   if (vec_len (locator_set_name) > 64)
14335     {
14336       errmsg ("locator-set name too long");
14337       vec_free (locator_set_name);
14338       return -99;
14339     }
14340   vec_add1 (locator_set_name, 0);
14341
14342   /* Construct the API message */
14343   M (ONE_ADD_DEL_LOCATOR, mp);
14344
14345   mp->is_add = is_add;
14346   mp->sw_if_index = ntohl (sw_if_index);
14347   mp->priority = priority;
14348   mp->weight = weight;
14349   clib_memcpy (mp->locator_set_name, locator_set_name,
14350                vec_len (locator_set_name));
14351   vec_free (locator_set_name);
14352
14353   /* send it... */
14354   S (mp);
14355
14356   /* Wait for a reply... */
14357   W (ret);
14358   return ret;
14359 }
14360
14361 #define api_lisp_add_del_locator api_one_add_del_locator
14362
14363 uword
14364 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
14365 {
14366   u32 *key_id = va_arg (*args, u32 *);
14367   u8 *s = 0;
14368
14369   if (unformat (input, "%s", &s))
14370     {
14371       if (!strcmp ((char *) s, "sha1"))
14372         key_id[0] = HMAC_SHA_1_96;
14373       else if (!strcmp ((char *) s, "sha256"))
14374         key_id[0] = HMAC_SHA_256_128;
14375       else
14376         {
14377           clib_warning ("invalid key_id: '%s'", s);
14378           key_id[0] = HMAC_NO_KEY;
14379         }
14380     }
14381   else
14382     return 0;
14383
14384   vec_free (s);
14385   return 1;
14386 }
14387
14388 static int
14389 api_one_add_del_local_eid (vat_main_t * vam)
14390 {
14391   unformat_input_t *input = vam->input;
14392   vl_api_one_add_del_local_eid_t *mp;
14393   u8 is_add = 1;
14394   u8 eid_set = 0;
14395   lisp_eid_vat_t _eid, *eid = &_eid;
14396   u8 *locator_set_name = 0;
14397   u8 locator_set_name_set = 0;
14398   u32 vni = 0;
14399   u16 key_id = 0;
14400   u8 *key = 0;
14401   int ret;
14402
14403   /* Parse args required to build the message */
14404   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14405     {
14406       if (unformat (input, "del"))
14407         {
14408           is_add = 0;
14409         }
14410       else if (unformat (input, "vni %d", &vni))
14411         {
14412           ;
14413         }
14414       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
14415         {
14416           eid_set = 1;
14417         }
14418       else if (unformat (input, "locator-set %s", &locator_set_name))
14419         {
14420           locator_set_name_set = 1;
14421         }
14422       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
14423         ;
14424       else if (unformat (input, "secret-key %_%v%_", &key))
14425         ;
14426       else
14427         break;
14428     }
14429
14430   if (locator_set_name_set == 0)
14431     {
14432       errmsg ("missing locator-set name");
14433       return -99;
14434     }
14435
14436   if (0 == eid_set)
14437     {
14438       errmsg ("EID address not set!");
14439       vec_free (locator_set_name);
14440       return -99;
14441     }
14442
14443   if (key && (0 == key_id))
14444     {
14445       errmsg ("invalid key_id!");
14446       return -99;
14447     }
14448
14449   if (vec_len (key) > 64)
14450     {
14451       errmsg ("key too long");
14452       vec_free (key);
14453       return -99;
14454     }
14455
14456   if (vec_len (locator_set_name) > 64)
14457     {
14458       errmsg ("locator-set name too long");
14459       vec_free (locator_set_name);
14460       return -99;
14461     }
14462   vec_add1 (locator_set_name, 0);
14463
14464   /* Construct the API message */
14465   M (ONE_ADD_DEL_LOCAL_EID, mp);
14466
14467   mp->is_add = is_add;
14468   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
14469   mp->eid_type = eid->type;
14470   mp->prefix_len = eid->len;
14471   mp->vni = clib_host_to_net_u32 (vni);
14472   mp->key_id = clib_host_to_net_u16 (key_id);
14473   clib_memcpy (mp->locator_set_name, locator_set_name,
14474                vec_len (locator_set_name));
14475   clib_memcpy (mp->key, key, vec_len (key));
14476
14477   vec_free (locator_set_name);
14478   vec_free (key);
14479
14480   /* send it... */
14481   S (mp);
14482
14483   /* Wait for a reply... */
14484   W (ret);
14485   return ret;
14486 }
14487
14488 #define api_lisp_add_del_local_eid api_one_add_del_local_eid
14489
14490 static int
14491 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
14492 {
14493   u32 dp_table = 0, vni = 0;;
14494   unformat_input_t *input = vam->input;
14495   vl_api_gpe_add_del_fwd_entry_t *mp;
14496   u8 is_add = 1;
14497   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
14498   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
14499   u8 rmt_eid_set = 0, lcl_eid_set = 0;
14500   u32 action = ~0, w;
14501   ip4_address_t rmt_rloc4, lcl_rloc4;
14502   ip6_address_t rmt_rloc6, lcl_rloc6;
14503   vl_api_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
14504   int ret;
14505
14506   clib_memset (&rloc, 0, sizeof (rloc));
14507
14508   /* Parse args required to build the message */
14509   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14510     {
14511       if (unformat (input, "del"))
14512         is_add = 0;
14513       else if (unformat (input, "add"))
14514         is_add = 1;
14515       else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
14516         {
14517           rmt_eid_set = 1;
14518         }
14519       else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
14520         {
14521           lcl_eid_set = 1;
14522         }
14523       else if (unformat (input, "vrf %d", &dp_table))
14524         ;
14525       else if (unformat (input, "bd %d", &dp_table))
14526         ;
14527       else if (unformat (input, "vni %d", &vni))
14528         ;
14529       else if (unformat (input, "w %d", &w))
14530         {
14531           if (!curr_rloc)
14532             {
14533               errmsg ("No RLOC configured for setting priority/weight!");
14534               return -99;
14535             }
14536           curr_rloc->weight = w;
14537         }
14538       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
14539                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
14540         {
14541           rloc.is_ip4 = 1;
14542
14543           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
14544           rloc.weight = 0;
14545           vec_add1 (lcl_locs, rloc);
14546
14547           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
14548           vec_add1 (rmt_locs, rloc);
14549           /* weight saved in rmt loc */
14550           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
14551         }
14552       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
14553                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
14554         {
14555           rloc.is_ip4 = 0;
14556           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
14557           rloc.weight = 0;
14558           vec_add1 (lcl_locs, rloc);
14559
14560           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
14561           vec_add1 (rmt_locs, rloc);
14562           /* weight saved in rmt loc */
14563           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
14564         }
14565       else if (unformat (input, "action %d", &action))
14566         {
14567           ;
14568         }
14569       else
14570         {
14571           clib_warning ("parse error '%U'", format_unformat_error, input);
14572           return -99;
14573         }
14574     }
14575
14576   if (!rmt_eid_set)
14577     {
14578       errmsg ("remote eid addresses not set");
14579       return -99;
14580     }
14581
14582   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
14583     {
14584       errmsg ("eid types don't match");
14585       return -99;
14586     }
14587
14588   if (0 == rmt_locs && (u32) ~ 0 == action)
14589     {
14590       errmsg ("action not set for negative mapping");
14591       return -99;
14592     }
14593
14594   /* Construct the API message */
14595   M2 (GPE_ADD_DEL_FWD_ENTRY, mp,
14596       sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs) * 2);
14597
14598   mp->is_add = is_add;
14599   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
14600   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
14601   mp->eid_type = rmt_eid->type;
14602   mp->dp_table = clib_host_to_net_u32 (dp_table);
14603   mp->vni = clib_host_to_net_u32 (vni);
14604   mp->rmt_len = rmt_eid->len;
14605   mp->lcl_len = lcl_eid->len;
14606   mp->action = action;
14607
14608   if (0 != rmt_locs && 0 != lcl_locs)
14609     {
14610       mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
14611       clib_memcpy (mp->locs, lcl_locs,
14612                    (sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs)));
14613
14614       u32 offset = sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs);
14615       clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
14616                    (sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs)));
14617     }
14618   vec_free (lcl_locs);
14619   vec_free (rmt_locs);
14620
14621   /* send it... */
14622   S (mp);
14623
14624   /* Wait for a reply... */
14625   W (ret);
14626   return ret;
14627 }
14628
14629 static int
14630 api_one_add_del_map_server (vat_main_t * vam)
14631 {
14632   unformat_input_t *input = vam->input;
14633   vl_api_one_add_del_map_server_t *mp;
14634   u8 is_add = 1;
14635   u8 ipv4_set = 0;
14636   u8 ipv6_set = 0;
14637   ip4_address_t ipv4;
14638   ip6_address_t ipv6;
14639   int ret;
14640
14641   /* Parse args required to build the message */
14642   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14643     {
14644       if (unformat (input, "del"))
14645         {
14646           is_add = 0;
14647         }
14648       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
14649         {
14650           ipv4_set = 1;
14651         }
14652       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
14653         {
14654           ipv6_set = 1;
14655         }
14656       else
14657         break;
14658     }
14659
14660   if (ipv4_set && ipv6_set)
14661     {
14662       errmsg ("both eid v4 and v6 addresses set");
14663       return -99;
14664     }
14665
14666   if (!ipv4_set && !ipv6_set)
14667     {
14668       errmsg ("eid addresses not set");
14669       return -99;
14670     }
14671
14672   /* Construct the API message */
14673   M (ONE_ADD_DEL_MAP_SERVER, mp);
14674
14675   mp->is_add = is_add;
14676   if (ipv6_set)
14677     {
14678       mp->is_ipv6 = 1;
14679       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
14680     }
14681   else
14682     {
14683       mp->is_ipv6 = 0;
14684       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
14685     }
14686
14687   /* send it... */
14688   S (mp);
14689
14690   /* Wait for a reply... */
14691   W (ret);
14692   return ret;
14693 }
14694
14695 #define api_lisp_add_del_map_server api_one_add_del_map_server
14696
14697 static int
14698 api_one_add_del_map_resolver (vat_main_t * vam)
14699 {
14700   unformat_input_t *input = vam->input;
14701   vl_api_one_add_del_map_resolver_t *mp;
14702   u8 is_add = 1;
14703   u8 ipv4_set = 0;
14704   u8 ipv6_set = 0;
14705   ip4_address_t ipv4;
14706   ip6_address_t ipv6;
14707   int ret;
14708
14709   /* Parse args required to build the message */
14710   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14711     {
14712       if (unformat (input, "del"))
14713         {
14714           is_add = 0;
14715         }
14716       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
14717         {
14718           ipv4_set = 1;
14719         }
14720       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
14721         {
14722           ipv6_set = 1;
14723         }
14724       else
14725         break;
14726     }
14727
14728   if (ipv4_set && ipv6_set)
14729     {
14730       errmsg ("both eid v4 and v6 addresses set");
14731       return -99;
14732     }
14733
14734   if (!ipv4_set && !ipv6_set)
14735     {
14736       errmsg ("eid addresses not set");
14737       return -99;
14738     }
14739
14740   /* Construct the API message */
14741   M (ONE_ADD_DEL_MAP_RESOLVER, mp);
14742
14743   mp->is_add = is_add;
14744   if (ipv6_set)
14745     {
14746       mp->is_ipv6 = 1;
14747       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
14748     }
14749   else
14750     {
14751       mp->is_ipv6 = 0;
14752       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
14753     }
14754
14755   /* send it... */
14756   S (mp);
14757
14758   /* Wait for a reply... */
14759   W (ret);
14760   return ret;
14761 }
14762
14763 #define api_lisp_add_del_map_resolver api_one_add_del_map_resolver
14764
14765 static int
14766 api_lisp_gpe_enable_disable (vat_main_t * vam)
14767 {
14768   unformat_input_t *input = vam->input;
14769   vl_api_gpe_enable_disable_t *mp;
14770   u8 is_set = 0;
14771   u8 is_en = 1;
14772   int ret;
14773
14774   /* Parse args required to build the message */
14775   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14776     {
14777       if (unformat (input, "enable"))
14778         {
14779           is_set = 1;
14780           is_en = 1;
14781         }
14782       else if (unformat (input, "disable"))
14783         {
14784           is_set = 1;
14785           is_en = 0;
14786         }
14787       else
14788         break;
14789     }
14790
14791   if (is_set == 0)
14792     {
14793       errmsg ("Value not set");
14794       return -99;
14795     }
14796
14797   /* Construct the API message */
14798   M (GPE_ENABLE_DISABLE, mp);
14799
14800   mp->is_en = is_en;
14801
14802   /* send it... */
14803   S (mp);
14804
14805   /* Wait for a reply... */
14806   W (ret);
14807   return ret;
14808 }
14809
14810 static int
14811 api_one_rloc_probe_enable_disable (vat_main_t * vam)
14812 {
14813   unformat_input_t *input = vam->input;
14814   vl_api_one_rloc_probe_enable_disable_t *mp;
14815   u8 is_set = 0;
14816   u8 is_en = 0;
14817   int ret;
14818
14819   /* Parse args required to build the message */
14820   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14821     {
14822       if (unformat (input, "enable"))
14823         {
14824           is_set = 1;
14825           is_en = 1;
14826         }
14827       else if (unformat (input, "disable"))
14828         is_set = 1;
14829       else
14830         break;
14831     }
14832
14833   if (!is_set)
14834     {
14835       errmsg ("Value not set");
14836       return -99;
14837     }
14838
14839   /* Construct the API message */
14840   M (ONE_RLOC_PROBE_ENABLE_DISABLE, mp);
14841
14842   mp->is_enabled = is_en;
14843
14844   /* send it... */
14845   S (mp);
14846
14847   /* Wait for a reply... */
14848   W (ret);
14849   return ret;
14850 }
14851
14852 #define api_lisp_rloc_probe_enable_disable api_one_rloc_probe_enable_disable
14853
14854 static int
14855 api_one_map_register_enable_disable (vat_main_t * vam)
14856 {
14857   unformat_input_t *input = vam->input;
14858   vl_api_one_map_register_enable_disable_t *mp;
14859   u8 is_set = 0;
14860   u8 is_en = 0;
14861   int ret;
14862
14863   /* Parse args required to build the message */
14864   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14865     {
14866       if (unformat (input, "enable"))
14867         {
14868           is_set = 1;
14869           is_en = 1;
14870         }
14871       else if (unformat (input, "disable"))
14872         is_set = 1;
14873       else
14874         break;
14875     }
14876
14877   if (!is_set)
14878     {
14879       errmsg ("Value not set");
14880       return -99;
14881     }
14882
14883   /* Construct the API message */
14884   M (ONE_MAP_REGISTER_ENABLE_DISABLE, mp);
14885
14886   mp->is_enabled = is_en;
14887
14888   /* send it... */
14889   S (mp);
14890
14891   /* Wait for a reply... */
14892   W (ret);
14893   return ret;
14894 }
14895
14896 #define api_lisp_map_register_enable_disable api_one_map_register_enable_disable
14897
14898 static int
14899 api_one_enable_disable (vat_main_t * vam)
14900 {
14901   unformat_input_t *input = vam->input;
14902   vl_api_one_enable_disable_t *mp;
14903   u8 is_set = 0;
14904   u8 is_en = 0;
14905   int ret;
14906
14907   /* Parse args required to build the message */
14908   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14909     {
14910       if (unformat (input, "enable"))
14911         {
14912           is_set = 1;
14913           is_en = 1;
14914         }
14915       else if (unformat (input, "disable"))
14916         {
14917           is_set = 1;
14918         }
14919       else
14920         break;
14921     }
14922
14923   if (!is_set)
14924     {
14925       errmsg ("Value not set");
14926       return -99;
14927     }
14928
14929   /* Construct the API message */
14930   M (ONE_ENABLE_DISABLE, mp);
14931
14932   mp->is_en = is_en;
14933
14934   /* send it... */
14935   S (mp);
14936
14937   /* Wait for a reply... */
14938   W (ret);
14939   return ret;
14940 }
14941
14942 #define api_lisp_enable_disable api_one_enable_disable
14943
14944 static int
14945 api_one_enable_disable_xtr_mode (vat_main_t * vam)
14946 {
14947   unformat_input_t *input = vam->input;
14948   vl_api_one_enable_disable_xtr_mode_t *mp;
14949   u8 is_set = 0;
14950   u8 is_en = 0;
14951   int ret;
14952
14953   /* Parse args required to build the message */
14954   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14955     {
14956       if (unformat (input, "enable"))
14957         {
14958           is_set = 1;
14959           is_en = 1;
14960         }
14961       else if (unformat (input, "disable"))
14962         {
14963           is_set = 1;
14964         }
14965       else
14966         break;
14967     }
14968
14969   if (!is_set)
14970     {
14971       errmsg ("Value not set");
14972       return -99;
14973     }
14974
14975   /* Construct the API message */
14976   M (ONE_ENABLE_DISABLE_XTR_MODE, mp);
14977
14978   mp->is_en = is_en;
14979
14980   /* send it... */
14981   S (mp);
14982
14983   /* Wait for a reply... */
14984   W (ret);
14985   return ret;
14986 }
14987
14988 static int
14989 api_one_show_xtr_mode (vat_main_t * vam)
14990 {
14991   vl_api_one_show_xtr_mode_t *mp;
14992   int ret;
14993
14994   /* Construct the API message */
14995   M (ONE_SHOW_XTR_MODE, mp);
14996
14997   /* send it... */
14998   S (mp);
14999
15000   /* Wait for a reply... */
15001   W (ret);
15002   return ret;
15003 }
15004
15005 static int
15006 api_one_enable_disable_pitr_mode (vat_main_t * vam)
15007 {
15008   unformat_input_t *input = vam->input;
15009   vl_api_one_enable_disable_pitr_mode_t *mp;
15010   u8 is_set = 0;
15011   u8 is_en = 0;
15012   int ret;
15013
15014   /* Parse args required to build the message */
15015   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15016     {
15017       if (unformat (input, "enable"))
15018         {
15019           is_set = 1;
15020           is_en = 1;
15021         }
15022       else if (unformat (input, "disable"))
15023         {
15024           is_set = 1;
15025         }
15026       else
15027         break;
15028     }
15029
15030   if (!is_set)
15031     {
15032       errmsg ("Value not set");
15033       return -99;
15034     }
15035
15036   /* Construct the API message */
15037   M (ONE_ENABLE_DISABLE_PITR_MODE, mp);
15038
15039   mp->is_en = is_en;
15040
15041   /* send it... */
15042   S (mp);
15043
15044   /* Wait for a reply... */
15045   W (ret);
15046   return ret;
15047 }
15048
15049 static int
15050 api_one_show_pitr_mode (vat_main_t * vam)
15051 {
15052   vl_api_one_show_pitr_mode_t *mp;
15053   int ret;
15054
15055   /* Construct the API message */
15056   M (ONE_SHOW_PITR_MODE, mp);
15057
15058   /* send it... */
15059   S (mp);
15060
15061   /* Wait for a reply... */
15062   W (ret);
15063   return ret;
15064 }
15065
15066 static int
15067 api_one_enable_disable_petr_mode (vat_main_t * vam)
15068 {
15069   unformat_input_t *input = vam->input;
15070   vl_api_one_enable_disable_petr_mode_t *mp;
15071   u8 is_set = 0;
15072   u8 is_en = 0;
15073   int ret;
15074
15075   /* Parse args required to build the message */
15076   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15077     {
15078       if (unformat (input, "enable"))
15079         {
15080           is_set = 1;
15081           is_en = 1;
15082         }
15083       else if (unformat (input, "disable"))
15084         {
15085           is_set = 1;
15086         }
15087       else
15088         break;
15089     }
15090
15091   if (!is_set)
15092     {
15093       errmsg ("Value not set");
15094       return -99;
15095     }
15096
15097   /* Construct the API message */
15098   M (ONE_ENABLE_DISABLE_PETR_MODE, mp);
15099
15100   mp->is_en = is_en;
15101
15102   /* send it... */
15103   S (mp);
15104
15105   /* Wait for a reply... */
15106   W (ret);
15107   return ret;
15108 }
15109
15110 static int
15111 api_one_show_petr_mode (vat_main_t * vam)
15112 {
15113   vl_api_one_show_petr_mode_t *mp;
15114   int ret;
15115
15116   /* Construct the API message */
15117   M (ONE_SHOW_PETR_MODE, mp);
15118
15119   /* send it... */
15120   S (mp);
15121
15122   /* Wait for a reply... */
15123   W (ret);
15124   return ret;
15125 }
15126
15127 static int
15128 api_show_one_map_register_state (vat_main_t * vam)
15129 {
15130   vl_api_show_one_map_register_state_t *mp;
15131   int ret;
15132
15133   M (SHOW_ONE_MAP_REGISTER_STATE, mp);
15134
15135   /* send */
15136   S (mp);
15137
15138   /* wait for reply */
15139   W (ret);
15140   return ret;
15141 }
15142
15143 #define api_show_lisp_map_register_state api_show_one_map_register_state
15144
15145 static int
15146 api_show_one_rloc_probe_state (vat_main_t * vam)
15147 {
15148   vl_api_show_one_rloc_probe_state_t *mp;
15149   int ret;
15150
15151   M (SHOW_ONE_RLOC_PROBE_STATE, mp);
15152
15153   /* send */
15154   S (mp);
15155
15156   /* wait for reply */
15157   W (ret);
15158   return ret;
15159 }
15160
15161 #define api_show_lisp_rloc_probe_state api_show_one_rloc_probe_state
15162
15163 static int
15164 api_one_add_del_ndp_entry (vat_main_t * vam)
15165 {
15166   vl_api_one_add_del_ndp_entry_t *mp;
15167   unformat_input_t *input = vam->input;
15168   u8 is_add = 1;
15169   u8 mac_set = 0;
15170   u8 bd_set = 0;
15171   u8 ip_set = 0;
15172   u8 mac[6] = { 0, };
15173   u8 ip6[16] = { 0, };
15174   u32 bd = ~0;
15175   int ret;
15176
15177   /* Parse args required to build the message */
15178   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15179     {
15180       if (unformat (input, "del"))
15181         is_add = 0;
15182       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
15183         mac_set = 1;
15184       else if (unformat (input, "ip %U", unformat_ip6_address, ip6))
15185         ip_set = 1;
15186       else if (unformat (input, "bd %d", &bd))
15187         bd_set = 1;
15188       else
15189         {
15190           errmsg ("parse error '%U'", format_unformat_error, input);
15191           return -99;
15192         }
15193     }
15194
15195   if (!bd_set || !ip_set || (!mac_set && is_add))
15196     {
15197       errmsg ("Missing BD, IP or MAC!");
15198       return -99;
15199     }
15200
15201   M (ONE_ADD_DEL_NDP_ENTRY, mp);
15202   mp->is_add = is_add;
15203   clib_memcpy (mp->mac, mac, 6);
15204   mp->bd = clib_host_to_net_u32 (bd);
15205   clib_memcpy (mp->ip6, ip6, sizeof (mp->ip6));
15206
15207   /* send */
15208   S (mp);
15209
15210   /* wait for reply */
15211   W (ret);
15212   return ret;
15213 }
15214
15215 static int
15216 api_one_add_del_l2_arp_entry (vat_main_t * vam)
15217 {
15218   vl_api_one_add_del_l2_arp_entry_t *mp;
15219   unformat_input_t *input = vam->input;
15220   u8 is_add = 1;
15221   u8 mac_set = 0;
15222   u8 bd_set = 0;
15223   u8 ip_set = 0;
15224   u8 mac[6] = { 0, };
15225   u32 ip4 = 0, bd = ~0;
15226   int ret;
15227
15228   /* Parse args required to build the message */
15229   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15230     {
15231       if (unformat (input, "del"))
15232         is_add = 0;
15233       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
15234         mac_set = 1;
15235       else if (unformat (input, "ip %U", unformat_ip4_address, &ip4))
15236         ip_set = 1;
15237       else if (unformat (input, "bd %d", &bd))
15238         bd_set = 1;
15239       else
15240         {
15241           errmsg ("parse error '%U'", format_unformat_error, input);
15242           return -99;
15243         }
15244     }
15245
15246   if (!bd_set || !ip_set || (!mac_set && is_add))
15247     {
15248       errmsg ("Missing BD, IP or MAC!");
15249       return -99;
15250     }
15251
15252   M (ONE_ADD_DEL_L2_ARP_ENTRY, mp);
15253   mp->is_add = is_add;
15254   clib_memcpy (mp->mac, mac, 6);
15255   mp->bd = clib_host_to_net_u32 (bd);
15256   mp->ip4 = ip4;
15257
15258   /* send */
15259   S (mp);
15260
15261   /* wait for reply */
15262   W (ret);
15263   return ret;
15264 }
15265
15266 static int
15267 api_one_ndp_bd_get (vat_main_t * vam)
15268 {
15269   vl_api_one_ndp_bd_get_t *mp;
15270   int ret;
15271
15272   M (ONE_NDP_BD_GET, mp);
15273
15274   /* send */
15275   S (mp);
15276
15277   /* wait for reply */
15278   W (ret);
15279   return ret;
15280 }
15281
15282 static int
15283 api_one_ndp_entries_get (vat_main_t * vam)
15284 {
15285   vl_api_one_ndp_entries_get_t *mp;
15286   unformat_input_t *input = vam->input;
15287   u8 bd_set = 0;
15288   u32 bd = ~0;
15289   int ret;
15290
15291   /* Parse args required to build the message */
15292   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15293     {
15294       if (unformat (input, "bd %d", &bd))
15295         bd_set = 1;
15296       else
15297         {
15298           errmsg ("parse error '%U'", format_unformat_error, input);
15299           return -99;
15300         }
15301     }
15302
15303   if (!bd_set)
15304     {
15305       errmsg ("Expected bridge domain!");
15306       return -99;
15307     }
15308
15309   M (ONE_NDP_ENTRIES_GET, mp);
15310   mp->bd = clib_host_to_net_u32 (bd);
15311
15312   /* send */
15313   S (mp);
15314
15315   /* wait for reply */
15316   W (ret);
15317   return ret;
15318 }
15319
15320 static int
15321 api_one_l2_arp_bd_get (vat_main_t * vam)
15322 {
15323   vl_api_one_l2_arp_bd_get_t *mp;
15324   int ret;
15325
15326   M (ONE_L2_ARP_BD_GET, mp);
15327
15328   /* send */
15329   S (mp);
15330
15331   /* wait for reply */
15332   W (ret);
15333   return ret;
15334 }
15335
15336 static int
15337 api_one_l2_arp_entries_get (vat_main_t * vam)
15338 {
15339   vl_api_one_l2_arp_entries_get_t *mp;
15340   unformat_input_t *input = vam->input;
15341   u8 bd_set = 0;
15342   u32 bd = ~0;
15343   int ret;
15344
15345   /* Parse args required to build the message */
15346   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15347     {
15348       if (unformat (input, "bd %d", &bd))
15349         bd_set = 1;
15350       else
15351         {
15352           errmsg ("parse error '%U'", format_unformat_error, input);
15353           return -99;
15354         }
15355     }
15356
15357   if (!bd_set)
15358     {
15359       errmsg ("Expected bridge domain!");
15360       return -99;
15361     }
15362
15363   M (ONE_L2_ARP_ENTRIES_GET, mp);
15364   mp->bd = clib_host_to_net_u32 (bd);
15365
15366   /* send */
15367   S (mp);
15368
15369   /* wait for reply */
15370   W (ret);
15371   return ret;
15372 }
15373
15374 static int
15375 api_one_stats_enable_disable (vat_main_t * vam)
15376 {
15377   vl_api_one_stats_enable_disable_t *mp;
15378   unformat_input_t *input = vam->input;
15379   u8 is_set = 0;
15380   u8 is_en = 0;
15381   int ret;
15382
15383   /* Parse args required to build the message */
15384   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15385     {
15386       if (unformat (input, "enable"))
15387         {
15388           is_set = 1;
15389           is_en = 1;
15390         }
15391       else if (unformat (input, "disable"))
15392         {
15393           is_set = 1;
15394         }
15395       else
15396         break;
15397     }
15398
15399   if (!is_set)
15400     {
15401       errmsg ("Value not set");
15402       return -99;
15403     }
15404
15405   M (ONE_STATS_ENABLE_DISABLE, mp);
15406   mp->is_en = is_en;
15407
15408   /* send */
15409   S (mp);
15410
15411   /* wait for reply */
15412   W (ret);
15413   return ret;
15414 }
15415
15416 static int
15417 api_show_one_stats_enable_disable (vat_main_t * vam)
15418 {
15419   vl_api_show_one_stats_enable_disable_t *mp;
15420   int ret;
15421
15422   M (SHOW_ONE_STATS_ENABLE_DISABLE, mp);
15423
15424   /* send */
15425   S (mp);
15426
15427   /* wait for reply */
15428   W (ret);
15429   return ret;
15430 }
15431
15432 static int
15433 api_show_one_map_request_mode (vat_main_t * vam)
15434 {
15435   vl_api_show_one_map_request_mode_t *mp;
15436   int ret;
15437
15438   M (SHOW_ONE_MAP_REQUEST_MODE, mp);
15439
15440   /* send */
15441   S (mp);
15442
15443   /* wait for reply */
15444   W (ret);
15445   return ret;
15446 }
15447
15448 #define api_show_lisp_map_request_mode api_show_one_map_request_mode
15449
15450 static int
15451 api_one_map_request_mode (vat_main_t * vam)
15452 {
15453   unformat_input_t *input = vam->input;
15454   vl_api_one_map_request_mode_t *mp;
15455   u8 mode = 0;
15456   int ret;
15457
15458   /* Parse args required to build the message */
15459   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15460     {
15461       if (unformat (input, "dst-only"))
15462         mode = 0;
15463       else if (unformat (input, "src-dst"))
15464         mode = 1;
15465       else
15466         {
15467           errmsg ("parse error '%U'", format_unformat_error, input);
15468           return -99;
15469         }
15470     }
15471
15472   M (ONE_MAP_REQUEST_MODE, mp);
15473
15474   mp->mode = mode;
15475
15476   /* send */
15477   S (mp);
15478
15479   /* wait for reply */
15480   W (ret);
15481   return ret;
15482 }
15483
15484 #define api_lisp_map_request_mode api_one_map_request_mode
15485
15486 /**
15487  * Enable/disable ONE proxy ITR.
15488  *
15489  * @param vam vpp API test context
15490  * @return return code
15491  */
15492 static int
15493 api_one_pitr_set_locator_set (vat_main_t * vam)
15494 {
15495   u8 ls_name_set = 0;
15496   unformat_input_t *input = vam->input;
15497   vl_api_one_pitr_set_locator_set_t *mp;
15498   u8 is_add = 1;
15499   u8 *ls_name = 0;
15500   int ret;
15501
15502   /* Parse args required to build the message */
15503   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15504     {
15505       if (unformat (input, "del"))
15506         is_add = 0;
15507       else if (unformat (input, "locator-set %s", &ls_name))
15508         ls_name_set = 1;
15509       else
15510         {
15511           errmsg ("parse error '%U'", format_unformat_error, input);
15512           return -99;
15513         }
15514     }
15515
15516   if (!ls_name_set)
15517     {
15518       errmsg ("locator-set name not set!");
15519       return -99;
15520     }
15521
15522   M (ONE_PITR_SET_LOCATOR_SET, mp);
15523
15524   mp->is_add = is_add;
15525   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
15526   vec_free (ls_name);
15527
15528   /* send */
15529   S (mp);
15530
15531   /* wait for reply */
15532   W (ret);
15533   return ret;
15534 }
15535
15536 #define api_lisp_pitr_set_locator_set api_one_pitr_set_locator_set
15537
15538 static int
15539 api_one_nsh_set_locator_set (vat_main_t * vam)
15540 {
15541   u8 ls_name_set = 0;
15542   unformat_input_t *input = vam->input;
15543   vl_api_one_nsh_set_locator_set_t *mp;
15544   u8 is_add = 1;
15545   u8 *ls_name = 0;
15546   int ret;
15547
15548   /* Parse args required to build the message */
15549   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15550     {
15551       if (unformat (input, "del"))
15552         is_add = 0;
15553       else if (unformat (input, "ls %s", &ls_name))
15554         ls_name_set = 1;
15555       else
15556         {
15557           errmsg ("parse error '%U'", format_unformat_error, input);
15558           return -99;
15559         }
15560     }
15561
15562   if (!ls_name_set && is_add)
15563     {
15564       errmsg ("locator-set name not set!");
15565       return -99;
15566     }
15567
15568   M (ONE_NSH_SET_LOCATOR_SET, mp);
15569
15570   mp->is_add = is_add;
15571   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
15572   vec_free (ls_name);
15573
15574   /* send */
15575   S (mp);
15576
15577   /* wait for reply */
15578   W (ret);
15579   return ret;
15580 }
15581
15582 static int
15583 api_show_one_pitr (vat_main_t * vam)
15584 {
15585   vl_api_show_one_pitr_t *mp;
15586   int ret;
15587
15588   if (!vam->json_output)
15589     {
15590       print (vam->ofp, "%=20s", "lisp status:");
15591     }
15592
15593   M (SHOW_ONE_PITR, mp);
15594   /* send it... */
15595   S (mp);
15596
15597   /* Wait for a reply... */
15598   W (ret);
15599   return ret;
15600 }
15601
15602 #define api_show_lisp_pitr api_show_one_pitr
15603
15604 static int
15605 api_one_use_petr (vat_main_t * vam)
15606 {
15607   unformat_input_t *input = vam->input;
15608   vl_api_one_use_petr_t *mp;
15609   u8 is_add = 0;
15610   ip_address_t ip;
15611   int ret;
15612
15613   clib_memset (&ip, 0, sizeof (ip));
15614
15615   /* Parse args required to build the message */
15616   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15617     {
15618       if (unformat (input, "disable"))
15619         is_add = 0;
15620       else
15621         if (unformat (input, "%U", unformat_ip4_address, &ip_addr_v4 (&ip)))
15622         {
15623           is_add = 1;
15624           ip_addr_version (&ip) = AF_IP4;
15625         }
15626       else
15627         if (unformat (input, "%U", unformat_ip6_address, &ip_addr_v6 (&ip)))
15628         {
15629           is_add = 1;
15630           ip_addr_version (&ip) = AF_IP6;
15631         }
15632       else
15633         {
15634           errmsg ("parse error '%U'", format_unformat_error, input);
15635           return -99;
15636         }
15637     }
15638
15639   M (ONE_USE_PETR, mp);
15640
15641   mp->is_add = is_add;
15642   if (is_add)
15643     {
15644       mp->is_ip4 = ip_addr_version (&ip) == AF_IP4 ? 1 : 0;
15645       if (mp->is_ip4)
15646         clib_memcpy (mp->address, &ip, 4);
15647       else
15648         clib_memcpy (mp->address, &ip, 16);
15649     }
15650
15651   /* send */
15652   S (mp);
15653
15654   /* wait for reply */
15655   W (ret);
15656   return ret;
15657 }
15658
15659 #define api_lisp_use_petr api_one_use_petr
15660
15661 static int
15662 api_show_one_nsh_mapping (vat_main_t * vam)
15663 {
15664   vl_api_show_one_use_petr_t *mp;
15665   int ret;
15666
15667   if (!vam->json_output)
15668     {
15669       print (vam->ofp, "%=20s", "local ONE NSH mapping:");
15670     }
15671
15672   M (SHOW_ONE_NSH_MAPPING, mp);
15673   /* send it... */
15674   S (mp);
15675
15676   /* Wait for a reply... */
15677   W (ret);
15678   return ret;
15679 }
15680
15681 static int
15682 api_show_one_use_petr (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", "Proxy-ETR status:");
15690     }
15691
15692   M (SHOW_ONE_USE_PETR, mp);
15693   /* send it... */
15694   S (mp);
15695
15696   /* Wait for a reply... */
15697   W (ret);
15698   return ret;
15699 }
15700
15701 #define api_show_lisp_use_petr api_show_one_use_petr
15702
15703 /**
15704  * Add/delete mapping between vni and vrf
15705  */
15706 static int
15707 api_one_eid_table_add_del_map (vat_main_t * vam)
15708 {
15709   unformat_input_t *input = vam->input;
15710   vl_api_one_eid_table_add_del_map_t *mp;
15711   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
15712   u32 vni, vrf, bd_index;
15713   int ret;
15714
15715   /* Parse args required to build the message */
15716   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15717     {
15718       if (unformat (input, "del"))
15719         is_add = 0;
15720       else if (unformat (input, "vrf %d", &vrf))
15721         vrf_set = 1;
15722       else if (unformat (input, "bd_index %d", &bd_index))
15723         bd_index_set = 1;
15724       else if (unformat (input, "vni %d", &vni))
15725         vni_set = 1;
15726       else
15727         break;
15728     }
15729
15730   if (!vni_set || (!vrf_set && !bd_index_set))
15731     {
15732       errmsg ("missing arguments!");
15733       return -99;
15734     }
15735
15736   if (vrf_set && bd_index_set)
15737     {
15738       errmsg ("error: both vrf and bd entered!");
15739       return -99;
15740     }
15741
15742   M (ONE_EID_TABLE_ADD_DEL_MAP, mp);
15743
15744   mp->is_add = is_add;
15745   mp->vni = htonl (vni);
15746   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
15747   mp->is_l2 = bd_index_set;
15748
15749   /* send */
15750   S (mp);
15751
15752   /* wait for reply */
15753   W (ret);
15754   return ret;
15755 }
15756
15757 #define api_lisp_eid_table_add_del_map api_one_eid_table_add_del_map
15758
15759 uword
15760 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
15761 {
15762   u32 *action = va_arg (*args, u32 *);
15763   u8 *s = 0;
15764
15765   if (unformat (input, "%s", &s))
15766     {
15767       if (!strcmp ((char *) s, "no-action"))
15768         action[0] = 0;
15769       else if (!strcmp ((char *) s, "natively-forward"))
15770         action[0] = 1;
15771       else if (!strcmp ((char *) s, "send-map-request"))
15772         action[0] = 2;
15773       else if (!strcmp ((char *) s, "drop"))
15774         action[0] = 3;
15775       else
15776         {
15777           clib_warning ("invalid action: '%s'", s);
15778           action[0] = 3;
15779         }
15780     }
15781   else
15782     return 0;
15783
15784   vec_free (s);
15785   return 1;
15786 }
15787
15788 /**
15789  * Add/del remote mapping to/from ONE control plane
15790  *
15791  * @param vam vpp API test context
15792  * @return return code
15793  */
15794 static int
15795 api_one_add_del_remote_mapping (vat_main_t * vam)
15796 {
15797   unformat_input_t *input = vam->input;
15798   vl_api_one_add_del_remote_mapping_t *mp;
15799   u32 vni = 0;
15800   lisp_eid_vat_t _eid, *eid = &_eid;
15801   lisp_eid_vat_t _seid, *seid = &_seid;
15802   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
15803   u32 action = ~0, p, w, data_len;
15804   ip4_address_t rloc4;
15805   ip6_address_t rloc6;
15806   vl_api_remote_locator_t *rlocs = 0, rloc, *curr_rloc = 0;
15807   int ret;
15808
15809   clib_memset (&rloc, 0, sizeof (rloc));
15810
15811   /* Parse args required to build the message */
15812   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15813     {
15814       if (unformat (input, "del-all"))
15815         {
15816           del_all = 1;
15817         }
15818       else if (unformat (input, "del"))
15819         {
15820           is_add = 0;
15821         }
15822       else if (unformat (input, "add"))
15823         {
15824           is_add = 1;
15825         }
15826       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
15827         {
15828           eid_set = 1;
15829         }
15830       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
15831         {
15832           seid_set = 1;
15833         }
15834       else if (unformat (input, "vni %d", &vni))
15835         {
15836           ;
15837         }
15838       else if (unformat (input, "p %d w %d", &p, &w))
15839         {
15840           if (!curr_rloc)
15841             {
15842               errmsg ("No RLOC configured for setting priority/weight!");
15843               return -99;
15844             }
15845           curr_rloc->priority = p;
15846           curr_rloc->weight = w;
15847         }
15848       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
15849         {
15850           rloc.is_ip4 = 1;
15851           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
15852           vec_add1 (rlocs, rloc);
15853           curr_rloc = &rlocs[vec_len (rlocs) - 1];
15854         }
15855       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
15856         {
15857           rloc.is_ip4 = 0;
15858           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
15859           vec_add1 (rlocs, rloc);
15860           curr_rloc = &rlocs[vec_len (rlocs) - 1];
15861         }
15862       else if (unformat (input, "action %U",
15863                          unformat_negative_mapping_action, &action))
15864         {
15865           ;
15866         }
15867       else
15868         {
15869           clib_warning ("parse error '%U'", format_unformat_error, input);
15870           return -99;
15871         }
15872     }
15873
15874   if (0 == eid_set)
15875     {
15876       errmsg ("missing params!");
15877       return -99;
15878     }
15879
15880   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
15881     {
15882       errmsg ("no action set for negative map-reply!");
15883       return -99;
15884     }
15885
15886   data_len = vec_len (rlocs) * sizeof (vl_api_remote_locator_t);
15887
15888   M2 (ONE_ADD_DEL_REMOTE_MAPPING, mp, data_len);
15889   mp->is_add = is_add;
15890   mp->vni = htonl (vni);
15891   mp->action = (u8) action;
15892   mp->is_src_dst = seid_set;
15893   mp->eid_len = eid->len;
15894   mp->seid_len = seid->len;
15895   mp->del_all = del_all;
15896   mp->eid_type = eid->type;
15897   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
15898   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
15899
15900   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
15901   clib_memcpy (mp->rlocs, rlocs, data_len);
15902   vec_free (rlocs);
15903
15904   /* send it... */
15905   S (mp);
15906
15907   /* Wait for a reply... */
15908   W (ret);
15909   return ret;
15910 }
15911
15912 #define api_lisp_add_del_remote_mapping api_one_add_del_remote_mapping
15913
15914 /**
15915  * Add/del ONE adjacency. Saves mapping in ONE control plane and updates
15916  * forwarding entries in data-plane accordingly.
15917  *
15918  * @param vam vpp API test context
15919  * @return return code
15920  */
15921 static int
15922 api_one_add_del_adjacency (vat_main_t * vam)
15923 {
15924   unformat_input_t *input = vam->input;
15925   vl_api_one_add_del_adjacency_t *mp;
15926   u32 vni = 0;
15927   ip4_address_t leid4, reid4;
15928   ip6_address_t leid6, reid6;
15929   u8 reid_mac[6] = { 0 };
15930   u8 leid_mac[6] = { 0 };
15931   u8 reid_type, leid_type;
15932   u32 leid_len = 0, reid_len = 0, len;
15933   u8 is_add = 1;
15934   int ret;
15935
15936   leid_type = reid_type = (u8) ~ 0;
15937
15938   /* Parse args required to build the message */
15939   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15940     {
15941       if (unformat (input, "del"))
15942         {
15943           is_add = 0;
15944         }
15945       else if (unformat (input, "add"))
15946         {
15947           is_add = 1;
15948         }
15949       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
15950                          &reid4, &len))
15951         {
15952           reid_type = 0;        /* ipv4 */
15953           reid_len = len;
15954         }
15955       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
15956                          &reid6, &len))
15957         {
15958           reid_type = 1;        /* ipv6 */
15959           reid_len = len;
15960         }
15961       else if (unformat (input, "reid %U", unformat_ethernet_address,
15962                          reid_mac))
15963         {
15964           reid_type = 2;        /* mac */
15965         }
15966       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
15967                          &leid4, &len))
15968         {
15969           leid_type = 0;        /* ipv4 */
15970           leid_len = len;
15971         }
15972       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
15973                          &leid6, &len))
15974         {
15975           leid_type = 1;        /* ipv6 */
15976           leid_len = len;
15977         }
15978       else if (unformat (input, "leid %U", unformat_ethernet_address,
15979                          leid_mac))
15980         {
15981           leid_type = 2;        /* mac */
15982         }
15983       else if (unformat (input, "vni %d", &vni))
15984         {
15985           ;
15986         }
15987       else
15988         {
15989           errmsg ("parse error '%U'", format_unformat_error, input);
15990           return -99;
15991         }
15992     }
15993
15994   if ((u8) ~ 0 == reid_type)
15995     {
15996       errmsg ("missing params!");
15997       return -99;
15998     }
15999
16000   if (leid_type != reid_type)
16001     {
16002       errmsg ("remote and local EIDs are of different types!");
16003       return -99;
16004     }
16005
16006   M (ONE_ADD_DEL_ADJACENCY, mp);
16007   mp->is_add = is_add;
16008   mp->vni = htonl (vni);
16009   mp->leid_len = leid_len;
16010   mp->reid_len = reid_len;
16011   mp->eid_type = reid_type;
16012
16013   switch (mp->eid_type)
16014     {
16015     case 0:
16016       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
16017       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
16018       break;
16019     case 1:
16020       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
16021       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
16022       break;
16023     case 2:
16024       clib_memcpy (mp->leid, leid_mac, 6);
16025       clib_memcpy (mp->reid, reid_mac, 6);
16026       break;
16027     default:
16028       errmsg ("unknown EID type %d!", mp->eid_type);
16029       return 0;
16030     }
16031
16032   /* send it... */
16033   S (mp);
16034
16035   /* Wait for a reply... */
16036   W (ret);
16037   return ret;
16038 }
16039
16040 #define api_lisp_add_del_adjacency api_one_add_del_adjacency
16041
16042 uword
16043 unformat_gpe_encap_mode (unformat_input_t * input, va_list * args)
16044 {
16045   u32 *mode = va_arg (*args, u32 *);
16046
16047   if (unformat (input, "lisp"))
16048     *mode = 0;
16049   else if (unformat (input, "vxlan"))
16050     *mode = 1;
16051   else
16052     return 0;
16053
16054   return 1;
16055 }
16056
16057 static int
16058 api_gpe_get_encap_mode (vat_main_t * vam)
16059 {
16060   vl_api_gpe_get_encap_mode_t *mp;
16061   int ret;
16062
16063   /* Construct the API message */
16064   M (GPE_GET_ENCAP_MODE, mp);
16065
16066   /* send it... */
16067   S (mp);
16068
16069   /* Wait for a reply... */
16070   W (ret);
16071   return ret;
16072 }
16073
16074 static int
16075 api_gpe_set_encap_mode (vat_main_t * vam)
16076 {
16077   unformat_input_t *input = vam->input;
16078   vl_api_gpe_set_encap_mode_t *mp;
16079   int ret;
16080   u32 mode = 0;
16081
16082   /* Parse args required to build the message */
16083   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16084     {
16085       if (unformat (input, "%U", unformat_gpe_encap_mode, &mode))
16086         ;
16087       else
16088         break;
16089     }
16090
16091   /* Construct the API message */
16092   M (GPE_SET_ENCAP_MODE, mp);
16093
16094   mp->mode = mode;
16095
16096   /* send it... */
16097   S (mp);
16098
16099   /* Wait for a reply... */
16100   W (ret);
16101   return ret;
16102 }
16103
16104 static int
16105 api_lisp_gpe_add_del_iface (vat_main_t * vam)
16106 {
16107   unformat_input_t *input = vam->input;
16108   vl_api_gpe_add_del_iface_t *mp;
16109   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
16110   u32 dp_table = 0, vni = 0;
16111   int ret;
16112
16113   /* Parse args required to build the message */
16114   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16115     {
16116       if (unformat (input, "up"))
16117         {
16118           action_set = 1;
16119           is_add = 1;
16120         }
16121       else if (unformat (input, "down"))
16122         {
16123           action_set = 1;
16124           is_add = 0;
16125         }
16126       else if (unformat (input, "table_id %d", &dp_table))
16127         {
16128           dp_table_set = 1;
16129         }
16130       else if (unformat (input, "bd_id %d", &dp_table))
16131         {
16132           dp_table_set = 1;
16133           is_l2 = 1;
16134         }
16135       else if (unformat (input, "vni %d", &vni))
16136         {
16137           vni_set = 1;
16138         }
16139       else
16140         break;
16141     }
16142
16143   if (action_set == 0)
16144     {
16145       errmsg ("Action not set");
16146       return -99;
16147     }
16148   if (dp_table_set == 0 || vni_set == 0)
16149     {
16150       errmsg ("vni and dp_table must be set");
16151       return -99;
16152     }
16153
16154   /* Construct the API message */
16155   M (GPE_ADD_DEL_IFACE, mp);
16156
16157   mp->is_add = is_add;
16158   mp->dp_table = clib_host_to_net_u32 (dp_table);
16159   mp->is_l2 = is_l2;
16160   mp->vni = clib_host_to_net_u32 (vni);
16161
16162   /* send it... */
16163   S (mp);
16164
16165   /* Wait for a reply... */
16166   W (ret);
16167   return ret;
16168 }
16169
16170 static int
16171 api_one_map_register_fallback_threshold (vat_main_t * vam)
16172 {
16173   unformat_input_t *input = vam->input;
16174   vl_api_one_map_register_fallback_threshold_t *mp;
16175   u32 value = 0;
16176   u8 is_set = 0;
16177   int ret;
16178
16179   /* Parse args required to build the message */
16180   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16181     {
16182       if (unformat (input, "%u", &value))
16183         is_set = 1;
16184       else
16185         {
16186           clib_warning ("parse error '%U'", format_unformat_error, input);
16187           return -99;
16188         }
16189     }
16190
16191   if (!is_set)
16192     {
16193       errmsg ("fallback threshold value is missing!");
16194       return -99;
16195     }
16196
16197   M (ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
16198   mp->value = clib_host_to_net_u32 (value);
16199
16200   /* send it... */
16201   S (mp);
16202
16203   /* Wait for a reply... */
16204   W (ret);
16205   return ret;
16206 }
16207
16208 static int
16209 api_show_one_map_register_fallback_threshold (vat_main_t * vam)
16210 {
16211   vl_api_show_one_map_register_fallback_threshold_t *mp;
16212   int ret;
16213
16214   M (SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
16215
16216   /* send it... */
16217   S (mp);
16218
16219   /* Wait for a reply... */
16220   W (ret);
16221   return ret;
16222 }
16223
16224 uword
16225 unformat_lisp_transport_protocol (unformat_input_t * input, va_list * args)
16226 {
16227   u32 *proto = va_arg (*args, u32 *);
16228
16229   if (unformat (input, "udp"))
16230     *proto = 1;
16231   else if (unformat (input, "api"))
16232     *proto = 2;
16233   else
16234     return 0;
16235
16236   return 1;
16237 }
16238
16239 static int
16240 api_one_set_transport_protocol (vat_main_t * vam)
16241 {
16242   unformat_input_t *input = vam->input;
16243   vl_api_one_set_transport_protocol_t *mp;
16244   u8 is_set = 0;
16245   u32 protocol = 0;
16246   int ret;
16247
16248   /* Parse args required to build the message */
16249   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16250     {
16251       if (unformat (input, "%U", unformat_lisp_transport_protocol, &protocol))
16252         is_set = 1;
16253       else
16254         {
16255           clib_warning ("parse error '%U'", format_unformat_error, input);
16256           return -99;
16257         }
16258     }
16259
16260   if (!is_set)
16261     {
16262       errmsg ("Transport protocol missing!");
16263       return -99;
16264     }
16265
16266   M (ONE_SET_TRANSPORT_PROTOCOL, mp);
16267   mp->protocol = (u8) protocol;
16268
16269   /* send it... */
16270   S (mp);
16271
16272   /* Wait for a reply... */
16273   W (ret);
16274   return ret;
16275 }
16276
16277 static int
16278 api_one_get_transport_protocol (vat_main_t * vam)
16279 {
16280   vl_api_one_get_transport_protocol_t *mp;
16281   int ret;
16282
16283   M (ONE_GET_TRANSPORT_PROTOCOL, mp);
16284
16285   /* send it... */
16286   S (mp);
16287
16288   /* Wait for a reply... */
16289   W (ret);
16290   return ret;
16291 }
16292
16293 static int
16294 api_one_map_register_set_ttl (vat_main_t * vam)
16295 {
16296   unformat_input_t *input = vam->input;
16297   vl_api_one_map_register_set_ttl_t *mp;
16298   u32 ttl = 0;
16299   u8 is_set = 0;
16300   int ret;
16301
16302   /* Parse args required to build the message */
16303   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16304     {
16305       if (unformat (input, "%u", &ttl))
16306         is_set = 1;
16307       else
16308         {
16309           clib_warning ("parse error '%U'", format_unformat_error, input);
16310           return -99;
16311         }
16312     }
16313
16314   if (!is_set)
16315     {
16316       errmsg ("TTL value missing!");
16317       return -99;
16318     }
16319
16320   M (ONE_MAP_REGISTER_SET_TTL, mp);
16321   mp->ttl = clib_host_to_net_u32 (ttl);
16322
16323   /* send it... */
16324   S (mp);
16325
16326   /* Wait for a reply... */
16327   W (ret);
16328   return ret;
16329 }
16330
16331 static int
16332 api_show_one_map_register_ttl (vat_main_t * vam)
16333 {
16334   vl_api_show_one_map_register_ttl_t *mp;
16335   int ret;
16336
16337   M (SHOW_ONE_MAP_REGISTER_TTL, mp);
16338
16339   /* send it... */
16340   S (mp);
16341
16342   /* Wait for a reply... */
16343   W (ret);
16344   return ret;
16345 }
16346
16347 /**
16348  * Add/del map request itr rlocs from ONE control plane and updates
16349  *
16350  * @param vam vpp API test context
16351  * @return return code
16352  */
16353 static int
16354 api_one_add_del_map_request_itr_rlocs (vat_main_t * vam)
16355 {
16356   unformat_input_t *input = vam->input;
16357   vl_api_one_add_del_map_request_itr_rlocs_t *mp;
16358   u8 *locator_set_name = 0;
16359   u8 locator_set_name_set = 0;
16360   u8 is_add = 1;
16361   int ret;
16362
16363   /* Parse args required to build the message */
16364   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16365     {
16366       if (unformat (input, "del"))
16367         {
16368           is_add = 0;
16369         }
16370       else if (unformat (input, "%_%v%_", &locator_set_name))
16371         {
16372           locator_set_name_set = 1;
16373         }
16374       else
16375         {
16376           clib_warning ("parse error '%U'", format_unformat_error, input);
16377           return -99;
16378         }
16379     }
16380
16381   if (is_add && !locator_set_name_set)
16382     {
16383       errmsg ("itr-rloc is not set!");
16384       return -99;
16385     }
16386
16387   if (is_add && vec_len (locator_set_name) > 64)
16388     {
16389       errmsg ("itr-rloc locator-set name too long");
16390       vec_free (locator_set_name);
16391       return -99;
16392     }
16393
16394   M (ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS, mp);
16395   mp->is_add = is_add;
16396   if (is_add)
16397     {
16398       clib_memcpy (mp->locator_set_name, locator_set_name,
16399                    vec_len (locator_set_name));
16400     }
16401   else
16402     {
16403       clib_memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
16404     }
16405   vec_free (locator_set_name);
16406
16407   /* send it... */
16408   S (mp);
16409
16410   /* Wait for a reply... */
16411   W (ret);
16412   return ret;
16413 }
16414
16415 #define api_lisp_add_del_map_request_itr_rlocs api_one_add_del_map_request_itr_rlocs
16416
16417 static int
16418 api_one_locator_dump (vat_main_t * vam)
16419 {
16420   unformat_input_t *input = vam->input;
16421   vl_api_one_locator_dump_t *mp;
16422   vl_api_control_ping_t *mp_ping;
16423   u8 is_index_set = 0, is_name_set = 0;
16424   u8 *ls_name = 0;
16425   u32 ls_index = ~0;
16426   int ret;
16427
16428   /* Parse args required to build the message */
16429   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16430     {
16431       if (unformat (input, "ls_name %_%v%_", &ls_name))
16432         {
16433           is_name_set = 1;
16434         }
16435       else if (unformat (input, "ls_index %d", &ls_index))
16436         {
16437           is_index_set = 1;
16438         }
16439       else
16440         {
16441           errmsg ("parse error '%U'", format_unformat_error, input);
16442           return -99;
16443         }
16444     }
16445
16446   if (!is_index_set && !is_name_set)
16447     {
16448       errmsg ("error: expected one of index or name!");
16449       return -99;
16450     }
16451
16452   if (is_index_set && is_name_set)
16453     {
16454       errmsg ("error: only one param expected!");
16455       return -99;
16456     }
16457
16458   if (vec_len (ls_name) > 62)
16459     {
16460       errmsg ("error: locator set name too long!");
16461       return -99;
16462     }
16463
16464   if (!vam->json_output)
16465     {
16466       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
16467     }
16468
16469   M (ONE_LOCATOR_DUMP, mp);
16470   mp->is_index_set = is_index_set;
16471
16472   if (is_index_set)
16473     mp->ls_index = clib_host_to_net_u32 (ls_index);
16474   else
16475     {
16476       vec_add1 (ls_name, 0);
16477       strncpy ((char *) mp->ls_name, (char *) ls_name,
16478                sizeof (mp->ls_name) - 1);
16479     }
16480
16481   /* send it... */
16482   S (mp);
16483
16484   /* Use a control ping for synchronization */
16485   MPING (CONTROL_PING, mp_ping);
16486   S (mp_ping);
16487
16488   /* Wait for a reply... */
16489   W (ret);
16490   return ret;
16491 }
16492
16493 #define api_lisp_locator_dump api_one_locator_dump
16494
16495 static int
16496 api_one_locator_set_dump (vat_main_t * vam)
16497 {
16498   vl_api_one_locator_set_dump_t *mp;
16499   vl_api_control_ping_t *mp_ping;
16500   unformat_input_t *input = vam->input;
16501   u8 filter = 0;
16502   int ret;
16503
16504   /* Parse args required to build the message */
16505   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16506     {
16507       if (unformat (input, "local"))
16508         {
16509           filter = 1;
16510         }
16511       else if (unformat (input, "remote"))
16512         {
16513           filter = 2;
16514         }
16515       else
16516         {
16517           errmsg ("parse error '%U'", format_unformat_error, input);
16518           return -99;
16519         }
16520     }
16521
16522   if (!vam->json_output)
16523     {
16524       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
16525     }
16526
16527   M (ONE_LOCATOR_SET_DUMP, mp);
16528
16529   mp->filter = filter;
16530
16531   /* send it... */
16532   S (mp);
16533
16534   /* Use a control ping for synchronization */
16535   MPING (CONTROL_PING, mp_ping);
16536   S (mp_ping);
16537
16538   /* Wait for a reply... */
16539   W (ret);
16540   return ret;
16541 }
16542
16543 #define api_lisp_locator_set_dump api_one_locator_set_dump
16544
16545 static int
16546 api_one_eid_table_map_dump (vat_main_t * vam)
16547 {
16548   u8 is_l2 = 0;
16549   u8 mode_set = 0;
16550   unformat_input_t *input = vam->input;
16551   vl_api_one_eid_table_map_dump_t *mp;
16552   vl_api_control_ping_t *mp_ping;
16553   int ret;
16554
16555   /* Parse args required to build the message */
16556   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16557     {
16558       if (unformat (input, "l2"))
16559         {
16560           is_l2 = 1;
16561           mode_set = 1;
16562         }
16563       else if (unformat (input, "l3"))
16564         {
16565           is_l2 = 0;
16566           mode_set = 1;
16567         }
16568       else
16569         {
16570           errmsg ("parse error '%U'", format_unformat_error, input);
16571           return -99;
16572         }
16573     }
16574
16575   if (!mode_set)
16576     {
16577       errmsg ("expected one of 'l2' or 'l3' parameter!");
16578       return -99;
16579     }
16580
16581   if (!vam->json_output)
16582     {
16583       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
16584     }
16585
16586   M (ONE_EID_TABLE_MAP_DUMP, mp);
16587   mp->is_l2 = is_l2;
16588
16589   /* send it... */
16590   S (mp);
16591
16592   /* Use a control ping for synchronization */
16593   MPING (CONTROL_PING, mp_ping);
16594   S (mp_ping);
16595
16596   /* Wait for a reply... */
16597   W (ret);
16598   return ret;
16599 }
16600
16601 #define api_lisp_eid_table_map_dump api_one_eid_table_map_dump
16602
16603 static int
16604 api_one_eid_table_vni_dump (vat_main_t * vam)
16605 {
16606   vl_api_one_eid_table_vni_dump_t *mp;
16607   vl_api_control_ping_t *mp_ping;
16608   int ret;
16609
16610   if (!vam->json_output)
16611     {
16612       print (vam->ofp, "VNI");
16613     }
16614
16615   M (ONE_EID_TABLE_VNI_DUMP, mp);
16616
16617   /* send it... */
16618   S (mp);
16619
16620   /* Use a control ping for synchronization */
16621   MPING (CONTROL_PING, mp_ping);
16622   S (mp_ping);
16623
16624   /* Wait for a reply... */
16625   W (ret);
16626   return ret;
16627 }
16628
16629 #define api_lisp_eid_table_vni_dump api_one_eid_table_vni_dump
16630
16631 static int
16632 api_one_eid_table_dump (vat_main_t * vam)
16633 {
16634   unformat_input_t *i = vam->input;
16635   vl_api_one_eid_table_dump_t *mp;
16636   vl_api_control_ping_t *mp_ping;
16637   struct in_addr ip4;
16638   struct in6_addr ip6;
16639   u8 mac[6];
16640   u8 eid_type = ~0, eid_set = 0;
16641   u32 prefix_length = ~0, t, vni = 0;
16642   u8 filter = 0;
16643   int ret;
16644   lisp_nsh_api_t nsh;
16645
16646   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16647     {
16648       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
16649         {
16650           eid_set = 1;
16651           eid_type = 0;
16652           prefix_length = t;
16653         }
16654       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
16655         {
16656           eid_set = 1;
16657           eid_type = 1;
16658           prefix_length = t;
16659         }
16660       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
16661         {
16662           eid_set = 1;
16663           eid_type = 2;
16664         }
16665       else if (unformat (i, "eid %U", unformat_nsh_address, &nsh))
16666         {
16667           eid_set = 1;
16668           eid_type = 3;
16669         }
16670       else if (unformat (i, "vni %d", &t))
16671         {
16672           vni = t;
16673         }
16674       else if (unformat (i, "local"))
16675         {
16676           filter = 1;
16677         }
16678       else if (unformat (i, "remote"))
16679         {
16680           filter = 2;
16681         }
16682       else
16683         {
16684           errmsg ("parse error '%U'", format_unformat_error, i);
16685           return -99;
16686         }
16687     }
16688
16689   if (!vam->json_output)
16690     {
16691       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
16692              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
16693     }
16694
16695   M (ONE_EID_TABLE_DUMP, mp);
16696
16697   mp->filter = filter;
16698   if (eid_set)
16699     {
16700       mp->eid_set = 1;
16701       mp->vni = htonl (vni);
16702       mp->eid_type = eid_type;
16703       switch (eid_type)
16704         {
16705         case 0:
16706           mp->prefix_length = prefix_length;
16707           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
16708           break;
16709         case 1:
16710           mp->prefix_length = prefix_length;
16711           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
16712           break;
16713         case 2:
16714           clib_memcpy (mp->eid, mac, sizeof (mac));
16715           break;
16716         case 3:
16717           clib_memcpy (mp->eid, &nsh, sizeof (nsh));
16718           break;
16719         default:
16720           errmsg ("unknown EID type %d!", eid_type);
16721           return -99;
16722         }
16723     }
16724
16725   /* send it... */
16726   S (mp);
16727
16728   /* Use a control ping for synchronization */
16729   MPING (CONTROL_PING, mp_ping);
16730   S (mp_ping);
16731
16732   /* Wait for a reply... */
16733   W (ret);
16734   return ret;
16735 }
16736
16737 #define api_lisp_eid_table_dump api_one_eid_table_dump
16738
16739 static int
16740 api_lisp_gpe_fwd_entries_get (vat_main_t * vam)
16741 {
16742   unformat_input_t *i = vam->input;
16743   vl_api_gpe_fwd_entries_get_t *mp;
16744   u8 vni_set = 0;
16745   u32 vni = ~0;
16746   int ret;
16747
16748   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16749     {
16750       if (unformat (i, "vni %d", &vni))
16751         {
16752           vni_set = 1;
16753         }
16754       else
16755         {
16756           errmsg ("parse error '%U'", format_unformat_error, i);
16757           return -99;
16758         }
16759     }
16760
16761   if (!vni_set)
16762     {
16763       errmsg ("vni not set!");
16764       return -99;
16765     }
16766
16767   if (!vam->json_output)
16768     {
16769       print (vam->ofp, "%10s %10s %s %40s", "fwd_index", "dp_table",
16770              "leid", "reid");
16771     }
16772
16773   M (GPE_FWD_ENTRIES_GET, mp);
16774   mp->vni = clib_host_to_net_u32 (vni);
16775
16776   /* send it... */
16777   S (mp);
16778
16779   /* Wait for a reply... */
16780   W (ret);
16781   return ret;
16782 }
16783
16784 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_endian vl_noop_handler
16785 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_print vl_noop_handler
16786 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_endian vl_noop_handler
16787 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_print vl_noop_handler
16788 #define vl_api_gpe_fwd_entries_get_reply_t_endian vl_noop_handler
16789 #define vl_api_gpe_fwd_entries_get_reply_t_print vl_noop_handler
16790 #define vl_api_gpe_fwd_entry_path_details_t_endian vl_noop_handler
16791 #define vl_api_gpe_fwd_entry_path_details_t_print vl_noop_handler
16792
16793 static int
16794 api_one_adjacencies_get (vat_main_t * vam)
16795 {
16796   unformat_input_t *i = vam->input;
16797   vl_api_one_adjacencies_get_t *mp;
16798   u8 vni_set = 0;
16799   u32 vni = ~0;
16800   int ret;
16801
16802   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16803     {
16804       if (unformat (i, "vni %d", &vni))
16805         {
16806           vni_set = 1;
16807         }
16808       else
16809         {
16810           errmsg ("parse error '%U'", format_unformat_error, i);
16811           return -99;
16812         }
16813     }
16814
16815   if (!vni_set)
16816     {
16817       errmsg ("vni not set!");
16818       return -99;
16819     }
16820
16821   if (!vam->json_output)
16822     {
16823       print (vam->ofp, "%s %40s", "leid", "reid");
16824     }
16825
16826   M (ONE_ADJACENCIES_GET, mp);
16827   mp->vni = clib_host_to_net_u32 (vni);
16828
16829   /* send it... */
16830   S (mp);
16831
16832   /* Wait for a reply... */
16833   W (ret);
16834   return ret;
16835 }
16836
16837 #define api_lisp_adjacencies_get api_one_adjacencies_get
16838
16839 static int
16840 api_gpe_native_fwd_rpaths_get (vat_main_t * vam)
16841 {
16842   unformat_input_t *i = vam->input;
16843   vl_api_gpe_native_fwd_rpaths_get_t *mp;
16844   int ret;
16845   u8 ip_family_set = 0, is_ip4 = 1;
16846
16847   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16848     {
16849       if (unformat (i, "ip4"))
16850         {
16851           ip_family_set = 1;
16852           is_ip4 = 1;
16853         }
16854       else if (unformat (i, "ip6"))
16855         {
16856           ip_family_set = 1;
16857           is_ip4 = 0;
16858         }
16859       else
16860         {
16861           errmsg ("parse error '%U'", format_unformat_error, i);
16862           return -99;
16863         }
16864     }
16865
16866   if (!ip_family_set)
16867     {
16868       errmsg ("ip family not set!");
16869       return -99;
16870     }
16871
16872   M (GPE_NATIVE_FWD_RPATHS_GET, mp);
16873   mp->is_ip4 = is_ip4;
16874
16875   /* send it... */
16876   S (mp);
16877
16878   /* Wait for a reply... */
16879   W (ret);
16880   return ret;
16881 }
16882
16883 static int
16884 api_gpe_fwd_entry_vnis_get (vat_main_t * vam)
16885 {
16886   vl_api_gpe_fwd_entry_vnis_get_t *mp;
16887   int ret;
16888
16889   if (!vam->json_output)
16890     {
16891       print (vam->ofp, "VNIs");
16892     }
16893
16894   M (GPE_FWD_ENTRY_VNIS_GET, mp);
16895
16896   /* send it... */
16897   S (mp);
16898
16899   /* Wait for a reply... */
16900   W (ret);
16901   return ret;
16902 }
16903
16904 static int
16905 api_gpe_add_del_native_fwd_rpath (vat_main_t * vam)
16906 {
16907   unformat_input_t *i = vam->input;
16908   vl_api_gpe_add_del_native_fwd_rpath_t *mp;
16909   int ret = 0;
16910   u8 is_add = 1, ip_set = 0, is_ip4 = 1;
16911   struct in_addr ip4;
16912   struct in6_addr ip6;
16913   u32 table_id = 0, nh_sw_if_index = ~0;
16914
16915   clib_memset (&ip4, 0, sizeof (ip4));
16916   clib_memset (&ip6, 0, sizeof (ip6));
16917
16918   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16919     {
16920       if (unformat (i, "del"))
16921         is_add = 0;
16922       else if (unformat (i, "via %U %U", unformat_ip4_address, &ip4,
16923                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
16924         {
16925           ip_set = 1;
16926           is_ip4 = 1;
16927         }
16928       else if (unformat (i, "via %U %U", unformat_ip6_address, &ip6,
16929                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
16930         {
16931           ip_set = 1;
16932           is_ip4 = 0;
16933         }
16934       else if (unformat (i, "via %U", unformat_ip4_address, &ip4))
16935         {
16936           ip_set = 1;
16937           is_ip4 = 1;
16938           nh_sw_if_index = ~0;
16939         }
16940       else if (unformat (i, "via %U", unformat_ip6_address, &ip6))
16941         {
16942           ip_set = 1;
16943           is_ip4 = 0;
16944           nh_sw_if_index = ~0;
16945         }
16946       else if (unformat (i, "table %d", &table_id))
16947         ;
16948       else
16949         {
16950           errmsg ("parse error '%U'", format_unformat_error, i);
16951           return -99;
16952         }
16953     }
16954
16955   if (!ip_set)
16956     {
16957       errmsg ("nh addr not set!");
16958       return -99;
16959     }
16960
16961   M (GPE_ADD_DEL_NATIVE_FWD_RPATH, mp);
16962   mp->is_add = is_add;
16963   mp->table_id = clib_host_to_net_u32 (table_id);
16964   mp->nh_sw_if_index = clib_host_to_net_u32 (nh_sw_if_index);
16965   mp->is_ip4 = is_ip4;
16966   if (is_ip4)
16967     clib_memcpy (mp->nh_addr, &ip4, sizeof (ip4));
16968   else
16969     clib_memcpy (mp->nh_addr, &ip6, sizeof (ip6));
16970
16971   /* send it... */
16972   S (mp);
16973
16974   /* Wait for a reply... */
16975   W (ret);
16976   return ret;
16977 }
16978
16979 static int
16980 api_one_map_server_dump (vat_main_t * vam)
16981 {
16982   vl_api_one_map_server_dump_t *mp;
16983   vl_api_control_ping_t *mp_ping;
16984   int ret;
16985
16986   if (!vam->json_output)
16987     {
16988       print (vam->ofp, "%=20s", "Map server");
16989     }
16990
16991   M (ONE_MAP_SERVER_DUMP, mp);
16992   /* send it... */
16993   S (mp);
16994
16995   /* Use a control ping for synchronization */
16996   MPING (CONTROL_PING, mp_ping);
16997   S (mp_ping);
16998
16999   /* Wait for a reply... */
17000   W (ret);
17001   return ret;
17002 }
17003
17004 #define api_lisp_map_server_dump api_one_map_server_dump
17005
17006 static int
17007 api_one_map_resolver_dump (vat_main_t * vam)
17008 {
17009   vl_api_one_map_resolver_dump_t *mp;
17010   vl_api_control_ping_t *mp_ping;
17011   int ret;
17012
17013   if (!vam->json_output)
17014     {
17015       print (vam->ofp, "%=20s", "Map resolver");
17016     }
17017
17018   M (ONE_MAP_RESOLVER_DUMP, mp);
17019   /* send it... */
17020   S (mp);
17021
17022   /* Use a control ping for synchronization */
17023   MPING (CONTROL_PING, mp_ping);
17024   S (mp_ping);
17025
17026   /* Wait for a reply... */
17027   W (ret);
17028   return ret;
17029 }
17030
17031 #define api_lisp_map_resolver_dump api_one_map_resolver_dump
17032
17033 static int
17034 api_one_stats_flush (vat_main_t * vam)
17035 {
17036   vl_api_one_stats_flush_t *mp;
17037   int ret = 0;
17038
17039   M (ONE_STATS_FLUSH, mp);
17040   S (mp);
17041   W (ret);
17042   return ret;
17043 }
17044
17045 static int
17046 api_one_stats_dump (vat_main_t * vam)
17047 {
17048   vl_api_one_stats_dump_t *mp;
17049   vl_api_control_ping_t *mp_ping;
17050   int ret;
17051
17052   M (ONE_STATS_DUMP, mp);
17053   /* send it... */
17054   S (mp);
17055
17056   /* Use a control ping for synchronization */
17057   MPING (CONTROL_PING, mp_ping);
17058   S (mp_ping);
17059
17060   /* Wait for a reply... */
17061   W (ret);
17062   return ret;
17063 }
17064
17065 static int
17066 api_show_one_status (vat_main_t * vam)
17067 {
17068   vl_api_show_one_status_t *mp;
17069   int ret;
17070
17071   if (!vam->json_output)
17072     {
17073       print (vam->ofp, "%-20s%-16s", "ONE status", "locator-set");
17074     }
17075
17076   M (SHOW_ONE_STATUS, mp);
17077   /* send it... */
17078   S (mp);
17079   /* Wait for a reply... */
17080   W (ret);
17081   return ret;
17082 }
17083
17084 #define api_show_lisp_status api_show_one_status
17085
17086 static int
17087 api_lisp_gpe_fwd_entry_path_dump (vat_main_t * vam)
17088 {
17089   vl_api_gpe_fwd_entry_path_dump_t *mp;
17090   vl_api_control_ping_t *mp_ping;
17091   unformat_input_t *i = vam->input;
17092   u32 fwd_entry_index = ~0;
17093   int ret;
17094
17095   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17096     {
17097       if (unformat (i, "index %d", &fwd_entry_index))
17098         ;
17099       else
17100         break;
17101     }
17102
17103   if (~0 == fwd_entry_index)
17104     {
17105       errmsg ("no index specified!");
17106       return -99;
17107     }
17108
17109   if (!vam->json_output)
17110     {
17111       print (vam->ofp, "first line");
17112     }
17113
17114   M (GPE_FWD_ENTRY_PATH_DUMP, mp);
17115
17116   /* send it... */
17117   S (mp);
17118   /* Use a control ping for synchronization */
17119   MPING (CONTROL_PING, mp_ping);
17120   S (mp_ping);
17121
17122   /* Wait for a reply... */
17123   W (ret);
17124   return ret;
17125 }
17126
17127 static int
17128 api_one_get_map_request_itr_rlocs (vat_main_t * vam)
17129 {
17130   vl_api_one_get_map_request_itr_rlocs_t *mp;
17131   int ret;
17132
17133   if (!vam->json_output)
17134     {
17135       print (vam->ofp, "%=20s", "itr-rlocs:");
17136     }
17137
17138   M (ONE_GET_MAP_REQUEST_ITR_RLOCS, mp);
17139   /* send it... */
17140   S (mp);
17141   /* Wait for a reply... */
17142   W (ret);
17143   return ret;
17144 }
17145
17146 #define api_lisp_get_map_request_itr_rlocs api_one_get_map_request_itr_rlocs
17147
17148 static int
17149 api_af_packet_create (vat_main_t * vam)
17150 {
17151   unformat_input_t *i = vam->input;
17152   vl_api_af_packet_create_t *mp;
17153   u8 *host_if_name = 0;
17154   u8 hw_addr[6];
17155   u8 random_hw_addr = 1;
17156   int ret;
17157
17158   clib_memset (hw_addr, 0, sizeof (hw_addr));
17159
17160   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17161     {
17162       if (unformat (i, "name %s", &host_if_name))
17163         vec_add1 (host_if_name, 0);
17164       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
17165         random_hw_addr = 0;
17166       else
17167         break;
17168     }
17169
17170   if (!vec_len (host_if_name))
17171     {
17172       errmsg ("host-interface name must be specified");
17173       return -99;
17174     }
17175
17176   if (vec_len (host_if_name) > 64)
17177     {
17178       errmsg ("host-interface name too long");
17179       return -99;
17180     }
17181
17182   M (AF_PACKET_CREATE, mp);
17183
17184   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
17185   clib_memcpy (mp->hw_addr, hw_addr, 6);
17186   mp->use_random_hw_addr = random_hw_addr;
17187   vec_free (host_if_name);
17188
17189   S (mp);
17190
17191   /* *INDENT-OFF* */
17192   W2 (ret,
17193       ({
17194         if (ret == 0)
17195           fprintf (vam->ofp ? vam->ofp : stderr,
17196                    " new sw_if_index = %d\n", vam->sw_if_index);
17197       }));
17198   /* *INDENT-ON* */
17199   return ret;
17200 }
17201
17202 static int
17203 api_af_packet_delete (vat_main_t * vam)
17204 {
17205   unformat_input_t *i = vam->input;
17206   vl_api_af_packet_delete_t *mp;
17207   u8 *host_if_name = 0;
17208   int ret;
17209
17210   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17211     {
17212       if (unformat (i, "name %s", &host_if_name))
17213         vec_add1 (host_if_name, 0);
17214       else
17215         break;
17216     }
17217
17218   if (!vec_len (host_if_name))
17219     {
17220       errmsg ("host-interface name must be specified");
17221       return -99;
17222     }
17223
17224   if (vec_len (host_if_name) > 64)
17225     {
17226       errmsg ("host-interface name too long");
17227       return -99;
17228     }
17229
17230   M (AF_PACKET_DELETE, mp);
17231
17232   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
17233   vec_free (host_if_name);
17234
17235   S (mp);
17236   W (ret);
17237   return ret;
17238 }
17239
17240 static void vl_api_af_packet_details_t_handler
17241   (vl_api_af_packet_details_t * mp)
17242 {
17243   vat_main_t *vam = &vat_main;
17244
17245   print (vam->ofp, "%-16s %d",
17246          mp->host_if_name, clib_net_to_host_u32 (mp->sw_if_index));
17247 }
17248
17249 static void vl_api_af_packet_details_t_handler_json
17250   (vl_api_af_packet_details_t * mp)
17251 {
17252   vat_main_t *vam = &vat_main;
17253   vat_json_node_t *node = NULL;
17254
17255   if (VAT_JSON_ARRAY != vam->json_tree.type)
17256     {
17257       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17258       vat_json_init_array (&vam->json_tree);
17259     }
17260   node = vat_json_array_add (&vam->json_tree);
17261
17262   vat_json_init_object (node);
17263   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
17264   vat_json_object_add_string_copy (node, "dev_name", mp->host_if_name);
17265 }
17266
17267 static int
17268 api_af_packet_dump (vat_main_t * vam)
17269 {
17270   vl_api_af_packet_dump_t *mp;
17271   vl_api_control_ping_t *mp_ping;
17272   int ret;
17273
17274   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
17275   /* Get list of tap interfaces */
17276   M (AF_PACKET_DUMP, mp);
17277   S (mp);
17278
17279   /* Use a control ping for synchronization */
17280   MPING (CONTROL_PING, mp_ping);
17281   S (mp_ping);
17282
17283   W (ret);
17284   return ret;
17285 }
17286
17287 static int
17288 api_policer_add_del (vat_main_t * vam)
17289 {
17290   unformat_input_t *i = vam->input;
17291   vl_api_policer_add_del_t *mp;
17292   u8 is_add = 1;
17293   u8 *name = 0;
17294   u32 cir = 0;
17295   u32 eir = 0;
17296   u64 cb = 0;
17297   u64 eb = 0;
17298   u8 rate_type = 0;
17299   u8 round_type = 0;
17300   u8 type = 0;
17301   u8 color_aware = 0;
17302   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
17303   int ret;
17304
17305   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
17306   conform_action.dscp = 0;
17307   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
17308   exceed_action.dscp = 0;
17309   violate_action.action_type = SSE2_QOS_ACTION_DROP;
17310   violate_action.dscp = 0;
17311
17312   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17313     {
17314       if (unformat (i, "del"))
17315         is_add = 0;
17316       else if (unformat (i, "name %s", &name))
17317         vec_add1 (name, 0);
17318       else if (unformat (i, "cir %u", &cir))
17319         ;
17320       else if (unformat (i, "eir %u", &eir))
17321         ;
17322       else if (unformat (i, "cb %u", &cb))
17323         ;
17324       else if (unformat (i, "eb %u", &eb))
17325         ;
17326       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
17327                          &rate_type))
17328         ;
17329       else if (unformat (i, "round_type %U", unformat_policer_round_type,
17330                          &round_type))
17331         ;
17332       else if (unformat (i, "type %U", unformat_policer_type, &type))
17333         ;
17334       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
17335                          &conform_action))
17336         ;
17337       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
17338                          &exceed_action))
17339         ;
17340       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
17341                          &violate_action))
17342         ;
17343       else if (unformat (i, "color-aware"))
17344         color_aware = 1;
17345       else
17346         break;
17347     }
17348
17349   if (!vec_len (name))
17350     {
17351       errmsg ("policer name must be specified");
17352       return -99;
17353     }
17354
17355   if (vec_len (name) > 64)
17356     {
17357       errmsg ("policer name too long");
17358       return -99;
17359     }
17360
17361   M (POLICER_ADD_DEL, mp);
17362
17363   clib_memcpy (mp->name, name, vec_len (name));
17364   vec_free (name);
17365   mp->is_add = is_add;
17366   mp->cir = ntohl (cir);
17367   mp->eir = ntohl (eir);
17368   mp->cb = clib_net_to_host_u64 (cb);
17369   mp->eb = clib_net_to_host_u64 (eb);
17370   mp->rate_type = rate_type;
17371   mp->round_type = round_type;
17372   mp->type = type;
17373   mp->conform_action_type = conform_action.action_type;
17374   mp->conform_dscp = conform_action.dscp;
17375   mp->exceed_action_type = exceed_action.action_type;
17376   mp->exceed_dscp = exceed_action.dscp;
17377   mp->violate_action_type = violate_action.action_type;
17378   mp->violate_dscp = violate_action.dscp;
17379   mp->color_aware = color_aware;
17380
17381   S (mp);
17382   W (ret);
17383   return ret;
17384 }
17385
17386 static int
17387 api_policer_dump (vat_main_t * vam)
17388 {
17389   unformat_input_t *i = vam->input;
17390   vl_api_policer_dump_t *mp;
17391   vl_api_control_ping_t *mp_ping;
17392   u8 *match_name = 0;
17393   u8 match_name_valid = 0;
17394   int ret;
17395
17396   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17397     {
17398       if (unformat (i, "name %s", &match_name))
17399         {
17400           vec_add1 (match_name, 0);
17401           match_name_valid = 1;
17402         }
17403       else
17404         break;
17405     }
17406
17407   M (POLICER_DUMP, mp);
17408   mp->match_name_valid = match_name_valid;
17409   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
17410   vec_free (match_name);
17411   /* send it... */
17412   S (mp);
17413
17414   /* Use a control ping for synchronization */
17415   MPING (CONTROL_PING, mp_ping);
17416   S (mp_ping);
17417
17418   /* Wait for a reply... */
17419   W (ret);
17420   return ret;
17421 }
17422
17423 static int
17424 api_policer_classify_set_interface (vat_main_t * vam)
17425 {
17426   unformat_input_t *i = vam->input;
17427   vl_api_policer_classify_set_interface_t *mp;
17428   u32 sw_if_index;
17429   int sw_if_index_set;
17430   u32 ip4_table_index = ~0;
17431   u32 ip6_table_index = ~0;
17432   u32 l2_table_index = ~0;
17433   u8 is_add = 1;
17434   int ret;
17435
17436   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17437     {
17438       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17439         sw_if_index_set = 1;
17440       else if (unformat (i, "sw_if_index %d", &sw_if_index))
17441         sw_if_index_set = 1;
17442       else if (unformat (i, "del"))
17443         is_add = 0;
17444       else if (unformat (i, "ip4-table %d", &ip4_table_index))
17445         ;
17446       else if (unformat (i, "ip6-table %d", &ip6_table_index))
17447         ;
17448       else if (unformat (i, "l2-table %d", &l2_table_index))
17449         ;
17450       else
17451         {
17452           clib_warning ("parse error '%U'", format_unformat_error, i);
17453           return -99;
17454         }
17455     }
17456
17457   if (sw_if_index_set == 0)
17458     {
17459       errmsg ("missing interface name or sw_if_index");
17460       return -99;
17461     }
17462
17463   M (POLICER_CLASSIFY_SET_INTERFACE, mp);
17464
17465   mp->sw_if_index = ntohl (sw_if_index);
17466   mp->ip4_table_index = ntohl (ip4_table_index);
17467   mp->ip6_table_index = ntohl (ip6_table_index);
17468   mp->l2_table_index = ntohl (l2_table_index);
17469   mp->is_add = is_add;
17470
17471   S (mp);
17472   W (ret);
17473   return ret;
17474 }
17475
17476 static int
17477 api_policer_classify_dump (vat_main_t * vam)
17478 {
17479   unformat_input_t *i = vam->input;
17480   vl_api_policer_classify_dump_t *mp;
17481   vl_api_control_ping_t *mp_ping;
17482   u8 type = POLICER_CLASSIFY_N_TABLES;
17483   int ret;
17484
17485   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
17486     ;
17487   else
17488     {
17489       errmsg ("classify table type must be specified");
17490       return -99;
17491     }
17492
17493   if (!vam->json_output)
17494     {
17495       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
17496     }
17497
17498   M (POLICER_CLASSIFY_DUMP, mp);
17499   mp->type = type;
17500   /* send it... */
17501   S (mp);
17502
17503   /* Use a control ping for synchronization */
17504   MPING (CONTROL_PING, mp_ping);
17505   S (mp_ping);
17506
17507   /* Wait for a reply... */
17508   W (ret);
17509   return ret;
17510 }
17511
17512 static int
17513 api_netmap_create (vat_main_t * vam)
17514 {
17515   unformat_input_t *i = vam->input;
17516   vl_api_netmap_create_t *mp;
17517   u8 *if_name = 0;
17518   u8 hw_addr[6];
17519   u8 random_hw_addr = 1;
17520   u8 is_pipe = 0;
17521   u8 is_master = 0;
17522   int ret;
17523
17524   clib_memset (hw_addr, 0, sizeof (hw_addr));
17525
17526   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17527     {
17528       if (unformat (i, "name %s", &if_name))
17529         vec_add1 (if_name, 0);
17530       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
17531         random_hw_addr = 0;
17532       else if (unformat (i, "pipe"))
17533         is_pipe = 1;
17534       else if (unformat (i, "master"))
17535         is_master = 1;
17536       else if (unformat (i, "slave"))
17537         is_master = 0;
17538       else
17539         break;
17540     }
17541
17542   if (!vec_len (if_name))
17543     {
17544       errmsg ("interface name must be specified");
17545       return -99;
17546     }
17547
17548   if (vec_len (if_name) > 64)
17549     {
17550       errmsg ("interface name too long");
17551       return -99;
17552     }
17553
17554   M (NETMAP_CREATE, mp);
17555
17556   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
17557   clib_memcpy (mp->hw_addr, hw_addr, 6);
17558   mp->use_random_hw_addr = random_hw_addr;
17559   mp->is_pipe = is_pipe;
17560   mp->is_master = is_master;
17561   vec_free (if_name);
17562
17563   S (mp);
17564   W (ret);
17565   return ret;
17566 }
17567
17568 static int
17569 api_netmap_delete (vat_main_t * vam)
17570 {
17571   unformat_input_t *i = vam->input;
17572   vl_api_netmap_delete_t *mp;
17573   u8 *if_name = 0;
17574   int ret;
17575
17576   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17577     {
17578       if (unformat (i, "name %s", &if_name))
17579         vec_add1 (if_name, 0);
17580       else
17581         break;
17582     }
17583
17584   if (!vec_len (if_name))
17585     {
17586       errmsg ("interface name must be specified");
17587       return -99;
17588     }
17589
17590   if (vec_len (if_name) > 64)
17591     {
17592       errmsg ("interface name too long");
17593       return -99;
17594     }
17595
17596   M (NETMAP_DELETE, mp);
17597
17598   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
17599   vec_free (if_name);
17600
17601   S (mp);
17602   W (ret);
17603   return ret;
17604 }
17605
17606 static u8 *
17607 format_fib_api_path_nh_proto (u8 * s, va_list * args)
17608 {
17609   vl_api_fib_path_nh_proto_t proto =
17610     va_arg (*args, vl_api_fib_path_nh_proto_t);
17611
17612   switch (proto)
17613     {
17614     case FIB_API_PATH_NH_PROTO_IP4:
17615       s = format (s, "ip4");
17616       break;
17617     case FIB_API_PATH_NH_PROTO_IP6:
17618       s = format (s, "ip6");
17619       break;
17620     case FIB_API_PATH_NH_PROTO_MPLS:
17621       s = format (s, "mpls");
17622       break;
17623     case FIB_API_PATH_NH_PROTO_BIER:
17624       s = format (s, "bier");
17625       break;
17626     case FIB_API_PATH_NH_PROTO_ETHERNET:
17627       s = format (s, "ethernet");
17628       break;
17629     }
17630
17631   return (s);
17632 }
17633
17634 static u8 *
17635 format_vl_api_ip_address_union (u8 * s, va_list * args)
17636 {
17637   vl_api_address_family_t af = va_arg (*args, vl_api_address_family_t);
17638   const vl_api_address_union_t *u = va_arg (*args, vl_api_address_union_t *);
17639
17640   switch (af)
17641     {
17642     case ADDRESS_IP4:
17643       s = format (s, "%U", format_ip4_address, u->ip4);
17644       break;
17645     case ADDRESS_IP6:
17646       s = format (s, "%U", format_ip6_address, u->ip6);
17647       break;
17648     }
17649   return (s);
17650 }
17651
17652 static u8 *
17653 format_vl_api_fib_path_type (u8 * s, va_list * args)
17654 {
17655   vl_api_fib_path_type_t t = va_arg (*args, vl_api_fib_path_type_t);
17656
17657   switch (t)
17658     {
17659     case FIB_API_PATH_TYPE_NORMAL:
17660       s = format (s, "normal");
17661       break;
17662     case FIB_API_PATH_TYPE_LOCAL:
17663       s = format (s, "local");
17664       break;
17665     case FIB_API_PATH_TYPE_DROP:
17666       s = format (s, "drop");
17667       break;
17668     case FIB_API_PATH_TYPE_UDP_ENCAP:
17669       s = format (s, "udp-encap");
17670       break;
17671     case FIB_API_PATH_TYPE_BIER_IMP:
17672       s = format (s, "bier-imp");
17673       break;
17674     case FIB_API_PATH_TYPE_ICMP_UNREACH:
17675       s = format (s, "unreach");
17676       break;
17677     case FIB_API_PATH_TYPE_ICMP_PROHIBIT:
17678       s = format (s, "prohibit");
17679       break;
17680     case FIB_API_PATH_TYPE_SOURCE_LOOKUP:
17681       s = format (s, "src-lookup");
17682       break;
17683     case FIB_API_PATH_TYPE_DVR:
17684       s = format (s, "dvr");
17685       break;
17686     case FIB_API_PATH_TYPE_INTERFACE_RX:
17687       s = format (s, "interface-rx");
17688       break;
17689     case FIB_API_PATH_TYPE_CLASSIFY:
17690       s = format (s, "classify");
17691       break;
17692     }
17693
17694   return (s);
17695 }
17696
17697 static void
17698 vl_api_fib_path_print (vat_main_t * vam, vl_api_fib_path_t * fp)
17699 {
17700   print (vam->ofp,
17701          "  weight %d, sw_if_index %d, type %U, afi %U, next_hop %U",
17702          ntohl (fp->weight), ntohl (fp->sw_if_index),
17703          format_vl_api_fib_path_type, fp->type,
17704          format_fib_api_path_nh_proto, fp->proto,
17705          format_vl_api_ip_address_union, &fp->nh.address);
17706 }
17707
17708 static void
17709 vl_api_mpls_fib_path_json_print (vat_json_node_t * node,
17710                                  vl_api_fib_path_t * fp)
17711 {
17712   struct in_addr ip4;
17713   struct in6_addr ip6;
17714
17715   vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
17716   vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
17717   vat_json_object_add_uint (node, "type", fp->type);
17718   vat_json_object_add_uint (node, "next_hop_proto", fp->proto);
17719   if (fp->proto == FIB_API_PATH_NH_PROTO_IP4)
17720     {
17721       clib_memcpy (&ip4, &fp->nh.address.ip4, sizeof (ip4));
17722       vat_json_object_add_ip4 (node, "next_hop", ip4);
17723     }
17724   else if (fp->proto == FIB_API_PATH_NH_PROTO_IP4)
17725     {
17726       clib_memcpy (&ip6, &fp->nh.address.ip6, sizeof (ip6));
17727       vat_json_object_add_ip6 (node, "next_hop", ip6);
17728     }
17729 }
17730
17731 static void
17732 vl_api_mpls_tunnel_details_t_handler (vl_api_mpls_tunnel_details_t * mp)
17733 {
17734   vat_main_t *vam = &vat_main;
17735   int count = ntohl (mp->mt_tunnel.mt_n_paths);
17736   vl_api_fib_path_t *fp;
17737   i32 i;
17738
17739   print (vam->ofp, "sw_if_index %d via:",
17740          ntohl (mp->mt_tunnel.mt_sw_if_index));
17741   fp = mp->mt_tunnel.mt_paths;
17742   for (i = 0; i < count; i++)
17743     {
17744       vl_api_fib_path_print (vam, fp);
17745       fp++;
17746     }
17747
17748   print (vam->ofp, "");
17749 }
17750
17751 #define vl_api_mpls_tunnel_details_t_endian vl_noop_handler
17752 #define vl_api_mpls_tunnel_details_t_print vl_noop_handler
17753
17754 static void
17755 vl_api_mpls_tunnel_details_t_handler_json (vl_api_mpls_tunnel_details_t * mp)
17756 {
17757   vat_main_t *vam = &vat_main;
17758   vat_json_node_t *node = NULL;
17759   int count = ntohl (mp->mt_tunnel.mt_n_paths);
17760   vl_api_fib_path_t *fp;
17761   i32 i;
17762
17763   if (VAT_JSON_ARRAY != vam->json_tree.type)
17764     {
17765       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17766       vat_json_init_array (&vam->json_tree);
17767     }
17768   node = vat_json_array_add (&vam->json_tree);
17769
17770   vat_json_init_object (node);
17771   vat_json_object_add_uint (node, "sw_if_index",
17772                             ntohl (mp->mt_tunnel.mt_sw_if_index));
17773
17774   vat_json_object_add_uint (node, "l2_only", mp->mt_tunnel.mt_l2_only);
17775
17776   fp = mp->mt_tunnel.mt_paths;
17777   for (i = 0; i < count; i++)
17778     {
17779       vl_api_mpls_fib_path_json_print (node, fp);
17780       fp++;
17781     }
17782 }
17783
17784 static int
17785 api_mpls_tunnel_dump (vat_main_t * vam)
17786 {
17787   vl_api_mpls_tunnel_dump_t *mp;
17788   vl_api_control_ping_t *mp_ping;
17789   int ret;
17790
17791   M (MPLS_TUNNEL_DUMP, mp);
17792
17793   S (mp);
17794
17795   /* Use a control ping for synchronization */
17796   MPING (CONTROL_PING, mp_ping);
17797   S (mp_ping);
17798
17799   W (ret);
17800   return ret;
17801 }
17802
17803 #define vl_api_mpls_table_details_t_endian vl_noop_handler
17804 #define vl_api_mpls_table_details_t_print vl_noop_handler
17805
17806
17807 static void
17808 vl_api_mpls_table_details_t_handler (vl_api_mpls_table_details_t * mp)
17809 {
17810   vat_main_t *vam = &vat_main;
17811
17812   print (vam->ofp, "table-id %d,", ntohl (mp->mt_table.mt_table_id));
17813 }
17814
17815 static void vl_api_mpls_table_details_t_handler_json
17816   (vl_api_mpls_table_details_t * mp)
17817 {
17818   vat_main_t *vam = &vat_main;
17819   vat_json_node_t *node = NULL;
17820
17821   if (VAT_JSON_ARRAY != vam->json_tree.type)
17822     {
17823       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17824       vat_json_init_array (&vam->json_tree);
17825     }
17826   node = vat_json_array_add (&vam->json_tree);
17827
17828   vat_json_init_object (node);
17829   vat_json_object_add_uint (node, "table", ntohl (mp->mt_table.mt_table_id));
17830 }
17831
17832 static int
17833 api_mpls_table_dump (vat_main_t * vam)
17834 {
17835   vl_api_mpls_table_dump_t *mp;
17836   vl_api_control_ping_t *mp_ping;
17837   int ret;
17838
17839   M (MPLS_TABLE_DUMP, mp);
17840   S (mp);
17841
17842   /* Use a control ping for synchronization */
17843   MPING (CONTROL_PING, mp_ping);
17844   S (mp_ping);
17845
17846   W (ret);
17847   return ret;
17848 }
17849
17850 #define vl_api_mpls_route_details_t_endian vl_noop_handler
17851 #define vl_api_mpls_route_details_t_print vl_noop_handler
17852
17853 static void
17854 vl_api_mpls_route_details_t_handler (vl_api_mpls_route_details_t * mp)
17855 {
17856   vat_main_t *vam = &vat_main;
17857   int count = (int) clib_net_to_host_u32 (mp->mr_route.mr_n_paths);
17858   vl_api_fib_path_t *fp;
17859   int i;
17860
17861   print (vam->ofp,
17862          "table-id %d, label %u, ess_bit %u",
17863          ntohl (mp->mr_route.mr_table_id),
17864          ntohl (mp->mr_route.mr_label), mp->mr_route.mr_eos);
17865   fp = mp->mr_route.mr_paths;
17866   for (i = 0; i < count; i++)
17867     {
17868       vl_api_fib_path_print (vam, fp);
17869       fp++;
17870     }
17871 }
17872
17873 static void vl_api_mpls_route_details_t_handler_json
17874   (vl_api_mpls_route_details_t * mp)
17875 {
17876   vat_main_t *vam = &vat_main;
17877   int count = (int) clib_host_to_net_u32 (mp->mr_route.mr_n_paths);
17878   vat_json_node_t *node = NULL;
17879   vl_api_fib_path_t *fp;
17880   int i;
17881
17882   if (VAT_JSON_ARRAY != vam->json_tree.type)
17883     {
17884       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17885       vat_json_init_array (&vam->json_tree);
17886     }
17887   node = vat_json_array_add (&vam->json_tree);
17888
17889   vat_json_init_object (node);
17890   vat_json_object_add_uint (node, "table", ntohl (mp->mr_route.mr_table_id));
17891   vat_json_object_add_uint (node, "s_bit", mp->mr_route.mr_eos);
17892   vat_json_object_add_uint (node, "label", ntohl (mp->mr_route.mr_label));
17893   vat_json_object_add_uint (node, "path_count", count);
17894   fp = mp->mr_route.mr_paths;
17895   for (i = 0; i < count; i++)
17896     {
17897       vl_api_mpls_fib_path_json_print (node, fp);
17898       fp++;
17899     }
17900 }
17901
17902 static int
17903 api_mpls_route_dump (vat_main_t * vam)
17904 {
17905   unformat_input_t *input = vam->input;
17906   vl_api_mpls_route_dump_t *mp;
17907   vl_api_control_ping_t *mp_ping;
17908   u32 table_id;
17909   int ret;
17910
17911   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17912     {
17913       if (unformat (input, "table_id %d", &table_id))
17914         ;
17915       else
17916         break;
17917     }
17918   if (table_id == ~0)
17919     {
17920       errmsg ("missing table id");
17921       return -99;
17922     }
17923
17924   M (MPLS_ROUTE_DUMP, mp);
17925
17926   mp->table.mt_table_id = ntohl (table_id);
17927   S (mp);
17928
17929   /* Use a control ping for synchronization */
17930   MPING (CONTROL_PING, mp_ping);
17931   S (mp_ping);
17932
17933   W (ret);
17934   return ret;
17935 }
17936
17937 #define vl_api_ip_table_details_t_endian vl_noop_handler
17938 #define vl_api_ip_table_details_t_print vl_noop_handler
17939
17940 static void
17941 vl_api_ip_table_details_t_handler (vl_api_ip_table_details_t * mp)
17942 {
17943   vat_main_t *vam = &vat_main;
17944
17945   print (vam->ofp,
17946          "%s; table-id %d, prefix %U/%d",
17947          mp->table.name, ntohl (mp->table.table_id));
17948 }
17949
17950
17951 static void vl_api_ip_table_details_t_handler_json
17952   (vl_api_ip_table_details_t * mp)
17953 {
17954   vat_main_t *vam = &vat_main;
17955   vat_json_node_t *node = NULL;
17956
17957   if (VAT_JSON_ARRAY != vam->json_tree.type)
17958     {
17959       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17960       vat_json_init_array (&vam->json_tree);
17961     }
17962   node = vat_json_array_add (&vam->json_tree);
17963
17964   vat_json_init_object (node);
17965   vat_json_object_add_uint (node, "table", ntohl (mp->table.table_id));
17966 }
17967
17968 static int
17969 api_ip_table_dump (vat_main_t * vam)
17970 {
17971   vl_api_ip_table_dump_t *mp;
17972   vl_api_control_ping_t *mp_ping;
17973   int ret;
17974
17975   M (IP_TABLE_DUMP, mp);
17976   S (mp);
17977
17978   /* Use a control ping for synchronization */
17979   MPING (CONTROL_PING, mp_ping);
17980   S (mp_ping);
17981
17982   W (ret);
17983   return ret;
17984 }
17985
17986 static int
17987 api_ip_mtable_dump (vat_main_t * vam)
17988 {
17989   vl_api_ip_mtable_dump_t *mp;
17990   vl_api_control_ping_t *mp_ping;
17991   int ret;
17992
17993   M (IP_MTABLE_DUMP, mp);
17994   S (mp);
17995
17996   /* Use a control ping for synchronization */
17997   MPING (CONTROL_PING, mp_ping);
17998   S (mp_ping);
17999
18000   W (ret);
18001   return ret;
18002 }
18003
18004 static int
18005 api_ip_mroute_dump (vat_main_t * vam)
18006 {
18007   unformat_input_t *input = vam->input;
18008   vl_api_control_ping_t *mp_ping;
18009   vl_api_ip_mroute_dump_t *mp;
18010   int ret, is_ip6;
18011   u32 table_id;
18012
18013   is_ip6 = 0;
18014   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18015     {
18016       if (unformat (input, "table_id %d", &table_id))
18017         ;
18018       else if (unformat (input, "ip6"))
18019         is_ip6 = 1;
18020       else if (unformat (input, "ip4"))
18021         is_ip6 = 0;
18022       else
18023         break;
18024     }
18025   if (table_id == ~0)
18026     {
18027       errmsg ("missing table id");
18028       return -99;
18029     }
18030
18031   M (IP_MROUTE_DUMP, mp);
18032   mp->table.table_id = table_id;
18033   mp->table.is_ip6 = is_ip6;
18034   S (mp);
18035
18036   /* Use a control ping for synchronization */
18037   MPING (CONTROL_PING, mp_ping);
18038   S (mp_ping);
18039
18040   W (ret);
18041   return ret;
18042 }
18043
18044 #define vl_api_ip_route_details_t_endian vl_noop_handler
18045 #define vl_api_ip_route_details_t_print vl_noop_handler
18046
18047 static void
18048 vl_api_ip_route_details_t_handler (vl_api_ip_route_details_t * mp)
18049 {
18050   vat_main_t *vam = &vat_main;
18051   u8 count = mp->route.n_paths;
18052   vl_api_fib_path_t *fp;
18053   int i;
18054
18055   print (vam->ofp,
18056          "table-id %d, prefix %U/%d",
18057          ntohl (mp->route.table_id),
18058          format_ip46_address, mp->route.prefix.address, mp->route.prefix.len);
18059   for (i = 0; i < count; i++)
18060     {
18061       fp = &mp->route.paths[i];
18062
18063       vl_api_fib_path_print (vam, fp);
18064       fp++;
18065     }
18066 }
18067
18068 static void vl_api_ip_route_details_t_handler_json
18069   (vl_api_ip_route_details_t * mp)
18070 {
18071   vat_main_t *vam = &vat_main;
18072   u8 count = mp->route.n_paths;
18073   vat_json_node_t *node = NULL;
18074   struct in_addr ip4;
18075   struct in6_addr ip6;
18076   vl_api_fib_path_t *fp;
18077   int i;
18078
18079   if (VAT_JSON_ARRAY != vam->json_tree.type)
18080     {
18081       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18082       vat_json_init_array (&vam->json_tree);
18083     }
18084   node = vat_json_array_add (&vam->json_tree);
18085
18086   vat_json_init_object (node);
18087   vat_json_object_add_uint (node, "table", ntohl (mp->route.table_id));
18088   if (ADDRESS_IP6 == mp->route.prefix.address.af)
18089     {
18090       clib_memcpy (&ip6, &mp->route.prefix.address.un.ip6, sizeof (ip6));
18091       vat_json_object_add_ip6 (node, "prefix", ip6);
18092     }
18093   else
18094     {
18095       clib_memcpy (&ip4, &mp->route.prefix.address.un.ip4, sizeof (ip4));
18096       vat_json_object_add_ip4 (node, "prefix", ip4);
18097     }
18098   vat_json_object_add_uint (node, "mask_length", mp->route.prefix.len);
18099   vat_json_object_add_uint (node, "path_count", count);
18100   for (i = 0; i < count; i++)
18101     {
18102       fp = &mp->route.paths[i];
18103       vl_api_mpls_fib_path_json_print (node, fp);
18104     }
18105 }
18106
18107 static int
18108 api_ip_route_dump (vat_main_t * vam)
18109 {
18110   unformat_input_t *input = vam->input;
18111   vl_api_ip_route_dump_t *mp;
18112   vl_api_control_ping_t *mp_ping;
18113   u32 table_id;
18114   u8 is_ip6;
18115   int ret;
18116
18117   is_ip6 = 0;
18118   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18119     {
18120       if (unformat (input, "table_id %d", &table_id))
18121         ;
18122       else if (unformat (input, "ip6"))
18123         is_ip6 = 1;
18124       else if (unformat (input, "ip4"))
18125         is_ip6 = 0;
18126       else
18127         break;
18128     }
18129   if (table_id == ~0)
18130     {
18131       errmsg ("missing table id");
18132       return -99;
18133     }
18134
18135   M (IP_ROUTE_DUMP, mp);
18136
18137   mp->table.table_id = table_id;
18138   mp->table.is_ip6 = is_ip6;
18139
18140   S (mp);
18141
18142   /* Use a control ping for synchronization */
18143   MPING (CONTROL_PING, mp_ping);
18144   S (mp_ping);
18145
18146   W (ret);
18147   return ret;
18148 }
18149
18150 int
18151 api_classify_table_ids (vat_main_t * vam)
18152 {
18153   vl_api_classify_table_ids_t *mp;
18154   int ret;
18155
18156   /* Construct the API message */
18157   M (CLASSIFY_TABLE_IDS, mp);
18158   mp->context = 0;
18159
18160   S (mp);
18161   W (ret);
18162   return ret;
18163 }
18164
18165 int
18166 api_classify_table_by_interface (vat_main_t * vam)
18167 {
18168   unformat_input_t *input = vam->input;
18169   vl_api_classify_table_by_interface_t *mp;
18170
18171   u32 sw_if_index = ~0;
18172   int ret;
18173   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18174     {
18175       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18176         ;
18177       else if (unformat (input, "sw_if_index %d", &sw_if_index))
18178         ;
18179       else
18180         break;
18181     }
18182   if (sw_if_index == ~0)
18183     {
18184       errmsg ("missing interface name or sw_if_index");
18185       return -99;
18186     }
18187
18188   /* Construct the API message */
18189   M (CLASSIFY_TABLE_BY_INTERFACE, mp);
18190   mp->context = 0;
18191   mp->sw_if_index = ntohl (sw_if_index);
18192
18193   S (mp);
18194   W (ret);
18195   return ret;
18196 }
18197
18198 int
18199 api_classify_table_info (vat_main_t * vam)
18200 {
18201   unformat_input_t *input = vam->input;
18202   vl_api_classify_table_info_t *mp;
18203
18204   u32 table_id = ~0;
18205   int ret;
18206   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18207     {
18208       if (unformat (input, "table_id %d", &table_id))
18209         ;
18210       else
18211         break;
18212     }
18213   if (table_id == ~0)
18214     {
18215       errmsg ("missing table id");
18216       return -99;
18217     }
18218
18219   /* Construct the API message */
18220   M (CLASSIFY_TABLE_INFO, mp);
18221   mp->context = 0;
18222   mp->table_id = ntohl (table_id);
18223
18224   S (mp);
18225   W (ret);
18226   return ret;
18227 }
18228
18229 int
18230 api_classify_session_dump (vat_main_t * vam)
18231 {
18232   unformat_input_t *input = vam->input;
18233   vl_api_classify_session_dump_t *mp;
18234   vl_api_control_ping_t *mp_ping;
18235
18236   u32 table_id = ~0;
18237   int ret;
18238   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18239     {
18240       if (unformat (input, "table_id %d", &table_id))
18241         ;
18242       else
18243         break;
18244     }
18245   if (table_id == ~0)
18246     {
18247       errmsg ("missing table id");
18248       return -99;
18249     }
18250
18251   /* Construct the API message */
18252   M (CLASSIFY_SESSION_DUMP, mp);
18253   mp->context = 0;
18254   mp->table_id = ntohl (table_id);
18255   S (mp);
18256
18257   /* Use a control ping for synchronization */
18258   MPING (CONTROL_PING, mp_ping);
18259   S (mp_ping);
18260
18261   W (ret);
18262   return ret;
18263 }
18264
18265 static void
18266 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
18267 {
18268   vat_main_t *vam = &vat_main;
18269
18270   print (vam->ofp, "collector_address %U, collector_port %d, "
18271          "src_address %U, vrf_id %d, path_mtu %u, "
18272          "template_interval %u, udp_checksum %d",
18273          format_ip4_address, mp->collector_address,
18274          ntohs (mp->collector_port),
18275          format_ip4_address, mp->src_address,
18276          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
18277          ntohl (mp->template_interval), mp->udp_checksum);
18278
18279   vam->retval = 0;
18280   vam->result_ready = 1;
18281 }
18282
18283 static void
18284   vl_api_ipfix_exporter_details_t_handler_json
18285   (vl_api_ipfix_exporter_details_t * mp)
18286 {
18287   vat_main_t *vam = &vat_main;
18288   vat_json_node_t node;
18289   struct in_addr collector_address;
18290   struct in_addr src_address;
18291
18292   vat_json_init_object (&node);
18293   clib_memcpy (&collector_address, &mp->collector_address,
18294                sizeof (collector_address));
18295   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
18296   vat_json_object_add_uint (&node, "collector_port",
18297                             ntohs (mp->collector_port));
18298   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
18299   vat_json_object_add_ip4 (&node, "src_address", src_address);
18300   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
18301   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
18302   vat_json_object_add_uint (&node, "template_interval",
18303                             ntohl (mp->template_interval));
18304   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
18305
18306   vat_json_print (vam->ofp, &node);
18307   vat_json_free (&node);
18308   vam->retval = 0;
18309   vam->result_ready = 1;
18310 }
18311
18312 int
18313 api_ipfix_exporter_dump (vat_main_t * vam)
18314 {
18315   vl_api_ipfix_exporter_dump_t *mp;
18316   int ret;
18317
18318   /* Construct the API message */
18319   M (IPFIX_EXPORTER_DUMP, mp);
18320   mp->context = 0;
18321
18322   S (mp);
18323   W (ret);
18324   return ret;
18325 }
18326
18327 static int
18328 api_ipfix_classify_stream_dump (vat_main_t * vam)
18329 {
18330   vl_api_ipfix_classify_stream_dump_t *mp;
18331   int ret;
18332
18333   /* Construct the API message */
18334   M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
18335   mp->context = 0;
18336
18337   S (mp);
18338   W (ret);
18339   return ret;
18340   /* NOTREACHED */
18341   return 0;
18342 }
18343
18344 static void
18345   vl_api_ipfix_classify_stream_details_t_handler
18346   (vl_api_ipfix_classify_stream_details_t * mp)
18347 {
18348   vat_main_t *vam = &vat_main;
18349   print (vam->ofp, "domain_id %d, src_port %d",
18350          ntohl (mp->domain_id), ntohs (mp->src_port));
18351   vam->retval = 0;
18352   vam->result_ready = 1;
18353 }
18354
18355 static void
18356   vl_api_ipfix_classify_stream_details_t_handler_json
18357   (vl_api_ipfix_classify_stream_details_t * mp)
18358 {
18359   vat_main_t *vam = &vat_main;
18360   vat_json_node_t node;
18361
18362   vat_json_init_object (&node);
18363   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
18364   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
18365
18366   vat_json_print (vam->ofp, &node);
18367   vat_json_free (&node);
18368   vam->retval = 0;
18369   vam->result_ready = 1;
18370 }
18371
18372 static int
18373 api_ipfix_classify_table_dump (vat_main_t * vam)
18374 {
18375   vl_api_ipfix_classify_table_dump_t *mp;
18376   vl_api_control_ping_t *mp_ping;
18377   int ret;
18378
18379   if (!vam->json_output)
18380     {
18381       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
18382              "transport_protocol");
18383     }
18384
18385   /* Construct the API message */
18386   M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
18387
18388   /* send it... */
18389   S (mp);
18390
18391   /* Use a control ping for synchronization */
18392   MPING (CONTROL_PING, mp_ping);
18393   S (mp_ping);
18394
18395   W (ret);
18396   return ret;
18397 }
18398
18399 static void
18400   vl_api_ipfix_classify_table_details_t_handler
18401   (vl_api_ipfix_classify_table_details_t * mp)
18402 {
18403   vat_main_t *vam = &vat_main;
18404   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
18405          mp->transport_protocol);
18406 }
18407
18408 static void
18409   vl_api_ipfix_classify_table_details_t_handler_json
18410   (vl_api_ipfix_classify_table_details_t * mp)
18411 {
18412   vat_json_node_t *node = NULL;
18413   vat_main_t *vam = &vat_main;
18414
18415   if (VAT_JSON_ARRAY != vam->json_tree.type)
18416     {
18417       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18418       vat_json_init_array (&vam->json_tree);
18419     }
18420
18421   node = vat_json_array_add (&vam->json_tree);
18422   vat_json_init_object (node);
18423
18424   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
18425   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
18426   vat_json_object_add_uint (node, "transport_protocol",
18427                             mp->transport_protocol);
18428 }
18429
18430 static int
18431 api_sw_interface_span_enable_disable (vat_main_t * vam)
18432 {
18433   unformat_input_t *i = vam->input;
18434   vl_api_sw_interface_span_enable_disable_t *mp;
18435   u32 src_sw_if_index = ~0;
18436   u32 dst_sw_if_index = ~0;
18437   u8 state = 3;
18438   int ret;
18439   u8 is_l2 = 0;
18440
18441   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18442     {
18443       if (unformat
18444           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
18445         ;
18446       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
18447         ;
18448       else
18449         if (unformat
18450             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
18451         ;
18452       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
18453         ;
18454       else if (unformat (i, "disable"))
18455         state = 0;
18456       else if (unformat (i, "rx"))
18457         state = 1;
18458       else if (unformat (i, "tx"))
18459         state = 2;
18460       else if (unformat (i, "both"))
18461         state = 3;
18462       else if (unformat (i, "l2"))
18463         is_l2 = 1;
18464       else
18465         break;
18466     }
18467
18468   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
18469
18470   mp->sw_if_index_from = htonl (src_sw_if_index);
18471   mp->sw_if_index_to = htonl (dst_sw_if_index);
18472   mp->state = state;
18473   mp->is_l2 = is_l2;
18474
18475   S (mp);
18476   W (ret);
18477   return ret;
18478 }
18479
18480 static void
18481 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
18482                                             * mp)
18483 {
18484   vat_main_t *vam = &vat_main;
18485   u8 *sw_if_from_name = 0;
18486   u8 *sw_if_to_name = 0;
18487   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
18488   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
18489   char *states[] = { "none", "rx", "tx", "both" };
18490   hash_pair_t *p;
18491
18492   /* *INDENT-OFF* */
18493   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
18494   ({
18495     if ((u32) p->value[0] == sw_if_index_from)
18496       {
18497         sw_if_from_name = (u8 *)(p->key);
18498         if (sw_if_to_name)
18499           break;
18500       }
18501     if ((u32) p->value[0] == sw_if_index_to)
18502       {
18503         sw_if_to_name = (u8 *)(p->key);
18504         if (sw_if_from_name)
18505           break;
18506       }
18507   }));
18508   /* *INDENT-ON* */
18509   print (vam->ofp, "%20s => %20s (%s) %s",
18510          sw_if_from_name, sw_if_to_name, states[mp->state],
18511          mp->is_l2 ? "l2" : "device");
18512 }
18513
18514 static void
18515   vl_api_sw_interface_span_details_t_handler_json
18516   (vl_api_sw_interface_span_details_t * mp)
18517 {
18518   vat_main_t *vam = &vat_main;
18519   vat_json_node_t *node = NULL;
18520   u8 *sw_if_from_name = 0;
18521   u8 *sw_if_to_name = 0;
18522   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
18523   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
18524   hash_pair_t *p;
18525
18526   /* *INDENT-OFF* */
18527   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
18528   ({
18529     if ((u32) p->value[0] == sw_if_index_from)
18530       {
18531         sw_if_from_name = (u8 *)(p->key);
18532         if (sw_if_to_name)
18533           break;
18534       }
18535     if ((u32) p->value[0] == sw_if_index_to)
18536       {
18537         sw_if_to_name = (u8 *)(p->key);
18538         if (sw_if_from_name)
18539           break;
18540       }
18541   }));
18542   /* *INDENT-ON* */
18543
18544   if (VAT_JSON_ARRAY != vam->json_tree.type)
18545     {
18546       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18547       vat_json_init_array (&vam->json_tree);
18548     }
18549   node = vat_json_array_add (&vam->json_tree);
18550
18551   vat_json_init_object (node);
18552   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
18553   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
18554   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
18555   if (0 != sw_if_to_name)
18556     {
18557       vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
18558     }
18559   vat_json_object_add_uint (node, "state", mp->state);
18560   vat_json_object_add_uint (node, "is-l2", mp->is_l2);
18561 }
18562
18563 static int
18564 api_sw_interface_span_dump (vat_main_t * vam)
18565 {
18566   unformat_input_t *input = vam->input;
18567   vl_api_sw_interface_span_dump_t *mp;
18568   vl_api_control_ping_t *mp_ping;
18569   u8 is_l2 = 0;
18570   int ret;
18571
18572   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18573     {
18574       if (unformat (input, "l2"))
18575         is_l2 = 1;
18576       else
18577         break;
18578     }
18579
18580   M (SW_INTERFACE_SPAN_DUMP, mp);
18581   mp->is_l2 = is_l2;
18582   S (mp);
18583
18584   /* Use a control ping for synchronization */
18585   MPING (CONTROL_PING, mp_ping);
18586   S (mp_ping);
18587
18588   W (ret);
18589   return ret;
18590 }
18591
18592 int
18593 api_pg_create_interface (vat_main_t * vam)
18594 {
18595   unformat_input_t *input = vam->input;
18596   vl_api_pg_create_interface_t *mp;
18597
18598   u32 if_id = ~0, gso_size = 0;
18599   u8 gso_enabled = 0;
18600   int ret;
18601   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18602     {
18603       if (unformat (input, "if_id %d", &if_id))
18604         ;
18605       else if (unformat (input, "gso-enabled"))
18606         {
18607           gso_enabled = 1;
18608           if (unformat (input, "gso-size %u", &gso_size))
18609             ;
18610           else
18611             {
18612               errmsg ("missing gso-size");
18613               return -99;
18614             }
18615         }
18616       else
18617         break;
18618     }
18619   if (if_id == ~0)
18620     {
18621       errmsg ("missing pg interface index");
18622       return -99;
18623     }
18624
18625   /* Construct the API message */
18626   M (PG_CREATE_INTERFACE, mp);
18627   mp->context = 0;
18628   mp->interface_id = ntohl (if_id);
18629   mp->gso_enabled = gso_enabled;
18630
18631   S (mp);
18632   W (ret);
18633   return ret;
18634 }
18635
18636 int
18637 api_pg_capture (vat_main_t * vam)
18638 {
18639   unformat_input_t *input = vam->input;
18640   vl_api_pg_capture_t *mp;
18641
18642   u32 if_id = ~0;
18643   u8 enable = 1;
18644   u32 count = 1;
18645   u8 pcap_file_set = 0;
18646   u8 *pcap_file = 0;
18647   int ret;
18648   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18649     {
18650       if (unformat (input, "if_id %d", &if_id))
18651         ;
18652       else if (unformat (input, "pcap %s", &pcap_file))
18653         pcap_file_set = 1;
18654       else if (unformat (input, "count %d", &count))
18655         ;
18656       else if (unformat (input, "disable"))
18657         enable = 0;
18658       else
18659         break;
18660     }
18661   if (if_id == ~0)
18662     {
18663       errmsg ("missing pg interface index");
18664       return -99;
18665     }
18666   if (pcap_file_set > 0)
18667     {
18668       if (vec_len (pcap_file) > 255)
18669         {
18670           errmsg ("pcap file name is too long");
18671           return -99;
18672         }
18673     }
18674
18675   u32 name_len = vec_len (pcap_file);
18676   /* Construct the API message */
18677   M (PG_CAPTURE, mp);
18678   mp->context = 0;
18679   mp->interface_id = ntohl (if_id);
18680   mp->is_enabled = enable;
18681   mp->count = ntohl (count);
18682   mp->pcap_name_length = ntohl (name_len);
18683   if (pcap_file_set != 0)
18684     {
18685       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
18686     }
18687   vec_free (pcap_file);
18688
18689   S (mp);
18690   W (ret);
18691   return ret;
18692 }
18693
18694 int
18695 api_pg_enable_disable (vat_main_t * vam)
18696 {
18697   unformat_input_t *input = vam->input;
18698   vl_api_pg_enable_disable_t *mp;
18699
18700   u8 enable = 1;
18701   u8 stream_name_set = 0;
18702   u8 *stream_name = 0;
18703   int ret;
18704   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18705     {
18706       if (unformat (input, "stream %s", &stream_name))
18707         stream_name_set = 1;
18708       else if (unformat (input, "disable"))
18709         enable = 0;
18710       else
18711         break;
18712     }
18713
18714   if (stream_name_set > 0)
18715     {
18716       if (vec_len (stream_name) > 255)
18717         {
18718           errmsg ("stream name too long");
18719           return -99;
18720         }
18721     }
18722
18723   u32 name_len = vec_len (stream_name);
18724   /* Construct the API message */
18725   M (PG_ENABLE_DISABLE, mp);
18726   mp->context = 0;
18727   mp->is_enabled = enable;
18728   if (stream_name_set != 0)
18729     {
18730       mp->stream_name_length = ntohl (name_len);
18731       clib_memcpy (mp->stream_name, stream_name, name_len);
18732     }
18733   vec_free (stream_name);
18734
18735   S (mp);
18736   W (ret);
18737   return ret;
18738 }
18739
18740 int
18741 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
18742 {
18743   unformat_input_t *input = vam->input;
18744   vl_api_ip_source_and_port_range_check_add_del_t *mp;
18745
18746   u16 *low_ports = 0;
18747   u16 *high_ports = 0;
18748   u16 this_low;
18749   u16 this_hi;
18750   vl_api_prefix_t prefix;
18751   u32 tmp, tmp2;
18752   u8 prefix_set = 0;
18753   u32 vrf_id = ~0;
18754   u8 is_add = 1;
18755   int ret;
18756
18757   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18758     {
18759       if (unformat (input, "%U", unformat_vl_api_prefix, &prefix))
18760         prefix_set = 1;
18761       else if (unformat (input, "vrf %d", &vrf_id))
18762         ;
18763       else if (unformat (input, "del"))
18764         is_add = 0;
18765       else if (unformat (input, "port %d", &tmp))
18766         {
18767           if (tmp == 0 || tmp > 65535)
18768             {
18769               errmsg ("port %d out of range", tmp);
18770               return -99;
18771             }
18772           this_low = tmp;
18773           this_hi = this_low + 1;
18774           vec_add1 (low_ports, this_low);
18775           vec_add1 (high_ports, this_hi);
18776         }
18777       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
18778         {
18779           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
18780             {
18781               errmsg ("incorrect range parameters");
18782               return -99;
18783             }
18784           this_low = tmp;
18785           /* Note: in debug CLI +1 is added to high before
18786              passing to real fn that does "the work"
18787              (ip_source_and_port_range_check_add_del).
18788              This fn is a wrapper around the binary API fn a
18789              control plane will call, which expects this increment
18790              to have occurred. Hence letting the binary API control
18791              plane fn do the increment for consistency between VAT
18792              and other control planes.
18793            */
18794           this_hi = tmp2;
18795           vec_add1 (low_ports, this_low);
18796           vec_add1 (high_ports, this_hi);
18797         }
18798       else
18799         break;
18800     }
18801
18802   if (prefix_set == 0)
18803     {
18804       errmsg ("<address>/<mask> not specified");
18805       return -99;
18806     }
18807
18808   if (vrf_id == ~0)
18809     {
18810       errmsg ("VRF ID required, not specified");
18811       return -99;
18812     }
18813
18814   if (vrf_id == 0)
18815     {
18816       errmsg
18817         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
18818       return -99;
18819     }
18820
18821   if (vec_len (low_ports) == 0)
18822     {
18823       errmsg ("At least one port or port range required");
18824       return -99;
18825     }
18826
18827   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
18828
18829   mp->is_add = is_add;
18830
18831   clib_memcpy (&mp->prefix, &prefix, sizeof (prefix));
18832
18833   mp->number_of_ranges = vec_len (low_ports);
18834
18835   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
18836   vec_free (low_ports);
18837
18838   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
18839   vec_free (high_ports);
18840
18841   mp->vrf_id = ntohl (vrf_id);
18842
18843   S (mp);
18844   W (ret);
18845   return ret;
18846 }
18847
18848 int
18849 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
18850 {
18851   unformat_input_t *input = vam->input;
18852   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
18853   u32 sw_if_index = ~0;
18854   int vrf_set = 0;
18855   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
18856   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
18857   u8 is_add = 1;
18858   int ret;
18859
18860   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18861     {
18862       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18863         ;
18864       else if (unformat (input, "sw_if_index %d", &sw_if_index))
18865         ;
18866       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
18867         vrf_set = 1;
18868       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
18869         vrf_set = 1;
18870       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
18871         vrf_set = 1;
18872       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
18873         vrf_set = 1;
18874       else if (unformat (input, "del"))
18875         is_add = 0;
18876       else
18877         break;
18878     }
18879
18880   if (sw_if_index == ~0)
18881     {
18882       errmsg ("Interface required but not specified");
18883       return -99;
18884     }
18885
18886   if (vrf_set == 0)
18887     {
18888       errmsg ("VRF ID required but not specified");
18889       return -99;
18890     }
18891
18892   if (tcp_out_vrf_id == 0
18893       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
18894     {
18895       errmsg
18896         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
18897       return -99;
18898     }
18899
18900   /* Construct the API message */
18901   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
18902
18903   mp->sw_if_index = ntohl (sw_if_index);
18904   mp->is_add = is_add;
18905   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
18906   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
18907   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
18908   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
18909
18910   /* send it... */
18911   S (mp);
18912
18913   /* Wait for a reply... */
18914   W (ret);
18915   return ret;
18916 }
18917
18918 static int
18919 api_set_punt (vat_main_t * vam)
18920 {
18921   unformat_input_t *i = vam->input;
18922   vl_api_address_family_t af;
18923   vl_api_set_punt_t *mp;
18924   u32 protocol = ~0;
18925   u32 port = ~0;
18926   int is_add = 1;
18927   int ret;
18928
18929   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18930     {
18931       if (unformat (i, "%U", unformat_vl_api_address_family, &af))
18932         ;
18933       else if (unformat (i, "protocol %d", &protocol))
18934         ;
18935       else if (unformat (i, "port %d", &port))
18936         ;
18937       else if (unformat (i, "del"))
18938         is_add = 0;
18939       else
18940         {
18941           clib_warning ("parse error '%U'", format_unformat_error, i);
18942           return -99;
18943         }
18944     }
18945
18946   M (SET_PUNT, mp);
18947
18948   mp->is_add = (u8) is_add;
18949   mp->punt.type = PUNT_API_TYPE_L4;
18950   mp->punt.punt.l4.af = af;
18951   mp->punt.punt.l4.protocol = (u8) protocol;
18952   mp->punt.punt.l4.port = htons ((u16) port);
18953
18954   S (mp);
18955   W (ret);
18956   return ret;
18957 }
18958
18959 static int
18960 api_delete_subif (vat_main_t * vam)
18961 {
18962   unformat_input_t *i = vam->input;
18963   vl_api_delete_subif_t *mp;
18964   u32 sw_if_index = ~0;
18965   int ret;
18966
18967   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18968     {
18969       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18970         ;
18971       if (unformat (i, "sw_if_index %d", &sw_if_index))
18972         ;
18973       else
18974         break;
18975     }
18976
18977   if (sw_if_index == ~0)
18978     {
18979       errmsg ("missing sw_if_index");
18980       return -99;
18981     }
18982
18983   /* Construct the API message */
18984   M (DELETE_SUBIF, mp);
18985   mp->sw_if_index = ntohl (sw_if_index);
18986
18987   S (mp);
18988   W (ret);
18989   return ret;
18990 }
18991
18992 #define foreach_pbb_vtr_op      \
18993 _("disable",  L2_VTR_DISABLED)  \
18994 _("pop",  L2_VTR_POP_2)         \
18995 _("push",  L2_VTR_PUSH_2)
18996
18997 static int
18998 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
18999 {
19000   unformat_input_t *i = vam->input;
19001   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
19002   u32 sw_if_index = ~0, vtr_op = ~0;
19003   u16 outer_tag = ~0;
19004   u8 dmac[6], smac[6];
19005   u8 dmac_set = 0, smac_set = 0;
19006   u16 vlanid = 0;
19007   u32 sid = ~0;
19008   u32 tmp;
19009   int ret;
19010
19011   /* Shut up coverity */
19012   clib_memset (dmac, 0, sizeof (dmac));
19013   clib_memset (smac, 0, sizeof (smac));
19014
19015   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19016     {
19017       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19018         ;
19019       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19020         ;
19021       else if (unformat (i, "vtr_op %d", &vtr_op))
19022         ;
19023 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
19024       foreach_pbb_vtr_op
19025 #undef _
19026         else if (unformat (i, "translate_pbb_stag"))
19027         {
19028           if (unformat (i, "%d", &tmp))
19029             {
19030               vtr_op = L2_VTR_TRANSLATE_2_1;
19031               outer_tag = tmp;
19032             }
19033           else
19034             {
19035               errmsg
19036                 ("translate_pbb_stag operation requires outer tag definition");
19037               return -99;
19038             }
19039         }
19040       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
19041         dmac_set++;
19042       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
19043         smac_set++;
19044       else if (unformat (i, "sid %d", &sid))
19045         ;
19046       else if (unformat (i, "vlanid %d", &tmp))
19047         vlanid = tmp;
19048       else
19049         {
19050           clib_warning ("parse error '%U'", format_unformat_error, i);
19051           return -99;
19052         }
19053     }
19054
19055   if ((sw_if_index == ~0) || (vtr_op == ~0))
19056     {
19057       errmsg ("missing sw_if_index or vtr operation");
19058       return -99;
19059     }
19060   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
19061       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
19062     {
19063       errmsg
19064         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
19065       return -99;
19066     }
19067
19068   M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
19069   mp->sw_if_index = ntohl (sw_if_index);
19070   mp->vtr_op = ntohl (vtr_op);
19071   mp->outer_tag = ntohs (outer_tag);
19072   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
19073   clib_memcpy (mp->b_smac, smac, sizeof (smac));
19074   mp->b_vlanid = ntohs (vlanid);
19075   mp->i_sid = ntohl (sid);
19076
19077   S (mp);
19078   W (ret);
19079   return ret;
19080 }
19081
19082 static int
19083 api_flow_classify_set_interface (vat_main_t * vam)
19084 {
19085   unformat_input_t *i = vam->input;
19086   vl_api_flow_classify_set_interface_t *mp;
19087   u32 sw_if_index;
19088   int sw_if_index_set;
19089   u32 ip4_table_index = ~0;
19090   u32 ip6_table_index = ~0;
19091   u8 is_add = 1;
19092   int ret;
19093
19094   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19095     {
19096       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19097         sw_if_index_set = 1;
19098       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19099         sw_if_index_set = 1;
19100       else if (unformat (i, "del"))
19101         is_add = 0;
19102       else if (unformat (i, "ip4-table %d", &ip4_table_index))
19103         ;
19104       else if (unformat (i, "ip6-table %d", &ip6_table_index))
19105         ;
19106       else
19107         {
19108           clib_warning ("parse error '%U'", format_unformat_error, i);
19109           return -99;
19110         }
19111     }
19112
19113   if (sw_if_index_set == 0)
19114     {
19115       errmsg ("missing interface name or sw_if_index");
19116       return -99;
19117     }
19118
19119   M (FLOW_CLASSIFY_SET_INTERFACE, mp);
19120
19121   mp->sw_if_index = ntohl (sw_if_index);
19122   mp->ip4_table_index = ntohl (ip4_table_index);
19123   mp->ip6_table_index = ntohl (ip6_table_index);
19124   mp->is_add = is_add;
19125
19126   S (mp);
19127   W (ret);
19128   return ret;
19129 }
19130
19131 static int
19132 api_flow_classify_dump (vat_main_t * vam)
19133 {
19134   unformat_input_t *i = vam->input;
19135   vl_api_flow_classify_dump_t *mp;
19136   vl_api_control_ping_t *mp_ping;
19137   u8 type = FLOW_CLASSIFY_N_TABLES;
19138   int ret;
19139
19140   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
19141     ;
19142   else
19143     {
19144       errmsg ("classify table type must be specified");
19145       return -99;
19146     }
19147
19148   if (!vam->json_output)
19149     {
19150       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
19151     }
19152
19153   M (FLOW_CLASSIFY_DUMP, mp);
19154   mp->type = type;
19155   /* send it... */
19156   S (mp);
19157
19158   /* Use a control ping for synchronization */
19159   MPING (CONTROL_PING, mp_ping);
19160   S (mp_ping);
19161
19162   /* Wait for a reply... */
19163   W (ret);
19164   return ret;
19165 }
19166
19167 static int
19168 api_feature_enable_disable (vat_main_t * vam)
19169 {
19170   unformat_input_t *i = vam->input;
19171   vl_api_feature_enable_disable_t *mp;
19172   u8 *arc_name = 0;
19173   u8 *feature_name = 0;
19174   u32 sw_if_index = ~0;
19175   u8 enable = 1;
19176   int ret;
19177
19178   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19179     {
19180       if (unformat (i, "arc_name %s", &arc_name))
19181         ;
19182       else if (unformat (i, "feature_name %s", &feature_name))
19183         ;
19184       else
19185         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19186         ;
19187       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19188         ;
19189       else if (unformat (i, "disable"))
19190         enable = 0;
19191       else
19192         break;
19193     }
19194
19195   if (arc_name == 0)
19196     {
19197       errmsg ("missing arc name");
19198       return -99;
19199     }
19200   if (vec_len (arc_name) > 63)
19201     {
19202       errmsg ("arc name too long");
19203     }
19204
19205   if (feature_name == 0)
19206     {
19207       errmsg ("missing feature name");
19208       return -99;
19209     }
19210   if (vec_len (feature_name) > 63)
19211     {
19212       errmsg ("feature name too long");
19213     }
19214
19215   if (sw_if_index == ~0)
19216     {
19217       errmsg ("missing interface name or sw_if_index");
19218       return -99;
19219     }
19220
19221   /* Construct the API message */
19222   M (FEATURE_ENABLE_DISABLE, mp);
19223   mp->sw_if_index = ntohl (sw_if_index);
19224   mp->enable = enable;
19225   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
19226   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
19227   vec_free (arc_name);
19228   vec_free (feature_name);
19229
19230   S (mp);
19231   W (ret);
19232   return ret;
19233 }
19234
19235 static int
19236 api_feature_gso_enable_disable (vat_main_t * vam)
19237 {
19238   unformat_input_t *i = vam->input;
19239   vl_api_feature_gso_enable_disable_t *mp;
19240   u32 sw_if_index = ~0;
19241   u8 enable = 1;
19242   int ret;
19243
19244   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19245     {
19246       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19247         ;
19248       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19249         ;
19250       else if (unformat (i, "enable"))
19251         enable = 1;
19252       else if (unformat (i, "disable"))
19253         enable = 0;
19254       else
19255         break;
19256     }
19257
19258   if (sw_if_index == ~0)
19259     {
19260       errmsg ("missing interface name or sw_if_index");
19261       return -99;
19262     }
19263
19264   /* Construct the API message */
19265   M (FEATURE_GSO_ENABLE_DISABLE, mp);
19266   mp->sw_if_index = ntohl (sw_if_index);
19267   mp->enable_disable = enable;
19268
19269   S (mp);
19270   W (ret);
19271   return ret;
19272 }
19273
19274 static int
19275 api_sw_interface_tag_add_del (vat_main_t * vam)
19276 {
19277   unformat_input_t *i = vam->input;
19278   vl_api_sw_interface_tag_add_del_t *mp;
19279   u32 sw_if_index = ~0;
19280   u8 *tag = 0;
19281   u8 enable = 1;
19282   int ret;
19283
19284   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19285     {
19286       if (unformat (i, "tag %s", &tag))
19287         ;
19288       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19289         ;
19290       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19291         ;
19292       else if (unformat (i, "del"))
19293         enable = 0;
19294       else
19295         break;
19296     }
19297
19298   if (sw_if_index == ~0)
19299     {
19300       errmsg ("missing interface name or sw_if_index");
19301       return -99;
19302     }
19303
19304   if (enable && (tag == 0))
19305     {
19306       errmsg ("no tag specified");
19307       return -99;
19308     }
19309
19310   /* Construct the API message */
19311   M (SW_INTERFACE_TAG_ADD_DEL, mp);
19312   mp->sw_if_index = ntohl (sw_if_index);
19313   mp->is_add = enable;
19314   if (enable)
19315     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
19316   vec_free (tag);
19317
19318   S (mp);
19319   W (ret);
19320   return ret;
19321 }
19322
19323 static int
19324 api_sw_interface_add_del_mac_address (vat_main_t * vam)
19325 {
19326   unformat_input_t *i = vam->input;
19327   vl_api_mac_address_t mac = { 0 };
19328   vl_api_sw_interface_add_del_mac_address_t *mp;
19329   u32 sw_if_index = ~0;
19330   u8 is_add = 1;
19331   u8 mac_set = 0;
19332   int ret;
19333
19334   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19335     {
19336       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19337         ;
19338       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19339         ;
19340       else if (unformat (i, "%U", unformat_vl_api_mac_address, &mac))
19341         mac_set++;
19342       else if (unformat (i, "del"))
19343         is_add = 0;
19344       else
19345         break;
19346     }
19347
19348   if (sw_if_index == ~0)
19349     {
19350       errmsg ("missing interface name or sw_if_index");
19351       return -99;
19352     }
19353
19354   if (!mac_set)
19355     {
19356       errmsg ("missing MAC address");
19357       return -99;
19358     }
19359
19360   /* Construct the API message */
19361   M (SW_INTERFACE_ADD_DEL_MAC_ADDRESS, mp);
19362   mp->sw_if_index = ntohl (sw_if_index);
19363   mp->is_add = is_add;
19364   clib_memcpy (&mp->addr, &mac, sizeof (mac));
19365
19366   S (mp);
19367   W (ret);
19368   return ret;
19369 }
19370
19371 static void vl_api_l2_xconnect_details_t_handler
19372   (vl_api_l2_xconnect_details_t * mp)
19373 {
19374   vat_main_t *vam = &vat_main;
19375
19376   print (vam->ofp, "%15d%15d",
19377          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
19378 }
19379
19380 static void vl_api_l2_xconnect_details_t_handler_json
19381   (vl_api_l2_xconnect_details_t * mp)
19382 {
19383   vat_main_t *vam = &vat_main;
19384   vat_json_node_t *node = NULL;
19385
19386   if (VAT_JSON_ARRAY != vam->json_tree.type)
19387     {
19388       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19389       vat_json_init_array (&vam->json_tree);
19390     }
19391   node = vat_json_array_add (&vam->json_tree);
19392
19393   vat_json_init_object (node);
19394   vat_json_object_add_uint (node, "rx_sw_if_index",
19395                             ntohl (mp->rx_sw_if_index));
19396   vat_json_object_add_uint (node, "tx_sw_if_index",
19397                             ntohl (mp->tx_sw_if_index));
19398 }
19399
19400 static int
19401 api_l2_xconnect_dump (vat_main_t * vam)
19402 {
19403   vl_api_l2_xconnect_dump_t *mp;
19404   vl_api_control_ping_t *mp_ping;
19405   int ret;
19406
19407   if (!vam->json_output)
19408     {
19409       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
19410     }
19411
19412   M (L2_XCONNECT_DUMP, mp);
19413
19414   S (mp);
19415
19416   /* Use a control ping for synchronization */
19417   MPING (CONTROL_PING, mp_ping);
19418   S (mp_ping);
19419
19420   W (ret);
19421   return ret;
19422 }
19423
19424 static int
19425 api_hw_interface_set_mtu (vat_main_t * vam)
19426 {
19427   unformat_input_t *i = vam->input;
19428   vl_api_hw_interface_set_mtu_t *mp;
19429   u32 sw_if_index = ~0;
19430   u32 mtu = 0;
19431   int ret;
19432
19433   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19434     {
19435       if (unformat (i, "mtu %d", &mtu))
19436         ;
19437       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19438         ;
19439       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19440         ;
19441       else
19442         break;
19443     }
19444
19445   if (sw_if_index == ~0)
19446     {
19447       errmsg ("missing interface name or sw_if_index");
19448       return -99;
19449     }
19450
19451   if (mtu == 0)
19452     {
19453       errmsg ("no mtu specified");
19454       return -99;
19455     }
19456
19457   /* Construct the API message */
19458   M (HW_INTERFACE_SET_MTU, mp);
19459   mp->sw_if_index = ntohl (sw_if_index);
19460   mp->mtu = ntohs ((u16) mtu);
19461
19462   S (mp);
19463   W (ret);
19464   return ret;
19465 }
19466
19467 static int
19468 api_p2p_ethernet_add (vat_main_t * vam)
19469 {
19470   unformat_input_t *i = vam->input;
19471   vl_api_p2p_ethernet_add_t *mp;
19472   u32 parent_if_index = ~0;
19473   u32 sub_id = ~0;
19474   u8 remote_mac[6];
19475   u8 mac_set = 0;
19476   int ret;
19477
19478   clib_memset (remote_mac, 0, sizeof (remote_mac));
19479   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19480     {
19481       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
19482         ;
19483       else if (unformat (i, "sw_if_index %d", &parent_if_index))
19484         ;
19485       else
19486         if (unformat
19487             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
19488         mac_set++;
19489       else if (unformat (i, "sub_id %d", &sub_id))
19490         ;
19491       else
19492         {
19493           clib_warning ("parse error '%U'", format_unformat_error, i);
19494           return -99;
19495         }
19496     }
19497
19498   if (parent_if_index == ~0)
19499     {
19500       errmsg ("missing interface name or sw_if_index");
19501       return -99;
19502     }
19503   if (mac_set == 0)
19504     {
19505       errmsg ("missing remote mac address");
19506       return -99;
19507     }
19508   if (sub_id == ~0)
19509     {
19510       errmsg ("missing sub-interface id");
19511       return -99;
19512     }
19513
19514   M (P2P_ETHERNET_ADD, mp);
19515   mp->parent_if_index = ntohl (parent_if_index);
19516   mp->subif_id = ntohl (sub_id);
19517   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
19518
19519   S (mp);
19520   W (ret);
19521   return ret;
19522 }
19523
19524 static int
19525 api_p2p_ethernet_del (vat_main_t * vam)
19526 {
19527   unformat_input_t *i = vam->input;
19528   vl_api_p2p_ethernet_del_t *mp;
19529   u32 parent_if_index = ~0;
19530   u8 remote_mac[6];
19531   u8 mac_set = 0;
19532   int ret;
19533
19534   clib_memset (remote_mac, 0, sizeof (remote_mac));
19535   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19536     {
19537       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
19538         ;
19539       else if (unformat (i, "sw_if_index %d", &parent_if_index))
19540         ;
19541       else
19542         if (unformat
19543             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
19544         mac_set++;
19545       else
19546         {
19547           clib_warning ("parse error '%U'", format_unformat_error, i);
19548           return -99;
19549         }
19550     }
19551
19552   if (parent_if_index == ~0)
19553     {
19554       errmsg ("missing interface name or sw_if_index");
19555       return -99;
19556     }
19557   if (mac_set == 0)
19558     {
19559       errmsg ("missing remote mac address");
19560       return -99;
19561     }
19562
19563   M (P2P_ETHERNET_DEL, mp);
19564   mp->parent_if_index = ntohl (parent_if_index);
19565   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
19566
19567   S (mp);
19568   W (ret);
19569   return ret;
19570 }
19571
19572 static int
19573 api_lldp_config (vat_main_t * vam)
19574 {
19575   unformat_input_t *i = vam->input;
19576   vl_api_lldp_config_t *mp;
19577   int tx_hold = 0;
19578   int tx_interval = 0;
19579   u8 *sys_name = NULL;
19580   int ret;
19581
19582   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19583     {
19584       if (unformat (i, "system-name %s", &sys_name))
19585         ;
19586       else if (unformat (i, "tx-hold %d", &tx_hold))
19587         ;
19588       else if (unformat (i, "tx-interval %d", &tx_interval))
19589         ;
19590       else
19591         {
19592           clib_warning ("parse error '%U'", format_unformat_error, i);
19593           return -99;
19594         }
19595     }
19596
19597   vec_add1 (sys_name, 0);
19598
19599   M (LLDP_CONFIG, mp);
19600   mp->tx_hold = htonl (tx_hold);
19601   mp->tx_interval = htonl (tx_interval);
19602   clib_memcpy (mp->system_name, sys_name, vec_len (sys_name));
19603   vec_free (sys_name);
19604
19605   S (mp);
19606   W (ret);
19607   return ret;
19608 }
19609
19610 static int
19611 api_sw_interface_set_lldp (vat_main_t * vam)
19612 {
19613   unformat_input_t *i = vam->input;
19614   vl_api_sw_interface_set_lldp_t *mp;
19615   u32 sw_if_index = ~0;
19616   u32 enable = 1;
19617   u8 *port_desc = NULL, *mgmt_oid = NULL;
19618   ip4_address_t ip4_addr;
19619   ip6_address_t ip6_addr;
19620   int ret;
19621
19622   clib_memset (&ip4_addr, 0, sizeof (ip4_addr));
19623   clib_memset (&ip6_addr, 0, sizeof (ip6_addr));
19624
19625   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19626     {
19627       if (unformat (i, "disable"))
19628         enable = 0;
19629       else
19630         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19631         ;
19632       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19633         ;
19634       else if (unformat (i, "port-desc %s", &port_desc))
19635         ;
19636       else if (unformat (i, "mgmt-ip4 %U", unformat_ip4_address, &ip4_addr))
19637         ;
19638       else if (unformat (i, "mgmt-ip6 %U", unformat_ip6_address, &ip6_addr))
19639         ;
19640       else if (unformat (i, "mgmt-oid %s", &mgmt_oid))
19641         ;
19642       else
19643         break;
19644     }
19645
19646   if (sw_if_index == ~0)
19647     {
19648       errmsg ("missing interface name or sw_if_index");
19649       return -99;
19650     }
19651
19652   /* Construct the API message */
19653   vec_add1 (port_desc, 0);
19654   vec_add1 (mgmt_oid, 0);
19655   M (SW_INTERFACE_SET_LLDP, mp);
19656   mp->sw_if_index = ntohl (sw_if_index);
19657   mp->enable = enable;
19658   clib_memcpy (mp->port_desc, port_desc, vec_len (port_desc));
19659   clib_memcpy (mp->mgmt_oid, mgmt_oid, vec_len (mgmt_oid));
19660   clib_memcpy (mp->mgmt_ip4, &ip4_addr, sizeof (ip4_addr));
19661   clib_memcpy (mp->mgmt_ip6, &ip6_addr, sizeof (ip6_addr));
19662   vec_free (port_desc);
19663   vec_free (mgmt_oid);
19664
19665   S (mp);
19666   W (ret);
19667   return ret;
19668 }
19669
19670 static int
19671 api_tcp_configure_src_addresses (vat_main_t * vam)
19672 {
19673   vl_api_tcp_configure_src_addresses_t *mp;
19674   unformat_input_t *i = vam->input;
19675   vl_api_address_t first, last;
19676   u8 range_set = 0;
19677   u32 vrf_id = 0;
19678   int ret;
19679
19680   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19681     {
19682       if (unformat (i, "%U - %U",
19683                     unformat_vl_api_address, &first,
19684                     unformat_vl_api_address, &last))
19685         {
19686           if (range_set)
19687             {
19688               errmsg ("one range per message (range already set)");
19689               return -99;
19690             }
19691           range_set = 1;
19692         }
19693       else if (unformat (i, "vrf %d", &vrf_id))
19694         ;
19695       else
19696         break;
19697     }
19698
19699   if (range_set == 0)
19700     {
19701       errmsg ("address range not set");
19702       return -99;
19703     }
19704
19705   M (TCP_CONFIGURE_SRC_ADDRESSES, mp);
19706
19707   mp->vrf_id = ntohl (vrf_id);
19708   clib_memcpy (&mp->first_address, &first, sizeof (first));
19709   clib_memcpy (&mp->last_address, &last, sizeof (last));
19710
19711   S (mp);
19712   W (ret);
19713   return ret;
19714 }
19715
19716 static void vl_api_app_namespace_add_del_reply_t_handler
19717   (vl_api_app_namespace_add_del_reply_t * mp)
19718 {
19719   vat_main_t *vam = &vat_main;
19720   i32 retval = ntohl (mp->retval);
19721   if (vam->async_mode)
19722     {
19723       vam->async_errors += (retval < 0);
19724     }
19725   else
19726     {
19727       vam->retval = retval;
19728       if (retval == 0)
19729         errmsg ("app ns index %d\n", ntohl (mp->appns_index));
19730       vam->result_ready = 1;
19731     }
19732 }
19733
19734 static void vl_api_app_namespace_add_del_reply_t_handler_json
19735   (vl_api_app_namespace_add_del_reply_t * mp)
19736 {
19737   vat_main_t *vam = &vat_main;
19738   vat_json_node_t node;
19739
19740   vat_json_init_object (&node);
19741   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
19742   vat_json_object_add_uint (&node, "appns_index", ntohl (mp->appns_index));
19743
19744   vat_json_print (vam->ofp, &node);
19745   vat_json_free (&node);
19746
19747   vam->retval = ntohl (mp->retval);
19748   vam->result_ready = 1;
19749 }
19750
19751 static int
19752 api_app_namespace_add_del (vat_main_t * vam)
19753 {
19754   vl_api_app_namespace_add_del_t *mp;
19755   unformat_input_t *i = vam->input;
19756   u8 *ns_id = 0, secret_set = 0, sw_if_index_set = 0;
19757   u32 sw_if_index, ip4_fib_id, ip6_fib_id;
19758   u64 secret;
19759   int ret;
19760
19761   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19762     {
19763       if (unformat (i, "id %_%v%_", &ns_id))
19764         ;
19765       else if (unformat (i, "secret %lu", &secret))
19766         secret_set = 1;
19767       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19768         sw_if_index_set = 1;
19769       else if (unformat (i, "ip4_fib_id %d", &ip4_fib_id))
19770         ;
19771       else if (unformat (i, "ip6_fib_id %d", &ip6_fib_id))
19772         ;
19773       else
19774         break;
19775     }
19776   if (!ns_id || !secret_set || !sw_if_index_set)
19777     {
19778       errmsg ("namespace id, secret and sw_if_index must be set");
19779       return -99;
19780     }
19781   if (vec_len (ns_id) > 64)
19782     {
19783       errmsg ("namespace id too long");
19784       return -99;
19785     }
19786   M (APP_NAMESPACE_ADD_DEL, mp);
19787
19788   clib_memcpy (mp->namespace_id, ns_id, vec_len (ns_id));
19789   mp->namespace_id_len = vec_len (ns_id);
19790   mp->secret = clib_host_to_net_u64 (secret);
19791   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
19792   mp->ip4_fib_id = clib_host_to_net_u32 (ip4_fib_id);
19793   mp->ip6_fib_id = clib_host_to_net_u32 (ip6_fib_id);
19794   vec_free (ns_id);
19795   S (mp);
19796   W (ret);
19797   return ret;
19798 }
19799
19800 static int
19801 api_sock_init_shm (vat_main_t * vam)
19802 {
19803 #if VPP_API_TEST_BUILTIN == 0
19804   unformat_input_t *i = vam->input;
19805   vl_api_shm_elem_config_t *config = 0;
19806   u64 size = 64 << 20;
19807   int rv;
19808
19809   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19810     {
19811       if (unformat (i, "size %U", unformat_memory_size, &size))
19812         ;
19813       else
19814         break;
19815     }
19816
19817   /*
19818    * Canned custom ring allocator config.
19819    * Should probably parse all of this
19820    */
19821   vec_validate (config, 6);
19822   config[0].type = VL_API_VLIB_RING;
19823   config[0].size = 256;
19824   config[0].count = 32;
19825
19826   config[1].type = VL_API_VLIB_RING;
19827   config[1].size = 1024;
19828   config[1].count = 16;
19829
19830   config[2].type = VL_API_VLIB_RING;
19831   config[2].size = 4096;
19832   config[2].count = 2;
19833
19834   config[3].type = VL_API_CLIENT_RING;
19835   config[3].size = 256;
19836   config[3].count = 32;
19837
19838   config[4].type = VL_API_CLIENT_RING;
19839   config[4].size = 1024;
19840   config[4].count = 16;
19841
19842   config[5].type = VL_API_CLIENT_RING;
19843   config[5].size = 4096;
19844   config[5].count = 2;
19845
19846   config[6].type = VL_API_QUEUE;
19847   config[6].count = 128;
19848   config[6].size = sizeof (uword);
19849
19850   rv = vl_socket_client_init_shm (config, 1 /* want_pthread */ );
19851   if (!rv)
19852     vam->client_index_invalid = 1;
19853   return rv;
19854 #else
19855   return -99;
19856 #endif
19857 }
19858
19859 static void
19860 vl_api_session_rules_details_t_handler (vl_api_session_rules_details_t * mp)
19861 {
19862   vat_main_t *vam = &vat_main;
19863
19864   if (mp->is_ip4)
19865     {
19866       print (vam->ofp,
19867              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
19868              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
19869              mp->scope, format_ip4_address, &mp->lcl_ip, mp->lcl_plen,
19870              clib_net_to_host_u16 (mp->lcl_port), format_ip4_address,
19871              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
19872              clib_net_to_host_u32 (mp->action_index), mp->tag);
19873     }
19874   else
19875     {
19876       print (vam->ofp,
19877              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
19878              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
19879              mp->scope, format_ip6_address, &mp->lcl_ip, mp->lcl_plen,
19880              clib_net_to_host_u16 (mp->lcl_port), format_ip6_address,
19881              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
19882              clib_net_to_host_u32 (mp->action_index), mp->tag);
19883     }
19884 }
19885
19886 static void
19887 vl_api_session_rules_details_t_handler_json (vl_api_session_rules_details_t *
19888                                              mp)
19889 {
19890   vat_main_t *vam = &vat_main;
19891   vat_json_node_t *node = NULL;
19892   struct in6_addr ip6;
19893   struct in_addr ip4;
19894
19895   if (VAT_JSON_ARRAY != vam->json_tree.type)
19896     {
19897       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19898       vat_json_init_array (&vam->json_tree);
19899     }
19900   node = vat_json_array_add (&vam->json_tree);
19901   vat_json_init_object (node);
19902
19903   vat_json_object_add_uint (node, "is_ip4", mp->is_ip4 ? 1 : 0);
19904   vat_json_object_add_uint (node, "appns_index",
19905                             clib_net_to_host_u32 (mp->appns_index));
19906   vat_json_object_add_uint (node, "transport_proto", mp->transport_proto);
19907   vat_json_object_add_uint (node, "scope", mp->scope);
19908   vat_json_object_add_uint (node, "action_index",
19909                             clib_net_to_host_u32 (mp->action_index));
19910   vat_json_object_add_uint (node, "lcl_port",
19911                             clib_net_to_host_u16 (mp->lcl_port));
19912   vat_json_object_add_uint (node, "rmt_port",
19913                             clib_net_to_host_u16 (mp->rmt_port));
19914   vat_json_object_add_uint (node, "lcl_plen", mp->lcl_plen);
19915   vat_json_object_add_uint (node, "rmt_plen", mp->rmt_plen);
19916   vat_json_object_add_string_copy (node, "tag", mp->tag);
19917   if (mp->is_ip4)
19918     {
19919       clib_memcpy (&ip4, mp->lcl_ip, sizeof (ip4));
19920       vat_json_object_add_ip4 (node, "lcl_ip", ip4);
19921       clib_memcpy (&ip4, mp->rmt_ip, sizeof (ip4));
19922       vat_json_object_add_ip4 (node, "rmt_ip", ip4);
19923     }
19924   else
19925     {
19926       clib_memcpy (&ip6, mp->lcl_ip, sizeof (ip6));
19927       vat_json_object_add_ip6 (node, "lcl_ip", ip6);
19928       clib_memcpy (&ip6, mp->rmt_ip, sizeof (ip6));
19929       vat_json_object_add_ip6 (node, "rmt_ip", ip6);
19930     }
19931 }
19932
19933 static int
19934 api_session_rule_add_del (vat_main_t * vam)
19935 {
19936   vl_api_session_rule_add_del_t *mp;
19937   unformat_input_t *i = vam->input;
19938   u32 proto = ~0, lcl_port, rmt_port, action = 0, lcl_plen, rmt_plen;
19939   u32 appns_index = 0, scope = 0;
19940   ip4_address_t lcl_ip4, rmt_ip4;
19941   ip6_address_t lcl_ip6, rmt_ip6;
19942   u8 is_ip4 = 1, conn_set = 0;
19943   u8 is_add = 1, *tag = 0;
19944   int ret;
19945
19946   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19947     {
19948       if (unformat (i, "del"))
19949         is_add = 0;
19950       else if (unformat (i, "add"))
19951         ;
19952       else if (unformat (i, "proto tcp"))
19953         proto = 0;
19954       else if (unformat (i, "proto udp"))
19955         proto = 1;
19956       else if (unformat (i, "appns %d", &appns_index))
19957         ;
19958       else if (unformat (i, "scope %d", &scope))
19959         ;
19960       else if (unformat (i, "tag %_%v%_", &tag))
19961         ;
19962       else
19963         if (unformat
19964             (i, "%U/%d %d %U/%d %d", unformat_ip4_address, &lcl_ip4,
19965              &lcl_plen, &lcl_port, unformat_ip4_address, &rmt_ip4, &rmt_plen,
19966              &rmt_port))
19967         {
19968           is_ip4 = 1;
19969           conn_set = 1;
19970         }
19971       else
19972         if (unformat
19973             (i, "%U/%d %d %U/%d %d", unformat_ip6_address, &lcl_ip6,
19974              &lcl_plen, &lcl_port, unformat_ip6_address, &rmt_ip6, &rmt_plen,
19975              &rmt_port))
19976         {
19977           is_ip4 = 0;
19978           conn_set = 1;
19979         }
19980       else if (unformat (i, "action %d", &action))
19981         ;
19982       else
19983         break;
19984     }
19985   if (proto == ~0 || !conn_set || action == ~0)
19986     {
19987       errmsg ("transport proto, connection and action must be set");
19988       return -99;
19989     }
19990
19991   if (scope > 3)
19992     {
19993       errmsg ("scope should be 0-3");
19994       return -99;
19995     }
19996
19997   M (SESSION_RULE_ADD_DEL, mp);
19998
19999   mp->is_ip4 = is_ip4;
20000   mp->transport_proto = proto;
20001   mp->lcl_port = clib_host_to_net_u16 ((u16) lcl_port);
20002   mp->rmt_port = clib_host_to_net_u16 ((u16) rmt_port);
20003   mp->lcl_plen = lcl_plen;
20004   mp->rmt_plen = rmt_plen;
20005   mp->action_index = clib_host_to_net_u32 (action);
20006   mp->appns_index = clib_host_to_net_u32 (appns_index);
20007   mp->scope = scope;
20008   mp->is_add = is_add;
20009   if (is_ip4)
20010     {
20011       clib_memcpy (mp->lcl_ip, &lcl_ip4, sizeof (lcl_ip4));
20012       clib_memcpy (mp->rmt_ip, &rmt_ip4, sizeof (rmt_ip4));
20013     }
20014   else
20015     {
20016       clib_memcpy (mp->lcl_ip, &lcl_ip6, sizeof (lcl_ip6));
20017       clib_memcpy (mp->rmt_ip, &rmt_ip6, sizeof (rmt_ip6));
20018     }
20019   if (tag)
20020     {
20021       clib_memcpy (mp->tag, tag, vec_len (tag));
20022       vec_free (tag);
20023     }
20024
20025   S (mp);
20026   W (ret);
20027   return ret;
20028 }
20029
20030 static int
20031 api_session_rules_dump (vat_main_t * vam)
20032 {
20033   vl_api_session_rules_dump_t *mp;
20034   vl_api_control_ping_t *mp_ping;
20035   int ret;
20036
20037   if (!vam->json_output)
20038     {
20039       print (vam->ofp, "%=20s", "Session Rules");
20040     }
20041
20042   M (SESSION_RULES_DUMP, mp);
20043   /* send it... */
20044   S (mp);
20045
20046   /* Use a control ping for synchronization */
20047   MPING (CONTROL_PING, mp_ping);
20048   S (mp_ping);
20049
20050   /* Wait for a reply... */
20051   W (ret);
20052   return ret;
20053 }
20054
20055 static int
20056 api_ip_container_proxy_add_del (vat_main_t * vam)
20057 {
20058   vl_api_ip_container_proxy_add_del_t *mp;
20059   unformat_input_t *i = vam->input;
20060   u32 sw_if_index = ~0;
20061   vl_api_prefix_t pfx = { };
20062   u8 is_add = 1;
20063   int ret;
20064
20065   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20066     {
20067       if (unformat (i, "del"))
20068         is_add = 0;
20069       else if (unformat (i, "add"))
20070         ;
20071       if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
20072         ;
20073       else if (unformat (i, "sw_if_index %u", &sw_if_index))
20074         ;
20075       else
20076         break;
20077     }
20078   if (sw_if_index == ~0 || pfx.len == 0)
20079     {
20080       errmsg ("address and sw_if_index must be set");
20081       return -99;
20082     }
20083
20084   M (IP_CONTAINER_PROXY_ADD_DEL, mp);
20085
20086   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
20087   mp->is_add = is_add;
20088   clib_memcpy (&mp->pfx, &pfx, sizeof (pfx));
20089
20090   S (mp);
20091   W (ret);
20092   return ret;
20093 }
20094
20095 static int
20096 api_qos_record_enable_disable (vat_main_t * vam)
20097 {
20098   unformat_input_t *i = vam->input;
20099   vl_api_qos_record_enable_disable_t *mp;
20100   u32 sw_if_index, qs = 0xff;
20101   u8 sw_if_index_set = 0;
20102   u8 enable = 1;
20103   int ret;
20104
20105   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20106     {
20107       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20108         sw_if_index_set = 1;
20109       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20110         sw_if_index_set = 1;
20111       else if (unformat (i, "%U", unformat_qos_source, &qs))
20112         ;
20113       else if (unformat (i, "disable"))
20114         enable = 0;
20115       else
20116         {
20117           clib_warning ("parse error '%U'", format_unformat_error, i);
20118           return -99;
20119         }
20120     }
20121
20122   if (sw_if_index_set == 0)
20123     {
20124       errmsg ("missing interface name or sw_if_index");
20125       return -99;
20126     }
20127   if (qs == 0xff)
20128     {
20129       errmsg ("input location must be specified");
20130       return -99;
20131     }
20132
20133   M (QOS_RECORD_ENABLE_DISABLE, mp);
20134
20135   mp->record.sw_if_index = ntohl (sw_if_index);
20136   mp->record.input_source = qs;
20137   mp->enable = enable;
20138
20139   S (mp);
20140   W (ret);
20141   return ret;
20142 }
20143
20144
20145 static int
20146 q_or_quit (vat_main_t * vam)
20147 {
20148 #if VPP_API_TEST_BUILTIN == 0
20149   longjmp (vam->jump_buf, 1);
20150 #endif
20151   return 0;                     /* not so much */
20152 }
20153
20154 static int
20155 q (vat_main_t * vam)
20156 {
20157   return q_or_quit (vam);
20158 }
20159
20160 static int
20161 quit (vat_main_t * vam)
20162 {
20163   return q_or_quit (vam);
20164 }
20165
20166 static int
20167 comment (vat_main_t * vam)
20168 {
20169   return 0;
20170 }
20171
20172 static int
20173 elog_save (vat_main_t * vam)
20174 {
20175 #if VPP_API_TEST_BUILTIN == 0
20176   elog_main_t *em = &vam->elog_main;
20177   unformat_input_t *i = vam->input;
20178   char *file, *chroot_file;
20179   clib_error_t *error;
20180
20181   if (!unformat (i, "%s", &file))
20182     {
20183       errmsg ("expected file name, got `%U'", format_unformat_error, i);
20184       return 0;
20185     }
20186
20187   /* It's fairly hard to get "../oopsie" through unformat; just in case */
20188   if (strstr (file, "..") || index (file, '/'))
20189     {
20190       errmsg ("illegal characters in filename '%s'", file);
20191       return 0;
20192     }
20193
20194   chroot_file = (char *) format (0, "/tmp/%s%c", file, 0);
20195
20196   vec_free (file);
20197
20198   errmsg ("Saving %wd of %wd events to %s",
20199           elog_n_events_in_buffer (em),
20200           elog_buffer_capacity (em), chroot_file);
20201
20202   error = elog_write_file (em, chroot_file, 1 /* flush ring */ );
20203   vec_free (chroot_file);
20204
20205   if (error)
20206     clib_error_report (error);
20207 #else
20208   errmsg ("Use the vpp event loger...");
20209 #endif
20210
20211   return 0;
20212 }
20213
20214 static int
20215 elog_setup (vat_main_t * vam)
20216 {
20217 #if VPP_API_TEST_BUILTIN == 0
20218   elog_main_t *em = &vam->elog_main;
20219   unformat_input_t *i = vam->input;
20220   u32 nevents = 128 << 10;
20221
20222   (void) unformat (i, "nevents %d", &nevents);
20223
20224   elog_init (em, nevents);
20225   vl_api_set_elog_main (em);
20226   vl_api_set_elog_trace_api_messages (1);
20227   errmsg ("Event logger initialized with %u events", nevents);
20228 #else
20229   errmsg ("Use the vpp event loger...");
20230 #endif
20231   return 0;
20232 }
20233
20234 static int
20235 elog_enable (vat_main_t * vam)
20236 {
20237 #if VPP_API_TEST_BUILTIN == 0
20238   elog_main_t *em = &vam->elog_main;
20239
20240   elog_enable_disable (em, 1 /* enable */ );
20241   vl_api_set_elog_trace_api_messages (1);
20242   errmsg ("Event logger enabled...");
20243 #else
20244   errmsg ("Use the vpp event loger...");
20245 #endif
20246   return 0;
20247 }
20248
20249 static int
20250 elog_disable (vat_main_t * vam)
20251 {
20252 #if VPP_API_TEST_BUILTIN == 0
20253   elog_main_t *em = &vam->elog_main;
20254
20255   elog_enable_disable (em, 0 /* enable */ );
20256   vl_api_set_elog_trace_api_messages (1);
20257   errmsg ("Event logger disabled...");
20258 #else
20259   errmsg ("Use the vpp event loger...");
20260 #endif
20261   return 0;
20262 }
20263
20264 static int
20265 statseg (vat_main_t * vam)
20266 {
20267   ssvm_private_t *ssvmp = &vam->stat_segment;
20268   ssvm_shared_header_t *shared_header = ssvmp->sh;
20269   vlib_counter_t **counters;
20270   u64 thread0_index1_packets;
20271   u64 thread0_index1_bytes;
20272   f64 vector_rate, input_rate;
20273   uword *p;
20274
20275   uword *counter_vector_by_name;
20276   if (vam->stat_segment_lockp == 0)
20277     {
20278       errmsg ("Stat segment not mapped...");
20279       return -99;
20280     }
20281
20282   /* look up "/if/rx for sw_if_index 1 as a test */
20283
20284   clib_spinlock_lock (vam->stat_segment_lockp);
20285
20286   counter_vector_by_name = (uword *) shared_header->opaque[1];
20287
20288   p = hash_get_mem (counter_vector_by_name, "/if/rx");
20289   if (p == 0)
20290     {
20291       clib_spinlock_unlock (vam->stat_segment_lockp);
20292       errmsg ("/if/tx not found?");
20293       return -99;
20294     }
20295
20296   /* Fish per-thread vector of combined counters from shared memory */
20297   counters = (vlib_counter_t **) p[0];
20298
20299   if (vec_len (counters[0]) < 2)
20300     {
20301       clib_spinlock_unlock (vam->stat_segment_lockp);
20302       errmsg ("/if/tx vector length %d", vec_len (counters[0]));
20303       return -99;
20304     }
20305
20306   /* Read thread 0 sw_if_index 1 counter */
20307   thread0_index1_packets = counters[0][1].packets;
20308   thread0_index1_bytes = counters[0][1].bytes;
20309
20310   p = hash_get_mem (counter_vector_by_name, "vector_rate");
20311   if (p == 0)
20312     {
20313       clib_spinlock_unlock (vam->stat_segment_lockp);
20314       errmsg ("vector_rate not found?");
20315       return -99;
20316     }
20317
20318   vector_rate = *(f64 *) (p[0]);
20319   p = hash_get_mem (counter_vector_by_name, "input_rate");
20320   if (p == 0)
20321     {
20322       clib_spinlock_unlock (vam->stat_segment_lockp);
20323       errmsg ("input_rate not found?");
20324       return -99;
20325     }
20326   input_rate = *(f64 *) (p[0]);
20327
20328   clib_spinlock_unlock (vam->stat_segment_lockp);
20329
20330   print (vam->ofp, "vector_rate %.2f input_rate %.2f",
20331          vector_rate, input_rate);
20332   print (vam->ofp, "thread 0 sw_if_index 1 rx pkts %lld, bytes %lld",
20333          thread0_index1_packets, thread0_index1_bytes);
20334
20335   return 0;
20336 }
20337
20338 static int
20339 cmd_cmp (void *a1, void *a2)
20340 {
20341   u8 **c1 = a1;
20342   u8 **c2 = a2;
20343
20344   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
20345 }
20346
20347 static int
20348 help (vat_main_t * vam)
20349 {
20350   u8 **cmds = 0;
20351   u8 *name = 0;
20352   hash_pair_t *p;
20353   unformat_input_t *i = vam->input;
20354   int j;
20355
20356   if (unformat (i, "%s", &name))
20357     {
20358       uword *hs;
20359
20360       vec_add1 (name, 0);
20361
20362       hs = hash_get_mem (vam->help_by_name, name);
20363       if (hs)
20364         print (vam->ofp, "usage: %s %s", name, hs[0]);
20365       else
20366         print (vam->ofp, "No such msg / command '%s'", name);
20367       vec_free (name);
20368       return 0;
20369     }
20370
20371   print (vam->ofp, "Help is available for the following:");
20372
20373     /* *INDENT-OFF* */
20374     hash_foreach_pair (p, vam->function_by_name,
20375     ({
20376       vec_add1 (cmds, (u8 *)(p->key));
20377     }));
20378     /* *INDENT-ON* */
20379
20380   vec_sort_with_function (cmds, cmd_cmp);
20381
20382   for (j = 0; j < vec_len (cmds); j++)
20383     print (vam->ofp, "%s", cmds[j]);
20384
20385   vec_free (cmds);
20386   return 0;
20387 }
20388
20389 static int
20390 set (vat_main_t * vam)
20391 {
20392   u8 *name = 0, *value = 0;
20393   unformat_input_t *i = vam->input;
20394
20395   if (unformat (i, "%s", &name))
20396     {
20397       /* The input buffer is a vector, not a string. */
20398       value = vec_dup (i->buffer);
20399       vec_delete (value, i->index, 0);
20400       /* Almost certainly has a trailing newline */
20401       if (value[vec_len (value) - 1] == '\n')
20402         value[vec_len (value) - 1] = 0;
20403       /* Make sure it's a proper string, one way or the other */
20404       vec_add1 (value, 0);
20405       (void) clib_macro_set_value (&vam->macro_main,
20406                                    (char *) name, (char *) value);
20407     }
20408   else
20409     errmsg ("usage: set <name> <value>");
20410
20411   vec_free (name);
20412   vec_free (value);
20413   return 0;
20414 }
20415
20416 static int
20417 unset (vat_main_t * vam)
20418 {
20419   u8 *name = 0;
20420
20421   if (unformat (vam->input, "%s", &name))
20422     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
20423       errmsg ("unset: %s wasn't set", name);
20424   vec_free (name);
20425   return 0;
20426 }
20427
20428 typedef struct
20429 {
20430   u8 *name;
20431   u8 *value;
20432 } macro_sort_t;
20433
20434
20435 static int
20436 macro_sort_cmp (void *a1, void *a2)
20437 {
20438   macro_sort_t *s1 = a1;
20439   macro_sort_t *s2 = a2;
20440
20441   return strcmp ((char *) (s1->name), (char *) (s2->name));
20442 }
20443
20444 static int
20445 dump_macro_table (vat_main_t * vam)
20446 {
20447   macro_sort_t *sort_me = 0, *sm;
20448   int i;
20449   hash_pair_t *p;
20450
20451     /* *INDENT-OFF* */
20452     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
20453     ({
20454       vec_add2 (sort_me, sm, 1);
20455       sm->name = (u8 *)(p->key);
20456       sm->value = (u8 *) (p->value[0]);
20457     }));
20458     /* *INDENT-ON* */
20459
20460   vec_sort_with_function (sort_me, macro_sort_cmp);
20461
20462   if (vec_len (sort_me))
20463     print (vam->ofp, "%-15s%s", "Name", "Value");
20464   else
20465     print (vam->ofp, "The macro table is empty...");
20466
20467   for (i = 0; i < vec_len (sort_me); i++)
20468     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
20469   return 0;
20470 }
20471
20472 static int
20473 dump_node_table (vat_main_t * vam)
20474 {
20475   int i, j;
20476   vlib_node_t *node, *next_node;
20477
20478   if (vec_len (vam->graph_nodes) == 0)
20479     {
20480       print (vam->ofp, "Node table empty, issue get_node_graph...");
20481       return 0;
20482     }
20483
20484   for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
20485     {
20486       node = vam->graph_nodes[0][i];
20487       print (vam->ofp, "[%d] %s", i, node->name);
20488       for (j = 0; j < vec_len (node->next_nodes); j++)
20489         {
20490           if (node->next_nodes[j] != ~0)
20491             {
20492               next_node = vam->graph_nodes[0][node->next_nodes[j]];
20493               print (vam->ofp, "  [%d] %s", j, next_node->name);
20494             }
20495         }
20496     }
20497   return 0;
20498 }
20499
20500 static int
20501 value_sort_cmp (void *a1, void *a2)
20502 {
20503   name_sort_t *n1 = a1;
20504   name_sort_t *n2 = a2;
20505
20506   if (n1->value < n2->value)
20507     return -1;
20508   if (n1->value > n2->value)
20509     return 1;
20510   return 0;
20511 }
20512
20513
20514 static int
20515 dump_msg_api_table (vat_main_t * vam)
20516 {
20517   api_main_t *am = vlibapi_get_main ();
20518   name_sort_t *nses = 0, *ns;
20519   hash_pair_t *hp;
20520   int i;
20521
20522   /* *INDENT-OFF* */
20523   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
20524   ({
20525     vec_add2 (nses, ns, 1);
20526     ns->name = (u8 *)(hp->key);
20527     ns->value = (u32) hp->value[0];
20528   }));
20529   /* *INDENT-ON* */
20530
20531   vec_sort_with_function (nses, value_sort_cmp);
20532
20533   for (i = 0; i < vec_len (nses); i++)
20534     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
20535   vec_free (nses);
20536   return 0;
20537 }
20538
20539 static int
20540 get_msg_id (vat_main_t * vam)
20541 {
20542   u8 *name_and_crc;
20543   u32 message_index;
20544
20545   if (unformat (vam->input, "%s", &name_and_crc))
20546     {
20547       message_index = vl_msg_api_get_msg_index (name_and_crc);
20548       if (message_index == ~0)
20549         {
20550           print (vam->ofp, " '%s' not found", name_and_crc);
20551           return 0;
20552         }
20553       print (vam->ofp, " '%s' has message index %d",
20554              name_and_crc, message_index);
20555       return 0;
20556     }
20557   errmsg ("name_and_crc required...");
20558   return 0;
20559 }
20560
20561 static int
20562 search_node_table (vat_main_t * vam)
20563 {
20564   unformat_input_t *line_input = vam->input;
20565   u8 *node_to_find;
20566   int j;
20567   vlib_node_t *node, *next_node;
20568   uword *p;
20569
20570   if (vam->graph_node_index_by_name == 0)
20571     {
20572       print (vam->ofp, "Node table empty, issue get_node_graph...");
20573       return 0;
20574     }
20575
20576   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
20577     {
20578       if (unformat (line_input, "%s", &node_to_find))
20579         {
20580           vec_add1 (node_to_find, 0);
20581           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
20582           if (p == 0)
20583             {
20584               print (vam->ofp, "%s not found...", node_to_find);
20585               goto out;
20586             }
20587           node = vam->graph_nodes[0][p[0]];
20588           print (vam->ofp, "[%d] %s", p[0], node->name);
20589           for (j = 0; j < vec_len (node->next_nodes); j++)
20590             {
20591               if (node->next_nodes[j] != ~0)
20592                 {
20593                   next_node = vam->graph_nodes[0][node->next_nodes[j]];
20594                   print (vam->ofp, "  [%d] %s", j, next_node->name);
20595                 }
20596             }
20597         }
20598
20599       else
20600         {
20601           clib_warning ("parse error '%U'", format_unformat_error,
20602                         line_input);
20603           return -99;
20604         }
20605
20606     out:
20607       vec_free (node_to_find);
20608
20609     }
20610
20611   return 0;
20612 }
20613
20614
20615 static int
20616 script (vat_main_t * vam)
20617 {
20618 #if (VPP_API_TEST_BUILTIN==0)
20619   u8 *s = 0;
20620   char *save_current_file;
20621   unformat_input_t save_input;
20622   jmp_buf save_jump_buf;
20623   u32 save_line_number;
20624
20625   FILE *new_fp, *save_ifp;
20626
20627   if (unformat (vam->input, "%s", &s))
20628     {
20629       new_fp = fopen ((char *) s, "r");
20630       if (new_fp == 0)
20631         {
20632           errmsg ("Couldn't open script file %s", s);
20633           vec_free (s);
20634           return -99;
20635         }
20636     }
20637   else
20638     {
20639       errmsg ("Missing script name");
20640       return -99;
20641     }
20642
20643   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
20644   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
20645   save_ifp = vam->ifp;
20646   save_line_number = vam->input_line_number;
20647   save_current_file = (char *) vam->current_file;
20648
20649   vam->input_line_number = 0;
20650   vam->ifp = new_fp;
20651   vam->current_file = s;
20652   do_one_file (vam);
20653
20654   clib_memcpy (&vam->input, &save_input, sizeof (save_input));
20655   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
20656   vam->ifp = save_ifp;
20657   vam->input_line_number = save_line_number;
20658   vam->current_file = (u8 *) save_current_file;
20659   vec_free (s);
20660
20661   return 0;
20662 #else
20663   clib_warning ("use the exec command...");
20664   return -99;
20665 #endif
20666 }
20667
20668 static int
20669 echo (vat_main_t * vam)
20670 {
20671   print (vam->ofp, "%v", vam->input->buffer);
20672   return 0;
20673 }
20674
20675 /* List of API message constructors, CLI names map to api_xxx */
20676 #define foreach_vpe_api_msg                                             \
20677 _(create_loopback,"[mac <mac-addr>] [instance <instance>]")             \
20678 _(sw_interface_dump,"")                                                 \
20679 _(sw_interface_set_flags,                                               \
20680   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
20681 _(sw_interface_add_del_address,                                         \
20682   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
20683 _(sw_interface_set_rx_mode,                                             \
20684   "<intfc> | sw_if_index <id> [queue <id>] <polling | interrupt | adaptive>") \
20685 _(sw_interface_set_rx_placement,                                        \
20686   "<intfc> | sw_if_index <id> [queue <id>] [worker <id> | main]")       \
20687 _(sw_interface_rx_placement_dump,                                       \
20688   "[<intfc> | sw_if_index <id>]")                                         \
20689 _(sw_interface_set_table,                                               \
20690   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
20691 _(sw_interface_set_mpls_enable,                                         \
20692   "<intfc> | sw_if_index [disable | dis]")                              \
20693 _(sw_interface_set_vpath,                                               \
20694   "<intfc> | sw_if_index <id> enable | disable")                        \
20695 _(sw_interface_set_vxlan_bypass,                                        \
20696   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
20697 _(sw_interface_set_geneve_bypass,                                       \
20698   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
20699 _(sw_interface_set_l2_xconnect,                                         \
20700   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
20701   "enable | disable")                                                   \
20702 _(sw_interface_set_l2_bridge,                                           \
20703   "{<intfc> | sw_if_index <id>} bd_id <bridge-domain-id>\n"             \
20704   "[shg <split-horizon-group>] [bvi]\n"                                 \
20705   "enable | disable")                                                   \
20706 _(bridge_domain_set_mac_age, "bd_id <bridge-domain-id> mac-age 0-255")  \
20707 _(bridge_domain_add_del,                                                \
20708   "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") \
20709 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
20710 _(l2fib_add_del,                                                        \
20711   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
20712 _(l2fib_flush_bd, "bd_id <bridge-domain-id>")                           \
20713 _(l2fib_flush_int, "<intfc> | sw_if_index <id>")                        \
20714 _(l2_flags,                                                             \
20715   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
20716 _(bridge_flags,                                                         \
20717   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
20718 _(tap_create_v2,                                                        \
20719   "id <num> [hw-addr <mac-addr>] [host-ns <name>] [rx-ring-size <num> [tx-ring-size <num>] [host-mtu-size <mtu>] [gso | no-gso]") \
20720 _(tap_delete_v2,                                                        \
20721   "<vpp-if-name> | sw_if_index <id>")                                   \
20722 _(sw_interface_tap_v2_dump, "")                                         \
20723 _(virtio_pci_create,                                                    \
20724   "pci-addr <pci-address> [use_random_mac | hw-addr <mac-addr>] [features <hex-value>] [gso-enabled]") \
20725 _(virtio_pci_delete,                                                    \
20726   "<vpp-if-name> | sw_if_index <id>")                                   \
20727 _(sw_interface_virtio_pci_dump, "")                                     \
20728 _(bond_create,                                                          \
20729   "[hw-addr <mac-addr>] {round-robin | active-backup | "                \
20730   "broadcast | {lacp | xor} [load-balance { l2 | l23 | l34 }]} "        \
20731   "[id <if-id>]")                                                       \
20732 _(bond_delete,                                                          \
20733   "<vpp-if-name> | sw_if_index <id>")                                   \
20734 _(bond_enslave,                                                         \
20735   "sw_if_index <n> bond <sw_if_index> [is_passive] [is_long_timeout]")  \
20736 _(bond_detach_slave,                                                    \
20737   "sw_if_index <n>")                                                    \
20738  _(sw_interface_set_bond_weight, "<intfc> | sw_if_index <nn> weight <value>") \
20739 _(sw_interface_bond_dump, "")                                           \
20740 _(sw_interface_slave_dump,                                              \
20741   "<vpp-if-name> | sw_if_index <id>")                                   \
20742 _(ip_table_add_del,                                                     \
20743   "table <n> [ipv6] [add | del]\n")                                     \
20744 _(ip_route_add_del,                                                     \
20745   "<addr>/<mask> via <<addr>|<intfc>|sw_if_index <id>|via-label <n>>\n" \
20746   "[table-id <n>] [<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"\
20747   "[weight <n>] [drop] [local] [classify <n>]  [out-label <n>]\n"       \
20748   "[multipath] [count <n>] [del]")                                      \
20749 _(ip_mroute_add_del,                                                    \
20750   "<src> <grp>/<mask> [table-id <n>]\n"                                 \
20751   "[<intfc> | sw_if_index <id>] [local] [del]")                         \
20752 _(mpls_table_add_del,                                                   \
20753   "table <n> [add | del]\n")                                            \
20754 _(mpls_route_add_del,                                                   \
20755   "<label> <eos> via <addr | next-hop-table <n> | via-label <n> |\n"    \
20756   "lookup-ip4-table <n> | lookup-in-ip6-table <n> |\n"                  \
20757   "l2-input-on <intfc> | l2-input-on sw_if_index <id>>\n"               \
20758   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>] [weight <n>]\n"  \
20759   "[drop] [local] [classify <n>] [out-label <n>] [multipath]\n"         \
20760   "[count <n>] [del]")                                                  \
20761 _(mpls_ip_bind_unbind,                                                  \
20762   "<label> <addr/len>")                                                 \
20763 _(mpls_tunnel_add_del,                                                  \
20764   "[add | del <intfc | sw_if_index <id>>] via <addr | via-label <n>>\n" \
20765   "[<intfc> | sw_if_index <id> | next-hop-table <id>]\n"                \
20766   "[l2-only]  [out-label <n>]")                                         \
20767 _(sr_mpls_policy_add,                                                   \
20768   "bsid <id> [weight <n>] [spray] next <sid> [next <sid>]")             \
20769 _(sr_mpls_policy_del,                                                   \
20770   "bsid <id>")                                                          \
20771 _(bier_table_add_del,                                                   \
20772   "<label> <sub-domain> <set> <bsl> [del]")                             \
20773 _(bier_route_add_del,                                                   \
20774   "<bit-position> <sub-domain> <set> <bsl> via <addr> [table-id <n>]\n" \
20775   "[<intfc> | sw_if_index <id>]"                                        \
20776   "[weight <n>] [del] [multipath]")                                     \
20777 _(sw_interface_set_unnumbered,                                          \
20778   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
20779 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
20780 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
20781   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
20782   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
20783   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
20784 _(ip_table_replace_begin, "table <n> [ipv6]")                           \
20785 _(ip_table_flush, "table <n> [ipv6]")                                   \
20786 _(ip_table_replace_end, "table <n> [ipv6]")                             \
20787 _(set_ip_flow_hash,                                                     \
20788   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
20789 _(sw_interface_ip6_enable_disable,                                      \
20790   "<intfc> | sw_if_index <id> enable | disable")                        \
20791 _(l2_patch_add_del,                                                     \
20792   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
20793   "enable | disable")                                                   \
20794 _(sr_localsid_add_del,                                                  \
20795   "(del) address <addr> next_hop <addr> behavior <beh>\n"               \
20796   "fib-table <num> (end.psp) sw_if_index <num>")                        \
20797 _(classify_add_del_table,                                               \
20798   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
20799   " [del] [del-chain] mask <mask-value>\n"                              \
20800   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
20801   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
20802 _(classify_add_del_session,                                             \
20803   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
20804   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
20805   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
20806   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
20807 _(classify_set_interface_ip_table,                                      \
20808   "<intfc> | sw_if_index <nn> table <nn>")                              \
20809 _(classify_set_interface_l2_tables,                                     \
20810   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
20811   "  [other-table <nn>]")                                               \
20812 _(get_node_index, "node <node-name")                                    \
20813 _(add_node_next, "node <node-name> next <next-node-name>")              \
20814 _(l2tpv3_create_tunnel,                                                 \
20815   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
20816   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
20817   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
20818 _(l2tpv3_set_tunnel_cookies,                                            \
20819   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
20820   "[new_remote_cookie <nn>]\n")                                         \
20821 _(l2tpv3_interface_enable_disable,                                      \
20822   "<intfc> | sw_if_index <nn> enable | disable")                        \
20823 _(l2tpv3_set_lookup_key,                                                \
20824   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
20825 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
20826 _(vxlan_offload_rx,                                                     \
20827   "hw { <interface name> | hw_if_index <nn>} "                          \
20828   "rx { <vxlan tunnel name> | sw_if_index <nn> } [del]")                \
20829 _(vxlan_add_del_tunnel,                                                 \
20830   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
20831   "{ <intfc> | mcast_sw_if_index <nn> } [instance <id>]}\n"             \
20832   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
20833 _(geneve_add_del_tunnel,                                                \
20834   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
20835   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
20836   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
20837 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
20838 _(geneve_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                   \
20839 _(gre_tunnel_add_del,                                                   \
20840   "src <ip-addr> dst <ip-addr> [outer-fib-id <nn>] [instance <n>]\n"    \
20841   "[teb | erspan <session-id>] [del]")                                  \
20842 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
20843 _(l2_fib_clear_table, "")                                               \
20844 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
20845 _(l2_interface_vlan_tag_rewrite,                                        \
20846   "<intfc> | sw_if_index <nn> \n"                                       \
20847   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
20848   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
20849 _(create_vhost_user_if,                                                 \
20850         "socket <filename> [server] [renumber <dev_instance>] "         \
20851         "[disable_mrg_rxbuf] [disable_indirect_desc] [gso] "            \
20852         "[mac <mac_address>]")                                          \
20853 _(modify_vhost_user_if,                                                 \
20854         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
20855         "[server] [renumber <dev_instance>] [gso]")                     \
20856 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
20857 _(sw_interface_vhost_user_dump, "")                                     \
20858 _(show_version, "")                                                     \
20859 _(show_threads, "")                                                     \
20860 _(vxlan_gpe_add_del_tunnel,                                             \
20861   "local <addr> remote <addr>  | group <mcast-ip-addr>\n"               \
20862   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
20863   "vni <nn> [encap-vrf-id <nn>] [decap-vrf-id <nn>]\n"                  \
20864   "[next-ip4][next-ip6][next-ethernet] [next-nsh] [del]\n")             \
20865 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
20866 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
20867 _(interface_name_renumber,                                              \
20868   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
20869 _(input_acl_set_interface,                                              \
20870   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
20871   "  [l2-table <nn>] [del]")                                            \
20872 _(want_l2_macs_events, "[disable] [learn-limit <n>] [scan-delay <n>] [max-entries <n>]") \
20873 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
20874 _(ip_dump, "ipv4 | ipv6")                                               \
20875 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
20876 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
20877   "  spid_id <n> ")                                                     \
20878 _(ipsec_sad_entry_add_del, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
20879   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
20880   "  integ_alg <alg> integ_key <hex>")                                  \
20881 _(ipsec_spd_entry_add_del, "spd_id <n> priority <n> action <action>\n"  \
20882   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
20883   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
20884   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
20885 _(ipsec_tunnel_if_add_del, "local_spi <n> remote_spi <n>\n"             \
20886   "  crypto_alg <alg> local_crypto_key <hex> remote_crypto_key <hex>\n" \
20887   "  integ_alg <alg> local_integ_key <hex> remote_integ_key <hex>\n"    \
20888   "  local_ip <addr> remote_ip <addr> [esn] [anti_replay] [del]\n"      \
20889   "  [instance <n>]")     \
20890 _(ipsec_sa_dump, "[sa_id <n>]")                                         \
20891 _(ipsec_tunnel_if_set_sa, "<intfc> sa_id <n> <inbound|outbound>\n")     \
20892 _(delete_loopback,"sw_if_index <nn>")                                   \
20893 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
20894 _(bd_ip_mac_flush, "bd_id <bridge-domain-id>")                          \
20895 _(bd_ip_mac_dump, "[bd_id] <bridge-domain-id>")                         \
20896 _(want_interface_events,  "enable|disable")                             \
20897 _(get_first_msg_id, "client <name>")                                    \
20898 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
20899 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
20900   "fib-id <nn> [ip4][ip6][default]")                                    \
20901 _(get_node_graph, " ")                                                  \
20902 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
20903 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
20904 _(ioam_disable, "")                                                     \
20905 _(one_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
20906                             " sw_if_index <sw_if_index> p <priority> "  \
20907                             "w <weight>] [del]")                        \
20908 _(one_add_del_locator, "locator-set <locator_name> "                    \
20909                         "iface <intf> | sw_if_index <sw_if_index> "     \
20910                         "p <priority> w <weight> [del]")                \
20911 _(one_add_del_local_eid,"vni <vni> eid "                                \
20912                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
20913                          "locator-set <locator_name> [del]"             \
20914                          "[key-id sha1|sha256 secret-key <secret-key>]")\
20915 _(one_add_del_map_resolver, "<ip4|6-addr> [del]")                       \
20916 _(one_add_del_map_server, "<ip4|6-addr> [del]")                         \
20917 _(one_enable_disable, "enable|disable")                                 \
20918 _(one_map_register_enable_disable, "enable|disable")                    \
20919 _(one_map_register_fallback_threshold, "<value>")                       \
20920 _(one_rloc_probe_enable_disable, "enable|disable")                      \
20921 _(one_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "       \
20922                                "[seid <seid>] "                         \
20923                                "rloc <locator> p <prio> "               \
20924                                "w <weight> [rloc <loc> ... ] "          \
20925                                "action <action> [del-all]")             \
20926 _(one_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "    \
20927                           "<local-eid>")                                \
20928 _(one_pitr_set_locator_set, "locator-set <loc-set-name> | del")         \
20929 _(one_use_petr, "ip-address> | disable")                                \
20930 _(one_map_request_mode, "src-dst|dst-only")                             \
20931 _(one_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")            \
20932 _(one_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")               \
20933 _(one_locator_set_dump, "[local | remote]")                             \
20934 _(one_locator_dump, "ls_index <index> | ls_name <name>")                \
20935 _(one_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "       \
20936                        "[local] | [remote]")                            \
20937 _(one_add_del_ndp_entry, "[del] mac <mac> bd <bd> ip6 <ip6>")           \
20938 _(one_ndp_bd_get, "")                                                   \
20939 _(one_ndp_entries_get, "bd <bridge-domain>")                            \
20940 _(one_add_del_l2_arp_entry, "[del] mac <mac> bd <bd> ip4 <ip4>")        \
20941 _(one_l2_arp_bd_get, "")                                                \
20942 _(one_l2_arp_entries_get, "bd <bridge-domain>")                         \
20943 _(one_stats_enable_disable, "enable|disable")                           \
20944 _(show_one_stats_enable_disable, "")                                    \
20945 _(one_eid_table_vni_dump, "")                                           \
20946 _(one_eid_table_map_dump, "l2|l3")                                      \
20947 _(one_map_resolver_dump, "")                                            \
20948 _(one_map_server_dump, "")                                              \
20949 _(one_adjacencies_get, "vni <vni>")                                     \
20950 _(one_nsh_set_locator_set, "[del] ls <locator-set-name>")               \
20951 _(show_one_rloc_probe_state, "")                                        \
20952 _(show_one_map_register_state, "")                                      \
20953 _(show_one_status, "")                                                  \
20954 _(one_stats_dump, "")                                                   \
20955 _(one_stats_flush, "")                                                  \
20956 _(one_get_map_request_itr_rlocs, "")                                    \
20957 _(one_map_register_set_ttl, "<ttl>")                                    \
20958 _(one_set_transport_protocol, "udp|api")                                \
20959 _(one_get_transport_protocol, "")                                       \
20960 _(one_enable_disable_xtr_mode, "enable|disable")                        \
20961 _(one_show_xtr_mode, "")                                                \
20962 _(one_enable_disable_pitr_mode, "enable|disable")                       \
20963 _(one_show_pitr_mode, "")                                               \
20964 _(one_enable_disable_petr_mode, "enable|disable")                       \
20965 _(one_show_petr_mode, "")                                               \
20966 _(show_one_nsh_mapping, "")                                             \
20967 _(show_one_pitr, "")                                                    \
20968 _(show_one_use_petr, "")                                                \
20969 _(show_one_map_request_mode, "")                                        \
20970 _(show_one_map_register_ttl, "")                                        \
20971 _(show_one_map_register_fallback_threshold, "")                         \
20972 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
20973                             " sw_if_index <sw_if_index> p <priority> "  \
20974                             "w <weight>] [del]")                        \
20975 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
20976                         "iface <intf> | sw_if_index <sw_if_index> "     \
20977                         "p <priority> w <weight> [del]")                \
20978 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
20979                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
20980                          "locator-set <locator_name> [del]"             \
20981                          "[key-id sha1|sha256 secret-key <secret-key>]") \
20982 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
20983 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
20984 _(lisp_enable_disable, "enable|disable")                                \
20985 _(lisp_map_register_enable_disable, "enable|disable")                   \
20986 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
20987 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
20988                                "[seid <seid>] "                         \
20989                                "rloc <locator> p <prio> "               \
20990                                "w <weight> [rloc <loc> ... ] "          \
20991                                "action <action> [del-all]")             \
20992 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
20993                           "<local-eid>")                                \
20994 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
20995 _(lisp_use_petr, "<ip-address> | disable")                              \
20996 _(lisp_map_request_mode, "src-dst|dst-only")                            \
20997 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
20998 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
20999 _(lisp_locator_set_dump, "[local | remote]")                            \
21000 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
21001 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
21002                        "[local] | [remote]")                            \
21003 _(lisp_eid_table_vni_dump, "")                                          \
21004 _(lisp_eid_table_map_dump, "l2|l3")                                     \
21005 _(lisp_map_resolver_dump, "")                                           \
21006 _(lisp_map_server_dump, "")                                             \
21007 _(lisp_adjacencies_get, "vni <vni>")                                    \
21008 _(gpe_fwd_entry_vnis_get, "")                                           \
21009 _(gpe_native_fwd_rpaths_get, "ip4 | ip6")                               \
21010 _(gpe_add_del_native_fwd_rpath, "[del] via <nh-ip-addr> [iface] "       \
21011                                 "[table <table-id>]")                   \
21012 _(lisp_gpe_fwd_entries_get, "vni <vni>")                                \
21013 _(lisp_gpe_fwd_entry_path_dump, "index <fwd_entry_index>")              \
21014 _(gpe_set_encap_mode, "lisp|vxlan")                                     \
21015 _(gpe_get_encap_mode, "")                                               \
21016 _(lisp_gpe_add_del_iface, "up|down")                                    \
21017 _(lisp_gpe_enable_disable, "enable|disable")                            \
21018 _(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>"       \
21019   "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
21020 _(show_lisp_rloc_probe_state, "")                                       \
21021 _(show_lisp_map_register_state, "")                                     \
21022 _(show_lisp_status, "")                                                 \
21023 _(lisp_get_map_request_itr_rlocs, "")                                   \
21024 _(show_lisp_pitr, "")                                                   \
21025 _(show_lisp_use_petr, "")                                               \
21026 _(show_lisp_map_request_mode, "")                                       \
21027 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
21028 _(af_packet_delete, "name <host interface name>")                       \
21029 _(af_packet_dump, "")                                                   \
21030 _(policer_add_del, "name <policer name> <params> [del]")                \
21031 _(policer_dump, "[name <policer name>]")                                \
21032 _(policer_classify_set_interface,                                       \
21033   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
21034   "  [l2-table <nn>] [del]")                                            \
21035 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
21036 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
21037     "[master|slave]")                                                   \
21038 _(netmap_delete, "name <interface name>")                               \
21039 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
21040 _(mpls_table_dump, "")                                                  \
21041 _(mpls_route_dump, "table-id <ID>")                                     \
21042 _(classify_table_ids, "")                                               \
21043 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
21044 _(classify_table_info, "table_id <nn>")                                 \
21045 _(classify_session_dump, "table_id <nn>")                               \
21046 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
21047     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
21048     "[template_interval <nn>] [udp_checksum]")                          \
21049 _(ipfix_exporter_dump, "")                                              \
21050 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
21051 _(ipfix_classify_stream_dump, "")                                       \
21052 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
21053 _(ipfix_classify_table_dump, "")                                        \
21054 _(sw_interface_span_enable_disable, "[l2] [src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
21055 _(sw_interface_span_dump, "[l2]")                                           \
21056 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
21057 _(pg_create_interface, "if_id <nn> [gso-enabled gso-size <size>]")      \
21058 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
21059 _(pg_enable_disable, "[stream <id>] disable")                           \
21060 _(ip_source_and_port_range_check_add_del,                               \
21061   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
21062 _(ip_source_and_port_range_check_interface_add_del,                     \
21063   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
21064   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
21065 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
21066 _(l2_interface_pbb_tag_rewrite,                                         \
21067   "<intfc> | sw_if_index <nn> \n"                                       \
21068   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
21069   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
21070 _(set_punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
21071 _(flow_classify_set_interface,                                          \
21072   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
21073 _(flow_classify_dump, "type [ip4|ip6]")                                 \
21074 _(ip_table_dump, "")                                                    \
21075 _(ip_route_dump, "table-id [ip4|ip6]")                                  \
21076 _(ip_mtable_dump, "")                                                   \
21077 _(ip_mroute_dump, "table-id [ip4|ip6]")                                 \
21078 _(feature_enable_disable, "arc_name <arc_name> "                        \
21079   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
21080 _(feature_gso_enable_disable, "<intfc> | sw_if_index <nn> "             \
21081   "[enable | disable] ")                                                \
21082 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
21083 "[disable]")                                                            \
21084 _(sw_interface_add_del_mac_address, "<intfc> | sw_if_index <nn> "       \
21085   "mac <mac-address> [del]")                                            \
21086 _(l2_xconnect_dump, "")                                                 \
21087 _(hw_interface_set_mtu, "<intfc> | hw_if_index <nn> mtu <nn>")        \
21088 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")          \
21089 _(p2p_ethernet_add, "<intfc> | sw_if_index <nn> remote_mac <mac-address> sub_id <id>") \
21090 _(p2p_ethernet_del, "<intfc> | sw_if_index <nn> remote_mac <mac-address>") \
21091 _(lldp_config, "system-name <name> tx-hold <nn> tx-interval <nn>") \
21092 _(sw_interface_set_lldp, "<intfc> | sw_if_index <nn> [port-desc <description>]\n" \
21093   " [mgmt-ip4 <ip4>] [mgmt-ip6 <ip6>] [mgmt-oid <object id>] [disable]") \
21094 _(tcp_configure_src_addresses, "<ip4|6>first-<ip4|6>last [vrf <id>]")   \
21095 _(sock_init_shm, "size <nnn>")                                          \
21096 _(app_namespace_add_del, "[add] id <ns-id> secret <nn> sw_if_index <nn>")\
21097 _(session_rule_add_del, "[add|del] proto <tcp/udp> <lcl-ip>/<plen> "    \
21098   "<lcl-port> <rmt-ip>/<plen> <rmt-port> action <nn>")                  \
21099 _(session_rules_dump, "")                                               \
21100 _(ip_container_proxy_add_del, "[add|del] <address> <sw_if_index>")      \
21101 _(output_acl_set_interface,                                             \
21102   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
21103   "  [l2-table <nn>] [del]")                                            \
21104 _(qos_record_enable_disable, "<record-source> <intfc> | sw_if_index <id> [disable]")
21105
21106 /* List of command functions, CLI names map directly to functions */
21107 #define foreach_cli_function                                    \
21108 _(comment, "usage: comment <ignore-rest-of-line>")              \
21109 _(dump_interface_table, "usage: dump_interface_table")          \
21110 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
21111 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
21112 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
21113 _(dump_macro_table, "usage: dump_macro_table ")                 \
21114 _(dump_node_table, "usage: dump_node_table")                    \
21115 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
21116 _(elog_setup, "usage: elog_setup [nevents, default 128K]")      \
21117 _(elog_disable, "usage: elog_disable")                          \
21118 _(elog_enable, "usage: elog_enable")                            \
21119 _(elog_save, "usage: elog_save <filename>")                     \
21120 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
21121 _(echo, "usage: echo <message>")                                \
21122 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
21123 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
21124 _(help, "usage: help")                                          \
21125 _(q, "usage: quit")                                             \
21126 _(quit, "usage: quit")                                          \
21127 _(search_node_table, "usage: search_node_table <name>...")      \
21128 _(set, "usage: set <variable-name> <value>")                    \
21129 _(script, "usage: script <file-name>")                          \
21130 _(statseg, "usage: statseg")                                    \
21131 _(unset, "usage: unset <variable-name>")
21132
21133 #define _(N,n)                                  \
21134     static void vl_api_##n##_t_handler_uni      \
21135     (vl_api_##n##_t * mp)                       \
21136     {                                           \
21137         vat_main_t * vam = &vat_main;           \
21138         if (vam->json_output) {                 \
21139             vl_api_##n##_t_handler_json(mp);    \
21140         } else {                                \
21141             vl_api_##n##_t_handler(mp);         \
21142         }                                       \
21143     }
21144 foreach_vpe_api_reply_msg;
21145 #if VPP_API_TEST_BUILTIN == 0
21146 foreach_standalone_reply_msg;
21147 #endif
21148 #undef _
21149
21150 void
21151 vat_api_hookup (vat_main_t * vam)
21152 {
21153 #define _(N,n)                                                  \
21154     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
21155                            vl_api_##n##_t_handler_uni,          \
21156                            vl_noop_handler,                     \
21157                            vl_api_##n##_t_endian,               \
21158                            vl_api_##n##_t_print,                \
21159                            sizeof(vl_api_##n##_t), 1);
21160   foreach_vpe_api_reply_msg;
21161 #if VPP_API_TEST_BUILTIN == 0
21162   foreach_standalone_reply_msg;
21163 #endif
21164 #undef _
21165
21166 #if (VPP_API_TEST_BUILTIN==0)
21167   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
21168
21169   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
21170
21171   vam->function_by_name = hash_create_string (0, sizeof (uword));
21172
21173   vam->help_by_name = hash_create_string (0, sizeof (uword));
21174 #endif
21175
21176   /* API messages we can send */
21177 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
21178   foreach_vpe_api_msg;
21179 #undef _
21180
21181   /* Help strings */
21182 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
21183   foreach_vpe_api_msg;
21184 #undef _
21185
21186   /* CLI functions */
21187 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
21188   foreach_cli_function;
21189 #undef _
21190
21191   /* Help strings */
21192 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
21193   foreach_cli_function;
21194 #undef _
21195 }
21196
21197 #if VPP_API_TEST_BUILTIN
21198 static clib_error_t *
21199 vat_api_hookup_shim (vlib_main_t * vm)
21200 {
21201   vat_api_hookup (&vat_main);
21202   return 0;
21203 }
21204
21205 VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
21206 #endif
21207
21208 /*
21209  * fd.io coding-style-patch-verification: ON
21210  *
21211  * Local Variables:
21212  * eval: (c-set-style "gnu")
21213  * End:
21214  */