api: Use vl_msg_push/pop_heap
[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/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_ip4_arp_event_t_handler (vl_api_ip4_arp_event_t * mp)
1433 {
1434   u32 sw_if_index = ntohl (mp->sw_if_index);
1435   errmsg ("arp %s event: pid %d address %U new mac %U sw_if_index %d\n",
1436           mp->mac_ip ? "mac/ip binding" : "address resolution",
1437           ntohl (mp->pid), format_ip4_address, mp->ip,
1438           format_vl_api_mac_address, &mp->mac, sw_if_index);
1439 }
1440
1441 static void
1442 vl_api_ip4_arp_event_t_handler_json (vl_api_ip4_arp_event_t * mp)
1443 {
1444   /* JSON output not supported */
1445 }
1446
1447 static void
1448 vl_api_ip6_nd_event_t_handler (vl_api_ip6_nd_event_t * mp)
1449 {
1450   u32 sw_if_index = ntohl (mp->sw_if_index);
1451   errmsg ("ip6 nd %s event: pid %d address %U new mac %U sw_if_index %d\n",
1452           mp->mac_ip ? "mac/ip binding" : "address resolution",
1453           ntohl (mp->pid), format_vl_api_ip6_address, mp->ip,
1454           format_vl_api_mac_address, mp->mac, sw_if_index);
1455 }
1456
1457 static void
1458 vl_api_ip6_nd_event_t_handler_json (vl_api_ip6_nd_event_t * mp)
1459 {
1460   /* JSON output not supported */
1461 }
1462
1463 static void
1464 vl_api_l2_macs_event_t_handler (vl_api_l2_macs_event_t * mp)
1465 {
1466   u32 n_macs = ntohl (mp->n_macs);
1467   errmsg ("L2MAC event received with pid %d cl-idx %d for %d macs: \n",
1468           ntohl (mp->pid), mp->client_index, n_macs);
1469   int i;
1470   for (i = 0; i < n_macs; i++)
1471     {
1472       vl_api_mac_entry_t *mac = &mp->mac[i];
1473       errmsg (" [%d] sw_if_index %d  mac_addr %U  action %d \n",
1474               i + 1, ntohl (mac->sw_if_index),
1475               format_ethernet_address, mac->mac_addr, mac->action);
1476       if (i == 1000)
1477         break;
1478     }
1479 }
1480
1481 static void
1482 vl_api_l2_macs_event_t_handler_json (vl_api_l2_macs_event_t * mp)
1483 {
1484   /* JSON output not supported */
1485 }
1486
1487 #define vl_api_bridge_domain_details_t_endian vl_noop_handler
1488 #define vl_api_bridge_domain_details_t_print vl_noop_handler
1489
1490 /*
1491  * Special-case: build the bridge domain table, maintain
1492  * the next bd id vbl.
1493  */
1494 static void vl_api_bridge_domain_details_t_handler
1495   (vl_api_bridge_domain_details_t * mp)
1496 {
1497   vat_main_t *vam = &vat_main;
1498   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1499   int i;
1500
1501   print (vam->ofp, "\n%-3s %-3s %-3s %-3s %-3s %-6s %-3s",
1502          " ID", "LRN", "FWD", "FLD", "BVI", "UU-FWD", "#IF");
1503
1504   print (vam->ofp, "%3d %3d %3d %3d %3d %6d %3d",
1505          ntohl (mp->bd_id), mp->learn, mp->forward,
1506          mp->flood, ntohl (mp->bvi_sw_if_index),
1507          ntohl (mp->uu_fwd_sw_if_index), n_sw_ifs);
1508
1509   if (n_sw_ifs)
1510     {
1511       vl_api_bridge_domain_sw_if_t *sw_ifs;
1512       print (vam->ofp, "\n\n%s %s  %s", "sw_if_index", "SHG",
1513              "Interface Name");
1514
1515       sw_ifs = mp->sw_if_details;
1516       for (i = 0; i < n_sw_ifs; i++)
1517         {
1518           u8 *sw_if_name = 0;
1519           u32 sw_if_index;
1520           hash_pair_t *p;
1521
1522           sw_if_index = ntohl (sw_ifs->sw_if_index);
1523
1524           /* *INDENT-OFF* */
1525           hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
1526                              ({
1527                                if ((u32) p->value[0] == sw_if_index)
1528                                  {
1529                                    sw_if_name = (u8 *)(p->key);
1530                                    break;
1531                                  }
1532                              }));
1533           /* *INDENT-ON* */
1534           print (vam->ofp, "%7d     %3d  %s", sw_if_index,
1535                  sw_ifs->shg, sw_if_name ? (char *) sw_if_name :
1536                  "sw_if_index not found!");
1537
1538           sw_ifs++;
1539         }
1540     }
1541 }
1542
1543 static void vl_api_bridge_domain_details_t_handler_json
1544   (vl_api_bridge_domain_details_t * mp)
1545 {
1546   vat_main_t *vam = &vat_main;
1547   vat_json_node_t *node, *array = NULL;
1548   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1549
1550   if (VAT_JSON_ARRAY != vam->json_tree.type)
1551     {
1552       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1553       vat_json_init_array (&vam->json_tree);
1554     }
1555   node = vat_json_array_add (&vam->json_tree);
1556
1557   vat_json_init_object (node);
1558   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1559   vat_json_object_add_uint (node, "flood", mp->flood);
1560   vat_json_object_add_uint (node, "forward", mp->forward);
1561   vat_json_object_add_uint (node, "learn", mp->learn);
1562   vat_json_object_add_uint (node, "bvi_sw_if_index",
1563                             ntohl (mp->bvi_sw_if_index));
1564   vat_json_object_add_uint (node, "n_sw_ifs", n_sw_ifs);
1565   array = vat_json_object_add (node, "sw_if");
1566   vat_json_init_array (array);
1567
1568
1569
1570   if (n_sw_ifs)
1571     {
1572       vl_api_bridge_domain_sw_if_t *sw_ifs;
1573       int i;
1574
1575       sw_ifs = mp->sw_if_details;
1576       for (i = 0; i < n_sw_ifs; i++)
1577         {
1578           node = vat_json_array_add (array);
1579           vat_json_init_object (node);
1580           vat_json_object_add_uint (node, "sw_if_index",
1581                                     ntohl (sw_ifs->sw_if_index));
1582           vat_json_object_add_uint (node, "shg", sw_ifs->shg);
1583           sw_ifs++;
1584         }
1585     }
1586 }
1587
1588 static void vl_api_control_ping_reply_t_handler
1589   (vl_api_control_ping_reply_t * mp)
1590 {
1591   vat_main_t *vam = &vat_main;
1592   i32 retval = ntohl (mp->retval);
1593   if (vam->async_mode)
1594     {
1595       vam->async_errors += (retval < 0);
1596     }
1597   else
1598     {
1599       vam->retval = retval;
1600       vam->result_ready = 1;
1601     }
1602   if (vam->socket_client_main)
1603     vam->socket_client_main->control_pings_outstanding--;
1604 }
1605
1606 static void vl_api_control_ping_reply_t_handler_json
1607   (vl_api_control_ping_reply_t * mp)
1608 {
1609   vat_main_t *vam = &vat_main;
1610   i32 retval = ntohl (mp->retval);
1611
1612   if (VAT_JSON_NONE != vam->json_tree.type)
1613     {
1614       vat_json_print (vam->ofp, &vam->json_tree);
1615       vat_json_free (&vam->json_tree);
1616       vam->json_tree.type = VAT_JSON_NONE;
1617     }
1618   else
1619     {
1620       /* just print [] */
1621       vat_json_init_array (&vam->json_tree);
1622       vat_json_print (vam->ofp, &vam->json_tree);
1623       vam->json_tree.type = VAT_JSON_NONE;
1624     }
1625
1626   vam->retval = retval;
1627   vam->result_ready = 1;
1628 }
1629
1630 static void
1631   vl_api_bridge_domain_set_mac_age_reply_t_handler
1632   (vl_api_bridge_domain_set_mac_age_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_bridge_domain_set_mac_age_reply_t_handler_json
1648   (vl_api_bridge_domain_set_mac_age_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
1656   vat_json_print (vam->ofp, &node);
1657   vat_json_free (&node);
1658
1659   vam->retval = ntohl (mp->retval);
1660   vam->result_ready = 1;
1661 }
1662
1663 static void
1664 vl_api_l2_flags_reply_t_handler (vl_api_l2_flags_reply_t * mp)
1665 {
1666   vat_main_t *vam = &vat_main;
1667   i32 retval = ntohl (mp->retval);
1668   if (vam->async_mode)
1669     {
1670       vam->async_errors += (retval < 0);
1671     }
1672   else
1673     {
1674       vam->retval = retval;
1675       vam->result_ready = 1;
1676     }
1677 }
1678
1679 static void vl_api_l2_flags_reply_t_handler_json
1680   (vl_api_l2_flags_reply_t * mp)
1681 {
1682   vat_main_t *vam = &vat_main;
1683   vat_json_node_t node;
1684
1685   vat_json_init_object (&node);
1686   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1687   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1688                             ntohl (mp->resulting_feature_bitmap));
1689
1690   vat_json_print (vam->ofp, &node);
1691   vat_json_free (&node);
1692
1693   vam->retval = ntohl (mp->retval);
1694   vam->result_ready = 1;
1695 }
1696
1697 static void vl_api_bridge_flags_reply_t_handler
1698   (vl_api_bridge_flags_reply_t * mp)
1699 {
1700   vat_main_t *vam = &vat_main;
1701   i32 retval = ntohl (mp->retval);
1702   if (vam->async_mode)
1703     {
1704       vam->async_errors += (retval < 0);
1705     }
1706   else
1707     {
1708       vam->retval = retval;
1709       vam->result_ready = 1;
1710     }
1711 }
1712
1713 static void vl_api_bridge_flags_reply_t_handler_json
1714   (vl_api_bridge_flags_reply_t * mp)
1715 {
1716   vat_main_t *vam = &vat_main;
1717   vat_json_node_t node;
1718
1719   vat_json_init_object (&node);
1720   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1721   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1722                             ntohl (mp->resulting_feature_bitmap));
1723
1724   vat_json_print (vam->ofp, &node);
1725   vat_json_free (&node);
1726
1727   vam->retval = ntohl (mp->retval);
1728   vam->result_ready = 1;
1729 }
1730
1731 static void
1732 vl_api_tap_create_v2_reply_t_handler (vl_api_tap_create_v2_reply_t * mp)
1733 {
1734   vat_main_t *vam = &vat_main;
1735   i32 retval = ntohl (mp->retval);
1736   if (vam->async_mode)
1737     {
1738       vam->async_errors += (retval < 0);
1739     }
1740   else
1741     {
1742       vam->retval = retval;
1743       vam->sw_if_index = ntohl (mp->sw_if_index);
1744       vam->result_ready = 1;
1745     }
1746
1747 }
1748
1749 static void vl_api_tap_create_v2_reply_t_handler_json
1750   (vl_api_tap_create_v2_reply_t * mp)
1751 {
1752   vat_main_t *vam = &vat_main;
1753   vat_json_node_t node;
1754
1755   vat_json_init_object (&node);
1756   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1757   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1758
1759   vat_json_print (vam->ofp, &node);
1760   vat_json_free (&node);
1761
1762   vam->retval = ntohl (mp->retval);
1763   vam->result_ready = 1;
1764
1765 }
1766
1767 static void
1768 vl_api_tap_delete_v2_reply_t_handler (vl_api_tap_delete_v2_reply_t * mp)
1769 {
1770   vat_main_t *vam = &vat_main;
1771   i32 retval = ntohl (mp->retval);
1772   if (vam->async_mode)
1773     {
1774       vam->async_errors += (retval < 0);
1775     }
1776   else
1777     {
1778       vam->retval = retval;
1779       vam->result_ready = 1;
1780     }
1781 }
1782
1783 static void vl_api_tap_delete_v2_reply_t_handler_json
1784   (vl_api_tap_delete_v2_reply_t * mp)
1785 {
1786   vat_main_t *vam = &vat_main;
1787   vat_json_node_t node;
1788
1789   vat_json_init_object (&node);
1790   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1791
1792   vat_json_print (vam->ofp, &node);
1793   vat_json_free (&node);
1794
1795   vam->retval = ntohl (mp->retval);
1796   vam->result_ready = 1;
1797 }
1798
1799 static void
1800 vl_api_virtio_pci_create_reply_t_handler (vl_api_virtio_pci_create_reply_t *
1801                                           mp)
1802 {
1803   vat_main_t *vam = &vat_main;
1804   i32 retval = ntohl (mp->retval);
1805   if (vam->async_mode)
1806     {
1807       vam->async_errors += (retval < 0);
1808     }
1809   else
1810     {
1811       vam->retval = retval;
1812       vam->sw_if_index = ntohl (mp->sw_if_index);
1813       vam->result_ready = 1;
1814     }
1815 }
1816
1817 static void vl_api_virtio_pci_create_reply_t_handler_json
1818   (vl_api_virtio_pci_create_reply_t * mp)
1819 {
1820   vat_main_t *vam = &vat_main;
1821   vat_json_node_t node;
1822
1823   vat_json_init_object (&node);
1824   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1825   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1826
1827   vat_json_print (vam->ofp, &node);
1828   vat_json_free (&node);
1829
1830   vam->retval = ntohl (mp->retval);
1831   vam->result_ready = 1;
1832
1833 }
1834
1835 static void
1836 vl_api_virtio_pci_delete_reply_t_handler (vl_api_virtio_pci_delete_reply_t *
1837                                           mp)
1838 {
1839   vat_main_t *vam = &vat_main;
1840   i32 retval = ntohl (mp->retval);
1841   if (vam->async_mode)
1842     {
1843       vam->async_errors += (retval < 0);
1844     }
1845   else
1846     {
1847       vam->retval = retval;
1848       vam->result_ready = 1;
1849     }
1850 }
1851
1852 static void vl_api_virtio_pci_delete_reply_t_handler_json
1853   (vl_api_virtio_pci_delete_reply_t * mp)
1854 {
1855   vat_main_t *vam = &vat_main;
1856   vat_json_node_t node;
1857
1858   vat_json_init_object (&node);
1859   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1860
1861   vat_json_print (vam->ofp, &node);
1862   vat_json_free (&node);
1863
1864   vam->retval = ntohl (mp->retval);
1865   vam->result_ready = 1;
1866 }
1867
1868 static void
1869 vl_api_bond_create_reply_t_handler (vl_api_bond_create_reply_t * mp)
1870 {
1871   vat_main_t *vam = &vat_main;
1872   i32 retval = ntohl (mp->retval);
1873
1874   if (vam->async_mode)
1875     {
1876       vam->async_errors += (retval < 0);
1877     }
1878   else
1879     {
1880       vam->retval = retval;
1881       vam->sw_if_index = ntohl (mp->sw_if_index);
1882       vam->result_ready = 1;
1883     }
1884 }
1885
1886 static void vl_api_bond_create_reply_t_handler_json
1887   (vl_api_bond_create_reply_t * mp)
1888 {
1889   vat_main_t *vam = &vat_main;
1890   vat_json_node_t node;
1891
1892   vat_json_init_object (&node);
1893   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1894   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1895
1896   vat_json_print (vam->ofp, &node);
1897   vat_json_free (&node);
1898
1899   vam->retval = ntohl (mp->retval);
1900   vam->result_ready = 1;
1901 }
1902
1903 static void
1904 vl_api_bond_delete_reply_t_handler (vl_api_bond_delete_reply_t * mp)
1905 {
1906   vat_main_t *vam = &vat_main;
1907   i32 retval = ntohl (mp->retval);
1908
1909   if (vam->async_mode)
1910     {
1911       vam->async_errors += (retval < 0);
1912     }
1913   else
1914     {
1915       vam->retval = retval;
1916       vam->result_ready = 1;
1917     }
1918 }
1919
1920 static void vl_api_bond_delete_reply_t_handler_json
1921   (vl_api_bond_delete_reply_t * mp)
1922 {
1923   vat_main_t *vam = &vat_main;
1924   vat_json_node_t node;
1925
1926   vat_json_init_object (&node);
1927   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1928
1929   vat_json_print (vam->ofp, &node);
1930   vat_json_free (&node);
1931
1932   vam->retval = ntohl (mp->retval);
1933   vam->result_ready = 1;
1934 }
1935
1936 static void
1937 vl_api_bond_enslave_reply_t_handler (vl_api_bond_enslave_reply_t * mp)
1938 {
1939   vat_main_t *vam = &vat_main;
1940   i32 retval = ntohl (mp->retval);
1941
1942   if (vam->async_mode)
1943     {
1944       vam->async_errors += (retval < 0);
1945     }
1946   else
1947     {
1948       vam->retval = retval;
1949       vam->result_ready = 1;
1950     }
1951 }
1952
1953 static void vl_api_bond_enslave_reply_t_handler_json
1954   (vl_api_bond_enslave_reply_t * mp)
1955 {
1956   vat_main_t *vam = &vat_main;
1957   vat_json_node_t node;
1958
1959   vat_json_init_object (&node);
1960   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1961
1962   vat_json_print (vam->ofp, &node);
1963   vat_json_free (&node);
1964
1965   vam->retval = ntohl (mp->retval);
1966   vam->result_ready = 1;
1967 }
1968
1969 static void
1970 vl_api_bond_detach_slave_reply_t_handler (vl_api_bond_detach_slave_reply_t *
1971                                           mp)
1972 {
1973   vat_main_t *vam = &vat_main;
1974   i32 retval = ntohl (mp->retval);
1975
1976   if (vam->async_mode)
1977     {
1978       vam->async_errors += (retval < 0);
1979     }
1980   else
1981     {
1982       vam->retval = retval;
1983       vam->result_ready = 1;
1984     }
1985 }
1986
1987 static void vl_api_bond_detach_slave_reply_t_handler_json
1988   (vl_api_bond_detach_slave_reply_t * mp)
1989 {
1990   vat_main_t *vam = &vat_main;
1991   vat_json_node_t node;
1992
1993   vat_json_init_object (&node);
1994   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1995
1996   vat_json_print (vam->ofp, &node);
1997   vat_json_free (&node);
1998
1999   vam->retval = ntohl (mp->retval);
2000   vam->result_ready = 1;
2001 }
2002
2003 static int
2004 api_sw_interface_set_bond_weight (vat_main_t * vam)
2005 {
2006   unformat_input_t *i = vam->input;
2007   vl_api_sw_interface_set_bond_weight_t *mp;
2008   u32 sw_if_index = ~0;
2009   u32 weight = 0;
2010   u8 weight_enter = 0;
2011   int ret;
2012
2013   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2014     {
2015       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
2016         ;
2017       else if (unformat (i, "sw_if_index %d", &sw_if_index))
2018         ;
2019       else if (unformat (i, "weight %u", &weight))
2020         weight_enter = 1;
2021       else
2022         break;
2023     }
2024
2025   if (sw_if_index == ~0)
2026     {
2027       errmsg ("missing interface name or sw_if_index");
2028       return -99;
2029     }
2030   if (weight_enter == 0)
2031     {
2032       errmsg ("missing valid weight");
2033       return -99;
2034     }
2035
2036   /* Construct the API message */
2037   M (SW_INTERFACE_SET_BOND_WEIGHT, mp);
2038   mp->sw_if_index = ntohl (sw_if_index);
2039   mp->weight = ntohl (weight);
2040
2041   S (mp);
2042   W (ret);
2043   return ret;
2044 }
2045
2046 static void vl_api_sw_interface_bond_details_t_handler
2047   (vl_api_sw_interface_bond_details_t * mp)
2048 {
2049   vat_main_t *vam = &vat_main;
2050
2051   print (vam->ofp,
2052          "%-16s %-12d %-12U %-13U %-14u %-14u",
2053          mp->interface_name, ntohl (mp->sw_if_index),
2054          format_bond_mode, ntohl (mp->mode), format_bond_load_balance,
2055          ntohl (mp->lb), ntohl (mp->active_slaves), ntohl (mp->slaves));
2056 }
2057
2058 static void vl_api_sw_interface_bond_details_t_handler_json
2059   (vl_api_sw_interface_bond_details_t * mp)
2060 {
2061   vat_main_t *vam = &vat_main;
2062   vat_json_node_t *node = NULL;
2063
2064   if (VAT_JSON_ARRAY != vam->json_tree.type)
2065     {
2066       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2067       vat_json_init_array (&vam->json_tree);
2068     }
2069   node = vat_json_array_add (&vam->json_tree);
2070
2071   vat_json_init_object (node);
2072   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
2073   vat_json_object_add_string_copy (node, "interface_name",
2074                                    mp->interface_name);
2075   vat_json_object_add_uint (node, "mode", ntohl (mp->mode));
2076   vat_json_object_add_uint (node, "load_balance", ntohl (mp->lb));
2077   vat_json_object_add_uint (node, "active_slaves", ntohl (mp->active_slaves));
2078   vat_json_object_add_uint (node, "slaves", ntohl (mp->slaves));
2079 }
2080
2081 static int
2082 api_sw_interface_bond_dump (vat_main_t * vam)
2083 {
2084   vl_api_sw_interface_bond_dump_t *mp;
2085   vl_api_control_ping_t *mp_ping;
2086   int ret;
2087
2088   print (vam->ofp,
2089          "\n%-16s %-12s %-12s %-13s %-14s %-14s",
2090          "interface name", "sw_if_index", "mode", "load balance",
2091          "active slaves", "slaves");
2092
2093   /* Get list of bond interfaces */
2094   M (SW_INTERFACE_BOND_DUMP, mp);
2095   S (mp);
2096
2097   /* Use a control ping for synchronization */
2098   MPING (CONTROL_PING, mp_ping);
2099   S (mp_ping);
2100
2101   W (ret);
2102   return ret;
2103 }
2104
2105 static void vl_api_sw_interface_slave_details_t_handler
2106   (vl_api_sw_interface_slave_details_t * mp)
2107 {
2108   vat_main_t *vam = &vat_main;
2109
2110   print (vam->ofp,
2111          "%-25s %-12d %-7d %-12d %-10d %-10d", mp->interface_name,
2112          ntohl (mp->sw_if_index), mp->is_passive, mp->is_long_timeout,
2113          ntohl (mp->weight), mp->is_local_numa);
2114 }
2115
2116 static void vl_api_sw_interface_slave_details_t_handler_json
2117   (vl_api_sw_interface_slave_details_t * mp)
2118 {
2119   vat_main_t *vam = &vat_main;
2120   vat_json_node_t *node = NULL;
2121
2122   if (VAT_JSON_ARRAY != vam->json_tree.type)
2123     {
2124       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2125       vat_json_init_array (&vam->json_tree);
2126     }
2127   node = vat_json_array_add (&vam->json_tree);
2128
2129   vat_json_init_object (node);
2130   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
2131   vat_json_object_add_string_copy (node, "interface_name",
2132                                    mp->interface_name);
2133   vat_json_object_add_uint (node, "passive", mp->is_passive);
2134   vat_json_object_add_uint (node, "long_timeout", mp->is_long_timeout);
2135   vat_json_object_add_uint (node, "weight", ntohl (mp->weight));
2136   vat_json_object_add_uint (node, "is_local_numa", mp->is_local_numa);
2137 }
2138
2139 static int
2140 api_sw_interface_slave_dump (vat_main_t * vam)
2141 {
2142   unformat_input_t *i = vam->input;
2143   vl_api_sw_interface_slave_dump_t *mp;
2144   vl_api_control_ping_t *mp_ping;
2145   u32 sw_if_index = ~0;
2146   u8 sw_if_index_set = 0;
2147   int ret;
2148
2149   /* Parse args required to build the message */
2150   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2151     {
2152       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
2153         sw_if_index_set = 1;
2154       else if (unformat (i, "sw_if_index %d", &sw_if_index))
2155         sw_if_index_set = 1;
2156       else
2157         break;
2158     }
2159
2160   if (sw_if_index_set == 0)
2161     {
2162       errmsg ("missing vpp interface name. ");
2163       return -99;
2164     }
2165
2166   print (vam->ofp,
2167          "\n%-25s %-12s %-7s %-12s %-10s %-10s",
2168          "slave interface name", "sw_if_index", "passive", "long_timeout",
2169          "weight", "local numa");
2170
2171   /* Get list of bond interfaces */
2172   M (SW_INTERFACE_SLAVE_DUMP, mp);
2173   mp->sw_if_index = ntohl (sw_if_index);
2174   S (mp);
2175
2176   /* Use a control ping for synchronization */
2177   MPING (CONTROL_PING, mp_ping);
2178   S (mp_ping);
2179
2180   W (ret);
2181   return ret;
2182 }
2183
2184 static void vl_api_mpls_tunnel_add_del_reply_t_handler
2185   (vl_api_mpls_tunnel_add_del_reply_t * mp)
2186 {
2187   vat_main_t *vam = &vat_main;
2188   i32 retval = ntohl (mp->retval);
2189   if (vam->async_mode)
2190     {
2191       vam->async_errors += (retval < 0);
2192     }
2193   else
2194     {
2195       vam->retval = retval;
2196       vam->sw_if_index = ntohl (mp->sw_if_index);
2197       vam->result_ready = 1;
2198     }
2199   vam->regenerate_interface_table = 1;
2200 }
2201
2202 static void vl_api_mpls_tunnel_add_del_reply_t_handler_json
2203   (vl_api_mpls_tunnel_add_del_reply_t * mp)
2204 {
2205   vat_main_t *vam = &vat_main;
2206   vat_json_node_t node;
2207
2208   vat_json_init_object (&node);
2209   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2210   vat_json_object_add_uint (&node, "tunnel_sw_if_index",
2211                             ntohl (mp->sw_if_index));
2212
2213   vat_json_print (vam->ofp, &node);
2214   vat_json_free (&node);
2215
2216   vam->retval = ntohl (mp->retval);
2217   vam->result_ready = 1;
2218 }
2219
2220 static void vl_api_l2tpv3_create_tunnel_reply_t_handler
2221   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
2222 {
2223   vat_main_t *vam = &vat_main;
2224   i32 retval = ntohl (mp->retval);
2225   if (vam->async_mode)
2226     {
2227       vam->async_errors += (retval < 0);
2228     }
2229   else
2230     {
2231       vam->retval = retval;
2232       vam->sw_if_index = ntohl (mp->sw_if_index);
2233       vam->result_ready = 1;
2234     }
2235 }
2236
2237 static void vl_api_l2tpv3_create_tunnel_reply_t_handler_json
2238   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
2239 {
2240   vat_main_t *vam = &vat_main;
2241   vat_json_node_t node;
2242
2243   vat_json_init_object (&node);
2244   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2245   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2246
2247   vat_json_print (vam->ofp, &node);
2248   vat_json_free (&node);
2249
2250   vam->retval = ntohl (mp->retval);
2251   vam->result_ready = 1;
2252 }
2253
2254 static void vl_api_gpe_add_del_fwd_entry_reply_t_handler
2255   (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
2256 {
2257   vat_main_t *vam = &vat_main;
2258   i32 retval = ntohl (mp->retval);
2259   if (vam->async_mode)
2260     {
2261       vam->async_errors += (retval < 0);
2262     }
2263   else
2264     {
2265       vam->retval = retval;
2266       vam->result_ready = 1;
2267     }
2268 }
2269
2270 static void vl_api_gpe_add_del_fwd_entry_reply_t_handler_json
2271   (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
2272 {
2273   vat_main_t *vam = &vat_main;
2274   vat_json_node_t node;
2275
2276   vat_json_init_object (&node);
2277   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2278   vat_json_object_add_uint (&node, "fwd_entry_index",
2279                             clib_net_to_host_u32 (mp->fwd_entry_index));
2280
2281   vat_json_print (vam->ofp, &node);
2282   vat_json_free (&node);
2283
2284   vam->retval = ntohl (mp->retval);
2285   vam->result_ready = 1;
2286 }
2287
2288 u8 *
2289 format_lisp_transport_protocol (u8 * s, va_list * args)
2290 {
2291   u32 proto = va_arg (*args, u32);
2292
2293   switch (proto)
2294     {
2295     case 1:
2296       return format (s, "udp");
2297     case 2:
2298       return format (s, "api");
2299     default:
2300       return 0;
2301     }
2302   return 0;
2303 }
2304
2305 static void vl_api_one_get_transport_protocol_reply_t_handler
2306   (vl_api_one_get_transport_protocol_reply_t * mp)
2307 {
2308   vat_main_t *vam = &vat_main;
2309   i32 retval = ntohl (mp->retval);
2310   if (vam->async_mode)
2311     {
2312       vam->async_errors += (retval < 0);
2313     }
2314   else
2315     {
2316       u32 proto = mp->protocol;
2317       print (vam->ofp, "Transport protocol: %U",
2318              format_lisp_transport_protocol, proto);
2319       vam->retval = retval;
2320       vam->result_ready = 1;
2321     }
2322 }
2323
2324 static void vl_api_one_get_transport_protocol_reply_t_handler_json
2325   (vl_api_one_get_transport_protocol_reply_t * mp)
2326 {
2327   vat_main_t *vam = &vat_main;
2328   vat_json_node_t node;
2329   u8 *s;
2330
2331   s = format (0, "%U", format_lisp_transport_protocol, mp->protocol);
2332   vec_add1 (s, 0);
2333
2334   vat_json_init_object (&node);
2335   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2336   vat_json_object_add_string_copy (&node, "transport-protocol", s);
2337
2338   vec_free (s);
2339   vat_json_print (vam->ofp, &node);
2340   vat_json_free (&node);
2341
2342   vam->retval = ntohl (mp->retval);
2343   vam->result_ready = 1;
2344 }
2345
2346 static void vl_api_one_add_del_locator_set_reply_t_handler
2347   (vl_api_one_add_del_locator_set_reply_t * mp)
2348 {
2349   vat_main_t *vam = &vat_main;
2350   i32 retval = ntohl (mp->retval);
2351   if (vam->async_mode)
2352     {
2353       vam->async_errors += (retval < 0);
2354     }
2355   else
2356     {
2357       vam->retval = retval;
2358       vam->result_ready = 1;
2359     }
2360 }
2361
2362 static void vl_api_one_add_del_locator_set_reply_t_handler_json
2363   (vl_api_one_add_del_locator_set_reply_t * mp)
2364 {
2365   vat_main_t *vam = &vat_main;
2366   vat_json_node_t node;
2367
2368   vat_json_init_object (&node);
2369   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2370   vat_json_object_add_uint (&node, "locator_set_index", ntohl (mp->ls_index));
2371
2372   vat_json_print (vam->ofp, &node);
2373   vat_json_free (&node);
2374
2375   vam->retval = ntohl (mp->retval);
2376   vam->result_ready = 1;
2377 }
2378
2379 static void vl_api_vxlan_add_del_tunnel_reply_t_handler
2380   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
2381 {
2382   vat_main_t *vam = &vat_main;
2383   i32 retval = ntohl (mp->retval);
2384   if (vam->async_mode)
2385     {
2386       vam->async_errors += (retval < 0);
2387     }
2388   else
2389     {
2390       vam->retval = retval;
2391       vam->sw_if_index = ntohl (mp->sw_if_index);
2392       vam->result_ready = 1;
2393     }
2394   vam->regenerate_interface_table = 1;
2395 }
2396
2397 static void vl_api_vxlan_add_del_tunnel_reply_t_handler_json
2398   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
2399 {
2400   vat_main_t *vam = &vat_main;
2401   vat_json_node_t node;
2402
2403   vat_json_init_object (&node);
2404   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2405   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
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_vxlan_offload_rx_reply_t_handler
2415   (vl_api_vxlan_offload_rx_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->result_ready = 1;
2427     }
2428 }
2429
2430 static void vl_api_vxlan_offload_rx_reply_t_handler_json
2431   (vl_api_vxlan_offload_rx_reply_t * mp)
2432 {
2433   vat_main_t *vam = &vat_main;
2434   vat_json_node_t node;
2435
2436   vat_json_init_object (&node);
2437   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2438
2439   vat_json_print (vam->ofp, &node);
2440   vat_json_free (&node);
2441
2442   vam->retval = ntohl (mp->retval);
2443   vam->result_ready = 1;
2444 }
2445
2446 static void vl_api_geneve_add_del_tunnel_reply_t_handler
2447   (vl_api_geneve_add_del_tunnel_reply_t * mp)
2448 {
2449   vat_main_t *vam = &vat_main;
2450   i32 retval = ntohl (mp->retval);
2451   if (vam->async_mode)
2452     {
2453       vam->async_errors += (retval < 0);
2454     }
2455   else
2456     {
2457       vam->retval = retval;
2458       vam->sw_if_index = ntohl (mp->sw_if_index);
2459       vam->result_ready = 1;
2460     }
2461 }
2462
2463 static void vl_api_geneve_add_del_tunnel_reply_t_handler_json
2464   (vl_api_geneve_add_del_tunnel_reply_t * mp)
2465 {
2466   vat_main_t *vam = &vat_main;
2467   vat_json_node_t node;
2468
2469   vat_json_init_object (&node);
2470   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2471   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2472
2473   vat_json_print (vam->ofp, &node);
2474   vat_json_free (&node);
2475
2476   vam->retval = ntohl (mp->retval);
2477   vam->result_ready = 1;
2478 }
2479
2480 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler
2481   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
2482 {
2483   vat_main_t *vam = &vat_main;
2484   i32 retval = ntohl (mp->retval);
2485   if (vam->async_mode)
2486     {
2487       vam->async_errors += (retval < 0);
2488     }
2489   else
2490     {
2491       vam->retval = retval;
2492       vam->sw_if_index = ntohl (mp->sw_if_index);
2493       vam->result_ready = 1;
2494     }
2495   vam->regenerate_interface_table = 1;
2496 }
2497
2498 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler_json
2499   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
2500 {
2501   vat_main_t *vam = &vat_main;
2502   vat_json_node_t node;
2503
2504   vat_json_init_object (&node);
2505   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2506   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2507
2508   vat_json_print (vam->ofp, &node);
2509   vat_json_free (&node);
2510
2511   vam->retval = ntohl (mp->retval);
2512   vam->result_ready = 1;
2513 }
2514
2515 static void vl_api_gre_tunnel_add_del_reply_t_handler
2516   (vl_api_gre_tunnel_add_del_reply_t * mp)
2517 {
2518   vat_main_t *vam = &vat_main;
2519   i32 retval = ntohl (mp->retval);
2520   if (vam->async_mode)
2521     {
2522       vam->async_errors += (retval < 0);
2523     }
2524   else
2525     {
2526       vam->retval = retval;
2527       vam->sw_if_index = ntohl (mp->sw_if_index);
2528       vam->result_ready = 1;
2529     }
2530 }
2531
2532 static void vl_api_gre_tunnel_add_del_reply_t_handler_json
2533   (vl_api_gre_tunnel_add_del_reply_t * mp)
2534 {
2535   vat_main_t *vam = &vat_main;
2536   vat_json_node_t node;
2537
2538   vat_json_init_object (&node);
2539   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2540   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2541
2542   vat_json_print (vam->ofp, &node);
2543   vat_json_free (&node);
2544
2545   vam->retval = ntohl (mp->retval);
2546   vam->result_ready = 1;
2547 }
2548
2549 static void vl_api_create_vhost_user_if_reply_t_handler
2550   (vl_api_create_vhost_user_if_reply_t * mp)
2551 {
2552   vat_main_t *vam = &vat_main;
2553   i32 retval = ntohl (mp->retval);
2554   if (vam->async_mode)
2555     {
2556       vam->async_errors += (retval < 0);
2557     }
2558   else
2559     {
2560       vam->retval = retval;
2561       vam->sw_if_index = ntohl (mp->sw_if_index);
2562       vam->result_ready = 1;
2563     }
2564   vam->regenerate_interface_table = 1;
2565 }
2566
2567 static void vl_api_create_vhost_user_if_reply_t_handler_json
2568   (vl_api_create_vhost_user_if_reply_t * mp)
2569 {
2570   vat_main_t *vam = &vat_main;
2571   vat_json_node_t node;
2572
2573   vat_json_init_object (&node);
2574   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2575   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2576
2577   vat_json_print (vam->ofp, &node);
2578   vat_json_free (&node);
2579
2580   vam->retval = ntohl (mp->retval);
2581   vam->result_ready = 1;
2582 }
2583
2584 static void vl_api_ip_address_details_t_handler
2585   (vl_api_ip_address_details_t * mp)
2586 {
2587   vat_main_t *vam = &vat_main;
2588   static ip_address_details_t empty_ip_address_details = { {0} };
2589   ip_address_details_t *address = NULL;
2590   ip_details_t *current_ip_details = NULL;
2591   ip_details_t *details = NULL;
2592
2593   details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
2594
2595   if (!details || vam->current_sw_if_index >= vec_len (details)
2596       || !details[vam->current_sw_if_index].present)
2597     {
2598       errmsg ("ip address details arrived but not stored");
2599       errmsg ("ip_dump should be called first");
2600       return;
2601     }
2602
2603   current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
2604
2605 #define addresses (current_ip_details->addr)
2606
2607   vec_validate_init_empty (addresses, vec_len (addresses),
2608                            empty_ip_address_details);
2609
2610   address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
2611
2612   clib_memcpy (&address->ip, &mp->prefix.address.un, sizeof (address->ip));
2613   address->prefix_length = mp->prefix.len;
2614 #undef addresses
2615 }
2616
2617 static void vl_api_ip_address_details_t_handler_json
2618   (vl_api_ip_address_details_t * mp)
2619 {
2620   vat_main_t *vam = &vat_main;
2621   vat_json_node_t *node = NULL;
2622
2623   if (VAT_JSON_ARRAY != vam->json_tree.type)
2624     {
2625       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2626       vat_json_init_array (&vam->json_tree);
2627     }
2628   node = vat_json_array_add (&vam->json_tree);
2629
2630   vat_json_init_object (node);
2631   vat_json_object_add_prefix (node, &mp->prefix);
2632 }
2633
2634 static void
2635 vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
2636 {
2637   vat_main_t *vam = &vat_main;
2638   static ip_details_t empty_ip_details = { 0 };
2639   ip_details_t *ip = NULL;
2640   u32 sw_if_index = ~0;
2641
2642   sw_if_index = ntohl (mp->sw_if_index);
2643
2644   vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2645                            sw_if_index, empty_ip_details);
2646
2647   ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2648                          sw_if_index);
2649
2650   ip->present = 1;
2651 }
2652
2653 static void
2654 vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
2655 {
2656   vat_main_t *vam = &vat_main;
2657
2658   if (VAT_JSON_ARRAY != vam->json_tree.type)
2659     {
2660       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2661       vat_json_init_array (&vam->json_tree);
2662     }
2663   vat_json_array_add_uint (&vam->json_tree,
2664                            clib_net_to_host_u32 (mp->sw_if_index));
2665 }
2666
2667 static void vl_api_get_first_msg_id_reply_t_handler
2668   (vl_api_get_first_msg_id_reply_t * mp)
2669 {
2670   vat_main_t *vam = &vat_main;
2671   i32 retval = ntohl (mp->retval);
2672
2673   if (vam->async_mode)
2674     {
2675       vam->async_errors += (retval < 0);
2676     }
2677   else
2678     {
2679       vam->retval = retval;
2680       vam->result_ready = 1;
2681     }
2682   if (retval >= 0)
2683     {
2684       errmsg ("first message id %d", ntohs (mp->first_msg_id));
2685     }
2686 }
2687
2688 static void vl_api_get_first_msg_id_reply_t_handler_json
2689   (vl_api_get_first_msg_id_reply_t * mp)
2690 {
2691   vat_main_t *vam = &vat_main;
2692   vat_json_node_t node;
2693
2694   vat_json_init_object (&node);
2695   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2696   vat_json_object_add_uint (&node, "first_msg_id",
2697                             (uint) ntohs (mp->first_msg_id));
2698
2699   vat_json_print (vam->ofp, &node);
2700   vat_json_free (&node);
2701
2702   vam->retval = ntohl (mp->retval);
2703   vam->result_ready = 1;
2704 }
2705
2706 static void vl_api_get_node_graph_reply_t_handler
2707   (vl_api_get_node_graph_reply_t * mp)
2708 {
2709   vat_main_t *vam = &vat_main;
2710   i32 retval = ntohl (mp->retval);
2711   u8 *pvt_copy, *reply;
2712   void *oldheap;
2713   vlib_node_t *node;
2714   int i;
2715
2716   if (vam->async_mode)
2717     {
2718       vam->async_errors += (retval < 0);
2719     }
2720   else
2721     {
2722       vam->retval = retval;
2723       vam->result_ready = 1;
2724     }
2725
2726   /* "Should never happen..." */
2727   if (retval != 0)
2728     return;
2729
2730   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2731   pvt_copy = vec_dup (reply);
2732
2733   /* Toss the shared-memory original... */
2734   oldheap = vl_msg_push_heap ();
2735
2736   vec_free (reply);
2737
2738   vl_msg_pop_heap (oldheap);
2739
2740   if (vam->graph_nodes)
2741     {
2742       hash_free (vam->graph_node_index_by_name);
2743
2744       for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
2745         {
2746           node = vam->graph_nodes[0][i];
2747           vec_free (node->name);
2748           vec_free (node->next_nodes);
2749           vec_free (node);
2750         }
2751       vec_free (vam->graph_nodes[0]);
2752       vec_free (vam->graph_nodes);
2753     }
2754
2755   vam->graph_node_index_by_name = hash_create_string (0, sizeof (uword));
2756   vam->graph_nodes = vlib_node_unserialize (pvt_copy);
2757   vec_free (pvt_copy);
2758
2759   for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
2760     {
2761       node = vam->graph_nodes[0][i];
2762       hash_set_mem (vam->graph_node_index_by_name, node->name, i);
2763     }
2764 }
2765
2766 static void vl_api_get_node_graph_reply_t_handler_json
2767   (vl_api_get_node_graph_reply_t * mp)
2768 {
2769   vat_main_t *vam = &vat_main;
2770   void *oldheap;
2771   vat_json_node_t node;
2772   u8 *reply;
2773
2774   /* $$$$ make this real? */
2775   vat_json_init_object (&node);
2776   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2777   vat_json_object_add_uint (&node, "reply_in_shmem", mp->reply_in_shmem);
2778
2779   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2780
2781   /* Toss the shared-memory original... */
2782   oldheap = vl_msg_push_heap ();
2783
2784   vec_free (reply);
2785
2786   vl_msg_pop_heap (oldheap);
2787
2788   vat_json_print (vam->ofp, &node);
2789   vat_json_free (&node);
2790
2791   vam->retval = ntohl (mp->retval);
2792   vam->result_ready = 1;
2793 }
2794
2795 static void
2796 vl_api_one_locator_details_t_handler (vl_api_one_locator_details_t * mp)
2797 {
2798   vat_main_t *vam = &vat_main;
2799   u8 *s = 0;
2800
2801   if (mp->local)
2802     {
2803       s = format (s, "%=16d%=16d%=16d",
2804                   ntohl (mp->sw_if_index), mp->priority, mp->weight);
2805     }
2806   else
2807     {
2808       s = format (s, "%=16U%=16d%=16d",
2809                   mp->is_ipv6 ? format_ip6_address :
2810                   format_ip4_address,
2811                   mp->ip_address, mp->priority, mp->weight);
2812     }
2813
2814   print (vam->ofp, "%v", s);
2815   vec_free (s);
2816 }
2817
2818 static void
2819 vl_api_one_locator_details_t_handler_json (vl_api_one_locator_details_t * mp)
2820 {
2821   vat_main_t *vam = &vat_main;
2822   vat_json_node_t *node = NULL;
2823   struct in6_addr ip6;
2824   struct in_addr ip4;
2825
2826   if (VAT_JSON_ARRAY != vam->json_tree.type)
2827     {
2828       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2829       vat_json_init_array (&vam->json_tree);
2830     }
2831   node = vat_json_array_add (&vam->json_tree);
2832   vat_json_init_object (node);
2833
2834   vat_json_object_add_uint (node, "local", mp->local ? 1 : 0);
2835   vat_json_object_add_uint (node, "priority", mp->priority);
2836   vat_json_object_add_uint (node, "weight", mp->weight);
2837
2838   if (mp->local)
2839     vat_json_object_add_uint (node, "sw_if_index",
2840                               clib_net_to_host_u32 (mp->sw_if_index));
2841   else
2842     {
2843       if (mp->is_ipv6)
2844         {
2845           clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2846           vat_json_object_add_ip6 (node, "address", ip6);
2847         }
2848       else
2849         {
2850           clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2851           vat_json_object_add_ip4 (node, "address", ip4);
2852         }
2853     }
2854 }
2855
2856 static void
2857 vl_api_one_locator_set_details_t_handler (vl_api_one_locator_set_details_t *
2858                                           mp)
2859 {
2860   vat_main_t *vam = &vat_main;
2861   u8 *ls_name = 0;
2862
2863   ls_name = format (0, "%s", mp->ls_name);
2864
2865   print (vam->ofp, "%=10d%=15v", clib_net_to_host_u32 (mp->ls_index),
2866          ls_name);
2867   vec_free (ls_name);
2868 }
2869
2870 static void
2871   vl_api_one_locator_set_details_t_handler_json
2872   (vl_api_one_locator_set_details_t * mp)
2873 {
2874   vat_main_t *vam = &vat_main;
2875   vat_json_node_t *node = 0;
2876   u8 *ls_name = 0;
2877
2878   ls_name = format (0, "%s", mp->ls_name);
2879   vec_add1 (ls_name, 0);
2880
2881   if (VAT_JSON_ARRAY != vam->json_tree.type)
2882     {
2883       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2884       vat_json_init_array (&vam->json_tree);
2885     }
2886   node = vat_json_array_add (&vam->json_tree);
2887
2888   vat_json_init_object (node);
2889   vat_json_object_add_string_copy (node, "ls_name", ls_name);
2890   vat_json_object_add_uint (node, "ls_index",
2891                             clib_net_to_host_u32 (mp->ls_index));
2892   vec_free (ls_name);
2893 }
2894
2895 typedef struct
2896 {
2897   u32 spi;
2898   u8 si;
2899 } __attribute__ ((__packed__)) lisp_nsh_api_t;
2900
2901 uword
2902 unformat_nsh_address (unformat_input_t * input, va_list * args)
2903 {
2904   lisp_nsh_api_t *nsh = va_arg (*args, lisp_nsh_api_t *);
2905   return unformat (input, "SPI:%d SI:%d", &nsh->spi, &nsh->si);
2906 }
2907
2908 u8 *
2909 format_nsh_address_vat (u8 * s, va_list * args)
2910 {
2911   nsh_t *a = va_arg (*args, nsh_t *);
2912   return format (s, "SPI:%d SI:%d", clib_net_to_host_u32 (a->spi), a->si);
2913 }
2914
2915 static u8 *
2916 format_lisp_flat_eid (u8 * s, va_list * args)
2917 {
2918   u32 type = va_arg (*args, u32);
2919   u8 *eid = va_arg (*args, u8 *);
2920   u32 eid_len = va_arg (*args, u32);
2921
2922   switch (type)
2923     {
2924     case 0:
2925       return format (s, "%U/%d", format_ip4_address, eid, eid_len);
2926     case 1:
2927       return format (s, "%U/%d", format_ip6_address, eid, eid_len);
2928     case 2:
2929       return format (s, "%U", format_ethernet_address, eid);
2930     case 3:
2931       return format (s, "%U", format_nsh_address_vat, eid);
2932     }
2933   return 0;
2934 }
2935
2936 static u8 *
2937 format_lisp_eid_vat (u8 * s, va_list * args)
2938 {
2939   u32 type = va_arg (*args, u32);
2940   u8 *eid = va_arg (*args, u8 *);
2941   u32 eid_len = va_arg (*args, u32);
2942   u8 *seid = va_arg (*args, u8 *);
2943   u32 seid_len = va_arg (*args, u32);
2944   u32 is_src_dst = va_arg (*args, u32);
2945
2946   if (is_src_dst)
2947     s = format (s, "%U|", format_lisp_flat_eid, type, seid, seid_len);
2948
2949   s = format (s, "%U", format_lisp_flat_eid, type, eid, eid_len);
2950
2951   return s;
2952 }
2953
2954 static void
2955 vl_api_one_eid_table_details_t_handler (vl_api_one_eid_table_details_t * mp)
2956 {
2957   vat_main_t *vam = &vat_main;
2958   u8 *s = 0, *eid = 0;
2959
2960   if (~0 == mp->locator_set_index)
2961     s = format (0, "action: %d", mp->action);
2962   else
2963     s = format (0, "%d", clib_net_to_host_u32 (mp->locator_set_index));
2964
2965   eid = format (0, "%U", format_lisp_eid_vat,
2966                 mp->eid_type,
2967                 mp->eid,
2968                 mp->eid_prefix_len,
2969                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
2970   vec_add1 (eid, 0);
2971
2972   print (vam->ofp, "[%d] %-35s%-20s%-30s%-20d%-20d%-10d%-20s",
2973          clib_net_to_host_u32 (mp->vni),
2974          eid,
2975          mp->is_local ? "local" : "remote",
2976          s, clib_net_to_host_u32 (mp->ttl), mp->authoritative,
2977          clib_net_to_host_u16 (mp->key_id), mp->key);
2978
2979   vec_free (s);
2980   vec_free (eid);
2981 }
2982
2983 static void
2984 vl_api_one_eid_table_details_t_handler_json (vl_api_one_eid_table_details_t
2985                                              * mp)
2986 {
2987   vat_main_t *vam = &vat_main;
2988   vat_json_node_t *node = 0;
2989   u8 *eid = 0;
2990
2991   if (VAT_JSON_ARRAY != vam->json_tree.type)
2992     {
2993       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2994       vat_json_init_array (&vam->json_tree);
2995     }
2996   node = vat_json_array_add (&vam->json_tree);
2997
2998   vat_json_init_object (node);
2999   if (~0 == mp->locator_set_index)
3000     vat_json_object_add_uint (node, "action", mp->action);
3001   else
3002     vat_json_object_add_uint (node, "locator_set_index",
3003                               clib_net_to_host_u32 (mp->locator_set_index));
3004
3005   vat_json_object_add_uint (node, "is_local", mp->is_local ? 1 : 0);
3006   if (mp->eid_type == 3)
3007     {
3008       vat_json_node_t *nsh_json = vat_json_object_add (node, "eid");
3009       vat_json_init_object (nsh_json);
3010       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) mp->eid;
3011       vat_json_object_add_uint (nsh_json, "spi",
3012                                 clib_net_to_host_u32 (nsh->spi));
3013       vat_json_object_add_uint (nsh_json, "si", nsh->si);
3014     }
3015   else
3016     {
3017       eid = format (0, "%U", format_lisp_eid_vat,
3018                     mp->eid_type,
3019                     mp->eid,
3020                     mp->eid_prefix_len,
3021                     mp->seid, mp->seid_prefix_len, mp->is_src_dst);
3022       vec_add1 (eid, 0);
3023       vat_json_object_add_string_copy (node, "eid", eid);
3024       vec_free (eid);
3025     }
3026   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3027   vat_json_object_add_uint (node, "ttl", clib_net_to_host_u32 (mp->ttl));
3028   vat_json_object_add_uint (node, "authoritative", (mp->authoritative));
3029
3030   if (mp->key_id)
3031     {
3032       vat_json_object_add_uint (node, "key_id",
3033                                 clib_net_to_host_u16 (mp->key_id));
3034       vat_json_object_add_string_copy (node, "key", mp->key);
3035     }
3036 }
3037
3038 static void
3039 vl_api_one_stats_details_t_handler (vl_api_one_stats_details_t * mp)
3040 {
3041   vat_main_t *vam = &vat_main;
3042   u8 *seid = 0, *deid = 0;
3043   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3044
3045   deid = format (0, "%U", format_lisp_eid_vat,
3046                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
3047
3048   seid = format (0, "%U", format_lisp_eid_vat,
3049                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
3050
3051   vec_add1 (deid, 0);
3052   vec_add1 (seid, 0);
3053
3054   if (mp->is_ip4)
3055     format_ip_address_fcn = format_ip4_address;
3056   else
3057     format_ip_address_fcn = format_ip6_address;
3058
3059
3060   print (vam->ofp, "([%d] %s %s) (%U %U) %u %u",
3061          clib_net_to_host_u32 (mp->vni),
3062          seid, deid,
3063          format_ip_address_fcn, mp->lloc,
3064          format_ip_address_fcn, mp->rloc,
3065          clib_net_to_host_u32 (mp->pkt_count),
3066          clib_net_to_host_u32 (mp->bytes));
3067
3068   vec_free (deid);
3069   vec_free (seid);
3070 }
3071
3072 static void
3073 vl_api_one_stats_details_t_handler_json (vl_api_one_stats_details_t * mp)
3074 {
3075   struct in6_addr ip6;
3076   struct in_addr ip4;
3077   vat_main_t *vam = &vat_main;
3078   vat_json_node_t *node = 0;
3079   u8 *deid = 0, *seid = 0;
3080
3081   if (VAT_JSON_ARRAY != vam->json_tree.type)
3082     {
3083       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3084       vat_json_init_array (&vam->json_tree);
3085     }
3086   node = vat_json_array_add (&vam->json_tree);
3087
3088   vat_json_init_object (node);
3089   deid = format (0, "%U", format_lisp_eid_vat,
3090                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
3091
3092   seid = format (0, "%U", format_lisp_eid_vat,
3093                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
3094
3095   vec_add1 (deid, 0);
3096   vec_add1 (seid, 0);
3097
3098   vat_json_object_add_string_copy (node, "seid", seid);
3099   vat_json_object_add_string_copy (node, "deid", deid);
3100   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3101
3102   if (mp->is_ip4)
3103     {
3104       clib_memcpy (&ip4, mp->lloc, sizeof (ip4));
3105       vat_json_object_add_ip4 (node, "lloc", ip4);
3106       clib_memcpy (&ip4, mp->rloc, sizeof (ip4));
3107       vat_json_object_add_ip4 (node, "rloc", ip4);
3108     }
3109   else
3110     {
3111       clib_memcpy (&ip6, mp->lloc, sizeof (ip6));
3112       vat_json_object_add_ip6 (node, "lloc", ip6);
3113       clib_memcpy (&ip6, mp->rloc, sizeof (ip6));
3114       vat_json_object_add_ip6 (node, "rloc", ip6);
3115     }
3116   vat_json_object_add_uint (node, "pkt_count",
3117                             clib_net_to_host_u32 (mp->pkt_count));
3118   vat_json_object_add_uint (node, "bytes", clib_net_to_host_u32 (mp->bytes));
3119
3120   vec_free (deid);
3121   vec_free (seid);
3122 }
3123
3124 static void
3125   vl_api_one_eid_table_map_details_t_handler
3126   (vl_api_one_eid_table_map_details_t * mp)
3127 {
3128   vat_main_t *vam = &vat_main;
3129
3130   u8 *line = format (0, "%=10d%=10d",
3131                      clib_net_to_host_u32 (mp->vni),
3132                      clib_net_to_host_u32 (mp->dp_table));
3133   print (vam->ofp, "%v", line);
3134   vec_free (line);
3135 }
3136
3137 static void
3138   vl_api_one_eid_table_map_details_t_handler_json
3139   (vl_api_one_eid_table_map_details_t * mp)
3140 {
3141   vat_main_t *vam = &vat_main;
3142   vat_json_node_t *node = NULL;
3143
3144   if (VAT_JSON_ARRAY != vam->json_tree.type)
3145     {
3146       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3147       vat_json_init_array (&vam->json_tree);
3148     }
3149   node = vat_json_array_add (&vam->json_tree);
3150   vat_json_init_object (node);
3151   vat_json_object_add_uint (node, "dp_table",
3152                             clib_net_to_host_u32 (mp->dp_table));
3153   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3154 }
3155
3156 static void
3157   vl_api_one_eid_table_vni_details_t_handler
3158   (vl_api_one_eid_table_vni_details_t * mp)
3159 {
3160   vat_main_t *vam = &vat_main;
3161
3162   u8 *line = format (0, "%d", clib_net_to_host_u32 (mp->vni));
3163   print (vam->ofp, "%v", line);
3164   vec_free (line);
3165 }
3166
3167 static void
3168   vl_api_one_eid_table_vni_details_t_handler_json
3169   (vl_api_one_eid_table_vni_details_t * mp)
3170 {
3171   vat_main_t *vam = &vat_main;
3172   vat_json_node_t *node = NULL;
3173
3174   if (VAT_JSON_ARRAY != vam->json_tree.type)
3175     {
3176       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3177       vat_json_init_array (&vam->json_tree);
3178     }
3179   node = vat_json_array_add (&vam->json_tree);
3180   vat_json_init_object (node);
3181   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3182 }
3183
3184 static void
3185   vl_api_show_one_map_register_fallback_threshold_reply_t_handler
3186   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
3187 {
3188   vat_main_t *vam = &vat_main;
3189   int retval = clib_net_to_host_u32 (mp->retval);
3190
3191   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
3192   print (vam->ofp, "fallback threshold value: %d", mp->value);
3193
3194   vam->retval = retval;
3195   vam->result_ready = 1;
3196 }
3197
3198 static void
3199   vl_api_show_one_map_register_fallback_threshold_reply_t_handler_json
3200   (vl_api_show_one_map_register_fallback_threshold_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   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
3207   vat_json_init_object (node);
3208   vat_json_object_add_uint (node, "value", mp->value);
3209
3210   vat_json_print (vam->ofp, node);
3211   vat_json_free (node);
3212
3213   vam->retval = retval;
3214   vam->result_ready = 1;
3215 }
3216
3217 static void
3218   vl_api_show_one_map_register_state_reply_t_handler
3219   (vl_api_show_one_map_register_state_reply_t * mp)
3220 {
3221   vat_main_t *vam = &vat_main;
3222   int retval = clib_net_to_host_u32 (mp->retval);
3223
3224   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
3225
3226   vam->retval = retval;
3227   vam->result_ready = 1;
3228 }
3229
3230 static void
3231   vl_api_show_one_map_register_state_reply_t_handler_json
3232   (vl_api_show_one_map_register_state_reply_t * mp)
3233 {
3234   vat_main_t *vam = &vat_main;
3235   vat_json_node_t _node, *node = &_node;
3236   int retval = clib_net_to_host_u32 (mp->retval);
3237
3238   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
3239
3240   vat_json_init_object (node);
3241   vat_json_object_add_string_copy (node, "state", s);
3242
3243   vat_json_print (vam->ofp, node);
3244   vat_json_free (node);
3245
3246   vam->retval = retval;
3247   vam->result_ready = 1;
3248   vec_free (s);
3249 }
3250
3251 static void
3252   vl_api_show_one_rloc_probe_state_reply_t_handler
3253   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3254 {
3255   vat_main_t *vam = &vat_main;
3256   int retval = clib_net_to_host_u32 (mp->retval);
3257
3258   if (retval)
3259     goto end;
3260
3261   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
3262 end:
3263   vam->retval = retval;
3264   vam->result_ready = 1;
3265 }
3266
3267 static void
3268   vl_api_show_one_rloc_probe_state_reply_t_handler_json
3269   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3270 {
3271   vat_main_t *vam = &vat_main;
3272   vat_json_node_t _node, *node = &_node;
3273   int retval = clib_net_to_host_u32 (mp->retval);
3274
3275   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
3276   vat_json_init_object (node);
3277   vat_json_object_add_string_copy (node, "state", s);
3278
3279   vat_json_print (vam->ofp, node);
3280   vat_json_free (node);
3281
3282   vam->retval = retval;
3283   vam->result_ready = 1;
3284   vec_free (s);
3285 }
3286
3287 static void
3288   vl_api_show_one_stats_enable_disable_reply_t_handler
3289   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3290 {
3291   vat_main_t *vam = &vat_main;
3292   int retval = clib_net_to_host_u32 (mp->retval);
3293
3294   if (retval)
3295     goto end;
3296
3297   print (vam->ofp, "%s", mp->is_en ? "enabled" : "disabled");
3298 end:
3299   vam->retval = retval;
3300   vam->result_ready = 1;
3301 }
3302
3303 static void
3304   vl_api_show_one_stats_enable_disable_reply_t_handler_json
3305   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3306 {
3307   vat_main_t *vam = &vat_main;
3308   vat_json_node_t _node, *node = &_node;
3309   int retval = clib_net_to_host_u32 (mp->retval);
3310
3311   u8 *s = format (0, "%s", mp->is_en ? "enabled" : "disabled");
3312   vat_json_init_object (node);
3313   vat_json_object_add_string_copy (node, "state", s);
3314
3315   vat_json_print (vam->ofp, node);
3316   vat_json_free (node);
3317
3318   vam->retval = retval;
3319   vam->result_ready = 1;
3320   vec_free (s);
3321 }
3322
3323 static void
3324 api_gpe_fwd_entry_net_to_host (vl_api_gpe_fwd_entry_t * e)
3325 {
3326   e->dp_table = clib_net_to_host_u32 (e->dp_table);
3327   e->fwd_entry_index = clib_net_to_host_u32 (e->fwd_entry_index);
3328   e->vni = clib_net_to_host_u32 (e->vni);
3329 }
3330
3331 static void
3332   gpe_fwd_entries_get_reply_t_net_to_host
3333   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3334 {
3335   u32 i;
3336
3337   mp->count = clib_net_to_host_u32 (mp->count);
3338   for (i = 0; i < mp->count; i++)
3339     {
3340       api_gpe_fwd_entry_net_to_host (&mp->entries[i]);
3341     }
3342 }
3343
3344 static u8 *
3345 format_gpe_encap_mode (u8 * s, va_list * args)
3346 {
3347   u32 mode = va_arg (*args, u32);
3348
3349   switch (mode)
3350     {
3351     case 0:
3352       return format (s, "lisp");
3353     case 1:
3354       return format (s, "vxlan");
3355     }
3356   return 0;
3357 }
3358
3359 static void
3360   vl_api_gpe_get_encap_mode_reply_t_handler
3361   (vl_api_gpe_get_encap_mode_reply_t * mp)
3362 {
3363   vat_main_t *vam = &vat_main;
3364
3365   print (vam->ofp, "gpe mode: %U", format_gpe_encap_mode, mp->encap_mode);
3366   vam->retval = ntohl (mp->retval);
3367   vam->result_ready = 1;
3368 }
3369
3370 static void
3371   vl_api_gpe_get_encap_mode_reply_t_handler_json
3372   (vl_api_gpe_get_encap_mode_reply_t * mp)
3373 {
3374   vat_main_t *vam = &vat_main;
3375   vat_json_node_t node;
3376
3377   u8 *encap_mode = format (0, "%U", format_gpe_encap_mode, mp->encap_mode);
3378   vec_add1 (encap_mode, 0);
3379
3380   vat_json_init_object (&node);
3381   vat_json_object_add_string_copy (&node, "gpe_mode", encap_mode);
3382
3383   vec_free (encap_mode);
3384   vat_json_print (vam->ofp, &node);
3385   vat_json_free (&node);
3386
3387   vam->retval = ntohl (mp->retval);
3388   vam->result_ready = 1;
3389 }
3390
3391 static void
3392   vl_api_gpe_fwd_entry_path_details_t_handler
3393   (vl_api_gpe_fwd_entry_path_details_t * mp)
3394 {
3395   vat_main_t *vam = &vat_main;
3396   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3397
3398   if (mp->lcl_loc.is_ip4)
3399     format_ip_address_fcn = format_ip4_address;
3400   else
3401     format_ip_address_fcn = format_ip6_address;
3402
3403   print (vam->ofp, "w:%d %30U %30U", mp->rmt_loc.weight,
3404          format_ip_address_fcn, &mp->lcl_loc,
3405          format_ip_address_fcn, &mp->rmt_loc);
3406 }
3407
3408 static void
3409 lisp_fill_locator_node (vat_json_node_t * n, vl_api_gpe_locator_t * loc)
3410 {
3411   struct in6_addr ip6;
3412   struct in_addr ip4;
3413
3414   if (loc->is_ip4)
3415     {
3416       clib_memcpy (&ip4, loc->addr, sizeof (ip4));
3417       vat_json_object_add_ip4 (n, "address", ip4);
3418     }
3419   else
3420     {
3421       clib_memcpy (&ip6, loc->addr, sizeof (ip6));
3422       vat_json_object_add_ip6 (n, "address", ip6);
3423     }
3424   vat_json_object_add_uint (n, "weight", loc->weight);
3425 }
3426
3427 static void
3428   vl_api_gpe_fwd_entry_path_details_t_handler_json
3429   (vl_api_gpe_fwd_entry_path_details_t * mp)
3430 {
3431   vat_main_t *vam = &vat_main;
3432   vat_json_node_t *node = NULL;
3433   vat_json_node_t *loc_node;
3434
3435   if (VAT_JSON_ARRAY != vam->json_tree.type)
3436     {
3437       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3438       vat_json_init_array (&vam->json_tree);
3439     }
3440   node = vat_json_array_add (&vam->json_tree);
3441   vat_json_init_object (node);
3442
3443   loc_node = vat_json_object_add (node, "local_locator");
3444   vat_json_init_object (loc_node);
3445   lisp_fill_locator_node (loc_node, &mp->lcl_loc);
3446
3447   loc_node = vat_json_object_add (node, "remote_locator");
3448   vat_json_init_object (loc_node);
3449   lisp_fill_locator_node (loc_node, &mp->rmt_loc);
3450 }
3451
3452 static void
3453   vl_api_gpe_fwd_entries_get_reply_t_handler
3454   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3455 {
3456   vat_main_t *vam = &vat_main;
3457   u32 i;
3458   int retval = clib_net_to_host_u32 (mp->retval);
3459   vl_api_gpe_fwd_entry_t *e;
3460
3461   if (retval)
3462     goto end;
3463
3464   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3465
3466   for (i = 0; i < mp->count; i++)
3467     {
3468       e = &mp->entries[i];
3469       print (vam->ofp, "%10d %10d %U %40U", e->fwd_entry_index, e->dp_table,
3470              format_lisp_flat_eid, e->eid_type, e->leid, e->leid_prefix_len,
3471              format_lisp_flat_eid, e->eid_type, e->reid, e->reid_prefix_len);
3472     }
3473
3474 end:
3475   vam->retval = retval;
3476   vam->result_ready = 1;
3477 }
3478
3479 static void
3480   vl_api_gpe_fwd_entries_get_reply_t_handler_json
3481   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3482 {
3483   u8 *s = 0;
3484   vat_main_t *vam = &vat_main;
3485   vat_json_node_t *e = 0, root;
3486   u32 i;
3487   int retval = clib_net_to_host_u32 (mp->retval);
3488   vl_api_gpe_fwd_entry_t *fwd;
3489
3490   if (retval)
3491     goto end;
3492
3493   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3494   vat_json_init_array (&root);
3495
3496   for (i = 0; i < mp->count; i++)
3497     {
3498       e = vat_json_array_add (&root);
3499       fwd = &mp->entries[i];
3500
3501       vat_json_init_object (e);
3502       vat_json_object_add_int (e, "fwd_entry_index", fwd->fwd_entry_index);
3503       vat_json_object_add_int (e, "dp_table", fwd->dp_table);
3504       vat_json_object_add_int (e, "vni", fwd->vni);
3505       vat_json_object_add_int (e, "action", fwd->action);
3506
3507       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->leid,
3508                   fwd->leid_prefix_len);
3509       vec_add1 (s, 0);
3510       vat_json_object_add_string_copy (e, "leid", s);
3511       vec_free (s);
3512
3513       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->reid,
3514                   fwd->reid_prefix_len);
3515       vec_add1 (s, 0);
3516       vat_json_object_add_string_copy (e, "reid", s);
3517       vec_free (s);
3518     }
3519
3520   vat_json_print (vam->ofp, &root);
3521   vat_json_free (&root);
3522
3523 end:
3524   vam->retval = retval;
3525   vam->result_ready = 1;
3526 }
3527
3528 static void
3529   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler
3530   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3531 {
3532   vat_main_t *vam = &vat_main;
3533   u32 i, n;
3534   int retval = clib_net_to_host_u32 (mp->retval);
3535   vl_api_gpe_native_fwd_rpath_t *r;
3536
3537   if (retval)
3538     goto end;
3539
3540   n = clib_net_to_host_u32 (mp->count);
3541
3542   for (i = 0; i < n; i++)
3543     {
3544       r = &mp->entries[i];
3545       print (vam->ofp, "fib_index: %d sw_if_index %d nh %U",
3546              clib_net_to_host_u32 (r->fib_index),
3547              clib_net_to_host_u32 (r->nh_sw_if_index),
3548              r->is_ip4 ? format_ip4_address : format_ip6_address, r->nh_addr);
3549     }
3550
3551 end:
3552   vam->retval = retval;
3553   vam->result_ready = 1;
3554 }
3555
3556 static void
3557   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler_json
3558   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3559 {
3560   vat_main_t *vam = &vat_main;
3561   vat_json_node_t root, *e;
3562   u32 i, n;
3563   int retval = clib_net_to_host_u32 (mp->retval);
3564   vl_api_gpe_native_fwd_rpath_t *r;
3565   u8 *s;
3566
3567   if (retval)
3568     goto end;
3569
3570   n = clib_net_to_host_u32 (mp->count);
3571   vat_json_init_array (&root);
3572
3573   for (i = 0; i < n; i++)
3574     {
3575       e = vat_json_array_add (&root);
3576       vat_json_init_object (e);
3577       r = &mp->entries[i];
3578       s =
3579         format (0, "%U", r->is_ip4 ? format_ip4_address : format_ip6_address,
3580                 r->nh_addr);
3581       vec_add1 (s, 0);
3582       vat_json_object_add_string_copy (e, "ip4", s);
3583       vec_free (s);
3584
3585       vat_json_object_add_uint (e, "fib_index",
3586                                 clib_net_to_host_u32 (r->fib_index));
3587       vat_json_object_add_uint (e, "nh_sw_if_index",
3588                                 clib_net_to_host_u32 (r->nh_sw_if_index));
3589     }
3590
3591   vat_json_print (vam->ofp, &root);
3592   vat_json_free (&root);
3593
3594 end:
3595   vam->retval = retval;
3596   vam->result_ready = 1;
3597 }
3598
3599 static void
3600   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler
3601   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3602 {
3603   vat_main_t *vam = &vat_main;
3604   u32 i, n;
3605   int retval = clib_net_to_host_u32 (mp->retval);
3606
3607   if (retval)
3608     goto end;
3609
3610   n = clib_net_to_host_u32 (mp->count);
3611
3612   for (i = 0; i < n; i++)
3613     print (vam->ofp, "%d", clib_net_to_host_u32 (mp->vnis[i]));
3614
3615 end:
3616   vam->retval = retval;
3617   vam->result_ready = 1;
3618 }
3619
3620 static void
3621   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler_json
3622   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3623 {
3624   vat_main_t *vam = &vat_main;
3625   vat_json_node_t root;
3626   u32 i, n;
3627   int retval = clib_net_to_host_u32 (mp->retval);
3628
3629   if (retval)
3630     goto end;
3631
3632   n = clib_net_to_host_u32 (mp->count);
3633   vat_json_init_array (&root);
3634
3635   for (i = 0; i < n; i++)
3636     vat_json_array_add_uint (&root, clib_net_to_host_u32 (mp->vnis[i]));
3637
3638   vat_json_print (vam->ofp, &root);
3639   vat_json_free (&root);
3640
3641 end:
3642   vam->retval = retval;
3643   vam->result_ready = 1;
3644 }
3645
3646 static void
3647   vl_api_one_ndp_entries_get_reply_t_handler
3648   (vl_api_one_ndp_entries_get_reply_t * mp)
3649 {
3650   vat_main_t *vam = &vat_main;
3651   u32 i, n;
3652   int retval = clib_net_to_host_u32 (mp->retval);
3653
3654   if (retval)
3655     goto end;
3656
3657   n = clib_net_to_host_u32 (mp->count);
3658
3659   for (i = 0; i < n; i++)
3660     print (vam->ofp, "%U -> %U", format_ip6_address, &mp->entries[i].ip6,
3661            format_ethernet_address, mp->entries[i].mac);
3662
3663 end:
3664   vam->retval = retval;
3665   vam->result_ready = 1;
3666 }
3667
3668 static void
3669   vl_api_one_ndp_entries_get_reply_t_handler_json
3670   (vl_api_one_ndp_entries_get_reply_t * mp)
3671 {
3672   u8 *s = 0;
3673   vat_main_t *vam = &vat_main;
3674   vat_json_node_t *e = 0, root;
3675   u32 i, n;
3676   int retval = clib_net_to_host_u32 (mp->retval);
3677   vl_api_one_ndp_entry_t *arp_entry;
3678
3679   if (retval)
3680     goto end;
3681
3682   n = clib_net_to_host_u32 (mp->count);
3683   vat_json_init_array (&root);
3684
3685   for (i = 0; i < n; i++)
3686     {
3687       e = vat_json_array_add (&root);
3688       arp_entry = &mp->entries[i];
3689
3690       vat_json_init_object (e);
3691       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
3692       vec_add1 (s, 0);
3693
3694       vat_json_object_add_string_copy (e, "mac", s);
3695       vec_free (s);
3696
3697       s = format (0, "%U", format_ip6_address, &arp_entry->ip6);
3698       vec_add1 (s, 0);
3699       vat_json_object_add_string_copy (e, "ip6", s);
3700       vec_free (s);
3701     }
3702
3703   vat_json_print (vam->ofp, &root);
3704   vat_json_free (&root);
3705
3706 end:
3707   vam->retval = retval;
3708   vam->result_ready = 1;
3709 }
3710
3711 static void
3712   vl_api_one_l2_arp_entries_get_reply_t_handler
3713   (vl_api_one_l2_arp_entries_get_reply_t * mp)
3714 {
3715   vat_main_t *vam = &vat_main;
3716   u32 i, n;
3717   int retval = clib_net_to_host_u32 (mp->retval);
3718
3719   if (retval)
3720     goto end;
3721
3722   n = clib_net_to_host_u32 (mp->count);
3723
3724   for (i = 0; i < n; i++)
3725     print (vam->ofp, "%U -> %U", format_ip4_address, &mp->entries[i].ip4,
3726            format_ethernet_address, mp->entries[i].mac);
3727
3728 end:
3729   vam->retval = retval;
3730   vam->result_ready = 1;
3731 }
3732
3733 static void
3734   vl_api_one_l2_arp_entries_get_reply_t_handler_json
3735   (vl_api_one_l2_arp_entries_get_reply_t * mp)
3736 {
3737   u8 *s = 0;
3738   vat_main_t *vam = &vat_main;
3739   vat_json_node_t *e = 0, root;
3740   u32 i, n;
3741   int retval = clib_net_to_host_u32 (mp->retval);
3742   vl_api_one_l2_arp_entry_t *arp_entry;
3743
3744   if (retval)
3745     goto end;
3746
3747   n = clib_net_to_host_u32 (mp->count);
3748   vat_json_init_array (&root);
3749
3750   for (i = 0; i < n; i++)
3751     {
3752       e = vat_json_array_add (&root);
3753       arp_entry = &mp->entries[i];
3754
3755       vat_json_init_object (e);
3756       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
3757       vec_add1 (s, 0);
3758
3759       vat_json_object_add_string_copy (e, "mac", s);
3760       vec_free (s);
3761
3762       s = format (0, "%U", format_ip4_address, &arp_entry->ip4);
3763       vec_add1 (s, 0);
3764       vat_json_object_add_string_copy (e, "ip4", s);
3765       vec_free (s);
3766     }
3767
3768   vat_json_print (vam->ofp, &root);
3769   vat_json_free (&root);
3770
3771 end:
3772   vam->retval = retval;
3773   vam->result_ready = 1;
3774 }
3775
3776 static void
3777 vl_api_one_ndp_bd_get_reply_t_handler (vl_api_one_ndp_bd_get_reply_t * mp)
3778 {
3779   vat_main_t *vam = &vat_main;
3780   u32 i, n;
3781   int retval = clib_net_to_host_u32 (mp->retval);
3782
3783   if (retval)
3784     goto end;
3785
3786   n = clib_net_to_host_u32 (mp->count);
3787
3788   for (i = 0; i < n; i++)
3789     {
3790       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
3791     }
3792
3793 end:
3794   vam->retval = retval;
3795   vam->result_ready = 1;
3796 }
3797
3798 static void
3799   vl_api_one_ndp_bd_get_reply_t_handler_json
3800   (vl_api_one_ndp_bd_get_reply_t * mp)
3801 {
3802   vat_main_t *vam = &vat_main;
3803   vat_json_node_t root;
3804   u32 i, n;
3805   int retval = clib_net_to_host_u32 (mp->retval);
3806
3807   if (retval)
3808     goto end;
3809
3810   n = clib_net_to_host_u32 (mp->count);
3811   vat_json_init_array (&root);
3812
3813   for (i = 0; i < n; i++)
3814     {
3815       vat_json_array_add_uint (&root,
3816                                clib_net_to_host_u32 (mp->bridge_domains[i]));
3817     }
3818
3819   vat_json_print (vam->ofp, &root);
3820   vat_json_free (&root);
3821
3822 end:
3823   vam->retval = retval;
3824   vam->result_ready = 1;
3825 }
3826
3827 static void
3828   vl_api_one_l2_arp_bd_get_reply_t_handler
3829   (vl_api_one_l2_arp_bd_get_reply_t * mp)
3830 {
3831   vat_main_t *vam = &vat_main;
3832   u32 i, n;
3833   int retval = clib_net_to_host_u32 (mp->retval);
3834
3835   if (retval)
3836     goto end;
3837
3838   n = clib_net_to_host_u32 (mp->count);
3839
3840   for (i = 0; i < n; i++)
3841     {
3842       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
3843     }
3844
3845 end:
3846   vam->retval = retval;
3847   vam->result_ready = 1;
3848 }
3849
3850 static void
3851   vl_api_one_l2_arp_bd_get_reply_t_handler_json
3852   (vl_api_one_l2_arp_bd_get_reply_t * mp)
3853 {
3854   vat_main_t *vam = &vat_main;
3855   vat_json_node_t root;
3856   u32 i, n;
3857   int retval = clib_net_to_host_u32 (mp->retval);
3858
3859   if (retval)
3860     goto end;
3861
3862   n = clib_net_to_host_u32 (mp->count);
3863   vat_json_init_array (&root);
3864
3865   for (i = 0; i < n; i++)
3866     {
3867       vat_json_array_add_uint (&root,
3868                                clib_net_to_host_u32 (mp->bridge_domains[i]));
3869     }
3870
3871   vat_json_print (vam->ofp, &root);
3872   vat_json_free (&root);
3873
3874 end:
3875   vam->retval = retval;
3876   vam->result_ready = 1;
3877 }
3878
3879 static void
3880   vl_api_one_adjacencies_get_reply_t_handler
3881   (vl_api_one_adjacencies_get_reply_t * mp)
3882 {
3883   vat_main_t *vam = &vat_main;
3884   u32 i, n;
3885   int retval = clib_net_to_host_u32 (mp->retval);
3886   vl_api_one_adjacency_t *a;
3887
3888   if (retval)
3889     goto end;
3890
3891   n = clib_net_to_host_u32 (mp->count);
3892
3893   for (i = 0; i < n; i++)
3894     {
3895       a = &mp->adjacencies[i];
3896       print (vam->ofp, "%U %40U",
3897              format_lisp_flat_eid, a->eid_type, a->leid, a->leid_prefix_len,
3898              format_lisp_flat_eid, a->eid_type, a->reid, a->reid_prefix_len);
3899     }
3900
3901 end:
3902   vam->retval = retval;
3903   vam->result_ready = 1;
3904 }
3905
3906 static void
3907   vl_api_one_adjacencies_get_reply_t_handler_json
3908   (vl_api_one_adjacencies_get_reply_t * mp)
3909 {
3910   u8 *s = 0;
3911   vat_main_t *vam = &vat_main;
3912   vat_json_node_t *e = 0, root;
3913   u32 i, n;
3914   int retval = clib_net_to_host_u32 (mp->retval);
3915   vl_api_one_adjacency_t *a;
3916
3917   if (retval)
3918     goto end;
3919
3920   n = clib_net_to_host_u32 (mp->count);
3921   vat_json_init_array (&root);
3922
3923   for (i = 0; i < n; i++)
3924     {
3925       e = vat_json_array_add (&root);
3926       a = &mp->adjacencies[i];
3927
3928       vat_json_init_object (e);
3929       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->leid,
3930                   a->leid_prefix_len);
3931       vec_add1 (s, 0);
3932       vat_json_object_add_string_copy (e, "leid", s);
3933       vec_free (s);
3934
3935       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->reid,
3936                   a->reid_prefix_len);
3937       vec_add1 (s, 0);
3938       vat_json_object_add_string_copy (e, "reid", s);
3939       vec_free (s);
3940     }
3941
3942   vat_json_print (vam->ofp, &root);
3943   vat_json_free (&root);
3944
3945 end:
3946   vam->retval = retval;
3947   vam->result_ready = 1;
3948 }
3949
3950 static void
3951 vl_api_one_map_server_details_t_handler (vl_api_one_map_server_details_t * mp)
3952 {
3953   vat_main_t *vam = &vat_main;
3954
3955   print (vam->ofp, "%=20U",
3956          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
3957          mp->ip_address);
3958 }
3959
3960 static void
3961   vl_api_one_map_server_details_t_handler_json
3962   (vl_api_one_map_server_details_t * mp)
3963 {
3964   vat_main_t *vam = &vat_main;
3965   vat_json_node_t *node = NULL;
3966   struct in6_addr ip6;
3967   struct in_addr ip4;
3968
3969   if (VAT_JSON_ARRAY != vam->json_tree.type)
3970     {
3971       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3972       vat_json_init_array (&vam->json_tree);
3973     }
3974   node = vat_json_array_add (&vam->json_tree);
3975
3976   vat_json_init_object (node);
3977   if (mp->is_ipv6)
3978     {
3979       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
3980       vat_json_object_add_ip6 (node, "map-server", ip6);
3981     }
3982   else
3983     {
3984       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
3985       vat_json_object_add_ip4 (node, "map-server", ip4);
3986     }
3987 }
3988
3989 static void
3990 vl_api_one_map_resolver_details_t_handler (vl_api_one_map_resolver_details_t
3991                                            * mp)
3992 {
3993   vat_main_t *vam = &vat_main;
3994
3995   print (vam->ofp, "%=20U",
3996          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
3997          mp->ip_address);
3998 }
3999
4000 static void
4001   vl_api_one_map_resolver_details_t_handler_json
4002   (vl_api_one_map_resolver_details_t * mp)
4003 {
4004   vat_main_t *vam = &vat_main;
4005   vat_json_node_t *node = NULL;
4006   struct in6_addr ip6;
4007   struct in_addr ip4;
4008
4009   if (VAT_JSON_ARRAY != vam->json_tree.type)
4010     {
4011       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4012       vat_json_init_array (&vam->json_tree);
4013     }
4014   node = vat_json_array_add (&vam->json_tree);
4015
4016   vat_json_init_object (node);
4017   if (mp->is_ipv6)
4018     {
4019       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
4020       vat_json_object_add_ip6 (node, "map resolver", ip6);
4021     }
4022   else
4023     {
4024       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
4025       vat_json_object_add_ip4 (node, "map resolver", ip4);
4026     }
4027 }
4028
4029 static void
4030 vl_api_show_one_status_reply_t_handler (vl_api_show_one_status_reply_t * mp)
4031 {
4032   vat_main_t *vam = &vat_main;
4033   i32 retval = ntohl (mp->retval);
4034
4035   if (0 <= retval)
4036     {
4037       print (vam->ofp, "feature: %s\ngpe: %s",
4038              mp->feature_status ? "enabled" : "disabled",
4039              mp->gpe_status ? "enabled" : "disabled");
4040     }
4041
4042   vam->retval = retval;
4043   vam->result_ready = 1;
4044 }
4045
4046 static void
4047   vl_api_show_one_status_reply_t_handler_json
4048   (vl_api_show_one_status_reply_t * mp)
4049 {
4050   vat_main_t *vam = &vat_main;
4051   vat_json_node_t node;
4052   u8 *gpe_status = NULL;
4053   u8 *feature_status = NULL;
4054
4055   gpe_status = format (0, "%s", mp->gpe_status ? "enabled" : "disabled");
4056   feature_status = format (0, "%s",
4057                            mp->feature_status ? "enabled" : "disabled");
4058   vec_add1 (gpe_status, 0);
4059   vec_add1 (feature_status, 0);
4060
4061   vat_json_init_object (&node);
4062   vat_json_object_add_string_copy (&node, "gpe_status", gpe_status);
4063   vat_json_object_add_string_copy (&node, "feature_status", feature_status);
4064
4065   vec_free (gpe_status);
4066   vec_free (feature_status);
4067
4068   vat_json_print (vam->ofp, &node);
4069   vat_json_free (&node);
4070
4071   vam->retval = ntohl (mp->retval);
4072   vam->result_ready = 1;
4073 }
4074
4075 static void
4076   vl_api_one_get_map_request_itr_rlocs_reply_t_handler
4077   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
4078 {
4079   vat_main_t *vam = &vat_main;
4080   i32 retval = ntohl (mp->retval);
4081
4082   if (retval >= 0)
4083     {
4084       print (vam->ofp, "%=20s", mp->locator_set_name);
4085     }
4086
4087   vam->retval = retval;
4088   vam->result_ready = 1;
4089 }
4090
4091 static void
4092   vl_api_one_get_map_request_itr_rlocs_reply_t_handler_json
4093   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
4094 {
4095   vat_main_t *vam = &vat_main;
4096   vat_json_node_t *node = NULL;
4097
4098   if (VAT_JSON_ARRAY != vam->json_tree.type)
4099     {
4100       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4101       vat_json_init_array (&vam->json_tree);
4102     }
4103   node = vat_json_array_add (&vam->json_tree);
4104
4105   vat_json_init_object (node);
4106   vat_json_object_add_string_copy (node, "itr-rlocs", mp->locator_set_name);
4107
4108   vat_json_print (vam->ofp, node);
4109   vat_json_free (node);
4110
4111   vam->retval = ntohl (mp->retval);
4112   vam->result_ready = 1;
4113 }
4114
4115 static u8 *
4116 format_lisp_map_request_mode (u8 * s, va_list * args)
4117 {
4118   u32 mode = va_arg (*args, u32);
4119
4120   switch (mode)
4121     {
4122     case 0:
4123       return format (0, "dst-only");
4124     case 1:
4125       return format (0, "src-dst");
4126     }
4127   return 0;
4128 }
4129
4130 static void
4131   vl_api_show_one_map_request_mode_reply_t_handler
4132   (vl_api_show_one_map_request_mode_reply_t * mp)
4133 {
4134   vat_main_t *vam = &vat_main;
4135   i32 retval = ntohl (mp->retval);
4136
4137   if (0 <= retval)
4138     {
4139       u32 mode = mp->mode;
4140       print (vam->ofp, "map_request_mode: %U",
4141              format_lisp_map_request_mode, mode);
4142     }
4143
4144   vam->retval = retval;
4145   vam->result_ready = 1;
4146 }
4147
4148 static void
4149   vl_api_show_one_map_request_mode_reply_t_handler_json
4150   (vl_api_show_one_map_request_mode_reply_t * mp)
4151 {
4152   vat_main_t *vam = &vat_main;
4153   vat_json_node_t node;
4154   u8 *s = 0;
4155   u32 mode;
4156
4157   mode = mp->mode;
4158   s = format (0, "%U", format_lisp_map_request_mode, mode);
4159   vec_add1 (s, 0);
4160
4161   vat_json_init_object (&node);
4162   vat_json_object_add_string_copy (&node, "map_request_mode", s);
4163   vat_json_print (vam->ofp, &node);
4164   vat_json_free (&node);
4165
4166   vec_free (s);
4167   vam->retval = ntohl (mp->retval);
4168   vam->result_ready = 1;
4169 }
4170
4171 static void
4172   vl_api_one_show_xtr_mode_reply_t_handler
4173   (vl_api_one_show_xtr_mode_reply_t * mp)
4174 {
4175   vat_main_t *vam = &vat_main;
4176   i32 retval = ntohl (mp->retval);
4177
4178   if (0 <= retval)
4179     {
4180       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4181     }
4182
4183   vam->retval = retval;
4184   vam->result_ready = 1;
4185 }
4186
4187 static void
4188   vl_api_one_show_xtr_mode_reply_t_handler_json
4189   (vl_api_one_show_xtr_mode_reply_t * mp)
4190 {
4191   vat_main_t *vam = &vat_main;
4192   vat_json_node_t node;
4193   u8 *status = 0;
4194
4195   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4196   vec_add1 (status, 0);
4197
4198   vat_json_init_object (&node);
4199   vat_json_object_add_string_copy (&node, "status", status);
4200
4201   vec_free (status);
4202
4203   vat_json_print (vam->ofp, &node);
4204   vat_json_free (&node);
4205
4206   vam->retval = ntohl (mp->retval);
4207   vam->result_ready = 1;
4208 }
4209
4210 static void
4211   vl_api_one_show_pitr_mode_reply_t_handler
4212   (vl_api_one_show_pitr_mode_reply_t * mp)
4213 {
4214   vat_main_t *vam = &vat_main;
4215   i32 retval = ntohl (mp->retval);
4216
4217   if (0 <= retval)
4218     {
4219       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4220     }
4221
4222   vam->retval = retval;
4223   vam->result_ready = 1;
4224 }
4225
4226 static void
4227   vl_api_one_show_pitr_mode_reply_t_handler_json
4228   (vl_api_one_show_pitr_mode_reply_t * mp)
4229 {
4230   vat_main_t *vam = &vat_main;
4231   vat_json_node_t node;
4232   u8 *status = 0;
4233
4234   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4235   vec_add1 (status, 0);
4236
4237   vat_json_init_object (&node);
4238   vat_json_object_add_string_copy (&node, "status", status);
4239
4240   vec_free (status);
4241
4242   vat_json_print (vam->ofp, &node);
4243   vat_json_free (&node);
4244
4245   vam->retval = ntohl (mp->retval);
4246   vam->result_ready = 1;
4247 }
4248
4249 static void
4250   vl_api_one_show_petr_mode_reply_t_handler
4251   (vl_api_one_show_petr_mode_reply_t * mp)
4252 {
4253   vat_main_t *vam = &vat_main;
4254   i32 retval = ntohl (mp->retval);
4255
4256   if (0 <= retval)
4257     {
4258       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4259     }
4260
4261   vam->retval = retval;
4262   vam->result_ready = 1;
4263 }
4264
4265 static void
4266   vl_api_one_show_petr_mode_reply_t_handler_json
4267   (vl_api_one_show_petr_mode_reply_t * mp)
4268 {
4269   vat_main_t *vam = &vat_main;
4270   vat_json_node_t node;
4271   u8 *status = 0;
4272
4273   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4274   vec_add1 (status, 0);
4275
4276   vat_json_init_object (&node);
4277   vat_json_object_add_string_copy (&node, "status", status);
4278
4279   vec_free (status);
4280
4281   vat_json_print (vam->ofp, &node);
4282   vat_json_free (&node);
4283
4284   vam->retval = ntohl (mp->retval);
4285   vam->result_ready = 1;
4286 }
4287
4288 static void
4289   vl_api_show_one_use_petr_reply_t_handler
4290   (vl_api_show_one_use_petr_reply_t * mp)
4291 {
4292   vat_main_t *vam = &vat_main;
4293   i32 retval = ntohl (mp->retval);
4294
4295   if (0 <= retval)
4296     {
4297       print (vam->ofp, "%s\n", mp->status ? "enabled" : "disabled");
4298       if (mp->status)
4299         {
4300           print (vam->ofp, "Proxy-ETR address; %U",
4301                  mp->is_ip4 ? format_ip4_address : format_ip6_address,
4302                  mp->address);
4303         }
4304     }
4305
4306   vam->retval = retval;
4307   vam->result_ready = 1;
4308 }
4309
4310 static void
4311   vl_api_show_one_use_petr_reply_t_handler_json
4312   (vl_api_show_one_use_petr_reply_t * mp)
4313 {
4314   vat_main_t *vam = &vat_main;
4315   vat_json_node_t node;
4316   u8 *status = 0;
4317   struct in_addr ip4;
4318   struct in6_addr ip6;
4319
4320   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4321   vec_add1 (status, 0);
4322
4323   vat_json_init_object (&node);
4324   vat_json_object_add_string_copy (&node, "status", status);
4325   if (mp->status)
4326     {
4327       if (mp->is_ip4)
4328         {
4329           clib_memcpy (&ip6, mp->address, sizeof (ip6));
4330           vat_json_object_add_ip6 (&node, "address", ip6);
4331         }
4332       else
4333         {
4334           clib_memcpy (&ip4, mp->address, sizeof (ip4));
4335           vat_json_object_add_ip4 (&node, "address", ip4);
4336         }
4337     }
4338
4339   vec_free (status);
4340
4341   vat_json_print (vam->ofp, &node);
4342   vat_json_free (&node);
4343
4344   vam->retval = ntohl (mp->retval);
4345   vam->result_ready = 1;
4346 }
4347
4348 static void
4349   vl_api_show_one_nsh_mapping_reply_t_handler
4350   (vl_api_show_one_nsh_mapping_reply_t * mp)
4351 {
4352   vat_main_t *vam = &vat_main;
4353   i32 retval = ntohl (mp->retval);
4354
4355   if (0 <= retval)
4356     {
4357       print (vam->ofp, "%-20s%-16s",
4358              mp->is_set ? "set" : "not-set",
4359              mp->is_set ? (char *) mp->locator_set_name : "");
4360     }
4361
4362   vam->retval = retval;
4363   vam->result_ready = 1;
4364 }
4365
4366 static void
4367   vl_api_show_one_nsh_mapping_reply_t_handler_json
4368   (vl_api_show_one_nsh_mapping_reply_t * mp)
4369 {
4370   vat_main_t *vam = &vat_main;
4371   vat_json_node_t node;
4372   u8 *status = 0;
4373
4374   status = format (0, "%s", mp->is_set ? "yes" : "no");
4375   vec_add1 (status, 0);
4376
4377   vat_json_init_object (&node);
4378   vat_json_object_add_string_copy (&node, "is_set", status);
4379   if (mp->is_set)
4380     {
4381       vat_json_object_add_string_copy (&node, "locator_set",
4382                                        mp->locator_set_name);
4383     }
4384
4385   vec_free (status);
4386
4387   vat_json_print (vam->ofp, &node);
4388   vat_json_free (&node);
4389
4390   vam->retval = ntohl (mp->retval);
4391   vam->result_ready = 1;
4392 }
4393
4394 static void
4395   vl_api_show_one_map_register_ttl_reply_t_handler
4396   (vl_api_show_one_map_register_ttl_reply_t * mp)
4397 {
4398   vat_main_t *vam = &vat_main;
4399   i32 retval = ntohl (mp->retval);
4400
4401   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4402
4403   if (0 <= retval)
4404     {
4405       print (vam->ofp, "ttl: %u", mp->ttl);
4406     }
4407
4408   vam->retval = retval;
4409   vam->result_ready = 1;
4410 }
4411
4412 static void
4413   vl_api_show_one_map_register_ttl_reply_t_handler_json
4414   (vl_api_show_one_map_register_ttl_reply_t * mp)
4415 {
4416   vat_main_t *vam = &vat_main;
4417   vat_json_node_t node;
4418
4419   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4420   vat_json_init_object (&node);
4421   vat_json_object_add_uint (&node, "ttl", mp->ttl);
4422
4423   vat_json_print (vam->ofp, &node);
4424   vat_json_free (&node);
4425
4426   vam->retval = ntohl (mp->retval);
4427   vam->result_ready = 1;
4428 }
4429
4430 static void
4431 vl_api_show_one_pitr_reply_t_handler (vl_api_show_one_pitr_reply_t * mp)
4432 {
4433   vat_main_t *vam = &vat_main;
4434   i32 retval = ntohl (mp->retval);
4435
4436   if (0 <= retval)
4437     {
4438       print (vam->ofp, "%-20s%-16s",
4439              mp->status ? "enabled" : "disabled",
4440              mp->status ? (char *) mp->locator_set_name : "");
4441     }
4442
4443   vam->retval = retval;
4444   vam->result_ready = 1;
4445 }
4446
4447 static void
4448 vl_api_show_one_pitr_reply_t_handler_json (vl_api_show_one_pitr_reply_t * mp)
4449 {
4450   vat_main_t *vam = &vat_main;
4451   vat_json_node_t node;
4452   u8 *status = 0;
4453
4454   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4455   vec_add1 (status, 0);
4456
4457   vat_json_init_object (&node);
4458   vat_json_object_add_string_copy (&node, "status", status);
4459   if (mp->status)
4460     {
4461       vat_json_object_add_string_copy (&node, "locator_set",
4462                                        mp->locator_set_name);
4463     }
4464
4465   vec_free (status);
4466
4467   vat_json_print (vam->ofp, &node);
4468   vat_json_free (&node);
4469
4470   vam->retval = ntohl (mp->retval);
4471   vam->result_ready = 1;
4472 }
4473
4474 static u8 *
4475 format_policer_type (u8 * s, va_list * va)
4476 {
4477   u32 i = va_arg (*va, u32);
4478
4479   if (i == SSE2_QOS_POLICER_TYPE_1R2C)
4480     s = format (s, "1r2c");
4481   else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
4482     s = format (s, "1r3c");
4483   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
4484     s = format (s, "2r3c-2698");
4485   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
4486     s = format (s, "2r3c-4115");
4487   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
4488     s = format (s, "2r3c-mef5cf1");
4489   else
4490     s = format (s, "ILLEGAL");
4491   return s;
4492 }
4493
4494 static u8 *
4495 format_policer_rate_type (u8 * s, va_list * va)
4496 {
4497   u32 i = va_arg (*va, u32);
4498
4499   if (i == SSE2_QOS_RATE_KBPS)
4500     s = format (s, "kbps");
4501   else if (i == SSE2_QOS_RATE_PPS)
4502     s = format (s, "pps");
4503   else
4504     s = format (s, "ILLEGAL");
4505   return s;
4506 }
4507
4508 static u8 *
4509 format_policer_round_type (u8 * s, va_list * va)
4510 {
4511   u32 i = va_arg (*va, u32);
4512
4513   if (i == SSE2_QOS_ROUND_TO_CLOSEST)
4514     s = format (s, "closest");
4515   else if (i == SSE2_QOS_ROUND_TO_UP)
4516     s = format (s, "up");
4517   else if (i == SSE2_QOS_ROUND_TO_DOWN)
4518     s = format (s, "down");
4519   else
4520     s = format (s, "ILLEGAL");
4521   return s;
4522 }
4523
4524 static u8 *
4525 format_policer_action_type (u8 * s, va_list * va)
4526 {
4527   u32 i = va_arg (*va, u32);
4528
4529   if (i == SSE2_QOS_ACTION_DROP)
4530     s = format (s, "drop");
4531   else if (i == SSE2_QOS_ACTION_TRANSMIT)
4532     s = format (s, "transmit");
4533   else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4534     s = format (s, "mark-and-transmit");
4535   else
4536     s = format (s, "ILLEGAL");
4537   return s;
4538 }
4539
4540 static u8 *
4541 format_dscp (u8 * s, va_list * va)
4542 {
4543   u32 i = va_arg (*va, u32);
4544   char *t = 0;
4545
4546   switch (i)
4547     {
4548 #define _(v,f,str) case VNET_DSCP_##f: t = str; break;
4549       foreach_vnet_dscp
4550 #undef _
4551     default:
4552       return format (s, "ILLEGAL");
4553     }
4554   s = format (s, "%s", t);
4555   return s;
4556 }
4557
4558 static void
4559 vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
4560 {
4561   vat_main_t *vam = &vat_main;
4562   u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
4563
4564   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4565     conform_dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
4566   else
4567     conform_dscp_str = format (0, "");
4568
4569   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4570     exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
4571   else
4572     exceed_dscp_str = format (0, "");
4573
4574   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4575     violate_dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
4576   else
4577     violate_dscp_str = format (0, "");
4578
4579   print (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
4580          "rate type %U, round type %U, %s rate, %s color-aware, "
4581          "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
4582          "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
4583          "conform action %U%s, exceed action %U%s, violate action %U%s",
4584          mp->name,
4585          format_policer_type, mp->type,
4586          ntohl (mp->cir),
4587          ntohl (mp->eir),
4588          clib_net_to_host_u64 (mp->cb),
4589          clib_net_to_host_u64 (mp->eb),
4590          format_policer_rate_type, mp->rate_type,
4591          format_policer_round_type, mp->round_type,
4592          mp->single_rate ? "single" : "dual",
4593          mp->color_aware ? "is" : "not",
4594          ntohl (mp->cir_tokens_per_period),
4595          ntohl (mp->pir_tokens_per_period),
4596          ntohl (mp->scale),
4597          ntohl (mp->current_limit),
4598          ntohl (mp->current_bucket),
4599          ntohl (mp->extended_limit),
4600          ntohl (mp->extended_bucket),
4601          clib_net_to_host_u64 (mp->last_update_time),
4602          format_policer_action_type, mp->conform_action_type,
4603          conform_dscp_str,
4604          format_policer_action_type, mp->exceed_action_type,
4605          exceed_dscp_str,
4606          format_policer_action_type, mp->violate_action_type,
4607          violate_dscp_str);
4608
4609   vec_free (conform_dscp_str);
4610   vec_free (exceed_dscp_str);
4611   vec_free (violate_dscp_str);
4612 }
4613
4614 static void vl_api_policer_details_t_handler_json
4615   (vl_api_policer_details_t * mp)
4616 {
4617   vat_main_t *vam = &vat_main;
4618   vat_json_node_t *node;
4619   u8 *rate_type_str, *round_type_str, *type_str;
4620   u8 *conform_action_str, *exceed_action_str, *violate_action_str;
4621
4622   rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
4623   round_type_str =
4624     format (0, "%U", format_policer_round_type, mp->round_type);
4625   type_str = format (0, "%U", format_policer_type, mp->type);
4626   conform_action_str = format (0, "%U", format_policer_action_type,
4627                                mp->conform_action_type);
4628   exceed_action_str = format (0, "%U", format_policer_action_type,
4629                               mp->exceed_action_type);
4630   violate_action_str = format (0, "%U", format_policer_action_type,
4631                                mp->violate_action_type);
4632
4633   if (VAT_JSON_ARRAY != vam->json_tree.type)
4634     {
4635       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4636       vat_json_init_array (&vam->json_tree);
4637     }
4638   node = vat_json_array_add (&vam->json_tree);
4639
4640   vat_json_init_object (node);
4641   vat_json_object_add_string_copy (node, "name", mp->name);
4642   vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
4643   vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
4644   vat_json_object_add_uint (node, "cb", clib_net_to_host_u64 (mp->cb));
4645   vat_json_object_add_uint (node, "eb", clib_net_to_host_u64 (mp->eb));
4646   vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
4647   vat_json_object_add_string_copy (node, "round_type", round_type_str);
4648   vat_json_object_add_string_copy (node, "type", type_str);
4649   vat_json_object_add_uint (node, "single_rate", mp->single_rate);
4650   vat_json_object_add_uint (node, "color_aware", mp->color_aware);
4651   vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
4652   vat_json_object_add_uint (node, "cir_tokens_per_period",
4653                             ntohl (mp->cir_tokens_per_period));
4654   vat_json_object_add_uint (node, "eir_tokens_per_period",
4655                             ntohl (mp->pir_tokens_per_period));
4656   vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
4657   vat_json_object_add_uint (node, "current_bucket",
4658                             ntohl (mp->current_bucket));
4659   vat_json_object_add_uint (node, "extended_limit",
4660                             ntohl (mp->extended_limit));
4661   vat_json_object_add_uint (node, "extended_bucket",
4662                             ntohl (mp->extended_bucket));
4663   vat_json_object_add_uint (node, "last_update_time",
4664                             ntohl (mp->last_update_time));
4665   vat_json_object_add_string_copy (node, "conform_action",
4666                                    conform_action_str);
4667   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4668     {
4669       u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
4670       vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
4671       vec_free (dscp_str);
4672     }
4673   vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
4674   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4675     {
4676       u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
4677       vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
4678       vec_free (dscp_str);
4679     }
4680   vat_json_object_add_string_copy (node, "violate_action",
4681                                    violate_action_str);
4682   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4683     {
4684       u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
4685       vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
4686       vec_free (dscp_str);
4687     }
4688
4689   vec_free (rate_type_str);
4690   vec_free (round_type_str);
4691   vec_free (type_str);
4692   vec_free (conform_action_str);
4693   vec_free (exceed_action_str);
4694   vec_free (violate_action_str);
4695 }
4696
4697 static void
4698 vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
4699                                            mp)
4700 {
4701   vat_main_t *vam = &vat_main;
4702   int i, count = ntohl (mp->count);
4703
4704   if (count > 0)
4705     print (vam->ofp, "classify table ids (%d) : ", count);
4706   for (i = 0; i < count; i++)
4707     {
4708       print (vam->ofp, "%d", ntohl (mp->ids[i]));
4709       print (vam->ofp, (i < count - 1) ? "," : "");
4710     }
4711   vam->retval = ntohl (mp->retval);
4712   vam->result_ready = 1;
4713 }
4714
4715 static void
4716   vl_api_classify_table_ids_reply_t_handler_json
4717   (vl_api_classify_table_ids_reply_t * mp)
4718 {
4719   vat_main_t *vam = &vat_main;
4720   int i, count = ntohl (mp->count);
4721
4722   if (count > 0)
4723     {
4724       vat_json_node_t node;
4725
4726       vat_json_init_object (&node);
4727       for (i = 0; i < count; i++)
4728         {
4729           vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
4730         }
4731       vat_json_print (vam->ofp, &node);
4732       vat_json_free (&node);
4733     }
4734   vam->retval = ntohl (mp->retval);
4735   vam->result_ready = 1;
4736 }
4737
4738 static void
4739   vl_api_classify_table_by_interface_reply_t_handler
4740   (vl_api_classify_table_by_interface_reply_t * mp)
4741 {
4742   vat_main_t *vam = &vat_main;
4743   u32 table_id;
4744
4745   table_id = ntohl (mp->l2_table_id);
4746   if (table_id != ~0)
4747     print (vam->ofp, "l2 table id : %d", table_id);
4748   else
4749     print (vam->ofp, "l2 table id : No input ACL tables configured");
4750   table_id = ntohl (mp->ip4_table_id);
4751   if (table_id != ~0)
4752     print (vam->ofp, "ip4 table id : %d", table_id);
4753   else
4754     print (vam->ofp, "ip4 table id : No input ACL tables configured");
4755   table_id = ntohl (mp->ip6_table_id);
4756   if (table_id != ~0)
4757     print (vam->ofp, "ip6 table id : %d", table_id);
4758   else
4759     print (vam->ofp, "ip6 table id : No input ACL tables configured");
4760   vam->retval = ntohl (mp->retval);
4761   vam->result_ready = 1;
4762 }
4763
4764 static void
4765   vl_api_classify_table_by_interface_reply_t_handler_json
4766   (vl_api_classify_table_by_interface_reply_t * mp)
4767 {
4768   vat_main_t *vam = &vat_main;
4769   vat_json_node_t node;
4770
4771   vat_json_init_object (&node);
4772
4773   vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
4774   vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
4775   vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
4776
4777   vat_json_print (vam->ofp, &node);
4778   vat_json_free (&node);
4779
4780   vam->retval = ntohl (mp->retval);
4781   vam->result_ready = 1;
4782 }
4783
4784 static void vl_api_policer_add_del_reply_t_handler
4785   (vl_api_policer_add_del_reply_t * mp)
4786 {
4787   vat_main_t *vam = &vat_main;
4788   i32 retval = ntohl (mp->retval);
4789   if (vam->async_mode)
4790     {
4791       vam->async_errors += (retval < 0);
4792     }
4793   else
4794     {
4795       vam->retval = retval;
4796       vam->result_ready = 1;
4797       if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
4798         /*
4799          * Note: this is just barely thread-safe, depends on
4800          * the main thread spinning waiting for an answer...
4801          */
4802         errmsg ("policer index %d", ntohl (mp->policer_index));
4803     }
4804 }
4805
4806 static void vl_api_policer_add_del_reply_t_handler_json
4807   (vl_api_policer_add_del_reply_t * mp)
4808 {
4809   vat_main_t *vam = &vat_main;
4810   vat_json_node_t node;
4811
4812   vat_json_init_object (&node);
4813   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
4814   vat_json_object_add_uint (&node, "policer_index",
4815                             ntohl (mp->policer_index));
4816
4817   vat_json_print (vam->ofp, &node);
4818   vat_json_free (&node);
4819
4820   vam->retval = ntohl (mp->retval);
4821   vam->result_ready = 1;
4822 }
4823
4824 /* Format hex dump. */
4825 u8 *
4826 format_hex_bytes (u8 * s, va_list * va)
4827 {
4828   u8 *bytes = va_arg (*va, u8 *);
4829   int n_bytes = va_arg (*va, int);
4830   uword i;
4831
4832   /* Print short or long form depending on byte count. */
4833   uword short_form = n_bytes <= 32;
4834   u32 indent = format_get_indent (s);
4835
4836   if (n_bytes == 0)
4837     return s;
4838
4839   for (i = 0; i < n_bytes; i++)
4840     {
4841       if (!short_form && (i % 32) == 0)
4842         s = format (s, "%08x: ", i);
4843       s = format (s, "%02x", bytes[i]);
4844       if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
4845         s = format (s, "\n%U", format_white_space, indent);
4846     }
4847
4848   return s;
4849 }
4850
4851 static void
4852 vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
4853                                             * mp)
4854 {
4855   vat_main_t *vam = &vat_main;
4856   i32 retval = ntohl (mp->retval);
4857   if (retval == 0)
4858     {
4859       print (vam->ofp, "classify table info :");
4860       print (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d",
4861              ntohl (mp->active_sessions), ntohl (mp->next_table_index),
4862              ntohl (mp->miss_next_index));
4863       print (vam->ofp, "nbuckets: %d skip: %d match: %d",
4864              ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
4865              ntohl (mp->match_n_vectors));
4866       print (vam->ofp, "mask: %U", format_hex_bytes, mp->mask,
4867              ntohl (mp->mask_length));
4868     }
4869   vam->retval = retval;
4870   vam->result_ready = 1;
4871 }
4872
4873 static void
4874   vl_api_classify_table_info_reply_t_handler_json
4875   (vl_api_classify_table_info_reply_t * mp)
4876 {
4877   vat_main_t *vam = &vat_main;
4878   vat_json_node_t node;
4879
4880   i32 retval = ntohl (mp->retval);
4881   if (retval == 0)
4882     {
4883       vat_json_init_object (&node);
4884
4885       vat_json_object_add_int (&node, "sessions",
4886                                ntohl (mp->active_sessions));
4887       vat_json_object_add_int (&node, "nexttbl",
4888                                ntohl (mp->next_table_index));
4889       vat_json_object_add_int (&node, "nextnode",
4890                                ntohl (mp->miss_next_index));
4891       vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
4892       vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
4893       vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
4894       u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
4895                       ntohl (mp->mask_length), 0);
4896       vat_json_object_add_string_copy (&node, "mask", s);
4897
4898       vat_json_print (vam->ofp, &node);
4899       vat_json_free (&node);
4900     }
4901   vam->retval = ntohl (mp->retval);
4902   vam->result_ready = 1;
4903 }
4904
4905 static void
4906 vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
4907                                            mp)
4908 {
4909   vat_main_t *vam = &vat_main;
4910
4911   print (vam->ofp, "next_index: %d advance: %d opaque: %d ",
4912          ntohl (mp->hit_next_index), ntohl (mp->advance),
4913          ntohl (mp->opaque_index));
4914   print (vam->ofp, "mask: %U", format_hex_bytes, mp->match,
4915          ntohl (mp->match_length));
4916 }
4917
4918 static void
4919   vl_api_classify_session_details_t_handler_json
4920   (vl_api_classify_session_details_t * mp)
4921 {
4922   vat_main_t *vam = &vat_main;
4923   vat_json_node_t *node = NULL;
4924
4925   if (VAT_JSON_ARRAY != vam->json_tree.type)
4926     {
4927       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4928       vat_json_init_array (&vam->json_tree);
4929     }
4930   node = vat_json_array_add (&vam->json_tree);
4931
4932   vat_json_init_object (node);
4933   vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
4934   vat_json_object_add_int (node, "advance", ntohl (mp->advance));
4935   vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
4936   u8 *s =
4937     format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
4938             0);
4939   vat_json_object_add_string_copy (node, "match", s);
4940 }
4941
4942 static void vl_api_pg_create_interface_reply_t_handler
4943   (vl_api_pg_create_interface_reply_t * mp)
4944 {
4945   vat_main_t *vam = &vat_main;
4946
4947   vam->retval = ntohl (mp->retval);
4948   vam->result_ready = 1;
4949 }
4950
4951 static void vl_api_pg_create_interface_reply_t_handler_json
4952   (vl_api_pg_create_interface_reply_t * mp)
4953 {
4954   vat_main_t *vam = &vat_main;
4955   vat_json_node_t node;
4956
4957   i32 retval = ntohl (mp->retval);
4958   if (retval == 0)
4959     {
4960       vat_json_init_object (&node);
4961
4962       vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
4963
4964       vat_json_print (vam->ofp, &node);
4965       vat_json_free (&node);
4966     }
4967   vam->retval = ntohl (mp->retval);
4968   vam->result_ready = 1;
4969 }
4970
4971 static void vl_api_policer_classify_details_t_handler
4972   (vl_api_policer_classify_details_t * mp)
4973 {
4974   vat_main_t *vam = &vat_main;
4975
4976   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
4977          ntohl (mp->table_index));
4978 }
4979
4980 static void vl_api_policer_classify_details_t_handler_json
4981   (vl_api_policer_classify_details_t * mp)
4982 {
4983   vat_main_t *vam = &vat_main;
4984   vat_json_node_t *node;
4985
4986   if (VAT_JSON_ARRAY != vam->json_tree.type)
4987     {
4988       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4989       vat_json_init_array (&vam->json_tree);
4990     }
4991   node = vat_json_array_add (&vam->json_tree);
4992
4993   vat_json_init_object (node);
4994   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
4995   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
4996 }
4997
4998 static void vl_api_flow_classify_details_t_handler
4999   (vl_api_flow_classify_details_t * mp)
5000 {
5001   vat_main_t *vam = &vat_main;
5002
5003   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
5004          ntohl (mp->table_index));
5005 }
5006
5007 static void vl_api_flow_classify_details_t_handler_json
5008   (vl_api_flow_classify_details_t * mp)
5009 {
5010   vat_main_t *vam = &vat_main;
5011   vat_json_node_t *node;
5012
5013   if (VAT_JSON_ARRAY != vam->json_tree.type)
5014     {
5015       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5016       vat_json_init_array (&vam->json_tree);
5017     }
5018   node = vat_json_array_add (&vam->json_tree);
5019
5020   vat_json_init_object (node);
5021   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
5022   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
5023 }
5024
5025 #define vl_api_one_adjacencies_get_reply_t_endian vl_noop_handler
5026 #define vl_api_one_adjacencies_get_reply_t_print vl_noop_handler
5027 #define vl_api_one_l2_arp_bd_get_reply_t_print vl_noop_handler
5028 #define vl_api_one_l2_arp_entries_get_reply_t_endian vl_noop_handler
5029 #define vl_api_one_l2_arp_entries_get_reply_t_print vl_noop_handler
5030 #define vl_api_one_l2_arp_bd_get_reply_t_endian vl_noop_handler
5031 #define vl_api_one_ndp_bd_get_reply_t_endian vl_noop_handler
5032 #define vl_api_one_ndp_bd_get_reply_t_print vl_noop_handler
5033 #define vl_api_one_ndp_entries_get_reply_t_print vl_noop_handler
5034 #define vl_api_one_ndp_entries_get_reply_t_endian vl_noop_handler
5035
5036 /*
5037  * Generate boilerplate reply handlers, which
5038  * dig the return value out of the xxx_reply_t API message,
5039  * stick it into vam->retval, and set vam->result_ready
5040  *
5041  * Could also do this by pointing N message decode slots at
5042  * a single function, but that could break in subtle ways.
5043  */
5044
5045 #define foreach_standard_reply_retval_handler           \
5046 _(sw_interface_set_flags_reply)                         \
5047 _(sw_interface_add_del_address_reply)                   \
5048 _(sw_interface_set_rx_mode_reply)                       \
5049 _(sw_interface_set_rx_placement_reply)                  \
5050 _(sw_interface_set_table_reply)                         \
5051 _(sw_interface_set_mpls_enable_reply)                   \
5052 _(sw_interface_set_vpath_reply)                         \
5053 _(sw_interface_set_vxlan_bypass_reply)                  \
5054 _(sw_interface_set_geneve_bypass_reply)                 \
5055 _(sw_interface_set_vxlan_gpe_bypass_reply)              \
5056 _(sw_interface_set_l2_bridge_reply)                     \
5057 _(sw_interface_set_bond_weight_reply)                   \
5058 _(bridge_domain_add_del_reply)                          \
5059 _(sw_interface_set_l2_xconnect_reply)                   \
5060 _(l2fib_add_del_reply)                                  \
5061 _(l2fib_flush_int_reply)                                \
5062 _(l2fib_flush_bd_reply)                                 \
5063 _(ip_route_add_del_reply)                               \
5064 _(ip_table_add_del_reply)                               \
5065 _(ip_table_replace_begin_reply)                         \
5066 _(ip_table_flush_reply)                                 \
5067 _(ip_table_replace_end_reply)                           \
5068 _(ip_mroute_add_del_reply)                              \
5069 _(mpls_route_add_del_reply)                             \
5070 _(mpls_table_add_del_reply)                             \
5071 _(mpls_ip_bind_unbind_reply)                            \
5072 _(bier_route_add_del_reply)                             \
5073 _(bier_table_add_del_reply)                             \
5074 _(proxy_arp_add_del_reply)                              \
5075 _(proxy_arp_intfc_enable_disable_reply)                 \
5076 _(sw_interface_set_unnumbered_reply)                    \
5077 _(ip_neighbor_add_del_reply)                            \
5078 _(set_ip_flow_hash_reply)                               \
5079 _(sw_interface_ip6_enable_disable_reply)                \
5080 _(ip6nd_proxy_add_del_reply)                            \
5081 _(sw_interface_ip6nd_ra_prefix_reply)                   \
5082 _(sw_interface_ip6nd_ra_config_reply)                   \
5083 _(set_arp_neighbor_limit_reply)                         \
5084 _(l2_patch_add_del_reply)                               \
5085 _(sr_mpls_policy_add_reply)                             \
5086 _(sr_mpls_policy_mod_reply)                             \
5087 _(sr_mpls_policy_del_reply)                             \
5088 _(sr_policy_add_reply)                                  \
5089 _(sr_policy_mod_reply)                                  \
5090 _(sr_policy_del_reply)                                  \
5091 _(sr_localsid_add_del_reply)                            \
5092 _(sr_steering_add_del_reply)                            \
5093 _(classify_add_del_session_reply)                       \
5094 _(classify_set_interface_ip_table_reply)                \
5095 _(classify_set_interface_l2_tables_reply)               \
5096 _(l2tpv3_set_tunnel_cookies_reply)                      \
5097 _(l2tpv3_interface_enable_disable_reply)                \
5098 _(l2tpv3_set_lookup_key_reply)                          \
5099 _(l2_fib_clear_table_reply)                             \
5100 _(l2_interface_efp_filter_reply)                        \
5101 _(l2_interface_vlan_tag_rewrite_reply)                  \
5102 _(modify_vhost_user_if_reply)                           \
5103 _(delete_vhost_user_if_reply)                           \
5104 _(ip_probe_neighbor_reply)                              \
5105 _(ip_scan_neighbor_enable_disable_reply)                \
5106 _(want_ip4_arp_events_reply)                            \
5107 _(want_ip6_nd_events_reply)                             \
5108 _(want_l2_macs_events_reply)                            \
5109 _(input_acl_set_interface_reply)                        \
5110 _(ipsec_spd_add_del_reply)                              \
5111 _(ipsec_interface_add_del_spd_reply)                    \
5112 _(ipsec_spd_entry_add_del_reply)                        \
5113 _(ipsec_sad_entry_add_del_reply)                        \
5114 _(ipsec_tunnel_if_add_del_reply)                        \
5115 _(ipsec_tunnel_if_set_sa_reply)                         \
5116 _(delete_loopback_reply)                                \
5117 _(bd_ip_mac_add_del_reply)                              \
5118 _(bd_ip_mac_flush_reply)                                \
5119 _(want_interface_events_reply)                          \
5120 _(cop_interface_enable_disable_reply)                   \
5121 _(cop_whitelist_enable_disable_reply)                   \
5122 _(sw_interface_clear_stats_reply)                       \
5123 _(ioam_enable_reply)                                    \
5124 _(ioam_disable_reply)                                   \
5125 _(one_add_del_locator_reply)                            \
5126 _(one_add_del_local_eid_reply)                          \
5127 _(one_add_del_remote_mapping_reply)                     \
5128 _(one_add_del_adjacency_reply)                          \
5129 _(one_add_del_map_resolver_reply)                       \
5130 _(one_add_del_map_server_reply)                         \
5131 _(one_enable_disable_reply)                             \
5132 _(one_rloc_probe_enable_disable_reply)                  \
5133 _(one_map_register_enable_disable_reply)                \
5134 _(one_map_register_set_ttl_reply)                       \
5135 _(one_set_transport_protocol_reply)                     \
5136 _(one_map_register_fallback_threshold_reply)            \
5137 _(one_pitr_set_locator_set_reply)                       \
5138 _(one_map_request_mode_reply)                           \
5139 _(one_add_del_map_request_itr_rlocs_reply)              \
5140 _(one_eid_table_add_del_map_reply)                      \
5141 _(one_use_petr_reply)                                   \
5142 _(one_stats_enable_disable_reply)                       \
5143 _(one_add_del_l2_arp_entry_reply)                       \
5144 _(one_add_del_ndp_entry_reply)                          \
5145 _(one_stats_flush_reply)                                \
5146 _(one_enable_disable_xtr_mode_reply)                    \
5147 _(one_enable_disable_pitr_mode_reply)                   \
5148 _(one_enable_disable_petr_mode_reply)                   \
5149 _(gpe_enable_disable_reply)                             \
5150 _(gpe_set_encap_mode_reply)                             \
5151 _(gpe_add_del_iface_reply)                              \
5152 _(gpe_add_del_native_fwd_rpath_reply)                   \
5153 _(af_packet_delete_reply)                               \
5154 _(policer_classify_set_interface_reply)                 \
5155 _(netmap_create_reply)                                  \
5156 _(netmap_delete_reply)                                  \
5157 _(set_ipfix_exporter_reply)                             \
5158 _(set_ipfix_classify_stream_reply)                      \
5159 _(ipfix_classify_table_add_del_reply)                   \
5160 _(flow_classify_set_interface_reply)                    \
5161 _(sw_interface_span_enable_disable_reply)               \
5162 _(pg_capture_reply)                                     \
5163 _(pg_enable_disable_reply)                              \
5164 _(ip_source_and_port_range_check_add_del_reply)         \
5165 _(ip_source_and_port_range_check_interface_add_del_reply)\
5166 _(delete_subif_reply)                                   \
5167 _(l2_interface_pbb_tag_rewrite_reply)                   \
5168 _(set_punt_reply)                                       \
5169 _(feature_enable_disable_reply)                         \
5170 _(feature_gso_enable_disable_reply)                     \
5171 _(sw_interface_tag_add_del_reply)                       \
5172 _(sw_interface_add_del_mac_address_reply)               \
5173 _(hw_interface_set_mtu_reply)                           \
5174 _(p2p_ethernet_add_reply)                               \
5175 _(p2p_ethernet_del_reply)                               \
5176 _(lldp_config_reply)                                    \
5177 _(sw_interface_set_lldp_reply)                          \
5178 _(tcp_configure_src_addresses_reply)                    \
5179 _(session_rule_add_del_reply)                           \
5180 _(ip_container_proxy_add_del_reply)                     \
5181 _(output_acl_set_interface_reply)                       \
5182 _(qos_record_enable_disable_reply)
5183
5184 #define _(n)                                    \
5185     static void vl_api_##n##_t_handler          \
5186     (vl_api_##n##_t * mp)                       \
5187     {                                           \
5188         vat_main_t * vam = &vat_main;           \
5189         i32 retval = ntohl(mp->retval);         \
5190         if (vam->async_mode) {                  \
5191             vam->async_errors += (retval < 0);  \
5192         } else {                                \
5193             vam->retval = retval;               \
5194             vam->result_ready = 1;              \
5195         }                                       \
5196     }
5197 foreach_standard_reply_retval_handler;
5198 #undef _
5199
5200 #define _(n)                                    \
5201     static void vl_api_##n##_t_handler_json     \
5202     (vl_api_##n##_t * mp)                       \
5203     {                                           \
5204         vat_main_t * vam = &vat_main;           \
5205         vat_json_node_t node;                   \
5206         vat_json_init_object(&node);            \
5207         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
5208         vat_json_print(vam->ofp, &node);        \
5209         vam->retval = ntohl(mp->retval);        \
5210         vam->result_ready = 1;                  \
5211     }
5212 foreach_standard_reply_retval_handler;
5213 #undef _
5214
5215 /*
5216  * Table of message reply handlers, must include boilerplate handlers
5217  * we just generated
5218  */
5219
5220 #define foreach_vpe_api_reply_msg                                       \
5221 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
5222 _(CREATE_LOOPBACK_INSTANCE_REPLY, create_loopback_instance_reply)       \
5223 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
5224 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
5225 _(CONTROL_PING_REPLY, control_ping_reply)                               \
5226 _(CLI_REPLY, cli_reply)                                                 \
5227 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
5228 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
5229   sw_interface_add_del_address_reply)                                   \
5230 _(SW_INTERFACE_SET_RX_MODE_REPLY, sw_interface_set_rx_mode_reply)       \
5231 _(SW_INTERFACE_SET_RX_PLACEMENT_REPLY, sw_interface_set_rx_placement_reply)     \
5232 _(SW_INTERFACE_RX_PLACEMENT_DETAILS, sw_interface_rx_placement_details) \
5233 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
5234 _(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
5235 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
5236 _(SW_INTERFACE_SET_VXLAN_BYPASS_REPLY, sw_interface_set_vxlan_bypass_reply) \
5237 _(SW_INTERFACE_SET_GENEVE_BYPASS_REPLY, sw_interface_set_geneve_bypass_reply) \
5238 _(SW_INTERFACE_SET_VXLAN_GPE_BYPASS_REPLY, sw_interface_set_vxlan_gpe_bypass_reply) \
5239 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
5240   sw_interface_set_l2_xconnect_reply)                                   \
5241 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
5242   sw_interface_set_l2_bridge_reply)                                     \
5243 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
5244 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
5245 _(BRIDGE_DOMAIN_SET_MAC_AGE_REPLY, bridge_domain_set_mac_age_reply)     \
5246 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
5247 _(L2FIB_FLUSH_INT_REPLY, l2fib_flush_int_reply)                         \
5248 _(L2FIB_FLUSH_BD_REPLY, l2fib_flush_bd_reply)                           \
5249 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
5250 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
5251 _(TAP_CREATE_V2_REPLY, tap_create_v2_reply)                             \
5252 _(TAP_DELETE_V2_REPLY, tap_delete_v2_reply)                             \
5253 _(SW_INTERFACE_TAP_V2_DETAILS, sw_interface_tap_v2_details)             \
5254 _(VIRTIO_PCI_CREATE_REPLY, virtio_pci_create_reply)                     \
5255 _(VIRTIO_PCI_DELETE_REPLY, virtio_pci_delete_reply)                     \
5256 _(SW_INTERFACE_VIRTIO_PCI_DETAILS, sw_interface_virtio_pci_details)     \
5257 _(BOND_CREATE_REPLY, bond_create_reply)                                 \
5258 _(BOND_DELETE_REPLY, bond_delete_reply)                                 \
5259 _(BOND_ENSLAVE_REPLY, bond_enslave_reply)                               \
5260 _(BOND_DETACH_SLAVE_REPLY, bond_detach_slave_reply)                     \
5261 _(SW_INTERFACE_SET_BOND_WEIGHT_REPLY, sw_interface_set_bond_weight_reply) \
5262 _(SW_INTERFACE_BOND_DETAILS, sw_interface_bond_details)                 \
5263 _(SW_INTERFACE_SLAVE_DETAILS, sw_interface_slave_details)               \
5264 _(IP_ROUTE_ADD_DEL_REPLY, ip_route_add_del_reply)                       \
5265 _(IP_TABLE_ADD_DEL_REPLY, ip_table_add_del_reply)                       \
5266 _(IP_TABLE_REPLACE_BEGIN_REPLY, ip_table_replace_begin_reply)           \
5267 _(IP_TABLE_FLUSH_REPLY, ip_table_flush_reply)                           \
5268 _(IP_TABLE_REPLACE_END_REPLY, ip_table_replace_end_reply)               \
5269 _(IP_MROUTE_ADD_DEL_REPLY, ip_mroute_add_del_reply)                     \
5270 _(MPLS_TABLE_ADD_DEL_REPLY, mpls_table_add_del_reply)                   \
5271 _(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply)                   \
5272 _(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply)                 \
5273 _(BIER_ROUTE_ADD_DEL_REPLY, bier_route_add_del_reply)                   \
5274 _(BIER_TABLE_ADD_DEL_REPLY, bier_table_add_del_reply)                   \
5275 _(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply)                     \
5276 _(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY,                                 \
5277   proxy_arp_intfc_enable_disable_reply)                                 \
5278 _(MPLS_TUNNEL_ADD_DEL_REPLY, mpls_tunnel_add_del_reply)                 \
5279 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
5280   sw_interface_set_unnumbered_reply)                                    \
5281 _(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply)                 \
5282 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
5283 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
5284 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
5285 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
5286   sw_interface_ip6_enable_disable_reply)                                \
5287 _(IP6ND_PROXY_ADD_DEL_REPLY, ip6nd_proxy_add_del_reply)                 \
5288 _(IP6ND_PROXY_DETAILS, ip6nd_proxy_details)                             \
5289 _(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY,                                   \
5290   sw_interface_ip6nd_ra_prefix_reply)                                   \
5291 _(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY,                                   \
5292   sw_interface_ip6nd_ra_config_reply)                                   \
5293 _(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply)           \
5294 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
5295 _(SR_MPLS_POLICY_ADD_REPLY, sr_mpls_policy_add_reply)                   \
5296 _(SR_MPLS_POLICY_MOD_REPLY, sr_mpls_policy_mod_reply)                   \
5297 _(SR_MPLS_POLICY_DEL_REPLY, sr_mpls_policy_del_reply)                   \
5298 _(SR_POLICY_ADD_REPLY, sr_policy_add_reply)                             \
5299 _(SR_POLICY_MOD_REPLY, sr_policy_mod_reply)                             \
5300 _(SR_POLICY_DEL_REPLY, sr_policy_del_reply)                             \
5301 _(SR_LOCALSID_ADD_DEL_REPLY, sr_localsid_add_del_reply)                 \
5302 _(SR_STEERING_ADD_DEL_REPLY, sr_steering_add_del_reply)                 \
5303 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
5304 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
5305 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
5306 classify_set_interface_ip_table_reply)                                  \
5307 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
5308   classify_set_interface_l2_tables_reply)                               \
5309 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
5310 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
5311 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
5312 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
5313 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
5314   l2tpv3_interface_enable_disable_reply)                                \
5315 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
5316 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
5317 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
5318 _(VXLAN_OFFLOAD_RX_REPLY, vxlan_offload_rx_reply)               \
5319 _(GENEVE_ADD_DEL_TUNNEL_REPLY, geneve_add_del_tunnel_reply)             \
5320 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
5321 _(GENEVE_TUNNEL_DETAILS, geneve_tunnel_details)                         \
5322 _(GRE_TUNNEL_ADD_DEL_REPLY, gre_tunnel_add_del_reply)                   \
5323 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
5324 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
5325 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
5326 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
5327 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
5328 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
5329 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
5330 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
5331 _(SHOW_VERSION_REPLY, show_version_reply)                               \
5332 _(SHOW_THREADS_REPLY, show_threads_reply)                               \
5333 _(L2_FIB_TABLE_DETAILS, l2_fib_table_details)                           \
5334 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)       \
5335 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
5336 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
5337 _(IP_PROBE_NEIGHBOR_REPLY, ip_probe_neighbor_reply)                     \
5338 _(IP_SCAN_NEIGHBOR_ENABLE_DISABLE_REPLY, ip_scan_neighbor_enable_disable_reply) \
5339 _(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply)                 \
5340 _(IP4_ARP_EVENT, ip4_arp_event)                                         \
5341 _(WANT_IP6_ND_EVENTS_REPLY, want_ip6_nd_events_reply)                   \
5342 _(IP6_ND_EVENT, ip6_nd_event)                                           \
5343 _(WANT_L2_MACS_EVENTS_REPLY, want_l2_macs_events_reply)                 \
5344 _(L2_MACS_EVENT, l2_macs_event)                                         \
5345 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
5346 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
5347 _(IP_DETAILS, ip_details)                                               \
5348 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
5349 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
5350 _(IPSEC_SPD_ENTRY_ADD_DEL_REPLY, ipsec_spd_entry_add_del_reply)         \
5351 _(IPSEC_SAD_ENTRY_ADD_DEL_REPLY, ipsec_sad_entry_add_del_reply)         \
5352 _(IPSEC_SA_DETAILS, ipsec_sa_details)                                   \
5353 _(IPSEC_TUNNEL_IF_ADD_DEL_REPLY, ipsec_tunnel_if_add_del_reply)         \
5354 _(IPSEC_TUNNEL_IF_SET_SA_REPLY, ipsec_tunnel_if_set_sa_reply)           \
5355 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
5356 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
5357 _(BD_IP_MAC_FLUSH_REPLY, bd_ip_mac_flush_reply)                         \
5358 _(BD_IP_MAC_DETAILS, bd_ip_mac_details)                                 \
5359 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
5360 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
5361 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
5362 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
5363 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
5364 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
5365 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
5366 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
5367 _(ONE_ADD_DEL_LOCATOR_SET_REPLY, one_add_del_locator_set_reply)         \
5368 _(ONE_ADD_DEL_LOCATOR_REPLY, one_add_del_locator_reply)                 \
5369 _(ONE_ADD_DEL_LOCAL_EID_REPLY, one_add_del_local_eid_reply)             \
5370 _(ONE_ADD_DEL_REMOTE_MAPPING_REPLY, one_add_del_remote_mapping_reply)   \
5371 _(ONE_ADD_DEL_ADJACENCY_REPLY, one_add_del_adjacency_reply)             \
5372 _(ONE_ADD_DEL_MAP_RESOLVER_REPLY, one_add_del_map_resolver_reply)       \
5373 _(ONE_ADD_DEL_MAP_SERVER_REPLY, one_add_del_map_server_reply)           \
5374 _(ONE_ENABLE_DISABLE_REPLY, one_enable_disable_reply)                   \
5375 _(ONE_MAP_REGISTER_ENABLE_DISABLE_REPLY,                                \
5376   one_map_register_enable_disable_reply)                                \
5377 _(ONE_MAP_REGISTER_SET_TTL_REPLY, one_map_register_set_ttl_reply)       \
5378 _(ONE_SET_TRANSPORT_PROTOCOL_REPLY, one_set_transport_protocol_reply)   \
5379 _(ONE_GET_TRANSPORT_PROTOCOL_REPLY, one_get_transport_protocol_reply)   \
5380 _(ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                            \
5381   one_map_register_fallback_threshold_reply)                            \
5382 _(ONE_RLOC_PROBE_ENABLE_DISABLE_REPLY,                                  \
5383   one_rloc_probe_enable_disable_reply)                                  \
5384 _(ONE_PITR_SET_LOCATOR_SET_REPLY, one_pitr_set_locator_set_reply)       \
5385 _(ONE_USE_PETR_REPLY, one_use_petr_reply)                               \
5386 _(ONE_MAP_REQUEST_MODE_REPLY, one_map_request_mode_reply)               \
5387 _(ONE_EID_TABLE_ADD_DEL_MAP_REPLY, one_eid_table_add_del_map_reply)     \
5388 _(ONE_LOCATOR_SET_DETAILS, one_locator_set_details)                     \
5389 _(ONE_LOCATOR_DETAILS, one_locator_details)                             \
5390 _(ONE_EID_TABLE_DETAILS, one_eid_table_details)                         \
5391 _(ONE_EID_TABLE_MAP_DETAILS, one_eid_table_map_details)                 \
5392 _(ONE_EID_TABLE_VNI_DETAILS, one_eid_table_vni_details)                 \
5393 _(ONE_MAP_RESOLVER_DETAILS, one_map_resolver_details)                   \
5394 _(ONE_MAP_SERVER_DETAILS, one_map_server_details)                       \
5395 _(ONE_ADJACENCIES_GET_REPLY, one_adjacencies_get_reply)                 \
5396 _(ONE_STATS_DETAILS, one_stats_details)                                 \
5397 _(ONE_STATS_FLUSH_REPLY, one_stats_flush_reply)                         \
5398 _(ONE_STATS_ENABLE_DISABLE_REPLY, one_stats_enable_disable_reply)       \
5399 _(SHOW_ONE_STATS_ENABLE_DISABLE_REPLY,                                  \
5400   show_one_stats_enable_disable_reply)                                  \
5401 _(ONE_ADD_DEL_NDP_ENTRY_REPLY, one_add_del_ndp_entry_reply)             \
5402 _(ONE_NDP_BD_GET_REPLY, one_ndp_bd_get_reply)                           \
5403 _(ONE_NDP_ENTRIES_GET_REPLY, one_ndp_entries_get_reply)                 \
5404 _(ONE_ADD_DEL_L2_ARP_ENTRY_REPLY, one_add_del_l2_arp_entry_reply)       \
5405 _(ONE_L2_ARP_BD_GET_REPLY, one_l2_arp_bd_get_reply)                     \
5406 _(ONE_L2_ARP_ENTRIES_GET_REPLY, one_l2_arp_entries_get_reply)           \
5407 _(ONE_ENABLE_DISABLE_XTR_MODE_REPLY, one_enable_disable_xtr_mode_reply) \
5408 _(ONE_ENABLE_DISABLE_PITR_MODE_REPLY,                                   \
5409   one_enable_disable_pitr_mode_reply)                                   \
5410 _(ONE_ENABLE_DISABLE_PETR_MODE_REPLY,                                   \
5411   one_enable_disable_petr_mode_reply)                                   \
5412 _(ONE_SHOW_XTR_MODE_REPLY, one_show_xtr_mode_reply)                     \
5413 _(ONE_SHOW_PITR_MODE_REPLY, one_show_pitr_mode_reply)                   \
5414 _(ONE_SHOW_PETR_MODE_REPLY, one_show_petr_mode_reply)                   \
5415 _(GPE_SET_ENCAP_MODE_REPLY, gpe_set_encap_mode_reply)                   \
5416 _(GPE_GET_ENCAP_MODE_REPLY, gpe_get_encap_mode_reply)                   \
5417 _(GPE_ADD_DEL_IFACE_REPLY, gpe_add_del_iface_reply)                     \
5418 _(GPE_ENABLE_DISABLE_REPLY, gpe_enable_disable_reply)                   \
5419 _(GPE_ADD_DEL_FWD_ENTRY_REPLY, gpe_add_del_fwd_entry_reply)             \
5420 _(GPE_FWD_ENTRY_VNIS_GET_REPLY, gpe_fwd_entry_vnis_get_reply)           \
5421 _(GPE_FWD_ENTRIES_GET_REPLY, gpe_fwd_entries_get_reply)                 \
5422 _(GPE_NATIVE_FWD_RPATHS_GET_REPLY, gpe_native_fwd_rpaths_get_reply)     \
5423 _(GPE_ADD_DEL_NATIVE_FWD_RPATH_REPLY,                                   \
5424   gpe_add_del_native_fwd_rpath_reply)                                   \
5425 _(GPE_FWD_ENTRY_PATH_DETAILS,                                           \
5426   gpe_fwd_entry_path_details)                                           \
5427 _(SHOW_ONE_STATUS_REPLY, show_one_status_reply)                         \
5428 _(ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                              \
5429   one_add_del_map_request_itr_rlocs_reply)                              \
5430 _(ONE_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                  \
5431   one_get_map_request_itr_rlocs_reply)                                  \
5432 _(SHOW_ONE_NSH_MAPPING_REPLY, show_one_nsh_mapping_reply)               \
5433 _(SHOW_ONE_PITR_REPLY, show_one_pitr_reply)                             \
5434 _(SHOW_ONE_USE_PETR_REPLY, show_one_use_petr_reply)                     \
5435 _(SHOW_ONE_MAP_REQUEST_MODE_REPLY, show_one_map_request_mode_reply)     \
5436 _(SHOW_ONE_RLOC_PROBE_STATE_REPLY, show_one_rloc_probe_state_reply)     \
5437 _(SHOW_ONE_MAP_REGISTER_STATE_REPLY,                                    \
5438   show_one_map_register_state_reply)                                    \
5439 _(SHOW_ONE_MAP_REGISTER_TTL_REPLY, show_one_map_register_ttl_reply)     \
5440 _(SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                       \
5441   show_one_map_register_fallback_threshold_reply)                       \
5442 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
5443 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
5444 _(AF_PACKET_DETAILS, af_packet_details)                                 \
5445 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
5446 _(POLICER_DETAILS, policer_details)                                     \
5447 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
5448 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
5449 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
5450 _(NETMAP_DELETE_REPLY, netmap_delete_reply)                             \
5451 _(MPLS_TUNNEL_DETAILS, mpls_tunnel_details)                             \
5452 _(MPLS_TABLE_DETAILS, mpls_table_details)                               \
5453 _(MPLS_ROUTE_DETAILS, mpls_route_details)                               \
5454 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
5455 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
5456 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
5457 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
5458 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
5459 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
5460 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
5461 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
5462 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
5463 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
5464 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
5465 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
5466 _(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
5467 _(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details)                 \
5468 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
5469 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
5470 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
5471 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
5472 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
5473  ip_source_and_port_range_check_add_del_reply)                          \
5474 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
5475  ip_source_and_port_range_check_interface_add_del_reply)                \
5476 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
5477 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
5478 _(SET_PUNT_REPLY, set_punt_reply)                                       \
5479 _(IP_TABLE_DETAILS, ip_table_details)                                   \
5480 _(IP_ROUTE_DETAILS, ip_route_details)                                   \
5481 _(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply)           \
5482 _(FEATURE_GSO_ENABLE_DISABLE_REPLY, feature_gso_enable_disable_reply)   \
5483 _(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply)       \
5484 _(SW_INTERFACE_ADD_DEL_MAC_ADDRESS_REPLY, sw_interface_add_del_mac_address_reply) \
5485 _(L2_XCONNECT_DETAILS, l2_xconnect_details)                             \
5486 _(HW_INTERFACE_SET_MTU_REPLY, hw_interface_set_mtu_reply)               \
5487 _(IP_NEIGHBOR_DETAILS, ip_neighbor_details)                             \
5488 _(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply)           \
5489 _(P2P_ETHERNET_ADD_REPLY, p2p_ethernet_add_reply)                       \
5490 _(P2P_ETHERNET_DEL_REPLY, p2p_ethernet_del_reply)                       \
5491 _(LLDP_CONFIG_REPLY, lldp_config_reply)                                 \
5492 _(SW_INTERFACE_SET_LLDP_REPLY, sw_interface_set_lldp_reply)             \
5493 _(TCP_CONFIGURE_SRC_ADDRESSES_REPLY, tcp_configure_src_addresses_reply) \
5494 _(APP_NAMESPACE_ADD_DEL_REPLY, app_namespace_add_del_reply)             \
5495 _(SESSION_RULE_ADD_DEL_REPLY, session_rule_add_del_reply)               \
5496 _(SESSION_RULES_DETAILS, session_rules_details)                         \
5497 _(IP_CONTAINER_PROXY_ADD_DEL_REPLY, ip_container_proxy_add_del_reply)   \
5498 _(OUTPUT_ACL_SET_INTERFACE_REPLY, output_acl_set_interface_reply)       \
5499 _(QOS_RECORD_ENABLE_DISABLE_REPLY, qos_record_enable_disable_reply)
5500
5501 #define foreach_standalone_reply_msg                                    \
5502 _(SW_INTERFACE_EVENT, sw_interface_event)
5503
5504 typedef struct
5505 {
5506   u8 *name;
5507   u32 value;
5508 } name_sort_t;
5509
5510 #define STR_VTR_OP_CASE(op)     \
5511     case L2_VTR_ ## op:         \
5512         return "" # op;
5513
5514 static const char *
5515 str_vtr_op (u32 vtr_op)
5516 {
5517   switch (vtr_op)
5518     {
5519       STR_VTR_OP_CASE (DISABLED);
5520       STR_VTR_OP_CASE (PUSH_1);
5521       STR_VTR_OP_CASE (PUSH_2);
5522       STR_VTR_OP_CASE (POP_1);
5523       STR_VTR_OP_CASE (POP_2);
5524       STR_VTR_OP_CASE (TRANSLATE_1_1);
5525       STR_VTR_OP_CASE (TRANSLATE_1_2);
5526       STR_VTR_OP_CASE (TRANSLATE_2_1);
5527       STR_VTR_OP_CASE (TRANSLATE_2_2);
5528     }
5529
5530   return "UNKNOWN";
5531 }
5532
5533 static int
5534 dump_sub_interface_table (vat_main_t * vam)
5535 {
5536   const sw_interface_subif_t *sub = NULL;
5537
5538   if (vam->json_output)
5539     {
5540       clib_warning
5541         ("JSON output supported only for VPE API calls and dump_stats_table");
5542       return -99;
5543     }
5544
5545   print (vam->ofp,
5546          "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
5547          "Interface", "sw_if_index",
5548          "sub id", "dot1ad", "tags", "outer id",
5549          "inner id", "exact", "default", "outer any", "inner any");
5550
5551   vec_foreach (sub, vam->sw_if_subif_table)
5552   {
5553     print (vam->ofp,
5554            "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
5555            sub->interface_name,
5556            sub->sw_if_index,
5557            sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
5558            sub->sub_number_of_tags, sub->sub_outer_vlan_id,
5559            sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
5560            sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
5561     if (sub->vtr_op != L2_VTR_DISABLED)
5562       {
5563         print (vam->ofp,
5564                "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
5565                "tag1: %d tag2: %d ]",
5566                str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
5567                sub->vtr_tag1, sub->vtr_tag2);
5568       }
5569   }
5570
5571   return 0;
5572 }
5573
5574 static int
5575 name_sort_cmp (void *a1, void *a2)
5576 {
5577   name_sort_t *n1 = a1;
5578   name_sort_t *n2 = a2;
5579
5580   return strcmp ((char *) n1->name, (char *) n2->name);
5581 }
5582
5583 static int
5584 dump_interface_table (vat_main_t * vam)
5585 {
5586   hash_pair_t *p;
5587   name_sort_t *nses = 0, *ns;
5588
5589   if (vam->json_output)
5590     {
5591       clib_warning
5592         ("JSON output supported only for VPE API calls and dump_stats_table");
5593       return -99;
5594     }
5595
5596   /* *INDENT-OFF* */
5597   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5598   ({
5599     vec_add2 (nses, ns, 1);
5600     ns->name = (u8 *)(p->key);
5601     ns->value = (u32) p->value[0];
5602   }));
5603   /* *INDENT-ON* */
5604
5605   vec_sort_with_function (nses, name_sort_cmp);
5606
5607   print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
5608   vec_foreach (ns, nses)
5609   {
5610     print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
5611   }
5612   vec_free (nses);
5613   return 0;
5614 }
5615
5616 static int
5617 dump_ip_table (vat_main_t * vam, int is_ipv6)
5618 {
5619   const ip_details_t *det = NULL;
5620   const ip_address_details_t *address = NULL;
5621   u32 i = ~0;
5622
5623   print (vam->ofp, "%-12s", "sw_if_index");
5624
5625   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
5626   {
5627     i++;
5628     if (!det->present)
5629       {
5630         continue;
5631       }
5632     print (vam->ofp, "%-12d", i);
5633     print (vam->ofp, "            %-30s%-13s", "Address", "Prefix length");
5634     if (!det->addr)
5635       {
5636         continue;
5637       }
5638     vec_foreach (address, det->addr)
5639     {
5640       print (vam->ofp,
5641              "            %-30U%-13d",
5642              is_ipv6 ? format_ip6_address : format_ip4_address,
5643              address->ip, address->prefix_length);
5644     }
5645   }
5646
5647   return 0;
5648 }
5649
5650 static int
5651 dump_ipv4_table (vat_main_t * vam)
5652 {
5653   if (vam->json_output)
5654     {
5655       clib_warning
5656         ("JSON output supported only for VPE API calls and dump_stats_table");
5657       return -99;
5658     }
5659
5660   return dump_ip_table (vam, 0);
5661 }
5662
5663 static int
5664 dump_ipv6_table (vat_main_t * vam)
5665 {
5666   if (vam->json_output)
5667     {
5668       clib_warning
5669         ("JSON output supported only for VPE API calls and dump_stats_table");
5670       return -99;
5671     }
5672
5673   return dump_ip_table (vam, 1);
5674 }
5675
5676 /*
5677  * Pass CLI buffers directly in the CLI_INBAND API message,
5678  * instead of an additional shared memory area.
5679  */
5680 static int
5681 exec_inband (vat_main_t * vam)
5682 {
5683   vl_api_cli_inband_t *mp;
5684   unformat_input_t *i = vam->input;
5685   int ret;
5686
5687   if (vec_len (i->buffer) == 0)
5688     return -1;
5689
5690   if (vam->exec_mode == 0 && unformat (i, "mode"))
5691     {
5692       vam->exec_mode = 1;
5693       return 0;
5694     }
5695   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
5696     {
5697       vam->exec_mode = 0;
5698       return 0;
5699     }
5700
5701   /*
5702    * In order for the CLI command to work, it
5703    * must be a vector ending in \n, not a C-string ending
5704    * in \n\0.
5705    */
5706   u32 len = vec_len (vam->input->buffer);
5707   M2 (CLI_INBAND, mp, len);
5708   vl_api_to_api_string (len - 1, (const char *) vam->input->buffer, &mp->cmd);
5709
5710   S (mp);
5711   W (ret);
5712   /* json responses may or may not include a useful reply... */
5713   if (vec_len (vam->cmd_reply))
5714     print (vam->ofp, "%v", (char *) (vam->cmd_reply));
5715   return ret;
5716 }
5717
5718 int
5719 exec (vat_main_t * vam)
5720 {
5721   return exec_inband (vam);
5722 }
5723
5724 static int
5725 api_create_loopback (vat_main_t * vam)
5726 {
5727   unformat_input_t *i = vam->input;
5728   vl_api_create_loopback_t *mp;
5729   vl_api_create_loopback_instance_t *mp_lbi;
5730   u8 mac_address[6];
5731   u8 mac_set = 0;
5732   u8 is_specified = 0;
5733   u32 user_instance = 0;
5734   int ret;
5735
5736   clib_memset (mac_address, 0, sizeof (mac_address));
5737
5738   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5739     {
5740       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5741         mac_set = 1;
5742       if (unformat (i, "instance %d", &user_instance))
5743         is_specified = 1;
5744       else
5745         break;
5746     }
5747
5748   if (is_specified)
5749     {
5750       M (CREATE_LOOPBACK_INSTANCE, mp_lbi);
5751       mp_lbi->is_specified = is_specified;
5752       if (is_specified)
5753         mp_lbi->user_instance = htonl (user_instance);
5754       if (mac_set)
5755         clib_memcpy (mp_lbi->mac_address, mac_address, sizeof (mac_address));
5756       S (mp_lbi);
5757     }
5758   else
5759     {
5760       /* Construct the API message */
5761       M (CREATE_LOOPBACK, mp);
5762       if (mac_set)
5763         clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
5764       S (mp);
5765     }
5766
5767   W (ret);
5768   return ret;
5769 }
5770
5771 static int
5772 api_delete_loopback (vat_main_t * vam)
5773 {
5774   unformat_input_t *i = vam->input;
5775   vl_api_delete_loopback_t *mp;
5776   u32 sw_if_index = ~0;
5777   int ret;
5778
5779   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5780     {
5781       if (unformat (i, "sw_if_index %d", &sw_if_index))
5782         ;
5783       else
5784         break;
5785     }
5786
5787   if (sw_if_index == ~0)
5788     {
5789       errmsg ("missing sw_if_index");
5790       return -99;
5791     }
5792
5793   /* Construct the API message */
5794   M (DELETE_LOOPBACK, mp);
5795   mp->sw_if_index = ntohl (sw_if_index);
5796
5797   S (mp);
5798   W (ret);
5799   return ret;
5800 }
5801
5802 static int
5803 api_want_interface_events (vat_main_t * vam)
5804 {
5805   unformat_input_t *i = vam->input;
5806   vl_api_want_interface_events_t *mp;
5807   int enable = -1;
5808   int ret;
5809
5810   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5811     {
5812       if (unformat (i, "enable"))
5813         enable = 1;
5814       else if (unformat (i, "disable"))
5815         enable = 0;
5816       else
5817         break;
5818     }
5819
5820   if (enable == -1)
5821     {
5822       errmsg ("missing enable|disable");
5823       return -99;
5824     }
5825
5826   M (WANT_INTERFACE_EVENTS, mp);
5827   mp->enable_disable = enable;
5828
5829   vam->interface_event_display = enable;
5830
5831   S (mp);
5832   W (ret);
5833   return ret;
5834 }
5835
5836
5837 /* Note: non-static, called once to set up the initial intfc table */
5838 int
5839 api_sw_interface_dump (vat_main_t * vam)
5840 {
5841   vl_api_sw_interface_dump_t *mp;
5842   vl_api_control_ping_t *mp_ping;
5843   hash_pair_t *p;
5844   name_sort_t *nses = 0, *ns;
5845   sw_interface_subif_t *sub = NULL;
5846   int ret;
5847
5848   /* Toss the old name table */
5849   /* *INDENT-OFF* */
5850   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5851   ({
5852     vec_add2 (nses, ns, 1);
5853     ns->name = (u8 *)(p->key);
5854     ns->value = (u32) p->value[0];
5855   }));
5856   /* *INDENT-ON* */
5857
5858   hash_free (vam->sw_if_index_by_interface_name);
5859
5860   vec_foreach (ns, nses) vec_free (ns->name);
5861
5862   vec_free (nses);
5863
5864   vec_foreach (sub, vam->sw_if_subif_table)
5865   {
5866     vec_free (sub->interface_name);
5867   }
5868   vec_free (vam->sw_if_subif_table);
5869
5870   /* recreate the interface name hash table */
5871   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
5872
5873   /*
5874    * Ask for all interface names. Otherwise, the epic catalog of
5875    * name filters becomes ridiculously long, and vat ends up needing
5876    * to be taught about new interface types.
5877    */
5878   M (SW_INTERFACE_DUMP, mp);
5879   S (mp);
5880
5881   /* Use a control ping for synchronization */
5882   MPING (CONTROL_PING, mp_ping);
5883   S (mp_ping);
5884
5885   W (ret);
5886   return ret;
5887 }
5888
5889 static int
5890 api_sw_interface_set_flags (vat_main_t * vam)
5891 {
5892   unformat_input_t *i = vam->input;
5893   vl_api_sw_interface_set_flags_t *mp;
5894   u32 sw_if_index;
5895   u8 sw_if_index_set = 0;
5896   u8 admin_up = 0;
5897   int ret;
5898
5899   /* Parse args required to build the message */
5900   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5901     {
5902       if (unformat (i, "admin-up"))
5903         admin_up = 1;
5904       else if (unformat (i, "admin-down"))
5905         admin_up = 0;
5906       else
5907         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5908         sw_if_index_set = 1;
5909       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5910         sw_if_index_set = 1;
5911       else
5912         break;
5913     }
5914
5915   if (sw_if_index_set == 0)
5916     {
5917       errmsg ("missing interface name or sw_if_index");
5918       return -99;
5919     }
5920
5921   /* Construct the API message */
5922   M (SW_INTERFACE_SET_FLAGS, mp);
5923   mp->sw_if_index = ntohl (sw_if_index);
5924   mp->flags = ntohl ((admin_up) ? IF_STATUS_API_FLAG_ADMIN_UP : 0);
5925
5926   /* send it... */
5927   S (mp);
5928
5929   /* Wait for a reply, return the good/bad news... */
5930   W (ret);
5931   return ret;
5932 }
5933
5934 static int
5935 api_sw_interface_set_rx_mode (vat_main_t * vam)
5936 {
5937   unformat_input_t *i = vam->input;
5938   vl_api_sw_interface_set_rx_mode_t *mp;
5939   u32 sw_if_index;
5940   u8 sw_if_index_set = 0;
5941   int ret;
5942   u8 queue_id_valid = 0;
5943   u32 queue_id;
5944   vnet_hw_interface_rx_mode mode = VNET_HW_INTERFACE_RX_MODE_UNKNOWN;
5945
5946   /* Parse args required to build the message */
5947   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5948     {
5949       if (unformat (i, "queue %d", &queue_id))
5950         queue_id_valid = 1;
5951       else if (unformat (i, "polling"))
5952         mode = VNET_HW_INTERFACE_RX_MODE_POLLING;
5953       else if (unformat (i, "interrupt"))
5954         mode = VNET_HW_INTERFACE_RX_MODE_INTERRUPT;
5955       else if (unformat (i, "adaptive"))
5956         mode = VNET_HW_INTERFACE_RX_MODE_ADAPTIVE;
5957       else
5958         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5959         sw_if_index_set = 1;
5960       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5961         sw_if_index_set = 1;
5962       else
5963         break;
5964     }
5965
5966   if (sw_if_index_set == 0)
5967     {
5968       errmsg ("missing interface name or sw_if_index");
5969       return -99;
5970     }
5971   if (mode == VNET_HW_INTERFACE_RX_MODE_UNKNOWN)
5972     {
5973       errmsg ("missing rx-mode");
5974       return -99;
5975     }
5976
5977   /* Construct the API message */
5978   M (SW_INTERFACE_SET_RX_MODE, mp);
5979   mp->sw_if_index = ntohl (sw_if_index);
5980   mp->mode = (vl_api_rx_mode_t) mode;
5981   mp->queue_id_valid = queue_id_valid;
5982   mp->queue_id = queue_id_valid ? ntohl (queue_id) : ~0;
5983
5984   /* send it... */
5985   S (mp);
5986
5987   /* Wait for a reply, return the good/bad news... */
5988   W (ret);
5989   return ret;
5990 }
5991
5992 static int
5993 api_sw_interface_set_rx_placement (vat_main_t * vam)
5994 {
5995   unformat_input_t *i = vam->input;
5996   vl_api_sw_interface_set_rx_placement_t *mp;
5997   u32 sw_if_index;
5998   u8 sw_if_index_set = 0;
5999   int ret;
6000   u8 is_main = 0;
6001   u32 queue_id, thread_index;
6002
6003   /* Parse args required to build the message */
6004   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6005     {
6006       if (unformat (i, "queue %d", &queue_id))
6007         ;
6008       else if (unformat (i, "main"))
6009         is_main = 1;
6010       else if (unformat (i, "worker %d", &thread_index))
6011         ;
6012       else
6013         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6014         sw_if_index_set = 1;
6015       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6016         sw_if_index_set = 1;
6017       else
6018         break;
6019     }
6020
6021   if (sw_if_index_set == 0)
6022     {
6023       errmsg ("missing interface name or sw_if_index");
6024       return -99;
6025     }
6026
6027   if (is_main)
6028     thread_index = 0;
6029   /* Construct the API message */
6030   M (SW_INTERFACE_SET_RX_PLACEMENT, mp);
6031   mp->sw_if_index = ntohl (sw_if_index);
6032   mp->worker_id = ntohl (thread_index);
6033   mp->queue_id = ntohl (queue_id);
6034   mp->is_main = is_main;
6035
6036   /* send it... */
6037   S (mp);
6038   /* Wait for a reply, return the good/bad news... */
6039   W (ret);
6040   return ret;
6041 }
6042
6043 static void vl_api_sw_interface_rx_placement_details_t_handler
6044   (vl_api_sw_interface_rx_placement_details_t * mp)
6045 {
6046   vat_main_t *vam = &vat_main;
6047   u32 worker_id = ntohl (mp->worker_id);
6048
6049   print (vam->ofp,
6050          "\n%-11d %-11s %-6d %-5d %-9s",
6051          ntohl (mp->sw_if_index), (worker_id == 0) ? "main" : "worker",
6052          worker_id, ntohl (mp->queue_id),
6053          (mp->mode ==
6054           1) ? "polling" : ((mp->mode == 2) ? "interrupt" : "adaptive"));
6055 }
6056
6057 static void vl_api_sw_interface_rx_placement_details_t_handler_json
6058   (vl_api_sw_interface_rx_placement_details_t * mp)
6059 {
6060   vat_main_t *vam = &vat_main;
6061   vat_json_node_t *node = NULL;
6062
6063   if (VAT_JSON_ARRAY != vam->json_tree.type)
6064     {
6065       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
6066       vat_json_init_array (&vam->json_tree);
6067     }
6068   node = vat_json_array_add (&vam->json_tree);
6069
6070   vat_json_init_object (node);
6071   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
6072   vat_json_object_add_uint (node, "worker_id", ntohl (mp->worker_id));
6073   vat_json_object_add_uint (node, "queue_id", ntohl (mp->queue_id));
6074   vat_json_object_add_uint (node, "mode", mp->mode);
6075 }
6076
6077 static int
6078 api_sw_interface_rx_placement_dump (vat_main_t * vam)
6079 {
6080   unformat_input_t *i = vam->input;
6081   vl_api_sw_interface_rx_placement_dump_t *mp;
6082   vl_api_control_ping_t *mp_ping;
6083   int ret;
6084   u32 sw_if_index;
6085   u8 sw_if_index_set = 0;
6086
6087   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6088     {
6089       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6090         sw_if_index_set++;
6091       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6092         sw_if_index_set++;
6093       else
6094         break;
6095     }
6096
6097   print (vam->ofp,
6098          "\n%-11s %-11s %-6s %-5s %-4s",
6099          "sw_if_index", "main/worker", "thread", "queue", "mode");
6100
6101   /* Dump Interface rx placement */
6102   M (SW_INTERFACE_RX_PLACEMENT_DUMP, mp);
6103
6104   if (sw_if_index_set)
6105     mp->sw_if_index = htonl (sw_if_index);
6106   else
6107     mp->sw_if_index = ~0;
6108
6109   S (mp);
6110
6111   /* Use a control ping for synchronization */
6112   MPING (CONTROL_PING, mp_ping);
6113   S (mp_ping);
6114
6115   W (ret);
6116   return ret;
6117 }
6118
6119 static int
6120 api_sw_interface_clear_stats (vat_main_t * vam)
6121 {
6122   unformat_input_t *i = vam->input;
6123   vl_api_sw_interface_clear_stats_t *mp;
6124   u32 sw_if_index;
6125   u8 sw_if_index_set = 0;
6126   int ret;
6127
6128   /* Parse args required to build the message */
6129   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6130     {
6131       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6132         sw_if_index_set = 1;
6133       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6134         sw_if_index_set = 1;
6135       else
6136         break;
6137     }
6138
6139   /* Construct the API message */
6140   M (SW_INTERFACE_CLEAR_STATS, mp);
6141
6142   if (sw_if_index_set == 1)
6143     mp->sw_if_index = ntohl (sw_if_index);
6144   else
6145     mp->sw_if_index = ~0;
6146
6147   /* send it... */
6148   S (mp);
6149
6150   /* Wait for a reply, return the good/bad news... */
6151   W (ret);
6152   return ret;
6153 }
6154
6155 static int
6156 api_sw_interface_add_del_address (vat_main_t * vam)
6157 {
6158   unformat_input_t *i = vam->input;
6159   vl_api_sw_interface_add_del_address_t *mp;
6160   u32 sw_if_index;
6161   u8 sw_if_index_set = 0;
6162   u8 is_add = 1, del_all = 0;
6163   u32 address_length = 0;
6164   u8 v4_address_set = 0;
6165   u8 v6_address_set = 0;
6166   ip4_address_t v4address;
6167   ip6_address_t v6address;
6168   int ret;
6169
6170   /* Parse args required to build the message */
6171   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6172     {
6173       if (unformat (i, "del-all"))
6174         del_all = 1;
6175       else if (unformat (i, "del"))
6176         is_add = 0;
6177       else
6178         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6179         sw_if_index_set = 1;
6180       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6181         sw_if_index_set = 1;
6182       else if (unformat (i, "%U/%d",
6183                          unformat_ip4_address, &v4address, &address_length))
6184         v4_address_set = 1;
6185       else if (unformat (i, "%U/%d",
6186                          unformat_ip6_address, &v6address, &address_length))
6187         v6_address_set = 1;
6188       else
6189         break;
6190     }
6191
6192   if (sw_if_index_set == 0)
6193     {
6194       errmsg ("missing interface name or sw_if_index");
6195       return -99;
6196     }
6197   if (v4_address_set && v6_address_set)
6198     {
6199       errmsg ("both v4 and v6 addresses set");
6200       return -99;
6201     }
6202   if (!v4_address_set && !v6_address_set && !del_all)
6203     {
6204       errmsg ("no addresses set");
6205       return -99;
6206     }
6207
6208   /* Construct the API message */
6209   M (SW_INTERFACE_ADD_DEL_ADDRESS, mp);
6210
6211   mp->sw_if_index = ntohl (sw_if_index);
6212   mp->is_add = is_add;
6213   mp->del_all = del_all;
6214   if (v6_address_set)
6215     {
6216       mp->prefix.address.af = ADDRESS_IP6;
6217       clib_memcpy (mp->prefix.address.un.ip6, &v6address, sizeof (v6address));
6218     }
6219   else
6220     {
6221       mp->prefix.address.af = ADDRESS_IP4;
6222       clib_memcpy (mp->prefix.address.un.ip4, &v4address, sizeof (v4address));
6223     }
6224   mp->prefix.len = address_length;
6225
6226   /* send it... */
6227   S (mp);
6228
6229   /* Wait for a reply, return good/bad news  */
6230   W (ret);
6231   return ret;
6232 }
6233
6234 static int
6235 api_sw_interface_set_mpls_enable (vat_main_t * vam)
6236 {
6237   unformat_input_t *i = vam->input;
6238   vl_api_sw_interface_set_mpls_enable_t *mp;
6239   u32 sw_if_index;
6240   u8 sw_if_index_set = 0;
6241   u8 enable = 1;
6242   int ret;
6243
6244   /* Parse args required to build the message */
6245   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6246     {
6247       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6248         sw_if_index_set = 1;
6249       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6250         sw_if_index_set = 1;
6251       else if (unformat (i, "disable"))
6252         enable = 0;
6253       else if (unformat (i, "dis"))
6254         enable = 0;
6255       else
6256         break;
6257     }
6258
6259   if (sw_if_index_set == 0)
6260     {
6261       errmsg ("missing interface name or sw_if_index");
6262       return -99;
6263     }
6264
6265   /* Construct the API message */
6266   M (SW_INTERFACE_SET_MPLS_ENABLE, mp);
6267
6268   mp->sw_if_index = ntohl (sw_if_index);
6269   mp->enable = enable;
6270
6271   /* send it... */
6272   S (mp);
6273
6274   /* Wait for a reply... */
6275   W (ret);
6276   return ret;
6277 }
6278
6279 static int
6280 api_sw_interface_set_table (vat_main_t * vam)
6281 {
6282   unformat_input_t *i = vam->input;
6283   vl_api_sw_interface_set_table_t *mp;
6284   u32 sw_if_index, vrf_id = 0;
6285   u8 sw_if_index_set = 0;
6286   u8 is_ipv6 = 0;
6287   int ret;
6288
6289   /* Parse args required to build the message */
6290   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6291     {
6292       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6293         sw_if_index_set = 1;
6294       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6295         sw_if_index_set = 1;
6296       else if (unformat (i, "vrf %d", &vrf_id))
6297         ;
6298       else if (unformat (i, "ipv6"))
6299         is_ipv6 = 1;
6300       else
6301         break;
6302     }
6303
6304   if (sw_if_index_set == 0)
6305     {
6306       errmsg ("missing interface name or sw_if_index");
6307       return -99;
6308     }
6309
6310   /* Construct the API message */
6311   M (SW_INTERFACE_SET_TABLE, mp);
6312
6313   mp->sw_if_index = ntohl (sw_if_index);
6314   mp->is_ipv6 = is_ipv6;
6315   mp->vrf_id = ntohl (vrf_id);
6316
6317   /* send it... */
6318   S (mp);
6319
6320   /* Wait for a reply... */
6321   W (ret);
6322   return ret;
6323 }
6324
6325 static void vl_api_sw_interface_get_table_reply_t_handler
6326   (vl_api_sw_interface_get_table_reply_t * mp)
6327 {
6328   vat_main_t *vam = &vat_main;
6329
6330   print (vam->ofp, "%d", ntohl (mp->vrf_id));
6331
6332   vam->retval = ntohl (mp->retval);
6333   vam->result_ready = 1;
6334
6335 }
6336
6337 static void vl_api_sw_interface_get_table_reply_t_handler_json
6338   (vl_api_sw_interface_get_table_reply_t * mp)
6339 {
6340   vat_main_t *vam = &vat_main;
6341   vat_json_node_t node;
6342
6343   vat_json_init_object (&node);
6344   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
6345   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
6346
6347   vat_json_print (vam->ofp, &node);
6348   vat_json_free (&node);
6349
6350   vam->retval = ntohl (mp->retval);
6351   vam->result_ready = 1;
6352 }
6353
6354 static int
6355 api_sw_interface_get_table (vat_main_t * vam)
6356 {
6357   unformat_input_t *i = vam->input;
6358   vl_api_sw_interface_get_table_t *mp;
6359   u32 sw_if_index;
6360   u8 sw_if_index_set = 0;
6361   u8 is_ipv6 = 0;
6362   int ret;
6363
6364   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6365     {
6366       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6367         sw_if_index_set = 1;
6368       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6369         sw_if_index_set = 1;
6370       else if (unformat (i, "ipv6"))
6371         is_ipv6 = 1;
6372       else
6373         break;
6374     }
6375
6376   if (sw_if_index_set == 0)
6377     {
6378       errmsg ("missing interface name or sw_if_index");
6379       return -99;
6380     }
6381
6382   M (SW_INTERFACE_GET_TABLE, mp);
6383   mp->sw_if_index = htonl (sw_if_index);
6384   mp->is_ipv6 = is_ipv6;
6385
6386   S (mp);
6387   W (ret);
6388   return ret;
6389 }
6390
6391 static int
6392 api_sw_interface_set_vpath (vat_main_t * vam)
6393 {
6394   unformat_input_t *i = vam->input;
6395   vl_api_sw_interface_set_vpath_t *mp;
6396   u32 sw_if_index = 0;
6397   u8 sw_if_index_set = 0;
6398   u8 is_enable = 0;
6399   int ret;
6400
6401   /* Parse args required to build the message */
6402   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6403     {
6404       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6405         sw_if_index_set = 1;
6406       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6407         sw_if_index_set = 1;
6408       else if (unformat (i, "enable"))
6409         is_enable = 1;
6410       else if (unformat (i, "disable"))
6411         is_enable = 0;
6412       else
6413         break;
6414     }
6415
6416   if (sw_if_index_set == 0)
6417     {
6418       errmsg ("missing interface name or sw_if_index");
6419       return -99;
6420     }
6421
6422   /* Construct the API message */
6423   M (SW_INTERFACE_SET_VPATH, mp);
6424
6425   mp->sw_if_index = ntohl (sw_if_index);
6426   mp->enable = is_enable;
6427
6428   /* send it... */
6429   S (mp);
6430
6431   /* Wait for a reply... */
6432   W (ret);
6433   return ret;
6434 }
6435
6436 static int
6437 api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
6438 {
6439   unformat_input_t *i = vam->input;
6440   vl_api_sw_interface_set_vxlan_bypass_t *mp;
6441   u32 sw_if_index = 0;
6442   u8 sw_if_index_set = 0;
6443   u8 is_enable = 1;
6444   u8 is_ipv6 = 0;
6445   int ret;
6446
6447   /* Parse args required to build the message */
6448   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6449     {
6450       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6451         sw_if_index_set = 1;
6452       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6453         sw_if_index_set = 1;
6454       else if (unformat (i, "enable"))
6455         is_enable = 1;
6456       else if (unformat (i, "disable"))
6457         is_enable = 0;
6458       else if (unformat (i, "ip4"))
6459         is_ipv6 = 0;
6460       else if (unformat (i, "ip6"))
6461         is_ipv6 = 1;
6462       else
6463         break;
6464     }
6465
6466   if (sw_if_index_set == 0)
6467     {
6468       errmsg ("missing interface name or sw_if_index");
6469       return -99;
6470     }
6471
6472   /* Construct the API message */
6473   M (SW_INTERFACE_SET_VXLAN_BYPASS, mp);
6474
6475   mp->sw_if_index = ntohl (sw_if_index);
6476   mp->enable = is_enable;
6477   mp->is_ipv6 = is_ipv6;
6478
6479   /* send it... */
6480   S (mp);
6481
6482   /* Wait for a reply... */
6483   W (ret);
6484   return ret;
6485 }
6486
6487 static int
6488 api_sw_interface_set_geneve_bypass (vat_main_t * vam)
6489 {
6490   unformat_input_t *i = vam->input;
6491   vl_api_sw_interface_set_geneve_bypass_t *mp;
6492   u32 sw_if_index = 0;
6493   u8 sw_if_index_set = 0;
6494   u8 is_enable = 1;
6495   u8 is_ipv6 = 0;
6496   int ret;
6497
6498   /* Parse args required to build the message */
6499   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6500     {
6501       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6502         sw_if_index_set = 1;
6503       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6504         sw_if_index_set = 1;
6505       else if (unformat (i, "enable"))
6506         is_enable = 1;
6507       else if (unformat (i, "disable"))
6508         is_enable = 0;
6509       else if (unformat (i, "ip4"))
6510         is_ipv6 = 0;
6511       else if (unformat (i, "ip6"))
6512         is_ipv6 = 1;
6513       else
6514         break;
6515     }
6516
6517   if (sw_if_index_set == 0)
6518     {
6519       errmsg ("missing interface name or sw_if_index");
6520       return -99;
6521     }
6522
6523   /* Construct the API message */
6524   M (SW_INTERFACE_SET_GENEVE_BYPASS, mp);
6525
6526   mp->sw_if_index = ntohl (sw_if_index);
6527   mp->enable = is_enable;
6528   mp->is_ipv6 = is_ipv6;
6529
6530   /* send it... */
6531   S (mp);
6532
6533   /* Wait for a reply... */
6534   W (ret);
6535   return ret;
6536 }
6537
6538 static int
6539 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
6540 {
6541   unformat_input_t *i = vam->input;
6542   vl_api_sw_interface_set_l2_xconnect_t *mp;
6543   u32 rx_sw_if_index;
6544   u8 rx_sw_if_index_set = 0;
6545   u32 tx_sw_if_index;
6546   u8 tx_sw_if_index_set = 0;
6547   u8 enable = 1;
6548   int ret;
6549
6550   /* Parse args required to build the message */
6551   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6552     {
6553       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
6554         rx_sw_if_index_set = 1;
6555       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
6556         tx_sw_if_index_set = 1;
6557       else if (unformat (i, "rx"))
6558         {
6559           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6560             {
6561               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6562                             &rx_sw_if_index))
6563                 rx_sw_if_index_set = 1;
6564             }
6565           else
6566             break;
6567         }
6568       else if (unformat (i, "tx"))
6569         {
6570           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6571             {
6572               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6573                             &tx_sw_if_index))
6574                 tx_sw_if_index_set = 1;
6575             }
6576           else
6577             break;
6578         }
6579       else if (unformat (i, "enable"))
6580         enable = 1;
6581       else if (unformat (i, "disable"))
6582         enable = 0;
6583       else
6584         break;
6585     }
6586
6587   if (rx_sw_if_index_set == 0)
6588     {
6589       errmsg ("missing rx interface name or rx_sw_if_index");
6590       return -99;
6591     }
6592
6593   if (enable && (tx_sw_if_index_set == 0))
6594     {
6595       errmsg ("missing tx interface name or tx_sw_if_index");
6596       return -99;
6597     }
6598
6599   M (SW_INTERFACE_SET_L2_XCONNECT, mp);
6600
6601   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6602   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
6603   mp->enable = enable;
6604
6605   S (mp);
6606   W (ret);
6607   return ret;
6608 }
6609
6610 static int
6611 api_sw_interface_set_l2_bridge (vat_main_t * vam)
6612 {
6613   unformat_input_t *i = vam->input;
6614   vl_api_sw_interface_set_l2_bridge_t *mp;
6615   vl_api_l2_port_type_t port_type;
6616   u32 rx_sw_if_index;
6617   u8 rx_sw_if_index_set = 0;
6618   u32 bd_id;
6619   u8 bd_id_set = 0;
6620   u32 shg = 0;
6621   u8 enable = 1;
6622   int ret;
6623
6624   port_type = L2_API_PORT_TYPE_NORMAL;
6625
6626   /* Parse args required to build the message */
6627   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6628     {
6629       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
6630         rx_sw_if_index_set = 1;
6631       else if (unformat (i, "bd_id %d", &bd_id))
6632         bd_id_set = 1;
6633       else
6634         if (unformat
6635             (i, "%U", api_unformat_sw_if_index, vam, &rx_sw_if_index))
6636         rx_sw_if_index_set = 1;
6637       else if (unformat (i, "shg %d", &shg))
6638         ;
6639       else if (unformat (i, "bvi"))
6640         port_type = L2_API_PORT_TYPE_BVI;
6641       else if (unformat (i, "uu-fwd"))
6642         port_type = L2_API_PORT_TYPE_UU_FWD;
6643       else if (unformat (i, "enable"))
6644         enable = 1;
6645       else if (unformat (i, "disable"))
6646         enable = 0;
6647       else
6648         break;
6649     }
6650
6651   if (rx_sw_if_index_set == 0)
6652     {
6653       errmsg ("missing rx interface name or sw_if_index");
6654       return -99;
6655     }
6656
6657   if (enable && (bd_id_set == 0))
6658     {
6659       errmsg ("missing bridge domain");
6660       return -99;
6661     }
6662
6663   M (SW_INTERFACE_SET_L2_BRIDGE, mp);
6664
6665   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6666   mp->bd_id = ntohl (bd_id);
6667   mp->shg = (u8) shg;
6668   mp->port_type = ntohl (port_type);
6669   mp->enable = enable;
6670
6671   S (mp);
6672   W (ret);
6673   return ret;
6674 }
6675
6676 static int
6677 api_bridge_domain_dump (vat_main_t * vam)
6678 {
6679   unformat_input_t *i = vam->input;
6680   vl_api_bridge_domain_dump_t *mp;
6681   vl_api_control_ping_t *mp_ping;
6682   u32 bd_id = ~0;
6683   int ret;
6684
6685   /* Parse args required to build the message */
6686   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6687     {
6688       if (unformat (i, "bd_id %d", &bd_id))
6689         ;
6690       else
6691         break;
6692     }
6693
6694   M (BRIDGE_DOMAIN_DUMP, mp);
6695   mp->bd_id = ntohl (bd_id);
6696   S (mp);
6697
6698   /* Use a control ping for synchronization */
6699   MPING (CONTROL_PING, mp_ping);
6700   S (mp_ping);
6701
6702   W (ret);
6703   return ret;
6704 }
6705
6706 static int
6707 api_bridge_domain_add_del (vat_main_t * vam)
6708 {
6709   unformat_input_t *i = vam->input;
6710   vl_api_bridge_domain_add_del_t *mp;
6711   u32 bd_id = ~0;
6712   u8 is_add = 1;
6713   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
6714   u8 *bd_tag = NULL;
6715   u32 mac_age = 0;
6716   int ret;
6717
6718   /* Parse args required to build the message */
6719   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6720     {
6721       if (unformat (i, "bd_id %d", &bd_id))
6722         ;
6723       else if (unformat (i, "flood %d", &flood))
6724         ;
6725       else if (unformat (i, "uu-flood %d", &uu_flood))
6726         ;
6727       else if (unformat (i, "forward %d", &forward))
6728         ;
6729       else if (unformat (i, "learn %d", &learn))
6730         ;
6731       else if (unformat (i, "arp-term %d", &arp_term))
6732         ;
6733       else if (unformat (i, "mac-age %d", &mac_age))
6734         ;
6735       else if (unformat (i, "bd-tag %s", &bd_tag))
6736         ;
6737       else if (unformat (i, "del"))
6738         {
6739           is_add = 0;
6740           flood = uu_flood = forward = learn = 0;
6741         }
6742       else
6743         break;
6744     }
6745
6746   if (bd_id == ~0)
6747     {
6748       errmsg ("missing bridge domain");
6749       ret = -99;
6750       goto done;
6751     }
6752
6753   if (mac_age > 255)
6754     {
6755       errmsg ("mac age must be less than 256 ");
6756       ret = -99;
6757       goto done;
6758     }
6759
6760   if ((bd_tag) && (vec_len (bd_tag) > 63))
6761     {
6762       errmsg ("bd-tag cannot be longer than 63");
6763       ret = -99;
6764       goto done;
6765     }
6766
6767   M (BRIDGE_DOMAIN_ADD_DEL, mp);
6768
6769   mp->bd_id = ntohl (bd_id);
6770   mp->flood = flood;
6771   mp->uu_flood = uu_flood;
6772   mp->forward = forward;
6773   mp->learn = learn;
6774   mp->arp_term = arp_term;
6775   mp->is_add = is_add;
6776   mp->mac_age = (u8) mac_age;
6777   if (bd_tag)
6778     {
6779       clib_memcpy (mp->bd_tag, bd_tag, vec_len (bd_tag));
6780       mp->bd_tag[vec_len (bd_tag)] = 0;
6781     }
6782   S (mp);
6783   W (ret);
6784
6785 done:
6786   vec_free (bd_tag);
6787   return ret;
6788 }
6789
6790 static int
6791 api_l2fib_flush_bd (vat_main_t * vam)
6792 {
6793   unformat_input_t *i = vam->input;
6794   vl_api_l2fib_flush_bd_t *mp;
6795   u32 bd_id = ~0;
6796   int ret;
6797
6798   /* Parse args required to build the message */
6799   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6800     {
6801       if (unformat (i, "bd_id %d", &bd_id));
6802       else
6803         break;
6804     }
6805
6806   if (bd_id == ~0)
6807     {
6808       errmsg ("missing bridge domain");
6809       return -99;
6810     }
6811
6812   M (L2FIB_FLUSH_BD, mp);
6813
6814   mp->bd_id = htonl (bd_id);
6815
6816   S (mp);
6817   W (ret);
6818   return ret;
6819 }
6820
6821 static int
6822 api_l2fib_flush_int (vat_main_t * vam)
6823 {
6824   unformat_input_t *i = vam->input;
6825   vl_api_l2fib_flush_int_t *mp;
6826   u32 sw_if_index = ~0;
6827   int ret;
6828
6829   /* Parse args required to build the message */
6830   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6831     {
6832       if (unformat (i, "sw_if_index %d", &sw_if_index));
6833       else
6834         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index));
6835       else
6836         break;
6837     }
6838
6839   if (sw_if_index == ~0)
6840     {
6841       errmsg ("missing interface name or sw_if_index");
6842       return -99;
6843     }
6844
6845   M (L2FIB_FLUSH_INT, mp);
6846
6847   mp->sw_if_index = ntohl (sw_if_index);
6848
6849   S (mp);
6850   W (ret);
6851   return ret;
6852 }
6853
6854 static int
6855 api_l2fib_add_del (vat_main_t * vam)
6856 {
6857   unformat_input_t *i = vam->input;
6858   vl_api_l2fib_add_del_t *mp;
6859   f64 timeout;
6860   u8 mac[6] = { 0 };
6861   u8 mac_set = 0;
6862   u32 bd_id;
6863   u8 bd_id_set = 0;
6864   u32 sw_if_index = 0;
6865   u8 sw_if_index_set = 0;
6866   u8 is_add = 1;
6867   u8 static_mac = 0;
6868   u8 filter_mac = 0;
6869   u8 bvi_mac = 0;
6870   int count = 1;
6871   f64 before = 0;
6872   int j;
6873
6874   /* Parse args required to build the message */
6875   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6876     {
6877       if (unformat (i, "mac %U", unformat_ethernet_address, mac))
6878         mac_set = 1;
6879       else if (unformat (i, "bd_id %d", &bd_id))
6880         bd_id_set = 1;
6881       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6882         sw_if_index_set = 1;
6883       else if (unformat (i, "sw_if"))
6884         {
6885           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6886             {
6887               if (unformat
6888                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6889                 sw_if_index_set = 1;
6890             }
6891           else
6892             break;
6893         }
6894       else if (unformat (i, "static"))
6895         static_mac = 1;
6896       else if (unformat (i, "filter"))
6897         {
6898           filter_mac = 1;
6899           static_mac = 1;
6900         }
6901       else if (unformat (i, "bvi"))
6902         {
6903           bvi_mac = 1;
6904           static_mac = 1;
6905         }
6906       else if (unformat (i, "del"))
6907         is_add = 0;
6908       else if (unformat (i, "count %d", &count))
6909         ;
6910       else
6911         break;
6912     }
6913
6914   if (mac_set == 0)
6915     {
6916       errmsg ("missing mac address");
6917       return -99;
6918     }
6919
6920   if (bd_id_set == 0)
6921     {
6922       errmsg ("missing bridge domain");
6923       return -99;
6924     }
6925
6926   if (is_add && sw_if_index_set == 0 && filter_mac == 0)
6927     {
6928       errmsg ("missing interface name or sw_if_index");
6929       return -99;
6930     }
6931
6932   if (count > 1)
6933     {
6934       /* Turn on async mode */
6935       vam->async_mode = 1;
6936       vam->async_errors = 0;
6937       before = vat_time_now (vam);
6938     }
6939
6940   for (j = 0; j < count; j++)
6941     {
6942       M (L2FIB_ADD_DEL, mp);
6943
6944       clib_memcpy (mp->mac, mac, 6);
6945       mp->bd_id = ntohl (bd_id);
6946       mp->is_add = is_add;
6947       mp->sw_if_index = ntohl (sw_if_index);
6948
6949       if (is_add)
6950         {
6951           mp->static_mac = static_mac;
6952           mp->filter_mac = filter_mac;
6953           mp->bvi_mac = bvi_mac;
6954         }
6955       increment_mac_address (mac);
6956       /* send it... */
6957       S (mp);
6958     }
6959
6960   if (count > 1)
6961     {
6962       vl_api_control_ping_t *mp_ping;
6963       f64 after;
6964
6965       /* Shut off async mode */
6966       vam->async_mode = 0;
6967
6968       MPING (CONTROL_PING, mp_ping);
6969       S (mp_ping);
6970
6971       timeout = vat_time_now (vam) + 1.0;
6972       while (vat_time_now (vam) < timeout)
6973         if (vam->result_ready == 1)
6974           goto out;
6975       vam->retval = -99;
6976
6977     out:
6978       if (vam->retval == -99)
6979         errmsg ("timeout");
6980
6981       if (vam->async_errors > 0)
6982         {
6983           errmsg ("%d asynchronous errors", vam->async_errors);
6984           vam->retval = -98;
6985         }
6986       vam->async_errors = 0;
6987       after = vat_time_now (vam);
6988
6989       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
6990              count, after - before, count / (after - before));
6991     }
6992   else
6993     {
6994       int ret;
6995
6996       /* Wait for a reply... */
6997       W (ret);
6998       return ret;
6999     }
7000   /* Return the good/bad news */
7001   return (vam->retval);
7002 }
7003
7004 static int
7005 api_bridge_domain_set_mac_age (vat_main_t * vam)
7006 {
7007   unformat_input_t *i = vam->input;
7008   vl_api_bridge_domain_set_mac_age_t *mp;
7009   u32 bd_id = ~0;
7010   u32 mac_age = 0;
7011   int ret;
7012
7013   /* Parse args required to build the message */
7014   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7015     {
7016       if (unformat (i, "bd_id %d", &bd_id));
7017       else if (unformat (i, "mac-age %d", &mac_age));
7018       else
7019         break;
7020     }
7021
7022   if (bd_id == ~0)
7023     {
7024       errmsg ("missing bridge domain");
7025       return -99;
7026     }
7027
7028   if (mac_age > 255)
7029     {
7030       errmsg ("mac age must be less than 256 ");
7031       return -99;
7032     }
7033
7034   M (BRIDGE_DOMAIN_SET_MAC_AGE, mp);
7035
7036   mp->bd_id = htonl (bd_id);
7037   mp->mac_age = (u8) mac_age;
7038
7039   S (mp);
7040   W (ret);
7041   return ret;
7042 }
7043
7044 static int
7045 api_l2_flags (vat_main_t * vam)
7046 {
7047   unformat_input_t *i = vam->input;
7048   vl_api_l2_flags_t *mp;
7049   u32 sw_if_index;
7050   u32 flags = 0;
7051   u8 sw_if_index_set = 0;
7052   u8 is_set = 0;
7053   int ret;
7054
7055   /* Parse args required to build the message */
7056   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7057     {
7058       if (unformat (i, "sw_if_index %d", &sw_if_index))
7059         sw_if_index_set = 1;
7060       else if (unformat (i, "sw_if"))
7061         {
7062           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7063             {
7064               if (unformat
7065                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7066                 sw_if_index_set = 1;
7067             }
7068           else
7069             break;
7070         }
7071       else if (unformat (i, "learn"))
7072         flags |= L2_LEARN;
7073       else if (unformat (i, "forward"))
7074         flags |= L2_FWD;
7075       else if (unformat (i, "flood"))
7076         flags |= L2_FLOOD;
7077       else if (unformat (i, "uu-flood"))
7078         flags |= L2_UU_FLOOD;
7079       else if (unformat (i, "arp-term"))
7080         flags |= L2_ARP_TERM;
7081       else if (unformat (i, "off"))
7082         is_set = 0;
7083       else if (unformat (i, "disable"))
7084         is_set = 0;
7085       else
7086         break;
7087     }
7088
7089   if (sw_if_index_set == 0)
7090     {
7091       errmsg ("missing interface name or sw_if_index");
7092       return -99;
7093     }
7094
7095   M (L2_FLAGS, mp);
7096
7097   mp->sw_if_index = ntohl (sw_if_index);
7098   mp->feature_bitmap = ntohl (flags);
7099   mp->is_set = is_set;
7100
7101   S (mp);
7102   W (ret);
7103   return ret;
7104 }
7105
7106 static int
7107 api_bridge_flags (vat_main_t * vam)
7108 {
7109   unformat_input_t *i = vam->input;
7110   vl_api_bridge_flags_t *mp;
7111   u32 bd_id;
7112   u8 bd_id_set = 0;
7113   u8 is_set = 1;
7114   bd_flags_t flags = 0;
7115   int ret;
7116
7117   /* Parse args required to build the message */
7118   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7119     {
7120       if (unformat (i, "bd_id %d", &bd_id))
7121         bd_id_set = 1;
7122       else if (unformat (i, "learn"))
7123         flags |= BRIDGE_API_FLAG_LEARN;
7124       else if (unformat (i, "forward"))
7125         flags |= BRIDGE_API_FLAG_FWD;
7126       else if (unformat (i, "flood"))
7127         flags |= BRIDGE_API_FLAG_FLOOD;
7128       else if (unformat (i, "uu-flood"))
7129         flags |= BRIDGE_API_FLAG_UU_FLOOD;
7130       else if (unformat (i, "arp-term"))
7131         flags |= BRIDGE_API_FLAG_ARP_TERM;
7132       else if (unformat (i, "off"))
7133         is_set = 0;
7134       else if (unformat (i, "disable"))
7135         is_set = 0;
7136       else
7137         break;
7138     }
7139
7140   if (bd_id_set == 0)
7141     {
7142       errmsg ("missing bridge domain");
7143       return -99;
7144     }
7145
7146   M (BRIDGE_FLAGS, mp);
7147
7148   mp->bd_id = ntohl (bd_id);
7149   mp->flags = ntohl (flags);
7150   mp->is_set = is_set;
7151
7152   S (mp);
7153   W (ret);
7154   return ret;
7155 }
7156
7157 static int
7158 api_bd_ip_mac_add_del (vat_main_t * vam)
7159 {
7160   vl_api_address_t ip = VL_API_ZERO_ADDRESS;
7161   vl_api_mac_address_t mac = { 0 };
7162   unformat_input_t *i = vam->input;
7163   vl_api_bd_ip_mac_add_del_t *mp;
7164   u32 bd_id;
7165   u8 is_add = 1;
7166   u8 bd_id_set = 0;
7167   u8 ip_set = 0;
7168   u8 mac_set = 0;
7169   int ret;
7170
7171
7172   /* Parse args required to build the message */
7173   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7174     {
7175       if (unformat (i, "bd_id %d", &bd_id))
7176         {
7177           bd_id_set++;
7178         }
7179       else if (unformat (i, "%U", unformat_vl_api_address, &ip))
7180         {
7181           ip_set++;
7182         }
7183       else if (unformat (i, "%U", unformat_vl_api_mac_address, &mac))
7184         {
7185           mac_set++;
7186         }
7187       else if (unformat (i, "del"))
7188         is_add = 0;
7189       else
7190         break;
7191     }
7192
7193   if (bd_id_set == 0)
7194     {
7195       errmsg ("missing bridge domain");
7196       return -99;
7197     }
7198   else if (ip_set == 0)
7199     {
7200       errmsg ("missing IP address");
7201       return -99;
7202     }
7203   else if (mac_set == 0)
7204     {
7205       errmsg ("missing MAC address");
7206       return -99;
7207     }
7208
7209   M (BD_IP_MAC_ADD_DEL, mp);
7210
7211   mp->entry.bd_id = ntohl (bd_id);
7212   mp->is_add = is_add;
7213
7214   clib_memcpy (&mp->entry.ip, &ip, sizeof (ip));
7215   clib_memcpy (&mp->entry.mac, &mac, sizeof (mac));
7216
7217   S (mp);
7218   W (ret);
7219   return ret;
7220 }
7221
7222 static int
7223 api_bd_ip_mac_flush (vat_main_t * vam)
7224 {
7225   unformat_input_t *i = vam->input;
7226   vl_api_bd_ip_mac_flush_t *mp;
7227   u32 bd_id;
7228   u8 bd_id_set = 0;
7229   int ret;
7230
7231   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7232     {
7233       if (unformat (i, "bd_id %d", &bd_id))
7234         {
7235           bd_id_set++;
7236         }
7237       else
7238         break;
7239     }
7240
7241   if (bd_id_set == 0)
7242     {
7243       errmsg ("missing bridge domain");
7244       return -99;
7245     }
7246
7247   M (BD_IP_MAC_FLUSH, mp);
7248
7249   mp->bd_id = ntohl (bd_id);
7250
7251   S (mp);
7252   W (ret);
7253   return ret;
7254 }
7255
7256 static void vl_api_bd_ip_mac_details_t_handler
7257   (vl_api_bd_ip_mac_details_t * mp)
7258 {
7259   vat_main_t *vam = &vat_main;
7260
7261   print (vam->ofp,
7262          "\n%-5d %U %U",
7263          ntohl (mp->entry.bd_id),
7264          format_vl_api_mac_address, mp->entry.mac,
7265          format_vl_api_address, &mp->entry.ip);
7266 }
7267
7268 static void vl_api_bd_ip_mac_details_t_handler_json
7269   (vl_api_bd_ip_mac_details_t * mp)
7270 {
7271   vat_main_t *vam = &vat_main;
7272   vat_json_node_t *node = NULL;
7273
7274   if (VAT_JSON_ARRAY != vam->json_tree.type)
7275     {
7276       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
7277       vat_json_init_array (&vam->json_tree);
7278     }
7279   node = vat_json_array_add (&vam->json_tree);
7280
7281   vat_json_init_object (node);
7282   vat_json_object_add_uint (node, "bd_id", ntohl (mp->entry.bd_id));
7283   vat_json_object_add_string_copy (node, "mac_address",
7284                                    format (0, "%U", format_vl_api_mac_address,
7285                                            &mp->entry.mac));
7286   u8 *ip = 0;
7287
7288   ip = format (0, "%U", format_vl_api_address, &mp->entry.ip);
7289   vat_json_object_add_string_copy (node, "ip_address", ip);
7290   vec_free (ip);
7291 }
7292
7293 static int
7294 api_bd_ip_mac_dump (vat_main_t * vam)
7295 {
7296   unformat_input_t *i = vam->input;
7297   vl_api_bd_ip_mac_dump_t *mp;
7298   vl_api_control_ping_t *mp_ping;
7299   int ret;
7300   u32 bd_id;
7301   u8 bd_id_set = 0;
7302
7303   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7304     {
7305       if (unformat (i, "bd_id %d", &bd_id))
7306         {
7307           bd_id_set++;
7308         }
7309       else
7310         break;
7311     }
7312
7313   print (vam->ofp,
7314          "\n%-5s %-7s %-20s %-30s",
7315          "bd_id", "is_ipv6", "mac_address", "ip_address");
7316
7317   /* Dump Bridge Domain Ip to Mac entries */
7318   M (BD_IP_MAC_DUMP, mp);
7319
7320   if (bd_id_set)
7321     mp->bd_id = htonl (bd_id);
7322   else
7323     mp->bd_id = ~0;
7324
7325   S (mp);
7326
7327   /* Use a control ping for synchronization */
7328   MPING (CONTROL_PING, mp_ping);
7329   S (mp_ping);
7330
7331   W (ret);
7332   return ret;
7333 }
7334
7335 static int
7336 api_tap_create_v2 (vat_main_t * vam)
7337 {
7338   unformat_input_t *i = vam->input;
7339   vl_api_tap_create_v2_t *mp;
7340 #define TAP_FLAG_GSO (1 << 0)
7341   u8 mac_address[6];
7342   u8 random_mac = 1;
7343   u32 id = ~0;
7344   u8 *host_if_name = 0;
7345   u8 *host_ns = 0;
7346   u8 host_mac_addr[6];
7347   u8 host_mac_addr_set = 0;
7348   u8 *host_bridge = 0;
7349   ip4_address_t host_ip4_addr;
7350   ip4_address_t host_ip4_gw;
7351   u8 host_ip4_gw_set = 0;
7352   u32 host_ip4_prefix_len = 0;
7353   ip6_address_t host_ip6_addr;
7354   ip6_address_t host_ip6_gw;
7355   u8 host_ip6_gw_set = 0;
7356   u32 host_ip6_prefix_len = 0;
7357   u8 host_mtu_set = 0;
7358   u32 host_mtu_size = 0;
7359   u32 tap_flags = 0;
7360   int ret;
7361   u32 rx_ring_sz = 0, tx_ring_sz = 0;
7362
7363   clib_memset (mac_address, 0, sizeof (mac_address));
7364
7365   /* Parse args required to build the message */
7366   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7367     {
7368       if (unformat (i, "hw-addr %U", unformat_ethernet_address, mac_address))
7369         {
7370           random_mac = 0;
7371         }
7372       else if (unformat (i, "id %u", &id))
7373         ;
7374       else if (unformat (i, "host-if-name %s", &host_if_name))
7375         ;
7376       else if (unformat (i, "host-ns %s", &host_ns))
7377         ;
7378       else if (unformat (i, "host-mac-addr %U", unformat_ethernet_address,
7379                          host_mac_addr))
7380         host_mac_addr_set = 1;
7381       else if (unformat (i, "host-bridge %s", &host_bridge))
7382         ;
7383       else if (unformat (i, "host-ip4-addr %U/%d", unformat_ip4_address,
7384                          &host_ip4_addr, &host_ip4_prefix_len))
7385         ;
7386       else if (unformat (i, "host-ip6-addr %U/%d", unformat_ip6_address,
7387                          &host_ip6_addr, &host_ip6_prefix_len))
7388         ;
7389       else if (unformat (i, "host-ip4-gw %U", unformat_ip4_address,
7390                          &host_ip4_gw))
7391         host_ip4_gw_set = 1;
7392       else if (unformat (i, "host-ip6-gw %U", unformat_ip6_address,
7393                          &host_ip6_gw))
7394         host_ip6_gw_set = 1;
7395       else if (unformat (i, "rx-ring-size %d", &rx_ring_sz))
7396         ;
7397       else if (unformat (i, "tx-ring-size %d", &tx_ring_sz))
7398         ;
7399       else if (unformat (i, "host-mtu-size %d", &host_mtu_size))
7400         host_mtu_set = 1;
7401       else if (unformat (i, "no-gso"))
7402         tap_flags &= ~TAP_FLAG_GSO;
7403       else if (unformat (i, "gso"))
7404         tap_flags |= TAP_FLAG_GSO;
7405       else
7406         break;
7407     }
7408
7409   if (vec_len (host_if_name) > 63)
7410     {
7411       errmsg ("tap name too long. ");
7412       return -99;
7413     }
7414   if (vec_len (host_ns) > 63)
7415     {
7416       errmsg ("host name space too long. ");
7417       return -99;
7418     }
7419   if (vec_len (host_bridge) > 63)
7420     {
7421       errmsg ("host bridge name too long. ");
7422       return -99;
7423     }
7424   if (host_ip4_prefix_len > 32)
7425     {
7426       errmsg ("host ip4 prefix length not valid. ");
7427       return -99;
7428     }
7429   if (host_ip6_prefix_len > 128)
7430     {
7431       errmsg ("host ip6 prefix length not valid. ");
7432       return -99;
7433     }
7434   if (!is_pow2 (rx_ring_sz))
7435     {
7436       errmsg ("rx ring size must be power of 2. ");
7437       return -99;
7438     }
7439   if (rx_ring_sz > 32768)
7440     {
7441       errmsg ("rx ring size must be 32768 or lower. ");
7442       return -99;
7443     }
7444   if (!is_pow2 (tx_ring_sz))
7445     {
7446       errmsg ("tx ring size must be power of 2. ");
7447       return -99;
7448     }
7449   if (tx_ring_sz > 32768)
7450     {
7451       errmsg ("tx ring size must be 32768 or lower. ");
7452       return -99;
7453     }
7454   if (host_mtu_set && (host_mtu_size < 64 || host_mtu_size > 65355))
7455     {
7456       errmsg ("host MTU size must be in between 64 and 65355. ");
7457       return -99;
7458     }
7459
7460   /* Construct the API message */
7461   M (TAP_CREATE_V2, mp);
7462
7463   mp->use_random_mac = random_mac;
7464
7465   mp->id = ntohl (id);
7466   mp->host_namespace_set = host_ns != 0;
7467   mp->host_bridge_set = host_bridge != 0;
7468   mp->host_ip4_prefix_set = host_ip4_prefix_len != 0;
7469   mp->host_ip6_prefix_set = host_ip6_prefix_len != 0;
7470   mp->rx_ring_sz = ntohs (rx_ring_sz);
7471   mp->tx_ring_sz = ntohs (tx_ring_sz);
7472   mp->host_mtu_set = host_mtu_set;
7473   mp->host_mtu_size = ntohl (host_mtu_size);
7474   mp->tap_flags = ntohl (tap_flags);
7475
7476   if (random_mac == 0)
7477     clib_memcpy (mp->mac_address, mac_address, 6);
7478   if (host_mac_addr_set)
7479     clib_memcpy (mp->host_mac_addr, host_mac_addr, 6);
7480   if (host_if_name)
7481     clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
7482   if (host_ns)
7483     clib_memcpy (mp->host_namespace, host_ns, vec_len (host_ns));
7484   if (host_bridge)
7485     clib_memcpy (mp->host_bridge, host_bridge, vec_len (host_bridge));
7486   if (host_ip4_prefix_len)
7487     clib_memcpy (mp->host_ip4_prefix.address, &host_ip4_addr, 4);
7488   if (host_ip6_prefix_len)
7489     clib_memcpy (mp->host_ip6_prefix.address, &host_ip6_addr, 16);
7490   if (host_ip4_gw_set)
7491     clib_memcpy (mp->host_ip4_gw, &host_ip4_gw, 4);
7492   if (host_ip6_gw_set)
7493     clib_memcpy (mp->host_ip6_gw, &host_ip6_gw, 16);
7494
7495   vec_free (host_ns);
7496   vec_free (host_if_name);
7497   vec_free (host_bridge);
7498
7499   /* send it... */
7500   S (mp);
7501
7502   /* Wait for a reply... */
7503   W (ret);
7504   return ret;
7505 }
7506
7507 static int
7508 api_tap_delete_v2 (vat_main_t * vam)
7509 {
7510   unformat_input_t *i = vam->input;
7511   vl_api_tap_delete_v2_t *mp;
7512   u32 sw_if_index = ~0;
7513   u8 sw_if_index_set = 0;
7514   int ret;
7515
7516   /* Parse args required to build the message */
7517   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7518     {
7519       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7520         sw_if_index_set = 1;
7521       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7522         sw_if_index_set = 1;
7523       else
7524         break;
7525     }
7526
7527   if (sw_if_index_set == 0)
7528     {
7529       errmsg ("missing vpp interface name. ");
7530       return -99;
7531     }
7532
7533   /* Construct the API message */
7534   M (TAP_DELETE_V2, mp);
7535
7536   mp->sw_if_index = ntohl (sw_if_index);
7537
7538   /* send it... */
7539   S (mp);
7540
7541   /* Wait for a reply... */
7542   W (ret);
7543   return ret;
7544 }
7545
7546 uword
7547 unformat_vlib_pci_addr (unformat_input_t * input, va_list * args)
7548 {
7549   vlib_pci_addr_t *addr = va_arg (*args, vlib_pci_addr_t *);
7550   u32 x[4];
7551
7552   if (!unformat (input, "%x:%x:%x.%x", &x[0], &x[1], &x[2], &x[3]))
7553     return 0;
7554
7555   addr->domain = x[0];
7556   addr->bus = x[1];
7557   addr->slot = x[2];
7558   addr->function = x[3];
7559
7560   return 1;
7561 }
7562
7563 static int
7564 api_virtio_pci_create (vat_main_t * vam)
7565 {
7566   unformat_input_t *i = vam->input;
7567   vl_api_virtio_pci_create_t *mp;
7568   u8 mac_address[6];
7569   u8 random_mac = 1;
7570   u8 gso_enabled = 0;
7571   u32 pci_addr = 0;
7572   u64 features = (u64) ~ (0ULL);
7573   int ret;
7574
7575   clib_memset (mac_address, 0, sizeof (mac_address));
7576
7577   /* Parse args required to build the message */
7578   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7579     {
7580       if (unformat (i, "hw-addr %U", unformat_ethernet_address, mac_address))
7581         {
7582           random_mac = 0;
7583         }
7584       else if (unformat (i, "pci-addr %U", unformat_vlib_pci_addr, &pci_addr))
7585         ;
7586       else if (unformat (i, "features 0x%llx", &features))
7587         ;
7588       else if (unformat (i, "gso-enabled"))
7589         gso_enabled = 1;
7590       else
7591         break;
7592     }
7593
7594   if (pci_addr == 0)
7595     {
7596       errmsg ("pci address must be non zero. ");
7597       return -99;
7598     }
7599
7600   /* Construct the API message */
7601   M (VIRTIO_PCI_CREATE, mp);
7602
7603   mp->use_random_mac = random_mac;
7604
7605   mp->pci_addr = htonl (pci_addr);
7606   mp->features = clib_host_to_net_u64 (features);
7607   mp->gso_enabled = gso_enabled;
7608
7609   if (random_mac == 0)
7610     clib_memcpy (mp->mac_address, mac_address, 6);
7611
7612   /* send it... */
7613   S (mp);
7614
7615   /* Wait for a reply... */
7616   W (ret);
7617   return ret;
7618 }
7619
7620 static int
7621 api_virtio_pci_delete (vat_main_t * vam)
7622 {
7623   unformat_input_t *i = vam->input;
7624   vl_api_virtio_pci_delete_t *mp;
7625   u32 sw_if_index = ~0;
7626   u8 sw_if_index_set = 0;
7627   int ret;
7628
7629   /* Parse args required to build the message */
7630   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7631     {
7632       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7633         sw_if_index_set = 1;
7634       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7635         sw_if_index_set = 1;
7636       else
7637         break;
7638     }
7639
7640   if (sw_if_index_set == 0)
7641     {
7642       errmsg ("missing vpp interface name. ");
7643       return -99;
7644     }
7645
7646   /* Construct the API message */
7647   M (VIRTIO_PCI_DELETE, mp);
7648
7649   mp->sw_if_index = htonl (sw_if_index);
7650
7651   /* send it... */
7652   S (mp);
7653
7654   /* Wait for a reply... */
7655   W (ret);
7656   return ret;
7657 }
7658
7659 static int
7660 api_bond_create (vat_main_t * vam)
7661 {
7662   unformat_input_t *i = vam->input;
7663   vl_api_bond_create_t *mp;
7664   u8 mac_address[6];
7665   u8 custom_mac = 0;
7666   int ret;
7667   u8 mode;
7668   u8 lb;
7669   u8 mode_is_set = 0;
7670   u32 id = ~0;
7671   u8 numa_only = 0;
7672
7673   clib_memset (mac_address, 0, sizeof (mac_address));
7674   lb = BOND_LB_L2;
7675
7676   /* Parse args required to build the message */
7677   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7678     {
7679       if (unformat (i, "mode %U", unformat_bond_mode, &mode))
7680         mode_is_set = 1;
7681       else if (((mode == BOND_MODE_LACP) || (mode == BOND_MODE_XOR))
7682                && unformat (i, "lb %U", unformat_bond_load_balance, &lb))
7683         ;
7684       else if (unformat (i, "hw-addr %U", unformat_ethernet_address,
7685                          mac_address))
7686         custom_mac = 1;
7687       else if (unformat (i, "numa-only"))
7688         numa_only = 1;
7689       else if (unformat (i, "id %u", &id))
7690         ;
7691       else
7692         break;
7693     }
7694
7695   if (mode_is_set == 0)
7696     {
7697       errmsg ("Missing bond mode. ");
7698       return -99;
7699     }
7700
7701   /* Construct the API message */
7702   M (BOND_CREATE, mp);
7703
7704   mp->use_custom_mac = custom_mac;
7705
7706   mp->mode = htonl (mode);
7707   mp->lb = htonl (lb);
7708   mp->id = htonl (id);
7709   mp->numa_only = numa_only;
7710
7711   if (custom_mac)
7712     clib_memcpy (mp->mac_address, mac_address, 6);
7713
7714   /* send it... */
7715   S (mp);
7716
7717   /* Wait for a reply... */
7718   W (ret);
7719   return ret;
7720 }
7721
7722 static int
7723 api_bond_delete (vat_main_t * vam)
7724 {
7725   unformat_input_t *i = vam->input;
7726   vl_api_bond_delete_t *mp;
7727   u32 sw_if_index = ~0;
7728   u8 sw_if_index_set = 0;
7729   int ret;
7730
7731   /* Parse args required to build the message */
7732   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7733     {
7734       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7735         sw_if_index_set = 1;
7736       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7737         sw_if_index_set = 1;
7738       else
7739         break;
7740     }
7741
7742   if (sw_if_index_set == 0)
7743     {
7744       errmsg ("missing vpp interface name. ");
7745       return -99;
7746     }
7747
7748   /* Construct the API message */
7749   M (BOND_DELETE, mp);
7750
7751   mp->sw_if_index = ntohl (sw_if_index);
7752
7753   /* send it... */
7754   S (mp);
7755
7756   /* Wait for a reply... */
7757   W (ret);
7758   return ret;
7759 }
7760
7761 static int
7762 api_bond_enslave (vat_main_t * vam)
7763 {
7764   unformat_input_t *i = vam->input;
7765   vl_api_bond_enslave_t *mp;
7766   u32 bond_sw_if_index;
7767   int ret;
7768   u8 is_passive;
7769   u8 is_long_timeout;
7770   u32 bond_sw_if_index_is_set = 0;
7771   u32 sw_if_index;
7772   u8 sw_if_index_is_set = 0;
7773
7774   /* Parse args required to build the message */
7775   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7776     {
7777       if (unformat (i, "sw_if_index %d", &sw_if_index))
7778         sw_if_index_is_set = 1;
7779       else if (unformat (i, "bond %u", &bond_sw_if_index))
7780         bond_sw_if_index_is_set = 1;
7781       else if (unformat (i, "passive %d", &is_passive))
7782         ;
7783       else if (unformat (i, "long-timeout %d", &is_long_timeout))
7784         ;
7785       else
7786         break;
7787     }
7788
7789   if (bond_sw_if_index_is_set == 0)
7790     {
7791       errmsg ("Missing bond sw_if_index. ");
7792       return -99;
7793     }
7794   if (sw_if_index_is_set == 0)
7795     {
7796       errmsg ("Missing slave sw_if_index. ");
7797       return -99;
7798     }
7799
7800   /* Construct the API message */
7801   M (BOND_ENSLAVE, mp);
7802
7803   mp->bond_sw_if_index = ntohl (bond_sw_if_index);
7804   mp->sw_if_index = ntohl (sw_if_index);
7805   mp->is_long_timeout = is_long_timeout;
7806   mp->is_passive = is_passive;
7807
7808   /* send it... */
7809   S (mp);
7810
7811   /* Wait for a reply... */
7812   W (ret);
7813   return ret;
7814 }
7815
7816 static int
7817 api_bond_detach_slave (vat_main_t * vam)
7818 {
7819   unformat_input_t *i = vam->input;
7820   vl_api_bond_detach_slave_t *mp;
7821   u32 sw_if_index = ~0;
7822   u8 sw_if_index_set = 0;
7823   int ret;
7824
7825   /* Parse args required to build the message */
7826   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7827     {
7828       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7829         sw_if_index_set = 1;
7830       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7831         sw_if_index_set = 1;
7832       else
7833         break;
7834     }
7835
7836   if (sw_if_index_set == 0)
7837     {
7838       errmsg ("missing vpp interface name. ");
7839       return -99;
7840     }
7841
7842   /* Construct the API message */
7843   M (BOND_DETACH_SLAVE, mp);
7844
7845   mp->sw_if_index = ntohl (sw_if_index);
7846
7847   /* send it... */
7848   S (mp);
7849
7850   /* Wait for a reply... */
7851   W (ret);
7852   return ret;
7853 }
7854
7855 static int
7856 api_ip_table_add_del (vat_main_t * vam)
7857 {
7858   unformat_input_t *i = vam->input;
7859   vl_api_ip_table_add_del_t *mp;
7860   u32 table_id = ~0;
7861   u8 is_ipv6 = 0;
7862   u8 is_add = 1;
7863   int ret = 0;
7864
7865   /* Parse args required to build the message */
7866   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7867     {
7868       if (unformat (i, "ipv6"))
7869         is_ipv6 = 1;
7870       else if (unformat (i, "del"))
7871         is_add = 0;
7872       else if (unformat (i, "add"))
7873         is_add = 1;
7874       else if (unformat (i, "table %d", &table_id))
7875         ;
7876       else
7877         {
7878           clib_warning ("parse error '%U'", format_unformat_error, i);
7879           return -99;
7880         }
7881     }
7882
7883   if (~0 == table_id)
7884     {
7885       errmsg ("missing table-ID");
7886       return -99;
7887     }
7888
7889   /* Construct the API message */
7890   M (IP_TABLE_ADD_DEL, mp);
7891
7892   mp->table.table_id = ntohl (table_id);
7893   mp->table.is_ip6 = is_ipv6;
7894   mp->is_add = is_add;
7895
7896   /* send it... */
7897   S (mp);
7898
7899   /* Wait for a reply... */
7900   W (ret);
7901
7902   return ret;
7903 }
7904
7905 uword
7906 unformat_fib_path (unformat_input_t * input, va_list * args)
7907 {
7908   vat_main_t *vam = va_arg (*args, vat_main_t *);
7909   vl_api_fib_path_t *path = va_arg (*args, vl_api_fib_path_t *);
7910   u32 weight, preference;
7911   mpls_label_t out_label;
7912
7913   clib_memset (path, 0, sizeof (*path));
7914   path->weight = 1;
7915   path->sw_if_index = ~0;
7916   path->rpf_id = ~0;
7917   path->n_labels = 0;
7918
7919   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7920     {
7921       if (unformat (input, "%U %U",
7922                     unformat_vl_api_ip4_address,
7923                     &path->nh.address.ip4,
7924                     api_unformat_sw_if_index, vam, &path->sw_if_index))
7925         {
7926           path->proto = FIB_API_PATH_NH_PROTO_IP4;
7927         }
7928       else if (unformat (input, "%U %U",
7929                          unformat_vl_api_ip6_address,
7930                          &path->nh.address.ip6,
7931                          api_unformat_sw_if_index, vam, &path->sw_if_index))
7932         {
7933           path->proto = FIB_API_PATH_NH_PROTO_IP6;
7934         }
7935       else if (unformat (input, "weight %u", &weight))
7936         {
7937           path->weight = weight;
7938         }
7939       else if (unformat (input, "preference %u", &preference))
7940         {
7941           path->preference = preference;
7942         }
7943       else if (unformat (input, "%U next-hop-table %d",
7944                          unformat_vl_api_ip4_address,
7945                          &path->nh.address.ip4, &path->table_id))
7946         {
7947           path->proto = FIB_API_PATH_NH_PROTO_IP4;
7948         }
7949       else if (unformat (input, "%U next-hop-table %d",
7950                          unformat_vl_api_ip6_address,
7951                          &path->nh.address.ip6, &path->table_id))
7952         {
7953           path->proto = FIB_API_PATH_NH_PROTO_IP6;
7954         }
7955       else if (unformat (input, "%U",
7956                          unformat_vl_api_ip4_address, &path->nh.address.ip4))
7957         {
7958           /*
7959            * the recursive next-hops are by default in the default table
7960            */
7961           path->table_id = 0;
7962           path->sw_if_index = ~0;
7963           path->proto = FIB_API_PATH_NH_PROTO_IP4;
7964         }
7965       else if (unformat (input, "%U",
7966                          unformat_vl_api_ip6_address, &path->nh.address.ip6))
7967         {
7968           /*
7969            * the recursive next-hops are by default in the default table
7970            */
7971           path->table_id = 0;
7972           path->sw_if_index = ~0;
7973           path->proto = FIB_API_PATH_NH_PROTO_IP6;
7974         }
7975       else if (unformat (input, "resolve-via-host"))
7976         {
7977           path->flags |= FIB_API_PATH_FLAG_RESOLVE_VIA_HOST;
7978         }
7979       else if (unformat (input, "resolve-via-attached"))
7980         {
7981           path->flags |= FIB_API_PATH_FLAG_RESOLVE_VIA_ATTACHED;
7982         }
7983       else if (unformat (input, "ip4-lookup-in-table %d", &path->table_id))
7984         {
7985           path->type = FIB_API_PATH_TYPE_LOCAL;
7986           path->sw_if_index = ~0;
7987           path->proto = FIB_API_PATH_NH_PROTO_IP4;
7988         }
7989       else if (unformat (input, "ip6-lookup-in-table %d", &path->table_id))
7990         {
7991           path->type = FIB_API_PATH_TYPE_LOCAL;
7992           path->sw_if_index = ~0;
7993           path->proto = FIB_API_PATH_NH_PROTO_IP6;
7994         }
7995       else if (unformat (input, "sw_if_index %d", &path->sw_if_index))
7996         ;
7997       else if (unformat (input, "via-label %d", &path->nh.via_label))
7998         {
7999           path->proto = FIB_API_PATH_NH_PROTO_MPLS;
8000           path->sw_if_index = ~0;
8001         }
8002       else if (unformat (input, "l2-input-on %d", &path->sw_if_index))
8003         {
8004           path->proto = FIB_API_PATH_NH_PROTO_ETHERNET;
8005           path->type = FIB_API_PATH_TYPE_INTERFACE_RX;
8006         }
8007       else if (unformat (input, "local"))
8008         {
8009           path->type = FIB_API_PATH_TYPE_LOCAL;
8010         }
8011       else if (unformat (input, "out-labels"))
8012         {
8013           while (unformat (input, "%d", &out_label))
8014             {
8015               path->label_stack[path->n_labels].label = out_label;
8016               path->label_stack[path->n_labels].is_uniform = 0;
8017               path->label_stack[path->n_labels].ttl = 64;
8018               path->n_labels++;
8019             }
8020         }
8021       else if (unformat (input, "via"))
8022         {
8023           /* new path, back up and return */
8024           unformat_put_input (input);
8025           unformat_put_input (input);
8026           unformat_put_input (input);
8027           unformat_put_input (input);
8028           break;
8029         }
8030       else
8031         {
8032           return (0);
8033         }
8034     }
8035
8036   path->proto = ntohl (path->proto);
8037   path->type = ntohl (path->type);
8038   path->flags = ntohl (path->flags);
8039   path->table_id = ntohl (path->table_id);
8040   path->sw_if_index = ntohl (path->sw_if_index);
8041
8042   return (1);
8043 }
8044
8045 static int
8046 api_ip_route_add_del (vat_main_t * vam)
8047 {
8048   unformat_input_t *i = vam->input;
8049   vl_api_ip_route_add_del_t *mp;
8050   u32 vrf_id = 0;
8051   u8 is_add = 1;
8052   u8 is_multipath = 0;
8053   u8 prefix_set = 0;
8054   u8 path_count = 0;
8055   vl_api_prefix_t pfx = { };
8056   vl_api_fib_path_t paths[8];
8057   int count = 1;
8058   int j;
8059   f64 before = 0;
8060   u32 random_add_del = 0;
8061   u32 *random_vector = 0;
8062   u32 random_seed = 0xdeaddabe;
8063
8064   /* Parse args required to build the message */
8065   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8066     {
8067       if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
8068         prefix_set = 1;
8069       else if (unformat (i, "del"))
8070         is_add = 0;
8071       else if (unformat (i, "add"))
8072         is_add = 1;
8073       else if (unformat (i, "vrf %d", &vrf_id))
8074         ;
8075       else if (unformat (i, "count %d", &count))
8076         ;
8077       else if (unformat (i, "random"))
8078         random_add_del = 1;
8079       else if (unformat (i, "multipath"))
8080         is_multipath = 1;
8081       else if (unformat (i, "seed %d", &random_seed))
8082         ;
8083       else
8084         if (unformat
8085             (i, "via %U", unformat_fib_path, vam, &paths[path_count]))
8086         {
8087           path_count++;
8088           if (8 == path_count)
8089             {
8090               errmsg ("max 8 paths");
8091               return -99;
8092             }
8093         }
8094       else
8095         {
8096           clib_warning ("parse error '%U'", format_unformat_error, i);
8097           return -99;
8098         }
8099     }
8100
8101   if (!path_count)
8102     {
8103       errmsg ("specify a path; via ...");
8104       return -99;
8105     }
8106   if (prefix_set == 0)
8107     {
8108       errmsg ("missing prefix");
8109       return -99;
8110     }
8111
8112   /* Generate a pile of unique, random routes */
8113   if (random_add_del)
8114     {
8115       ip4_address_t *i = (ip4_address_t *) & paths[0].nh.address.ip4;
8116       u32 this_random_address;
8117       uword *random_hash;
8118
8119       random_hash = hash_create (count, sizeof (uword));
8120
8121       hash_set (random_hash, i->as_u32, 1);
8122       for (j = 0; j <= count; j++)
8123         {
8124           do
8125             {
8126               this_random_address = random_u32 (&random_seed);
8127               this_random_address =
8128                 clib_host_to_net_u32 (this_random_address);
8129             }
8130           while (hash_get (random_hash, this_random_address));
8131           vec_add1 (random_vector, this_random_address);
8132           hash_set (random_hash, this_random_address, 1);
8133         }
8134       hash_free (random_hash);
8135       set_ip4_address (&pfx.address, random_vector[0]);
8136     }
8137
8138   if (count > 1)
8139     {
8140       /* Turn on async mode */
8141       vam->async_mode = 1;
8142       vam->async_errors = 0;
8143       before = vat_time_now (vam);
8144     }
8145
8146   for (j = 0; j < count; j++)
8147     {
8148       /* Construct the API message */
8149       M2 (IP_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t) * path_count);
8150
8151       mp->is_add = is_add;
8152       mp->is_multipath = is_multipath;
8153
8154       clib_memcpy (&mp->route.prefix, &pfx, sizeof (pfx));
8155       mp->route.table_id = ntohl (vrf_id);
8156       mp->route.n_paths = path_count;
8157
8158       clib_memcpy (&mp->route.paths, &paths, sizeof (paths[0]) * path_count);
8159
8160       if (random_add_del)
8161         set_ip4_address (&pfx.address, random_vector[j + 1]);
8162       else
8163         increment_address (&pfx.address);
8164       /* send it... */
8165       S (mp);
8166       /* If we receive SIGTERM, stop now... */
8167       if (vam->do_exit)
8168         break;
8169     }
8170
8171   /* When testing multiple add/del ops, use a control-ping to sync */
8172   if (count > 1)
8173     {
8174       vl_api_control_ping_t *mp_ping;
8175       f64 after;
8176       f64 timeout;
8177
8178       /* Shut off async mode */
8179       vam->async_mode = 0;
8180
8181       MPING (CONTROL_PING, mp_ping);
8182       S (mp_ping);
8183
8184       timeout = vat_time_now (vam) + 1.0;
8185       while (vat_time_now (vam) < timeout)
8186         if (vam->result_ready == 1)
8187           goto out;
8188       vam->retval = -99;
8189
8190     out:
8191       if (vam->retval == -99)
8192         errmsg ("timeout");
8193
8194       if (vam->async_errors > 0)
8195         {
8196           errmsg ("%d asynchronous errors", vam->async_errors);
8197           vam->retval = -98;
8198         }
8199       vam->async_errors = 0;
8200       after = vat_time_now (vam);
8201
8202       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8203       if (j > 0)
8204         count = j;
8205
8206       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8207              count, after - before, count / (after - before));
8208     }
8209   else
8210     {
8211       int ret;
8212
8213       /* Wait for a reply... */
8214       W (ret);
8215       return ret;
8216     }
8217
8218   /* Return the good/bad news */
8219   return (vam->retval);
8220 }
8221
8222 static int
8223 api_ip_mroute_add_del (vat_main_t * vam)
8224 {
8225   unformat_input_t *i = vam->input;
8226   u8 path_set = 0, prefix_set = 0, is_add = 1;
8227   vl_api_ip_mroute_add_del_t *mp;
8228   mfib_entry_flags_t eflags = 0;
8229   vl_api_mfib_path_t path;
8230   vl_api_mprefix_t pfx = { };
8231   u32 vrf_id = 0;
8232   int ret;
8233
8234   /* Parse args required to build the message */
8235   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8236     {
8237       if (unformat (i, "%U", unformat_vl_api_mprefix, &pfx))
8238         {
8239           prefix_set = 1;
8240           pfx.grp_address_length = htons (pfx.grp_address_length);
8241         }
8242       else if (unformat (i, "del"))
8243         is_add = 0;
8244       else if (unformat (i, "add"))
8245         is_add = 1;
8246       else if (unformat (i, "vrf %d", &vrf_id))
8247         ;
8248       else if (unformat (i, "%U", unformat_mfib_itf_flags, &path.itf_flags))
8249         path.itf_flags = htonl (path.itf_flags);
8250       else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
8251         ;
8252       else if (unformat (i, "via %U", unformat_fib_path, vam, &path.path))
8253         path_set = 1;
8254       else
8255         {
8256           clib_warning ("parse error '%U'", format_unformat_error, i);
8257           return -99;
8258         }
8259     }
8260
8261   if (prefix_set == 0)
8262     {
8263       errmsg ("missing addresses\n");
8264       return -99;
8265     }
8266   if (path_set == 0)
8267     {
8268       errmsg ("missing path\n");
8269       return -99;
8270     }
8271
8272   /* Construct the API message */
8273   M (IP_MROUTE_ADD_DEL, mp);
8274
8275   mp->is_add = is_add;
8276   mp->is_multipath = 1;
8277
8278   clib_memcpy (&mp->route.prefix, &pfx, sizeof (pfx));
8279   mp->route.table_id = htonl (vrf_id);
8280   mp->route.n_paths = 1;
8281   mp->route.entry_flags = htonl (eflags);
8282
8283   clib_memcpy (&mp->route.paths, &path, sizeof (path));
8284
8285   /* send it... */
8286   S (mp);
8287   /* Wait for a reply... */
8288   W (ret);
8289   return ret;
8290 }
8291
8292 static int
8293 api_mpls_table_add_del (vat_main_t * vam)
8294 {
8295   unformat_input_t *i = vam->input;
8296   vl_api_mpls_table_add_del_t *mp;
8297   u32 table_id = ~0;
8298   u8 is_add = 1;
8299   int ret = 0;
8300
8301   /* Parse args required to build the message */
8302   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8303     {
8304       if (unformat (i, "table %d", &table_id))
8305         ;
8306       else if (unformat (i, "del"))
8307         is_add = 0;
8308       else if (unformat (i, "add"))
8309         is_add = 1;
8310       else
8311         {
8312           clib_warning ("parse error '%U'", format_unformat_error, i);
8313           return -99;
8314         }
8315     }
8316
8317   if (~0 == table_id)
8318     {
8319       errmsg ("missing table-ID");
8320       return -99;
8321     }
8322
8323   /* Construct the API message */
8324   M (MPLS_TABLE_ADD_DEL, mp);
8325
8326   mp->mt_table.mt_table_id = ntohl (table_id);
8327   mp->mt_is_add = is_add;
8328
8329   /* send it... */
8330   S (mp);
8331
8332   /* Wait for a reply... */
8333   W (ret);
8334
8335   return ret;
8336 }
8337
8338 static int
8339 api_mpls_route_add_del (vat_main_t * vam)
8340 {
8341   u8 is_add = 1, path_count = 0, is_multipath = 0, is_eos = 0;
8342   mpls_label_t local_label = MPLS_LABEL_INVALID;
8343   unformat_input_t *i = vam->input;
8344   vl_api_mpls_route_add_del_t *mp;
8345   vl_api_fib_path_t paths[8];
8346   int count = 1, j;
8347   f64 before = 0;
8348
8349   /* Parse args required to build the message */
8350   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8351     {
8352       if (unformat (i, "%d", &local_label))
8353         ;
8354       else if (unformat (i, "eos"))
8355         is_eos = 1;
8356       else if (unformat (i, "non-eos"))
8357         is_eos = 0;
8358       else if (unformat (i, "del"))
8359         is_add = 0;
8360       else if (unformat (i, "add"))
8361         is_add = 1;
8362       else if (unformat (i, "multipath"))
8363         is_multipath = 1;
8364       else if (unformat (i, "count %d", &count))
8365         ;
8366       else
8367         if (unformat
8368             (i, "via %U", unformat_fib_path, vam, &paths[path_count]))
8369         {
8370           path_count++;
8371           if (8 == path_count)
8372             {
8373               errmsg ("max 8 paths");
8374               return -99;
8375             }
8376         }
8377       else
8378         {
8379           clib_warning ("parse error '%U'", format_unformat_error, i);
8380           return -99;
8381         }
8382     }
8383
8384   if (!path_count)
8385     {
8386       errmsg ("specify a path; via ...");
8387       return -99;
8388     }
8389
8390   if (MPLS_LABEL_INVALID == local_label)
8391     {
8392       errmsg ("missing label");
8393       return -99;
8394     }
8395
8396   if (count > 1)
8397     {
8398       /* Turn on async mode */
8399       vam->async_mode = 1;
8400       vam->async_errors = 0;
8401       before = vat_time_now (vam);
8402     }
8403
8404   for (j = 0; j < count; j++)
8405     {
8406       /* Construct the API message */
8407       M2 (MPLS_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t) * path_count);
8408
8409       mp->mr_is_add = is_add;
8410       mp->mr_is_multipath = is_multipath;
8411
8412       mp->mr_route.mr_label = local_label;
8413       mp->mr_route.mr_eos = is_eos;
8414       mp->mr_route.mr_table_id = 0;
8415       mp->mr_route.mr_n_paths = path_count;
8416
8417       clib_memcpy (&mp->mr_route.mr_paths, paths,
8418                    sizeof (paths[0]) * path_count);
8419
8420       local_label++;
8421
8422       /* send it... */
8423       S (mp);
8424       /* If we receive SIGTERM, stop now... */
8425       if (vam->do_exit)
8426         break;
8427     }
8428
8429   /* When testing multiple add/del ops, use a control-ping to sync */
8430   if (count > 1)
8431     {
8432       vl_api_control_ping_t *mp_ping;
8433       f64 after;
8434       f64 timeout;
8435
8436       /* Shut off async mode */
8437       vam->async_mode = 0;
8438
8439       MPING (CONTROL_PING, mp_ping);
8440       S (mp_ping);
8441
8442       timeout = vat_time_now (vam) + 1.0;
8443       while (vat_time_now (vam) < timeout)
8444         if (vam->result_ready == 1)
8445           goto out;
8446       vam->retval = -99;
8447
8448     out:
8449       if (vam->retval == -99)
8450         errmsg ("timeout");
8451
8452       if (vam->async_errors > 0)
8453         {
8454           errmsg ("%d asynchronous errors", vam->async_errors);
8455           vam->retval = -98;
8456         }
8457       vam->async_errors = 0;
8458       after = vat_time_now (vam);
8459
8460       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8461       if (j > 0)
8462         count = j;
8463
8464       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8465              count, after - before, count / (after - before));
8466     }
8467   else
8468     {
8469       int ret;
8470
8471       /* Wait for a reply... */
8472       W (ret);
8473       return ret;
8474     }
8475
8476   /* Return the good/bad news */
8477   return (vam->retval);
8478   return (0);
8479 }
8480
8481 static int
8482 api_mpls_ip_bind_unbind (vat_main_t * vam)
8483 {
8484   unformat_input_t *i = vam->input;
8485   vl_api_mpls_ip_bind_unbind_t *mp;
8486   u32 ip_table_id = 0;
8487   u8 is_bind = 1;
8488   vl_api_prefix_t pfx;
8489   u8 prefix_set = 0;
8490   mpls_label_t local_label = MPLS_LABEL_INVALID;
8491   int ret;
8492
8493   /* Parse args required to build the message */
8494   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8495     {
8496       if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
8497         prefix_set = 1;
8498       else if (unformat (i, "%d", &local_label))
8499         ;
8500       else if (unformat (i, "table-id %d", &ip_table_id))
8501         ;
8502       else if (unformat (i, "unbind"))
8503         is_bind = 0;
8504       else if (unformat (i, "bind"))
8505         is_bind = 1;
8506       else
8507         {
8508           clib_warning ("parse error '%U'", format_unformat_error, i);
8509           return -99;
8510         }
8511     }
8512
8513   if (!prefix_set)
8514     {
8515       errmsg ("IP prefix not set");
8516       return -99;
8517     }
8518
8519   if (MPLS_LABEL_INVALID == local_label)
8520     {
8521       errmsg ("missing label");
8522       return -99;
8523     }
8524
8525   /* Construct the API message */
8526   M (MPLS_IP_BIND_UNBIND, mp);
8527
8528   mp->mb_is_bind = is_bind;
8529   mp->mb_ip_table_id = ntohl (ip_table_id);
8530   mp->mb_mpls_table_id = 0;
8531   mp->mb_label = ntohl (local_label);
8532   clib_memcpy (&mp->mb_prefix, &pfx, sizeof (pfx));
8533
8534   /* send it... */
8535   S (mp);
8536
8537   /* Wait for a reply... */
8538   W (ret);
8539   return ret;
8540   return (0);
8541 }
8542
8543 static int
8544 api_sr_mpls_policy_add (vat_main_t * vam)
8545 {
8546   unformat_input_t *i = vam->input;
8547   vl_api_sr_mpls_policy_add_t *mp;
8548   u32 bsid = 0;
8549   u32 weight = 1;
8550   u8 type = 0;
8551   u8 n_segments = 0;
8552   u32 sid;
8553   u32 *segments = NULL;
8554   int ret;
8555
8556   /* Parse args required to build the message */
8557   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8558     {
8559       if (unformat (i, "bsid %d", &bsid))
8560         ;
8561       else if (unformat (i, "weight %d", &weight))
8562         ;
8563       else if (unformat (i, "spray"))
8564         type = 1;
8565       else if (unformat (i, "next %d", &sid))
8566         {
8567           n_segments += 1;
8568           vec_add1 (segments, htonl (sid));
8569         }
8570       else
8571         {
8572           clib_warning ("parse error '%U'", format_unformat_error, i);
8573           return -99;
8574         }
8575     }
8576
8577   if (bsid == 0)
8578     {
8579       errmsg ("bsid not set");
8580       return -99;
8581     }
8582
8583   if (n_segments == 0)
8584     {
8585       errmsg ("no sid in segment stack");
8586       return -99;
8587     }
8588
8589   /* Construct the API message */
8590   M2 (SR_MPLS_POLICY_ADD, mp, sizeof (u32) * n_segments);
8591
8592   mp->bsid = htonl (bsid);
8593   mp->weight = htonl (weight);
8594   mp->type = type;
8595   mp->n_segments = n_segments;
8596   memcpy (mp->segments, segments, sizeof (u32) * n_segments);
8597   vec_free (segments);
8598
8599   /* send it... */
8600   S (mp);
8601
8602   /* Wait for a reply... */
8603   W (ret);
8604   return ret;
8605 }
8606
8607 static int
8608 api_sr_mpls_policy_del (vat_main_t * vam)
8609 {
8610   unformat_input_t *i = vam->input;
8611   vl_api_sr_mpls_policy_del_t *mp;
8612   u32 bsid = 0;
8613   int ret;
8614
8615   /* Parse args required to build the message */
8616   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8617     {
8618       if (unformat (i, "bsid %d", &bsid))
8619         ;
8620       else
8621         {
8622           clib_warning ("parse error '%U'", format_unformat_error, i);
8623           return -99;
8624         }
8625     }
8626
8627   if (bsid == 0)
8628     {
8629       errmsg ("bsid not set");
8630       return -99;
8631     }
8632
8633   /* Construct the API message */
8634   M (SR_MPLS_POLICY_DEL, mp);
8635
8636   mp->bsid = htonl (bsid);
8637
8638   /* send it... */
8639   S (mp);
8640
8641   /* Wait for a reply... */
8642   W (ret);
8643   return ret;
8644 }
8645
8646 static int
8647 api_bier_table_add_del (vat_main_t * vam)
8648 {
8649   unformat_input_t *i = vam->input;
8650   vl_api_bier_table_add_del_t *mp;
8651   u8 is_add = 1;
8652   u32 set = 0, sub_domain = 0, hdr_len = 3;
8653   mpls_label_t local_label = MPLS_LABEL_INVALID;
8654   int ret;
8655
8656   /* Parse args required to build the message */
8657   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8658     {
8659       if (unformat (i, "sub-domain %d", &sub_domain))
8660         ;
8661       else if (unformat (i, "set %d", &set))
8662         ;
8663       else if (unformat (i, "label %d", &local_label))
8664         ;
8665       else if (unformat (i, "hdr-len %d", &hdr_len))
8666         ;
8667       else if (unformat (i, "add"))
8668         is_add = 1;
8669       else if (unformat (i, "del"))
8670         is_add = 0;
8671       else
8672         {
8673           clib_warning ("parse error '%U'", format_unformat_error, i);
8674           return -99;
8675         }
8676     }
8677
8678   if (MPLS_LABEL_INVALID == local_label)
8679     {
8680       errmsg ("missing label\n");
8681       return -99;
8682     }
8683
8684   /* Construct the API message */
8685   M (BIER_TABLE_ADD_DEL, mp);
8686
8687   mp->bt_is_add = is_add;
8688   mp->bt_label = ntohl (local_label);
8689   mp->bt_tbl_id.bt_set = set;
8690   mp->bt_tbl_id.bt_sub_domain = sub_domain;
8691   mp->bt_tbl_id.bt_hdr_len_id = hdr_len;
8692
8693   /* send it... */
8694   S (mp);
8695
8696   /* Wait for a reply... */
8697   W (ret);
8698
8699   return (ret);
8700 }
8701
8702 static int
8703 api_bier_route_add_del (vat_main_t * vam)
8704 {
8705   unformat_input_t *i = vam->input;
8706   vl_api_bier_route_add_del_t *mp;
8707   u8 is_add = 1;
8708   u32 set = 0, sub_domain = 0, hdr_len = 3, bp = 0;
8709   ip4_address_t v4_next_hop_address;
8710   ip6_address_t v6_next_hop_address;
8711   u8 next_hop_set = 0;
8712   u8 next_hop_proto_is_ip4 = 1;
8713   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8714   int ret;
8715
8716   /* Parse args required to build the message */
8717   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8718     {
8719       if (unformat (i, "%U", unformat_ip4_address, &v4_next_hop_address))
8720         {
8721           next_hop_proto_is_ip4 = 1;
8722           next_hop_set = 1;
8723         }
8724       else if (unformat (i, "%U", unformat_ip6_address, &v6_next_hop_address))
8725         {
8726           next_hop_proto_is_ip4 = 0;
8727           next_hop_set = 1;
8728         }
8729       if (unformat (i, "sub-domain %d", &sub_domain))
8730         ;
8731       else if (unformat (i, "set %d", &set))
8732         ;
8733       else if (unformat (i, "hdr-len %d", &hdr_len))
8734         ;
8735       else if (unformat (i, "bp %d", &bp))
8736         ;
8737       else if (unformat (i, "add"))
8738         is_add = 1;
8739       else if (unformat (i, "del"))
8740         is_add = 0;
8741       else if (unformat (i, "out-label %d", &next_hop_out_label))
8742         ;
8743       else
8744         {
8745           clib_warning ("parse error '%U'", format_unformat_error, i);
8746           return -99;
8747         }
8748     }
8749
8750   if (!next_hop_set || (MPLS_LABEL_INVALID == next_hop_out_label))
8751     {
8752       errmsg ("next hop / label set\n");
8753       return -99;
8754     }
8755   if (0 == bp)
8756     {
8757       errmsg ("bit=position not set\n");
8758       return -99;
8759     }
8760
8761   /* Construct the API message */
8762   M2 (BIER_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t));
8763
8764   mp->br_is_add = is_add;
8765   mp->br_route.br_tbl_id.bt_set = set;
8766   mp->br_route.br_tbl_id.bt_sub_domain = sub_domain;
8767   mp->br_route.br_tbl_id.bt_hdr_len_id = hdr_len;
8768   mp->br_route.br_bp = ntohs (bp);
8769   mp->br_route.br_n_paths = 1;
8770   mp->br_route.br_paths[0].n_labels = 1;
8771   mp->br_route.br_paths[0].label_stack[0].label = ntohl (next_hop_out_label);
8772   mp->br_route.br_paths[0].proto = (next_hop_proto_is_ip4 ?
8773                                     FIB_API_PATH_NH_PROTO_IP4 :
8774                                     FIB_API_PATH_NH_PROTO_IP6);
8775
8776   if (next_hop_proto_is_ip4)
8777     {
8778       clib_memcpy (&mp->br_route.br_paths[0].nh.address.ip4,
8779                    &v4_next_hop_address, sizeof (v4_next_hop_address));
8780     }
8781   else
8782     {
8783       clib_memcpy (&mp->br_route.br_paths[0].nh.address.ip6,
8784                    &v6_next_hop_address, sizeof (v6_next_hop_address));
8785     }
8786
8787   /* send it... */
8788   S (mp);
8789
8790   /* Wait for a reply... */
8791   W (ret);
8792
8793   return (ret);
8794 }
8795
8796 static int
8797 api_proxy_arp_add_del (vat_main_t * vam)
8798 {
8799   unformat_input_t *i = vam->input;
8800   vl_api_proxy_arp_add_del_t *mp;
8801   u32 vrf_id = 0;
8802   u8 is_add = 1;
8803   vl_api_ip4_address_t lo, hi;
8804   u8 range_set = 0;
8805   int ret;
8806
8807   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8808     {
8809       if (unformat (i, "vrf %d", &vrf_id))
8810         ;
8811       else if (unformat (i, "%U - %U", unformat_vl_api_ip4_address, &lo,
8812                          unformat_vl_api_ip4_address, &hi))
8813         range_set = 1;
8814       else if (unformat (i, "del"))
8815         is_add = 0;
8816       else
8817         {
8818           clib_warning ("parse error '%U'", format_unformat_error, i);
8819           return -99;
8820         }
8821     }
8822
8823   if (range_set == 0)
8824     {
8825       errmsg ("address range not set");
8826       return -99;
8827     }
8828
8829   M (PROXY_ARP_ADD_DEL, mp);
8830
8831   mp->proxy.table_id = ntohl (vrf_id);
8832   mp->is_add = is_add;
8833   clib_memcpy (mp->proxy.low, &lo, sizeof (lo));
8834   clib_memcpy (mp->proxy.hi, &hi, sizeof (hi));
8835
8836   S (mp);
8837   W (ret);
8838   return ret;
8839 }
8840
8841 static int
8842 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
8843 {
8844   unformat_input_t *i = vam->input;
8845   vl_api_proxy_arp_intfc_enable_disable_t *mp;
8846   u32 sw_if_index;
8847   u8 enable = 1;
8848   u8 sw_if_index_set = 0;
8849   int ret;
8850
8851   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8852     {
8853       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8854         sw_if_index_set = 1;
8855       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8856         sw_if_index_set = 1;
8857       else if (unformat (i, "enable"))
8858         enable = 1;
8859       else if (unformat (i, "disable"))
8860         enable = 0;
8861       else
8862         {
8863           clib_warning ("parse error '%U'", format_unformat_error, i);
8864           return -99;
8865         }
8866     }
8867
8868   if (sw_if_index_set == 0)
8869     {
8870       errmsg ("missing interface name or sw_if_index");
8871       return -99;
8872     }
8873
8874   M (PROXY_ARP_INTFC_ENABLE_DISABLE, mp);
8875
8876   mp->sw_if_index = ntohl (sw_if_index);
8877   mp->enable_disable = enable;
8878
8879   S (mp);
8880   W (ret);
8881   return ret;
8882 }
8883
8884 static int
8885 api_mpls_tunnel_add_del (vat_main_t * vam)
8886 {
8887   unformat_input_t *i = vam->input;
8888   vl_api_mpls_tunnel_add_del_t *mp;
8889
8890   vl_api_fib_path_t paths[8];
8891   u32 sw_if_index = ~0;
8892   u8 path_count = 0;
8893   u8 l2_only = 0;
8894   u8 is_add = 1;
8895   int ret;
8896
8897   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8898     {
8899       if (unformat (i, "add"))
8900         is_add = 1;
8901       else
8902         if (unformat
8903             (i, "del %U", api_unformat_sw_if_index, vam, &sw_if_index))
8904         is_add = 0;
8905       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
8906         is_add = 0;
8907       else if (unformat (i, "l2-only"))
8908         l2_only = 1;
8909       else
8910         if (unformat
8911             (i, "via %U", unformat_fib_path, vam, &paths[path_count]))
8912         {
8913           path_count++;
8914           if (8 == path_count)
8915             {
8916               errmsg ("max 8 paths");
8917               return -99;
8918             }
8919         }
8920       else
8921         {
8922           clib_warning ("parse error '%U'", format_unformat_error, i);
8923           return -99;
8924         }
8925     }
8926
8927   M2 (MPLS_TUNNEL_ADD_DEL, mp, sizeof (vl_api_fib_path_t) * path_count);
8928
8929   mp->mt_is_add = is_add;
8930   mp->mt_tunnel.mt_sw_if_index = ntohl (sw_if_index);
8931   mp->mt_tunnel.mt_l2_only = l2_only;
8932   mp->mt_tunnel.mt_is_multicast = 0;
8933   mp->mt_tunnel.mt_n_paths = path_count;
8934
8935   clib_memcpy (&mp->mt_tunnel.mt_paths, &paths,
8936                sizeof (paths[0]) * path_count);
8937
8938   S (mp);
8939   W (ret);
8940   return ret;
8941 }
8942
8943 static int
8944 api_sw_interface_set_unnumbered (vat_main_t * vam)
8945 {
8946   unformat_input_t *i = vam->input;
8947   vl_api_sw_interface_set_unnumbered_t *mp;
8948   u32 sw_if_index;
8949   u32 unnum_sw_index = ~0;
8950   u8 is_add = 1;
8951   u8 sw_if_index_set = 0;
8952   int ret;
8953
8954   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8955     {
8956       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8957         sw_if_index_set = 1;
8958       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8959         sw_if_index_set = 1;
8960       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
8961         ;
8962       else if (unformat (i, "del"))
8963         is_add = 0;
8964       else
8965         {
8966           clib_warning ("parse error '%U'", format_unformat_error, i);
8967           return -99;
8968         }
8969     }
8970
8971   if (sw_if_index_set == 0)
8972     {
8973       errmsg ("missing interface name or sw_if_index");
8974       return -99;
8975     }
8976
8977   M (SW_INTERFACE_SET_UNNUMBERED, mp);
8978
8979   mp->sw_if_index = ntohl (sw_if_index);
8980   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
8981   mp->is_add = is_add;
8982
8983   S (mp);
8984   W (ret);
8985   return ret;
8986 }
8987
8988 static int
8989 api_ip_neighbor_add_del (vat_main_t * vam)
8990 {
8991   vl_api_mac_address_t mac_address;
8992   unformat_input_t *i = vam->input;
8993   vl_api_ip_neighbor_add_del_t *mp;
8994   vl_api_address_t ip_address;
8995   u32 sw_if_index;
8996   u8 sw_if_index_set = 0;
8997   u8 is_add = 1;
8998   u8 mac_set = 0;
8999   u8 address_set = 0;
9000   int ret;
9001   ip_neighbor_flags_t flags;
9002
9003   flags = IP_NEIGHBOR_FLAG_NONE;
9004   clib_memset (&ip_address, 0, sizeof (ip_address));
9005   clib_memset (&mac_address, 0, sizeof (mac_address));
9006
9007   /* Parse args required to build the message */
9008   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9009     {
9010       if (unformat (i, "mac %U", unformat_vl_api_mac_address, &mac_address))
9011         {
9012           mac_set = 1;
9013         }
9014       else if (unformat (i, "del"))
9015         is_add = 0;
9016       else
9017         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9018         sw_if_index_set = 1;
9019       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9020         sw_if_index_set = 1;
9021       else if (unformat (i, "static"))
9022         flags |= IP_NEIGHBOR_FLAG_STATIC;
9023       else if (unformat (i, "no-fib-entry"))
9024         flags |= IP_NEIGHBOR_FLAG_NO_FIB_ENTRY;
9025       else if (unformat (i, "dst %U", unformat_vl_api_address, &ip_address))
9026         address_set = 1;
9027       else
9028         {
9029           clib_warning ("parse error '%U'", format_unformat_error, i);
9030           return -99;
9031         }
9032     }
9033
9034   if (sw_if_index_set == 0)
9035     {
9036       errmsg ("missing interface name or sw_if_index");
9037       return -99;
9038     }
9039   if (!address_set)
9040     {
9041       errmsg ("no address set");
9042       return -99;
9043     }
9044
9045   /* Construct the API message */
9046   M (IP_NEIGHBOR_ADD_DEL, mp);
9047
9048   mp->neighbor.sw_if_index = ntohl (sw_if_index);
9049   mp->is_add = is_add;
9050   mp->neighbor.flags = htonl (flags);
9051   if (mac_set)
9052     clib_memcpy (&mp->neighbor.mac_address, &mac_address,
9053                  sizeof (mac_address));
9054   if (address_set)
9055     clib_memcpy (&mp->neighbor.ip_address, &ip_address, sizeof (ip_address));
9056
9057   /* send it... */
9058   S (mp);
9059
9060   /* Wait for a reply, return good/bad news  */
9061   W (ret);
9062   return ret;
9063 }
9064
9065 static int
9066 api_create_vlan_subif (vat_main_t * vam)
9067 {
9068   unformat_input_t *i = vam->input;
9069   vl_api_create_vlan_subif_t *mp;
9070   u32 sw_if_index;
9071   u8 sw_if_index_set = 0;
9072   u32 vlan_id;
9073   u8 vlan_id_set = 0;
9074   int ret;
9075
9076   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9077     {
9078       if (unformat (i, "sw_if_index %d", &sw_if_index))
9079         sw_if_index_set = 1;
9080       else
9081         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9082         sw_if_index_set = 1;
9083       else if (unformat (i, "vlan %d", &vlan_id))
9084         vlan_id_set = 1;
9085       else
9086         {
9087           clib_warning ("parse error '%U'", format_unformat_error, i);
9088           return -99;
9089         }
9090     }
9091
9092   if (sw_if_index_set == 0)
9093     {
9094       errmsg ("missing interface name or sw_if_index");
9095       return -99;
9096     }
9097
9098   if (vlan_id_set == 0)
9099     {
9100       errmsg ("missing vlan_id");
9101       return -99;
9102     }
9103   M (CREATE_VLAN_SUBIF, mp);
9104
9105   mp->sw_if_index = ntohl (sw_if_index);
9106   mp->vlan_id = ntohl (vlan_id);
9107
9108   S (mp);
9109   W (ret);
9110   return ret;
9111 }
9112
9113 #define foreach_create_subif_bit                \
9114 _(no_tags)                                      \
9115 _(one_tag)                                      \
9116 _(two_tags)                                     \
9117 _(dot1ad)                                       \
9118 _(exact_match)                                  \
9119 _(default_sub)                                  \
9120 _(outer_vlan_id_any)                            \
9121 _(inner_vlan_id_any)
9122
9123 #define foreach_create_subif_flag               \
9124 _(0, "no_tags")                                 \
9125 _(1, "one_tag")                                 \
9126 _(2, "two_tags")                                \
9127 _(3, "dot1ad")                                  \
9128 _(4, "exact_match")                             \
9129 _(5, "default_sub")                             \
9130 _(6, "outer_vlan_id_any")                       \
9131 _(7, "inner_vlan_id_any")
9132
9133 static int
9134 api_create_subif (vat_main_t * vam)
9135 {
9136   unformat_input_t *i = vam->input;
9137   vl_api_create_subif_t *mp;
9138   u32 sw_if_index;
9139   u8 sw_if_index_set = 0;
9140   u32 sub_id;
9141   u8 sub_id_set = 0;
9142   u32 __attribute__ ((unused)) no_tags = 0;
9143   u32 __attribute__ ((unused)) one_tag = 0;
9144   u32 __attribute__ ((unused)) two_tags = 0;
9145   u32 __attribute__ ((unused)) dot1ad = 0;
9146   u32 __attribute__ ((unused)) exact_match = 0;
9147   u32 __attribute__ ((unused)) default_sub = 0;
9148   u32 __attribute__ ((unused)) outer_vlan_id_any = 0;
9149   u32 __attribute__ ((unused)) inner_vlan_id_any = 0;
9150   u32 tmp;
9151   u16 outer_vlan_id = 0;
9152   u16 inner_vlan_id = 0;
9153   int ret;
9154
9155   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9156     {
9157       if (unformat (i, "sw_if_index %d", &sw_if_index))
9158         sw_if_index_set = 1;
9159       else
9160         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9161         sw_if_index_set = 1;
9162       else if (unformat (i, "sub_id %d", &sub_id))
9163         sub_id_set = 1;
9164       else if (unformat (i, "outer_vlan_id %d", &tmp))
9165         outer_vlan_id = tmp;
9166       else if (unformat (i, "inner_vlan_id %d", &tmp))
9167         inner_vlan_id = tmp;
9168
9169 #define _(a) else if (unformat (i, #a)) a = 1 ;
9170       foreach_create_subif_bit
9171 #undef _
9172         else
9173         {
9174           clib_warning ("parse error '%U'", format_unformat_error, i);
9175           return -99;
9176         }
9177     }
9178
9179   if (sw_if_index_set == 0)
9180     {
9181       errmsg ("missing interface name or sw_if_index");
9182       return -99;
9183     }
9184
9185   if (sub_id_set == 0)
9186     {
9187       errmsg ("missing sub_id");
9188       return -99;
9189     }
9190   M (CREATE_SUBIF, mp);
9191
9192   mp->sw_if_index = ntohl (sw_if_index);
9193   mp->sub_id = ntohl (sub_id);
9194
9195 #define _(a,b) mp->sub_if_flags |= (1 << a);
9196   foreach_create_subif_flag;
9197 #undef _
9198
9199   mp->outer_vlan_id = ntohs (outer_vlan_id);
9200   mp->inner_vlan_id = ntohs (inner_vlan_id);
9201
9202   S (mp);
9203   W (ret);
9204   return ret;
9205 }
9206
9207 static int
9208 api_ip_table_replace_begin (vat_main_t * vam)
9209 {
9210   unformat_input_t *i = vam->input;
9211   vl_api_ip_table_replace_begin_t *mp;
9212   u32 table_id = 0;
9213   u8 is_ipv6 = 0;
9214
9215   int ret;
9216   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9217     {
9218       if (unformat (i, "table %d", &table_id))
9219         ;
9220       else if (unformat (i, "ipv6"))
9221         is_ipv6 = 1;
9222       else
9223         {
9224           clib_warning ("parse error '%U'", format_unformat_error, i);
9225           return -99;
9226         }
9227     }
9228
9229   M (IP_TABLE_REPLACE_BEGIN, mp);
9230
9231   mp->table.table_id = ntohl (table_id);
9232   mp->table.is_ip6 = is_ipv6;
9233
9234   S (mp);
9235   W (ret);
9236   return ret;
9237 }
9238
9239 static int
9240 api_ip_table_flush (vat_main_t * vam)
9241 {
9242   unformat_input_t *i = vam->input;
9243   vl_api_ip_table_flush_t *mp;
9244   u32 table_id = 0;
9245   u8 is_ipv6 = 0;
9246
9247   int ret;
9248   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9249     {
9250       if (unformat (i, "table %d", &table_id))
9251         ;
9252       else if (unformat (i, "ipv6"))
9253         is_ipv6 = 1;
9254       else
9255         {
9256           clib_warning ("parse error '%U'", format_unformat_error, i);
9257           return -99;
9258         }
9259     }
9260
9261   M (IP_TABLE_FLUSH, mp);
9262
9263   mp->table.table_id = ntohl (table_id);
9264   mp->table.is_ip6 = is_ipv6;
9265
9266   S (mp);
9267   W (ret);
9268   return ret;
9269 }
9270
9271 static int
9272 api_ip_table_replace_end (vat_main_t * vam)
9273 {
9274   unformat_input_t *i = vam->input;
9275   vl_api_ip_table_replace_end_t *mp;
9276   u32 table_id = 0;
9277   u8 is_ipv6 = 0;
9278
9279   int ret;
9280   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9281     {
9282       if (unformat (i, "table %d", &table_id))
9283         ;
9284       else if (unformat (i, "ipv6"))
9285         is_ipv6 = 1;
9286       else
9287         {
9288           clib_warning ("parse error '%U'", format_unformat_error, i);
9289           return -99;
9290         }
9291     }
9292
9293   M (IP_TABLE_REPLACE_END, mp);
9294
9295   mp->table.table_id = ntohl (table_id);
9296   mp->table.is_ip6 = is_ipv6;
9297
9298   S (mp);
9299   W (ret);
9300   return ret;
9301 }
9302
9303 static int
9304 api_set_ip_flow_hash (vat_main_t * vam)
9305 {
9306   unformat_input_t *i = vam->input;
9307   vl_api_set_ip_flow_hash_t *mp;
9308   u32 vrf_id = 0;
9309   u8 is_ipv6 = 0;
9310   u8 vrf_id_set = 0;
9311   u8 src = 0;
9312   u8 dst = 0;
9313   u8 sport = 0;
9314   u8 dport = 0;
9315   u8 proto = 0;
9316   u8 reverse = 0;
9317   int ret;
9318
9319   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9320     {
9321       if (unformat (i, "vrf %d", &vrf_id))
9322         vrf_id_set = 1;
9323       else if (unformat (i, "ipv6"))
9324         is_ipv6 = 1;
9325       else if (unformat (i, "src"))
9326         src = 1;
9327       else if (unformat (i, "dst"))
9328         dst = 1;
9329       else if (unformat (i, "sport"))
9330         sport = 1;
9331       else if (unformat (i, "dport"))
9332         dport = 1;
9333       else if (unformat (i, "proto"))
9334         proto = 1;
9335       else if (unformat (i, "reverse"))
9336         reverse = 1;
9337
9338       else
9339         {
9340           clib_warning ("parse error '%U'", format_unformat_error, i);
9341           return -99;
9342         }
9343     }
9344
9345   if (vrf_id_set == 0)
9346     {
9347       errmsg ("missing vrf id");
9348       return -99;
9349     }
9350
9351   M (SET_IP_FLOW_HASH, mp);
9352   mp->src = src;
9353   mp->dst = dst;
9354   mp->sport = sport;
9355   mp->dport = dport;
9356   mp->proto = proto;
9357   mp->reverse = reverse;
9358   mp->vrf_id = ntohl (vrf_id);
9359   mp->is_ipv6 = is_ipv6;
9360
9361   S (mp);
9362   W (ret);
9363   return ret;
9364 }
9365
9366 static int
9367 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
9368 {
9369   unformat_input_t *i = vam->input;
9370   vl_api_sw_interface_ip6_enable_disable_t *mp;
9371   u32 sw_if_index;
9372   u8 sw_if_index_set = 0;
9373   u8 enable = 0;
9374   int ret;
9375
9376   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9377     {
9378       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9379         sw_if_index_set = 1;
9380       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9381         sw_if_index_set = 1;
9382       else if (unformat (i, "enable"))
9383         enable = 1;
9384       else if (unformat (i, "disable"))
9385         enable = 0;
9386       else
9387         {
9388           clib_warning ("parse error '%U'", format_unformat_error, i);
9389           return -99;
9390         }
9391     }
9392
9393   if (sw_if_index_set == 0)
9394     {
9395       errmsg ("missing interface name or sw_if_index");
9396       return -99;
9397     }
9398
9399   M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
9400
9401   mp->sw_if_index = ntohl (sw_if_index);
9402   mp->enable = enable;
9403
9404   S (mp);
9405   W (ret);
9406   return ret;
9407 }
9408
9409 static int
9410 api_ip6nd_proxy_add_del (vat_main_t * vam)
9411 {
9412   unformat_input_t *i = vam->input;
9413   vl_api_ip6nd_proxy_add_del_t *mp;
9414   u32 sw_if_index = ~0;
9415   u8 v6_address_set = 0;
9416   vl_api_ip6_address_t v6address;
9417   u8 is_del = 0;
9418   int ret;
9419
9420   /* Parse args required to build the message */
9421   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9422     {
9423       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9424         ;
9425       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9426         ;
9427       else if (unformat (i, "%U", unformat_vl_api_ip6_address, &v6address))
9428         v6_address_set = 1;
9429       if (unformat (i, "del"))
9430         is_del = 1;
9431       else
9432         {
9433           clib_warning ("parse error '%U'", format_unformat_error, i);
9434           return -99;
9435         }
9436     }
9437
9438   if (sw_if_index == ~0)
9439     {
9440       errmsg ("missing interface name or sw_if_index");
9441       return -99;
9442     }
9443   if (!v6_address_set)
9444     {
9445       errmsg ("no address set");
9446       return -99;
9447     }
9448
9449   /* Construct the API message */
9450   M (IP6ND_PROXY_ADD_DEL, mp);
9451
9452   mp->is_del = is_del;
9453   mp->sw_if_index = ntohl (sw_if_index);
9454   clib_memcpy (mp->ip, v6address, sizeof (v6address));
9455
9456   /* send it... */
9457   S (mp);
9458
9459   /* Wait for a reply, return good/bad news  */
9460   W (ret);
9461   return ret;
9462 }
9463
9464 static int
9465 api_ip6nd_proxy_dump (vat_main_t * vam)
9466 {
9467   vl_api_ip6nd_proxy_dump_t *mp;
9468   vl_api_control_ping_t *mp_ping;
9469   int ret;
9470
9471   M (IP6ND_PROXY_DUMP, mp);
9472
9473   S (mp);
9474
9475   /* Use a control ping for synchronization */
9476   MPING (CONTROL_PING, mp_ping);
9477   S (mp_ping);
9478
9479   W (ret);
9480   return ret;
9481 }
9482
9483 static void vl_api_ip6nd_proxy_details_t_handler
9484   (vl_api_ip6nd_proxy_details_t * mp)
9485 {
9486   vat_main_t *vam = &vat_main;
9487
9488   print (vam->ofp, "host %U sw_if_index %d",
9489          format_vl_api_ip6_address, mp->ip, ntohl (mp->sw_if_index));
9490 }
9491
9492 static void vl_api_ip6nd_proxy_details_t_handler_json
9493   (vl_api_ip6nd_proxy_details_t * mp)
9494 {
9495   vat_main_t *vam = &vat_main;
9496   struct in6_addr ip6;
9497   vat_json_node_t *node = NULL;
9498
9499   if (VAT_JSON_ARRAY != vam->json_tree.type)
9500     {
9501       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9502       vat_json_init_array (&vam->json_tree);
9503     }
9504   node = vat_json_array_add (&vam->json_tree);
9505
9506   vat_json_init_object (node);
9507   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
9508
9509   clib_memcpy (&ip6, mp->ip, sizeof (ip6));
9510   vat_json_object_add_ip6 (node, "host", ip6);
9511 }
9512
9513 static int
9514 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
9515 {
9516   unformat_input_t *i = vam->input;
9517   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
9518   u32 sw_if_index;
9519   u8 sw_if_index_set = 0;
9520   u8 v6_address_set = 0;
9521   vl_api_prefix_t pfx;
9522   u8 use_default = 0;
9523   u8 no_advertise = 0;
9524   u8 off_link = 0;
9525   u8 no_autoconfig = 0;
9526   u8 no_onlink = 0;
9527   u8 is_no = 0;
9528   u32 val_lifetime = 0;
9529   u32 pref_lifetime = 0;
9530   int ret;
9531
9532   /* Parse args required to build the message */
9533   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9534     {
9535       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9536         sw_if_index_set = 1;
9537       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9538         sw_if_index_set = 1;
9539       else if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
9540         v6_address_set = 1;
9541       else if (unformat (i, "val_life %d", &val_lifetime))
9542         ;
9543       else if (unformat (i, "pref_life %d", &pref_lifetime))
9544         ;
9545       else if (unformat (i, "def"))
9546         use_default = 1;
9547       else if (unformat (i, "noadv"))
9548         no_advertise = 1;
9549       else if (unformat (i, "offl"))
9550         off_link = 1;
9551       else if (unformat (i, "noauto"))
9552         no_autoconfig = 1;
9553       else if (unformat (i, "nolink"))
9554         no_onlink = 1;
9555       else if (unformat (i, "isno"))
9556         is_no = 1;
9557       else
9558         {
9559           clib_warning ("parse error '%U'", format_unformat_error, i);
9560           return -99;
9561         }
9562     }
9563
9564   if (sw_if_index_set == 0)
9565     {
9566       errmsg ("missing interface name or sw_if_index");
9567       return -99;
9568     }
9569   if (!v6_address_set)
9570     {
9571       errmsg ("no address set");
9572       return -99;
9573     }
9574
9575   /* Construct the API message */
9576   M (SW_INTERFACE_IP6ND_RA_PREFIX, mp);
9577
9578   mp->sw_if_index = ntohl (sw_if_index);
9579   clib_memcpy (&mp->prefix, &pfx, sizeof (pfx));
9580   mp->use_default = use_default;
9581   mp->no_advertise = no_advertise;
9582   mp->off_link = off_link;
9583   mp->no_autoconfig = no_autoconfig;
9584   mp->no_onlink = no_onlink;
9585   mp->is_no = is_no;
9586   mp->val_lifetime = ntohl (val_lifetime);
9587   mp->pref_lifetime = ntohl (pref_lifetime);
9588
9589   /* send it... */
9590   S (mp);
9591
9592   /* Wait for a reply, return good/bad news  */
9593   W (ret);
9594   return ret;
9595 }
9596
9597 static int
9598 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
9599 {
9600   unformat_input_t *i = vam->input;
9601   vl_api_sw_interface_ip6nd_ra_config_t *mp;
9602   u32 sw_if_index;
9603   u8 sw_if_index_set = 0;
9604   u8 suppress = 0;
9605   u8 managed = 0;
9606   u8 other = 0;
9607   u8 ll_option = 0;
9608   u8 send_unicast = 0;
9609   u8 cease = 0;
9610   u8 is_no = 0;
9611   u8 default_router = 0;
9612   u32 max_interval = 0;
9613   u32 min_interval = 0;
9614   u32 lifetime = 0;
9615   u32 initial_count = 0;
9616   u32 initial_interval = 0;
9617   int ret;
9618
9619
9620   /* Parse args required to build the message */
9621   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9622     {
9623       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9624         sw_if_index_set = 1;
9625       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9626         sw_if_index_set = 1;
9627       else if (unformat (i, "maxint %d", &max_interval))
9628         ;
9629       else if (unformat (i, "minint %d", &min_interval))
9630         ;
9631       else if (unformat (i, "life %d", &lifetime))
9632         ;
9633       else if (unformat (i, "count %d", &initial_count))
9634         ;
9635       else if (unformat (i, "interval %d", &initial_interval))
9636         ;
9637       else if (unformat (i, "suppress") || unformat (i, "surpress"))
9638         suppress = 1;
9639       else if (unformat (i, "managed"))
9640         managed = 1;
9641       else if (unformat (i, "other"))
9642         other = 1;
9643       else if (unformat (i, "ll"))
9644         ll_option = 1;
9645       else if (unformat (i, "send"))
9646         send_unicast = 1;
9647       else if (unformat (i, "cease"))
9648         cease = 1;
9649       else if (unformat (i, "isno"))
9650         is_no = 1;
9651       else if (unformat (i, "def"))
9652         default_router = 1;
9653       else
9654         {
9655           clib_warning ("parse error '%U'", format_unformat_error, i);
9656           return -99;
9657         }
9658     }
9659
9660   if (sw_if_index_set == 0)
9661     {
9662       errmsg ("missing interface name or sw_if_index");
9663       return -99;
9664     }
9665
9666   /* Construct the API message */
9667   M (SW_INTERFACE_IP6ND_RA_CONFIG, mp);
9668
9669   mp->sw_if_index = ntohl (sw_if_index);
9670   mp->max_interval = ntohl (max_interval);
9671   mp->min_interval = ntohl (min_interval);
9672   mp->lifetime = ntohl (lifetime);
9673   mp->initial_count = ntohl (initial_count);
9674   mp->initial_interval = ntohl (initial_interval);
9675   mp->suppress = suppress;
9676   mp->managed = managed;
9677   mp->other = other;
9678   mp->ll_option = ll_option;
9679   mp->send_unicast = send_unicast;
9680   mp->cease = cease;
9681   mp->is_no = is_no;
9682   mp->default_router = default_router;
9683
9684   /* send it... */
9685   S (mp);
9686
9687   /* Wait for a reply, return good/bad news  */
9688   W (ret);
9689   return ret;
9690 }
9691
9692 static int
9693 api_set_arp_neighbor_limit (vat_main_t * vam)
9694 {
9695   unformat_input_t *i = vam->input;
9696   vl_api_set_arp_neighbor_limit_t *mp;
9697   u32 arp_nbr_limit;
9698   u8 limit_set = 0;
9699   u8 is_ipv6 = 0;
9700   int ret;
9701
9702   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9703     {
9704       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
9705         limit_set = 1;
9706       else if (unformat (i, "ipv6"))
9707         is_ipv6 = 1;
9708       else
9709         {
9710           clib_warning ("parse error '%U'", format_unformat_error, i);
9711           return -99;
9712         }
9713     }
9714
9715   if (limit_set == 0)
9716     {
9717       errmsg ("missing limit value");
9718       return -99;
9719     }
9720
9721   M (SET_ARP_NEIGHBOR_LIMIT, mp);
9722
9723   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
9724   mp->is_ipv6 = is_ipv6;
9725
9726   S (mp);
9727   W (ret);
9728   return ret;
9729 }
9730
9731 static int
9732 api_l2_patch_add_del (vat_main_t * vam)
9733 {
9734   unformat_input_t *i = vam->input;
9735   vl_api_l2_patch_add_del_t *mp;
9736   u32 rx_sw_if_index;
9737   u8 rx_sw_if_index_set = 0;
9738   u32 tx_sw_if_index;
9739   u8 tx_sw_if_index_set = 0;
9740   u8 is_add = 1;
9741   int ret;
9742
9743   /* Parse args required to build the message */
9744   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9745     {
9746       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
9747         rx_sw_if_index_set = 1;
9748       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
9749         tx_sw_if_index_set = 1;
9750       else if (unformat (i, "rx"))
9751         {
9752           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9753             {
9754               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
9755                             &rx_sw_if_index))
9756                 rx_sw_if_index_set = 1;
9757             }
9758           else
9759             break;
9760         }
9761       else if (unformat (i, "tx"))
9762         {
9763           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9764             {
9765               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
9766                             &tx_sw_if_index))
9767                 tx_sw_if_index_set = 1;
9768             }
9769           else
9770             break;
9771         }
9772       else if (unformat (i, "del"))
9773         is_add = 0;
9774       else
9775         break;
9776     }
9777
9778   if (rx_sw_if_index_set == 0)
9779     {
9780       errmsg ("missing rx interface name or rx_sw_if_index");
9781       return -99;
9782     }
9783
9784   if (tx_sw_if_index_set == 0)
9785     {
9786       errmsg ("missing tx interface name or tx_sw_if_index");
9787       return -99;
9788     }
9789
9790   M (L2_PATCH_ADD_DEL, mp);
9791
9792   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
9793   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
9794   mp->is_add = is_add;
9795
9796   S (mp);
9797   W (ret);
9798   return ret;
9799 }
9800
9801 u8 is_del;
9802 u8 localsid_addr[16];
9803 u8 end_psp;
9804 u8 behavior;
9805 u32 sw_if_index;
9806 u32 vlan_index;
9807 u32 fib_table;
9808 u8 nh_addr[16];
9809
9810 static int
9811 api_sr_localsid_add_del (vat_main_t * vam)
9812 {
9813   unformat_input_t *i = vam->input;
9814   vl_api_sr_localsid_add_del_t *mp;
9815
9816   u8 is_del;
9817   ip6_address_t localsid;
9818   u8 end_psp = 0;
9819   u8 behavior = ~0;
9820   u32 sw_if_index;
9821   u32 fib_table = ~(u32) 0;
9822   ip6_address_t nh_addr6;
9823   ip4_address_t nh_addr4;
9824   clib_memset (&nh_addr6, 0, sizeof (ip6_address_t));
9825   clib_memset (&nh_addr4, 0, sizeof (ip4_address_t));
9826
9827   bool nexthop_set = 0;
9828
9829   int ret;
9830
9831   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9832     {
9833       if (unformat (i, "del"))
9834         is_del = 1;
9835       else if (unformat (i, "address %U", unformat_ip6_address, &localsid));
9836       else if (unformat (i, "next-hop %U", unformat_ip4_address, &nh_addr4))
9837         nexthop_set = 1;
9838       else if (unformat (i, "next-hop %U", unformat_ip6_address, &nh_addr6))
9839         nexthop_set = 1;
9840       else if (unformat (i, "behavior %u", &behavior));
9841       else if (unformat (i, "sw_if_index %u", &sw_if_index));
9842       else if (unformat (i, "fib-table %u", &fib_table));
9843       else if (unformat (i, "end.psp %u", &behavior));
9844       else
9845         break;
9846     }
9847
9848   M (SR_LOCALSID_ADD_DEL, mp);
9849
9850   clib_memcpy (mp->localsid.addr, &localsid, sizeof (mp->localsid));
9851
9852   if (nexthop_set)
9853     {
9854       clib_memcpy (mp->nh_addr6, &nh_addr6, sizeof (mp->nh_addr6));
9855       clib_memcpy (mp->nh_addr4, &nh_addr4, sizeof (mp->nh_addr4));
9856     }
9857   mp->behavior = behavior;
9858   mp->sw_if_index = ntohl (sw_if_index);
9859   mp->fib_table = ntohl (fib_table);
9860   mp->end_psp = end_psp;
9861   mp->is_del = is_del;
9862
9863   S (mp);
9864   W (ret);
9865   return ret;
9866 }
9867
9868 static int
9869 api_ioam_enable (vat_main_t * vam)
9870 {
9871   unformat_input_t *input = vam->input;
9872   vl_api_ioam_enable_t *mp;
9873   u32 id = 0;
9874   int has_trace_option = 0;
9875   int has_pot_option = 0;
9876   int has_seqno_option = 0;
9877   int has_analyse_option = 0;
9878   int ret;
9879
9880   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9881     {
9882       if (unformat (input, "trace"))
9883         has_trace_option = 1;
9884       else if (unformat (input, "pot"))
9885         has_pot_option = 1;
9886       else if (unformat (input, "seqno"))
9887         has_seqno_option = 1;
9888       else if (unformat (input, "analyse"))
9889         has_analyse_option = 1;
9890       else
9891         break;
9892     }
9893   M (IOAM_ENABLE, mp);
9894   mp->id = htons (id);
9895   mp->seqno = has_seqno_option;
9896   mp->analyse = has_analyse_option;
9897   mp->pot_enable = has_pot_option;
9898   mp->trace_enable = has_trace_option;
9899
9900   S (mp);
9901   W (ret);
9902   return ret;
9903 }
9904
9905
9906 static int
9907 api_ioam_disable (vat_main_t * vam)
9908 {
9909   vl_api_ioam_disable_t *mp;
9910   int ret;
9911
9912   M (IOAM_DISABLE, mp);
9913   S (mp);
9914   W (ret);
9915   return ret;
9916 }
9917
9918 #define foreach_tcp_proto_field                 \
9919 _(src_port)                                     \
9920 _(dst_port)
9921
9922 #define foreach_udp_proto_field                 \
9923 _(src_port)                                     \
9924 _(dst_port)
9925
9926 #define foreach_ip4_proto_field                 \
9927 _(src_address)                                  \
9928 _(dst_address)                                  \
9929 _(tos)                                          \
9930 _(length)                                       \
9931 _(fragment_id)                                  \
9932 _(ttl)                                          \
9933 _(protocol)                                     \
9934 _(checksum)
9935
9936 typedef struct
9937 {
9938   u16 src_port, dst_port;
9939 } tcpudp_header_t;
9940
9941 #if VPP_API_TEST_BUILTIN == 0
9942 uword
9943 unformat_tcp_mask (unformat_input_t * input, va_list * args)
9944 {
9945   u8 **maskp = va_arg (*args, u8 **);
9946   u8 *mask = 0;
9947   u8 found_something = 0;
9948   tcp_header_t *tcp;
9949
9950 #define _(a) u8 a=0;
9951   foreach_tcp_proto_field;
9952 #undef _
9953
9954   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9955     {
9956       if (0);
9957 #define _(a) else if (unformat (input, #a)) a=1;
9958       foreach_tcp_proto_field
9959 #undef _
9960         else
9961         break;
9962     }
9963
9964 #define _(a) found_something += a;
9965   foreach_tcp_proto_field;
9966 #undef _
9967
9968   if (found_something == 0)
9969     return 0;
9970
9971   vec_validate (mask, sizeof (*tcp) - 1);
9972
9973   tcp = (tcp_header_t *) mask;
9974
9975 #define _(a) if (a) clib_memset (&tcp->a, 0xff, sizeof (tcp->a));
9976   foreach_tcp_proto_field;
9977 #undef _
9978
9979   *maskp = mask;
9980   return 1;
9981 }
9982
9983 uword
9984 unformat_udp_mask (unformat_input_t * input, va_list * args)
9985 {
9986   u8 **maskp = va_arg (*args, u8 **);
9987   u8 *mask = 0;
9988   u8 found_something = 0;
9989   udp_header_t *udp;
9990
9991 #define _(a) u8 a=0;
9992   foreach_udp_proto_field;
9993 #undef _
9994
9995   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9996     {
9997       if (0);
9998 #define _(a) else if (unformat (input, #a)) a=1;
9999       foreach_udp_proto_field
10000 #undef _
10001         else
10002         break;
10003     }
10004
10005 #define _(a) found_something += a;
10006   foreach_udp_proto_field;
10007 #undef _
10008
10009   if (found_something == 0)
10010     return 0;
10011
10012   vec_validate (mask, sizeof (*udp) - 1);
10013
10014   udp = (udp_header_t *) mask;
10015
10016 #define _(a) if (a) clib_memset (&udp->a, 0xff, sizeof (udp->a));
10017   foreach_udp_proto_field;
10018 #undef _
10019
10020   *maskp = mask;
10021   return 1;
10022 }
10023
10024 uword
10025 unformat_l4_mask (unformat_input_t * input, va_list * args)
10026 {
10027   u8 **maskp = va_arg (*args, u8 **);
10028   u16 src_port = 0, dst_port = 0;
10029   tcpudp_header_t *tcpudp;
10030
10031   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10032     {
10033       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
10034         return 1;
10035       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
10036         return 1;
10037       else if (unformat (input, "src_port"))
10038         src_port = 0xFFFF;
10039       else if (unformat (input, "dst_port"))
10040         dst_port = 0xFFFF;
10041       else
10042         return 0;
10043     }
10044
10045   if (!src_port && !dst_port)
10046     return 0;
10047
10048   u8 *mask = 0;
10049   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
10050
10051   tcpudp = (tcpudp_header_t *) mask;
10052   tcpudp->src_port = src_port;
10053   tcpudp->dst_port = dst_port;
10054
10055   *maskp = mask;
10056
10057   return 1;
10058 }
10059
10060 uword
10061 unformat_ip4_mask (unformat_input_t * input, va_list * args)
10062 {
10063   u8 **maskp = va_arg (*args, u8 **);
10064   u8 *mask = 0;
10065   u8 found_something = 0;
10066   ip4_header_t *ip;
10067
10068 #define _(a) u8 a=0;
10069   foreach_ip4_proto_field;
10070 #undef _
10071   u8 version = 0;
10072   u8 hdr_length = 0;
10073
10074
10075   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10076     {
10077       if (unformat (input, "version"))
10078         version = 1;
10079       else if (unformat (input, "hdr_length"))
10080         hdr_length = 1;
10081       else if (unformat (input, "src"))
10082         src_address = 1;
10083       else if (unformat (input, "dst"))
10084         dst_address = 1;
10085       else if (unformat (input, "proto"))
10086         protocol = 1;
10087
10088 #define _(a) else if (unformat (input, #a)) a=1;
10089       foreach_ip4_proto_field
10090 #undef _
10091         else
10092         break;
10093     }
10094
10095 #define _(a) found_something += a;
10096   foreach_ip4_proto_field;
10097 #undef _
10098
10099   if (found_something == 0)
10100     return 0;
10101
10102   vec_validate (mask, sizeof (*ip) - 1);
10103
10104   ip = (ip4_header_t *) mask;
10105
10106 #define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
10107   foreach_ip4_proto_field;
10108 #undef _
10109
10110   ip->ip_version_and_header_length = 0;
10111
10112   if (version)
10113     ip->ip_version_and_header_length |= 0xF0;
10114
10115   if (hdr_length)
10116     ip->ip_version_and_header_length |= 0x0F;
10117
10118   *maskp = mask;
10119   return 1;
10120 }
10121
10122 #define foreach_ip6_proto_field                 \
10123 _(src_address)                                  \
10124 _(dst_address)                                  \
10125 _(payload_length)                               \
10126 _(hop_limit)                                    \
10127 _(protocol)
10128
10129 uword
10130 unformat_ip6_mask (unformat_input_t * input, va_list * args)
10131 {
10132   u8 **maskp = va_arg (*args, u8 **);
10133   u8 *mask = 0;
10134   u8 found_something = 0;
10135   ip6_header_t *ip;
10136   u32 ip_version_traffic_class_and_flow_label;
10137
10138 #define _(a) u8 a=0;
10139   foreach_ip6_proto_field;
10140 #undef _
10141   u8 version = 0;
10142   u8 traffic_class = 0;
10143   u8 flow_label = 0;
10144
10145   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10146     {
10147       if (unformat (input, "version"))
10148         version = 1;
10149       else if (unformat (input, "traffic-class"))
10150         traffic_class = 1;
10151       else if (unformat (input, "flow-label"))
10152         flow_label = 1;
10153       else if (unformat (input, "src"))
10154         src_address = 1;
10155       else if (unformat (input, "dst"))
10156         dst_address = 1;
10157       else if (unformat (input, "proto"))
10158         protocol = 1;
10159
10160 #define _(a) else if (unformat (input, #a)) a=1;
10161       foreach_ip6_proto_field
10162 #undef _
10163         else
10164         break;
10165     }
10166
10167 #define _(a) found_something += a;
10168   foreach_ip6_proto_field;
10169 #undef _
10170
10171   if (found_something == 0)
10172     return 0;
10173
10174   vec_validate (mask, sizeof (*ip) - 1);
10175
10176   ip = (ip6_header_t *) mask;
10177
10178 #define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
10179   foreach_ip6_proto_field;
10180 #undef _
10181
10182   ip_version_traffic_class_and_flow_label = 0;
10183
10184   if (version)
10185     ip_version_traffic_class_and_flow_label |= 0xF0000000;
10186
10187   if (traffic_class)
10188     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
10189
10190   if (flow_label)
10191     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
10192
10193   ip->ip_version_traffic_class_and_flow_label =
10194     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
10195
10196   *maskp = mask;
10197   return 1;
10198 }
10199
10200 uword
10201 unformat_l3_mask (unformat_input_t * input, va_list * args)
10202 {
10203   u8 **maskp = va_arg (*args, u8 **);
10204
10205   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10206     {
10207       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
10208         return 1;
10209       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
10210         return 1;
10211       else
10212         break;
10213     }
10214   return 0;
10215 }
10216
10217 uword
10218 unformat_l2_mask (unformat_input_t * input, va_list * args)
10219 {
10220   u8 **maskp = va_arg (*args, u8 **);
10221   u8 *mask = 0;
10222   u8 src = 0;
10223   u8 dst = 0;
10224   u8 proto = 0;
10225   u8 tag1 = 0;
10226   u8 tag2 = 0;
10227   u8 ignore_tag1 = 0;
10228   u8 ignore_tag2 = 0;
10229   u8 cos1 = 0;
10230   u8 cos2 = 0;
10231   u8 dot1q = 0;
10232   u8 dot1ad = 0;
10233   int len = 14;
10234
10235   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10236     {
10237       if (unformat (input, "src"))
10238         src = 1;
10239       else if (unformat (input, "dst"))
10240         dst = 1;
10241       else if (unformat (input, "proto"))
10242         proto = 1;
10243       else if (unformat (input, "tag1"))
10244         tag1 = 1;
10245       else if (unformat (input, "tag2"))
10246         tag2 = 1;
10247       else if (unformat (input, "ignore-tag1"))
10248         ignore_tag1 = 1;
10249       else if (unformat (input, "ignore-tag2"))
10250         ignore_tag2 = 1;
10251       else if (unformat (input, "cos1"))
10252         cos1 = 1;
10253       else if (unformat (input, "cos2"))
10254         cos2 = 1;
10255       else if (unformat (input, "dot1q"))
10256         dot1q = 1;
10257       else if (unformat (input, "dot1ad"))
10258         dot1ad = 1;
10259       else
10260         break;
10261     }
10262   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
10263        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
10264     return 0;
10265
10266   if (tag1 || ignore_tag1 || cos1 || dot1q)
10267     len = 18;
10268   if (tag2 || ignore_tag2 || cos2 || dot1ad)
10269     len = 22;
10270
10271   vec_validate (mask, len - 1);
10272
10273   if (dst)
10274     clib_memset (mask, 0xff, 6);
10275
10276   if (src)
10277     clib_memset (mask + 6, 0xff, 6);
10278
10279   if (tag2 || dot1ad)
10280     {
10281       /* inner vlan tag */
10282       if (tag2)
10283         {
10284           mask[19] = 0xff;
10285           mask[18] = 0x0f;
10286         }
10287       if (cos2)
10288         mask[18] |= 0xe0;
10289       if (proto)
10290         mask[21] = mask[20] = 0xff;
10291       if (tag1)
10292         {
10293           mask[15] = 0xff;
10294           mask[14] = 0x0f;
10295         }
10296       if (cos1)
10297         mask[14] |= 0xe0;
10298       *maskp = mask;
10299       return 1;
10300     }
10301   if (tag1 | dot1q)
10302     {
10303       if (tag1)
10304         {
10305           mask[15] = 0xff;
10306           mask[14] = 0x0f;
10307         }
10308       if (cos1)
10309         mask[14] |= 0xe0;
10310       if (proto)
10311         mask[16] = mask[17] = 0xff;
10312
10313       *maskp = mask;
10314       return 1;
10315     }
10316   if (cos2)
10317     mask[18] |= 0xe0;
10318   if (cos1)
10319     mask[14] |= 0xe0;
10320   if (proto)
10321     mask[12] = mask[13] = 0xff;
10322
10323   *maskp = mask;
10324   return 1;
10325 }
10326
10327 uword
10328 unformat_classify_mask (unformat_input_t * input, va_list * args)
10329 {
10330   u8 **maskp = va_arg (*args, u8 **);
10331   u32 *skipp = va_arg (*args, u32 *);
10332   u32 *matchp = va_arg (*args, u32 *);
10333   u32 match;
10334   u8 *mask = 0;
10335   u8 *l2 = 0;
10336   u8 *l3 = 0;
10337   u8 *l4 = 0;
10338   int i;
10339
10340   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10341     {
10342       if (unformat (input, "hex %U", unformat_hex_string, &mask))
10343         ;
10344       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
10345         ;
10346       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
10347         ;
10348       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
10349         ;
10350       else
10351         break;
10352     }
10353
10354   if (l4 && !l3)
10355     {
10356       vec_free (mask);
10357       vec_free (l2);
10358       vec_free (l4);
10359       return 0;
10360     }
10361
10362   if (mask || l2 || l3 || l4)
10363     {
10364       if (l2 || l3 || l4)
10365         {
10366           /* "With a free Ethernet header in every package" */
10367           if (l2 == 0)
10368             vec_validate (l2, 13);
10369           mask = l2;
10370           if (vec_len (l3))
10371             {
10372               vec_append (mask, l3);
10373               vec_free (l3);
10374             }
10375           if (vec_len (l4))
10376             {
10377               vec_append (mask, l4);
10378               vec_free (l4);
10379             }
10380         }
10381
10382       /* Scan forward looking for the first significant mask octet */
10383       for (i = 0; i < vec_len (mask); i++)
10384         if (mask[i])
10385           break;
10386
10387       /* compute (skip, match) params */
10388       *skipp = i / sizeof (u32x4);
10389       vec_delete (mask, *skipp * sizeof (u32x4), 0);
10390
10391       /* Pad mask to an even multiple of the vector size */
10392       while (vec_len (mask) % sizeof (u32x4))
10393         vec_add1 (mask, 0);
10394
10395       match = vec_len (mask) / sizeof (u32x4);
10396
10397       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
10398         {
10399           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
10400           if (*tmp || *(tmp + 1))
10401             break;
10402           match--;
10403         }
10404       if (match == 0)
10405         clib_warning ("BUG: match 0");
10406
10407       _vec_len (mask) = match * sizeof (u32x4);
10408
10409       *matchp = match;
10410       *maskp = mask;
10411
10412       return 1;
10413     }
10414
10415   return 0;
10416 }
10417 #endif /* VPP_API_TEST_BUILTIN */
10418
10419 #define foreach_l2_next                         \
10420 _(drop, DROP)                                   \
10421 _(ethernet, ETHERNET_INPUT)                     \
10422 _(ip4, IP4_INPUT)                               \
10423 _(ip6, IP6_INPUT)
10424
10425 uword
10426 unformat_l2_next_index (unformat_input_t * input, va_list * args)
10427 {
10428   u32 *miss_next_indexp = va_arg (*args, u32 *);
10429   u32 next_index = 0;
10430   u32 tmp;
10431
10432 #define _(n,N) \
10433   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
10434   foreach_l2_next;
10435 #undef _
10436
10437   if (unformat (input, "%d", &tmp))
10438     {
10439       next_index = tmp;
10440       goto out;
10441     }
10442
10443   return 0;
10444
10445 out:
10446   *miss_next_indexp = next_index;
10447   return 1;
10448 }
10449
10450 #define foreach_ip_next                         \
10451 _(drop, DROP)                                   \
10452 _(local, LOCAL)                                 \
10453 _(rewrite, REWRITE)
10454
10455 uword
10456 api_unformat_ip_next_index (unformat_input_t * input, va_list * args)
10457 {
10458   u32 *miss_next_indexp = va_arg (*args, u32 *);
10459   u32 next_index = 0;
10460   u32 tmp;
10461
10462 #define _(n,N) \
10463   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
10464   foreach_ip_next;
10465 #undef _
10466
10467   if (unformat (input, "%d", &tmp))
10468     {
10469       next_index = tmp;
10470       goto out;
10471     }
10472
10473   return 0;
10474
10475 out:
10476   *miss_next_indexp = next_index;
10477   return 1;
10478 }
10479
10480 #define foreach_acl_next                        \
10481 _(deny, DENY)
10482
10483 uword
10484 api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
10485 {
10486   u32 *miss_next_indexp = va_arg (*args, u32 *);
10487   u32 next_index = 0;
10488   u32 tmp;
10489
10490 #define _(n,N) \
10491   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
10492   foreach_acl_next;
10493 #undef _
10494
10495   if (unformat (input, "permit"))
10496     {
10497       next_index = ~0;
10498       goto out;
10499     }
10500   else if (unformat (input, "%d", &tmp))
10501     {
10502       next_index = tmp;
10503       goto out;
10504     }
10505
10506   return 0;
10507
10508 out:
10509   *miss_next_indexp = next_index;
10510   return 1;
10511 }
10512
10513 uword
10514 unformat_policer_precolor (unformat_input_t * input, va_list * args)
10515 {
10516   u32 *r = va_arg (*args, u32 *);
10517
10518   if (unformat (input, "conform-color"))
10519     *r = POLICE_CONFORM;
10520   else if (unformat (input, "exceed-color"))
10521     *r = POLICE_EXCEED;
10522   else
10523     return 0;
10524
10525   return 1;
10526 }
10527
10528 static int
10529 api_classify_add_del_table (vat_main_t * vam)
10530 {
10531   unformat_input_t *i = vam->input;
10532   vl_api_classify_add_del_table_t *mp;
10533
10534   u32 nbuckets = 2;
10535   u32 skip = ~0;
10536   u32 match = ~0;
10537   int is_add = 1;
10538   int del_chain = 0;
10539   u32 table_index = ~0;
10540   u32 next_table_index = ~0;
10541   u32 miss_next_index = ~0;
10542   u32 memory_size = 32 << 20;
10543   u8 *mask = 0;
10544   u32 current_data_flag = 0;
10545   int current_data_offset = 0;
10546   int ret;
10547
10548   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10549     {
10550       if (unformat (i, "del"))
10551         is_add = 0;
10552       else if (unformat (i, "del-chain"))
10553         {
10554           is_add = 0;
10555           del_chain = 1;
10556         }
10557       else if (unformat (i, "buckets %d", &nbuckets))
10558         ;
10559       else if (unformat (i, "memory_size %d", &memory_size))
10560         ;
10561       else if (unformat (i, "skip %d", &skip))
10562         ;
10563       else if (unformat (i, "match %d", &match))
10564         ;
10565       else if (unformat (i, "table %d", &table_index))
10566         ;
10567       else if (unformat (i, "mask %U", unformat_classify_mask,
10568                          &mask, &skip, &match))
10569         ;
10570       else if (unformat (i, "next-table %d", &next_table_index))
10571         ;
10572       else if (unformat (i, "miss-next %U", api_unformat_ip_next_index,
10573                          &miss_next_index))
10574         ;
10575       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
10576                          &miss_next_index))
10577         ;
10578       else if (unformat (i, "acl-miss-next %U", api_unformat_acl_next_index,
10579                          &miss_next_index))
10580         ;
10581       else if (unformat (i, "current-data-flag %d", &current_data_flag))
10582         ;
10583       else if (unformat (i, "current-data-offset %d", &current_data_offset))
10584         ;
10585       else
10586         break;
10587     }
10588
10589   if (is_add && mask == 0)
10590     {
10591       errmsg ("Mask required");
10592       return -99;
10593     }
10594
10595   if (is_add && skip == ~0)
10596     {
10597       errmsg ("skip count required");
10598       return -99;
10599     }
10600
10601   if (is_add && match == ~0)
10602     {
10603       errmsg ("match count required");
10604       return -99;
10605     }
10606
10607   if (!is_add && table_index == ~0)
10608     {
10609       errmsg ("table index required for delete");
10610       return -99;
10611     }
10612
10613   M2 (CLASSIFY_ADD_DEL_TABLE, mp, vec_len (mask));
10614
10615   mp->is_add = is_add;
10616   mp->del_chain = del_chain;
10617   mp->table_index = ntohl (table_index);
10618   mp->nbuckets = ntohl (nbuckets);
10619   mp->memory_size = ntohl (memory_size);
10620   mp->skip_n_vectors = ntohl (skip);
10621   mp->match_n_vectors = ntohl (match);
10622   mp->next_table_index = ntohl (next_table_index);
10623   mp->miss_next_index = ntohl (miss_next_index);
10624   mp->current_data_flag = ntohl (current_data_flag);
10625   mp->current_data_offset = ntohl (current_data_offset);
10626   mp->mask_len = ntohl (vec_len (mask));
10627   clib_memcpy (mp->mask, mask, vec_len (mask));
10628
10629   vec_free (mask);
10630
10631   S (mp);
10632   W (ret);
10633   return ret;
10634 }
10635
10636 #if VPP_API_TEST_BUILTIN == 0
10637 uword
10638 unformat_l4_match (unformat_input_t * input, va_list * args)
10639 {
10640   u8 **matchp = va_arg (*args, u8 **);
10641
10642   u8 *proto_header = 0;
10643   int src_port = 0;
10644   int dst_port = 0;
10645
10646   tcpudp_header_t h;
10647
10648   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10649     {
10650       if (unformat (input, "src_port %d", &src_port))
10651         ;
10652       else if (unformat (input, "dst_port %d", &dst_port))
10653         ;
10654       else
10655         return 0;
10656     }
10657
10658   h.src_port = clib_host_to_net_u16 (src_port);
10659   h.dst_port = clib_host_to_net_u16 (dst_port);
10660   vec_validate (proto_header, sizeof (h) - 1);
10661   memcpy (proto_header, &h, sizeof (h));
10662
10663   *matchp = proto_header;
10664
10665   return 1;
10666 }
10667
10668 uword
10669 unformat_ip4_match (unformat_input_t * input, va_list * args)
10670 {
10671   u8 **matchp = va_arg (*args, u8 **);
10672   u8 *match = 0;
10673   ip4_header_t *ip;
10674   int version = 0;
10675   u32 version_val;
10676   int hdr_length = 0;
10677   u32 hdr_length_val;
10678   int src = 0, dst = 0;
10679   ip4_address_t src_val, dst_val;
10680   int proto = 0;
10681   u32 proto_val;
10682   int tos = 0;
10683   u32 tos_val;
10684   int length = 0;
10685   u32 length_val;
10686   int fragment_id = 0;
10687   u32 fragment_id_val;
10688   int ttl = 0;
10689   int ttl_val;
10690   int checksum = 0;
10691   u32 checksum_val;
10692
10693   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10694     {
10695       if (unformat (input, "version %d", &version_val))
10696         version = 1;
10697       else if (unformat (input, "hdr_length %d", &hdr_length_val))
10698         hdr_length = 1;
10699       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
10700         src = 1;
10701       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
10702         dst = 1;
10703       else if (unformat (input, "proto %d", &proto_val))
10704         proto = 1;
10705       else if (unformat (input, "tos %d", &tos_val))
10706         tos = 1;
10707       else if (unformat (input, "length %d", &length_val))
10708         length = 1;
10709       else if (unformat (input, "fragment_id %d", &fragment_id_val))
10710         fragment_id = 1;
10711       else if (unformat (input, "ttl %d", &ttl_val))
10712         ttl = 1;
10713       else if (unformat (input, "checksum %d", &checksum_val))
10714         checksum = 1;
10715       else
10716         break;
10717     }
10718
10719   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
10720       + ttl + checksum == 0)
10721     return 0;
10722
10723   /*
10724    * Aligned because we use the real comparison functions
10725    */
10726   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
10727
10728   ip = (ip4_header_t *) match;
10729
10730   /* These are realistically matched in practice */
10731   if (src)
10732     ip->src_address.as_u32 = src_val.as_u32;
10733
10734   if (dst)
10735     ip->dst_address.as_u32 = dst_val.as_u32;
10736
10737   if (proto)
10738     ip->protocol = proto_val;
10739
10740
10741   /* These are not, but they're included for completeness */
10742   if (version)
10743     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
10744
10745   if (hdr_length)
10746     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
10747
10748   if (tos)
10749     ip->tos = tos_val;
10750
10751   if (length)
10752     ip->length = clib_host_to_net_u16 (length_val);
10753
10754   if (ttl)
10755     ip->ttl = ttl_val;
10756
10757   if (checksum)
10758     ip->checksum = clib_host_to_net_u16 (checksum_val);
10759
10760   *matchp = match;
10761   return 1;
10762 }
10763
10764 uword
10765 unformat_ip6_match (unformat_input_t * input, va_list * args)
10766 {
10767   u8 **matchp = va_arg (*args, u8 **);
10768   u8 *match = 0;
10769   ip6_header_t *ip;
10770   int version = 0;
10771   u32 version_val;
10772   u8 traffic_class = 0;
10773   u32 traffic_class_val = 0;
10774   u8 flow_label = 0;
10775   u8 flow_label_val;
10776   int src = 0, dst = 0;
10777   ip6_address_t src_val, dst_val;
10778   int proto = 0;
10779   u32 proto_val;
10780   int payload_length = 0;
10781   u32 payload_length_val;
10782   int hop_limit = 0;
10783   int hop_limit_val;
10784   u32 ip_version_traffic_class_and_flow_label;
10785
10786   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10787     {
10788       if (unformat (input, "version %d", &version_val))
10789         version = 1;
10790       else if (unformat (input, "traffic_class %d", &traffic_class_val))
10791         traffic_class = 1;
10792       else if (unformat (input, "flow_label %d", &flow_label_val))
10793         flow_label = 1;
10794       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
10795         src = 1;
10796       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
10797         dst = 1;
10798       else if (unformat (input, "proto %d", &proto_val))
10799         proto = 1;
10800       else if (unformat (input, "payload_length %d", &payload_length_val))
10801         payload_length = 1;
10802       else if (unformat (input, "hop_limit %d", &hop_limit_val))
10803         hop_limit = 1;
10804       else
10805         break;
10806     }
10807
10808   if (version + traffic_class + flow_label + src + dst + proto +
10809       payload_length + hop_limit == 0)
10810     return 0;
10811
10812   /*
10813    * Aligned because we use the real comparison functions
10814    */
10815   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
10816
10817   ip = (ip6_header_t *) match;
10818
10819   if (src)
10820     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
10821
10822   if (dst)
10823     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
10824
10825   if (proto)
10826     ip->protocol = proto_val;
10827
10828   ip_version_traffic_class_and_flow_label = 0;
10829
10830   if (version)
10831     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
10832
10833   if (traffic_class)
10834     ip_version_traffic_class_and_flow_label |=
10835       (traffic_class_val & 0xFF) << 20;
10836
10837   if (flow_label)
10838     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
10839
10840   ip->ip_version_traffic_class_and_flow_label =
10841     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
10842
10843   if (payload_length)
10844     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
10845
10846   if (hop_limit)
10847     ip->hop_limit = hop_limit_val;
10848
10849   *matchp = match;
10850   return 1;
10851 }
10852
10853 uword
10854 unformat_l3_match (unformat_input_t * input, va_list * args)
10855 {
10856   u8 **matchp = va_arg (*args, u8 **);
10857
10858   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10859     {
10860       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
10861         return 1;
10862       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
10863         return 1;
10864       else
10865         break;
10866     }
10867   return 0;
10868 }
10869
10870 uword
10871 unformat_vlan_tag (unformat_input_t * input, va_list * args)
10872 {
10873   u8 *tagp = va_arg (*args, u8 *);
10874   u32 tag;
10875
10876   if (unformat (input, "%d", &tag))
10877     {
10878       tagp[0] = (tag >> 8) & 0x0F;
10879       tagp[1] = tag & 0xFF;
10880       return 1;
10881     }
10882
10883   return 0;
10884 }
10885
10886 uword
10887 unformat_l2_match (unformat_input_t * input, va_list * args)
10888 {
10889   u8 **matchp = va_arg (*args, u8 **);
10890   u8 *match = 0;
10891   u8 src = 0;
10892   u8 src_val[6];
10893   u8 dst = 0;
10894   u8 dst_val[6];
10895   u8 proto = 0;
10896   u16 proto_val;
10897   u8 tag1 = 0;
10898   u8 tag1_val[2];
10899   u8 tag2 = 0;
10900   u8 tag2_val[2];
10901   int len = 14;
10902   u8 ignore_tag1 = 0;
10903   u8 ignore_tag2 = 0;
10904   u8 cos1 = 0;
10905   u8 cos2 = 0;
10906   u32 cos1_val = 0;
10907   u32 cos2_val = 0;
10908
10909   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10910     {
10911       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
10912         src = 1;
10913       else
10914         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
10915         dst = 1;
10916       else if (unformat (input, "proto %U",
10917                          unformat_ethernet_type_host_byte_order, &proto_val))
10918         proto = 1;
10919       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
10920         tag1 = 1;
10921       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
10922         tag2 = 1;
10923       else if (unformat (input, "ignore-tag1"))
10924         ignore_tag1 = 1;
10925       else if (unformat (input, "ignore-tag2"))
10926         ignore_tag2 = 1;
10927       else if (unformat (input, "cos1 %d", &cos1_val))
10928         cos1 = 1;
10929       else if (unformat (input, "cos2 %d", &cos2_val))
10930         cos2 = 1;
10931       else
10932         break;
10933     }
10934   if ((src + dst + proto + tag1 + tag2 +
10935        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
10936     return 0;
10937
10938   if (tag1 || ignore_tag1 || cos1)
10939     len = 18;
10940   if (tag2 || ignore_tag2 || cos2)
10941     len = 22;
10942
10943   vec_validate_aligned (match, len - 1, sizeof (u32x4));
10944
10945   if (dst)
10946     clib_memcpy (match, dst_val, 6);
10947
10948   if (src)
10949     clib_memcpy (match + 6, src_val, 6);
10950
10951   if (tag2)
10952     {
10953       /* inner vlan tag */
10954       match[19] = tag2_val[1];
10955       match[18] = tag2_val[0];
10956       if (cos2)
10957         match[18] |= (cos2_val & 0x7) << 5;
10958       if (proto)
10959         {
10960           match[21] = proto_val & 0xff;
10961           match[20] = proto_val >> 8;
10962         }
10963       if (tag1)
10964         {
10965           match[15] = tag1_val[1];
10966           match[14] = tag1_val[0];
10967         }
10968       if (cos1)
10969         match[14] |= (cos1_val & 0x7) << 5;
10970       *matchp = match;
10971       return 1;
10972     }
10973   if (tag1)
10974     {
10975       match[15] = tag1_val[1];
10976       match[14] = tag1_val[0];
10977       if (proto)
10978         {
10979           match[17] = proto_val & 0xff;
10980           match[16] = proto_val >> 8;
10981         }
10982       if (cos1)
10983         match[14] |= (cos1_val & 0x7) << 5;
10984
10985       *matchp = match;
10986       return 1;
10987     }
10988   if (cos2)
10989     match[18] |= (cos2_val & 0x7) << 5;
10990   if (cos1)
10991     match[14] |= (cos1_val & 0x7) << 5;
10992   if (proto)
10993     {
10994       match[13] = proto_val & 0xff;
10995       match[12] = proto_val >> 8;
10996     }
10997
10998   *matchp = match;
10999   return 1;
11000 }
11001
11002 uword
11003 unformat_qos_source (unformat_input_t * input, va_list * args)
11004 {
11005   int *qs = va_arg (*args, int *);
11006
11007   if (unformat (input, "ip"))
11008     *qs = QOS_SOURCE_IP;
11009   else if (unformat (input, "mpls"))
11010     *qs = QOS_SOURCE_MPLS;
11011   else if (unformat (input, "ext"))
11012     *qs = QOS_SOURCE_EXT;
11013   else if (unformat (input, "vlan"))
11014     *qs = QOS_SOURCE_VLAN;
11015   else
11016     return 0;
11017
11018   return 1;
11019 }
11020 #endif
11021
11022 uword
11023 api_unformat_classify_match (unformat_input_t * input, va_list * args)
11024 {
11025   u8 **matchp = va_arg (*args, u8 **);
11026   u32 skip_n_vectors = va_arg (*args, u32);
11027   u32 match_n_vectors = va_arg (*args, u32);
11028
11029   u8 *match = 0;
11030   u8 *l2 = 0;
11031   u8 *l3 = 0;
11032   u8 *l4 = 0;
11033
11034   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11035     {
11036       if (unformat (input, "hex %U", unformat_hex_string, &match))
11037         ;
11038       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
11039         ;
11040       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
11041         ;
11042       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
11043         ;
11044       else
11045         break;
11046     }
11047
11048   if (l4 && !l3)
11049     {
11050       vec_free (match);
11051       vec_free (l2);
11052       vec_free (l4);
11053       return 0;
11054     }
11055
11056   if (match || l2 || l3 || l4)
11057     {
11058       if (l2 || l3 || l4)
11059         {
11060           /* "Win a free Ethernet header in every packet" */
11061           if (l2 == 0)
11062             vec_validate_aligned (l2, 13, sizeof (u32x4));
11063           match = l2;
11064           if (vec_len (l3))
11065             {
11066               vec_append_aligned (match, l3, sizeof (u32x4));
11067               vec_free (l3);
11068             }
11069           if (vec_len (l4))
11070             {
11071               vec_append_aligned (match, l4, sizeof (u32x4));
11072               vec_free (l4);
11073             }
11074         }
11075
11076       /* Make sure the vector is big enough even if key is all 0's */
11077       vec_validate_aligned
11078         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
11079          sizeof (u32x4));
11080
11081       /* Set size, include skipped vectors */
11082       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
11083
11084       *matchp = match;
11085
11086       return 1;
11087     }
11088
11089   return 0;
11090 }
11091
11092 static int
11093 api_classify_add_del_session (vat_main_t * vam)
11094 {
11095   unformat_input_t *i = vam->input;
11096   vl_api_classify_add_del_session_t *mp;
11097   int is_add = 1;
11098   u32 table_index = ~0;
11099   u32 hit_next_index = ~0;
11100   u32 opaque_index = ~0;
11101   u8 *match = 0;
11102   i32 advance = 0;
11103   u32 skip_n_vectors = 0;
11104   u32 match_n_vectors = 0;
11105   u32 action = 0;
11106   u32 metadata = 0;
11107   int ret;
11108
11109   /*
11110    * Warning: you have to supply skip_n and match_n
11111    * because the API client cant simply look at the classify
11112    * table object.
11113    */
11114
11115   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11116     {
11117       if (unformat (i, "del"))
11118         is_add = 0;
11119       else if (unformat (i, "hit-next %U", api_unformat_ip_next_index,
11120                          &hit_next_index))
11121         ;
11122       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
11123                          &hit_next_index))
11124         ;
11125       else if (unformat (i, "acl-hit-next %U", api_unformat_acl_next_index,
11126                          &hit_next_index))
11127         ;
11128       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
11129         ;
11130       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
11131         ;
11132       else if (unformat (i, "opaque-index %d", &opaque_index))
11133         ;
11134       else if (unformat (i, "skip_n %d", &skip_n_vectors))
11135         ;
11136       else if (unformat (i, "match_n %d", &match_n_vectors))
11137         ;
11138       else if (unformat (i, "match %U", api_unformat_classify_match,
11139                          &match, skip_n_vectors, match_n_vectors))
11140         ;
11141       else if (unformat (i, "advance %d", &advance))
11142         ;
11143       else if (unformat (i, "table-index %d", &table_index))
11144         ;
11145       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
11146         action = 1;
11147       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
11148         action = 2;
11149       else if (unformat (i, "action %d", &action))
11150         ;
11151       else if (unformat (i, "metadata %d", &metadata))
11152         ;
11153       else
11154         break;
11155     }
11156
11157   if (table_index == ~0)
11158     {
11159       errmsg ("Table index required");
11160       return -99;
11161     }
11162
11163   if (is_add && match == 0)
11164     {
11165       errmsg ("Match value required");
11166       return -99;
11167     }
11168
11169   M2 (CLASSIFY_ADD_DEL_SESSION, mp, vec_len (match));
11170
11171   mp->is_add = is_add;
11172   mp->table_index = ntohl (table_index);
11173   mp->hit_next_index = ntohl (hit_next_index);
11174   mp->opaque_index = ntohl (opaque_index);
11175   mp->advance = ntohl (advance);
11176   mp->action = action;
11177   mp->metadata = ntohl (metadata);
11178   mp->match_len = ntohl (vec_len (match));
11179   clib_memcpy (mp->match, match, vec_len (match));
11180   vec_free (match);
11181
11182   S (mp);
11183   W (ret);
11184   return ret;
11185 }
11186
11187 static int
11188 api_classify_set_interface_ip_table (vat_main_t * vam)
11189 {
11190   unformat_input_t *i = vam->input;
11191   vl_api_classify_set_interface_ip_table_t *mp;
11192   u32 sw_if_index;
11193   int sw_if_index_set;
11194   u32 table_index = ~0;
11195   u8 is_ipv6 = 0;
11196   int ret;
11197
11198   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11199     {
11200       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11201         sw_if_index_set = 1;
11202       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11203         sw_if_index_set = 1;
11204       else if (unformat (i, "table %d", &table_index))
11205         ;
11206       else
11207         {
11208           clib_warning ("parse error '%U'", format_unformat_error, i);
11209           return -99;
11210         }
11211     }
11212
11213   if (sw_if_index_set == 0)
11214     {
11215       errmsg ("missing interface name or sw_if_index");
11216       return -99;
11217     }
11218
11219
11220   M (CLASSIFY_SET_INTERFACE_IP_TABLE, mp);
11221
11222   mp->sw_if_index = ntohl (sw_if_index);
11223   mp->table_index = ntohl (table_index);
11224   mp->is_ipv6 = is_ipv6;
11225
11226   S (mp);
11227   W (ret);
11228   return ret;
11229 }
11230
11231 static int
11232 api_classify_set_interface_l2_tables (vat_main_t * vam)
11233 {
11234   unformat_input_t *i = vam->input;
11235   vl_api_classify_set_interface_l2_tables_t *mp;
11236   u32 sw_if_index;
11237   int sw_if_index_set;
11238   u32 ip4_table_index = ~0;
11239   u32 ip6_table_index = ~0;
11240   u32 other_table_index = ~0;
11241   u32 is_input = 1;
11242   int ret;
11243
11244   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11245     {
11246       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11247         sw_if_index_set = 1;
11248       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11249         sw_if_index_set = 1;
11250       else if (unformat (i, "ip4-table %d", &ip4_table_index))
11251         ;
11252       else if (unformat (i, "ip6-table %d", &ip6_table_index))
11253         ;
11254       else if (unformat (i, "other-table %d", &other_table_index))
11255         ;
11256       else if (unformat (i, "is-input %d", &is_input))
11257         ;
11258       else
11259         {
11260           clib_warning ("parse error '%U'", format_unformat_error, i);
11261           return -99;
11262         }
11263     }
11264
11265   if (sw_if_index_set == 0)
11266     {
11267       errmsg ("missing interface name or sw_if_index");
11268       return -99;
11269     }
11270
11271
11272   M (CLASSIFY_SET_INTERFACE_L2_TABLES, mp);
11273
11274   mp->sw_if_index = ntohl (sw_if_index);
11275   mp->ip4_table_index = ntohl (ip4_table_index);
11276   mp->ip6_table_index = ntohl (ip6_table_index);
11277   mp->other_table_index = ntohl (other_table_index);
11278   mp->is_input = (u8) is_input;
11279
11280   S (mp);
11281   W (ret);
11282   return ret;
11283 }
11284
11285 static int
11286 api_set_ipfix_exporter (vat_main_t * vam)
11287 {
11288   unformat_input_t *i = vam->input;
11289   vl_api_set_ipfix_exporter_t *mp;
11290   ip4_address_t collector_address;
11291   u8 collector_address_set = 0;
11292   u32 collector_port = ~0;
11293   ip4_address_t src_address;
11294   u8 src_address_set = 0;
11295   u32 vrf_id = ~0;
11296   u32 path_mtu = ~0;
11297   u32 template_interval = ~0;
11298   u8 udp_checksum = 0;
11299   int ret;
11300
11301   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11302     {
11303       if (unformat (i, "collector_address %U", unformat_ip4_address,
11304                     &collector_address))
11305         collector_address_set = 1;
11306       else if (unformat (i, "collector_port %d", &collector_port))
11307         ;
11308       else if (unformat (i, "src_address %U", unformat_ip4_address,
11309                          &src_address))
11310         src_address_set = 1;
11311       else if (unformat (i, "vrf_id %d", &vrf_id))
11312         ;
11313       else if (unformat (i, "path_mtu %d", &path_mtu))
11314         ;
11315       else if (unformat (i, "template_interval %d", &template_interval))
11316         ;
11317       else if (unformat (i, "udp_checksum"))
11318         udp_checksum = 1;
11319       else
11320         break;
11321     }
11322
11323   if (collector_address_set == 0)
11324     {
11325       errmsg ("collector_address required");
11326       return -99;
11327     }
11328
11329   if (src_address_set == 0)
11330     {
11331       errmsg ("src_address required");
11332       return -99;
11333     }
11334
11335   M (SET_IPFIX_EXPORTER, mp);
11336
11337   memcpy (mp->collector_address.un.ip4, collector_address.data,
11338           sizeof (collector_address.data));
11339   mp->collector_port = htons ((u16) collector_port);
11340   memcpy (mp->src_address.un.ip4, src_address.data,
11341           sizeof (src_address.data));
11342   mp->vrf_id = htonl (vrf_id);
11343   mp->path_mtu = htonl (path_mtu);
11344   mp->template_interval = htonl (template_interval);
11345   mp->udp_checksum = udp_checksum;
11346
11347   S (mp);
11348   W (ret);
11349   return ret;
11350 }
11351
11352 static int
11353 api_set_ipfix_classify_stream (vat_main_t * vam)
11354 {
11355   unformat_input_t *i = vam->input;
11356   vl_api_set_ipfix_classify_stream_t *mp;
11357   u32 domain_id = 0;
11358   u32 src_port = UDP_DST_PORT_ipfix;
11359   int ret;
11360
11361   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11362     {
11363       if (unformat (i, "domain %d", &domain_id))
11364         ;
11365       else if (unformat (i, "src_port %d", &src_port))
11366         ;
11367       else
11368         {
11369           errmsg ("unknown input `%U'", format_unformat_error, i);
11370           return -99;
11371         }
11372     }
11373
11374   M (SET_IPFIX_CLASSIFY_STREAM, mp);
11375
11376   mp->domain_id = htonl (domain_id);
11377   mp->src_port = htons ((u16) src_port);
11378
11379   S (mp);
11380   W (ret);
11381   return ret;
11382 }
11383
11384 static int
11385 api_ipfix_classify_table_add_del (vat_main_t * vam)
11386 {
11387   unformat_input_t *i = vam->input;
11388   vl_api_ipfix_classify_table_add_del_t *mp;
11389   int is_add = -1;
11390   u32 classify_table_index = ~0;
11391   u8 ip_version = 0;
11392   u8 transport_protocol = 255;
11393   int ret;
11394
11395   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11396     {
11397       if (unformat (i, "add"))
11398         is_add = 1;
11399       else if (unformat (i, "del"))
11400         is_add = 0;
11401       else if (unformat (i, "table %d", &classify_table_index))
11402         ;
11403       else if (unformat (i, "ip4"))
11404         ip_version = 4;
11405       else if (unformat (i, "ip6"))
11406         ip_version = 6;
11407       else if (unformat (i, "tcp"))
11408         transport_protocol = 6;
11409       else if (unformat (i, "udp"))
11410         transport_protocol = 17;
11411       else
11412         {
11413           errmsg ("unknown input `%U'", format_unformat_error, i);
11414           return -99;
11415         }
11416     }
11417
11418   if (is_add == -1)
11419     {
11420       errmsg ("expecting: add|del");
11421       return -99;
11422     }
11423   if (classify_table_index == ~0)
11424     {
11425       errmsg ("classifier table not specified");
11426       return -99;
11427     }
11428   if (ip_version == 0)
11429     {
11430       errmsg ("IP version not specified");
11431       return -99;
11432     }
11433
11434   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, mp);
11435
11436   mp->is_add = is_add;
11437   mp->table_id = htonl (classify_table_index);
11438   mp->ip_version = ip_version;
11439   mp->transport_protocol = transport_protocol;
11440
11441   S (mp);
11442   W (ret);
11443   return ret;
11444 }
11445
11446 static int
11447 api_get_node_index (vat_main_t * vam)
11448 {
11449   unformat_input_t *i = vam->input;
11450   vl_api_get_node_index_t *mp;
11451   u8 *name = 0;
11452   int ret;
11453
11454   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11455     {
11456       if (unformat (i, "node %s", &name))
11457         ;
11458       else
11459         break;
11460     }
11461   if (name == 0)
11462     {
11463       errmsg ("node name required");
11464       return -99;
11465     }
11466   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
11467     {
11468       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11469       return -99;
11470     }
11471
11472   M (GET_NODE_INDEX, mp);
11473   clib_memcpy (mp->node_name, name, vec_len (name));
11474   vec_free (name);
11475
11476   S (mp);
11477   W (ret);
11478   return ret;
11479 }
11480
11481 static int
11482 api_get_next_index (vat_main_t * vam)
11483 {
11484   unformat_input_t *i = vam->input;
11485   vl_api_get_next_index_t *mp;
11486   u8 *node_name = 0, *next_node_name = 0;
11487   int ret;
11488
11489   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11490     {
11491       if (unformat (i, "node-name %s", &node_name))
11492         ;
11493       else if (unformat (i, "next-node-name %s", &next_node_name))
11494         break;
11495     }
11496
11497   if (node_name == 0)
11498     {
11499       errmsg ("node name required");
11500       return -99;
11501     }
11502   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
11503     {
11504       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11505       return -99;
11506     }
11507
11508   if (next_node_name == 0)
11509     {
11510       errmsg ("next node name required");
11511       return -99;
11512     }
11513   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
11514     {
11515       errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
11516       return -99;
11517     }
11518
11519   M (GET_NEXT_INDEX, mp);
11520   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
11521   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
11522   vec_free (node_name);
11523   vec_free (next_node_name);
11524
11525   S (mp);
11526   W (ret);
11527   return ret;
11528 }
11529
11530 static int
11531 api_add_node_next (vat_main_t * vam)
11532 {
11533   unformat_input_t *i = vam->input;
11534   vl_api_add_node_next_t *mp;
11535   u8 *name = 0;
11536   u8 *next = 0;
11537   int ret;
11538
11539   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11540     {
11541       if (unformat (i, "node %s", &name))
11542         ;
11543       else if (unformat (i, "next %s", &next))
11544         ;
11545       else
11546         break;
11547     }
11548   if (name == 0)
11549     {
11550       errmsg ("node name required");
11551       return -99;
11552     }
11553   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
11554     {
11555       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11556       return -99;
11557     }
11558   if (next == 0)
11559     {
11560       errmsg ("next node required");
11561       return -99;
11562     }
11563   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
11564     {
11565       errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
11566       return -99;
11567     }
11568
11569   M (ADD_NODE_NEXT, mp);
11570   clib_memcpy (mp->node_name, name, vec_len (name));
11571   clib_memcpy (mp->next_name, next, vec_len (next));
11572   vec_free (name);
11573   vec_free (next);
11574
11575   S (mp);
11576   W (ret);
11577   return ret;
11578 }
11579
11580 static int
11581 api_l2tpv3_create_tunnel (vat_main_t * vam)
11582 {
11583   unformat_input_t *i = vam->input;
11584   ip6_address_t client_address, our_address;
11585   int client_address_set = 0;
11586   int our_address_set = 0;
11587   u32 local_session_id = 0;
11588   u32 remote_session_id = 0;
11589   u64 local_cookie = 0;
11590   u64 remote_cookie = 0;
11591   u8 l2_sublayer_present = 0;
11592   vl_api_l2tpv3_create_tunnel_t *mp;
11593   int ret;
11594
11595   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11596     {
11597       if (unformat (i, "client_address %U", unformat_ip6_address,
11598                     &client_address))
11599         client_address_set = 1;
11600       else if (unformat (i, "our_address %U", unformat_ip6_address,
11601                          &our_address))
11602         our_address_set = 1;
11603       else if (unformat (i, "local_session_id %d", &local_session_id))
11604         ;
11605       else if (unformat (i, "remote_session_id %d", &remote_session_id))
11606         ;
11607       else if (unformat (i, "local_cookie %lld", &local_cookie))
11608         ;
11609       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
11610         ;
11611       else if (unformat (i, "l2-sublayer-present"))
11612         l2_sublayer_present = 1;
11613       else
11614         break;
11615     }
11616
11617   if (client_address_set == 0)
11618     {
11619       errmsg ("client_address required");
11620       return -99;
11621     }
11622
11623   if (our_address_set == 0)
11624     {
11625       errmsg ("our_address required");
11626       return -99;
11627     }
11628
11629   M (L2TPV3_CREATE_TUNNEL, mp);
11630
11631   clib_memcpy (mp->client_address.un.ip6, client_address.as_u8,
11632                sizeof (ip6_address_t));
11633
11634   clib_memcpy (mp->our_address.un.ip6, our_address.as_u8,
11635                sizeof (ip6_address_t));
11636
11637   mp->local_session_id = ntohl (local_session_id);
11638   mp->remote_session_id = ntohl (remote_session_id);
11639   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
11640   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
11641   mp->l2_sublayer_present = l2_sublayer_present;
11642
11643   S (mp);
11644   W (ret);
11645   return ret;
11646 }
11647
11648 static int
11649 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
11650 {
11651   unformat_input_t *i = vam->input;
11652   u32 sw_if_index;
11653   u8 sw_if_index_set = 0;
11654   u64 new_local_cookie = 0;
11655   u64 new_remote_cookie = 0;
11656   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
11657   int ret;
11658
11659   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11660     {
11661       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11662         sw_if_index_set = 1;
11663       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11664         sw_if_index_set = 1;
11665       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
11666         ;
11667       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
11668         ;
11669       else
11670         break;
11671     }
11672
11673   if (sw_if_index_set == 0)
11674     {
11675       errmsg ("missing interface name or sw_if_index");
11676       return -99;
11677     }
11678
11679   M (L2TPV3_SET_TUNNEL_COOKIES, mp);
11680
11681   mp->sw_if_index = ntohl (sw_if_index);
11682   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
11683   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
11684
11685   S (mp);
11686   W (ret);
11687   return ret;
11688 }
11689
11690 static int
11691 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
11692 {
11693   unformat_input_t *i = vam->input;
11694   vl_api_l2tpv3_interface_enable_disable_t *mp;
11695   u32 sw_if_index;
11696   u8 sw_if_index_set = 0;
11697   u8 enable_disable = 1;
11698   int ret;
11699
11700   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11701     {
11702       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11703         sw_if_index_set = 1;
11704       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11705         sw_if_index_set = 1;
11706       else if (unformat (i, "enable"))
11707         enable_disable = 1;
11708       else if (unformat (i, "disable"))
11709         enable_disable = 0;
11710       else
11711         break;
11712     }
11713
11714   if (sw_if_index_set == 0)
11715     {
11716       errmsg ("missing interface name or sw_if_index");
11717       return -99;
11718     }
11719
11720   M (L2TPV3_INTERFACE_ENABLE_DISABLE, mp);
11721
11722   mp->sw_if_index = ntohl (sw_if_index);
11723   mp->enable_disable = enable_disable;
11724
11725   S (mp);
11726   W (ret);
11727   return ret;
11728 }
11729
11730 static int
11731 api_l2tpv3_set_lookup_key (vat_main_t * vam)
11732 {
11733   unformat_input_t *i = vam->input;
11734   vl_api_l2tpv3_set_lookup_key_t *mp;
11735   u8 key = ~0;
11736   int ret;
11737
11738   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11739     {
11740       if (unformat (i, "lookup_v6_src"))
11741         key = L2T_LOOKUP_SRC_ADDRESS;
11742       else if (unformat (i, "lookup_v6_dst"))
11743         key = L2T_LOOKUP_DST_ADDRESS;
11744       else if (unformat (i, "lookup_session_id"))
11745         key = L2T_LOOKUP_SESSION_ID;
11746       else
11747         break;
11748     }
11749
11750   if (key == (u8) ~ 0)
11751     {
11752       errmsg ("l2tp session lookup key unset");
11753       return -99;
11754     }
11755
11756   M (L2TPV3_SET_LOOKUP_KEY, mp);
11757
11758   mp->key = key;
11759
11760   S (mp);
11761   W (ret);
11762   return ret;
11763 }
11764
11765 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
11766   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
11767 {
11768   vat_main_t *vam = &vat_main;
11769
11770   print (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)",
11771          format_ip6_address, mp->our_address,
11772          format_ip6_address, mp->client_address,
11773          clib_net_to_host_u32 (mp->sw_if_index));
11774
11775   print (vam->ofp,
11776          "   local cookies %016llx %016llx remote cookie %016llx",
11777          clib_net_to_host_u64 (mp->local_cookie[0]),
11778          clib_net_to_host_u64 (mp->local_cookie[1]),
11779          clib_net_to_host_u64 (mp->remote_cookie));
11780
11781   print (vam->ofp, "   local session-id %d remote session-id %d",
11782          clib_net_to_host_u32 (mp->local_session_id),
11783          clib_net_to_host_u32 (mp->remote_session_id));
11784
11785   print (vam->ofp, "   l2 specific sublayer %s\n",
11786          mp->l2_sublayer_present ? "preset" : "absent");
11787
11788 }
11789
11790 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
11791   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
11792 {
11793   vat_main_t *vam = &vat_main;
11794   vat_json_node_t *node = NULL;
11795   struct in6_addr addr;
11796
11797   if (VAT_JSON_ARRAY != vam->json_tree.type)
11798     {
11799       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11800       vat_json_init_array (&vam->json_tree);
11801     }
11802   node = vat_json_array_add (&vam->json_tree);
11803
11804   vat_json_init_object (node);
11805
11806   clib_memcpy (&addr, mp->our_address.un.ip6, sizeof (addr));
11807   vat_json_object_add_ip6 (node, "our_address", addr);
11808   clib_memcpy (&addr, mp->client_address.un.ip6, sizeof (addr));
11809   vat_json_object_add_ip6 (node, "client_address", addr);
11810
11811   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
11812   vat_json_init_array (lc);
11813   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
11814   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
11815   vat_json_object_add_uint (node, "remote_cookie",
11816                             clib_net_to_host_u64 (mp->remote_cookie));
11817
11818   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
11819   vat_json_object_add_uint (node, "local_session_id",
11820                             clib_net_to_host_u32 (mp->local_session_id));
11821   vat_json_object_add_uint (node, "remote_session_id",
11822                             clib_net_to_host_u32 (mp->remote_session_id));
11823   vat_json_object_add_string_copy (node, "l2_sublayer",
11824                                    mp->l2_sublayer_present ? (u8 *) "present"
11825                                    : (u8 *) "absent");
11826 }
11827
11828 static int
11829 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
11830 {
11831   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
11832   vl_api_control_ping_t *mp_ping;
11833   int ret;
11834
11835   /* Get list of l2tpv3-tunnel interfaces */
11836   M (SW_IF_L2TPV3_TUNNEL_DUMP, mp);
11837   S (mp);
11838
11839   /* Use a control ping for synchronization */
11840   MPING (CONTROL_PING, mp_ping);
11841   S (mp_ping);
11842
11843   W (ret);
11844   return ret;
11845 }
11846
11847
11848 static void vl_api_sw_interface_tap_v2_details_t_handler
11849   (vl_api_sw_interface_tap_v2_details_t * mp)
11850 {
11851   vat_main_t *vam = &vat_main;
11852
11853   u8 *ip4 =
11854     format (0, "%U/%d", format_ip4_address, mp->host_ip4_prefix.address,
11855             mp->host_ip4_prefix.len);
11856   u8 *ip6 =
11857     format (0, "%U/%d", format_ip6_address, mp->host_ip6_prefix.address,
11858             mp->host_ip6_prefix.len);
11859
11860   print (vam->ofp,
11861          "\n%-16s %-12d %-5d %-12d %-12d %-14U %-30s %-20s %-20s %-30s 0x%-08x",
11862          mp->dev_name, ntohl (mp->sw_if_index), ntohl (mp->id),
11863          ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
11864          format_ethernet_address, mp->host_mac_addr, mp->host_namespace,
11865          mp->host_bridge, ip4, ip6, ntohl (mp->tap_flags));
11866
11867   vec_free (ip4);
11868   vec_free (ip6);
11869 }
11870
11871 static void vl_api_sw_interface_tap_v2_details_t_handler_json
11872   (vl_api_sw_interface_tap_v2_details_t * mp)
11873 {
11874   vat_main_t *vam = &vat_main;
11875   vat_json_node_t *node = NULL;
11876
11877   if (VAT_JSON_ARRAY != vam->json_tree.type)
11878     {
11879       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11880       vat_json_init_array (&vam->json_tree);
11881     }
11882   node = vat_json_array_add (&vam->json_tree);
11883
11884   vat_json_init_object (node);
11885   vat_json_object_add_uint (node, "id", ntohl (mp->id));
11886   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11887   vat_json_object_add_uint (node, "tap_flags", ntohl (mp->tap_flags));
11888   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
11889   vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
11890   vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
11891   vat_json_object_add_string_copy (node, "host_mac_addr",
11892                                    format (0, "%U", format_ethernet_address,
11893                                            &mp->host_mac_addr));
11894   vat_json_object_add_string_copy (node, "host_namespace",
11895                                    mp->host_namespace);
11896   vat_json_object_add_string_copy (node, "host_bridge", mp->host_bridge);
11897   vat_json_object_add_string_copy (node, "host_ip4_addr",
11898                                    format (0, "%U/%d", format_ip4_address,
11899                                            mp->host_ip4_prefix.address,
11900                                            mp->host_ip4_prefix.len));
11901   vat_json_object_add_string_copy (node, "host_ip6_prefix",
11902                                    format (0, "%U/%d", format_ip6_address,
11903                                            mp->host_ip6_prefix.address,
11904                                            mp->host_ip6_prefix.len));
11905
11906 }
11907
11908 static int
11909 api_sw_interface_tap_v2_dump (vat_main_t * vam)
11910 {
11911   vl_api_sw_interface_tap_v2_dump_t *mp;
11912   vl_api_control_ping_t *mp_ping;
11913   int ret;
11914
11915   print (vam->ofp,
11916          "\n%-16s %-12s %-5s %-12s %-12s %-14s %-30s %-20s %-20s %-30s",
11917          "dev_name", "sw_if_index", "id", "rx_ring_sz", "tx_ring_sz",
11918          "host_mac_addr", "host_namespace", "host_bridge", "host_ip4_addr",
11919          "host_ip6_addr");
11920
11921   /* Get list of tap interfaces */
11922   M (SW_INTERFACE_TAP_V2_DUMP, mp);
11923   S (mp);
11924
11925   /* Use a control ping for synchronization */
11926   MPING (CONTROL_PING, mp_ping);
11927   S (mp_ping);
11928
11929   W (ret);
11930   return ret;
11931 }
11932
11933 static void vl_api_sw_interface_virtio_pci_details_t_handler
11934   (vl_api_sw_interface_virtio_pci_details_t * mp)
11935 {
11936   vat_main_t *vam = &vat_main;
11937
11938   typedef union
11939   {
11940     struct
11941     {
11942       u16 domain;
11943       u8 bus;
11944       u8 slot:5;
11945       u8 function:3;
11946     };
11947     u32 as_u32;
11948   } pci_addr_t;
11949   pci_addr_t addr;
11950   addr.as_u32 = ntohl (mp->pci_addr);
11951   u8 *pci_addr = format (0, "%04x:%02x:%02x.%x", addr.domain, addr.bus,
11952                          addr.slot, addr.function);
11953
11954   print (vam->ofp,
11955          "\n%-12s %-12d %-12d %-12d %-17U 0x%-08llx",
11956          pci_addr, ntohl (mp->sw_if_index),
11957          ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
11958          format_ethernet_address, mp->mac_addr,
11959          clib_net_to_host_u64 (mp->features));
11960   vec_free (pci_addr);
11961 }
11962
11963 static void vl_api_sw_interface_virtio_pci_details_t_handler_json
11964   (vl_api_sw_interface_virtio_pci_details_t * mp)
11965 {
11966   vat_main_t *vam = &vat_main;
11967   vat_json_node_t *node = NULL;
11968
11969   if (VAT_JSON_ARRAY != vam->json_tree.type)
11970     {
11971       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11972       vat_json_init_array (&vam->json_tree);
11973     }
11974   node = vat_json_array_add (&vam->json_tree);
11975
11976   vat_json_init_object (node);
11977   vat_json_object_add_uint (node, "pci-addr", ntohl (mp->pci_addr));
11978   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11979   vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
11980   vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
11981   vat_json_object_add_uint (node, "features",
11982                             clib_net_to_host_u64 (mp->features));
11983   vat_json_object_add_string_copy (node, "mac_addr",
11984                                    format (0, "%U", format_ethernet_address,
11985                                            &mp->mac_addr));
11986 }
11987
11988 static int
11989 api_sw_interface_virtio_pci_dump (vat_main_t * vam)
11990 {
11991   vl_api_sw_interface_virtio_pci_dump_t *mp;
11992   vl_api_control_ping_t *mp_ping;
11993   int ret;
11994
11995   print (vam->ofp,
11996          "\n%-12s %-12s %-12s %-12s %-17s %-08s",
11997          "pci_addr", "sw_if_index", "rx_ring_sz", "tx_ring_sz",
11998          "mac_addr", "features");
11999
12000   /* Get list of tap interfaces */
12001   M (SW_INTERFACE_VIRTIO_PCI_DUMP, mp);
12002   S (mp);
12003
12004   /* Use a control ping for synchronization */
12005   MPING (CONTROL_PING, mp_ping);
12006   S (mp_ping);
12007
12008   W (ret);
12009   return ret;
12010 }
12011
12012 static int
12013 api_vxlan_offload_rx (vat_main_t * vam)
12014 {
12015   unformat_input_t *line_input = vam->input;
12016   vl_api_vxlan_offload_rx_t *mp;
12017   u32 hw_if_index = ~0, rx_if_index = ~0;
12018   u8 is_add = 1;
12019   int ret;
12020
12021   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12022     {
12023       if (unformat (line_input, "del"))
12024         is_add = 0;
12025       else if (unformat (line_input, "hw %U", api_unformat_hw_if_index, vam,
12026                          &hw_if_index))
12027         ;
12028       else if (unformat (line_input, "hw hw_if_index %u", &hw_if_index))
12029         ;
12030       else if (unformat (line_input, "rx %U", api_unformat_sw_if_index, vam,
12031                          &rx_if_index))
12032         ;
12033       else if (unformat (line_input, "rx sw_if_index %u", &rx_if_index))
12034         ;
12035       else
12036         {
12037           errmsg ("parse error '%U'", format_unformat_error, line_input);
12038           return -99;
12039         }
12040     }
12041
12042   if (hw_if_index == ~0)
12043     {
12044       errmsg ("no hw interface");
12045       return -99;
12046     }
12047
12048   if (rx_if_index == ~0)
12049     {
12050       errmsg ("no rx tunnel");
12051       return -99;
12052     }
12053
12054   M (VXLAN_OFFLOAD_RX, mp);
12055
12056   mp->hw_if_index = ntohl (hw_if_index);
12057   mp->sw_if_index = ntohl (rx_if_index);
12058   mp->enable = is_add;
12059
12060   S (mp);
12061   W (ret);
12062   return ret;
12063 }
12064
12065 static uword unformat_vxlan_decap_next
12066   (unformat_input_t * input, va_list * args)
12067 {
12068   u32 *result = va_arg (*args, u32 *);
12069   u32 tmp;
12070
12071   if (unformat (input, "l2"))
12072     *result = VXLAN_INPUT_NEXT_L2_INPUT;
12073   else if (unformat (input, "%d", &tmp))
12074     *result = tmp;
12075   else
12076     return 0;
12077   return 1;
12078 }
12079
12080 static int
12081 api_vxlan_add_del_tunnel (vat_main_t * vam)
12082 {
12083   unformat_input_t *line_input = vam->input;
12084   vl_api_vxlan_add_del_tunnel_t *mp;
12085   ip46_address_t src, dst;
12086   u8 is_add = 1;
12087   u8 ipv4_set = 0, ipv6_set = 0;
12088   u8 src_set = 0;
12089   u8 dst_set = 0;
12090   u8 grp_set = 0;
12091   u32 instance = ~0;
12092   u32 mcast_sw_if_index = ~0;
12093   u32 encap_vrf_id = 0;
12094   u32 decap_next_index = ~0;
12095   u32 vni = 0;
12096   int ret;
12097
12098   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
12099   clib_memset (&src, 0, sizeof src);
12100   clib_memset (&dst, 0, sizeof dst);
12101
12102   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12103     {
12104       if (unformat (line_input, "del"))
12105         is_add = 0;
12106       else if (unformat (line_input, "instance %d", &instance))
12107         ;
12108       else
12109         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
12110         {
12111           ipv4_set = 1;
12112           src_set = 1;
12113         }
12114       else
12115         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
12116         {
12117           ipv4_set = 1;
12118           dst_set = 1;
12119         }
12120       else
12121         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
12122         {
12123           ipv6_set = 1;
12124           src_set = 1;
12125         }
12126       else
12127         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
12128         {
12129           ipv6_set = 1;
12130           dst_set = 1;
12131         }
12132       else if (unformat (line_input, "group %U %U",
12133                          unformat_ip4_address, &dst.ip4,
12134                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12135         {
12136           grp_set = dst_set = 1;
12137           ipv4_set = 1;
12138         }
12139       else if (unformat (line_input, "group %U",
12140                          unformat_ip4_address, &dst.ip4))
12141         {
12142           grp_set = dst_set = 1;
12143           ipv4_set = 1;
12144         }
12145       else if (unformat (line_input, "group %U %U",
12146                          unformat_ip6_address, &dst.ip6,
12147                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12148         {
12149           grp_set = dst_set = 1;
12150           ipv6_set = 1;
12151         }
12152       else if (unformat (line_input, "group %U",
12153                          unformat_ip6_address, &dst.ip6))
12154         {
12155           grp_set = dst_set = 1;
12156           ipv6_set = 1;
12157         }
12158       else
12159         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
12160         ;
12161       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
12162         ;
12163       else if (unformat (line_input, "decap-next %U",
12164                          unformat_vxlan_decap_next, &decap_next_index))
12165         ;
12166       else if (unformat (line_input, "vni %d", &vni))
12167         ;
12168       else
12169         {
12170           errmsg ("parse error '%U'", format_unformat_error, line_input);
12171           return -99;
12172         }
12173     }
12174
12175   if (src_set == 0)
12176     {
12177       errmsg ("tunnel src address not specified");
12178       return -99;
12179     }
12180   if (dst_set == 0)
12181     {
12182       errmsg ("tunnel dst address not specified");
12183       return -99;
12184     }
12185
12186   if (grp_set && !ip46_address_is_multicast (&dst))
12187     {
12188       errmsg ("tunnel group address not multicast");
12189       return -99;
12190     }
12191   if (grp_set && mcast_sw_if_index == ~0)
12192     {
12193       errmsg ("tunnel nonexistent multicast device");
12194       return -99;
12195     }
12196   if (grp_set == 0 && ip46_address_is_multicast (&dst))
12197     {
12198       errmsg ("tunnel dst address must be unicast");
12199       return -99;
12200     }
12201
12202
12203   if (ipv4_set && ipv6_set)
12204     {
12205       errmsg ("both IPv4 and IPv6 addresses specified");
12206       return -99;
12207     }
12208
12209   if ((vni == 0) || (vni >> 24))
12210     {
12211       errmsg ("vni not specified or out of range");
12212       return -99;
12213     }
12214
12215   M (VXLAN_ADD_DEL_TUNNEL, mp);
12216
12217   if (ipv6_set)
12218     {
12219       clib_memcpy (mp->src_address, &src.ip6, sizeof (src.ip6));
12220       clib_memcpy (mp->dst_address, &dst.ip6, sizeof (dst.ip6));
12221     }
12222   else
12223     {
12224       clib_memcpy (mp->src_address, &src.ip4, sizeof (src.ip4));
12225       clib_memcpy (mp->dst_address, &dst.ip4, sizeof (dst.ip4));
12226     }
12227
12228   mp->instance = htonl (instance);
12229   mp->encap_vrf_id = ntohl (encap_vrf_id);
12230   mp->decap_next_index = ntohl (decap_next_index);
12231   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
12232   mp->vni = ntohl (vni);
12233   mp->is_add = is_add;
12234   mp->is_ipv6 = ipv6_set;
12235
12236   S (mp);
12237   W (ret);
12238   return ret;
12239 }
12240
12241 static void vl_api_vxlan_tunnel_details_t_handler
12242   (vl_api_vxlan_tunnel_details_t * mp)
12243 {
12244   vat_main_t *vam = &vat_main;
12245   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
12246   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
12247
12248   print (vam->ofp, "%11d%11d%24U%24U%14d%18d%13d%19d",
12249          ntohl (mp->sw_if_index),
12250          ntohl (mp->instance),
12251          format_ip46_address, &src, IP46_TYPE_ANY,
12252          format_ip46_address, &dst, IP46_TYPE_ANY,
12253          ntohl (mp->encap_vrf_id),
12254          ntohl (mp->decap_next_index), ntohl (mp->vni),
12255          ntohl (mp->mcast_sw_if_index));
12256 }
12257
12258 static void vl_api_vxlan_tunnel_details_t_handler_json
12259   (vl_api_vxlan_tunnel_details_t * mp)
12260 {
12261   vat_main_t *vam = &vat_main;
12262   vat_json_node_t *node = NULL;
12263
12264   if (VAT_JSON_ARRAY != vam->json_tree.type)
12265     {
12266       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12267       vat_json_init_array (&vam->json_tree);
12268     }
12269   node = vat_json_array_add (&vam->json_tree);
12270
12271   vat_json_init_object (node);
12272   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12273
12274   vat_json_object_add_uint (node, "instance", ntohl (mp->instance));
12275
12276   if (mp->is_ipv6)
12277     {
12278       struct in6_addr ip6;
12279
12280       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
12281       vat_json_object_add_ip6 (node, "src_address", ip6);
12282       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
12283       vat_json_object_add_ip6 (node, "dst_address", ip6);
12284     }
12285   else
12286     {
12287       struct in_addr ip4;
12288
12289       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
12290       vat_json_object_add_ip4 (node, "src_address", ip4);
12291       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
12292       vat_json_object_add_ip4 (node, "dst_address", ip4);
12293     }
12294   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
12295   vat_json_object_add_uint (node, "decap_next_index",
12296                             ntohl (mp->decap_next_index));
12297   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
12298   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
12299   vat_json_object_add_uint (node, "mcast_sw_if_index",
12300                             ntohl (mp->mcast_sw_if_index));
12301 }
12302
12303 static int
12304 api_vxlan_tunnel_dump (vat_main_t * vam)
12305 {
12306   unformat_input_t *i = vam->input;
12307   vl_api_vxlan_tunnel_dump_t *mp;
12308   vl_api_control_ping_t *mp_ping;
12309   u32 sw_if_index;
12310   u8 sw_if_index_set = 0;
12311   int ret;
12312
12313   /* Parse args required to build the message */
12314   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12315     {
12316       if (unformat (i, "sw_if_index %d", &sw_if_index))
12317         sw_if_index_set = 1;
12318       else
12319         break;
12320     }
12321
12322   if (sw_if_index_set == 0)
12323     {
12324       sw_if_index = ~0;
12325     }
12326
12327   if (!vam->json_output)
12328     {
12329       print (vam->ofp, "%11s%11s%24s%24s%14s%18s%13s%19s",
12330              "sw_if_index", "instance", "src_address", "dst_address",
12331              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
12332     }
12333
12334   /* Get list of vxlan-tunnel interfaces */
12335   M (VXLAN_TUNNEL_DUMP, mp);
12336
12337   mp->sw_if_index = htonl (sw_if_index);
12338
12339   S (mp);
12340
12341   /* Use a control ping for synchronization */
12342   MPING (CONTROL_PING, mp_ping);
12343   S (mp_ping);
12344
12345   W (ret);
12346   return ret;
12347 }
12348
12349 static uword unformat_geneve_decap_next
12350   (unformat_input_t * input, va_list * args)
12351 {
12352   u32 *result = va_arg (*args, u32 *);
12353   u32 tmp;
12354
12355   if (unformat (input, "l2"))
12356     *result = GENEVE_INPUT_NEXT_L2_INPUT;
12357   else if (unformat (input, "%d", &tmp))
12358     *result = tmp;
12359   else
12360     return 0;
12361   return 1;
12362 }
12363
12364 static int
12365 api_geneve_add_del_tunnel (vat_main_t * vam)
12366 {
12367   unformat_input_t *line_input = vam->input;
12368   vl_api_geneve_add_del_tunnel_t *mp;
12369   ip46_address_t src, dst;
12370   u8 is_add = 1;
12371   u8 ipv4_set = 0, ipv6_set = 0;
12372   u8 src_set = 0;
12373   u8 dst_set = 0;
12374   u8 grp_set = 0;
12375   u32 mcast_sw_if_index = ~0;
12376   u32 encap_vrf_id = 0;
12377   u32 decap_next_index = ~0;
12378   u32 vni = 0;
12379   int ret;
12380
12381   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
12382   clib_memset (&src, 0, sizeof src);
12383   clib_memset (&dst, 0, sizeof dst);
12384
12385   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12386     {
12387       if (unformat (line_input, "del"))
12388         is_add = 0;
12389       else
12390         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
12391         {
12392           ipv4_set = 1;
12393           src_set = 1;
12394         }
12395       else
12396         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
12397         {
12398           ipv4_set = 1;
12399           dst_set = 1;
12400         }
12401       else
12402         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
12403         {
12404           ipv6_set = 1;
12405           src_set = 1;
12406         }
12407       else
12408         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
12409         {
12410           ipv6_set = 1;
12411           dst_set = 1;
12412         }
12413       else if (unformat (line_input, "group %U %U",
12414                          unformat_ip4_address, &dst.ip4,
12415                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12416         {
12417           grp_set = dst_set = 1;
12418           ipv4_set = 1;
12419         }
12420       else if (unformat (line_input, "group %U",
12421                          unformat_ip4_address, &dst.ip4))
12422         {
12423           grp_set = dst_set = 1;
12424           ipv4_set = 1;
12425         }
12426       else if (unformat (line_input, "group %U %U",
12427                          unformat_ip6_address, &dst.ip6,
12428                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12429         {
12430           grp_set = dst_set = 1;
12431           ipv6_set = 1;
12432         }
12433       else if (unformat (line_input, "group %U",
12434                          unformat_ip6_address, &dst.ip6))
12435         {
12436           grp_set = dst_set = 1;
12437           ipv6_set = 1;
12438         }
12439       else
12440         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
12441         ;
12442       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
12443         ;
12444       else if (unformat (line_input, "decap-next %U",
12445                          unformat_geneve_decap_next, &decap_next_index))
12446         ;
12447       else if (unformat (line_input, "vni %d", &vni))
12448         ;
12449       else
12450         {
12451           errmsg ("parse error '%U'", format_unformat_error, line_input);
12452           return -99;
12453         }
12454     }
12455
12456   if (src_set == 0)
12457     {
12458       errmsg ("tunnel src address not specified");
12459       return -99;
12460     }
12461   if (dst_set == 0)
12462     {
12463       errmsg ("tunnel dst address not specified");
12464       return -99;
12465     }
12466
12467   if (grp_set && !ip46_address_is_multicast (&dst))
12468     {
12469       errmsg ("tunnel group address not multicast");
12470       return -99;
12471     }
12472   if (grp_set && mcast_sw_if_index == ~0)
12473     {
12474       errmsg ("tunnel nonexistent multicast device");
12475       return -99;
12476     }
12477   if (grp_set == 0 && ip46_address_is_multicast (&dst))
12478     {
12479       errmsg ("tunnel dst address must be unicast");
12480       return -99;
12481     }
12482
12483
12484   if (ipv4_set && ipv6_set)
12485     {
12486       errmsg ("both IPv4 and IPv6 addresses specified");
12487       return -99;
12488     }
12489
12490   if ((vni == 0) || (vni >> 24))
12491     {
12492       errmsg ("vni not specified or out of range");
12493       return -99;
12494     }
12495
12496   M (GENEVE_ADD_DEL_TUNNEL, mp);
12497
12498   if (ipv6_set)
12499     {
12500       clib_memcpy (&mp->local_address.un.ip6, &src.ip6, sizeof (src.ip6));
12501       clib_memcpy (&mp->remote_address.un.ip6, &dst.ip6, sizeof (dst.ip6));
12502     }
12503   else
12504     {
12505       clib_memcpy (&mp->local_address.un.ip4, &src.ip4, sizeof (src.ip4));
12506       clib_memcpy (&mp->remote_address.un.ip4, &dst.ip4, sizeof (dst.ip4));
12507     }
12508   mp->encap_vrf_id = ntohl (encap_vrf_id);
12509   mp->decap_next_index = ntohl (decap_next_index);
12510   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
12511   mp->vni = ntohl (vni);
12512   mp->is_add = is_add;
12513
12514   S (mp);
12515   W (ret);
12516   return ret;
12517 }
12518
12519 static void vl_api_geneve_tunnel_details_t_handler
12520   (vl_api_geneve_tunnel_details_t * mp)
12521 {
12522   vat_main_t *vam = &vat_main;
12523   ip46_address_t src = {.as_u64[0] = 0,.as_u64[1] = 0 };
12524   ip46_address_t dst = {.as_u64[0] = 0,.as_u64[1] = 0 };
12525
12526   if (mp->src_address.af == ADDRESS_IP6)
12527     {
12528       clib_memcpy (&src.ip6, &mp->src_address.un.ip6, sizeof (ip6_address_t));
12529       clib_memcpy (&dst.ip6, &mp->dst_address.un.ip6, sizeof (ip6_address_t));
12530     }
12531   else
12532     {
12533       clib_memcpy (&src.ip4, &mp->src_address.un.ip4, sizeof (ip4_address_t));
12534       clib_memcpy (&dst.ip4, &mp->dst_address.un.ip4, sizeof (ip4_address_t));
12535     }
12536
12537   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
12538          ntohl (mp->sw_if_index),
12539          format_ip46_address, &src, IP46_TYPE_ANY,
12540          format_ip46_address, &dst, IP46_TYPE_ANY,
12541          ntohl (mp->encap_vrf_id),
12542          ntohl (mp->decap_next_index), ntohl (mp->vni),
12543          ntohl (mp->mcast_sw_if_index));
12544 }
12545
12546 static void vl_api_geneve_tunnel_details_t_handler_json
12547   (vl_api_geneve_tunnel_details_t * mp)
12548 {
12549   vat_main_t *vam = &vat_main;
12550   vat_json_node_t *node = NULL;
12551   bool is_ipv6;
12552
12553   if (VAT_JSON_ARRAY != vam->json_tree.type)
12554     {
12555       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12556       vat_json_init_array (&vam->json_tree);
12557     }
12558   node = vat_json_array_add (&vam->json_tree);
12559
12560   vat_json_init_object (node);
12561   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12562   is_ipv6 = mp->src_address.af == ADDRESS_IP6;
12563   if (is_ipv6)
12564     {
12565       struct in6_addr ip6;
12566
12567       clib_memcpy (&ip6, &mp->src_address.un.ip6, sizeof (ip6));
12568       vat_json_object_add_ip6 (node, "src_address", ip6);
12569       clib_memcpy (&ip6, &mp->dst_address.un.ip6, sizeof (ip6));
12570       vat_json_object_add_ip6 (node, "dst_address", ip6);
12571     }
12572   else
12573     {
12574       struct in_addr ip4;
12575
12576       clib_memcpy (&ip4, &mp->src_address.un.ip4, sizeof (ip4));
12577       vat_json_object_add_ip4 (node, "src_address", ip4);
12578       clib_memcpy (&ip4, &mp->dst_address.un.ip4, sizeof (ip4));
12579       vat_json_object_add_ip4 (node, "dst_address", ip4);
12580     }
12581   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
12582   vat_json_object_add_uint (node, "decap_next_index",
12583                             ntohl (mp->decap_next_index));
12584   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
12585   vat_json_object_add_uint (node, "mcast_sw_if_index",
12586                             ntohl (mp->mcast_sw_if_index));
12587 }
12588
12589 static int
12590 api_geneve_tunnel_dump (vat_main_t * vam)
12591 {
12592   unformat_input_t *i = vam->input;
12593   vl_api_geneve_tunnel_dump_t *mp;
12594   vl_api_control_ping_t *mp_ping;
12595   u32 sw_if_index;
12596   u8 sw_if_index_set = 0;
12597   int ret;
12598
12599   /* Parse args required to build the message */
12600   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12601     {
12602       if (unformat (i, "sw_if_index %d", &sw_if_index))
12603         sw_if_index_set = 1;
12604       else
12605         break;
12606     }
12607
12608   if (sw_if_index_set == 0)
12609     {
12610       sw_if_index = ~0;
12611     }
12612
12613   if (!vam->json_output)
12614     {
12615       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
12616              "sw_if_index", "local_address", "remote_address",
12617              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
12618     }
12619
12620   /* Get list of geneve-tunnel interfaces */
12621   M (GENEVE_TUNNEL_DUMP, mp);
12622
12623   mp->sw_if_index = htonl (sw_if_index);
12624
12625   S (mp);
12626
12627   /* Use a control ping for synchronization */
12628   M (CONTROL_PING, mp_ping);
12629   S (mp_ping);
12630
12631   W (ret);
12632   return ret;
12633 }
12634
12635 static int
12636 api_gre_tunnel_add_del (vat_main_t * vam)
12637 {
12638   unformat_input_t *line_input = vam->input;
12639   vl_api_address_t src = { }, dst =
12640   {
12641   };
12642   vl_api_gre_tunnel_add_del_t *mp;
12643   vl_api_gre_tunnel_type_t t_type;
12644   u8 is_add = 1;
12645   u8 src_set = 0;
12646   u8 dst_set = 0;
12647   u32 outer_table_id = 0;
12648   u32 session_id = 0;
12649   u32 instance = ~0;
12650   int ret;
12651
12652   t_type = GRE_API_TUNNEL_TYPE_L3;
12653
12654   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12655     {
12656       if (unformat (line_input, "del"))
12657         is_add = 0;
12658       else if (unformat (line_input, "instance %d", &instance))
12659         ;
12660       else if (unformat (line_input, "src %U", unformat_vl_api_address, &src))
12661         {
12662           src_set = 1;
12663         }
12664       else if (unformat (line_input, "dst %U", unformat_vl_api_address, &dst))
12665         {
12666           dst_set = 1;
12667         }
12668       else if (unformat (line_input, "outer-table-id %d", &outer_table_id))
12669         ;
12670       else if (unformat (line_input, "teb"))
12671         t_type = GRE_API_TUNNEL_TYPE_TEB;
12672       else if (unformat (line_input, "erspan %d", &session_id))
12673         t_type = GRE_API_TUNNEL_TYPE_ERSPAN;
12674       else
12675         {
12676           errmsg ("parse error '%U'", format_unformat_error, line_input);
12677           return -99;
12678         }
12679     }
12680
12681   if (src_set == 0)
12682     {
12683       errmsg ("tunnel src address not specified");
12684       return -99;
12685     }
12686   if (dst_set == 0)
12687     {
12688       errmsg ("tunnel dst address not specified");
12689       return -99;
12690     }
12691
12692   M (GRE_TUNNEL_ADD_DEL, mp);
12693
12694   clib_memcpy (&mp->tunnel.src, &src, sizeof (mp->tunnel.src));
12695   clib_memcpy (&mp->tunnel.dst, &dst, sizeof (mp->tunnel.dst));
12696
12697   mp->tunnel.instance = htonl (instance);
12698   mp->tunnel.outer_table_id = htonl (outer_table_id);
12699   mp->is_add = is_add;
12700   mp->tunnel.session_id = htons ((u16) session_id);
12701   mp->tunnel.type = htonl (t_type);
12702
12703   S (mp);
12704   W (ret);
12705   return ret;
12706 }
12707
12708 static void vl_api_gre_tunnel_details_t_handler
12709   (vl_api_gre_tunnel_details_t * mp)
12710 {
12711   vat_main_t *vam = &vat_main;
12712
12713   print (vam->ofp, "%11d%11d%24U%24U%13d%14d%12d",
12714          ntohl (mp->tunnel.sw_if_index),
12715          ntohl (mp->tunnel.instance),
12716          format_vl_api_address, &mp->tunnel.src,
12717          format_vl_api_address, &mp->tunnel.dst,
12718          mp->tunnel.type, ntohl (mp->tunnel.outer_table_id),
12719          ntohl (mp->tunnel.session_id));
12720 }
12721
12722 static void vl_api_gre_tunnel_details_t_handler_json
12723   (vl_api_gre_tunnel_details_t * mp)
12724 {
12725   vat_main_t *vam = &vat_main;
12726   vat_json_node_t *node = NULL;
12727
12728   if (VAT_JSON_ARRAY != vam->json_tree.type)
12729     {
12730       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12731       vat_json_init_array (&vam->json_tree);
12732     }
12733   node = vat_json_array_add (&vam->json_tree);
12734
12735   vat_json_init_object (node);
12736   vat_json_object_add_uint (node, "sw_if_index",
12737                             ntohl (mp->tunnel.sw_if_index));
12738   vat_json_object_add_uint (node, "instance", ntohl (mp->tunnel.instance));
12739
12740   vat_json_object_add_address (node, "src", &mp->tunnel.src);
12741   vat_json_object_add_address (node, "dst", &mp->tunnel.dst);
12742   vat_json_object_add_uint (node, "tunnel_type", mp->tunnel.type);
12743   vat_json_object_add_uint (node, "outer_table_id",
12744                             ntohl (mp->tunnel.outer_table_id));
12745   vat_json_object_add_uint (node, "session_id", mp->tunnel.session_id);
12746 }
12747
12748 static int
12749 api_gre_tunnel_dump (vat_main_t * vam)
12750 {
12751   unformat_input_t *i = vam->input;
12752   vl_api_gre_tunnel_dump_t *mp;
12753   vl_api_control_ping_t *mp_ping;
12754   u32 sw_if_index;
12755   u8 sw_if_index_set = 0;
12756   int ret;
12757
12758   /* Parse args required to build the message */
12759   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12760     {
12761       if (unformat (i, "sw_if_index %d", &sw_if_index))
12762         sw_if_index_set = 1;
12763       else
12764         break;
12765     }
12766
12767   if (sw_if_index_set == 0)
12768     {
12769       sw_if_index = ~0;
12770     }
12771
12772   if (!vam->json_output)
12773     {
12774       print (vam->ofp, "%11s%11s%24s%24s%13s%14s%12s",
12775              "sw_if_index", "instance", "src_address", "dst_address",
12776              "tunnel_type", "outer_fib_id", "session_id");
12777     }
12778
12779   /* Get list of gre-tunnel interfaces */
12780   M (GRE_TUNNEL_DUMP, mp);
12781
12782   mp->sw_if_index = htonl (sw_if_index);
12783
12784   S (mp);
12785
12786   /* Use a control ping for synchronization */
12787   MPING (CONTROL_PING, mp_ping);
12788   S (mp_ping);
12789
12790   W (ret);
12791   return ret;
12792 }
12793
12794 static int
12795 api_l2_fib_clear_table (vat_main_t * vam)
12796 {
12797 //  unformat_input_t * i = vam->input;
12798   vl_api_l2_fib_clear_table_t *mp;
12799   int ret;
12800
12801   M (L2_FIB_CLEAR_TABLE, mp);
12802
12803   S (mp);
12804   W (ret);
12805   return ret;
12806 }
12807
12808 static int
12809 api_l2_interface_efp_filter (vat_main_t * vam)
12810 {
12811   unformat_input_t *i = vam->input;
12812   vl_api_l2_interface_efp_filter_t *mp;
12813   u32 sw_if_index;
12814   u8 enable = 1;
12815   u8 sw_if_index_set = 0;
12816   int ret;
12817
12818   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12819     {
12820       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12821         sw_if_index_set = 1;
12822       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12823         sw_if_index_set = 1;
12824       else if (unformat (i, "enable"))
12825         enable = 1;
12826       else if (unformat (i, "disable"))
12827         enable = 0;
12828       else
12829         {
12830           clib_warning ("parse error '%U'", format_unformat_error, i);
12831           return -99;
12832         }
12833     }
12834
12835   if (sw_if_index_set == 0)
12836     {
12837       errmsg ("missing sw_if_index");
12838       return -99;
12839     }
12840
12841   M (L2_INTERFACE_EFP_FILTER, mp);
12842
12843   mp->sw_if_index = ntohl (sw_if_index);
12844   mp->enable_disable = enable;
12845
12846   S (mp);
12847   W (ret);
12848   return ret;
12849 }
12850
12851 #define foreach_vtr_op                          \
12852 _("disable",  L2_VTR_DISABLED)                  \
12853 _("push-1",  L2_VTR_PUSH_1)                     \
12854 _("push-2",  L2_VTR_PUSH_2)                     \
12855 _("pop-1",  L2_VTR_POP_1)                       \
12856 _("pop-2",  L2_VTR_POP_2)                       \
12857 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
12858 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
12859 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
12860 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
12861
12862 static int
12863 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
12864 {
12865   unformat_input_t *i = vam->input;
12866   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
12867   u32 sw_if_index;
12868   u8 sw_if_index_set = 0;
12869   u8 vtr_op_set = 0;
12870   u32 vtr_op = 0;
12871   u32 push_dot1q = 1;
12872   u32 tag1 = ~0;
12873   u32 tag2 = ~0;
12874   int ret;
12875
12876   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12877     {
12878       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12879         sw_if_index_set = 1;
12880       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12881         sw_if_index_set = 1;
12882       else if (unformat (i, "vtr_op %d", &vtr_op))
12883         vtr_op_set = 1;
12884 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
12885       foreach_vtr_op
12886 #undef _
12887         else if (unformat (i, "push_dot1q %d", &push_dot1q))
12888         ;
12889       else if (unformat (i, "tag1 %d", &tag1))
12890         ;
12891       else if (unformat (i, "tag2 %d", &tag2))
12892         ;
12893       else
12894         {
12895           clib_warning ("parse error '%U'", format_unformat_error, i);
12896           return -99;
12897         }
12898     }
12899
12900   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
12901     {
12902       errmsg ("missing vtr operation or sw_if_index");
12903       return -99;
12904     }
12905
12906   M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
12907   mp->sw_if_index = ntohl (sw_if_index);
12908   mp->vtr_op = ntohl (vtr_op);
12909   mp->push_dot1q = ntohl (push_dot1q);
12910   mp->tag1 = ntohl (tag1);
12911   mp->tag2 = ntohl (tag2);
12912
12913   S (mp);
12914   W (ret);
12915   return ret;
12916 }
12917
12918 static int
12919 api_create_vhost_user_if (vat_main_t * vam)
12920 {
12921   unformat_input_t *i = vam->input;
12922   vl_api_create_vhost_user_if_t *mp;
12923   u8 *file_name;
12924   u8 is_server = 0;
12925   u8 file_name_set = 0;
12926   u32 custom_dev_instance = ~0;
12927   u8 hwaddr[6];
12928   u8 use_custom_mac = 0;
12929   u8 disable_mrg_rxbuf = 0;
12930   u8 disable_indirect_desc = 0;
12931   u8 *tag = 0;
12932   u8 enable_gso = 0;
12933   int ret;
12934
12935   /* Shut up coverity */
12936   clib_memset (hwaddr, 0, sizeof (hwaddr));
12937
12938   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12939     {
12940       if (unformat (i, "socket %s", &file_name))
12941         {
12942           file_name_set = 1;
12943         }
12944       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
12945         ;
12946       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
12947         use_custom_mac = 1;
12948       else if (unformat (i, "server"))
12949         is_server = 1;
12950       else if (unformat (i, "disable_mrg_rxbuf"))
12951         disable_mrg_rxbuf = 1;
12952       else if (unformat (i, "disable_indirect_desc"))
12953         disable_indirect_desc = 1;
12954       else if (unformat (i, "gso"))
12955         enable_gso = 1;
12956       else if (unformat (i, "tag %s", &tag))
12957         ;
12958       else
12959         break;
12960     }
12961
12962   if (file_name_set == 0)
12963     {
12964       errmsg ("missing socket file name");
12965       return -99;
12966     }
12967
12968   if (vec_len (file_name) > 255)
12969     {
12970       errmsg ("socket file name too long");
12971       return -99;
12972     }
12973   vec_add1 (file_name, 0);
12974
12975   M (CREATE_VHOST_USER_IF, mp);
12976
12977   mp->is_server = is_server;
12978   mp->disable_mrg_rxbuf = disable_mrg_rxbuf;
12979   mp->disable_indirect_desc = disable_indirect_desc;
12980   mp->enable_gso = enable_gso;
12981   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
12982   vec_free (file_name);
12983   if (custom_dev_instance != ~0)
12984     {
12985       mp->renumber = 1;
12986       mp->custom_dev_instance = ntohl (custom_dev_instance);
12987     }
12988
12989   mp->use_custom_mac = use_custom_mac;
12990   clib_memcpy (mp->mac_address, hwaddr, 6);
12991   if (tag)
12992     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
12993   vec_free (tag);
12994
12995   S (mp);
12996   W (ret);
12997   return ret;
12998 }
12999
13000 static int
13001 api_modify_vhost_user_if (vat_main_t * vam)
13002 {
13003   unformat_input_t *i = vam->input;
13004   vl_api_modify_vhost_user_if_t *mp;
13005   u8 *file_name;
13006   u8 is_server = 0;
13007   u8 file_name_set = 0;
13008   u32 custom_dev_instance = ~0;
13009   u8 sw_if_index_set = 0;
13010   u32 sw_if_index = (u32) ~ 0;
13011   u8 enable_gso = 0;
13012   int ret;
13013
13014   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13015     {
13016       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13017         sw_if_index_set = 1;
13018       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13019         sw_if_index_set = 1;
13020       else if (unformat (i, "socket %s", &file_name))
13021         {
13022           file_name_set = 1;
13023         }
13024       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
13025         ;
13026       else if (unformat (i, "server"))
13027         is_server = 1;
13028       else if (unformat (i, "gso"))
13029         enable_gso = 1;
13030       else
13031         break;
13032     }
13033
13034   if (sw_if_index_set == 0)
13035     {
13036       errmsg ("missing sw_if_index or interface name");
13037       return -99;
13038     }
13039
13040   if (file_name_set == 0)
13041     {
13042       errmsg ("missing socket file name");
13043       return -99;
13044     }
13045
13046   if (vec_len (file_name) > 255)
13047     {
13048       errmsg ("socket file name too long");
13049       return -99;
13050     }
13051   vec_add1 (file_name, 0);
13052
13053   M (MODIFY_VHOST_USER_IF, mp);
13054
13055   mp->sw_if_index = ntohl (sw_if_index);
13056   mp->is_server = is_server;
13057   mp->enable_gso = enable_gso;
13058   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
13059   vec_free (file_name);
13060   if (custom_dev_instance != ~0)
13061     {
13062       mp->renumber = 1;
13063       mp->custom_dev_instance = ntohl (custom_dev_instance);
13064     }
13065
13066   S (mp);
13067   W (ret);
13068   return ret;
13069 }
13070
13071 static int
13072 api_delete_vhost_user_if (vat_main_t * vam)
13073 {
13074   unformat_input_t *i = vam->input;
13075   vl_api_delete_vhost_user_if_t *mp;
13076   u32 sw_if_index = ~0;
13077   u8 sw_if_index_set = 0;
13078   int ret;
13079
13080   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13081     {
13082       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13083         sw_if_index_set = 1;
13084       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13085         sw_if_index_set = 1;
13086       else
13087         break;
13088     }
13089
13090   if (sw_if_index_set == 0)
13091     {
13092       errmsg ("missing sw_if_index or interface name");
13093       return -99;
13094     }
13095
13096
13097   M (DELETE_VHOST_USER_IF, mp);
13098
13099   mp->sw_if_index = ntohl (sw_if_index);
13100
13101   S (mp);
13102   W (ret);
13103   return ret;
13104 }
13105
13106 static void vl_api_sw_interface_vhost_user_details_t_handler
13107   (vl_api_sw_interface_vhost_user_details_t * mp)
13108 {
13109   vat_main_t *vam = &vat_main;
13110   u64 features;
13111
13112   features =
13113     clib_net_to_host_u32 (mp->features_first_32) | ((u64)
13114                                                     clib_net_to_host_u32
13115                                                     (mp->features_last_32) <<
13116                                                     32);
13117
13118   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s",
13119          (char *) mp->interface_name,
13120          ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
13121          features, mp->is_server,
13122          ntohl (mp->num_regions), (char *) mp->sock_filename);
13123   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
13124 }
13125
13126 static void vl_api_sw_interface_vhost_user_details_t_handler_json
13127   (vl_api_sw_interface_vhost_user_details_t * mp)
13128 {
13129   vat_main_t *vam = &vat_main;
13130   vat_json_node_t *node = NULL;
13131
13132   if (VAT_JSON_ARRAY != vam->json_tree.type)
13133     {
13134       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13135       vat_json_init_array (&vam->json_tree);
13136     }
13137   node = vat_json_array_add (&vam->json_tree);
13138
13139   vat_json_init_object (node);
13140   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13141   vat_json_object_add_string_copy (node, "interface_name",
13142                                    mp->interface_name);
13143   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
13144                             ntohl (mp->virtio_net_hdr_sz));
13145   vat_json_object_add_uint (node, "features_first_32",
13146                             clib_net_to_host_u32 (mp->features_first_32));
13147   vat_json_object_add_uint (node, "features_last_32",
13148                             clib_net_to_host_u32 (mp->features_last_32));
13149   vat_json_object_add_uint (node, "is_server", mp->is_server);
13150   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
13151   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
13152   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
13153 }
13154
13155 static int
13156 api_sw_interface_vhost_user_dump (vat_main_t * vam)
13157 {
13158   vl_api_sw_interface_vhost_user_dump_t *mp;
13159   vl_api_control_ping_t *mp_ping;
13160   int ret;
13161   print (vam->ofp,
13162          "Interface name            idx hdr_sz features server regions filename");
13163
13164   /* Get list of vhost-user interfaces */
13165   M (SW_INTERFACE_VHOST_USER_DUMP, mp);
13166   S (mp);
13167
13168   /* Use a control ping for synchronization */
13169   MPING (CONTROL_PING, mp_ping);
13170   S (mp_ping);
13171
13172   W (ret);
13173   return ret;
13174 }
13175
13176 static int
13177 api_show_version (vat_main_t * vam)
13178 {
13179   vl_api_show_version_t *mp;
13180   int ret;
13181
13182   M (SHOW_VERSION, mp);
13183
13184   S (mp);
13185   W (ret);
13186   return ret;
13187 }
13188
13189
13190 static int
13191 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
13192 {
13193   unformat_input_t *line_input = vam->input;
13194   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
13195   ip4_address_t local4, remote4;
13196   ip6_address_t local6, remote6;
13197   u8 is_add = 1;
13198   u8 ipv4_set = 0, ipv6_set = 0;
13199   u8 local_set = 0;
13200   u8 remote_set = 0;
13201   u8 grp_set = 0;
13202   u32 mcast_sw_if_index = ~0;
13203   u32 encap_vrf_id = 0;
13204   u32 decap_vrf_id = 0;
13205   u8 protocol = ~0;
13206   u32 vni;
13207   u8 vni_set = 0;
13208   int ret;
13209
13210   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
13211   clib_memset (&local4, 0, sizeof local4);
13212   clib_memset (&remote4, 0, sizeof remote4);
13213   clib_memset (&local6, 0, sizeof local6);
13214   clib_memset (&remote6, 0, sizeof remote6);
13215
13216   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13217     {
13218       if (unformat (line_input, "del"))
13219         is_add = 0;
13220       else if (unformat (line_input, "local %U",
13221                          unformat_ip4_address, &local4))
13222         {
13223           local_set = 1;
13224           ipv4_set = 1;
13225         }
13226       else if (unformat (line_input, "remote %U",
13227                          unformat_ip4_address, &remote4))
13228         {
13229           remote_set = 1;
13230           ipv4_set = 1;
13231         }
13232       else if (unformat (line_input, "local %U",
13233                          unformat_ip6_address, &local6))
13234         {
13235           local_set = 1;
13236           ipv6_set = 1;
13237         }
13238       else if (unformat (line_input, "remote %U",
13239                          unformat_ip6_address, &remote6))
13240         {
13241           remote_set = 1;
13242           ipv6_set = 1;
13243         }
13244       else if (unformat (line_input, "group %U %U",
13245                          unformat_ip4_address, &remote4,
13246                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13247         {
13248           grp_set = remote_set = 1;
13249           ipv4_set = 1;
13250         }
13251       else if (unformat (line_input, "group %U",
13252                          unformat_ip4_address, &remote4))
13253         {
13254           grp_set = remote_set = 1;
13255           ipv4_set = 1;
13256         }
13257       else if (unformat (line_input, "group %U %U",
13258                          unformat_ip6_address, &remote6,
13259                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13260         {
13261           grp_set = remote_set = 1;
13262           ipv6_set = 1;
13263         }
13264       else if (unformat (line_input, "group %U",
13265                          unformat_ip6_address, &remote6))
13266         {
13267           grp_set = remote_set = 1;
13268           ipv6_set = 1;
13269         }
13270       else
13271         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
13272         ;
13273       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
13274         ;
13275       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
13276         ;
13277       else if (unformat (line_input, "vni %d", &vni))
13278         vni_set = 1;
13279       else if (unformat (line_input, "next-ip4"))
13280         protocol = 1;
13281       else if (unformat (line_input, "next-ip6"))
13282         protocol = 2;
13283       else if (unformat (line_input, "next-ethernet"))
13284         protocol = 3;
13285       else if (unformat (line_input, "next-nsh"))
13286         protocol = 4;
13287       else
13288         {
13289           errmsg ("parse error '%U'", format_unformat_error, line_input);
13290           return -99;
13291         }
13292     }
13293
13294   if (local_set == 0)
13295     {
13296       errmsg ("tunnel local address not specified");
13297       return -99;
13298     }
13299   if (remote_set == 0)
13300     {
13301       errmsg ("tunnel remote address not specified");
13302       return -99;
13303     }
13304   if (grp_set && mcast_sw_if_index == ~0)
13305     {
13306       errmsg ("tunnel nonexistent multicast device");
13307       return -99;
13308     }
13309   if (ipv4_set && ipv6_set)
13310     {
13311       errmsg ("both IPv4 and IPv6 addresses specified");
13312       return -99;
13313     }
13314
13315   if (vni_set == 0)
13316     {
13317       errmsg ("vni not specified");
13318       return -99;
13319     }
13320
13321   M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
13322
13323
13324   if (ipv6_set)
13325     {
13326       clib_memcpy (&mp->local, &local6, sizeof (local6));
13327       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
13328     }
13329   else
13330     {
13331       clib_memcpy (&mp->local, &local4, sizeof (local4));
13332       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
13333     }
13334
13335   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
13336   mp->encap_vrf_id = ntohl (encap_vrf_id);
13337   mp->decap_vrf_id = ntohl (decap_vrf_id);
13338   mp->protocol = protocol;
13339   mp->vni = ntohl (vni);
13340   mp->is_add = is_add;
13341   mp->is_ipv6 = ipv6_set;
13342
13343   S (mp);
13344   W (ret);
13345   return ret;
13346 }
13347
13348 static void vl_api_vxlan_gpe_tunnel_details_t_handler
13349   (vl_api_vxlan_gpe_tunnel_details_t * mp)
13350 {
13351   vat_main_t *vam = &vat_main;
13352   ip46_address_t local = to_ip46 (mp->is_ipv6, mp->local);
13353   ip46_address_t remote = to_ip46 (mp->is_ipv6, mp->remote);
13354
13355   print (vam->ofp, "%11d%24U%24U%13d%12d%19d%14d%14d",
13356          ntohl (mp->sw_if_index),
13357          format_ip46_address, &local, IP46_TYPE_ANY,
13358          format_ip46_address, &remote, IP46_TYPE_ANY,
13359          ntohl (mp->vni), mp->protocol,
13360          ntohl (mp->mcast_sw_if_index),
13361          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
13362 }
13363
13364
13365 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
13366   (vl_api_vxlan_gpe_tunnel_details_t * mp)
13367 {
13368   vat_main_t *vam = &vat_main;
13369   vat_json_node_t *node = NULL;
13370   struct in_addr ip4;
13371   struct in6_addr ip6;
13372
13373   if (VAT_JSON_ARRAY != vam->json_tree.type)
13374     {
13375       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13376       vat_json_init_array (&vam->json_tree);
13377     }
13378   node = vat_json_array_add (&vam->json_tree);
13379
13380   vat_json_init_object (node);
13381   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13382   if (mp->is_ipv6)
13383     {
13384       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
13385       vat_json_object_add_ip6 (node, "local", ip6);
13386       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
13387       vat_json_object_add_ip6 (node, "remote", ip6);
13388     }
13389   else
13390     {
13391       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
13392       vat_json_object_add_ip4 (node, "local", ip4);
13393       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
13394       vat_json_object_add_ip4 (node, "remote", ip4);
13395     }
13396   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
13397   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
13398   vat_json_object_add_uint (node, "mcast_sw_if_index",
13399                             ntohl (mp->mcast_sw_if_index));
13400   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
13401   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
13402   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
13403 }
13404
13405 static int
13406 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
13407 {
13408   unformat_input_t *i = vam->input;
13409   vl_api_vxlan_gpe_tunnel_dump_t *mp;
13410   vl_api_control_ping_t *mp_ping;
13411   u32 sw_if_index;
13412   u8 sw_if_index_set = 0;
13413   int ret;
13414
13415   /* Parse args required to build the message */
13416   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13417     {
13418       if (unformat (i, "sw_if_index %d", &sw_if_index))
13419         sw_if_index_set = 1;
13420       else
13421         break;
13422     }
13423
13424   if (sw_if_index_set == 0)
13425     {
13426       sw_if_index = ~0;
13427     }
13428
13429   if (!vam->json_output)
13430     {
13431       print (vam->ofp, "%11s%24s%24s%13s%15s%19s%14s%14s",
13432              "sw_if_index", "local", "remote", "vni",
13433              "protocol", "mcast_sw_if_index", "encap_vrf_id", "decap_vrf_id");
13434     }
13435
13436   /* Get list of vxlan-tunnel interfaces */
13437   M (VXLAN_GPE_TUNNEL_DUMP, mp);
13438
13439   mp->sw_if_index = htonl (sw_if_index);
13440
13441   S (mp);
13442
13443   /* Use a control ping for synchronization */
13444   MPING (CONTROL_PING, mp_ping);
13445   S (mp_ping);
13446
13447   W (ret);
13448   return ret;
13449 }
13450
13451 static void vl_api_l2_fib_table_details_t_handler
13452   (vl_api_l2_fib_table_details_t * mp)
13453 {
13454   vat_main_t *vam = &vat_main;
13455
13456   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
13457          "       %d       %d     %d",
13458          ntohl (mp->bd_id), format_ethernet_address, mp->mac,
13459          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
13460          mp->bvi_mac);
13461 }
13462
13463 static void vl_api_l2_fib_table_details_t_handler_json
13464   (vl_api_l2_fib_table_details_t * mp)
13465 {
13466   vat_main_t *vam = &vat_main;
13467   vat_json_node_t *node = NULL;
13468
13469   if (VAT_JSON_ARRAY != vam->json_tree.type)
13470     {
13471       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13472       vat_json_init_array (&vam->json_tree);
13473     }
13474   node = vat_json_array_add (&vam->json_tree);
13475
13476   vat_json_init_object (node);
13477   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
13478   vat_json_object_add_bytes (node, "mac", mp->mac, 6);
13479   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13480   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
13481   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
13482   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
13483 }
13484
13485 static int
13486 api_l2_fib_table_dump (vat_main_t * vam)
13487 {
13488   unformat_input_t *i = vam->input;
13489   vl_api_l2_fib_table_dump_t *mp;
13490   vl_api_control_ping_t *mp_ping;
13491   u32 bd_id;
13492   u8 bd_id_set = 0;
13493   int ret;
13494
13495   /* Parse args required to build the message */
13496   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13497     {
13498       if (unformat (i, "bd_id %d", &bd_id))
13499         bd_id_set = 1;
13500       else
13501         break;
13502     }
13503
13504   if (bd_id_set == 0)
13505     {
13506       errmsg ("missing bridge domain");
13507       return -99;
13508     }
13509
13510   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
13511
13512   /* Get list of l2 fib entries */
13513   M (L2_FIB_TABLE_DUMP, mp);
13514
13515   mp->bd_id = ntohl (bd_id);
13516   S (mp);
13517
13518   /* Use a control ping for synchronization */
13519   MPING (CONTROL_PING, mp_ping);
13520   S (mp_ping);
13521
13522   W (ret);
13523   return ret;
13524 }
13525
13526
13527 static int
13528 api_interface_name_renumber (vat_main_t * vam)
13529 {
13530   unformat_input_t *line_input = vam->input;
13531   vl_api_interface_name_renumber_t *mp;
13532   u32 sw_if_index = ~0;
13533   u32 new_show_dev_instance = ~0;
13534   int ret;
13535
13536   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13537     {
13538       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
13539                     &sw_if_index))
13540         ;
13541       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
13542         ;
13543       else if (unformat (line_input, "new_show_dev_instance %d",
13544                          &new_show_dev_instance))
13545         ;
13546       else
13547         break;
13548     }
13549
13550   if (sw_if_index == ~0)
13551     {
13552       errmsg ("missing interface name or sw_if_index");
13553       return -99;
13554     }
13555
13556   if (new_show_dev_instance == ~0)
13557     {
13558       errmsg ("missing new_show_dev_instance");
13559       return -99;
13560     }
13561
13562   M (INTERFACE_NAME_RENUMBER, mp);
13563
13564   mp->sw_if_index = ntohl (sw_if_index);
13565   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
13566
13567   S (mp);
13568   W (ret);
13569   return ret;
13570 }
13571
13572 static int
13573 api_ip_probe_neighbor (vat_main_t * vam)
13574 {
13575   unformat_input_t *i = vam->input;
13576   vl_api_ip_probe_neighbor_t *mp;
13577   vl_api_address_t dst_adr = { };
13578   u8 int_set = 0;
13579   u8 adr_set = 0;
13580   u32 sw_if_index;
13581   int ret;
13582
13583   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13584     {
13585       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13586         int_set = 1;
13587       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13588         int_set = 1;
13589       else if (unformat (i, "address %U", unformat_vl_api_address, &dst_adr))
13590         adr_set = 1;
13591       else
13592         break;
13593     }
13594
13595   if (int_set == 0)
13596     {
13597       errmsg ("missing interface");
13598       return -99;
13599     }
13600
13601   if (adr_set == 0)
13602     {
13603       errmsg ("missing addresses");
13604       return -99;
13605     }
13606
13607   M (IP_PROBE_NEIGHBOR, mp);
13608
13609   mp->sw_if_index = ntohl (sw_if_index);
13610   clib_memcpy (&mp->dst, &dst_adr, sizeof (dst_adr));
13611
13612   S (mp);
13613   W (ret);
13614   return ret;
13615 }
13616
13617 static int
13618 api_ip_scan_neighbor_enable_disable (vat_main_t * vam)
13619 {
13620   unformat_input_t *i = vam->input;
13621   vl_api_ip_scan_neighbor_enable_disable_t *mp;
13622   u8 mode = IP_SCAN_V46_NEIGHBORS;
13623   u32 interval = 0, time = 0, update = 0, delay = 0, stale = 0;
13624   int ret;
13625
13626   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13627     {
13628       if (unformat (i, "ip4"))
13629         mode = IP_SCAN_V4_NEIGHBORS;
13630       else if (unformat (i, "ip6"))
13631         mode = IP_SCAN_V6_NEIGHBORS;
13632       if (unformat (i, "both"))
13633         mode = IP_SCAN_V46_NEIGHBORS;
13634       else if (unformat (i, "disable"))
13635         mode = IP_SCAN_DISABLED;
13636       else if (unformat (i, "interval %d", &interval))
13637         ;
13638       else if (unformat (i, "max-time %d", &time))
13639         ;
13640       else if (unformat (i, "max-update %d", &update))
13641         ;
13642       else if (unformat (i, "delay %d", &delay))
13643         ;
13644       else if (unformat (i, "stale %d", &stale))
13645         ;
13646       else
13647         break;
13648     }
13649
13650   if (interval > 255)
13651     {
13652       errmsg ("interval cannot exceed 255 minutes.");
13653       return -99;
13654     }
13655   if (time > 255)
13656     {
13657       errmsg ("max-time cannot exceed 255 usec.");
13658       return -99;
13659     }
13660   if (update > 255)
13661     {
13662       errmsg ("max-update cannot exceed 255.");
13663       return -99;
13664     }
13665   if (delay > 255)
13666     {
13667       errmsg ("delay cannot exceed 255 msec.");
13668       return -99;
13669     }
13670   if (stale > 255)
13671     {
13672       errmsg ("stale cannot exceed 255 minutes.");
13673       return -99;
13674     }
13675
13676   M (IP_SCAN_NEIGHBOR_ENABLE_DISABLE, mp);
13677   mp->mode = mode;
13678   mp->scan_interval = interval;
13679   mp->max_proc_time = time;
13680   mp->max_update = update;
13681   mp->scan_int_delay = delay;
13682   mp->stale_threshold = stale;
13683
13684   S (mp);
13685   W (ret);
13686   return ret;
13687 }
13688
13689 static int
13690 api_want_ip4_arp_events (vat_main_t * vam)
13691 {
13692   unformat_input_t *line_input = vam->input;
13693   vl_api_want_ip4_arp_events_t *mp;
13694   ip4_address_t address;
13695   int address_set = 0;
13696   u32 enable_disable = 1;
13697   int ret;
13698
13699   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13700     {
13701       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
13702         address_set = 1;
13703       else if (unformat (line_input, "del"))
13704         enable_disable = 0;
13705       else
13706         break;
13707     }
13708
13709   if (address_set == 0)
13710     {
13711       errmsg ("missing addresses");
13712       return -99;
13713     }
13714
13715   M (WANT_IP4_ARP_EVENTS, mp);
13716   mp->enable_disable = enable_disable;
13717   mp->pid = htonl (getpid ());
13718   clib_memcpy (mp->ip, &address, sizeof (address));
13719
13720   S (mp);
13721   W (ret);
13722   return ret;
13723 }
13724
13725 static int
13726 api_want_ip6_nd_events (vat_main_t * vam)
13727 {
13728   unformat_input_t *line_input = vam->input;
13729   vl_api_want_ip6_nd_events_t *mp;
13730   vl_api_ip6_address_t address;
13731   int address_set = 0;
13732   u32 enable_disable = 1;
13733   int ret;
13734
13735   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13736     {
13737       if (unformat
13738           (line_input, "address %U", unformat_vl_api_ip6_address, &address))
13739         address_set = 1;
13740       else if (unformat (line_input, "del"))
13741         enable_disable = 0;
13742       else
13743         break;
13744     }
13745
13746   if (address_set == 0)
13747     {
13748       errmsg ("missing addresses");
13749       return -99;
13750     }
13751
13752   M (WANT_IP6_ND_EVENTS, mp);
13753   mp->enable_disable = enable_disable;
13754   mp->pid = htonl (getpid ());
13755   clib_memcpy (&mp->ip, &address, sizeof (address));
13756
13757   S (mp);
13758   W (ret);
13759   return ret;
13760 }
13761
13762 static int
13763 api_want_l2_macs_events (vat_main_t * vam)
13764 {
13765   unformat_input_t *line_input = vam->input;
13766   vl_api_want_l2_macs_events_t *mp;
13767   u8 enable_disable = 1;
13768   u32 scan_delay = 0;
13769   u32 max_macs_in_event = 0;
13770   u32 learn_limit = 0;
13771   int ret;
13772
13773   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13774     {
13775       if (unformat (line_input, "learn-limit %d", &learn_limit))
13776         ;
13777       else if (unformat (line_input, "scan-delay %d", &scan_delay))
13778         ;
13779       else if (unformat (line_input, "max-entries %d", &max_macs_in_event))
13780         ;
13781       else if (unformat (line_input, "disable"))
13782         enable_disable = 0;
13783       else
13784         break;
13785     }
13786
13787   M (WANT_L2_MACS_EVENTS, mp);
13788   mp->enable_disable = enable_disable;
13789   mp->pid = htonl (getpid ());
13790   mp->learn_limit = htonl (learn_limit);
13791   mp->scan_delay = (u8) scan_delay;
13792   mp->max_macs_in_event = (u8) (max_macs_in_event / 10);
13793   S (mp);
13794   W (ret);
13795   return ret;
13796 }
13797
13798 static int
13799 api_input_acl_set_interface (vat_main_t * vam)
13800 {
13801   unformat_input_t *i = vam->input;
13802   vl_api_input_acl_set_interface_t *mp;
13803   u32 sw_if_index;
13804   int sw_if_index_set;
13805   u32 ip4_table_index = ~0;
13806   u32 ip6_table_index = ~0;
13807   u32 l2_table_index = ~0;
13808   u8 is_add = 1;
13809   int ret;
13810
13811   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13812     {
13813       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13814         sw_if_index_set = 1;
13815       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13816         sw_if_index_set = 1;
13817       else if (unformat (i, "del"))
13818         is_add = 0;
13819       else if (unformat (i, "ip4-table %d", &ip4_table_index))
13820         ;
13821       else if (unformat (i, "ip6-table %d", &ip6_table_index))
13822         ;
13823       else if (unformat (i, "l2-table %d", &l2_table_index))
13824         ;
13825       else
13826         {
13827           clib_warning ("parse error '%U'", format_unformat_error, i);
13828           return -99;
13829         }
13830     }
13831
13832   if (sw_if_index_set == 0)
13833     {
13834       errmsg ("missing interface name or sw_if_index");
13835       return -99;
13836     }
13837
13838   M (INPUT_ACL_SET_INTERFACE, mp);
13839
13840   mp->sw_if_index = ntohl (sw_if_index);
13841   mp->ip4_table_index = ntohl (ip4_table_index);
13842   mp->ip6_table_index = ntohl (ip6_table_index);
13843   mp->l2_table_index = ntohl (l2_table_index);
13844   mp->is_add = is_add;
13845
13846   S (mp);
13847   W (ret);
13848   return ret;
13849 }
13850
13851 static int
13852 api_output_acl_set_interface (vat_main_t * vam)
13853 {
13854   unformat_input_t *i = vam->input;
13855   vl_api_output_acl_set_interface_t *mp;
13856   u32 sw_if_index;
13857   int sw_if_index_set;
13858   u32 ip4_table_index = ~0;
13859   u32 ip6_table_index = ~0;
13860   u32 l2_table_index = ~0;
13861   u8 is_add = 1;
13862   int ret;
13863
13864   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13865     {
13866       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13867         sw_if_index_set = 1;
13868       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13869         sw_if_index_set = 1;
13870       else if (unformat (i, "del"))
13871         is_add = 0;
13872       else if (unformat (i, "ip4-table %d", &ip4_table_index))
13873         ;
13874       else if (unformat (i, "ip6-table %d", &ip6_table_index))
13875         ;
13876       else if (unformat (i, "l2-table %d", &l2_table_index))
13877         ;
13878       else
13879         {
13880           clib_warning ("parse error '%U'", format_unformat_error, i);
13881           return -99;
13882         }
13883     }
13884
13885   if (sw_if_index_set == 0)
13886     {
13887       errmsg ("missing interface name or sw_if_index");
13888       return -99;
13889     }
13890
13891   M (OUTPUT_ACL_SET_INTERFACE, mp);
13892
13893   mp->sw_if_index = ntohl (sw_if_index);
13894   mp->ip4_table_index = ntohl (ip4_table_index);
13895   mp->ip6_table_index = ntohl (ip6_table_index);
13896   mp->l2_table_index = ntohl (l2_table_index);
13897   mp->is_add = is_add;
13898
13899   S (mp);
13900   W (ret);
13901   return ret;
13902 }
13903
13904 static int
13905 api_ip_address_dump (vat_main_t * vam)
13906 {
13907   unformat_input_t *i = vam->input;
13908   vl_api_ip_address_dump_t *mp;
13909   vl_api_control_ping_t *mp_ping;
13910   u32 sw_if_index = ~0;
13911   u8 sw_if_index_set = 0;
13912   u8 ipv4_set = 0;
13913   u8 ipv6_set = 0;
13914   int ret;
13915
13916   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13917     {
13918       if (unformat (i, "sw_if_index %d", &sw_if_index))
13919         sw_if_index_set = 1;
13920       else
13921         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13922         sw_if_index_set = 1;
13923       else if (unformat (i, "ipv4"))
13924         ipv4_set = 1;
13925       else if (unformat (i, "ipv6"))
13926         ipv6_set = 1;
13927       else
13928         break;
13929     }
13930
13931   if (ipv4_set && ipv6_set)
13932     {
13933       errmsg ("ipv4 and ipv6 flags cannot be both set");
13934       return -99;
13935     }
13936
13937   if ((!ipv4_set) && (!ipv6_set))
13938     {
13939       errmsg ("no ipv4 nor ipv6 flag set");
13940       return -99;
13941     }
13942
13943   if (sw_if_index_set == 0)
13944     {
13945       errmsg ("missing interface name or sw_if_index");
13946       return -99;
13947     }
13948
13949   vam->current_sw_if_index = sw_if_index;
13950   vam->is_ipv6 = ipv6_set;
13951
13952   M (IP_ADDRESS_DUMP, mp);
13953   mp->sw_if_index = ntohl (sw_if_index);
13954   mp->is_ipv6 = ipv6_set;
13955   S (mp);
13956
13957   /* Use a control ping for synchronization */
13958   MPING (CONTROL_PING, mp_ping);
13959   S (mp_ping);
13960
13961   W (ret);
13962   return ret;
13963 }
13964
13965 static int
13966 api_ip_dump (vat_main_t * vam)
13967 {
13968   vl_api_ip_dump_t *mp;
13969   vl_api_control_ping_t *mp_ping;
13970   unformat_input_t *in = vam->input;
13971   int ipv4_set = 0;
13972   int ipv6_set = 0;
13973   int is_ipv6;
13974   int i;
13975   int ret;
13976
13977   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
13978     {
13979       if (unformat (in, "ipv4"))
13980         ipv4_set = 1;
13981       else if (unformat (in, "ipv6"))
13982         ipv6_set = 1;
13983       else
13984         break;
13985     }
13986
13987   if (ipv4_set && ipv6_set)
13988     {
13989       errmsg ("ipv4 and ipv6 flags cannot be both set");
13990       return -99;
13991     }
13992
13993   if ((!ipv4_set) && (!ipv6_set))
13994     {
13995       errmsg ("no ipv4 nor ipv6 flag set");
13996       return -99;
13997     }
13998
13999   is_ipv6 = ipv6_set;
14000   vam->is_ipv6 = is_ipv6;
14001
14002   /* free old data */
14003   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
14004     {
14005       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
14006     }
14007   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
14008
14009   M (IP_DUMP, mp);
14010   mp->is_ipv6 = ipv6_set;
14011   S (mp);
14012
14013   /* Use a control ping for synchronization */
14014   MPING (CONTROL_PING, mp_ping);
14015   S (mp_ping);
14016
14017   W (ret);
14018   return ret;
14019 }
14020
14021 static int
14022 api_ipsec_spd_add_del (vat_main_t * vam)
14023 {
14024   unformat_input_t *i = vam->input;
14025   vl_api_ipsec_spd_add_del_t *mp;
14026   u32 spd_id = ~0;
14027   u8 is_add = 1;
14028   int ret;
14029
14030   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14031     {
14032       if (unformat (i, "spd_id %d", &spd_id))
14033         ;
14034       else if (unformat (i, "del"))
14035         is_add = 0;
14036       else
14037         {
14038           clib_warning ("parse error '%U'", format_unformat_error, i);
14039           return -99;
14040         }
14041     }
14042   if (spd_id == ~0)
14043     {
14044       errmsg ("spd_id must be set");
14045       return -99;
14046     }
14047
14048   M (IPSEC_SPD_ADD_DEL, mp);
14049
14050   mp->spd_id = ntohl (spd_id);
14051   mp->is_add = is_add;
14052
14053   S (mp);
14054   W (ret);
14055   return ret;
14056 }
14057
14058 static int
14059 api_ipsec_interface_add_del_spd (vat_main_t * vam)
14060 {
14061   unformat_input_t *i = vam->input;
14062   vl_api_ipsec_interface_add_del_spd_t *mp;
14063   u32 sw_if_index;
14064   u8 sw_if_index_set = 0;
14065   u32 spd_id = (u32) ~ 0;
14066   u8 is_add = 1;
14067   int ret;
14068
14069   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14070     {
14071       if (unformat (i, "del"))
14072         is_add = 0;
14073       else if (unformat (i, "spd_id %d", &spd_id))
14074         ;
14075       else
14076         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14077         sw_if_index_set = 1;
14078       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14079         sw_if_index_set = 1;
14080       else
14081         {
14082           clib_warning ("parse error '%U'", format_unformat_error, i);
14083           return -99;
14084         }
14085
14086     }
14087
14088   if (spd_id == (u32) ~ 0)
14089     {
14090       errmsg ("spd_id must be set");
14091       return -99;
14092     }
14093
14094   if (sw_if_index_set == 0)
14095     {
14096       errmsg ("missing interface name or sw_if_index");
14097       return -99;
14098     }
14099
14100   M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
14101
14102   mp->spd_id = ntohl (spd_id);
14103   mp->sw_if_index = ntohl (sw_if_index);
14104   mp->is_add = is_add;
14105
14106   S (mp);
14107   W (ret);
14108   return ret;
14109 }
14110
14111 static int
14112 api_ipsec_spd_entry_add_del (vat_main_t * vam)
14113 {
14114   unformat_input_t *i = vam->input;
14115   vl_api_ipsec_spd_entry_add_del_t *mp;
14116   u8 is_add = 1, is_outbound = 0;
14117   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
14118   i32 priority = 0;
14119   u32 rport_start = 0, rport_stop = (u32) ~ 0;
14120   u32 lport_start = 0, lport_stop = (u32) ~ 0;
14121   vl_api_address_t laddr_start = { }, laddr_stop =
14122   {
14123   }, raddr_start =
14124   {
14125   }, raddr_stop =
14126   {
14127   };
14128   int ret;
14129
14130   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14131     {
14132       if (unformat (i, "del"))
14133         is_add = 0;
14134       if (unformat (i, "outbound"))
14135         is_outbound = 1;
14136       if (unformat (i, "inbound"))
14137         is_outbound = 0;
14138       else if (unformat (i, "spd_id %d", &spd_id))
14139         ;
14140       else if (unformat (i, "sa_id %d", &sa_id))
14141         ;
14142       else if (unformat (i, "priority %d", &priority))
14143         ;
14144       else if (unformat (i, "protocol %d", &protocol))
14145         ;
14146       else if (unformat (i, "lport_start %d", &lport_start))
14147         ;
14148       else if (unformat (i, "lport_stop %d", &lport_stop))
14149         ;
14150       else if (unformat (i, "rport_start %d", &rport_start))
14151         ;
14152       else if (unformat (i, "rport_stop %d", &rport_stop))
14153         ;
14154       else if (unformat (i, "laddr_start %U",
14155                          unformat_vl_api_address, &laddr_start))
14156         ;
14157       else if (unformat (i, "laddr_stop %U", unformat_vl_api_address,
14158                          &laddr_stop))
14159         ;
14160       else if (unformat (i, "raddr_start %U", unformat_vl_api_address,
14161                          &raddr_start))
14162         ;
14163       else if (unformat (i, "raddr_stop %U", unformat_vl_api_address,
14164                          &raddr_stop))
14165         ;
14166       else
14167         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
14168         {
14169           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
14170             {
14171               clib_warning ("unsupported action: 'resolve'");
14172               return -99;
14173             }
14174         }
14175       else
14176         {
14177           clib_warning ("parse error '%U'", format_unformat_error, i);
14178           return -99;
14179         }
14180
14181     }
14182
14183   M (IPSEC_SPD_ENTRY_ADD_DEL, mp);
14184
14185   mp->is_add = is_add;
14186
14187   mp->entry.spd_id = ntohl (spd_id);
14188   mp->entry.priority = ntohl (priority);
14189   mp->entry.is_outbound = is_outbound;
14190
14191   clib_memcpy (&mp->entry.remote_address_start, &raddr_start,
14192                sizeof (vl_api_address_t));
14193   clib_memcpy (&mp->entry.remote_address_stop, &raddr_stop,
14194                sizeof (vl_api_address_t));
14195   clib_memcpy (&mp->entry.local_address_start, &laddr_start,
14196                sizeof (vl_api_address_t));
14197   clib_memcpy (&mp->entry.local_address_stop, &laddr_stop,
14198                sizeof (vl_api_address_t));
14199
14200   mp->entry.protocol = (u8) protocol;
14201   mp->entry.local_port_start = ntohs ((u16) lport_start);
14202   mp->entry.local_port_stop = ntohs ((u16) lport_stop);
14203   mp->entry.remote_port_start = ntohs ((u16) rport_start);
14204   mp->entry.remote_port_stop = ntohs ((u16) rport_stop);
14205   mp->entry.policy = (u8) policy;
14206   mp->entry.sa_id = ntohl (sa_id);
14207
14208   S (mp);
14209   W (ret);
14210   return ret;
14211 }
14212
14213 static int
14214 api_ipsec_sad_entry_add_del (vat_main_t * vam)
14215 {
14216   unformat_input_t *i = vam->input;
14217   vl_api_ipsec_sad_entry_add_del_t *mp;
14218   u32 sad_id = 0, spi = 0;
14219   u8 *ck = 0, *ik = 0;
14220   u8 is_add = 1;
14221
14222   vl_api_ipsec_crypto_alg_t crypto_alg = IPSEC_API_CRYPTO_ALG_NONE;
14223   vl_api_ipsec_integ_alg_t integ_alg = IPSEC_API_INTEG_ALG_NONE;
14224   vl_api_ipsec_sad_flags_t flags = IPSEC_API_SAD_FLAG_NONE;
14225   vl_api_ipsec_proto_t protocol = IPSEC_API_PROTO_AH;
14226   vl_api_address_t tun_src, tun_dst;
14227   int ret;
14228
14229   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14230     {
14231       if (unformat (i, "del"))
14232         is_add = 0;
14233       else if (unformat (i, "sad_id %d", &sad_id))
14234         ;
14235       else if (unformat (i, "spi %d", &spi))
14236         ;
14237       else if (unformat (i, "esp"))
14238         protocol = IPSEC_API_PROTO_ESP;
14239       else
14240         if (unformat (i, "tunnel_src %U", unformat_vl_api_address, &tun_src))
14241         {
14242           flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL;
14243           if (ADDRESS_IP6 == tun_src.af)
14244             flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL_V6;
14245         }
14246       else
14247         if (unformat (i, "tunnel_dst %U", unformat_vl_api_address, &tun_dst))
14248         {
14249           flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL;
14250           if (ADDRESS_IP6 == tun_src.af)
14251             flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL_V6;
14252         }
14253       else
14254         if (unformat (i, "crypto_alg %U",
14255                       unformat_ipsec_api_crypto_alg, &crypto_alg))
14256         ;
14257       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
14258         ;
14259       else if (unformat (i, "integ_alg %U",
14260                          unformat_ipsec_api_integ_alg, &integ_alg))
14261         ;
14262       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
14263         ;
14264       else
14265         {
14266           clib_warning ("parse error '%U'", format_unformat_error, i);
14267           return -99;
14268         }
14269
14270     }
14271
14272   M (IPSEC_SAD_ENTRY_ADD_DEL, mp);
14273
14274   mp->is_add = is_add;
14275   mp->entry.sad_id = ntohl (sad_id);
14276   mp->entry.protocol = protocol;
14277   mp->entry.spi = ntohl (spi);
14278   mp->entry.flags = flags;
14279
14280   mp->entry.crypto_algorithm = crypto_alg;
14281   mp->entry.integrity_algorithm = integ_alg;
14282   mp->entry.crypto_key.length = vec_len (ck);
14283   mp->entry.integrity_key.length = vec_len (ik);
14284
14285   if (mp->entry.crypto_key.length > sizeof (mp->entry.crypto_key.data))
14286     mp->entry.crypto_key.length = sizeof (mp->entry.crypto_key.data);
14287
14288   if (mp->entry.integrity_key.length > sizeof (mp->entry.integrity_key.data))
14289     mp->entry.integrity_key.length = sizeof (mp->entry.integrity_key.data);
14290
14291   if (ck)
14292     clib_memcpy (mp->entry.crypto_key.data, ck, mp->entry.crypto_key.length);
14293   if (ik)
14294     clib_memcpy (mp->entry.integrity_key.data, ik,
14295                  mp->entry.integrity_key.length);
14296
14297   if (flags & IPSEC_API_SAD_FLAG_IS_TUNNEL)
14298     {
14299       clib_memcpy (&mp->entry.tunnel_src, &tun_src,
14300                    sizeof (mp->entry.tunnel_src));
14301       clib_memcpy (&mp->entry.tunnel_dst, &tun_dst,
14302                    sizeof (mp->entry.tunnel_dst));
14303     }
14304
14305   S (mp);
14306   W (ret);
14307   return ret;
14308 }
14309
14310 static int
14311 api_ipsec_tunnel_if_add_del (vat_main_t * vam)
14312 {
14313   unformat_input_t *i = vam->input;
14314   vl_api_ipsec_tunnel_if_add_del_t *mp;
14315   u32 local_spi = 0, remote_spi = 0;
14316   u32 crypto_alg = 0, integ_alg = 0;
14317   u8 *lck = NULL, *rck = NULL;
14318   u8 *lik = NULL, *rik = NULL;
14319   vl_api_address_t local_ip = { 0 };
14320   vl_api_address_t remote_ip = { 0 };
14321   f64 before = 0;
14322   u8 is_add = 1;
14323   u8 esn = 0;
14324   u8 anti_replay = 0;
14325   u8 renumber = 0;
14326   u32 instance = ~0;
14327   u32 count = 1, jj;
14328   int ret = -1;
14329
14330   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14331     {
14332       if (unformat (i, "del"))
14333         is_add = 0;
14334       else if (unformat (i, "esn"))
14335         esn = 1;
14336       else if (unformat (i, "anti-replay"))
14337         anti_replay = 1;
14338       else if (unformat (i, "count %d", &count))
14339         ;
14340       else if (unformat (i, "local_spi %d", &local_spi))
14341         ;
14342       else if (unformat (i, "remote_spi %d", &remote_spi))
14343         ;
14344       else
14345         if (unformat (i, "local_ip %U", unformat_vl_api_address, &local_ip))
14346         ;
14347       else
14348         if (unformat (i, "remote_ip %U", unformat_vl_api_address, &remote_ip))
14349         ;
14350       else if (unformat (i, "local_crypto_key %U", unformat_hex_string, &lck))
14351         ;
14352       else
14353         if (unformat (i, "remote_crypto_key %U", unformat_hex_string, &rck))
14354         ;
14355       else if (unformat (i, "local_integ_key %U", unformat_hex_string, &lik))
14356         ;
14357       else if (unformat (i, "remote_integ_key %U", unformat_hex_string, &rik))
14358         ;
14359       else
14360         if (unformat
14361             (i, "crypto_alg %U", unformat_ipsec_api_crypto_alg, &crypto_alg))
14362         {
14363           if (crypto_alg >= IPSEC_CRYPTO_N_ALG)
14364             {
14365               errmsg ("unsupported crypto-alg: '%U'\n",
14366                       format_ipsec_crypto_alg, crypto_alg);
14367               return -99;
14368             }
14369         }
14370       else
14371         if (unformat
14372             (i, "integ_alg %U", unformat_ipsec_api_integ_alg, &integ_alg))
14373         {
14374           if (integ_alg >= IPSEC_INTEG_N_ALG)
14375             {
14376               errmsg ("unsupported integ-alg: '%U'\n",
14377                       format_ipsec_integ_alg, integ_alg);
14378               return -99;
14379             }
14380         }
14381       else if (unformat (i, "instance %u", &instance))
14382         renumber = 1;
14383       else
14384         {
14385           errmsg ("parse error '%U'\n", format_unformat_error, i);
14386           return -99;
14387         }
14388     }
14389
14390   if (count > 1)
14391     {
14392       /* Turn on async mode */
14393       vam->async_mode = 1;
14394       vam->async_errors = 0;
14395       before = vat_time_now (vam);
14396     }
14397
14398   for (jj = 0; jj < count; jj++)
14399     {
14400       M (IPSEC_TUNNEL_IF_ADD_DEL, mp);
14401
14402       mp->is_add = is_add;
14403       mp->esn = esn;
14404       mp->anti_replay = anti_replay;
14405
14406       if (jj > 0)
14407         increment_address (&remote_ip);
14408
14409       clib_memcpy (&mp->local_ip, &local_ip, sizeof (local_ip));
14410       clib_memcpy (&mp->remote_ip, &remote_ip, sizeof (remote_ip));
14411
14412       mp->local_spi = htonl (local_spi + jj);
14413       mp->remote_spi = htonl (remote_spi + jj);
14414       mp->crypto_alg = (u8) crypto_alg;
14415
14416       mp->local_crypto_key_len = 0;
14417       if (lck)
14418         {
14419           mp->local_crypto_key_len = vec_len (lck);
14420           if (mp->local_crypto_key_len > sizeof (mp->local_crypto_key))
14421             mp->local_crypto_key_len = sizeof (mp->local_crypto_key);
14422           clib_memcpy (mp->local_crypto_key, lck, mp->local_crypto_key_len);
14423         }
14424
14425       mp->remote_crypto_key_len = 0;
14426       if (rck)
14427         {
14428           mp->remote_crypto_key_len = vec_len (rck);
14429           if (mp->remote_crypto_key_len > sizeof (mp->remote_crypto_key))
14430             mp->remote_crypto_key_len = sizeof (mp->remote_crypto_key);
14431           clib_memcpy (mp->remote_crypto_key, rck, mp->remote_crypto_key_len);
14432         }
14433
14434       mp->integ_alg = (u8) integ_alg;
14435
14436       mp->local_integ_key_len = 0;
14437       if (lik)
14438         {
14439           mp->local_integ_key_len = vec_len (lik);
14440           if (mp->local_integ_key_len > sizeof (mp->local_integ_key))
14441             mp->local_integ_key_len = sizeof (mp->local_integ_key);
14442           clib_memcpy (mp->local_integ_key, lik, mp->local_integ_key_len);
14443         }
14444
14445       mp->remote_integ_key_len = 0;
14446       if (rik)
14447         {
14448           mp->remote_integ_key_len = vec_len (rik);
14449           if (mp->remote_integ_key_len > sizeof (mp->remote_integ_key))
14450             mp->remote_integ_key_len = sizeof (mp->remote_integ_key);
14451           clib_memcpy (mp->remote_integ_key, rik, mp->remote_integ_key_len);
14452         }
14453
14454       if (renumber)
14455         {
14456           mp->renumber = renumber;
14457           mp->show_instance = ntohl (instance);
14458         }
14459       S (mp);
14460     }
14461
14462   /* When testing multiple add/del ops, use a control-ping to sync */
14463   if (count > 1)
14464     {
14465       vl_api_control_ping_t *mp_ping;
14466       f64 after;
14467       f64 timeout;
14468
14469       /* Shut off async mode */
14470       vam->async_mode = 0;
14471
14472       MPING (CONTROL_PING, mp_ping);
14473       S (mp_ping);
14474
14475       timeout = vat_time_now (vam) + 1.0;
14476       while (vat_time_now (vam) < timeout)
14477         if (vam->result_ready == 1)
14478           goto out;
14479       vam->retval = -99;
14480
14481     out:
14482       if (vam->retval == -99)
14483         errmsg ("timeout");
14484
14485       if (vam->async_errors > 0)
14486         {
14487           errmsg ("%d asynchronous errors", vam->async_errors);
14488           vam->retval = -98;
14489         }
14490       vam->async_errors = 0;
14491       after = vat_time_now (vam);
14492
14493       /* slim chance, but we might have eaten SIGTERM on the first iteration */
14494       if (jj > 0)
14495         count = jj;
14496
14497       print (vam->ofp, "%d tunnels in %.6f secs, %.2f tunnels/sec",
14498              count, after - before, count / (after - before));
14499     }
14500   else
14501     {
14502       /* Wait for a reply... */
14503       W (ret);
14504       return ret;
14505     }
14506
14507   return ret;
14508 }
14509
14510 static void
14511 vl_api_ipsec_sa_details_t_handler (vl_api_ipsec_sa_details_t * mp)
14512 {
14513   vat_main_t *vam = &vat_main;
14514
14515   print (vam->ofp, "sa_id %u sw_if_index %u spi %u proto %u crypto_alg %u "
14516          "crypto_key %U integ_alg %u integ_key %U flags %x "
14517          "tunnel_src_addr %U tunnel_dst_addr %U "
14518          "salt %u seq_outbound %lu last_seq_inbound %lu "
14519          "replay_window %lu\n",
14520          ntohl (mp->entry.sad_id),
14521          ntohl (mp->sw_if_index),
14522          ntohl (mp->entry.spi),
14523          ntohl (mp->entry.protocol),
14524          ntohl (mp->entry.crypto_algorithm),
14525          format_hex_bytes, mp->entry.crypto_key.data,
14526          mp->entry.crypto_key.length, ntohl (mp->entry.integrity_algorithm),
14527          format_hex_bytes, mp->entry.integrity_key.data,
14528          mp->entry.integrity_key.length, ntohl (mp->entry.flags),
14529          format_vl_api_address, &mp->entry.tunnel_src, format_vl_api_address,
14530          &mp->entry.tunnel_dst, ntohl (mp->salt),
14531          clib_net_to_host_u64 (mp->seq_outbound),
14532          clib_net_to_host_u64 (mp->last_seq_inbound),
14533          clib_net_to_host_u64 (mp->replay_window));
14534 }
14535
14536 #define vl_api_ipsec_sa_details_t_endian vl_noop_handler
14537 #define vl_api_ipsec_sa_details_t_print vl_noop_handler
14538
14539 static void vl_api_ipsec_sa_details_t_handler_json
14540   (vl_api_ipsec_sa_details_t * mp)
14541 {
14542   vat_main_t *vam = &vat_main;
14543   vat_json_node_t *node = NULL;
14544   vl_api_ipsec_sad_flags_t flags;
14545
14546   if (VAT_JSON_ARRAY != vam->json_tree.type)
14547     {
14548       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14549       vat_json_init_array (&vam->json_tree);
14550     }
14551   node = vat_json_array_add (&vam->json_tree);
14552
14553   vat_json_init_object (node);
14554   vat_json_object_add_uint (node, "sa_id", ntohl (mp->entry.sad_id));
14555   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
14556   vat_json_object_add_uint (node, "spi", ntohl (mp->entry.spi));
14557   vat_json_object_add_uint (node, "proto", ntohl (mp->entry.protocol));
14558   vat_json_object_add_uint (node, "crypto_alg",
14559                             ntohl (mp->entry.crypto_algorithm));
14560   vat_json_object_add_uint (node, "integ_alg",
14561                             ntohl (mp->entry.integrity_algorithm));
14562   flags = ntohl (mp->entry.flags);
14563   vat_json_object_add_uint (node, "use_esn",
14564                             ! !(flags & IPSEC_API_SAD_FLAG_USE_ESN));
14565   vat_json_object_add_uint (node, "use_anti_replay",
14566                             ! !(flags & IPSEC_API_SAD_FLAG_USE_ANTI_REPLAY));
14567   vat_json_object_add_uint (node, "is_tunnel",
14568                             ! !(flags & IPSEC_API_SAD_FLAG_IS_TUNNEL));
14569   vat_json_object_add_uint (node, "is_tunnel_ip6",
14570                             ! !(flags & IPSEC_API_SAD_FLAG_IS_TUNNEL_V6));
14571   vat_json_object_add_uint (node, "udp_encap",
14572                             ! !(flags & IPSEC_API_SAD_FLAG_UDP_ENCAP));
14573   vat_json_object_add_bytes (node, "crypto_key", mp->entry.crypto_key.data,
14574                              mp->entry.crypto_key.length);
14575   vat_json_object_add_bytes (node, "integ_key", mp->entry.integrity_key.data,
14576                              mp->entry.integrity_key.length);
14577   vat_json_object_add_address (node, "src", &mp->entry.tunnel_src);
14578   vat_json_object_add_address (node, "dst", &mp->entry.tunnel_dst);
14579   vat_json_object_add_uint (node, "replay_window",
14580                             clib_net_to_host_u64 (mp->replay_window));
14581 }
14582
14583 static int
14584 api_ipsec_sa_dump (vat_main_t * vam)
14585 {
14586   unformat_input_t *i = vam->input;
14587   vl_api_ipsec_sa_dump_t *mp;
14588   vl_api_control_ping_t *mp_ping;
14589   u32 sa_id = ~0;
14590   int ret;
14591
14592   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14593     {
14594       if (unformat (i, "sa_id %d", &sa_id))
14595         ;
14596       else
14597         {
14598           clib_warning ("parse error '%U'", format_unformat_error, i);
14599           return -99;
14600         }
14601     }
14602
14603   M (IPSEC_SA_DUMP, mp);
14604
14605   mp->sa_id = ntohl (sa_id);
14606
14607   S (mp);
14608
14609   /* Use a control ping for synchronization */
14610   M (CONTROL_PING, mp_ping);
14611   S (mp_ping);
14612
14613   W (ret);
14614   return ret;
14615 }
14616
14617 static int
14618 api_ipsec_tunnel_if_set_sa (vat_main_t * vam)
14619 {
14620   unformat_input_t *i = vam->input;
14621   vl_api_ipsec_tunnel_if_set_sa_t *mp;
14622   u32 sw_if_index = ~0;
14623   u32 sa_id = ~0;
14624   u8 is_outbound = (u8) ~ 0;
14625   int ret;
14626
14627   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14628     {
14629       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14630         ;
14631       else if (unformat (i, "sa_id %d", &sa_id))
14632         ;
14633       else if (unformat (i, "outbound"))
14634         is_outbound = 1;
14635       else if (unformat (i, "inbound"))
14636         is_outbound = 0;
14637       else
14638         {
14639           clib_warning ("parse error '%U'", format_unformat_error, i);
14640           return -99;
14641         }
14642     }
14643
14644   if (sw_if_index == ~0)
14645     {
14646       errmsg ("interface must be specified");
14647       return -99;
14648     }
14649
14650   if (sa_id == ~0)
14651     {
14652       errmsg ("SA ID must be specified");
14653       return -99;
14654     }
14655
14656   M (IPSEC_TUNNEL_IF_SET_SA, mp);
14657
14658   mp->sw_if_index = htonl (sw_if_index);
14659   mp->sa_id = htonl (sa_id);
14660   mp->is_outbound = is_outbound;
14661
14662   S (mp);
14663   W (ret);
14664
14665   return ret;
14666 }
14667
14668 static int
14669 api_get_first_msg_id (vat_main_t * vam)
14670 {
14671   vl_api_get_first_msg_id_t *mp;
14672   unformat_input_t *i = vam->input;
14673   u8 *name;
14674   u8 name_set = 0;
14675   int ret;
14676
14677   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14678     {
14679       if (unformat (i, "client %s", &name))
14680         name_set = 1;
14681       else
14682         break;
14683     }
14684
14685   if (name_set == 0)
14686     {
14687       errmsg ("missing client name");
14688       return -99;
14689     }
14690   vec_add1 (name, 0);
14691
14692   if (vec_len (name) > 63)
14693     {
14694       errmsg ("client name too long");
14695       return -99;
14696     }
14697
14698   M (GET_FIRST_MSG_ID, mp);
14699   clib_memcpy (mp->name, name, vec_len (name));
14700   S (mp);
14701   W (ret);
14702   return ret;
14703 }
14704
14705 static int
14706 api_cop_interface_enable_disable (vat_main_t * vam)
14707 {
14708   unformat_input_t *line_input = vam->input;
14709   vl_api_cop_interface_enable_disable_t *mp;
14710   u32 sw_if_index = ~0;
14711   u8 enable_disable = 1;
14712   int ret;
14713
14714   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14715     {
14716       if (unformat (line_input, "disable"))
14717         enable_disable = 0;
14718       if (unformat (line_input, "enable"))
14719         enable_disable = 1;
14720       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
14721                          vam, &sw_if_index))
14722         ;
14723       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
14724         ;
14725       else
14726         break;
14727     }
14728
14729   if (sw_if_index == ~0)
14730     {
14731       errmsg ("missing interface name or sw_if_index");
14732       return -99;
14733     }
14734
14735   /* Construct the API message */
14736   M (COP_INTERFACE_ENABLE_DISABLE, mp);
14737   mp->sw_if_index = ntohl (sw_if_index);
14738   mp->enable_disable = enable_disable;
14739
14740   /* send it... */
14741   S (mp);
14742   /* Wait for the reply */
14743   W (ret);
14744   return ret;
14745 }
14746
14747 static int
14748 api_cop_whitelist_enable_disable (vat_main_t * vam)
14749 {
14750   unformat_input_t *line_input = vam->input;
14751   vl_api_cop_whitelist_enable_disable_t *mp;
14752   u32 sw_if_index = ~0;
14753   u8 ip4 = 0, ip6 = 0, default_cop = 0;
14754   u32 fib_id = 0;
14755   int ret;
14756
14757   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14758     {
14759       if (unformat (line_input, "ip4"))
14760         ip4 = 1;
14761       else if (unformat (line_input, "ip6"))
14762         ip6 = 1;
14763       else if (unformat (line_input, "default"))
14764         default_cop = 1;
14765       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
14766                          vam, &sw_if_index))
14767         ;
14768       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
14769         ;
14770       else if (unformat (line_input, "fib-id %d", &fib_id))
14771         ;
14772       else
14773         break;
14774     }
14775
14776   if (sw_if_index == ~0)
14777     {
14778       errmsg ("missing interface name or sw_if_index");
14779       return -99;
14780     }
14781
14782   /* Construct the API message */
14783   M (COP_WHITELIST_ENABLE_DISABLE, mp);
14784   mp->sw_if_index = ntohl (sw_if_index);
14785   mp->fib_id = ntohl (fib_id);
14786   mp->ip4 = ip4;
14787   mp->ip6 = ip6;
14788   mp->default_cop = default_cop;
14789
14790   /* send it... */
14791   S (mp);
14792   /* Wait for the reply */
14793   W (ret);
14794   return ret;
14795 }
14796
14797 static int
14798 api_get_node_graph (vat_main_t * vam)
14799 {
14800   vl_api_get_node_graph_t *mp;
14801   int ret;
14802
14803   M (GET_NODE_GRAPH, mp);
14804
14805   /* send it... */
14806   S (mp);
14807   /* Wait for the reply */
14808   W (ret);
14809   return ret;
14810 }
14811
14812 /* *INDENT-OFF* */
14813 /** Used for parsing LISP eids */
14814 typedef CLIB_PACKED(struct{
14815   u8 addr[16];   /**< eid address */
14816   u32 len;       /**< prefix length if IP */
14817   u8 type;      /**< type of eid */
14818 }) lisp_eid_vat_t;
14819 /* *INDENT-ON* */
14820
14821 static uword
14822 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
14823 {
14824   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
14825
14826   clib_memset (a, 0, sizeof (a[0]));
14827
14828   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
14829     {
14830       a->type = 0;              /* ipv4 type */
14831     }
14832   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
14833     {
14834       a->type = 1;              /* ipv6 type */
14835     }
14836   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
14837     {
14838       a->type = 2;              /* mac type */
14839     }
14840   else if (unformat (input, "%U", unformat_nsh_address, a->addr))
14841     {
14842       a->type = 3;              /* NSH type */
14843       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) a->addr;
14844       nsh->spi = clib_host_to_net_u32 (nsh->spi);
14845     }
14846   else
14847     {
14848       return 0;
14849     }
14850
14851   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
14852     {
14853       return 0;
14854     }
14855
14856   return 1;
14857 }
14858
14859 static int
14860 lisp_eid_size_vat (u8 type)
14861 {
14862   switch (type)
14863     {
14864     case 0:
14865       return 4;
14866     case 1:
14867       return 16;
14868     case 2:
14869       return 6;
14870     case 3:
14871       return 5;
14872     }
14873   return 0;
14874 }
14875
14876 static void
14877 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
14878 {
14879   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
14880 }
14881
14882 static int
14883 api_one_add_del_locator_set (vat_main_t * vam)
14884 {
14885   unformat_input_t *input = vam->input;
14886   vl_api_one_add_del_locator_set_t *mp;
14887   u8 is_add = 1;
14888   u8 *locator_set_name = NULL;
14889   u8 locator_set_name_set = 0;
14890   vl_api_local_locator_t locator, *locators = 0;
14891   u32 sw_if_index, priority, weight;
14892   u32 data_len = 0;
14893
14894   int ret;
14895   /* Parse args required to build the message */
14896   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14897     {
14898       if (unformat (input, "del"))
14899         {
14900           is_add = 0;
14901         }
14902       else if (unformat (input, "locator-set %s", &locator_set_name))
14903         {
14904           locator_set_name_set = 1;
14905         }
14906       else if (unformat (input, "sw_if_index %u p %u w %u",
14907                          &sw_if_index, &priority, &weight))
14908         {
14909           locator.sw_if_index = htonl (sw_if_index);
14910           locator.priority = priority;
14911           locator.weight = weight;
14912           vec_add1 (locators, locator);
14913         }
14914       else
14915         if (unformat
14916             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
14917              &sw_if_index, &priority, &weight))
14918         {
14919           locator.sw_if_index = htonl (sw_if_index);
14920           locator.priority = priority;
14921           locator.weight = weight;
14922           vec_add1 (locators, locator);
14923         }
14924       else
14925         break;
14926     }
14927
14928   if (locator_set_name_set == 0)
14929     {
14930       errmsg ("missing locator-set name");
14931       vec_free (locators);
14932       return -99;
14933     }
14934
14935   if (vec_len (locator_set_name) > 64)
14936     {
14937       errmsg ("locator-set name too long");
14938       vec_free (locator_set_name);
14939       vec_free (locators);
14940       return -99;
14941     }
14942   vec_add1 (locator_set_name, 0);
14943
14944   data_len = sizeof (vl_api_local_locator_t) * vec_len (locators);
14945
14946   /* Construct the API message */
14947   M2 (ONE_ADD_DEL_LOCATOR_SET, mp, data_len);
14948
14949   mp->is_add = is_add;
14950   clib_memcpy (mp->locator_set_name, locator_set_name,
14951                vec_len (locator_set_name));
14952   vec_free (locator_set_name);
14953
14954   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
14955   if (locators)
14956     clib_memcpy (mp->locators, locators, data_len);
14957   vec_free (locators);
14958
14959   /* send it... */
14960   S (mp);
14961
14962   /* Wait for a reply... */
14963   W (ret);
14964   return ret;
14965 }
14966
14967 #define api_lisp_add_del_locator_set api_one_add_del_locator_set
14968
14969 static int
14970 api_one_add_del_locator (vat_main_t * vam)
14971 {
14972   unformat_input_t *input = vam->input;
14973   vl_api_one_add_del_locator_t *mp;
14974   u32 tmp_if_index = ~0;
14975   u32 sw_if_index = ~0;
14976   u8 sw_if_index_set = 0;
14977   u8 sw_if_index_if_name_set = 0;
14978   u32 priority = ~0;
14979   u8 priority_set = 0;
14980   u32 weight = ~0;
14981   u8 weight_set = 0;
14982   u8 is_add = 1;
14983   u8 *locator_set_name = NULL;
14984   u8 locator_set_name_set = 0;
14985   int ret;
14986
14987   /* Parse args required to build the message */
14988   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14989     {
14990       if (unformat (input, "del"))
14991         {
14992           is_add = 0;
14993         }
14994       else if (unformat (input, "locator-set %s", &locator_set_name))
14995         {
14996           locator_set_name_set = 1;
14997         }
14998       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
14999                          &tmp_if_index))
15000         {
15001           sw_if_index_if_name_set = 1;
15002           sw_if_index = tmp_if_index;
15003         }
15004       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
15005         {
15006           sw_if_index_set = 1;
15007           sw_if_index = tmp_if_index;
15008         }
15009       else if (unformat (input, "p %d", &priority))
15010         {
15011           priority_set = 1;
15012         }
15013       else if (unformat (input, "w %d", &weight))
15014         {
15015           weight_set = 1;
15016         }
15017       else
15018         break;
15019     }
15020
15021   if (locator_set_name_set == 0)
15022     {
15023       errmsg ("missing locator-set name");
15024       return -99;
15025     }
15026
15027   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
15028     {
15029       errmsg ("missing sw_if_index");
15030       vec_free (locator_set_name);
15031       return -99;
15032     }
15033
15034   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
15035     {
15036       errmsg ("cannot use both params interface name and sw_if_index");
15037       vec_free (locator_set_name);
15038       return -99;
15039     }
15040
15041   if (priority_set == 0)
15042     {
15043       errmsg ("missing locator-set priority");
15044       vec_free (locator_set_name);
15045       return -99;
15046     }
15047
15048   if (weight_set == 0)
15049     {
15050       errmsg ("missing locator-set weight");
15051       vec_free (locator_set_name);
15052       return -99;
15053     }
15054
15055   if (vec_len (locator_set_name) > 64)
15056     {
15057       errmsg ("locator-set name too long");
15058       vec_free (locator_set_name);
15059       return -99;
15060     }
15061   vec_add1 (locator_set_name, 0);
15062
15063   /* Construct the API message */
15064   M (ONE_ADD_DEL_LOCATOR, mp);
15065
15066   mp->is_add = is_add;
15067   mp->sw_if_index = ntohl (sw_if_index);
15068   mp->priority = priority;
15069   mp->weight = weight;
15070   clib_memcpy (mp->locator_set_name, locator_set_name,
15071                vec_len (locator_set_name));
15072   vec_free (locator_set_name);
15073
15074   /* send it... */
15075   S (mp);
15076
15077   /* Wait for a reply... */
15078   W (ret);
15079   return ret;
15080 }
15081
15082 #define api_lisp_add_del_locator api_one_add_del_locator
15083
15084 uword
15085 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
15086 {
15087   u32 *key_id = va_arg (*args, u32 *);
15088   u8 *s = 0;
15089
15090   if (unformat (input, "%s", &s))
15091     {
15092       if (!strcmp ((char *) s, "sha1"))
15093         key_id[0] = HMAC_SHA_1_96;
15094       else if (!strcmp ((char *) s, "sha256"))
15095         key_id[0] = HMAC_SHA_256_128;
15096       else
15097         {
15098           clib_warning ("invalid key_id: '%s'", s);
15099           key_id[0] = HMAC_NO_KEY;
15100         }
15101     }
15102   else
15103     return 0;
15104
15105   vec_free (s);
15106   return 1;
15107 }
15108
15109 static int
15110 api_one_add_del_local_eid (vat_main_t * vam)
15111 {
15112   unformat_input_t *input = vam->input;
15113   vl_api_one_add_del_local_eid_t *mp;
15114   u8 is_add = 1;
15115   u8 eid_set = 0;
15116   lisp_eid_vat_t _eid, *eid = &_eid;
15117   u8 *locator_set_name = 0;
15118   u8 locator_set_name_set = 0;
15119   u32 vni = 0;
15120   u16 key_id = 0;
15121   u8 *key = 0;
15122   int ret;
15123
15124   /* Parse args required to build the message */
15125   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15126     {
15127       if (unformat (input, "del"))
15128         {
15129           is_add = 0;
15130         }
15131       else if (unformat (input, "vni %d", &vni))
15132         {
15133           ;
15134         }
15135       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
15136         {
15137           eid_set = 1;
15138         }
15139       else if (unformat (input, "locator-set %s", &locator_set_name))
15140         {
15141           locator_set_name_set = 1;
15142         }
15143       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
15144         ;
15145       else if (unformat (input, "secret-key %_%v%_", &key))
15146         ;
15147       else
15148         break;
15149     }
15150
15151   if (locator_set_name_set == 0)
15152     {
15153       errmsg ("missing locator-set name");
15154       return -99;
15155     }
15156
15157   if (0 == eid_set)
15158     {
15159       errmsg ("EID address not set!");
15160       vec_free (locator_set_name);
15161       return -99;
15162     }
15163
15164   if (key && (0 == key_id))
15165     {
15166       errmsg ("invalid key_id!");
15167       return -99;
15168     }
15169
15170   if (vec_len (key) > 64)
15171     {
15172       errmsg ("key too long");
15173       vec_free (key);
15174       return -99;
15175     }
15176
15177   if (vec_len (locator_set_name) > 64)
15178     {
15179       errmsg ("locator-set name too long");
15180       vec_free (locator_set_name);
15181       return -99;
15182     }
15183   vec_add1 (locator_set_name, 0);
15184
15185   /* Construct the API message */
15186   M (ONE_ADD_DEL_LOCAL_EID, mp);
15187
15188   mp->is_add = is_add;
15189   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
15190   mp->eid_type = eid->type;
15191   mp->prefix_len = eid->len;
15192   mp->vni = clib_host_to_net_u32 (vni);
15193   mp->key_id = clib_host_to_net_u16 (key_id);
15194   clib_memcpy (mp->locator_set_name, locator_set_name,
15195                vec_len (locator_set_name));
15196   clib_memcpy (mp->key, key, vec_len (key));
15197
15198   vec_free (locator_set_name);
15199   vec_free (key);
15200
15201   /* send it... */
15202   S (mp);
15203
15204   /* Wait for a reply... */
15205   W (ret);
15206   return ret;
15207 }
15208
15209 #define api_lisp_add_del_local_eid api_one_add_del_local_eid
15210
15211 static int
15212 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
15213 {
15214   u32 dp_table = 0, vni = 0;;
15215   unformat_input_t *input = vam->input;
15216   vl_api_gpe_add_del_fwd_entry_t *mp;
15217   u8 is_add = 1;
15218   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
15219   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
15220   u8 rmt_eid_set = 0, lcl_eid_set = 0;
15221   u32 action = ~0, w;
15222   ip4_address_t rmt_rloc4, lcl_rloc4;
15223   ip6_address_t rmt_rloc6, lcl_rloc6;
15224   vl_api_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
15225   int ret;
15226
15227   clib_memset (&rloc, 0, sizeof (rloc));
15228
15229   /* Parse args required to build the message */
15230   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15231     {
15232       if (unformat (input, "del"))
15233         is_add = 0;
15234       else if (unformat (input, "add"))
15235         is_add = 1;
15236       else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
15237         {
15238           rmt_eid_set = 1;
15239         }
15240       else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
15241         {
15242           lcl_eid_set = 1;
15243         }
15244       else if (unformat (input, "vrf %d", &dp_table))
15245         ;
15246       else if (unformat (input, "bd %d", &dp_table))
15247         ;
15248       else if (unformat (input, "vni %d", &vni))
15249         ;
15250       else if (unformat (input, "w %d", &w))
15251         {
15252           if (!curr_rloc)
15253             {
15254               errmsg ("No RLOC configured for setting priority/weight!");
15255               return -99;
15256             }
15257           curr_rloc->weight = w;
15258         }
15259       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
15260                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
15261         {
15262           rloc.is_ip4 = 1;
15263
15264           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
15265           rloc.weight = 0;
15266           vec_add1 (lcl_locs, rloc);
15267
15268           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
15269           vec_add1 (rmt_locs, rloc);
15270           /* weight saved in rmt loc */
15271           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
15272         }
15273       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
15274                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
15275         {
15276           rloc.is_ip4 = 0;
15277           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
15278           rloc.weight = 0;
15279           vec_add1 (lcl_locs, rloc);
15280
15281           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
15282           vec_add1 (rmt_locs, rloc);
15283           /* weight saved in rmt loc */
15284           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
15285         }
15286       else if (unformat (input, "action %d", &action))
15287         {
15288           ;
15289         }
15290       else
15291         {
15292           clib_warning ("parse error '%U'", format_unformat_error, input);
15293           return -99;
15294         }
15295     }
15296
15297   if (!rmt_eid_set)
15298     {
15299       errmsg ("remote eid addresses not set");
15300       return -99;
15301     }
15302
15303   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
15304     {
15305       errmsg ("eid types don't match");
15306       return -99;
15307     }
15308
15309   if (0 == rmt_locs && (u32) ~ 0 == action)
15310     {
15311       errmsg ("action not set for negative mapping");
15312       return -99;
15313     }
15314
15315   /* Construct the API message */
15316   M2 (GPE_ADD_DEL_FWD_ENTRY, mp,
15317       sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs) * 2);
15318
15319   mp->is_add = is_add;
15320   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
15321   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
15322   mp->eid_type = rmt_eid->type;
15323   mp->dp_table = clib_host_to_net_u32 (dp_table);
15324   mp->vni = clib_host_to_net_u32 (vni);
15325   mp->rmt_len = rmt_eid->len;
15326   mp->lcl_len = lcl_eid->len;
15327   mp->action = action;
15328
15329   if (0 != rmt_locs && 0 != lcl_locs)
15330     {
15331       mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
15332       clib_memcpy (mp->locs, lcl_locs,
15333                    (sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs)));
15334
15335       u32 offset = sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs);
15336       clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
15337                    (sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs)));
15338     }
15339   vec_free (lcl_locs);
15340   vec_free (rmt_locs);
15341
15342   /* send it... */
15343   S (mp);
15344
15345   /* Wait for a reply... */
15346   W (ret);
15347   return ret;
15348 }
15349
15350 static int
15351 api_one_add_del_map_server (vat_main_t * vam)
15352 {
15353   unformat_input_t *input = vam->input;
15354   vl_api_one_add_del_map_server_t *mp;
15355   u8 is_add = 1;
15356   u8 ipv4_set = 0;
15357   u8 ipv6_set = 0;
15358   ip4_address_t ipv4;
15359   ip6_address_t ipv6;
15360   int ret;
15361
15362   /* Parse args required to build the message */
15363   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15364     {
15365       if (unformat (input, "del"))
15366         {
15367           is_add = 0;
15368         }
15369       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
15370         {
15371           ipv4_set = 1;
15372         }
15373       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
15374         {
15375           ipv6_set = 1;
15376         }
15377       else
15378         break;
15379     }
15380
15381   if (ipv4_set && ipv6_set)
15382     {
15383       errmsg ("both eid v4 and v6 addresses set");
15384       return -99;
15385     }
15386
15387   if (!ipv4_set && !ipv6_set)
15388     {
15389       errmsg ("eid addresses not set");
15390       return -99;
15391     }
15392
15393   /* Construct the API message */
15394   M (ONE_ADD_DEL_MAP_SERVER, mp);
15395
15396   mp->is_add = is_add;
15397   if (ipv6_set)
15398     {
15399       mp->is_ipv6 = 1;
15400       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
15401     }
15402   else
15403     {
15404       mp->is_ipv6 = 0;
15405       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
15406     }
15407
15408   /* send it... */
15409   S (mp);
15410
15411   /* Wait for a reply... */
15412   W (ret);
15413   return ret;
15414 }
15415
15416 #define api_lisp_add_del_map_server api_one_add_del_map_server
15417
15418 static int
15419 api_one_add_del_map_resolver (vat_main_t * vam)
15420 {
15421   unformat_input_t *input = vam->input;
15422   vl_api_one_add_del_map_resolver_t *mp;
15423   u8 is_add = 1;
15424   u8 ipv4_set = 0;
15425   u8 ipv6_set = 0;
15426   ip4_address_t ipv4;
15427   ip6_address_t ipv6;
15428   int ret;
15429
15430   /* Parse args required to build the message */
15431   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15432     {
15433       if (unformat (input, "del"))
15434         {
15435           is_add = 0;
15436         }
15437       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
15438         {
15439           ipv4_set = 1;
15440         }
15441       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
15442         {
15443           ipv6_set = 1;
15444         }
15445       else
15446         break;
15447     }
15448
15449   if (ipv4_set && ipv6_set)
15450     {
15451       errmsg ("both eid v4 and v6 addresses set");
15452       return -99;
15453     }
15454
15455   if (!ipv4_set && !ipv6_set)
15456     {
15457       errmsg ("eid addresses not set");
15458       return -99;
15459     }
15460
15461   /* Construct the API message */
15462   M (ONE_ADD_DEL_MAP_RESOLVER, mp);
15463
15464   mp->is_add = is_add;
15465   if (ipv6_set)
15466     {
15467       mp->is_ipv6 = 1;
15468       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
15469     }
15470   else
15471     {
15472       mp->is_ipv6 = 0;
15473       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
15474     }
15475
15476   /* send it... */
15477   S (mp);
15478
15479   /* Wait for a reply... */
15480   W (ret);
15481   return ret;
15482 }
15483
15484 #define api_lisp_add_del_map_resolver api_one_add_del_map_resolver
15485
15486 static int
15487 api_lisp_gpe_enable_disable (vat_main_t * vam)
15488 {
15489   unformat_input_t *input = vam->input;
15490   vl_api_gpe_enable_disable_t *mp;
15491   u8 is_set = 0;
15492   u8 is_en = 1;
15493   int ret;
15494
15495   /* Parse args required to build the message */
15496   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15497     {
15498       if (unformat (input, "enable"))
15499         {
15500           is_set = 1;
15501           is_en = 1;
15502         }
15503       else if (unformat (input, "disable"))
15504         {
15505           is_set = 1;
15506           is_en = 0;
15507         }
15508       else
15509         break;
15510     }
15511
15512   if (is_set == 0)
15513     {
15514       errmsg ("Value not set");
15515       return -99;
15516     }
15517
15518   /* Construct the API message */
15519   M (GPE_ENABLE_DISABLE, mp);
15520
15521   mp->is_en = is_en;
15522
15523   /* send it... */
15524   S (mp);
15525
15526   /* Wait for a reply... */
15527   W (ret);
15528   return ret;
15529 }
15530
15531 static int
15532 api_one_rloc_probe_enable_disable (vat_main_t * vam)
15533 {
15534   unformat_input_t *input = vam->input;
15535   vl_api_one_rloc_probe_enable_disable_t *mp;
15536   u8 is_set = 0;
15537   u8 is_en = 0;
15538   int ret;
15539
15540   /* Parse args required to build the message */
15541   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15542     {
15543       if (unformat (input, "enable"))
15544         {
15545           is_set = 1;
15546           is_en = 1;
15547         }
15548       else if (unformat (input, "disable"))
15549         is_set = 1;
15550       else
15551         break;
15552     }
15553
15554   if (!is_set)
15555     {
15556       errmsg ("Value not set");
15557       return -99;
15558     }
15559
15560   /* Construct the API message */
15561   M (ONE_RLOC_PROBE_ENABLE_DISABLE, mp);
15562
15563   mp->is_enabled = is_en;
15564
15565   /* send it... */
15566   S (mp);
15567
15568   /* Wait for a reply... */
15569   W (ret);
15570   return ret;
15571 }
15572
15573 #define api_lisp_rloc_probe_enable_disable api_one_rloc_probe_enable_disable
15574
15575 static int
15576 api_one_map_register_enable_disable (vat_main_t * vam)
15577 {
15578   unformat_input_t *input = vam->input;
15579   vl_api_one_map_register_enable_disable_t *mp;
15580   u8 is_set = 0;
15581   u8 is_en = 0;
15582   int ret;
15583
15584   /* Parse args required to build the message */
15585   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15586     {
15587       if (unformat (input, "enable"))
15588         {
15589           is_set = 1;
15590           is_en = 1;
15591         }
15592       else if (unformat (input, "disable"))
15593         is_set = 1;
15594       else
15595         break;
15596     }
15597
15598   if (!is_set)
15599     {
15600       errmsg ("Value not set");
15601       return -99;
15602     }
15603
15604   /* Construct the API message */
15605   M (ONE_MAP_REGISTER_ENABLE_DISABLE, mp);
15606
15607   mp->is_enabled = is_en;
15608
15609   /* send it... */
15610   S (mp);
15611
15612   /* Wait for a reply... */
15613   W (ret);
15614   return ret;
15615 }
15616
15617 #define api_lisp_map_register_enable_disable api_one_map_register_enable_disable
15618
15619 static int
15620 api_one_enable_disable (vat_main_t * vam)
15621 {
15622   unformat_input_t *input = vam->input;
15623   vl_api_one_enable_disable_t *mp;
15624   u8 is_set = 0;
15625   u8 is_en = 0;
15626   int ret;
15627
15628   /* Parse args required to build the message */
15629   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15630     {
15631       if (unformat (input, "enable"))
15632         {
15633           is_set = 1;
15634           is_en = 1;
15635         }
15636       else if (unformat (input, "disable"))
15637         {
15638           is_set = 1;
15639         }
15640       else
15641         break;
15642     }
15643
15644   if (!is_set)
15645     {
15646       errmsg ("Value not set");
15647       return -99;
15648     }
15649
15650   /* Construct the API message */
15651   M (ONE_ENABLE_DISABLE, mp);
15652
15653   mp->is_en = is_en;
15654
15655   /* send it... */
15656   S (mp);
15657
15658   /* Wait for a reply... */
15659   W (ret);
15660   return ret;
15661 }
15662
15663 #define api_lisp_enable_disable api_one_enable_disable
15664
15665 static int
15666 api_one_enable_disable_xtr_mode (vat_main_t * vam)
15667 {
15668   unformat_input_t *input = vam->input;
15669   vl_api_one_enable_disable_xtr_mode_t *mp;
15670   u8 is_set = 0;
15671   u8 is_en = 0;
15672   int ret;
15673
15674   /* Parse args required to build the message */
15675   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15676     {
15677       if (unformat (input, "enable"))
15678         {
15679           is_set = 1;
15680           is_en = 1;
15681         }
15682       else if (unformat (input, "disable"))
15683         {
15684           is_set = 1;
15685         }
15686       else
15687         break;
15688     }
15689
15690   if (!is_set)
15691     {
15692       errmsg ("Value not set");
15693       return -99;
15694     }
15695
15696   /* Construct the API message */
15697   M (ONE_ENABLE_DISABLE_XTR_MODE, mp);
15698
15699   mp->is_en = is_en;
15700
15701   /* send it... */
15702   S (mp);
15703
15704   /* Wait for a reply... */
15705   W (ret);
15706   return ret;
15707 }
15708
15709 static int
15710 api_one_show_xtr_mode (vat_main_t * vam)
15711 {
15712   vl_api_one_show_xtr_mode_t *mp;
15713   int ret;
15714
15715   /* Construct the API message */
15716   M (ONE_SHOW_XTR_MODE, mp);
15717
15718   /* send it... */
15719   S (mp);
15720
15721   /* Wait for a reply... */
15722   W (ret);
15723   return ret;
15724 }
15725
15726 static int
15727 api_one_enable_disable_pitr_mode (vat_main_t * vam)
15728 {
15729   unformat_input_t *input = vam->input;
15730   vl_api_one_enable_disable_pitr_mode_t *mp;
15731   u8 is_set = 0;
15732   u8 is_en = 0;
15733   int ret;
15734
15735   /* Parse args required to build the message */
15736   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15737     {
15738       if (unformat (input, "enable"))
15739         {
15740           is_set = 1;
15741           is_en = 1;
15742         }
15743       else if (unformat (input, "disable"))
15744         {
15745           is_set = 1;
15746         }
15747       else
15748         break;
15749     }
15750
15751   if (!is_set)
15752     {
15753       errmsg ("Value not set");
15754       return -99;
15755     }
15756
15757   /* Construct the API message */
15758   M (ONE_ENABLE_DISABLE_PITR_MODE, mp);
15759
15760   mp->is_en = is_en;
15761
15762   /* send it... */
15763   S (mp);
15764
15765   /* Wait for a reply... */
15766   W (ret);
15767   return ret;
15768 }
15769
15770 static int
15771 api_one_show_pitr_mode (vat_main_t * vam)
15772 {
15773   vl_api_one_show_pitr_mode_t *mp;
15774   int ret;
15775
15776   /* Construct the API message */
15777   M (ONE_SHOW_PITR_MODE, mp);
15778
15779   /* send it... */
15780   S (mp);
15781
15782   /* Wait for a reply... */
15783   W (ret);
15784   return ret;
15785 }
15786
15787 static int
15788 api_one_enable_disable_petr_mode (vat_main_t * vam)
15789 {
15790   unformat_input_t *input = vam->input;
15791   vl_api_one_enable_disable_petr_mode_t *mp;
15792   u8 is_set = 0;
15793   u8 is_en = 0;
15794   int ret;
15795
15796   /* Parse args required to build the message */
15797   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15798     {
15799       if (unformat (input, "enable"))
15800         {
15801           is_set = 1;
15802           is_en = 1;
15803         }
15804       else if (unformat (input, "disable"))
15805         {
15806           is_set = 1;
15807         }
15808       else
15809         break;
15810     }
15811
15812   if (!is_set)
15813     {
15814       errmsg ("Value not set");
15815       return -99;
15816     }
15817
15818   /* Construct the API message */
15819   M (ONE_ENABLE_DISABLE_PETR_MODE, mp);
15820
15821   mp->is_en = is_en;
15822
15823   /* send it... */
15824   S (mp);
15825
15826   /* Wait for a reply... */
15827   W (ret);
15828   return ret;
15829 }
15830
15831 static int
15832 api_one_show_petr_mode (vat_main_t * vam)
15833 {
15834   vl_api_one_show_petr_mode_t *mp;
15835   int ret;
15836
15837   /* Construct the API message */
15838   M (ONE_SHOW_PETR_MODE, mp);
15839
15840   /* send it... */
15841   S (mp);
15842
15843   /* Wait for a reply... */
15844   W (ret);
15845   return ret;
15846 }
15847
15848 static int
15849 api_show_one_map_register_state (vat_main_t * vam)
15850 {
15851   vl_api_show_one_map_register_state_t *mp;
15852   int ret;
15853
15854   M (SHOW_ONE_MAP_REGISTER_STATE, mp);
15855
15856   /* send */
15857   S (mp);
15858
15859   /* wait for reply */
15860   W (ret);
15861   return ret;
15862 }
15863
15864 #define api_show_lisp_map_register_state api_show_one_map_register_state
15865
15866 static int
15867 api_show_one_rloc_probe_state (vat_main_t * vam)
15868 {
15869   vl_api_show_one_rloc_probe_state_t *mp;
15870   int ret;
15871
15872   M (SHOW_ONE_RLOC_PROBE_STATE, mp);
15873
15874   /* send */
15875   S (mp);
15876
15877   /* wait for reply */
15878   W (ret);
15879   return ret;
15880 }
15881
15882 #define api_show_lisp_rloc_probe_state api_show_one_rloc_probe_state
15883
15884 static int
15885 api_one_add_del_ndp_entry (vat_main_t * vam)
15886 {
15887   vl_api_one_add_del_ndp_entry_t *mp;
15888   unformat_input_t *input = vam->input;
15889   u8 is_add = 1;
15890   u8 mac_set = 0;
15891   u8 bd_set = 0;
15892   u8 ip_set = 0;
15893   u8 mac[6] = { 0, };
15894   u8 ip6[16] = { 0, };
15895   u32 bd = ~0;
15896   int ret;
15897
15898   /* Parse args required to build the message */
15899   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15900     {
15901       if (unformat (input, "del"))
15902         is_add = 0;
15903       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
15904         mac_set = 1;
15905       else if (unformat (input, "ip %U", unformat_ip6_address, ip6))
15906         ip_set = 1;
15907       else if (unformat (input, "bd %d", &bd))
15908         bd_set = 1;
15909       else
15910         {
15911           errmsg ("parse error '%U'", format_unformat_error, input);
15912           return -99;
15913         }
15914     }
15915
15916   if (!bd_set || !ip_set || (!mac_set && is_add))
15917     {
15918       errmsg ("Missing BD, IP or MAC!");
15919       return -99;
15920     }
15921
15922   M (ONE_ADD_DEL_NDP_ENTRY, mp);
15923   mp->is_add = is_add;
15924   clib_memcpy (mp->mac, mac, 6);
15925   mp->bd = clib_host_to_net_u32 (bd);
15926   clib_memcpy (mp->ip6, ip6, sizeof (mp->ip6));
15927
15928   /* send */
15929   S (mp);
15930
15931   /* wait for reply */
15932   W (ret);
15933   return ret;
15934 }
15935
15936 static int
15937 api_one_add_del_l2_arp_entry (vat_main_t * vam)
15938 {
15939   vl_api_one_add_del_l2_arp_entry_t *mp;
15940   unformat_input_t *input = vam->input;
15941   u8 is_add = 1;
15942   u8 mac_set = 0;
15943   u8 bd_set = 0;
15944   u8 ip_set = 0;
15945   u8 mac[6] = { 0, };
15946   u32 ip4 = 0, bd = ~0;
15947   int ret;
15948
15949   /* Parse args required to build the message */
15950   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15951     {
15952       if (unformat (input, "del"))
15953         is_add = 0;
15954       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
15955         mac_set = 1;
15956       else if (unformat (input, "ip %U", unformat_ip4_address, &ip4))
15957         ip_set = 1;
15958       else if (unformat (input, "bd %d", &bd))
15959         bd_set = 1;
15960       else
15961         {
15962           errmsg ("parse error '%U'", format_unformat_error, input);
15963           return -99;
15964         }
15965     }
15966
15967   if (!bd_set || !ip_set || (!mac_set && is_add))
15968     {
15969       errmsg ("Missing BD, IP or MAC!");
15970       return -99;
15971     }
15972
15973   M (ONE_ADD_DEL_L2_ARP_ENTRY, mp);
15974   mp->is_add = is_add;
15975   clib_memcpy (mp->mac, mac, 6);
15976   mp->bd = clib_host_to_net_u32 (bd);
15977   mp->ip4 = ip4;
15978
15979   /* send */
15980   S (mp);
15981
15982   /* wait for reply */
15983   W (ret);
15984   return ret;
15985 }
15986
15987 static int
15988 api_one_ndp_bd_get (vat_main_t * vam)
15989 {
15990   vl_api_one_ndp_bd_get_t *mp;
15991   int ret;
15992
15993   M (ONE_NDP_BD_GET, mp);
15994
15995   /* send */
15996   S (mp);
15997
15998   /* wait for reply */
15999   W (ret);
16000   return ret;
16001 }
16002
16003 static int
16004 api_one_ndp_entries_get (vat_main_t * vam)
16005 {
16006   vl_api_one_ndp_entries_get_t *mp;
16007   unformat_input_t *input = vam->input;
16008   u8 bd_set = 0;
16009   u32 bd = ~0;
16010   int ret;
16011
16012   /* Parse args required to build the message */
16013   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16014     {
16015       if (unformat (input, "bd %d", &bd))
16016         bd_set = 1;
16017       else
16018         {
16019           errmsg ("parse error '%U'", format_unformat_error, input);
16020           return -99;
16021         }
16022     }
16023
16024   if (!bd_set)
16025     {
16026       errmsg ("Expected bridge domain!");
16027       return -99;
16028     }
16029
16030   M (ONE_NDP_ENTRIES_GET, mp);
16031   mp->bd = clib_host_to_net_u32 (bd);
16032
16033   /* send */
16034   S (mp);
16035
16036   /* wait for reply */
16037   W (ret);
16038   return ret;
16039 }
16040
16041 static int
16042 api_one_l2_arp_bd_get (vat_main_t * vam)
16043 {
16044   vl_api_one_l2_arp_bd_get_t *mp;
16045   int ret;
16046
16047   M (ONE_L2_ARP_BD_GET, mp);
16048
16049   /* send */
16050   S (mp);
16051
16052   /* wait for reply */
16053   W (ret);
16054   return ret;
16055 }
16056
16057 static int
16058 api_one_l2_arp_entries_get (vat_main_t * vam)
16059 {
16060   vl_api_one_l2_arp_entries_get_t *mp;
16061   unformat_input_t *input = vam->input;
16062   u8 bd_set = 0;
16063   u32 bd = ~0;
16064   int ret;
16065
16066   /* Parse args required to build the message */
16067   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16068     {
16069       if (unformat (input, "bd %d", &bd))
16070         bd_set = 1;
16071       else
16072         {
16073           errmsg ("parse error '%U'", format_unformat_error, input);
16074           return -99;
16075         }
16076     }
16077
16078   if (!bd_set)
16079     {
16080       errmsg ("Expected bridge domain!");
16081       return -99;
16082     }
16083
16084   M (ONE_L2_ARP_ENTRIES_GET, mp);
16085   mp->bd = clib_host_to_net_u32 (bd);
16086
16087   /* send */
16088   S (mp);
16089
16090   /* wait for reply */
16091   W (ret);
16092   return ret;
16093 }
16094
16095 static int
16096 api_one_stats_enable_disable (vat_main_t * vam)
16097 {
16098   vl_api_one_stats_enable_disable_t *mp;
16099   unformat_input_t *input = vam->input;
16100   u8 is_set = 0;
16101   u8 is_en = 0;
16102   int ret;
16103
16104   /* Parse args required to build the message */
16105   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16106     {
16107       if (unformat (input, "enable"))
16108         {
16109           is_set = 1;
16110           is_en = 1;
16111         }
16112       else if (unformat (input, "disable"))
16113         {
16114           is_set = 1;
16115         }
16116       else
16117         break;
16118     }
16119
16120   if (!is_set)
16121     {
16122       errmsg ("Value not set");
16123       return -99;
16124     }
16125
16126   M (ONE_STATS_ENABLE_DISABLE, mp);
16127   mp->is_en = is_en;
16128
16129   /* send */
16130   S (mp);
16131
16132   /* wait for reply */
16133   W (ret);
16134   return ret;
16135 }
16136
16137 static int
16138 api_show_one_stats_enable_disable (vat_main_t * vam)
16139 {
16140   vl_api_show_one_stats_enable_disable_t *mp;
16141   int ret;
16142
16143   M (SHOW_ONE_STATS_ENABLE_DISABLE, mp);
16144
16145   /* send */
16146   S (mp);
16147
16148   /* wait for reply */
16149   W (ret);
16150   return ret;
16151 }
16152
16153 static int
16154 api_show_one_map_request_mode (vat_main_t * vam)
16155 {
16156   vl_api_show_one_map_request_mode_t *mp;
16157   int ret;
16158
16159   M (SHOW_ONE_MAP_REQUEST_MODE, mp);
16160
16161   /* send */
16162   S (mp);
16163
16164   /* wait for reply */
16165   W (ret);
16166   return ret;
16167 }
16168
16169 #define api_show_lisp_map_request_mode api_show_one_map_request_mode
16170
16171 static int
16172 api_one_map_request_mode (vat_main_t * vam)
16173 {
16174   unformat_input_t *input = vam->input;
16175   vl_api_one_map_request_mode_t *mp;
16176   u8 mode = 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, "dst-only"))
16183         mode = 0;
16184       else if (unformat (input, "src-dst"))
16185         mode = 1;
16186       else
16187         {
16188           errmsg ("parse error '%U'", format_unformat_error, input);
16189           return -99;
16190         }
16191     }
16192
16193   M (ONE_MAP_REQUEST_MODE, mp);
16194
16195   mp->mode = mode;
16196
16197   /* send */
16198   S (mp);
16199
16200   /* wait for reply */
16201   W (ret);
16202   return ret;
16203 }
16204
16205 #define api_lisp_map_request_mode api_one_map_request_mode
16206
16207 /**
16208  * Enable/disable ONE proxy ITR.
16209  *
16210  * @param vam vpp API test context
16211  * @return return code
16212  */
16213 static int
16214 api_one_pitr_set_locator_set (vat_main_t * vam)
16215 {
16216   u8 ls_name_set = 0;
16217   unformat_input_t *input = vam->input;
16218   vl_api_one_pitr_set_locator_set_t *mp;
16219   u8 is_add = 1;
16220   u8 *ls_name = 0;
16221   int ret;
16222
16223   /* Parse args required to build the message */
16224   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16225     {
16226       if (unformat (input, "del"))
16227         is_add = 0;
16228       else if (unformat (input, "locator-set %s", &ls_name))
16229         ls_name_set = 1;
16230       else
16231         {
16232           errmsg ("parse error '%U'", format_unformat_error, input);
16233           return -99;
16234         }
16235     }
16236
16237   if (!ls_name_set)
16238     {
16239       errmsg ("locator-set name not set!");
16240       return -99;
16241     }
16242
16243   M (ONE_PITR_SET_LOCATOR_SET, mp);
16244
16245   mp->is_add = is_add;
16246   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
16247   vec_free (ls_name);
16248
16249   /* send */
16250   S (mp);
16251
16252   /* wait for reply */
16253   W (ret);
16254   return ret;
16255 }
16256
16257 #define api_lisp_pitr_set_locator_set api_one_pitr_set_locator_set
16258
16259 static int
16260 api_one_nsh_set_locator_set (vat_main_t * vam)
16261 {
16262   u8 ls_name_set = 0;
16263   unformat_input_t *input = vam->input;
16264   vl_api_one_nsh_set_locator_set_t *mp;
16265   u8 is_add = 1;
16266   u8 *ls_name = 0;
16267   int ret;
16268
16269   /* Parse args required to build the message */
16270   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16271     {
16272       if (unformat (input, "del"))
16273         is_add = 0;
16274       else if (unformat (input, "ls %s", &ls_name))
16275         ls_name_set = 1;
16276       else
16277         {
16278           errmsg ("parse error '%U'", format_unformat_error, input);
16279           return -99;
16280         }
16281     }
16282
16283   if (!ls_name_set && is_add)
16284     {
16285       errmsg ("locator-set name not set!");
16286       return -99;
16287     }
16288
16289   M (ONE_NSH_SET_LOCATOR_SET, mp);
16290
16291   mp->is_add = is_add;
16292   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
16293   vec_free (ls_name);
16294
16295   /* send */
16296   S (mp);
16297
16298   /* wait for reply */
16299   W (ret);
16300   return ret;
16301 }
16302
16303 static int
16304 api_show_one_pitr (vat_main_t * vam)
16305 {
16306   vl_api_show_one_pitr_t *mp;
16307   int ret;
16308
16309   if (!vam->json_output)
16310     {
16311       print (vam->ofp, "%=20s", "lisp status:");
16312     }
16313
16314   M (SHOW_ONE_PITR, mp);
16315   /* send it... */
16316   S (mp);
16317
16318   /* Wait for a reply... */
16319   W (ret);
16320   return ret;
16321 }
16322
16323 #define api_show_lisp_pitr api_show_one_pitr
16324
16325 static int
16326 api_one_use_petr (vat_main_t * vam)
16327 {
16328   unformat_input_t *input = vam->input;
16329   vl_api_one_use_petr_t *mp;
16330   u8 is_add = 0;
16331   ip_address_t ip;
16332   int ret;
16333
16334   clib_memset (&ip, 0, sizeof (ip));
16335
16336   /* Parse args required to build the message */
16337   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16338     {
16339       if (unformat (input, "disable"))
16340         is_add = 0;
16341       else
16342         if (unformat (input, "%U", unformat_ip4_address, &ip_addr_v4 (&ip)))
16343         {
16344           is_add = 1;
16345           ip_addr_version (&ip) = AF_IP4;
16346         }
16347       else
16348         if (unformat (input, "%U", unformat_ip6_address, &ip_addr_v6 (&ip)))
16349         {
16350           is_add = 1;
16351           ip_addr_version (&ip) = AF_IP6;
16352         }
16353       else
16354         {
16355           errmsg ("parse error '%U'", format_unformat_error, input);
16356           return -99;
16357         }
16358     }
16359
16360   M (ONE_USE_PETR, mp);
16361
16362   mp->is_add = is_add;
16363   if (is_add)
16364     {
16365       mp->is_ip4 = ip_addr_version (&ip) == AF_IP4 ? 1 : 0;
16366       if (mp->is_ip4)
16367         clib_memcpy (mp->address, &ip, 4);
16368       else
16369         clib_memcpy (mp->address, &ip, 16);
16370     }
16371
16372   /* send */
16373   S (mp);
16374
16375   /* wait for reply */
16376   W (ret);
16377   return ret;
16378 }
16379
16380 #define api_lisp_use_petr api_one_use_petr
16381
16382 static int
16383 api_show_one_nsh_mapping (vat_main_t * vam)
16384 {
16385   vl_api_show_one_use_petr_t *mp;
16386   int ret;
16387
16388   if (!vam->json_output)
16389     {
16390       print (vam->ofp, "%=20s", "local ONE NSH mapping:");
16391     }
16392
16393   M (SHOW_ONE_NSH_MAPPING, mp);
16394   /* send it... */
16395   S (mp);
16396
16397   /* Wait for a reply... */
16398   W (ret);
16399   return ret;
16400 }
16401
16402 static int
16403 api_show_one_use_petr (vat_main_t * vam)
16404 {
16405   vl_api_show_one_use_petr_t *mp;
16406   int ret;
16407
16408   if (!vam->json_output)
16409     {
16410       print (vam->ofp, "%=20s", "Proxy-ETR status:");
16411     }
16412
16413   M (SHOW_ONE_USE_PETR, mp);
16414   /* send it... */
16415   S (mp);
16416
16417   /* Wait for a reply... */
16418   W (ret);
16419   return ret;
16420 }
16421
16422 #define api_show_lisp_use_petr api_show_one_use_petr
16423
16424 /**
16425  * Add/delete mapping between vni and vrf
16426  */
16427 static int
16428 api_one_eid_table_add_del_map (vat_main_t * vam)
16429 {
16430   unformat_input_t *input = vam->input;
16431   vl_api_one_eid_table_add_del_map_t *mp;
16432   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
16433   u32 vni, vrf, bd_index;
16434   int ret;
16435
16436   /* Parse args required to build the message */
16437   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16438     {
16439       if (unformat (input, "del"))
16440         is_add = 0;
16441       else if (unformat (input, "vrf %d", &vrf))
16442         vrf_set = 1;
16443       else if (unformat (input, "bd_index %d", &bd_index))
16444         bd_index_set = 1;
16445       else if (unformat (input, "vni %d", &vni))
16446         vni_set = 1;
16447       else
16448         break;
16449     }
16450
16451   if (!vni_set || (!vrf_set && !bd_index_set))
16452     {
16453       errmsg ("missing arguments!");
16454       return -99;
16455     }
16456
16457   if (vrf_set && bd_index_set)
16458     {
16459       errmsg ("error: both vrf and bd entered!");
16460       return -99;
16461     }
16462
16463   M (ONE_EID_TABLE_ADD_DEL_MAP, mp);
16464
16465   mp->is_add = is_add;
16466   mp->vni = htonl (vni);
16467   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
16468   mp->is_l2 = bd_index_set;
16469
16470   /* send */
16471   S (mp);
16472
16473   /* wait for reply */
16474   W (ret);
16475   return ret;
16476 }
16477
16478 #define api_lisp_eid_table_add_del_map api_one_eid_table_add_del_map
16479
16480 uword
16481 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
16482 {
16483   u32 *action = va_arg (*args, u32 *);
16484   u8 *s = 0;
16485
16486   if (unformat (input, "%s", &s))
16487     {
16488       if (!strcmp ((char *) s, "no-action"))
16489         action[0] = 0;
16490       else if (!strcmp ((char *) s, "natively-forward"))
16491         action[0] = 1;
16492       else if (!strcmp ((char *) s, "send-map-request"))
16493         action[0] = 2;
16494       else if (!strcmp ((char *) s, "drop"))
16495         action[0] = 3;
16496       else
16497         {
16498           clib_warning ("invalid action: '%s'", s);
16499           action[0] = 3;
16500         }
16501     }
16502   else
16503     return 0;
16504
16505   vec_free (s);
16506   return 1;
16507 }
16508
16509 /**
16510  * Add/del remote mapping to/from ONE control plane
16511  *
16512  * @param vam vpp API test context
16513  * @return return code
16514  */
16515 static int
16516 api_one_add_del_remote_mapping (vat_main_t * vam)
16517 {
16518   unformat_input_t *input = vam->input;
16519   vl_api_one_add_del_remote_mapping_t *mp;
16520   u32 vni = 0;
16521   lisp_eid_vat_t _eid, *eid = &_eid;
16522   lisp_eid_vat_t _seid, *seid = &_seid;
16523   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
16524   u32 action = ~0, p, w, data_len;
16525   ip4_address_t rloc4;
16526   ip6_address_t rloc6;
16527   vl_api_remote_locator_t *rlocs = 0, rloc, *curr_rloc = 0;
16528   int ret;
16529
16530   clib_memset (&rloc, 0, sizeof (rloc));
16531
16532   /* Parse args required to build the message */
16533   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16534     {
16535       if (unformat (input, "del-all"))
16536         {
16537           del_all = 1;
16538         }
16539       else if (unformat (input, "del"))
16540         {
16541           is_add = 0;
16542         }
16543       else if (unformat (input, "add"))
16544         {
16545           is_add = 1;
16546         }
16547       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
16548         {
16549           eid_set = 1;
16550         }
16551       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
16552         {
16553           seid_set = 1;
16554         }
16555       else if (unformat (input, "vni %d", &vni))
16556         {
16557           ;
16558         }
16559       else if (unformat (input, "p %d w %d", &p, &w))
16560         {
16561           if (!curr_rloc)
16562             {
16563               errmsg ("No RLOC configured for setting priority/weight!");
16564               return -99;
16565             }
16566           curr_rloc->priority = p;
16567           curr_rloc->weight = w;
16568         }
16569       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
16570         {
16571           rloc.is_ip4 = 1;
16572           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
16573           vec_add1 (rlocs, rloc);
16574           curr_rloc = &rlocs[vec_len (rlocs) - 1];
16575         }
16576       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
16577         {
16578           rloc.is_ip4 = 0;
16579           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
16580           vec_add1 (rlocs, rloc);
16581           curr_rloc = &rlocs[vec_len (rlocs) - 1];
16582         }
16583       else if (unformat (input, "action %U",
16584                          unformat_negative_mapping_action, &action))
16585         {
16586           ;
16587         }
16588       else
16589         {
16590           clib_warning ("parse error '%U'", format_unformat_error, input);
16591           return -99;
16592         }
16593     }
16594
16595   if (0 == eid_set)
16596     {
16597       errmsg ("missing params!");
16598       return -99;
16599     }
16600
16601   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
16602     {
16603       errmsg ("no action set for negative map-reply!");
16604       return -99;
16605     }
16606
16607   data_len = vec_len (rlocs) * sizeof (vl_api_remote_locator_t);
16608
16609   M2 (ONE_ADD_DEL_REMOTE_MAPPING, mp, data_len);
16610   mp->is_add = is_add;
16611   mp->vni = htonl (vni);
16612   mp->action = (u8) action;
16613   mp->is_src_dst = seid_set;
16614   mp->eid_len = eid->len;
16615   mp->seid_len = seid->len;
16616   mp->del_all = del_all;
16617   mp->eid_type = eid->type;
16618   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
16619   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
16620
16621   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
16622   clib_memcpy (mp->rlocs, rlocs, data_len);
16623   vec_free (rlocs);
16624
16625   /* send it... */
16626   S (mp);
16627
16628   /* Wait for a reply... */
16629   W (ret);
16630   return ret;
16631 }
16632
16633 #define api_lisp_add_del_remote_mapping api_one_add_del_remote_mapping
16634
16635 /**
16636  * Add/del ONE adjacency. Saves mapping in ONE control plane and updates
16637  * forwarding entries in data-plane accordingly.
16638  *
16639  * @param vam vpp API test context
16640  * @return return code
16641  */
16642 static int
16643 api_one_add_del_adjacency (vat_main_t * vam)
16644 {
16645   unformat_input_t *input = vam->input;
16646   vl_api_one_add_del_adjacency_t *mp;
16647   u32 vni = 0;
16648   ip4_address_t leid4, reid4;
16649   ip6_address_t leid6, reid6;
16650   u8 reid_mac[6] = { 0 };
16651   u8 leid_mac[6] = { 0 };
16652   u8 reid_type, leid_type;
16653   u32 leid_len = 0, reid_len = 0, len;
16654   u8 is_add = 1;
16655   int ret;
16656
16657   leid_type = reid_type = (u8) ~ 0;
16658
16659   /* Parse args required to build the message */
16660   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16661     {
16662       if (unformat (input, "del"))
16663         {
16664           is_add = 0;
16665         }
16666       else if (unformat (input, "add"))
16667         {
16668           is_add = 1;
16669         }
16670       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
16671                          &reid4, &len))
16672         {
16673           reid_type = 0;        /* ipv4 */
16674           reid_len = len;
16675         }
16676       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
16677                          &reid6, &len))
16678         {
16679           reid_type = 1;        /* ipv6 */
16680           reid_len = len;
16681         }
16682       else if (unformat (input, "reid %U", unformat_ethernet_address,
16683                          reid_mac))
16684         {
16685           reid_type = 2;        /* mac */
16686         }
16687       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
16688                          &leid4, &len))
16689         {
16690           leid_type = 0;        /* ipv4 */
16691           leid_len = len;
16692         }
16693       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
16694                          &leid6, &len))
16695         {
16696           leid_type = 1;        /* ipv6 */
16697           leid_len = len;
16698         }
16699       else if (unformat (input, "leid %U", unformat_ethernet_address,
16700                          leid_mac))
16701         {
16702           leid_type = 2;        /* mac */
16703         }
16704       else if (unformat (input, "vni %d", &vni))
16705         {
16706           ;
16707         }
16708       else
16709         {
16710           errmsg ("parse error '%U'", format_unformat_error, input);
16711           return -99;
16712         }
16713     }
16714
16715   if ((u8) ~ 0 == reid_type)
16716     {
16717       errmsg ("missing params!");
16718       return -99;
16719     }
16720
16721   if (leid_type != reid_type)
16722     {
16723       errmsg ("remote and local EIDs are of different types!");
16724       return -99;
16725     }
16726
16727   M (ONE_ADD_DEL_ADJACENCY, mp);
16728   mp->is_add = is_add;
16729   mp->vni = htonl (vni);
16730   mp->leid_len = leid_len;
16731   mp->reid_len = reid_len;
16732   mp->eid_type = reid_type;
16733
16734   switch (mp->eid_type)
16735     {
16736     case 0:
16737       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
16738       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
16739       break;
16740     case 1:
16741       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
16742       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
16743       break;
16744     case 2:
16745       clib_memcpy (mp->leid, leid_mac, 6);
16746       clib_memcpy (mp->reid, reid_mac, 6);
16747       break;
16748     default:
16749       errmsg ("unknown EID type %d!", mp->eid_type);
16750       return 0;
16751     }
16752
16753   /* send it... */
16754   S (mp);
16755
16756   /* Wait for a reply... */
16757   W (ret);
16758   return ret;
16759 }
16760
16761 #define api_lisp_add_del_adjacency api_one_add_del_adjacency
16762
16763 uword
16764 unformat_gpe_encap_mode (unformat_input_t * input, va_list * args)
16765 {
16766   u32 *mode = va_arg (*args, u32 *);
16767
16768   if (unformat (input, "lisp"))
16769     *mode = 0;
16770   else if (unformat (input, "vxlan"))
16771     *mode = 1;
16772   else
16773     return 0;
16774
16775   return 1;
16776 }
16777
16778 static int
16779 api_gpe_get_encap_mode (vat_main_t * vam)
16780 {
16781   vl_api_gpe_get_encap_mode_t *mp;
16782   int ret;
16783
16784   /* Construct the API message */
16785   M (GPE_GET_ENCAP_MODE, mp);
16786
16787   /* send it... */
16788   S (mp);
16789
16790   /* Wait for a reply... */
16791   W (ret);
16792   return ret;
16793 }
16794
16795 static int
16796 api_gpe_set_encap_mode (vat_main_t * vam)
16797 {
16798   unformat_input_t *input = vam->input;
16799   vl_api_gpe_set_encap_mode_t *mp;
16800   int ret;
16801   u32 mode = 0;
16802
16803   /* Parse args required to build the message */
16804   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16805     {
16806       if (unformat (input, "%U", unformat_gpe_encap_mode, &mode))
16807         ;
16808       else
16809         break;
16810     }
16811
16812   /* Construct the API message */
16813   M (GPE_SET_ENCAP_MODE, mp);
16814
16815   mp->mode = mode;
16816
16817   /* send it... */
16818   S (mp);
16819
16820   /* Wait for a reply... */
16821   W (ret);
16822   return ret;
16823 }
16824
16825 static int
16826 api_lisp_gpe_add_del_iface (vat_main_t * vam)
16827 {
16828   unformat_input_t *input = vam->input;
16829   vl_api_gpe_add_del_iface_t *mp;
16830   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
16831   u32 dp_table = 0, vni = 0;
16832   int ret;
16833
16834   /* Parse args required to build the message */
16835   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16836     {
16837       if (unformat (input, "up"))
16838         {
16839           action_set = 1;
16840           is_add = 1;
16841         }
16842       else if (unformat (input, "down"))
16843         {
16844           action_set = 1;
16845           is_add = 0;
16846         }
16847       else if (unformat (input, "table_id %d", &dp_table))
16848         {
16849           dp_table_set = 1;
16850         }
16851       else if (unformat (input, "bd_id %d", &dp_table))
16852         {
16853           dp_table_set = 1;
16854           is_l2 = 1;
16855         }
16856       else if (unformat (input, "vni %d", &vni))
16857         {
16858           vni_set = 1;
16859         }
16860       else
16861         break;
16862     }
16863
16864   if (action_set == 0)
16865     {
16866       errmsg ("Action not set");
16867       return -99;
16868     }
16869   if (dp_table_set == 0 || vni_set == 0)
16870     {
16871       errmsg ("vni and dp_table must be set");
16872       return -99;
16873     }
16874
16875   /* Construct the API message */
16876   M (GPE_ADD_DEL_IFACE, mp);
16877
16878   mp->is_add = is_add;
16879   mp->dp_table = clib_host_to_net_u32 (dp_table);
16880   mp->is_l2 = is_l2;
16881   mp->vni = clib_host_to_net_u32 (vni);
16882
16883   /* send it... */
16884   S (mp);
16885
16886   /* Wait for a reply... */
16887   W (ret);
16888   return ret;
16889 }
16890
16891 static int
16892 api_one_map_register_fallback_threshold (vat_main_t * vam)
16893 {
16894   unformat_input_t *input = vam->input;
16895   vl_api_one_map_register_fallback_threshold_t *mp;
16896   u32 value = 0;
16897   u8 is_set = 0;
16898   int ret;
16899
16900   /* Parse args required to build the message */
16901   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16902     {
16903       if (unformat (input, "%u", &value))
16904         is_set = 1;
16905       else
16906         {
16907           clib_warning ("parse error '%U'", format_unformat_error, input);
16908           return -99;
16909         }
16910     }
16911
16912   if (!is_set)
16913     {
16914       errmsg ("fallback threshold value is missing!");
16915       return -99;
16916     }
16917
16918   M (ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
16919   mp->value = clib_host_to_net_u32 (value);
16920
16921   /* send it... */
16922   S (mp);
16923
16924   /* Wait for a reply... */
16925   W (ret);
16926   return ret;
16927 }
16928
16929 static int
16930 api_show_one_map_register_fallback_threshold (vat_main_t * vam)
16931 {
16932   vl_api_show_one_map_register_fallback_threshold_t *mp;
16933   int ret;
16934
16935   M (SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
16936
16937   /* send it... */
16938   S (mp);
16939
16940   /* Wait for a reply... */
16941   W (ret);
16942   return ret;
16943 }
16944
16945 uword
16946 unformat_lisp_transport_protocol (unformat_input_t * input, va_list * args)
16947 {
16948   u32 *proto = va_arg (*args, u32 *);
16949
16950   if (unformat (input, "udp"))
16951     *proto = 1;
16952   else if (unformat (input, "api"))
16953     *proto = 2;
16954   else
16955     return 0;
16956
16957   return 1;
16958 }
16959
16960 static int
16961 api_one_set_transport_protocol (vat_main_t * vam)
16962 {
16963   unformat_input_t *input = vam->input;
16964   vl_api_one_set_transport_protocol_t *mp;
16965   u8 is_set = 0;
16966   u32 protocol = 0;
16967   int ret;
16968
16969   /* Parse args required to build the message */
16970   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16971     {
16972       if (unformat (input, "%U", unformat_lisp_transport_protocol, &protocol))
16973         is_set = 1;
16974       else
16975         {
16976           clib_warning ("parse error '%U'", format_unformat_error, input);
16977           return -99;
16978         }
16979     }
16980
16981   if (!is_set)
16982     {
16983       errmsg ("Transport protocol missing!");
16984       return -99;
16985     }
16986
16987   M (ONE_SET_TRANSPORT_PROTOCOL, mp);
16988   mp->protocol = (u8) protocol;
16989
16990   /* send it... */
16991   S (mp);
16992
16993   /* Wait for a reply... */
16994   W (ret);
16995   return ret;
16996 }
16997
16998 static int
16999 api_one_get_transport_protocol (vat_main_t * vam)
17000 {
17001   vl_api_one_get_transport_protocol_t *mp;
17002   int ret;
17003
17004   M (ONE_GET_TRANSPORT_PROTOCOL, mp);
17005
17006   /* send it... */
17007   S (mp);
17008
17009   /* Wait for a reply... */
17010   W (ret);
17011   return ret;
17012 }
17013
17014 static int
17015 api_one_map_register_set_ttl (vat_main_t * vam)
17016 {
17017   unformat_input_t *input = vam->input;
17018   vl_api_one_map_register_set_ttl_t *mp;
17019   u32 ttl = 0;
17020   u8 is_set = 0;
17021   int ret;
17022
17023   /* Parse args required to build the message */
17024   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17025     {
17026       if (unformat (input, "%u", &ttl))
17027         is_set = 1;
17028       else
17029         {
17030           clib_warning ("parse error '%U'", format_unformat_error, input);
17031           return -99;
17032         }
17033     }
17034
17035   if (!is_set)
17036     {
17037       errmsg ("TTL value missing!");
17038       return -99;
17039     }
17040
17041   M (ONE_MAP_REGISTER_SET_TTL, mp);
17042   mp->ttl = clib_host_to_net_u32 (ttl);
17043
17044   /* send it... */
17045   S (mp);
17046
17047   /* Wait for a reply... */
17048   W (ret);
17049   return ret;
17050 }
17051
17052 static int
17053 api_show_one_map_register_ttl (vat_main_t * vam)
17054 {
17055   vl_api_show_one_map_register_ttl_t *mp;
17056   int ret;
17057
17058   M (SHOW_ONE_MAP_REGISTER_TTL, mp);
17059
17060   /* send it... */
17061   S (mp);
17062
17063   /* Wait for a reply... */
17064   W (ret);
17065   return ret;
17066 }
17067
17068 /**
17069  * Add/del map request itr rlocs from ONE control plane and updates
17070  *
17071  * @param vam vpp API test context
17072  * @return return code
17073  */
17074 static int
17075 api_one_add_del_map_request_itr_rlocs (vat_main_t * vam)
17076 {
17077   unformat_input_t *input = vam->input;
17078   vl_api_one_add_del_map_request_itr_rlocs_t *mp;
17079   u8 *locator_set_name = 0;
17080   u8 locator_set_name_set = 0;
17081   u8 is_add = 1;
17082   int ret;
17083
17084   /* Parse args required to build the message */
17085   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17086     {
17087       if (unformat (input, "del"))
17088         {
17089           is_add = 0;
17090         }
17091       else if (unformat (input, "%_%v%_", &locator_set_name))
17092         {
17093           locator_set_name_set = 1;
17094         }
17095       else
17096         {
17097           clib_warning ("parse error '%U'", format_unformat_error, input);
17098           return -99;
17099         }
17100     }
17101
17102   if (is_add && !locator_set_name_set)
17103     {
17104       errmsg ("itr-rloc is not set!");
17105       return -99;
17106     }
17107
17108   if (is_add && vec_len (locator_set_name) > 64)
17109     {
17110       errmsg ("itr-rloc locator-set name too long");
17111       vec_free (locator_set_name);
17112       return -99;
17113     }
17114
17115   M (ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS, mp);
17116   mp->is_add = is_add;
17117   if (is_add)
17118     {
17119       clib_memcpy (mp->locator_set_name, locator_set_name,
17120                    vec_len (locator_set_name));
17121     }
17122   else
17123     {
17124       clib_memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
17125     }
17126   vec_free (locator_set_name);
17127
17128   /* send it... */
17129   S (mp);
17130
17131   /* Wait for a reply... */
17132   W (ret);
17133   return ret;
17134 }
17135
17136 #define api_lisp_add_del_map_request_itr_rlocs api_one_add_del_map_request_itr_rlocs
17137
17138 static int
17139 api_one_locator_dump (vat_main_t * vam)
17140 {
17141   unformat_input_t *input = vam->input;
17142   vl_api_one_locator_dump_t *mp;
17143   vl_api_control_ping_t *mp_ping;
17144   u8 is_index_set = 0, is_name_set = 0;
17145   u8 *ls_name = 0;
17146   u32 ls_index = ~0;
17147   int ret;
17148
17149   /* Parse args required to build the message */
17150   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17151     {
17152       if (unformat (input, "ls_name %_%v%_", &ls_name))
17153         {
17154           is_name_set = 1;
17155         }
17156       else if (unformat (input, "ls_index %d", &ls_index))
17157         {
17158           is_index_set = 1;
17159         }
17160       else
17161         {
17162           errmsg ("parse error '%U'", format_unformat_error, input);
17163           return -99;
17164         }
17165     }
17166
17167   if (!is_index_set && !is_name_set)
17168     {
17169       errmsg ("error: expected one of index or name!");
17170       return -99;
17171     }
17172
17173   if (is_index_set && is_name_set)
17174     {
17175       errmsg ("error: only one param expected!");
17176       return -99;
17177     }
17178
17179   if (vec_len (ls_name) > 62)
17180     {
17181       errmsg ("error: locator set name too long!");
17182       return -99;
17183     }
17184
17185   if (!vam->json_output)
17186     {
17187       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
17188     }
17189
17190   M (ONE_LOCATOR_DUMP, mp);
17191   mp->is_index_set = is_index_set;
17192
17193   if (is_index_set)
17194     mp->ls_index = clib_host_to_net_u32 (ls_index);
17195   else
17196     {
17197       vec_add1 (ls_name, 0);
17198       strncpy ((char *) mp->ls_name, (char *) ls_name,
17199                sizeof (mp->ls_name) - 1);
17200     }
17201
17202   /* send it... */
17203   S (mp);
17204
17205   /* Use a control ping for synchronization */
17206   MPING (CONTROL_PING, mp_ping);
17207   S (mp_ping);
17208
17209   /* Wait for a reply... */
17210   W (ret);
17211   return ret;
17212 }
17213
17214 #define api_lisp_locator_dump api_one_locator_dump
17215
17216 static int
17217 api_one_locator_set_dump (vat_main_t * vam)
17218 {
17219   vl_api_one_locator_set_dump_t *mp;
17220   vl_api_control_ping_t *mp_ping;
17221   unformat_input_t *input = vam->input;
17222   u8 filter = 0;
17223   int ret;
17224
17225   /* Parse args required to build the message */
17226   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17227     {
17228       if (unformat (input, "local"))
17229         {
17230           filter = 1;
17231         }
17232       else if (unformat (input, "remote"))
17233         {
17234           filter = 2;
17235         }
17236       else
17237         {
17238           errmsg ("parse error '%U'", format_unformat_error, input);
17239           return -99;
17240         }
17241     }
17242
17243   if (!vam->json_output)
17244     {
17245       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
17246     }
17247
17248   M (ONE_LOCATOR_SET_DUMP, mp);
17249
17250   mp->filter = filter;
17251
17252   /* send it... */
17253   S (mp);
17254
17255   /* Use a control ping for synchronization */
17256   MPING (CONTROL_PING, mp_ping);
17257   S (mp_ping);
17258
17259   /* Wait for a reply... */
17260   W (ret);
17261   return ret;
17262 }
17263
17264 #define api_lisp_locator_set_dump api_one_locator_set_dump
17265
17266 static int
17267 api_one_eid_table_map_dump (vat_main_t * vam)
17268 {
17269   u8 is_l2 = 0;
17270   u8 mode_set = 0;
17271   unformat_input_t *input = vam->input;
17272   vl_api_one_eid_table_map_dump_t *mp;
17273   vl_api_control_ping_t *mp_ping;
17274   int ret;
17275
17276   /* Parse args required to build the message */
17277   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17278     {
17279       if (unformat (input, "l2"))
17280         {
17281           is_l2 = 1;
17282           mode_set = 1;
17283         }
17284       else if (unformat (input, "l3"))
17285         {
17286           is_l2 = 0;
17287           mode_set = 1;
17288         }
17289       else
17290         {
17291           errmsg ("parse error '%U'", format_unformat_error, input);
17292           return -99;
17293         }
17294     }
17295
17296   if (!mode_set)
17297     {
17298       errmsg ("expected one of 'l2' or 'l3' parameter!");
17299       return -99;
17300     }
17301
17302   if (!vam->json_output)
17303     {
17304       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
17305     }
17306
17307   M (ONE_EID_TABLE_MAP_DUMP, mp);
17308   mp->is_l2 = is_l2;
17309
17310   /* send it... */
17311   S (mp);
17312
17313   /* Use a control ping for synchronization */
17314   MPING (CONTROL_PING, mp_ping);
17315   S (mp_ping);
17316
17317   /* Wait for a reply... */
17318   W (ret);
17319   return ret;
17320 }
17321
17322 #define api_lisp_eid_table_map_dump api_one_eid_table_map_dump
17323
17324 static int
17325 api_one_eid_table_vni_dump (vat_main_t * vam)
17326 {
17327   vl_api_one_eid_table_vni_dump_t *mp;
17328   vl_api_control_ping_t *mp_ping;
17329   int ret;
17330
17331   if (!vam->json_output)
17332     {
17333       print (vam->ofp, "VNI");
17334     }
17335
17336   M (ONE_EID_TABLE_VNI_DUMP, mp);
17337
17338   /* send it... */
17339   S (mp);
17340
17341   /* Use a control ping for synchronization */
17342   MPING (CONTROL_PING, mp_ping);
17343   S (mp_ping);
17344
17345   /* Wait for a reply... */
17346   W (ret);
17347   return ret;
17348 }
17349
17350 #define api_lisp_eid_table_vni_dump api_one_eid_table_vni_dump
17351
17352 static int
17353 api_one_eid_table_dump (vat_main_t * vam)
17354 {
17355   unformat_input_t *i = vam->input;
17356   vl_api_one_eid_table_dump_t *mp;
17357   vl_api_control_ping_t *mp_ping;
17358   struct in_addr ip4;
17359   struct in6_addr ip6;
17360   u8 mac[6];
17361   u8 eid_type = ~0, eid_set = 0;
17362   u32 prefix_length = ~0, t, vni = 0;
17363   u8 filter = 0;
17364   int ret;
17365   lisp_nsh_api_t nsh;
17366
17367   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17368     {
17369       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
17370         {
17371           eid_set = 1;
17372           eid_type = 0;
17373           prefix_length = t;
17374         }
17375       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
17376         {
17377           eid_set = 1;
17378           eid_type = 1;
17379           prefix_length = t;
17380         }
17381       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
17382         {
17383           eid_set = 1;
17384           eid_type = 2;
17385         }
17386       else if (unformat (i, "eid %U", unformat_nsh_address, &nsh))
17387         {
17388           eid_set = 1;
17389           eid_type = 3;
17390         }
17391       else if (unformat (i, "vni %d", &t))
17392         {
17393           vni = t;
17394         }
17395       else if (unformat (i, "local"))
17396         {
17397           filter = 1;
17398         }
17399       else if (unformat (i, "remote"))
17400         {
17401           filter = 2;
17402         }
17403       else
17404         {
17405           errmsg ("parse error '%U'", format_unformat_error, i);
17406           return -99;
17407         }
17408     }
17409
17410   if (!vam->json_output)
17411     {
17412       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
17413              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
17414     }
17415
17416   M (ONE_EID_TABLE_DUMP, mp);
17417
17418   mp->filter = filter;
17419   if (eid_set)
17420     {
17421       mp->eid_set = 1;
17422       mp->vni = htonl (vni);
17423       mp->eid_type = eid_type;
17424       switch (eid_type)
17425         {
17426         case 0:
17427           mp->prefix_length = prefix_length;
17428           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
17429           break;
17430         case 1:
17431           mp->prefix_length = prefix_length;
17432           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
17433           break;
17434         case 2:
17435           clib_memcpy (mp->eid, mac, sizeof (mac));
17436           break;
17437         case 3:
17438           clib_memcpy (mp->eid, &nsh, sizeof (nsh));
17439           break;
17440         default:
17441           errmsg ("unknown EID type %d!", eid_type);
17442           return -99;
17443         }
17444     }
17445
17446   /* send it... */
17447   S (mp);
17448
17449   /* Use a control ping for synchronization */
17450   MPING (CONTROL_PING, mp_ping);
17451   S (mp_ping);
17452
17453   /* Wait for a reply... */
17454   W (ret);
17455   return ret;
17456 }
17457
17458 #define api_lisp_eid_table_dump api_one_eid_table_dump
17459
17460 static int
17461 api_lisp_gpe_fwd_entries_get (vat_main_t * vam)
17462 {
17463   unformat_input_t *i = vam->input;
17464   vl_api_gpe_fwd_entries_get_t *mp;
17465   u8 vni_set = 0;
17466   u32 vni = ~0;
17467   int ret;
17468
17469   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17470     {
17471       if (unformat (i, "vni %d", &vni))
17472         {
17473           vni_set = 1;
17474         }
17475       else
17476         {
17477           errmsg ("parse error '%U'", format_unformat_error, i);
17478           return -99;
17479         }
17480     }
17481
17482   if (!vni_set)
17483     {
17484       errmsg ("vni not set!");
17485       return -99;
17486     }
17487
17488   if (!vam->json_output)
17489     {
17490       print (vam->ofp, "%10s %10s %s %40s", "fwd_index", "dp_table",
17491              "leid", "reid");
17492     }
17493
17494   M (GPE_FWD_ENTRIES_GET, mp);
17495   mp->vni = clib_host_to_net_u32 (vni);
17496
17497   /* send it... */
17498   S (mp);
17499
17500   /* Wait for a reply... */
17501   W (ret);
17502   return ret;
17503 }
17504
17505 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_endian vl_noop_handler
17506 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_print vl_noop_handler
17507 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_endian vl_noop_handler
17508 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_print vl_noop_handler
17509 #define vl_api_gpe_fwd_entries_get_reply_t_endian vl_noop_handler
17510 #define vl_api_gpe_fwd_entries_get_reply_t_print vl_noop_handler
17511 #define vl_api_gpe_fwd_entry_path_details_t_endian vl_noop_handler
17512 #define vl_api_gpe_fwd_entry_path_details_t_print vl_noop_handler
17513
17514 static int
17515 api_one_adjacencies_get (vat_main_t * vam)
17516 {
17517   unformat_input_t *i = vam->input;
17518   vl_api_one_adjacencies_get_t *mp;
17519   u8 vni_set = 0;
17520   u32 vni = ~0;
17521   int ret;
17522
17523   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17524     {
17525       if (unformat (i, "vni %d", &vni))
17526         {
17527           vni_set = 1;
17528         }
17529       else
17530         {
17531           errmsg ("parse error '%U'", format_unformat_error, i);
17532           return -99;
17533         }
17534     }
17535
17536   if (!vni_set)
17537     {
17538       errmsg ("vni not set!");
17539       return -99;
17540     }
17541
17542   if (!vam->json_output)
17543     {
17544       print (vam->ofp, "%s %40s", "leid", "reid");
17545     }
17546
17547   M (ONE_ADJACENCIES_GET, mp);
17548   mp->vni = clib_host_to_net_u32 (vni);
17549
17550   /* send it... */
17551   S (mp);
17552
17553   /* Wait for a reply... */
17554   W (ret);
17555   return ret;
17556 }
17557
17558 #define api_lisp_adjacencies_get api_one_adjacencies_get
17559
17560 static int
17561 api_gpe_native_fwd_rpaths_get (vat_main_t * vam)
17562 {
17563   unformat_input_t *i = vam->input;
17564   vl_api_gpe_native_fwd_rpaths_get_t *mp;
17565   int ret;
17566   u8 ip_family_set = 0, is_ip4 = 1;
17567
17568   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17569     {
17570       if (unformat (i, "ip4"))
17571         {
17572           ip_family_set = 1;
17573           is_ip4 = 1;
17574         }
17575       else if (unformat (i, "ip6"))
17576         {
17577           ip_family_set = 1;
17578           is_ip4 = 0;
17579         }
17580       else
17581         {
17582           errmsg ("parse error '%U'", format_unformat_error, i);
17583           return -99;
17584         }
17585     }
17586
17587   if (!ip_family_set)
17588     {
17589       errmsg ("ip family not set!");
17590       return -99;
17591     }
17592
17593   M (GPE_NATIVE_FWD_RPATHS_GET, mp);
17594   mp->is_ip4 = is_ip4;
17595
17596   /* send it... */
17597   S (mp);
17598
17599   /* Wait for a reply... */
17600   W (ret);
17601   return ret;
17602 }
17603
17604 static int
17605 api_gpe_fwd_entry_vnis_get (vat_main_t * vam)
17606 {
17607   vl_api_gpe_fwd_entry_vnis_get_t *mp;
17608   int ret;
17609
17610   if (!vam->json_output)
17611     {
17612       print (vam->ofp, "VNIs");
17613     }
17614
17615   M (GPE_FWD_ENTRY_VNIS_GET, mp);
17616
17617   /* send it... */
17618   S (mp);
17619
17620   /* Wait for a reply... */
17621   W (ret);
17622   return ret;
17623 }
17624
17625 static int
17626 api_gpe_add_del_native_fwd_rpath (vat_main_t * vam)
17627 {
17628   unformat_input_t *i = vam->input;
17629   vl_api_gpe_add_del_native_fwd_rpath_t *mp;
17630   int ret = 0;
17631   u8 is_add = 1, ip_set = 0, is_ip4 = 1;
17632   struct in_addr ip4;
17633   struct in6_addr ip6;
17634   u32 table_id = 0, nh_sw_if_index = ~0;
17635
17636   clib_memset (&ip4, 0, sizeof (ip4));
17637   clib_memset (&ip6, 0, sizeof (ip6));
17638
17639   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17640     {
17641       if (unformat (i, "del"))
17642         is_add = 0;
17643       else if (unformat (i, "via %U %U", unformat_ip4_address, &ip4,
17644                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
17645         {
17646           ip_set = 1;
17647           is_ip4 = 1;
17648         }
17649       else if (unformat (i, "via %U %U", unformat_ip6_address, &ip6,
17650                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
17651         {
17652           ip_set = 1;
17653           is_ip4 = 0;
17654         }
17655       else if (unformat (i, "via %U", unformat_ip4_address, &ip4))
17656         {
17657           ip_set = 1;
17658           is_ip4 = 1;
17659           nh_sw_if_index = ~0;
17660         }
17661       else if (unformat (i, "via %U", unformat_ip6_address, &ip6))
17662         {
17663           ip_set = 1;
17664           is_ip4 = 0;
17665           nh_sw_if_index = ~0;
17666         }
17667       else if (unformat (i, "table %d", &table_id))
17668         ;
17669       else
17670         {
17671           errmsg ("parse error '%U'", format_unformat_error, i);
17672           return -99;
17673         }
17674     }
17675
17676   if (!ip_set)
17677     {
17678       errmsg ("nh addr not set!");
17679       return -99;
17680     }
17681
17682   M (GPE_ADD_DEL_NATIVE_FWD_RPATH, mp);
17683   mp->is_add = is_add;
17684   mp->table_id = clib_host_to_net_u32 (table_id);
17685   mp->nh_sw_if_index = clib_host_to_net_u32 (nh_sw_if_index);
17686   mp->is_ip4 = is_ip4;
17687   if (is_ip4)
17688     clib_memcpy (mp->nh_addr, &ip4, sizeof (ip4));
17689   else
17690     clib_memcpy (mp->nh_addr, &ip6, sizeof (ip6));
17691
17692   /* send it... */
17693   S (mp);
17694
17695   /* Wait for a reply... */
17696   W (ret);
17697   return ret;
17698 }
17699
17700 static int
17701 api_one_map_server_dump (vat_main_t * vam)
17702 {
17703   vl_api_one_map_server_dump_t *mp;
17704   vl_api_control_ping_t *mp_ping;
17705   int ret;
17706
17707   if (!vam->json_output)
17708     {
17709       print (vam->ofp, "%=20s", "Map server");
17710     }
17711
17712   M (ONE_MAP_SERVER_DUMP, mp);
17713   /* send it... */
17714   S (mp);
17715
17716   /* Use a control ping for synchronization */
17717   MPING (CONTROL_PING, mp_ping);
17718   S (mp_ping);
17719
17720   /* Wait for a reply... */
17721   W (ret);
17722   return ret;
17723 }
17724
17725 #define api_lisp_map_server_dump api_one_map_server_dump
17726
17727 static int
17728 api_one_map_resolver_dump (vat_main_t * vam)
17729 {
17730   vl_api_one_map_resolver_dump_t *mp;
17731   vl_api_control_ping_t *mp_ping;
17732   int ret;
17733
17734   if (!vam->json_output)
17735     {
17736       print (vam->ofp, "%=20s", "Map resolver");
17737     }
17738
17739   M (ONE_MAP_RESOLVER_DUMP, mp);
17740   /* send it... */
17741   S (mp);
17742
17743   /* Use a control ping for synchronization */
17744   MPING (CONTROL_PING, mp_ping);
17745   S (mp_ping);
17746
17747   /* Wait for a reply... */
17748   W (ret);
17749   return ret;
17750 }
17751
17752 #define api_lisp_map_resolver_dump api_one_map_resolver_dump
17753
17754 static int
17755 api_one_stats_flush (vat_main_t * vam)
17756 {
17757   vl_api_one_stats_flush_t *mp;
17758   int ret = 0;
17759
17760   M (ONE_STATS_FLUSH, mp);
17761   S (mp);
17762   W (ret);
17763   return ret;
17764 }
17765
17766 static int
17767 api_one_stats_dump (vat_main_t * vam)
17768 {
17769   vl_api_one_stats_dump_t *mp;
17770   vl_api_control_ping_t *mp_ping;
17771   int ret;
17772
17773   M (ONE_STATS_DUMP, mp);
17774   /* send it... */
17775   S (mp);
17776
17777   /* Use a control ping for synchronization */
17778   MPING (CONTROL_PING, mp_ping);
17779   S (mp_ping);
17780
17781   /* Wait for a reply... */
17782   W (ret);
17783   return ret;
17784 }
17785
17786 static int
17787 api_show_one_status (vat_main_t * vam)
17788 {
17789   vl_api_show_one_status_t *mp;
17790   int ret;
17791
17792   if (!vam->json_output)
17793     {
17794       print (vam->ofp, "%-20s%-16s", "ONE status", "locator-set");
17795     }
17796
17797   M (SHOW_ONE_STATUS, mp);
17798   /* send it... */
17799   S (mp);
17800   /* Wait for a reply... */
17801   W (ret);
17802   return ret;
17803 }
17804
17805 #define api_show_lisp_status api_show_one_status
17806
17807 static int
17808 api_lisp_gpe_fwd_entry_path_dump (vat_main_t * vam)
17809 {
17810   vl_api_gpe_fwd_entry_path_dump_t *mp;
17811   vl_api_control_ping_t *mp_ping;
17812   unformat_input_t *i = vam->input;
17813   u32 fwd_entry_index = ~0;
17814   int ret;
17815
17816   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17817     {
17818       if (unformat (i, "index %d", &fwd_entry_index))
17819         ;
17820       else
17821         break;
17822     }
17823
17824   if (~0 == fwd_entry_index)
17825     {
17826       errmsg ("no index specified!");
17827       return -99;
17828     }
17829
17830   if (!vam->json_output)
17831     {
17832       print (vam->ofp, "first line");
17833     }
17834
17835   M (GPE_FWD_ENTRY_PATH_DUMP, mp);
17836
17837   /* send it... */
17838   S (mp);
17839   /* Use a control ping for synchronization */
17840   MPING (CONTROL_PING, mp_ping);
17841   S (mp_ping);
17842
17843   /* Wait for a reply... */
17844   W (ret);
17845   return ret;
17846 }
17847
17848 static int
17849 api_one_get_map_request_itr_rlocs (vat_main_t * vam)
17850 {
17851   vl_api_one_get_map_request_itr_rlocs_t *mp;
17852   int ret;
17853
17854   if (!vam->json_output)
17855     {
17856       print (vam->ofp, "%=20s", "itr-rlocs:");
17857     }
17858
17859   M (ONE_GET_MAP_REQUEST_ITR_RLOCS, mp);
17860   /* send it... */
17861   S (mp);
17862   /* Wait for a reply... */
17863   W (ret);
17864   return ret;
17865 }
17866
17867 #define api_lisp_get_map_request_itr_rlocs api_one_get_map_request_itr_rlocs
17868
17869 static int
17870 api_af_packet_create (vat_main_t * vam)
17871 {
17872   unformat_input_t *i = vam->input;
17873   vl_api_af_packet_create_t *mp;
17874   u8 *host_if_name = 0;
17875   u8 hw_addr[6];
17876   u8 random_hw_addr = 1;
17877   int ret;
17878
17879   clib_memset (hw_addr, 0, sizeof (hw_addr));
17880
17881   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17882     {
17883       if (unformat (i, "name %s", &host_if_name))
17884         vec_add1 (host_if_name, 0);
17885       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
17886         random_hw_addr = 0;
17887       else
17888         break;
17889     }
17890
17891   if (!vec_len (host_if_name))
17892     {
17893       errmsg ("host-interface name must be specified");
17894       return -99;
17895     }
17896
17897   if (vec_len (host_if_name) > 64)
17898     {
17899       errmsg ("host-interface name too long");
17900       return -99;
17901     }
17902
17903   M (AF_PACKET_CREATE, mp);
17904
17905   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
17906   clib_memcpy (mp->hw_addr, hw_addr, 6);
17907   mp->use_random_hw_addr = random_hw_addr;
17908   vec_free (host_if_name);
17909
17910   S (mp);
17911
17912   /* *INDENT-OFF* */
17913   W2 (ret,
17914       ({
17915         if (ret == 0)
17916           fprintf (vam->ofp ? vam->ofp : stderr,
17917                    " new sw_if_index = %d\n", vam->sw_if_index);
17918       }));
17919   /* *INDENT-ON* */
17920   return ret;
17921 }
17922
17923 static int
17924 api_af_packet_delete (vat_main_t * vam)
17925 {
17926   unformat_input_t *i = vam->input;
17927   vl_api_af_packet_delete_t *mp;
17928   u8 *host_if_name = 0;
17929   int ret;
17930
17931   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17932     {
17933       if (unformat (i, "name %s", &host_if_name))
17934         vec_add1 (host_if_name, 0);
17935       else
17936         break;
17937     }
17938
17939   if (!vec_len (host_if_name))
17940     {
17941       errmsg ("host-interface name must be specified");
17942       return -99;
17943     }
17944
17945   if (vec_len (host_if_name) > 64)
17946     {
17947       errmsg ("host-interface name too long");
17948       return -99;
17949     }
17950
17951   M (AF_PACKET_DELETE, mp);
17952
17953   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
17954   vec_free (host_if_name);
17955
17956   S (mp);
17957   W (ret);
17958   return ret;
17959 }
17960
17961 static void vl_api_af_packet_details_t_handler
17962   (vl_api_af_packet_details_t * mp)
17963 {
17964   vat_main_t *vam = &vat_main;
17965
17966   print (vam->ofp, "%-16s %d",
17967          mp->host_if_name, clib_net_to_host_u32 (mp->sw_if_index));
17968 }
17969
17970 static void vl_api_af_packet_details_t_handler_json
17971   (vl_api_af_packet_details_t * mp)
17972 {
17973   vat_main_t *vam = &vat_main;
17974   vat_json_node_t *node = NULL;
17975
17976   if (VAT_JSON_ARRAY != vam->json_tree.type)
17977     {
17978       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17979       vat_json_init_array (&vam->json_tree);
17980     }
17981   node = vat_json_array_add (&vam->json_tree);
17982
17983   vat_json_init_object (node);
17984   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
17985   vat_json_object_add_string_copy (node, "dev_name", mp->host_if_name);
17986 }
17987
17988 static int
17989 api_af_packet_dump (vat_main_t * vam)
17990 {
17991   vl_api_af_packet_dump_t *mp;
17992   vl_api_control_ping_t *mp_ping;
17993   int ret;
17994
17995   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
17996   /* Get list of tap interfaces */
17997   M (AF_PACKET_DUMP, mp);
17998   S (mp);
17999
18000   /* Use a control ping for synchronization */
18001   MPING (CONTROL_PING, mp_ping);
18002   S (mp_ping);
18003
18004   W (ret);
18005   return ret;
18006 }
18007
18008 static int
18009 api_policer_add_del (vat_main_t * vam)
18010 {
18011   unformat_input_t *i = vam->input;
18012   vl_api_policer_add_del_t *mp;
18013   u8 is_add = 1;
18014   u8 *name = 0;
18015   u32 cir = 0;
18016   u32 eir = 0;
18017   u64 cb = 0;
18018   u64 eb = 0;
18019   u8 rate_type = 0;
18020   u8 round_type = 0;
18021   u8 type = 0;
18022   u8 color_aware = 0;
18023   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
18024   int ret;
18025
18026   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
18027   conform_action.dscp = 0;
18028   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
18029   exceed_action.dscp = 0;
18030   violate_action.action_type = SSE2_QOS_ACTION_DROP;
18031   violate_action.dscp = 0;
18032
18033   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18034     {
18035       if (unformat (i, "del"))
18036         is_add = 0;
18037       else if (unformat (i, "name %s", &name))
18038         vec_add1 (name, 0);
18039       else if (unformat (i, "cir %u", &cir))
18040         ;
18041       else if (unformat (i, "eir %u", &eir))
18042         ;
18043       else if (unformat (i, "cb %u", &cb))
18044         ;
18045       else if (unformat (i, "eb %u", &eb))
18046         ;
18047       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
18048                          &rate_type))
18049         ;
18050       else if (unformat (i, "round_type %U", unformat_policer_round_type,
18051                          &round_type))
18052         ;
18053       else if (unformat (i, "type %U", unformat_policer_type, &type))
18054         ;
18055       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
18056                          &conform_action))
18057         ;
18058       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
18059                          &exceed_action))
18060         ;
18061       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
18062                          &violate_action))
18063         ;
18064       else if (unformat (i, "color-aware"))
18065         color_aware = 1;
18066       else
18067         break;
18068     }
18069
18070   if (!vec_len (name))
18071     {
18072       errmsg ("policer name must be specified");
18073       return -99;
18074     }
18075
18076   if (vec_len (name) > 64)
18077     {
18078       errmsg ("policer name too long");
18079       return -99;
18080     }
18081
18082   M (POLICER_ADD_DEL, mp);
18083
18084   clib_memcpy (mp->name, name, vec_len (name));
18085   vec_free (name);
18086   mp->is_add = is_add;
18087   mp->cir = ntohl (cir);
18088   mp->eir = ntohl (eir);
18089   mp->cb = clib_net_to_host_u64 (cb);
18090   mp->eb = clib_net_to_host_u64 (eb);
18091   mp->rate_type = rate_type;
18092   mp->round_type = round_type;
18093   mp->type = type;
18094   mp->conform_action_type = conform_action.action_type;
18095   mp->conform_dscp = conform_action.dscp;
18096   mp->exceed_action_type = exceed_action.action_type;
18097   mp->exceed_dscp = exceed_action.dscp;
18098   mp->violate_action_type = violate_action.action_type;
18099   mp->violate_dscp = violate_action.dscp;
18100   mp->color_aware = color_aware;
18101
18102   S (mp);
18103   W (ret);
18104   return ret;
18105 }
18106
18107 static int
18108 api_policer_dump (vat_main_t * vam)
18109 {
18110   unformat_input_t *i = vam->input;
18111   vl_api_policer_dump_t *mp;
18112   vl_api_control_ping_t *mp_ping;
18113   u8 *match_name = 0;
18114   u8 match_name_valid = 0;
18115   int ret;
18116
18117   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18118     {
18119       if (unformat (i, "name %s", &match_name))
18120         {
18121           vec_add1 (match_name, 0);
18122           match_name_valid = 1;
18123         }
18124       else
18125         break;
18126     }
18127
18128   M (POLICER_DUMP, mp);
18129   mp->match_name_valid = match_name_valid;
18130   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
18131   vec_free (match_name);
18132   /* send it... */
18133   S (mp);
18134
18135   /* Use a control ping for synchronization */
18136   MPING (CONTROL_PING, mp_ping);
18137   S (mp_ping);
18138
18139   /* Wait for a reply... */
18140   W (ret);
18141   return ret;
18142 }
18143
18144 static int
18145 api_policer_classify_set_interface (vat_main_t * vam)
18146 {
18147   unformat_input_t *i = vam->input;
18148   vl_api_policer_classify_set_interface_t *mp;
18149   u32 sw_if_index;
18150   int sw_if_index_set;
18151   u32 ip4_table_index = ~0;
18152   u32 ip6_table_index = ~0;
18153   u32 l2_table_index = ~0;
18154   u8 is_add = 1;
18155   int ret;
18156
18157   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18158     {
18159       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18160         sw_if_index_set = 1;
18161       else if (unformat (i, "sw_if_index %d", &sw_if_index))
18162         sw_if_index_set = 1;
18163       else if (unformat (i, "del"))
18164         is_add = 0;
18165       else if (unformat (i, "ip4-table %d", &ip4_table_index))
18166         ;
18167       else if (unformat (i, "ip6-table %d", &ip6_table_index))
18168         ;
18169       else if (unformat (i, "l2-table %d", &l2_table_index))
18170         ;
18171       else
18172         {
18173           clib_warning ("parse error '%U'", format_unformat_error, i);
18174           return -99;
18175         }
18176     }
18177
18178   if (sw_if_index_set == 0)
18179     {
18180       errmsg ("missing interface name or sw_if_index");
18181       return -99;
18182     }
18183
18184   M (POLICER_CLASSIFY_SET_INTERFACE, mp);
18185
18186   mp->sw_if_index = ntohl (sw_if_index);
18187   mp->ip4_table_index = ntohl (ip4_table_index);
18188   mp->ip6_table_index = ntohl (ip6_table_index);
18189   mp->l2_table_index = ntohl (l2_table_index);
18190   mp->is_add = is_add;
18191
18192   S (mp);
18193   W (ret);
18194   return ret;
18195 }
18196
18197 static int
18198 api_policer_classify_dump (vat_main_t * vam)
18199 {
18200   unformat_input_t *i = vam->input;
18201   vl_api_policer_classify_dump_t *mp;
18202   vl_api_control_ping_t *mp_ping;
18203   u8 type = POLICER_CLASSIFY_N_TABLES;
18204   int ret;
18205
18206   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
18207     ;
18208   else
18209     {
18210       errmsg ("classify table type must be specified");
18211       return -99;
18212     }
18213
18214   if (!vam->json_output)
18215     {
18216       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
18217     }
18218
18219   M (POLICER_CLASSIFY_DUMP, mp);
18220   mp->type = type;
18221   /* send it... */
18222   S (mp);
18223
18224   /* Use a control ping for synchronization */
18225   MPING (CONTROL_PING, mp_ping);
18226   S (mp_ping);
18227
18228   /* Wait for a reply... */
18229   W (ret);
18230   return ret;
18231 }
18232
18233 static int
18234 api_netmap_create (vat_main_t * vam)
18235 {
18236   unformat_input_t *i = vam->input;
18237   vl_api_netmap_create_t *mp;
18238   u8 *if_name = 0;
18239   u8 hw_addr[6];
18240   u8 random_hw_addr = 1;
18241   u8 is_pipe = 0;
18242   u8 is_master = 0;
18243   int ret;
18244
18245   clib_memset (hw_addr, 0, sizeof (hw_addr));
18246
18247   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18248     {
18249       if (unformat (i, "name %s", &if_name))
18250         vec_add1 (if_name, 0);
18251       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
18252         random_hw_addr = 0;
18253       else if (unformat (i, "pipe"))
18254         is_pipe = 1;
18255       else if (unformat (i, "master"))
18256         is_master = 1;
18257       else if (unformat (i, "slave"))
18258         is_master = 0;
18259       else
18260         break;
18261     }
18262
18263   if (!vec_len (if_name))
18264     {
18265       errmsg ("interface name must be specified");
18266       return -99;
18267     }
18268
18269   if (vec_len (if_name) > 64)
18270     {
18271       errmsg ("interface name too long");
18272       return -99;
18273     }
18274
18275   M (NETMAP_CREATE, mp);
18276
18277   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
18278   clib_memcpy (mp->hw_addr, hw_addr, 6);
18279   mp->use_random_hw_addr = random_hw_addr;
18280   mp->is_pipe = is_pipe;
18281   mp->is_master = is_master;
18282   vec_free (if_name);
18283
18284   S (mp);
18285   W (ret);
18286   return ret;
18287 }
18288
18289 static int
18290 api_netmap_delete (vat_main_t * vam)
18291 {
18292   unformat_input_t *i = vam->input;
18293   vl_api_netmap_delete_t *mp;
18294   u8 *if_name = 0;
18295   int ret;
18296
18297   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18298     {
18299       if (unformat (i, "name %s", &if_name))
18300         vec_add1 (if_name, 0);
18301       else
18302         break;
18303     }
18304
18305   if (!vec_len (if_name))
18306     {
18307       errmsg ("interface name must be specified");
18308       return -99;
18309     }
18310
18311   if (vec_len (if_name) > 64)
18312     {
18313       errmsg ("interface name too long");
18314       return -99;
18315     }
18316
18317   M (NETMAP_DELETE, mp);
18318
18319   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
18320   vec_free (if_name);
18321
18322   S (mp);
18323   W (ret);
18324   return ret;
18325 }
18326
18327 static u8 *
18328 format_fib_api_path_nh_proto (u8 * s, va_list * args)
18329 {
18330   vl_api_fib_path_nh_proto_t proto =
18331     va_arg (*args, vl_api_fib_path_nh_proto_t);
18332
18333   switch (proto)
18334     {
18335     case FIB_API_PATH_NH_PROTO_IP4:
18336       s = format (s, "ip4");
18337       break;
18338     case FIB_API_PATH_NH_PROTO_IP6:
18339       s = format (s, "ip6");
18340       break;
18341     case FIB_API_PATH_NH_PROTO_MPLS:
18342       s = format (s, "mpls");
18343       break;
18344     case FIB_API_PATH_NH_PROTO_BIER:
18345       s = format (s, "bier");
18346       break;
18347     case FIB_API_PATH_NH_PROTO_ETHERNET:
18348       s = format (s, "ethernet");
18349       break;
18350     }
18351
18352   return (s);
18353 }
18354
18355 static u8 *
18356 format_vl_api_ip_address_union (u8 * s, va_list * args)
18357 {
18358   vl_api_address_family_t af = va_arg (*args, vl_api_address_family_t);
18359   const vl_api_address_union_t *u = va_arg (*args, vl_api_address_union_t *);
18360
18361   switch (af)
18362     {
18363     case ADDRESS_IP4:
18364       s = format (s, "%U", format_ip4_address, u->ip4);
18365       break;
18366     case ADDRESS_IP6:
18367       s = format (s, "%U", format_ip6_address, u->ip6);
18368       break;
18369     }
18370   return (s);
18371 }
18372
18373 static u8 *
18374 format_vl_api_fib_path_type (u8 * s, va_list * args)
18375 {
18376   vl_api_fib_path_type_t t = va_arg (*args, vl_api_fib_path_type_t);
18377
18378   switch (t)
18379     {
18380     case FIB_API_PATH_TYPE_NORMAL:
18381       s = format (s, "normal");
18382       break;
18383     case FIB_API_PATH_TYPE_LOCAL:
18384       s = format (s, "local");
18385       break;
18386     case FIB_API_PATH_TYPE_DROP:
18387       s = format (s, "drop");
18388       break;
18389     case FIB_API_PATH_TYPE_UDP_ENCAP:
18390       s = format (s, "udp-encap");
18391       break;
18392     case FIB_API_PATH_TYPE_BIER_IMP:
18393       s = format (s, "bier-imp");
18394       break;
18395     case FIB_API_PATH_TYPE_ICMP_UNREACH:
18396       s = format (s, "unreach");
18397       break;
18398     case FIB_API_PATH_TYPE_ICMP_PROHIBIT:
18399       s = format (s, "prohibit");
18400       break;
18401     case FIB_API_PATH_TYPE_SOURCE_LOOKUP:
18402       s = format (s, "src-lookup");
18403       break;
18404     case FIB_API_PATH_TYPE_DVR:
18405       s = format (s, "dvr");
18406       break;
18407     case FIB_API_PATH_TYPE_INTERFACE_RX:
18408       s = format (s, "interface-rx");
18409       break;
18410     case FIB_API_PATH_TYPE_CLASSIFY:
18411       s = format (s, "classify");
18412       break;
18413     }
18414
18415   return (s);
18416 }
18417
18418 static void
18419 vl_api_fib_path_print (vat_main_t * vam, vl_api_fib_path_t * fp)
18420 {
18421   print (vam->ofp,
18422          "  weight %d, sw_if_index %d, type %U, afi %U, next_hop %U",
18423          ntohl (fp->weight), ntohl (fp->sw_if_index),
18424          format_vl_api_fib_path_type, fp->type,
18425          format_fib_api_path_nh_proto, fp->proto,
18426          format_vl_api_ip_address_union, &fp->nh.address);
18427 }
18428
18429 static void
18430 vl_api_mpls_fib_path_json_print (vat_json_node_t * node,
18431                                  vl_api_fib_path_t * fp)
18432 {
18433   struct in_addr ip4;
18434   struct in6_addr ip6;
18435
18436   vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
18437   vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
18438   vat_json_object_add_uint (node, "type", fp->type);
18439   vat_json_object_add_uint (node, "next_hop_proto", fp->proto);
18440   if (fp->proto == FIB_API_PATH_NH_PROTO_IP4)
18441     {
18442       clib_memcpy (&ip4, &fp->nh.address.ip4, sizeof (ip4));
18443       vat_json_object_add_ip4 (node, "next_hop", ip4);
18444     }
18445   else if (fp->proto == FIB_API_PATH_NH_PROTO_IP4)
18446     {
18447       clib_memcpy (&ip6, &fp->nh.address.ip6, sizeof (ip6));
18448       vat_json_object_add_ip6 (node, "next_hop", ip6);
18449     }
18450 }
18451
18452 static void
18453 vl_api_mpls_tunnel_details_t_handler (vl_api_mpls_tunnel_details_t * mp)
18454 {
18455   vat_main_t *vam = &vat_main;
18456   int count = ntohl (mp->mt_tunnel.mt_n_paths);
18457   vl_api_fib_path_t *fp;
18458   i32 i;
18459
18460   print (vam->ofp, "sw_if_index %d via:",
18461          ntohl (mp->mt_tunnel.mt_sw_if_index));
18462   fp = mp->mt_tunnel.mt_paths;
18463   for (i = 0; i < count; i++)
18464     {
18465       vl_api_fib_path_print (vam, fp);
18466       fp++;
18467     }
18468
18469   print (vam->ofp, "");
18470 }
18471
18472 #define vl_api_mpls_tunnel_details_t_endian vl_noop_handler
18473 #define vl_api_mpls_tunnel_details_t_print vl_noop_handler
18474
18475 static void
18476 vl_api_mpls_tunnel_details_t_handler_json (vl_api_mpls_tunnel_details_t * mp)
18477 {
18478   vat_main_t *vam = &vat_main;
18479   vat_json_node_t *node = NULL;
18480   int count = ntohl (mp->mt_tunnel.mt_n_paths);
18481   vl_api_fib_path_t *fp;
18482   i32 i;
18483
18484   if (VAT_JSON_ARRAY != vam->json_tree.type)
18485     {
18486       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18487       vat_json_init_array (&vam->json_tree);
18488     }
18489   node = vat_json_array_add (&vam->json_tree);
18490
18491   vat_json_init_object (node);
18492   vat_json_object_add_uint (node, "sw_if_index",
18493                             ntohl (mp->mt_tunnel.mt_sw_if_index));
18494
18495   vat_json_object_add_uint (node, "l2_only", mp->mt_tunnel.mt_l2_only);
18496
18497   fp = mp->mt_tunnel.mt_paths;
18498   for (i = 0; i < count; i++)
18499     {
18500       vl_api_mpls_fib_path_json_print (node, fp);
18501       fp++;
18502     }
18503 }
18504
18505 static int
18506 api_mpls_tunnel_dump (vat_main_t * vam)
18507 {
18508   vl_api_mpls_tunnel_dump_t *mp;
18509   vl_api_control_ping_t *mp_ping;
18510   int ret;
18511
18512   M (MPLS_TUNNEL_DUMP, mp);
18513
18514   S (mp);
18515
18516   /* Use a control ping for synchronization */
18517   MPING (CONTROL_PING, mp_ping);
18518   S (mp_ping);
18519
18520   W (ret);
18521   return ret;
18522 }
18523
18524 #define vl_api_mpls_table_details_t_endian vl_noop_handler
18525 #define vl_api_mpls_table_details_t_print vl_noop_handler
18526
18527
18528 static void
18529 vl_api_mpls_table_details_t_handler (vl_api_mpls_table_details_t * mp)
18530 {
18531   vat_main_t *vam = &vat_main;
18532
18533   print (vam->ofp, "table-id %d,", ntohl (mp->mt_table.mt_table_id));
18534 }
18535
18536 static void vl_api_mpls_table_details_t_handler_json
18537   (vl_api_mpls_table_details_t * mp)
18538 {
18539   vat_main_t *vam = &vat_main;
18540   vat_json_node_t *node = NULL;
18541
18542   if (VAT_JSON_ARRAY != vam->json_tree.type)
18543     {
18544       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18545       vat_json_init_array (&vam->json_tree);
18546     }
18547   node = vat_json_array_add (&vam->json_tree);
18548
18549   vat_json_init_object (node);
18550   vat_json_object_add_uint (node, "table", ntohl (mp->mt_table.mt_table_id));
18551 }
18552
18553 static int
18554 api_mpls_table_dump (vat_main_t * vam)
18555 {
18556   vl_api_mpls_table_dump_t *mp;
18557   vl_api_control_ping_t *mp_ping;
18558   int ret;
18559
18560   M (MPLS_TABLE_DUMP, mp);
18561   S (mp);
18562
18563   /* Use a control ping for synchronization */
18564   MPING (CONTROL_PING, mp_ping);
18565   S (mp_ping);
18566
18567   W (ret);
18568   return ret;
18569 }
18570
18571 #define vl_api_mpls_route_details_t_endian vl_noop_handler
18572 #define vl_api_mpls_route_details_t_print vl_noop_handler
18573
18574 static void
18575 vl_api_mpls_route_details_t_handler (vl_api_mpls_route_details_t * mp)
18576 {
18577   vat_main_t *vam = &vat_main;
18578   int count = (int) clib_net_to_host_u32 (mp->mr_route.mr_n_paths);
18579   vl_api_fib_path_t *fp;
18580   int i;
18581
18582   print (vam->ofp,
18583          "table-id %d, label %u, ess_bit %u",
18584          ntohl (mp->mr_route.mr_table_id),
18585          ntohl (mp->mr_route.mr_label), mp->mr_route.mr_eos);
18586   fp = mp->mr_route.mr_paths;
18587   for (i = 0; i < count; i++)
18588     {
18589       vl_api_fib_path_print (vam, fp);
18590       fp++;
18591     }
18592 }
18593
18594 static void vl_api_mpls_route_details_t_handler_json
18595   (vl_api_mpls_route_details_t * mp)
18596 {
18597   vat_main_t *vam = &vat_main;
18598   int count = (int) clib_host_to_net_u32 (mp->mr_route.mr_n_paths);
18599   vat_json_node_t *node = NULL;
18600   vl_api_fib_path_t *fp;
18601   int i;
18602
18603   if (VAT_JSON_ARRAY != vam->json_tree.type)
18604     {
18605       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18606       vat_json_init_array (&vam->json_tree);
18607     }
18608   node = vat_json_array_add (&vam->json_tree);
18609
18610   vat_json_init_object (node);
18611   vat_json_object_add_uint (node, "table", ntohl (mp->mr_route.mr_table_id));
18612   vat_json_object_add_uint (node, "s_bit", mp->mr_route.mr_eos);
18613   vat_json_object_add_uint (node, "label", ntohl (mp->mr_route.mr_label));
18614   vat_json_object_add_uint (node, "path_count", count);
18615   fp = mp->mr_route.mr_paths;
18616   for (i = 0; i < count; i++)
18617     {
18618       vl_api_mpls_fib_path_json_print (node, fp);
18619       fp++;
18620     }
18621 }
18622
18623 static int
18624 api_mpls_route_dump (vat_main_t * vam)
18625 {
18626   unformat_input_t *input = vam->input;
18627   vl_api_mpls_route_dump_t *mp;
18628   vl_api_control_ping_t *mp_ping;
18629   u32 table_id;
18630   int ret;
18631
18632   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18633     {
18634       if (unformat (input, "table_id %d", &table_id))
18635         ;
18636       else
18637         break;
18638     }
18639   if (table_id == ~0)
18640     {
18641       errmsg ("missing table id");
18642       return -99;
18643     }
18644
18645   M (MPLS_ROUTE_DUMP, mp);
18646
18647   mp->table.mt_table_id = ntohl (table_id);
18648   S (mp);
18649
18650   /* Use a control ping for synchronization */
18651   MPING (CONTROL_PING, mp_ping);
18652   S (mp_ping);
18653
18654   W (ret);
18655   return ret;
18656 }
18657
18658 #define vl_api_ip_table_details_t_endian vl_noop_handler
18659 #define vl_api_ip_table_details_t_print vl_noop_handler
18660
18661 static void
18662 vl_api_ip_table_details_t_handler (vl_api_ip_table_details_t * mp)
18663 {
18664   vat_main_t *vam = &vat_main;
18665
18666   print (vam->ofp,
18667          "%s; table-id %d, prefix %U/%d",
18668          mp->table.name, ntohl (mp->table.table_id));
18669 }
18670
18671
18672 static void vl_api_ip_table_details_t_handler_json
18673   (vl_api_ip_table_details_t * mp)
18674 {
18675   vat_main_t *vam = &vat_main;
18676   vat_json_node_t *node = NULL;
18677
18678   if (VAT_JSON_ARRAY != vam->json_tree.type)
18679     {
18680       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18681       vat_json_init_array (&vam->json_tree);
18682     }
18683   node = vat_json_array_add (&vam->json_tree);
18684
18685   vat_json_init_object (node);
18686   vat_json_object_add_uint (node, "table", ntohl (mp->table.table_id));
18687 }
18688
18689 static int
18690 api_ip_table_dump (vat_main_t * vam)
18691 {
18692   vl_api_ip_table_dump_t *mp;
18693   vl_api_control_ping_t *mp_ping;
18694   int ret;
18695
18696   M (IP_TABLE_DUMP, mp);
18697   S (mp);
18698
18699   /* Use a control ping for synchronization */
18700   MPING (CONTROL_PING, mp_ping);
18701   S (mp_ping);
18702
18703   W (ret);
18704   return ret;
18705 }
18706
18707 static int
18708 api_ip_mtable_dump (vat_main_t * vam)
18709 {
18710   vl_api_ip_mtable_dump_t *mp;
18711   vl_api_control_ping_t *mp_ping;
18712   int ret;
18713
18714   M (IP_MTABLE_DUMP, mp);
18715   S (mp);
18716
18717   /* Use a control ping for synchronization */
18718   MPING (CONTROL_PING, mp_ping);
18719   S (mp_ping);
18720
18721   W (ret);
18722   return ret;
18723 }
18724
18725 static int
18726 api_ip_mroute_dump (vat_main_t * vam)
18727 {
18728   unformat_input_t *input = vam->input;
18729   vl_api_control_ping_t *mp_ping;
18730   vl_api_ip_mroute_dump_t *mp;
18731   int ret, is_ip6;
18732   u32 table_id;
18733
18734   is_ip6 = 0;
18735   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18736     {
18737       if (unformat (input, "table_id %d", &table_id))
18738         ;
18739       else if (unformat (input, "ip6"))
18740         is_ip6 = 1;
18741       else if (unformat (input, "ip4"))
18742         is_ip6 = 0;
18743       else
18744         break;
18745     }
18746   if (table_id == ~0)
18747     {
18748       errmsg ("missing table id");
18749       return -99;
18750     }
18751
18752   M (IP_MROUTE_DUMP, mp);
18753   mp->table.table_id = table_id;
18754   mp->table.is_ip6 = is_ip6;
18755   S (mp);
18756
18757   /* Use a control ping for synchronization */
18758   MPING (CONTROL_PING, mp_ping);
18759   S (mp_ping);
18760
18761   W (ret);
18762   return ret;
18763 }
18764
18765 static void vl_api_ip_neighbor_details_t_handler
18766   (vl_api_ip_neighbor_details_t * mp)
18767 {
18768   vat_main_t *vam = &vat_main;
18769
18770   print (vam->ofp, "%c %U %U",
18771          (ntohl (mp->neighbor.flags) & IP_NEIGHBOR_FLAG_STATIC) ? 'S' : 'D',
18772          format_vl_api_mac_address, &mp->neighbor.mac_address,
18773          format_vl_api_address, &mp->neighbor.ip_address);
18774 }
18775
18776 static void vl_api_ip_neighbor_details_t_handler_json
18777   (vl_api_ip_neighbor_details_t * mp)
18778 {
18779
18780   vat_main_t *vam = &vat_main;
18781   vat_json_node_t *node;
18782
18783   if (VAT_JSON_ARRAY != vam->json_tree.type)
18784     {
18785       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18786       vat_json_init_array (&vam->json_tree);
18787     }
18788   node = vat_json_array_add (&vam->json_tree);
18789
18790   vat_json_init_object (node);
18791   vat_json_object_add_string_copy
18792     (node, "flag",
18793      ((ntohl (mp->neighbor.flags) & IP_NEIGHBOR_FLAG_STATIC) ?
18794       (u8 *) "static" : (u8 *) "dynamic"));
18795
18796   vat_json_object_add_string_copy (node, "link_layer",
18797                                    format (0, "%U", format_vl_api_mac_address,
18798                                            &mp->neighbor.mac_address));
18799   vat_json_object_add_address (node, "ip", &mp->neighbor.ip_address);
18800 }
18801
18802 static int
18803 api_ip_neighbor_dump (vat_main_t * vam)
18804 {
18805   unformat_input_t *i = vam->input;
18806   vl_api_ip_neighbor_dump_t *mp;
18807   vl_api_control_ping_t *mp_ping;
18808   u8 is_ipv6 = 0;
18809   u32 sw_if_index = ~0;
18810   int ret;
18811
18812   /* Parse args required to build the message */
18813   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18814     {
18815       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18816         ;
18817       else if (unformat (i, "sw_if_index %d", &sw_if_index))
18818         ;
18819       else if (unformat (i, "ip6"))
18820         is_ipv6 = 1;
18821       else
18822         break;
18823     }
18824
18825   if (sw_if_index == ~0)
18826     {
18827       errmsg ("missing interface name or sw_if_index");
18828       return -99;
18829     }
18830
18831   M (IP_NEIGHBOR_DUMP, mp);
18832   mp->is_ipv6 = (u8) is_ipv6;
18833   mp->sw_if_index = ntohl (sw_if_index);
18834   S (mp);
18835
18836   /* Use a control ping for synchronization */
18837   MPING (CONTROL_PING, mp_ping);
18838   S (mp_ping);
18839
18840   W (ret);
18841   return ret;
18842 }
18843
18844 #define vl_api_ip_route_details_t_endian vl_noop_handler
18845 #define vl_api_ip_route_details_t_print vl_noop_handler
18846
18847 static void
18848 vl_api_ip_route_details_t_handler (vl_api_ip_route_details_t * mp)
18849 {
18850   vat_main_t *vam = &vat_main;
18851   u8 count = mp->route.n_paths;
18852   vl_api_fib_path_t *fp;
18853   int i;
18854
18855   print (vam->ofp,
18856          "table-id %d, prefix %U/%d",
18857          ntohl (mp->route.table_id),
18858          format_ip46_address, mp->route.prefix.address, mp->route.prefix.len);
18859   for (i = 0; i < count; i++)
18860     {
18861       fp = &mp->route.paths[i];
18862
18863       vl_api_fib_path_print (vam, fp);
18864       fp++;
18865     }
18866 }
18867
18868 static void vl_api_ip_route_details_t_handler_json
18869   (vl_api_ip_route_details_t * mp)
18870 {
18871   vat_main_t *vam = &vat_main;
18872   u8 count = mp->route.n_paths;
18873   vat_json_node_t *node = NULL;
18874   struct in_addr ip4;
18875   struct in6_addr ip6;
18876   vl_api_fib_path_t *fp;
18877   int i;
18878
18879   if (VAT_JSON_ARRAY != vam->json_tree.type)
18880     {
18881       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18882       vat_json_init_array (&vam->json_tree);
18883     }
18884   node = vat_json_array_add (&vam->json_tree);
18885
18886   vat_json_init_object (node);
18887   vat_json_object_add_uint (node, "table", ntohl (mp->route.table_id));
18888   if (ADDRESS_IP6 == mp->route.prefix.address.af)
18889     {
18890       clib_memcpy (&ip6, &mp->route.prefix.address.un.ip6, sizeof (ip6));
18891       vat_json_object_add_ip6 (node, "prefix", ip6);
18892     }
18893   else
18894     {
18895       clib_memcpy (&ip4, &mp->route.prefix.address.un.ip4, sizeof (ip4));
18896       vat_json_object_add_ip4 (node, "prefix", ip4);
18897     }
18898   vat_json_object_add_uint (node, "mask_length", mp->route.prefix.len);
18899   vat_json_object_add_uint (node, "path_count", count);
18900   for (i = 0; i < count; i++)
18901     {
18902       fp = &mp->route.paths[i];
18903       vl_api_mpls_fib_path_json_print (node, fp);
18904     }
18905 }
18906
18907 static int
18908 api_ip_route_dump (vat_main_t * vam)
18909 {
18910   unformat_input_t *input = vam->input;
18911   vl_api_ip_route_dump_t *mp;
18912   vl_api_control_ping_t *mp_ping;
18913   u32 table_id;
18914   u8 is_ip6;
18915   int ret;
18916
18917   is_ip6 = 0;
18918   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18919     {
18920       if (unformat (input, "table_id %d", &table_id))
18921         ;
18922       else if (unformat (input, "ip6"))
18923         is_ip6 = 1;
18924       else if (unformat (input, "ip4"))
18925         is_ip6 = 0;
18926       else
18927         break;
18928     }
18929   if (table_id == ~0)
18930     {
18931       errmsg ("missing table id");
18932       return -99;
18933     }
18934
18935   M (IP_ROUTE_DUMP, mp);
18936
18937   mp->table.table_id = table_id;
18938   mp->table.is_ip6 = is_ip6;
18939
18940   S (mp);
18941
18942   /* Use a control ping for synchronization */
18943   MPING (CONTROL_PING, mp_ping);
18944   S (mp_ping);
18945
18946   W (ret);
18947   return ret;
18948 }
18949
18950 int
18951 api_classify_table_ids (vat_main_t * vam)
18952 {
18953   vl_api_classify_table_ids_t *mp;
18954   int ret;
18955
18956   /* Construct the API message */
18957   M (CLASSIFY_TABLE_IDS, mp);
18958   mp->context = 0;
18959
18960   S (mp);
18961   W (ret);
18962   return ret;
18963 }
18964
18965 int
18966 api_classify_table_by_interface (vat_main_t * vam)
18967 {
18968   unformat_input_t *input = vam->input;
18969   vl_api_classify_table_by_interface_t *mp;
18970
18971   u32 sw_if_index = ~0;
18972   int ret;
18973   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18974     {
18975       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18976         ;
18977       else if (unformat (input, "sw_if_index %d", &sw_if_index))
18978         ;
18979       else
18980         break;
18981     }
18982   if (sw_if_index == ~0)
18983     {
18984       errmsg ("missing interface name or sw_if_index");
18985       return -99;
18986     }
18987
18988   /* Construct the API message */
18989   M (CLASSIFY_TABLE_BY_INTERFACE, mp);
18990   mp->context = 0;
18991   mp->sw_if_index = ntohl (sw_if_index);
18992
18993   S (mp);
18994   W (ret);
18995   return ret;
18996 }
18997
18998 int
18999 api_classify_table_info (vat_main_t * vam)
19000 {
19001   unformat_input_t *input = vam->input;
19002   vl_api_classify_table_info_t *mp;
19003
19004   u32 table_id = ~0;
19005   int ret;
19006   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19007     {
19008       if (unformat (input, "table_id %d", &table_id))
19009         ;
19010       else
19011         break;
19012     }
19013   if (table_id == ~0)
19014     {
19015       errmsg ("missing table id");
19016       return -99;
19017     }
19018
19019   /* Construct the API message */
19020   M (CLASSIFY_TABLE_INFO, mp);
19021   mp->context = 0;
19022   mp->table_id = ntohl (table_id);
19023
19024   S (mp);
19025   W (ret);
19026   return ret;
19027 }
19028
19029 int
19030 api_classify_session_dump (vat_main_t * vam)
19031 {
19032   unformat_input_t *input = vam->input;
19033   vl_api_classify_session_dump_t *mp;
19034   vl_api_control_ping_t *mp_ping;
19035
19036   u32 table_id = ~0;
19037   int ret;
19038   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19039     {
19040       if (unformat (input, "table_id %d", &table_id))
19041         ;
19042       else
19043         break;
19044     }
19045   if (table_id == ~0)
19046     {
19047       errmsg ("missing table id");
19048       return -99;
19049     }
19050
19051   /* Construct the API message */
19052   M (CLASSIFY_SESSION_DUMP, mp);
19053   mp->context = 0;
19054   mp->table_id = ntohl (table_id);
19055   S (mp);
19056
19057   /* Use a control ping for synchronization */
19058   MPING (CONTROL_PING, mp_ping);
19059   S (mp_ping);
19060
19061   W (ret);
19062   return ret;
19063 }
19064
19065 static void
19066 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
19067 {
19068   vat_main_t *vam = &vat_main;
19069
19070   print (vam->ofp, "collector_address %U, collector_port %d, "
19071          "src_address %U, vrf_id %d, path_mtu %u, "
19072          "template_interval %u, udp_checksum %d",
19073          format_ip4_address, mp->collector_address,
19074          ntohs (mp->collector_port),
19075          format_ip4_address, mp->src_address,
19076          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
19077          ntohl (mp->template_interval), mp->udp_checksum);
19078
19079   vam->retval = 0;
19080   vam->result_ready = 1;
19081 }
19082
19083 static void
19084   vl_api_ipfix_exporter_details_t_handler_json
19085   (vl_api_ipfix_exporter_details_t * mp)
19086 {
19087   vat_main_t *vam = &vat_main;
19088   vat_json_node_t node;
19089   struct in_addr collector_address;
19090   struct in_addr src_address;
19091
19092   vat_json_init_object (&node);
19093   clib_memcpy (&collector_address, &mp->collector_address,
19094                sizeof (collector_address));
19095   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
19096   vat_json_object_add_uint (&node, "collector_port",
19097                             ntohs (mp->collector_port));
19098   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
19099   vat_json_object_add_ip4 (&node, "src_address", src_address);
19100   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
19101   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
19102   vat_json_object_add_uint (&node, "template_interval",
19103                             ntohl (mp->template_interval));
19104   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
19105
19106   vat_json_print (vam->ofp, &node);
19107   vat_json_free (&node);
19108   vam->retval = 0;
19109   vam->result_ready = 1;
19110 }
19111
19112 int
19113 api_ipfix_exporter_dump (vat_main_t * vam)
19114 {
19115   vl_api_ipfix_exporter_dump_t *mp;
19116   int ret;
19117
19118   /* Construct the API message */
19119   M (IPFIX_EXPORTER_DUMP, mp);
19120   mp->context = 0;
19121
19122   S (mp);
19123   W (ret);
19124   return ret;
19125 }
19126
19127 static int
19128 api_ipfix_classify_stream_dump (vat_main_t * vam)
19129 {
19130   vl_api_ipfix_classify_stream_dump_t *mp;
19131   int ret;
19132
19133   /* Construct the API message */
19134   M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
19135   mp->context = 0;
19136
19137   S (mp);
19138   W (ret);
19139   return ret;
19140   /* NOTREACHED */
19141   return 0;
19142 }
19143
19144 static void
19145   vl_api_ipfix_classify_stream_details_t_handler
19146   (vl_api_ipfix_classify_stream_details_t * mp)
19147 {
19148   vat_main_t *vam = &vat_main;
19149   print (vam->ofp, "domain_id %d, src_port %d",
19150          ntohl (mp->domain_id), ntohs (mp->src_port));
19151   vam->retval = 0;
19152   vam->result_ready = 1;
19153 }
19154
19155 static void
19156   vl_api_ipfix_classify_stream_details_t_handler_json
19157   (vl_api_ipfix_classify_stream_details_t * mp)
19158 {
19159   vat_main_t *vam = &vat_main;
19160   vat_json_node_t node;
19161
19162   vat_json_init_object (&node);
19163   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
19164   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
19165
19166   vat_json_print (vam->ofp, &node);
19167   vat_json_free (&node);
19168   vam->retval = 0;
19169   vam->result_ready = 1;
19170 }
19171
19172 static int
19173 api_ipfix_classify_table_dump (vat_main_t * vam)
19174 {
19175   vl_api_ipfix_classify_table_dump_t *mp;
19176   vl_api_control_ping_t *mp_ping;
19177   int ret;
19178
19179   if (!vam->json_output)
19180     {
19181       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
19182              "transport_protocol");
19183     }
19184
19185   /* Construct the API message */
19186   M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
19187
19188   /* send it... */
19189   S (mp);
19190
19191   /* Use a control ping for synchronization */
19192   MPING (CONTROL_PING, mp_ping);
19193   S (mp_ping);
19194
19195   W (ret);
19196   return ret;
19197 }
19198
19199 static void
19200   vl_api_ipfix_classify_table_details_t_handler
19201   (vl_api_ipfix_classify_table_details_t * mp)
19202 {
19203   vat_main_t *vam = &vat_main;
19204   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
19205          mp->transport_protocol);
19206 }
19207
19208 static void
19209   vl_api_ipfix_classify_table_details_t_handler_json
19210   (vl_api_ipfix_classify_table_details_t * mp)
19211 {
19212   vat_json_node_t *node = NULL;
19213   vat_main_t *vam = &vat_main;
19214
19215   if (VAT_JSON_ARRAY != vam->json_tree.type)
19216     {
19217       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19218       vat_json_init_array (&vam->json_tree);
19219     }
19220
19221   node = vat_json_array_add (&vam->json_tree);
19222   vat_json_init_object (node);
19223
19224   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
19225   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
19226   vat_json_object_add_uint (node, "transport_protocol",
19227                             mp->transport_protocol);
19228 }
19229
19230 static int
19231 api_sw_interface_span_enable_disable (vat_main_t * vam)
19232 {
19233   unformat_input_t *i = vam->input;
19234   vl_api_sw_interface_span_enable_disable_t *mp;
19235   u32 src_sw_if_index = ~0;
19236   u32 dst_sw_if_index = ~0;
19237   u8 state = 3;
19238   int ret;
19239   u8 is_l2 = 0;
19240
19241   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19242     {
19243       if (unformat
19244           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
19245         ;
19246       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
19247         ;
19248       else
19249         if (unformat
19250             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
19251         ;
19252       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
19253         ;
19254       else if (unformat (i, "disable"))
19255         state = 0;
19256       else if (unformat (i, "rx"))
19257         state = 1;
19258       else if (unformat (i, "tx"))
19259         state = 2;
19260       else if (unformat (i, "both"))
19261         state = 3;
19262       else if (unformat (i, "l2"))
19263         is_l2 = 1;
19264       else
19265         break;
19266     }
19267
19268   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
19269
19270   mp->sw_if_index_from = htonl (src_sw_if_index);
19271   mp->sw_if_index_to = htonl (dst_sw_if_index);
19272   mp->state = state;
19273   mp->is_l2 = is_l2;
19274
19275   S (mp);
19276   W (ret);
19277   return ret;
19278 }
19279
19280 static void
19281 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
19282                                             * mp)
19283 {
19284   vat_main_t *vam = &vat_main;
19285   u8 *sw_if_from_name = 0;
19286   u8 *sw_if_to_name = 0;
19287   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
19288   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
19289   char *states[] = { "none", "rx", "tx", "both" };
19290   hash_pair_t *p;
19291
19292   /* *INDENT-OFF* */
19293   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
19294   ({
19295     if ((u32) p->value[0] == sw_if_index_from)
19296       {
19297         sw_if_from_name = (u8 *)(p->key);
19298         if (sw_if_to_name)
19299           break;
19300       }
19301     if ((u32) p->value[0] == sw_if_index_to)
19302       {
19303         sw_if_to_name = (u8 *)(p->key);
19304         if (sw_if_from_name)
19305           break;
19306       }
19307   }));
19308   /* *INDENT-ON* */
19309   print (vam->ofp, "%20s => %20s (%s) %s",
19310          sw_if_from_name, sw_if_to_name, states[mp->state],
19311          mp->is_l2 ? "l2" : "device");
19312 }
19313
19314 static void
19315   vl_api_sw_interface_span_details_t_handler_json
19316   (vl_api_sw_interface_span_details_t * mp)
19317 {
19318   vat_main_t *vam = &vat_main;
19319   vat_json_node_t *node = NULL;
19320   u8 *sw_if_from_name = 0;
19321   u8 *sw_if_to_name = 0;
19322   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
19323   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
19324   hash_pair_t *p;
19325
19326   /* *INDENT-OFF* */
19327   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
19328   ({
19329     if ((u32) p->value[0] == sw_if_index_from)
19330       {
19331         sw_if_from_name = (u8 *)(p->key);
19332         if (sw_if_to_name)
19333           break;
19334       }
19335     if ((u32) p->value[0] == sw_if_index_to)
19336       {
19337         sw_if_to_name = (u8 *)(p->key);
19338         if (sw_if_from_name)
19339           break;
19340       }
19341   }));
19342   /* *INDENT-ON* */
19343
19344   if (VAT_JSON_ARRAY != vam->json_tree.type)
19345     {
19346       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19347       vat_json_init_array (&vam->json_tree);
19348     }
19349   node = vat_json_array_add (&vam->json_tree);
19350
19351   vat_json_init_object (node);
19352   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
19353   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
19354   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
19355   if (0 != sw_if_to_name)
19356     {
19357       vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
19358     }
19359   vat_json_object_add_uint (node, "state", mp->state);
19360   vat_json_object_add_uint (node, "is-l2", mp->is_l2);
19361 }
19362
19363 static int
19364 api_sw_interface_span_dump (vat_main_t * vam)
19365 {
19366   unformat_input_t *input = vam->input;
19367   vl_api_sw_interface_span_dump_t *mp;
19368   vl_api_control_ping_t *mp_ping;
19369   u8 is_l2 = 0;
19370   int ret;
19371
19372   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19373     {
19374       if (unformat (input, "l2"))
19375         is_l2 = 1;
19376       else
19377         break;
19378     }
19379
19380   M (SW_INTERFACE_SPAN_DUMP, mp);
19381   mp->is_l2 = is_l2;
19382   S (mp);
19383
19384   /* Use a control ping for synchronization */
19385   MPING (CONTROL_PING, mp_ping);
19386   S (mp_ping);
19387
19388   W (ret);
19389   return ret;
19390 }
19391
19392 int
19393 api_pg_create_interface (vat_main_t * vam)
19394 {
19395   unformat_input_t *input = vam->input;
19396   vl_api_pg_create_interface_t *mp;
19397
19398   u32 if_id = ~0, gso_size = 0;
19399   u8 gso_enabled = 0;
19400   int ret;
19401   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19402     {
19403       if (unformat (input, "if_id %d", &if_id))
19404         ;
19405       else if (unformat (input, "gso-enabled"))
19406         {
19407           gso_enabled = 1;
19408           if (unformat (input, "gso-size %u", &gso_size))
19409             ;
19410           else
19411             {
19412               errmsg ("missing gso-size");
19413               return -99;
19414             }
19415         }
19416       else
19417         break;
19418     }
19419   if (if_id == ~0)
19420     {
19421       errmsg ("missing pg interface index");
19422       return -99;
19423     }
19424
19425   /* Construct the API message */
19426   M (PG_CREATE_INTERFACE, mp);
19427   mp->context = 0;
19428   mp->interface_id = ntohl (if_id);
19429   mp->gso_enabled = gso_enabled;
19430
19431   S (mp);
19432   W (ret);
19433   return ret;
19434 }
19435
19436 int
19437 api_pg_capture (vat_main_t * vam)
19438 {
19439   unformat_input_t *input = vam->input;
19440   vl_api_pg_capture_t *mp;
19441
19442   u32 if_id = ~0;
19443   u8 enable = 1;
19444   u32 count = 1;
19445   u8 pcap_file_set = 0;
19446   u8 *pcap_file = 0;
19447   int ret;
19448   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19449     {
19450       if (unformat (input, "if_id %d", &if_id))
19451         ;
19452       else if (unformat (input, "pcap %s", &pcap_file))
19453         pcap_file_set = 1;
19454       else if (unformat (input, "count %d", &count))
19455         ;
19456       else if (unformat (input, "disable"))
19457         enable = 0;
19458       else
19459         break;
19460     }
19461   if (if_id == ~0)
19462     {
19463       errmsg ("missing pg interface index");
19464       return -99;
19465     }
19466   if (pcap_file_set > 0)
19467     {
19468       if (vec_len (pcap_file) > 255)
19469         {
19470           errmsg ("pcap file name is too long");
19471           return -99;
19472         }
19473     }
19474
19475   u32 name_len = vec_len (pcap_file);
19476   /* Construct the API message */
19477   M (PG_CAPTURE, mp);
19478   mp->context = 0;
19479   mp->interface_id = ntohl (if_id);
19480   mp->is_enabled = enable;
19481   mp->count = ntohl (count);
19482   mp->pcap_name_length = ntohl (name_len);
19483   if (pcap_file_set != 0)
19484     {
19485       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
19486     }
19487   vec_free (pcap_file);
19488
19489   S (mp);
19490   W (ret);
19491   return ret;
19492 }
19493
19494 int
19495 api_pg_enable_disable (vat_main_t * vam)
19496 {
19497   unformat_input_t *input = vam->input;
19498   vl_api_pg_enable_disable_t *mp;
19499
19500   u8 enable = 1;
19501   u8 stream_name_set = 0;
19502   u8 *stream_name = 0;
19503   int ret;
19504   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19505     {
19506       if (unformat (input, "stream %s", &stream_name))
19507         stream_name_set = 1;
19508       else if (unformat (input, "disable"))
19509         enable = 0;
19510       else
19511         break;
19512     }
19513
19514   if (stream_name_set > 0)
19515     {
19516       if (vec_len (stream_name) > 255)
19517         {
19518           errmsg ("stream name too long");
19519           return -99;
19520         }
19521     }
19522
19523   u32 name_len = vec_len (stream_name);
19524   /* Construct the API message */
19525   M (PG_ENABLE_DISABLE, mp);
19526   mp->context = 0;
19527   mp->is_enabled = enable;
19528   if (stream_name_set != 0)
19529     {
19530       mp->stream_name_length = ntohl (name_len);
19531       clib_memcpy (mp->stream_name, stream_name, name_len);
19532     }
19533   vec_free (stream_name);
19534
19535   S (mp);
19536   W (ret);
19537   return ret;
19538 }
19539
19540 int
19541 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
19542 {
19543   unformat_input_t *input = vam->input;
19544   vl_api_ip_source_and_port_range_check_add_del_t *mp;
19545
19546   u16 *low_ports = 0;
19547   u16 *high_ports = 0;
19548   u16 this_low;
19549   u16 this_hi;
19550   vl_api_prefix_t prefix;
19551   u32 tmp, tmp2;
19552   u8 prefix_set = 0;
19553   u32 vrf_id = ~0;
19554   u8 is_add = 1;
19555   int ret;
19556
19557   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19558     {
19559       if (unformat (input, "%U", unformat_vl_api_prefix, &prefix))
19560         prefix_set = 1;
19561       else if (unformat (input, "vrf %d", &vrf_id))
19562         ;
19563       else if (unformat (input, "del"))
19564         is_add = 0;
19565       else if (unformat (input, "port %d", &tmp))
19566         {
19567           if (tmp == 0 || tmp > 65535)
19568             {
19569               errmsg ("port %d out of range", tmp);
19570               return -99;
19571             }
19572           this_low = tmp;
19573           this_hi = this_low + 1;
19574           vec_add1 (low_ports, this_low);
19575           vec_add1 (high_ports, this_hi);
19576         }
19577       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
19578         {
19579           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
19580             {
19581               errmsg ("incorrect range parameters");
19582               return -99;
19583             }
19584           this_low = tmp;
19585           /* Note: in debug CLI +1 is added to high before
19586              passing to real fn that does "the work"
19587              (ip_source_and_port_range_check_add_del).
19588              This fn is a wrapper around the binary API fn a
19589              control plane will call, which expects this increment
19590              to have occurred. Hence letting the binary API control
19591              plane fn do the increment for consistency between VAT
19592              and other control planes.
19593            */
19594           this_hi = tmp2;
19595           vec_add1 (low_ports, this_low);
19596           vec_add1 (high_ports, this_hi);
19597         }
19598       else
19599         break;
19600     }
19601
19602   if (prefix_set == 0)
19603     {
19604       errmsg ("<address>/<mask> not specified");
19605       return -99;
19606     }
19607
19608   if (vrf_id == ~0)
19609     {
19610       errmsg ("VRF ID required, not specified");
19611       return -99;
19612     }
19613
19614   if (vrf_id == 0)
19615     {
19616       errmsg
19617         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
19618       return -99;
19619     }
19620
19621   if (vec_len (low_ports) == 0)
19622     {
19623       errmsg ("At least one port or port range required");
19624       return -99;
19625     }
19626
19627   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
19628
19629   mp->is_add = is_add;
19630
19631   clib_memcpy (&mp->prefix, &prefix, sizeof (prefix));
19632
19633   mp->number_of_ranges = vec_len (low_ports);
19634
19635   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
19636   vec_free (low_ports);
19637
19638   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
19639   vec_free (high_ports);
19640
19641   mp->vrf_id = ntohl (vrf_id);
19642
19643   S (mp);
19644   W (ret);
19645   return ret;
19646 }
19647
19648 int
19649 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
19650 {
19651   unformat_input_t *input = vam->input;
19652   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
19653   u32 sw_if_index = ~0;
19654   int vrf_set = 0;
19655   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
19656   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
19657   u8 is_add = 1;
19658   int ret;
19659
19660   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19661     {
19662       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19663         ;
19664       else if (unformat (input, "sw_if_index %d", &sw_if_index))
19665         ;
19666       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
19667         vrf_set = 1;
19668       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
19669         vrf_set = 1;
19670       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
19671         vrf_set = 1;
19672       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
19673         vrf_set = 1;
19674       else if (unformat (input, "del"))
19675         is_add = 0;
19676       else
19677         break;
19678     }
19679
19680   if (sw_if_index == ~0)
19681     {
19682       errmsg ("Interface required but not specified");
19683       return -99;
19684     }
19685
19686   if (vrf_set == 0)
19687     {
19688       errmsg ("VRF ID required but not specified");
19689       return -99;
19690     }
19691
19692   if (tcp_out_vrf_id == 0
19693       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
19694     {
19695       errmsg
19696         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
19697       return -99;
19698     }
19699
19700   /* Construct the API message */
19701   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
19702
19703   mp->sw_if_index = ntohl (sw_if_index);
19704   mp->is_add = is_add;
19705   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
19706   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
19707   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
19708   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
19709
19710   /* send it... */
19711   S (mp);
19712
19713   /* Wait for a reply... */
19714   W (ret);
19715   return ret;
19716 }
19717
19718 static int
19719 api_set_punt (vat_main_t * vam)
19720 {
19721   unformat_input_t *i = vam->input;
19722   vl_api_address_family_t af;
19723   vl_api_set_punt_t *mp;
19724   u32 protocol = ~0;
19725   u32 port = ~0;
19726   int is_add = 1;
19727   int ret;
19728
19729   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19730     {
19731       if (unformat (i, "%U", unformat_vl_api_address_family, &af))
19732         ;
19733       else if (unformat (i, "protocol %d", &protocol))
19734         ;
19735       else if (unformat (i, "port %d", &port))
19736         ;
19737       else if (unformat (i, "del"))
19738         is_add = 0;
19739       else
19740         {
19741           clib_warning ("parse error '%U'", format_unformat_error, i);
19742           return -99;
19743         }
19744     }
19745
19746   M (SET_PUNT, mp);
19747
19748   mp->is_add = (u8) is_add;
19749   mp->punt.type = PUNT_API_TYPE_L4;
19750   mp->punt.punt.l4.af = af;
19751   mp->punt.punt.l4.protocol = (u8) protocol;
19752   mp->punt.punt.l4.port = htons ((u16) port);
19753
19754   S (mp);
19755   W (ret);
19756   return ret;
19757 }
19758
19759 static int
19760 api_delete_subif (vat_main_t * vam)
19761 {
19762   unformat_input_t *i = vam->input;
19763   vl_api_delete_subif_t *mp;
19764   u32 sw_if_index = ~0;
19765   int ret;
19766
19767   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19768     {
19769       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19770         ;
19771       if (unformat (i, "sw_if_index %d", &sw_if_index))
19772         ;
19773       else
19774         break;
19775     }
19776
19777   if (sw_if_index == ~0)
19778     {
19779       errmsg ("missing sw_if_index");
19780       return -99;
19781     }
19782
19783   /* Construct the API message */
19784   M (DELETE_SUBIF, mp);
19785   mp->sw_if_index = ntohl (sw_if_index);
19786
19787   S (mp);
19788   W (ret);
19789   return ret;
19790 }
19791
19792 #define foreach_pbb_vtr_op      \
19793 _("disable",  L2_VTR_DISABLED)  \
19794 _("pop",  L2_VTR_POP_2)         \
19795 _("push",  L2_VTR_PUSH_2)
19796
19797 static int
19798 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
19799 {
19800   unformat_input_t *i = vam->input;
19801   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
19802   u32 sw_if_index = ~0, vtr_op = ~0;
19803   u16 outer_tag = ~0;
19804   u8 dmac[6], smac[6];
19805   u8 dmac_set = 0, smac_set = 0;
19806   u16 vlanid = 0;
19807   u32 sid = ~0;
19808   u32 tmp;
19809   int ret;
19810
19811   /* Shut up coverity */
19812   clib_memset (dmac, 0, sizeof (dmac));
19813   clib_memset (smac, 0, sizeof (smac));
19814
19815   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19816     {
19817       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19818         ;
19819       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19820         ;
19821       else if (unformat (i, "vtr_op %d", &vtr_op))
19822         ;
19823 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
19824       foreach_pbb_vtr_op
19825 #undef _
19826         else if (unformat (i, "translate_pbb_stag"))
19827         {
19828           if (unformat (i, "%d", &tmp))
19829             {
19830               vtr_op = L2_VTR_TRANSLATE_2_1;
19831               outer_tag = tmp;
19832             }
19833           else
19834             {
19835               errmsg
19836                 ("translate_pbb_stag operation requires outer tag definition");
19837               return -99;
19838             }
19839         }
19840       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
19841         dmac_set++;
19842       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
19843         smac_set++;
19844       else if (unformat (i, "sid %d", &sid))
19845         ;
19846       else if (unformat (i, "vlanid %d", &tmp))
19847         vlanid = tmp;
19848       else
19849         {
19850           clib_warning ("parse error '%U'", format_unformat_error, i);
19851           return -99;
19852         }
19853     }
19854
19855   if ((sw_if_index == ~0) || (vtr_op == ~0))
19856     {
19857       errmsg ("missing sw_if_index or vtr operation");
19858       return -99;
19859     }
19860   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
19861       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
19862     {
19863       errmsg
19864         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
19865       return -99;
19866     }
19867
19868   M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
19869   mp->sw_if_index = ntohl (sw_if_index);
19870   mp->vtr_op = ntohl (vtr_op);
19871   mp->outer_tag = ntohs (outer_tag);
19872   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
19873   clib_memcpy (mp->b_smac, smac, sizeof (smac));
19874   mp->b_vlanid = ntohs (vlanid);
19875   mp->i_sid = ntohl (sid);
19876
19877   S (mp);
19878   W (ret);
19879   return ret;
19880 }
19881
19882 static int
19883 api_flow_classify_set_interface (vat_main_t * vam)
19884 {
19885   unformat_input_t *i = vam->input;
19886   vl_api_flow_classify_set_interface_t *mp;
19887   u32 sw_if_index;
19888   int sw_if_index_set;
19889   u32 ip4_table_index = ~0;
19890   u32 ip6_table_index = ~0;
19891   u8 is_add = 1;
19892   int ret;
19893
19894   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19895     {
19896       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19897         sw_if_index_set = 1;
19898       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19899         sw_if_index_set = 1;
19900       else if (unformat (i, "del"))
19901         is_add = 0;
19902       else if (unformat (i, "ip4-table %d", &ip4_table_index))
19903         ;
19904       else if (unformat (i, "ip6-table %d", &ip6_table_index))
19905         ;
19906       else
19907         {
19908           clib_warning ("parse error '%U'", format_unformat_error, i);
19909           return -99;
19910         }
19911     }
19912
19913   if (sw_if_index_set == 0)
19914     {
19915       errmsg ("missing interface name or sw_if_index");
19916       return -99;
19917     }
19918
19919   M (FLOW_CLASSIFY_SET_INTERFACE, mp);
19920
19921   mp->sw_if_index = ntohl (sw_if_index);
19922   mp->ip4_table_index = ntohl (ip4_table_index);
19923   mp->ip6_table_index = ntohl (ip6_table_index);
19924   mp->is_add = is_add;
19925
19926   S (mp);
19927   W (ret);
19928   return ret;
19929 }
19930
19931 static int
19932 api_flow_classify_dump (vat_main_t * vam)
19933 {
19934   unformat_input_t *i = vam->input;
19935   vl_api_flow_classify_dump_t *mp;
19936   vl_api_control_ping_t *mp_ping;
19937   u8 type = FLOW_CLASSIFY_N_TABLES;
19938   int ret;
19939
19940   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
19941     ;
19942   else
19943     {
19944       errmsg ("classify table type must be specified");
19945       return -99;
19946     }
19947
19948   if (!vam->json_output)
19949     {
19950       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
19951     }
19952
19953   M (FLOW_CLASSIFY_DUMP, mp);
19954   mp->type = type;
19955   /* send it... */
19956   S (mp);
19957
19958   /* Use a control ping for synchronization */
19959   MPING (CONTROL_PING, mp_ping);
19960   S (mp_ping);
19961
19962   /* Wait for a reply... */
19963   W (ret);
19964   return ret;
19965 }
19966
19967 static int
19968 api_feature_enable_disable (vat_main_t * vam)
19969 {
19970   unformat_input_t *i = vam->input;
19971   vl_api_feature_enable_disable_t *mp;
19972   u8 *arc_name = 0;
19973   u8 *feature_name = 0;
19974   u32 sw_if_index = ~0;
19975   u8 enable = 1;
19976   int ret;
19977
19978   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19979     {
19980       if (unformat (i, "arc_name %s", &arc_name))
19981         ;
19982       else if (unformat (i, "feature_name %s", &feature_name))
19983         ;
19984       else
19985         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19986         ;
19987       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19988         ;
19989       else if (unformat (i, "disable"))
19990         enable = 0;
19991       else
19992         break;
19993     }
19994
19995   if (arc_name == 0)
19996     {
19997       errmsg ("missing arc name");
19998       return -99;
19999     }
20000   if (vec_len (arc_name) > 63)
20001     {
20002       errmsg ("arc name too long");
20003     }
20004
20005   if (feature_name == 0)
20006     {
20007       errmsg ("missing feature name");
20008       return -99;
20009     }
20010   if (vec_len (feature_name) > 63)
20011     {
20012       errmsg ("feature name too long");
20013     }
20014
20015   if (sw_if_index == ~0)
20016     {
20017       errmsg ("missing interface name or sw_if_index");
20018       return -99;
20019     }
20020
20021   /* Construct the API message */
20022   M (FEATURE_ENABLE_DISABLE, mp);
20023   mp->sw_if_index = ntohl (sw_if_index);
20024   mp->enable = enable;
20025   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
20026   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
20027   vec_free (arc_name);
20028   vec_free (feature_name);
20029
20030   S (mp);
20031   W (ret);
20032   return ret;
20033 }
20034
20035 static int
20036 api_feature_gso_enable_disable (vat_main_t * vam)
20037 {
20038   unformat_input_t *i = vam->input;
20039   vl_api_feature_gso_enable_disable_t *mp;
20040   u32 sw_if_index = ~0;
20041   u8 enable = 1;
20042   int ret;
20043
20044   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20045     {
20046       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20047         ;
20048       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20049         ;
20050       else if (unformat (i, "enable"))
20051         enable = 1;
20052       else if (unformat (i, "disable"))
20053         enable = 0;
20054       else
20055         break;
20056     }
20057
20058   if (sw_if_index == ~0)
20059     {
20060       errmsg ("missing interface name or sw_if_index");
20061       return -99;
20062     }
20063
20064   /* Construct the API message */
20065   M (FEATURE_GSO_ENABLE_DISABLE, mp);
20066   mp->sw_if_index = ntohl (sw_if_index);
20067   mp->enable_disable = enable;
20068
20069   S (mp);
20070   W (ret);
20071   return ret;
20072 }
20073
20074 static int
20075 api_sw_interface_tag_add_del (vat_main_t * vam)
20076 {
20077   unformat_input_t *i = vam->input;
20078   vl_api_sw_interface_tag_add_del_t *mp;
20079   u32 sw_if_index = ~0;
20080   u8 *tag = 0;
20081   u8 enable = 1;
20082   int ret;
20083
20084   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20085     {
20086       if (unformat (i, "tag %s", &tag))
20087         ;
20088       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20089         ;
20090       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20091         ;
20092       else if (unformat (i, "del"))
20093         enable = 0;
20094       else
20095         break;
20096     }
20097
20098   if (sw_if_index == ~0)
20099     {
20100       errmsg ("missing interface name or sw_if_index");
20101       return -99;
20102     }
20103
20104   if (enable && (tag == 0))
20105     {
20106       errmsg ("no tag specified");
20107       return -99;
20108     }
20109
20110   /* Construct the API message */
20111   M (SW_INTERFACE_TAG_ADD_DEL, mp);
20112   mp->sw_if_index = ntohl (sw_if_index);
20113   mp->is_add = enable;
20114   if (enable)
20115     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
20116   vec_free (tag);
20117
20118   S (mp);
20119   W (ret);
20120   return ret;
20121 }
20122
20123 static int
20124 api_sw_interface_add_del_mac_address (vat_main_t * vam)
20125 {
20126   unformat_input_t *i = vam->input;
20127   vl_api_mac_address_t mac = { 0 };
20128   vl_api_sw_interface_add_del_mac_address_t *mp;
20129   u32 sw_if_index = ~0;
20130   u8 is_add = 1;
20131   u8 mac_set = 0;
20132   int ret;
20133
20134   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20135     {
20136       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20137         ;
20138       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20139         ;
20140       else if (unformat (i, "%U", unformat_vl_api_mac_address, &mac))
20141         mac_set++;
20142       else if (unformat (i, "del"))
20143         is_add = 0;
20144       else
20145         break;
20146     }
20147
20148   if (sw_if_index == ~0)
20149     {
20150       errmsg ("missing interface name or sw_if_index");
20151       return -99;
20152     }
20153
20154   if (!mac_set)
20155     {
20156       errmsg ("missing MAC address");
20157       return -99;
20158     }
20159
20160   /* Construct the API message */
20161   M (SW_INTERFACE_ADD_DEL_MAC_ADDRESS, mp);
20162   mp->sw_if_index = ntohl (sw_if_index);
20163   mp->is_add = is_add;
20164   clib_memcpy (&mp->addr, &mac, sizeof (mac));
20165
20166   S (mp);
20167   W (ret);
20168   return ret;
20169 }
20170
20171 static void vl_api_l2_xconnect_details_t_handler
20172   (vl_api_l2_xconnect_details_t * mp)
20173 {
20174   vat_main_t *vam = &vat_main;
20175
20176   print (vam->ofp, "%15d%15d",
20177          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
20178 }
20179
20180 static void vl_api_l2_xconnect_details_t_handler_json
20181   (vl_api_l2_xconnect_details_t * mp)
20182 {
20183   vat_main_t *vam = &vat_main;
20184   vat_json_node_t *node = NULL;
20185
20186   if (VAT_JSON_ARRAY != vam->json_tree.type)
20187     {
20188       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20189       vat_json_init_array (&vam->json_tree);
20190     }
20191   node = vat_json_array_add (&vam->json_tree);
20192
20193   vat_json_init_object (node);
20194   vat_json_object_add_uint (node, "rx_sw_if_index",
20195                             ntohl (mp->rx_sw_if_index));
20196   vat_json_object_add_uint (node, "tx_sw_if_index",
20197                             ntohl (mp->tx_sw_if_index));
20198 }
20199
20200 static int
20201 api_l2_xconnect_dump (vat_main_t * vam)
20202 {
20203   vl_api_l2_xconnect_dump_t *mp;
20204   vl_api_control_ping_t *mp_ping;
20205   int ret;
20206
20207   if (!vam->json_output)
20208     {
20209       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
20210     }
20211
20212   M (L2_XCONNECT_DUMP, mp);
20213
20214   S (mp);
20215
20216   /* Use a control ping for synchronization */
20217   MPING (CONTROL_PING, mp_ping);
20218   S (mp_ping);
20219
20220   W (ret);
20221   return ret;
20222 }
20223
20224 static int
20225 api_hw_interface_set_mtu (vat_main_t * vam)
20226 {
20227   unformat_input_t *i = vam->input;
20228   vl_api_hw_interface_set_mtu_t *mp;
20229   u32 sw_if_index = ~0;
20230   u32 mtu = 0;
20231   int ret;
20232
20233   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20234     {
20235       if (unformat (i, "mtu %d", &mtu))
20236         ;
20237       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20238         ;
20239       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20240         ;
20241       else
20242         break;
20243     }
20244
20245   if (sw_if_index == ~0)
20246     {
20247       errmsg ("missing interface name or sw_if_index");
20248       return -99;
20249     }
20250
20251   if (mtu == 0)
20252     {
20253       errmsg ("no mtu specified");
20254       return -99;
20255     }
20256
20257   /* Construct the API message */
20258   M (HW_INTERFACE_SET_MTU, mp);
20259   mp->sw_if_index = ntohl (sw_if_index);
20260   mp->mtu = ntohs ((u16) mtu);
20261
20262   S (mp);
20263   W (ret);
20264   return ret;
20265 }
20266
20267 static int
20268 api_p2p_ethernet_add (vat_main_t * vam)
20269 {
20270   unformat_input_t *i = vam->input;
20271   vl_api_p2p_ethernet_add_t *mp;
20272   u32 parent_if_index = ~0;
20273   u32 sub_id = ~0;
20274   u8 remote_mac[6];
20275   u8 mac_set = 0;
20276   int ret;
20277
20278   clib_memset (remote_mac, 0, sizeof (remote_mac));
20279   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20280     {
20281       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
20282         ;
20283       else if (unformat (i, "sw_if_index %d", &parent_if_index))
20284         ;
20285       else
20286         if (unformat
20287             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
20288         mac_set++;
20289       else if (unformat (i, "sub_id %d", &sub_id))
20290         ;
20291       else
20292         {
20293           clib_warning ("parse error '%U'", format_unformat_error, i);
20294           return -99;
20295         }
20296     }
20297
20298   if (parent_if_index == ~0)
20299     {
20300       errmsg ("missing interface name or sw_if_index");
20301       return -99;
20302     }
20303   if (mac_set == 0)
20304     {
20305       errmsg ("missing remote mac address");
20306       return -99;
20307     }
20308   if (sub_id == ~0)
20309     {
20310       errmsg ("missing sub-interface id");
20311       return -99;
20312     }
20313
20314   M (P2P_ETHERNET_ADD, mp);
20315   mp->parent_if_index = ntohl (parent_if_index);
20316   mp->subif_id = ntohl (sub_id);
20317   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
20318
20319   S (mp);
20320   W (ret);
20321   return ret;
20322 }
20323
20324 static int
20325 api_p2p_ethernet_del (vat_main_t * vam)
20326 {
20327   unformat_input_t *i = vam->input;
20328   vl_api_p2p_ethernet_del_t *mp;
20329   u32 parent_if_index = ~0;
20330   u8 remote_mac[6];
20331   u8 mac_set = 0;
20332   int ret;
20333
20334   clib_memset (remote_mac, 0, sizeof (remote_mac));
20335   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20336     {
20337       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
20338         ;
20339       else if (unformat (i, "sw_if_index %d", &parent_if_index))
20340         ;
20341       else
20342         if (unformat
20343             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
20344         mac_set++;
20345       else
20346         {
20347           clib_warning ("parse error '%U'", format_unformat_error, i);
20348           return -99;
20349         }
20350     }
20351
20352   if (parent_if_index == ~0)
20353     {
20354       errmsg ("missing interface name or sw_if_index");
20355       return -99;
20356     }
20357   if (mac_set == 0)
20358     {
20359       errmsg ("missing remote mac address");
20360       return -99;
20361     }
20362
20363   M (P2P_ETHERNET_DEL, mp);
20364   mp->parent_if_index = ntohl (parent_if_index);
20365   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
20366
20367   S (mp);
20368   W (ret);
20369   return ret;
20370 }
20371
20372 static int
20373 api_lldp_config (vat_main_t * vam)
20374 {
20375   unformat_input_t *i = vam->input;
20376   vl_api_lldp_config_t *mp;
20377   int tx_hold = 0;
20378   int tx_interval = 0;
20379   u8 *sys_name = NULL;
20380   int ret;
20381
20382   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20383     {
20384       if (unformat (i, "system-name %s", &sys_name))
20385         ;
20386       else if (unformat (i, "tx-hold %d", &tx_hold))
20387         ;
20388       else if (unformat (i, "tx-interval %d", &tx_interval))
20389         ;
20390       else
20391         {
20392           clib_warning ("parse error '%U'", format_unformat_error, i);
20393           return -99;
20394         }
20395     }
20396
20397   vec_add1 (sys_name, 0);
20398
20399   M (LLDP_CONFIG, mp);
20400   mp->tx_hold = htonl (tx_hold);
20401   mp->tx_interval = htonl (tx_interval);
20402   clib_memcpy (mp->system_name, sys_name, vec_len (sys_name));
20403   vec_free (sys_name);
20404
20405   S (mp);
20406   W (ret);
20407   return ret;
20408 }
20409
20410 static int
20411 api_sw_interface_set_lldp (vat_main_t * vam)
20412 {
20413   unformat_input_t *i = vam->input;
20414   vl_api_sw_interface_set_lldp_t *mp;
20415   u32 sw_if_index = ~0;
20416   u32 enable = 1;
20417   u8 *port_desc = NULL, *mgmt_oid = NULL;
20418   ip4_address_t ip4_addr;
20419   ip6_address_t ip6_addr;
20420   int ret;
20421
20422   clib_memset (&ip4_addr, 0, sizeof (ip4_addr));
20423   clib_memset (&ip6_addr, 0, sizeof (ip6_addr));
20424
20425   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20426     {
20427       if (unformat (i, "disable"))
20428         enable = 0;
20429       else
20430         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20431         ;
20432       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20433         ;
20434       else if (unformat (i, "port-desc %s", &port_desc))
20435         ;
20436       else if (unformat (i, "mgmt-ip4 %U", unformat_ip4_address, &ip4_addr))
20437         ;
20438       else if (unformat (i, "mgmt-ip6 %U", unformat_ip6_address, &ip6_addr))
20439         ;
20440       else if (unformat (i, "mgmt-oid %s", &mgmt_oid))
20441         ;
20442       else
20443         break;
20444     }
20445
20446   if (sw_if_index == ~0)
20447     {
20448       errmsg ("missing interface name or sw_if_index");
20449       return -99;
20450     }
20451
20452   /* Construct the API message */
20453   vec_add1 (port_desc, 0);
20454   vec_add1 (mgmt_oid, 0);
20455   M (SW_INTERFACE_SET_LLDP, mp);
20456   mp->sw_if_index = ntohl (sw_if_index);
20457   mp->enable = enable;
20458   clib_memcpy (mp->port_desc, port_desc, vec_len (port_desc));
20459   clib_memcpy (mp->mgmt_oid, mgmt_oid, vec_len (mgmt_oid));
20460   clib_memcpy (mp->mgmt_ip4, &ip4_addr, sizeof (ip4_addr));
20461   clib_memcpy (mp->mgmt_ip6, &ip6_addr, sizeof (ip6_addr));
20462   vec_free (port_desc);
20463   vec_free (mgmt_oid);
20464
20465   S (mp);
20466   W (ret);
20467   return ret;
20468 }
20469
20470 static int
20471 api_tcp_configure_src_addresses (vat_main_t * vam)
20472 {
20473   vl_api_tcp_configure_src_addresses_t *mp;
20474   unformat_input_t *i = vam->input;
20475   ip4_address_t v4first, v4last;
20476   ip6_address_t v6first, v6last;
20477   u8 range_set = 0;
20478   u32 vrf_id = 0;
20479   int ret;
20480
20481   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20482     {
20483       if (unformat (i, "%U - %U",
20484                     unformat_ip4_address, &v4first,
20485                     unformat_ip4_address, &v4last))
20486         {
20487           if (range_set)
20488             {
20489               errmsg ("one range per message (range already set)");
20490               return -99;
20491             }
20492           range_set = 1;
20493         }
20494       else if (unformat (i, "%U - %U",
20495                          unformat_ip6_address, &v6first,
20496                          unformat_ip6_address, &v6last))
20497         {
20498           if (range_set)
20499             {
20500               errmsg ("one range per message (range already set)");
20501               return -99;
20502             }
20503           range_set = 2;
20504         }
20505       else if (unformat (i, "vrf %d", &vrf_id))
20506         ;
20507       else
20508         break;
20509     }
20510
20511   if (range_set == 0)
20512     {
20513       errmsg ("address range not set");
20514       return -99;
20515     }
20516
20517   M (TCP_CONFIGURE_SRC_ADDRESSES, mp);
20518   mp->vrf_id = ntohl (vrf_id);
20519   /* ipv6? */
20520   if (range_set == 2)
20521     {
20522       mp->is_ipv6 = 1;
20523       clib_memcpy (mp->first_address, &v6first, sizeof (v6first));
20524       clib_memcpy (mp->last_address, &v6last, sizeof (v6last));
20525     }
20526   else
20527     {
20528       mp->is_ipv6 = 0;
20529       clib_memcpy (mp->first_address, &v4first, sizeof (v4first));
20530       clib_memcpy (mp->last_address, &v4last, sizeof (v4last));
20531     }
20532   S (mp);
20533   W (ret);
20534   return ret;
20535 }
20536
20537 static void vl_api_app_namespace_add_del_reply_t_handler
20538   (vl_api_app_namespace_add_del_reply_t * mp)
20539 {
20540   vat_main_t *vam = &vat_main;
20541   i32 retval = ntohl (mp->retval);
20542   if (vam->async_mode)
20543     {
20544       vam->async_errors += (retval < 0);
20545     }
20546   else
20547     {
20548       vam->retval = retval;
20549       if (retval == 0)
20550         errmsg ("app ns index %d\n", ntohl (mp->appns_index));
20551       vam->result_ready = 1;
20552     }
20553 }
20554
20555 static void vl_api_app_namespace_add_del_reply_t_handler_json
20556   (vl_api_app_namespace_add_del_reply_t * mp)
20557 {
20558   vat_main_t *vam = &vat_main;
20559   vat_json_node_t node;
20560
20561   vat_json_init_object (&node);
20562   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
20563   vat_json_object_add_uint (&node, "appns_index", ntohl (mp->appns_index));
20564
20565   vat_json_print (vam->ofp, &node);
20566   vat_json_free (&node);
20567
20568   vam->retval = ntohl (mp->retval);
20569   vam->result_ready = 1;
20570 }
20571
20572 static int
20573 api_app_namespace_add_del (vat_main_t * vam)
20574 {
20575   vl_api_app_namespace_add_del_t *mp;
20576   unformat_input_t *i = vam->input;
20577   u8 *ns_id = 0, secret_set = 0, sw_if_index_set = 0;
20578   u32 sw_if_index, ip4_fib_id, ip6_fib_id;
20579   u64 secret;
20580   int ret;
20581
20582   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20583     {
20584       if (unformat (i, "id %_%v%_", &ns_id))
20585         ;
20586       else if (unformat (i, "secret %lu", &secret))
20587         secret_set = 1;
20588       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20589         sw_if_index_set = 1;
20590       else if (unformat (i, "ip4_fib_id %d", &ip4_fib_id))
20591         ;
20592       else if (unformat (i, "ip6_fib_id %d", &ip6_fib_id))
20593         ;
20594       else
20595         break;
20596     }
20597   if (!ns_id || !secret_set || !sw_if_index_set)
20598     {
20599       errmsg ("namespace id, secret and sw_if_index must be set");
20600       return -99;
20601     }
20602   if (vec_len (ns_id) > 64)
20603     {
20604       errmsg ("namespace id too long");
20605       return -99;
20606     }
20607   M (APP_NAMESPACE_ADD_DEL, mp);
20608
20609   clib_memcpy (mp->namespace_id, ns_id, vec_len (ns_id));
20610   mp->namespace_id_len = vec_len (ns_id);
20611   mp->secret = clib_host_to_net_u64 (secret);
20612   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
20613   mp->ip4_fib_id = clib_host_to_net_u32 (ip4_fib_id);
20614   mp->ip6_fib_id = clib_host_to_net_u32 (ip6_fib_id);
20615   vec_free (ns_id);
20616   S (mp);
20617   W (ret);
20618   return ret;
20619 }
20620
20621 static int
20622 api_sock_init_shm (vat_main_t * vam)
20623 {
20624 #if VPP_API_TEST_BUILTIN == 0
20625   unformat_input_t *i = vam->input;
20626   vl_api_shm_elem_config_t *config = 0;
20627   u64 size = 64 << 20;
20628   int rv;
20629
20630   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20631     {
20632       if (unformat (i, "size %U", unformat_memory_size, &size))
20633         ;
20634       else
20635         break;
20636     }
20637
20638   /*
20639    * Canned custom ring allocator config.
20640    * Should probably parse all of this
20641    */
20642   vec_validate (config, 6);
20643   config[0].type = VL_API_VLIB_RING;
20644   config[0].size = 256;
20645   config[0].count = 32;
20646
20647   config[1].type = VL_API_VLIB_RING;
20648   config[1].size = 1024;
20649   config[1].count = 16;
20650
20651   config[2].type = VL_API_VLIB_RING;
20652   config[2].size = 4096;
20653   config[2].count = 2;
20654
20655   config[3].type = VL_API_CLIENT_RING;
20656   config[3].size = 256;
20657   config[3].count = 32;
20658
20659   config[4].type = VL_API_CLIENT_RING;
20660   config[4].size = 1024;
20661   config[4].count = 16;
20662
20663   config[5].type = VL_API_CLIENT_RING;
20664   config[5].size = 4096;
20665   config[5].count = 2;
20666
20667   config[6].type = VL_API_QUEUE;
20668   config[6].count = 128;
20669   config[6].size = sizeof (uword);
20670
20671   rv = vl_socket_client_init_shm (config, 1 /* want_pthread */ );
20672   if (!rv)
20673     vam->client_index_invalid = 1;
20674   return rv;
20675 #else
20676   return -99;
20677 #endif
20678 }
20679
20680 static void
20681 vl_api_session_rules_details_t_handler (vl_api_session_rules_details_t * mp)
20682 {
20683   vat_main_t *vam = &vat_main;
20684
20685   if (mp->is_ip4)
20686     {
20687       print (vam->ofp,
20688              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
20689              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
20690              mp->scope, format_ip4_address, &mp->lcl_ip, mp->lcl_plen,
20691              clib_net_to_host_u16 (mp->lcl_port), format_ip4_address,
20692              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
20693              clib_net_to_host_u32 (mp->action_index), mp->tag);
20694     }
20695   else
20696     {
20697       print (vam->ofp,
20698              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
20699              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
20700              mp->scope, format_ip6_address, &mp->lcl_ip, mp->lcl_plen,
20701              clib_net_to_host_u16 (mp->lcl_port), format_ip6_address,
20702              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
20703              clib_net_to_host_u32 (mp->action_index), mp->tag);
20704     }
20705 }
20706
20707 static void
20708 vl_api_session_rules_details_t_handler_json (vl_api_session_rules_details_t *
20709                                              mp)
20710 {
20711   vat_main_t *vam = &vat_main;
20712   vat_json_node_t *node = NULL;
20713   struct in6_addr ip6;
20714   struct in_addr ip4;
20715
20716   if (VAT_JSON_ARRAY != vam->json_tree.type)
20717     {
20718       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20719       vat_json_init_array (&vam->json_tree);
20720     }
20721   node = vat_json_array_add (&vam->json_tree);
20722   vat_json_init_object (node);
20723
20724   vat_json_object_add_uint (node, "is_ip4", mp->is_ip4 ? 1 : 0);
20725   vat_json_object_add_uint (node, "appns_index",
20726                             clib_net_to_host_u32 (mp->appns_index));
20727   vat_json_object_add_uint (node, "transport_proto", mp->transport_proto);
20728   vat_json_object_add_uint (node, "scope", mp->scope);
20729   vat_json_object_add_uint (node, "action_index",
20730                             clib_net_to_host_u32 (mp->action_index));
20731   vat_json_object_add_uint (node, "lcl_port",
20732                             clib_net_to_host_u16 (mp->lcl_port));
20733   vat_json_object_add_uint (node, "rmt_port",
20734                             clib_net_to_host_u16 (mp->rmt_port));
20735   vat_json_object_add_uint (node, "lcl_plen", mp->lcl_plen);
20736   vat_json_object_add_uint (node, "rmt_plen", mp->rmt_plen);
20737   vat_json_object_add_string_copy (node, "tag", mp->tag);
20738   if (mp->is_ip4)
20739     {
20740       clib_memcpy (&ip4, mp->lcl_ip, sizeof (ip4));
20741       vat_json_object_add_ip4 (node, "lcl_ip", ip4);
20742       clib_memcpy (&ip4, mp->rmt_ip, sizeof (ip4));
20743       vat_json_object_add_ip4 (node, "rmt_ip", ip4);
20744     }
20745   else
20746     {
20747       clib_memcpy (&ip6, mp->lcl_ip, sizeof (ip6));
20748       vat_json_object_add_ip6 (node, "lcl_ip", ip6);
20749       clib_memcpy (&ip6, mp->rmt_ip, sizeof (ip6));
20750       vat_json_object_add_ip6 (node, "rmt_ip", ip6);
20751     }
20752 }
20753
20754 static int
20755 api_session_rule_add_del (vat_main_t * vam)
20756 {
20757   vl_api_session_rule_add_del_t *mp;
20758   unformat_input_t *i = vam->input;
20759   u32 proto = ~0, lcl_port, rmt_port, action = 0, lcl_plen, rmt_plen;
20760   u32 appns_index = 0, scope = 0;
20761   ip4_address_t lcl_ip4, rmt_ip4;
20762   ip6_address_t lcl_ip6, rmt_ip6;
20763   u8 is_ip4 = 1, conn_set = 0;
20764   u8 is_add = 1, *tag = 0;
20765   int ret;
20766
20767   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20768     {
20769       if (unformat (i, "del"))
20770         is_add = 0;
20771       else if (unformat (i, "add"))
20772         ;
20773       else if (unformat (i, "proto tcp"))
20774         proto = 0;
20775       else if (unformat (i, "proto udp"))
20776         proto = 1;
20777       else if (unformat (i, "appns %d", &appns_index))
20778         ;
20779       else if (unformat (i, "scope %d", &scope))
20780         ;
20781       else if (unformat (i, "tag %_%v%_", &tag))
20782         ;
20783       else
20784         if (unformat
20785             (i, "%U/%d %d %U/%d %d", unformat_ip4_address, &lcl_ip4,
20786              &lcl_plen, &lcl_port, unformat_ip4_address, &rmt_ip4, &rmt_plen,
20787              &rmt_port))
20788         {
20789           is_ip4 = 1;
20790           conn_set = 1;
20791         }
20792       else
20793         if (unformat
20794             (i, "%U/%d %d %U/%d %d", unformat_ip6_address, &lcl_ip6,
20795              &lcl_plen, &lcl_port, unformat_ip6_address, &rmt_ip6, &rmt_plen,
20796              &rmt_port))
20797         {
20798           is_ip4 = 0;
20799           conn_set = 1;
20800         }
20801       else if (unformat (i, "action %d", &action))
20802         ;
20803       else
20804         break;
20805     }
20806   if (proto == ~0 || !conn_set || action == ~0)
20807     {
20808       errmsg ("transport proto, connection and action must be set");
20809       return -99;
20810     }
20811
20812   if (scope > 3)
20813     {
20814       errmsg ("scope should be 0-3");
20815       return -99;
20816     }
20817
20818   M (SESSION_RULE_ADD_DEL, mp);
20819
20820   mp->is_ip4 = is_ip4;
20821   mp->transport_proto = proto;
20822   mp->lcl_port = clib_host_to_net_u16 ((u16) lcl_port);
20823   mp->rmt_port = clib_host_to_net_u16 ((u16) rmt_port);
20824   mp->lcl_plen = lcl_plen;
20825   mp->rmt_plen = rmt_plen;
20826   mp->action_index = clib_host_to_net_u32 (action);
20827   mp->appns_index = clib_host_to_net_u32 (appns_index);
20828   mp->scope = scope;
20829   mp->is_add = is_add;
20830   if (is_ip4)
20831     {
20832       clib_memcpy (mp->lcl_ip, &lcl_ip4, sizeof (lcl_ip4));
20833       clib_memcpy (mp->rmt_ip, &rmt_ip4, sizeof (rmt_ip4));
20834     }
20835   else
20836     {
20837       clib_memcpy (mp->lcl_ip, &lcl_ip6, sizeof (lcl_ip6));
20838       clib_memcpy (mp->rmt_ip, &rmt_ip6, sizeof (rmt_ip6));
20839     }
20840   if (tag)
20841     {
20842       clib_memcpy (mp->tag, tag, vec_len (tag));
20843       vec_free (tag);
20844     }
20845
20846   S (mp);
20847   W (ret);
20848   return ret;
20849 }
20850
20851 static int
20852 api_session_rules_dump (vat_main_t * vam)
20853 {
20854   vl_api_session_rules_dump_t *mp;
20855   vl_api_control_ping_t *mp_ping;
20856   int ret;
20857
20858   if (!vam->json_output)
20859     {
20860       print (vam->ofp, "%=20s", "Session Rules");
20861     }
20862
20863   M (SESSION_RULES_DUMP, mp);
20864   /* send it... */
20865   S (mp);
20866
20867   /* Use a control ping for synchronization */
20868   MPING (CONTROL_PING, mp_ping);
20869   S (mp_ping);
20870
20871   /* Wait for a reply... */
20872   W (ret);
20873   return ret;
20874 }
20875
20876 static int
20877 api_ip_container_proxy_add_del (vat_main_t * vam)
20878 {
20879   vl_api_ip_container_proxy_add_del_t *mp;
20880   unformat_input_t *i = vam->input;
20881   u32 sw_if_index = ~0;
20882   vl_api_prefix_t pfx = { };
20883   u8 is_add = 1;
20884   int ret;
20885
20886   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20887     {
20888       if (unformat (i, "del"))
20889         is_add = 0;
20890       else if (unformat (i, "add"))
20891         ;
20892       if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
20893         ;
20894       else if (unformat (i, "sw_if_index %u", &sw_if_index))
20895         ;
20896       else
20897         break;
20898     }
20899   if (sw_if_index == ~0 || pfx.len == 0)
20900     {
20901       errmsg ("address and sw_if_index must be set");
20902       return -99;
20903     }
20904
20905   M (IP_CONTAINER_PROXY_ADD_DEL, mp);
20906
20907   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
20908   mp->is_add = is_add;
20909   clib_memcpy (&mp->pfx, &pfx, sizeof (pfx));
20910
20911   S (mp);
20912   W (ret);
20913   return ret;
20914 }
20915
20916 static int
20917 api_qos_record_enable_disable (vat_main_t * vam)
20918 {
20919   unformat_input_t *i = vam->input;
20920   vl_api_qos_record_enable_disable_t *mp;
20921   u32 sw_if_index, qs = 0xff;
20922   u8 sw_if_index_set = 0;
20923   u8 enable = 1;
20924   int ret;
20925
20926   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20927     {
20928       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20929         sw_if_index_set = 1;
20930       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20931         sw_if_index_set = 1;
20932       else if (unformat (i, "%U", unformat_qos_source, &qs))
20933         ;
20934       else if (unformat (i, "disable"))
20935         enable = 0;
20936       else
20937         {
20938           clib_warning ("parse error '%U'", format_unformat_error, i);
20939           return -99;
20940         }
20941     }
20942
20943   if (sw_if_index_set == 0)
20944     {
20945       errmsg ("missing interface name or sw_if_index");
20946       return -99;
20947     }
20948   if (qs == 0xff)
20949     {
20950       errmsg ("input location must be specified");
20951       return -99;
20952     }
20953
20954   M (QOS_RECORD_ENABLE_DISABLE, mp);
20955
20956   mp->record.sw_if_index = ntohl (sw_if_index);
20957   mp->record.input_source = qs;
20958   mp->enable = enable;
20959
20960   S (mp);
20961   W (ret);
20962   return ret;
20963 }
20964
20965
20966 static int
20967 q_or_quit (vat_main_t * vam)
20968 {
20969 #if VPP_API_TEST_BUILTIN == 0
20970   longjmp (vam->jump_buf, 1);
20971 #endif
20972   return 0;                     /* not so much */
20973 }
20974
20975 static int
20976 q (vat_main_t * vam)
20977 {
20978   return q_or_quit (vam);
20979 }
20980
20981 static int
20982 quit (vat_main_t * vam)
20983 {
20984   return q_or_quit (vam);
20985 }
20986
20987 static int
20988 comment (vat_main_t * vam)
20989 {
20990   return 0;
20991 }
20992
20993 static int
20994 elog_save (vat_main_t * vam)
20995 {
20996 #if VPP_API_TEST_BUILTIN == 0
20997   elog_main_t *em = &vam->elog_main;
20998   unformat_input_t *i = vam->input;
20999   char *file, *chroot_file;
21000   clib_error_t *error;
21001
21002   if (!unformat (i, "%s", &file))
21003     {
21004       errmsg ("expected file name, got `%U'", format_unformat_error, i);
21005       return 0;
21006     }
21007
21008   /* It's fairly hard to get "../oopsie" through unformat; just in case */
21009   if (strstr (file, "..") || index (file, '/'))
21010     {
21011       errmsg ("illegal characters in filename '%s'", file);
21012       return 0;
21013     }
21014
21015   chroot_file = (char *) format (0, "/tmp/%s%c", file, 0);
21016
21017   vec_free (file);
21018
21019   errmsg ("Saving %wd of %wd events to %s",
21020           elog_n_events_in_buffer (em),
21021           elog_buffer_capacity (em), chroot_file);
21022
21023   error = elog_write_file (em, chroot_file, 1 /* flush ring */ );
21024   vec_free (chroot_file);
21025
21026   if (error)
21027     clib_error_report (error);
21028 #else
21029   errmsg ("Use the vpp event loger...");
21030 #endif
21031
21032   return 0;
21033 }
21034
21035 static int
21036 elog_setup (vat_main_t * vam)
21037 {
21038 #if VPP_API_TEST_BUILTIN == 0
21039   elog_main_t *em = &vam->elog_main;
21040   unformat_input_t *i = vam->input;
21041   u32 nevents = 128 << 10;
21042
21043   (void) unformat (i, "nevents %d", &nevents);
21044
21045   elog_init (em, nevents);
21046   vl_api_set_elog_main (em);
21047   vl_api_set_elog_trace_api_messages (1);
21048   errmsg ("Event logger initialized with %u events", nevents);
21049 #else
21050   errmsg ("Use the vpp event loger...");
21051 #endif
21052   return 0;
21053 }
21054
21055 static int
21056 elog_enable (vat_main_t * vam)
21057 {
21058 #if VPP_API_TEST_BUILTIN == 0
21059   elog_main_t *em = &vam->elog_main;
21060
21061   elog_enable_disable (em, 1 /* enable */ );
21062   vl_api_set_elog_trace_api_messages (1);
21063   errmsg ("Event logger enabled...");
21064 #else
21065   errmsg ("Use the vpp event loger...");
21066 #endif
21067   return 0;
21068 }
21069
21070 static int
21071 elog_disable (vat_main_t * vam)
21072 {
21073 #if VPP_API_TEST_BUILTIN == 0
21074   elog_main_t *em = &vam->elog_main;
21075
21076   elog_enable_disable (em, 0 /* enable */ );
21077   vl_api_set_elog_trace_api_messages (1);
21078   errmsg ("Event logger disabled...");
21079 #else
21080   errmsg ("Use the vpp event loger...");
21081 #endif
21082   return 0;
21083 }
21084
21085 static int
21086 statseg (vat_main_t * vam)
21087 {
21088   ssvm_private_t *ssvmp = &vam->stat_segment;
21089   ssvm_shared_header_t *shared_header = ssvmp->sh;
21090   vlib_counter_t **counters;
21091   u64 thread0_index1_packets;
21092   u64 thread0_index1_bytes;
21093   f64 vector_rate, input_rate;
21094   uword *p;
21095
21096   uword *counter_vector_by_name;
21097   if (vam->stat_segment_lockp == 0)
21098     {
21099       errmsg ("Stat segment not mapped...");
21100       return -99;
21101     }
21102
21103   /* look up "/if/rx for sw_if_index 1 as a test */
21104
21105   clib_spinlock_lock (vam->stat_segment_lockp);
21106
21107   counter_vector_by_name = (uword *) shared_header->opaque[1];
21108
21109   p = hash_get_mem (counter_vector_by_name, "/if/rx");
21110   if (p == 0)
21111     {
21112       clib_spinlock_unlock (vam->stat_segment_lockp);
21113       errmsg ("/if/tx not found?");
21114       return -99;
21115     }
21116
21117   /* Fish per-thread vector of combined counters from shared memory */
21118   counters = (vlib_counter_t **) p[0];
21119
21120   if (vec_len (counters[0]) < 2)
21121     {
21122       clib_spinlock_unlock (vam->stat_segment_lockp);
21123       errmsg ("/if/tx vector length %d", vec_len (counters[0]));
21124       return -99;
21125     }
21126
21127   /* Read thread 0 sw_if_index 1 counter */
21128   thread0_index1_packets = counters[0][1].packets;
21129   thread0_index1_bytes = counters[0][1].bytes;
21130
21131   p = hash_get_mem (counter_vector_by_name, "vector_rate");
21132   if (p == 0)
21133     {
21134       clib_spinlock_unlock (vam->stat_segment_lockp);
21135       errmsg ("vector_rate not found?");
21136       return -99;
21137     }
21138
21139   vector_rate = *(f64 *) (p[0]);
21140   p = hash_get_mem (counter_vector_by_name, "input_rate");
21141   if (p == 0)
21142     {
21143       clib_spinlock_unlock (vam->stat_segment_lockp);
21144       errmsg ("input_rate not found?");
21145       return -99;
21146     }
21147   input_rate = *(f64 *) (p[0]);
21148
21149   clib_spinlock_unlock (vam->stat_segment_lockp);
21150
21151   print (vam->ofp, "vector_rate %.2f input_rate %.2f",
21152          vector_rate, input_rate);
21153   print (vam->ofp, "thread 0 sw_if_index 1 rx pkts %lld, bytes %lld",
21154          thread0_index1_packets, thread0_index1_bytes);
21155
21156   return 0;
21157 }
21158
21159 static int
21160 cmd_cmp (void *a1, void *a2)
21161 {
21162   u8 **c1 = a1;
21163   u8 **c2 = a2;
21164
21165   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
21166 }
21167
21168 static int
21169 help (vat_main_t * vam)
21170 {
21171   u8 **cmds = 0;
21172   u8 *name = 0;
21173   hash_pair_t *p;
21174   unformat_input_t *i = vam->input;
21175   int j;
21176
21177   if (unformat (i, "%s", &name))
21178     {
21179       uword *hs;
21180
21181       vec_add1 (name, 0);
21182
21183       hs = hash_get_mem (vam->help_by_name, name);
21184       if (hs)
21185         print (vam->ofp, "usage: %s %s", name, hs[0]);
21186       else
21187         print (vam->ofp, "No such msg / command '%s'", name);
21188       vec_free (name);
21189       return 0;
21190     }
21191
21192   print (vam->ofp, "Help is available for the following:");
21193
21194     /* *INDENT-OFF* */
21195     hash_foreach_pair (p, vam->function_by_name,
21196     ({
21197       vec_add1 (cmds, (u8 *)(p->key));
21198     }));
21199     /* *INDENT-ON* */
21200
21201   vec_sort_with_function (cmds, cmd_cmp);
21202
21203   for (j = 0; j < vec_len (cmds); j++)
21204     print (vam->ofp, "%s", cmds[j]);
21205
21206   vec_free (cmds);
21207   return 0;
21208 }
21209
21210 static int
21211 set (vat_main_t * vam)
21212 {
21213   u8 *name = 0, *value = 0;
21214   unformat_input_t *i = vam->input;
21215
21216   if (unformat (i, "%s", &name))
21217     {
21218       /* The input buffer is a vector, not a string. */
21219       value = vec_dup (i->buffer);
21220       vec_delete (value, i->index, 0);
21221       /* Almost certainly has a trailing newline */
21222       if (value[vec_len (value) - 1] == '\n')
21223         value[vec_len (value) - 1] = 0;
21224       /* Make sure it's a proper string, one way or the other */
21225       vec_add1 (value, 0);
21226       (void) clib_macro_set_value (&vam->macro_main,
21227                                    (char *) name, (char *) value);
21228     }
21229   else
21230     errmsg ("usage: set <name> <value>");
21231
21232   vec_free (name);
21233   vec_free (value);
21234   return 0;
21235 }
21236
21237 static int
21238 unset (vat_main_t * vam)
21239 {
21240   u8 *name = 0;
21241
21242   if (unformat (vam->input, "%s", &name))
21243     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
21244       errmsg ("unset: %s wasn't set", name);
21245   vec_free (name);
21246   return 0;
21247 }
21248
21249 typedef struct
21250 {
21251   u8 *name;
21252   u8 *value;
21253 } macro_sort_t;
21254
21255
21256 static int
21257 macro_sort_cmp (void *a1, void *a2)
21258 {
21259   macro_sort_t *s1 = a1;
21260   macro_sort_t *s2 = a2;
21261
21262   return strcmp ((char *) (s1->name), (char *) (s2->name));
21263 }
21264
21265 static int
21266 dump_macro_table (vat_main_t * vam)
21267 {
21268   macro_sort_t *sort_me = 0, *sm;
21269   int i;
21270   hash_pair_t *p;
21271
21272     /* *INDENT-OFF* */
21273     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
21274     ({
21275       vec_add2 (sort_me, sm, 1);
21276       sm->name = (u8 *)(p->key);
21277       sm->value = (u8 *) (p->value[0]);
21278     }));
21279     /* *INDENT-ON* */
21280
21281   vec_sort_with_function (sort_me, macro_sort_cmp);
21282
21283   if (vec_len (sort_me))
21284     print (vam->ofp, "%-15s%s", "Name", "Value");
21285   else
21286     print (vam->ofp, "The macro table is empty...");
21287
21288   for (i = 0; i < vec_len (sort_me); i++)
21289     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
21290   return 0;
21291 }
21292
21293 static int
21294 dump_node_table (vat_main_t * vam)
21295 {
21296   int i, j;
21297   vlib_node_t *node, *next_node;
21298
21299   if (vec_len (vam->graph_nodes) == 0)
21300     {
21301       print (vam->ofp, "Node table empty, issue get_node_graph...");
21302       return 0;
21303     }
21304
21305   for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
21306     {
21307       node = vam->graph_nodes[0][i];
21308       print (vam->ofp, "[%d] %s", i, node->name);
21309       for (j = 0; j < vec_len (node->next_nodes); j++)
21310         {
21311           if (node->next_nodes[j] != ~0)
21312             {
21313               next_node = vam->graph_nodes[0][node->next_nodes[j]];
21314               print (vam->ofp, "  [%d] %s", j, next_node->name);
21315             }
21316         }
21317     }
21318   return 0;
21319 }
21320
21321 static int
21322 value_sort_cmp (void *a1, void *a2)
21323 {
21324   name_sort_t *n1 = a1;
21325   name_sort_t *n2 = a2;
21326
21327   if (n1->value < n2->value)
21328     return -1;
21329   if (n1->value > n2->value)
21330     return 1;
21331   return 0;
21332 }
21333
21334
21335 static int
21336 dump_msg_api_table (vat_main_t * vam)
21337 {
21338   api_main_t *am = vlibapi_get_main ();
21339   name_sort_t *nses = 0, *ns;
21340   hash_pair_t *hp;
21341   int i;
21342
21343   /* *INDENT-OFF* */
21344   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
21345   ({
21346     vec_add2 (nses, ns, 1);
21347     ns->name = (u8 *)(hp->key);
21348     ns->value = (u32) hp->value[0];
21349   }));
21350   /* *INDENT-ON* */
21351
21352   vec_sort_with_function (nses, value_sort_cmp);
21353
21354   for (i = 0; i < vec_len (nses); i++)
21355     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
21356   vec_free (nses);
21357   return 0;
21358 }
21359
21360 static int
21361 get_msg_id (vat_main_t * vam)
21362 {
21363   u8 *name_and_crc;
21364   u32 message_index;
21365
21366   if (unformat (vam->input, "%s", &name_and_crc))
21367     {
21368       message_index = vl_msg_api_get_msg_index (name_and_crc);
21369       if (message_index == ~0)
21370         {
21371           print (vam->ofp, " '%s' not found", name_and_crc);
21372           return 0;
21373         }
21374       print (vam->ofp, " '%s' has message index %d",
21375              name_and_crc, message_index);
21376       return 0;
21377     }
21378   errmsg ("name_and_crc required...");
21379   return 0;
21380 }
21381
21382 static int
21383 search_node_table (vat_main_t * vam)
21384 {
21385   unformat_input_t *line_input = vam->input;
21386   u8 *node_to_find;
21387   int j;
21388   vlib_node_t *node, *next_node;
21389   uword *p;
21390
21391   if (vam->graph_node_index_by_name == 0)
21392     {
21393       print (vam->ofp, "Node table empty, issue get_node_graph...");
21394       return 0;
21395     }
21396
21397   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
21398     {
21399       if (unformat (line_input, "%s", &node_to_find))
21400         {
21401           vec_add1 (node_to_find, 0);
21402           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
21403           if (p == 0)
21404             {
21405               print (vam->ofp, "%s not found...", node_to_find);
21406               goto out;
21407             }
21408           node = vam->graph_nodes[0][p[0]];
21409           print (vam->ofp, "[%d] %s", p[0], node->name);
21410           for (j = 0; j < vec_len (node->next_nodes); j++)
21411             {
21412               if (node->next_nodes[j] != ~0)
21413                 {
21414                   next_node = vam->graph_nodes[0][node->next_nodes[j]];
21415                   print (vam->ofp, "  [%d] %s", j, next_node->name);
21416                 }
21417             }
21418         }
21419
21420       else
21421         {
21422           clib_warning ("parse error '%U'", format_unformat_error,
21423                         line_input);
21424           return -99;
21425         }
21426
21427     out:
21428       vec_free (node_to_find);
21429
21430     }
21431
21432   return 0;
21433 }
21434
21435
21436 static int
21437 script (vat_main_t * vam)
21438 {
21439 #if (VPP_API_TEST_BUILTIN==0)
21440   u8 *s = 0;
21441   char *save_current_file;
21442   unformat_input_t save_input;
21443   jmp_buf save_jump_buf;
21444   u32 save_line_number;
21445
21446   FILE *new_fp, *save_ifp;
21447
21448   if (unformat (vam->input, "%s", &s))
21449     {
21450       new_fp = fopen ((char *) s, "r");
21451       if (new_fp == 0)
21452         {
21453           errmsg ("Couldn't open script file %s", s);
21454           vec_free (s);
21455           return -99;
21456         }
21457     }
21458   else
21459     {
21460       errmsg ("Missing script name");
21461       return -99;
21462     }
21463
21464   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
21465   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
21466   save_ifp = vam->ifp;
21467   save_line_number = vam->input_line_number;
21468   save_current_file = (char *) vam->current_file;
21469
21470   vam->input_line_number = 0;
21471   vam->ifp = new_fp;
21472   vam->current_file = s;
21473   do_one_file (vam);
21474
21475   clib_memcpy (&vam->input, &save_input, sizeof (save_input));
21476   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
21477   vam->ifp = save_ifp;
21478   vam->input_line_number = save_line_number;
21479   vam->current_file = (u8 *) save_current_file;
21480   vec_free (s);
21481
21482   return 0;
21483 #else
21484   clib_warning ("use the exec command...");
21485   return -99;
21486 #endif
21487 }
21488
21489 static int
21490 echo (vat_main_t * vam)
21491 {
21492   print (vam->ofp, "%v", vam->input->buffer);
21493   return 0;
21494 }
21495
21496 /* List of API message constructors, CLI names map to api_xxx */
21497 #define foreach_vpe_api_msg                                             \
21498 _(create_loopback,"[mac <mac-addr>] [instance <instance>]")             \
21499 _(sw_interface_dump,"")                                                 \
21500 _(sw_interface_set_flags,                                               \
21501   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
21502 _(sw_interface_add_del_address,                                         \
21503   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
21504 _(sw_interface_set_rx_mode,                                             \
21505   "<intfc> | sw_if_index <id> [queue <id>] <polling | interrupt | adaptive>") \
21506 _(sw_interface_set_rx_placement,                                        \
21507   "<intfc> | sw_if_index <id> [queue <id>] [worker <id> | main]")       \
21508 _(sw_interface_rx_placement_dump,                                       \
21509   "[<intfc> | sw_if_index <id>]")                                         \
21510 _(sw_interface_set_table,                                               \
21511   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
21512 _(sw_interface_set_mpls_enable,                                         \
21513   "<intfc> | sw_if_index [disable | dis]")                              \
21514 _(sw_interface_set_vpath,                                               \
21515   "<intfc> | sw_if_index <id> enable | disable")                        \
21516 _(sw_interface_set_vxlan_bypass,                                        \
21517   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
21518 _(sw_interface_set_geneve_bypass,                                       \
21519   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
21520 _(sw_interface_set_l2_xconnect,                                         \
21521   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
21522   "enable | disable")                                                   \
21523 _(sw_interface_set_l2_bridge,                                           \
21524   "{<intfc> | sw_if_index <id>} bd_id <bridge-domain-id>\n"             \
21525   "[shg <split-horizon-group>] [bvi]\n"                                 \
21526   "enable | disable")                                                   \
21527 _(bridge_domain_set_mac_age, "bd_id <bridge-domain-id> mac-age 0-255")  \
21528 _(bridge_domain_add_del,                                                \
21529   "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") \
21530 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
21531 _(l2fib_add_del,                                                        \
21532   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
21533 _(l2fib_flush_bd, "bd_id <bridge-domain-id>")                           \
21534 _(l2fib_flush_int, "<intfc> | sw_if_index <id>")                        \
21535 _(l2_flags,                                                             \
21536   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
21537 _(bridge_flags,                                                         \
21538   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
21539 _(tap_create_v2,                                                        \
21540   "id <num> [hw-addr <mac-addr>] [host-ns <name>] [rx-ring-size <num> [tx-ring-size <num>] [host-mtu-size <mtu>] [gso | no-gso]") \
21541 _(tap_delete_v2,                                                        \
21542   "<vpp-if-name> | sw_if_index <id>")                                   \
21543 _(sw_interface_tap_v2_dump, "")                                         \
21544 _(virtio_pci_create,                                                    \
21545   "pci-addr <pci-address> [use_random_mac | hw-addr <mac-addr>] [features <hex-value>] [gso-enabled]") \
21546 _(virtio_pci_delete,                                                    \
21547   "<vpp-if-name> | sw_if_index <id>")                                   \
21548 _(sw_interface_virtio_pci_dump, "")                                     \
21549 _(bond_create,                                                          \
21550   "[hw-addr <mac-addr>] {round-robin | active-backup | "                \
21551   "broadcast | {lacp | xor} [load-balance { l2 | l23 | l34 }]} "        \
21552   "[id <if-id>]")                                                       \
21553 _(bond_delete,                                                          \
21554   "<vpp-if-name> | sw_if_index <id>")                                   \
21555 _(bond_enslave,                                                         \
21556   "sw_if_index <n> bond <sw_if_index> [is_passive] [is_long_timeout]")  \
21557 _(bond_detach_slave,                                                    \
21558   "sw_if_index <n>")                                                    \
21559  _(sw_interface_set_bond_weight, "<intfc> | sw_if_index <nn> weight <value>") \
21560 _(sw_interface_bond_dump, "")                                           \
21561 _(sw_interface_slave_dump,                                              \
21562   "<vpp-if-name> | sw_if_index <id>")                                   \
21563 _(ip_table_add_del,                                                     \
21564   "table <n> [ipv6] [add | del]\n")                                     \
21565 _(ip_route_add_del,                                                     \
21566   "<addr>/<mask> via <<addr>|<intfc>|sw_if_index <id>|via-label <n>>\n" \
21567   "[table-id <n>] [<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"\
21568   "[weight <n>] [drop] [local] [classify <n>]  [out-label <n>]\n"       \
21569   "[multipath] [count <n>] [del]")                                      \
21570 _(ip_mroute_add_del,                                                    \
21571   "<src> <grp>/<mask> [table-id <n>]\n"                                 \
21572   "[<intfc> | sw_if_index <id>] [local] [del]")                         \
21573 _(mpls_table_add_del,                                                   \
21574   "table <n> [add | del]\n")                                            \
21575 _(mpls_route_add_del,                                                   \
21576   "<label> <eos> via <addr | next-hop-table <n> | via-label <n> |\n"    \
21577   "lookup-ip4-table <n> | lookup-in-ip6-table <n> |\n"                  \
21578   "l2-input-on <intfc> | l2-input-on sw_if_index <id>>\n"               \
21579   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>] [weight <n>]\n"  \
21580   "[drop] [local] [classify <n>] [out-label <n>] [multipath]\n"         \
21581   "[count <n>] [del]")                                                  \
21582 _(mpls_ip_bind_unbind,                                                  \
21583   "<label> <addr/len>")                                                 \
21584 _(mpls_tunnel_add_del,                                                  \
21585   "[add | del <intfc | sw_if_index <id>>] via <addr | via-label <n>>\n" \
21586   "[<intfc> | sw_if_index <id> | next-hop-table <id>]\n"                \
21587   "[l2-only]  [out-label <n>]")                                         \
21588 _(sr_mpls_policy_add,                                                   \
21589   "bsid <id> [weight <n>] [spray] next <sid> [next <sid>]")             \
21590 _(sr_mpls_policy_del,                                                   \
21591   "bsid <id>")                                                          \
21592 _(bier_table_add_del,                                                   \
21593   "<label> <sub-domain> <set> <bsl> [del]")                             \
21594 _(bier_route_add_del,                                                   \
21595   "<bit-position> <sub-domain> <set> <bsl> via <addr> [table-id <n>]\n" \
21596   "[<intfc> | sw_if_index <id>]"                                        \
21597   "[weight <n>] [del] [multipath]")                                     \
21598 _(proxy_arp_add_del,                                                    \
21599   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
21600 _(proxy_arp_intfc_enable_disable,                                       \
21601   "<intfc> | sw_if_index <id> enable | disable")                        \
21602 _(sw_interface_set_unnumbered,                                          \
21603   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
21604 _(ip_neighbor_add_del,                                                  \
21605   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
21606   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
21607 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
21608 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
21609   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
21610   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
21611   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
21612 _(ip_table_replace_begin, "table <n> [ipv6]")                           \
21613 _(ip_table_flush, "table <n> [ipv6]")                                   \
21614 _(ip_table_replace_end, "table <n> [ipv6]")                             \
21615 _(set_ip_flow_hash,                                                     \
21616   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
21617 _(sw_interface_ip6_enable_disable,                                      \
21618   "<intfc> | sw_if_index <id> enable | disable")                        \
21619 _(ip6nd_proxy_add_del,                                                  \
21620   "<intfc> | sw_if_index <id> <ip6-address>")                           \
21621 _(ip6nd_proxy_dump, "")                                                 \
21622 _(sw_interface_ip6nd_ra_prefix,                                         \
21623   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
21624   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
21625   "[nolink] [isno]")                                                    \
21626 _(sw_interface_ip6nd_ra_config,                                         \
21627   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
21628   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
21629   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
21630 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
21631 _(l2_patch_add_del,                                                     \
21632   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
21633   "enable | disable")                                                   \
21634 _(sr_localsid_add_del,                                                  \
21635   "(del) address <addr> next_hop <addr> behavior <beh>\n"               \
21636   "fib-table <num> (end.psp) sw_if_index <num>")                        \
21637 _(classify_add_del_table,                                               \
21638   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
21639   " [del] [del-chain] mask <mask-value>\n"                              \
21640   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
21641   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
21642 _(classify_add_del_session,                                             \
21643   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
21644   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
21645   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
21646   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
21647 _(classify_set_interface_ip_table,                                      \
21648   "<intfc> | sw_if_index <nn> table <nn>")                              \
21649 _(classify_set_interface_l2_tables,                                     \
21650   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
21651   "  [other-table <nn>]")                                               \
21652 _(get_node_index, "node <node-name")                                    \
21653 _(add_node_next, "node <node-name> next <next-node-name>")              \
21654 _(l2tpv3_create_tunnel,                                                 \
21655   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
21656   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
21657   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
21658 _(l2tpv3_set_tunnel_cookies,                                            \
21659   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
21660   "[new_remote_cookie <nn>]\n")                                         \
21661 _(l2tpv3_interface_enable_disable,                                      \
21662   "<intfc> | sw_if_index <nn> enable | disable")                        \
21663 _(l2tpv3_set_lookup_key,                                                \
21664   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
21665 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
21666 _(vxlan_offload_rx,                                                     \
21667   "hw { <interface name> | hw_if_index <nn>} "                          \
21668   "rx { <vxlan tunnel name> | sw_if_index <nn> } [del]")                \
21669 _(vxlan_add_del_tunnel,                                                 \
21670   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
21671   "{ <intfc> | mcast_sw_if_index <nn> } [instance <id>]}\n"             \
21672   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
21673 _(geneve_add_del_tunnel,                                                \
21674   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
21675   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
21676   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
21677 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
21678 _(geneve_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                   \
21679 _(gre_tunnel_add_del,                                                   \
21680   "src <ip-addr> dst <ip-addr> [outer-fib-id <nn>] [instance <n>]\n"    \
21681   "[teb | erspan <session-id>] [del]")                                  \
21682 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
21683 _(l2_fib_clear_table, "")                                               \
21684 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
21685 _(l2_interface_vlan_tag_rewrite,                                        \
21686   "<intfc> | sw_if_index <nn> \n"                                       \
21687   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
21688   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
21689 _(create_vhost_user_if,                                                 \
21690         "socket <filename> [server] [renumber <dev_instance>] "         \
21691         "[disable_mrg_rxbuf] [disable_indirect_desc] [gso] "            \
21692         "[mac <mac_address>]")                                          \
21693 _(modify_vhost_user_if,                                                 \
21694         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
21695         "[server] [renumber <dev_instance>] [gso]")                     \
21696 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
21697 _(sw_interface_vhost_user_dump, "")                                     \
21698 _(show_version, "")                                                     \
21699 _(show_threads, "")                                                     \
21700 _(vxlan_gpe_add_del_tunnel,                                             \
21701   "local <addr> remote <addr>  | group <mcast-ip-addr>\n"               \
21702   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
21703   "vni <nn> [encap-vrf-id <nn>] [decap-vrf-id <nn>]\n"                  \
21704   "[next-ip4][next-ip6][next-ethernet] [next-nsh] [del]\n")             \
21705 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
21706 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
21707 _(interface_name_renumber,                                              \
21708   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
21709 _(input_acl_set_interface,                                              \
21710   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
21711   "  [l2-table <nn>] [del]")                                            \
21712 _(ip_probe_neighbor, "(<intc> | sw_if_index <nn>) address <ip4|ip6-addr>") \
21713 _(ip_scan_neighbor_enable_disable, "[ip4|ip6|both|disable] [interval <n-min>]\n" \
21714   "  [max-time <n-usec>] [max-update <n>] [delay <n-msec>] [stale <n-min>]") \
21715 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
21716 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
21717 _(want_l2_macs_events, "[disable] [learn-limit <n>] [scan-delay <n>] [max-entries <n>]") \
21718 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
21719 _(ip_dump, "ipv4 | ipv6")                                               \
21720 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
21721 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
21722   "  spid_id <n> ")                                                     \
21723 _(ipsec_sad_entry_add_del, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
21724   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
21725   "  integ_alg <alg> integ_key <hex>")                                  \
21726 _(ipsec_spd_entry_add_del, "spd_id <n> priority <n> action <action>\n"  \
21727   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
21728   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
21729   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
21730 _(ipsec_tunnel_if_add_del, "local_spi <n> remote_spi <n>\n"             \
21731   "  crypto_alg <alg> local_crypto_key <hex> remote_crypto_key <hex>\n" \
21732   "  integ_alg <alg> local_integ_key <hex> remote_integ_key <hex>\n"    \
21733   "  local_ip <addr> remote_ip <addr> [esn] [anti_replay] [del]\n"      \
21734   "  [instance <n>]")     \
21735 _(ipsec_sa_dump, "[sa_id <n>]")                                         \
21736 _(ipsec_tunnel_if_set_sa, "<intfc> sa_id <n> <inbound|outbound>\n")     \
21737 _(delete_loopback,"sw_if_index <nn>")                                   \
21738 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
21739 _(bd_ip_mac_flush, "bd_id <bridge-domain-id>")                          \
21740 _(bd_ip_mac_dump, "[bd_id] <bridge-domain-id>")                         \
21741 _(want_interface_events,  "enable|disable")                             \
21742 _(get_first_msg_id, "client <name>")                                    \
21743 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
21744 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
21745   "fib-id <nn> [ip4][ip6][default]")                                    \
21746 _(get_node_graph, " ")                                                  \
21747 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
21748 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
21749 _(ioam_disable, "")                                                     \
21750 _(one_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
21751                             " sw_if_index <sw_if_index> p <priority> "  \
21752                             "w <weight>] [del]")                        \
21753 _(one_add_del_locator, "locator-set <locator_name> "                    \
21754                         "iface <intf> | sw_if_index <sw_if_index> "     \
21755                         "p <priority> w <weight> [del]")                \
21756 _(one_add_del_local_eid,"vni <vni> eid "                                \
21757                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
21758                          "locator-set <locator_name> [del]"             \
21759                          "[key-id sha1|sha256 secret-key <secret-key>]")\
21760 _(one_add_del_map_resolver, "<ip4|6-addr> [del]")                       \
21761 _(one_add_del_map_server, "<ip4|6-addr> [del]")                         \
21762 _(one_enable_disable, "enable|disable")                                 \
21763 _(one_map_register_enable_disable, "enable|disable")                    \
21764 _(one_map_register_fallback_threshold, "<value>")                       \
21765 _(one_rloc_probe_enable_disable, "enable|disable")                      \
21766 _(one_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "       \
21767                                "[seid <seid>] "                         \
21768                                "rloc <locator> p <prio> "               \
21769                                "w <weight> [rloc <loc> ... ] "          \
21770                                "action <action> [del-all]")             \
21771 _(one_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "    \
21772                           "<local-eid>")                                \
21773 _(one_pitr_set_locator_set, "locator-set <loc-set-name> | del")         \
21774 _(one_use_petr, "ip-address> | disable")                                \
21775 _(one_map_request_mode, "src-dst|dst-only")                             \
21776 _(one_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")            \
21777 _(one_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")               \
21778 _(one_locator_set_dump, "[local | remote]")                             \
21779 _(one_locator_dump, "ls_index <index> | ls_name <name>")                \
21780 _(one_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "       \
21781                        "[local] | [remote]")                            \
21782 _(one_add_del_ndp_entry, "[del] mac <mac> bd <bd> ip6 <ip6>")           \
21783 _(one_ndp_bd_get, "")                                                   \
21784 _(one_ndp_entries_get, "bd <bridge-domain>")                            \
21785 _(one_add_del_l2_arp_entry, "[del] mac <mac> bd <bd> ip4 <ip4>")        \
21786 _(one_l2_arp_bd_get, "")                                                \
21787 _(one_l2_arp_entries_get, "bd <bridge-domain>")                         \
21788 _(one_stats_enable_disable, "enable|disable")                           \
21789 _(show_one_stats_enable_disable, "")                                    \
21790 _(one_eid_table_vni_dump, "")                                           \
21791 _(one_eid_table_map_dump, "l2|l3")                                      \
21792 _(one_map_resolver_dump, "")                                            \
21793 _(one_map_server_dump, "")                                              \
21794 _(one_adjacencies_get, "vni <vni>")                                     \
21795 _(one_nsh_set_locator_set, "[del] ls <locator-set-name>")               \
21796 _(show_one_rloc_probe_state, "")                                        \
21797 _(show_one_map_register_state, "")                                      \
21798 _(show_one_status, "")                                                  \
21799 _(one_stats_dump, "")                                                   \
21800 _(one_stats_flush, "")                                                  \
21801 _(one_get_map_request_itr_rlocs, "")                                    \
21802 _(one_map_register_set_ttl, "<ttl>")                                    \
21803 _(one_set_transport_protocol, "udp|api")                                \
21804 _(one_get_transport_protocol, "")                                       \
21805 _(one_enable_disable_xtr_mode, "enable|disable")                        \
21806 _(one_show_xtr_mode, "")                                                \
21807 _(one_enable_disable_pitr_mode, "enable|disable")                       \
21808 _(one_show_pitr_mode, "")                                               \
21809 _(one_enable_disable_petr_mode, "enable|disable")                       \
21810 _(one_show_petr_mode, "")                                               \
21811 _(show_one_nsh_mapping, "")                                             \
21812 _(show_one_pitr, "")                                                    \
21813 _(show_one_use_petr, "")                                                \
21814 _(show_one_map_request_mode, "")                                        \
21815 _(show_one_map_register_ttl, "")                                        \
21816 _(show_one_map_register_fallback_threshold, "")                         \
21817 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
21818                             " sw_if_index <sw_if_index> p <priority> "  \
21819                             "w <weight>] [del]")                        \
21820 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
21821                         "iface <intf> | sw_if_index <sw_if_index> "     \
21822                         "p <priority> w <weight> [del]")                \
21823 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
21824                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
21825                          "locator-set <locator_name> [del]"             \
21826                          "[key-id sha1|sha256 secret-key <secret-key>]") \
21827 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
21828 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
21829 _(lisp_enable_disable, "enable|disable")                                \
21830 _(lisp_map_register_enable_disable, "enable|disable")                   \
21831 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
21832 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
21833                                "[seid <seid>] "                         \
21834                                "rloc <locator> p <prio> "               \
21835                                "w <weight> [rloc <loc> ... ] "          \
21836                                "action <action> [del-all]")             \
21837 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
21838                           "<local-eid>")                                \
21839 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
21840 _(lisp_use_petr, "<ip-address> | disable")                              \
21841 _(lisp_map_request_mode, "src-dst|dst-only")                            \
21842 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
21843 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
21844 _(lisp_locator_set_dump, "[local | remote]")                            \
21845 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
21846 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
21847                        "[local] | [remote]")                            \
21848 _(lisp_eid_table_vni_dump, "")                                          \
21849 _(lisp_eid_table_map_dump, "l2|l3")                                     \
21850 _(lisp_map_resolver_dump, "")                                           \
21851 _(lisp_map_server_dump, "")                                             \
21852 _(lisp_adjacencies_get, "vni <vni>")                                    \
21853 _(gpe_fwd_entry_vnis_get, "")                                           \
21854 _(gpe_native_fwd_rpaths_get, "ip4 | ip6")                               \
21855 _(gpe_add_del_native_fwd_rpath, "[del] via <nh-ip-addr> [iface] "       \
21856                                 "[table <table-id>]")                   \
21857 _(lisp_gpe_fwd_entries_get, "vni <vni>")                                \
21858 _(lisp_gpe_fwd_entry_path_dump, "index <fwd_entry_index>")              \
21859 _(gpe_set_encap_mode, "lisp|vxlan")                                     \
21860 _(gpe_get_encap_mode, "")                                               \
21861 _(lisp_gpe_add_del_iface, "up|down")                                    \
21862 _(lisp_gpe_enable_disable, "enable|disable")                            \
21863 _(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>"       \
21864   "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
21865 _(show_lisp_rloc_probe_state, "")                                       \
21866 _(show_lisp_map_register_state, "")                                     \
21867 _(show_lisp_status, "")                                                 \
21868 _(lisp_get_map_request_itr_rlocs, "")                                   \
21869 _(show_lisp_pitr, "")                                                   \
21870 _(show_lisp_use_petr, "")                                               \
21871 _(show_lisp_map_request_mode, "")                                       \
21872 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
21873 _(af_packet_delete, "name <host interface name>")                       \
21874 _(af_packet_dump, "")                                                   \
21875 _(policer_add_del, "name <policer name> <params> [del]")                \
21876 _(policer_dump, "[name <policer name>]")                                \
21877 _(policer_classify_set_interface,                                       \
21878   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
21879   "  [l2-table <nn>] [del]")                                            \
21880 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
21881 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
21882     "[master|slave]")                                                   \
21883 _(netmap_delete, "name <interface name>")                               \
21884 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
21885 _(mpls_table_dump, "")                                                  \
21886 _(mpls_route_dump, "table-id <ID>")                                     \
21887 _(classify_table_ids, "")                                               \
21888 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
21889 _(classify_table_info, "table_id <nn>")                                 \
21890 _(classify_session_dump, "table_id <nn>")                               \
21891 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
21892     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
21893     "[template_interval <nn>] [udp_checksum]")                          \
21894 _(ipfix_exporter_dump, "")                                              \
21895 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
21896 _(ipfix_classify_stream_dump, "")                                       \
21897 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
21898 _(ipfix_classify_table_dump, "")                                        \
21899 _(sw_interface_span_enable_disable, "[l2] [src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
21900 _(sw_interface_span_dump, "[l2]")                                           \
21901 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
21902 _(pg_create_interface, "if_id <nn> [gso-enabled gso-size <size>]")      \
21903 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
21904 _(pg_enable_disable, "[stream <id>] disable")                           \
21905 _(ip_source_and_port_range_check_add_del,                               \
21906   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
21907 _(ip_source_and_port_range_check_interface_add_del,                     \
21908   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
21909   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
21910 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
21911 _(l2_interface_pbb_tag_rewrite,                                         \
21912   "<intfc> | sw_if_index <nn> \n"                                       \
21913   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
21914   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
21915 _(set_punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
21916 _(flow_classify_set_interface,                                          \
21917   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
21918 _(flow_classify_dump, "type [ip4|ip6]")                                 \
21919 _(ip_table_dump, "")                                                    \
21920 _(ip_route_dump, "table-id [ip4|ip6]")                                  \
21921 _(ip_mtable_dump, "")                                                   \
21922 _(ip_mroute_dump, "table-id [ip4|ip6]")                                 \
21923 _(feature_enable_disable, "arc_name <arc_name> "                        \
21924   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
21925 _(feature_gso_enable_disable, "<intfc> | sw_if_index <nn> "             \
21926   "[enable | disable] ")                                                \
21927 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
21928 "[disable]")                                                            \
21929 _(sw_interface_add_del_mac_address, "<intfc> | sw_if_index <nn> "       \
21930   "mac <mac-address> [del]")                                            \
21931 _(l2_xconnect_dump, "")                                                 \
21932 _(hw_interface_set_mtu, "<intfc> | hw_if_index <nn> mtu <nn>")        \
21933 _(ip_neighbor_dump, "[ip6] <intfc> | sw_if_index <nn>")                 \
21934 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")          \
21935 _(p2p_ethernet_add, "<intfc> | sw_if_index <nn> remote_mac <mac-address> sub_id <id>") \
21936 _(p2p_ethernet_del, "<intfc> | sw_if_index <nn> remote_mac <mac-address>") \
21937 _(lldp_config, "system-name <name> tx-hold <nn> tx-interval <nn>") \
21938 _(sw_interface_set_lldp, "<intfc> | sw_if_index <nn> [port-desc <description>]\n" \
21939   " [mgmt-ip4 <ip4>] [mgmt-ip6 <ip6>] [mgmt-oid <object id>] [disable]") \
21940 _(tcp_configure_src_addresses, "<ip4|6>first-<ip4|6>last [vrf <id>]")   \
21941 _(sock_init_shm, "size <nnn>")                                          \
21942 _(app_namespace_add_del, "[add] id <ns-id> secret <nn> sw_if_index <nn>")\
21943 _(session_rule_add_del, "[add|del] proto <tcp/udp> <lcl-ip>/<plen> "    \
21944   "<lcl-port> <rmt-ip>/<plen> <rmt-port> action <nn>")                  \
21945 _(session_rules_dump, "")                                               \
21946 _(ip_container_proxy_add_del, "[add|del] <address> <sw_if_index>")      \
21947 _(output_acl_set_interface,                                             \
21948   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
21949   "  [l2-table <nn>] [del]")                                            \
21950 _(qos_record_enable_disable, "<record-source> <intfc> | sw_if_index <id> [disable]")
21951
21952 /* List of command functions, CLI names map directly to functions */
21953 #define foreach_cli_function                                    \
21954 _(comment, "usage: comment <ignore-rest-of-line>")              \
21955 _(dump_interface_table, "usage: dump_interface_table")          \
21956 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
21957 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
21958 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
21959 _(dump_macro_table, "usage: dump_macro_table ")                 \
21960 _(dump_node_table, "usage: dump_node_table")                    \
21961 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
21962 _(elog_setup, "usage: elog_setup [nevents, default 128K]")      \
21963 _(elog_disable, "usage: elog_disable")                          \
21964 _(elog_enable, "usage: elog_enable")                            \
21965 _(elog_save, "usage: elog_save <filename>")                     \
21966 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
21967 _(echo, "usage: echo <message>")                                \
21968 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
21969 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
21970 _(help, "usage: help")                                          \
21971 _(q, "usage: quit")                                             \
21972 _(quit, "usage: quit")                                          \
21973 _(search_node_table, "usage: search_node_table <name>...")      \
21974 _(set, "usage: set <variable-name> <value>")                    \
21975 _(script, "usage: script <file-name>")                          \
21976 _(statseg, "usage: statseg")                                    \
21977 _(unset, "usage: unset <variable-name>")
21978
21979 #define _(N,n)                                  \
21980     static void vl_api_##n##_t_handler_uni      \
21981     (vl_api_##n##_t * mp)                       \
21982     {                                           \
21983         vat_main_t * vam = &vat_main;           \
21984         if (vam->json_output) {                 \
21985             vl_api_##n##_t_handler_json(mp);    \
21986         } else {                                \
21987             vl_api_##n##_t_handler(mp);         \
21988         }                                       \
21989     }
21990 foreach_vpe_api_reply_msg;
21991 #if VPP_API_TEST_BUILTIN == 0
21992 foreach_standalone_reply_msg;
21993 #endif
21994 #undef _
21995
21996 void
21997 vat_api_hookup (vat_main_t * vam)
21998 {
21999 #define _(N,n)                                                  \
22000     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
22001                            vl_api_##n##_t_handler_uni,          \
22002                            vl_noop_handler,                     \
22003                            vl_api_##n##_t_endian,               \
22004                            vl_api_##n##_t_print,                \
22005                            sizeof(vl_api_##n##_t), 1);
22006   foreach_vpe_api_reply_msg;
22007 #if VPP_API_TEST_BUILTIN == 0
22008   foreach_standalone_reply_msg;
22009 #endif
22010 #undef _
22011
22012 #if (VPP_API_TEST_BUILTIN==0)
22013   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
22014
22015   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
22016
22017   vam->function_by_name = hash_create_string (0, sizeof (uword));
22018
22019   vam->help_by_name = hash_create_string (0, sizeof (uword));
22020 #endif
22021
22022   /* API messages we can send */
22023 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
22024   foreach_vpe_api_msg;
22025 #undef _
22026
22027   /* Help strings */
22028 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
22029   foreach_vpe_api_msg;
22030 #undef _
22031
22032   /* CLI functions */
22033 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
22034   foreach_cli_function;
22035 #undef _
22036
22037   /* Help strings */
22038 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
22039   foreach_cli_function;
22040 #undef _
22041 }
22042
22043 #if VPP_API_TEST_BUILTIN
22044 static clib_error_t *
22045 vat_api_hookup_shim (vlib_main_t * vm)
22046 {
22047   vat_api_hookup (&vat_main);
22048   return 0;
22049 }
22050
22051 VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
22052 #endif
22053
22054 /*
22055  * fd.io coding-style-patch-verification: ON
22056  *
22057  * Local Variables:
22058  * eval: (c-set-style "gnu")
22059  * End:
22060  */