interface: callback to manage extra MAC addresses
[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_uint (node, "flags", mp->flags);
1033   vat_json_object_add_uint (node, "link_duplex", mp->link_duplex);
1034   vat_json_object_add_uint (node, "link_speed", mp->link_speed);
1035   vat_json_object_add_uint (node, "mtu", ntohs (mp->link_mtu));
1036   vat_json_object_add_uint (node, "sub_id", ntohl (mp->sub_id));
1037   vat_json_object_add_uint (node, "sub_number_of_tags",
1038                             mp->sub_number_of_tags);
1039   vat_json_object_add_uint (node, "sub_outer_vlan_id",
1040                             ntohs (mp->sub_outer_vlan_id));
1041   vat_json_object_add_uint (node, "sub_inner_vlan_id",
1042                             ntohs (mp->sub_inner_vlan_id));
1043   vat_json_object_add_uint (node, "sub_if_flags", ntohl (mp->sub_if_flags));
1044   vat_json_object_add_uint (node, "vtr_op", ntohl (mp->vtr_op));
1045   vat_json_object_add_uint (node, "vtr_push_dot1q",
1046                             ntohl (mp->vtr_push_dot1q));
1047   vat_json_object_add_uint (node, "vtr_tag1", ntohl (mp->vtr_tag1));
1048   vat_json_object_add_uint (node, "vtr_tag2", ntohl (mp->vtr_tag2));
1049   if (ntohl (mp->sub_if_flags) & SUB_IF_API_FLAG_DOT1AH)
1050     {
1051       vat_json_object_add_string_copy (node, "pbb_vtr_dmac",
1052                                        format (0, "%U",
1053                                                format_ethernet_address,
1054                                                &mp->b_dmac));
1055       vat_json_object_add_string_copy (node, "pbb_vtr_smac",
1056                                        format (0, "%U",
1057                                                format_ethernet_address,
1058                                                &mp->b_smac));
1059       vat_json_object_add_uint (node, "pbb_vtr_b_vlanid", mp->b_vlanid);
1060       vat_json_object_add_uint (node, "pbb_vtr_i_sid", mp->i_sid);
1061     }
1062 }
1063
1064 #if VPP_API_TEST_BUILTIN == 0
1065 static void vl_api_sw_interface_event_t_handler
1066   (vl_api_sw_interface_event_t * mp)
1067 {
1068   vat_main_t *vam = &vat_main;
1069   if (vam->interface_event_display)
1070     errmsg ("interface flags: sw_if_index %d %s %s",
1071             ntohl (mp->sw_if_index),
1072             ((ntohl (mp->flags)) & IF_STATUS_API_FLAG_ADMIN_UP) ?
1073             "admin-up" : "admin-down",
1074             ((ntohl (mp->flags)) & IF_STATUS_API_FLAG_LINK_UP) ?
1075             "link-up" : "link-down");
1076 }
1077 #endif
1078
1079 __clib_unused static void
1080 vl_api_sw_interface_event_t_handler_json (vl_api_sw_interface_event_t * mp)
1081 {
1082   /* JSON output not supported */
1083 }
1084
1085 static void
1086 vl_api_cli_reply_t_handler (vl_api_cli_reply_t * mp)
1087 {
1088   vat_main_t *vam = &vat_main;
1089   i32 retval = ntohl (mp->retval);
1090
1091   vam->retval = retval;
1092   vam->shmem_result = uword_to_pointer (mp->reply_in_shmem, u8 *);
1093   vam->result_ready = 1;
1094 }
1095
1096 static void
1097 vl_api_cli_reply_t_handler_json (vl_api_cli_reply_t * mp)
1098 {
1099   vat_main_t *vam = &vat_main;
1100   vat_json_node_t node;
1101   api_main_t *am = &api_main;
1102   void *oldheap;
1103   u8 *reply;
1104
1105   vat_json_init_object (&node);
1106   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1107   vat_json_object_add_uint (&node, "reply_in_shmem",
1108                             ntohl (mp->reply_in_shmem));
1109   /* Toss the shared-memory original... */
1110   pthread_mutex_lock (&am->vlib_rp->mutex);
1111   oldheap = svm_push_data_heap (am->vlib_rp);
1112
1113   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
1114   vec_free (reply);
1115
1116   svm_pop_heap (oldheap);
1117   pthread_mutex_unlock (&am->vlib_rp->mutex);
1118
1119   vat_json_print (vam->ofp, &node);
1120   vat_json_free (&node);
1121
1122   vam->retval = ntohl (mp->retval);
1123   vam->result_ready = 1;
1124 }
1125
1126 static void
1127 vl_api_cli_inband_reply_t_handler (vl_api_cli_inband_reply_t * mp)
1128 {
1129   vat_main_t *vam = &vat_main;
1130   i32 retval = ntohl (mp->retval);
1131   u32 length = vl_api_string_len (&mp->reply);
1132
1133   vec_reset_length (vam->cmd_reply);
1134
1135   vam->retval = retval;
1136   if (retval == 0)
1137     {
1138       vec_validate (vam->cmd_reply, length);
1139       clib_memcpy ((char *) (vam->cmd_reply),
1140                    vl_api_from_api_string (&mp->reply), length);
1141       vam->cmd_reply[length] = 0;
1142     }
1143   vam->result_ready = 1;
1144 }
1145
1146 static void
1147 vl_api_cli_inband_reply_t_handler_json (vl_api_cli_inband_reply_t * mp)
1148 {
1149   vat_main_t *vam = &vat_main;
1150   vat_json_node_t node;
1151
1152   vec_reset_length (vam->cmd_reply);
1153
1154   vat_json_init_object (&node);
1155   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1156   vat_json_object_add_string_copy (&node, "reply",
1157                                    vl_api_from_api_string (&mp->reply));
1158
1159   vat_json_print (vam->ofp, &node);
1160   vat_json_free (&node);
1161
1162   vam->retval = ntohl (mp->retval);
1163   vam->result_ready = 1;
1164 }
1165
1166 static void vl_api_classify_add_del_table_reply_t_handler
1167   (vl_api_classify_add_del_table_reply_t * mp)
1168 {
1169   vat_main_t *vam = &vat_main;
1170   i32 retval = ntohl (mp->retval);
1171   if (vam->async_mode)
1172     {
1173       vam->async_errors += (retval < 0);
1174     }
1175   else
1176     {
1177       vam->retval = retval;
1178       if (retval == 0 &&
1179           ((mp->new_table_index != 0xFFFFFFFF) ||
1180            (mp->skip_n_vectors != 0xFFFFFFFF) ||
1181            (mp->match_n_vectors != 0xFFFFFFFF)))
1182         /*
1183          * Note: this is just barely thread-safe, depends on
1184          * the main thread spinning waiting for an answer...
1185          */
1186         errmsg ("new index %d, skip_n_vectors %d, match_n_vectors %d",
1187                 ntohl (mp->new_table_index),
1188                 ntohl (mp->skip_n_vectors), ntohl (mp->match_n_vectors));
1189       vam->result_ready = 1;
1190     }
1191 }
1192
1193 static void vl_api_classify_add_del_table_reply_t_handler_json
1194   (vl_api_classify_add_del_table_reply_t * mp)
1195 {
1196   vat_main_t *vam = &vat_main;
1197   vat_json_node_t node;
1198
1199   vat_json_init_object (&node);
1200   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1201   vat_json_object_add_uint (&node, "new_table_index",
1202                             ntohl (mp->new_table_index));
1203   vat_json_object_add_uint (&node, "skip_n_vectors",
1204                             ntohl (mp->skip_n_vectors));
1205   vat_json_object_add_uint (&node, "match_n_vectors",
1206                             ntohl (mp->match_n_vectors));
1207
1208   vat_json_print (vam->ofp, &node);
1209   vat_json_free (&node);
1210
1211   vam->retval = ntohl (mp->retval);
1212   vam->result_ready = 1;
1213 }
1214
1215 static void vl_api_get_node_index_reply_t_handler
1216   (vl_api_get_node_index_reply_t * mp)
1217 {
1218   vat_main_t *vam = &vat_main;
1219   i32 retval = ntohl (mp->retval);
1220   if (vam->async_mode)
1221     {
1222       vam->async_errors += (retval < 0);
1223     }
1224   else
1225     {
1226       vam->retval = retval;
1227       if (retval == 0)
1228         errmsg ("node index %d", ntohl (mp->node_index));
1229       vam->result_ready = 1;
1230     }
1231 }
1232
1233 static void vl_api_get_node_index_reply_t_handler_json
1234   (vl_api_get_node_index_reply_t * mp)
1235 {
1236   vat_main_t *vam = &vat_main;
1237   vat_json_node_t node;
1238
1239   vat_json_init_object (&node);
1240   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1241   vat_json_object_add_uint (&node, "node_index", ntohl (mp->node_index));
1242
1243   vat_json_print (vam->ofp, &node);
1244   vat_json_free (&node);
1245
1246   vam->retval = ntohl (mp->retval);
1247   vam->result_ready = 1;
1248 }
1249
1250 static void vl_api_get_next_index_reply_t_handler
1251   (vl_api_get_next_index_reply_t * mp)
1252 {
1253   vat_main_t *vam = &vat_main;
1254   i32 retval = ntohl (mp->retval);
1255   if (vam->async_mode)
1256     {
1257       vam->async_errors += (retval < 0);
1258     }
1259   else
1260     {
1261       vam->retval = retval;
1262       if (retval == 0)
1263         errmsg ("next node index %d", ntohl (mp->next_index));
1264       vam->result_ready = 1;
1265     }
1266 }
1267
1268 static void vl_api_get_next_index_reply_t_handler_json
1269   (vl_api_get_next_index_reply_t * mp)
1270 {
1271   vat_main_t *vam = &vat_main;
1272   vat_json_node_t node;
1273
1274   vat_json_init_object (&node);
1275   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1276   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1277
1278   vat_json_print (vam->ofp, &node);
1279   vat_json_free (&node);
1280
1281   vam->retval = ntohl (mp->retval);
1282   vam->result_ready = 1;
1283 }
1284
1285 static void vl_api_add_node_next_reply_t_handler
1286   (vl_api_add_node_next_reply_t * mp)
1287 {
1288   vat_main_t *vam = &vat_main;
1289   i32 retval = ntohl (mp->retval);
1290   if (vam->async_mode)
1291     {
1292       vam->async_errors += (retval < 0);
1293     }
1294   else
1295     {
1296       vam->retval = retval;
1297       if (retval == 0)
1298         errmsg ("next index %d", ntohl (mp->next_index));
1299       vam->result_ready = 1;
1300     }
1301 }
1302
1303 static void vl_api_add_node_next_reply_t_handler_json
1304   (vl_api_add_node_next_reply_t * mp)
1305 {
1306   vat_main_t *vam = &vat_main;
1307   vat_json_node_t node;
1308
1309   vat_json_init_object (&node);
1310   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1311   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1312
1313   vat_json_print (vam->ofp, &node);
1314   vat_json_free (&node);
1315
1316   vam->retval = ntohl (mp->retval);
1317   vam->result_ready = 1;
1318 }
1319
1320 static void vl_api_show_version_reply_t_handler
1321   (vl_api_show_version_reply_t * mp)
1322 {
1323   vat_main_t *vam = &vat_main;
1324   i32 retval = ntohl (mp->retval);
1325
1326   if (retval >= 0)
1327     {
1328       errmsg ("        program: %s", mp->program);
1329       errmsg ("        version: %s", mp->version);
1330       errmsg ("     build date: %s", mp->build_date);
1331       errmsg ("build directory: %s", mp->build_directory);
1332     }
1333   vam->retval = retval;
1334   vam->result_ready = 1;
1335 }
1336
1337 static void vl_api_show_version_reply_t_handler_json
1338   (vl_api_show_version_reply_t * mp)
1339 {
1340   vat_main_t *vam = &vat_main;
1341   vat_json_node_t node;
1342
1343   vat_json_init_object (&node);
1344   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1345   vat_json_object_add_string_copy (&node, "program", mp->program);
1346   vat_json_object_add_string_copy (&node, "version", mp->version);
1347   vat_json_object_add_string_copy (&node, "build_date", mp->build_date);
1348   vat_json_object_add_string_copy (&node, "build_directory",
1349                                    mp->build_directory);
1350
1351   vat_json_print (vam->ofp, &node);
1352   vat_json_free (&node);
1353
1354   vam->retval = ntohl (mp->retval);
1355   vam->result_ready = 1;
1356 }
1357
1358 static void vl_api_show_threads_reply_t_handler
1359   (vl_api_show_threads_reply_t * mp)
1360 {
1361   vat_main_t *vam = &vat_main;
1362   i32 retval = ntohl (mp->retval);
1363   int i, count = 0;
1364
1365   if (retval >= 0)
1366     count = ntohl (mp->count);
1367
1368   for (i = 0; i < count; i++)
1369     print (vam->ofp,
1370            "\n%-2d %-11s %-11s %-5d %-6d %-4d %-6d",
1371            ntohl (mp->thread_data[i].id), mp->thread_data[i].name,
1372            mp->thread_data[i].type, ntohl (mp->thread_data[i].pid),
1373            ntohl (mp->thread_data[i].cpu_id), ntohl (mp->thread_data[i].core),
1374            ntohl (mp->thread_data[i].cpu_socket));
1375
1376   vam->retval = retval;
1377   vam->result_ready = 1;
1378 }
1379
1380 static void vl_api_show_threads_reply_t_handler_json
1381   (vl_api_show_threads_reply_t * mp)
1382 {
1383   vat_main_t *vam = &vat_main;
1384   vat_json_node_t node;
1385   vl_api_thread_data_t *td;
1386   i32 retval = ntohl (mp->retval);
1387   int i, count = 0;
1388
1389   if (retval >= 0)
1390     count = ntohl (mp->count);
1391
1392   vat_json_init_object (&node);
1393   vat_json_object_add_int (&node, "retval", retval);
1394   vat_json_object_add_uint (&node, "count", count);
1395
1396   for (i = 0; i < count; i++)
1397     {
1398       td = &mp->thread_data[i];
1399       vat_json_object_add_uint (&node, "id", ntohl (td->id));
1400       vat_json_object_add_string_copy (&node, "name", td->name);
1401       vat_json_object_add_string_copy (&node, "type", td->type);
1402       vat_json_object_add_uint (&node, "pid", ntohl (td->pid));
1403       vat_json_object_add_int (&node, "cpu_id", ntohl (td->cpu_id));
1404       vat_json_object_add_int (&node, "core", ntohl (td->id));
1405       vat_json_object_add_int (&node, "cpu_socket", ntohl (td->cpu_socket));
1406     }
1407
1408   vat_json_print (vam->ofp, &node);
1409   vat_json_free (&node);
1410
1411   vam->retval = retval;
1412   vam->result_ready = 1;
1413 }
1414
1415 static int
1416 api_show_threads (vat_main_t * vam)
1417 {
1418   vl_api_show_threads_t *mp;
1419   int ret;
1420
1421   print (vam->ofp,
1422          "\n%-2s %-11s %-11s %-5s %-6s %-4s %-6s",
1423          "ID", "Name", "Type", "LWP", "cpu_id", "Core", "Socket");
1424
1425   M (SHOW_THREADS, mp);
1426
1427   S (mp);
1428   W (ret);
1429   return ret;
1430 }
1431
1432 static void
1433 vl_api_ip4_arp_event_t_handler (vl_api_ip4_arp_event_t * mp)
1434 {
1435   u32 sw_if_index = ntohl (mp->sw_if_index);
1436   errmsg ("arp %s event: pid %d address %U new mac %U sw_if_index %d\n",
1437           mp->mac_ip ? "mac/ip binding" : "address resolution",
1438           ntohl (mp->pid), format_ip4_address, mp->ip,
1439           format_vl_api_mac_address, &mp->mac, sw_if_index);
1440 }
1441
1442 static void
1443 vl_api_ip4_arp_event_t_handler_json (vl_api_ip4_arp_event_t * mp)
1444 {
1445   /* JSON output not supported */
1446 }
1447
1448 static void
1449 vl_api_ip6_nd_event_t_handler (vl_api_ip6_nd_event_t * mp)
1450 {
1451   u32 sw_if_index = ntohl (mp->sw_if_index);
1452   errmsg ("ip6 nd %s event: pid %d address %U new mac %U sw_if_index %d\n",
1453           mp->mac_ip ? "mac/ip binding" : "address resolution",
1454           ntohl (mp->pid), format_vl_api_ip6_address, mp->ip,
1455           format_vl_api_mac_address, mp->mac, sw_if_index);
1456 }
1457
1458 static void
1459 vl_api_ip6_nd_event_t_handler_json (vl_api_ip6_nd_event_t * mp)
1460 {
1461   /* JSON output not supported */
1462 }
1463
1464 static void
1465 vl_api_l2_macs_event_t_handler (vl_api_l2_macs_event_t * mp)
1466 {
1467   u32 n_macs = ntohl (mp->n_macs);
1468   errmsg ("L2MAC event received with pid %d cl-idx %d for %d macs: \n",
1469           ntohl (mp->pid), mp->client_index, n_macs);
1470   int i;
1471   for (i = 0; i < n_macs; i++)
1472     {
1473       vl_api_mac_entry_t *mac = &mp->mac[i];
1474       errmsg (" [%d] sw_if_index %d  mac_addr %U  action %d \n",
1475               i + 1, ntohl (mac->sw_if_index),
1476               format_ethernet_address, mac->mac_addr, mac->action);
1477       if (i == 1000)
1478         break;
1479     }
1480 }
1481
1482 static void
1483 vl_api_l2_macs_event_t_handler_json (vl_api_l2_macs_event_t * mp)
1484 {
1485   /* JSON output not supported */
1486 }
1487
1488 #define vl_api_bridge_domain_details_t_endian vl_noop_handler
1489 #define vl_api_bridge_domain_details_t_print vl_noop_handler
1490
1491 /*
1492  * Special-case: build the bridge domain table, maintain
1493  * the next bd id vbl.
1494  */
1495 static void vl_api_bridge_domain_details_t_handler
1496   (vl_api_bridge_domain_details_t * mp)
1497 {
1498   vat_main_t *vam = &vat_main;
1499   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1500   int i;
1501
1502   print (vam->ofp, "\n%-3s %-3s %-3s %-3s %-3s %-6s %-3s",
1503          " ID", "LRN", "FWD", "FLD", "BVI", "UU-FWD", "#IF");
1504
1505   print (vam->ofp, "%3d %3d %3d %3d %3d %6d %3d",
1506          ntohl (mp->bd_id), mp->learn, mp->forward,
1507          mp->flood, ntohl (mp->bvi_sw_if_index),
1508          ntohl (mp->uu_fwd_sw_if_index), n_sw_ifs);
1509
1510   if (n_sw_ifs)
1511     {
1512       vl_api_bridge_domain_sw_if_t *sw_ifs;
1513       print (vam->ofp, "\n\n%s %s  %s", "sw_if_index", "SHG",
1514              "Interface Name");
1515
1516       sw_ifs = mp->sw_if_details;
1517       for (i = 0; i < n_sw_ifs; i++)
1518         {
1519           u8 *sw_if_name = 0;
1520           u32 sw_if_index;
1521           hash_pair_t *p;
1522
1523           sw_if_index = ntohl (sw_ifs->sw_if_index);
1524
1525           /* *INDENT-OFF* */
1526           hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
1527                              ({
1528                                if ((u32) p->value[0] == sw_if_index)
1529                                  {
1530                                    sw_if_name = (u8 *)(p->key);
1531                                    break;
1532                                  }
1533                              }));
1534           /* *INDENT-ON* */
1535           print (vam->ofp, "%7d     %3d  %s", sw_if_index,
1536                  sw_ifs->shg, sw_if_name ? (char *) sw_if_name :
1537                  "sw_if_index not found!");
1538
1539           sw_ifs++;
1540         }
1541     }
1542 }
1543
1544 static void vl_api_bridge_domain_details_t_handler_json
1545   (vl_api_bridge_domain_details_t * mp)
1546 {
1547   vat_main_t *vam = &vat_main;
1548   vat_json_node_t *node, *array = NULL;
1549   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1550
1551   if (VAT_JSON_ARRAY != vam->json_tree.type)
1552     {
1553       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1554       vat_json_init_array (&vam->json_tree);
1555     }
1556   node = vat_json_array_add (&vam->json_tree);
1557
1558   vat_json_init_object (node);
1559   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1560   vat_json_object_add_uint (node, "flood", mp->flood);
1561   vat_json_object_add_uint (node, "forward", mp->forward);
1562   vat_json_object_add_uint (node, "learn", mp->learn);
1563   vat_json_object_add_uint (node, "bvi_sw_if_index",
1564                             ntohl (mp->bvi_sw_if_index));
1565   vat_json_object_add_uint (node, "n_sw_ifs", n_sw_ifs);
1566   array = vat_json_object_add (node, "sw_if");
1567   vat_json_init_array (array);
1568
1569
1570
1571   if (n_sw_ifs)
1572     {
1573       vl_api_bridge_domain_sw_if_t *sw_ifs;
1574       int i;
1575
1576       sw_ifs = mp->sw_if_details;
1577       for (i = 0; i < n_sw_ifs; i++)
1578         {
1579           node = vat_json_array_add (array);
1580           vat_json_init_object (node);
1581           vat_json_object_add_uint (node, "sw_if_index",
1582                                     ntohl (sw_ifs->sw_if_index));
1583           vat_json_object_add_uint (node, "shg", sw_ifs->shg);
1584           sw_ifs++;
1585         }
1586     }
1587 }
1588
1589 static void vl_api_control_ping_reply_t_handler
1590   (vl_api_control_ping_reply_t * mp)
1591 {
1592   vat_main_t *vam = &vat_main;
1593   i32 retval = ntohl (mp->retval);
1594   if (vam->async_mode)
1595     {
1596       vam->async_errors += (retval < 0);
1597     }
1598   else
1599     {
1600       vam->retval = retval;
1601       vam->result_ready = 1;
1602     }
1603   if (vam->socket_client_main)
1604     vam->socket_client_main->control_pings_outstanding--;
1605 }
1606
1607 static void vl_api_control_ping_reply_t_handler_json
1608   (vl_api_control_ping_reply_t * mp)
1609 {
1610   vat_main_t *vam = &vat_main;
1611   i32 retval = ntohl (mp->retval);
1612
1613   if (VAT_JSON_NONE != vam->json_tree.type)
1614     {
1615       vat_json_print (vam->ofp, &vam->json_tree);
1616       vat_json_free (&vam->json_tree);
1617       vam->json_tree.type = VAT_JSON_NONE;
1618     }
1619   else
1620     {
1621       /* just print [] */
1622       vat_json_init_array (&vam->json_tree);
1623       vat_json_print (vam->ofp, &vam->json_tree);
1624       vam->json_tree.type = VAT_JSON_NONE;
1625     }
1626
1627   vam->retval = retval;
1628   vam->result_ready = 1;
1629 }
1630
1631 static void
1632   vl_api_bridge_domain_set_mac_age_reply_t_handler
1633   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1634 {
1635   vat_main_t *vam = &vat_main;
1636   i32 retval = ntohl (mp->retval);
1637   if (vam->async_mode)
1638     {
1639       vam->async_errors += (retval < 0);
1640     }
1641   else
1642     {
1643       vam->retval = retval;
1644       vam->result_ready = 1;
1645     }
1646 }
1647
1648 static void vl_api_bridge_domain_set_mac_age_reply_t_handler_json
1649   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1650 {
1651   vat_main_t *vam = &vat_main;
1652   vat_json_node_t node;
1653
1654   vat_json_init_object (&node);
1655   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1656
1657   vat_json_print (vam->ofp, &node);
1658   vat_json_free (&node);
1659
1660   vam->retval = ntohl (mp->retval);
1661   vam->result_ready = 1;
1662 }
1663
1664 static void
1665 vl_api_l2_flags_reply_t_handler (vl_api_l2_flags_reply_t * mp)
1666 {
1667   vat_main_t *vam = &vat_main;
1668   i32 retval = ntohl (mp->retval);
1669   if (vam->async_mode)
1670     {
1671       vam->async_errors += (retval < 0);
1672     }
1673   else
1674     {
1675       vam->retval = retval;
1676       vam->result_ready = 1;
1677     }
1678 }
1679
1680 static void vl_api_l2_flags_reply_t_handler_json
1681   (vl_api_l2_flags_reply_t * mp)
1682 {
1683   vat_main_t *vam = &vat_main;
1684   vat_json_node_t node;
1685
1686   vat_json_init_object (&node);
1687   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1688   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1689                             ntohl (mp->resulting_feature_bitmap));
1690
1691   vat_json_print (vam->ofp, &node);
1692   vat_json_free (&node);
1693
1694   vam->retval = ntohl (mp->retval);
1695   vam->result_ready = 1;
1696 }
1697
1698 static void vl_api_bridge_flags_reply_t_handler
1699   (vl_api_bridge_flags_reply_t * mp)
1700 {
1701   vat_main_t *vam = &vat_main;
1702   i32 retval = ntohl (mp->retval);
1703   if (vam->async_mode)
1704     {
1705       vam->async_errors += (retval < 0);
1706     }
1707   else
1708     {
1709       vam->retval = retval;
1710       vam->result_ready = 1;
1711     }
1712 }
1713
1714 static void vl_api_bridge_flags_reply_t_handler_json
1715   (vl_api_bridge_flags_reply_t * mp)
1716 {
1717   vat_main_t *vam = &vat_main;
1718   vat_json_node_t node;
1719
1720   vat_json_init_object (&node);
1721   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1722   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1723                             ntohl (mp->resulting_feature_bitmap));
1724
1725   vat_json_print (vam->ofp, &node);
1726   vat_json_free (&node);
1727
1728   vam->retval = ntohl (mp->retval);
1729   vam->result_ready = 1;
1730 }
1731
1732 static void
1733 vl_api_tap_create_v2_reply_t_handler (vl_api_tap_create_v2_reply_t * mp)
1734 {
1735   vat_main_t *vam = &vat_main;
1736   i32 retval = ntohl (mp->retval);
1737   if (vam->async_mode)
1738     {
1739       vam->async_errors += (retval < 0);
1740     }
1741   else
1742     {
1743       vam->retval = retval;
1744       vam->sw_if_index = ntohl (mp->sw_if_index);
1745       vam->result_ready = 1;
1746     }
1747
1748 }
1749
1750 static void vl_api_tap_create_v2_reply_t_handler_json
1751   (vl_api_tap_create_v2_reply_t * mp)
1752 {
1753   vat_main_t *vam = &vat_main;
1754   vat_json_node_t node;
1755
1756   vat_json_init_object (&node);
1757   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1758   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1759
1760   vat_json_print (vam->ofp, &node);
1761   vat_json_free (&node);
1762
1763   vam->retval = ntohl (mp->retval);
1764   vam->result_ready = 1;
1765
1766 }
1767
1768 static void
1769 vl_api_tap_delete_v2_reply_t_handler (vl_api_tap_delete_v2_reply_t * mp)
1770 {
1771   vat_main_t *vam = &vat_main;
1772   i32 retval = ntohl (mp->retval);
1773   if (vam->async_mode)
1774     {
1775       vam->async_errors += (retval < 0);
1776     }
1777   else
1778     {
1779       vam->retval = retval;
1780       vam->result_ready = 1;
1781     }
1782 }
1783
1784 static void vl_api_tap_delete_v2_reply_t_handler_json
1785   (vl_api_tap_delete_v2_reply_t * mp)
1786 {
1787   vat_main_t *vam = &vat_main;
1788   vat_json_node_t node;
1789
1790   vat_json_init_object (&node);
1791   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1792
1793   vat_json_print (vam->ofp, &node);
1794   vat_json_free (&node);
1795
1796   vam->retval = ntohl (mp->retval);
1797   vam->result_ready = 1;
1798 }
1799
1800 static void
1801 vl_api_virtio_pci_create_reply_t_handler (vl_api_virtio_pci_create_reply_t *
1802                                           mp)
1803 {
1804   vat_main_t *vam = &vat_main;
1805   i32 retval = ntohl (mp->retval);
1806   if (vam->async_mode)
1807     {
1808       vam->async_errors += (retval < 0);
1809     }
1810   else
1811     {
1812       vam->retval = retval;
1813       vam->sw_if_index = ntohl (mp->sw_if_index);
1814       vam->result_ready = 1;
1815     }
1816 }
1817
1818 static void vl_api_virtio_pci_create_reply_t_handler_json
1819   (vl_api_virtio_pci_create_reply_t * mp)
1820 {
1821   vat_main_t *vam = &vat_main;
1822   vat_json_node_t node;
1823
1824   vat_json_init_object (&node);
1825   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1826   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1827
1828   vat_json_print (vam->ofp, &node);
1829   vat_json_free (&node);
1830
1831   vam->retval = ntohl (mp->retval);
1832   vam->result_ready = 1;
1833
1834 }
1835
1836 static void
1837 vl_api_virtio_pci_delete_reply_t_handler (vl_api_virtio_pci_delete_reply_t *
1838                                           mp)
1839 {
1840   vat_main_t *vam = &vat_main;
1841   i32 retval = ntohl (mp->retval);
1842   if (vam->async_mode)
1843     {
1844       vam->async_errors += (retval < 0);
1845     }
1846   else
1847     {
1848       vam->retval = retval;
1849       vam->result_ready = 1;
1850     }
1851 }
1852
1853 static void vl_api_virtio_pci_delete_reply_t_handler_json
1854   (vl_api_virtio_pci_delete_reply_t * mp)
1855 {
1856   vat_main_t *vam = &vat_main;
1857   vat_json_node_t node;
1858
1859   vat_json_init_object (&node);
1860   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1861
1862   vat_json_print (vam->ofp, &node);
1863   vat_json_free (&node);
1864
1865   vam->retval = ntohl (mp->retval);
1866   vam->result_ready = 1;
1867 }
1868
1869 static void
1870 vl_api_bond_create_reply_t_handler (vl_api_bond_create_reply_t * mp)
1871 {
1872   vat_main_t *vam = &vat_main;
1873   i32 retval = ntohl (mp->retval);
1874
1875   if (vam->async_mode)
1876     {
1877       vam->async_errors += (retval < 0);
1878     }
1879   else
1880     {
1881       vam->retval = retval;
1882       vam->sw_if_index = ntohl (mp->sw_if_index);
1883       vam->result_ready = 1;
1884     }
1885 }
1886
1887 static void vl_api_bond_create_reply_t_handler_json
1888   (vl_api_bond_create_reply_t * mp)
1889 {
1890   vat_main_t *vam = &vat_main;
1891   vat_json_node_t node;
1892
1893   vat_json_init_object (&node);
1894   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1895   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1896
1897   vat_json_print (vam->ofp, &node);
1898   vat_json_free (&node);
1899
1900   vam->retval = ntohl (mp->retval);
1901   vam->result_ready = 1;
1902 }
1903
1904 static void
1905 vl_api_bond_delete_reply_t_handler (vl_api_bond_delete_reply_t * mp)
1906 {
1907   vat_main_t *vam = &vat_main;
1908   i32 retval = ntohl (mp->retval);
1909
1910   if (vam->async_mode)
1911     {
1912       vam->async_errors += (retval < 0);
1913     }
1914   else
1915     {
1916       vam->retval = retval;
1917       vam->result_ready = 1;
1918     }
1919 }
1920
1921 static void vl_api_bond_delete_reply_t_handler_json
1922   (vl_api_bond_delete_reply_t * mp)
1923 {
1924   vat_main_t *vam = &vat_main;
1925   vat_json_node_t node;
1926
1927   vat_json_init_object (&node);
1928   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1929
1930   vat_json_print (vam->ofp, &node);
1931   vat_json_free (&node);
1932
1933   vam->retval = ntohl (mp->retval);
1934   vam->result_ready = 1;
1935 }
1936
1937 static void
1938 vl_api_bond_enslave_reply_t_handler (vl_api_bond_enslave_reply_t * mp)
1939 {
1940   vat_main_t *vam = &vat_main;
1941   i32 retval = ntohl (mp->retval);
1942
1943   if (vam->async_mode)
1944     {
1945       vam->async_errors += (retval < 0);
1946     }
1947   else
1948     {
1949       vam->retval = retval;
1950       vam->result_ready = 1;
1951     }
1952 }
1953
1954 static void vl_api_bond_enslave_reply_t_handler_json
1955   (vl_api_bond_enslave_reply_t * mp)
1956 {
1957   vat_main_t *vam = &vat_main;
1958   vat_json_node_t node;
1959
1960   vat_json_init_object (&node);
1961   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1962
1963   vat_json_print (vam->ofp, &node);
1964   vat_json_free (&node);
1965
1966   vam->retval = ntohl (mp->retval);
1967   vam->result_ready = 1;
1968 }
1969
1970 static void
1971 vl_api_bond_detach_slave_reply_t_handler (vl_api_bond_detach_slave_reply_t *
1972                                           mp)
1973 {
1974   vat_main_t *vam = &vat_main;
1975   i32 retval = ntohl (mp->retval);
1976
1977   if (vam->async_mode)
1978     {
1979       vam->async_errors += (retval < 0);
1980     }
1981   else
1982     {
1983       vam->retval = retval;
1984       vam->result_ready = 1;
1985     }
1986 }
1987
1988 static void vl_api_bond_detach_slave_reply_t_handler_json
1989   (vl_api_bond_detach_slave_reply_t * mp)
1990 {
1991   vat_main_t *vam = &vat_main;
1992   vat_json_node_t node;
1993
1994   vat_json_init_object (&node);
1995   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1996
1997   vat_json_print (vam->ofp, &node);
1998   vat_json_free (&node);
1999
2000   vam->retval = ntohl (mp->retval);
2001   vam->result_ready = 1;
2002 }
2003
2004 static int
2005 api_sw_interface_set_bond_weight (vat_main_t * vam)
2006 {
2007   unformat_input_t *i = vam->input;
2008   vl_api_sw_interface_set_bond_weight_t *mp;
2009   u32 sw_if_index = ~0;
2010   u32 weight = 0;
2011   u8 weight_enter = 0;
2012   int ret;
2013
2014   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2015     {
2016       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
2017         ;
2018       else if (unformat (i, "sw_if_index %d", &sw_if_index))
2019         ;
2020       else if (unformat (i, "weight %u", &weight))
2021         weight_enter = 1;
2022       else
2023         break;
2024     }
2025
2026   if (sw_if_index == ~0)
2027     {
2028       errmsg ("missing interface name or sw_if_index");
2029       return -99;
2030     }
2031   if (weight_enter == 0)
2032     {
2033       errmsg ("missing valid weight");
2034       return -99;
2035     }
2036
2037   /* Construct the API message */
2038   M (SW_INTERFACE_SET_BOND_WEIGHT, mp);
2039   mp->sw_if_index = ntohl (sw_if_index);
2040   mp->weight = ntohl (weight);
2041
2042   S (mp);
2043   W (ret);
2044   return ret;
2045 }
2046
2047 static void vl_api_sw_interface_bond_details_t_handler
2048   (vl_api_sw_interface_bond_details_t * mp)
2049 {
2050   vat_main_t *vam = &vat_main;
2051
2052   print (vam->ofp,
2053          "%-16s %-12d %-12U %-13U %-14u %-14u",
2054          mp->interface_name, ntohl (mp->sw_if_index),
2055          format_bond_mode, ntohl (mp->mode), format_bond_load_balance,
2056          ntohl (mp->lb), ntohl (mp->active_slaves), ntohl (mp->slaves));
2057 }
2058
2059 static void vl_api_sw_interface_bond_details_t_handler_json
2060   (vl_api_sw_interface_bond_details_t * mp)
2061 {
2062   vat_main_t *vam = &vat_main;
2063   vat_json_node_t *node = NULL;
2064
2065   if (VAT_JSON_ARRAY != vam->json_tree.type)
2066     {
2067       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2068       vat_json_init_array (&vam->json_tree);
2069     }
2070   node = vat_json_array_add (&vam->json_tree);
2071
2072   vat_json_init_object (node);
2073   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
2074   vat_json_object_add_string_copy (node, "interface_name",
2075                                    mp->interface_name);
2076   vat_json_object_add_uint (node, "mode", ntohl (mp->mode));
2077   vat_json_object_add_uint (node, "load_balance", ntohl (mp->lb));
2078   vat_json_object_add_uint (node, "active_slaves", ntohl (mp->active_slaves));
2079   vat_json_object_add_uint (node, "slaves", ntohl (mp->slaves));
2080 }
2081
2082 static int
2083 api_sw_interface_bond_dump (vat_main_t * vam)
2084 {
2085   vl_api_sw_interface_bond_dump_t *mp;
2086   vl_api_control_ping_t *mp_ping;
2087   int ret;
2088
2089   print (vam->ofp,
2090          "\n%-16s %-12s %-12s %-13s %-14s %-14s",
2091          "interface name", "sw_if_index", "mode", "load balance",
2092          "active slaves", "slaves");
2093
2094   /* Get list of bond interfaces */
2095   M (SW_INTERFACE_BOND_DUMP, mp);
2096   S (mp);
2097
2098   /* Use a control ping for synchronization */
2099   MPING (CONTROL_PING, mp_ping);
2100   S (mp_ping);
2101
2102   W (ret);
2103   return ret;
2104 }
2105
2106 static void vl_api_sw_interface_slave_details_t_handler
2107   (vl_api_sw_interface_slave_details_t * mp)
2108 {
2109   vat_main_t *vam = &vat_main;
2110
2111   print (vam->ofp,
2112          "%-25s %-12d %-7d %-12d %-10d %-10d", mp->interface_name,
2113          ntohl (mp->sw_if_index), mp->is_passive, mp->is_long_timeout,
2114          ntohl (mp->weight), mp->is_local_numa);
2115 }
2116
2117 static void vl_api_sw_interface_slave_details_t_handler_json
2118   (vl_api_sw_interface_slave_details_t * mp)
2119 {
2120   vat_main_t *vam = &vat_main;
2121   vat_json_node_t *node = NULL;
2122
2123   if (VAT_JSON_ARRAY != vam->json_tree.type)
2124     {
2125       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2126       vat_json_init_array (&vam->json_tree);
2127     }
2128   node = vat_json_array_add (&vam->json_tree);
2129
2130   vat_json_init_object (node);
2131   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
2132   vat_json_object_add_string_copy (node, "interface_name",
2133                                    mp->interface_name);
2134   vat_json_object_add_uint (node, "passive", mp->is_passive);
2135   vat_json_object_add_uint (node, "long_timeout", mp->is_long_timeout);
2136   vat_json_object_add_uint (node, "weight", ntohl (mp->weight));
2137   vat_json_object_add_uint (node, "is_local_numa", mp->is_local_numa);
2138 }
2139
2140 static int
2141 api_sw_interface_slave_dump (vat_main_t * vam)
2142 {
2143   unformat_input_t *i = vam->input;
2144   vl_api_sw_interface_slave_dump_t *mp;
2145   vl_api_control_ping_t *mp_ping;
2146   u32 sw_if_index = ~0;
2147   u8 sw_if_index_set = 0;
2148   int ret;
2149
2150   /* Parse args required to build the message */
2151   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2152     {
2153       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
2154         sw_if_index_set = 1;
2155       else if (unformat (i, "sw_if_index %d", &sw_if_index))
2156         sw_if_index_set = 1;
2157       else
2158         break;
2159     }
2160
2161   if (sw_if_index_set == 0)
2162     {
2163       errmsg ("missing vpp interface name. ");
2164       return -99;
2165     }
2166
2167   print (vam->ofp,
2168          "\n%-25s %-12s %-7s %-12s %-10s %-10s",
2169          "slave interface name", "sw_if_index", "passive", "long_timeout",
2170          "weight", "local numa");
2171
2172   /* Get list of bond interfaces */
2173   M (SW_INTERFACE_SLAVE_DUMP, mp);
2174   mp->sw_if_index = ntohl (sw_if_index);
2175   S (mp);
2176
2177   /* Use a control ping for synchronization */
2178   MPING (CONTROL_PING, mp_ping);
2179   S (mp_ping);
2180
2181   W (ret);
2182   return ret;
2183 }
2184
2185 static void vl_api_mpls_tunnel_add_del_reply_t_handler
2186   (vl_api_mpls_tunnel_add_del_reply_t * mp)
2187 {
2188   vat_main_t *vam = &vat_main;
2189   i32 retval = ntohl (mp->retval);
2190   if (vam->async_mode)
2191     {
2192       vam->async_errors += (retval < 0);
2193     }
2194   else
2195     {
2196       vam->retval = retval;
2197       vam->sw_if_index = ntohl (mp->sw_if_index);
2198       vam->result_ready = 1;
2199     }
2200   vam->regenerate_interface_table = 1;
2201 }
2202
2203 static void vl_api_mpls_tunnel_add_del_reply_t_handler_json
2204   (vl_api_mpls_tunnel_add_del_reply_t * mp)
2205 {
2206   vat_main_t *vam = &vat_main;
2207   vat_json_node_t node;
2208
2209   vat_json_init_object (&node);
2210   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2211   vat_json_object_add_uint (&node, "tunnel_sw_if_index",
2212                             ntohl (mp->sw_if_index));
2213
2214   vat_json_print (vam->ofp, &node);
2215   vat_json_free (&node);
2216
2217   vam->retval = ntohl (mp->retval);
2218   vam->result_ready = 1;
2219 }
2220
2221 static void vl_api_l2tpv3_create_tunnel_reply_t_handler
2222   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
2223 {
2224   vat_main_t *vam = &vat_main;
2225   i32 retval = ntohl (mp->retval);
2226   if (vam->async_mode)
2227     {
2228       vam->async_errors += (retval < 0);
2229     }
2230   else
2231     {
2232       vam->retval = retval;
2233       vam->sw_if_index = ntohl (mp->sw_if_index);
2234       vam->result_ready = 1;
2235     }
2236 }
2237
2238 static void vl_api_l2tpv3_create_tunnel_reply_t_handler_json
2239   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
2240 {
2241   vat_main_t *vam = &vat_main;
2242   vat_json_node_t node;
2243
2244   vat_json_init_object (&node);
2245   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2246   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2247
2248   vat_json_print (vam->ofp, &node);
2249   vat_json_free (&node);
2250
2251   vam->retval = ntohl (mp->retval);
2252   vam->result_ready = 1;
2253 }
2254
2255 static void vl_api_gpe_add_del_fwd_entry_reply_t_handler
2256   (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
2257 {
2258   vat_main_t *vam = &vat_main;
2259   i32 retval = ntohl (mp->retval);
2260   if (vam->async_mode)
2261     {
2262       vam->async_errors += (retval < 0);
2263     }
2264   else
2265     {
2266       vam->retval = retval;
2267       vam->result_ready = 1;
2268     }
2269 }
2270
2271 static void vl_api_gpe_add_del_fwd_entry_reply_t_handler_json
2272   (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
2273 {
2274   vat_main_t *vam = &vat_main;
2275   vat_json_node_t node;
2276
2277   vat_json_init_object (&node);
2278   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2279   vat_json_object_add_uint (&node, "fwd_entry_index",
2280                             clib_net_to_host_u32 (mp->fwd_entry_index));
2281
2282   vat_json_print (vam->ofp, &node);
2283   vat_json_free (&node);
2284
2285   vam->retval = ntohl (mp->retval);
2286   vam->result_ready = 1;
2287 }
2288
2289 u8 *
2290 format_lisp_transport_protocol (u8 * s, va_list * args)
2291 {
2292   u32 proto = va_arg (*args, u32);
2293
2294   switch (proto)
2295     {
2296     case 1:
2297       return format (s, "udp");
2298     case 2:
2299       return format (s, "api");
2300     default:
2301       return 0;
2302     }
2303   return 0;
2304 }
2305
2306 static void vl_api_one_get_transport_protocol_reply_t_handler
2307   (vl_api_one_get_transport_protocol_reply_t * mp)
2308 {
2309   vat_main_t *vam = &vat_main;
2310   i32 retval = ntohl (mp->retval);
2311   if (vam->async_mode)
2312     {
2313       vam->async_errors += (retval < 0);
2314     }
2315   else
2316     {
2317       u32 proto = mp->protocol;
2318       print (vam->ofp, "Transport protocol: %U",
2319              format_lisp_transport_protocol, proto);
2320       vam->retval = retval;
2321       vam->result_ready = 1;
2322     }
2323 }
2324
2325 static void vl_api_one_get_transport_protocol_reply_t_handler_json
2326   (vl_api_one_get_transport_protocol_reply_t * mp)
2327 {
2328   vat_main_t *vam = &vat_main;
2329   vat_json_node_t node;
2330   u8 *s;
2331
2332   s = format (0, "%U", format_lisp_transport_protocol, mp->protocol);
2333   vec_add1 (s, 0);
2334
2335   vat_json_init_object (&node);
2336   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2337   vat_json_object_add_string_copy (&node, "transport-protocol", s);
2338
2339   vec_free (s);
2340   vat_json_print (vam->ofp, &node);
2341   vat_json_free (&node);
2342
2343   vam->retval = ntohl (mp->retval);
2344   vam->result_ready = 1;
2345 }
2346
2347 static void vl_api_one_add_del_locator_set_reply_t_handler
2348   (vl_api_one_add_del_locator_set_reply_t * mp)
2349 {
2350   vat_main_t *vam = &vat_main;
2351   i32 retval = ntohl (mp->retval);
2352   if (vam->async_mode)
2353     {
2354       vam->async_errors += (retval < 0);
2355     }
2356   else
2357     {
2358       vam->retval = retval;
2359       vam->result_ready = 1;
2360     }
2361 }
2362
2363 static void vl_api_one_add_del_locator_set_reply_t_handler_json
2364   (vl_api_one_add_del_locator_set_reply_t * mp)
2365 {
2366   vat_main_t *vam = &vat_main;
2367   vat_json_node_t node;
2368
2369   vat_json_init_object (&node);
2370   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2371   vat_json_object_add_uint (&node, "locator_set_index", ntohl (mp->ls_index));
2372
2373   vat_json_print (vam->ofp, &node);
2374   vat_json_free (&node);
2375
2376   vam->retval = ntohl (mp->retval);
2377   vam->result_ready = 1;
2378 }
2379
2380 static void vl_api_vxlan_add_del_tunnel_reply_t_handler
2381   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
2382 {
2383   vat_main_t *vam = &vat_main;
2384   i32 retval = ntohl (mp->retval);
2385   if (vam->async_mode)
2386     {
2387       vam->async_errors += (retval < 0);
2388     }
2389   else
2390     {
2391       vam->retval = retval;
2392       vam->sw_if_index = ntohl (mp->sw_if_index);
2393       vam->result_ready = 1;
2394     }
2395   vam->regenerate_interface_table = 1;
2396 }
2397
2398 static void vl_api_vxlan_add_del_tunnel_reply_t_handler_json
2399   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
2400 {
2401   vat_main_t *vam = &vat_main;
2402   vat_json_node_t node;
2403
2404   vat_json_init_object (&node);
2405   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2406   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2407
2408   vat_json_print (vam->ofp, &node);
2409   vat_json_free (&node);
2410
2411   vam->retval = ntohl (mp->retval);
2412   vam->result_ready = 1;
2413 }
2414
2415 static void vl_api_vxlan_offload_rx_reply_t_handler
2416   (vl_api_vxlan_offload_rx_reply_t * mp)
2417 {
2418   vat_main_t *vam = &vat_main;
2419   i32 retval = ntohl (mp->retval);
2420   if (vam->async_mode)
2421     {
2422       vam->async_errors += (retval < 0);
2423     }
2424   else
2425     {
2426       vam->retval = retval;
2427       vam->result_ready = 1;
2428     }
2429 }
2430
2431 static void vl_api_vxlan_offload_rx_reply_t_handler_json
2432   (vl_api_vxlan_offload_rx_reply_t * mp)
2433 {
2434   vat_main_t *vam = &vat_main;
2435   vat_json_node_t node;
2436
2437   vat_json_init_object (&node);
2438   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2439
2440   vat_json_print (vam->ofp, &node);
2441   vat_json_free (&node);
2442
2443   vam->retval = ntohl (mp->retval);
2444   vam->result_ready = 1;
2445 }
2446
2447 static void vl_api_geneve_add_del_tunnel_reply_t_handler
2448   (vl_api_geneve_add_del_tunnel_reply_t * mp)
2449 {
2450   vat_main_t *vam = &vat_main;
2451   i32 retval = ntohl (mp->retval);
2452   if (vam->async_mode)
2453     {
2454       vam->async_errors += (retval < 0);
2455     }
2456   else
2457     {
2458       vam->retval = retval;
2459       vam->sw_if_index = ntohl (mp->sw_if_index);
2460       vam->result_ready = 1;
2461     }
2462 }
2463
2464 static void vl_api_geneve_add_del_tunnel_reply_t_handler_json
2465   (vl_api_geneve_add_del_tunnel_reply_t * mp)
2466 {
2467   vat_main_t *vam = &vat_main;
2468   vat_json_node_t node;
2469
2470   vat_json_init_object (&node);
2471   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2472   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2473
2474   vat_json_print (vam->ofp, &node);
2475   vat_json_free (&node);
2476
2477   vam->retval = ntohl (mp->retval);
2478   vam->result_ready = 1;
2479 }
2480
2481 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler
2482   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
2483 {
2484   vat_main_t *vam = &vat_main;
2485   i32 retval = ntohl (mp->retval);
2486   if (vam->async_mode)
2487     {
2488       vam->async_errors += (retval < 0);
2489     }
2490   else
2491     {
2492       vam->retval = retval;
2493       vam->sw_if_index = ntohl (mp->sw_if_index);
2494       vam->result_ready = 1;
2495     }
2496   vam->regenerate_interface_table = 1;
2497 }
2498
2499 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler_json
2500   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
2501 {
2502   vat_main_t *vam = &vat_main;
2503   vat_json_node_t node;
2504
2505   vat_json_init_object (&node);
2506   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2507   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2508
2509   vat_json_print (vam->ofp, &node);
2510   vat_json_free (&node);
2511
2512   vam->retval = ntohl (mp->retval);
2513   vam->result_ready = 1;
2514 }
2515
2516 static void vl_api_gre_tunnel_add_del_reply_t_handler
2517   (vl_api_gre_tunnel_add_del_reply_t * mp)
2518 {
2519   vat_main_t *vam = &vat_main;
2520   i32 retval = ntohl (mp->retval);
2521   if (vam->async_mode)
2522     {
2523       vam->async_errors += (retval < 0);
2524     }
2525   else
2526     {
2527       vam->retval = retval;
2528       vam->sw_if_index = ntohl (mp->sw_if_index);
2529       vam->result_ready = 1;
2530     }
2531 }
2532
2533 static void vl_api_gre_tunnel_add_del_reply_t_handler_json
2534   (vl_api_gre_tunnel_add_del_reply_t * mp)
2535 {
2536   vat_main_t *vam = &vat_main;
2537   vat_json_node_t node;
2538
2539   vat_json_init_object (&node);
2540   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2541   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2542
2543   vat_json_print (vam->ofp, &node);
2544   vat_json_free (&node);
2545
2546   vam->retval = ntohl (mp->retval);
2547   vam->result_ready = 1;
2548 }
2549
2550 static void vl_api_create_vhost_user_if_reply_t_handler
2551   (vl_api_create_vhost_user_if_reply_t * mp)
2552 {
2553   vat_main_t *vam = &vat_main;
2554   i32 retval = ntohl (mp->retval);
2555   if (vam->async_mode)
2556     {
2557       vam->async_errors += (retval < 0);
2558     }
2559   else
2560     {
2561       vam->retval = retval;
2562       vam->sw_if_index = ntohl (mp->sw_if_index);
2563       vam->result_ready = 1;
2564     }
2565   vam->regenerate_interface_table = 1;
2566 }
2567
2568 static void vl_api_create_vhost_user_if_reply_t_handler_json
2569   (vl_api_create_vhost_user_if_reply_t * mp)
2570 {
2571   vat_main_t *vam = &vat_main;
2572   vat_json_node_t node;
2573
2574   vat_json_init_object (&node);
2575   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2576   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2577
2578   vat_json_print (vam->ofp, &node);
2579   vat_json_free (&node);
2580
2581   vam->retval = ntohl (mp->retval);
2582   vam->result_ready = 1;
2583 }
2584
2585 static void vl_api_ip_address_details_t_handler
2586   (vl_api_ip_address_details_t * mp)
2587 {
2588   vat_main_t *vam = &vat_main;
2589   static ip_address_details_t empty_ip_address_details = { {0} };
2590   ip_address_details_t *address = NULL;
2591   ip_details_t *current_ip_details = NULL;
2592   ip_details_t *details = NULL;
2593
2594   details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
2595
2596   if (!details || vam->current_sw_if_index >= vec_len (details)
2597       || !details[vam->current_sw_if_index].present)
2598     {
2599       errmsg ("ip address details arrived but not stored");
2600       errmsg ("ip_dump should be called first");
2601       return;
2602     }
2603
2604   current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
2605
2606 #define addresses (current_ip_details->addr)
2607
2608   vec_validate_init_empty (addresses, vec_len (addresses),
2609                            empty_ip_address_details);
2610
2611   address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
2612
2613   clib_memcpy (&address->ip, &mp->prefix.address.un, sizeof (address->ip));
2614   address->prefix_length = mp->prefix.len;
2615 #undef addresses
2616 }
2617
2618 static void vl_api_ip_address_details_t_handler_json
2619   (vl_api_ip_address_details_t * mp)
2620 {
2621   vat_main_t *vam = &vat_main;
2622   vat_json_node_t *node = NULL;
2623
2624   if (VAT_JSON_ARRAY != vam->json_tree.type)
2625     {
2626       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2627       vat_json_init_array (&vam->json_tree);
2628     }
2629   node = vat_json_array_add (&vam->json_tree);
2630
2631   vat_json_init_object (node);
2632   vat_json_object_add_prefix (node, &mp->prefix);
2633 }
2634
2635 static void
2636 vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
2637 {
2638   vat_main_t *vam = &vat_main;
2639   static ip_details_t empty_ip_details = { 0 };
2640   ip_details_t *ip = NULL;
2641   u32 sw_if_index = ~0;
2642
2643   sw_if_index = ntohl (mp->sw_if_index);
2644
2645   vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2646                            sw_if_index, empty_ip_details);
2647
2648   ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2649                          sw_if_index);
2650
2651   ip->present = 1;
2652 }
2653
2654 static void
2655 vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
2656 {
2657   vat_main_t *vam = &vat_main;
2658
2659   if (VAT_JSON_ARRAY != vam->json_tree.type)
2660     {
2661       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2662       vat_json_init_array (&vam->json_tree);
2663     }
2664   vat_json_array_add_uint (&vam->json_tree,
2665                            clib_net_to_host_u32 (mp->sw_if_index));
2666 }
2667
2668 static void vl_api_get_first_msg_id_reply_t_handler
2669   (vl_api_get_first_msg_id_reply_t * mp)
2670 {
2671   vat_main_t *vam = &vat_main;
2672   i32 retval = ntohl (mp->retval);
2673
2674   if (vam->async_mode)
2675     {
2676       vam->async_errors += (retval < 0);
2677     }
2678   else
2679     {
2680       vam->retval = retval;
2681       vam->result_ready = 1;
2682     }
2683   if (retval >= 0)
2684     {
2685       errmsg ("first message id %d", ntohs (mp->first_msg_id));
2686     }
2687 }
2688
2689 static void vl_api_get_first_msg_id_reply_t_handler_json
2690   (vl_api_get_first_msg_id_reply_t * mp)
2691 {
2692   vat_main_t *vam = &vat_main;
2693   vat_json_node_t node;
2694
2695   vat_json_init_object (&node);
2696   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2697   vat_json_object_add_uint (&node, "first_msg_id",
2698                             (uint) ntohs (mp->first_msg_id));
2699
2700   vat_json_print (vam->ofp, &node);
2701   vat_json_free (&node);
2702
2703   vam->retval = ntohl (mp->retval);
2704   vam->result_ready = 1;
2705 }
2706
2707 static void vl_api_get_node_graph_reply_t_handler
2708   (vl_api_get_node_graph_reply_t * mp)
2709 {
2710   vat_main_t *vam = &vat_main;
2711   api_main_t *am = &api_main;
2712   i32 retval = ntohl (mp->retval);
2713   u8 *pvt_copy, *reply;
2714   void *oldheap;
2715   vlib_node_t *node;
2716   int i;
2717
2718   if (vam->async_mode)
2719     {
2720       vam->async_errors += (retval < 0);
2721     }
2722   else
2723     {
2724       vam->retval = retval;
2725       vam->result_ready = 1;
2726     }
2727
2728   /* "Should never happen..." */
2729   if (retval != 0)
2730     return;
2731
2732   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2733   pvt_copy = vec_dup (reply);
2734
2735   /* Toss the shared-memory original... */
2736   pthread_mutex_lock (&am->vlib_rp->mutex);
2737   oldheap = svm_push_data_heap (am->vlib_rp);
2738
2739   vec_free (reply);
2740
2741   svm_pop_heap (oldheap);
2742   pthread_mutex_unlock (&am->vlib_rp->mutex);
2743
2744   if (vam->graph_nodes)
2745     {
2746       hash_free (vam->graph_node_index_by_name);
2747
2748       for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
2749         {
2750           node = vam->graph_nodes[0][i];
2751           vec_free (node->name);
2752           vec_free (node->next_nodes);
2753           vec_free (node);
2754         }
2755       vec_free (vam->graph_nodes[0]);
2756       vec_free (vam->graph_nodes);
2757     }
2758
2759   vam->graph_node_index_by_name = hash_create_string (0, sizeof (uword));
2760   vam->graph_nodes = vlib_node_unserialize (pvt_copy);
2761   vec_free (pvt_copy);
2762
2763   for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
2764     {
2765       node = vam->graph_nodes[0][i];
2766       hash_set_mem (vam->graph_node_index_by_name, node->name, i);
2767     }
2768 }
2769
2770 static void vl_api_get_node_graph_reply_t_handler_json
2771   (vl_api_get_node_graph_reply_t * mp)
2772 {
2773   vat_main_t *vam = &vat_main;
2774   api_main_t *am = &api_main;
2775   void *oldheap;
2776   vat_json_node_t node;
2777   u8 *reply;
2778
2779   /* $$$$ make this real? */
2780   vat_json_init_object (&node);
2781   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2782   vat_json_object_add_uint (&node, "reply_in_shmem", mp->reply_in_shmem);
2783
2784   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2785
2786   /* Toss the shared-memory original... */
2787   pthread_mutex_lock (&am->vlib_rp->mutex);
2788   oldheap = svm_push_data_heap (am->vlib_rp);
2789
2790   vec_free (reply);
2791
2792   svm_pop_heap (oldheap);
2793   pthread_mutex_unlock (&am->vlib_rp->mutex);
2794
2795   vat_json_print (vam->ofp, &node);
2796   vat_json_free (&node);
2797
2798   vam->retval = ntohl (mp->retval);
2799   vam->result_ready = 1;
2800 }
2801
2802 static void
2803 vl_api_one_locator_details_t_handler (vl_api_one_locator_details_t * mp)
2804 {
2805   vat_main_t *vam = &vat_main;
2806   u8 *s = 0;
2807
2808   if (mp->local)
2809     {
2810       s = format (s, "%=16d%=16d%=16d",
2811                   ntohl (mp->sw_if_index), mp->priority, mp->weight);
2812     }
2813   else
2814     {
2815       s = format (s, "%=16U%=16d%=16d",
2816                   mp->is_ipv6 ? format_ip6_address :
2817                   format_ip4_address,
2818                   mp->ip_address, mp->priority, mp->weight);
2819     }
2820
2821   print (vam->ofp, "%v", s);
2822   vec_free (s);
2823 }
2824
2825 static void
2826 vl_api_one_locator_details_t_handler_json (vl_api_one_locator_details_t * mp)
2827 {
2828   vat_main_t *vam = &vat_main;
2829   vat_json_node_t *node = NULL;
2830   struct in6_addr ip6;
2831   struct in_addr ip4;
2832
2833   if (VAT_JSON_ARRAY != vam->json_tree.type)
2834     {
2835       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2836       vat_json_init_array (&vam->json_tree);
2837     }
2838   node = vat_json_array_add (&vam->json_tree);
2839   vat_json_init_object (node);
2840
2841   vat_json_object_add_uint (node, "local", mp->local ? 1 : 0);
2842   vat_json_object_add_uint (node, "priority", mp->priority);
2843   vat_json_object_add_uint (node, "weight", mp->weight);
2844
2845   if (mp->local)
2846     vat_json_object_add_uint (node, "sw_if_index",
2847                               clib_net_to_host_u32 (mp->sw_if_index));
2848   else
2849     {
2850       if (mp->is_ipv6)
2851         {
2852           clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2853           vat_json_object_add_ip6 (node, "address", ip6);
2854         }
2855       else
2856         {
2857           clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2858           vat_json_object_add_ip4 (node, "address", ip4);
2859         }
2860     }
2861 }
2862
2863 static void
2864 vl_api_one_locator_set_details_t_handler (vl_api_one_locator_set_details_t *
2865                                           mp)
2866 {
2867   vat_main_t *vam = &vat_main;
2868   u8 *ls_name = 0;
2869
2870   ls_name = format (0, "%s", mp->ls_name);
2871
2872   print (vam->ofp, "%=10d%=15v", clib_net_to_host_u32 (mp->ls_index),
2873          ls_name);
2874   vec_free (ls_name);
2875 }
2876
2877 static void
2878   vl_api_one_locator_set_details_t_handler_json
2879   (vl_api_one_locator_set_details_t * mp)
2880 {
2881   vat_main_t *vam = &vat_main;
2882   vat_json_node_t *node = 0;
2883   u8 *ls_name = 0;
2884
2885   ls_name = format (0, "%s", mp->ls_name);
2886   vec_add1 (ls_name, 0);
2887
2888   if (VAT_JSON_ARRAY != vam->json_tree.type)
2889     {
2890       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2891       vat_json_init_array (&vam->json_tree);
2892     }
2893   node = vat_json_array_add (&vam->json_tree);
2894
2895   vat_json_init_object (node);
2896   vat_json_object_add_string_copy (node, "ls_name", ls_name);
2897   vat_json_object_add_uint (node, "ls_index",
2898                             clib_net_to_host_u32 (mp->ls_index));
2899   vec_free (ls_name);
2900 }
2901
2902 typedef struct
2903 {
2904   u32 spi;
2905   u8 si;
2906 } __attribute__ ((__packed__)) lisp_nsh_api_t;
2907
2908 uword
2909 unformat_nsh_address (unformat_input_t * input, va_list * args)
2910 {
2911   lisp_nsh_api_t *nsh = va_arg (*args, lisp_nsh_api_t *);
2912   return unformat (input, "SPI:%d SI:%d", &nsh->spi, &nsh->si);
2913 }
2914
2915 u8 *
2916 format_nsh_address_vat (u8 * s, va_list * args)
2917 {
2918   nsh_t *a = va_arg (*args, nsh_t *);
2919   return format (s, "SPI:%d SI:%d", clib_net_to_host_u32 (a->spi), a->si);
2920 }
2921
2922 static u8 *
2923 format_lisp_flat_eid (u8 * s, va_list * args)
2924 {
2925   u32 type = va_arg (*args, u32);
2926   u8 *eid = va_arg (*args, u8 *);
2927   u32 eid_len = va_arg (*args, u32);
2928
2929   switch (type)
2930     {
2931     case 0:
2932       return format (s, "%U/%d", format_ip4_address, eid, eid_len);
2933     case 1:
2934       return format (s, "%U/%d", format_ip6_address, eid, eid_len);
2935     case 2:
2936       return format (s, "%U", format_ethernet_address, eid);
2937     case 3:
2938       return format (s, "%U", format_nsh_address_vat, eid);
2939     }
2940   return 0;
2941 }
2942
2943 static u8 *
2944 format_lisp_eid_vat (u8 * s, va_list * args)
2945 {
2946   u32 type = va_arg (*args, u32);
2947   u8 *eid = va_arg (*args, u8 *);
2948   u32 eid_len = va_arg (*args, u32);
2949   u8 *seid = va_arg (*args, u8 *);
2950   u32 seid_len = va_arg (*args, u32);
2951   u32 is_src_dst = va_arg (*args, u32);
2952
2953   if (is_src_dst)
2954     s = format (s, "%U|", format_lisp_flat_eid, type, seid, seid_len);
2955
2956   s = format (s, "%U", format_lisp_flat_eid, type, eid, eid_len);
2957
2958   return s;
2959 }
2960
2961 static void
2962 vl_api_one_eid_table_details_t_handler (vl_api_one_eid_table_details_t * mp)
2963 {
2964   vat_main_t *vam = &vat_main;
2965   u8 *s = 0, *eid = 0;
2966
2967   if (~0 == mp->locator_set_index)
2968     s = format (0, "action: %d", mp->action);
2969   else
2970     s = format (0, "%d", clib_net_to_host_u32 (mp->locator_set_index));
2971
2972   eid = format (0, "%U", format_lisp_eid_vat,
2973                 mp->eid_type,
2974                 mp->eid,
2975                 mp->eid_prefix_len,
2976                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
2977   vec_add1 (eid, 0);
2978
2979   print (vam->ofp, "[%d] %-35s%-20s%-30s%-20d%-20d%-10d%-20s",
2980          clib_net_to_host_u32 (mp->vni),
2981          eid,
2982          mp->is_local ? "local" : "remote",
2983          s, clib_net_to_host_u32 (mp->ttl), mp->authoritative,
2984          clib_net_to_host_u16 (mp->key_id), mp->key);
2985
2986   vec_free (s);
2987   vec_free (eid);
2988 }
2989
2990 static void
2991 vl_api_one_eid_table_details_t_handler_json (vl_api_one_eid_table_details_t
2992                                              * mp)
2993 {
2994   vat_main_t *vam = &vat_main;
2995   vat_json_node_t *node = 0;
2996   u8 *eid = 0;
2997
2998   if (VAT_JSON_ARRAY != vam->json_tree.type)
2999     {
3000       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3001       vat_json_init_array (&vam->json_tree);
3002     }
3003   node = vat_json_array_add (&vam->json_tree);
3004
3005   vat_json_init_object (node);
3006   if (~0 == mp->locator_set_index)
3007     vat_json_object_add_uint (node, "action", mp->action);
3008   else
3009     vat_json_object_add_uint (node, "locator_set_index",
3010                               clib_net_to_host_u32 (mp->locator_set_index));
3011
3012   vat_json_object_add_uint (node, "is_local", mp->is_local ? 1 : 0);
3013   if (mp->eid_type == 3)
3014     {
3015       vat_json_node_t *nsh_json = vat_json_object_add (node, "eid");
3016       vat_json_init_object (nsh_json);
3017       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) mp->eid;
3018       vat_json_object_add_uint (nsh_json, "spi",
3019                                 clib_net_to_host_u32 (nsh->spi));
3020       vat_json_object_add_uint (nsh_json, "si", nsh->si);
3021     }
3022   else
3023     {
3024       eid = format (0, "%U", format_lisp_eid_vat,
3025                     mp->eid_type,
3026                     mp->eid,
3027                     mp->eid_prefix_len,
3028                     mp->seid, mp->seid_prefix_len, mp->is_src_dst);
3029       vec_add1 (eid, 0);
3030       vat_json_object_add_string_copy (node, "eid", eid);
3031       vec_free (eid);
3032     }
3033   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3034   vat_json_object_add_uint (node, "ttl", clib_net_to_host_u32 (mp->ttl));
3035   vat_json_object_add_uint (node, "authoritative", (mp->authoritative));
3036
3037   if (mp->key_id)
3038     {
3039       vat_json_object_add_uint (node, "key_id",
3040                                 clib_net_to_host_u16 (mp->key_id));
3041       vat_json_object_add_string_copy (node, "key", mp->key);
3042     }
3043 }
3044
3045 static void
3046 vl_api_one_stats_details_t_handler (vl_api_one_stats_details_t * mp)
3047 {
3048   vat_main_t *vam = &vat_main;
3049   u8 *seid = 0, *deid = 0;
3050   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3051
3052   deid = format (0, "%U", format_lisp_eid_vat,
3053                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
3054
3055   seid = format (0, "%U", format_lisp_eid_vat,
3056                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
3057
3058   vec_add1 (deid, 0);
3059   vec_add1 (seid, 0);
3060
3061   if (mp->is_ip4)
3062     format_ip_address_fcn = format_ip4_address;
3063   else
3064     format_ip_address_fcn = format_ip6_address;
3065
3066
3067   print (vam->ofp, "([%d] %s %s) (%U %U) %u %u",
3068          clib_net_to_host_u32 (mp->vni),
3069          seid, deid,
3070          format_ip_address_fcn, mp->lloc,
3071          format_ip_address_fcn, mp->rloc,
3072          clib_net_to_host_u32 (mp->pkt_count),
3073          clib_net_to_host_u32 (mp->bytes));
3074
3075   vec_free (deid);
3076   vec_free (seid);
3077 }
3078
3079 static void
3080 vl_api_one_stats_details_t_handler_json (vl_api_one_stats_details_t * mp)
3081 {
3082   struct in6_addr ip6;
3083   struct in_addr ip4;
3084   vat_main_t *vam = &vat_main;
3085   vat_json_node_t *node = 0;
3086   u8 *deid = 0, *seid = 0;
3087
3088   if (VAT_JSON_ARRAY != vam->json_tree.type)
3089     {
3090       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3091       vat_json_init_array (&vam->json_tree);
3092     }
3093   node = vat_json_array_add (&vam->json_tree);
3094
3095   vat_json_init_object (node);
3096   deid = format (0, "%U", format_lisp_eid_vat,
3097                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
3098
3099   seid = format (0, "%U", format_lisp_eid_vat,
3100                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
3101
3102   vec_add1 (deid, 0);
3103   vec_add1 (seid, 0);
3104
3105   vat_json_object_add_string_copy (node, "seid", seid);
3106   vat_json_object_add_string_copy (node, "deid", deid);
3107   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3108
3109   if (mp->is_ip4)
3110     {
3111       clib_memcpy (&ip4, mp->lloc, sizeof (ip4));
3112       vat_json_object_add_ip4 (node, "lloc", ip4);
3113       clib_memcpy (&ip4, mp->rloc, sizeof (ip4));
3114       vat_json_object_add_ip4 (node, "rloc", ip4);
3115     }
3116   else
3117     {
3118       clib_memcpy (&ip6, mp->lloc, sizeof (ip6));
3119       vat_json_object_add_ip6 (node, "lloc", ip6);
3120       clib_memcpy (&ip6, mp->rloc, sizeof (ip6));
3121       vat_json_object_add_ip6 (node, "rloc", ip6);
3122     }
3123   vat_json_object_add_uint (node, "pkt_count",
3124                             clib_net_to_host_u32 (mp->pkt_count));
3125   vat_json_object_add_uint (node, "bytes", clib_net_to_host_u32 (mp->bytes));
3126
3127   vec_free (deid);
3128   vec_free (seid);
3129 }
3130
3131 static void
3132   vl_api_one_eid_table_map_details_t_handler
3133   (vl_api_one_eid_table_map_details_t * mp)
3134 {
3135   vat_main_t *vam = &vat_main;
3136
3137   u8 *line = format (0, "%=10d%=10d",
3138                      clib_net_to_host_u32 (mp->vni),
3139                      clib_net_to_host_u32 (mp->dp_table));
3140   print (vam->ofp, "%v", line);
3141   vec_free (line);
3142 }
3143
3144 static void
3145   vl_api_one_eid_table_map_details_t_handler_json
3146   (vl_api_one_eid_table_map_details_t * mp)
3147 {
3148   vat_main_t *vam = &vat_main;
3149   vat_json_node_t *node = NULL;
3150
3151   if (VAT_JSON_ARRAY != vam->json_tree.type)
3152     {
3153       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3154       vat_json_init_array (&vam->json_tree);
3155     }
3156   node = vat_json_array_add (&vam->json_tree);
3157   vat_json_init_object (node);
3158   vat_json_object_add_uint (node, "dp_table",
3159                             clib_net_to_host_u32 (mp->dp_table));
3160   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3161 }
3162
3163 static void
3164   vl_api_one_eid_table_vni_details_t_handler
3165   (vl_api_one_eid_table_vni_details_t * mp)
3166 {
3167   vat_main_t *vam = &vat_main;
3168
3169   u8 *line = format (0, "%d", clib_net_to_host_u32 (mp->vni));
3170   print (vam->ofp, "%v", line);
3171   vec_free (line);
3172 }
3173
3174 static void
3175   vl_api_one_eid_table_vni_details_t_handler_json
3176   (vl_api_one_eid_table_vni_details_t * mp)
3177 {
3178   vat_main_t *vam = &vat_main;
3179   vat_json_node_t *node = NULL;
3180
3181   if (VAT_JSON_ARRAY != vam->json_tree.type)
3182     {
3183       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3184       vat_json_init_array (&vam->json_tree);
3185     }
3186   node = vat_json_array_add (&vam->json_tree);
3187   vat_json_init_object (node);
3188   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3189 }
3190
3191 static void
3192   vl_api_show_one_map_register_fallback_threshold_reply_t_handler
3193   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
3194 {
3195   vat_main_t *vam = &vat_main;
3196   int retval = clib_net_to_host_u32 (mp->retval);
3197
3198   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
3199   print (vam->ofp, "fallback threshold value: %d", mp->value);
3200
3201   vam->retval = retval;
3202   vam->result_ready = 1;
3203 }
3204
3205 static void
3206   vl_api_show_one_map_register_fallback_threshold_reply_t_handler_json
3207   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
3208 {
3209   vat_main_t *vam = &vat_main;
3210   vat_json_node_t _node, *node = &_node;
3211   int retval = clib_net_to_host_u32 (mp->retval);
3212
3213   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
3214   vat_json_init_object (node);
3215   vat_json_object_add_uint (node, "value", mp->value);
3216
3217   vat_json_print (vam->ofp, node);
3218   vat_json_free (node);
3219
3220   vam->retval = retval;
3221   vam->result_ready = 1;
3222 }
3223
3224 static void
3225   vl_api_show_one_map_register_state_reply_t_handler
3226   (vl_api_show_one_map_register_state_reply_t * mp)
3227 {
3228   vat_main_t *vam = &vat_main;
3229   int retval = clib_net_to_host_u32 (mp->retval);
3230
3231   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
3232
3233   vam->retval = retval;
3234   vam->result_ready = 1;
3235 }
3236
3237 static void
3238   vl_api_show_one_map_register_state_reply_t_handler_json
3239   (vl_api_show_one_map_register_state_reply_t * mp)
3240 {
3241   vat_main_t *vam = &vat_main;
3242   vat_json_node_t _node, *node = &_node;
3243   int retval = clib_net_to_host_u32 (mp->retval);
3244
3245   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
3246
3247   vat_json_init_object (node);
3248   vat_json_object_add_string_copy (node, "state", s);
3249
3250   vat_json_print (vam->ofp, node);
3251   vat_json_free (node);
3252
3253   vam->retval = retval;
3254   vam->result_ready = 1;
3255   vec_free (s);
3256 }
3257
3258 static void
3259   vl_api_show_one_rloc_probe_state_reply_t_handler
3260   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3261 {
3262   vat_main_t *vam = &vat_main;
3263   int retval = clib_net_to_host_u32 (mp->retval);
3264
3265   if (retval)
3266     goto end;
3267
3268   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
3269 end:
3270   vam->retval = retval;
3271   vam->result_ready = 1;
3272 }
3273
3274 static void
3275   vl_api_show_one_rloc_probe_state_reply_t_handler_json
3276   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3277 {
3278   vat_main_t *vam = &vat_main;
3279   vat_json_node_t _node, *node = &_node;
3280   int retval = clib_net_to_host_u32 (mp->retval);
3281
3282   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
3283   vat_json_init_object (node);
3284   vat_json_object_add_string_copy (node, "state", s);
3285
3286   vat_json_print (vam->ofp, node);
3287   vat_json_free (node);
3288
3289   vam->retval = retval;
3290   vam->result_ready = 1;
3291   vec_free (s);
3292 }
3293
3294 static void
3295   vl_api_show_one_stats_enable_disable_reply_t_handler
3296   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3297 {
3298   vat_main_t *vam = &vat_main;
3299   int retval = clib_net_to_host_u32 (mp->retval);
3300
3301   if (retval)
3302     goto end;
3303
3304   print (vam->ofp, "%s", mp->is_en ? "enabled" : "disabled");
3305 end:
3306   vam->retval = retval;
3307   vam->result_ready = 1;
3308 }
3309
3310 static void
3311   vl_api_show_one_stats_enable_disable_reply_t_handler_json
3312   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3313 {
3314   vat_main_t *vam = &vat_main;
3315   vat_json_node_t _node, *node = &_node;
3316   int retval = clib_net_to_host_u32 (mp->retval);
3317
3318   u8 *s = format (0, "%s", mp->is_en ? "enabled" : "disabled");
3319   vat_json_init_object (node);
3320   vat_json_object_add_string_copy (node, "state", s);
3321
3322   vat_json_print (vam->ofp, node);
3323   vat_json_free (node);
3324
3325   vam->retval = retval;
3326   vam->result_ready = 1;
3327   vec_free (s);
3328 }
3329
3330 static void
3331 api_gpe_fwd_entry_net_to_host (vl_api_gpe_fwd_entry_t * e)
3332 {
3333   e->dp_table = clib_net_to_host_u32 (e->dp_table);
3334   e->fwd_entry_index = clib_net_to_host_u32 (e->fwd_entry_index);
3335   e->vni = clib_net_to_host_u32 (e->vni);
3336 }
3337
3338 static void
3339   gpe_fwd_entries_get_reply_t_net_to_host
3340   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3341 {
3342   u32 i;
3343
3344   mp->count = clib_net_to_host_u32 (mp->count);
3345   for (i = 0; i < mp->count; i++)
3346     {
3347       api_gpe_fwd_entry_net_to_host (&mp->entries[i]);
3348     }
3349 }
3350
3351 static u8 *
3352 format_gpe_encap_mode (u8 * s, va_list * args)
3353 {
3354   u32 mode = va_arg (*args, u32);
3355
3356   switch (mode)
3357     {
3358     case 0:
3359       return format (s, "lisp");
3360     case 1:
3361       return format (s, "vxlan");
3362     }
3363   return 0;
3364 }
3365
3366 static void
3367   vl_api_gpe_get_encap_mode_reply_t_handler
3368   (vl_api_gpe_get_encap_mode_reply_t * mp)
3369 {
3370   vat_main_t *vam = &vat_main;
3371
3372   print (vam->ofp, "gpe mode: %U", format_gpe_encap_mode, mp->encap_mode);
3373   vam->retval = ntohl (mp->retval);
3374   vam->result_ready = 1;
3375 }
3376
3377 static void
3378   vl_api_gpe_get_encap_mode_reply_t_handler_json
3379   (vl_api_gpe_get_encap_mode_reply_t * mp)
3380 {
3381   vat_main_t *vam = &vat_main;
3382   vat_json_node_t node;
3383
3384   u8 *encap_mode = format (0, "%U", format_gpe_encap_mode, mp->encap_mode);
3385   vec_add1 (encap_mode, 0);
3386
3387   vat_json_init_object (&node);
3388   vat_json_object_add_string_copy (&node, "gpe_mode", encap_mode);
3389
3390   vec_free (encap_mode);
3391   vat_json_print (vam->ofp, &node);
3392   vat_json_free (&node);
3393
3394   vam->retval = ntohl (mp->retval);
3395   vam->result_ready = 1;
3396 }
3397
3398 static void
3399   vl_api_gpe_fwd_entry_path_details_t_handler
3400   (vl_api_gpe_fwd_entry_path_details_t * mp)
3401 {
3402   vat_main_t *vam = &vat_main;
3403   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3404
3405   if (mp->lcl_loc.is_ip4)
3406     format_ip_address_fcn = format_ip4_address;
3407   else
3408     format_ip_address_fcn = format_ip6_address;
3409
3410   print (vam->ofp, "w:%d %30U %30U", mp->rmt_loc.weight,
3411          format_ip_address_fcn, &mp->lcl_loc,
3412          format_ip_address_fcn, &mp->rmt_loc);
3413 }
3414
3415 static void
3416 lisp_fill_locator_node (vat_json_node_t * n, vl_api_gpe_locator_t * loc)
3417 {
3418   struct in6_addr ip6;
3419   struct in_addr ip4;
3420
3421   if (loc->is_ip4)
3422     {
3423       clib_memcpy (&ip4, loc->addr, sizeof (ip4));
3424       vat_json_object_add_ip4 (n, "address", ip4);
3425     }
3426   else
3427     {
3428       clib_memcpy (&ip6, loc->addr, sizeof (ip6));
3429       vat_json_object_add_ip6 (n, "address", ip6);
3430     }
3431   vat_json_object_add_uint (n, "weight", loc->weight);
3432 }
3433
3434 static void
3435   vl_api_gpe_fwd_entry_path_details_t_handler_json
3436   (vl_api_gpe_fwd_entry_path_details_t * mp)
3437 {
3438   vat_main_t *vam = &vat_main;
3439   vat_json_node_t *node = NULL;
3440   vat_json_node_t *loc_node;
3441
3442   if (VAT_JSON_ARRAY != vam->json_tree.type)
3443     {
3444       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3445       vat_json_init_array (&vam->json_tree);
3446     }
3447   node = vat_json_array_add (&vam->json_tree);
3448   vat_json_init_object (node);
3449
3450   loc_node = vat_json_object_add (node, "local_locator");
3451   vat_json_init_object (loc_node);
3452   lisp_fill_locator_node (loc_node, &mp->lcl_loc);
3453
3454   loc_node = vat_json_object_add (node, "remote_locator");
3455   vat_json_init_object (loc_node);
3456   lisp_fill_locator_node (loc_node, &mp->rmt_loc);
3457 }
3458
3459 static void
3460   vl_api_gpe_fwd_entries_get_reply_t_handler
3461   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3462 {
3463   vat_main_t *vam = &vat_main;
3464   u32 i;
3465   int retval = clib_net_to_host_u32 (mp->retval);
3466   vl_api_gpe_fwd_entry_t *e;
3467
3468   if (retval)
3469     goto end;
3470
3471   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3472
3473   for (i = 0; i < mp->count; i++)
3474     {
3475       e = &mp->entries[i];
3476       print (vam->ofp, "%10d %10d %U %40U", e->fwd_entry_index, e->dp_table,
3477              format_lisp_flat_eid, e->eid_type, e->leid, e->leid_prefix_len,
3478              format_lisp_flat_eid, e->eid_type, e->reid, e->reid_prefix_len);
3479     }
3480
3481 end:
3482   vam->retval = retval;
3483   vam->result_ready = 1;
3484 }
3485
3486 static void
3487   vl_api_gpe_fwd_entries_get_reply_t_handler_json
3488   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3489 {
3490   u8 *s = 0;
3491   vat_main_t *vam = &vat_main;
3492   vat_json_node_t *e = 0, root;
3493   u32 i;
3494   int retval = clib_net_to_host_u32 (mp->retval);
3495   vl_api_gpe_fwd_entry_t *fwd;
3496
3497   if (retval)
3498     goto end;
3499
3500   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3501   vat_json_init_array (&root);
3502
3503   for (i = 0; i < mp->count; i++)
3504     {
3505       e = vat_json_array_add (&root);
3506       fwd = &mp->entries[i];
3507
3508       vat_json_init_object (e);
3509       vat_json_object_add_int (e, "fwd_entry_index", fwd->fwd_entry_index);
3510       vat_json_object_add_int (e, "dp_table", fwd->dp_table);
3511       vat_json_object_add_int (e, "vni", fwd->vni);
3512       vat_json_object_add_int (e, "action", fwd->action);
3513
3514       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->leid,
3515                   fwd->leid_prefix_len);
3516       vec_add1 (s, 0);
3517       vat_json_object_add_string_copy (e, "leid", s);
3518       vec_free (s);
3519
3520       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->reid,
3521                   fwd->reid_prefix_len);
3522       vec_add1 (s, 0);
3523       vat_json_object_add_string_copy (e, "reid", s);
3524       vec_free (s);
3525     }
3526
3527   vat_json_print (vam->ofp, &root);
3528   vat_json_free (&root);
3529
3530 end:
3531   vam->retval = retval;
3532   vam->result_ready = 1;
3533 }
3534
3535 static void
3536   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler
3537   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3538 {
3539   vat_main_t *vam = &vat_main;
3540   u32 i, n;
3541   int retval = clib_net_to_host_u32 (mp->retval);
3542   vl_api_gpe_native_fwd_rpath_t *r;
3543
3544   if (retval)
3545     goto end;
3546
3547   n = clib_net_to_host_u32 (mp->count);
3548
3549   for (i = 0; i < n; i++)
3550     {
3551       r = &mp->entries[i];
3552       print (vam->ofp, "fib_index: %d sw_if_index %d nh %U",
3553              clib_net_to_host_u32 (r->fib_index),
3554              clib_net_to_host_u32 (r->nh_sw_if_index),
3555              r->is_ip4 ? format_ip4_address : format_ip6_address, r->nh_addr);
3556     }
3557
3558 end:
3559   vam->retval = retval;
3560   vam->result_ready = 1;
3561 }
3562
3563 static void
3564   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler_json
3565   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3566 {
3567   vat_main_t *vam = &vat_main;
3568   vat_json_node_t root, *e;
3569   u32 i, n;
3570   int retval = clib_net_to_host_u32 (mp->retval);
3571   vl_api_gpe_native_fwd_rpath_t *r;
3572   u8 *s;
3573
3574   if (retval)
3575     goto end;
3576
3577   n = clib_net_to_host_u32 (mp->count);
3578   vat_json_init_array (&root);
3579
3580   for (i = 0; i < n; i++)
3581     {
3582       e = vat_json_array_add (&root);
3583       vat_json_init_object (e);
3584       r = &mp->entries[i];
3585       s =
3586         format (0, "%U", r->is_ip4 ? format_ip4_address : format_ip6_address,
3587                 r->nh_addr);
3588       vec_add1 (s, 0);
3589       vat_json_object_add_string_copy (e, "ip4", s);
3590       vec_free (s);
3591
3592       vat_json_object_add_uint (e, "fib_index",
3593                                 clib_net_to_host_u32 (r->fib_index));
3594       vat_json_object_add_uint (e, "nh_sw_if_index",
3595                                 clib_net_to_host_u32 (r->nh_sw_if_index));
3596     }
3597
3598   vat_json_print (vam->ofp, &root);
3599   vat_json_free (&root);
3600
3601 end:
3602   vam->retval = retval;
3603   vam->result_ready = 1;
3604 }
3605
3606 static void
3607   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler
3608   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3609 {
3610   vat_main_t *vam = &vat_main;
3611   u32 i, n;
3612   int retval = clib_net_to_host_u32 (mp->retval);
3613
3614   if (retval)
3615     goto end;
3616
3617   n = clib_net_to_host_u32 (mp->count);
3618
3619   for (i = 0; i < n; i++)
3620     print (vam->ofp, "%d", clib_net_to_host_u32 (mp->vnis[i]));
3621
3622 end:
3623   vam->retval = retval;
3624   vam->result_ready = 1;
3625 }
3626
3627 static void
3628   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler_json
3629   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3630 {
3631   vat_main_t *vam = &vat_main;
3632   vat_json_node_t root;
3633   u32 i, n;
3634   int retval = clib_net_to_host_u32 (mp->retval);
3635
3636   if (retval)
3637     goto end;
3638
3639   n = clib_net_to_host_u32 (mp->count);
3640   vat_json_init_array (&root);
3641
3642   for (i = 0; i < n; i++)
3643     vat_json_array_add_uint (&root, clib_net_to_host_u32 (mp->vnis[i]));
3644
3645   vat_json_print (vam->ofp, &root);
3646   vat_json_free (&root);
3647
3648 end:
3649   vam->retval = retval;
3650   vam->result_ready = 1;
3651 }
3652
3653 static void
3654   vl_api_one_ndp_entries_get_reply_t_handler
3655   (vl_api_one_ndp_entries_get_reply_t * mp)
3656 {
3657   vat_main_t *vam = &vat_main;
3658   u32 i, n;
3659   int retval = clib_net_to_host_u32 (mp->retval);
3660
3661   if (retval)
3662     goto end;
3663
3664   n = clib_net_to_host_u32 (mp->count);
3665
3666   for (i = 0; i < n; i++)
3667     print (vam->ofp, "%U -> %U", format_ip6_address, &mp->entries[i].ip6,
3668            format_ethernet_address, mp->entries[i].mac);
3669
3670 end:
3671   vam->retval = retval;
3672   vam->result_ready = 1;
3673 }
3674
3675 static void
3676   vl_api_one_ndp_entries_get_reply_t_handler_json
3677   (vl_api_one_ndp_entries_get_reply_t * mp)
3678 {
3679   u8 *s = 0;
3680   vat_main_t *vam = &vat_main;
3681   vat_json_node_t *e = 0, root;
3682   u32 i, n;
3683   int retval = clib_net_to_host_u32 (mp->retval);
3684   vl_api_one_ndp_entry_t *arp_entry;
3685
3686   if (retval)
3687     goto end;
3688
3689   n = clib_net_to_host_u32 (mp->count);
3690   vat_json_init_array (&root);
3691
3692   for (i = 0; i < n; i++)
3693     {
3694       e = vat_json_array_add (&root);
3695       arp_entry = &mp->entries[i];
3696
3697       vat_json_init_object (e);
3698       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
3699       vec_add1 (s, 0);
3700
3701       vat_json_object_add_string_copy (e, "mac", s);
3702       vec_free (s);
3703
3704       s = format (0, "%U", format_ip6_address, &arp_entry->ip6);
3705       vec_add1 (s, 0);
3706       vat_json_object_add_string_copy (e, "ip6", s);
3707       vec_free (s);
3708     }
3709
3710   vat_json_print (vam->ofp, &root);
3711   vat_json_free (&root);
3712
3713 end:
3714   vam->retval = retval;
3715   vam->result_ready = 1;
3716 }
3717
3718 static void
3719   vl_api_one_l2_arp_entries_get_reply_t_handler
3720   (vl_api_one_l2_arp_entries_get_reply_t * mp)
3721 {
3722   vat_main_t *vam = &vat_main;
3723   u32 i, n;
3724   int retval = clib_net_to_host_u32 (mp->retval);
3725
3726   if (retval)
3727     goto end;
3728
3729   n = clib_net_to_host_u32 (mp->count);
3730
3731   for (i = 0; i < n; i++)
3732     print (vam->ofp, "%U -> %U", format_ip4_address, &mp->entries[i].ip4,
3733            format_ethernet_address, mp->entries[i].mac);
3734
3735 end:
3736   vam->retval = retval;
3737   vam->result_ready = 1;
3738 }
3739
3740 static void
3741   vl_api_one_l2_arp_entries_get_reply_t_handler_json
3742   (vl_api_one_l2_arp_entries_get_reply_t * mp)
3743 {
3744   u8 *s = 0;
3745   vat_main_t *vam = &vat_main;
3746   vat_json_node_t *e = 0, root;
3747   u32 i, n;
3748   int retval = clib_net_to_host_u32 (mp->retval);
3749   vl_api_one_l2_arp_entry_t *arp_entry;
3750
3751   if (retval)
3752     goto end;
3753
3754   n = clib_net_to_host_u32 (mp->count);
3755   vat_json_init_array (&root);
3756
3757   for (i = 0; i < n; i++)
3758     {
3759       e = vat_json_array_add (&root);
3760       arp_entry = &mp->entries[i];
3761
3762       vat_json_init_object (e);
3763       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
3764       vec_add1 (s, 0);
3765
3766       vat_json_object_add_string_copy (e, "mac", s);
3767       vec_free (s);
3768
3769       s = format (0, "%U", format_ip4_address, &arp_entry->ip4);
3770       vec_add1 (s, 0);
3771       vat_json_object_add_string_copy (e, "ip4", s);
3772       vec_free (s);
3773     }
3774
3775   vat_json_print (vam->ofp, &root);
3776   vat_json_free (&root);
3777
3778 end:
3779   vam->retval = retval;
3780   vam->result_ready = 1;
3781 }
3782
3783 static void
3784 vl_api_one_ndp_bd_get_reply_t_handler (vl_api_one_ndp_bd_get_reply_t * mp)
3785 {
3786   vat_main_t *vam = &vat_main;
3787   u32 i, n;
3788   int retval = clib_net_to_host_u32 (mp->retval);
3789
3790   if (retval)
3791     goto end;
3792
3793   n = clib_net_to_host_u32 (mp->count);
3794
3795   for (i = 0; i < n; i++)
3796     {
3797       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
3798     }
3799
3800 end:
3801   vam->retval = retval;
3802   vam->result_ready = 1;
3803 }
3804
3805 static void
3806   vl_api_one_ndp_bd_get_reply_t_handler_json
3807   (vl_api_one_ndp_bd_get_reply_t * mp)
3808 {
3809   vat_main_t *vam = &vat_main;
3810   vat_json_node_t root;
3811   u32 i, n;
3812   int retval = clib_net_to_host_u32 (mp->retval);
3813
3814   if (retval)
3815     goto end;
3816
3817   n = clib_net_to_host_u32 (mp->count);
3818   vat_json_init_array (&root);
3819
3820   for (i = 0; i < n; i++)
3821     {
3822       vat_json_array_add_uint (&root,
3823                                clib_net_to_host_u32 (mp->bridge_domains[i]));
3824     }
3825
3826   vat_json_print (vam->ofp, &root);
3827   vat_json_free (&root);
3828
3829 end:
3830   vam->retval = retval;
3831   vam->result_ready = 1;
3832 }
3833
3834 static void
3835   vl_api_one_l2_arp_bd_get_reply_t_handler
3836   (vl_api_one_l2_arp_bd_get_reply_t * mp)
3837 {
3838   vat_main_t *vam = &vat_main;
3839   u32 i, n;
3840   int retval = clib_net_to_host_u32 (mp->retval);
3841
3842   if (retval)
3843     goto end;
3844
3845   n = clib_net_to_host_u32 (mp->count);
3846
3847   for (i = 0; i < n; i++)
3848     {
3849       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
3850     }
3851
3852 end:
3853   vam->retval = retval;
3854   vam->result_ready = 1;
3855 }
3856
3857 static void
3858   vl_api_one_l2_arp_bd_get_reply_t_handler_json
3859   (vl_api_one_l2_arp_bd_get_reply_t * mp)
3860 {
3861   vat_main_t *vam = &vat_main;
3862   vat_json_node_t root;
3863   u32 i, n;
3864   int retval = clib_net_to_host_u32 (mp->retval);
3865
3866   if (retval)
3867     goto end;
3868
3869   n = clib_net_to_host_u32 (mp->count);
3870   vat_json_init_array (&root);
3871
3872   for (i = 0; i < n; i++)
3873     {
3874       vat_json_array_add_uint (&root,
3875                                clib_net_to_host_u32 (mp->bridge_domains[i]));
3876     }
3877
3878   vat_json_print (vam->ofp, &root);
3879   vat_json_free (&root);
3880
3881 end:
3882   vam->retval = retval;
3883   vam->result_ready = 1;
3884 }
3885
3886 static void
3887   vl_api_one_adjacencies_get_reply_t_handler
3888   (vl_api_one_adjacencies_get_reply_t * mp)
3889 {
3890   vat_main_t *vam = &vat_main;
3891   u32 i, n;
3892   int retval = clib_net_to_host_u32 (mp->retval);
3893   vl_api_one_adjacency_t *a;
3894
3895   if (retval)
3896     goto end;
3897
3898   n = clib_net_to_host_u32 (mp->count);
3899
3900   for (i = 0; i < n; i++)
3901     {
3902       a = &mp->adjacencies[i];
3903       print (vam->ofp, "%U %40U",
3904              format_lisp_flat_eid, a->eid_type, a->leid, a->leid_prefix_len,
3905              format_lisp_flat_eid, a->eid_type, a->reid, a->reid_prefix_len);
3906     }
3907
3908 end:
3909   vam->retval = retval;
3910   vam->result_ready = 1;
3911 }
3912
3913 static void
3914   vl_api_one_adjacencies_get_reply_t_handler_json
3915   (vl_api_one_adjacencies_get_reply_t * mp)
3916 {
3917   u8 *s = 0;
3918   vat_main_t *vam = &vat_main;
3919   vat_json_node_t *e = 0, root;
3920   u32 i, n;
3921   int retval = clib_net_to_host_u32 (mp->retval);
3922   vl_api_one_adjacency_t *a;
3923
3924   if (retval)
3925     goto end;
3926
3927   n = clib_net_to_host_u32 (mp->count);
3928   vat_json_init_array (&root);
3929
3930   for (i = 0; i < n; i++)
3931     {
3932       e = vat_json_array_add (&root);
3933       a = &mp->adjacencies[i];
3934
3935       vat_json_init_object (e);
3936       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->leid,
3937                   a->leid_prefix_len);
3938       vec_add1 (s, 0);
3939       vat_json_object_add_string_copy (e, "leid", s);
3940       vec_free (s);
3941
3942       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->reid,
3943                   a->reid_prefix_len);
3944       vec_add1 (s, 0);
3945       vat_json_object_add_string_copy (e, "reid", s);
3946       vec_free (s);
3947     }
3948
3949   vat_json_print (vam->ofp, &root);
3950   vat_json_free (&root);
3951
3952 end:
3953   vam->retval = retval;
3954   vam->result_ready = 1;
3955 }
3956
3957 static void
3958 vl_api_one_map_server_details_t_handler (vl_api_one_map_server_details_t * mp)
3959 {
3960   vat_main_t *vam = &vat_main;
3961
3962   print (vam->ofp, "%=20U",
3963          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
3964          mp->ip_address);
3965 }
3966
3967 static void
3968   vl_api_one_map_server_details_t_handler_json
3969   (vl_api_one_map_server_details_t * mp)
3970 {
3971   vat_main_t *vam = &vat_main;
3972   vat_json_node_t *node = NULL;
3973   struct in6_addr ip6;
3974   struct in_addr ip4;
3975
3976   if (VAT_JSON_ARRAY != vam->json_tree.type)
3977     {
3978       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3979       vat_json_init_array (&vam->json_tree);
3980     }
3981   node = vat_json_array_add (&vam->json_tree);
3982
3983   vat_json_init_object (node);
3984   if (mp->is_ipv6)
3985     {
3986       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
3987       vat_json_object_add_ip6 (node, "map-server", ip6);
3988     }
3989   else
3990     {
3991       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
3992       vat_json_object_add_ip4 (node, "map-server", ip4);
3993     }
3994 }
3995
3996 static void
3997 vl_api_one_map_resolver_details_t_handler (vl_api_one_map_resolver_details_t
3998                                            * mp)
3999 {
4000   vat_main_t *vam = &vat_main;
4001
4002   print (vam->ofp, "%=20U",
4003          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
4004          mp->ip_address);
4005 }
4006
4007 static void
4008   vl_api_one_map_resolver_details_t_handler_json
4009   (vl_api_one_map_resolver_details_t * mp)
4010 {
4011   vat_main_t *vam = &vat_main;
4012   vat_json_node_t *node = NULL;
4013   struct in6_addr ip6;
4014   struct in_addr ip4;
4015
4016   if (VAT_JSON_ARRAY != vam->json_tree.type)
4017     {
4018       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4019       vat_json_init_array (&vam->json_tree);
4020     }
4021   node = vat_json_array_add (&vam->json_tree);
4022
4023   vat_json_init_object (node);
4024   if (mp->is_ipv6)
4025     {
4026       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
4027       vat_json_object_add_ip6 (node, "map resolver", ip6);
4028     }
4029   else
4030     {
4031       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
4032       vat_json_object_add_ip4 (node, "map resolver", ip4);
4033     }
4034 }
4035
4036 static void
4037 vl_api_show_one_status_reply_t_handler (vl_api_show_one_status_reply_t * mp)
4038 {
4039   vat_main_t *vam = &vat_main;
4040   i32 retval = ntohl (mp->retval);
4041
4042   if (0 <= retval)
4043     {
4044       print (vam->ofp, "feature: %s\ngpe: %s",
4045              mp->feature_status ? "enabled" : "disabled",
4046              mp->gpe_status ? "enabled" : "disabled");
4047     }
4048
4049   vam->retval = retval;
4050   vam->result_ready = 1;
4051 }
4052
4053 static void
4054   vl_api_show_one_status_reply_t_handler_json
4055   (vl_api_show_one_status_reply_t * mp)
4056 {
4057   vat_main_t *vam = &vat_main;
4058   vat_json_node_t node;
4059   u8 *gpe_status = NULL;
4060   u8 *feature_status = NULL;
4061
4062   gpe_status = format (0, "%s", mp->gpe_status ? "enabled" : "disabled");
4063   feature_status = format (0, "%s",
4064                            mp->feature_status ? "enabled" : "disabled");
4065   vec_add1 (gpe_status, 0);
4066   vec_add1 (feature_status, 0);
4067
4068   vat_json_init_object (&node);
4069   vat_json_object_add_string_copy (&node, "gpe_status", gpe_status);
4070   vat_json_object_add_string_copy (&node, "feature_status", feature_status);
4071
4072   vec_free (gpe_status);
4073   vec_free (feature_status);
4074
4075   vat_json_print (vam->ofp, &node);
4076   vat_json_free (&node);
4077
4078   vam->retval = ntohl (mp->retval);
4079   vam->result_ready = 1;
4080 }
4081
4082 static void
4083   vl_api_one_get_map_request_itr_rlocs_reply_t_handler
4084   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
4085 {
4086   vat_main_t *vam = &vat_main;
4087   i32 retval = ntohl (mp->retval);
4088
4089   if (retval >= 0)
4090     {
4091       print (vam->ofp, "%=20s", mp->locator_set_name);
4092     }
4093
4094   vam->retval = retval;
4095   vam->result_ready = 1;
4096 }
4097
4098 static void
4099   vl_api_one_get_map_request_itr_rlocs_reply_t_handler_json
4100   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
4101 {
4102   vat_main_t *vam = &vat_main;
4103   vat_json_node_t *node = NULL;
4104
4105   if (VAT_JSON_ARRAY != vam->json_tree.type)
4106     {
4107       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4108       vat_json_init_array (&vam->json_tree);
4109     }
4110   node = vat_json_array_add (&vam->json_tree);
4111
4112   vat_json_init_object (node);
4113   vat_json_object_add_string_copy (node, "itr-rlocs", mp->locator_set_name);
4114
4115   vat_json_print (vam->ofp, node);
4116   vat_json_free (node);
4117
4118   vam->retval = ntohl (mp->retval);
4119   vam->result_ready = 1;
4120 }
4121
4122 static u8 *
4123 format_lisp_map_request_mode (u8 * s, va_list * args)
4124 {
4125   u32 mode = va_arg (*args, u32);
4126
4127   switch (mode)
4128     {
4129     case 0:
4130       return format (0, "dst-only");
4131     case 1:
4132       return format (0, "src-dst");
4133     }
4134   return 0;
4135 }
4136
4137 static void
4138   vl_api_show_one_map_request_mode_reply_t_handler
4139   (vl_api_show_one_map_request_mode_reply_t * mp)
4140 {
4141   vat_main_t *vam = &vat_main;
4142   i32 retval = ntohl (mp->retval);
4143
4144   if (0 <= retval)
4145     {
4146       u32 mode = mp->mode;
4147       print (vam->ofp, "map_request_mode: %U",
4148              format_lisp_map_request_mode, mode);
4149     }
4150
4151   vam->retval = retval;
4152   vam->result_ready = 1;
4153 }
4154
4155 static void
4156   vl_api_show_one_map_request_mode_reply_t_handler_json
4157   (vl_api_show_one_map_request_mode_reply_t * mp)
4158 {
4159   vat_main_t *vam = &vat_main;
4160   vat_json_node_t node;
4161   u8 *s = 0;
4162   u32 mode;
4163
4164   mode = mp->mode;
4165   s = format (0, "%U", format_lisp_map_request_mode, mode);
4166   vec_add1 (s, 0);
4167
4168   vat_json_init_object (&node);
4169   vat_json_object_add_string_copy (&node, "map_request_mode", s);
4170   vat_json_print (vam->ofp, &node);
4171   vat_json_free (&node);
4172
4173   vec_free (s);
4174   vam->retval = ntohl (mp->retval);
4175   vam->result_ready = 1;
4176 }
4177
4178 static void
4179   vl_api_one_show_xtr_mode_reply_t_handler
4180   (vl_api_one_show_xtr_mode_reply_t * mp)
4181 {
4182   vat_main_t *vam = &vat_main;
4183   i32 retval = ntohl (mp->retval);
4184
4185   if (0 <= retval)
4186     {
4187       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4188     }
4189
4190   vam->retval = retval;
4191   vam->result_ready = 1;
4192 }
4193
4194 static void
4195   vl_api_one_show_xtr_mode_reply_t_handler_json
4196   (vl_api_one_show_xtr_mode_reply_t * mp)
4197 {
4198   vat_main_t *vam = &vat_main;
4199   vat_json_node_t node;
4200   u8 *status = 0;
4201
4202   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4203   vec_add1 (status, 0);
4204
4205   vat_json_init_object (&node);
4206   vat_json_object_add_string_copy (&node, "status", status);
4207
4208   vec_free (status);
4209
4210   vat_json_print (vam->ofp, &node);
4211   vat_json_free (&node);
4212
4213   vam->retval = ntohl (mp->retval);
4214   vam->result_ready = 1;
4215 }
4216
4217 static void
4218   vl_api_one_show_pitr_mode_reply_t_handler
4219   (vl_api_one_show_pitr_mode_reply_t * mp)
4220 {
4221   vat_main_t *vam = &vat_main;
4222   i32 retval = ntohl (mp->retval);
4223
4224   if (0 <= retval)
4225     {
4226       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4227     }
4228
4229   vam->retval = retval;
4230   vam->result_ready = 1;
4231 }
4232
4233 static void
4234   vl_api_one_show_pitr_mode_reply_t_handler_json
4235   (vl_api_one_show_pitr_mode_reply_t * mp)
4236 {
4237   vat_main_t *vam = &vat_main;
4238   vat_json_node_t node;
4239   u8 *status = 0;
4240
4241   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4242   vec_add1 (status, 0);
4243
4244   vat_json_init_object (&node);
4245   vat_json_object_add_string_copy (&node, "status", status);
4246
4247   vec_free (status);
4248
4249   vat_json_print (vam->ofp, &node);
4250   vat_json_free (&node);
4251
4252   vam->retval = ntohl (mp->retval);
4253   vam->result_ready = 1;
4254 }
4255
4256 static void
4257   vl_api_one_show_petr_mode_reply_t_handler
4258   (vl_api_one_show_petr_mode_reply_t * mp)
4259 {
4260   vat_main_t *vam = &vat_main;
4261   i32 retval = ntohl (mp->retval);
4262
4263   if (0 <= retval)
4264     {
4265       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4266     }
4267
4268   vam->retval = retval;
4269   vam->result_ready = 1;
4270 }
4271
4272 static void
4273   vl_api_one_show_petr_mode_reply_t_handler_json
4274   (vl_api_one_show_petr_mode_reply_t * mp)
4275 {
4276   vat_main_t *vam = &vat_main;
4277   vat_json_node_t node;
4278   u8 *status = 0;
4279
4280   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4281   vec_add1 (status, 0);
4282
4283   vat_json_init_object (&node);
4284   vat_json_object_add_string_copy (&node, "status", status);
4285
4286   vec_free (status);
4287
4288   vat_json_print (vam->ofp, &node);
4289   vat_json_free (&node);
4290
4291   vam->retval = ntohl (mp->retval);
4292   vam->result_ready = 1;
4293 }
4294
4295 static void
4296   vl_api_show_one_use_petr_reply_t_handler
4297   (vl_api_show_one_use_petr_reply_t * mp)
4298 {
4299   vat_main_t *vam = &vat_main;
4300   i32 retval = ntohl (mp->retval);
4301
4302   if (0 <= retval)
4303     {
4304       print (vam->ofp, "%s\n", mp->status ? "enabled" : "disabled");
4305       if (mp->status)
4306         {
4307           print (vam->ofp, "Proxy-ETR address; %U",
4308                  mp->is_ip4 ? format_ip4_address : format_ip6_address,
4309                  mp->address);
4310         }
4311     }
4312
4313   vam->retval = retval;
4314   vam->result_ready = 1;
4315 }
4316
4317 static void
4318   vl_api_show_one_use_petr_reply_t_handler_json
4319   (vl_api_show_one_use_petr_reply_t * mp)
4320 {
4321   vat_main_t *vam = &vat_main;
4322   vat_json_node_t node;
4323   u8 *status = 0;
4324   struct in_addr ip4;
4325   struct in6_addr ip6;
4326
4327   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4328   vec_add1 (status, 0);
4329
4330   vat_json_init_object (&node);
4331   vat_json_object_add_string_copy (&node, "status", status);
4332   if (mp->status)
4333     {
4334       if (mp->is_ip4)
4335         {
4336           clib_memcpy (&ip6, mp->address, sizeof (ip6));
4337           vat_json_object_add_ip6 (&node, "address", ip6);
4338         }
4339       else
4340         {
4341           clib_memcpy (&ip4, mp->address, sizeof (ip4));
4342           vat_json_object_add_ip4 (&node, "address", ip4);
4343         }
4344     }
4345
4346   vec_free (status);
4347
4348   vat_json_print (vam->ofp, &node);
4349   vat_json_free (&node);
4350
4351   vam->retval = ntohl (mp->retval);
4352   vam->result_ready = 1;
4353 }
4354
4355 static void
4356   vl_api_show_one_nsh_mapping_reply_t_handler
4357   (vl_api_show_one_nsh_mapping_reply_t * mp)
4358 {
4359   vat_main_t *vam = &vat_main;
4360   i32 retval = ntohl (mp->retval);
4361
4362   if (0 <= retval)
4363     {
4364       print (vam->ofp, "%-20s%-16s",
4365              mp->is_set ? "set" : "not-set",
4366              mp->is_set ? (char *) mp->locator_set_name : "");
4367     }
4368
4369   vam->retval = retval;
4370   vam->result_ready = 1;
4371 }
4372
4373 static void
4374   vl_api_show_one_nsh_mapping_reply_t_handler_json
4375   (vl_api_show_one_nsh_mapping_reply_t * mp)
4376 {
4377   vat_main_t *vam = &vat_main;
4378   vat_json_node_t node;
4379   u8 *status = 0;
4380
4381   status = format (0, "%s", mp->is_set ? "yes" : "no");
4382   vec_add1 (status, 0);
4383
4384   vat_json_init_object (&node);
4385   vat_json_object_add_string_copy (&node, "is_set", status);
4386   if (mp->is_set)
4387     {
4388       vat_json_object_add_string_copy (&node, "locator_set",
4389                                        mp->locator_set_name);
4390     }
4391
4392   vec_free (status);
4393
4394   vat_json_print (vam->ofp, &node);
4395   vat_json_free (&node);
4396
4397   vam->retval = ntohl (mp->retval);
4398   vam->result_ready = 1;
4399 }
4400
4401 static void
4402   vl_api_show_one_map_register_ttl_reply_t_handler
4403   (vl_api_show_one_map_register_ttl_reply_t * mp)
4404 {
4405   vat_main_t *vam = &vat_main;
4406   i32 retval = ntohl (mp->retval);
4407
4408   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4409
4410   if (0 <= retval)
4411     {
4412       print (vam->ofp, "ttl: %u", mp->ttl);
4413     }
4414
4415   vam->retval = retval;
4416   vam->result_ready = 1;
4417 }
4418
4419 static void
4420   vl_api_show_one_map_register_ttl_reply_t_handler_json
4421   (vl_api_show_one_map_register_ttl_reply_t * mp)
4422 {
4423   vat_main_t *vam = &vat_main;
4424   vat_json_node_t node;
4425
4426   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4427   vat_json_init_object (&node);
4428   vat_json_object_add_uint (&node, "ttl", mp->ttl);
4429
4430   vat_json_print (vam->ofp, &node);
4431   vat_json_free (&node);
4432
4433   vam->retval = ntohl (mp->retval);
4434   vam->result_ready = 1;
4435 }
4436
4437 static void
4438 vl_api_show_one_pitr_reply_t_handler (vl_api_show_one_pitr_reply_t * mp)
4439 {
4440   vat_main_t *vam = &vat_main;
4441   i32 retval = ntohl (mp->retval);
4442
4443   if (0 <= retval)
4444     {
4445       print (vam->ofp, "%-20s%-16s",
4446              mp->status ? "enabled" : "disabled",
4447              mp->status ? (char *) mp->locator_set_name : "");
4448     }
4449
4450   vam->retval = retval;
4451   vam->result_ready = 1;
4452 }
4453
4454 static void
4455 vl_api_show_one_pitr_reply_t_handler_json (vl_api_show_one_pitr_reply_t * mp)
4456 {
4457   vat_main_t *vam = &vat_main;
4458   vat_json_node_t node;
4459   u8 *status = 0;
4460
4461   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4462   vec_add1 (status, 0);
4463
4464   vat_json_init_object (&node);
4465   vat_json_object_add_string_copy (&node, "status", status);
4466   if (mp->status)
4467     {
4468       vat_json_object_add_string_copy (&node, "locator_set",
4469                                        mp->locator_set_name);
4470     }
4471
4472   vec_free (status);
4473
4474   vat_json_print (vam->ofp, &node);
4475   vat_json_free (&node);
4476
4477   vam->retval = ntohl (mp->retval);
4478   vam->result_ready = 1;
4479 }
4480
4481 static u8 *
4482 format_policer_type (u8 * s, va_list * va)
4483 {
4484   u32 i = va_arg (*va, u32);
4485
4486   if (i == SSE2_QOS_POLICER_TYPE_1R2C)
4487     s = format (s, "1r2c");
4488   else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
4489     s = format (s, "1r3c");
4490   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
4491     s = format (s, "2r3c-2698");
4492   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
4493     s = format (s, "2r3c-4115");
4494   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
4495     s = format (s, "2r3c-mef5cf1");
4496   else
4497     s = format (s, "ILLEGAL");
4498   return s;
4499 }
4500
4501 static u8 *
4502 format_policer_rate_type (u8 * s, va_list * va)
4503 {
4504   u32 i = va_arg (*va, u32);
4505
4506   if (i == SSE2_QOS_RATE_KBPS)
4507     s = format (s, "kbps");
4508   else if (i == SSE2_QOS_RATE_PPS)
4509     s = format (s, "pps");
4510   else
4511     s = format (s, "ILLEGAL");
4512   return s;
4513 }
4514
4515 static u8 *
4516 format_policer_round_type (u8 * s, va_list * va)
4517 {
4518   u32 i = va_arg (*va, u32);
4519
4520   if (i == SSE2_QOS_ROUND_TO_CLOSEST)
4521     s = format (s, "closest");
4522   else if (i == SSE2_QOS_ROUND_TO_UP)
4523     s = format (s, "up");
4524   else if (i == SSE2_QOS_ROUND_TO_DOWN)
4525     s = format (s, "down");
4526   else
4527     s = format (s, "ILLEGAL");
4528   return s;
4529 }
4530
4531 static u8 *
4532 format_policer_action_type (u8 * s, va_list * va)
4533 {
4534   u32 i = va_arg (*va, u32);
4535
4536   if (i == SSE2_QOS_ACTION_DROP)
4537     s = format (s, "drop");
4538   else if (i == SSE2_QOS_ACTION_TRANSMIT)
4539     s = format (s, "transmit");
4540   else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4541     s = format (s, "mark-and-transmit");
4542   else
4543     s = format (s, "ILLEGAL");
4544   return s;
4545 }
4546
4547 static u8 *
4548 format_dscp (u8 * s, va_list * va)
4549 {
4550   u32 i = va_arg (*va, u32);
4551   char *t = 0;
4552
4553   switch (i)
4554     {
4555 #define _(v,f,str) case VNET_DSCP_##f: t = str; break;
4556       foreach_vnet_dscp
4557 #undef _
4558     default:
4559       return format (s, "ILLEGAL");
4560     }
4561   s = format (s, "%s", t);
4562   return s;
4563 }
4564
4565 static void
4566 vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
4567 {
4568   vat_main_t *vam = &vat_main;
4569   u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
4570
4571   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4572     conform_dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
4573   else
4574     conform_dscp_str = format (0, "");
4575
4576   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4577     exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
4578   else
4579     exceed_dscp_str = format (0, "");
4580
4581   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4582     violate_dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
4583   else
4584     violate_dscp_str = format (0, "");
4585
4586   print (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
4587          "rate type %U, round type %U, %s rate, %s color-aware, "
4588          "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
4589          "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
4590          "conform action %U%s, exceed action %U%s, violate action %U%s",
4591          mp->name,
4592          format_policer_type, mp->type,
4593          ntohl (mp->cir),
4594          ntohl (mp->eir),
4595          clib_net_to_host_u64 (mp->cb),
4596          clib_net_to_host_u64 (mp->eb),
4597          format_policer_rate_type, mp->rate_type,
4598          format_policer_round_type, mp->round_type,
4599          mp->single_rate ? "single" : "dual",
4600          mp->color_aware ? "is" : "not",
4601          ntohl (mp->cir_tokens_per_period),
4602          ntohl (mp->pir_tokens_per_period),
4603          ntohl (mp->scale),
4604          ntohl (mp->current_limit),
4605          ntohl (mp->current_bucket),
4606          ntohl (mp->extended_limit),
4607          ntohl (mp->extended_bucket),
4608          clib_net_to_host_u64 (mp->last_update_time),
4609          format_policer_action_type, mp->conform_action_type,
4610          conform_dscp_str,
4611          format_policer_action_type, mp->exceed_action_type,
4612          exceed_dscp_str,
4613          format_policer_action_type, mp->violate_action_type,
4614          violate_dscp_str);
4615
4616   vec_free (conform_dscp_str);
4617   vec_free (exceed_dscp_str);
4618   vec_free (violate_dscp_str);
4619 }
4620
4621 static void vl_api_policer_details_t_handler_json
4622   (vl_api_policer_details_t * mp)
4623 {
4624   vat_main_t *vam = &vat_main;
4625   vat_json_node_t *node;
4626   u8 *rate_type_str, *round_type_str, *type_str;
4627   u8 *conform_action_str, *exceed_action_str, *violate_action_str;
4628
4629   rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
4630   round_type_str =
4631     format (0, "%U", format_policer_round_type, mp->round_type);
4632   type_str = format (0, "%U", format_policer_type, mp->type);
4633   conform_action_str = format (0, "%U", format_policer_action_type,
4634                                mp->conform_action_type);
4635   exceed_action_str = format (0, "%U", format_policer_action_type,
4636                               mp->exceed_action_type);
4637   violate_action_str = format (0, "%U", format_policer_action_type,
4638                                mp->violate_action_type);
4639
4640   if (VAT_JSON_ARRAY != vam->json_tree.type)
4641     {
4642       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4643       vat_json_init_array (&vam->json_tree);
4644     }
4645   node = vat_json_array_add (&vam->json_tree);
4646
4647   vat_json_init_object (node);
4648   vat_json_object_add_string_copy (node, "name", mp->name);
4649   vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
4650   vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
4651   vat_json_object_add_uint (node, "cb", clib_net_to_host_u64 (mp->cb));
4652   vat_json_object_add_uint (node, "eb", clib_net_to_host_u64 (mp->eb));
4653   vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
4654   vat_json_object_add_string_copy (node, "round_type", round_type_str);
4655   vat_json_object_add_string_copy (node, "type", type_str);
4656   vat_json_object_add_uint (node, "single_rate", mp->single_rate);
4657   vat_json_object_add_uint (node, "color_aware", mp->color_aware);
4658   vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
4659   vat_json_object_add_uint (node, "cir_tokens_per_period",
4660                             ntohl (mp->cir_tokens_per_period));
4661   vat_json_object_add_uint (node, "eir_tokens_per_period",
4662                             ntohl (mp->pir_tokens_per_period));
4663   vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
4664   vat_json_object_add_uint (node, "current_bucket",
4665                             ntohl (mp->current_bucket));
4666   vat_json_object_add_uint (node, "extended_limit",
4667                             ntohl (mp->extended_limit));
4668   vat_json_object_add_uint (node, "extended_bucket",
4669                             ntohl (mp->extended_bucket));
4670   vat_json_object_add_uint (node, "last_update_time",
4671                             ntohl (mp->last_update_time));
4672   vat_json_object_add_string_copy (node, "conform_action",
4673                                    conform_action_str);
4674   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4675     {
4676       u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
4677       vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
4678       vec_free (dscp_str);
4679     }
4680   vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
4681   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4682     {
4683       u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
4684       vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
4685       vec_free (dscp_str);
4686     }
4687   vat_json_object_add_string_copy (node, "violate_action",
4688                                    violate_action_str);
4689   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4690     {
4691       u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
4692       vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
4693       vec_free (dscp_str);
4694     }
4695
4696   vec_free (rate_type_str);
4697   vec_free (round_type_str);
4698   vec_free (type_str);
4699   vec_free (conform_action_str);
4700   vec_free (exceed_action_str);
4701   vec_free (violate_action_str);
4702 }
4703
4704 static void
4705 vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
4706                                            mp)
4707 {
4708   vat_main_t *vam = &vat_main;
4709   int i, count = ntohl (mp->count);
4710
4711   if (count > 0)
4712     print (vam->ofp, "classify table ids (%d) : ", count);
4713   for (i = 0; i < count; i++)
4714     {
4715       print (vam->ofp, "%d", ntohl (mp->ids[i]));
4716       print (vam->ofp, (i < count - 1) ? "," : "");
4717     }
4718   vam->retval = ntohl (mp->retval);
4719   vam->result_ready = 1;
4720 }
4721
4722 static void
4723   vl_api_classify_table_ids_reply_t_handler_json
4724   (vl_api_classify_table_ids_reply_t * mp)
4725 {
4726   vat_main_t *vam = &vat_main;
4727   int i, count = ntohl (mp->count);
4728
4729   if (count > 0)
4730     {
4731       vat_json_node_t node;
4732
4733       vat_json_init_object (&node);
4734       for (i = 0; i < count; i++)
4735         {
4736           vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
4737         }
4738       vat_json_print (vam->ofp, &node);
4739       vat_json_free (&node);
4740     }
4741   vam->retval = ntohl (mp->retval);
4742   vam->result_ready = 1;
4743 }
4744
4745 static void
4746   vl_api_classify_table_by_interface_reply_t_handler
4747   (vl_api_classify_table_by_interface_reply_t * mp)
4748 {
4749   vat_main_t *vam = &vat_main;
4750   u32 table_id;
4751
4752   table_id = ntohl (mp->l2_table_id);
4753   if (table_id != ~0)
4754     print (vam->ofp, "l2 table id : %d", table_id);
4755   else
4756     print (vam->ofp, "l2 table id : No input ACL tables configured");
4757   table_id = ntohl (mp->ip4_table_id);
4758   if (table_id != ~0)
4759     print (vam->ofp, "ip4 table id : %d", table_id);
4760   else
4761     print (vam->ofp, "ip4 table id : No input ACL tables configured");
4762   table_id = ntohl (mp->ip6_table_id);
4763   if (table_id != ~0)
4764     print (vam->ofp, "ip6 table id : %d", table_id);
4765   else
4766     print (vam->ofp, "ip6 table id : No input ACL tables configured");
4767   vam->retval = ntohl (mp->retval);
4768   vam->result_ready = 1;
4769 }
4770
4771 static void
4772   vl_api_classify_table_by_interface_reply_t_handler_json
4773   (vl_api_classify_table_by_interface_reply_t * mp)
4774 {
4775   vat_main_t *vam = &vat_main;
4776   vat_json_node_t node;
4777
4778   vat_json_init_object (&node);
4779
4780   vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
4781   vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
4782   vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
4783
4784   vat_json_print (vam->ofp, &node);
4785   vat_json_free (&node);
4786
4787   vam->retval = ntohl (mp->retval);
4788   vam->result_ready = 1;
4789 }
4790
4791 static void vl_api_policer_add_del_reply_t_handler
4792   (vl_api_policer_add_del_reply_t * mp)
4793 {
4794   vat_main_t *vam = &vat_main;
4795   i32 retval = ntohl (mp->retval);
4796   if (vam->async_mode)
4797     {
4798       vam->async_errors += (retval < 0);
4799     }
4800   else
4801     {
4802       vam->retval = retval;
4803       vam->result_ready = 1;
4804       if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
4805         /*
4806          * Note: this is just barely thread-safe, depends on
4807          * the main thread spinning waiting for an answer...
4808          */
4809         errmsg ("policer index %d", ntohl (mp->policer_index));
4810     }
4811 }
4812
4813 static void vl_api_policer_add_del_reply_t_handler_json
4814   (vl_api_policer_add_del_reply_t * mp)
4815 {
4816   vat_main_t *vam = &vat_main;
4817   vat_json_node_t node;
4818
4819   vat_json_init_object (&node);
4820   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
4821   vat_json_object_add_uint (&node, "policer_index",
4822                             ntohl (mp->policer_index));
4823
4824   vat_json_print (vam->ofp, &node);
4825   vat_json_free (&node);
4826
4827   vam->retval = ntohl (mp->retval);
4828   vam->result_ready = 1;
4829 }
4830
4831 /* Format hex dump. */
4832 u8 *
4833 format_hex_bytes (u8 * s, va_list * va)
4834 {
4835   u8 *bytes = va_arg (*va, u8 *);
4836   int n_bytes = va_arg (*va, int);
4837   uword i;
4838
4839   /* Print short or long form depending on byte count. */
4840   uword short_form = n_bytes <= 32;
4841   u32 indent = format_get_indent (s);
4842
4843   if (n_bytes == 0)
4844     return s;
4845
4846   for (i = 0; i < n_bytes; i++)
4847     {
4848       if (!short_form && (i % 32) == 0)
4849         s = format (s, "%08x: ", i);
4850       s = format (s, "%02x", bytes[i]);
4851       if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
4852         s = format (s, "\n%U", format_white_space, indent);
4853     }
4854
4855   return s;
4856 }
4857
4858 static void
4859 vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
4860                                             * mp)
4861 {
4862   vat_main_t *vam = &vat_main;
4863   i32 retval = ntohl (mp->retval);
4864   if (retval == 0)
4865     {
4866       print (vam->ofp, "classify table info :");
4867       print (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d",
4868              ntohl (mp->active_sessions), ntohl (mp->next_table_index),
4869              ntohl (mp->miss_next_index));
4870       print (vam->ofp, "nbuckets: %d skip: %d match: %d",
4871              ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
4872              ntohl (mp->match_n_vectors));
4873       print (vam->ofp, "mask: %U", format_hex_bytes, mp->mask,
4874              ntohl (mp->mask_length));
4875     }
4876   vam->retval = retval;
4877   vam->result_ready = 1;
4878 }
4879
4880 static void
4881   vl_api_classify_table_info_reply_t_handler_json
4882   (vl_api_classify_table_info_reply_t * mp)
4883 {
4884   vat_main_t *vam = &vat_main;
4885   vat_json_node_t node;
4886
4887   i32 retval = ntohl (mp->retval);
4888   if (retval == 0)
4889     {
4890       vat_json_init_object (&node);
4891
4892       vat_json_object_add_int (&node, "sessions",
4893                                ntohl (mp->active_sessions));
4894       vat_json_object_add_int (&node, "nexttbl",
4895                                ntohl (mp->next_table_index));
4896       vat_json_object_add_int (&node, "nextnode",
4897                                ntohl (mp->miss_next_index));
4898       vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
4899       vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
4900       vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
4901       u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
4902                       ntohl (mp->mask_length), 0);
4903       vat_json_object_add_string_copy (&node, "mask", s);
4904
4905       vat_json_print (vam->ofp, &node);
4906       vat_json_free (&node);
4907     }
4908   vam->retval = ntohl (mp->retval);
4909   vam->result_ready = 1;
4910 }
4911
4912 static void
4913 vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
4914                                            mp)
4915 {
4916   vat_main_t *vam = &vat_main;
4917
4918   print (vam->ofp, "next_index: %d advance: %d opaque: %d ",
4919          ntohl (mp->hit_next_index), ntohl (mp->advance),
4920          ntohl (mp->opaque_index));
4921   print (vam->ofp, "mask: %U", format_hex_bytes, mp->match,
4922          ntohl (mp->match_length));
4923 }
4924
4925 static void
4926   vl_api_classify_session_details_t_handler_json
4927   (vl_api_classify_session_details_t * mp)
4928 {
4929   vat_main_t *vam = &vat_main;
4930   vat_json_node_t *node = NULL;
4931
4932   if (VAT_JSON_ARRAY != vam->json_tree.type)
4933     {
4934       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4935       vat_json_init_array (&vam->json_tree);
4936     }
4937   node = vat_json_array_add (&vam->json_tree);
4938
4939   vat_json_init_object (node);
4940   vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
4941   vat_json_object_add_int (node, "advance", ntohl (mp->advance));
4942   vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
4943   u8 *s =
4944     format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
4945             0);
4946   vat_json_object_add_string_copy (node, "match", s);
4947 }
4948
4949 static void vl_api_pg_create_interface_reply_t_handler
4950   (vl_api_pg_create_interface_reply_t * mp)
4951 {
4952   vat_main_t *vam = &vat_main;
4953
4954   vam->retval = ntohl (mp->retval);
4955   vam->result_ready = 1;
4956 }
4957
4958 static void vl_api_pg_create_interface_reply_t_handler_json
4959   (vl_api_pg_create_interface_reply_t * mp)
4960 {
4961   vat_main_t *vam = &vat_main;
4962   vat_json_node_t node;
4963
4964   i32 retval = ntohl (mp->retval);
4965   if (retval == 0)
4966     {
4967       vat_json_init_object (&node);
4968
4969       vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
4970
4971       vat_json_print (vam->ofp, &node);
4972       vat_json_free (&node);
4973     }
4974   vam->retval = ntohl (mp->retval);
4975   vam->result_ready = 1;
4976 }
4977
4978 static void vl_api_policer_classify_details_t_handler
4979   (vl_api_policer_classify_details_t * mp)
4980 {
4981   vat_main_t *vam = &vat_main;
4982
4983   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
4984          ntohl (mp->table_index));
4985 }
4986
4987 static void vl_api_policer_classify_details_t_handler_json
4988   (vl_api_policer_classify_details_t * mp)
4989 {
4990   vat_main_t *vam = &vat_main;
4991   vat_json_node_t *node;
4992
4993   if (VAT_JSON_ARRAY != vam->json_tree.type)
4994     {
4995       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4996       vat_json_init_array (&vam->json_tree);
4997     }
4998   node = vat_json_array_add (&vam->json_tree);
4999
5000   vat_json_init_object (node);
5001   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
5002   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
5003 }
5004
5005 static void vl_api_flow_classify_details_t_handler
5006   (vl_api_flow_classify_details_t * mp)
5007 {
5008   vat_main_t *vam = &vat_main;
5009
5010   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
5011          ntohl (mp->table_index));
5012 }
5013
5014 static void vl_api_flow_classify_details_t_handler_json
5015   (vl_api_flow_classify_details_t * mp)
5016 {
5017   vat_main_t *vam = &vat_main;
5018   vat_json_node_t *node;
5019
5020   if (VAT_JSON_ARRAY != vam->json_tree.type)
5021     {
5022       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5023       vat_json_init_array (&vam->json_tree);
5024     }
5025   node = vat_json_array_add (&vam->json_tree);
5026
5027   vat_json_init_object (node);
5028   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
5029   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
5030 }
5031
5032 #define vl_api_one_adjacencies_get_reply_t_endian vl_noop_handler
5033 #define vl_api_one_adjacencies_get_reply_t_print vl_noop_handler
5034 #define vl_api_one_l2_arp_bd_get_reply_t_print vl_noop_handler
5035 #define vl_api_one_l2_arp_entries_get_reply_t_endian vl_noop_handler
5036 #define vl_api_one_l2_arp_entries_get_reply_t_print vl_noop_handler
5037 #define vl_api_one_l2_arp_bd_get_reply_t_endian vl_noop_handler
5038 #define vl_api_one_ndp_bd_get_reply_t_endian vl_noop_handler
5039 #define vl_api_one_ndp_bd_get_reply_t_print vl_noop_handler
5040 #define vl_api_one_ndp_entries_get_reply_t_print vl_noop_handler
5041 #define vl_api_one_ndp_entries_get_reply_t_endian vl_noop_handler
5042
5043 /*
5044  * Generate boilerplate reply handlers, which
5045  * dig the return value out of the xxx_reply_t API message,
5046  * stick it into vam->retval, and set vam->result_ready
5047  *
5048  * Could also do this by pointing N message decode slots at
5049  * a single function, but that could break in subtle ways.
5050  */
5051
5052 #define foreach_standard_reply_retval_handler           \
5053 _(sw_interface_set_flags_reply)                         \
5054 _(sw_interface_add_del_address_reply)                   \
5055 _(sw_interface_set_rx_mode_reply)                       \
5056 _(sw_interface_set_rx_placement_reply)                  \
5057 _(sw_interface_set_table_reply)                         \
5058 _(sw_interface_set_mpls_enable_reply)                   \
5059 _(sw_interface_set_vpath_reply)                         \
5060 _(sw_interface_set_vxlan_bypass_reply)                  \
5061 _(sw_interface_set_geneve_bypass_reply)                 \
5062 _(sw_interface_set_vxlan_gpe_bypass_reply)              \
5063 _(sw_interface_set_l2_bridge_reply)                     \
5064 _(sw_interface_set_bond_weight_reply)                   \
5065 _(bridge_domain_add_del_reply)                          \
5066 _(sw_interface_set_l2_xconnect_reply)                   \
5067 _(l2fib_add_del_reply)                                  \
5068 _(l2fib_flush_int_reply)                                \
5069 _(l2fib_flush_bd_reply)                                 \
5070 _(ip_route_add_del_reply)                               \
5071 _(ip_table_add_del_reply)                               \
5072 _(ip_mroute_add_del_reply)                              \
5073 _(mpls_route_add_del_reply)                             \
5074 _(mpls_table_add_del_reply)                             \
5075 _(mpls_ip_bind_unbind_reply)                            \
5076 _(bier_route_add_del_reply)                             \
5077 _(bier_table_add_del_reply)                             \
5078 _(proxy_arp_add_del_reply)                              \
5079 _(proxy_arp_intfc_enable_disable_reply)                 \
5080 _(sw_interface_set_unnumbered_reply)                    \
5081 _(ip_neighbor_add_del_reply)                            \
5082 _(reset_fib_reply)                                      \
5083 _(set_ip_flow_hash_reply)                               \
5084 _(sw_interface_ip6_enable_disable_reply)                \
5085 _(ip6nd_proxy_add_del_reply)                            \
5086 _(sw_interface_ip6nd_ra_prefix_reply)                   \
5087 _(sw_interface_ip6nd_ra_config_reply)                   \
5088 _(set_arp_neighbor_limit_reply)                         \
5089 _(l2_patch_add_del_reply)                               \
5090 _(sr_mpls_policy_add_reply)                             \
5091 _(sr_mpls_policy_mod_reply)                             \
5092 _(sr_mpls_policy_del_reply)                             \
5093 _(sr_policy_add_reply)                                  \
5094 _(sr_policy_mod_reply)                                  \
5095 _(sr_policy_del_reply)                                  \
5096 _(sr_localsid_add_del_reply)                            \
5097 _(sr_steering_add_del_reply)                            \
5098 _(classify_add_del_session_reply)                       \
5099 _(classify_set_interface_ip_table_reply)                \
5100 _(classify_set_interface_l2_tables_reply)               \
5101 _(l2tpv3_set_tunnel_cookies_reply)                      \
5102 _(l2tpv3_interface_enable_disable_reply)                \
5103 _(l2tpv3_set_lookup_key_reply)                          \
5104 _(l2_fib_clear_table_reply)                             \
5105 _(l2_interface_efp_filter_reply)                        \
5106 _(l2_interface_vlan_tag_rewrite_reply)                  \
5107 _(modify_vhost_user_if_reply)                           \
5108 _(delete_vhost_user_if_reply)                           \
5109 _(ip_probe_neighbor_reply)                              \
5110 _(ip_scan_neighbor_enable_disable_reply)                \
5111 _(want_ip4_arp_events_reply)                            \
5112 _(want_ip6_nd_events_reply)                             \
5113 _(want_l2_macs_events_reply)                            \
5114 _(input_acl_set_interface_reply)                        \
5115 _(ipsec_spd_add_del_reply)                              \
5116 _(ipsec_interface_add_del_spd_reply)                    \
5117 _(ipsec_spd_entry_add_del_reply)                        \
5118 _(ipsec_sad_entry_add_del_reply)                        \
5119 _(ipsec_tunnel_if_add_del_reply)                        \
5120 _(ipsec_tunnel_if_set_sa_reply)                         \
5121 _(delete_loopback_reply)                                \
5122 _(bd_ip_mac_add_del_reply)                              \
5123 _(bd_ip_mac_flush_reply)                                \
5124 _(want_interface_events_reply)                          \
5125 _(cop_interface_enable_disable_reply)                   \
5126 _(cop_whitelist_enable_disable_reply)                   \
5127 _(sw_interface_clear_stats_reply)                       \
5128 _(ioam_enable_reply)                                    \
5129 _(ioam_disable_reply)                                   \
5130 _(one_add_del_locator_reply)                            \
5131 _(one_add_del_local_eid_reply)                          \
5132 _(one_add_del_remote_mapping_reply)                     \
5133 _(one_add_del_adjacency_reply)                          \
5134 _(one_add_del_map_resolver_reply)                       \
5135 _(one_add_del_map_server_reply)                         \
5136 _(one_enable_disable_reply)                             \
5137 _(one_rloc_probe_enable_disable_reply)                  \
5138 _(one_map_register_enable_disable_reply)                \
5139 _(one_map_register_set_ttl_reply)                       \
5140 _(one_set_transport_protocol_reply)                     \
5141 _(one_map_register_fallback_threshold_reply)            \
5142 _(one_pitr_set_locator_set_reply)                       \
5143 _(one_map_request_mode_reply)                           \
5144 _(one_add_del_map_request_itr_rlocs_reply)              \
5145 _(one_eid_table_add_del_map_reply)                      \
5146 _(one_use_petr_reply)                                   \
5147 _(one_stats_enable_disable_reply)                       \
5148 _(one_add_del_l2_arp_entry_reply)                       \
5149 _(one_add_del_ndp_entry_reply)                          \
5150 _(one_stats_flush_reply)                                \
5151 _(one_enable_disable_xtr_mode_reply)                    \
5152 _(one_enable_disable_pitr_mode_reply)                   \
5153 _(one_enable_disable_petr_mode_reply)                   \
5154 _(gpe_enable_disable_reply)                             \
5155 _(gpe_set_encap_mode_reply)                             \
5156 _(gpe_add_del_iface_reply)                              \
5157 _(gpe_add_del_native_fwd_rpath_reply)                   \
5158 _(af_packet_delete_reply)                               \
5159 _(policer_classify_set_interface_reply)                 \
5160 _(netmap_create_reply)                                  \
5161 _(netmap_delete_reply)                                  \
5162 _(set_ipfix_exporter_reply)                             \
5163 _(set_ipfix_classify_stream_reply)                      \
5164 _(ipfix_classify_table_add_del_reply)                   \
5165 _(flow_classify_set_interface_reply)                    \
5166 _(sw_interface_span_enable_disable_reply)               \
5167 _(pg_capture_reply)                                     \
5168 _(pg_enable_disable_reply)                              \
5169 _(ip_source_and_port_range_check_add_del_reply)         \
5170 _(ip_source_and_port_range_check_interface_add_del_reply)\
5171 _(delete_subif_reply)                                   \
5172 _(l2_interface_pbb_tag_rewrite_reply)                   \
5173 _(set_punt_reply)                                       \
5174 _(feature_enable_disable_reply)                         \
5175 _(sw_interface_tag_add_del_reply)                       \
5176 _(sw_interface_add_del_mac_address_reply)               \
5177 _(hw_interface_set_mtu_reply)                           \
5178 _(p2p_ethernet_add_reply)                               \
5179 _(p2p_ethernet_del_reply)                               \
5180 _(lldp_config_reply)                                    \
5181 _(sw_interface_set_lldp_reply)                          \
5182 _(tcp_configure_src_addresses_reply)                    \
5183 _(session_rule_add_del_reply)                           \
5184 _(ip_container_proxy_add_del_reply)                     \
5185 _(output_acl_set_interface_reply)                       \
5186 _(qos_record_enable_disable_reply)
5187
5188 #define _(n)                                    \
5189     static void vl_api_##n##_t_handler          \
5190     (vl_api_##n##_t * mp)                       \
5191     {                                           \
5192         vat_main_t * vam = &vat_main;           \
5193         i32 retval = ntohl(mp->retval);         \
5194         if (vam->async_mode) {                  \
5195             vam->async_errors += (retval < 0);  \
5196         } else {                                \
5197             vam->retval = retval;               \
5198             vam->result_ready = 1;              \
5199         }                                       \
5200     }
5201 foreach_standard_reply_retval_handler;
5202 #undef _
5203
5204 #define _(n)                                    \
5205     static void vl_api_##n##_t_handler_json     \
5206     (vl_api_##n##_t * mp)                       \
5207     {                                           \
5208         vat_main_t * vam = &vat_main;           \
5209         vat_json_node_t node;                   \
5210         vat_json_init_object(&node);            \
5211         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
5212         vat_json_print(vam->ofp, &node);        \
5213         vam->retval = ntohl(mp->retval);        \
5214         vam->result_ready = 1;                  \
5215     }
5216 foreach_standard_reply_retval_handler;
5217 #undef _
5218
5219 /*
5220  * Table of message reply handlers, must include boilerplate handlers
5221  * we just generated
5222  */
5223
5224 #define foreach_vpe_api_reply_msg                                       \
5225 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
5226 _(CREATE_LOOPBACK_INSTANCE_REPLY, create_loopback_instance_reply)       \
5227 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
5228 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
5229 _(CONTROL_PING_REPLY, control_ping_reply)                               \
5230 _(CLI_REPLY, cli_reply)                                                 \
5231 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
5232 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
5233   sw_interface_add_del_address_reply)                                   \
5234 _(SW_INTERFACE_SET_RX_MODE_REPLY, sw_interface_set_rx_mode_reply)       \
5235 _(SW_INTERFACE_SET_RX_PLACEMENT_REPLY, sw_interface_set_rx_placement_reply)     \
5236 _(SW_INTERFACE_RX_PLACEMENT_DETAILS, sw_interface_rx_placement_details) \
5237 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
5238 _(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
5239 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
5240 _(SW_INTERFACE_SET_VXLAN_BYPASS_REPLY, sw_interface_set_vxlan_bypass_reply) \
5241 _(SW_INTERFACE_SET_GENEVE_BYPASS_REPLY, sw_interface_set_geneve_bypass_reply) \
5242 _(SW_INTERFACE_SET_VXLAN_GPE_BYPASS_REPLY, sw_interface_set_vxlan_gpe_bypass_reply) \
5243 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
5244   sw_interface_set_l2_xconnect_reply)                                   \
5245 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
5246   sw_interface_set_l2_bridge_reply)                                     \
5247 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
5248 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
5249 _(BRIDGE_DOMAIN_SET_MAC_AGE_REPLY, bridge_domain_set_mac_age_reply)     \
5250 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
5251 _(L2FIB_FLUSH_INT_REPLY, l2fib_flush_int_reply)                         \
5252 _(L2FIB_FLUSH_BD_REPLY, l2fib_flush_bd_reply)                           \
5253 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
5254 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
5255 _(TAP_CREATE_V2_REPLY, tap_create_v2_reply)                             \
5256 _(TAP_DELETE_V2_REPLY, tap_delete_v2_reply)                             \
5257 _(SW_INTERFACE_TAP_V2_DETAILS, sw_interface_tap_v2_details)             \
5258 _(VIRTIO_PCI_CREATE_REPLY, virtio_pci_create_reply)                     \
5259 _(VIRTIO_PCI_DELETE_REPLY, virtio_pci_delete_reply)                     \
5260 _(SW_INTERFACE_VIRTIO_PCI_DETAILS, sw_interface_virtio_pci_details)     \
5261 _(BOND_CREATE_REPLY, bond_create_reply)                                 \
5262 _(BOND_DELETE_REPLY, bond_delete_reply)                                 \
5263 _(BOND_ENSLAVE_REPLY, bond_enslave_reply)                               \
5264 _(BOND_DETACH_SLAVE_REPLY, bond_detach_slave_reply)                     \
5265 _(SW_INTERFACE_SET_BOND_WEIGHT_REPLY, sw_interface_set_bond_weight_reply) \
5266 _(SW_INTERFACE_BOND_DETAILS, sw_interface_bond_details)                 \
5267 _(SW_INTERFACE_SLAVE_DETAILS, sw_interface_slave_details)               \
5268 _(IP_ROUTE_ADD_DEL_REPLY, ip_route_add_del_reply)                       \
5269 _(IP_TABLE_ADD_DEL_REPLY, ip_table_add_del_reply)                       \
5270 _(IP_MROUTE_ADD_DEL_REPLY, ip_mroute_add_del_reply)                     \
5271 _(MPLS_TABLE_ADD_DEL_REPLY, mpls_table_add_del_reply)                   \
5272 _(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply)                   \
5273 _(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply)                 \
5274 _(BIER_ROUTE_ADD_DEL_REPLY, bier_route_add_del_reply)                   \
5275 _(BIER_TABLE_ADD_DEL_REPLY, bier_table_add_del_reply)                   \
5276 _(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply)                     \
5277 _(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY,                                 \
5278   proxy_arp_intfc_enable_disable_reply)                                 \
5279 _(MPLS_TUNNEL_ADD_DEL_REPLY, mpls_tunnel_add_del_reply)                 \
5280 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
5281   sw_interface_set_unnumbered_reply)                                    \
5282 _(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply)                 \
5283 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
5284 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
5285 _(RESET_FIB_REPLY, reset_fib_reply)                                     \
5286 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
5287 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
5288   sw_interface_ip6_enable_disable_reply)                                \
5289 _(IP6ND_PROXY_ADD_DEL_REPLY, ip6nd_proxy_add_del_reply)                 \
5290 _(IP6ND_PROXY_DETAILS, ip6nd_proxy_details)                             \
5291 _(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY,                                   \
5292   sw_interface_ip6nd_ra_prefix_reply)                                   \
5293 _(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY,                                   \
5294   sw_interface_ip6nd_ra_config_reply)                                   \
5295 _(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply)           \
5296 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
5297 _(SR_MPLS_POLICY_ADD_REPLY, sr_mpls_policy_add_reply)                   \
5298 _(SR_MPLS_POLICY_MOD_REPLY, sr_mpls_policy_mod_reply)                   \
5299 _(SR_MPLS_POLICY_DEL_REPLY, sr_mpls_policy_del_reply)                   \
5300 _(SR_POLICY_ADD_REPLY, sr_policy_add_reply)                             \
5301 _(SR_POLICY_MOD_REPLY, sr_policy_mod_reply)                             \
5302 _(SR_POLICY_DEL_REPLY, sr_policy_del_reply)                             \
5303 _(SR_LOCALSID_ADD_DEL_REPLY, sr_localsid_add_del_reply)                 \
5304 _(SR_STEERING_ADD_DEL_REPLY, sr_steering_add_del_reply)                 \
5305 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
5306 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
5307 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
5308 classify_set_interface_ip_table_reply)                                  \
5309 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
5310   classify_set_interface_l2_tables_reply)                               \
5311 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
5312 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
5313 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
5314 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
5315 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
5316   l2tpv3_interface_enable_disable_reply)                                \
5317 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
5318 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
5319 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
5320 _(VXLAN_OFFLOAD_RX_REPLY, vxlan_offload_rx_reply)               \
5321 _(GENEVE_ADD_DEL_TUNNEL_REPLY, geneve_add_del_tunnel_reply)             \
5322 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
5323 _(GENEVE_TUNNEL_DETAILS, geneve_tunnel_details)                         \
5324 _(GRE_TUNNEL_ADD_DEL_REPLY, gre_tunnel_add_del_reply)                   \
5325 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
5326 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
5327 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
5328 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
5329 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
5330 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
5331 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
5332 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
5333 _(SHOW_VERSION_REPLY, show_version_reply)                               \
5334 _(SHOW_THREADS_REPLY, show_threads_reply)                               \
5335 _(L2_FIB_TABLE_DETAILS, l2_fib_table_details)                           \
5336 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)       \
5337 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
5338 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
5339 _(IP_PROBE_NEIGHBOR_REPLY, ip_probe_neighbor_reply)                     \
5340 _(IP_SCAN_NEIGHBOR_ENABLE_DISABLE_REPLY, ip_scan_neighbor_enable_disable_reply) \
5341 _(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply)                 \
5342 _(IP4_ARP_EVENT, ip4_arp_event)                                         \
5343 _(WANT_IP6_ND_EVENTS_REPLY, want_ip6_nd_events_reply)                   \
5344 _(IP6_ND_EVENT, ip6_nd_event)                                           \
5345 _(WANT_L2_MACS_EVENTS_REPLY, want_l2_macs_events_reply)                 \
5346 _(L2_MACS_EVENT, l2_macs_event)                                         \
5347 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
5348 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
5349 _(IP_DETAILS, ip_details)                                               \
5350 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
5351 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
5352 _(IPSEC_SPD_ENTRY_ADD_DEL_REPLY, ipsec_spd_entry_add_del_reply)         \
5353 _(IPSEC_SAD_ENTRY_ADD_DEL_REPLY, ipsec_sad_entry_add_del_reply)         \
5354 _(IPSEC_SA_DETAILS, ipsec_sa_details)                                   \
5355 _(IPSEC_TUNNEL_IF_ADD_DEL_REPLY, ipsec_tunnel_if_add_del_reply)         \
5356 _(IPSEC_TUNNEL_IF_SET_SA_REPLY, ipsec_tunnel_if_set_sa_reply)           \
5357 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
5358 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
5359 _(BD_IP_MAC_FLUSH_REPLY, bd_ip_mac_flush_reply)                         \
5360 _(BD_IP_MAC_DETAILS, bd_ip_mac_details)                                 \
5361 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
5362 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
5363 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
5364 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
5365 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
5366 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
5367 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
5368 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
5369 _(ONE_ADD_DEL_LOCATOR_SET_REPLY, one_add_del_locator_set_reply)         \
5370 _(ONE_ADD_DEL_LOCATOR_REPLY, one_add_del_locator_reply)                 \
5371 _(ONE_ADD_DEL_LOCAL_EID_REPLY, one_add_del_local_eid_reply)             \
5372 _(ONE_ADD_DEL_REMOTE_MAPPING_REPLY, one_add_del_remote_mapping_reply)   \
5373 _(ONE_ADD_DEL_ADJACENCY_REPLY, one_add_del_adjacency_reply)             \
5374 _(ONE_ADD_DEL_MAP_RESOLVER_REPLY, one_add_del_map_resolver_reply)       \
5375 _(ONE_ADD_DEL_MAP_SERVER_REPLY, one_add_del_map_server_reply)           \
5376 _(ONE_ENABLE_DISABLE_REPLY, one_enable_disable_reply)                   \
5377 _(ONE_MAP_REGISTER_ENABLE_DISABLE_REPLY,                                \
5378   one_map_register_enable_disable_reply)                                \
5379 _(ONE_MAP_REGISTER_SET_TTL_REPLY, one_map_register_set_ttl_reply)       \
5380 _(ONE_SET_TRANSPORT_PROTOCOL_REPLY, one_set_transport_protocol_reply)   \
5381 _(ONE_GET_TRANSPORT_PROTOCOL_REPLY, one_get_transport_protocol_reply)   \
5382 _(ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                            \
5383   one_map_register_fallback_threshold_reply)                            \
5384 _(ONE_RLOC_PROBE_ENABLE_DISABLE_REPLY,                                  \
5385   one_rloc_probe_enable_disable_reply)                                  \
5386 _(ONE_PITR_SET_LOCATOR_SET_REPLY, one_pitr_set_locator_set_reply)       \
5387 _(ONE_USE_PETR_REPLY, one_use_petr_reply)                               \
5388 _(ONE_MAP_REQUEST_MODE_REPLY, one_map_request_mode_reply)               \
5389 _(ONE_EID_TABLE_ADD_DEL_MAP_REPLY, one_eid_table_add_del_map_reply)     \
5390 _(ONE_LOCATOR_SET_DETAILS, one_locator_set_details)                     \
5391 _(ONE_LOCATOR_DETAILS, one_locator_details)                             \
5392 _(ONE_EID_TABLE_DETAILS, one_eid_table_details)                         \
5393 _(ONE_EID_TABLE_MAP_DETAILS, one_eid_table_map_details)                 \
5394 _(ONE_EID_TABLE_VNI_DETAILS, one_eid_table_vni_details)                 \
5395 _(ONE_MAP_RESOLVER_DETAILS, one_map_resolver_details)                   \
5396 _(ONE_MAP_SERVER_DETAILS, one_map_server_details)                       \
5397 _(ONE_ADJACENCIES_GET_REPLY, one_adjacencies_get_reply)                 \
5398 _(ONE_STATS_DETAILS, one_stats_details)                                 \
5399 _(ONE_STATS_FLUSH_REPLY, one_stats_flush_reply)                         \
5400 _(ONE_STATS_ENABLE_DISABLE_REPLY, one_stats_enable_disable_reply)       \
5401 _(SHOW_ONE_STATS_ENABLE_DISABLE_REPLY,                                  \
5402   show_one_stats_enable_disable_reply)                                  \
5403 _(ONE_ADD_DEL_NDP_ENTRY_REPLY, one_add_del_ndp_entry_reply)             \
5404 _(ONE_NDP_BD_GET_REPLY, one_ndp_bd_get_reply)                           \
5405 _(ONE_NDP_ENTRIES_GET_REPLY, one_ndp_entries_get_reply)                 \
5406 _(ONE_ADD_DEL_L2_ARP_ENTRY_REPLY, one_add_del_l2_arp_entry_reply)       \
5407 _(ONE_L2_ARP_BD_GET_REPLY, one_l2_arp_bd_get_reply)                     \
5408 _(ONE_L2_ARP_ENTRIES_GET_REPLY, one_l2_arp_entries_get_reply)           \
5409 _(ONE_ENABLE_DISABLE_XTR_MODE_REPLY, one_enable_disable_xtr_mode_reply) \
5410 _(ONE_ENABLE_DISABLE_PITR_MODE_REPLY,                                   \
5411   one_enable_disable_pitr_mode_reply)                                   \
5412 _(ONE_ENABLE_DISABLE_PETR_MODE_REPLY,                                   \
5413   one_enable_disable_petr_mode_reply)                                   \
5414 _(ONE_SHOW_XTR_MODE_REPLY, one_show_xtr_mode_reply)                     \
5415 _(ONE_SHOW_PITR_MODE_REPLY, one_show_pitr_mode_reply)                   \
5416 _(ONE_SHOW_PETR_MODE_REPLY, one_show_petr_mode_reply)                   \
5417 _(GPE_SET_ENCAP_MODE_REPLY, gpe_set_encap_mode_reply)                   \
5418 _(GPE_GET_ENCAP_MODE_REPLY, gpe_get_encap_mode_reply)                   \
5419 _(GPE_ADD_DEL_IFACE_REPLY, gpe_add_del_iface_reply)                     \
5420 _(GPE_ENABLE_DISABLE_REPLY, gpe_enable_disable_reply)                   \
5421 _(GPE_ADD_DEL_FWD_ENTRY_REPLY, gpe_add_del_fwd_entry_reply)             \
5422 _(GPE_FWD_ENTRY_VNIS_GET_REPLY, gpe_fwd_entry_vnis_get_reply)           \
5423 _(GPE_FWD_ENTRIES_GET_REPLY, gpe_fwd_entries_get_reply)                 \
5424 _(GPE_NATIVE_FWD_RPATHS_GET_REPLY, gpe_native_fwd_rpaths_get_reply)     \
5425 _(GPE_ADD_DEL_NATIVE_FWD_RPATH_REPLY,                                   \
5426   gpe_add_del_native_fwd_rpath_reply)                                   \
5427 _(GPE_FWD_ENTRY_PATH_DETAILS,                                           \
5428   gpe_fwd_entry_path_details)                                           \
5429 _(SHOW_ONE_STATUS_REPLY, show_one_status_reply)                         \
5430 _(ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                              \
5431   one_add_del_map_request_itr_rlocs_reply)                              \
5432 _(ONE_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                  \
5433   one_get_map_request_itr_rlocs_reply)                                  \
5434 _(SHOW_ONE_NSH_MAPPING_REPLY, show_one_nsh_mapping_reply)               \
5435 _(SHOW_ONE_PITR_REPLY, show_one_pitr_reply)                             \
5436 _(SHOW_ONE_USE_PETR_REPLY, show_one_use_petr_reply)                     \
5437 _(SHOW_ONE_MAP_REQUEST_MODE_REPLY, show_one_map_request_mode_reply)     \
5438 _(SHOW_ONE_RLOC_PROBE_STATE_REPLY, show_one_rloc_probe_state_reply)     \
5439 _(SHOW_ONE_MAP_REGISTER_STATE_REPLY,                                    \
5440   show_one_map_register_state_reply)                                    \
5441 _(SHOW_ONE_MAP_REGISTER_TTL_REPLY, show_one_map_register_ttl_reply)     \
5442 _(SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                       \
5443   show_one_map_register_fallback_threshold_reply)                       \
5444 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
5445 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
5446 _(AF_PACKET_DETAILS, af_packet_details)                                 \
5447 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
5448 _(POLICER_DETAILS, policer_details)                                     \
5449 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
5450 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
5451 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
5452 _(NETMAP_DELETE_REPLY, netmap_delete_reply)                             \
5453 _(MPLS_TUNNEL_DETAILS, mpls_tunnel_details)                             \
5454 _(MPLS_TABLE_DETAILS, mpls_table_details)                               \
5455 _(MPLS_ROUTE_DETAILS, mpls_route_details)                               \
5456 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
5457 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
5458 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
5459 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
5460 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
5461 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
5462 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
5463 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
5464 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
5465 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
5466 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
5467 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
5468 _(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
5469 _(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details)                 \
5470 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
5471 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
5472 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
5473 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
5474 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
5475  ip_source_and_port_range_check_add_del_reply)                          \
5476 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
5477  ip_source_and_port_range_check_interface_add_del_reply)                \
5478 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
5479 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
5480 _(SET_PUNT_REPLY, set_punt_reply)                                       \
5481 _(IP_TABLE_DETAILS, ip_table_details)                                   \
5482 _(IP_ROUTE_DETAILS, ip_route_details)                                   \
5483 _(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply)           \
5484 _(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply)       \
5485 _(SW_INTERFACE_ADD_DEL_MAC_ADDRESS_REPLY, sw_interface_add_del_mac_address_reply) \
5486 _(L2_XCONNECT_DETAILS, l2_xconnect_details)                             \
5487 _(HW_INTERFACE_SET_MTU_REPLY, hw_interface_set_mtu_reply)               \
5488 _(IP_NEIGHBOR_DETAILS, ip_neighbor_details)                             \
5489 _(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply)           \
5490 _(P2P_ETHERNET_ADD_REPLY, p2p_ethernet_add_reply)                       \
5491 _(P2P_ETHERNET_DEL_REPLY, p2p_ethernet_del_reply)                       \
5492 _(LLDP_CONFIG_REPLY, lldp_config_reply)                                 \
5493 _(SW_INTERFACE_SET_LLDP_REPLY, sw_interface_set_lldp_reply)             \
5494 _(TCP_CONFIGURE_SRC_ADDRESSES_REPLY, tcp_configure_src_addresses_reply) \
5495 _(APP_NAMESPACE_ADD_DEL_REPLY, app_namespace_add_del_reply)             \
5496 _(SESSION_RULE_ADD_DEL_REPLY, session_rule_add_del_reply)               \
5497 _(SESSION_RULES_DETAILS, session_rules_details)                         \
5498 _(IP_CONTAINER_PROXY_ADD_DEL_REPLY, ip_container_proxy_add_del_reply)   \
5499 _(OUTPUT_ACL_SET_INTERFACE_REPLY, output_acl_set_interface_reply)       \
5500 _(QOS_RECORD_ENABLE_DISABLE_REPLY, qos_record_enable_disable_reply)
5501
5502 #define foreach_standalone_reply_msg                                    \
5503 _(SW_INTERFACE_EVENT, sw_interface_event)
5504
5505 typedef struct
5506 {
5507   u8 *name;
5508   u32 value;
5509 } name_sort_t;
5510
5511 #define STR_VTR_OP_CASE(op)     \
5512     case L2_VTR_ ## op:         \
5513         return "" # op;
5514
5515 static const char *
5516 str_vtr_op (u32 vtr_op)
5517 {
5518   switch (vtr_op)
5519     {
5520       STR_VTR_OP_CASE (DISABLED);
5521       STR_VTR_OP_CASE (PUSH_1);
5522       STR_VTR_OP_CASE (PUSH_2);
5523       STR_VTR_OP_CASE (POP_1);
5524       STR_VTR_OP_CASE (POP_2);
5525       STR_VTR_OP_CASE (TRANSLATE_1_1);
5526       STR_VTR_OP_CASE (TRANSLATE_1_2);
5527       STR_VTR_OP_CASE (TRANSLATE_2_1);
5528       STR_VTR_OP_CASE (TRANSLATE_2_2);
5529     }
5530
5531   return "UNKNOWN";
5532 }
5533
5534 static int
5535 dump_sub_interface_table (vat_main_t * vam)
5536 {
5537   const sw_interface_subif_t *sub = NULL;
5538
5539   if (vam->json_output)
5540     {
5541       clib_warning
5542         ("JSON output supported only for VPE API calls and dump_stats_table");
5543       return -99;
5544     }
5545
5546   print (vam->ofp,
5547          "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
5548          "Interface", "sw_if_index",
5549          "sub id", "dot1ad", "tags", "outer id",
5550          "inner id", "exact", "default", "outer any", "inner any");
5551
5552   vec_foreach (sub, vam->sw_if_subif_table)
5553   {
5554     print (vam->ofp,
5555            "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
5556            sub->interface_name,
5557            sub->sw_if_index,
5558            sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
5559            sub->sub_number_of_tags, sub->sub_outer_vlan_id,
5560            sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
5561            sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
5562     if (sub->vtr_op != L2_VTR_DISABLED)
5563       {
5564         print (vam->ofp,
5565                "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
5566                "tag1: %d tag2: %d ]",
5567                str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
5568                sub->vtr_tag1, sub->vtr_tag2);
5569       }
5570   }
5571
5572   return 0;
5573 }
5574
5575 static int
5576 name_sort_cmp (void *a1, void *a2)
5577 {
5578   name_sort_t *n1 = a1;
5579   name_sort_t *n2 = a2;
5580
5581   return strcmp ((char *) n1->name, (char *) n2->name);
5582 }
5583
5584 static int
5585 dump_interface_table (vat_main_t * vam)
5586 {
5587   hash_pair_t *p;
5588   name_sort_t *nses = 0, *ns;
5589
5590   if (vam->json_output)
5591     {
5592       clib_warning
5593         ("JSON output supported only for VPE API calls and dump_stats_table");
5594       return -99;
5595     }
5596
5597   /* *INDENT-OFF* */
5598   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5599   ({
5600     vec_add2 (nses, ns, 1);
5601     ns->name = (u8 *)(p->key);
5602     ns->value = (u32) p->value[0];
5603   }));
5604   /* *INDENT-ON* */
5605
5606   vec_sort_with_function (nses, name_sort_cmp);
5607
5608   print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
5609   vec_foreach (ns, nses)
5610   {
5611     print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
5612   }
5613   vec_free (nses);
5614   return 0;
5615 }
5616
5617 static int
5618 dump_ip_table (vat_main_t * vam, int is_ipv6)
5619 {
5620   const ip_details_t *det = NULL;
5621   const ip_address_details_t *address = NULL;
5622   u32 i = ~0;
5623
5624   print (vam->ofp, "%-12s", "sw_if_index");
5625
5626   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
5627   {
5628     i++;
5629     if (!det->present)
5630       {
5631         continue;
5632       }
5633     print (vam->ofp, "%-12d", i);
5634     print (vam->ofp, "            %-30s%-13s", "Address", "Prefix length");
5635     if (!det->addr)
5636       {
5637         continue;
5638       }
5639     vec_foreach (address, det->addr)
5640     {
5641       print (vam->ofp,
5642              "            %-30U%-13d",
5643              is_ipv6 ? format_ip6_address : format_ip4_address,
5644              address->ip, address->prefix_length);
5645     }
5646   }
5647
5648   return 0;
5649 }
5650
5651 static int
5652 dump_ipv4_table (vat_main_t * vam)
5653 {
5654   if (vam->json_output)
5655     {
5656       clib_warning
5657         ("JSON output supported only for VPE API calls and dump_stats_table");
5658       return -99;
5659     }
5660
5661   return dump_ip_table (vam, 0);
5662 }
5663
5664 static int
5665 dump_ipv6_table (vat_main_t * vam)
5666 {
5667   if (vam->json_output)
5668     {
5669       clib_warning
5670         ("JSON output supported only for VPE API calls and dump_stats_table");
5671       return -99;
5672     }
5673
5674   return dump_ip_table (vam, 1);
5675 }
5676
5677 /*
5678  * Pass CLI buffers directly in the CLI_INBAND API message,
5679  * instead of an additional shared memory area.
5680  */
5681 static int
5682 exec_inband (vat_main_t * vam)
5683 {
5684   vl_api_cli_inband_t *mp;
5685   unformat_input_t *i = vam->input;
5686   int ret;
5687
5688   if (vec_len (i->buffer) == 0)
5689     return -1;
5690
5691   if (vam->exec_mode == 0 && unformat (i, "mode"))
5692     {
5693       vam->exec_mode = 1;
5694       return 0;
5695     }
5696   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
5697     {
5698       vam->exec_mode = 0;
5699       return 0;
5700     }
5701
5702   /*
5703    * In order for the CLI command to work, it
5704    * must be a vector ending in \n, not a C-string ending
5705    * in \n\0.
5706    */
5707   u32 len = vec_len (vam->input->buffer);
5708   M2 (CLI_INBAND, mp, len);
5709   vl_api_to_api_string (len - 1, (const char *) vam->input->buffer, &mp->cmd);
5710
5711   S (mp);
5712   W (ret);
5713   /* json responses may or may not include a useful reply... */
5714   if (vec_len (vam->cmd_reply))
5715     print (vam->ofp, "%v", (char *) (vam->cmd_reply));
5716   return ret;
5717 }
5718
5719 int
5720 exec (vat_main_t * vam)
5721 {
5722   return exec_inband (vam);
5723 }
5724
5725 static int
5726 api_create_loopback (vat_main_t * vam)
5727 {
5728   unformat_input_t *i = vam->input;
5729   vl_api_create_loopback_t *mp;
5730   vl_api_create_loopback_instance_t *mp_lbi;
5731   u8 mac_address[6];
5732   u8 mac_set = 0;
5733   u8 is_specified = 0;
5734   u32 user_instance = 0;
5735   int ret;
5736
5737   clib_memset (mac_address, 0, sizeof (mac_address));
5738
5739   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5740     {
5741       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5742         mac_set = 1;
5743       if (unformat (i, "instance %d", &user_instance))
5744         is_specified = 1;
5745       else
5746         break;
5747     }
5748
5749   if (is_specified)
5750     {
5751       M (CREATE_LOOPBACK_INSTANCE, mp_lbi);
5752       mp_lbi->is_specified = is_specified;
5753       if (is_specified)
5754         mp_lbi->user_instance = htonl (user_instance);
5755       if (mac_set)
5756         clib_memcpy (mp_lbi->mac_address, mac_address, sizeof (mac_address));
5757       S (mp_lbi);
5758     }
5759   else
5760     {
5761       /* Construct the API message */
5762       M (CREATE_LOOPBACK, mp);
5763       if (mac_set)
5764         clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
5765       S (mp);
5766     }
5767
5768   W (ret);
5769   return ret;
5770 }
5771
5772 static int
5773 api_delete_loopback (vat_main_t * vam)
5774 {
5775   unformat_input_t *i = vam->input;
5776   vl_api_delete_loopback_t *mp;
5777   u32 sw_if_index = ~0;
5778   int ret;
5779
5780   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5781     {
5782       if (unformat (i, "sw_if_index %d", &sw_if_index))
5783         ;
5784       else
5785         break;
5786     }
5787
5788   if (sw_if_index == ~0)
5789     {
5790       errmsg ("missing sw_if_index");
5791       return -99;
5792     }
5793
5794   /* Construct the API message */
5795   M (DELETE_LOOPBACK, mp);
5796   mp->sw_if_index = ntohl (sw_if_index);
5797
5798   S (mp);
5799   W (ret);
5800   return ret;
5801 }
5802
5803 static int
5804 api_want_interface_events (vat_main_t * vam)
5805 {
5806   unformat_input_t *i = vam->input;
5807   vl_api_want_interface_events_t *mp;
5808   int enable = -1;
5809   int ret;
5810
5811   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5812     {
5813       if (unformat (i, "enable"))
5814         enable = 1;
5815       else if (unformat (i, "disable"))
5816         enable = 0;
5817       else
5818         break;
5819     }
5820
5821   if (enable == -1)
5822     {
5823       errmsg ("missing enable|disable");
5824       return -99;
5825     }
5826
5827   M (WANT_INTERFACE_EVENTS, mp);
5828   mp->enable_disable = enable;
5829
5830   vam->interface_event_display = enable;
5831
5832   S (mp);
5833   W (ret);
5834   return ret;
5835 }
5836
5837
5838 /* Note: non-static, called once to set up the initial intfc table */
5839 int
5840 api_sw_interface_dump (vat_main_t * vam)
5841 {
5842   vl_api_sw_interface_dump_t *mp;
5843   vl_api_control_ping_t *mp_ping;
5844   hash_pair_t *p;
5845   name_sort_t *nses = 0, *ns;
5846   sw_interface_subif_t *sub = NULL;
5847   int ret;
5848
5849   /* Toss the old name table */
5850   /* *INDENT-OFF* */
5851   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5852   ({
5853     vec_add2 (nses, ns, 1);
5854     ns->name = (u8 *)(p->key);
5855     ns->value = (u32) p->value[0];
5856   }));
5857   /* *INDENT-ON* */
5858
5859   hash_free (vam->sw_if_index_by_interface_name);
5860
5861   vec_foreach (ns, nses) vec_free (ns->name);
5862
5863   vec_free (nses);
5864
5865   vec_foreach (sub, vam->sw_if_subif_table)
5866   {
5867     vec_free (sub->interface_name);
5868   }
5869   vec_free (vam->sw_if_subif_table);
5870
5871   /* recreate the interface name hash table */
5872   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
5873
5874   /*
5875    * Ask for all interface names. Otherwise, the epic catalog of
5876    * name filters becomes ridiculously long, and vat ends up needing
5877    * to be taught about new interface types.
5878    */
5879   M (SW_INTERFACE_DUMP, mp);
5880   S (mp);
5881
5882   /* Use a control ping for synchronization */
5883   MPING (CONTROL_PING, mp_ping);
5884   S (mp_ping);
5885
5886   W (ret);
5887   return ret;
5888 }
5889
5890 static int
5891 api_sw_interface_set_flags (vat_main_t * vam)
5892 {
5893   unformat_input_t *i = vam->input;
5894   vl_api_sw_interface_set_flags_t *mp;
5895   u32 sw_if_index;
5896   u8 sw_if_index_set = 0;
5897   u8 admin_up = 0;
5898   int ret;
5899
5900   /* Parse args required to build the message */
5901   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5902     {
5903       if (unformat (i, "admin-up"))
5904         admin_up = 1;
5905       else if (unformat (i, "admin-down"))
5906         admin_up = 0;
5907       else
5908         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5909         sw_if_index_set = 1;
5910       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5911         sw_if_index_set = 1;
5912       else
5913         break;
5914     }
5915
5916   if (sw_if_index_set == 0)
5917     {
5918       errmsg ("missing interface name or sw_if_index");
5919       return -99;
5920     }
5921
5922   /* Construct the API message */
5923   M (SW_INTERFACE_SET_FLAGS, mp);
5924   mp->sw_if_index = ntohl (sw_if_index);
5925   mp->flags = ntohl ((admin_up) ? IF_STATUS_API_FLAG_ADMIN_UP : 0);
5926
5927   /* send it... */
5928   S (mp);
5929
5930   /* Wait for a reply, return the good/bad news... */
5931   W (ret);
5932   return ret;
5933 }
5934
5935 static int
5936 api_sw_interface_set_rx_mode (vat_main_t * vam)
5937 {
5938   unformat_input_t *i = vam->input;
5939   vl_api_sw_interface_set_rx_mode_t *mp;
5940   u32 sw_if_index;
5941   u8 sw_if_index_set = 0;
5942   int ret;
5943   u8 queue_id_valid = 0;
5944   u32 queue_id;
5945   vnet_hw_interface_rx_mode mode = VNET_HW_INTERFACE_RX_MODE_UNKNOWN;
5946
5947   /* Parse args required to build the message */
5948   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5949     {
5950       if (unformat (i, "queue %d", &queue_id))
5951         queue_id_valid = 1;
5952       else if (unformat (i, "polling"))
5953         mode = VNET_HW_INTERFACE_RX_MODE_POLLING;
5954       else if (unformat (i, "interrupt"))
5955         mode = VNET_HW_INTERFACE_RX_MODE_INTERRUPT;
5956       else if (unformat (i, "adaptive"))
5957         mode = VNET_HW_INTERFACE_RX_MODE_ADAPTIVE;
5958       else
5959         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5960         sw_if_index_set = 1;
5961       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5962         sw_if_index_set = 1;
5963       else
5964         break;
5965     }
5966
5967   if (sw_if_index_set == 0)
5968     {
5969       errmsg ("missing interface name or sw_if_index");
5970       return -99;
5971     }
5972   if (mode == VNET_HW_INTERFACE_RX_MODE_UNKNOWN)
5973     {
5974       errmsg ("missing rx-mode");
5975       return -99;
5976     }
5977
5978   /* Construct the API message */
5979   M (SW_INTERFACE_SET_RX_MODE, mp);
5980   mp->sw_if_index = ntohl (sw_if_index);
5981   mp->mode = (vl_api_rx_mode_t) mode;
5982   mp->queue_id_valid = queue_id_valid;
5983   mp->queue_id = queue_id_valid ? ntohl (queue_id) : ~0;
5984
5985   /* send it... */
5986   S (mp);
5987
5988   /* Wait for a reply, return the good/bad news... */
5989   W (ret);
5990   return ret;
5991 }
5992
5993 static int
5994 api_sw_interface_set_rx_placement (vat_main_t * vam)
5995 {
5996   unformat_input_t *i = vam->input;
5997   vl_api_sw_interface_set_rx_placement_t *mp;
5998   u32 sw_if_index;
5999   u8 sw_if_index_set = 0;
6000   int ret;
6001   u8 is_main = 0;
6002   u32 queue_id, thread_index;
6003
6004   /* Parse args required to build the message */
6005   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6006     {
6007       if (unformat (i, "queue %d", &queue_id))
6008         ;
6009       else if (unformat (i, "main"))
6010         is_main = 1;
6011       else if (unformat (i, "worker %d", &thread_index))
6012         ;
6013       else
6014         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6015         sw_if_index_set = 1;
6016       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6017         sw_if_index_set = 1;
6018       else
6019         break;
6020     }
6021
6022   if (sw_if_index_set == 0)
6023     {
6024       errmsg ("missing interface name or sw_if_index");
6025       return -99;
6026     }
6027
6028   if (is_main)
6029     thread_index = 0;
6030   /* Construct the API message */
6031   M (SW_INTERFACE_SET_RX_PLACEMENT, mp);
6032   mp->sw_if_index = ntohl (sw_if_index);
6033   mp->worker_id = ntohl (thread_index);
6034   mp->queue_id = ntohl (queue_id);
6035   mp->is_main = is_main;
6036
6037   /* send it... */
6038   S (mp);
6039   /* Wait for a reply, return the good/bad news... */
6040   W (ret);
6041   return ret;
6042 }
6043
6044 static void vl_api_sw_interface_rx_placement_details_t_handler
6045   (vl_api_sw_interface_rx_placement_details_t * mp)
6046 {
6047   vat_main_t *vam = &vat_main;
6048   u32 worker_id = ntohl (mp->worker_id);
6049
6050   print (vam->ofp,
6051          "\n%-11d %-11s %-6d %-5d %-9s",
6052          ntohl (mp->sw_if_index), (worker_id == 0) ? "main" : "worker",
6053          worker_id, ntohl (mp->queue_id),
6054          (mp->mode ==
6055           1) ? "polling" : ((mp->mode == 2) ? "interrupt" : "adaptive"));
6056 }
6057
6058 static void vl_api_sw_interface_rx_placement_details_t_handler_json
6059   (vl_api_sw_interface_rx_placement_details_t * mp)
6060 {
6061   vat_main_t *vam = &vat_main;
6062   vat_json_node_t *node = NULL;
6063
6064   if (VAT_JSON_ARRAY != vam->json_tree.type)
6065     {
6066       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
6067       vat_json_init_array (&vam->json_tree);
6068     }
6069   node = vat_json_array_add (&vam->json_tree);
6070
6071   vat_json_init_object (node);
6072   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
6073   vat_json_object_add_uint (node, "worker_id", ntohl (mp->worker_id));
6074   vat_json_object_add_uint (node, "queue_id", ntohl (mp->queue_id));
6075   vat_json_object_add_uint (node, "mode", mp->mode);
6076 }
6077
6078 static int
6079 api_sw_interface_rx_placement_dump (vat_main_t * vam)
6080 {
6081   unformat_input_t *i = vam->input;
6082   vl_api_sw_interface_rx_placement_dump_t *mp;
6083   vl_api_control_ping_t *mp_ping;
6084   int ret;
6085   u32 sw_if_index;
6086   u8 sw_if_index_set = 0;
6087
6088   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6089     {
6090       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6091         sw_if_index_set++;
6092       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6093         sw_if_index_set++;
6094       else
6095         break;
6096     }
6097
6098   print (vam->ofp,
6099          "\n%-11s %-11s %-6s %-5s %-4s",
6100          "sw_if_index", "main/worker", "thread", "queue", "mode");
6101
6102   /* Dump Interface rx placement */
6103   M (SW_INTERFACE_RX_PLACEMENT_DUMP, mp);
6104
6105   if (sw_if_index_set)
6106     mp->sw_if_index = htonl (sw_if_index);
6107   else
6108     mp->sw_if_index = ~0;
6109
6110   S (mp);
6111
6112   /* Use a control ping for synchronization */
6113   MPING (CONTROL_PING, mp_ping);
6114   S (mp_ping);
6115
6116   W (ret);
6117   return ret;
6118 }
6119
6120 static int
6121 api_sw_interface_clear_stats (vat_main_t * vam)
6122 {
6123   unformat_input_t *i = vam->input;
6124   vl_api_sw_interface_clear_stats_t *mp;
6125   u32 sw_if_index;
6126   u8 sw_if_index_set = 0;
6127   int ret;
6128
6129   /* Parse args required to build the message */
6130   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6131     {
6132       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6133         sw_if_index_set = 1;
6134       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6135         sw_if_index_set = 1;
6136       else
6137         break;
6138     }
6139
6140   /* Construct the API message */
6141   M (SW_INTERFACE_CLEAR_STATS, mp);
6142
6143   if (sw_if_index_set == 1)
6144     mp->sw_if_index = ntohl (sw_if_index);
6145   else
6146     mp->sw_if_index = ~0;
6147
6148   /* send it... */
6149   S (mp);
6150
6151   /* Wait for a reply, return the good/bad news... */
6152   W (ret);
6153   return ret;
6154 }
6155
6156 static int
6157 api_sw_interface_add_del_address (vat_main_t * vam)
6158 {
6159   unformat_input_t *i = vam->input;
6160   vl_api_sw_interface_add_del_address_t *mp;
6161   u32 sw_if_index;
6162   u8 sw_if_index_set = 0;
6163   u8 is_add = 1, del_all = 0;
6164   u32 address_length = 0;
6165   u8 v4_address_set = 0;
6166   u8 v6_address_set = 0;
6167   ip4_address_t v4address;
6168   ip6_address_t v6address;
6169   int ret;
6170
6171   /* Parse args required to build the message */
6172   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6173     {
6174       if (unformat (i, "del-all"))
6175         del_all = 1;
6176       else if (unformat (i, "del"))
6177         is_add = 0;
6178       else
6179         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6180         sw_if_index_set = 1;
6181       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6182         sw_if_index_set = 1;
6183       else if (unformat (i, "%U/%d",
6184                          unformat_ip4_address, &v4address, &address_length))
6185         v4_address_set = 1;
6186       else if (unformat (i, "%U/%d",
6187                          unformat_ip6_address, &v6address, &address_length))
6188         v6_address_set = 1;
6189       else
6190         break;
6191     }
6192
6193   if (sw_if_index_set == 0)
6194     {
6195       errmsg ("missing interface name or sw_if_index");
6196       return -99;
6197     }
6198   if (v4_address_set && v6_address_set)
6199     {
6200       errmsg ("both v4 and v6 addresses set");
6201       return -99;
6202     }
6203   if (!v4_address_set && !v6_address_set && !del_all)
6204     {
6205       errmsg ("no addresses set");
6206       return -99;
6207     }
6208
6209   /* Construct the API message */
6210   M (SW_INTERFACE_ADD_DEL_ADDRESS, mp);
6211
6212   mp->sw_if_index = ntohl (sw_if_index);
6213   mp->is_add = is_add;
6214   mp->del_all = del_all;
6215   if (v6_address_set)
6216     {
6217       mp->prefix.address.af = ADDRESS_IP6;
6218       clib_memcpy (mp->prefix.address.un.ip6, &v6address, sizeof (v6address));
6219     }
6220   else
6221     {
6222       mp->prefix.address.af = ADDRESS_IP4;
6223       clib_memcpy (mp->prefix.address.un.ip4, &v4address, sizeof (v4address));
6224     }
6225   mp->prefix.len = address_length;
6226
6227   /* send it... */
6228   S (mp);
6229
6230   /* Wait for a reply, return good/bad news  */
6231   W (ret);
6232   return ret;
6233 }
6234
6235 static int
6236 api_sw_interface_set_mpls_enable (vat_main_t * vam)
6237 {
6238   unformat_input_t *i = vam->input;
6239   vl_api_sw_interface_set_mpls_enable_t *mp;
6240   u32 sw_if_index;
6241   u8 sw_if_index_set = 0;
6242   u8 enable = 1;
6243   int ret;
6244
6245   /* Parse args required to build the message */
6246   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6247     {
6248       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6249         sw_if_index_set = 1;
6250       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6251         sw_if_index_set = 1;
6252       else if (unformat (i, "disable"))
6253         enable = 0;
6254       else if (unformat (i, "dis"))
6255         enable = 0;
6256       else
6257         break;
6258     }
6259
6260   if (sw_if_index_set == 0)
6261     {
6262       errmsg ("missing interface name or sw_if_index");
6263       return -99;
6264     }
6265
6266   /* Construct the API message */
6267   M (SW_INTERFACE_SET_MPLS_ENABLE, mp);
6268
6269   mp->sw_if_index = ntohl (sw_if_index);
6270   mp->enable = enable;
6271
6272   /* send it... */
6273   S (mp);
6274
6275   /* Wait for a reply... */
6276   W (ret);
6277   return ret;
6278 }
6279
6280 static int
6281 api_sw_interface_set_table (vat_main_t * vam)
6282 {
6283   unformat_input_t *i = vam->input;
6284   vl_api_sw_interface_set_table_t *mp;
6285   u32 sw_if_index, vrf_id = 0;
6286   u8 sw_if_index_set = 0;
6287   u8 is_ipv6 = 0;
6288   int ret;
6289
6290   /* Parse args required to build the message */
6291   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6292     {
6293       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6294         sw_if_index_set = 1;
6295       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6296         sw_if_index_set = 1;
6297       else if (unformat (i, "vrf %d", &vrf_id))
6298         ;
6299       else if (unformat (i, "ipv6"))
6300         is_ipv6 = 1;
6301       else
6302         break;
6303     }
6304
6305   if (sw_if_index_set == 0)
6306     {
6307       errmsg ("missing interface name or sw_if_index");
6308       return -99;
6309     }
6310
6311   /* Construct the API message */
6312   M (SW_INTERFACE_SET_TABLE, mp);
6313
6314   mp->sw_if_index = ntohl (sw_if_index);
6315   mp->is_ipv6 = is_ipv6;
6316   mp->vrf_id = ntohl (vrf_id);
6317
6318   /* send it... */
6319   S (mp);
6320
6321   /* Wait for a reply... */
6322   W (ret);
6323   return ret;
6324 }
6325
6326 static void vl_api_sw_interface_get_table_reply_t_handler
6327   (vl_api_sw_interface_get_table_reply_t * mp)
6328 {
6329   vat_main_t *vam = &vat_main;
6330
6331   print (vam->ofp, "%d", ntohl (mp->vrf_id));
6332
6333   vam->retval = ntohl (mp->retval);
6334   vam->result_ready = 1;
6335
6336 }
6337
6338 static void vl_api_sw_interface_get_table_reply_t_handler_json
6339   (vl_api_sw_interface_get_table_reply_t * mp)
6340 {
6341   vat_main_t *vam = &vat_main;
6342   vat_json_node_t node;
6343
6344   vat_json_init_object (&node);
6345   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
6346   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
6347
6348   vat_json_print (vam->ofp, &node);
6349   vat_json_free (&node);
6350
6351   vam->retval = ntohl (mp->retval);
6352   vam->result_ready = 1;
6353 }
6354
6355 static int
6356 api_sw_interface_get_table (vat_main_t * vam)
6357 {
6358   unformat_input_t *i = vam->input;
6359   vl_api_sw_interface_get_table_t *mp;
6360   u32 sw_if_index;
6361   u8 sw_if_index_set = 0;
6362   u8 is_ipv6 = 0;
6363   int ret;
6364
6365   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6366     {
6367       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6368         sw_if_index_set = 1;
6369       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6370         sw_if_index_set = 1;
6371       else if (unformat (i, "ipv6"))
6372         is_ipv6 = 1;
6373       else
6374         break;
6375     }
6376
6377   if (sw_if_index_set == 0)
6378     {
6379       errmsg ("missing interface name or sw_if_index");
6380       return -99;
6381     }
6382
6383   M (SW_INTERFACE_GET_TABLE, mp);
6384   mp->sw_if_index = htonl (sw_if_index);
6385   mp->is_ipv6 = is_ipv6;
6386
6387   S (mp);
6388   W (ret);
6389   return ret;
6390 }
6391
6392 static int
6393 api_sw_interface_set_vpath (vat_main_t * vam)
6394 {
6395   unformat_input_t *i = vam->input;
6396   vl_api_sw_interface_set_vpath_t *mp;
6397   u32 sw_if_index = 0;
6398   u8 sw_if_index_set = 0;
6399   u8 is_enable = 0;
6400   int ret;
6401
6402   /* Parse args required to build the message */
6403   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6404     {
6405       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6406         sw_if_index_set = 1;
6407       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6408         sw_if_index_set = 1;
6409       else if (unformat (i, "enable"))
6410         is_enable = 1;
6411       else if (unformat (i, "disable"))
6412         is_enable = 0;
6413       else
6414         break;
6415     }
6416
6417   if (sw_if_index_set == 0)
6418     {
6419       errmsg ("missing interface name or sw_if_index");
6420       return -99;
6421     }
6422
6423   /* Construct the API message */
6424   M (SW_INTERFACE_SET_VPATH, mp);
6425
6426   mp->sw_if_index = ntohl (sw_if_index);
6427   mp->enable = is_enable;
6428
6429   /* send it... */
6430   S (mp);
6431
6432   /* Wait for a reply... */
6433   W (ret);
6434   return ret;
6435 }
6436
6437 static int
6438 api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
6439 {
6440   unformat_input_t *i = vam->input;
6441   vl_api_sw_interface_set_vxlan_bypass_t *mp;
6442   u32 sw_if_index = 0;
6443   u8 sw_if_index_set = 0;
6444   u8 is_enable = 1;
6445   u8 is_ipv6 = 0;
6446   int ret;
6447
6448   /* Parse args required to build the message */
6449   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6450     {
6451       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6452         sw_if_index_set = 1;
6453       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6454         sw_if_index_set = 1;
6455       else if (unformat (i, "enable"))
6456         is_enable = 1;
6457       else if (unformat (i, "disable"))
6458         is_enable = 0;
6459       else if (unformat (i, "ip4"))
6460         is_ipv6 = 0;
6461       else if (unformat (i, "ip6"))
6462         is_ipv6 = 1;
6463       else
6464         break;
6465     }
6466
6467   if (sw_if_index_set == 0)
6468     {
6469       errmsg ("missing interface name or sw_if_index");
6470       return -99;
6471     }
6472
6473   /* Construct the API message */
6474   M (SW_INTERFACE_SET_VXLAN_BYPASS, mp);
6475
6476   mp->sw_if_index = ntohl (sw_if_index);
6477   mp->enable = is_enable;
6478   mp->is_ipv6 = is_ipv6;
6479
6480   /* send it... */
6481   S (mp);
6482
6483   /* Wait for a reply... */
6484   W (ret);
6485   return ret;
6486 }
6487
6488 static int
6489 api_sw_interface_set_geneve_bypass (vat_main_t * vam)
6490 {
6491   unformat_input_t *i = vam->input;
6492   vl_api_sw_interface_set_geneve_bypass_t *mp;
6493   u32 sw_if_index = 0;
6494   u8 sw_if_index_set = 0;
6495   u8 is_enable = 1;
6496   u8 is_ipv6 = 0;
6497   int ret;
6498
6499   /* Parse args required to build the message */
6500   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6501     {
6502       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6503         sw_if_index_set = 1;
6504       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6505         sw_if_index_set = 1;
6506       else if (unformat (i, "enable"))
6507         is_enable = 1;
6508       else if (unformat (i, "disable"))
6509         is_enable = 0;
6510       else if (unformat (i, "ip4"))
6511         is_ipv6 = 0;
6512       else if (unformat (i, "ip6"))
6513         is_ipv6 = 1;
6514       else
6515         break;
6516     }
6517
6518   if (sw_if_index_set == 0)
6519     {
6520       errmsg ("missing interface name or sw_if_index");
6521       return -99;
6522     }
6523
6524   /* Construct the API message */
6525   M (SW_INTERFACE_SET_GENEVE_BYPASS, mp);
6526
6527   mp->sw_if_index = ntohl (sw_if_index);
6528   mp->enable = is_enable;
6529   mp->is_ipv6 = is_ipv6;
6530
6531   /* send it... */
6532   S (mp);
6533
6534   /* Wait for a reply... */
6535   W (ret);
6536   return ret;
6537 }
6538
6539 static int
6540 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
6541 {
6542   unformat_input_t *i = vam->input;
6543   vl_api_sw_interface_set_l2_xconnect_t *mp;
6544   u32 rx_sw_if_index;
6545   u8 rx_sw_if_index_set = 0;
6546   u32 tx_sw_if_index;
6547   u8 tx_sw_if_index_set = 0;
6548   u8 enable = 1;
6549   int ret;
6550
6551   /* Parse args required to build the message */
6552   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6553     {
6554       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
6555         rx_sw_if_index_set = 1;
6556       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
6557         tx_sw_if_index_set = 1;
6558       else if (unformat (i, "rx"))
6559         {
6560           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6561             {
6562               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6563                             &rx_sw_if_index))
6564                 rx_sw_if_index_set = 1;
6565             }
6566           else
6567             break;
6568         }
6569       else if (unformat (i, "tx"))
6570         {
6571           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6572             {
6573               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6574                             &tx_sw_if_index))
6575                 tx_sw_if_index_set = 1;
6576             }
6577           else
6578             break;
6579         }
6580       else if (unformat (i, "enable"))
6581         enable = 1;
6582       else if (unformat (i, "disable"))
6583         enable = 0;
6584       else
6585         break;
6586     }
6587
6588   if (rx_sw_if_index_set == 0)
6589     {
6590       errmsg ("missing rx interface name or rx_sw_if_index");
6591       return -99;
6592     }
6593
6594   if (enable && (tx_sw_if_index_set == 0))
6595     {
6596       errmsg ("missing tx interface name or tx_sw_if_index");
6597       return -99;
6598     }
6599
6600   M (SW_INTERFACE_SET_L2_XCONNECT, mp);
6601
6602   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6603   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
6604   mp->enable = enable;
6605
6606   S (mp);
6607   W (ret);
6608   return ret;
6609 }
6610
6611 static int
6612 api_sw_interface_set_l2_bridge (vat_main_t * vam)
6613 {
6614   unformat_input_t *i = vam->input;
6615   vl_api_sw_interface_set_l2_bridge_t *mp;
6616   vl_api_l2_port_type_t port_type;
6617   u32 rx_sw_if_index;
6618   u8 rx_sw_if_index_set = 0;
6619   u32 bd_id;
6620   u8 bd_id_set = 0;
6621   u32 shg = 0;
6622   u8 enable = 1;
6623   int ret;
6624
6625   port_type = L2_API_PORT_TYPE_NORMAL;
6626
6627   /* Parse args required to build the message */
6628   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6629     {
6630       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
6631         rx_sw_if_index_set = 1;
6632       else if (unformat (i, "bd_id %d", &bd_id))
6633         bd_id_set = 1;
6634       else
6635         if (unformat
6636             (i, "%U", api_unformat_sw_if_index, vam, &rx_sw_if_index))
6637         rx_sw_if_index_set = 1;
6638       else if (unformat (i, "shg %d", &shg))
6639         ;
6640       else if (unformat (i, "bvi"))
6641         port_type = L2_API_PORT_TYPE_BVI;
6642       else if (unformat (i, "uu-fwd"))
6643         port_type = L2_API_PORT_TYPE_UU_FWD;
6644       else if (unformat (i, "enable"))
6645         enable = 1;
6646       else if (unformat (i, "disable"))
6647         enable = 0;
6648       else
6649         break;
6650     }
6651
6652   if (rx_sw_if_index_set == 0)
6653     {
6654       errmsg ("missing rx interface name or sw_if_index");
6655       return -99;
6656     }
6657
6658   if (enable && (bd_id_set == 0))
6659     {
6660       errmsg ("missing bridge domain");
6661       return -99;
6662     }
6663
6664   M (SW_INTERFACE_SET_L2_BRIDGE, mp);
6665
6666   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6667   mp->bd_id = ntohl (bd_id);
6668   mp->shg = (u8) shg;
6669   mp->port_type = ntohl (port_type);
6670   mp->enable = enable;
6671
6672   S (mp);
6673   W (ret);
6674   return ret;
6675 }
6676
6677 static int
6678 api_bridge_domain_dump (vat_main_t * vam)
6679 {
6680   unformat_input_t *i = vam->input;
6681   vl_api_bridge_domain_dump_t *mp;
6682   vl_api_control_ping_t *mp_ping;
6683   u32 bd_id = ~0;
6684   int ret;
6685
6686   /* Parse args required to build the message */
6687   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6688     {
6689       if (unformat (i, "bd_id %d", &bd_id))
6690         ;
6691       else
6692         break;
6693     }
6694
6695   M (BRIDGE_DOMAIN_DUMP, mp);
6696   mp->bd_id = ntohl (bd_id);
6697   S (mp);
6698
6699   /* Use a control ping for synchronization */
6700   MPING (CONTROL_PING, mp_ping);
6701   S (mp_ping);
6702
6703   W (ret);
6704   return ret;
6705 }
6706
6707 static int
6708 api_bridge_domain_add_del (vat_main_t * vam)
6709 {
6710   unformat_input_t *i = vam->input;
6711   vl_api_bridge_domain_add_del_t *mp;
6712   u32 bd_id = ~0;
6713   u8 is_add = 1;
6714   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
6715   u8 *bd_tag = NULL;
6716   u32 mac_age = 0;
6717   int ret;
6718
6719   /* Parse args required to build the message */
6720   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6721     {
6722       if (unformat (i, "bd_id %d", &bd_id))
6723         ;
6724       else if (unformat (i, "flood %d", &flood))
6725         ;
6726       else if (unformat (i, "uu-flood %d", &uu_flood))
6727         ;
6728       else if (unformat (i, "forward %d", &forward))
6729         ;
6730       else if (unformat (i, "learn %d", &learn))
6731         ;
6732       else if (unformat (i, "arp-term %d", &arp_term))
6733         ;
6734       else if (unformat (i, "mac-age %d", &mac_age))
6735         ;
6736       else if (unformat (i, "bd-tag %s", &bd_tag))
6737         ;
6738       else if (unformat (i, "del"))
6739         {
6740           is_add = 0;
6741           flood = uu_flood = forward = learn = 0;
6742         }
6743       else
6744         break;
6745     }
6746
6747   if (bd_id == ~0)
6748     {
6749       errmsg ("missing bridge domain");
6750       ret = -99;
6751       goto done;
6752     }
6753
6754   if (mac_age > 255)
6755     {
6756       errmsg ("mac age must be less than 256 ");
6757       ret = -99;
6758       goto done;
6759     }
6760
6761   if ((bd_tag) && (vec_len (bd_tag) > 63))
6762     {
6763       errmsg ("bd-tag cannot be longer than 63");
6764       ret = -99;
6765       goto done;
6766     }
6767
6768   M (BRIDGE_DOMAIN_ADD_DEL, mp);
6769
6770   mp->bd_id = ntohl (bd_id);
6771   mp->flood = flood;
6772   mp->uu_flood = uu_flood;
6773   mp->forward = forward;
6774   mp->learn = learn;
6775   mp->arp_term = arp_term;
6776   mp->is_add = is_add;
6777   mp->mac_age = (u8) mac_age;
6778   if (bd_tag)
6779     {
6780       clib_memcpy (mp->bd_tag, bd_tag, vec_len (bd_tag));
6781       mp->bd_tag[vec_len (bd_tag)] = 0;
6782     }
6783   S (mp);
6784   W (ret);
6785
6786 done:
6787   vec_free (bd_tag);
6788   return ret;
6789 }
6790
6791 static int
6792 api_l2fib_flush_bd (vat_main_t * vam)
6793 {
6794   unformat_input_t *i = vam->input;
6795   vl_api_l2fib_flush_bd_t *mp;
6796   u32 bd_id = ~0;
6797   int ret;
6798
6799   /* Parse args required to build the message */
6800   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6801     {
6802       if (unformat (i, "bd_id %d", &bd_id));
6803       else
6804         break;
6805     }
6806
6807   if (bd_id == ~0)
6808     {
6809       errmsg ("missing bridge domain");
6810       return -99;
6811     }
6812
6813   M (L2FIB_FLUSH_BD, mp);
6814
6815   mp->bd_id = htonl (bd_id);
6816
6817   S (mp);
6818   W (ret);
6819   return ret;
6820 }
6821
6822 static int
6823 api_l2fib_flush_int (vat_main_t * vam)
6824 {
6825   unformat_input_t *i = vam->input;
6826   vl_api_l2fib_flush_int_t *mp;
6827   u32 sw_if_index = ~0;
6828   int ret;
6829
6830   /* Parse args required to build the message */
6831   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6832     {
6833       if (unformat (i, "sw_if_index %d", &sw_if_index));
6834       else
6835         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index));
6836       else
6837         break;
6838     }
6839
6840   if (sw_if_index == ~0)
6841     {
6842       errmsg ("missing interface name or sw_if_index");
6843       return -99;
6844     }
6845
6846   M (L2FIB_FLUSH_INT, mp);
6847
6848   mp->sw_if_index = ntohl (sw_if_index);
6849
6850   S (mp);
6851   W (ret);
6852   return ret;
6853 }
6854
6855 static int
6856 api_l2fib_add_del (vat_main_t * vam)
6857 {
6858   unformat_input_t *i = vam->input;
6859   vl_api_l2fib_add_del_t *mp;
6860   f64 timeout;
6861   u8 mac[6] = { 0 };
6862   u8 mac_set = 0;
6863   u32 bd_id;
6864   u8 bd_id_set = 0;
6865   u32 sw_if_index = 0;
6866   u8 sw_if_index_set = 0;
6867   u8 is_add = 1;
6868   u8 static_mac = 0;
6869   u8 filter_mac = 0;
6870   u8 bvi_mac = 0;
6871   int count = 1;
6872   f64 before = 0;
6873   int j;
6874
6875   /* Parse args required to build the message */
6876   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6877     {
6878       if (unformat (i, "mac %U", unformat_ethernet_address, mac))
6879         mac_set = 1;
6880       else if (unformat (i, "bd_id %d", &bd_id))
6881         bd_id_set = 1;
6882       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6883         sw_if_index_set = 1;
6884       else if (unformat (i, "sw_if"))
6885         {
6886           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6887             {
6888               if (unformat
6889                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6890                 sw_if_index_set = 1;
6891             }
6892           else
6893             break;
6894         }
6895       else if (unformat (i, "static"))
6896         static_mac = 1;
6897       else if (unformat (i, "filter"))
6898         {
6899           filter_mac = 1;
6900           static_mac = 1;
6901         }
6902       else if (unformat (i, "bvi"))
6903         {
6904           bvi_mac = 1;
6905           static_mac = 1;
6906         }
6907       else if (unformat (i, "del"))
6908         is_add = 0;
6909       else if (unformat (i, "count %d", &count))
6910         ;
6911       else
6912         break;
6913     }
6914
6915   if (mac_set == 0)
6916     {
6917       errmsg ("missing mac address");
6918       return -99;
6919     }
6920
6921   if (bd_id_set == 0)
6922     {
6923       errmsg ("missing bridge domain");
6924       return -99;
6925     }
6926
6927   if (is_add && sw_if_index_set == 0 && filter_mac == 0)
6928     {
6929       errmsg ("missing interface name or sw_if_index");
6930       return -99;
6931     }
6932
6933   if (count > 1)
6934     {
6935       /* Turn on async mode */
6936       vam->async_mode = 1;
6937       vam->async_errors = 0;
6938       before = vat_time_now (vam);
6939     }
6940
6941   for (j = 0; j < count; j++)
6942     {
6943       M (L2FIB_ADD_DEL, mp);
6944
6945       clib_memcpy (mp->mac, mac, 6);
6946       mp->bd_id = ntohl (bd_id);
6947       mp->is_add = is_add;
6948       mp->sw_if_index = ntohl (sw_if_index);
6949
6950       if (is_add)
6951         {
6952           mp->static_mac = static_mac;
6953           mp->filter_mac = filter_mac;
6954           mp->bvi_mac = bvi_mac;
6955         }
6956       increment_mac_address (mac);
6957       /* send it... */
6958       S (mp);
6959     }
6960
6961   if (count > 1)
6962     {
6963       vl_api_control_ping_t *mp_ping;
6964       f64 after;
6965
6966       /* Shut off async mode */
6967       vam->async_mode = 0;
6968
6969       MPING (CONTROL_PING, mp_ping);
6970       S (mp_ping);
6971
6972       timeout = vat_time_now (vam) + 1.0;
6973       while (vat_time_now (vam) < timeout)
6974         if (vam->result_ready == 1)
6975           goto out;
6976       vam->retval = -99;
6977
6978     out:
6979       if (vam->retval == -99)
6980         errmsg ("timeout");
6981
6982       if (vam->async_errors > 0)
6983         {
6984           errmsg ("%d asynchronous errors", vam->async_errors);
6985           vam->retval = -98;
6986         }
6987       vam->async_errors = 0;
6988       after = vat_time_now (vam);
6989
6990       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
6991              count, after - before, count / (after - before));
6992     }
6993   else
6994     {
6995       int ret;
6996
6997       /* Wait for a reply... */
6998       W (ret);
6999       return ret;
7000     }
7001   /* Return the good/bad news */
7002   return (vam->retval);
7003 }
7004
7005 static int
7006 api_bridge_domain_set_mac_age (vat_main_t * vam)
7007 {
7008   unformat_input_t *i = vam->input;
7009   vl_api_bridge_domain_set_mac_age_t *mp;
7010   u32 bd_id = ~0;
7011   u32 mac_age = 0;
7012   int ret;
7013
7014   /* Parse args required to build the message */
7015   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7016     {
7017       if (unformat (i, "bd_id %d", &bd_id));
7018       else if (unformat (i, "mac-age %d", &mac_age));
7019       else
7020         break;
7021     }
7022
7023   if (bd_id == ~0)
7024     {
7025       errmsg ("missing bridge domain");
7026       return -99;
7027     }
7028
7029   if (mac_age > 255)
7030     {
7031       errmsg ("mac age must be less than 256 ");
7032       return -99;
7033     }
7034
7035   M (BRIDGE_DOMAIN_SET_MAC_AGE, mp);
7036
7037   mp->bd_id = htonl (bd_id);
7038   mp->mac_age = (u8) mac_age;
7039
7040   S (mp);
7041   W (ret);
7042   return ret;
7043 }
7044
7045 static int
7046 api_l2_flags (vat_main_t * vam)
7047 {
7048   unformat_input_t *i = vam->input;
7049   vl_api_l2_flags_t *mp;
7050   u32 sw_if_index;
7051   u32 flags = 0;
7052   u8 sw_if_index_set = 0;
7053   u8 is_set = 0;
7054   int ret;
7055
7056   /* Parse args required to build the message */
7057   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7058     {
7059       if (unformat (i, "sw_if_index %d", &sw_if_index))
7060         sw_if_index_set = 1;
7061       else if (unformat (i, "sw_if"))
7062         {
7063           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7064             {
7065               if (unformat
7066                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7067                 sw_if_index_set = 1;
7068             }
7069           else
7070             break;
7071         }
7072       else if (unformat (i, "learn"))
7073         flags |= L2_LEARN;
7074       else if (unformat (i, "forward"))
7075         flags |= L2_FWD;
7076       else if (unformat (i, "flood"))
7077         flags |= L2_FLOOD;
7078       else if (unformat (i, "uu-flood"))
7079         flags |= L2_UU_FLOOD;
7080       else if (unformat (i, "arp-term"))
7081         flags |= L2_ARP_TERM;
7082       else if (unformat (i, "off"))
7083         is_set = 0;
7084       else if (unformat (i, "disable"))
7085         is_set = 0;
7086       else
7087         break;
7088     }
7089
7090   if (sw_if_index_set == 0)
7091     {
7092       errmsg ("missing interface name or sw_if_index");
7093       return -99;
7094     }
7095
7096   M (L2_FLAGS, mp);
7097
7098   mp->sw_if_index = ntohl (sw_if_index);
7099   mp->feature_bitmap = ntohl (flags);
7100   mp->is_set = is_set;
7101
7102   S (mp);
7103   W (ret);
7104   return ret;
7105 }
7106
7107 static int
7108 api_bridge_flags (vat_main_t * vam)
7109 {
7110   unformat_input_t *i = vam->input;
7111   vl_api_bridge_flags_t *mp;
7112   u32 bd_id;
7113   u8 bd_id_set = 0;
7114   u8 is_set = 1;
7115   bd_flags_t flags = 0;
7116   int ret;
7117
7118   /* Parse args required to build the message */
7119   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7120     {
7121       if (unformat (i, "bd_id %d", &bd_id))
7122         bd_id_set = 1;
7123       else if (unformat (i, "learn"))
7124         flags |= BRIDGE_API_FLAG_LEARN;
7125       else if (unformat (i, "forward"))
7126         flags |= BRIDGE_API_FLAG_FWD;
7127       else if (unformat (i, "flood"))
7128         flags |= BRIDGE_API_FLAG_FLOOD;
7129       else if (unformat (i, "uu-flood"))
7130         flags |= BRIDGE_API_FLAG_UU_FLOOD;
7131       else if (unformat (i, "arp-term"))
7132         flags |= BRIDGE_API_FLAG_ARP_TERM;
7133       else if (unformat (i, "off"))
7134         is_set = 0;
7135       else if (unformat (i, "disable"))
7136         is_set = 0;
7137       else
7138         break;
7139     }
7140
7141   if (bd_id_set == 0)
7142     {
7143       errmsg ("missing bridge domain");
7144       return -99;
7145     }
7146
7147   M (BRIDGE_FLAGS, mp);
7148
7149   mp->bd_id = ntohl (bd_id);
7150   mp->flags = ntohl (flags);
7151   mp->is_set = is_set;
7152
7153   S (mp);
7154   W (ret);
7155   return ret;
7156 }
7157
7158 static int
7159 api_bd_ip_mac_add_del (vat_main_t * vam)
7160 {
7161   vl_api_address_t ip = VL_API_ZERO_ADDRESS;
7162   vl_api_mac_address_t mac = { 0 };
7163   unformat_input_t *i = vam->input;
7164   vl_api_bd_ip_mac_add_del_t *mp;
7165   u32 bd_id;
7166   u8 is_add = 1;
7167   u8 bd_id_set = 0;
7168   u8 ip_set = 0;
7169   u8 mac_set = 0;
7170   int ret;
7171
7172
7173   /* Parse args required to build the message */
7174   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7175     {
7176       if (unformat (i, "bd_id %d", &bd_id))
7177         {
7178           bd_id_set++;
7179         }
7180       else if (unformat (i, "%U", unformat_vl_api_address, &ip))
7181         {
7182           ip_set++;
7183         }
7184       else if (unformat (i, "%U", unformat_vl_api_mac_address, &mac))
7185         {
7186           mac_set++;
7187         }
7188       else if (unformat (i, "del"))
7189         is_add = 0;
7190       else
7191         break;
7192     }
7193
7194   if (bd_id_set == 0)
7195     {
7196       errmsg ("missing bridge domain");
7197       return -99;
7198     }
7199   else if (ip_set == 0)
7200     {
7201       errmsg ("missing IP address");
7202       return -99;
7203     }
7204   else if (mac_set == 0)
7205     {
7206       errmsg ("missing MAC address");
7207       return -99;
7208     }
7209
7210   M (BD_IP_MAC_ADD_DEL, mp);
7211
7212   mp->entry.bd_id = ntohl (bd_id);
7213   mp->is_add = is_add;
7214
7215   clib_memcpy (&mp->entry.ip, &ip, sizeof (ip));
7216   clib_memcpy (&mp->entry.mac, &mac, sizeof (mac));
7217
7218   S (mp);
7219   W (ret);
7220   return ret;
7221 }
7222
7223 static int
7224 api_bd_ip_mac_flush (vat_main_t * vam)
7225 {
7226   unformat_input_t *i = vam->input;
7227   vl_api_bd_ip_mac_flush_t *mp;
7228   u32 bd_id;
7229   u8 bd_id_set = 0;
7230   int ret;
7231
7232   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7233     {
7234       if (unformat (i, "bd_id %d", &bd_id))
7235         {
7236           bd_id_set++;
7237         }
7238       else
7239         break;
7240     }
7241
7242   if (bd_id_set == 0)
7243     {
7244       errmsg ("missing bridge domain");
7245       return -99;
7246     }
7247
7248   M (BD_IP_MAC_FLUSH, mp);
7249
7250   mp->bd_id = ntohl (bd_id);
7251
7252   S (mp);
7253   W (ret);
7254   return ret;
7255 }
7256
7257 static void vl_api_bd_ip_mac_details_t_handler
7258   (vl_api_bd_ip_mac_details_t * mp)
7259 {
7260   vat_main_t *vam = &vat_main;
7261
7262   print (vam->ofp,
7263          "\n%-5d %U %U",
7264          ntohl (mp->entry.bd_id),
7265          format_vl_api_mac_address, mp->entry.mac,
7266          format_vl_api_address, &mp->entry.ip);
7267 }
7268
7269 static void vl_api_bd_ip_mac_details_t_handler_json
7270   (vl_api_bd_ip_mac_details_t * mp)
7271 {
7272   vat_main_t *vam = &vat_main;
7273   vat_json_node_t *node = NULL;
7274
7275   if (VAT_JSON_ARRAY != vam->json_tree.type)
7276     {
7277       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
7278       vat_json_init_array (&vam->json_tree);
7279     }
7280   node = vat_json_array_add (&vam->json_tree);
7281
7282   vat_json_init_object (node);
7283   vat_json_object_add_uint (node, "bd_id", ntohl (mp->entry.bd_id));
7284   vat_json_object_add_string_copy (node, "mac_address",
7285                                    format (0, "%U", format_vl_api_mac_address,
7286                                            &mp->entry.mac));
7287   u8 *ip = 0;
7288
7289   ip = format (0, "%U", format_vl_api_address, &mp->entry.ip);
7290   vat_json_object_add_string_copy (node, "ip_address", ip);
7291   vec_free (ip);
7292 }
7293
7294 static int
7295 api_bd_ip_mac_dump (vat_main_t * vam)
7296 {
7297   unformat_input_t *i = vam->input;
7298   vl_api_bd_ip_mac_dump_t *mp;
7299   vl_api_control_ping_t *mp_ping;
7300   int ret;
7301   u32 bd_id;
7302   u8 bd_id_set = 0;
7303
7304   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7305     {
7306       if (unformat (i, "bd_id %d", &bd_id))
7307         {
7308           bd_id_set++;
7309         }
7310       else
7311         break;
7312     }
7313
7314   print (vam->ofp,
7315          "\n%-5s %-7s %-20s %-30s",
7316          "bd_id", "is_ipv6", "mac_address", "ip_address");
7317
7318   /* Dump Bridge Domain Ip to Mac entries */
7319   M (BD_IP_MAC_DUMP, mp);
7320
7321   if (bd_id_set)
7322     mp->bd_id = htonl (bd_id);
7323   else
7324     mp->bd_id = ~0;
7325
7326   S (mp);
7327
7328   /* Use a control ping for synchronization */
7329   MPING (CONTROL_PING, mp_ping);
7330   S (mp_ping);
7331
7332   W (ret);
7333   return ret;
7334 }
7335
7336 static int
7337 api_tap_create_v2 (vat_main_t * vam)
7338 {
7339   unformat_input_t *i = vam->input;
7340   vl_api_tap_create_v2_t *mp;
7341 #define TAP_FLAG_GSO (1 << 0)
7342   u8 mac_address[6];
7343   u8 random_mac = 1;
7344   u32 id = ~0;
7345   u8 *host_if_name = 0;
7346   u8 *host_ns = 0;
7347   u8 host_mac_addr[6];
7348   u8 host_mac_addr_set = 0;
7349   u8 *host_bridge = 0;
7350   ip4_address_t host_ip4_addr;
7351   ip4_address_t host_ip4_gw;
7352   u8 host_ip4_gw_set = 0;
7353   u32 host_ip4_prefix_len = 0;
7354   ip6_address_t host_ip6_addr;
7355   ip6_address_t host_ip6_gw;
7356   u8 host_ip6_gw_set = 0;
7357   u32 host_ip6_prefix_len = 0;
7358   u8 host_mtu_set = 0;
7359   u32 host_mtu_size = 0;
7360   u32 tap_flags = 0;
7361   int ret;
7362   u32 rx_ring_sz = 0, tx_ring_sz = 0;
7363
7364   clib_memset (mac_address, 0, sizeof (mac_address));
7365
7366   /* Parse args required to build the message */
7367   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7368     {
7369       if (unformat (i, "hw-addr %U", unformat_ethernet_address, mac_address))
7370         {
7371           random_mac = 0;
7372         }
7373       else if (unformat (i, "id %u", &id))
7374         ;
7375       else if (unformat (i, "host-if-name %s", &host_if_name))
7376         ;
7377       else if (unformat (i, "host-ns %s", &host_ns))
7378         ;
7379       else if (unformat (i, "host-mac-addr %U", unformat_ethernet_address,
7380                          host_mac_addr))
7381         host_mac_addr_set = 1;
7382       else if (unformat (i, "host-bridge %s", &host_bridge))
7383         ;
7384       else if (unformat (i, "host-ip4-addr %U/%d", unformat_ip4_address,
7385                          &host_ip4_addr, &host_ip4_prefix_len))
7386         ;
7387       else if (unformat (i, "host-ip6-addr %U/%d", unformat_ip6_address,
7388                          &host_ip6_addr, &host_ip6_prefix_len))
7389         ;
7390       else if (unformat (i, "host-ip4-gw %U", unformat_ip4_address,
7391                          &host_ip4_gw))
7392         host_ip4_gw_set = 1;
7393       else if (unformat (i, "host-ip6-gw %U", unformat_ip6_address,
7394                          &host_ip6_gw))
7395         host_ip6_gw_set = 1;
7396       else if (unformat (i, "rx-ring-size %d", &rx_ring_sz))
7397         ;
7398       else if (unformat (i, "tx-ring-size %d", &tx_ring_sz))
7399         ;
7400       else if (unformat (i, "host-mtu-size %d", &host_mtu_size))
7401         host_mtu_set = 1;
7402       else if (unformat (i, "no-gso"))
7403         tap_flags &= ~TAP_FLAG_GSO;
7404       else if (unformat (i, "gso"))
7405         tap_flags |= TAP_FLAG_GSO;
7406       else
7407         break;
7408     }
7409
7410   if (vec_len (host_if_name) > 63)
7411     {
7412       errmsg ("tap name too long. ");
7413       return -99;
7414     }
7415   if (vec_len (host_ns) > 63)
7416     {
7417       errmsg ("host name space too long. ");
7418       return -99;
7419     }
7420   if (vec_len (host_bridge) > 63)
7421     {
7422       errmsg ("host bridge name too long. ");
7423       return -99;
7424     }
7425   if (host_ip4_prefix_len > 32)
7426     {
7427       errmsg ("host ip4 prefix length not valid. ");
7428       return -99;
7429     }
7430   if (host_ip6_prefix_len > 128)
7431     {
7432       errmsg ("host ip6 prefix length not valid. ");
7433       return -99;
7434     }
7435   if (!is_pow2 (rx_ring_sz))
7436     {
7437       errmsg ("rx ring size must be power of 2. ");
7438       return -99;
7439     }
7440   if (rx_ring_sz > 32768)
7441     {
7442       errmsg ("rx ring size must be 32768 or lower. ");
7443       return -99;
7444     }
7445   if (!is_pow2 (tx_ring_sz))
7446     {
7447       errmsg ("tx ring size must be power of 2. ");
7448       return -99;
7449     }
7450   if (tx_ring_sz > 32768)
7451     {
7452       errmsg ("tx ring size must be 32768 or lower. ");
7453       return -99;
7454     }
7455   if (host_mtu_set && (host_mtu_size < 64 || host_mtu_size > 65355))
7456     {
7457       errmsg ("host MTU size must be in between 64 and 65355. ");
7458       return -99;
7459     }
7460
7461   /* Construct the API message */
7462   M (TAP_CREATE_V2, mp);
7463
7464   mp->use_random_mac = random_mac;
7465
7466   mp->id = ntohl (id);
7467   mp->host_namespace_set = host_ns != 0;
7468   mp->host_bridge_set = host_bridge != 0;
7469   mp->host_ip4_addr_set = host_ip4_prefix_len != 0;
7470   mp->host_ip6_addr_set = host_ip6_prefix_len != 0;
7471   mp->rx_ring_sz = ntohs (rx_ring_sz);
7472   mp->tx_ring_sz = ntohs (tx_ring_sz);
7473   mp->host_mtu_set = host_mtu_set;
7474   mp->host_mtu_size = ntohl (host_mtu_size);
7475   mp->tap_flags = ntohl (tap_flags);
7476
7477   if (random_mac == 0)
7478     clib_memcpy (mp->mac_address, mac_address, 6);
7479   if (host_mac_addr_set)
7480     clib_memcpy (mp->host_mac_addr, host_mac_addr, 6);
7481   if (host_if_name)
7482     clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
7483   if (host_ns)
7484     clib_memcpy (mp->host_namespace, host_ns, vec_len (host_ns));
7485   if (host_bridge)
7486     clib_memcpy (mp->host_bridge, host_bridge, vec_len (host_bridge));
7487   if (host_ip4_prefix_len)
7488     clib_memcpy (mp->host_ip4_addr, &host_ip4_addr, 4);
7489   if (host_ip6_prefix_len)
7490     clib_memcpy (mp->host_ip6_addr, &host_ip6_addr, 16);
7491   if (host_ip4_gw_set)
7492     clib_memcpy (mp->host_ip4_gw, &host_ip4_gw, 4);
7493   if (host_ip6_gw_set)
7494     clib_memcpy (mp->host_ip6_gw, &host_ip6_gw, 16);
7495
7496   vec_free (host_ns);
7497   vec_free (host_if_name);
7498   vec_free (host_bridge);
7499
7500   /* send it... */
7501   S (mp);
7502
7503   /* Wait for a reply... */
7504   W (ret);
7505   return ret;
7506 }
7507
7508 static int
7509 api_tap_delete_v2 (vat_main_t * vam)
7510 {
7511   unformat_input_t *i = vam->input;
7512   vl_api_tap_delete_v2_t *mp;
7513   u32 sw_if_index = ~0;
7514   u8 sw_if_index_set = 0;
7515   int ret;
7516
7517   /* Parse args required to build the message */
7518   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7519     {
7520       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7521         sw_if_index_set = 1;
7522       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7523         sw_if_index_set = 1;
7524       else
7525         break;
7526     }
7527
7528   if (sw_if_index_set == 0)
7529     {
7530       errmsg ("missing vpp interface name. ");
7531       return -99;
7532     }
7533
7534   /* Construct the API message */
7535   M (TAP_DELETE_V2, mp);
7536
7537   mp->sw_if_index = ntohl (sw_if_index);
7538
7539   /* send it... */
7540   S (mp);
7541
7542   /* Wait for a reply... */
7543   W (ret);
7544   return ret;
7545 }
7546
7547 uword
7548 unformat_vlib_pci_addr (unformat_input_t * input, va_list * args)
7549 {
7550   vlib_pci_addr_t *addr = va_arg (*args, vlib_pci_addr_t *);
7551   u32 x[4];
7552
7553   if (!unformat (input, "%x:%x:%x.%x", &x[0], &x[1], &x[2], &x[3]))
7554     return 0;
7555
7556   addr->domain = x[0];
7557   addr->bus = x[1];
7558   addr->slot = x[2];
7559   addr->function = x[3];
7560
7561   return 1;
7562 }
7563
7564 static int
7565 api_virtio_pci_create (vat_main_t * vam)
7566 {
7567   unformat_input_t *i = vam->input;
7568   vl_api_virtio_pci_create_t *mp;
7569   u8 mac_address[6];
7570   u8 random_mac = 1;
7571   u8 gso_enabled = 0;
7572   u32 pci_addr = 0;
7573   u64 features = (u64) ~ (0ULL);
7574   int ret;
7575
7576   clib_memset (mac_address, 0, sizeof (mac_address));
7577
7578   /* Parse args required to build the message */
7579   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7580     {
7581       if (unformat (i, "hw-addr %U", unformat_ethernet_address, mac_address))
7582         {
7583           random_mac = 0;
7584         }
7585       else if (unformat (i, "pci-addr %U", unformat_vlib_pci_addr, &pci_addr))
7586         ;
7587       else if (unformat (i, "features 0x%llx", &features))
7588         ;
7589       else if (unformat (i, "gso-enabled"))
7590         gso_enabled = 1;
7591       else
7592         break;
7593     }
7594
7595   if (pci_addr == 0)
7596     {
7597       errmsg ("pci address must be non zero. ");
7598       return -99;
7599     }
7600
7601   /* Construct the API message */
7602   M (VIRTIO_PCI_CREATE, mp);
7603
7604   mp->use_random_mac = random_mac;
7605
7606   mp->pci_addr = htonl (pci_addr);
7607   mp->features = clib_host_to_net_u64 (features);
7608   mp->gso_enabled = gso_enabled;
7609
7610   if (random_mac == 0)
7611     clib_memcpy (mp->mac_address, mac_address, 6);
7612
7613   /* send it... */
7614   S (mp);
7615
7616   /* Wait for a reply... */
7617   W (ret);
7618   return ret;
7619 }
7620
7621 static int
7622 api_virtio_pci_delete (vat_main_t * vam)
7623 {
7624   unformat_input_t *i = vam->input;
7625   vl_api_virtio_pci_delete_t *mp;
7626   u32 sw_if_index = ~0;
7627   u8 sw_if_index_set = 0;
7628   int ret;
7629
7630   /* Parse args required to build the message */
7631   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7632     {
7633       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7634         sw_if_index_set = 1;
7635       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7636         sw_if_index_set = 1;
7637       else
7638         break;
7639     }
7640
7641   if (sw_if_index_set == 0)
7642     {
7643       errmsg ("missing vpp interface name. ");
7644       return -99;
7645     }
7646
7647   /* Construct the API message */
7648   M (VIRTIO_PCI_DELETE, mp);
7649
7650   mp->sw_if_index = htonl (sw_if_index);
7651
7652   /* send it... */
7653   S (mp);
7654
7655   /* Wait for a reply... */
7656   W (ret);
7657   return ret;
7658 }
7659
7660 static int
7661 api_bond_create (vat_main_t * vam)
7662 {
7663   unformat_input_t *i = vam->input;
7664   vl_api_bond_create_t *mp;
7665   u8 mac_address[6];
7666   u8 custom_mac = 0;
7667   int ret;
7668   u8 mode;
7669   u8 lb;
7670   u8 mode_is_set = 0;
7671   u32 id = ~0;
7672   u8 numa_only = 0;
7673
7674   clib_memset (mac_address, 0, sizeof (mac_address));
7675   lb = BOND_LB_L2;
7676
7677   /* Parse args required to build the message */
7678   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7679     {
7680       if (unformat (i, "mode %U", unformat_bond_mode, &mode))
7681         mode_is_set = 1;
7682       else if (((mode == BOND_MODE_LACP) || (mode == BOND_MODE_XOR))
7683                && unformat (i, "lb %U", unformat_bond_load_balance, &lb))
7684         ;
7685       else if (unformat (i, "hw-addr %U", unformat_ethernet_address,
7686                          mac_address))
7687         custom_mac = 1;
7688       else if (unformat (i, "numa-only"))
7689         numa_only = 1;
7690       else if (unformat (i, "id %u", &id))
7691         ;
7692       else
7693         break;
7694     }
7695
7696   if (mode_is_set == 0)
7697     {
7698       errmsg ("Missing bond mode. ");
7699       return -99;
7700     }
7701
7702   /* Construct the API message */
7703   M (BOND_CREATE, mp);
7704
7705   mp->use_custom_mac = custom_mac;
7706
7707   mp->mode = htonl (mode);
7708   mp->lb = htonl (lb);
7709   mp->id = htonl (id);
7710   mp->numa_only = numa_only;
7711
7712   if (custom_mac)
7713     clib_memcpy (mp->mac_address, mac_address, 6);
7714
7715   /* send it... */
7716   S (mp);
7717
7718   /* Wait for a reply... */
7719   W (ret);
7720   return ret;
7721 }
7722
7723 static int
7724 api_bond_delete (vat_main_t * vam)
7725 {
7726   unformat_input_t *i = vam->input;
7727   vl_api_bond_delete_t *mp;
7728   u32 sw_if_index = ~0;
7729   u8 sw_if_index_set = 0;
7730   int ret;
7731
7732   /* Parse args required to build the message */
7733   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7734     {
7735       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7736         sw_if_index_set = 1;
7737       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7738         sw_if_index_set = 1;
7739       else
7740         break;
7741     }
7742
7743   if (sw_if_index_set == 0)
7744     {
7745       errmsg ("missing vpp interface name. ");
7746       return -99;
7747     }
7748
7749   /* Construct the API message */
7750   M (BOND_DELETE, mp);
7751
7752   mp->sw_if_index = ntohl (sw_if_index);
7753
7754   /* send it... */
7755   S (mp);
7756
7757   /* Wait for a reply... */
7758   W (ret);
7759   return ret;
7760 }
7761
7762 static int
7763 api_bond_enslave (vat_main_t * vam)
7764 {
7765   unformat_input_t *i = vam->input;
7766   vl_api_bond_enslave_t *mp;
7767   u32 bond_sw_if_index;
7768   int ret;
7769   u8 is_passive;
7770   u8 is_long_timeout;
7771   u32 bond_sw_if_index_is_set = 0;
7772   u32 sw_if_index;
7773   u8 sw_if_index_is_set = 0;
7774
7775   /* Parse args required to build the message */
7776   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7777     {
7778       if (unformat (i, "sw_if_index %d", &sw_if_index))
7779         sw_if_index_is_set = 1;
7780       else if (unformat (i, "bond %u", &bond_sw_if_index))
7781         bond_sw_if_index_is_set = 1;
7782       else if (unformat (i, "passive %d", &is_passive))
7783         ;
7784       else if (unformat (i, "long-timeout %d", &is_long_timeout))
7785         ;
7786       else
7787         break;
7788     }
7789
7790   if (bond_sw_if_index_is_set == 0)
7791     {
7792       errmsg ("Missing bond sw_if_index. ");
7793       return -99;
7794     }
7795   if (sw_if_index_is_set == 0)
7796     {
7797       errmsg ("Missing slave sw_if_index. ");
7798       return -99;
7799     }
7800
7801   /* Construct the API message */
7802   M (BOND_ENSLAVE, mp);
7803
7804   mp->bond_sw_if_index = ntohl (bond_sw_if_index);
7805   mp->sw_if_index = ntohl (sw_if_index);
7806   mp->is_long_timeout = is_long_timeout;
7807   mp->is_passive = is_passive;
7808
7809   /* send it... */
7810   S (mp);
7811
7812   /* Wait for a reply... */
7813   W (ret);
7814   return ret;
7815 }
7816
7817 static int
7818 api_bond_detach_slave (vat_main_t * vam)
7819 {
7820   unformat_input_t *i = vam->input;
7821   vl_api_bond_detach_slave_t *mp;
7822   u32 sw_if_index = ~0;
7823   u8 sw_if_index_set = 0;
7824   int ret;
7825
7826   /* Parse args required to build the message */
7827   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7828     {
7829       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7830         sw_if_index_set = 1;
7831       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7832         sw_if_index_set = 1;
7833       else
7834         break;
7835     }
7836
7837   if (sw_if_index_set == 0)
7838     {
7839       errmsg ("missing vpp interface name. ");
7840       return -99;
7841     }
7842
7843   /* Construct the API message */
7844   M (BOND_DETACH_SLAVE, mp);
7845
7846   mp->sw_if_index = ntohl (sw_if_index);
7847
7848   /* send it... */
7849   S (mp);
7850
7851   /* Wait for a reply... */
7852   W (ret);
7853   return ret;
7854 }
7855
7856 static int
7857 api_ip_table_add_del (vat_main_t * vam)
7858 {
7859   unformat_input_t *i = vam->input;
7860   vl_api_ip_table_add_del_t *mp;
7861   u32 table_id = ~0;
7862   u8 is_ipv6 = 0;
7863   u8 is_add = 1;
7864   int ret = 0;
7865
7866   /* Parse args required to build the message */
7867   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7868     {
7869       if (unformat (i, "ipv6"))
7870         is_ipv6 = 1;
7871       else if (unformat (i, "del"))
7872         is_add = 0;
7873       else if (unformat (i, "add"))
7874         is_add = 1;
7875       else if (unformat (i, "table %d", &table_id))
7876         ;
7877       else
7878         {
7879           clib_warning ("parse error '%U'", format_unformat_error, i);
7880           return -99;
7881         }
7882     }
7883
7884   if (~0 == table_id)
7885     {
7886       errmsg ("missing table-ID");
7887       return -99;
7888     }
7889
7890   /* Construct the API message */
7891   M (IP_TABLE_ADD_DEL, mp);
7892
7893   mp->table.table_id = ntohl (table_id);
7894   mp->table.is_ip6 = is_ipv6;
7895   mp->is_add = is_add;
7896
7897   /* send it... */
7898   S (mp);
7899
7900   /* Wait for a reply... */
7901   W (ret);
7902
7903   return ret;
7904 }
7905
7906 uword
7907 unformat_fib_path (unformat_input_t * input, va_list * args)
7908 {
7909   vat_main_t *vam = va_arg (*args, vat_main_t *);
7910   vl_api_fib_path_t *path = va_arg (*args, vl_api_fib_path_t *);
7911   u32 weight, preference;
7912   mpls_label_t out_label;
7913
7914   clib_memset (path, 0, sizeof (*path));
7915   path->weight = 1;
7916   path->sw_if_index = ~0;
7917   path->rpf_id = ~0;
7918   path->n_labels = 0;
7919
7920   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7921     {
7922       if (unformat (input, "%U %U",
7923                     unformat_vl_api_ip4_address,
7924                     &path->nh.address.ip4,
7925                     api_unformat_sw_if_index, vam, &path->sw_if_index))
7926         {
7927           path->proto = FIB_API_PATH_NH_PROTO_IP4;
7928         }
7929       else if (unformat (input, "%U %U",
7930                          unformat_vl_api_ip6_address,
7931                          &path->nh.address.ip6,
7932                          api_unformat_sw_if_index, vam, &path->sw_if_index))
7933         {
7934           path->proto = FIB_API_PATH_NH_PROTO_IP6;
7935         }
7936       else if (unformat (input, "weight %u", &weight))
7937         {
7938           path->weight = weight;
7939         }
7940       else if (unformat (input, "preference %u", &preference))
7941         {
7942           path->preference = preference;
7943         }
7944       else if (unformat (input, "%U next-hop-table %d",
7945                          unformat_vl_api_ip4_address,
7946                          &path->nh.address.ip4, &path->table_id))
7947         {
7948           path->proto = FIB_API_PATH_NH_PROTO_IP4;
7949         }
7950       else if (unformat (input, "%U next-hop-table %d",
7951                          unformat_vl_api_ip6_address,
7952                          &path->nh.address.ip6, &path->table_id))
7953         {
7954           path->proto = FIB_API_PATH_NH_PROTO_IP6;
7955         }
7956       else if (unformat (input, "%U",
7957                          unformat_vl_api_ip4_address, &path->nh.address.ip4))
7958         {
7959           /*
7960            * the recursive next-hops are by default in the default table
7961            */
7962           path->table_id = 0;
7963           path->sw_if_index = ~0;
7964           path->proto = FIB_API_PATH_NH_PROTO_IP4;
7965         }
7966       else if (unformat (input, "%U",
7967                          unformat_vl_api_ip6_address, &path->nh.address.ip6))
7968         {
7969           /*
7970            * the recursive next-hops are by default in the default table
7971            */
7972           path->table_id = 0;
7973           path->sw_if_index = ~0;
7974           path->proto = FIB_API_PATH_NH_PROTO_IP6;
7975         }
7976       else if (unformat (input, "resolve-via-host"))
7977         {
7978           path->flags |= FIB_API_PATH_FLAG_RESOLVE_VIA_HOST;
7979         }
7980       else if (unformat (input, "resolve-via-attached"))
7981         {
7982           path->flags |= FIB_API_PATH_FLAG_RESOLVE_VIA_ATTACHED;
7983         }
7984       else if (unformat (input, "ip4-lookup-in-table %d", &path->table_id))
7985         {
7986           path->type = FIB_API_PATH_TYPE_LOCAL;
7987           path->sw_if_index = ~0;
7988           path->proto = FIB_API_PATH_NH_PROTO_IP4;
7989         }
7990       else if (unformat (input, "ip6-lookup-in-table %d", &path->table_id))
7991         {
7992           path->type = FIB_API_PATH_TYPE_LOCAL;
7993           path->sw_if_index = ~0;
7994           path->proto = FIB_API_PATH_NH_PROTO_IP6;
7995         }
7996       else if (unformat (input, "sw_if_index %d", &path->sw_if_index))
7997         ;
7998       else if (unformat (input, "via-label %d", &path->nh.via_label))
7999         {
8000           path->proto = FIB_API_PATH_NH_PROTO_MPLS;
8001           path->sw_if_index = ~0;
8002         }
8003       else if (unformat (input, "l2-input-on %d", &path->sw_if_index))
8004         {
8005           path->proto = FIB_API_PATH_NH_PROTO_ETHERNET;
8006           path->type = FIB_API_PATH_TYPE_INTERFACE_RX;
8007         }
8008       else if (unformat (input, "local"))
8009         {
8010           path->type = FIB_API_PATH_TYPE_LOCAL;
8011         }
8012       else if (unformat (input, "out-labels"))
8013         {
8014           while (unformat (input, "%d", &out_label))
8015             {
8016               path->label_stack[path->n_labels].label = out_label;
8017               path->label_stack[path->n_labels].is_uniform = 0;
8018               path->label_stack[path->n_labels].ttl = 64;
8019               path->n_labels++;
8020             }
8021         }
8022       else if (unformat (input, "via"))
8023         {
8024           /* new path, back up and return */
8025           unformat_put_input (input);
8026           unformat_put_input (input);
8027           unformat_put_input (input);
8028           unformat_put_input (input);
8029           break;
8030         }
8031       else
8032         {
8033           return (0);
8034         }
8035     }
8036
8037   path->proto = ntohl (path->proto);
8038   path->type = ntohl (path->type);
8039   path->flags = ntohl (path->flags);
8040   path->table_id = ntohl (path->table_id);
8041   path->sw_if_index = ntohl (path->sw_if_index);
8042
8043   return (1);
8044 }
8045
8046 static int
8047 api_ip_route_add_del (vat_main_t * vam)
8048 {
8049   unformat_input_t *i = vam->input;
8050   vl_api_ip_route_add_del_t *mp;
8051   u32 vrf_id = 0;
8052   u8 is_add = 1;
8053   u8 is_multipath = 0;
8054   u8 prefix_set = 0;
8055   u8 path_count = 0;
8056   vl_api_prefix_t pfx = { };
8057   vl_api_fib_path_t paths[8];
8058   int count = 1;
8059   int j;
8060   f64 before = 0;
8061   u32 random_add_del = 0;
8062   u32 *random_vector = 0;
8063   u32 random_seed = 0xdeaddabe;
8064
8065   /* Parse args required to build the message */
8066   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8067     {
8068       if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
8069         prefix_set = 1;
8070       else if (unformat (i, "del"))
8071         is_add = 0;
8072       else if (unformat (i, "add"))
8073         is_add = 1;
8074       else if (unformat (i, "vrf %d", &vrf_id))
8075         ;
8076       else if (unformat (i, "count %d", &count))
8077         ;
8078       else if (unformat (i, "random"))
8079         random_add_del = 1;
8080       else if (unformat (i, "multipath"))
8081         is_multipath = 1;
8082       else if (unformat (i, "seed %d", &random_seed))
8083         ;
8084       else
8085         if (unformat
8086             (i, "via %U", unformat_fib_path, vam, &paths[path_count]))
8087         {
8088           path_count++;
8089           if (8 == path_count)
8090             {
8091               errmsg ("max 8 paths");
8092               return -99;
8093             }
8094         }
8095       else
8096         {
8097           clib_warning ("parse error '%U'", format_unformat_error, i);
8098           return -99;
8099         }
8100     }
8101
8102   if (!path_count)
8103     {
8104       errmsg ("specify a path; via ...");
8105       return -99;
8106     }
8107   if (prefix_set == 0)
8108     {
8109       errmsg ("missing prefix");
8110       return -99;
8111     }
8112
8113   /* Generate a pile of unique, random routes */
8114   if (random_add_del)
8115     {
8116       ip4_address_t *i = (ip4_address_t *) & paths[0].nh.address.ip4;
8117       u32 this_random_address;
8118       uword *random_hash;
8119
8120       random_hash = hash_create (count, sizeof (uword));
8121
8122       hash_set (random_hash, i->as_u32, 1);
8123       for (j = 0; j <= count; j++)
8124         {
8125           do
8126             {
8127               this_random_address = random_u32 (&random_seed);
8128               this_random_address =
8129                 clib_host_to_net_u32 (this_random_address);
8130             }
8131           while (hash_get (random_hash, this_random_address));
8132           vec_add1 (random_vector, this_random_address);
8133           hash_set (random_hash, this_random_address, 1);
8134         }
8135       hash_free (random_hash);
8136       set_ip4_address (&pfx.address, random_vector[0]);
8137     }
8138
8139   if (count > 1)
8140     {
8141       /* Turn on async mode */
8142       vam->async_mode = 1;
8143       vam->async_errors = 0;
8144       before = vat_time_now (vam);
8145     }
8146
8147   for (j = 0; j < count; j++)
8148     {
8149       /* Construct the API message */
8150       M2 (IP_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t) * path_count);
8151
8152       mp->is_add = is_add;
8153       mp->is_multipath = is_multipath;
8154
8155       clib_memcpy (&mp->route.prefix, &pfx, sizeof (pfx));
8156       mp->route.table_id = ntohl (vrf_id);
8157       mp->route.n_paths = path_count;
8158
8159       clib_memcpy (&mp->route.paths, &paths, sizeof (paths[0]) * path_count);
8160
8161       if (random_add_del)
8162         set_ip4_address (&pfx.address, random_vector[j + 1]);
8163       else
8164         increment_address (&pfx.address);
8165       /* send it... */
8166       S (mp);
8167       /* If we receive SIGTERM, stop now... */
8168       if (vam->do_exit)
8169         break;
8170     }
8171
8172   /* When testing multiple add/del ops, use a control-ping to sync */
8173   if (count > 1)
8174     {
8175       vl_api_control_ping_t *mp_ping;
8176       f64 after;
8177       f64 timeout;
8178
8179       /* Shut off async mode */
8180       vam->async_mode = 0;
8181
8182       MPING (CONTROL_PING, mp_ping);
8183       S (mp_ping);
8184
8185       timeout = vat_time_now (vam) + 1.0;
8186       while (vat_time_now (vam) < timeout)
8187         if (vam->result_ready == 1)
8188           goto out;
8189       vam->retval = -99;
8190
8191     out:
8192       if (vam->retval == -99)
8193         errmsg ("timeout");
8194
8195       if (vam->async_errors > 0)
8196         {
8197           errmsg ("%d asynchronous errors", vam->async_errors);
8198           vam->retval = -98;
8199         }
8200       vam->async_errors = 0;
8201       after = vat_time_now (vam);
8202
8203       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8204       if (j > 0)
8205         count = j;
8206
8207       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8208              count, after - before, count / (after - before));
8209     }
8210   else
8211     {
8212       int ret;
8213
8214       /* Wait for a reply... */
8215       W (ret);
8216       return ret;
8217     }
8218
8219   /* Return the good/bad news */
8220   return (vam->retval);
8221 }
8222
8223 static int
8224 api_ip_mroute_add_del (vat_main_t * vam)
8225 {
8226   unformat_input_t *i = vam->input;
8227   u8 path_set = 0, prefix_set = 0, is_add = 1;
8228   vl_api_ip_mroute_add_del_t *mp;
8229   mfib_entry_flags_t eflags = 0;
8230   vl_api_mfib_path_t path;
8231   vl_api_mprefix_t pfx = { };
8232   u32 vrf_id = 0;
8233   int ret;
8234
8235   /* Parse args required to build the message */
8236   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8237     {
8238       if (unformat (i, "%U", unformat_vl_api_mprefix, &pfx))
8239         {
8240           prefix_set = 1;
8241           pfx.grp_address_length = htons (pfx.grp_address_length);
8242         }
8243       else if (unformat (i, "del"))
8244         is_add = 0;
8245       else if (unformat (i, "add"))
8246         is_add = 1;
8247       else if (unformat (i, "vrf %d", &vrf_id))
8248         ;
8249       else if (unformat (i, "%U", unformat_mfib_itf_flags, &path.itf_flags))
8250         path.itf_flags = htonl (path.itf_flags);
8251       else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
8252         ;
8253       else if (unformat (i, "via %U", unformat_fib_path, vam, &path.path))
8254         path_set = 1;
8255       else
8256         {
8257           clib_warning ("parse error '%U'", format_unformat_error, i);
8258           return -99;
8259         }
8260     }
8261
8262   if (prefix_set == 0)
8263     {
8264       errmsg ("missing addresses\n");
8265       return -99;
8266     }
8267   if (path_set == 0)
8268     {
8269       errmsg ("missing path\n");
8270       return -99;
8271     }
8272
8273   /* Construct the API message */
8274   M (IP_MROUTE_ADD_DEL, mp);
8275
8276   mp->is_add = is_add;
8277   mp->is_multipath = 1;
8278
8279   clib_memcpy (&mp->route.prefix, &pfx, sizeof (pfx));
8280   mp->route.table_id = htonl (vrf_id);
8281   mp->route.n_paths = 1;
8282   mp->route.entry_flags = htonl (eflags);
8283
8284   clib_memcpy (&mp->route.paths, &path, sizeof (path));
8285
8286   /* send it... */
8287   S (mp);
8288   /* Wait for a reply... */
8289   W (ret);
8290   return ret;
8291 }
8292
8293 static int
8294 api_mpls_table_add_del (vat_main_t * vam)
8295 {
8296   unformat_input_t *i = vam->input;
8297   vl_api_mpls_table_add_del_t *mp;
8298   u32 table_id = ~0;
8299   u8 is_add = 1;
8300   int ret = 0;
8301
8302   /* Parse args required to build the message */
8303   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8304     {
8305       if (unformat (i, "table %d", &table_id))
8306         ;
8307       else if (unformat (i, "del"))
8308         is_add = 0;
8309       else if (unformat (i, "add"))
8310         is_add = 1;
8311       else
8312         {
8313           clib_warning ("parse error '%U'", format_unformat_error, i);
8314           return -99;
8315         }
8316     }
8317
8318   if (~0 == table_id)
8319     {
8320       errmsg ("missing table-ID");
8321       return -99;
8322     }
8323
8324   /* Construct the API message */
8325   M (MPLS_TABLE_ADD_DEL, mp);
8326
8327   mp->mt_table.mt_table_id = ntohl (table_id);
8328   mp->mt_is_add = is_add;
8329
8330   /* send it... */
8331   S (mp);
8332
8333   /* Wait for a reply... */
8334   W (ret);
8335
8336   return ret;
8337 }
8338
8339 static int
8340 api_mpls_route_add_del (vat_main_t * vam)
8341 {
8342   u8 is_add = 1, path_count = 0, is_multipath = 0, is_eos = 0;
8343   mpls_label_t local_label = MPLS_LABEL_INVALID;
8344   unformat_input_t *i = vam->input;
8345   vl_api_mpls_route_add_del_t *mp;
8346   vl_api_fib_path_t paths[8];
8347   int count = 1, j;
8348   f64 before = 0;
8349
8350   /* Parse args required to build the message */
8351   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8352     {
8353       if (unformat (i, "%d", &local_label))
8354         ;
8355       else if (unformat (i, "eos"))
8356         is_eos = 1;
8357       else if (unformat (i, "non-eos"))
8358         is_eos = 0;
8359       else if (unformat (i, "del"))
8360         is_add = 0;
8361       else if (unformat (i, "add"))
8362         is_add = 1;
8363       else if (unformat (i, "multipath"))
8364         is_multipath = 1;
8365       else if (unformat (i, "count %d", &count))
8366         ;
8367       else
8368         if (unformat
8369             (i, "via %U", unformat_fib_path, vam, &paths[path_count]))
8370         {
8371           path_count++;
8372           if (8 == path_count)
8373             {
8374               errmsg ("max 8 paths");
8375               return -99;
8376             }
8377         }
8378       else
8379         {
8380           clib_warning ("parse error '%U'", format_unformat_error, i);
8381           return -99;
8382         }
8383     }
8384
8385   if (!path_count)
8386     {
8387       errmsg ("specify a path; via ...");
8388       return -99;
8389     }
8390
8391   if (MPLS_LABEL_INVALID == local_label)
8392     {
8393       errmsg ("missing label");
8394       return -99;
8395     }
8396
8397   if (count > 1)
8398     {
8399       /* Turn on async mode */
8400       vam->async_mode = 1;
8401       vam->async_errors = 0;
8402       before = vat_time_now (vam);
8403     }
8404
8405   for (j = 0; j < count; j++)
8406     {
8407       /* Construct the API message */
8408       M2 (MPLS_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t) * path_count);
8409
8410       mp->mr_is_add = is_add;
8411       mp->mr_is_multipath = is_multipath;
8412
8413       mp->mr_route.mr_label = local_label;
8414       mp->mr_route.mr_eos = is_eos;
8415       mp->mr_route.mr_table_id = 0;
8416       mp->mr_route.mr_n_paths = path_count;
8417
8418       clib_memcpy (&mp->mr_route.mr_paths, paths,
8419                    sizeof (paths[0]) * path_count);
8420
8421       local_label++;
8422
8423       /* send it... */
8424       S (mp);
8425       /* If we receive SIGTERM, stop now... */
8426       if (vam->do_exit)
8427         break;
8428     }
8429
8430   /* When testing multiple add/del ops, use a control-ping to sync */
8431   if (count > 1)
8432     {
8433       vl_api_control_ping_t *mp_ping;
8434       f64 after;
8435       f64 timeout;
8436
8437       /* Shut off async mode */
8438       vam->async_mode = 0;
8439
8440       MPING (CONTROL_PING, mp_ping);
8441       S (mp_ping);
8442
8443       timeout = vat_time_now (vam) + 1.0;
8444       while (vat_time_now (vam) < timeout)
8445         if (vam->result_ready == 1)
8446           goto out;
8447       vam->retval = -99;
8448
8449     out:
8450       if (vam->retval == -99)
8451         errmsg ("timeout");
8452
8453       if (vam->async_errors > 0)
8454         {
8455           errmsg ("%d asynchronous errors", vam->async_errors);
8456           vam->retval = -98;
8457         }
8458       vam->async_errors = 0;
8459       after = vat_time_now (vam);
8460
8461       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8462       if (j > 0)
8463         count = j;
8464
8465       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8466              count, after - before, count / (after - before));
8467     }
8468   else
8469     {
8470       int ret;
8471
8472       /* Wait for a reply... */
8473       W (ret);
8474       return ret;
8475     }
8476
8477   /* Return the good/bad news */
8478   return (vam->retval);
8479   return (0);
8480 }
8481
8482 static int
8483 api_mpls_ip_bind_unbind (vat_main_t * vam)
8484 {
8485   unformat_input_t *i = vam->input;
8486   vl_api_mpls_ip_bind_unbind_t *mp;
8487   u32 ip_table_id = 0;
8488   u8 is_bind = 1;
8489   vl_api_prefix_t pfx;
8490   u8 prefix_set = 0;
8491   mpls_label_t local_label = MPLS_LABEL_INVALID;
8492   int ret;
8493
8494   /* Parse args required to build the message */
8495   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8496     {
8497       if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
8498         prefix_set = 1;
8499       else if (unformat (i, "%d", &local_label))
8500         ;
8501       else if (unformat (i, "table-id %d", &ip_table_id))
8502         ;
8503       else if (unformat (i, "unbind"))
8504         is_bind = 0;
8505       else if (unformat (i, "bind"))
8506         is_bind = 1;
8507       else
8508         {
8509           clib_warning ("parse error '%U'", format_unformat_error, i);
8510           return -99;
8511         }
8512     }
8513
8514   if (!prefix_set)
8515     {
8516       errmsg ("IP prefix not set");
8517       return -99;
8518     }
8519
8520   if (MPLS_LABEL_INVALID == local_label)
8521     {
8522       errmsg ("missing label");
8523       return -99;
8524     }
8525
8526   /* Construct the API message */
8527   M (MPLS_IP_BIND_UNBIND, mp);
8528
8529   mp->mb_is_bind = is_bind;
8530   mp->mb_ip_table_id = ntohl (ip_table_id);
8531   mp->mb_mpls_table_id = 0;
8532   mp->mb_label = ntohl (local_label);
8533   clib_memcpy (&mp->mb_prefix, &pfx, sizeof (pfx));
8534
8535   /* send it... */
8536   S (mp);
8537
8538   /* Wait for a reply... */
8539   W (ret);
8540   return ret;
8541   return (0);
8542 }
8543
8544 static int
8545 api_sr_mpls_policy_add (vat_main_t * vam)
8546 {
8547   unformat_input_t *i = vam->input;
8548   vl_api_sr_mpls_policy_add_t *mp;
8549   u32 bsid = 0;
8550   u32 weight = 1;
8551   u8 type = 0;
8552   u8 n_segments = 0;
8553   u32 sid;
8554   u32 *segments = NULL;
8555   int ret;
8556
8557   /* Parse args required to build the message */
8558   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8559     {
8560       if (unformat (i, "bsid %d", &bsid))
8561         ;
8562       else if (unformat (i, "weight %d", &weight))
8563         ;
8564       else if (unformat (i, "spray"))
8565         type = 1;
8566       else if (unformat (i, "next %d", &sid))
8567         {
8568           n_segments += 1;
8569           vec_add1 (segments, htonl (sid));
8570         }
8571       else
8572         {
8573           clib_warning ("parse error '%U'", format_unformat_error, i);
8574           return -99;
8575         }
8576     }
8577
8578   if (bsid == 0)
8579     {
8580       errmsg ("bsid not set");
8581       return -99;
8582     }
8583
8584   if (n_segments == 0)
8585     {
8586       errmsg ("no sid in segment stack");
8587       return -99;
8588     }
8589
8590   /* Construct the API message */
8591   M2 (SR_MPLS_POLICY_ADD, mp, sizeof (u32) * n_segments);
8592
8593   mp->bsid = htonl (bsid);
8594   mp->weight = htonl (weight);
8595   mp->type = type;
8596   mp->n_segments = n_segments;
8597   memcpy (mp->segments, segments, sizeof (u32) * n_segments);
8598   vec_free (segments);
8599
8600   /* send it... */
8601   S (mp);
8602
8603   /* Wait for a reply... */
8604   W (ret);
8605   return ret;
8606 }
8607
8608 static int
8609 api_sr_mpls_policy_del (vat_main_t * vam)
8610 {
8611   unformat_input_t *i = vam->input;
8612   vl_api_sr_mpls_policy_del_t *mp;
8613   u32 bsid = 0;
8614   int ret;
8615
8616   /* Parse args required to build the message */
8617   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8618     {
8619       if (unformat (i, "bsid %d", &bsid))
8620         ;
8621       else
8622         {
8623           clib_warning ("parse error '%U'", format_unformat_error, i);
8624           return -99;
8625         }
8626     }
8627
8628   if (bsid == 0)
8629     {
8630       errmsg ("bsid not set");
8631       return -99;
8632     }
8633
8634   /* Construct the API message */
8635   M (SR_MPLS_POLICY_DEL, mp);
8636
8637   mp->bsid = htonl (bsid);
8638
8639   /* send it... */
8640   S (mp);
8641
8642   /* Wait for a reply... */
8643   W (ret);
8644   return ret;
8645 }
8646
8647 static int
8648 api_bier_table_add_del (vat_main_t * vam)
8649 {
8650   unformat_input_t *i = vam->input;
8651   vl_api_bier_table_add_del_t *mp;
8652   u8 is_add = 1;
8653   u32 set = 0, sub_domain = 0, hdr_len = 3;
8654   mpls_label_t local_label = MPLS_LABEL_INVALID;
8655   int ret;
8656
8657   /* Parse args required to build the message */
8658   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8659     {
8660       if (unformat (i, "sub-domain %d", &sub_domain))
8661         ;
8662       else if (unformat (i, "set %d", &set))
8663         ;
8664       else if (unformat (i, "label %d", &local_label))
8665         ;
8666       else if (unformat (i, "hdr-len %d", &hdr_len))
8667         ;
8668       else if (unformat (i, "add"))
8669         is_add = 1;
8670       else if (unformat (i, "del"))
8671         is_add = 0;
8672       else
8673         {
8674           clib_warning ("parse error '%U'", format_unformat_error, i);
8675           return -99;
8676         }
8677     }
8678
8679   if (MPLS_LABEL_INVALID == local_label)
8680     {
8681       errmsg ("missing label\n");
8682       return -99;
8683     }
8684
8685   /* Construct the API message */
8686   M (BIER_TABLE_ADD_DEL, mp);
8687
8688   mp->bt_is_add = is_add;
8689   mp->bt_label = ntohl (local_label);
8690   mp->bt_tbl_id.bt_set = set;
8691   mp->bt_tbl_id.bt_sub_domain = sub_domain;
8692   mp->bt_tbl_id.bt_hdr_len_id = hdr_len;
8693
8694   /* send it... */
8695   S (mp);
8696
8697   /* Wait for a reply... */
8698   W (ret);
8699
8700   return (ret);
8701 }
8702
8703 static int
8704 api_bier_route_add_del (vat_main_t * vam)
8705 {
8706   unformat_input_t *i = vam->input;
8707   vl_api_bier_route_add_del_t *mp;
8708   u8 is_add = 1;
8709   u32 set = 0, sub_domain = 0, hdr_len = 3, bp = 0;
8710   ip4_address_t v4_next_hop_address;
8711   ip6_address_t v6_next_hop_address;
8712   u8 next_hop_set = 0;
8713   u8 next_hop_proto_is_ip4 = 1;
8714   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8715   int ret;
8716
8717   /* Parse args required to build the message */
8718   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8719     {
8720       if (unformat (i, "%U", unformat_ip4_address, &v4_next_hop_address))
8721         {
8722           next_hop_proto_is_ip4 = 1;
8723           next_hop_set = 1;
8724         }
8725       else if (unformat (i, "%U", unformat_ip6_address, &v6_next_hop_address))
8726         {
8727           next_hop_proto_is_ip4 = 0;
8728           next_hop_set = 1;
8729         }
8730       if (unformat (i, "sub-domain %d", &sub_domain))
8731         ;
8732       else if (unformat (i, "set %d", &set))
8733         ;
8734       else if (unformat (i, "hdr-len %d", &hdr_len))
8735         ;
8736       else if (unformat (i, "bp %d", &bp))
8737         ;
8738       else if (unformat (i, "add"))
8739         is_add = 1;
8740       else if (unformat (i, "del"))
8741         is_add = 0;
8742       else if (unformat (i, "out-label %d", &next_hop_out_label))
8743         ;
8744       else
8745         {
8746           clib_warning ("parse error '%U'", format_unformat_error, i);
8747           return -99;
8748         }
8749     }
8750
8751   if (!next_hop_set || (MPLS_LABEL_INVALID == next_hop_out_label))
8752     {
8753       errmsg ("next hop / label set\n");
8754       return -99;
8755     }
8756   if (0 == bp)
8757     {
8758       errmsg ("bit=position not set\n");
8759       return -99;
8760     }
8761
8762   /* Construct the API message */
8763   M2 (BIER_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t));
8764
8765   mp->br_is_add = is_add;
8766   mp->br_route.br_tbl_id.bt_set = set;
8767   mp->br_route.br_tbl_id.bt_sub_domain = sub_domain;
8768   mp->br_route.br_tbl_id.bt_hdr_len_id = hdr_len;
8769   mp->br_route.br_bp = ntohs (bp);
8770   mp->br_route.br_n_paths = 1;
8771   mp->br_route.br_paths[0].n_labels = 1;
8772   mp->br_route.br_paths[0].label_stack[0].label = ntohl (next_hop_out_label);
8773   mp->br_route.br_paths[0].proto = (next_hop_proto_is_ip4 ?
8774                                     FIB_API_PATH_NH_PROTO_IP4 :
8775                                     FIB_API_PATH_NH_PROTO_IP6);
8776
8777   if (next_hop_proto_is_ip4)
8778     {
8779       clib_memcpy (&mp->br_route.br_paths[0].nh.address.ip4,
8780                    &v4_next_hop_address, sizeof (v4_next_hop_address));
8781     }
8782   else
8783     {
8784       clib_memcpy (&mp->br_route.br_paths[0].nh.address.ip6,
8785                    &v6_next_hop_address, sizeof (v6_next_hop_address));
8786     }
8787
8788   /* send it... */
8789   S (mp);
8790
8791   /* Wait for a reply... */
8792   W (ret);
8793
8794   return (ret);
8795 }
8796
8797 static int
8798 api_proxy_arp_add_del (vat_main_t * vam)
8799 {
8800   unformat_input_t *i = vam->input;
8801   vl_api_proxy_arp_add_del_t *mp;
8802   u32 vrf_id = 0;
8803   u8 is_add = 1;
8804   vl_api_ip4_address_t lo, hi;
8805   u8 range_set = 0;
8806   int ret;
8807
8808   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8809     {
8810       if (unformat (i, "vrf %d", &vrf_id))
8811         ;
8812       else if (unformat (i, "%U - %U", unformat_vl_api_ip4_address, &lo,
8813                          unformat_vl_api_ip4_address, &hi))
8814         range_set = 1;
8815       else if (unformat (i, "del"))
8816         is_add = 0;
8817       else
8818         {
8819           clib_warning ("parse error '%U'", format_unformat_error, i);
8820           return -99;
8821         }
8822     }
8823
8824   if (range_set == 0)
8825     {
8826       errmsg ("address range not set");
8827       return -99;
8828     }
8829
8830   M (PROXY_ARP_ADD_DEL, mp);
8831
8832   mp->proxy.table_id = ntohl (vrf_id);
8833   mp->is_add = is_add;
8834   clib_memcpy (mp->proxy.low, &lo, sizeof (lo));
8835   clib_memcpy (mp->proxy.hi, &hi, sizeof (hi));
8836
8837   S (mp);
8838   W (ret);
8839   return ret;
8840 }
8841
8842 static int
8843 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
8844 {
8845   unformat_input_t *i = vam->input;
8846   vl_api_proxy_arp_intfc_enable_disable_t *mp;
8847   u32 sw_if_index;
8848   u8 enable = 1;
8849   u8 sw_if_index_set = 0;
8850   int ret;
8851
8852   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8853     {
8854       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8855         sw_if_index_set = 1;
8856       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8857         sw_if_index_set = 1;
8858       else if (unformat (i, "enable"))
8859         enable = 1;
8860       else if (unformat (i, "disable"))
8861         enable = 0;
8862       else
8863         {
8864           clib_warning ("parse error '%U'", format_unformat_error, i);
8865           return -99;
8866         }
8867     }
8868
8869   if (sw_if_index_set == 0)
8870     {
8871       errmsg ("missing interface name or sw_if_index");
8872       return -99;
8873     }
8874
8875   M (PROXY_ARP_INTFC_ENABLE_DISABLE, mp);
8876
8877   mp->sw_if_index = ntohl (sw_if_index);
8878   mp->enable_disable = enable;
8879
8880   S (mp);
8881   W (ret);
8882   return ret;
8883 }
8884
8885 static int
8886 api_mpls_tunnel_add_del (vat_main_t * vam)
8887 {
8888   unformat_input_t *i = vam->input;
8889   vl_api_mpls_tunnel_add_del_t *mp;
8890
8891   vl_api_fib_path_t paths[8];
8892   u32 sw_if_index = ~0;
8893   u8 path_count = 0;
8894   u8 l2_only = 0;
8895   u8 is_add = 1;
8896   int ret;
8897
8898   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8899     {
8900       if (unformat (i, "add"))
8901         is_add = 1;
8902       else
8903         if (unformat
8904             (i, "del %U", api_unformat_sw_if_index, vam, &sw_if_index))
8905         is_add = 0;
8906       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
8907         is_add = 0;
8908       else if (unformat (i, "l2-only"))
8909         l2_only = 1;
8910       else
8911         if (unformat
8912             (i, "via %U", unformat_fib_path, vam, &paths[path_count]))
8913         {
8914           path_count++;
8915           if (8 == path_count)
8916             {
8917               errmsg ("max 8 paths");
8918               return -99;
8919             }
8920         }
8921       else
8922         {
8923           clib_warning ("parse error '%U'", format_unformat_error, i);
8924           return -99;
8925         }
8926     }
8927
8928   M2 (MPLS_TUNNEL_ADD_DEL, mp, sizeof (vl_api_fib_path_t) * path_count);
8929
8930   mp->mt_is_add = is_add;
8931   mp->mt_tunnel.mt_sw_if_index = ntohl (sw_if_index);
8932   mp->mt_tunnel.mt_l2_only = l2_only;
8933   mp->mt_tunnel.mt_is_multicast = 0;
8934   mp->mt_tunnel.mt_n_paths = path_count;
8935
8936   clib_memcpy (&mp->mt_tunnel.mt_paths, &paths,
8937                sizeof (paths[0]) * path_count);
8938
8939   S (mp);
8940   W (ret);
8941   return ret;
8942 }
8943
8944 static int
8945 api_sw_interface_set_unnumbered (vat_main_t * vam)
8946 {
8947   unformat_input_t *i = vam->input;
8948   vl_api_sw_interface_set_unnumbered_t *mp;
8949   u32 sw_if_index;
8950   u32 unnum_sw_index = ~0;
8951   u8 is_add = 1;
8952   u8 sw_if_index_set = 0;
8953   int ret;
8954
8955   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8956     {
8957       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8958         sw_if_index_set = 1;
8959       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8960         sw_if_index_set = 1;
8961       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
8962         ;
8963       else if (unformat (i, "del"))
8964         is_add = 0;
8965       else
8966         {
8967           clib_warning ("parse error '%U'", format_unformat_error, i);
8968           return -99;
8969         }
8970     }
8971
8972   if (sw_if_index_set == 0)
8973     {
8974       errmsg ("missing interface name or sw_if_index");
8975       return -99;
8976     }
8977
8978   M (SW_INTERFACE_SET_UNNUMBERED, mp);
8979
8980   mp->sw_if_index = ntohl (sw_if_index);
8981   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
8982   mp->is_add = is_add;
8983
8984   S (mp);
8985   W (ret);
8986   return ret;
8987 }
8988
8989 static int
8990 api_ip_neighbor_add_del (vat_main_t * vam)
8991 {
8992   vl_api_mac_address_t mac_address;
8993   unformat_input_t *i = vam->input;
8994   vl_api_ip_neighbor_add_del_t *mp;
8995   vl_api_address_t ip_address;
8996   u32 sw_if_index;
8997   u8 sw_if_index_set = 0;
8998   u8 is_add = 1;
8999   u8 mac_set = 0;
9000   u8 address_set = 0;
9001   int ret;
9002   ip_neighbor_flags_t flags;
9003
9004   flags = IP_NEIGHBOR_FLAG_NONE;
9005   clib_memset (&ip_address, 0, sizeof (ip_address));
9006   clib_memset (&mac_address, 0, sizeof (mac_address));
9007
9008   /* Parse args required to build the message */
9009   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9010     {
9011       if (unformat (i, "mac %U", unformat_vl_api_mac_address, &mac_address))
9012         {
9013           mac_set = 1;
9014         }
9015       else if (unformat (i, "del"))
9016         is_add = 0;
9017       else
9018         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9019         sw_if_index_set = 1;
9020       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9021         sw_if_index_set = 1;
9022       else if (unformat (i, "static"))
9023         flags |= IP_NEIGHBOR_FLAG_STATIC;
9024       else if (unformat (i, "no-fib-entry"))
9025         flags |= IP_NEIGHBOR_FLAG_NO_FIB_ENTRY;
9026       else if (unformat (i, "dst %U", unformat_vl_api_address, &ip_address))
9027         address_set = 1;
9028       else
9029         {
9030           clib_warning ("parse error '%U'", format_unformat_error, i);
9031           return -99;
9032         }
9033     }
9034
9035   if (sw_if_index_set == 0)
9036     {
9037       errmsg ("missing interface name or sw_if_index");
9038       return -99;
9039     }
9040   if (!address_set)
9041     {
9042       errmsg ("no address set");
9043       return -99;
9044     }
9045
9046   /* Construct the API message */
9047   M (IP_NEIGHBOR_ADD_DEL, mp);
9048
9049   mp->neighbor.sw_if_index = ntohl (sw_if_index);
9050   mp->is_add = is_add;
9051   mp->neighbor.flags = htonl (flags);
9052   if (mac_set)
9053     clib_memcpy (&mp->neighbor.mac_address, &mac_address,
9054                  sizeof (mac_address));
9055   if (address_set)
9056     clib_memcpy (&mp->neighbor.ip_address, &ip_address, sizeof (ip_address));
9057
9058   /* send it... */
9059   S (mp);
9060
9061   /* Wait for a reply, return good/bad news  */
9062   W (ret);
9063   return ret;
9064 }
9065
9066 static int
9067 api_create_vlan_subif (vat_main_t * vam)
9068 {
9069   unformat_input_t *i = vam->input;
9070   vl_api_create_vlan_subif_t *mp;
9071   u32 sw_if_index;
9072   u8 sw_if_index_set = 0;
9073   u32 vlan_id;
9074   u8 vlan_id_set = 0;
9075   int ret;
9076
9077   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9078     {
9079       if (unformat (i, "sw_if_index %d", &sw_if_index))
9080         sw_if_index_set = 1;
9081       else
9082         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9083         sw_if_index_set = 1;
9084       else if (unformat (i, "vlan %d", &vlan_id))
9085         vlan_id_set = 1;
9086       else
9087         {
9088           clib_warning ("parse error '%U'", format_unformat_error, i);
9089           return -99;
9090         }
9091     }
9092
9093   if (sw_if_index_set == 0)
9094     {
9095       errmsg ("missing interface name or sw_if_index");
9096       return -99;
9097     }
9098
9099   if (vlan_id_set == 0)
9100     {
9101       errmsg ("missing vlan_id");
9102       return -99;
9103     }
9104   M (CREATE_VLAN_SUBIF, mp);
9105
9106   mp->sw_if_index = ntohl (sw_if_index);
9107   mp->vlan_id = ntohl (vlan_id);
9108
9109   S (mp);
9110   W (ret);
9111   return ret;
9112 }
9113
9114 #define foreach_create_subif_bit                \
9115 _(no_tags)                                      \
9116 _(one_tag)                                      \
9117 _(two_tags)                                     \
9118 _(dot1ad)                                       \
9119 _(exact_match)                                  \
9120 _(default_sub)                                  \
9121 _(outer_vlan_id_any)                            \
9122 _(inner_vlan_id_any)
9123
9124 #define foreach_create_subif_flag               \
9125 _(0, "no_tags")                                 \
9126 _(1, "one_tag")                                 \
9127 _(2, "two_tags")                                \
9128 _(3, "dot1ad")                                  \
9129 _(4, "exact_match")                             \
9130 _(5, "default_sub")                             \
9131 _(6, "outer_vlan_id_any")                       \
9132 _(7, "inner_vlan_id_any")
9133
9134 static int
9135 api_create_subif (vat_main_t * vam)
9136 {
9137   unformat_input_t *i = vam->input;
9138   vl_api_create_subif_t *mp;
9139   u32 sw_if_index;
9140   u8 sw_if_index_set = 0;
9141   u32 sub_id;
9142   u8 sub_id_set = 0;
9143   u32 __attribute__ ((unused)) no_tags = 0;
9144   u32 __attribute__ ((unused)) one_tag = 0;
9145   u32 __attribute__ ((unused)) two_tags = 0;
9146   u32 __attribute__ ((unused)) dot1ad = 0;
9147   u32 __attribute__ ((unused)) exact_match = 0;
9148   u32 __attribute__ ((unused)) default_sub = 0;
9149   u32 __attribute__ ((unused)) outer_vlan_id_any = 0;
9150   u32 __attribute__ ((unused)) inner_vlan_id_any = 0;
9151   u32 tmp;
9152   u16 outer_vlan_id = 0;
9153   u16 inner_vlan_id = 0;
9154   int ret;
9155
9156   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9157     {
9158       if (unformat (i, "sw_if_index %d", &sw_if_index))
9159         sw_if_index_set = 1;
9160       else
9161         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9162         sw_if_index_set = 1;
9163       else if (unformat (i, "sub_id %d", &sub_id))
9164         sub_id_set = 1;
9165       else if (unformat (i, "outer_vlan_id %d", &tmp))
9166         outer_vlan_id = tmp;
9167       else if (unformat (i, "inner_vlan_id %d", &tmp))
9168         inner_vlan_id = tmp;
9169
9170 #define _(a) else if (unformat (i, #a)) a = 1 ;
9171       foreach_create_subif_bit
9172 #undef _
9173         else
9174         {
9175           clib_warning ("parse error '%U'", format_unformat_error, i);
9176           return -99;
9177         }
9178     }
9179
9180   if (sw_if_index_set == 0)
9181     {
9182       errmsg ("missing interface name or sw_if_index");
9183       return -99;
9184     }
9185
9186   if (sub_id_set == 0)
9187     {
9188       errmsg ("missing sub_id");
9189       return -99;
9190     }
9191   M (CREATE_SUBIF, mp);
9192
9193   mp->sw_if_index = ntohl (sw_if_index);
9194   mp->sub_id = ntohl (sub_id);
9195
9196 #define _(a,b) mp->sub_if_flags |= (1 << a);
9197   foreach_create_subif_flag;
9198 #undef _
9199
9200   mp->outer_vlan_id = ntohs (outer_vlan_id);
9201   mp->inner_vlan_id = ntohs (inner_vlan_id);
9202
9203   S (mp);
9204   W (ret);
9205   return ret;
9206 }
9207
9208 static int
9209 api_reset_fib (vat_main_t * vam)
9210 {
9211   unformat_input_t *i = vam->input;
9212   vl_api_reset_fib_t *mp;
9213   u32 vrf_id = 0;
9214   u8 is_ipv6 = 0;
9215   u8 vrf_id_set = 0;
9216
9217   int ret;
9218   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9219     {
9220       if (unformat (i, "vrf %d", &vrf_id))
9221         vrf_id_set = 1;
9222       else if (unformat (i, "ipv6"))
9223         is_ipv6 = 1;
9224       else
9225         {
9226           clib_warning ("parse error '%U'", format_unformat_error, i);
9227           return -99;
9228         }
9229     }
9230
9231   if (vrf_id_set == 0)
9232     {
9233       errmsg ("missing vrf id");
9234       return -99;
9235     }
9236
9237   M (RESET_FIB, mp);
9238
9239   mp->vrf_id = ntohl (vrf_id);
9240   mp->is_ipv6 = is_ipv6;
9241
9242   S (mp);
9243   W (ret);
9244   return ret;
9245 }
9246
9247 static int
9248 api_set_ip_flow_hash (vat_main_t * vam)
9249 {
9250   unformat_input_t *i = vam->input;
9251   vl_api_set_ip_flow_hash_t *mp;
9252   u32 vrf_id = 0;
9253   u8 is_ipv6 = 0;
9254   u8 vrf_id_set = 0;
9255   u8 src = 0;
9256   u8 dst = 0;
9257   u8 sport = 0;
9258   u8 dport = 0;
9259   u8 proto = 0;
9260   u8 reverse = 0;
9261   int ret;
9262
9263   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9264     {
9265       if (unformat (i, "vrf %d", &vrf_id))
9266         vrf_id_set = 1;
9267       else if (unformat (i, "ipv6"))
9268         is_ipv6 = 1;
9269       else if (unformat (i, "src"))
9270         src = 1;
9271       else if (unformat (i, "dst"))
9272         dst = 1;
9273       else if (unformat (i, "sport"))
9274         sport = 1;
9275       else if (unformat (i, "dport"))
9276         dport = 1;
9277       else if (unformat (i, "proto"))
9278         proto = 1;
9279       else if (unformat (i, "reverse"))
9280         reverse = 1;
9281
9282       else
9283         {
9284           clib_warning ("parse error '%U'", format_unformat_error, i);
9285           return -99;
9286         }
9287     }
9288
9289   if (vrf_id_set == 0)
9290     {
9291       errmsg ("missing vrf id");
9292       return -99;
9293     }
9294
9295   M (SET_IP_FLOW_HASH, mp);
9296   mp->src = src;
9297   mp->dst = dst;
9298   mp->sport = sport;
9299   mp->dport = dport;
9300   mp->proto = proto;
9301   mp->reverse = reverse;
9302   mp->vrf_id = ntohl (vrf_id);
9303   mp->is_ipv6 = is_ipv6;
9304
9305   S (mp);
9306   W (ret);
9307   return ret;
9308 }
9309
9310 static int
9311 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
9312 {
9313   unformat_input_t *i = vam->input;
9314   vl_api_sw_interface_ip6_enable_disable_t *mp;
9315   u32 sw_if_index;
9316   u8 sw_if_index_set = 0;
9317   u8 enable = 0;
9318   int ret;
9319
9320   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9321     {
9322       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9323         sw_if_index_set = 1;
9324       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9325         sw_if_index_set = 1;
9326       else if (unformat (i, "enable"))
9327         enable = 1;
9328       else if (unformat (i, "disable"))
9329         enable = 0;
9330       else
9331         {
9332           clib_warning ("parse error '%U'", format_unformat_error, i);
9333           return -99;
9334         }
9335     }
9336
9337   if (sw_if_index_set == 0)
9338     {
9339       errmsg ("missing interface name or sw_if_index");
9340       return -99;
9341     }
9342
9343   M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
9344
9345   mp->sw_if_index = ntohl (sw_if_index);
9346   mp->enable = enable;
9347
9348   S (mp);
9349   W (ret);
9350   return ret;
9351 }
9352
9353 static int
9354 api_ip6nd_proxy_add_del (vat_main_t * vam)
9355 {
9356   unformat_input_t *i = vam->input;
9357   vl_api_ip6nd_proxy_add_del_t *mp;
9358   u32 sw_if_index = ~0;
9359   u8 v6_address_set = 0;
9360   vl_api_ip6_address_t v6address;
9361   u8 is_del = 0;
9362   int ret;
9363
9364   /* Parse args required to build the message */
9365   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9366     {
9367       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9368         ;
9369       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9370         ;
9371       else if (unformat (i, "%U", unformat_vl_api_ip6_address, &v6address))
9372         v6_address_set = 1;
9373       if (unformat (i, "del"))
9374         is_del = 1;
9375       else
9376         {
9377           clib_warning ("parse error '%U'", format_unformat_error, i);
9378           return -99;
9379         }
9380     }
9381
9382   if (sw_if_index == ~0)
9383     {
9384       errmsg ("missing interface name or sw_if_index");
9385       return -99;
9386     }
9387   if (!v6_address_set)
9388     {
9389       errmsg ("no address set");
9390       return -99;
9391     }
9392
9393   /* Construct the API message */
9394   M (IP6ND_PROXY_ADD_DEL, mp);
9395
9396   mp->is_del = is_del;
9397   mp->sw_if_index = ntohl (sw_if_index);
9398   clib_memcpy (mp->ip, v6address, sizeof (v6address));
9399
9400   /* send it... */
9401   S (mp);
9402
9403   /* Wait for a reply, return good/bad news  */
9404   W (ret);
9405   return ret;
9406 }
9407
9408 static int
9409 api_ip6nd_proxy_dump (vat_main_t * vam)
9410 {
9411   vl_api_ip6nd_proxy_dump_t *mp;
9412   vl_api_control_ping_t *mp_ping;
9413   int ret;
9414
9415   M (IP6ND_PROXY_DUMP, mp);
9416
9417   S (mp);
9418
9419   /* Use a control ping for synchronization */
9420   MPING (CONTROL_PING, mp_ping);
9421   S (mp_ping);
9422
9423   W (ret);
9424   return ret;
9425 }
9426
9427 static void vl_api_ip6nd_proxy_details_t_handler
9428   (vl_api_ip6nd_proxy_details_t * mp)
9429 {
9430   vat_main_t *vam = &vat_main;
9431
9432   print (vam->ofp, "host %U sw_if_index %d",
9433          format_vl_api_ip6_address, mp->ip, ntohl (mp->sw_if_index));
9434 }
9435
9436 static void vl_api_ip6nd_proxy_details_t_handler_json
9437   (vl_api_ip6nd_proxy_details_t * mp)
9438 {
9439   vat_main_t *vam = &vat_main;
9440   struct in6_addr ip6;
9441   vat_json_node_t *node = NULL;
9442
9443   if (VAT_JSON_ARRAY != vam->json_tree.type)
9444     {
9445       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9446       vat_json_init_array (&vam->json_tree);
9447     }
9448   node = vat_json_array_add (&vam->json_tree);
9449
9450   vat_json_init_object (node);
9451   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
9452
9453   clib_memcpy (&ip6, mp->ip, sizeof (ip6));
9454   vat_json_object_add_ip6 (node, "host", ip6);
9455 }
9456
9457 static int
9458 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
9459 {
9460   unformat_input_t *i = vam->input;
9461   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
9462   u32 sw_if_index;
9463   u8 sw_if_index_set = 0;
9464   u8 v6_address_set = 0;
9465   vl_api_prefix_t pfx;
9466   u8 use_default = 0;
9467   u8 no_advertise = 0;
9468   u8 off_link = 0;
9469   u8 no_autoconfig = 0;
9470   u8 no_onlink = 0;
9471   u8 is_no = 0;
9472   u32 val_lifetime = 0;
9473   u32 pref_lifetime = 0;
9474   int ret;
9475
9476   /* Parse args required to build the message */
9477   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9478     {
9479       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9480         sw_if_index_set = 1;
9481       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9482         sw_if_index_set = 1;
9483       else if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
9484         v6_address_set = 1;
9485       else if (unformat (i, "val_life %d", &val_lifetime))
9486         ;
9487       else if (unformat (i, "pref_life %d", &pref_lifetime))
9488         ;
9489       else if (unformat (i, "def"))
9490         use_default = 1;
9491       else if (unformat (i, "noadv"))
9492         no_advertise = 1;
9493       else if (unformat (i, "offl"))
9494         off_link = 1;
9495       else if (unformat (i, "noauto"))
9496         no_autoconfig = 1;
9497       else if (unformat (i, "nolink"))
9498         no_onlink = 1;
9499       else if (unformat (i, "isno"))
9500         is_no = 1;
9501       else
9502         {
9503           clib_warning ("parse error '%U'", format_unformat_error, i);
9504           return -99;
9505         }
9506     }
9507
9508   if (sw_if_index_set == 0)
9509     {
9510       errmsg ("missing interface name or sw_if_index");
9511       return -99;
9512     }
9513   if (!v6_address_set)
9514     {
9515       errmsg ("no address set");
9516       return -99;
9517     }
9518
9519   /* Construct the API message */
9520   M (SW_INTERFACE_IP6ND_RA_PREFIX, mp);
9521
9522   mp->sw_if_index = ntohl (sw_if_index);
9523   clib_memcpy (&mp->prefix, &pfx, sizeof (pfx));
9524   mp->use_default = use_default;
9525   mp->no_advertise = no_advertise;
9526   mp->off_link = off_link;
9527   mp->no_autoconfig = no_autoconfig;
9528   mp->no_onlink = no_onlink;
9529   mp->is_no = is_no;
9530   mp->val_lifetime = ntohl (val_lifetime);
9531   mp->pref_lifetime = ntohl (pref_lifetime);
9532
9533   /* send it... */
9534   S (mp);
9535
9536   /* Wait for a reply, return good/bad news  */
9537   W (ret);
9538   return ret;
9539 }
9540
9541 static int
9542 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
9543 {
9544   unformat_input_t *i = vam->input;
9545   vl_api_sw_interface_ip6nd_ra_config_t *mp;
9546   u32 sw_if_index;
9547   u8 sw_if_index_set = 0;
9548   u8 suppress = 0;
9549   u8 managed = 0;
9550   u8 other = 0;
9551   u8 ll_option = 0;
9552   u8 send_unicast = 0;
9553   u8 cease = 0;
9554   u8 is_no = 0;
9555   u8 default_router = 0;
9556   u32 max_interval = 0;
9557   u32 min_interval = 0;
9558   u32 lifetime = 0;
9559   u32 initial_count = 0;
9560   u32 initial_interval = 0;
9561   int ret;
9562
9563
9564   /* Parse args required to build the message */
9565   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9566     {
9567       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9568         sw_if_index_set = 1;
9569       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9570         sw_if_index_set = 1;
9571       else if (unformat (i, "maxint %d", &max_interval))
9572         ;
9573       else if (unformat (i, "minint %d", &min_interval))
9574         ;
9575       else if (unformat (i, "life %d", &lifetime))
9576         ;
9577       else if (unformat (i, "count %d", &initial_count))
9578         ;
9579       else if (unformat (i, "interval %d", &initial_interval))
9580         ;
9581       else if (unformat (i, "suppress") || unformat (i, "surpress"))
9582         suppress = 1;
9583       else if (unformat (i, "managed"))
9584         managed = 1;
9585       else if (unformat (i, "other"))
9586         other = 1;
9587       else if (unformat (i, "ll"))
9588         ll_option = 1;
9589       else if (unformat (i, "send"))
9590         send_unicast = 1;
9591       else if (unformat (i, "cease"))
9592         cease = 1;
9593       else if (unformat (i, "isno"))
9594         is_no = 1;
9595       else if (unformat (i, "def"))
9596         default_router = 1;
9597       else
9598         {
9599           clib_warning ("parse error '%U'", format_unformat_error, i);
9600           return -99;
9601         }
9602     }
9603
9604   if (sw_if_index_set == 0)
9605     {
9606       errmsg ("missing interface name or sw_if_index");
9607       return -99;
9608     }
9609
9610   /* Construct the API message */
9611   M (SW_INTERFACE_IP6ND_RA_CONFIG, mp);
9612
9613   mp->sw_if_index = ntohl (sw_if_index);
9614   mp->max_interval = ntohl (max_interval);
9615   mp->min_interval = ntohl (min_interval);
9616   mp->lifetime = ntohl (lifetime);
9617   mp->initial_count = ntohl (initial_count);
9618   mp->initial_interval = ntohl (initial_interval);
9619   mp->suppress = suppress;
9620   mp->managed = managed;
9621   mp->other = other;
9622   mp->ll_option = ll_option;
9623   mp->send_unicast = send_unicast;
9624   mp->cease = cease;
9625   mp->is_no = is_no;
9626   mp->default_router = default_router;
9627
9628   /* send it... */
9629   S (mp);
9630
9631   /* Wait for a reply, return good/bad news  */
9632   W (ret);
9633   return ret;
9634 }
9635
9636 static int
9637 api_set_arp_neighbor_limit (vat_main_t * vam)
9638 {
9639   unformat_input_t *i = vam->input;
9640   vl_api_set_arp_neighbor_limit_t *mp;
9641   u32 arp_nbr_limit;
9642   u8 limit_set = 0;
9643   u8 is_ipv6 = 0;
9644   int ret;
9645
9646   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9647     {
9648       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
9649         limit_set = 1;
9650       else if (unformat (i, "ipv6"))
9651         is_ipv6 = 1;
9652       else
9653         {
9654           clib_warning ("parse error '%U'", format_unformat_error, i);
9655           return -99;
9656         }
9657     }
9658
9659   if (limit_set == 0)
9660     {
9661       errmsg ("missing limit value");
9662       return -99;
9663     }
9664
9665   M (SET_ARP_NEIGHBOR_LIMIT, mp);
9666
9667   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
9668   mp->is_ipv6 = is_ipv6;
9669
9670   S (mp);
9671   W (ret);
9672   return ret;
9673 }
9674
9675 static int
9676 api_l2_patch_add_del (vat_main_t * vam)
9677 {
9678   unformat_input_t *i = vam->input;
9679   vl_api_l2_patch_add_del_t *mp;
9680   u32 rx_sw_if_index;
9681   u8 rx_sw_if_index_set = 0;
9682   u32 tx_sw_if_index;
9683   u8 tx_sw_if_index_set = 0;
9684   u8 is_add = 1;
9685   int ret;
9686
9687   /* Parse args required to build the message */
9688   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9689     {
9690       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
9691         rx_sw_if_index_set = 1;
9692       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
9693         tx_sw_if_index_set = 1;
9694       else if (unformat (i, "rx"))
9695         {
9696           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9697             {
9698               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
9699                             &rx_sw_if_index))
9700                 rx_sw_if_index_set = 1;
9701             }
9702           else
9703             break;
9704         }
9705       else if (unformat (i, "tx"))
9706         {
9707           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9708             {
9709               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
9710                             &tx_sw_if_index))
9711                 tx_sw_if_index_set = 1;
9712             }
9713           else
9714             break;
9715         }
9716       else if (unformat (i, "del"))
9717         is_add = 0;
9718       else
9719         break;
9720     }
9721
9722   if (rx_sw_if_index_set == 0)
9723     {
9724       errmsg ("missing rx interface name or rx_sw_if_index");
9725       return -99;
9726     }
9727
9728   if (tx_sw_if_index_set == 0)
9729     {
9730       errmsg ("missing tx interface name or tx_sw_if_index");
9731       return -99;
9732     }
9733
9734   M (L2_PATCH_ADD_DEL, mp);
9735
9736   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
9737   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
9738   mp->is_add = is_add;
9739
9740   S (mp);
9741   W (ret);
9742   return ret;
9743 }
9744
9745 u8 is_del;
9746 u8 localsid_addr[16];
9747 u8 end_psp;
9748 u8 behavior;
9749 u32 sw_if_index;
9750 u32 vlan_index;
9751 u32 fib_table;
9752 u8 nh_addr[16];
9753
9754 static int
9755 api_sr_localsid_add_del (vat_main_t * vam)
9756 {
9757   unformat_input_t *i = vam->input;
9758   vl_api_sr_localsid_add_del_t *mp;
9759
9760   u8 is_del;
9761   ip6_address_t localsid;
9762   u8 end_psp = 0;
9763   u8 behavior = ~0;
9764   u32 sw_if_index;
9765   u32 fib_table = ~(u32) 0;
9766   ip6_address_t nh_addr6;
9767   ip4_address_t nh_addr4;
9768   clib_memset (&nh_addr6, 0, sizeof (ip6_address_t));
9769   clib_memset (&nh_addr4, 0, sizeof (ip4_address_t));
9770
9771   bool nexthop_set = 0;
9772
9773   int ret;
9774
9775   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9776     {
9777       if (unformat (i, "del"))
9778         is_del = 1;
9779       else if (unformat (i, "address %U", unformat_ip6_address, &localsid));
9780       else if (unformat (i, "next-hop %U", unformat_ip4_address, &nh_addr4))
9781         nexthop_set = 1;
9782       else if (unformat (i, "next-hop %U", unformat_ip6_address, &nh_addr6))
9783         nexthop_set = 1;
9784       else if (unformat (i, "behavior %u", &behavior));
9785       else if (unformat (i, "sw_if_index %u", &sw_if_index));
9786       else if (unformat (i, "fib-table %u", &fib_table));
9787       else if (unformat (i, "end.psp %u", &behavior));
9788       else
9789         break;
9790     }
9791
9792   M (SR_LOCALSID_ADD_DEL, mp);
9793
9794   clib_memcpy (mp->localsid.addr, &localsid, sizeof (mp->localsid));
9795   if (nexthop_set)
9796     {
9797       clib_memcpy (mp->nh_addr6, &nh_addr6, sizeof (mp->nh_addr6));
9798       clib_memcpy (mp->nh_addr4, &nh_addr4, sizeof (mp->nh_addr4));
9799     }
9800   mp->behavior = behavior;
9801   mp->sw_if_index = ntohl (sw_if_index);
9802   mp->fib_table = ntohl (fib_table);
9803   mp->end_psp = end_psp;
9804   mp->is_del = is_del;
9805
9806   S (mp);
9807   W (ret);
9808   return ret;
9809 }
9810
9811 static int
9812 api_ioam_enable (vat_main_t * vam)
9813 {
9814   unformat_input_t *input = vam->input;
9815   vl_api_ioam_enable_t *mp;
9816   u32 id = 0;
9817   int has_trace_option = 0;
9818   int has_pot_option = 0;
9819   int has_seqno_option = 0;
9820   int has_analyse_option = 0;
9821   int ret;
9822
9823   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9824     {
9825       if (unformat (input, "trace"))
9826         has_trace_option = 1;
9827       else if (unformat (input, "pot"))
9828         has_pot_option = 1;
9829       else if (unformat (input, "seqno"))
9830         has_seqno_option = 1;
9831       else if (unformat (input, "analyse"))
9832         has_analyse_option = 1;
9833       else
9834         break;
9835     }
9836   M (IOAM_ENABLE, mp);
9837   mp->id = htons (id);
9838   mp->seqno = has_seqno_option;
9839   mp->analyse = has_analyse_option;
9840   mp->pot_enable = has_pot_option;
9841   mp->trace_enable = has_trace_option;
9842
9843   S (mp);
9844   W (ret);
9845   return ret;
9846 }
9847
9848
9849 static int
9850 api_ioam_disable (vat_main_t * vam)
9851 {
9852   vl_api_ioam_disable_t *mp;
9853   int ret;
9854
9855   M (IOAM_DISABLE, mp);
9856   S (mp);
9857   W (ret);
9858   return ret;
9859 }
9860
9861 #define foreach_tcp_proto_field                 \
9862 _(src_port)                                     \
9863 _(dst_port)
9864
9865 #define foreach_udp_proto_field                 \
9866 _(src_port)                                     \
9867 _(dst_port)
9868
9869 #define foreach_ip4_proto_field                 \
9870 _(src_address)                                  \
9871 _(dst_address)                                  \
9872 _(tos)                                          \
9873 _(length)                                       \
9874 _(fragment_id)                                  \
9875 _(ttl)                                          \
9876 _(protocol)                                     \
9877 _(checksum)
9878
9879 typedef struct
9880 {
9881   u16 src_port, dst_port;
9882 } tcpudp_header_t;
9883
9884 #if VPP_API_TEST_BUILTIN == 0
9885 uword
9886 unformat_tcp_mask (unformat_input_t * input, va_list * args)
9887 {
9888   u8 **maskp = va_arg (*args, u8 **);
9889   u8 *mask = 0;
9890   u8 found_something = 0;
9891   tcp_header_t *tcp;
9892
9893 #define _(a) u8 a=0;
9894   foreach_tcp_proto_field;
9895 #undef _
9896
9897   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9898     {
9899       if (0);
9900 #define _(a) else if (unformat (input, #a)) a=1;
9901       foreach_tcp_proto_field
9902 #undef _
9903         else
9904         break;
9905     }
9906
9907 #define _(a) found_something += a;
9908   foreach_tcp_proto_field;
9909 #undef _
9910
9911   if (found_something == 0)
9912     return 0;
9913
9914   vec_validate (mask, sizeof (*tcp) - 1);
9915
9916   tcp = (tcp_header_t *) mask;
9917
9918 #define _(a) if (a) clib_memset (&tcp->a, 0xff, sizeof (tcp->a));
9919   foreach_tcp_proto_field;
9920 #undef _
9921
9922   *maskp = mask;
9923   return 1;
9924 }
9925
9926 uword
9927 unformat_udp_mask (unformat_input_t * input, va_list * args)
9928 {
9929   u8 **maskp = va_arg (*args, u8 **);
9930   u8 *mask = 0;
9931   u8 found_something = 0;
9932   udp_header_t *udp;
9933
9934 #define _(a) u8 a=0;
9935   foreach_udp_proto_field;
9936 #undef _
9937
9938   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9939     {
9940       if (0);
9941 #define _(a) else if (unformat (input, #a)) a=1;
9942       foreach_udp_proto_field
9943 #undef _
9944         else
9945         break;
9946     }
9947
9948 #define _(a) found_something += a;
9949   foreach_udp_proto_field;
9950 #undef _
9951
9952   if (found_something == 0)
9953     return 0;
9954
9955   vec_validate (mask, sizeof (*udp) - 1);
9956
9957   udp = (udp_header_t *) mask;
9958
9959 #define _(a) if (a) clib_memset (&udp->a, 0xff, sizeof (udp->a));
9960   foreach_udp_proto_field;
9961 #undef _
9962
9963   *maskp = mask;
9964   return 1;
9965 }
9966
9967 uword
9968 unformat_l4_mask (unformat_input_t * input, va_list * args)
9969 {
9970   u8 **maskp = va_arg (*args, u8 **);
9971   u16 src_port = 0, dst_port = 0;
9972   tcpudp_header_t *tcpudp;
9973
9974   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9975     {
9976       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
9977         return 1;
9978       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
9979         return 1;
9980       else if (unformat (input, "src_port"))
9981         src_port = 0xFFFF;
9982       else if (unformat (input, "dst_port"))
9983         dst_port = 0xFFFF;
9984       else
9985         return 0;
9986     }
9987
9988   if (!src_port && !dst_port)
9989     return 0;
9990
9991   u8 *mask = 0;
9992   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
9993
9994   tcpudp = (tcpudp_header_t *) mask;
9995   tcpudp->src_port = src_port;
9996   tcpudp->dst_port = dst_port;
9997
9998   *maskp = mask;
9999
10000   return 1;
10001 }
10002
10003 uword
10004 unformat_ip4_mask (unformat_input_t * input, va_list * args)
10005 {
10006   u8 **maskp = va_arg (*args, u8 **);
10007   u8 *mask = 0;
10008   u8 found_something = 0;
10009   ip4_header_t *ip;
10010
10011 #define _(a) u8 a=0;
10012   foreach_ip4_proto_field;
10013 #undef _
10014   u8 version = 0;
10015   u8 hdr_length = 0;
10016
10017
10018   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10019     {
10020       if (unformat (input, "version"))
10021         version = 1;
10022       else if (unformat (input, "hdr_length"))
10023         hdr_length = 1;
10024       else if (unformat (input, "src"))
10025         src_address = 1;
10026       else if (unformat (input, "dst"))
10027         dst_address = 1;
10028       else if (unformat (input, "proto"))
10029         protocol = 1;
10030
10031 #define _(a) else if (unformat (input, #a)) a=1;
10032       foreach_ip4_proto_field
10033 #undef _
10034         else
10035         break;
10036     }
10037
10038 #define _(a) found_something += a;
10039   foreach_ip4_proto_field;
10040 #undef _
10041
10042   if (found_something == 0)
10043     return 0;
10044
10045   vec_validate (mask, sizeof (*ip) - 1);
10046
10047   ip = (ip4_header_t *) mask;
10048
10049 #define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
10050   foreach_ip4_proto_field;
10051 #undef _
10052
10053   ip->ip_version_and_header_length = 0;
10054
10055   if (version)
10056     ip->ip_version_and_header_length |= 0xF0;
10057
10058   if (hdr_length)
10059     ip->ip_version_and_header_length |= 0x0F;
10060
10061   *maskp = mask;
10062   return 1;
10063 }
10064
10065 #define foreach_ip6_proto_field                 \
10066 _(src_address)                                  \
10067 _(dst_address)                                  \
10068 _(payload_length)                               \
10069 _(hop_limit)                                    \
10070 _(protocol)
10071
10072 uword
10073 unformat_ip6_mask (unformat_input_t * input, va_list * args)
10074 {
10075   u8 **maskp = va_arg (*args, u8 **);
10076   u8 *mask = 0;
10077   u8 found_something = 0;
10078   ip6_header_t *ip;
10079   u32 ip_version_traffic_class_and_flow_label;
10080
10081 #define _(a) u8 a=0;
10082   foreach_ip6_proto_field;
10083 #undef _
10084   u8 version = 0;
10085   u8 traffic_class = 0;
10086   u8 flow_label = 0;
10087
10088   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10089     {
10090       if (unformat (input, "version"))
10091         version = 1;
10092       else if (unformat (input, "traffic-class"))
10093         traffic_class = 1;
10094       else if (unformat (input, "flow-label"))
10095         flow_label = 1;
10096       else if (unformat (input, "src"))
10097         src_address = 1;
10098       else if (unformat (input, "dst"))
10099         dst_address = 1;
10100       else if (unformat (input, "proto"))
10101         protocol = 1;
10102
10103 #define _(a) else if (unformat (input, #a)) a=1;
10104       foreach_ip6_proto_field
10105 #undef _
10106         else
10107         break;
10108     }
10109
10110 #define _(a) found_something += a;
10111   foreach_ip6_proto_field;
10112 #undef _
10113
10114   if (found_something == 0)
10115     return 0;
10116
10117   vec_validate (mask, sizeof (*ip) - 1);
10118
10119   ip = (ip6_header_t *) mask;
10120
10121 #define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
10122   foreach_ip6_proto_field;
10123 #undef _
10124
10125   ip_version_traffic_class_and_flow_label = 0;
10126
10127   if (version)
10128     ip_version_traffic_class_and_flow_label |= 0xF0000000;
10129
10130   if (traffic_class)
10131     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
10132
10133   if (flow_label)
10134     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
10135
10136   ip->ip_version_traffic_class_and_flow_label =
10137     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
10138
10139   *maskp = mask;
10140   return 1;
10141 }
10142
10143 uword
10144 unformat_l3_mask (unformat_input_t * input, va_list * args)
10145 {
10146   u8 **maskp = va_arg (*args, u8 **);
10147
10148   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10149     {
10150       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
10151         return 1;
10152       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
10153         return 1;
10154       else
10155         break;
10156     }
10157   return 0;
10158 }
10159
10160 uword
10161 unformat_l2_mask (unformat_input_t * input, va_list * args)
10162 {
10163   u8 **maskp = va_arg (*args, u8 **);
10164   u8 *mask = 0;
10165   u8 src = 0;
10166   u8 dst = 0;
10167   u8 proto = 0;
10168   u8 tag1 = 0;
10169   u8 tag2 = 0;
10170   u8 ignore_tag1 = 0;
10171   u8 ignore_tag2 = 0;
10172   u8 cos1 = 0;
10173   u8 cos2 = 0;
10174   u8 dot1q = 0;
10175   u8 dot1ad = 0;
10176   int len = 14;
10177
10178   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10179     {
10180       if (unformat (input, "src"))
10181         src = 1;
10182       else if (unformat (input, "dst"))
10183         dst = 1;
10184       else if (unformat (input, "proto"))
10185         proto = 1;
10186       else if (unformat (input, "tag1"))
10187         tag1 = 1;
10188       else if (unformat (input, "tag2"))
10189         tag2 = 1;
10190       else if (unformat (input, "ignore-tag1"))
10191         ignore_tag1 = 1;
10192       else if (unformat (input, "ignore-tag2"))
10193         ignore_tag2 = 1;
10194       else if (unformat (input, "cos1"))
10195         cos1 = 1;
10196       else if (unformat (input, "cos2"))
10197         cos2 = 1;
10198       else if (unformat (input, "dot1q"))
10199         dot1q = 1;
10200       else if (unformat (input, "dot1ad"))
10201         dot1ad = 1;
10202       else
10203         break;
10204     }
10205   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
10206        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
10207     return 0;
10208
10209   if (tag1 || ignore_tag1 || cos1 || dot1q)
10210     len = 18;
10211   if (tag2 || ignore_tag2 || cos2 || dot1ad)
10212     len = 22;
10213
10214   vec_validate (mask, len - 1);
10215
10216   if (dst)
10217     clib_memset (mask, 0xff, 6);
10218
10219   if (src)
10220     clib_memset (mask + 6, 0xff, 6);
10221
10222   if (tag2 || dot1ad)
10223     {
10224       /* inner vlan tag */
10225       if (tag2)
10226         {
10227           mask[19] = 0xff;
10228           mask[18] = 0x0f;
10229         }
10230       if (cos2)
10231         mask[18] |= 0xe0;
10232       if (proto)
10233         mask[21] = mask[20] = 0xff;
10234       if (tag1)
10235         {
10236           mask[15] = 0xff;
10237           mask[14] = 0x0f;
10238         }
10239       if (cos1)
10240         mask[14] |= 0xe0;
10241       *maskp = mask;
10242       return 1;
10243     }
10244   if (tag1 | dot1q)
10245     {
10246       if (tag1)
10247         {
10248           mask[15] = 0xff;
10249           mask[14] = 0x0f;
10250         }
10251       if (cos1)
10252         mask[14] |= 0xe0;
10253       if (proto)
10254         mask[16] = mask[17] = 0xff;
10255
10256       *maskp = mask;
10257       return 1;
10258     }
10259   if (cos2)
10260     mask[18] |= 0xe0;
10261   if (cos1)
10262     mask[14] |= 0xe0;
10263   if (proto)
10264     mask[12] = mask[13] = 0xff;
10265
10266   *maskp = mask;
10267   return 1;
10268 }
10269
10270 uword
10271 unformat_classify_mask (unformat_input_t * input, va_list * args)
10272 {
10273   u8 **maskp = va_arg (*args, u8 **);
10274   u32 *skipp = va_arg (*args, u32 *);
10275   u32 *matchp = va_arg (*args, u32 *);
10276   u32 match;
10277   u8 *mask = 0;
10278   u8 *l2 = 0;
10279   u8 *l3 = 0;
10280   u8 *l4 = 0;
10281   int i;
10282
10283   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10284     {
10285       if (unformat (input, "hex %U", unformat_hex_string, &mask))
10286         ;
10287       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
10288         ;
10289       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
10290         ;
10291       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
10292         ;
10293       else
10294         break;
10295     }
10296
10297   if (l4 && !l3)
10298     {
10299       vec_free (mask);
10300       vec_free (l2);
10301       vec_free (l4);
10302       return 0;
10303     }
10304
10305   if (mask || l2 || l3 || l4)
10306     {
10307       if (l2 || l3 || l4)
10308         {
10309           /* "With a free Ethernet header in every package" */
10310           if (l2 == 0)
10311             vec_validate (l2, 13);
10312           mask = l2;
10313           if (vec_len (l3))
10314             {
10315               vec_append (mask, l3);
10316               vec_free (l3);
10317             }
10318           if (vec_len (l4))
10319             {
10320               vec_append (mask, l4);
10321               vec_free (l4);
10322             }
10323         }
10324
10325       /* Scan forward looking for the first significant mask octet */
10326       for (i = 0; i < vec_len (mask); i++)
10327         if (mask[i])
10328           break;
10329
10330       /* compute (skip, match) params */
10331       *skipp = i / sizeof (u32x4);
10332       vec_delete (mask, *skipp * sizeof (u32x4), 0);
10333
10334       /* Pad mask to an even multiple of the vector size */
10335       while (vec_len (mask) % sizeof (u32x4))
10336         vec_add1 (mask, 0);
10337
10338       match = vec_len (mask) / sizeof (u32x4);
10339
10340       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
10341         {
10342           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
10343           if (*tmp || *(tmp + 1))
10344             break;
10345           match--;
10346         }
10347       if (match == 0)
10348         clib_warning ("BUG: match 0");
10349
10350       _vec_len (mask) = match * sizeof (u32x4);
10351
10352       *matchp = match;
10353       *maskp = mask;
10354
10355       return 1;
10356     }
10357
10358   return 0;
10359 }
10360 #endif /* VPP_API_TEST_BUILTIN */
10361
10362 #define foreach_l2_next                         \
10363 _(drop, DROP)                                   \
10364 _(ethernet, ETHERNET_INPUT)                     \
10365 _(ip4, IP4_INPUT)                               \
10366 _(ip6, IP6_INPUT)
10367
10368 uword
10369 unformat_l2_next_index (unformat_input_t * input, va_list * args)
10370 {
10371   u32 *miss_next_indexp = va_arg (*args, u32 *);
10372   u32 next_index = 0;
10373   u32 tmp;
10374
10375 #define _(n,N) \
10376   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
10377   foreach_l2_next;
10378 #undef _
10379
10380   if (unformat (input, "%d", &tmp))
10381     {
10382       next_index = tmp;
10383       goto out;
10384     }
10385
10386   return 0;
10387
10388 out:
10389   *miss_next_indexp = next_index;
10390   return 1;
10391 }
10392
10393 #define foreach_ip_next                         \
10394 _(drop, DROP)                                   \
10395 _(local, LOCAL)                                 \
10396 _(rewrite, REWRITE)
10397
10398 uword
10399 api_unformat_ip_next_index (unformat_input_t * input, va_list * args)
10400 {
10401   u32 *miss_next_indexp = va_arg (*args, u32 *);
10402   u32 next_index = 0;
10403   u32 tmp;
10404
10405 #define _(n,N) \
10406   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
10407   foreach_ip_next;
10408 #undef _
10409
10410   if (unformat (input, "%d", &tmp))
10411     {
10412       next_index = tmp;
10413       goto out;
10414     }
10415
10416   return 0;
10417
10418 out:
10419   *miss_next_indexp = next_index;
10420   return 1;
10421 }
10422
10423 #define foreach_acl_next                        \
10424 _(deny, DENY)
10425
10426 uword
10427 api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
10428 {
10429   u32 *miss_next_indexp = va_arg (*args, u32 *);
10430   u32 next_index = 0;
10431   u32 tmp;
10432
10433 #define _(n,N) \
10434   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
10435   foreach_acl_next;
10436 #undef _
10437
10438   if (unformat (input, "permit"))
10439     {
10440       next_index = ~0;
10441       goto out;
10442     }
10443   else if (unformat (input, "%d", &tmp))
10444     {
10445       next_index = tmp;
10446       goto out;
10447     }
10448
10449   return 0;
10450
10451 out:
10452   *miss_next_indexp = next_index;
10453   return 1;
10454 }
10455
10456 uword
10457 unformat_policer_precolor (unformat_input_t * input, va_list * args)
10458 {
10459   u32 *r = va_arg (*args, u32 *);
10460
10461   if (unformat (input, "conform-color"))
10462     *r = POLICE_CONFORM;
10463   else if (unformat (input, "exceed-color"))
10464     *r = POLICE_EXCEED;
10465   else
10466     return 0;
10467
10468   return 1;
10469 }
10470
10471 static int
10472 api_classify_add_del_table (vat_main_t * vam)
10473 {
10474   unformat_input_t *i = vam->input;
10475   vl_api_classify_add_del_table_t *mp;
10476
10477   u32 nbuckets = 2;
10478   u32 skip = ~0;
10479   u32 match = ~0;
10480   int is_add = 1;
10481   int del_chain = 0;
10482   u32 table_index = ~0;
10483   u32 next_table_index = ~0;
10484   u32 miss_next_index = ~0;
10485   u32 memory_size = 32 << 20;
10486   u8 *mask = 0;
10487   u32 current_data_flag = 0;
10488   int current_data_offset = 0;
10489   int ret;
10490
10491   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10492     {
10493       if (unformat (i, "del"))
10494         is_add = 0;
10495       else if (unformat (i, "del-chain"))
10496         {
10497           is_add = 0;
10498           del_chain = 1;
10499         }
10500       else if (unformat (i, "buckets %d", &nbuckets))
10501         ;
10502       else if (unformat (i, "memory_size %d", &memory_size))
10503         ;
10504       else if (unformat (i, "skip %d", &skip))
10505         ;
10506       else if (unformat (i, "match %d", &match))
10507         ;
10508       else if (unformat (i, "table %d", &table_index))
10509         ;
10510       else if (unformat (i, "mask %U", unformat_classify_mask,
10511                          &mask, &skip, &match))
10512         ;
10513       else if (unformat (i, "next-table %d", &next_table_index))
10514         ;
10515       else if (unformat (i, "miss-next %U", api_unformat_ip_next_index,
10516                          &miss_next_index))
10517         ;
10518       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
10519                          &miss_next_index))
10520         ;
10521       else if (unformat (i, "acl-miss-next %U", api_unformat_acl_next_index,
10522                          &miss_next_index))
10523         ;
10524       else if (unformat (i, "current-data-flag %d", &current_data_flag))
10525         ;
10526       else if (unformat (i, "current-data-offset %d", &current_data_offset))
10527         ;
10528       else
10529         break;
10530     }
10531
10532   if (is_add && mask == 0)
10533     {
10534       errmsg ("Mask required");
10535       return -99;
10536     }
10537
10538   if (is_add && skip == ~0)
10539     {
10540       errmsg ("skip count required");
10541       return -99;
10542     }
10543
10544   if (is_add && match == ~0)
10545     {
10546       errmsg ("match count required");
10547       return -99;
10548     }
10549
10550   if (!is_add && table_index == ~0)
10551     {
10552       errmsg ("table index required for delete");
10553       return -99;
10554     }
10555
10556   M2 (CLASSIFY_ADD_DEL_TABLE, mp, vec_len (mask));
10557
10558   mp->is_add = is_add;
10559   mp->del_chain = del_chain;
10560   mp->table_index = ntohl (table_index);
10561   mp->nbuckets = ntohl (nbuckets);
10562   mp->memory_size = ntohl (memory_size);
10563   mp->skip_n_vectors = ntohl (skip);
10564   mp->match_n_vectors = ntohl (match);
10565   mp->next_table_index = ntohl (next_table_index);
10566   mp->miss_next_index = ntohl (miss_next_index);
10567   mp->current_data_flag = ntohl (current_data_flag);
10568   mp->current_data_offset = ntohl (current_data_offset);
10569   mp->mask_len = ntohl (vec_len (mask));
10570   clib_memcpy (mp->mask, mask, vec_len (mask));
10571
10572   vec_free (mask);
10573
10574   S (mp);
10575   W (ret);
10576   return ret;
10577 }
10578
10579 #if VPP_API_TEST_BUILTIN == 0
10580 uword
10581 unformat_l4_match (unformat_input_t * input, va_list * args)
10582 {
10583   u8 **matchp = va_arg (*args, u8 **);
10584
10585   u8 *proto_header = 0;
10586   int src_port = 0;
10587   int dst_port = 0;
10588
10589   tcpudp_header_t h;
10590
10591   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10592     {
10593       if (unformat (input, "src_port %d", &src_port))
10594         ;
10595       else if (unformat (input, "dst_port %d", &dst_port))
10596         ;
10597       else
10598         return 0;
10599     }
10600
10601   h.src_port = clib_host_to_net_u16 (src_port);
10602   h.dst_port = clib_host_to_net_u16 (dst_port);
10603   vec_validate (proto_header, sizeof (h) - 1);
10604   memcpy (proto_header, &h, sizeof (h));
10605
10606   *matchp = proto_header;
10607
10608   return 1;
10609 }
10610
10611 uword
10612 unformat_ip4_match (unformat_input_t * input, va_list * args)
10613 {
10614   u8 **matchp = va_arg (*args, u8 **);
10615   u8 *match = 0;
10616   ip4_header_t *ip;
10617   int version = 0;
10618   u32 version_val;
10619   int hdr_length = 0;
10620   u32 hdr_length_val;
10621   int src = 0, dst = 0;
10622   ip4_address_t src_val, dst_val;
10623   int proto = 0;
10624   u32 proto_val;
10625   int tos = 0;
10626   u32 tos_val;
10627   int length = 0;
10628   u32 length_val;
10629   int fragment_id = 0;
10630   u32 fragment_id_val;
10631   int ttl = 0;
10632   int ttl_val;
10633   int checksum = 0;
10634   u32 checksum_val;
10635
10636   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10637     {
10638       if (unformat (input, "version %d", &version_val))
10639         version = 1;
10640       else if (unformat (input, "hdr_length %d", &hdr_length_val))
10641         hdr_length = 1;
10642       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
10643         src = 1;
10644       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
10645         dst = 1;
10646       else if (unformat (input, "proto %d", &proto_val))
10647         proto = 1;
10648       else if (unformat (input, "tos %d", &tos_val))
10649         tos = 1;
10650       else if (unformat (input, "length %d", &length_val))
10651         length = 1;
10652       else if (unformat (input, "fragment_id %d", &fragment_id_val))
10653         fragment_id = 1;
10654       else if (unformat (input, "ttl %d", &ttl_val))
10655         ttl = 1;
10656       else if (unformat (input, "checksum %d", &checksum_val))
10657         checksum = 1;
10658       else
10659         break;
10660     }
10661
10662   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
10663       + ttl + checksum == 0)
10664     return 0;
10665
10666   /*
10667    * Aligned because we use the real comparison functions
10668    */
10669   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
10670
10671   ip = (ip4_header_t *) match;
10672
10673   /* These are realistically matched in practice */
10674   if (src)
10675     ip->src_address.as_u32 = src_val.as_u32;
10676
10677   if (dst)
10678     ip->dst_address.as_u32 = dst_val.as_u32;
10679
10680   if (proto)
10681     ip->protocol = proto_val;
10682
10683
10684   /* These are not, but they're included for completeness */
10685   if (version)
10686     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
10687
10688   if (hdr_length)
10689     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
10690
10691   if (tos)
10692     ip->tos = tos_val;
10693
10694   if (length)
10695     ip->length = clib_host_to_net_u16 (length_val);
10696
10697   if (ttl)
10698     ip->ttl = ttl_val;
10699
10700   if (checksum)
10701     ip->checksum = clib_host_to_net_u16 (checksum_val);
10702
10703   *matchp = match;
10704   return 1;
10705 }
10706
10707 uword
10708 unformat_ip6_match (unformat_input_t * input, va_list * args)
10709 {
10710   u8 **matchp = va_arg (*args, u8 **);
10711   u8 *match = 0;
10712   ip6_header_t *ip;
10713   int version = 0;
10714   u32 version_val;
10715   u8 traffic_class = 0;
10716   u32 traffic_class_val = 0;
10717   u8 flow_label = 0;
10718   u8 flow_label_val;
10719   int src = 0, dst = 0;
10720   ip6_address_t src_val, dst_val;
10721   int proto = 0;
10722   u32 proto_val;
10723   int payload_length = 0;
10724   u32 payload_length_val;
10725   int hop_limit = 0;
10726   int hop_limit_val;
10727   u32 ip_version_traffic_class_and_flow_label;
10728
10729   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10730     {
10731       if (unformat (input, "version %d", &version_val))
10732         version = 1;
10733       else if (unformat (input, "traffic_class %d", &traffic_class_val))
10734         traffic_class = 1;
10735       else if (unformat (input, "flow_label %d", &flow_label_val))
10736         flow_label = 1;
10737       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
10738         src = 1;
10739       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
10740         dst = 1;
10741       else if (unformat (input, "proto %d", &proto_val))
10742         proto = 1;
10743       else if (unformat (input, "payload_length %d", &payload_length_val))
10744         payload_length = 1;
10745       else if (unformat (input, "hop_limit %d", &hop_limit_val))
10746         hop_limit = 1;
10747       else
10748         break;
10749     }
10750
10751   if (version + traffic_class + flow_label + src + dst + proto +
10752       payload_length + hop_limit == 0)
10753     return 0;
10754
10755   /*
10756    * Aligned because we use the real comparison functions
10757    */
10758   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
10759
10760   ip = (ip6_header_t *) match;
10761
10762   if (src)
10763     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
10764
10765   if (dst)
10766     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
10767
10768   if (proto)
10769     ip->protocol = proto_val;
10770
10771   ip_version_traffic_class_and_flow_label = 0;
10772
10773   if (version)
10774     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
10775
10776   if (traffic_class)
10777     ip_version_traffic_class_and_flow_label |=
10778       (traffic_class_val & 0xFF) << 20;
10779
10780   if (flow_label)
10781     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
10782
10783   ip->ip_version_traffic_class_and_flow_label =
10784     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
10785
10786   if (payload_length)
10787     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
10788
10789   if (hop_limit)
10790     ip->hop_limit = hop_limit_val;
10791
10792   *matchp = match;
10793   return 1;
10794 }
10795
10796 uword
10797 unformat_l3_match (unformat_input_t * input, va_list * args)
10798 {
10799   u8 **matchp = va_arg (*args, u8 **);
10800
10801   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10802     {
10803       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
10804         return 1;
10805       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
10806         return 1;
10807       else
10808         break;
10809     }
10810   return 0;
10811 }
10812
10813 uword
10814 unformat_vlan_tag (unformat_input_t * input, va_list * args)
10815 {
10816   u8 *tagp = va_arg (*args, u8 *);
10817   u32 tag;
10818
10819   if (unformat (input, "%d", &tag))
10820     {
10821       tagp[0] = (tag >> 8) & 0x0F;
10822       tagp[1] = tag & 0xFF;
10823       return 1;
10824     }
10825
10826   return 0;
10827 }
10828
10829 uword
10830 unformat_l2_match (unformat_input_t * input, va_list * args)
10831 {
10832   u8 **matchp = va_arg (*args, u8 **);
10833   u8 *match = 0;
10834   u8 src = 0;
10835   u8 src_val[6];
10836   u8 dst = 0;
10837   u8 dst_val[6];
10838   u8 proto = 0;
10839   u16 proto_val;
10840   u8 tag1 = 0;
10841   u8 tag1_val[2];
10842   u8 tag2 = 0;
10843   u8 tag2_val[2];
10844   int len = 14;
10845   u8 ignore_tag1 = 0;
10846   u8 ignore_tag2 = 0;
10847   u8 cos1 = 0;
10848   u8 cos2 = 0;
10849   u32 cos1_val = 0;
10850   u32 cos2_val = 0;
10851
10852   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10853     {
10854       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
10855         src = 1;
10856       else
10857         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
10858         dst = 1;
10859       else if (unformat (input, "proto %U",
10860                          unformat_ethernet_type_host_byte_order, &proto_val))
10861         proto = 1;
10862       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
10863         tag1 = 1;
10864       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
10865         tag2 = 1;
10866       else if (unformat (input, "ignore-tag1"))
10867         ignore_tag1 = 1;
10868       else if (unformat (input, "ignore-tag2"))
10869         ignore_tag2 = 1;
10870       else if (unformat (input, "cos1 %d", &cos1_val))
10871         cos1 = 1;
10872       else if (unformat (input, "cos2 %d", &cos2_val))
10873         cos2 = 1;
10874       else
10875         break;
10876     }
10877   if ((src + dst + proto + tag1 + tag2 +
10878        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
10879     return 0;
10880
10881   if (tag1 || ignore_tag1 || cos1)
10882     len = 18;
10883   if (tag2 || ignore_tag2 || cos2)
10884     len = 22;
10885
10886   vec_validate_aligned (match, len - 1, sizeof (u32x4));
10887
10888   if (dst)
10889     clib_memcpy (match, dst_val, 6);
10890
10891   if (src)
10892     clib_memcpy (match + 6, src_val, 6);
10893
10894   if (tag2)
10895     {
10896       /* inner vlan tag */
10897       match[19] = tag2_val[1];
10898       match[18] = tag2_val[0];
10899       if (cos2)
10900         match[18] |= (cos2_val & 0x7) << 5;
10901       if (proto)
10902         {
10903           match[21] = proto_val & 0xff;
10904           match[20] = proto_val >> 8;
10905         }
10906       if (tag1)
10907         {
10908           match[15] = tag1_val[1];
10909           match[14] = tag1_val[0];
10910         }
10911       if (cos1)
10912         match[14] |= (cos1_val & 0x7) << 5;
10913       *matchp = match;
10914       return 1;
10915     }
10916   if (tag1)
10917     {
10918       match[15] = tag1_val[1];
10919       match[14] = tag1_val[0];
10920       if (proto)
10921         {
10922           match[17] = proto_val & 0xff;
10923           match[16] = proto_val >> 8;
10924         }
10925       if (cos1)
10926         match[14] |= (cos1_val & 0x7) << 5;
10927
10928       *matchp = match;
10929       return 1;
10930     }
10931   if (cos2)
10932     match[18] |= (cos2_val & 0x7) << 5;
10933   if (cos1)
10934     match[14] |= (cos1_val & 0x7) << 5;
10935   if (proto)
10936     {
10937       match[13] = proto_val & 0xff;
10938       match[12] = proto_val >> 8;
10939     }
10940
10941   *matchp = match;
10942   return 1;
10943 }
10944
10945 uword
10946 unformat_qos_source (unformat_input_t * input, va_list * args)
10947 {
10948   int *qs = va_arg (*args, int *);
10949
10950   if (unformat (input, "ip"))
10951     *qs = QOS_SOURCE_IP;
10952   else if (unformat (input, "mpls"))
10953     *qs = QOS_SOURCE_MPLS;
10954   else if (unformat (input, "ext"))
10955     *qs = QOS_SOURCE_EXT;
10956   else if (unformat (input, "vlan"))
10957     *qs = QOS_SOURCE_VLAN;
10958   else
10959     return 0;
10960
10961   return 1;
10962 }
10963 #endif
10964
10965 uword
10966 api_unformat_classify_match (unformat_input_t * input, va_list * args)
10967 {
10968   u8 **matchp = va_arg (*args, u8 **);
10969   u32 skip_n_vectors = va_arg (*args, u32);
10970   u32 match_n_vectors = va_arg (*args, u32);
10971
10972   u8 *match = 0;
10973   u8 *l2 = 0;
10974   u8 *l3 = 0;
10975   u8 *l4 = 0;
10976
10977   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10978     {
10979       if (unformat (input, "hex %U", unformat_hex_string, &match))
10980         ;
10981       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
10982         ;
10983       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
10984         ;
10985       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
10986         ;
10987       else
10988         break;
10989     }
10990
10991   if (l4 && !l3)
10992     {
10993       vec_free (match);
10994       vec_free (l2);
10995       vec_free (l4);
10996       return 0;
10997     }
10998
10999   if (match || l2 || l3 || l4)
11000     {
11001       if (l2 || l3 || l4)
11002         {
11003           /* "Win a free Ethernet header in every packet" */
11004           if (l2 == 0)
11005             vec_validate_aligned (l2, 13, sizeof (u32x4));
11006           match = l2;
11007           if (vec_len (l3))
11008             {
11009               vec_append_aligned (match, l3, sizeof (u32x4));
11010               vec_free (l3);
11011             }
11012           if (vec_len (l4))
11013             {
11014               vec_append_aligned (match, l4, sizeof (u32x4));
11015               vec_free (l4);
11016             }
11017         }
11018
11019       /* Make sure the vector is big enough even if key is all 0's */
11020       vec_validate_aligned
11021         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
11022          sizeof (u32x4));
11023
11024       /* Set size, include skipped vectors */
11025       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
11026
11027       *matchp = match;
11028
11029       return 1;
11030     }
11031
11032   return 0;
11033 }
11034
11035 static int
11036 api_classify_add_del_session (vat_main_t * vam)
11037 {
11038   unformat_input_t *i = vam->input;
11039   vl_api_classify_add_del_session_t *mp;
11040   int is_add = 1;
11041   u32 table_index = ~0;
11042   u32 hit_next_index = ~0;
11043   u32 opaque_index = ~0;
11044   u8 *match = 0;
11045   i32 advance = 0;
11046   u32 skip_n_vectors = 0;
11047   u32 match_n_vectors = 0;
11048   u32 action = 0;
11049   u32 metadata = 0;
11050   int ret;
11051
11052   /*
11053    * Warning: you have to supply skip_n and match_n
11054    * because the API client cant simply look at the classify
11055    * table object.
11056    */
11057
11058   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11059     {
11060       if (unformat (i, "del"))
11061         is_add = 0;
11062       else if (unformat (i, "hit-next %U", api_unformat_ip_next_index,
11063                          &hit_next_index))
11064         ;
11065       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
11066                          &hit_next_index))
11067         ;
11068       else if (unformat (i, "acl-hit-next %U", api_unformat_acl_next_index,
11069                          &hit_next_index))
11070         ;
11071       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
11072         ;
11073       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
11074         ;
11075       else if (unformat (i, "opaque-index %d", &opaque_index))
11076         ;
11077       else if (unformat (i, "skip_n %d", &skip_n_vectors))
11078         ;
11079       else if (unformat (i, "match_n %d", &match_n_vectors))
11080         ;
11081       else if (unformat (i, "match %U", api_unformat_classify_match,
11082                          &match, skip_n_vectors, match_n_vectors))
11083         ;
11084       else if (unformat (i, "advance %d", &advance))
11085         ;
11086       else if (unformat (i, "table-index %d", &table_index))
11087         ;
11088       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
11089         action = 1;
11090       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
11091         action = 2;
11092       else if (unformat (i, "action %d", &action))
11093         ;
11094       else if (unformat (i, "metadata %d", &metadata))
11095         ;
11096       else
11097         break;
11098     }
11099
11100   if (table_index == ~0)
11101     {
11102       errmsg ("Table index required");
11103       return -99;
11104     }
11105
11106   if (is_add && match == 0)
11107     {
11108       errmsg ("Match value required");
11109       return -99;
11110     }
11111
11112   M2 (CLASSIFY_ADD_DEL_SESSION, mp, vec_len (match));
11113
11114   mp->is_add = is_add;
11115   mp->table_index = ntohl (table_index);
11116   mp->hit_next_index = ntohl (hit_next_index);
11117   mp->opaque_index = ntohl (opaque_index);
11118   mp->advance = ntohl (advance);
11119   mp->action = action;
11120   mp->metadata = ntohl (metadata);
11121   mp->match_len = ntohl (vec_len (match));
11122   clib_memcpy (mp->match, match, vec_len (match));
11123   vec_free (match);
11124
11125   S (mp);
11126   W (ret);
11127   return ret;
11128 }
11129
11130 static int
11131 api_classify_set_interface_ip_table (vat_main_t * vam)
11132 {
11133   unformat_input_t *i = vam->input;
11134   vl_api_classify_set_interface_ip_table_t *mp;
11135   u32 sw_if_index;
11136   int sw_if_index_set;
11137   u32 table_index = ~0;
11138   u8 is_ipv6 = 0;
11139   int ret;
11140
11141   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11142     {
11143       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11144         sw_if_index_set = 1;
11145       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11146         sw_if_index_set = 1;
11147       else if (unformat (i, "table %d", &table_index))
11148         ;
11149       else
11150         {
11151           clib_warning ("parse error '%U'", format_unformat_error, i);
11152           return -99;
11153         }
11154     }
11155
11156   if (sw_if_index_set == 0)
11157     {
11158       errmsg ("missing interface name or sw_if_index");
11159       return -99;
11160     }
11161
11162
11163   M (CLASSIFY_SET_INTERFACE_IP_TABLE, mp);
11164
11165   mp->sw_if_index = ntohl (sw_if_index);
11166   mp->table_index = ntohl (table_index);
11167   mp->is_ipv6 = is_ipv6;
11168
11169   S (mp);
11170   W (ret);
11171   return ret;
11172 }
11173
11174 static int
11175 api_classify_set_interface_l2_tables (vat_main_t * vam)
11176 {
11177   unformat_input_t *i = vam->input;
11178   vl_api_classify_set_interface_l2_tables_t *mp;
11179   u32 sw_if_index;
11180   int sw_if_index_set;
11181   u32 ip4_table_index = ~0;
11182   u32 ip6_table_index = ~0;
11183   u32 other_table_index = ~0;
11184   u32 is_input = 1;
11185   int ret;
11186
11187   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11188     {
11189       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11190         sw_if_index_set = 1;
11191       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11192         sw_if_index_set = 1;
11193       else if (unformat (i, "ip4-table %d", &ip4_table_index))
11194         ;
11195       else if (unformat (i, "ip6-table %d", &ip6_table_index))
11196         ;
11197       else if (unformat (i, "other-table %d", &other_table_index))
11198         ;
11199       else if (unformat (i, "is-input %d", &is_input))
11200         ;
11201       else
11202         {
11203           clib_warning ("parse error '%U'", format_unformat_error, i);
11204           return -99;
11205         }
11206     }
11207
11208   if (sw_if_index_set == 0)
11209     {
11210       errmsg ("missing interface name or sw_if_index");
11211       return -99;
11212     }
11213
11214
11215   M (CLASSIFY_SET_INTERFACE_L2_TABLES, mp);
11216
11217   mp->sw_if_index = ntohl (sw_if_index);
11218   mp->ip4_table_index = ntohl (ip4_table_index);
11219   mp->ip6_table_index = ntohl (ip6_table_index);
11220   mp->other_table_index = ntohl (other_table_index);
11221   mp->is_input = (u8) is_input;
11222
11223   S (mp);
11224   W (ret);
11225   return ret;
11226 }
11227
11228 static int
11229 api_set_ipfix_exporter (vat_main_t * vam)
11230 {
11231   unformat_input_t *i = vam->input;
11232   vl_api_set_ipfix_exporter_t *mp;
11233   ip4_address_t collector_address;
11234   u8 collector_address_set = 0;
11235   u32 collector_port = ~0;
11236   ip4_address_t src_address;
11237   u8 src_address_set = 0;
11238   u32 vrf_id = ~0;
11239   u32 path_mtu = ~0;
11240   u32 template_interval = ~0;
11241   u8 udp_checksum = 0;
11242   int ret;
11243
11244   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11245     {
11246       if (unformat (i, "collector_address %U", unformat_ip4_address,
11247                     &collector_address))
11248         collector_address_set = 1;
11249       else if (unformat (i, "collector_port %d", &collector_port))
11250         ;
11251       else if (unformat (i, "src_address %U", unformat_ip4_address,
11252                          &src_address))
11253         src_address_set = 1;
11254       else if (unformat (i, "vrf_id %d", &vrf_id))
11255         ;
11256       else if (unformat (i, "path_mtu %d", &path_mtu))
11257         ;
11258       else if (unformat (i, "template_interval %d", &template_interval))
11259         ;
11260       else if (unformat (i, "udp_checksum"))
11261         udp_checksum = 1;
11262       else
11263         break;
11264     }
11265
11266   if (collector_address_set == 0)
11267     {
11268       errmsg ("collector_address required");
11269       return -99;
11270     }
11271
11272   if (src_address_set == 0)
11273     {
11274       errmsg ("src_address required");
11275       return -99;
11276     }
11277
11278   M (SET_IPFIX_EXPORTER, mp);
11279
11280   memcpy (mp->collector_address, collector_address.data,
11281           sizeof (collector_address.data));
11282   mp->collector_port = htons ((u16) collector_port);
11283   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
11284   mp->vrf_id = htonl (vrf_id);
11285   mp->path_mtu = htonl (path_mtu);
11286   mp->template_interval = htonl (template_interval);
11287   mp->udp_checksum = udp_checksum;
11288
11289   S (mp);
11290   W (ret);
11291   return ret;
11292 }
11293
11294 static int
11295 api_set_ipfix_classify_stream (vat_main_t * vam)
11296 {
11297   unformat_input_t *i = vam->input;
11298   vl_api_set_ipfix_classify_stream_t *mp;
11299   u32 domain_id = 0;
11300   u32 src_port = UDP_DST_PORT_ipfix;
11301   int ret;
11302
11303   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11304     {
11305       if (unformat (i, "domain %d", &domain_id))
11306         ;
11307       else if (unformat (i, "src_port %d", &src_port))
11308         ;
11309       else
11310         {
11311           errmsg ("unknown input `%U'", format_unformat_error, i);
11312           return -99;
11313         }
11314     }
11315
11316   M (SET_IPFIX_CLASSIFY_STREAM, mp);
11317
11318   mp->domain_id = htonl (domain_id);
11319   mp->src_port = htons ((u16) src_port);
11320
11321   S (mp);
11322   W (ret);
11323   return ret;
11324 }
11325
11326 static int
11327 api_ipfix_classify_table_add_del (vat_main_t * vam)
11328 {
11329   unformat_input_t *i = vam->input;
11330   vl_api_ipfix_classify_table_add_del_t *mp;
11331   int is_add = -1;
11332   u32 classify_table_index = ~0;
11333   u8 ip_version = 0;
11334   u8 transport_protocol = 255;
11335   int ret;
11336
11337   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11338     {
11339       if (unformat (i, "add"))
11340         is_add = 1;
11341       else if (unformat (i, "del"))
11342         is_add = 0;
11343       else if (unformat (i, "table %d", &classify_table_index))
11344         ;
11345       else if (unformat (i, "ip4"))
11346         ip_version = 4;
11347       else if (unformat (i, "ip6"))
11348         ip_version = 6;
11349       else if (unformat (i, "tcp"))
11350         transport_protocol = 6;
11351       else if (unformat (i, "udp"))
11352         transport_protocol = 17;
11353       else
11354         {
11355           errmsg ("unknown input `%U'", format_unformat_error, i);
11356           return -99;
11357         }
11358     }
11359
11360   if (is_add == -1)
11361     {
11362       errmsg ("expecting: add|del");
11363       return -99;
11364     }
11365   if (classify_table_index == ~0)
11366     {
11367       errmsg ("classifier table not specified");
11368       return -99;
11369     }
11370   if (ip_version == 0)
11371     {
11372       errmsg ("IP version not specified");
11373       return -99;
11374     }
11375
11376   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, mp);
11377
11378   mp->is_add = is_add;
11379   mp->table_id = htonl (classify_table_index);
11380   mp->ip_version = ip_version;
11381   mp->transport_protocol = transport_protocol;
11382
11383   S (mp);
11384   W (ret);
11385   return ret;
11386 }
11387
11388 static int
11389 api_get_node_index (vat_main_t * vam)
11390 {
11391   unformat_input_t *i = vam->input;
11392   vl_api_get_node_index_t *mp;
11393   u8 *name = 0;
11394   int ret;
11395
11396   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11397     {
11398       if (unformat (i, "node %s", &name))
11399         ;
11400       else
11401         break;
11402     }
11403   if (name == 0)
11404     {
11405       errmsg ("node name required");
11406       return -99;
11407     }
11408   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
11409     {
11410       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11411       return -99;
11412     }
11413
11414   M (GET_NODE_INDEX, mp);
11415   clib_memcpy (mp->node_name, name, vec_len (name));
11416   vec_free (name);
11417
11418   S (mp);
11419   W (ret);
11420   return ret;
11421 }
11422
11423 static int
11424 api_get_next_index (vat_main_t * vam)
11425 {
11426   unformat_input_t *i = vam->input;
11427   vl_api_get_next_index_t *mp;
11428   u8 *node_name = 0, *next_node_name = 0;
11429   int ret;
11430
11431   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11432     {
11433       if (unformat (i, "node-name %s", &node_name))
11434         ;
11435       else if (unformat (i, "next-node-name %s", &next_node_name))
11436         break;
11437     }
11438
11439   if (node_name == 0)
11440     {
11441       errmsg ("node name required");
11442       return -99;
11443     }
11444   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
11445     {
11446       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11447       return -99;
11448     }
11449
11450   if (next_node_name == 0)
11451     {
11452       errmsg ("next node name required");
11453       return -99;
11454     }
11455   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
11456     {
11457       errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
11458       return -99;
11459     }
11460
11461   M (GET_NEXT_INDEX, mp);
11462   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
11463   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
11464   vec_free (node_name);
11465   vec_free (next_node_name);
11466
11467   S (mp);
11468   W (ret);
11469   return ret;
11470 }
11471
11472 static int
11473 api_add_node_next (vat_main_t * vam)
11474 {
11475   unformat_input_t *i = vam->input;
11476   vl_api_add_node_next_t *mp;
11477   u8 *name = 0;
11478   u8 *next = 0;
11479   int ret;
11480
11481   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11482     {
11483       if (unformat (i, "node %s", &name))
11484         ;
11485       else if (unformat (i, "next %s", &next))
11486         ;
11487       else
11488         break;
11489     }
11490   if (name == 0)
11491     {
11492       errmsg ("node name required");
11493       return -99;
11494     }
11495   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
11496     {
11497       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11498       return -99;
11499     }
11500   if (next == 0)
11501     {
11502       errmsg ("next node required");
11503       return -99;
11504     }
11505   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
11506     {
11507       errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
11508       return -99;
11509     }
11510
11511   M (ADD_NODE_NEXT, mp);
11512   clib_memcpy (mp->node_name, name, vec_len (name));
11513   clib_memcpy (mp->next_name, next, vec_len (next));
11514   vec_free (name);
11515   vec_free (next);
11516
11517   S (mp);
11518   W (ret);
11519   return ret;
11520 }
11521
11522 static int
11523 api_l2tpv3_create_tunnel (vat_main_t * vam)
11524 {
11525   unformat_input_t *i = vam->input;
11526   ip6_address_t client_address, our_address;
11527   int client_address_set = 0;
11528   int our_address_set = 0;
11529   u32 local_session_id = 0;
11530   u32 remote_session_id = 0;
11531   u64 local_cookie = 0;
11532   u64 remote_cookie = 0;
11533   u8 l2_sublayer_present = 0;
11534   vl_api_l2tpv3_create_tunnel_t *mp;
11535   int ret;
11536
11537   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11538     {
11539       if (unformat (i, "client_address %U", unformat_ip6_address,
11540                     &client_address))
11541         client_address_set = 1;
11542       else if (unformat (i, "our_address %U", unformat_ip6_address,
11543                          &our_address))
11544         our_address_set = 1;
11545       else if (unformat (i, "local_session_id %d", &local_session_id))
11546         ;
11547       else if (unformat (i, "remote_session_id %d", &remote_session_id))
11548         ;
11549       else if (unformat (i, "local_cookie %lld", &local_cookie))
11550         ;
11551       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
11552         ;
11553       else if (unformat (i, "l2-sublayer-present"))
11554         l2_sublayer_present = 1;
11555       else
11556         break;
11557     }
11558
11559   if (client_address_set == 0)
11560     {
11561       errmsg ("client_address required");
11562       return -99;
11563     }
11564
11565   if (our_address_set == 0)
11566     {
11567       errmsg ("our_address required");
11568       return -99;
11569     }
11570
11571   M (L2TPV3_CREATE_TUNNEL, mp);
11572
11573   clib_memcpy (mp->client_address, client_address.as_u8,
11574                sizeof (mp->client_address));
11575
11576   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
11577
11578   mp->local_session_id = ntohl (local_session_id);
11579   mp->remote_session_id = ntohl (remote_session_id);
11580   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
11581   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
11582   mp->l2_sublayer_present = l2_sublayer_present;
11583   mp->is_ipv6 = 1;
11584
11585   S (mp);
11586   W (ret);
11587   return ret;
11588 }
11589
11590 static int
11591 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
11592 {
11593   unformat_input_t *i = vam->input;
11594   u32 sw_if_index;
11595   u8 sw_if_index_set = 0;
11596   u64 new_local_cookie = 0;
11597   u64 new_remote_cookie = 0;
11598   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
11599   int ret;
11600
11601   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11602     {
11603       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11604         sw_if_index_set = 1;
11605       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11606         sw_if_index_set = 1;
11607       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
11608         ;
11609       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
11610         ;
11611       else
11612         break;
11613     }
11614
11615   if (sw_if_index_set == 0)
11616     {
11617       errmsg ("missing interface name or sw_if_index");
11618       return -99;
11619     }
11620
11621   M (L2TPV3_SET_TUNNEL_COOKIES, mp);
11622
11623   mp->sw_if_index = ntohl (sw_if_index);
11624   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
11625   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
11626
11627   S (mp);
11628   W (ret);
11629   return ret;
11630 }
11631
11632 static int
11633 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
11634 {
11635   unformat_input_t *i = vam->input;
11636   vl_api_l2tpv3_interface_enable_disable_t *mp;
11637   u32 sw_if_index;
11638   u8 sw_if_index_set = 0;
11639   u8 enable_disable = 1;
11640   int ret;
11641
11642   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11643     {
11644       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11645         sw_if_index_set = 1;
11646       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11647         sw_if_index_set = 1;
11648       else if (unformat (i, "enable"))
11649         enable_disable = 1;
11650       else if (unformat (i, "disable"))
11651         enable_disable = 0;
11652       else
11653         break;
11654     }
11655
11656   if (sw_if_index_set == 0)
11657     {
11658       errmsg ("missing interface name or sw_if_index");
11659       return -99;
11660     }
11661
11662   M (L2TPV3_INTERFACE_ENABLE_DISABLE, mp);
11663
11664   mp->sw_if_index = ntohl (sw_if_index);
11665   mp->enable_disable = enable_disable;
11666
11667   S (mp);
11668   W (ret);
11669   return ret;
11670 }
11671
11672 static int
11673 api_l2tpv3_set_lookup_key (vat_main_t * vam)
11674 {
11675   unformat_input_t *i = vam->input;
11676   vl_api_l2tpv3_set_lookup_key_t *mp;
11677   u8 key = ~0;
11678   int ret;
11679
11680   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11681     {
11682       if (unformat (i, "lookup_v6_src"))
11683         key = L2T_LOOKUP_SRC_ADDRESS;
11684       else if (unformat (i, "lookup_v6_dst"))
11685         key = L2T_LOOKUP_DST_ADDRESS;
11686       else if (unformat (i, "lookup_session_id"))
11687         key = L2T_LOOKUP_SESSION_ID;
11688       else
11689         break;
11690     }
11691
11692   if (key == (u8) ~ 0)
11693     {
11694       errmsg ("l2tp session lookup key unset");
11695       return -99;
11696     }
11697
11698   M (L2TPV3_SET_LOOKUP_KEY, mp);
11699
11700   mp->key = key;
11701
11702   S (mp);
11703   W (ret);
11704   return ret;
11705 }
11706
11707 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
11708   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
11709 {
11710   vat_main_t *vam = &vat_main;
11711
11712   print (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)",
11713          format_ip6_address, mp->our_address,
11714          format_ip6_address, mp->client_address,
11715          clib_net_to_host_u32 (mp->sw_if_index));
11716
11717   print (vam->ofp,
11718          "   local cookies %016llx %016llx remote cookie %016llx",
11719          clib_net_to_host_u64 (mp->local_cookie[0]),
11720          clib_net_to_host_u64 (mp->local_cookie[1]),
11721          clib_net_to_host_u64 (mp->remote_cookie));
11722
11723   print (vam->ofp, "   local session-id %d remote session-id %d",
11724          clib_net_to_host_u32 (mp->local_session_id),
11725          clib_net_to_host_u32 (mp->remote_session_id));
11726
11727   print (vam->ofp, "   l2 specific sublayer %s\n",
11728          mp->l2_sublayer_present ? "preset" : "absent");
11729
11730 }
11731
11732 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
11733   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
11734 {
11735   vat_main_t *vam = &vat_main;
11736   vat_json_node_t *node = NULL;
11737   struct in6_addr addr;
11738
11739   if (VAT_JSON_ARRAY != vam->json_tree.type)
11740     {
11741       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11742       vat_json_init_array (&vam->json_tree);
11743     }
11744   node = vat_json_array_add (&vam->json_tree);
11745
11746   vat_json_init_object (node);
11747
11748   clib_memcpy (&addr, mp->our_address, sizeof (addr));
11749   vat_json_object_add_ip6 (node, "our_address", addr);
11750   clib_memcpy (&addr, mp->client_address, sizeof (addr));
11751   vat_json_object_add_ip6 (node, "client_address", addr);
11752
11753   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
11754   vat_json_init_array (lc);
11755   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
11756   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
11757   vat_json_object_add_uint (node, "remote_cookie",
11758                             clib_net_to_host_u64 (mp->remote_cookie));
11759
11760   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
11761   vat_json_object_add_uint (node, "local_session_id",
11762                             clib_net_to_host_u32 (mp->local_session_id));
11763   vat_json_object_add_uint (node, "remote_session_id",
11764                             clib_net_to_host_u32 (mp->remote_session_id));
11765   vat_json_object_add_string_copy (node, "l2_sublayer",
11766                                    mp->l2_sublayer_present ? (u8 *) "present"
11767                                    : (u8 *) "absent");
11768 }
11769
11770 static int
11771 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
11772 {
11773   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
11774   vl_api_control_ping_t *mp_ping;
11775   int ret;
11776
11777   /* Get list of l2tpv3-tunnel interfaces */
11778   M (SW_IF_L2TPV3_TUNNEL_DUMP, mp);
11779   S (mp);
11780
11781   /* Use a control ping for synchronization */
11782   MPING (CONTROL_PING, mp_ping);
11783   S (mp_ping);
11784
11785   W (ret);
11786   return ret;
11787 }
11788
11789
11790 static void vl_api_sw_interface_tap_v2_details_t_handler
11791   (vl_api_sw_interface_tap_v2_details_t * mp)
11792 {
11793   vat_main_t *vam = &vat_main;
11794
11795   u8 *ip4 = format (0, "%U/%d", format_ip4_address, mp->host_ip4_addr,
11796                     mp->host_ip4_prefix_len);
11797   u8 *ip6 = format (0, "%U/%d", format_ip6_address, mp->host_ip6_addr,
11798                     mp->host_ip6_prefix_len);
11799
11800   print (vam->ofp,
11801          "\n%-16s %-12d %-5d %-12d %-12d %-14U %-30s %-20s %-20s %-30s 0x%-08x",
11802          mp->dev_name, ntohl (mp->sw_if_index), ntohl (mp->id),
11803          ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
11804          format_ethernet_address, mp->host_mac_addr, mp->host_namespace,
11805          mp->host_bridge, ip4, ip6, ntohl (mp->tap_flags));
11806
11807   vec_free (ip4);
11808   vec_free (ip6);
11809 }
11810
11811 static void vl_api_sw_interface_tap_v2_details_t_handler_json
11812   (vl_api_sw_interface_tap_v2_details_t * mp)
11813 {
11814   vat_main_t *vam = &vat_main;
11815   vat_json_node_t *node = NULL;
11816
11817   if (VAT_JSON_ARRAY != vam->json_tree.type)
11818     {
11819       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11820       vat_json_init_array (&vam->json_tree);
11821     }
11822   node = vat_json_array_add (&vam->json_tree);
11823
11824   vat_json_init_object (node);
11825   vat_json_object_add_uint (node, "id", ntohl (mp->id));
11826   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11827   vat_json_object_add_uint (node, "tap_flags", ntohl (mp->tap_flags));
11828   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
11829   vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
11830   vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
11831   vat_json_object_add_string_copy (node, "host_mac_addr",
11832                                    format (0, "%U", format_ethernet_address,
11833                                            &mp->host_mac_addr));
11834   vat_json_object_add_string_copy (node, "host_namespace",
11835                                    mp->host_namespace);
11836   vat_json_object_add_string_copy (node, "host_bridge", mp->host_bridge);
11837   vat_json_object_add_string_copy (node, "host_ip4_addr",
11838                                    format (0, "%U/%d", format_ip4_address,
11839                                            mp->host_ip4_addr,
11840                                            mp->host_ip4_prefix_len));
11841   vat_json_object_add_string_copy (node, "host_ip6_addr",
11842                                    format (0, "%U/%d", format_ip6_address,
11843                                            mp->host_ip6_addr,
11844                                            mp->host_ip6_prefix_len));
11845
11846 }
11847
11848 static int
11849 api_sw_interface_tap_v2_dump (vat_main_t * vam)
11850 {
11851   vl_api_sw_interface_tap_v2_dump_t *mp;
11852   vl_api_control_ping_t *mp_ping;
11853   int ret;
11854
11855   print (vam->ofp,
11856          "\n%-16s %-12s %-5s %-12s %-12s %-14s %-30s %-20s %-20s %-30s",
11857          "dev_name", "sw_if_index", "id", "rx_ring_sz", "tx_ring_sz",
11858          "host_mac_addr", "host_namespace", "host_bridge", "host_ip4_addr",
11859          "host_ip6_addr");
11860
11861   /* Get list of tap interfaces */
11862   M (SW_INTERFACE_TAP_V2_DUMP, mp);
11863   S (mp);
11864
11865   /* Use a control ping for synchronization */
11866   MPING (CONTROL_PING, mp_ping);
11867   S (mp_ping);
11868
11869   W (ret);
11870   return ret;
11871 }
11872
11873 static void vl_api_sw_interface_virtio_pci_details_t_handler
11874   (vl_api_sw_interface_virtio_pci_details_t * mp)
11875 {
11876   vat_main_t *vam = &vat_main;
11877
11878   typedef union
11879   {
11880     struct
11881     {
11882       u16 domain;
11883       u8 bus;
11884       u8 slot:5;
11885       u8 function:3;
11886     };
11887     u32 as_u32;
11888   } pci_addr_t;
11889   pci_addr_t addr;
11890   addr.as_u32 = ntohl (mp->pci_addr);
11891   u8 *pci_addr = format (0, "%04x:%02x:%02x.%x", addr.domain, addr.bus,
11892                          addr.slot, addr.function);
11893
11894   print (vam->ofp,
11895          "\n%-12s %-12d %-12d %-12d %-17U 0x%-08llx",
11896          pci_addr, ntohl (mp->sw_if_index),
11897          ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
11898          format_ethernet_address, mp->mac_addr,
11899          clib_net_to_host_u64 (mp->features));
11900   vec_free (pci_addr);
11901 }
11902
11903 static void vl_api_sw_interface_virtio_pci_details_t_handler_json
11904   (vl_api_sw_interface_virtio_pci_details_t * mp)
11905 {
11906   vat_main_t *vam = &vat_main;
11907   vat_json_node_t *node = NULL;
11908
11909   if (VAT_JSON_ARRAY != vam->json_tree.type)
11910     {
11911       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11912       vat_json_init_array (&vam->json_tree);
11913     }
11914   node = vat_json_array_add (&vam->json_tree);
11915
11916   vat_json_init_object (node);
11917   vat_json_object_add_uint (node, "pci-addr", ntohl (mp->pci_addr));
11918   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11919   vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
11920   vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
11921   vat_json_object_add_uint (node, "features",
11922                             clib_net_to_host_u64 (mp->features));
11923   vat_json_object_add_string_copy (node, "mac_addr",
11924                                    format (0, "%U", format_ethernet_address,
11925                                            &mp->mac_addr));
11926 }
11927
11928 static int
11929 api_sw_interface_virtio_pci_dump (vat_main_t * vam)
11930 {
11931   vl_api_sw_interface_virtio_pci_dump_t *mp;
11932   vl_api_control_ping_t *mp_ping;
11933   int ret;
11934
11935   print (vam->ofp,
11936          "\n%-12s %-12s %-12s %-12s %-17s %-08s",
11937          "pci_addr", "sw_if_index", "rx_ring_sz", "tx_ring_sz",
11938          "mac_addr", "features");
11939
11940   /* Get list of tap interfaces */
11941   M (SW_INTERFACE_VIRTIO_PCI_DUMP, mp);
11942   S (mp);
11943
11944   /* Use a control ping for synchronization */
11945   MPING (CONTROL_PING, mp_ping);
11946   S (mp_ping);
11947
11948   W (ret);
11949   return ret;
11950 }
11951
11952 static int
11953 api_vxlan_offload_rx (vat_main_t * vam)
11954 {
11955   unformat_input_t *line_input = vam->input;
11956   vl_api_vxlan_offload_rx_t *mp;
11957   u32 hw_if_index = ~0, rx_if_index = ~0;
11958   u8 is_add = 1;
11959   int ret;
11960
11961   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11962     {
11963       if (unformat (line_input, "del"))
11964         is_add = 0;
11965       else if (unformat (line_input, "hw %U", api_unformat_hw_if_index, vam,
11966                          &hw_if_index))
11967         ;
11968       else if (unformat (line_input, "hw hw_if_index %u", &hw_if_index))
11969         ;
11970       else if (unformat (line_input, "rx %U", api_unformat_sw_if_index, vam,
11971                          &rx_if_index))
11972         ;
11973       else if (unformat (line_input, "rx sw_if_index %u", &rx_if_index))
11974         ;
11975       else
11976         {
11977           errmsg ("parse error '%U'", format_unformat_error, line_input);
11978           return -99;
11979         }
11980     }
11981
11982   if (hw_if_index == ~0)
11983     {
11984       errmsg ("no hw interface");
11985       return -99;
11986     }
11987
11988   if (rx_if_index == ~0)
11989     {
11990       errmsg ("no rx tunnel");
11991       return -99;
11992     }
11993
11994   M (VXLAN_OFFLOAD_RX, mp);
11995
11996   mp->hw_if_index = ntohl (hw_if_index);
11997   mp->sw_if_index = ntohl (rx_if_index);
11998   mp->enable = is_add;
11999
12000   S (mp);
12001   W (ret);
12002   return ret;
12003 }
12004
12005 static uword unformat_vxlan_decap_next
12006   (unformat_input_t * input, va_list * args)
12007 {
12008   u32 *result = va_arg (*args, u32 *);
12009   u32 tmp;
12010
12011   if (unformat (input, "l2"))
12012     *result = VXLAN_INPUT_NEXT_L2_INPUT;
12013   else if (unformat (input, "%d", &tmp))
12014     *result = tmp;
12015   else
12016     return 0;
12017   return 1;
12018 }
12019
12020 static int
12021 api_vxlan_add_del_tunnel (vat_main_t * vam)
12022 {
12023   unformat_input_t *line_input = vam->input;
12024   vl_api_vxlan_add_del_tunnel_t *mp;
12025   ip46_address_t src, dst;
12026   u8 is_add = 1;
12027   u8 ipv4_set = 0, ipv6_set = 0;
12028   u8 src_set = 0;
12029   u8 dst_set = 0;
12030   u8 grp_set = 0;
12031   u32 instance = ~0;
12032   u32 mcast_sw_if_index = ~0;
12033   u32 encap_vrf_id = 0;
12034   u32 decap_next_index = ~0;
12035   u32 vni = 0;
12036   int ret;
12037
12038   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
12039   clib_memset (&src, 0, sizeof src);
12040   clib_memset (&dst, 0, sizeof dst);
12041
12042   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12043     {
12044       if (unformat (line_input, "del"))
12045         is_add = 0;
12046       else if (unformat (line_input, "instance %d", &instance))
12047         ;
12048       else
12049         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
12050         {
12051           ipv4_set = 1;
12052           src_set = 1;
12053         }
12054       else
12055         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
12056         {
12057           ipv4_set = 1;
12058           dst_set = 1;
12059         }
12060       else
12061         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
12062         {
12063           ipv6_set = 1;
12064           src_set = 1;
12065         }
12066       else
12067         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
12068         {
12069           ipv6_set = 1;
12070           dst_set = 1;
12071         }
12072       else if (unformat (line_input, "group %U %U",
12073                          unformat_ip4_address, &dst.ip4,
12074                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12075         {
12076           grp_set = dst_set = 1;
12077           ipv4_set = 1;
12078         }
12079       else if (unformat (line_input, "group %U",
12080                          unformat_ip4_address, &dst.ip4))
12081         {
12082           grp_set = dst_set = 1;
12083           ipv4_set = 1;
12084         }
12085       else if (unformat (line_input, "group %U %U",
12086                          unformat_ip6_address, &dst.ip6,
12087                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12088         {
12089           grp_set = dst_set = 1;
12090           ipv6_set = 1;
12091         }
12092       else if (unformat (line_input, "group %U",
12093                          unformat_ip6_address, &dst.ip6))
12094         {
12095           grp_set = dst_set = 1;
12096           ipv6_set = 1;
12097         }
12098       else
12099         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
12100         ;
12101       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
12102         ;
12103       else if (unformat (line_input, "decap-next %U",
12104                          unformat_vxlan_decap_next, &decap_next_index))
12105         ;
12106       else if (unformat (line_input, "vni %d", &vni))
12107         ;
12108       else
12109         {
12110           errmsg ("parse error '%U'", format_unformat_error, line_input);
12111           return -99;
12112         }
12113     }
12114
12115   if (src_set == 0)
12116     {
12117       errmsg ("tunnel src address not specified");
12118       return -99;
12119     }
12120   if (dst_set == 0)
12121     {
12122       errmsg ("tunnel dst address not specified");
12123       return -99;
12124     }
12125
12126   if (grp_set && !ip46_address_is_multicast (&dst))
12127     {
12128       errmsg ("tunnel group address not multicast");
12129       return -99;
12130     }
12131   if (grp_set && mcast_sw_if_index == ~0)
12132     {
12133       errmsg ("tunnel nonexistent multicast device");
12134       return -99;
12135     }
12136   if (grp_set == 0 && ip46_address_is_multicast (&dst))
12137     {
12138       errmsg ("tunnel dst address must be unicast");
12139       return -99;
12140     }
12141
12142
12143   if (ipv4_set && ipv6_set)
12144     {
12145       errmsg ("both IPv4 and IPv6 addresses specified");
12146       return -99;
12147     }
12148
12149   if ((vni == 0) || (vni >> 24))
12150     {
12151       errmsg ("vni not specified or out of range");
12152       return -99;
12153     }
12154
12155   M (VXLAN_ADD_DEL_TUNNEL, mp);
12156
12157   if (ipv6_set)
12158     {
12159       clib_memcpy (mp->src_address, &src.ip6, sizeof (src.ip6));
12160       clib_memcpy (mp->dst_address, &dst.ip6, sizeof (dst.ip6));
12161     }
12162   else
12163     {
12164       clib_memcpy (mp->src_address, &src.ip4, sizeof (src.ip4));
12165       clib_memcpy (mp->dst_address, &dst.ip4, sizeof (dst.ip4));
12166     }
12167
12168   mp->instance = htonl (instance);
12169   mp->encap_vrf_id = ntohl (encap_vrf_id);
12170   mp->decap_next_index = ntohl (decap_next_index);
12171   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
12172   mp->vni = ntohl (vni);
12173   mp->is_add = is_add;
12174   mp->is_ipv6 = ipv6_set;
12175
12176   S (mp);
12177   W (ret);
12178   return ret;
12179 }
12180
12181 static void vl_api_vxlan_tunnel_details_t_handler
12182   (vl_api_vxlan_tunnel_details_t * mp)
12183 {
12184   vat_main_t *vam = &vat_main;
12185   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
12186   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
12187
12188   print (vam->ofp, "%11d%11d%24U%24U%14d%18d%13d%19d",
12189          ntohl (mp->sw_if_index),
12190          ntohl (mp->instance),
12191          format_ip46_address, &src, IP46_TYPE_ANY,
12192          format_ip46_address, &dst, IP46_TYPE_ANY,
12193          ntohl (mp->encap_vrf_id),
12194          ntohl (mp->decap_next_index), ntohl (mp->vni),
12195          ntohl (mp->mcast_sw_if_index));
12196 }
12197
12198 static void vl_api_vxlan_tunnel_details_t_handler_json
12199   (vl_api_vxlan_tunnel_details_t * mp)
12200 {
12201   vat_main_t *vam = &vat_main;
12202   vat_json_node_t *node = NULL;
12203
12204   if (VAT_JSON_ARRAY != vam->json_tree.type)
12205     {
12206       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12207       vat_json_init_array (&vam->json_tree);
12208     }
12209   node = vat_json_array_add (&vam->json_tree);
12210
12211   vat_json_init_object (node);
12212   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12213
12214   vat_json_object_add_uint (node, "instance", ntohl (mp->instance));
12215
12216   if (mp->is_ipv6)
12217     {
12218       struct in6_addr ip6;
12219
12220       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
12221       vat_json_object_add_ip6 (node, "src_address", ip6);
12222       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
12223       vat_json_object_add_ip6 (node, "dst_address", ip6);
12224     }
12225   else
12226     {
12227       struct in_addr ip4;
12228
12229       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
12230       vat_json_object_add_ip4 (node, "src_address", ip4);
12231       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
12232       vat_json_object_add_ip4 (node, "dst_address", ip4);
12233     }
12234   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
12235   vat_json_object_add_uint (node, "decap_next_index",
12236                             ntohl (mp->decap_next_index));
12237   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
12238   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
12239   vat_json_object_add_uint (node, "mcast_sw_if_index",
12240                             ntohl (mp->mcast_sw_if_index));
12241 }
12242
12243 static int
12244 api_vxlan_tunnel_dump (vat_main_t * vam)
12245 {
12246   unformat_input_t *i = vam->input;
12247   vl_api_vxlan_tunnel_dump_t *mp;
12248   vl_api_control_ping_t *mp_ping;
12249   u32 sw_if_index;
12250   u8 sw_if_index_set = 0;
12251   int ret;
12252
12253   /* Parse args required to build the message */
12254   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12255     {
12256       if (unformat (i, "sw_if_index %d", &sw_if_index))
12257         sw_if_index_set = 1;
12258       else
12259         break;
12260     }
12261
12262   if (sw_if_index_set == 0)
12263     {
12264       sw_if_index = ~0;
12265     }
12266
12267   if (!vam->json_output)
12268     {
12269       print (vam->ofp, "%11s%11s%24s%24s%14s%18s%13s%19s",
12270              "sw_if_index", "instance", "src_address", "dst_address",
12271              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
12272     }
12273
12274   /* Get list of vxlan-tunnel interfaces */
12275   M (VXLAN_TUNNEL_DUMP, mp);
12276
12277   mp->sw_if_index = htonl (sw_if_index);
12278
12279   S (mp);
12280
12281   /* Use a control ping for synchronization */
12282   MPING (CONTROL_PING, mp_ping);
12283   S (mp_ping);
12284
12285   W (ret);
12286   return ret;
12287 }
12288
12289 static uword unformat_geneve_decap_next
12290   (unformat_input_t * input, va_list * args)
12291 {
12292   u32 *result = va_arg (*args, u32 *);
12293   u32 tmp;
12294
12295   if (unformat (input, "l2"))
12296     *result = GENEVE_INPUT_NEXT_L2_INPUT;
12297   else if (unformat (input, "%d", &tmp))
12298     *result = tmp;
12299   else
12300     return 0;
12301   return 1;
12302 }
12303
12304 static int
12305 api_geneve_add_del_tunnel (vat_main_t * vam)
12306 {
12307   unformat_input_t *line_input = vam->input;
12308   vl_api_geneve_add_del_tunnel_t *mp;
12309   ip46_address_t src, dst;
12310   u8 is_add = 1;
12311   u8 ipv4_set = 0, ipv6_set = 0;
12312   u8 src_set = 0;
12313   u8 dst_set = 0;
12314   u8 grp_set = 0;
12315   u32 mcast_sw_if_index = ~0;
12316   u32 encap_vrf_id = 0;
12317   u32 decap_next_index = ~0;
12318   u32 vni = 0;
12319   int ret;
12320
12321   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
12322   clib_memset (&src, 0, sizeof src);
12323   clib_memset (&dst, 0, sizeof dst);
12324
12325   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12326     {
12327       if (unformat (line_input, "del"))
12328         is_add = 0;
12329       else
12330         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
12331         {
12332           ipv4_set = 1;
12333           src_set = 1;
12334         }
12335       else
12336         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
12337         {
12338           ipv4_set = 1;
12339           dst_set = 1;
12340         }
12341       else
12342         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
12343         {
12344           ipv6_set = 1;
12345           src_set = 1;
12346         }
12347       else
12348         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
12349         {
12350           ipv6_set = 1;
12351           dst_set = 1;
12352         }
12353       else if (unformat (line_input, "group %U %U",
12354                          unformat_ip4_address, &dst.ip4,
12355                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12356         {
12357           grp_set = dst_set = 1;
12358           ipv4_set = 1;
12359         }
12360       else if (unformat (line_input, "group %U",
12361                          unformat_ip4_address, &dst.ip4))
12362         {
12363           grp_set = dst_set = 1;
12364           ipv4_set = 1;
12365         }
12366       else if (unformat (line_input, "group %U %U",
12367                          unformat_ip6_address, &dst.ip6,
12368                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12369         {
12370           grp_set = dst_set = 1;
12371           ipv6_set = 1;
12372         }
12373       else if (unformat (line_input, "group %U",
12374                          unformat_ip6_address, &dst.ip6))
12375         {
12376           grp_set = dst_set = 1;
12377           ipv6_set = 1;
12378         }
12379       else
12380         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
12381         ;
12382       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
12383         ;
12384       else if (unformat (line_input, "decap-next %U",
12385                          unformat_geneve_decap_next, &decap_next_index))
12386         ;
12387       else if (unformat (line_input, "vni %d", &vni))
12388         ;
12389       else
12390         {
12391           errmsg ("parse error '%U'", format_unformat_error, line_input);
12392           return -99;
12393         }
12394     }
12395
12396   if (src_set == 0)
12397     {
12398       errmsg ("tunnel src address not specified");
12399       return -99;
12400     }
12401   if (dst_set == 0)
12402     {
12403       errmsg ("tunnel dst address not specified");
12404       return -99;
12405     }
12406
12407   if (grp_set && !ip46_address_is_multicast (&dst))
12408     {
12409       errmsg ("tunnel group address not multicast");
12410       return -99;
12411     }
12412   if (grp_set && mcast_sw_if_index == ~0)
12413     {
12414       errmsg ("tunnel nonexistent multicast device");
12415       return -99;
12416     }
12417   if (grp_set == 0 && ip46_address_is_multicast (&dst))
12418     {
12419       errmsg ("tunnel dst address must be unicast");
12420       return -99;
12421     }
12422
12423
12424   if (ipv4_set && ipv6_set)
12425     {
12426       errmsg ("both IPv4 and IPv6 addresses specified");
12427       return -99;
12428     }
12429
12430   if ((vni == 0) || (vni >> 24))
12431     {
12432       errmsg ("vni not specified or out of range");
12433       return -99;
12434     }
12435
12436   M (GENEVE_ADD_DEL_TUNNEL, mp);
12437
12438   if (ipv6_set)
12439     {
12440       clib_memcpy (mp->local_address, &src.ip6, sizeof (src.ip6));
12441       clib_memcpy (mp->remote_address, &dst.ip6, sizeof (dst.ip6));
12442     }
12443   else
12444     {
12445       clib_memcpy (mp->local_address, &src.ip4, sizeof (src.ip4));
12446       clib_memcpy (mp->remote_address, &dst.ip4, sizeof (dst.ip4));
12447     }
12448   mp->encap_vrf_id = ntohl (encap_vrf_id);
12449   mp->decap_next_index = ntohl (decap_next_index);
12450   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
12451   mp->vni = ntohl (vni);
12452   mp->is_add = is_add;
12453   mp->is_ipv6 = ipv6_set;
12454
12455   S (mp);
12456   W (ret);
12457   return ret;
12458 }
12459
12460 static void vl_api_geneve_tunnel_details_t_handler
12461   (vl_api_geneve_tunnel_details_t * mp)
12462 {
12463   vat_main_t *vam = &vat_main;
12464   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
12465   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
12466
12467   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
12468          ntohl (mp->sw_if_index),
12469          format_ip46_address, &src, IP46_TYPE_ANY,
12470          format_ip46_address, &dst, IP46_TYPE_ANY,
12471          ntohl (mp->encap_vrf_id),
12472          ntohl (mp->decap_next_index), ntohl (mp->vni),
12473          ntohl (mp->mcast_sw_if_index));
12474 }
12475
12476 static void vl_api_geneve_tunnel_details_t_handler_json
12477   (vl_api_geneve_tunnel_details_t * mp)
12478 {
12479   vat_main_t *vam = &vat_main;
12480   vat_json_node_t *node = NULL;
12481
12482   if (VAT_JSON_ARRAY != vam->json_tree.type)
12483     {
12484       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12485       vat_json_init_array (&vam->json_tree);
12486     }
12487   node = vat_json_array_add (&vam->json_tree);
12488
12489   vat_json_init_object (node);
12490   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12491   if (mp->is_ipv6)
12492     {
12493       struct in6_addr ip6;
12494
12495       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
12496       vat_json_object_add_ip6 (node, "src_address", ip6);
12497       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
12498       vat_json_object_add_ip6 (node, "dst_address", ip6);
12499     }
12500   else
12501     {
12502       struct in_addr ip4;
12503
12504       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
12505       vat_json_object_add_ip4 (node, "src_address", ip4);
12506       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
12507       vat_json_object_add_ip4 (node, "dst_address", ip4);
12508     }
12509   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
12510   vat_json_object_add_uint (node, "decap_next_index",
12511                             ntohl (mp->decap_next_index));
12512   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
12513   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
12514   vat_json_object_add_uint (node, "mcast_sw_if_index",
12515                             ntohl (mp->mcast_sw_if_index));
12516 }
12517
12518 static int
12519 api_geneve_tunnel_dump (vat_main_t * vam)
12520 {
12521   unformat_input_t *i = vam->input;
12522   vl_api_geneve_tunnel_dump_t *mp;
12523   vl_api_control_ping_t *mp_ping;
12524   u32 sw_if_index;
12525   u8 sw_if_index_set = 0;
12526   int ret;
12527
12528   /* Parse args required to build the message */
12529   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12530     {
12531       if (unformat (i, "sw_if_index %d", &sw_if_index))
12532         sw_if_index_set = 1;
12533       else
12534         break;
12535     }
12536
12537   if (sw_if_index_set == 0)
12538     {
12539       sw_if_index = ~0;
12540     }
12541
12542   if (!vam->json_output)
12543     {
12544       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
12545              "sw_if_index", "local_address", "remote_address",
12546              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
12547     }
12548
12549   /* Get list of geneve-tunnel interfaces */
12550   M (GENEVE_TUNNEL_DUMP, mp);
12551
12552   mp->sw_if_index = htonl (sw_if_index);
12553
12554   S (mp);
12555
12556   /* Use a control ping for synchronization */
12557   M (CONTROL_PING, mp_ping);
12558   S (mp_ping);
12559
12560   W (ret);
12561   return ret;
12562 }
12563
12564 static int
12565 api_gre_tunnel_add_del (vat_main_t * vam)
12566 {
12567   unformat_input_t *line_input = vam->input;
12568   vl_api_address_t src = { }, dst =
12569   {
12570   };
12571   vl_api_gre_tunnel_add_del_t *mp;
12572   vl_api_gre_tunnel_type_t t_type;
12573   u8 is_add = 1;
12574   u8 src_set = 0;
12575   u8 dst_set = 0;
12576   u32 outer_fib_id = 0;
12577   u32 session_id = 0;
12578   u32 instance = ~0;
12579   int ret;
12580
12581   t_type = GRE_API_TUNNEL_TYPE_L3;
12582
12583   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12584     {
12585       if (unformat (line_input, "del"))
12586         is_add = 0;
12587       else if (unformat (line_input, "instance %d", &instance))
12588         ;
12589       else if (unformat (line_input, "src %U", unformat_vl_api_address, &src))
12590         {
12591           src_set = 1;
12592         }
12593       else if (unformat (line_input, "dst %U", unformat_vl_api_address, &dst))
12594         {
12595           dst_set = 1;
12596         }
12597       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
12598         ;
12599       else if (unformat (line_input, "teb"))
12600         t_type = GRE_API_TUNNEL_TYPE_TEB;
12601       else if (unformat (line_input, "erspan %d", &session_id))
12602         t_type = GRE_API_TUNNEL_TYPE_ERSPAN;
12603       else
12604         {
12605           errmsg ("parse error '%U'", format_unformat_error, line_input);
12606           return -99;
12607         }
12608     }
12609
12610   if (src_set == 0)
12611     {
12612       errmsg ("tunnel src address not specified");
12613       return -99;
12614     }
12615   if (dst_set == 0)
12616     {
12617       errmsg ("tunnel dst address not specified");
12618       return -99;
12619     }
12620
12621   M (GRE_TUNNEL_ADD_DEL, mp);
12622
12623   clib_memcpy (&mp->tunnel.src, &src, sizeof (mp->tunnel.src));
12624   clib_memcpy (&mp->tunnel.dst, &dst, sizeof (mp->tunnel.dst));
12625
12626   mp->tunnel.instance = htonl (instance);
12627   mp->tunnel.outer_fib_id = htonl (outer_fib_id);
12628   mp->is_add = is_add;
12629   mp->tunnel.session_id = htons ((u16) session_id);
12630   mp->tunnel.type = htonl (t_type);
12631
12632   S (mp);
12633   W (ret);
12634   return ret;
12635 }
12636
12637 static void vl_api_gre_tunnel_details_t_handler
12638   (vl_api_gre_tunnel_details_t * mp)
12639 {
12640   vat_main_t *vam = &vat_main;
12641
12642   print (vam->ofp, "%11d%11d%24U%24U%13d%14d%12d",
12643          ntohl (mp->tunnel.sw_if_index),
12644          ntohl (mp->tunnel.instance),
12645          format_vl_api_address, &mp->tunnel.src,
12646          format_vl_api_address, &mp->tunnel.dst,
12647          mp->tunnel.type, ntohl (mp->tunnel.outer_fib_id),
12648          ntohl (mp->tunnel.session_id));
12649 }
12650
12651 static void vl_api_gre_tunnel_details_t_handler_json
12652   (vl_api_gre_tunnel_details_t * mp)
12653 {
12654   vat_main_t *vam = &vat_main;
12655   vat_json_node_t *node = NULL;
12656
12657   if (VAT_JSON_ARRAY != vam->json_tree.type)
12658     {
12659       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12660       vat_json_init_array (&vam->json_tree);
12661     }
12662   node = vat_json_array_add (&vam->json_tree);
12663
12664   vat_json_init_object (node);
12665   vat_json_object_add_uint (node, "sw_if_index",
12666                             ntohl (mp->tunnel.sw_if_index));
12667   vat_json_object_add_uint (node, "instance", ntohl (mp->tunnel.instance));
12668
12669   vat_json_object_add_address (node, "src", &mp->tunnel.src);
12670   vat_json_object_add_address (node, "dst", &mp->tunnel.dst);
12671   vat_json_object_add_uint (node, "tunnel_type", mp->tunnel.type);
12672   vat_json_object_add_uint (node, "outer_fib_id",
12673                             ntohl (mp->tunnel.outer_fib_id));
12674   vat_json_object_add_uint (node, "session_id", mp->tunnel.session_id);
12675 }
12676
12677 static int
12678 api_gre_tunnel_dump (vat_main_t * vam)
12679 {
12680   unformat_input_t *i = vam->input;
12681   vl_api_gre_tunnel_dump_t *mp;
12682   vl_api_control_ping_t *mp_ping;
12683   u32 sw_if_index;
12684   u8 sw_if_index_set = 0;
12685   int ret;
12686
12687   /* Parse args required to build the message */
12688   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12689     {
12690       if (unformat (i, "sw_if_index %d", &sw_if_index))
12691         sw_if_index_set = 1;
12692       else
12693         break;
12694     }
12695
12696   if (sw_if_index_set == 0)
12697     {
12698       sw_if_index = ~0;
12699     }
12700
12701   if (!vam->json_output)
12702     {
12703       print (vam->ofp, "%11s%11s%24s%24s%13s%14s%12s",
12704              "sw_if_index", "instance", "src_address", "dst_address",
12705              "tunnel_type", "outer_fib_id", "session_id");
12706     }
12707
12708   /* Get list of gre-tunnel interfaces */
12709   M (GRE_TUNNEL_DUMP, mp);
12710
12711   mp->sw_if_index = htonl (sw_if_index);
12712
12713   S (mp);
12714
12715   /* Use a control ping for synchronization */
12716   MPING (CONTROL_PING, mp_ping);
12717   S (mp_ping);
12718
12719   W (ret);
12720   return ret;
12721 }
12722
12723 static int
12724 api_l2_fib_clear_table (vat_main_t * vam)
12725 {
12726 //  unformat_input_t * i = vam->input;
12727   vl_api_l2_fib_clear_table_t *mp;
12728   int ret;
12729
12730   M (L2_FIB_CLEAR_TABLE, mp);
12731
12732   S (mp);
12733   W (ret);
12734   return ret;
12735 }
12736
12737 static int
12738 api_l2_interface_efp_filter (vat_main_t * vam)
12739 {
12740   unformat_input_t *i = vam->input;
12741   vl_api_l2_interface_efp_filter_t *mp;
12742   u32 sw_if_index;
12743   u8 enable = 1;
12744   u8 sw_if_index_set = 0;
12745   int ret;
12746
12747   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12748     {
12749       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12750         sw_if_index_set = 1;
12751       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12752         sw_if_index_set = 1;
12753       else if (unformat (i, "enable"))
12754         enable = 1;
12755       else if (unformat (i, "disable"))
12756         enable = 0;
12757       else
12758         {
12759           clib_warning ("parse error '%U'", format_unformat_error, i);
12760           return -99;
12761         }
12762     }
12763
12764   if (sw_if_index_set == 0)
12765     {
12766       errmsg ("missing sw_if_index");
12767       return -99;
12768     }
12769
12770   M (L2_INTERFACE_EFP_FILTER, mp);
12771
12772   mp->sw_if_index = ntohl (sw_if_index);
12773   mp->enable_disable = enable;
12774
12775   S (mp);
12776   W (ret);
12777   return ret;
12778 }
12779
12780 #define foreach_vtr_op                          \
12781 _("disable",  L2_VTR_DISABLED)                  \
12782 _("push-1",  L2_VTR_PUSH_1)                     \
12783 _("push-2",  L2_VTR_PUSH_2)                     \
12784 _("pop-1",  L2_VTR_POP_1)                       \
12785 _("pop-2",  L2_VTR_POP_2)                       \
12786 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
12787 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
12788 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
12789 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
12790
12791 static int
12792 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
12793 {
12794   unformat_input_t *i = vam->input;
12795   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
12796   u32 sw_if_index;
12797   u8 sw_if_index_set = 0;
12798   u8 vtr_op_set = 0;
12799   u32 vtr_op = 0;
12800   u32 push_dot1q = 1;
12801   u32 tag1 = ~0;
12802   u32 tag2 = ~0;
12803   int ret;
12804
12805   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12806     {
12807       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12808         sw_if_index_set = 1;
12809       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12810         sw_if_index_set = 1;
12811       else if (unformat (i, "vtr_op %d", &vtr_op))
12812         vtr_op_set = 1;
12813 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
12814       foreach_vtr_op
12815 #undef _
12816         else if (unformat (i, "push_dot1q %d", &push_dot1q))
12817         ;
12818       else if (unformat (i, "tag1 %d", &tag1))
12819         ;
12820       else if (unformat (i, "tag2 %d", &tag2))
12821         ;
12822       else
12823         {
12824           clib_warning ("parse error '%U'", format_unformat_error, i);
12825           return -99;
12826         }
12827     }
12828
12829   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
12830     {
12831       errmsg ("missing vtr operation or sw_if_index");
12832       return -99;
12833     }
12834
12835   M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
12836   mp->sw_if_index = ntohl (sw_if_index);
12837   mp->vtr_op = ntohl (vtr_op);
12838   mp->push_dot1q = ntohl (push_dot1q);
12839   mp->tag1 = ntohl (tag1);
12840   mp->tag2 = ntohl (tag2);
12841
12842   S (mp);
12843   W (ret);
12844   return ret;
12845 }
12846
12847 static int
12848 api_create_vhost_user_if (vat_main_t * vam)
12849 {
12850   unformat_input_t *i = vam->input;
12851   vl_api_create_vhost_user_if_t *mp;
12852   u8 *file_name;
12853   u8 is_server = 0;
12854   u8 file_name_set = 0;
12855   u32 custom_dev_instance = ~0;
12856   u8 hwaddr[6];
12857   u8 use_custom_mac = 0;
12858   u8 disable_mrg_rxbuf = 0;
12859   u8 disable_indirect_desc = 0;
12860   u8 *tag = 0;
12861   u8 enable_gso = 0;
12862   int ret;
12863
12864   /* Shut up coverity */
12865   clib_memset (hwaddr, 0, sizeof (hwaddr));
12866
12867   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12868     {
12869       if (unformat (i, "socket %s", &file_name))
12870         {
12871           file_name_set = 1;
12872         }
12873       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
12874         ;
12875       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
12876         use_custom_mac = 1;
12877       else if (unformat (i, "server"))
12878         is_server = 1;
12879       else if (unformat (i, "disable_mrg_rxbuf"))
12880         disable_mrg_rxbuf = 1;
12881       else if (unformat (i, "disable_indirect_desc"))
12882         disable_indirect_desc = 1;
12883       else if (unformat (i, "gso"))
12884         enable_gso = 1;
12885       else if (unformat (i, "tag %s", &tag))
12886         ;
12887       else
12888         break;
12889     }
12890
12891   if (file_name_set == 0)
12892     {
12893       errmsg ("missing socket file name");
12894       return -99;
12895     }
12896
12897   if (vec_len (file_name) > 255)
12898     {
12899       errmsg ("socket file name too long");
12900       return -99;
12901     }
12902   vec_add1 (file_name, 0);
12903
12904   M (CREATE_VHOST_USER_IF, mp);
12905
12906   mp->is_server = is_server;
12907   mp->disable_mrg_rxbuf = disable_mrg_rxbuf;
12908   mp->disable_indirect_desc = disable_indirect_desc;
12909   mp->enable_gso = enable_gso;
12910   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
12911   vec_free (file_name);
12912   if (custom_dev_instance != ~0)
12913     {
12914       mp->renumber = 1;
12915       mp->custom_dev_instance = ntohl (custom_dev_instance);
12916     }
12917
12918   mp->use_custom_mac = use_custom_mac;
12919   clib_memcpy (mp->mac_address, hwaddr, 6);
12920   if (tag)
12921     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
12922   vec_free (tag);
12923
12924   S (mp);
12925   W (ret);
12926   return ret;
12927 }
12928
12929 static int
12930 api_modify_vhost_user_if (vat_main_t * vam)
12931 {
12932   unformat_input_t *i = vam->input;
12933   vl_api_modify_vhost_user_if_t *mp;
12934   u8 *file_name;
12935   u8 is_server = 0;
12936   u8 file_name_set = 0;
12937   u32 custom_dev_instance = ~0;
12938   u8 sw_if_index_set = 0;
12939   u32 sw_if_index = (u32) ~ 0;
12940   u8 enable_gso = 0;
12941   int ret;
12942
12943   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12944     {
12945       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12946         sw_if_index_set = 1;
12947       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12948         sw_if_index_set = 1;
12949       else if (unformat (i, "socket %s", &file_name))
12950         {
12951           file_name_set = 1;
12952         }
12953       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
12954         ;
12955       else if (unformat (i, "server"))
12956         is_server = 1;
12957       else if (unformat (i, "gso"))
12958         enable_gso = 1;
12959       else
12960         break;
12961     }
12962
12963   if (sw_if_index_set == 0)
12964     {
12965       errmsg ("missing sw_if_index or interface name");
12966       return -99;
12967     }
12968
12969   if (file_name_set == 0)
12970     {
12971       errmsg ("missing socket file name");
12972       return -99;
12973     }
12974
12975   if (vec_len (file_name) > 255)
12976     {
12977       errmsg ("socket file name too long");
12978       return -99;
12979     }
12980   vec_add1 (file_name, 0);
12981
12982   M (MODIFY_VHOST_USER_IF, mp);
12983
12984   mp->sw_if_index = ntohl (sw_if_index);
12985   mp->is_server = is_server;
12986   mp->enable_gso = enable_gso;
12987   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
12988   vec_free (file_name);
12989   if (custom_dev_instance != ~0)
12990     {
12991       mp->renumber = 1;
12992       mp->custom_dev_instance = ntohl (custom_dev_instance);
12993     }
12994
12995   S (mp);
12996   W (ret);
12997   return ret;
12998 }
12999
13000 static int
13001 api_delete_vhost_user_if (vat_main_t * vam)
13002 {
13003   unformat_input_t *i = vam->input;
13004   vl_api_delete_vhost_user_if_t *mp;
13005   u32 sw_if_index = ~0;
13006   u8 sw_if_index_set = 0;
13007   int ret;
13008
13009   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13010     {
13011       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13012         sw_if_index_set = 1;
13013       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13014         sw_if_index_set = 1;
13015       else
13016         break;
13017     }
13018
13019   if (sw_if_index_set == 0)
13020     {
13021       errmsg ("missing sw_if_index or interface name");
13022       return -99;
13023     }
13024
13025
13026   M (DELETE_VHOST_USER_IF, mp);
13027
13028   mp->sw_if_index = ntohl (sw_if_index);
13029
13030   S (mp);
13031   W (ret);
13032   return ret;
13033 }
13034
13035 static void vl_api_sw_interface_vhost_user_details_t_handler
13036   (vl_api_sw_interface_vhost_user_details_t * mp)
13037 {
13038   vat_main_t *vam = &vat_main;
13039
13040   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s",
13041          (char *) mp->interface_name,
13042          ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
13043          clib_net_to_host_u64 (mp->features), mp->is_server,
13044          ntohl (mp->num_regions), (char *) mp->sock_filename);
13045   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
13046 }
13047
13048 static void vl_api_sw_interface_vhost_user_details_t_handler_json
13049   (vl_api_sw_interface_vhost_user_details_t * mp)
13050 {
13051   vat_main_t *vam = &vat_main;
13052   vat_json_node_t *node = NULL;
13053
13054   if (VAT_JSON_ARRAY != vam->json_tree.type)
13055     {
13056       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13057       vat_json_init_array (&vam->json_tree);
13058     }
13059   node = vat_json_array_add (&vam->json_tree);
13060
13061   vat_json_init_object (node);
13062   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13063   vat_json_object_add_string_copy (node, "interface_name",
13064                                    mp->interface_name);
13065   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
13066                             ntohl (mp->virtio_net_hdr_sz));
13067   vat_json_object_add_uint (node, "features",
13068                             clib_net_to_host_u64 (mp->features));
13069   vat_json_object_add_uint (node, "is_server", mp->is_server);
13070   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
13071   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
13072   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
13073 }
13074
13075 static int
13076 api_sw_interface_vhost_user_dump (vat_main_t * vam)
13077 {
13078   vl_api_sw_interface_vhost_user_dump_t *mp;
13079   vl_api_control_ping_t *mp_ping;
13080   int ret;
13081   print (vam->ofp,
13082          "Interface name            idx hdr_sz features server regions filename");
13083
13084   /* Get list of vhost-user interfaces */
13085   M (SW_INTERFACE_VHOST_USER_DUMP, mp);
13086   S (mp);
13087
13088   /* Use a control ping for synchronization */
13089   MPING (CONTROL_PING, mp_ping);
13090   S (mp_ping);
13091
13092   W (ret);
13093   return ret;
13094 }
13095
13096 static int
13097 api_show_version (vat_main_t * vam)
13098 {
13099   vl_api_show_version_t *mp;
13100   int ret;
13101
13102   M (SHOW_VERSION, mp);
13103
13104   S (mp);
13105   W (ret);
13106   return ret;
13107 }
13108
13109
13110 static int
13111 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
13112 {
13113   unformat_input_t *line_input = vam->input;
13114   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
13115   ip4_address_t local4, remote4;
13116   ip6_address_t local6, remote6;
13117   u8 is_add = 1;
13118   u8 ipv4_set = 0, ipv6_set = 0;
13119   u8 local_set = 0;
13120   u8 remote_set = 0;
13121   u8 grp_set = 0;
13122   u32 mcast_sw_if_index = ~0;
13123   u32 encap_vrf_id = 0;
13124   u32 decap_vrf_id = 0;
13125   u8 protocol = ~0;
13126   u32 vni;
13127   u8 vni_set = 0;
13128   int ret;
13129
13130   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
13131   clib_memset (&local4, 0, sizeof local4);
13132   clib_memset (&remote4, 0, sizeof remote4);
13133   clib_memset (&local6, 0, sizeof local6);
13134   clib_memset (&remote6, 0, sizeof remote6);
13135
13136   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13137     {
13138       if (unformat (line_input, "del"))
13139         is_add = 0;
13140       else if (unformat (line_input, "local %U",
13141                          unformat_ip4_address, &local4))
13142         {
13143           local_set = 1;
13144           ipv4_set = 1;
13145         }
13146       else if (unformat (line_input, "remote %U",
13147                          unformat_ip4_address, &remote4))
13148         {
13149           remote_set = 1;
13150           ipv4_set = 1;
13151         }
13152       else if (unformat (line_input, "local %U",
13153                          unformat_ip6_address, &local6))
13154         {
13155           local_set = 1;
13156           ipv6_set = 1;
13157         }
13158       else if (unformat (line_input, "remote %U",
13159                          unformat_ip6_address, &remote6))
13160         {
13161           remote_set = 1;
13162           ipv6_set = 1;
13163         }
13164       else if (unformat (line_input, "group %U %U",
13165                          unformat_ip4_address, &remote4,
13166                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13167         {
13168           grp_set = remote_set = 1;
13169           ipv4_set = 1;
13170         }
13171       else if (unformat (line_input, "group %U",
13172                          unformat_ip4_address, &remote4))
13173         {
13174           grp_set = remote_set = 1;
13175           ipv4_set = 1;
13176         }
13177       else if (unformat (line_input, "group %U %U",
13178                          unformat_ip6_address, &remote6,
13179                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13180         {
13181           grp_set = remote_set = 1;
13182           ipv6_set = 1;
13183         }
13184       else if (unformat (line_input, "group %U",
13185                          unformat_ip6_address, &remote6))
13186         {
13187           grp_set = remote_set = 1;
13188           ipv6_set = 1;
13189         }
13190       else
13191         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
13192         ;
13193       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
13194         ;
13195       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
13196         ;
13197       else if (unformat (line_input, "vni %d", &vni))
13198         vni_set = 1;
13199       else if (unformat (line_input, "next-ip4"))
13200         protocol = 1;
13201       else if (unformat (line_input, "next-ip6"))
13202         protocol = 2;
13203       else if (unformat (line_input, "next-ethernet"))
13204         protocol = 3;
13205       else if (unformat (line_input, "next-nsh"))
13206         protocol = 4;
13207       else
13208         {
13209           errmsg ("parse error '%U'", format_unformat_error, line_input);
13210           return -99;
13211         }
13212     }
13213
13214   if (local_set == 0)
13215     {
13216       errmsg ("tunnel local address not specified");
13217       return -99;
13218     }
13219   if (remote_set == 0)
13220     {
13221       errmsg ("tunnel remote address not specified");
13222       return -99;
13223     }
13224   if (grp_set && mcast_sw_if_index == ~0)
13225     {
13226       errmsg ("tunnel nonexistent multicast device");
13227       return -99;
13228     }
13229   if (ipv4_set && ipv6_set)
13230     {
13231       errmsg ("both IPv4 and IPv6 addresses specified");
13232       return -99;
13233     }
13234
13235   if (vni_set == 0)
13236     {
13237       errmsg ("vni not specified");
13238       return -99;
13239     }
13240
13241   M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
13242
13243
13244   if (ipv6_set)
13245     {
13246       clib_memcpy (&mp->local, &local6, sizeof (local6));
13247       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
13248     }
13249   else
13250     {
13251       clib_memcpy (&mp->local, &local4, sizeof (local4));
13252       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
13253     }
13254
13255   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
13256   mp->encap_vrf_id = ntohl (encap_vrf_id);
13257   mp->decap_vrf_id = ntohl (decap_vrf_id);
13258   mp->protocol = protocol;
13259   mp->vni = ntohl (vni);
13260   mp->is_add = is_add;
13261   mp->is_ipv6 = ipv6_set;
13262
13263   S (mp);
13264   W (ret);
13265   return ret;
13266 }
13267
13268 static void vl_api_vxlan_gpe_tunnel_details_t_handler
13269   (vl_api_vxlan_gpe_tunnel_details_t * mp)
13270 {
13271   vat_main_t *vam = &vat_main;
13272   ip46_address_t local = to_ip46 (mp->is_ipv6, mp->local);
13273   ip46_address_t remote = to_ip46 (mp->is_ipv6, mp->remote);
13274
13275   print (vam->ofp, "%11d%24U%24U%13d%12d%19d%14d%14d",
13276          ntohl (mp->sw_if_index),
13277          format_ip46_address, &local, IP46_TYPE_ANY,
13278          format_ip46_address, &remote, IP46_TYPE_ANY,
13279          ntohl (mp->vni), mp->protocol,
13280          ntohl (mp->mcast_sw_if_index),
13281          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
13282 }
13283
13284
13285 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
13286   (vl_api_vxlan_gpe_tunnel_details_t * mp)
13287 {
13288   vat_main_t *vam = &vat_main;
13289   vat_json_node_t *node = NULL;
13290   struct in_addr ip4;
13291   struct in6_addr ip6;
13292
13293   if (VAT_JSON_ARRAY != vam->json_tree.type)
13294     {
13295       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13296       vat_json_init_array (&vam->json_tree);
13297     }
13298   node = vat_json_array_add (&vam->json_tree);
13299
13300   vat_json_init_object (node);
13301   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13302   if (mp->is_ipv6)
13303     {
13304       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
13305       vat_json_object_add_ip6 (node, "local", ip6);
13306       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
13307       vat_json_object_add_ip6 (node, "remote", ip6);
13308     }
13309   else
13310     {
13311       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
13312       vat_json_object_add_ip4 (node, "local", ip4);
13313       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
13314       vat_json_object_add_ip4 (node, "remote", ip4);
13315     }
13316   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
13317   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
13318   vat_json_object_add_uint (node, "mcast_sw_if_index",
13319                             ntohl (mp->mcast_sw_if_index));
13320   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
13321   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
13322   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
13323 }
13324
13325 static int
13326 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
13327 {
13328   unformat_input_t *i = vam->input;
13329   vl_api_vxlan_gpe_tunnel_dump_t *mp;
13330   vl_api_control_ping_t *mp_ping;
13331   u32 sw_if_index;
13332   u8 sw_if_index_set = 0;
13333   int ret;
13334
13335   /* Parse args required to build the message */
13336   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13337     {
13338       if (unformat (i, "sw_if_index %d", &sw_if_index))
13339         sw_if_index_set = 1;
13340       else
13341         break;
13342     }
13343
13344   if (sw_if_index_set == 0)
13345     {
13346       sw_if_index = ~0;
13347     }
13348
13349   if (!vam->json_output)
13350     {
13351       print (vam->ofp, "%11s%24s%24s%13s%15s%19s%14s%14s",
13352              "sw_if_index", "local", "remote", "vni",
13353              "protocol", "mcast_sw_if_index", "encap_vrf_id", "decap_vrf_id");
13354     }
13355
13356   /* Get list of vxlan-tunnel interfaces */
13357   M (VXLAN_GPE_TUNNEL_DUMP, mp);
13358
13359   mp->sw_if_index = htonl (sw_if_index);
13360
13361   S (mp);
13362
13363   /* Use a control ping for synchronization */
13364   MPING (CONTROL_PING, mp_ping);
13365   S (mp_ping);
13366
13367   W (ret);
13368   return ret;
13369 }
13370
13371 static void vl_api_l2_fib_table_details_t_handler
13372   (vl_api_l2_fib_table_details_t * mp)
13373 {
13374   vat_main_t *vam = &vat_main;
13375
13376   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
13377          "       %d       %d     %d",
13378          ntohl (mp->bd_id), format_ethernet_address, mp->mac,
13379          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
13380          mp->bvi_mac);
13381 }
13382
13383 static void vl_api_l2_fib_table_details_t_handler_json
13384   (vl_api_l2_fib_table_details_t * mp)
13385 {
13386   vat_main_t *vam = &vat_main;
13387   vat_json_node_t *node = NULL;
13388
13389   if (VAT_JSON_ARRAY != vam->json_tree.type)
13390     {
13391       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13392       vat_json_init_array (&vam->json_tree);
13393     }
13394   node = vat_json_array_add (&vam->json_tree);
13395
13396   vat_json_init_object (node);
13397   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
13398   vat_json_object_add_bytes (node, "mac", mp->mac, 6);
13399   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13400   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
13401   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
13402   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
13403 }
13404
13405 static int
13406 api_l2_fib_table_dump (vat_main_t * vam)
13407 {
13408   unformat_input_t *i = vam->input;
13409   vl_api_l2_fib_table_dump_t *mp;
13410   vl_api_control_ping_t *mp_ping;
13411   u32 bd_id;
13412   u8 bd_id_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, "bd_id %d", &bd_id))
13419         bd_id_set = 1;
13420       else
13421         break;
13422     }
13423
13424   if (bd_id_set == 0)
13425     {
13426       errmsg ("missing bridge domain");
13427       return -99;
13428     }
13429
13430   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
13431
13432   /* Get list of l2 fib entries */
13433   M (L2_FIB_TABLE_DUMP, mp);
13434
13435   mp->bd_id = ntohl (bd_id);
13436   S (mp);
13437
13438   /* Use a control ping for synchronization */
13439   MPING (CONTROL_PING, mp_ping);
13440   S (mp_ping);
13441
13442   W (ret);
13443   return ret;
13444 }
13445
13446
13447 static int
13448 api_interface_name_renumber (vat_main_t * vam)
13449 {
13450   unformat_input_t *line_input = vam->input;
13451   vl_api_interface_name_renumber_t *mp;
13452   u32 sw_if_index = ~0;
13453   u32 new_show_dev_instance = ~0;
13454   int ret;
13455
13456   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13457     {
13458       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
13459                     &sw_if_index))
13460         ;
13461       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
13462         ;
13463       else if (unformat (line_input, "new_show_dev_instance %d",
13464                          &new_show_dev_instance))
13465         ;
13466       else
13467         break;
13468     }
13469
13470   if (sw_if_index == ~0)
13471     {
13472       errmsg ("missing interface name or sw_if_index");
13473       return -99;
13474     }
13475
13476   if (new_show_dev_instance == ~0)
13477     {
13478       errmsg ("missing new_show_dev_instance");
13479       return -99;
13480     }
13481
13482   M (INTERFACE_NAME_RENUMBER, mp);
13483
13484   mp->sw_if_index = ntohl (sw_if_index);
13485   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
13486
13487   S (mp);
13488   W (ret);
13489   return ret;
13490 }
13491
13492 static int
13493 api_ip_probe_neighbor (vat_main_t * vam)
13494 {
13495   unformat_input_t *i = vam->input;
13496   vl_api_ip_probe_neighbor_t *mp;
13497   vl_api_address_t dst_adr = { };
13498   u8 int_set = 0;
13499   u8 adr_set = 0;
13500   u32 sw_if_index;
13501   int ret;
13502
13503   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13504     {
13505       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13506         int_set = 1;
13507       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13508         int_set = 1;
13509       else if (unformat (i, "address %U", unformat_vl_api_address, &dst_adr))
13510         adr_set = 1;
13511       else
13512         break;
13513     }
13514
13515   if (int_set == 0)
13516     {
13517       errmsg ("missing interface");
13518       return -99;
13519     }
13520
13521   if (adr_set == 0)
13522     {
13523       errmsg ("missing addresses");
13524       return -99;
13525     }
13526
13527   M (IP_PROBE_NEIGHBOR, mp);
13528
13529   mp->sw_if_index = ntohl (sw_if_index);
13530   clib_memcpy (&mp->dst, &dst_adr, sizeof (dst_adr));
13531
13532   S (mp);
13533   W (ret);
13534   return ret;
13535 }
13536
13537 static int
13538 api_ip_scan_neighbor_enable_disable (vat_main_t * vam)
13539 {
13540   unformat_input_t *i = vam->input;
13541   vl_api_ip_scan_neighbor_enable_disable_t *mp;
13542   u8 mode = IP_SCAN_V46_NEIGHBORS;
13543   u32 interval = 0, time = 0, update = 0, delay = 0, stale = 0;
13544   int ret;
13545
13546   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13547     {
13548       if (unformat (i, "ip4"))
13549         mode = IP_SCAN_V4_NEIGHBORS;
13550       else if (unformat (i, "ip6"))
13551         mode = IP_SCAN_V6_NEIGHBORS;
13552       if (unformat (i, "both"))
13553         mode = IP_SCAN_V46_NEIGHBORS;
13554       else if (unformat (i, "disable"))
13555         mode = IP_SCAN_DISABLED;
13556       else if (unformat (i, "interval %d", &interval))
13557         ;
13558       else if (unformat (i, "max-time %d", &time))
13559         ;
13560       else if (unformat (i, "max-update %d", &update))
13561         ;
13562       else if (unformat (i, "delay %d", &delay))
13563         ;
13564       else if (unformat (i, "stale %d", &stale))
13565         ;
13566       else
13567         break;
13568     }
13569
13570   if (interval > 255)
13571     {
13572       errmsg ("interval cannot exceed 255 minutes.");
13573       return -99;
13574     }
13575   if (time > 255)
13576     {
13577       errmsg ("max-time cannot exceed 255 usec.");
13578       return -99;
13579     }
13580   if (update > 255)
13581     {
13582       errmsg ("max-update cannot exceed 255.");
13583       return -99;
13584     }
13585   if (delay > 255)
13586     {
13587       errmsg ("delay cannot exceed 255 msec.");
13588       return -99;
13589     }
13590   if (stale > 255)
13591     {
13592       errmsg ("stale cannot exceed 255 minutes.");
13593       return -99;
13594     }
13595
13596   M (IP_SCAN_NEIGHBOR_ENABLE_DISABLE, mp);
13597   mp->mode = mode;
13598   mp->scan_interval = interval;
13599   mp->max_proc_time = time;
13600   mp->max_update = update;
13601   mp->scan_int_delay = delay;
13602   mp->stale_threshold = stale;
13603
13604   S (mp);
13605   W (ret);
13606   return ret;
13607 }
13608
13609 static int
13610 api_want_ip4_arp_events (vat_main_t * vam)
13611 {
13612   unformat_input_t *line_input = vam->input;
13613   vl_api_want_ip4_arp_events_t *mp;
13614   ip4_address_t address;
13615   int address_set = 0;
13616   u32 enable_disable = 1;
13617   int ret;
13618
13619   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13620     {
13621       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
13622         address_set = 1;
13623       else if (unformat (line_input, "del"))
13624         enable_disable = 0;
13625       else
13626         break;
13627     }
13628
13629   if (address_set == 0)
13630     {
13631       errmsg ("missing addresses");
13632       return -99;
13633     }
13634
13635   M (WANT_IP4_ARP_EVENTS, mp);
13636   mp->enable_disable = enable_disable;
13637   mp->pid = htonl (getpid ());
13638   clib_memcpy (mp->ip, &address, sizeof (address));
13639
13640   S (mp);
13641   W (ret);
13642   return ret;
13643 }
13644
13645 static int
13646 api_want_ip6_nd_events (vat_main_t * vam)
13647 {
13648   unformat_input_t *line_input = vam->input;
13649   vl_api_want_ip6_nd_events_t *mp;
13650   vl_api_ip6_address_t address;
13651   int address_set = 0;
13652   u32 enable_disable = 1;
13653   int ret;
13654
13655   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13656     {
13657       if (unformat
13658           (line_input, "address %U", unformat_vl_api_ip6_address, &address))
13659         address_set = 1;
13660       else if (unformat (line_input, "del"))
13661         enable_disable = 0;
13662       else
13663         break;
13664     }
13665
13666   if (address_set == 0)
13667     {
13668       errmsg ("missing addresses");
13669       return -99;
13670     }
13671
13672   M (WANT_IP6_ND_EVENTS, mp);
13673   mp->enable_disable = enable_disable;
13674   mp->pid = htonl (getpid ());
13675   clib_memcpy (&mp->ip, &address, sizeof (address));
13676
13677   S (mp);
13678   W (ret);
13679   return ret;
13680 }
13681
13682 static int
13683 api_want_l2_macs_events (vat_main_t * vam)
13684 {
13685   unformat_input_t *line_input = vam->input;
13686   vl_api_want_l2_macs_events_t *mp;
13687   u8 enable_disable = 1;
13688   u32 scan_delay = 0;
13689   u32 max_macs_in_event = 0;
13690   u32 learn_limit = 0;
13691   int ret;
13692
13693   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13694     {
13695       if (unformat (line_input, "learn-limit %d", &learn_limit))
13696         ;
13697       else if (unformat (line_input, "scan-delay %d", &scan_delay))
13698         ;
13699       else if (unformat (line_input, "max-entries %d", &max_macs_in_event))
13700         ;
13701       else if (unformat (line_input, "disable"))
13702         enable_disable = 0;
13703       else
13704         break;
13705     }
13706
13707   M (WANT_L2_MACS_EVENTS, mp);
13708   mp->enable_disable = enable_disable;
13709   mp->pid = htonl (getpid ());
13710   mp->learn_limit = htonl (learn_limit);
13711   mp->scan_delay = (u8) scan_delay;
13712   mp->max_macs_in_event = (u8) (max_macs_in_event / 10);
13713   S (mp);
13714   W (ret);
13715   return ret;
13716 }
13717
13718 static int
13719 api_input_acl_set_interface (vat_main_t * vam)
13720 {
13721   unformat_input_t *i = vam->input;
13722   vl_api_input_acl_set_interface_t *mp;
13723   u32 sw_if_index;
13724   int sw_if_index_set;
13725   u32 ip4_table_index = ~0;
13726   u32 ip6_table_index = ~0;
13727   u32 l2_table_index = ~0;
13728   u8 is_add = 1;
13729   int ret;
13730
13731   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13732     {
13733       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13734         sw_if_index_set = 1;
13735       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13736         sw_if_index_set = 1;
13737       else if (unformat (i, "del"))
13738         is_add = 0;
13739       else if (unformat (i, "ip4-table %d", &ip4_table_index))
13740         ;
13741       else if (unformat (i, "ip6-table %d", &ip6_table_index))
13742         ;
13743       else if (unformat (i, "l2-table %d", &l2_table_index))
13744         ;
13745       else
13746         {
13747           clib_warning ("parse error '%U'", format_unformat_error, i);
13748           return -99;
13749         }
13750     }
13751
13752   if (sw_if_index_set == 0)
13753     {
13754       errmsg ("missing interface name or sw_if_index");
13755       return -99;
13756     }
13757
13758   M (INPUT_ACL_SET_INTERFACE, mp);
13759
13760   mp->sw_if_index = ntohl (sw_if_index);
13761   mp->ip4_table_index = ntohl (ip4_table_index);
13762   mp->ip6_table_index = ntohl (ip6_table_index);
13763   mp->l2_table_index = ntohl (l2_table_index);
13764   mp->is_add = is_add;
13765
13766   S (mp);
13767   W (ret);
13768   return ret;
13769 }
13770
13771 static int
13772 api_output_acl_set_interface (vat_main_t * vam)
13773 {
13774   unformat_input_t *i = vam->input;
13775   vl_api_output_acl_set_interface_t *mp;
13776   u32 sw_if_index;
13777   int sw_if_index_set;
13778   u32 ip4_table_index = ~0;
13779   u32 ip6_table_index = ~0;
13780   u32 l2_table_index = ~0;
13781   u8 is_add = 1;
13782   int ret;
13783
13784   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13785     {
13786       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13787         sw_if_index_set = 1;
13788       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13789         sw_if_index_set = 1;
13790       else if (unformat (i, "del"))
13791         is_add = 0;
13792       else if (unformat (i, "ip4-table %d", &ip4_table_index))
13793         ;
13794       else if (unformat (i, "ip6-table %d", &ip6_table_index))
13795         ;
13796       else if (unformat (i, "l2-table %d", &l2_table_index))
13797         ;
13798       else
13799         {
13800           clib_warning ("parse error '%U'", format_unformat_error, i);
13801           return -99;
13802         }
13803     }
13804
13805   if (sw_if_index_set == 0)
13806     {
13807       errmsg ("missing interface name or sw_if_index");
13808       return -99;
13809     }
13810
13811   M (OUTPUT_ACL_SET_INTERFACE, mp);
13812
13813   mp->sw_if_index = ntohl (sw_if_index);
13814   mp->ip4_table_index = ntohl (ip4_table_index);
13815   mp->ip6_table_index = ntohl (ip6_table_index);
13816   mp->l2_table_index = ntohl (l2_table_index);
13817   mp->is_add = is_add;
13818
13819   S (mp);
13820   W (ret);
13821   return ret;
13822 }
13823
13824 static int
13825 api_ip_address_dump (vat_main_t * vam)
13826 {
13827   unformat_input_t *i = vam->input;
13828   vl_api_ip_address_dump_t *mp;
13829   vl_api_control_ping_t *mp_ping;
13830   u32 sw_if_index = ~0;
13831   u8 sw_if_index_set = 0;
13832   u8 ipv4_set = 0;
13833   u8 ipv6_set = 0;
13834   int ret;
13835
13836   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13837     {
13838       if (unformat (i, "sw_if_index %d", &sw_if_index))
13839         sw_if_index_set = 1;
13840       else
13841         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13842         sw_if_index_set = 1;
13843       else if (unformat (i, "ipv4"))
13844         ipv4_set = 1;
13845       else if (unformat (i, "ipv6"))
13846         ipv6_set = 1;
13847       else
13848         break;
13849     }
13850
13851   if (ipv4_set && ipv6_set)
13852     {
13853       errmsg ("ipv4 and ipv6 flags cannot be both set");
13854       return -99;
13855     }
13856
13857   if ((!ipv4_set) && (!ipv6_set))
13858     {
13859       errmsg ("no ipv4 nor ipv6 flag set");
13860       return -99;
13861     }
13862
13863   if (sw_if_index_set == 0)
13864     {
13865       errmsg ("missing interface name or sw_if_index");
13866       return -99;
13867     }
13868
13869   vam->current_sw_if_index = sw_if_index;
13870   vam->is_ipv6 = ipv6_set;
13871
13872   M (IP_ADDRESS_DUMP, mp);
13873   mp->sw_if_index = ntohl (sw_if_index);
13874   mp->is_ipv6 = ipv6_set;
13875   S (mp);
13876
13877   /* Use a control ping for synchronization */
13878   MPING (CONTROL_PING, mp_ping);
13879   S (mp_ping);
13880
13881   W (ret);
13882   return ret;
13883 }
13884
13885 static int
13886 api_ip_dump (vat_main_t * vam)
13887 {
13888   vl_api_ip_dump_t *mp;
13889   vl_api_control_ping_t *mp_ping;
13890   unformat_input_t *in = vam->input;
13891   int ipv4_set = 0;
13892   int ipv6_set = 0;
13893   int is_ipv6;
13894   int i;
13895   int ret;
13896
13897   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
13898     {
13899       if (unformat (in, "ipv4"))
13900         ipv4_set = 1;
13901       else if (unformat (in, "ipv6"))
13902         ipv6_set = 1;
13903       else
13904         break;
13905     }
13906
13907   if (ipv4_set && ipv6_set)
13908     {
13909       errmsg ("ipv4 and ipv6 flags cannot be both set");
13910       return -99;
13911     }
13912
13913   if ((!ipv4_set) && (!ipv6_set))
13914     {
13915       errmsg ("no ipv4 nor ipv6 flag set");
13916       return -99;
13917     }
13918
13919   is_ipv6 = ipv6_set;
13920   vam->is_ipv6 = is_ipv6;
13921
13922   /* free old data */
13923   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
13924     {
13925       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
13926     }
13927   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
13928
13929   M (IP_DUMP, mp);
13930   mp->is_ipv6 = ipv6_set;
13931   S (mp);
13932
13933   /* Use a control ping for synchronization */
13934   MPING (CONTROL_PING, mp_ping);
13935   S (mp_ping);
13936
13937   W (ret);
13938   return ret;
13939 }
13940
13941 static int
13942 api_ipsec_spd_add_del (vat_main_t * vam)
13943 {
13944   unformat_input_t *i = vam->input;
13945   vl_api_ipsec_spd_add_del_t *mp;
13946   u32 spd_id = ~0;
13947   u8 is_add = 1;
13948   int ret;
13949
13950   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13951     {
13952       if (unformat (i, "spd_id %d", &spd_id))
13953         ;
13954       else if (unformat (i, "del"))
13955         is_add = 0;
13956       else
13957         {
13958           clib_warning ("parse error '%U'", format_unformat_error, i);
13959           return -99;
13960         }
13961     }
13962   if (spd_id == ~0)
13963     {
13964       errmsg ("spd_id must be set");
13965       return -99;
13966     }
13967
13968   M (IPSEC_SPD_ADD_DEL, mp);
13969
13970   mp->spd_id = ntohl (spd_id);
13971   mp->is_add = is_add;
13972
13973   S (mp);
13974   W (ret);
13975   return ret;
13976 }
13977
13978 static int
13979 api_ipsec_interface_add_del_spd (vat_main_t * vam)
13980 {
13981   unformat_input_t *i = vam->input;
13982   vl_api_ipsec_interface_add_del_spd_t *mp;
13983   u32 sw_if_index;
13984   u8 sw_if_index_set = 0;
13985   u32 spd_id = (u32) ~ 0;
13986   u8 is_add = 1;
13987   int ret;
13988
13989   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13990     {
13991       if (unformat (i, "del"))
13992         is_add = 0;
13993       else if (unformat (i, "spd_id %d", &spd_id))
13994         ;
13995       else
13996         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13997         sw_if_index_set = 1;
13998       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13999         sw_if_index_set = 1;
14000       else
14001         {
14002           clib_warning ("parse error '%U'", format_unformat_error, i);
14003           return -99;
14004         }
14005
14006     }
14007
14008   if (spd_id == (u32) ~ 0)
14009     {
14010       errmsg ("spd_id must be set");
14011       return -99;
14012     }
14013
14014   if (sw_if_index_set == 0)
14015     {
14016       errmsg ("missing interface name or sw_if_index");
14017       return -99;
14018     }
14019
14020   M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
14021
14022   mp->spd_id = ntohl (spd_id);
14023   mp->sw_if_index = ntohl (sw_if_index);
14024   mp->is_add = is_add;
14025
14026   S (mp);
14027   W (ret);
14028   return ret;
14029 }
14030
14031 static int
14032 api_ipsec_spd_entry_add_del (vat_main_t * vam)
14033 {
14034   unformat_input_t *i = vam->input;
14035   vl_api_ipsec_spd_entry_add_del_t *mp;
14036   u8 is_add = 1, is_outbound = 0;
14037   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
14038   i32 priority = 0;
14039   u32 rport_start = 0, rport_stop = (u32) ~ 0;
14040   u32 lport_start = 0, lport_stop = (u32) ~ 0;
14041   vl_api_address_t laddr_start = { }, laddr_stop =
14042   {
14043   }, raddr_start =
14044   {
14045   }, raddr_stop =
14046   {
14047   };
14048   int ret;
14049
14050   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14051     {
14052       if (unformat (i, "del"))
14053         is_add = 0;
14054       if (unformat (i, "outbound"))
14055         is_outbound = 1;
14056       if (unformat (i, "inbound"))
14057         is_outbound = 0;
14058       else if (unformat (i, "spd_id %d", &spd_id))
14059         ;
14060       else if (unformat (i, "sa_id %d", &sa_id))
14061         ;
14062       else if (unformat (i, "priority %d", &priority))
14063         ;
14064       else if (unformat (i, "protocol %d", &protocol))
14065         ;
14066       else if (unformat (i, "lport_start %d", &lport_start))
14067         ;
14068       else if (unformat (i, "lport_stop %d", &lport_stop))
14069         ;
14070       else if (unformat (i, "rport_start %d", &rport_start))
14071         ;
14072       else if (unformat (i, "rport_stop %d", &rport_stop))
14073         ;
14074       else if (unformat (i, "laddr_start %U",
14075                          unformat_vl_api_address, &laddr_start))
14076         ;
14077       else if (unformat (i, "laddr_stop %U", unformat_vl_api_address,
14078                          &laddr_stop))
14079         ;
14080       else if (unformat (i, "raddr_start %U", unformat_vl_api_address,
14081                          &raddr_start))
14082         ;
14083       else if (unformat (i, "raddr_stop %U", unformat_vl_api_address,
14084                          &raddr_stop))
14085         ;
14086       else
14087         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
14088         {
14089           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
14090             {
14091               clib_warning ("unsupported action: 'resolve'");
14092               return -99;
14093             }
14094         }
14095       else
14096         {
14097           clib_warning ("parse error '%U'", format_unformat_error, i);
14098           return -99;
14099         }
14100
14101     }
14102
14103   M (IPSEC_SPD_ENTRY_ADD_DEL, mp);
14104
14105   mp->is_add = is_add;
14106
14107   mp->entry.spd_id = ntohl (spd_id);
14108   mp->entry.priority = ntohl (priority);
14109   mp->entry.is_outbound = is_outbound;
14110
14111   clib_memcpy (&mp->entry.remote_address_start, &raddr_start,
14112                sizeof (vl_api_address_t));
14113   clib_memcpy (&mp->entry.remote_address_stop, &raddr_stop,
14114                sizeof (vl_api_address_t));
14115   clib_memcpy (&mp->entry.local_address_start, &laddr_start,
14116                sizeof (vl_api_address_t));
14117   clib_memcpy (&mp->entry.local_address_stop, &laddr_stop,
14118                sizeof (vl_api_address_t));
14119
14120   mp->entry.protocol = (u8) protocol;
14121   mp->entry.local_port_start = ntohs ((u16) lport_start);
14122   mp->entry.local_port_stop = ntohs ((u16) lport_stop);
14123   mp->entry.remote_port_start = ntohs ((u16) rport_start);
14124   mp->entry.remote_port_stop = ntohs ((u16) rport_stop);
14125   mp->entry.policy = (u8) policy;
14126   mp->entry.sa_id = ntohl (sa_id);
14127
14128   S (mp);
14129   W (ret);
14130   return ret;
14131 }
14132
14133 static int
14134 api_ipsec_sad_entry_add_del (vat_main_t * vam)
14135 {
14136   unformat_input_t *i = vam->input;
14137   vl_api_ipsec_sad_entry_add_del_t *mp;
14138   u32 sad_id = 0, spi = 0;
14139   u8 *ck = 0, *ik = 0;
14140   u8 is_add = 1;
14141
14142   vl_api_ipsec_crypto_alg_t crypto_alg = IPSEC_API_CRYPTO_ALG_NONE;
14143   vl_api_ipsec_integ_alg_t integ_alg = IPSEC_API_INTEG_ALG_NONE;
14144   vl_api_ipsec_sad_flags_t flags = IPSEC_API_SAD_FLAG_NONE;
14145   vl_api_ipsec_proto_t protocol = IPSEC_API_PROTO_AH;
14146   vl_api_address_t tun_src, tun_dst;
14147   int ret;
14148
14149   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14150     {
14151       if (unformat (i, "del"))
14152         is_add = 0;
14153       else if (unformat (i, "sad_id %d", &sad_id))
14154         ;
14155       else if (unformat (i, "spi %d", &spi))
14156         ;
14157       else if (unformat (i, "esp"))
14158         protocol = IPSEC_API_PROTO_ESP;
14159       else
14160         if (unformat (i, "tunnel_src %U", unformat_vl_api_address, &tun_src))
14161         {
14162           flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL;
14163           if (ADDRESS_IP6 == tun_src.af)
14164             flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL_V6;
14165         }
14166       else
14167         if (unformat (i, "tunnel_dst %U", unformat_vl_api_address, &tun_dst))
14168         {
14169           flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL;
14170           if (ADDRESS_IP6 == tun_src.af)
14171             flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL_V6;
14172         }
14173       else
14174         if (unformat (i, "crypto_alg %U",
14175                       unformat_ipsec_api_crypto_alg, &crypto_alg))
14176         ;
14177       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
14178         ;
14179       else if (unformat (i, "integ_alg %U",
14180                          unformat_ipsec_api_integ_alg, &integ_alg))
14181         ;
14182       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
14183         ;
14184       else
14185         {
14186           clib_warning ("parse error '%U'", format_unformat_error, i);
14187           return -99;
14188         }
14189
14190     }
14191
14192   M (IPSEC_SAD_ENTRY_ADD_DEL, mp);
14193
14194   mp->is_add = is_add;
14195   mp->entry.sad_id = ntohl (sad_id);
14196   mp->entry.protocol = protocol;
14197   mp->entry.spi = ntohl (spi);
14198   mp->entry.flags = flags;
14199
14200   mp->entry.crypto_algorithm = crypto_alg;
14201   mp->entry.integrity_algorithm = integ_alg;
14202   mp->entry.crypto_key.length = vec_len (ck);
14203   mp->entry.integrity_key.length = vec_len (ik);
14204
14205   if (mp->entry.crypto_key.length > sizeof (mp->entry.crypto_key.data))
14206     mp->entry.crypto_key.length = sizeof (mp->entry.crypto_key.data);
14207
14208   if (mp->entry.integrity_key.length > sizeof (mp->entry.integrity_key.data))
14209     mp->entry.integrity_key.length = sizeof (mp->entry.integrity_key.data);
14210
14211   if (ck)
14212     clib_memcpy (mp->entry.crypto_key.data, ck, mp->entry.crypto_key.length);
14213   if (ik)
14214     clib_memcpy (mp->entry.integrity_key.data, ik,
14215                  mp->entry.integrity_key.length);
14216
14217   if (flags & IPSEC_API_SAD_FLAG_IS_TUNNEL)
14218     {
14219       clib_memcpy (&mp->entry.tunnel_src, &tun_src,
14220                    sizeof (mp->entry.tunnel_src));
14221       clib_memcpy (&mp->entry.tunnel_dst, &tun_dst,
14222                    sizeof (mp->entry.tunnel_dst));
14223     }
14224
14225   S (mp);
14226   W (ret);
14227   return ret;
14228 }
14229
14230 static int
14231 api_ipsec_tunnel_if_add_del (vat_main_t * vam)
14232 {
14233   unformat_input_t *i = vam->input;
14234   vl_api_ipsec_tunnel_if_add_del_t *mp;
14235   u32 local_spi = 0, remote_spi = 0;
14236   u32 crypto_alg = 0, integ_alg = 0;
14237   u8 *lck = NULL, *rck = NULL;
14238   u8 *lik = NULL, *rik = NULL;
14239   vl_api_address_t local_ip = { 0 };
14240   vl_api_address_t remote_ip = { 0 };
14241   f64 before = 0;
14242   u8 is_add = 1;
14243   u8 esn = 0;
14244   u8 anti_replay = 0;
14245   u8 renumber = 0;
14246   u32 instance = ~0;
14247   u32 count = 1, jj;
14248   int ret = -1;
14249
14250   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14251     {
14252       if (unformat (i, "del"))
14253         is_add = 0;
14254       else if (unformat (i, "esn"))
14255         esn = 1;
14256       else if (unformat (i, "anti-replay"))
14257         anti_replay = 1;
14258       else if (unformat (i, "count %d", &count))
14259         ;
14260       else if (unformat (i, "local_spi %d", &local_spi))
14261         ;
14262       else if (unformat (i, "remote_spi %d", &remote_spi))
14263         ;
14264       else
14265         if (unformat (i, "local_ip %U", unformat_vl_api_address, &local_ip))
14266         ;
14267       else
14268         if (unformat (i, "remote_ip %U", unformat_vl_api_address, &remote_ip))
14269         ;
14270       else if (unformat (i, "local_crypto_key %U", unformat_hex_string, &lck))
14271         ;
14272       else
14273         if (unformat (i, "remote_crypto_key %U", unformat_hex_string, &rck))
14274         ;
14275       else if (unformat (i, "local_integ_key %U", unformat_hex_string, &lik))
14276         ;
14277       else if (unformat (i, "remote_integ_key %U", unformat_hex_string, &rik))
14278         ;
14279       else
14280         if (unformat
14281             (i, "crypto_alg %U", unformat_ipsec_api_crypto_alg, &crypto_alg))
14282         {
14283           if (crypto_alg >= IPSEC_CRYPTO_N_ALG)
14284             {
14285               errmsg ("unsupported crypto-alg: '%U'\n",
14286                       format_ipsec_crypto_alg, crypto_alg);
14287               return -99;
14288             }
14289         }
14290       else
14291         if (unformat
14292             (i, "integ_alg %U", unformat_ipsec_api_integ_alg, &integ_alg))
14293         {
14294           if (integ_alg >= IPSEC_INTEG_N_ALG)
14295             {
14296               errmsg ("unsupported integ-alg: '%U'\n",
14297                       format_ipsec_integ_alg, integ_alg);
14298               return -99;
14299             }
14300         }
14301       else if (unformat (i, "instance %u", &instance))
14302         renumber = 1;
14303       else
14304         {
14305           errmsg ("parse error '%U'\n", format_unformat_error, i);
14306           return -99;
14307         }
14308     }
14309
14310   if (count > 1)
14311     {
14312       /* Turn on async mode */
14313       vam->async_mode = 1;
14314       vam->async_errors = 0;
14315       before = vat_time_now (vam);
14316     }
14317
14318   for (jj = 0; jj < count; jj++)
14319     {
14320       M (IPSEC_TUNNEL_IF_ADD_DEL, mp);
14321
14322       mp->is_add = is_add;
14323       mp->esn = esn;
14324       mp->anti_replay = anti_replay;
14325
14326       if (jj > 0)
14327         increment_address (&remote_ip);
14328
14329       clib_memcpy (&mp->local_ip, &local_ip, sizeof (local_ip));
14330       clib_memcpy (&mp->remote_ip, &remote_ip, sizeof (remote_ip));
14331
14332       mp->local_spi = htonl (local_spi + jj);
14333       mp->remote_spi = htonl (remote_spi + jj);
14334       mp->crypto_alg = (u8) crypto_alg;
14335
14336       mp->local_crypto_key_len = 0;
14337       if (lck)
14338         {
14339           mp->local_crypto_key_len = vec_len (lck);
14340           if (mp->local_crypto_key_len > sizeof (mp->local_crypto_key))
14341             mp->local_crypto_key_len = sizeof (mp->local_crypto_key);
14342           clib_memcpy (mp->local_crypto_key, lck, mp->local_crypto_key_len);
14343         }
14344
14345       mp->remote_crypto_key_len = 0;
14346       if (rck)
14347         {
14348           mp->remote_crypto_key_len = vec_len (rck);
14349           if (mp->remote_crypto_key_len > sizeof (mp->remote_crypto_key))
14350             mp->remote_crypto_key_len = sizeof (mp->remote_crypto_key);
14351           clib_memcpy (mp->remote_crypto_key, rck, mp->remote_crypto_key_len);
14352         }
14353
14354       mp->integ_alg = (u8) integ_alg;
14355
14356       mp->local_integ_key_len = 0;
14357       if (lik)
14358         {
14359           mp->local_integ_key_len = vec_len (lik);
14360           if (mp->local_integ_key_len > sizeof (mp->local_integ_key))
14361             mp->local_integ_key_len = sizeof (mp->local_integ_key);
14362           clib_memcpy (mp->local_integ_key, lik, mp->local_integ_key_len);
14363         }
14364
14365       mp->remote_integ_key_len = 0;
14366       if (rik)
14367         {
14368           mp->remote_integ_key_len = vec_len (rik);
14369           if (mp->remote_integ_key_len > sizeof (mp->remote_integ_key))
14370             mp->remote_integ_key_len = sizeof (mp->remote_integ_key);
14371           clib_memcpy (mp->remote_integ_key, rik, mp->remote_integ_key_len);
14372         }
14373
14374       if (renumber)
14375         {
14376           mp->renumber = renumber;
14377           mp->show_instance = ntohl (instance);
14378         }
14379       S (mp);
14380     }
14381
14382   /* When testing multiple add/del ops, use a control-ping to sync */
14383   if (count > 1)
14384     {
14385       vl_api_control_ping_t *mp_ping;
14386       f64 after;
14387       f64 timeout;
14388
14389       /* Shut off async mode */
14390       vam->async_mode = 0;
14391
14392       MPING (CONTROL_PING, mp_ping);
14393       S (mp_ping);
14394
14395       timeout = vat_time_now (vam) + 1.0;
14396       while (vat_time_now (vam) < timeout)
14397         if (vam->result_ready == 1)
14398           goto out;
14399       vam->retval = -99;
14400
14401     out:
14402       if (vam->retval == -99)
14403         errmsg ("timeout");
14404
14405       if (vam->async_errors > 0)
14406         {
14407           errmsg ("%d asynchronous errors", vam->async_errors);
14408           vam->retval = -98;
14409         }
14410       vam->async_errors = 0;
14411       after = vat_time_now (vam);
14412
14413       /* slim chance, but we might have eaten SIGTERM on the first iteration */
14414       if (jj > 0)
14415         count = jj;
14416
14417       print (vam->ofp, "%d tunnels in %.6f secs, %.2f tunnels/sec",
14418              count, after - before, count / (after - before));
14419     }
14420   else
14421     {
14422       /* Wait for a reply... */
14423       W (ret);
14424       return ret;
14425     }
14426
14427   return ret;
14428 }
14429
14430 static void
14431 vl_api_ipsec_sa_details_t_handler (vl_api_ipsec_sa_details_t * mp)
14432 {
14433   vat_main_t *vam = &vat_main;
14434
14435   print (vam->ofp, "sa_id %u sw_if_index %u spi %u proto %u crypto_alg %u "
14436          "crypto_key %U integ_alg %u integ_key %U flags %x "
14437          "tunnel_src_addr %U tunnel_dst_addr %U "
14438          "salt %u seq_outbound %lu last_seq_inbound %lu "
14439          "replay_window %lu\n",
14440          ntohl (mp->entry.sad_id),
14441          ntohl (mp->sw_if_index),
14442          ntohl (mp->entry.spi),
14443          ntohl (mp->entry.protocol),
14444          ntohl (mp->entry.crypto_algorithm),
14445          format_hex_bytes, mp->entry.crypto_key.data,
14446          mp->entry.crypto_key.length, ntohl (mp->entry.integrity_algorithm),
14447          format_hex_bytes, mp->entry.integrity_key.data,
14448          mp->entry.integrity_key.length, ntohl (mp->entry.flags),
14449          format_vl_api_address, &mp->entry.tunnel_src, format_vl_api_address,
14450          &mp->entry.tunnel_dst, ntohl (mp->salt),
14451          clib_net_to_host_u64 (mp->seq_outbound),
14452          clib_net_to_host_u64 (mp->last_seq_inbound),
14453          clib_net_to_host_u64 (mp->replay_window));
14454 }
14455
14456 #define vl_api_ipsec_sa_details_t_endian vl_noop_handler
14457 #define vl_api_ipsec_sa_details_t_print vl_noop_handler
14458
14459 static void vl_api_ipsec_sa_details_t_handler_json
14460   (vl_api_ipsec_sa_details_t * mp)
14461 {
14462   vat_main_t *vam = &vat_main;
14463   vat_json_node_t *node = NULL;
14464   vl_api_ipsec_sad_flags_t flags;
14465
14466   if (VAT_JSON_ARRAY != vam->json_tree.type)
14467     {
14468       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14469       vat_json_init_array (&vam->json_tree);
14470     }
14471   node = vat_json_array_add (&vam->json_tree);
14472
14473   vat_json_init_object (node);
14474   vat_json_object_add_uint (node, "sa_id", ntohl (mp->entry.sad_id));
14475   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
14476   vat_json_object_add_uint (node, "spi", ntohl (mp->entry.spi));
14477   vat_json_object_add_uint (node, "proto", ntohl (mp->entry.protocol));
14478   vat_json_object_add_uint (node, "crypto_alg",
14479                             ntohl (mp->entry.crypto_algorithm));
14480   vat_json_object_add_uint (node, "integ_alg",
14481                             ntohl (mp->entry.integrity_algorithm));
14482   flags = ntohl (mp->entry.flags);
14483   vat_json_object_add_uint (node, "use_esn",
14484                             ! !(flags & IPSEC_API_SAD_FLAG_USE_ESN));
14485   vat_json_object_add_uint (node, "use_anti_replay",
14486                             ! !(flags & IPSEC_API_SAD_FLAG_USE_ANTI_REPLAY));
14487   vat_json_object_add_uint (node, "is_tunnel",
14488                             ! !(flags & IPSEC_API_SAD_FLAG_IS_TUNNEL));
14489   vat_json_object_add_uint (node, "is_tunnel_ip6",
14490                             ! !(flags & IPSEC_API_SAD_FLAG_IS_TUNNEL_V6));
14491   vat_json_object_add_uint (node, "udp_encap",
14492                             ! !(flags & IPSEC_API_SAD_FLAG_UDP_ENCAP));
14493   vat_json_object_add_bytes (node, "crypto_key", mp->entry.crypto_key.data,
14494                              mp->entry.crypto_key.length);
14495   vat_json_object_add_bytes (node, "integ_key", mp->entry.integrity_key.data,
14496                              mp->entry.integrity_key.length);
14497   vat_json_object_add_address (node, "src", &mp->entry.tunnel_src);
14498   vat_json_object_add_address (node, "dst", &mp->entry.tunnel_dst);
14499   vat_json_object_add_uint (node, "replay_window",
14500                             clib_net_to_host_u64 (mp->replay_window));
14501 }
14502
14503 static int
14504 api_ipsec_sa_dump (vat_main_t * vam)
14505 {
14506   unformat_input_t *i = vam->input;
14507   vl_api_ipsec_sa_dump_t *mp;
14508   vl_api_control_ping_t *mp_ping;
14509   u32 sa_id = ~0;
14510   int ret;
14511
14512   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14513     {
14514       if (unformat (i, "sa_id %d", &sa_id))
14515         ;
14516       else
14517         {
14518           clib_warning ("parse error '%U'", format_unformat_error, i);
14519           return -99;
14520         }
14521     }
14522
14523   M (IPSEC_SA_DUMP, mp);
14524
14525   mp->sa_id = ntohl (sa_id);
14526
14527   S (mp);
14528
14529   /* Use a control ping for synchronization */
14530   M (CONTROL_PING, mp_ping);
14531   S (mp_ping);
14532
14533   W (ret);
14534   return ret;
14535 }
14536
14537 static int
14538 api_ipsec_tunnel_if_set_sa (vat_main_t * vam)
14539 {
14540   unformat_input_t *i = vam->input;
14541   vl_api_ipsec_tunnel_if_set_sa_t *mp;
14542   u32 sw_if_index = ~0;
14543   u32 sa_id = ~0;
14544   u8 is_outbound = (u8) ~ 0;
14545   int ret;
14546
14547   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14548     {
14549       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14550         ;
14551       else if (unformat (i, "sa_id %d", &sa_id))
14552         ;
14553       else if (unformat (i, "outbound"))
14554         is_outbound = 1;
14555       else if (unformat (i, "inbound"))
14556         is_outbound = 0;
14557       else
14558         {
14559           clib_warning ("parse error '%U'", format_unformat_error, i);
14560           return -99;
14561         }
14562     }
14563
14564   if (sw_if_index == ~0)
14565     {
14566       errmsg ("interface must be specified");
14567       return -99;
14568     }
14569
14570   if (sa_id == ~0)
14571     {
14572       errmsg ("SA ID must be specified");
14573       return -99;
14574     }
14575
14576   M (IPSEC_TUNNEL_IF_SET_SA, mp);
14577
14578   mp->sw_if_index = htonl (sw_if_index);
14579   mp->sa_id = htonl (sa_id);
14580   mp->is_outbound = is_outbound;
14581
14582   S (mp);
14583   W (ret);
14584
14585   return ret;
14586 }
14587
14588 static int
14589 api_get_first_msg_id (vat_main_t * vam)
14590 {
14591   vl_api_get_first_msg_id_t *mp;
14592   unformat_input_t *i = vam->input;
14593   u8 *name;
14594   u8 name_set = 0;
14595   int ret;
14596
14597   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14598     {
14599       if (unformat (i, "client %s", &name))
14600         name_set = 1;
14601       else
14602         break;
14603     }
14604
14605   if (name_set == 0)
14606     {
14607       errmsg ("missing client name");
14608       return -99;
14609     }
14610   vec_add1 (name, 0);
14611
14612   if (vec_len (name) > 63)
14613     {
14614       errmsg ("client name too long");
14615       return -99;
14616     }
14617
14618   M (GET_FIRST_MSG_ID, mp);
14619   clib_memcpy (mp->name, name, vec_len (name));
14620   S (mp);
14621   W (ret);
14622   return ret;
14623 }
14624
14625 static int
14626 api_cop_interface_enable_disable (vat_main_t * vam)
14627 {
14628   unformat_input_t *line_input = vam->input;
14629   vl_api_cop_interface_enable_disable_t *mp;
14630   u32 sw_if_index = ~0;
14631   u8 enable_disable = 1;
14632   int ret;
14633
14634   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14635     {
14636       if (unformat (line_input, "disable"))
14637         enable_disable = 0;
14638       if (unformat (line_input, "enable"))
14639         enable_disable = 1;
14640       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
14641                          vam, &sw_if_index))
14642         ;
14643       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
14644         ;
14645       else
14646         break;
14647     }
14648
14649   if (sw_if_index == ~0)
14650     {
14651       errmsg ("missing interface name or sw_if_index");
14652       return -99;
14653     }
14654
14655   /* Construct the API message */
14656   M (COP_INTERFACE_ENABLE_DISABLE, mp);
14657   mp->sw_if_index = ntohl (sw_if_index);
14658   mp->enable_disable = enable_disable;
14659
14660   /* send it... */
14661   S (mp);
14662   /* Wait for the reply */
14663   W (ret);
14664   return ret;
14665 }
14666
14667 static int
14668 api_cop_whitelist_enable_disable (vat_main_t * vam)
14669 {
14670   unformat_input_t *line_input = vam->input;
14671   vl_api_cop_whitelist_enable_disable_t *mp;
14672   u32 sw_if_index = ~0;
14673   u8 ip4 = 0, ip6 = 0, default_cop = 0;
14674   u32 fib_id = 0;
14675   int ret;
14676
14677   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14678     {
14679       if (unformat (line_input, "ip4"))
14680         ip4 = 1;
14681       else if (unformat (line_input, "ip6"))
14682         ip6 = 1;
14683       else if (unformat (line_input, "default"))
14684         default_cop = 1;
14685       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
14686                          vam, &sw_if_index))
14687         ;
14688       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
14689         ;
14690       else if (unformat (line_input, "fib-id %d", &fib_id))
14691         ;
14692       else
14693         break;
14694     }
14695
14696   if (sw_if_index == ~0)
14697     {
14698       errmsg ("missing interface name or sw_if_index");
14699       return -99;
14700     }
14701
14702   /* Construct the API message */
14703   M (COP_WHITELIST_ENABLE_DISABLE, mp);
14704   mp->sw_if_index = ntohl (sw_if_index);
14705   mp->fib_id = ntohl (fib_id);
14706   mp->ip4 = ip4;
14707   mp->ip6 = ip6;
14708   mp->default_cop = default_cop;
14709
14710   /* send it... */
14711   S (mp);
14712   /* Wait for the reply */
14713   W (ret);
14714   return ret;
14715 }
14716
14717 static int
14718 api_get_node_graph (vat_main_t * vam)
14719 {
14720   vl_api_get_node_graph_t *mp;
14721   int ret;
14722
14723   M (GET_NODE_GRAPH, mp);
14724
14725   /* send it... */
14726   S (mp);
14727   /* Wait for the reply */
14728   W (ret);
14729   return ret;
14730 }
14731
14732 /* *INDENT-OFF* */
14733 /** Used for parsing LISP eids */
14734 typedef CLIB_PACKED(struct{
14735   u8 addr[16];   /**< eid address */
14736   u32 len;       /**< prefix length if IP */
14737   u8 type;      /**< type of eid */
14738 }) lisp_eid_vat_t;
14739 /* *INDENT-ON* */
14740
14741 static uword
14742 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
14743 {
14744   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
14745
14746   clib_memset (a, 0, sizeof (a[0]));
14747
14748   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
14749     {
14750       a->type = 0;              /* ipv4 type */
14751     }
14752   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
14753     {
14754       a->type = 1;              /* ipv6 type */
14755     }
14756   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
14757     {
14758       a->type = 2;              /* mac type */
14759     }
14760   else if (unformat (input, "%U", unformat_nsh_address, a->addr))
14761     {
14762       a->type = 3;              /* NSH type */
14763       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) a->addr;
14764       nsh->spi = clib_host_to_net_u32 (nsh->spi);
14765     }
14766   else
14767     {
14768       return 0;
14769     }
14770
14771   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
14772     {
14773       return 0;
14774     }
14775
14776   return 1;
14777 }
14778
14779 static int
14780 lisp_eid_size_vat (u8 type)
14781 {
14782   switch (type)
14783     {
14784     case 0:
14785       return 4;
14786     case 1:
14787       return 16;
14788     case 2:
14789       return 6;
14790     case 3:
14791       return 5;
14792     }
14793   return 0;
14794 }
14795
14796 static void
14797 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
14798 {
14799   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
14800 }
14801
14802 static int
14803 api_one_add_del_locator_set (vat_main_t * vam)
14804 {
14805   unformat_input_t *input = vam->input;
14806   vl_api_one_add_del_locator_set_t *mp;
14807   u8 is_add = 1;
14808   u8 *locator_set_name = NULL;
14809   u8 locator_set_name_set = 0;
14810   vl_api_local_locator_t locator, *locators = 0;
14811   u32 sw_if_index, priority, weight;
14812   u32 data_len = 0;
14813
14814   int ret;
14815   /* Parse args required to build the message */
14816   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14817     {
14818       if (unformat (input, "del"))
14819         {
14820           is_add = 0;
14821         }
14822       else if (unformat (input, "locator-set %s", &locator_set_name))
14823         {
14824           locator_set_name_set = 1;
14825         }
14826       else if (unformat (input, "sw_if_index %u p %u w %u",
14827                          &sw_if_index, &priority, &weight))
14828         {
14829           locator.sw_if_index = htonl (sw_if_index);
14830           locator.priority = priority;
14831           locator.weight = weight;
14832           vec_add1 (locators, locator);
14833         }
14834       else
14835         if (unformat
14836             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
14837              &sw_if_index, &priority, &weight))
14838         {
14839           locator.sw_if_index = htonl (sw_if_index);
14840           locator.priority = priority;
14841           locator.weight = weight;
14842           vec_add1 (locators, locator);
14843         }
14844       else
14845         break;
14846     }
14847
14848   if (locator_set_name_set == 0)
14849     {
14850       errmsg ("missing locator-set name");
14851       vec_free (locators);
14852       return -99;
14853     }
14854
14855   if (vec_len (locator_set_name) > 64)
14856     {
14857       errmsg ("locator-set name too long");
14858       vec_free (locator_set_name);
14859       vec_free (locators);
14860       return -99;
14861     }
14862   vec_add1 (locator_set_name, 0);
14863
14864   data_len = sizeof (vl_api_local_locator_t) * vec_len (locators);
14865
14866   /* Construct the API message */
14867   M2 (ONE_ADD_DEL_LOCATOR_SET, mp, data_len);
14868
14869   mp->is_add = is_add;
14870   clib_memcpy (mp->locator_set_name, locator_set_name,
14871                vec_len (locator_set_name));
14872   vec_free (locator_set_name);
14873
14874   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
14875   if (locators)
14876     clib_memcpy (mp->locators, locators, data_len);
14877   vec_free (locators);
14878
14879   /* send it... */
14880   S (mp);
14881
14882   /* Wait for a reply... */
14883   W (ret);
14884   return ret;
14885 }
14886
14887 #define api_lisp_add_del_locator_set api_one_add_del_locator_set
14888
14889 static int
14890 api_one_add_del_locator (vat_main_t * vam)
14891 {
14892   unformat_input_t *input = vam->input;
14893   vl_api_one_add_del_locator_t *mp;
14894   u32 tmp_if_index = ~0;
14895   u32 sw_if_index = ~0;
14896   u8 sw_if_index_set = 0;
14897   u8 sw_if_index_if_name_set = 0;
14898   u32 priority = ~0;
14899   u8 priority_set = 0;
14900   u32 weight = ~0;
14901   u8 weight_set = 0;
14902   u8 is_add = 1;
14903   u8 *locator_set_name = NULL;
14904   u8 locator_set_name_set = 0;
14905   int ret;
14906
14907   /* Parse args required to build the message */
14908   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14909     {
14910       if (unformat (input, "del"))
14911         {
14912           is_add = 0;
14913         }
14914       else if (unformat (input, "locator-set %s", &locator_set_name))
14915         {
14916           locator_set_name_set = 1;
14917         }
14918       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
14919                          &tmp_if_index))
14920         {
14921           sw_if_index_if_name_set = 1;
14922           sw_if_index = tmp_if_index;
14923         }
14924       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
14925         {
14926           sw_if_index_set = 1;
14927           sw_if_index = tmp_if_index;
14928         }
14929       else if (unformat (input, "p %d", &priority))
14930         {
14931           priority_set = 1;
14932         }
14933       else if (unformat (input, "w %d", &weight))
14934         {
14935           weight_set = 1;
14936         }
14937       else
14938         break;
14939     }
14940
14941   if (locator_set_name_set == 0)
14942     {
14943       errmsg ("missing locator-set name");
14944       return -99;
14945     }
14946
14947   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
14948     {
14949       errmsg ("missing sw_if_index");
14950       vec_free (locator_set_name);
14951       return -99;
14952     }
14953
14954   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
14955     {
14956       errmsg ("cannot use both params interface name and sw_if_index");
14957       vec_free (locator_set_name);
14958       return -99;
14959     }
14960
14961   if (priority_set == 0)
14962     {
14963       errmsg ("missing locator-set priority");
14964       vec_free (locator_set_name);
14965       return -99;
14966     }
14967
14968   if (weight_set == 0)
14969     {
14970       errmsg ("missing locator-set weight");
14971       vec_free (locator_set_name);
14972       return -99;
14973     }
14974
14975   if (vec_len (locator_set_name) > 64)
14976     {
14977       errmsg ("locator-set name too long");
14978       vec_free (locator_set_name);
14979       return -99;
14980     }
14981   vec_add1 (locator_set_name, 0);
14982
14983   /* Construct the API message */
14984   M (ONE_ADD_DEL_LOCATOR, mp);
14985
14986   mp->is_add = is_add;
14987   mp->sw_if_index = ntohl (sw_if_index);
14988   mp->priority = priority;
14989   mp->weight = weight;
14990   clib_memcpy (mp->locator_set_name, locator_set_name,
14991                vec_len (locator_set_name));
14992   vec_free (locator_set_name);
14993
14994   /* send it... */
14995   S (mp);
14996
14997   /* Wait for a reply... */
14998   W (ret);
14999   return ret;
15000 }
15001
15002 #define api_lisp_add_del_locator api_one_add_del_locator
15003
15004 uword
15005 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
15006 {
15007   u32 *key_id = va_arg (*args, u32 *);
15008   u8 *s = 0;
15009
15010   if (unformat (input, "%s", &s))
15011     {
15012       if (!strcmp ((char *) s, "sha1"))
15013         key_id[0] = HMAC_SHA_1_96;
15014       else if (!strcmp ((char *) s, "sha256"))
15015         key_id[0] = HMAC_SHA_256_128;
15016       else
15017         {
15018           clib_warning ("invalid key_id: '%s'", s);
15019           key_id[0] = HMAC_NO_KEY;
15020         }
15021     }
15022   else
15023     return 0;
15024
15025   vec_free (s);
15026   return 1;
15027 }
15028
15029 static int
15030 api_one_add_del_local_eid (vat_main_t * vam)
15031 {
15032   unformat_input_t *input = vam->input;
15033   vl_api_one_add_del_local_eid_t *mp;
15034   u8 is_add = 1;
15035   u8 eid_set = 0;
15036   lisp_eid_vat_t _eid, *eid = &_eid;
15037   u8 *locator_set_name = 0;
15038   u8 locator_set_name_set = 0;
15039   u32 vni = 0;
15040   u16 key_id = 0;
15041   u8 *key = 0;
15042   int ret;
15043
15044   /* Parse args required to build the message */
15045   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15046     {
15047       if (unformat (input, "del"))
15048         {
15049           is_add = 0;
15050         }
15051       else if (unformat (input, "vni %d", &vni))
15052         {
15053           ;
15054         }
15055       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
15056         {
15057           eid_set = 1;
15058         }
15059       else if (unformat (input, "locator-set %s", &locator_set_name))
15060         {
15061           locator_set_name_set = 1;
15062         }
15063       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
15064         ;
15065       else if (unformat (input, "secret-key %_%v%_", &key))
15066         ;
15067       else
15068         break;
15069     }
15070
15071   if (locator_set_name_set == 0)
15072     {
15073       errmsg ("missing locator-set name");
15074       return -99;
15075     }
15076
15077   if (0 == eid_set)
15078     {
15079       errmsg ("EID address not set!");
15080       vec_free (locator_set_name);
15081       return -99;
15082     }
15083
15084   if (key && (0 == key_id))
15085     {
15086       errmsg ("invalid key_id!");
15087       return -99;
15088     }
15089
15090   if (vec_len (key) > 64)
15091     {
15092       errmsg ("key too long");
15093       vec_free (key);
15094       return -99;
15095     }
15096
15097   if (vec_len (locator_set_name) > 64)
15098     {
15099       errmsg ("locator-set name too long");
15100       vec_free (locator_set_name);
15101       return -99;
15102     }
15103   vec_add1 (locator_set_name, 0);
15104
15105   /* Construct the API message */
15106   M (ONE_ADD_DEL_LOCAL_EID, mp);
15107
15108   mp->is_add = is_add;
15109   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
15110   mp->eid_type = eid->type;
15111   mp->prefix_len = eid->len;
15112   mp->vni = clib_host_to_net_u32 (vni);
15113   mp->key_id = clib_host_to_net_u16 (key_id);
15114   clib_memcpy (mp->locator_set_name, locator_set_name,
15115                vec_len (locator_set_name));
15116   clib_memcpy (mp->key, key, vec_len (key));
15117
15118   vec_free (locator_set_name);
15119   vec_free (key);
15120
15121   /* send it... */
15122   S (mp);
15123
15124   /* Wait for a reply... */
15125   W (ret);
15126   return ret;
15127 }
15128
15129 #define api_lisp_add_del_local_eid api_one_add_del_local_eid
15130
15131 static int
15132 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
15133 {
15134   u32 dp_table = 0, vni = 0;;
15135   unformat_input_t *input = vam->input;
15136   vl_api_gpe_add_del_fwd_entry_t *mp;
15137   u8 is_add = 1;
15138   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
15139   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
15140   u8 rmt_eid_set = 0, lcl_eid_set = 0;
15141   u32 action = ~0, w;
15142   ip4_address_t rmt_rloc4, lcl_rloc4;
15143   ip6_address_t rmt_rloc6, lcl_rloc6;
15144   vl_api_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
15145   int ret;
15146
15147   clib_memset (&rloc, 0, sizeof (rloc));
15148
15149   /* Parse args required to build the message */
15150   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15151     {
15152       if (unformat (input, "del"))
15153         is_add = 0;
15154       else if (unformat (input, "add"))
15155         is_add = 1;
15156       else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
15157         {
15158           rmt_eid_set = 1;
15159         }
15160       else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
15161         {
15162           lcl_eid_set = 1;
15163         }
15164       else if (unformat (input, "vrf %d", &dp_table))
15165         ;
15166       else if (unformat (input, "bd %d", &dp_table))
15167         ;
15168       else if (unformat (input, "vni %d", &vni))
15169         ;
15170       else if (unformat (input, "w %d", &w))
15171         {
15172           if (!curr_rloc)
15173             {
15174               errmsg ("No RLOC configured for setting priority/weight!");
15175               return -99;
15176             }
15177           curr_rloc->weight = w;
15178         }
15179       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
15180                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
15181         {
15182           rloc.is_ip4 = 1;
15183
15184           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
15185           rloc.weight = 0;
15186           vec_add1 (lcl_locs, rloc);
15187
15188           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
15189           vec_add1 (rmt_locs, rloc);
15190           /* weight saved in rmt loc */
15191           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
15192         }
15193       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
15194                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
15195         {
15196           rloc.is_ip4 = 0;
15197           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
15198           rloc.weight = 0;
15199           vec_add1 (lcl_locs, rloc);
15200
15201           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
15202           vec_add1 (rmt_locs, rloc);
15203           /* weight saved in rmt loc */
15204           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
15205         }
15206       else if (unformat (input, "action %d", &action))
15207         {
15208           ;
15209         }
15210       else
15211         {
15212           clib_warning ("parse error '%U'", format_unformat_error, input);
15213           return -99;
15214         }
15215     }
15216
15217   if (!rmt_eid_set)
15218     {
15219       errmsg ("remote eid addresses not set");
15220       return -99;
15221     }
15222
15223   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
15224     {
15225       errmsg ("eid types don't match");
15226       return -99;
15227     }
15228
15229   if (0 == rmt_locs && (u32) ~ 0 == action)
15230     {
15231       errmsg ("action not set for negative mapping");
15232       return -99;
15233     }
15234
15235   /* Construct the API message */
15236   M2 (GPE_ADD_DEL_FWD_ENTRY, mp,
15237       sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs) * 2);
15238
15239   mp->is_add = is_add;
15240   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
15241   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
15242   mp->eid_type = rmt_eid->type;
15243   mp->dp_table = clib_host_to_net_u32 (dp_table);
15244   mp->vni = clib_host_to_net_u32 (vni);
15245   mp->rmt_len = rmt_eid->len;
15246   mp->lcl_len = lcl_eid->len;
15247   mp->action = action;
15248
15249   if (0 != rmt_locs && 0 != lcl_locs)
15250     {
15251       mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
15252       clib_memcpy (mp->locs, lcl_locs,
15253                    (sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs)));
15254
15255       u32 offset = sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs);
15256       clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
15257                    (sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs)));
15258     }
15259   vec_free (lcl_locs);
15260   vec_free (rmt_locs);
15261
15262   /* send it... */
15263   S (mp);
15264
15265   /* Wait for a reply... */
15266   W (ret);
15267   return ret;
15268 }
15269
15270 static int
15271 api_one_add_del_map_server (vat_main_t * vam)
15272 {
15273   unformat_input_t *input = vam->input;
15274   vl_api_one_add_del_map_server_t *mp;
15275   u8 is_add = 1;
15276   u8 ipv4_set = 0;
15277   u8 ipv6_set = 0;
15278   ip4_address_t ipv4;
15279   ip6_address_t ipv6;
15280   int ret;
15281
15282   /* Parse args required to build the message */
15283   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15284     {
15285       if (unformat (input, "del"))
15286         {
15287           is_add = 0;
15288         }
15289       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
15290         {
15291           ipv4_set = 1;
15292         }
15293       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
15294         {
15295           ipv6_set = 1;
15296         }
15297       else
15298         break;
15299     }
15300
15301   if (ipv4_set && ipv6_set)
15302     {
15303       errmsg ("both eid v4 and v6 addresses set");
15304       return -99;
15305     }
15306
15307   if (!ipv4_set && !ipv6_set)
15308     {
15309       errmsg ("eid addresses not set");
15310       return -99;
15311     }
15312
15313   /* Construct the API message */
15314   M (ONE_ADD_DEL_MAP_SERVER, mp);
15315
15316   mp->is_add = is_add;
15317   if (ipv6_set)
15318     {
15319       mp->is_ipv6 = 1;
15320       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
15321     }
15322   else
15323     {
15324       mp->is_ipv6 = 0;
15325       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
15326     }
15327
15328   /* send it... */
15329   S (mp);
15330
15331   /* Wait for a reply... */
15332   W (ret);
15333   return ret;
15334 }
15335
15336 #define api_lisp_add_del_map_server api_one_add_del_map_server
15337
15338 static int
15339 api_one_add_del_map_resolver (vat_main_t * vam)
15340 {
15341   unformat_input_t *input = vam->input;
15342   vl_api_one_add_del_map_resolver_t *mp;
15343   u8 is_add = 1;
15344   u8 ipv4_set = 0;
15345   u8 ipv6_set = 0;
15346   ip4_address_t ipv4;
15347   ip6_address_t ipv6;
15348   int ret;
15349
15350   /* Parse args required to build the message */
15351   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15352     {
15353       if (unformat (input, "del"))
15354         {
15355           is_add = 0;
15356         }
15357       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
15358         {
15359           ipv4_set = 1;
15360         }
15361       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
15362         {
15363           ipv6_set = 1;
15364         }
15365       else
15366         break;
15367     }
15368
15369   if (ipv4_set && ipv6_set)
15370     {
15371       errmsg ("both eid v4 and v6 addresses set");
15372       return -99;
15373     }
15374
15375   if (!ipv4_set && !ipv6_set)
15376     {
15377       errmsg ("eid addresses not set");
15378       return -99;
15379     }
15380
15381   /* Construct the API message */
15382   M (ONE_ADD_DEL_MAP_RESOLVER, mp);
15383
15384   mp->is_add = is_add;
15385   if (ipv6_set)
15386     {
15387       mp->is_ipv6 = 1;
15388       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
15389     }
15390   else
15391     {
15392       mp->is_ipv6 = 0;
15393       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
15394     }
15395
15396   /* send it... */
15397   S (mp);
15398
15399   /* Wait for a reply... */
15400   W (ret);
15401   return ret;
15402 }
15403
15404 #define api_lisp_add_del_map_resolver api_one_add_del_map_resolver
15405
15406 static int
15407 api_lisp_gpe_enable_disable (vat_main_t * vam)
15408 {
15409   unformat_input_t *input = vam->input;
15410   vl_api_gpe_enable_disable_t *mp;
15411   u8 is_set = 0;
15412   u8 is_en = 1;
15413   int ret;
15414
15415   /* Parse args required to build the message */
15416   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15417     {
15418       if (unformat (input, "enable"))
15419         {
15420           is_set = 1;
15421           is_en = 1;
15422         }
15423       else if (unformat (input, "disable"))
15424         {
15425           is_set = 1;
15426           is_en = 0;
15427         }
15428       else
15429         break;
15430     }
15431
15432   if (is_set == 0)
15433     {
15434       errmsg ("Value not set");
15435       return -99;
15436     }
15437
15438   /* Construct the API message */
15439   M (GPE_ENABLE_DISABLE, mp);
15440
15441   mp->is_en = is_en;
15442
15443   /* send it... */
15444   S (mp);
15445
15446   /* Wait for a reply... */
15447   W (ret);
15448   return ret;
15449 }
15450
15451 static int
15452 api_one_rloc_probe_enable_disable (vat_main_t * vam)
15453 {
15454   unformat_input_t *input = vam->input;
15455   vl_api_one_rloc_probe_enable_disable_t *mp;
15456   u8 is_set = 0;
15457   u8 is_en = 0;
15458   int ret;
15459
15460   /* Parse args required to build the message */
15461   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15462     {
15463       if (unformat (input, "enable"))
15464         {
15465           is_set = 1;
15466           is_en = 1;
15467         }
15468       else if (unformat (input, "disable"))
15469         is_set = 1;
15470       else
15471         break;
15472     }
15473
15474   if (!is_set)
15475     {
15476       errmsg ("Value not set");
15477       return -99;
15478     }
15479
15480   /* Construct the API message */
15481   M (ONE_RLOC_PROBE_ENABLE_DISABLE, mp);
15482
15483   mp->is_enabled = is_en;
15484
15485   /* send it... */
15486   S (mp);
15487
15488   /* Wait for a reply... */
15489   W (ret);
15490   return ret;
15491 }
15492
15493 #define api_lisp_rloc_probe_enable_disable api_one_rloc_probe_enable_disable
15494
15495 static int
15496 api_one_map_register_enable_disable (vat_main_t * vam)
15497 {
15498   unformat_input_t *input = vam->input;
15499   vl_api_one_map_register_enable_disable_t *mp;
15500   u8 is_set = 0;
15501   u8 is_en = 0;
15502   int ret;
15503
15504   /* Parse args required to build the message */
15505   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15506     {
15507       if (unformat (input, "enable"))
15508         {
15509           is_set = 1;
15510           is_en = 1;
15511         }
15512       else if (unformat (input, "disable"))
15513         is_set = 1;
15514       else
15515         break;
15516     }
15517
15518   if (!is_set)
15519     {
15520       errmsg ("Value not set");
15521       return -99;
15522     }
15523
15524   /* Construct the API message */
15525   M (ONE_MAP_REGISTER_ENABLE_DISABLE, mp);
15526
15527   mp->is_enabled = is_en;
15528
15529   /* send it... */
15530   S (mp);
15531
15532   /* Wait for a reply... */
15533   W (ret);
15534   return ret;
15535 }
15536
15537 #define api_lisp_map_register_enable_disable api_one_map_register_enable_disable
15538
15539 static int
15540 api_one_enable_disable (vat_main_t * vam)
15541 {
15542   unformat_input_t *input = vam->input;
15543   vl_api_one_enable_disable_t *mp;
15544   u8 is_set = 0;
15545   u8 is_en = 0;
15546   int ret;
15547
15548   /* Parse args required to build the message */
15549   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15550     {
15551       if (unformat (input, "enable"))
15552         {
15553           is_set = 1;
15554           is_en = 1;
15555         }
15556       else if (unformat (input, "disable"))
15557         {
15558           is_set = 1;
15559         }
15560       else
15561         break;
15562     }
15563
15564   if (!is_set)
15565     {
15566       errmsg ("Value not set");
15567       return -99;
15568     }
15569
15570   /* Construct the API message */
15571   M (ONE_ENABLE_DISABLE, mp);
15572
15573   mp->is_en = is_en;
15574
15575   /* send it... */
15576   S (mp);
15577
15578   /* Wait for a reply... */
15579   W (ret);
15580   return ret;
15581 }
15582
15583 #define api_lisp_enable_disable api_one_enable_disable
15584
15585 static int
15586 api_one_enable_disable_xtr_mode (vat_main_t * vam)
15587 {
15588   unformat_input_t *input = vam->input;
15589   vl_api_one_enable_disable_xtr_mode_t *mp;
15590   u8 is_set = 0;
15591   u8 is_en = 0;
15592   int ret;
15593
15594   /* Parse args required to build the message */
15595   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15596     {
15597       if (unformat (input, "enable"))
15598         {
15599           is_set = 1;
15600           is_en = 1;
15601         }
15602       else if (unformat (input, "disable"))
15603         {
15604           is_set = 1;
15605         }
15606       else
15607         break;
15608     }
15609
15610   if (!is_set)
15611     {
15612       errmsg ("Value not set");
15613       return -99;
15614     }
15615
15616   /* Construct the API message */
15617   M (ONE_ENABLE_DISABLE_XTR_MODE, mp);
15618
15619   mp->is_en = is_en;
15620
15621   /* send it... */
15622   S (mp);
15623
15624   /* Wait for a reply... */
15625   W (ret);
15626   return ret;
15627 }
15628
15629 static int
15630 api_one_show_xtr_mode (vat_main_t * vam)
15631 {
15632   vl_api_one_show_xtr_mode_t *mp;
15633   int ret;
15634
15635   /* Construct the API message */
15636   M (ONE_SHOW_XTR_MODE, mp);
15637
15638   /* send it... */
15639   S (mp);
15640
15641   /* Wait for a reply... */
15642   W (ret);
15643   return ret;
15644 }
15645
15646 static int
15647 api_one_enable_disable_pitr_mode (vat_main_t * vam)
15648 {
15649   unformat_input_t *input = vam->input;
15650   vl_api_one_enable_disable_pitr_mode_t *mp;
15651   u8 is_set = 0;
15652   u8 is_en = 0;
15653   int ret;
15654
15655   /* Parse args required to build the message */
15656   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15657     {
15658       if (unformat (input, "enable"))
15659         {
15660           is_set = 1;
15661           is_en = 1;
15662         }
15663       else if (unformat (input, "disable"))
15664         {
15665           is_set = 1;
15666         }
15667       else
15668         break;
15669     }
15670
15671   if (!is_set)
15672     {
15673       errmsg ("Value not set");
15674       return -99;
15675     }
15676
15677   /* Construct the API message */
15678   M (ONE_ENABLE_DISABLE_PITR_MODE, mp);
15679
15680   mp->is_en = is_en;
15681
15682   /* send it... */
15683   S (mp);
15684
15685   /* Wait for a reply... */
15686   W (ret);
15687   return ret;
15688 }
15689
15690 static int
15691 api_one_show_pitr_mode (vat_main_t * vam)
15692 {
15693   vl_api_one_show_pitr_mode_t *mp;
15694   int ret;
15695
15696   /* Construct the API message */
15697   M (ONE_SHOW_PITR_MODE, mp);
15698
15699   /* send it... */
15700   S (mp);
15701
15702   /* Wait for a reply... */
15703   W (ret);
15704   return ret;
15705 }
15706
15707 static int
15708 api_one_enable_disable_petr_mode (vat_main_t * vam)
15709 {
15710   unformat_input_t *input = vam->input;
15711   vl_api_one_enable_disable_petr_mode_t *mp;
15712   u8 is_set = 0;
15713   u8 is_en = 0;
15714   int ret;
15715
15716   /* Parse args required to build the message */
15717   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15718     {
15719       if (unformat (input, "enable"))
15720         {
15721           is_set = 1;
15722           is_en = 1;
15723         }
15724       else if (unformat (input, "disable"))
15725         {
15726           is_set = 1;
15727         }
15728       else
15729         break;
15730     }
15731
15732   if (!is_set)
15733     {
15734       errmsg ("Value not set");
15735       return -99;
15736     }
15737
15738   /* Construct the API message */
15739   M (ONE_ENABLE_DISABLE_PETR_MODE, mp);
15740
15741   mp->is_en = is_en;
15742
15743   /* send it... */
15744   S (mp);
15745
15746   /* Wait for a reply... */
15747   W (ret);
15748   return ret;
15749 }
15750
15751 static int
15752 api_one_show_petr_mode (vat_main_t * vam)
15753 {
15754   vl_api_one_show_petr_mode_t *mp;
15755   int ret;
15756
15757   /* Construct the API message */
15758   M (ONE_SHOW_PETR_MODE, mp);
15759
15760   /* send it... */
15761   S (mp);
15762
15763   /* Wait for a reply... */
15764   W (ret);
15765   return ret;
15766 }
15767
15768 static int
15769 api_show_one_map_register_state (vat_main_t * vam)
15770 {
15771   vl_api_show_one_map_register_state_t *mp;
15772   int ret;
15773
15774   M (SHOW_ONE_MAP_REGISTER_STATE, mp);
15775
15776   /* send */
15777   S (mp);
15778
15779   /* wait for reply */
15780   W (ret);
15781   return ret;
15782 }
15783
15784 #define api_show_lisp_map_register_state api_show_one_map_register_state
15785
15786 static int
15787 api_show_one_rloc_probe_state (vat_main_t * vam)
15788 {
15789   vl_api_show_one_rloc_probe_state_t *mp;
15790   int ret;
15791
15792   M (SHOW_ONE_RLOC_PROBE_STATE, mp);
15793
15794   /* send */
15795   S (mp);
15796
15797   /* wait for reply */
15798   W (ret);
15799   return ret;
15800 }
15801
15802 #define api_show_lisp_rloc_probe_state api_show_one_rloc_probe_state
15803
15804 static int
15805 api_one_add_del_ndp_entry (vat_main_t * vam)
15806 {
15807   vl_api_one_add_del_ndp_entry_t *mp;
15808   unformat_input_t *input = vam->input;
15809   u8 is_add = 1;
15810   u8 mac_set = 0;
15811   u8 bd_set = 0;
15812   u8 ip_set = 0;
15813   u8 mac[6] = { 0, };
15814   u8 ip6[16] = { 0, };
15815   u32 bd = ~0;
15816   int ret;
15817
15818   /* Parse args required to build the message */
15819   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15820     {
15821       if (unformat (input, "del"))
15822         is_add = 0;
15823       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
15824         mac_set = 1;
15825       else if (unformat (input, "ip %U", unformat_ip6_address, ip6))
15826         ip_set = 1;
15827       else if (unformat (input, "bd %d", &bd))
15828         bd_set = 1;
15829       else
15830         {
15831           errmsg ("parse error '%U'", format_unformat_error, input);
15832           return -99;
15833         }
15834     }
15835
15836   if (!bd_set || !ip_set || (!mac_set && is_add))
15837     {
15838       errmsg ("Missing BD, IP or MAC!");
15839       return -99;
15840     }
15841
15842   M (ONE_ADD_DEL_NDP_ENTRY, mp);
15843   mp->is_add = is_add;
15844   clib_memcpy (mp->mac, mac, 6);
15845   mp->bd = clib_host_to_net_u32 (bd);
15846   clib_memcpy (mp->ip6, ip6, sizeof (mp->ip6));
15847
15848   /* send */
15849   S (mp);
15850
15851   /* wait for reply */
15852   W (ret);
15853   return ret;
15854 }
15855
15856 static int
15857 api_one_add_del_l2_arp_entry (vat_main_t * vam)
15858 {
15859   vl_api_one_add_del_l2_arp_entry_t *mp;
15860   unformat_input_t *input = vam->input;
15861   u8 is_add = 1;
15862   u8 mac_set = 0;
15863   u8 bd_set = 0;
15864   u8 ip_set = 0;
15865   u8 mac[6] = { 0, };
15866   u32 ip4 = 0, bd = ~0;
15867   int ret;
15868
15869   /* Parse args required to build the message */
15870   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15871     {
15872       if (unformat (input, "del"))
15873         is_add = 0;
15874       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
15875         mac_set = 1;
15876       else if (unformat (input, "ip %U", unformat_ip4_address, &ip4))
15877         ip_set = 1;
15878       else if (unformat (input, "bd %d", &bd))
15879         bd_set = 1;
15880       else
15881         {
15882           errmsg ("parse error '%U'", format_unformat_error, input);
15883           return -99;
15884         }
15885     }
15886
15887   if (!bd_set || !ip_set || (!mac_set && is_add))
15888     {
15889       errmsg ("Missing BD, IP or MAC!");
15890       return -99;
15891     }
15892
15893   M (ONE_ADD_DEL_L2_ARP_ENTRY, mp);
15894   mp->is_add = is_add;
15895   clib_memcpy (mp->mac, mac, 6);
15896   mp->bd = clib_host_to_net_u32 (bd);
15897   mp->ip4 = ip4;
15898
15899   /* send */
15900   S (mp);
15901
15902   /* wait for reply */
15903   W (ret);
15904   return ret;
15905 }
15906
15907 static int
15908 api_one_ndp_bd_get (vat_main_t * vam)
15909 {
15910   vl_api_one_ndp_bd_get_t *mp;
15911   int ret;
15912
15913   M (ONE_NDP_BD_GET, mp);
15914
15915   /* send */
15916   S (mp);
15917
15918   /* wait for reply */
15919   W (ret);
15920   return ret;
15921 }
15922
15923 static int
15924 api_one_ndp_entries_get (vat_main_t * vam)
15925 {
15926   vl_api_one_ndp_entries_get_t *mp;
15927   unformat_input_t *input = vam->input;
15928   u8 bd_set = 0;
15929   u32 bd = ~0;
15930   int ret;
15931
15932   /* Parse args required to build the message */
15933   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15934     {
15935       if (unformat (input, "bd %d", &bd))
15936         bd_set = 1;
15937       else
15938         {
15939           errmsg ("parse error '%U'", format_unformat_error, input);
15940           return -99;
15941         }
15942     }
15943
15944   if (!bd_set)
15945     {
15946       errmsg ("Expected bridge domain!");
15947       return -99;
15948     }
15949
15950   M (ONE_NDP_ENTRIES_GET, mp);
15951   mp->bd = clib_host_to_net_u32 (bd);
15952
15953   /* send */
15954   S (mp);
15955
15956   /* wait for reply */
15957   W (ret);
15958   return ret;
15959 }
15960
15961 static int
15962 api_one_l2_arp_bd_get (vat_main_t * vam)
15963 {
15964   vl_api_one_l2_arp_bd_get_t *mp;
15965   int ret;
15966
15967   M (ONE_L2_ARP_BD_GET, mp);
15968
15969   /* send */
15970   S (mp);
15971
15972   /* wait for reply */
15973   W (ret);
15974   return ret;
15975 }
15976
15977 static int
15978 api_one_l2_arp_entries_get (vat_main_t * vam)
15979 {
15980   vl_api_one_l2_arp_entries_get_t *mp;
15981   unformat_input_t *input = vam->input;
15982   u8 bd_set = 0;
15983   u32 bd = ~0;
15984   int ret;
15985
15986   /* Parse args required to build the message */
15987   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15988     {
15989       if (unformat (input, "bd %d", &bd))
15990         bd_set = 1;
15991       else
15992         {
15993           errmsg ("parse error '%U'", format_unformat_error, input);
15994           return -99;
15995         }
15996     }
15997
15998   if (!bd_set)
15999     {
16000       errmsg ("Expected bridge domain!");
16001       return -99;
16002     }
16003
16004   M (ONE_L2_ARP_ENTRIES_GET, mp);
16005   mp->bd = clib_host_to_net_u32 (bd);
16006
16007   /* send */
16008   S (mp);
16009
16010   /* wait for reply */
16011   W (ret);
16012   return ret;
16013 }
16014
16015 static int
16016 api_one_stats_enable_disable (vat_main_t * vam)
16017 {
16018   vl_api_one_stats_enable_disable_t *mp;
16019   unformat_input_t *input = vam->input;
16020   u8 is_set = 0;
16021   u8 is_en = 0;
16022   int ret;
16023
16024   /* Parse args required to build the message */
16025   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16026     {
16027       if (unformat (input, "enable"))
16028         {
16029           is_set = 1;
16030           is_en = 1;
16031         }
16032       else if (unformat (input, "disable"))
16033         {
16034           is_set = 1;
16035         }
16036       else
16037         break;
16038     }
16039
16040   if (!is_set)
16041     {
16042       errmsg ("Value not set");
16043       return -99;
16044     }
16045
16046   M (ONE_STATS_ENABLE_DISABLE, mp);
16047   mp->is_en = is_en;
16048
16049   /* send */
16050   S (mp);
16051
16052   /* wait for reply */
16053   W (ret);
16054   return ret;
16055 }
16056
16057 static int
16058 api_show_one_stats_enable_disable (vat_main_t * vam)
16059 {
16060   vl_api_show_one_stats_enable_disable_t *mp;
16061   int ret;
16062
16063   M (SHOW_ONE_STATS_ENABLE_DISABLE, mp);
16064
16065   /* send */
16066   S (mp);
16067
16068   /* wait for reply */
16069   W (ret);
16070   return ret;
16071 }
16072
16073 static int
16074 api_show_one_map_request_mode (vat_main_t * vam)
16075 {
16076   vl_api_show_one_map_request_mode_t *mp;
16077   int ret;
16078
16079   M (SHOW_ONE_MAP_REQUEST_MODE, mp);
16080
16081   /* send */
16082   S (mp);
16083
16084   /* wait for reply */
16085   W (ret);
16086   return ret;
16087 }
16088
16089 #define api_show_lisp_map_request_mode api_show_one_map_request_mode
16090
16091 static int
16092 api_one_map_request_mode (vat_main_t * vam)
16093 {
16094   unformat_input_t *input = vam->input;
16095   vl_api_one_map_request_mode_t *mp;
16096   u8 mode = 0;
16097   int ret;
16098
16099   /* Parse args required to build the message */
16100   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16101     {
16102       if (unformat (input, "dst-only"))
16103         mode = 0;
16104       else if (unformat (input, "src-dst"))
16105         mode = 1;
16106       else
16107         {
16108           errmsg ("parse error '%U'", format_unformat_error, input);
16109           return -99;
16110         }
16111     }
16112
16113   M (ONE_MAP_REQUEST_MODE, mp);
16114
16115   mp->mode = mode;
16116
16117   /* send */
16118   S (mp);
16119
16120   /* wait for reply */
16121   W (ret);
16122   return ret;
16123 }
16124
16125 #define api_lisp_map_request_mode api_one_map_request_mode
16126
16127 /**
16128  * Enable/disable ONE proxy ITR.
16129  *
16130  * @param vam vpp API test context
16131  * @return return code
16132  */
16133 static int
16134 api_one_pitr_set_locator_set (vat_main_t * vam)
16135 {
16136   u8 ls_name_set = 0;
16137   unformat_input_t *input = vam->input;
16138   vl_api_one_pitr_set_locator_set_t *mp;
16139   u8 is_add = 1;
16140   u8 *ls_name = 0;
16141   int ret;
16142
16143   /* Parse args required to build the message */
16144   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16145     {
16146       if (unformat (input, "del"))
16147         is_add = 0;
16148       else if (unformat (input, "locator-set %s", &ls_name))
16149         ls_name_set = 1;
16150       else
16151         {
16152           errmsg ("parse error '%U'", format_unformat_error, input);
16153           return -99;
16154         }
16155     }
16156
16157   if (!ls_name_set)
16158     {
16159       errmsg ("locator-set name not set!");
16160       return -99;
16161     }
16162
16163   M (ONE_PITR_SET_LOCATOR_SET, mp);
16164
16165   mp->is_add = is_add;
16166   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
16167   vec_free (ls_name);
16168
16169   /* send */
16170   S (mp);
16171
16172   /* wait for reply */
16173   W (ret);
16174   return ret;
16175 }
16176
16177 #define api_lisp_pitr_set_locator_set api_one_pitr_set_locator_set
16178
16179 static int
16180 api_one_nsh_set_locator_set (vat_main_t * vam)
16181 {
16182   u8 ls_name_set = 0;
16183   unformat_input_t *input = vam->input;
16184   vl_api_one_nsh_set_locator_set_t *mp;
16185   u8 is_add = 1;
16186   u8 *ls_name = 0;
16187   int ret;
16188
16189   /* Parse args required to build the message */
16190   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16191     {
16192       if (unformat (input, "del"))
16193         is_add = 0;
16194       else if (unformat (input, "ls %s", &ls_name))
16195         ls_name_set = 1;
16196       else
16197         {
16198           errmsg ("parse error '%U'", format_unformat_error, input);
16199           return -99;
16200         }
16201     }
16202
16203   if (!ls_name_set && is_add)
16204     {
16205       errmsg ("locator-set name not set!");
16206       return -99;
16207     }
16208
16209   M (ONE_NSH_SET_LOCATOR_SET, mp);
16210
16211   mp->is_add = is_add;
16212   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
16213   vec_free (ls_name);
16214
16215   /* send */
16216   S (mp);
16217
16218   /* wait for reply */
16219   W (ret);
16220   return ret;
16221 }
16222
16223 static int
16224 api_show_one_pitr (vat_main_t * vam)
16225 {
16226   vl_api_show_one_pitr_t *mp;
16227   int ret;
16228
16229   if (!vam->json_output)
16230     {
16231       print (vam->ofp, "%=20s", "lisp status:");
16232     }
16233
16234   M (SHOW_ONE_PITR, mp);
16235   /* send it... */
16236   S (mp);
16237
16238   /* Wait for a reply... */
16239   W (ret);
16240   return ret;
16241 }
16242
16243 #define api_show_lisp_pitr api_show_one_pitr
16244
16245 static int
16246 api_one_use_petr (vat_main_t * vam)
16247 {
16248   unformat_input_t *input = vam->input;
16249   vl_api_one_use_petr_t *mp;
16250   u8 is_add = 0;
16251   ip_address_t ip;
16252   int ret;
16253
16254   clib_memset (&ip, 0, sizeof (ip));
16255
16256   /* Parse args required to build the message */
16257   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16258     {
16259       if (unformat (input, "disable"))
16260         is_add = 0;
16261       else
16262         if (unformat (input, "%U", unformat_ip4_address, &ip_addr_v4 (&ip)))
16263         {
16264           is_add = 1;
16265           ip_addr_version (&ip) = IP4;
16266         }
16267       else
16268         if (unformat (input, "%U", unformat_ip6_address, &ip_addr_v6 (&ip)))
16269         {
16270           is_add = 1;
16271           ip_addr_version (&ip) = IP6;
16272         }
16273       else
16274         {
16275           errmsg ("parse error '%U'", format_unformat_error, input);
16276           return -99;
16277         }
16278     }
16279
16280   M (ONE_USE_PETR, mp);
16281
16282   mp->is_add = is_add;
16283   if (is_add)
16284     {
16285       mp->is_ip4 = ip_addr_version (&ip) == IP4 ? 1 : 0;
16286       if (mp->is_ip4)
16287         clib_memcpy (mp->address, &ip, 4);
16288       else
16289         clib_memcpy (mp->address, &ip, 16);
16290     }
16291
16292   /* send */
16293   S (mp);
16294
16295   /* wait for reply */
16296   W (ret);
16297   return ret;
16298 }
16299
16300 #define api_lisp_use_petr api_one_use_petr
16301
16302 static int
16303 api_show_one_nsh_mapping (vat_main_t * vam)
16304 {
16305   vl_api_show_one_use_petr_t *mp;
16306   int ret;
16307
16308   if (!vam->json_output)
16309     {
16310       print (vam->ofp, "%=20s", "local ONE NSH mapping:");
16311     }
16312
16313   M (SHOW_ONE_NSH_MAPPING, mp);
16314   /* send it... */
16315   S (mp);
16316
16317   /* Wait for a reply... */
16318   W (ret);
16319   return ret;
16320 }
16321
16322 static int
16323 api_show_one_use_petr (vat_main_t * vam)
16324 {
16325   vl_api_show_one_use_petr_t *mp;
16326   int ret;
16327
16328   if (!vam->json_output)
16329     {
16330       print (vam->ofp, "%=20s", "Proxy-ETR status:");
16331     }
16332
16333   M (SHOW_ONE_USE_PETR, mp);
16334   /* send it... */
16335   S (mp);
16336
16337   /* Wait for a reply... */
16338   W (ret);
16339   return ret;
16340 }
16341
16342 #define api_show_lisp_use_petr api_show_one_use_petr
16343
16344 /**
16345  * Add/delete mapping between vni and vrf
16346  */
16347 static int
16348 api_one_eid_table_add_del_map (vat_main_t * vam)
16349 {
16350   unformat_input_t *input = vam->input;
16351   vl_api_one_eid_table_add_del_map_t *mp;
16352   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
16353   u32 vni, vrf, bd_index;
16354   int ret;
16355
16356   /* Parse args required to build the message */
16357   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16358     {
16359       if (unformat (input, "del"))
16360         is_add = 0;
16361       else if (unformat (input, "vrf %d", &vrf))
16362         vrf_set = 1;
16363       else if (unformat (input, "bd_index %d", &bd_index))
16364         bd_index_set = 1;
16365       else if (unformat (input, "vni %d", &vni))
16366         vni_set = 1;
16367       else
16368         break;
16369     }
16370
16371   if (!vni_set || (!vrf_set && !bd_index_set))
16372     {
16373       errmsg ("missing arguments!");
16374       return -99;
16375     }
16376
16377   if (vrf_set && bd_index_set)
16378     {
16379       errmsg ("error: both vrf and bd entered!");
16380       return -99;
16381     }
16382
16383   M (ONE_EID_TABLE_ADD_DEL_MAP, mp);
16384
16385   mp->is_add = is_add;
16386   mp->vni = htonl (vni);
16387   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
16388   mp->is_l2 = bd_index_set;
16389
16390   /* send */
16391   S (mp);
16392
16393   /* wait for reply */
16394   W (ret);
16395   return ret;
16396 }
16397
16398 #define api_lisp_eid_table_add_del_map api_one_eid_table_add_del_map
16399
16400 uword
16401 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
16402 {
16403   u32 *action = va_arg (*args, u32 *);
16404   u8 *s = 0;
16405
16406   if (unformat (input, "%s", &s))
16407     {
16408       if (!strcmp ((char *) s, "no-action"))
16409         action[0] = 0;
16410       else if (!strcmp ((char *) s, "natively-forward"))
16411         action[0] = 1;
16412       else if (!strcmp ((char *) s, "send-map-request"))
16413         action[0] = 2;
16414       else if (!strcmp ((char *) s, "drop"))
16415         action[0] = 3;
16416       else
16417         {
16418           clib_warning ("invalid action: '%s'", s);
16419           action[0] = 3;
16420         }
16421     }
16422   else
16423     return 0;
16424
16425   vec_free (s);
16426   return 1;
16427 }
16428
16429 /**
16430  * Add/del remote mapping to/from ONE control plane
16431  *
16432  * @param vam vpp API test context
16433  * @return return code
16434  */
16435 static int
16436 api_one_add_del_remote_mapping (vat_main_t * vam)
16437 {
16438   unformat_input_t *input = vam->input;
16439   vl_api_one_add_del_remote_mapping_t *mp;
16440   u32 vni = 0;
16441   lisp_eid_vat_t _eid, *eid = &_eid;
16442   lisp_eid_vat_t _seid, *seid = &_seid;
16443   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
16444   u32 action = ~0, p, w, data_len;
16445   ip4_address_t rloc4;
16446   ip6_address_t rloc6;
16447   vl_api_remote_locator_t *rlocs = 0, rloc, *curr_rloc = 0;
16448   int ret;
16449
16450   clib_memset (&rloc, 0, sizeof (rloc));
16451
16452   /* Parse args required to build the message */
16453   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16454     {
16455       if (unformat (input, "del-all"))
16456         {
16457           del_all = 1;
16458         }
16459       else if (unformat (input, "del"))
16460         {
16461           is_add = 0;
16462         }
16463       else if (unformat (input, "add"))
16464         {
16465           is_add = 1;
16466         }
16467       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
16468         {
16469           eid_set = 1;
16470         }
16471       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
16472         {
16473           seid_set = 1;
16474         }
16475       else if (unformat (input, "vni %d", &vni))
16476         {
16477           ;
16478         }
16479       else if (unformat (input, "p %d w %d", &p, &w))
16480         {
16481           if (!curr_rloc)
16482             {
16483               errmsg ("No RLOC configured for setting priority/weight!");
16484               return -99;
16485             }
16486           curr_rloc->priority = p;
16487           curr_rloc->weight = w;
16488         }
16489       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
16490         {
16491           rloc.is_ip4 = 1;
16492           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
16493           vec_add1 (rlocs, rloc);
16494           curr_rloc = &rlocs[vec_len (rlocs) - 1];
16495         }
16496       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
16497         {
16498           rloc.is_ip4 = 0;
16499           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
16500           vec_add1 (rlocs, rloc);
16501           curr_rloc = &rlocs[vec_len (rlocs) - 1];
16502         }
16503       else if (unformat (input, "action %U",
16504                          unformat_negative_mapping_action, &action))
16505         {
16506           ;
16507         }
16508       else
16509         {
16510           clib_warning ("parse error '%U'", format_unformat_error, input);
16511           return -99;
16512         }
16513     }
16514
16515   if (0 == eid_set)
16516     {
16517       errmsg ("missing params!");
16518       return -99;
16519     }
16520
16521   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
16522     {
16523       errmsg ("no action set for negative map-reply!");
16524       return -99;
16525     }
16526
16527   data_len = vec_len (rlocs) * sizeof (vl_api_remote_locator_t);
16528
16529   M2 (ONE_ADD_DEL_REMOTE_MAPPING, mp, data_len);
16530   mp->is_add = is_add;
16531   mp->vni = htonl (vni);
16532   mp->action = (u8) action;
16533   mp->is_src_dst = seid_set;
16534   mp->eid_len = eid->len;
16535   mp->seid_len = seid->len;
16536   mp->del_all = del_all;
16537   mp->eid_type = eid->type;
16538   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
16539   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
16540
16541   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
16542   clib_memcpy (mp->rlocs, rlocs, data_len);
16543   vec_free (rlocs);
16544
16545   /* send it... */
16546   S (mp);
16547
16548   /* Wait for a reply... */
16549   W (ret);
16550   return ret;
16551 }
16552
16553 #define api_lisp_add_del_remote_mapping api_one_add_del_remote_mapping
16554
16555 /**
16556  * Add/del ONE adjacency. Saves mapping in ONE control plane and updates
16557  * forwarding entries in data-plane accordingly.
16558  *
16559  * @param vam vpp API test context
16560  * @return return code
16561  */
16562 static int
16563 api_one_add_del_adjacency (vat_main_t * vam)
16564 {
16565   unformat_input_t *input = vam->input;
16566   vl_api_one_add_del_adjacency_t *mp;
16567   u32 vni = 0;
16568   ip4_address_t leid4, reid4;
16569   ip6_address_t leid6, reid6;
16570   u8 reid_mac[6] = { 0 };
16571   u8 leid_mac[6] = { 0 };
16572   u8 reid_type, leid_type;
16573   u32 leid_len = 0, reid_len = 0, len;
16574   u8 is_add = 1;
16575   int ret;
16576
16577   leid_type = reid_type = (u8) ~ 0;
16578
16579   /* Parse args required to build the message */
16580   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16581     {
16582       if (unformat (input, "del"))
16583         {
16584           is_add = 0;
16585         }
16586       else if (unformat (input, "add"))
16587         {
16588           is_add = 1;
16589         }
16590       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
16591                          &reid4, &len))
16592         {
16593           reid_type = 0;        /* ipv4 */
16594           reid_len = len;
16595         }
16596       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
16597                          &reid6, &len))
16598         {
16599           reid_type = 1;        /* ipv6 */
16600           reid_len = len;
16601         }
16602       else if (unformat (input, "reid %U", unformat_ethernet_address,
16603                          reid_mac))
16604         {
16605           reid_type = 2;        /* mac */
16606         }
16607       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
16608                          &leid4, &len))
16609         {
16610           leid_type = 0;        /* ipv4 */
16611           leid_len = len;
16612         }
16613       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
16614                          &leid6, &len))
16615         {
16616           leid_type = 1;        /* ipv6 */
16617           leid_len = len;
16618         }
16619       else if (unformat (input, "leid %U", unformat_ethernet_address,
16620                          leid_mac))
16621         {
16622           leid_type = 2;        /* mac */
16623         }
16624       else if (unformat (input, "vni %d", &vni))
16625         {
16626           ;
16627         }
16628       else
16629         {
16630           errmsg ("parse error '%U'", format_unformat_error, input);
16631           return -99;
16632         }
16633     }
16634
16635   if ((u8) ~ 0 == reid_type)
16636     {
16637       errmsg ("missing params!");
16638       return -99;
16639     }
16640
16641   if (leid_type != reid_type)
16642     {
16643       errmsg ("remote and local EIDs are of different types!");
16644       return -99;
16645     }
16646
16647   M (ONE_ADD_DEL_ADJACENCY, mp);
16648   mp->is_add = is_add;
16649   mp->vni = htonl (vni);
16650   mp->leid_len = leid_len;
16651   mp->reid_len = reid_len;
16652   mp->eid_type = reid_type;
16653
16654   switch (mp->eid_type)
16655     {
16656     case 0:
16657       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
16658       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
16659       break;
16660     case 1:
16661       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
16662       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
16663       break;
16664     case 2:
16665       clib_memcpy (mp->leid, leid_mac, 6);
16666       clib_memcpy (mp->reid, reid_mac, 6);
16667       break;
16668     default:
16669       errmsg ("unknown EID type %d!", mp->eid_type);
16670       return 0;
16671     }
16672
16673   /* send it... */
16674   S (mp);
16675
16676   /* Wait for a reply... */
16677   W (ret);
16678   return ret;
16679 }
16680
16681 #define api_lisp_add_del_adjacency api_one_add_del_adjacency
16682
16683 uword
16684 unformat_gpe_encap_mode (unformat_input_t * input, va_list * args)
16685 {
16686   u32 *mode = va_arg (*args, u32 *);
16687
16688   if (unformat (input, "lisp"))
16689     *mode = 0;
16690   else if (unformat (input, "vxlan"))
16691     *mode = 1;
16692   else
16693     return 0;
16694
16695   return 1;
16696 }
16697
16698 static int
16699 api_gpe_get_encap_mode (vat_main_t * vam)
16700 {
16701   vl_api_gpe_get_encap_mode_t *mp;
16702   int ret;
16703
16704   /* Construct the API message */
16705   M (GPE_GET_ENCAP_MODE, mp);
16706
16707   /* send it... */
16708   S (mp);
16709
16710   /* Wait for a reply... */
16711   W (ret);
16712   return ret;
16713 }
16714
16715 static int
16716 api_gpe_set_encap_mode (vat_main_t * vam)
16717 {
16718   unformat_input_t *input = vam->input;
16719   vl_api_gpe_set_encap_mode_t *mp;
16720   int ret;
16721   u32 mode = 0;
16722
16723   /* Parse args required to build the message */
16724   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16725     {
16726       if (unformat (input, "%U", unformat_gpe_encap_mode, &mode))
16727         ;
16728       else
16729         break;
16730     }
16731
16732   /* Construct the API message */
16733   M (GPE_SET_ENCAP_MODE, mp);
16734
16735   mp->mode = mode;
16736
16737   /* send it... */
16738   S (mp);
16739
16740   /* Wait for a reply... */
16741   W (ret);
16742   return ret;
16743 }
16744
16745 static int
16746 api_lisp_gpe_add_del_iface (vat_main_t * vam)
16747 {
16748   unformat_input_t *input = vam->input;
16749   vl_api_gpe_add_del_iface_t *mp;
16750   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
16751   u32 dp_table = 0, vni = 0;
16752   int ret;
16753
16754   /* Parse args required to build the message */
16755   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16756     {
16757       if (unformat (input, "up"))
16758         {
16759           action_set = 1;
16760           is_add = 1;
16761         }
16762       else if (unformat (input, "down"))
16763         {
16764           action_set = 1;
16765           is_add = 0;
16766         }
16767       else if (unformat (input, "table_id %d", &dp_table))
16768         {
16769           dp_table_set = 1;
16770         }
16771       else if (unformat (input, "bd_id %d", &dp_table))
16772         {
16773           dp_table_set = 1;
16774           is_l2 = 1;
16775         }
16776       else if (unformat (input, "vni %d", &vni))
16777         {
16778           vni_set = 1;
16779         }
16780       else
16781         break;
16782     }
16783
16784   if (action_set == 0)
16785     {
16786       errmsg ("Action not set");
16787       return -99;
16788     }
16789   if (dp_table_set == 0 || vni_set == 0)
16790     {
16791       errmsg ("vni and dp_table must be set");
16792       return -99;
16793     }
16794
16795   /* Construct the API message */
16796   M (GPE_ADD_DEL_IFACE, mp);
16797
16798   mp->is_add = is_add;
16799   mp->dp_table = clib_host_to_net_u32 (dp_table);
16800   mp->is_l2 = is_l2;
16801   mp->vni = clib_host_to_net_u32 (vni);
16802
16803   /* send it... */
16804   S (mp);
16805
16806   /* Wait for a reply... */
16807   W (ret);
16808   return ret;
16809 }
16810
16811 static int
16812 api_one_map_register_fallback_threshold (vat_main_t * vam)
16813 {
16814   unformat_input_t *input = vam->input;
16815   vl_api_one_map_register_fallback_threshold_t *mp;
16816   u32 value = 0;
16817   u8 is_set = 0;
16818   int ret;
16819
16820   /* Parse args required to build the message */
16821   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16822     {
16823       if (unformat (input, "%u", &value))
16824         is_set = 1;
16825       else
16826         {
16827           clib_warning ("parse error '%U'", format_unformat_error, input);
16828           return -99;
16829         }
16830     }
16831
16832   if (!is_set)
16833     {
16834       errmsg ("fallback threshold value is missing!");
16835       return -99;
16836     }
16837
16838   M (ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
16839   mp->value = clib_host_to_net_u32 (value);
16840
16841   /* send it... */
16842   S (mp);
16843
16844   /* Wait for a reply... */
16845   W (ret);
16846   return ret;
16847 }
16848
16849 static int
16850 api_show_one_map_register_fallback_threshold (vat_main_t * vam)
16851 {
16852   vl_api_show_one_map_register_fallback_threshold_t *mp;
16853   int ret;
16854
16855   M (SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
16856
16857   /* send it... */
16858   S (mp);
16859
16860   /* Wait for a reply... */
16861   W (ret);
16862   return ret;
16863 }
16864
16865 uword
16866 unformat_lisp_transport_protocol (unformat_input_t * input, va_list * args)
16867 {
16868   u32 *proto = va_arg (*args, u32 *);
16869
16870   if (unformat (input, "udp"))
16871     *proto = 1;
16872   else if (unformat (input, "api"))
16873     *proto = 2;
16874   else
16875     return 0;
16876
16877   return 1;
16878 }
16879
16880 static int
16881 api_one_set_transport_protocol (vat_main_t * vam)
16882 {
16883   unformat_input_t *input = vam->input;
16884   vl_api_one_set_transport_protocol_t *mp;
16885   u8 is_set = 0;
16886   u32 protocol = 0;
16887   int ret;
16888
16889   /* Parse args required to build the message */
16890   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16891     {
16892       if (unformat (input, "%U", unformat_lisp_transport_protocol, &protocol))
16893         is_set = 1;
16894       else
16895         {
16896           clib_warning ("parse error '%U'", format_unformat_error, input);
16897           return -99;
16898         }
16899     }
16900
16901   if (!is_set)
16902     {
16903       errmsg ("Transport protocol missing!");
16904       return -99;
16905     }
16906
16907   M (ONE_SET_TRANSPORT_PROTOCOL, mp);
16908   mp->protocol = (u8) protocol;
16909
16910   /* send it... */
16911   S (mp);
16912
16913   /* Wait for a reply... */
16914   W (ret);
16915   return ret;
16916 }
16917
16918 static int
16919 api_one_get_transport_protocol (vat_main_t * vam)
16920 {
16921   vl_api_one_get_transport_protocol_t *mp;
16922   int ret;
16923
16924   M (ONE_GET_TRANSPORT_PROTOCOL, mp);
16925
16926   /* send it... */
16927   S (mp);
16928
16929   /* Wait for a reply... */
16930   W (ret);
16931   return ret;
16932 }
16933
16934 static int
16935 api_one_map_register_set_ttl (vat_main_t * vam)
16936 {
16937   unformat_input_t *input = vam->input;
16938   vl_api_one_map_register_set_ttl_t *mp;
16939   u32 ttl = 0;
16940   u8 is_set = 0;
16941   int ret;
16942
16943   /* Parse args required to build the message */
16944   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16945     {
16946       if (unformat (input, "%u", &ttl))
16947         is_set = 1;
16948       else
16949         {
16950           clib_warning ("parse error '%U'", format_unformat_error, input);
16951           return -99;
16952         }
16953     }
16954
16955   if (!is_set)
16956     {
16957       errmsg ("TTL value missing!");
16958       return -99;
16959     }
16960
16961   M (ONE_MAP_REGISTER_SET_TTL, mp);
16962   mp->ttl = clib_host_to_net_u32 (ttl);
16963
16964   /* send it... */
16965   S (mp);
16966
16967   /* Wait for a reply... */
16968   W (ret);
16969   return ret;
16970 }
16971
16972 static int
16973 api_show_one_map_register_ttl (vat_main_t * vam)
16974 {
16975   vl_api_show_one_map_register_ttl_t *mp;
16976   int ret;
16977
16978   M (SHOW_ONE_MAP_REGISTER_TTL, mp);
16979
16980   /* send it... */
16981   S (mp);
16982
16983   /* Wait for a reply... */
16984   W (ret);
16985   return ret;
16986 }
16987
16988 /**
16989  * Add/del map request itr rlocs from ONE control plane and updates
16990  *
16991  * @param vam vpp API test context
16992  * @return return code
16993  */
16994 static int
16995 api_one_add_del_map_request_itr_rlocs (vat_main_t * vam)
16996 {
16997   unformat_input_t *input = vam->input;
16998   vl_api_one_add_del_map_request_itr_rlocs_t *mp;
16999   u8 *locator_set_name = 0;
17000   u8 locator_set_name_set = 0;
17001   u8 is_add = 1;
17002   int ret;
17003
17004   /* Parse args required to build the message */
17005   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17006     {
17007       if (unformat (input, "del"))
17008         {
17009           is_add = 0;
17010         }
17011       else if (unformat (input, "%_%v%_", &locator_set_name))
17012         {
17013           locator_set_name_set = 1;
17014         }
17015       else
17016         {
17017           clib_warning ("parse error '%U'", format_unformat_error, input);
17018           return -99;
17019         }
17020     }
17021
17022   if (is_add && !locator_set_name_set)
17023     {
17024       errmsg ("itr-rloc is not set!");
17025       return -99;
17026     }
17027
17028   if (is_add && vec_len (locator_set_name) > 64)
17029     {
17030       errmsg ("itr-rloc locator-set name too long");
17031       vec_free (locator_set_name);
17032       return -99;
17033     }
17034
17035   M (ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS, mp);
17036   mp->is_add = is_add;
17037   if (is_add)
17038     {
17039       clib_memcpy (mp->locator_set_name, locator_set_name,
17040                    vec_len (locator_set_name));
17041     }
17042   else
17043     {
17044       clib_memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
17045     }
17046   vec_free (locator_set_name);
17047
17048   /* send it... */
17049   S (mp);
17050
17051   /* Wait for a reply... */
17052   W (ret);
17053   return ret;
17054 }
17055
17056 #define api_lisp_add_del_map_request_itr_rlocs api_one_add_del_map_request_itr_rlocs
17057
17058 static int
17059 api_one_locator_dump (vat_main_t * vam)
17060 {
17061   unformat_input_t *input = vam->input;
17062   vl_api_one_locator_dump_t *mp;
17063   vl_api_control_ping_t *mp_ping;
17064   u8 is_index_set = 0, is_name_set = 0;
17065   u8 *ls_name = 0;
17066   u32 ls_index = ~0;
17067   int ret;
17068
17069   /* Parse args required to build the message */
17070   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17071     {
17072       if (unformat (input, "ls_name %_%v%_", &ls_name))
17073         {
17074           is_name_set = 1;
17075         }
17076       else if (unformat (input, "ls_index %d", &ls_index))
17077         {
17078           is_index_set = 1;
17079         }
17080       else
17081         {
17082           errmsg ("parse error '%U'", format_unformat_error, input);
17083           return -99;
17084         }
17085     }
17086
17087   if (!is_index_set && !is_name_set)
17088     {
17089       errmsg ("error: expected one of index or name!");
17090       return -99;
17091     }
17092
17093   if (is_index_set && is_name_set)
17094     {
17095       errmsg ("error: only one param expected!");
17096       return -99;
17097     }
17098
17099   if (vec_len (ls_name) > 62)
17100     {
17101       errmsg ("error: locator set name too long!");
17102       return -99;
17103     }
17104
17105   if (!vam->json_output)
17106     {
17107       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
17108     }
17109
17110   M (ONE_LOCATOR_DUMP, mp);
17111   mp->is_index_set = is_index_set;
17112
17113   if (is_index_set)
17114     mp->ls_index = clib_host_to_net_u32 (ls_index);
17115   else
17116     {
17117       vec_add1 (ls_name, 0);
17118       strncpy ((char *) mp->ls_name, (char *) ls_name,
17119                sizeof (mp->ls_name) - 1);
17120     }
17121
17122   /* send it... */
17123   S (mp);
17124
17125   /* Use a control ping for synchronization */
17126   MPING (CONTROL_PING, mp_ping);
17127   S (mp_ping);
17128
17129   /* Wait for a reply... */
17130   W (ret);
17131   return ret;
17132 }
17133
17134 #define api_lisp_locator_dump api_one_locator_dump
17135
17136 static int
17137 api_one_locator_set_dump (vat_main_t * vam)
17138 {
17139   vl_api_one_locator_set_dump_t *mp;
17140   vl_api_control_ping_t *mp_ping;
17141   unformat_input_t *input = vam->input;
17142   u8 filter = 0;
17143   int ret;
17144
17145   /* Parse args required to build the message */
17146   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17147     {
17148       if (unformat (input, "local"))
17149         {
17150           filter = 1;
17151         }
17152       else if (unformat (input, "remote"))
17153         {
17154           filter = 2;
17155         }
17156       else
17157         {
17158           errmsg ("parse error '%U'", format_unformat_error, input);
17159           return -99;
17160         }
17161     }
17162
17163   if (!vam->json_output)
17164     {
17165       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
17166     }
17167
17168   M (ONE_LOCATOR_SET_DUMP, mp);
17169
17170   mp->filter = filter;
17171
17172   /* send it... */
17173   S (mp);
17174
17175   /* Use a control ping for synchronization */
17176   MPING (CONTROL_PING, mp_ping);
17177   S (mp_ping);
17178
17179   /* Wait for a reply... */
17180   W (ret);
17181   return ret;
17182 }
17183
17184 #define api_lisp_locator_set_dump api_one_locator_set_dump
17185
17186 static int
17187 api_one_eid_table_map_dump (vat_main_t * vam)
17188 {
17189   u8 is_l2 = 0;
17190   u8 mode_set = 0;
17191   unformat_input_t *input = vam->input;
17192   vl_api_one_eid_table_map_dump_t *mp;
17193   vl_api_control_ping_t *mp_ping;
17194   int ret;
17195
17196   /* Parse args required to build the message */
17197   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17198     {
17199       if (unformat (input, "l2"))
17200         {
17201           is_l2 = 1;
17202           mode_set = 1;
17203         }
17204       else if (unformat (input, "l3"))
17205         {
17206           is_l2 = 0;
17207           mode_set = 1;
17208         }
17209       else
17210         {
17211           errmsg ("parse error '%U'", format_unformat_error, input);
17212           return -99;
17213         }
17214     }
17215
17216   if (!mode_set)
17217     {
17218       errmsg ("expected one of 'l2' or 'l3' parameter!");
17219       return -99;
17220     }
17221
17222   if (!vam->json_output)
17223     {
17224       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
17225     }
17226
17227   M (ONE_EID_TABLE_MAP_DUMP, mp);
17228   mp->is_l2 = is_l2;
17229
17230   /* send it... */
17231   S (mp);
17232
17233   /* Use a control ping for synchronization */
17234   MPING (CONTROL_PING, mp_ping);
17235   S (mp_ping);
17236
17237   /* Wait for a reply... */
17238   W (ret);
17239   return ret;
17240 }
17241
17242 #define api_lisp_eid_table_map_dump api_one_eid_table_map_dump
17243
17244 static int
17245 api_one_eid_table_vni_dump (vat_main_t * vam)
17246 {
17247   vl_api_one_eid_table_vni_dump_t *mp;
17248   vl_api_control_ping_t *mp_ping;
17249   int ret;
17250
17251   if (!vam->json_output)
17252     {
17253       print (vam->ofp, "VNI");
17254     }
17255
17256   M (ONE_EID_TABLE_VNI_DUMP, mp);
17257
17258   /* send it... */
17259   S (mp);
17260
17261   /* Use a control ping for synchronization */
17262   MPING (CONTROL_PING, mp_ping);
17263   S (mp_ping);
17264
17265   /* Wait for a reply... */
17266   W (ret);
17267   return ret;
17268 }
17269
17270 #define api_lisp_eid_table_vni_dump api_one_eid_table_vni_dump
17271
17272 static int
17273 api_one_eid_table_dump (vat_main_t * vam)
17274 {
17275   unformat_input_t *i = vam->input;
17276   vl_api_one_eid_table_dump_t *mp;
17277   vl_api_control_ping_t *mp_ping;
17278   struct in_addr ip4;
17279   struct in6_addr ip6;
17280   u8 mac[6];
17281   u8 eid_type = ~0, eid_set = 0;
17282   u32 prefix_length = ~0, t, vni = 0;
17283   u8 filter = 0;
17284   int ret;
17285   lisp_nsh_api_t nsh;
17286
17287   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17288     {
17289       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
17290         {
17291           eid_set = 1;
17292           eid_type = 0;
17293           prefix_length = t;
17294         }
17295       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
17296         {
17297           eid_set = 1;
17298           eid_type = 1;
17299           prefix_length = t;
17300         }
17301       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
17302         {
17303           eid_set = 1;
17304           eid_type = 2;
17305         }
17306       else if (unformat (i, "eid %U", unformat_nsh_address, &nsh))
17307         {
17308           eid_set = 1;
17309           eid_type = 3;
17310         }
17311       else if (unformat (i, "vni %d", &t))
17312         {
17313           vni = t;
17314         }
17315       else if (unformat (i, "local"))
17316         {
17317           filter = 1;
17318         }
17319       else if (unformat (i, "remote"))
17320         {
17321           filter = 2;
17322         }
17323       else
17324         {
17325           errmsg ("parse error '%U'", format_unformat_error, i);
17326           return -99;
17327         }
17328     }
17329
17330   if (!vam->json_output)
17331     {
17332       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
17333              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
17334     }
17335
17336   M (ONE_EID_TABLE_DUMP, mp);
17337
17338   mp->filter = filter;
17339   if (eid_set)
17340     {
17341       mp->eid_set = 1;
17342       mp->vni = htonl (vni);
17343       mp->eid_type = eid_type;
17344       switch (eid_type)
17345         {
17346         case 0:
17347           mp->prefix_length = prefix_length;
17348           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
17349           break;
17350         case 1:
17351           mp->prefix_length = prefix_length;
17352           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
17353           break;
17354         case 2:
17355           clib_memcpy (mp->eid, mac, sizeof (mac));
17356           break;
17357         case 3:
17358           clib_memcpy (mp->eid, &nsh, sizeof (nsh));
17359           break;
17360         default:
17361           errmsg ("unknown EID type %d!", eid_type);
17362           return -99;
17363         }
17364     }
17365
17366   /* send it... */
17367   S (mp);
17368
17369   /* Use a control ping for synchronization */
17370   MPING (CONTROL_PING, mp_ping);
17371   S (mp_ping);
17372
17373   /* Wait for a reply... */
17374   W (ret);
17375   return ret;
17376 }
17377
17378 #define api_lisp_eid_table_dump api_one_eid_table_dump
17379
17380 static int
17381 api_lisp_gpe_fwd_entries_get (vat_main_t * vam)
17382 {
17383   unformat_input_t *i = vam->input;
17384   vl_api_gpe_fwd_entries_get_t *mp;
17385   u8 vni_set = 0;
17386   u32 vni = ~0;
17387   int ret;
17388
17389   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17390     {
17391       if (unformat (i, "vni %d", &vni))
17392         {
17393           vni_set = 1;
17394         }
17395       else
17396         {
17397           errmsg ("parse error '%U'", format_unformat_error, i);
17398           return -99;
17399         }
17400     }
17401
17402   if (!vni_set)
17403     {
17404       errmsg ("vni not set!");
17405       return -99;
17406     }
17407
17408   if (!vam->json_output)
17409     {
17410       print (vam->ofp, "%10s %10s %s %40s", "fwd_index", "dp_table",
17411              "leid", "reid");
17412     }
17413
17414   M (GPE_FWD_ENTRIES_GET, mp);
17415   mp->vni = clib_host_to_net_u32 (vni);
17416
17417   /* send it... */
17418   S (mp);
17419
17420   /* Wait for a reply... */
17421   W (ret);
17422   return ret;
17423 }
17424
17425 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_endian vl_noop_handler
17426 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_print vl_noop_handler
17427 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_endian vl_noop_handler
17428 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_print vl_noop_handler
17429 #define vl_api_gpe_fwd_entries_get_reply_t_endian vl_noop_handler
17430 #define vl_api_gpe_fwd_entries_get_reply_t_print vl_noop_handler
17431 #define vl_api_gpe_fwd_entry_path_details_t_endian vl_noop_handler
17432 #define vl_api_gpe_fwd_entry_path_details_t_print vl_noop_handler
17433
17434 static int
17435 api_one_adjacencies_get (vat_main_t * vam)
17436 {
17437   unformat_input_t *i = vam->input;
17438   vl_api_one_adjacencies_get_t *mp;
17439   u8 vni_set = 0;
17440   u32 vni = ~0;
17441   int ret;
17442
17443   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17444     {
17445       if (unformat (i, "vni %d", &vni))
17446         {
17447           vni_set = 1;
17448         }
17449       else
17450         {
17451           errmsg ("parse error '%U'", format_unformat_error, i);
17452           return -99;
17453         }
17454     }
17455
17456   if (!vni_set)
17457     {
17458       errmsg ("vni not set!");
17459       return -99;
17460     }
17461
17462   if (!vam->json_output)
17463     {
17464       print (vam->ofp, "%s %40s", "leid", "reid");
17465     }
17466
17467   M (ONE_ADJACENCIES_GET, mp);
17468   mp->vni = clib_host_to_net_u32 (vni);
17469
17470   /* send it... */
17471   S (mp);
17472
17473   /* Wait for a reply... */
17474   W (ret);
17475   return ret;
17476 }
17477
17478 #define api_lisp_adjacencies_get api_one_adjacencies_get
17479
17480 static int
17481 api_gpe_native_fwd_rpaths_get (vat_main_t * vam)
17482 {
17483   unformat_input_t *i = vam->input;
17484   vl_api_gpe_native_fwd_rpaths_get_t *mp;
17485   int ret;
17486   u8 ip_family_set = 0, is_ip4 = 1;
17487
17488   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17489     {
17490       if (unformat (i, "ip4"))
17491         {
17492           ip_family_set = 1;
17493           is_ip4 = 1;
17494         }
17495       else if (unformat (i, "ip6"))
17496         {
17497           ip_family_set = 1;
17498           is_ip4 = 0;
17499         }
17500       else
17501         {
17502           errmsg ("parse error '%U'", format_unformat_error, i);
17503           return -99;
17504         }
17505     }
17506
17507   if (!ip_family_set)
17508     {
17509       errmsg ("ip family not set!");
17510       return -99;
17511     }
17512
17513   M (GPE_NATIVE_FWD_RPATHS_GET, mp);
17514   mp->is_ip4 = is_ip4;
17515
17516   /* send it... */
17517   S (mp);
17518
17519   /* Wait for a reply... */
17520   W (ret);
17521   return ret;
17522 }
17523
17524 static int
17525 api_gpe_fwd_entry_vnis_get (vat_main_t * vam)
17526 {
17527   vl_api_gpe_fwd_entry_vnis_get_t *mp;
17528   int ret;
17529
17530   if (!vam->json_output)
17531     {
17532       print (vam->ofp, "VNIs");
17533     }
17534
17535   M (GPE_FWD_ENTRY_VNIS_GET, mp);
17536
17537   /* send it... */
17538   S (mp);
17539
17540   /* Wait for a reply... */
17541   W (ret);
17542   return ret;
17543 }
17544
17545 static int
17546 api_gpe_add_del_native_fwd_rpath (vat_main_t * vam)
17547 {
17548   unformat_input_t *i = vam->input;
17549   vl_api_gpe_add_del_native_fwd_rpath_t *mp;
17550   int ret = 0;
17551   u8 is_add = 1, ip_set = 0, is_ip4 = 1;
17552   struct in_addr ip4;
17553   struct in6_addr ip6;
17554   u32 table_id = 0, nh_sw_if_index = ~0;
17555
17556   clib_memset (&ip4, 0, sizeof (ip4));
17557   clib_memset (&ip6, 0, sizeof (ip6));
17558
17559   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17560     {
17561       if (unformat (i, "del"))
17562         is_add = 0;
17563       else if (unformat (i, "via %U %U", unformat_ip4_address, &ip4,
17564                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
17565         {
17566           ip_set = 1;
17567           is_ip4 = 1;
17568         }
17569       else if (unformat (i, "via %U %U", unformat_ip6_address, &ip6,
17570                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
17571         {
17572           ip_set = 1;
17573           is_ip4 = 0;
17574         }
17575       else if (unformat (i, "via %U", unformat_ip4_address, &ip4))
17576         {
17577           ip_set = 1;
17578           is_ip4 = 1;
17579           nh_sw_if_index = ~0;
17580         }
17581       else if (unformat (i, "via %U", unformat_ip6_address, &ip6))
17582         {
17583           ip_set = 1;
17584           is_ip4 = 0;
17585           nh_sw_if_index = ~0;
17586         }
17587       else if (unformat (i, "table %d", &table_id))
17588         ;
17589       else
17590         {
17591           errmsg ("parse error '%U'", format_unformat_error, i);
17592           return -99;
17593         }
17594     }
17595
17596   if (!ip_set)
17597     {
17598       errmsg ("nh addr not set!");
17599       return -99;
17600     }
17601
17602   M (GPE_ADD_DEL_NATIVE_FWD_RPATH, mp);
17603   mp->is_add = is_add;
17604   mp->table_id = clib_host_to_net_u32 (table_id);
17605   mp->nh_sw_if_index = clib_host_to_net_u32 (nh_sw_if_index);
17606   mp->is_ip4 = is_ip4;
17607   if (is_ip4)
17608     clib_memcpy (mp->nh_addr, &ip4, sizeof (ip4));
17609   else
17610     clib_memcpy (mp->nh_addr, &ip6, sizeof (ip6));
17611
17612   /* send it... */
17613   S (mp);
17614
17615   /* Wait for a reply... */
17616   W (ret);
17617   return ret;
17618 }
17619
17620 static int
17621 api_one_map_server_dump (vat_main_t * vam)
17622 {
17623   vl_api_one_map_server_dump_t *mp;
17624   vl_api_control_ping_t *mp_ping;
17625   int ret;
17626
17627   if (!vam->json_output)
17628     {
17629       print (vam->ofp, "%=20s", "Map server");
17630     }
17631
17632   M (ONE_MAP_SERVER_DUMP, mp);
17633   /* send it... */
17634   S (mp);
17635
17636   /* Use a control ping for synchronization */
17637   MPING (CONTROL_PING, mp_ping);
17638   S (mp_ping);
17639
17640   /* Wait for a reply... */
17641   W (ret);
17642   return ret;
17643 }
17644
17645 #define api_lisp_map_server_dump api_one_map_server_dump
17646
17647 static int
17648 api_one_map_resolver_dump (vat_main_t * vam)
17649 {
17650   vl_api_one_map_resolver_dump_t *mp;
17651   vl_api_control_ping_t *mp_ping;
17652   int ret;
17653
17654   if (!vam->json_output)
17655     {
17656       print (vam->ofp, "%=20s", "Map resolver");
17657     }
17658
17659   M (ONE_MAP_RESOLVER_DUMP, mp);
17660   /* send it... */
17661   S (mp);
17662
17663   /* Use a control ping for synchronization */
17664   MPING (CONTROL_PING, mp_ping);
17665   S (mp_ping);
17666
17667   /* Wait for a reply... */
17668   W (ret);
17669   return ret;
17670 }
17671
17672 #define api_lisp_map_resolver_dump api_one_map_resolver_dump
17673
17674 static int
17675 api_one_stats_flush (vat_main_t * vam)
17676 {
17677   vl_api_one_stats_flush_t *mp;
17678   int ret = 0;
17679
17680   M (ONE_STATS_FLUSH, mp);
17681   S (mp);
17682   W (ret);
17683   return ret;
17684 }
17685
17686 static int
17687 api_one_stats_dump (vat_main_t * vam)
17688 {
17689   vl_api_one_stats_dump_t *mp;
17690   vl_api_control_ping_t *mp_ping;
17691   int ret;
17692
17693   M (ONE_STATS_DUMP, mp);
17694   /* send it... */
17695   S (mp);
17696
17697   /* Use a control ping for synchronization */
17698   MPING (CONTROL_PING, mp_ping);
17699   S (mp_ping);
17700
17701   /* Wait for a reply... */
17702   W (ret);
17703   return ret;
17704 }
17705
17706 static int
17707 api_show_one_status (vat_main_t * vam)
17708 {
17709   vl_api_show_one_status_t *mp;
17710   int ret;
17711
17712   if (!vam->json_output)
17713     {
17714       print (vam->ofp, "%-20s%-16s", "ONE status", "locator-set");
17715     }
17716
17717   M (SHOW_ONE_STATUS, mp);
17718   /* send it... */
17719   S (mp);
17720   /* Wait for a reply... */
17721   W (ret);
17722   return ret;
17723 }
17724
17725 #define api_show_lisp_status api_show_one_status
17726
17727 static int
17728 api_lisp_gpe_fwd_entry_path_dump (vat_main_t * vam)
17729 {
17730   vl_api_gpe_fwd_entry_path_dump_t *mp;
17731   vl_api_control_ping_t *mp_ping;
17732   unformat_input_t *i = vam->input;
17733   u32 fwd_entry_index = ~0;
17734   int ret;
17735
17736   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17737     {
17738       if (unformat (i, "index %d", &fwd_entry_index))
17739         ;
17740       else
17741         break;
17742     }
17743
17744   if (~0 == fwd_entry_index)
17745     {
17746       errmsg ("no index specified!");
17747       return -99;
17748     }
17749
17750   if (!vam->json_output)
17751     {
17752       print (vam->ofp, "first line");
17753     }
17754
17755   M (GPE_FWD_ENTRY_PATH_DUMP, mp);
17756
17757   /* send it... */
17758   S (mp);
17759   /* Use a control ping for synchronization */
17760   MPING (CONTROL_PING, mp_ping);
17761   S (mp_ping);
17762
17763   /* Wait for a reply... */
17764   W (ret);
17765   return ret;
17766 }
17767
17768 static int
17769 api_one_get_map_request_itr_rlocs (vat_main_t * vam)
17770 {
17771   vl_api_one_get_map_request_itr_rlocs_t *mp;
17772   int ret;
17773
17774   if (!vam->json_output)
17775     {
17776       print (vam->ofp, "%=20s", "itr-rlocs:");
17777     }
17778
17779   M (ONE_GET_MAP_REQUEST_ITR_RLOCS, mp);
17780   /* send it... */
17781   S (mp);
17782   /* Wait for a reply... */
17783   W (ret);
17784   return ret;
17785 }
17786
17787 #define api_lisp_get_map_request_itr_rlocs api_one_get_map_request_itr_rlocs
17788
17789 static int
17790 api_af_packet_create (vat_main_t * vam)
17791 {
17792   unformat_input_t *i = vam->input;
17793   vl_api_af_packet_create_t *mp;
17794   u8 *host_if_name = 0;
17795   u8 hw_addr[6];
17796   u8 random_hw_addr = 1;
17797   int ret;
17798
17799   clib_memset (hw_addr, 0, sizeof (hw_addr));
17800
17801   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17802     {
17803       if (unformat (i, "name %s", &host_if_name))
17804         vec_add1 (host_if_name, 0);
17805       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
17806         random_hw_addr = 0;
17807       else
17808         break;
17809     }
17810
17811   if (!vec_len (host_if_name))
17812     {
17813       errmsg ("host-interface name must be specified");
17814       return -99;
17815     }
17816
17817   if (vec_len (host_if_name) > 64)
17818     {
17819       errmsg ("host-interface name too long");
17820       return -99;
17821     }
17822
17823   M (AF_PACKET_CREATE, mp);
17824
17825   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
17826   clib_memcpy (mp->hw_addr, hw_addr, 6);
17827   mp->use_random_hw_addr = random_hw_addr;
17828   vec_free (host_if_name);
17829
17830   S (mp);
17831
17832   /* *INDENT-OFF* */
17833   W2 (ret,
17834       ({
17835         if (ret == 0)
17836           fprintf (vam->ofp ? vam->ofp : stderr,
17837                    " new sw_if_index = %d\n", vam->sw_if_index);
17838       }));
17839   /* *INDENT-ON* */
17840   return ret;
17841 }
17842
17843 static int
17844 api_af_packet_delete (vat_main_t * vam)
17845 {
17846   unformat_input_t *i = vam->input;
17847   vl_api_af_packet_delete_t *mp;
17848   u8 *host_if_name = 0;
17849   int ret;
17850
17851   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17852     {
17853       if (unformat (i, "name %s", &host_if_name))
17854         vec_add1 (host_if_name, 0);
17855       else
17856         break;
17857     }
17858
17859   if (!vec_len (host_if_name))
17860     {
17861       errmsg ("host-interface name must be specified");
17862       return -99;
17863     }
17864
17865   if (vec_len (host_if_name) > 64)
17866     {
17867       errmsg ("host-interface name too long");
17868       return -99;
17869     }
17870
17871   M (AF_PACKET_DELETE, mp);
17872
17873   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
17874   vec_free (host_if_name);
17875
17876   S (mp);
17877   W (ret);
17878   return ret;
17879 }
17880
17881 static void vl_api_af_packet_details_t_handler
17882   (vl_api_af_packet_details_t * mp)
17883 {
17884   vat_main_t *vam = &vat_main;
17885
17886   print (vam->ofp, "%-16s %d",
17887          mp->host_if_name, clib_net_to_host_u32 (mp->sw_if_index));
17888 }
17889
17890 static void vl_api_af_packet_details_t_handler_json
17891   (vl_api_af_packet_details_t * mp)
17892 {
17893   vat_main_t *vam = &vat_main;
17894   vat_json_node_t *node = NULL;
17895
17896   if (VAT_JSON_ARRAY != vam->json_tree.type)
17897     {
17898       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17899       vat_json_init_array (&vam->json_tree);
17900     }
17901   node = vat_json_array_add (&vam->json_tree);
17902
17903   vat_json_init_object (node);
17904   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
17905   vat_json_object_add_string_copy (node, "dev_name", mp->host_if_name);
17906 }
17907
17908 static int
17909 api_af_packet_dump (vat_main_t * vam)
17910 {
17911   vl_api_af_packet_dump_t *mp;
17912   vl_api_control_ping_t *mp_ping;
17913   int ret;
17914
17915   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
17916   /* Get list of tap interfaces */
17917   M (AF_PACKET_DUMP, mp);
17918   S (mp);
17919
17920   /* Use a control ping for synchronization */
17921   MPING (CONTROL_PING, mp_ping);
17922   S (mp_ping);
17923
17924   W (ret);
17925   return ret;
17926 }
17927
17928 static int
17929 api_policer_add_del (vat_main_t * vam)
17930 {
17931   unformat_input_t *i = vam->input;
17932   vl_api_policer_add_del_t *mp;
17933   u8 is_add = 1;
17934   u8 *name = 0;
17935   u32 cir = 0;
17936   u32 eir = 0;
17937   u64 cb = 0;
17938   u64 eb = 0;
17939   u8 rate_type = 0;
17940   u8 round_type = 0;
17941   u8 type = 0;
17942   u8 color_aware = 0;
17943   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
17944   int ret;
17945
17946   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
17947   conform_action.dscp = 0;
17948   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
17949   exceed_action.dscp = 0;
17950   violate_action.action_type = SSE2_QOS_ACTION_DROP;
17951   violate_action.dscp = 0;
17952
17953   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17954     {
17955       if (unformat (i, "del"))
17956         is_add = 0;
17957       else if (unformat (i, "name %s", &name))
17958         vec_add1 (name, 0);
17959       else if (unformat (i, "cir %u", &cir))
17960         ;
17961       else if (unformat (i, "eir %u", &eir))
17962         ;
17963       else if (unformat (i, "cb %u", &cb))
17964         ;
17965       else if (unformat (i, "eb %u", &eb))
17966         ;
17967       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
17968                          &rate_type))
17969         ;
17970       else if (unformat (i, "round_type %U", unformat_policer_round_type,
17971                          &round_type))
17972         ;
17973       else if (unformat (i, "type %U", unformat_policer_type, &type))
17974         ;
17975       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
17976                          &conform_action))
17977         ;
17978       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
17979                          &exceed_action))
17980         ;
17981       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
17982                          &violate_action))
17983         ;
17984       else if (unformat (i, "color-aware"))
17985         color_aware = 1;
17986       else
17987         break;
17988     }
17989
17990   if (!vec_len (name))
17991     {
17992       errmsg ("policer name must be specified");
17993       return -99;
17994     }
17995
17996   if (vec_len (name) > 64)
17997     {
17998       errmsg ("policer name too long");
17999       return -99;
18000     }
18001
18002   M (POLICER_ADD_DEL, mp);
18003
18004   clib_memcpy (mp->name, name, vec_len (name));
18005   vec_free (name);
18006   mp->is_add = is_add;
18007   mp->cir = ntohl (cir);
18008   mp->eir = ntohl (eir);
18009   mp->cb = clib_net_to_host_u64 (cb);
18010   mp->eb = clib_net_to_host_u64 (eb);
18011   mp->rate_type = rate_type;
18012   mp->round_type = round_type;
18013   mp->type = type;
18014   mp->conform_action_type = conform_action.action_type;
18015   mp->conform_dscp = conform_action.dscp;
18016   mp->exceed_action_type = exceed_action.action_type;
18017   mp->exceed_dscp = exceed_action.dscp;
18018   mp->violate_action_type = violate_action.action_type;
18019   mp->violate_dscp = violate_action.dscp;
18020   mp->color_aware = color_aware;
18021
18022   S (mp);
18023   W (ret);
18024   return ret;
18025 }
18026
18027 static int
18028 api_policer_dump (vat_main_t * vam)
18029 {
18030   unformat_input_t *i = vam->input;
18031   vl_api_policer_dump_t *mp;
18032   vl_api_control_ping_t *mp_ping;
18033   u8 *match_name = 0;
18034   u8 match_name_valid = 0;
18035   int ret;
18036
18037   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18038     {
18039       if (unformat (i, "name %s", &match_name))
18040         {
18041           vec_add1 (match_name, 0);
18042           match_name_valid = 1;
18043         }
18044       else
18045         break;
18046     }
18047
18048   M (POLICER_DUMP, mp);
18049   mp->match_name_valid = match_name_valid;
18050   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
18051   vec_free (match_name);
18052   /* send it... */
18053   S (mp);
18054
18055   /* Use a control ping for synchronization */
18056   MPING (CONTROL_PING, mp_ping);
18057   S (mp_ping);
18058
18059   /* Wait for a reply... */
18060   W (ret);
18061   return ret;
18062 }
18063
18064 static int
18065 api_policer_classify_set_interface (vat_main_t * vam)
18066 {
18067   unformat_input_t *i = vam->input;
18068   vl_api_policer_classify_set_interface_t *mp;
18069   u32 sw_if_index;
18070   int sw_if_index_set;
18071   u32 ip4_table_index = ~0;
18072   u32 ip6_table_index = ~0;
18073   u32 l2_table_index = ~0;
18074   u8 is_add = 1;
18075   int ret;
18076
18077   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18078     {
18079       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18080         sw_if_index_set = 1;
18081       else if (unformat (i, "sw_if_index %d", &sw_if_index))
18082         sw_if_index_set = 1;
18083       else if (unformat (i, "del"))
18084         is_add = 0;
18085       else if (unformat (i, "ip4-table %d", &ip4_table_index))
18086         ;
18087       else if (unformat (i, "ip6-table %d", &ip6_table_index))
18088         ;
18089       else if (unformat (i, "l2-table %d", &l2_table_index))
18090         ;
18091       else
18092         {
18093           clib_warning ("parse error '%U'", format_unformat_error, i);
18094           return -99;
18095         }
18096     }
18097
18098   if (sw_if_index_set == 0)
18099     {
18100       errmsg ("missing interface name or sw_if_index");
18101       return -99;
18102     }
18103
18104   M (POLICER_CLASSIFY_SET_INTERFACE, mp);
18105
18106   mp->sw_if_index = ntohl (sw_if_index);
18107   mp->ip4_table_index = ntohl (ip4_table_index);
18108   mp->ip6_table_index = ntohl (ip6_table_index);
18109   mp->l2_table_index = ntohl (l2_table_index);
18110   mp->is_add = is_add;
18111
18112   S (mp);
18113   W (ret);
18114   return ret;
18115 }
18116
18117 static int
18118 api_policer_classify_dump (vat_main_t * vam)
18119 {
18120   unformat_input_t *i = vam->input;
18121   vl_api_policer_classify_dump_t *mp;
18122   vl_api_control_ping_t *mp_ping;
18123   u8 type = POLICER_CLASSIFY_N_TABLES;
18124   int ret;
18125
18126   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
18127     ;
18128   else
18129     {
18130       errmsg ("classify table type must be specified");
18131       return -99;
18132     }
18133
18134   if (!vam->json_output)
18135     {
18136       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
18137     }
18138
18139   M (POLICER_CLASSIFY_DUMP, mp);
18140   mp->type = type;
18141   /* send it... */
18142   S (mp);
18143
18144   /* Use a control ping for synchronization */
18145   MPING (CONTROL_PING, mp_ping);
18146   S (mp_ping);
18147
18148   /* Wait for a reply... */
18149   W (ret);
18150   return ret;
18151 }
18152
18153 static int
18154 api_netmap_create (vat_main_t * vam)
18155 {
18156   unformat_input_t *i = vam->input;
18157   vl_api_netmap_create_t *mp;
18158   u8 *if_name = 0;
18159   u8 hw_addr[6];
18160   u8 random_hw_addr = 1;
18161   u8 is_pipe = 0;
18162   u8 is_master = 0;
18163   int ret;
18164
18165   clib_memset (hw_addr, 0, sizeof (hw_addr));
18166
18167   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18168     {
18169       if (unformat (i, "name %s", &if_name))
18170         vec_add1 (if_name, 0);
18171       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
18172         random_hw_addr = 0;
18173       else if (unformat (i, "pipe"))
18174         is_pipe = 1;
18175       else if (unformat (i, "master"))
18176         is_master = 1;
18177       else if (unformat (i, "slave"))
18178         is_master = 0;
18179       else
18180         break;
18181     }
18182
18183   if (!vec_len (if_name))
18184     {
18185       errmsg ("interface name must be specified");
18186       return -99;
18187     }
18188
18189   if (vec_len (if_name) > 64)
18190     {
18191       errmsg ("interface name too long");
18192       return -99;
18193     }
18194
18195   M (NETMAP_CREATE, mp);
18196
18197   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
18198   clib_memcpy (mp->hw_addr, hw_addr, 6);
18199   mp->use_random_hw_addr = random_hw_addr;
18200   mp->is_pipe = is_pipe;
18201   mp->is_master = is_master;
18202   vec_free (if_name);
18203
18204   S (mp);
18205   W (ret);
18206   return ret;
18207 }
18208
18209 static int
18210 api_netmap_delete (vat_main_t * vam)
18211 {
18212   unformat_input_t *i = vam->input;
18213   vl_api_netmap_delete_t *mp;
18214   u8 *if_name = 0;
18215   int ret;
18216
18217   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18218     {
18219       if (unformat (i, "name %s", &if_name))
18220         vec_add1 (if_name, 0);
18221       else
18222         break;
18223     }
18224
18225   if (!vec_len (if_name))
18226     {
18227       errmsg ("interface name must be specified");
18228       return -99;
18229     }
18230
18231   if (vec_len (if_name) > 64)
18232     {
18233       errmsg ("interface name too long");
18234       return -99;
18235     }
18236
18237   M (NETMAP_DELETE, mp);
18238
18239   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
18240   vec_free (if_name);
18241
18242   S (mp);
18243   W (ret);
18244   return ret;
18245 }
18246
18247 static u8 *
18248 format_fib_api_path_nh_proto (u8 * s, va_list * args)
18249 {
18250   vl_api_fib_path_nh_proto_t proto =
18251     va_arg (*args, vl_api_fib_path_nh_proto_t);
18252
18253   switch (proto)
18254     {
18255     case FIB_API_PATH_NH_PROTO_IP4:
18256       s = format (s, "ip4");
18257       break;
18258     case FIB_API_PATH_NH_PROTO_IP6:
18259       s = format (s, "ip6");
18260       break;
18261     case FIB_API_PATH_NH_PROTO_MPLS:
18262       s = format (s, "mpls");
18263       break;
18264     case FIB_API_PATH_NH_PROTO_BIER:
18265       s = format (s, "bier");
18266       break;
18267     case FIB_API_PATH_NH_PROTO_ETHERNET:
18268       s = format (s, "ethernet");
18269       break;
18270     }
18271
18272   return (s);
18273 }
18274
18275 static u8 *
18276 format_vl_api_ip_address_union (u8 * s, va_list * args)
18277 {
18278   vl_api_address_family_t af = va_arg (*args, vl_api_address_family_t);
18279   const vl_api_address_union_t *u = va_arg (*args, vl_api_address_union_t *);
18280
18281   switch (af)
18282     {
18283     case ADDRESS_IP4:
18284       s = format (s, "%U", format_ip4_address, u->ip4);
18285       break;
18286     case ADDRESS_IP6:
18287       s = format (s, "%U", format_ip6_address, u->ip6);
18288       break;
18289     }
18290   return (s);
18291 }
18292
18293 static u8 *
18294 format_vl_api_fib_path_type (u8 * s, va_list * args)
18295 {
18296   vl_api_fib_path_type_t t = va_arg (*args, vl_api_fib_path_type_t);
18297
18298   switch (t)
18299     {
18300     case FIB_API_PATH_TYPE_NORMAL:
18301       s = format (s, "normal");
18302       break;
18303     case FIB_API_PATH_TYPE_LOCAL:
18304       s = format (s, "local");
18305       break;
18306     case FIB_API_PATH_TYPE_DROP:
18307       s = format (s, "drop");
18308       break;
18309     case FIB_API_PATH_TYPE_UDP_ENCAP:
18310       s = format (s, "udp-encap");
18311       break;
18312     case FIB_API_PATH_TYPE_BIER_IMP:
18313       s = format (s, "bier-imp");
18314       break;
18315     case FIB_API_PATH_TYPE_ICMP_UNREACH:
18316       s = format (s, "unreach");
18317       break;
18318     case FIB_API_PATH_TYPE_ICMP_PROHIBIT:
18319       s = format (s, "prohibit");
18320       break;
18321     case FIB_API_PATH_TYPE_SOURCE_LOOKUP:
18322       s = format (s, "src-lookup");
18323       break;
18324     case FIB_API_PATH_TYPE_DVR:
18325       s = format (s, "dvr");
18326       break;
18327     case FIB_API_PATH_TYPE_INTERFACE_RX:
18328       s = format (s, "interface-rx");
18329       break;
18330     case FIB_API_PATH_TYPE_CLASSIFY:
18331       s = format (s, "classify");
18332       break;
18333     }
18334
18335   return (s);
18336 }
18337
18338 static void
18339 vl_api_fib_path_print (vat_main_t * vam, vl_api_fib_path_t * fp)
18340 {
18341   print (vam->ofp,
18342          "  weight %d, sw_if_index %d, type %U, afi %U, next_hop %U",
18343          ntohl (fp->weight), ntohl (fp->sw_if_index),
18344          format_vl_api_fib_path_type, fp->type,
18345          format_fib_api_path_nh_proto, fp->proto,
18346          format_vl_api_ip_address_union, &fp->nh.address);
18347 }
18348
18349 static void
18350 vl_api_mpls_fib_path_json_print (vat_json_node_t * node,
18351                                  vl_api_fib_path_t * fp)
18352 {
18353   struct in_addr ip4;
18354   struct in6_addr ip6;
18355
18356   vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
18357   vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
18358   vat_json_object_add_uint (node, "type", fp->type);
18359   vat_json_object_add_uint (node, "next_hop_proto", fp->proto);
18360   if (fp->proto == FIB_API_PATH_NH_PROTO_IP4)
18361     {
18362       clib_memcpy (&ip4, &fp->nh.address.ip4, sizeof (ip4));
18363       vat_json_object_add_ip4 (node, "next_hop", ip4);
18364     }
18365   else if (fp->proto == FIB_API_PATH_NH_PROTO_IP4)
18366     {
18367       clib_memcpy (&ip6, &fp->nh.address.ip6, sizeof (ip6));
18368       vat_json_object_add_ip6 (node, "next_hop", ip6);
18369     }
18370 }
18371
18372 static void
18373 vl_api_mpls_tunnel_details_t_handler (vl_api_mpls_tunnel_details_t * mp)
18374 {
18375   vat_main_t *vam = &vat_main;
18376   int count = ntohl (mp->mt_tunnel.mt_n_paths);
18377   vl_api_fib_path_t *fp;
18378   i32 i;
18379
18380   print (vam->ofp, "sw_if_index %d via:",
18381          ntohl (mp->mt_tunnel.mt_sw_if_index));
18382   fp = mp->mt_tunnel.mt_paths;
18383   for (i = 0; i < count; i++)
18384     {
18385       vl_api_fib_path_print (vam, fp);
18386       fp++;
18387     }
18388
18389   print (vam->ofp, "");
18390 }
18391
18392 #define vl_api_mpls_tunnel_details_t_endian vl_noop_handler
18393 #define vl_api_mpls_tunnel_details_t_print vl_noop_handler
18394
18395 static void
18396 vl_api_mpls_tunnel_details_t_handler_json (vl_api_mpls_tunnel_details_t * mp)
18397 {
18398   vat_main_t *vam = &vat_main;
18399   vat_json_node_t *node = NULL;
18400   int count = ntohl (mp->mt_tunnel.mt_n_paths);
18401   vl_api_fib_path_t *fp;
18402   i32 i;
18403
18404   if (VAT_JSON_ARRAY != vam->json_tree.type)
18405     {
18406       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18407       vat_json_init_array (&vam->json_tree);
18408     }
18409   node = vat_json_array_add (&vam->json_tree);
18410
18411   vat_json_init_object (node);
18412   vat_json_object_add_uint (node, "sw_if_index",
18413                             ntohl (mp->mt_tunnel.mt_sw_if_index));
18414
18415   vat_json_object_add_uint (node, "l2_only", mp->mt_tunnel.mt_l2_only);
18416
18417   fp = mp->mt_tunnel.mt_paths;
18418   for (i = 0; i < count; i++)
18419     {
18420       vl_api_mpls_fib_path_json_print (node, fp);
18421       fp++;
18422     }
18423 }
18424
18425 static int
18426 api_mpls_tunnel_dump (vat_main_t * vam)
18427 {
18428   vl_api_mpls_tunnel_dump_t *mp;
18429   vl_api_control_ping_t *mp_ping;
18430   int ret;
18431
18432   M (MPLS_TUNNEL_DUMP, mp);
18433
18434   S (mp);
18435
18436   /* Use a control ping for synchronization */
18437   MPING (CONTROL_PING, mp_ping);
18438   S (mp_ping);
18439
18440   W (ret);
18441   return ret;
18442 }
18443
18444 #define vl_api_mpls_table_details_t_endian vl_noop_handler
18445 #define vl_api_mpls_table_details_t_print vl_noop_handler
18446
18447
18448 static void
18449 vl_api_mpls_table_details_t_handler (vl_api_mpls_table_details_t * mp)
18450 {
18451   vat_main_t *vam = &vat_main;
18452
18453   print (vam->ofp, "table-id %d,", ntohl (mp->mt_table.mt_table_id));
18454 }
18455
18456 static void vl_api_mpls_table_details_t_handler_json
18457   (vl_api_mpls_table_details_t * mp)
18458 {
18459   vat_main_t *vam = &vat_main;
18460   vat_json_node_t *node = NULL;
18461
18462   if (VAT_JSON_ARRAY != vam->json_tree.type)
18463     {
18464       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18465       vat_json_init_array (&vam->json_tree);
18466     }
18467   node = vat_json_array_add (&vam->json_tree);
18468
18469   vat_json_init_object (node);
18470   vat_json_object_add_uint (node, "table", ntohl (mp->mt_table.mt_table_id));
18471 }
18472
18473 static int
18474 api_mpls_table_dump (vat_main_t * vam)
18475 {
18476   vl_api_mpls_table_dump_t *mp;
18477   vl_api_control_ping_t *mp_ping;
18478   int ret;
18479
18480   M (MPLS_TABLE_DUMP, mp);
18481   S (mp);
18482
18483   /* Use a control ping for synchronization */
18484   MPING (CONTROL_PING, mp_ping);
18485   S (mp_ping);
18486
18487   W (ret);
18488   return ret;
18489 }
18490
18491 #define vl_api_mpls_route_details_t_endian vl_noop_handler
18492 #define vl_api_mpls_route_details_t_print vl_noop_handler
18493
18494 static void
18495 vl_api_mpls_route_details_t_handler (vl_api_mpls_route_details_t * mp)
18496 {
18497   vat_main_t *vam = &vat_main;
18498   int count = (int) clib_net_to_host_u32 (mp->mr_route.mr_n_paths);
18499   vl_api_fib_path_t *fp;
18500   int i;
18501
18502   print (vam->ofp,
18503          "table-id %d, label %u, ess_bit %u",
18504          ntohl (mp->mr_route.mr_table_id),
18505          ntohl (mp->mr_route.mr_label), mp->mr_route.mr_eos);
18506   fp = mp->mr_route.mr_paths;
18507   for (i = 0; i < count; i++)
18508     {
18509       vl_api_fib_path_print (vam, fp);
18510       fp++;
18511     }
18512 }
18513
18514 static void vl_api_mpls_route_details_t_handler_json
18515   (vl_api_mpls_route_details_t * mp)
18516 {
18517   vat_main_t *vam = &vat_main;
18518   int count = (int) clib_host_to_net_u32 (mp->mr_route.mr_n_paths);
18519   vat_json_node_t *node = NULL;
18520   vl_api_fib_path_t *fp;
18521   int i;
18522
18523   if (VAT_JSON_ARRAY != vam->json_tree.type)
18524     {
18525       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18526       vat_json_init_array (&vam->json_tree);
18527     }
18528   node = vat_json_array_add (&vam->json_tree);
18529
18530   vat_json_init_object (node);
18531   vat_json_object_add_uint (node, "table", ntohl (mp->mr_route.mr_table_id));
18532   vat_json_object_add_uint (node, "s_bit", mp->mr_route.mr_eos);
18533   vat_json_object_add_uint (node, "label", ntohl (mp->mr_route.mr_label));
18534   vat_json_object_add_uint (node, "path_count", count);
18535   fp = mp->mr_route.mr_paths;
18536   for (i = 0; i < count; i++)
18537     {
18538       vl_api_mpls_fib_path_json_print (node, fp);
18539       fp++;
18540     }
18541 }
18542
18543 static int
18544 api_mpls_route_dump (vat_main_t * vam)
18545 {
18546   unformat_input_t *input = vam->input;
18547   vl_api_mpls_route_dump_t *mp;
18548   vl_api_control_ping_t *mp_ping;
18549   u32 table_id;
18550   int ret;
18551
18552   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18553     {
18554       if (unformat (input, "table_id %d", &table_id))
18555         ;
18556       else
18557         break;
18558     }
18559   if (table_id == ~0)
18560     {
18561       errmsg ("missing table id");
18562       return -99;
18563     }
18564
18565   M (MPLS_ROUTE_DUMP, mp);
18566
18567   mp->table.mt_table_id = ntohl (table_id);
18568   S (mp);
18569
18570   /* Use a control ping for synchronization */
18571   MPING (CONTROL_PING, mp_ping);
18572   S (mp_ping);
18573
18574   W (ret);
18575   return ret;
18576 }
18577
18578 #define vl_api_ip_table_details_t_endian vl_noop_handler
18579 #define vl_api_ip_table_details_t_print vl_noop_handler
18580
18581 static void
18582 vl_api_ip_table_details_t_handler (vl_api_ip_table_details_t * mp)
18583 {
18584   vat_main_t *vam = &vat_main;
18585
18586   print (vam->ofp,
18587          "%s; table-id %d, prefix %U/%d",
18588          mp->table.name, ntohl (mp->table.table_id));
18589 }
18590
18591
18592 static void vl_api_ip_table_details_t_handler_json
18593   (vl_api_ip_table_details_t * mp)
18594 {
18595   vat_main_t *vam = &vat_main;
18596   vat_json_node_t *node = NULL;
18597
18598   if (VAT_JSON_ARRAY != vam->json_tree.type)
18599     {
18600       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18601       vat_json_init_array (&vam->json_tree);
18602     }
18603   node = vat_json_array_add (&vam->json_tree);
18604
18605   vat_json_init_object (node);
18606   vat_json_object_add_uint (node, "table", ntohl (mp->table.table_id));
18607 }
18608
18609 static int
18610 api_ip_table_dump (vat_main_t * vam)
18611 {
18612   vl_api_ip_table_dump_t *mp;
18613   vl_api_control_ping_t *mp_ping;
18614   int ret;
18615
18616   M (IP_TABLE_DUMP, mp);
18617   S (mp);
18618
18619   /* Use a control ping for synchronization */
18620   MPING (CONTROL_PING, mp_ping);
18621   S (mp_ping);
18622
18623   W (ret);
18624   return ret;
18625 }
18626
18627 static int
18628 api_ip_mtable_dump (vat_main_t * vam)
18629 {
18630   vl_api_ip_mtable_dump_t *mp;
18631   vl_api_control_ping_t *mp_ping;
18632   int ret;
18633
18634   M (IP_MTABLE_DUMP, mp);
18635   S (mp);
18636
18637   /* Use a control ping for synchronization */
18638   MPING (CONTROL_PING, mp_ping);
18639   S (mp_ping);
18640
18641   W (ret);
18642   return ret;
18643 }
18644
18645 static int
18646 api_ip_mroute_dump (vat_main_t * vam)
18647 {
18648   unformat_input_t *input = vam->input;
18649   vl_api_control_ping_t *mp_ping;
18650   vl_api_ip_mroute_dump_t *mp;
18651   int ret, is_ip6;
18652   u32 table_id;
18653
18654   is_ip6 = 0;
18655   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18656     {
18657       if (unformat (input, "table_id %d", &table_id))
18658         ;
18659       else if (unformat (input, "ip6"))
18660         is_ip6 = 1;
18661       else if (unformat (input, "ip4"))
18662         is_ip6 = 0;
18663       else
18664         break;
18665     }
18666   if (table_id == ~0)
18667     {
18668       errmsg ("missing table id");
18669       return -99;
18670     }
18671
18672   M (IP_MROUTE_DUMP, mp);
18673   mp->table.table_id = table_id;
18674   mp->table.is_ip6 = is_ip6;
18675   S (mp);
18676
18677   /* Use a control ping for synchronization */
18678   MPING (CONTROL_PING, mp_ping);
18679   S (mp_ping);
18680
18681   W (ret);
18682   return ret;
18683 }
18684
18685 static void vl_api_ip_neighbor_details_t_handler
18686   (vl_api_ip_neighbor_details_t * mp)
18687 {
18688   vat_main_t *vam = &vat_main;
18689
18690   print (vam->ofp, "%c %U %U",
18691          (ntohl (mp->neighbor.flags) & IP_NEIGHBOR_FLAG_STATIC) ? 'S' : 'D',
18692          format_vl_api_mac_address, &mp->neighbor.mac_address,
18693          format_vl_api_address, &mp->neighbor.ip_address);
18694 }
18695
18696 static void vl_api_ip_neighbor_details_t_handler_json
18697   (vl_api_ip_neighbor_details_t * mp)
18698 {
18699
18700   vat_main_t *vam = &vat_main;
18701   vat_json_node_t *node;
18702
18703   if (VAT_JSON_ARRAY != vam->json_tree.type)
18704     {
18705       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18706       vat_json_init_array (&vam->json_tree);
18707     }
18708   node = vat_json_array_add (&vam->json_tree);
18709
18710   vat_json_init_object (node);
18711   vat_json_object_add_string_copy
18712     (node, "flag",
18713      ((ntohl (mp->neighbor.flags) & IP_NEIGHBOR_FLAG_STATIC) ?
18714       (u8 *) "static" : (u8 *) "dynamic"));
18715
18716   vat_json_object_add_string_copy (node, "link_layer",
18717                                    format (0, "%U", format_vl_api_mac_address,
18718                                            &mp->neighbor.mac_address));
18719   vat_json_object_add_address (node, "ip", &mp->neighbor.ip_address);
18720 }
18721
18722 static int
18723 api_ip_neighbor_dump (vat_main_t * vam)
18724 {
18725   unformat_input_t *i = vam->input;
18726   vl_api_ip_neighbor_dump_t *mp;
18727   vl_api_control_ping_t *mp_ping;
18728   u8 is_ipv6 = 0;
18729   u32 sw_if_index = ~0;
18730   int ret;
18731
18732   /* Parse args required to build the message */
18733   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18734     {
18735       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18736         ;
18737       else if (unformat (i, "sw_if_index %d", &sw_if_index))
18738         ;
18739       else if (unformat (i, "ip6"))
18740         is_ipv6 = 1;
18741       else
18742         break;
18743     }
18744
18745   if (sw_if_index == ~0)
18746     {
18747       errmsg ("missing interface name or sw_if_index");
18748       return -99;
18749     }
18750
18751   M (IP_NEIGHBOR_DUMP, mp);
18752   mp->is_ipv6 = (u8) is_ipv6;
18753   mp->sw_if_index = ntohl (sw_if_index);
18754   S (mp);
18755
18756   /* Use a control ping for synchronization */
18757   MPING (CONTROL_PING, mp_ping);
18758   S (mp_ping);
18759
18760   W (ret);
18761   return ret;
18762 }
18763
18764 #define vl_api_ip_route_details_t_endian vl_noop_handler
18765 #define vl_api_ip_route_details_t_print vl_noop_handler
18766
18767 static void
18768 vl_api_ip_route_details_t_handler (vl_api_ip_route_details_t * mp)
18769 {
18770   vat_main_t *vam = &vat_main;
18771   u8 count = mp->route.n_paths;
18772   vl_api_fib_path_t *fp;
18773   int i;
18774
18775   print (vam->ofp,
18776          "table-id %d, prefix %U/%d",
18777          ntohl (mp->route.table_id),
18778          format_ip46_address, mp->route.prefix.address, mp->route.prefix.len);
18779   for (i = 0; i < count; i++)
18780     {
18781       fp = &mp->route.paths[i];
18782
18783       vl_api_fib_path_print (vam, fp);
18784       fp++;
18785     }
18786 }
18787
18788 static void vl_api_ip_route_details_t_handler_json
18789   (vl_api_ip_route_details_t * mp)
18790 {
18791   vat_main_t *vam = &vat_main;
18792   u8 count = mp->route.n_paths;
18793   vat_json_node_t *node = NULL;
18794   struct in_addr ip4;
18795   struct in6_addr ip6;
18796   vl_api_fib_path_t *fp;
18797   int i;
18798
18799   if (VAT_JSON_ARRAY != vam->json_tree.type)
18800     {
18801       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18802       vat_json_init_array (&vam->json_tree);
18803     }
18804   node = vat_json_array_add (&vam->json_tree);
18805
18806   vat_json_init_object (node);
18807   vat_json_object_add_uint (node, "table", ntohl (mp->route.table_id));
18808   if (ADDRESS_IP6 == mp->route.prefix.address.af)
18809     {
18810       clib_memcpy (&ip6, &mp->route.prefix.address.un.ip6, sizeof (ip6));
18811       vat_json_object_add_ip6 (node, "prefix", ip6);
18812     }
18813   else
18814     {
18815       clib_memcpy (&ip4, &mp->route.prefix.address.un.ip4, sizeof (ip4));
18816       vat_json_object_add_ip4 (node, "prefix", ip4);
18817     }
18818   vat_json_object_add_uint (node, "mask_length", mp->route.prefix.len);
18819   vat_json_object_add_uint (node, "path_count", count);
18820   for (i = 0; i < count; i++)
18821     {
18822       fp = &mp->route.paths[i];
18823       vl_api_mpls_fib_path_json_print (node, fp);
18824     }
18825 }
18826
18827 static int
18828 api_ip_route_dump (vat_main_t * vam)
18829 {
18830   unformat_input_t *input = vam->input;
18831   vl_api_ip_route_dump_t *mp;
18832   vl_api_control_ping_t *mp_ping;
18833   u32 table_id;
18834   u8 is_ip6;
18835   int ret;
18836
18837   is_ip6 = 0;
18838   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18839     {
18840       if (unformat (input, "table_id %d", &table_id))
18841         ;
18842       else if (unformat (input, "ip6"))
18843         is_ip6 = 1;
18844       else if (unformat (input, "ip4"))
18845         is_ip6 = 0;
18846       else
18847         break;
18848     }
18849   if (table_id == ~0)
18850     {
18851       errmsg ("missing table id");
18852       return -99;
18853     }
18854
18855   M (IP_ROUTE_DUMP, mp);
18856
18857   mp->table.table_id = table_id;
18858   mp->table.is_ip6 = is_ip6;
18859
18860   S (mp);
18861
18862   /* Use a control ping for synchronization */
18863   MPING (CONTROL_PING, mp_ping);
18864   S (mp_ping);
18865
18866   W (ret);
18867   return ret;
18868 }
18869
18870 int
18871 api_classify_table_ids (vat_main_t * vam)
18872 {
18873   vl_api_classify_table_ids_t *mp;
18874   int ret;
18875
18876   /* Construct the API message */
18877   M (CLASSIFY_TABLE_IDS, mp);
18878   mp->context = 0;
18879
18880   S (mp);
18881   W (ret);
18882   return ret;
18883 }
18884
18885 int
18886 api_classify_table_by_interface (vat_main_t * vam)
18887 {
18888   unformat_input_t *input = vam->input;
18889   vl_api_classify_table_by_interface_t *mp;
18890
18891   u32 sw_if_index = ~0;
18892   int ret;
18893   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18894     {
18895       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18896         ;
18897       else if (unformat (input, "sw_if_index %d", &sw_if_index))
18898         ;
18899       else
18900         break;
18901     }
18902   if (sw_if_index == ~0)
18903     {
18904       errmsg ("missing interface name or sw_if_index");
18905       return -99;
18906     }
18907
18908   /* Construct the API message */
18909   M (CLASSIFY_TABLE_BY_INTERFACE, mp);
18910   mp->context = 0;
18911   mp->sw_if_index = ntohl (sw_if_index);
18912
18913   S (mp);
18914   W (ret);
18915   return ret;
18916 }
18917
18918 int
18919 api_classify_table_info (vat_main_t * vam)
18920 {
18921   unformat_input_t *input = vam->input;
18922   vl_api_classify_table_info_t *mp;
18923
18924   u32 table_id = ~0;
18925   int ret;
18926   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18927     {
18928       if (unformat (input, "table_id %d", &table_id))
18929         ;
18930       else
18931         break;
18932     }
18933   if (table_id == ~0)
18934     {
18935       errmsg ("missing table id");
18936       return -99;
18937     }
18938
18939   /* Construct the API message */
18940   M (CLASSIFY_TABLE_INFO, mp);
18941   mp->context = 0;
18942   mp->table_id = ntohl (table_id);
18943
18944   S (mp);
18945   W (ret);
18946   return ret;
18947 }
18948
18949 int
18950 api_classify_session_dump (vat_main_t * vam)
18951 {
18952   unformat_input_t *input = vam->input;
18953   vl_api_classify_session_dump_t *mp;
18954   vl_api_control_ping_t *mp_ping;
18955
18956   u32 table_id = ~0;
18957   int ret;
18958   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18959     {
18960       if (unformat (input, "table_id %d", &table_id))
18961         ;
18962       else
18963         break;
18964     }
18965   if (table_id == ~0)
18966     {
18967       errmsg ("missing table id");
18968       return -99;
18969     }
18970
18971   /* Construct the API message */
18972   M (CLASSIFY_SESSION_DUMP, mp);
18973   mp->context = 0;
18974   mp->table_id = ntohl (table_id);
18975   S (mp);
18976
18977   /* Use a control ping for synchronization */
18978   MPING (CONTROL_PING, mp_ping);
18979   S (mp_ping);
18980
18981   W (ret);
18982   return ret;
18983 }
18984
18985 static void
18986 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
18987 {
18988   vat_main_t *vam = &vat_main;
18989
18990   print (vam->ofp, "collector_address %U, collector_port %d, "
18991          "src_address %U, vrf_id %d, path_mtu %u, "
18992          "template_interval %u, udp_checksum %d",
18993          format_ip4_address, mp->collector_address,
18994          ntohs (mp->collector_port),
18995          format_ip4_address, mp->src_address,
18996          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
18997          ntohl (mp->template_interval), mp->udp_checksum);
18998
18999   vam->retval = 0;
19000   vam->result_ready = 1;
19001 }
19002
19003 static void
19004   vl_api_ipfix_exporter_details_t_handler_json
19005   (vl_api_ipfix_exporter_details_t * mp)
19006 {
19007   vat_main_t *vam = &vat_main;
19008   vat_json_node_t node;
19009   struct in_addr collector_address;
19010   struct in_addr src_address;
19011
19012   vat_json_init_object (&node);
19013   clib_memcpy (&collector_address, &mp->collector_address,
19014                sizeof (collector_address));
19015   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
19016   vat_json_object_add_uint (&node, "collector_port",
19017                             ntohs (mp->collector_port));
19018   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
19019   vat_json_object_add_ip4 (&node, "src_address", src_address);
19020   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
19021   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
19022   vat_json_object_add_uint (&node, "template_interval",
19023                             ntohl (mp->template_interval));
19024   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
19025
19026   vat_json_print (vam->ofp, &node);
19027   vat_json_free (&node);
19028   vam->retval = 0;
19029   vam->result_ready = 1;
19030 }
19031
19032 int
19033 api_ipfix_exporter_dump (vat_main_t * vam)
19034 {
19035   vl_api_ipfix_exporter_dump_t *mp;
19036   int ret;
19037
19038   /* Construct the API message */
19039   M (IPFIX_EXPORTER_DUMP, mp);
19040   mp->context = 0;
19041
19042   S (mp);
19043   W (ret);
19044   return ret;
19045 }
19046
19047 static int
19048 api_ipfix_classify_stream_dump (vat_main_t * vam)
19049 {
19050   vl_api_ipfix_classify_stream_dump_t *mp;
19051   int ret;
19052
19053   /* Construct the API message */
19054   M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
19055   mp->context = 0;
19056
19057   S (mp);
19058   W (ret);
19059   return ret;
19060   /* NOTREACHED */
19061   return 0;
19062 }
19063
19064 static void
19065   vl_api_ipfix_classify_stream_details_t_handler
19066   (vl_api_ipfix_classify_stream_details_t * mp)
19067 {
19068   vat_main_t *vam = &vat_main;
19069   print (vam->ofp, "domain_id %d, src_port %d",
19070          ntohl (mp->domain_id), ntohs (mp->src_port));
19071   vam->retval = 0;
19072   vam->result_ready = 1;
19073 }
19074
19075 static void
19076   vl_api_ipfix_classify_stream_details_t_handler_json
19077   (vl_api_ipfix_classify_stream_details_t * mp)
19078 {
19079   vat_main_t *vam = &vat_main;
19080   vat_json_node_t node;
19081
19082   vat_json_init_object (&node);
19083   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
19084   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
19085
19086   vat_json_print (vam->ofp, &node);
19087   vat_json_free (&node);
19088   vam->retval = 0;
19089   vam->result_ready = 1;
19090 }
19091
19092 static int
19093 api_ipfix_classify_table_dump (vat_main_t * vam)
19094 {
19095   vl_api_ipfix_classify_table_dump_t *mp;
19096   vl_api_control_ping_t *mp_ping;
19097   int ret;
19098
19099   if (!vam->json_output)
19100     {
19101       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
19102              "transport_protocol");
19103     }
19104
19105   /* Construct the API message */
19106   M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
19107
19108   /* send it... */
19109   S (mp);
19110
19111   /* Use a control ping for synchronization */
19112   MPING (CONTROL_PING, mp_ping);
19113   S (mp_ping);
19114
19115   W (ret);
19116   return ret;
19117 }
19118
19119 static void
19120   vl_api_ipfix_classify_table_details_t_handler
19121   (vl_api_ipfix_classify_table_details_t * mp)
19122 {
19123   vat_main_t *vam = &vat_main;
19124   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
19125          mp->transport_protocol);
19126 }
19127
19128 static void
19129   vl_api_ipfix_classify_table_details_t_handler_json
19130   (vl_api_ipfix_classify_table_details_t * mp)
19131 {
19132   vat_json_node_t *node = NULL;
19133   vat_main_t *vam = &vat_main;
19134
19135   if (VAT_JSON_ARRAY != vam->json_tree.type)
19136     {
19137       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19138       vat_json_init_array (&vam->json_tree);
19139     }
19140
19141   node = vat_json_array_add (&vam->json_tree);
19142   vat_json_init_object (node);
19143
19144   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
19145   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
19146   vat_json_object_add_uint (node, "transport_protocol",
19147                             mp->transport_protocol);
19148 }
19149
19150 static int
19151 api_sw_interface_span_enable_disable (vat_main_t * vam)
19152 {
19153   unformat_input_t *i = vam->input;
19154   vl_api_sw_interface_span_enable_disable_t *mp;
19155   u32 src_sw_if_index = ~0;
19156   u32 dst_sw_if_index = ~0;
19157   u8 state = 3;
19158   int ret;
19159   u8 is_l2 = 0;
19160
19161   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19162     {
19163       if (unformat
19164           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
19165         ;
19166       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
19167         ;
19168       else
19169         if (unformat
19170             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
19171         ;
19172       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
19173         ;
19174       else if (unformat (i, "disable"))
19175         state = 0;
19176       else if (unformat (i, "rx"))
19177         state = 1;
19178       else if (unformat (i, "tx"))
19179         state = 2;
19180       else if (unformat (i, "both"))
19181         state = 3;
19182       else if (unformat (i, "l2"))
19183         is_l2 = 1;
19184       else
19185         break;
19186     }
19187
19188   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
19189
19190   mp->sw_if_index_from = htonl (src_sw_if_index);
19191   mp->sw_if_index_to = htonl (dst_sw_if_index);
19192   mp->state = state;
19193   mp->is_l2 = is_l2;
19194
19195   S (mp);
19196   W (ret);
19197   return ret;
19198 }
19199
19200 static void
19201 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
19202                                             * mp)
19203 {
19204   vat_main_t *vam = &vat_main;
19205   u8 *sw_if_from_name = 0;
19206   u8 *sw_if_to_name = 0;
19207   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
19208   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
19209   char *states[] = { "none", "rx", "tx", "both" };
19210   hash_pair_t *p;
19211
19212   /* *INDENT-OFF* */
19213   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
19214   ({
19215     if ((u32) p->value[0] == sw_if_index_from)
19216       {
19217         sw_if_from_name = (u8 *)(p->key);
19218         if (sw_if_to_name)
19219           break;
19220       }
19221     if ((u32) p->value[0] == sw_if_index_to)
19222       {
19223         sw_if_to_name = (u8 *)(p->key);
19224         if (sw_if_from_name)
19225           break;
19226       }
19227   }));
19228   /* *INDENT-ON* */
19229   print (vam->ofp, "%20s => %20s (%s) %s",
19230          sw_if_from_name, sw_if_to_name, states[mp->state],
19231          mp->is_l2 ? "l2" : "device");
19232 }
19233
19234 static void
19235   vl_api_sw_interface_span_details_t_handler_json
19236   (vl_api_sw_interface_span_details_t * mp)
19237 {
19238   vat_main_t *vam = &vat_main;
19239   vat_json_node_t *node = NULL;
19240   u8 *sw_if_from_name = 0;
19241   u8 *sw_if_to_name = 0;
19242   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
19243   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
19244   hash_pair_t *p;
19245
19246   /* *INDENT-OFF* */
19247   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
19248   ({
19249     if ((u32) p->value[0] == sw_if_index_from)
19250       {
19251         sw_if_from_name = (u8 *)(p->key);
19252         if (sw_if_to_name)
19253           break;
19254       }
19255     if ((u32) p->value[0] == sw_if_index_to)
19256       {
19257         sw_if_to_name = (u8 *)(p->key);
19258         if (sw_if_from_name)
19259           break;
19260       }
19261   }));
19262   /* *INDENT-ON* */
19263
19264   if (VAT_JSON_ARRAY != vam->json_tree.type)
19265     {
19266       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19267       vat_json_init_array (&vam->json_tree);
19268     }
19269   node = vat_json_array_add (&vam->json_tree);
19270
19271   vat_json_init_object (node);
19272   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
19273   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
19274   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
19275   if (0 != sw_if_to_name)
19276     {
19277       vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
19278     }
19279   vat_json_object_add_uint (node, "state", mp->state);
19280   vat_json_object_add_uint (node, "is-l2", mp->is_l2);
19281 }
19282
19283 static int
19284 api_sw_interface_span_dump (vat_main_t * vam)
19285 {
19286   unformat_input_t *input = vam->input;
19287   vl_api_sw_interface_span_dump_t *mp;
19288   vl_api_control_ping_t *mp_ping;
19289   u8 is_l2 = 0;
19290   int ret;
19291
19292   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19293     {
19294       if (unformat (input, "l2"))
19295         is_l2 = 1;
19296       else
19297         break;
19298     }
19299
19300   M (SW_INTERFACE_SPAN_DUMP, mp);
19301   mp->is_l2 = is_l2;
19302   S (mp);
19303
19304   /* Use a control ping for synchronization */
19305   MPING (CONTROL_PING, mp_ping);
19306   S (mp_ping);
19307
19308   W (ret);
19309   return ret;
19310 }
19311
19312 int
19313 api_pg_create_interface (vat_main_t * vam)
19314 {
19315   unformat_input_t *input = vam->input;
19316   vl_api_pg_create_interface_t *mp;
19317
19318   u32 if_id = ~0, gso_size = 0;
19319   u8 gso_enabled = 0;
19320   int ret;
19321   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19322     {
19323       if (unformat (input, "if_id %d", &if_id))
19324         ;
19325       else if (unformat (input, "gso-enabled"))
19326         {
19327           gso_enabled = 1;
19328           if (unformat (input, "gso-size %u", &gso_size))
19329             ;
19330           else
19331             {
19332               errmsg ("missing gso-size");
19333               return -99;
19334             }
19335         }
19336       else
19337         break;
19338     }
19339   if (if_id == ~0)
19340     {
19341       errmsg ("missing pg interface index");
19342       return -99;
19343     }
19344
19345   /* Construct the API message */
19346   M (PG_CREATE_INTERFACE, mp);
19347   mp->context = 0;
19348   mp->interface_id = ntohl (if_id);
19349   mp->gso_enabled = gso_enabled;
19350
19351   S (mp);
19352   W (ret);
19353   return ret;
19354 }
19355
19356 int
19357 api_pg_capture (vat_main_t * vam)
19358 {
19359   unformat_input_t *input = vam->input;
19360   vl_api_pg_capture_t *mp;
19361
19362   u32 if_id = ~0;
19363   u8 enable = 1;
19364   u32 count = 1;
19365   u8 pcap_file_set = 0;
19366   u8 *pcap_file = 0;
19367   int ret;
19368   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19369     {
19370       if (unformat (input, "if_id %d", &if_id))
19371         ;
19372       else if (unformat (input, "pcap %s", &pcap_file))
19373         pcap_file_set = 1;
19374       else if (unformat (input, "count %d", &count))
19375         ;
19376       else if (unformat (input, "disable"))
19377         enable = 0;
19378       else
19379         break;
19380     }
19381   if (if_id == ~0)
19382     {
19383       errmsg ("missing pg interface index");
19384       return -99;
19385     }
19386   if (pcap_file_set > 0)
19387     {
19388       if (vec_len (pcap_file) > 255)
19389         {
19390           errmsg ("pcap file name is too long");
19391           return -99;
19392         }
19393     }
19394
19395   u32 name_len = vec_len (pcap_file);
19396   /* Construct the API message */
19397   M (PG_CAPTURE, mp);
19398   mp->context = 0;
19399   mp->interface_id = ntohl (if_id);
19400   mp->is_enabled = enable;
19401   mp->count = ntohl (count);
19402   mp->pcap_name_length = ntohl (name_len);
19403   if (pcap_file_set != 0)
19404     {
19405       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
19406     }
19407   vec_free (pcap_file);
19408
19409   S (mp);
19410   W (ret);
19411   return ret;
19412 }
19413
19414 int
19415 api_pg_enable_disable (vat_main_t * vam)
19416 {
19417   unformat_input_t *input = vam->input;
19418   vl_api_pg_enable_disable_t *mp;
19419
19420   u8 enable = 1;
19421   u8 stream_name_set = 0;
19422   u8 *stream_name = 0;
19423   int ret;
19424   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19425     {
19426       if (unformat (input, "stream %s", &stream_name))
19427         stream_name_set = 1;
19428       else if (unformat (input, "disable"))
19429         enable = 0;
19430       else
19431         break;
19432     }
19433
19434   if (stream_name_set > 0)
19435     {
19436       if (vec_len (stream_name) > 255)
19437         {
19438           errmsg ("stream name too long");
19439           return -99;
19440         }
19441     }
19442
19443   u32 name_len = vec_len (stream_name);
19444   /* Construct the API message */
19445   M (PG_ENABLE_DISABLE, mp);
19446   mp->context = 0;
19447   mp->is_enabled = enable;
19448   if (stream_name_set != 0)
19449     {
19450       mp->stream_name_length = ntohl (name_len);
19451       clib_memcpy (mp->stream_name, stream_name, name_len);
19452     }
19453   vec_free (stream_name);
19454
19455   S (mp);
19456   W (ret);
19457   return ret;
19458 }
19459
19460 int
19461 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
19462 {
19463   unformat_input_t *input = vam->input;
19464   vl_api_ip_source_and_port_range_check_add_del_t *mp;
19465
19466   u16 *low_ports = 0;
19467   u16 *high_ports = 0;
19468   u16 this_low;
19469   u16 this_hi;
19470   vl_api_prefix_t prefix;
19471   u32 tmp, tmp2;
19472   u8 prefix_set = 0;
19473   u32 vrf_id = ~0;
19474   u8 is_add = 1;
19475   int ret;
19476
19477   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19478     {
19479       if (unformat (input, "%U", unformat_vl_api_prefix, &prefix))
19480         prefix_set = 1;
19481       else if (unformat (input, "vrf %d", &vrf_id))
19482         ;
19483       else if (unformat (input, "del"))
19484         is_add = 0;
19485       else if (unformat (input, "port %d", &tmp))
19486         {
19487           if (tmp == 0 || tmp > 65535)
19488             {
19489               errmsg ("port %d out of range", tmp);
19490               return -99;
19491             }
19492           this_low = tmp;
19493           this_hi = this_low + 1;
19494           vec_add1 (low_ports, this_low);
19495           vec_add1 (high_ports, this_hi);
19496         }
19497       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
19498         {
19499           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
19500             {
19501               errmsg ("incorrect range parameters");
19502               return -99;
19503             }
19504           this_low = tmp;
19505           /* Note: in debug CLI +1 is added to high before
19506              passing to real fn that does "the work"
19507              (ip_source_and_port_range_check_add_del).
19508              This fn is a wrapper around the binary API fn a
19509              control plane will call, which expects this increment
19510              to have occurred. Hence letting the binary API control
19511              plane fn do the increment for consistency between VAT
19512              and other control planes.
19513            */
19514           this_hi = tmp2;
19515           vec_add1 (low_ports, this_low);
19516           vec_add1 (high_ports, this_hi);
19517         }
19518       else
19519         break;
19520     }
19521
19522   if (prefix_set == 0)
19523     {
19524       errmsg ("<address>/<mask> not specified");
19525       return -99;
19526     }
19527
19528   if (vrf_id == ~0)
19529     {
19530       errmsg ("VRF ID required, not specified");
19531       return -99;
19532     }
19533
19534   if (vrf_id == 0)
19535     {
19536       errmsg
19537         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
19538       return -99;
19539     }
19540
19541   if (vec_len (low_ports) == 0)
19542     {
19543       errmsg ("At least one port or port range required");
19544       return -99;
19545     }
19546
19547   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
19548
19549   mp->is_add = is_add;
19550
19551   clib_memcpy (&mp->prefix, &prefix, sizeof (prefix));
19552
19553   mp->number_of_ranges = vec_len (low_ports);
19554
19555   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
19556   vec_free (low_ports);
19557
19558   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
19559   vec_free (high_ports);
19560
19561   mp->vrf_id = ntohl (vrf_id);
19562
19563   S (mp);
19564   W (ret);
19565   return ret;
19566 }
19567
19568 int
19569 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
19570 {
19571   unformat_input_t *input = vam->input;
19572   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
19573   u32 sw_if_index = ~0;
19574   int vrf_set = 0;
19575   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
19576   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
19577   u8 is_add = 1;
19578   int ret;
19579
19580   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19581     {
19582       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19583         ;
19584       else if (unformat (input, "sw_if_index %d", &sw_if_index))
19585         ;
19586       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
19587         vrf_set = 1;
19588       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
19589         vrf_set = 1;
19590       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
19591         vrf_set = 1;
19592       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
19593         vrf_set = 1;
19594       else if (unformat (input, "del"))
19595         is_add = 0;
19596       else
19597         break;
19598     }
19599
19600   if (sw_if_index == ~0)
19601     {
19602       errmsg ("Interface required but not specified");
19603       return -99;
19604     }
19605
19606   if (vrf_set == 0)
19607     {
19608       errmsg ("VRF ID required but not specified");
19609       return -99;
19610     }
19611
19612   if (tcp_out_vrf_id == 0
19613       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
19614     {
19615       errmsg
19616         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
19617       return -99;
19618     }
19619
19620   /* Construct the API message */
19621   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
19622
19623   mp->sw_if_index = ntohl (sw_if_index);
19624   mp->is_add = is_add;
19625   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
19626   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
19627   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
19628   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
19629
19630   /* send it... */
19631   S (mp);
19632
19633   /* Wait for a reply... */
19634   W (ret);
19635   return ret;
19636 }
19637
19638 static int
19639 api_set_punt (vat_main_t * vam)
19640 {
19641   unformat_input_t *i = vam->input;
19642   vl_api_address_family_t af;
19643   vl_api_set_punt_t *mp;
19644   u32 protocol = ~0;
19645   u32 port = ~0;
19646   int is_add = 1;
19647   int ret;
19648
19649   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19650     {
19651       if (unformat (i, "%U", unformat_vl_api_address_family, &af))
19652         ;
19653       else if (unformat (i, "protocol %d", &protocol))
19654         ;
19655       else if (unformat (i, "port %d", &port))
19656         ;
19657       else if (unformat (i, "del"))
19658         is_add = 0;
19659       else
19660         {
19661           clib_warning ("parse error '%U'", format_unformat_error, i);
19662           return -99;
19663         }
19664     }
19665
19666   M (SET_PUNT, mp);
19667
19668   mp->is_add = (u8) is_add;
19669   mp->punt.type = PUNT_API_TYPE_L4;
19670   mp->punt.punt.l4.af = af;
19671   mp->punt.punt.l4.protocol = (u8) protocol;
19672   mp->punt.punt.l4.port = htons ((u16) port);
19673
19674   S (mp);
19675   W (ret);
19676   return ret;
19677 }
19678
19679 static int
19680 api_delete_subif (vat_main_t * vam)
19681 {
19682   unformat_input_t *i = vam->input;
19683   vl_api_delete_subif_t *mp;
19684   u32 sw_if_index = ~0;
19685   int ret;
19686
19687   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19688     {
19689       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19690         ;
19691       if (unformat (i, "sw_if_index %d", &sw_if_index))
19692         ;
19693       else
19694         break;
19695     }
19696
19697   if (sw_if_index == ~0)
19698     {
19699       errmsg ("missing sw_if_index");
19700       return -99;
19701     }
19702
19703   /* Construct the API message */
19704   M (DELETE_SUBIF, mp);
19705   mp->sw_if_index = ntohl (sw_if_index);
19706
19707   S (mp);
19708   W (ret);
19709   return ret;
19710 }
19711
19712 #define foreach_pbb_vtr_op      \
19713 _("disable",  L2_VTR_DISABLED)  \
19714 _("pop",  L2_VTR_POP_2)         \
19715 _("push",  L2_VTR_PUSH_2)
19716
19717 static int
19718 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
19719 {
19720   unformat_input_t *i = vam->input;
19721   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
19722   u32 sw_if_index = ~0, vtr_op = ~0;
19723   u16 outer_tag = ~0;
19724   u8 dmac[6], smac[6];
19725   u8 dmac_set = 0, smac_set = 0;
19726   u16 vlanid = 0;
19727   u32 sid = ~0;
19728   u32 tmp;
19729   int ret;
19730
19731   /* Shut up coverity */
19732   clib_memset (dmac, 0, sizeof (dmac));
19733   clib_memset (smac, 0, sizeof (smac));
19734
19735   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19736     {
19737       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19738         ;
19739       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19740         ;
19741       else if (unformat (i, "vtr_op %d", &vtr_op))
19742         ;
19743 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
19744       foreach_pbb_vtr_op
19745 #undef _
19746         else if (unformat (i, "translate_pbb_stag"))
19747         {
19748           if (unformat (i, "%d", &tmp))
19749             {
19750               vtr_op = L2_VTR_TRANSLATE_2_1;
19751               outer_tag = tmp;
19752             }
19753           else
19754             {
19755               errmsg
19756                 ("translate_pbb_stag operation requires outer tag definition");
19757               return -99;
19758             }
19759         }
19760       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
19761         dmac_set++;
19762       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
19763         smac_set++;
19764       else if (unformat (i, "sid %d", &sid))
19765         ;
19766       else if (unformat (i, "vlanid %d", &tmp))
19767         vlanid = tmp;
19768       else
19769         {
19770           clib_warning ("parse error '%U'", format_unformat_error, i);
19771           return -99;
19772         }
19773     }
19774
19775   if ((sw_if_index == ~0) || (vtr_op == ~0))
19776     {
19777       errmsg ("missing sw_if_index or vtr operation");
19778       return -99;
19779     }
19780   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
19781       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
19782     {
19783       errmsg
19784         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
19785       return -99;
19786     }
19787
19788   M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
19789   mp->sw_if_index = ntohl (sw_if_index);
19790   mp->vtr_op = ntohl (vtr_op);
19791   mp->outer_tag = ntohs (outer_tag);
19792   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
19793   clib_memcpy (mp->b_smac, smac, sizeof (smac));
19794   mp->b_vlanid = ntohs (vlanid);
19795   mp->i_sid = ntohl (sid);
19796
19797   S (mp);
19798   W (ret);
19799   return ret;
19800 }
19801
19802 static int
19803 api_flow_classify_set_interface (vat_main_t * vam)
19804 {
19805   unformat_input_t *i = vam->input;
19806   vl_api_flow_classify_set_interface_t *mp;
19807   u32 sw_if_index;
19808   int sw_if_index_set;
19809   u32 ip4_table_index = ~0;
19810   u32 ip6_table_index = ~0;
19811   u8 is_add = 1;
19812   int ret;
19813
19814   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19815     {
19816       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19817         sw_if_index_set = 1;
19818       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19819         sw_if_index_set = 1;
19820       else if (unformat (i, "del"))
19821         is_add = 0;
19822       else if (unformat (i, "ip4-table %d", &ip4_table_index))
19823         ;
19824       else if (unformat (i, "ip6-table %d", &ip6_table_index))
19825         ;
19826       else
19827         {
19828           clib_warning ("parse error '%U'", format_unformat_error, i);
19829           return -99;
19830         }
19831     }
19832
19833   if (sw_if_index_set == 0)
19834     {
19835       errmsg ("missing interface name or sw_if_index");
19836       return -99;
19837     }
19838
19839   M (FLOW_CLASSIFY_SET_INTERFACE, mp);
19840
19841   mp->sw_if_index = ntohl (sw_if_index);
19842   mp->ip4_table_index = ntohl (ip4_table_index);
19843   mp->ip6_table_index = ntohl (ip6_table_index);
19844   mp->is_add = is_add;
19845
19846   S (mp);
19847   W (ret);
19848   return ret;
19849 }
19850
19851 static int
19852 api_flow_classify_dump (vat_main_t * vam)
19853 {
19854   unformat_input_t *i = vam->input;
19855   vl_api_flow_classify_dump_t *mp;
19856   vl_api_control_ping_t *mp_ping;
19857   u8 type = FLOW_CLASSIFY_N_TABLES;
19858   int ret;
19859
19860   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
19861     ;
19862   else
19863     {
19864       errmsg ("classify table type must be specified");
19865       return -99;
19866     }
19867
19868   if (!vam->json_output)
19869     {
19870       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
19871     }
19872
19873   M (FLOW_CLASSIFY_DUMP, mp);
19874   mp->type = type;
19875   /* send it... */
19876   S (mp);
19877
19878   /* Use a control ping for synchronization */
19879   MPING (CONTROL_PING, mp_ping);
19880   S (mp_ping);
19881
19882   /* Wait for a reply... */
19883   W (ret);
19884   return ret;
19885 }
19886
19887 static int
19888 api_feature_enable_disable (vat_main_t * vam)
19889 {
19890   unformat_input_t *i = vam->input;
19891   vl_api_feature_enable_disable_t *mp;
19892   u8 *arc_name = 0;
19893   u8 *feature_name = 0;
19894   u32 sw_if_index = ~0;
19895   u8 enable = 1;
19896   int ret;
19897
19898   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19899     {
19900       if (unformat (i, "arc_name %s", &arc_name))
19901         ;
19902       else if (unformat (i, "feature_name %s", &feature_name))
19903         ;
19904       else
19905         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19906         ;
19907       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19908         ;
19909       else if (unformat (i, "disable"))
19910         enable = 0;
19911       else
19912         break;
19913     }
19914
19915   if (arc_name == 0)
19916     {
19917       errmsg ("missing arc name");
19918       return -99;
19919     }
19920   if (vec_len (arc_name) > 63)
19921     {
19922       errmsg ("arc name too long");
19923     }
19924
19925   if (feature_name == 0)
19926     {
19927       errmsg ("missing feature name");
19928       return -99;
19929     }
19930   if (vec_len (feature_name) > 63)
19931     {
19932       errmsg ("feature name too long");
19933     }
19934
19935   if (sw_if_index == ~0)
19936     {
19937       errmsg ("missing interface name or sw_if_index");
19938       return -99;
19939     }
19940
19941   /* Construct the API message */
19942   M (FEATURE_ENABLE_DISABLE, mp);
19943   mp->sw_if_index = ntohl (sw_if_index);
19944   mp->enable = enable;
19945   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
19946   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
19947   vec_free (arc_name);
19948   vec_free (feature_name);
19949
19950   S (mp);
19951   W (ret);
19952   return ret;
19953 }
19954
19955 static int
19956 api_sw_interface_tag_add_del (vat_main_t * vam)
19957 {
19958   unformat_input_t *i = vam->input;
19959   vl_api_sw_interface_tag_add_del_t *mp;
19960   u32 sw_if_index = ~0;
19961   u8 *tag = 0;
19962   u8 enable = 1;
19963   int ret;
19964
19965   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19966     {
19967       if (unformat (i, "tag %s", &tag))
19968         ;
19969       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19970         ;
19971       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19972         ;
19973       else if (unformat (i, "del"))
19974         enable = 0;
19975       else
19976         break;
19977     }
19978
19979   if (sw_if_index == ~0)
19980     {
19981       errmsg ("missing interface name or sw_if_index");
19982       return -99;
19983     }
19984
19985   if (enable && (tag == 0))
19986     {
19987       errmsg ("no tag specified");
19988       return -99;
19989     }
19990
19991   /* Construct the API message */
19992   M (SW_INTERFACE_TAG_ADD_DEL, mp);
19993   mp->sw_if_index = ntohl (sw_if_index);
19994   mp->is_add = enable;
19995   if (enable)
19996     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
19997   vec_free (tag);
19998
19999   S (mp);
20000   W (ret);
20001   return ret;
20002 }
20003
20004 static int
20005 api_sw_interface_add_del_mac_address (vat_main_t * vam)
20006 {
20007   unformat_input_t *i = vam->input;
20008   vl_api_mac_address_t mac = { 0 };
20009   vl_api_sw_interface_add_del_mac_address_t *mp;
20010   u32 sw_if_index = ~0;
20011   u8 is_add = 1;
20012   u8 mac_set = 0;
20013   int ret;
20014
20015   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20016     {
20017       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20018         ;
20019       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20020         ;
20021       else if (unformat (i, "%U", unformat_vl_api_mac_address, &mac))
20022         mac_set++;
20023       else if (unformat (i, "del"))
20024         is_add = 0;
20025       else
20026         break;
20027     }
20028
20029   if (sw_if_index == ~0)
20030     {
20031       errmsg ("missing interface name or sw_if_index");
20032       return -99;
20033     }
20034
20035   if (!mac_set)
20036     {
20037       errmsg ("missing MAC address");
20038       return -99;
20039     }
20040
20041   /* Construct the API message */
20042   M (SW_INTERFACE_ADD_DEL_MAC_ADDRESS, mp);
20043   mp->sw_if_index = ntohl (sw_if_index);
20044   mp->is_add = is_add;
20045   clib_memcpy (&mp->addr, &mac, sizeof (mac));
20046
20047   S (mp);
20048   W (ret);
20049   return ret;
20050 }
20051
20052 static void vl_api_l2_xconnect_details_t_handler
20053   (vl_api_l2_xconnect_details_t * mp)
20054 {
20055   vat_main_t *vam = &vat_main;
20056
20057   print (vam->ofp, "%15d%15d",
20058          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
20059 }
20060
20061 static void vl_api_l2_xconnect_details_t_handler_json
20062   (vl_api_l2_xconnect_details_t * mp)
20063 {
20064   vat_main_t *vam = &vat_main;
20065   vat_json_node_t *node = NULL;
20066
20067   if (VAT_JSON_ARRAY != vam->json_tree.type)
20068     {
20069       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20070       vat_json_init_array (&vam->json_tree);
20071     }
20072   node = vat_json_array_add (&vam->json_tree);
20073
20074   vat_json_init_object (node);
20075   vat_json_object_add_uint (node, "rx_sw_if_index",
20076                             ntohl (mp->rx_sw_if_index));
20077   vat_json_object_add_uint (node, "tx_sw_if_index",
20078                             ntohl (mp->tx_sw_if_index));
20079 }
20080
20081 static int
20082 api_l2_xconnect_dump (vat_main_t * vam)
20083 {
20084   vl_api_l2_xconnect_dump_t *mp;
20085   vl_api_control_ping_t *mp_ping;
20086   int ret;
20087
20088   if (!vam->json_output)
20089     {
20090       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
20091     }
20092
20093   M (L2_XCONNECT_DUMP, mp);
20094
20095   S (mp);
20096
20097   /* Use a control ping for synchronization */
20098   MPING (CONTROL_PING, mp_ping);
20099   S (mp_ping);
20100
20101   W (ret);
20102   return ret;
20103 }
20104
20105 static int
20106 api_hw_interface_set_mtu (vat_main_t * vam)
20107 {
20108   unformat_input_t *i = vam->input;
20109   vl_api_hw_interface_set_mtu_t *mp;
20110   u32 sw_if_index = ~0;
20111   u32 mtu = 0;
20112   int ret;
20113
20114   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20115     {
20116       if (unformat (i, "mtu %d", &mtu))
20117         ;
20118       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20119         ;
20120       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20121         ;
20122       else
20123         break;
20124     }
20125
20126   if (sw_if_index == ~0)
20127     {
20128       errmsg ("missing interface name or sw_if_index");
20129       return -99;
20130     }
20131
20132   if (mtu == 0)
20133     {
20134       errmsg ("no mtu specified");
20135       return -99;
20136     }
20137
20138   /* Construct the API message */
20139   M (HW_INTERFACE_SET_MTU, mp);
20140   mp->sw_if_index = ntohl (sw_if_index);
20141   mp->mtu = ntohs ((u16) mtu);
20142
20143   S (mp);
20144   W (ret);
20145   return ret;
20146 }
20147
20148 static int
20149 api_p2p_ethernet_add (vat_main_t * vam)
20150 {
20151   unformat_input_t *i = vam->input;
20152   vl_api_p2p_ethernet_add_t *mp;
20153   u32 parent_if_index = ~0;
20154   u32 sub_id = ~0;
20155   u8 remote_mac[6];
20156   u8 mac_set = 0;
20157   int ret;
20158
20159   clib_memset (remote_mac, 0, sizeof (remote_mac));
20160   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20161     {
20162       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
20163         ;
20164       else if (unformat (i, "sw_if_index %d", &parent_if_index))
20165         ;
20166       else
20167         if (unformat
20168             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
20169         mac_set++;
20170       else if (unformat (i, "sub_id %d", &sub_id))
20171         ;
20172       else
20173         {
20174           clib_warning ("parse error '%U'", format_unformat_error, i);
20175           return -99;
20176         }
20177     }
20178
20179   if (parent_if_index == ~0)
20180     {
20181       errmsg ("missing interface name or sw_if_index");
20182       return -99;
20183     }
20184   if (mac_set == 0)
20185     {
20186       errmsg ("missing remote mac address");
20187       return -99;
20188     }
20189   if (sub_id == ~0)
20190     {
20191       errmsg ("missing sub-interface id");
20192       return -99;
20193     }
20194
20195   M (P2P_ETHERNET_ADD, mp);
20196   mp->parent_if_index = ntohl (parent_if_index);
20197   mp->subif_id = ntohl (sub_id);
20198   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
20199
20200   S (mp);
20201   W (ret);
20202   return ret;
20203 }
20204
20205 static int
20206 api_p2p_ethernet_del (vat_main_t * vam)
20207 {
20208   unformat_input_t *i = vam->input;
20209   vl_api_p2p_ethernet_del_t *mp;
20210   u32 parent_if_index = ~0;
20211   u8 remote_mac[6];
20212   u8 mac_set = 0;
20213   int ret;
20214
20215   clib_memset (remote_mac, 0, sizeof (remote_mac));
20216   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20217     {
20218       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
20219         ;
20220       else if (unformat (i, "sw_if_index %d", &parent_if_index))
20221         ;
20222       else
20223         if (unformat
20224             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
20225         mac_set++;
20226       else
20227         {
20228           clib_warning ("parse error '%U'", format_unformat_error, i);
20229           return -99;
20230         }
20231     }
20232
20233   if (parent_if_index == ~0)
20234     {
20235       errmsg ("missing interface name or sw_if_index");
20236       return -99;
20237     }
20238   if (mac_set == 0)
20239     {
20240       errmsg ("missing remote mac address");
20241       return -99;
20242     }
20243
20244   M (P2P_ETHERNET_DEL, mp);
20245   mp->parent_if_index = ntohl (parent_if_index);
20246   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
20247
20248   S (mp);
20249   W (ret);
20250   return ret;
20251 }
20252
20253 static int
20254 api_lldp_config (vat_main_t * vam)
20255 {
20256   unformat_input_t *i = vam->input;
20257   vl_api_lldp_config_t *mp;
20258   int tx_hold = 0;
20259   int tx_interval = 0;
20260   u8 *sys_name = NULL;
20261   int ret;
20262
20263   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20264     {
20265       if (unformat (i, "system-name %s", &sys_name))
20266         ;
20267       else if (unformat (i, "tx-hold %d", &tx_hold))
20268         ;
20269       else if (unformat (i, "tx-interval %d", &tx_interval))
20270         ;
20271       else
20272         {
20273           clib_warning ("parse error '%U'", format_unformat_error, i);
20274           return -99;
20275         }
20276     }
20277
20278   vec_add1 (sys_name, 0);
20279
20280   M (LLDP_CONFIG, mp);
20281   mp->tx_hold = htonl (tx_hold);
20282   mp->tx_interval = htonl (tx_interval);
20283   clib_memcpy (mp->system_name, sys_name, vec_len (sys_name));
20284   vec_free (sys_name);
20285
20286   S (mp);
20287   W (ret);
20288   return ret;
20289 }
20290
20291 static int
20292 api_sw_interface_set_lldp (vat_main_t * vam)
20293 {
20294   unformat_input_t *i = vam->input;
20295   vl_api_sw_interface_set_lldp_t *mp;
20296   u32 sw_if_index = ~0;
20297   u32 enable = 1;
20298   u8 *port_desc = NULL, *mgmt_oid = NULL;
20299   ip4_address_t ip4_addr;
20300   ip6_address_t ip6_addr;
20301   int ret;
20302
20303   clib_memset (&ip4_addr, 0, sizeof (ip4_addr));
20304   clib_memset (&ip6_addr, 0, sizeof (ip6_addr));
20305
20306   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20307     {
20308       if (unformat (i, "disable"))
20309         enable = 0;
20310       else
20311         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20312         ;
20313       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20314         ;
20315       else if (unformat (i, "port-desc %s", &port_desc))
20316         ;
20317       else if (unformat (i, "mgmt-ip4 %U", unformat_ip4_address, &ip4_addr))
20318         ;
20319       else if (unformat (i, "mgmt-ip6 %U", unformat_ip6_address, &ip6_addr))
20320         ;
20321       else if (unformat (i, "mgmt-oid %s", &mgmt_oid))
20322         ;
20323       else
20324         break;
20325     }
20326
20327   if (sw_if_index == ~0)
20328     {
20329       errmsg ("missing interface name or sw_if_index");
20330       return -99;
20331     }
20332
20333   /* Construct the API message */
20334   vec_add1 (port_desc, 0);
20335   vec_add1 (mgmt_oid, 0);
20336   M (SW_INTERFACE_SET_LLDP, mp);
20337   mp->sw_if_index = ntohl (sw_if_index);
20338   mp->enable = enable;
20339   clib_memcpy (mp->port_desc, port_desc, vec_len (port_desc));
20340   clib_memcpy (mp->mgmt_oid, mgmt_oid, vec_len (mgmt_oid));
20341   clib_memcpy (mp->mgmt_ip4, &ip4_addr, sizeof (ip4_addr));
20342   clib_memcpy (mp->mgmt_ip6, &ip6_addr, sizeof (ip6_addr));
20343   vec_free (port_desc);
20344   vec_free (mgmt_oid);
20345
20346   S (mp);
20347   W (ret);
20348   return ret;
20349 }
20350
20351 static int
20352 api_tcp_configure_src_addresses (vat_main_t * vam)
20353 {
20354   vl_api_tcp_configure_src_addresses_t *mp;
20355   unformat_input_t *i = vam->input;
20356   ip4_address_t v4first, v4last;
20357   ip6_address_t v6first, v6last;
20358   u8 range_set = 0;
20359   u32 vrf_id = 0;
20360   int ret;
20361
20362   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20363     {
20364       if (unformat (i, "%U - %U",
20365                     unformat_ip4_address, &v4first,
20366                     unformat_ip4_address, &v4last))
20367         {
20368           if (range_set)
20369             {
20370               errmsg ("one range per message (range already set)");
20371               return -99;
20372             }
20373           range_set = 1;
20374         }
20375       else if (unformat (i, "%U - %U",
20376                          unformat_ip6_address, &v6first,
20377                          unformat_ip6_address, &v6last))
20378         {
20379           if (range_set)
20380             {
20381               errmsg ("one range per message (range already set)");
20382               return -99;
20383             }
20384           range_set = 2;
20385         }
20386       else if (unformat (i, "vrf %d", &vrf_id))
20387         ;
20388       else
20389         break;
20390     }
20391
20392   if (range_set == 0)
20393     {
20394       errmsg ("address range not set");
20395       return -99;
20396     }
20397
20398   M (TCP_CONFIGURE_SRC_ADDRESSES, mp);
20399   mp->vrf_id = ntohl (vrf_id);
20400   /* ipv6? */
20401   if (range_set == 2)
20402     {
20403       mp->is_ipv6 = 1;
20404       clib_memcpy (mp->first_address, &v6first, sizeof (v6first));
20405       clib_memcpy (mp->last_address, &v6last, sizeof (v6last));
20406     }
20407   else
20408     {
20409       mp->is_ipv6 = 0;
20410       clib_memcpy (mp->first_address, &v4first, sizeof (v4first));
20411       clib_memcpy (mp->last_address, &v4last, sizeof (v4last));
20412     }
20413   S (mp);
20414   W (ret);
20415   return ret;
20416 }
20417
20418 static void vl_api_app_namespace_add_del_reply_t_handler
20419   (vl_api_app_namespace_add_del_reply_t * mp)
20420 {
20421   vat_main_t *vam = &vat_main;
20422   i32 retval = ntohl (mp->retval);
20423   if (vam->async_mode)
20424     {
20425       vam->async_errors += (retval < 0);
20426     }
20427   else
20428     {
20429       vam->retval = retval;
20430       if (retval == 0)
20431         errmsg ("app ns index %d\n", ntohl (mp->appns_index));
20432       vam->result_ready = 1;
20433     }
20434 }
20435
20436 static void vl_api_app_namespace_add_del_reply_t_handler_json
20437   (vl_api_app_namespace_add_del_reply_t * mp)
20438 {
20439   vat_main_t *vam = &vat_main;
20440   vat_json_node_t node;
20441
20442   vat_json_init_object (&node);
20443   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
20444   vat_json_object_add_uint (&node, "appns_index", ntohl (mp->appns_index));
20445
20446   vat_json_print (vam->ofp, &node);
20447   vat_json_free (&node);
20448
20449   vam->retval = ntohl (mp->retval);
20450   vam->result_ready = 1;
20451 }
20452
20453 static int
20454 api_app_namespace_add_del (vat_main_t * vam)
20455 {
20456   vl_api_app_namespace_add_del_t *mp;
20457   unformat_input_t *i = vam->input;
20458   u8 *ns_id = 0, secret_set = 0, sw_if_index_set = 0;
20459   u32 sw_if_index, ip4_fib_id, ip6_fib_id;
20460   u64 secret;
20461   int ret;
20462
20463   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20464     {
20465       if (unformat (i, "id %_%v%_", &ns_id))
20466         ;
20467       else if (unformat (i, "secret %lu", &secret))
20468         secret_set = 1;
20469       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20470         sw_if_index_set = 1;
20471       else if (unformat (i, "ip4_fib_id %d", &ip4_fib_id))
20472         ;
20473       else if (unformat (i, "ip6_fib_id %d", &ip6_fib_id))
20474         ;
20475       else
20476         break;
20477     }
20478   if (!ns_id || !secret_set || !sw_if_index_set)
20479     {
20480       errmsg ("namespace id, secret and sw_if_index must be set");
20481       return -99;
20482     }
20483   if (vec_len (ns_id) > 64)
20484     {
20485       errmsg ("namespace id too long");
20486       return -99;
20487     }
20488   M (APP_NAMESPACE_ADD_DEL, mp);
20489
20490   clib_memcpy (mp->namespace_id, ns_id, vec_len (ns_id));
20491   mp->namespace_id_len = vec_len (ns_id);
20492   mp->secret = clib_host_to_net_u64 (secret);
20493   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
20494   mp->ip4_fib_id = clib_host_to_net_u32 (ip4_fib_id);
20495   mp->ip6_fib_id = clib_host_to_net_u32 (ip6_fib_id);
20496   vec_free (ns_id);
20497   S (mp);
20498   W (ret);
20499   return ret;
20500 }
20501
20502 static int
20503 api_sock_init_shm (vat_main_t * vam)
20504 {
20505 #if VPP_API_TEST_BUILTIN == 0
20506   unformat_input_t *i = vam->input;
20507   vl_api_shm_elem_config_t *config = 0;
20508   u64 size = 64 << 20;
20509   int rv;
20510
20511   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20512     {
20513       if (unformat (i, "size %U", unformat_memory_size, &size))
20514         ;
20515       else
20516         break;
20517     }
20518
20519   /*
20520    * Canned custom ring allocator config.
20521    * Should probably parse all of this
20522    */
20523   vec_validate (config, 6);
20524   config[0].type = VL_API_VLIB_RING;
20525   config[0].size = 256;
20526   config[0].count = 32;
20527
20528   config[1].type = VL_API_VLIB_RING;
20529   config[1].size = 1024;
20530   config[1].count = 16;
20531
20532   config[2].type = VL_API_VLIB_RING;
20533   config[2].size = 4096;
20534   config[2].count = 2;
20535
20536   config[3].type = VL_API_CLIENT_RING;
20537   config[3].size = 256;
20538   config[3].count = 32;
20539
20540   config[4].type = VL_API_CLIENT_RING;
20541   config[4].size = 1024;
20542   config[4].count = 16;
20543
20544   config[5].type = VL_API_CLIENT_RING;
20545   config[5].size = 4096;
20546   config[5].count = 2;
20547
20548   config[6].type = VL_API_QUEUE;
20549   config[6].count = 128;
20550   config[6].size = sizeof (uword);
20551
20552   rv = vl_socket_client_init_shm (config, 1 /* want_pthread */ );
20553   if (!rv)
20554     vam->client_index_invalid = 1;
20555   return rv;
20556 #else
20557   return -99;
20558 #endif
20559 }
20560
20561 static void
20562 vl_api_session_rules_details_t_handler (vl_api_session_rules_details_t * mp)
20563 {
20564   vat_main_t *vam = &vat_main;
20565
20566   if (mp->is_ip4)
20567     {
20568       print (vam->ofp,
20569              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
20570              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
20571              mp->scope, format_ip4_address, &mp->lcl_ip, mp->lcl_plen,
20572              clib_net_to_host_u16 (mp->lcl_port), format_ip4_address,
20573              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
20574              clib_net_to_host_u32 (mp->action_index), mp->tag);
20575     }
20576   else
20577     {
20578       print (vam->ofp,
20579              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
20580              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
20581              mp->scope, format_ip6_address, &mp->lcl_ip, mp->lcl_plen,
20582              clib_net_to_host_u16 (mp->lcl_port), format_ip6_address,
20583              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
20584              clib_net_to_host_u32 (mp->action_index), mp->tag);
20585     }
20586 }
20587
20588 static void
20589 vl_api_session_rules_details_t_handler_json (vl_api_session_rules_details_t *
20590                                              mp)
20591 {
20592   vat_main_t *vam = &vat_main;
20593   vat_json_node_t *node = NULL;
20594   struct in6_addr ip6;
20595   struct in_addr ip4;
20596
20597   if (VAT_JSON_ARRAY != vam->json_tree.type)
20598     {
20599       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20600       vat_json_init_array (&vam->json_tree);
20601     }
20602   node = vat_json_array_add (&vam->json_tree);
20603   vat_json_init_object (node);
20604
20605   vat_json_object_add_uint (node, "is_ip4", mp->is_ip4 ? 1 : 0);
20606   vat_json_object_add_uint (node, "appns_index",
20607                             clib_net_to_host_u32 (mp->appns_index));
20608   vat_json_object_add_uint (node, "transport_proto", mp->transport_proto);
20609   vat_json_object_add_uint (node, "scope", mp->scope);
20610   vat_json_object_add_uint (node, "action_index",
20611                             clib_net_to_host_u32 (mp->action_index));
20612   vat_json_object_add_uint (node, "lcl_port",
20613                             clib_net_to_host_u16 (mp->lcl_port));
20614   vat_json_object_add_uint (node, "rmt_port",
20615                             clib_net_to_host_u16 (mp->rmt_port));
20616   vat_json_object_add_uint (node, "lcl_plen", mp->lcl_plen);
20617   vat_json_object_add_uint (node, "rmt_plen", mp->rmt_plen);
20618   vat_json_object_add_string_copy (node, "tag", mp->tag);
20619   if (mp->is_ip4)
20620     {
20621       clib_memcpy (&ip4, mp->lcl_ip, sizeof (ip4));
20622       vat_json_object_add_ip4 (node, "lcl_ip", ip4);
20623       clib_memcpy (&ip4, mp->rmt_ip, sizeof (ip4));
20624       vat_json_object_add_ip4 (node, "rmt_ip", ip4);
20625     }
20626   else
20627     {
20628       clib_memcpy (&ip6, mp->lcl_ip, sizeof (ip6));
20629       vat_json_object_add_ip6 (node, "lcl_ip", ip6);
20630       clib_memcpy (&ip6, mp->rmt_ip, sizeof (ip6));
20631       vat_json_object_add_ip6 (node, "rmt_ip", ip6);
20632     }
20633 }
20634
20635 static int
20636 api_session_rule_add_del (vat_main_t * vam)
20637 {
20638   vl_api_session_rule_add_del_t *mp;
20639   unformat_input_t *i = vam->input;
20640   u32 proto = ~0, lcl_port, rmt_port, action = 0, lcl_plen, rmt_plen;
20641   u32 appns_index = 0, scope = 0;
20642   ip4_address_t lcl_ip4, rmt_ip4;
20643   ip6_address_t lcl_ip6, rmt_ip6;
20644   u8 is_ip4 = 1, conn_set = 0;
20645   u8 is_add = 1, *tag = 0;
20646   int ret;
20647
20648   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20649     {
20650       if (unformat (i, "del"))
20651         is_add = 0;
20652       else if (unformat (i, "add"))
20653         ;
20654       else if (unformat (i, "proto tcp"))
20655         proto = 0;
20656       else if (unformat (i, "proto udp"))
20657         proto = 1;
20658       else if (unformat (i, "appns %d", &appns_index))
20659         ;
20660       else if (unformat (i, "scope %d", &scope))
20661         ;
20662       else if (unformat (i, "tag %_%v%_", &tag))
20663         ;
20664       else
20665         if (unformat
20666             (i, "%U/%d %d %U/%d %d", unformat_ip4_address, &lcl_ip4,
20667              &lcl_plen, &lcl_port, unformat_ip4_address, &rmt_ip4, &rmt_plen,
20668              &rmt_port))
20669         {
20670           is_ip4 = 1;
20671           conn_set = 1;
20672         }
20673       else
20674         if (unformat
20675             (i, "%U/%d %d %U/%d %d", unformat_ip6_address, &lcl_ip6,
20676              &lcl_plen, &lcl_port, unformat_ip6_address, &rmt_ip6, &rmt_plen,
20677              &rmt_port))
20678         {
20679           is_ip4 = 0;
20680           conn_set = 1;
20681         }
20682       else if (unformat (i, "action %d", &action))
20683         ;
20684       else
20685         break;
20686     }
20687   if (proto == ~0 || !conn_set || action == ~0)
20688     {
20689       errmsg ("transport proto, connection and action must be set");
20690       return -99;
20691     }
20692
20693   if (scope > 3)
20694     {
20695       errmsg ("scope should be 0-3");
20696       return -99;
20697     }
20698
20699   M (SESSION_RULE_ADD_DEL, mp);
20700
20701   mp->is_ip4 = is_ip4;
20702   mp->transport_proto = proto;
20703   mp->lcl_port = clib_host_to_net_u16 ((u16) lcl_port);
20704   mp->rmt_port = clib_host_to_net_u16 ((u16) rmt_port);
20705   mp->lcl_plen = lcl_plen;
20706   mp->rmt_plen = rmt_plen;
20707   mp->action_index = clib_host_to_net_u32 (action);
20708   mp->appns_index = clib_host_to_net_u32 (appns_index);
20709   mp->scope = scope;
20710   mp->is_add = is_add;
20711   if (is_ip4)
20712     {
20713       clib_memcpy (mp->lcl_ip, &lcl_ip4, sizeof (lcl_ip4));
20714       clib_memcpy (mp->rmt_ip, &rmt_ip4, sizeof (rmt_ip4));
20715     }
20716   else
20717     {
20718       clib_memcpy (mp->lcl_ip, &lcl_ip6, sizeof (lcl_ip6));
20719       clib_memcpy (mp->rmt_ip, &rmt_ip6, sizeof (rmt_ip6));
20720     }
20721   if (tag)
20722     {
20723       clib_memcpy (mp->tag, tag, vec_len (tag));
20724       vec_free (tag);
20725     }
20726
20727   S (mp);
20728   W (ret);
20729   return ret;
20730 }
20731
20732 static int
20733 api_session_rules_dump (vat_main_t * vam)
20734 {
20735   vl_api_session_rules_dump_t *mp;
20736   vl_api_control_ping_t *mp_ping;
20737   int ret;
20738
20739   if (!vam->json_output)
20740     {
20741       print (vam->ofp, "%=20s", "Session Rules");
20742     }
20743
20744   M (SESSION_RULES_DUMP, mp);
20745   /* send it... */
20746   S (mp);
20747
20748   /* Use a control ping for synchronization */
20749   MPING (CONTROL_PING, mp_ping);
20750   S (mp_ping);
20751
20752   /* Wait for a reply... */
20753   W (ret);
20754   return ret;
20755 }
20756
20757 static int
20758 api_ip_container_proxy_add_del (vat_main_t * vam)
20759 {
20760   vl_api_ip_container_proxy_add_del_t *mp;
20761   unformat_input_t *i = vam->input;
20762   u32 sw_if_index = ~0;
20763   vl_api_prefix_t pfx = { };
20764   u8 is_add = 1;
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       if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
20774         ;
20775       else if (unformat (i, "sw_if_index %u", &sw_if_index))
20776         ;
20777       else
20778         break;
20779     }
20780   if (sw_if_index == ~0 || pfx.len == 0)
20781     {
20782       errmsg ("address and sw_if_index must be set");
20783       return -99;
20784     }
20785
20786   M (IP_CONTAINER_PROXY_ADD_DEL, mp);
20787
20788   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
20789   mp->is_add = is_add;
20790   clib_memcpy (&mp->pfx, &pfx, sizeof (pfx));
20791
20792   S (mp);
20793   W (ret);
20794   return ret;
20795 }
20796
20797 static int
20798 api_qos_record_enable_disable (vat_main_t * vam)
20799 {
20800   unformat_input_t *i = vam->input;
20801   vl_api_qos_record_enable_disable_t *mp;
20802   u32 sw_if_index, qs = 0xff;
20803   u8 sw_if_index_set = 0;
20804   u8 enable = 1;
20805   int ret;
20806
20807   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20808     {
20809       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20810         sw_if_index_set = 1;
20811       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20812         sw_if_index_set = 1;
20813       else if (unformat (i, "%U", unformat_qos_source, &qs))
20814         ;
20815       else if (unformat (i, "disable"))
20816         enable = 0;
20817       else
20818         {
20819           clib_warning ("parse error '%U'", format_unformat_error, i);
20820           return -99;
20821         }
20822     }
20823
20824   if (sw_if_index_set == 0)
20825     {
20826       errmsg ("missing interface name or sw_if_index");
20827       return -99;
20828     }
20829   if (qs == 0xff)
20830     {
20831       errmsg ("input location must be specified");
20832       return -99;
20833     }
20834
20835   M (QOS_RECORD_ENABLE_DISABLE, mp);
20836
20837   mp->record.sw_if_index = ntohl (sw_if_index);
20838   mp->record.input_source = qs;
20839   mp->enable = enable;
20840
20841   S (mp);
20842   W (ret);
20843   return ret;
20844 }
20845
20846
20847 static int
20848 q_or_quit (vat_main_t * vam)
20849 {
20850 #if VPP_API_TEST_BUILTIN == 0
20851   longjmp (vam->jump_buf, 1);
20852 #endif
20853   return 0;                     /* not so much */
20854 }
20855
20856 static int
20857 q (vat_main_t * vam)
20858 {
20859   return q_or_quit (vam);
20860 }
20861
20862 static int
20863 quit (vat_main_t * vam)
20864 {
20865   return q_or_quit (vam);
20866 }
20867
20868 static int
20869 comment (vat_main_t * vam)
20870 {
20871   return 0;
20872 }
20873
20874 static int
20875 elog_save (vat_main_t * vam)
20876 {
20877 #if VPP_API_TEST_BUILTIN == 0
20878   elog_main_t *em = &vam->elog_main;
20879   unformat_input_t *i = vam->input;
20880   char *file, *chroot_file;
20881   clib_error_t *error;
20882
20883   if (!unformat (i, "%s", &file))
20884     {
20885       errmsg ("expected file name, got `%U'", format_unformat_error, i);
20886       return 0;
20887     }
20888
20889   /* It's fairly hard to get "../oopsie" through unformat; just in case */
20890   if (strstr (file, "..") || index (file, '/'))
20891     {
20892       errmsg ("illegal characters in filename '%s'", file);
20893       return 0;
20894     }
20895
20896   chroot_file = (char *) format (0, "/tmp/%s%c", file, 0);
20897
20898   vec_free (file);
20899
20900   errmsg ("Saving %wd of %wd events to %s",
20901           elog_n_events_in_buffer (em),
20902           elog_buffer_capacity (em), chroot_file);
20903
20904   error = elog_write_file (em, chroot_file, 1 /* flush ring */ );
20905   vec_free (chroot_file);
20906
20907   if (error)
20908     clib_error_report (error);
20909 #else
20910   errmsg ("Use the vpp event loger...");
20911 #endif
20912
20913   return 0;
20914 }
20915
20916 static int
20917 elog_setup (vat_main_t * vam)
20918 {
20919 #if VPP_API_TEST_BUILTIN == 0
20920   elog_main_t *em = &vam->elog_main;
20921   unformat_input_t *i = vam->input;
20922   u32 nevents = 128 << 10;
20923
20924   (void) unformat (i, "nevents %d", &nevents);
20925
20926   elog_init (em, nevents);
20927   vl_api_set_elog_main (em);
20928   vl_api_set_elog_trace_api_messages (1);
20929   errmsg ("Event logger initialized with %u events", nevents);
20930 #else
20931   errmsg ("Use the vpp event loger...");
20932 #endif
20933   return 0;
20934 }
20935
20936 static int
20937 elog_enable (vat_main_t * vam)
20938 {
20939 #if VPP_API_TEST_BUILTIN == 0
20940   elog_main_t *em = &vam->elog_main;
20941
20942   elog_enable_disable (em, 1 /* enable */ );
20943   vl_api_set_elog_trace_api_messages (1);
20944   errmsg ("Event logger enabled...");
20945 #else
20946   errmsg ("Use the vpp event loger...");
20947 #endif
20948   return 0;
20949 }
20950
20951 static int
20952 elog_disable (vat_main_t * vam)
20953 {
20954 #if VPP_API_TEST_BUILTIN == 0
20955   elog_main_t *em = &vam->elog_main;
20956
20957   elog_enable_disable (em, 0 /* enable */ );
20958   vl_api_set_elog_trace_api_messages (1);
20959   errmsg ("Event logger disabled...");
20960 #else
20961   errmsg ("Use the vpp event loger...");
20962 #endif
20963   return 0;
20964 }
20965
20966 static int
20967 statseg (vat_main_t * vam)
20968 {
20969   ssvm_private_t *ssvmp = &vam->stat_segment;
20970   ssvm_shared_header_t *shared_header = ssvmp->sh;
20971   vlib_counter_t **counters;
20972   u64 thread0_index1_packets;
20973   u64 thread0_index1_bytes;
20974   f64 vector_rate, input_rate;
20975   uword *p;
20976
20977   uword *counter_vector_by_name;
20978   if (vam->stat_segment_lockp == 0)
20979     {
20980       errmsg ("Stat segment not mapped...");
20981       return -99;
20982     }
20983
20984   /* look up "/if/rx for sw_if_index 1 as a test */
20985
20986   clib_spinlock_lock (vam->stat_segment_lockp);
20987
20988   counter_vector_by_name = (uword *) shared_header->opaque[1];
20989
20990   p = hash_get_mem (counter_vector_by_name, "/if/rx");
20991   if (p == 0)
20992     {
20993       clib_spinlock_unlock (vam->stat_segment_lockp);
20994       errmsg ("/if/tx not found?");
20995       return -99;
20996     }
20997
20998   /* Fish per-thread vector of combined counters from shared memory */
20999   counters = (vlib_counter_t **) p[0];
21000
21001   if (vec_len (counters[0]) < 2)
21002     {
21003       clib_spinlock_unlock (vam->stat_segment_lockp);
21004       errmsg ("/if/tx vector length %d", vec_len (counters[0]));
21005       return -99;
21006     }
21007
21008   /* Read thread 0 sw_if_index 1 counter */
21009   thread0_index1_packets = counters[0][1].packets;
21010   thread0_index1_bytes = counters[0][1].bytes;
21011
21012   p = hash_get_mem (counter_vector_by_name, "vector_rate");
21013   if (p == 0)
21014     {
21015       clib_spinlock_unlock (vam->stat_segment_lockp);
21016       errmsg ("vector_rate not found?");
21017       return -99;
21018     }
21019
21020   vector_rate = *(f64 *) (p[0]);
21021   p = hash_get_mem (counter_vector_by_name, "input_rate");
21022   if (p == 0)
21023     {
21024       clib_spinlock_unlock (vam->stat_segment_lockp);
21025       errmsg ("input_rate not found?");
21026       return -99;
21027     }
21028   input_rate = *(f64 *) (p[0]);
21029
21030   clib_spinlock_unlock (vam->stat_segment_lockp);
21031
21032   print (vam->ofp, "vector_rate %.2f input_rate %.2f",
21033          vector_rate, input_rate);
21034   print (vam->ofp, "thread 0 sw_if_index 1 rx pkts %lld, bytes %lld",
21035          thread0_index1_packets, thread0_index1_bytes);
21036
21037   return 0;
21038 }
21039
21040 static int
21041 cmd_cmp (void *a1, void *a2)
21042 {
21043   u8 **c1 = a1;
21044   u8 **c2 = a2;
21045
21046   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
21047 }
21048
21049 static int
21050 help (vat_main_t * vam)
21051 {
21052   u8 **cmds = 0;
21053   u8 *name = 0;
21054   hash_pair_t *p;
21055   unformat_input_t *i = vam->input;
21056   int j;
21057
21058   if (unformat (i, "%s", &name))
21059     {
21060       uword *hs;
21061
21062       vec_add1 (name, 0);
21063
21064       hs = hash_get_mem (vam->help_by_name, name);
21065       if (hs)
21066         print (vam->ofp, "usage: %s %s", name, hs[0]);
21067       else
21068         print (vam->ofp, "No such msg / command '%s'", name);
21069       vec_free (name);
21070       return 0;
21071     }
21072
21073   print (vam->ofp, "Help is available for the following:");
21074
21075     /* *INDENT-OFF* */
21076     hash_foreach_pair (p, vam->function_by_name,
21077     ({
21078       vec_add1 (cmds, (u8 *)(p->key));
21079     }));
21080     /* *INDENT-ON* */
21081
21082   vec_sort_with_function (cmds, cmd_cmp);
21083
21084   for (j = 0; j < vec_len (cmds); j++)
21085     print (vam->ofp, "%s", cmds[j]);
21086
21087   vec_free (cmds);
21088   return 0;
21089 }
21090
21091 static int
21092 set (vat_main_t * vam)
21093 {
21094   u8 *name = 0, *value = 0;
21095   unformat_input_t *i = vam->input;
21096
21097   if (unformat (i, "%s", &name))
21098     {
21099       /* The input buffer is a vector, not a string. */
21100       value = vec_dup (i->buffer);
21101       vec_delete (value, i->index, 0);
21102       /* Almost certainly has a trailing newline */
21103       if (value[vec_len (value) - 1] == '\n')
21104         value[vec_len (value) - 1] = 0;
21105       /* Make sure it's a proper string, one way or the other */
21106       vec_add1 (value, 0);
21107       (void) clib_macro_set_value (&vam->macro_main,
21108                                    (char *) name, (char *) value);
21109     }
21110   else
21111     errmsg ("usage: set <name> <value>");
21112
21113   vec_free (name);
21114   vec_free (value);
21115   return 0;
21116 }
21117
21118 static int
21119 unset (vat_main_t * vam)
21120 {
21121   u8 *name = 0;
21122
21123   if (unformat (vam->input, "%s", &name))
21124     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
21125       errmsg ("unset: %s wasn't set", name);
21126   vec_free (name);
21127   return 0;
21128 }
21129
21130 typedef struct
21131 {
21132   u8 *name;
21133   u8 *value;
21134 } macro_sort_t;
21135
21136
21137 static int
21138 macro_sort_cmp (void *a1, void *a2)
21139 {
21140   macro_sort_t *s1 = a1;
21141   macro_sort_t *s2 = a2;
21142
21143   return strcmp ((char *) (s1->name), (char *) (s2->name));
21144 }
21145
21146 static int
21147 dump_macro_table (vat_main_t * vam)
21148 {
21149   macro_sort_t *sort_me = 0, *sm;
21150   int i;
21151   hash_pair_t *p;
21152
21153     /* *INDENT-OFF* */
21154     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
21155     ({
21156       vec_add2 (sort_me, sm, 1);
21157       sm->name = (u8 *)(p->key);
21158       sm->value = (u8 *) (p->value[0]);
21159     }));
21160     /* *INDENT-ON* */
21161
21162   vec_sort_with_function (sort_me, macro_sort_cmp);
21163
21164   if (vec_len (sort_me))
21165     print (vam->ofp, "%-15s%s", "Name", "Value");
21166   else
21167     print (vam->ofp, "The macro table is empty...");
21168
21169   for (i = 0; i < vec_len (sort_me); i++)
21170     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
21171   return 0;
21172 }
21173
21174 static int
21175 dump_node_table (vat_main_t * vam)
21176 {
21177   int i, j;
21178   vlib_node_t *node, *next_node;
21179
21180   if (vec_len (vam->graph_nodes) == 0)
21181     {
21182       print (vam->ofp, "Node table empty, issue get_node_graph...");
21183       return 0;
21184     }
21185
21186   for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
21187     {
21188       node = vam->graph_nodes[0][i];
21189       print (vam->ofp, "[%d] %s", i, node->name);
21190       for (j = 0; j < vec_len (node->next_nodes); j++)
21191         {
21192           if (node->next_nodes[j] != ~0)
21193             {
21194               next_node = vam->graph_nodes[0][node->next_nodes[j]];
21195               print (vam->ofp, "  [%d] %s", j, next_node->name);
21196             }
21197         }
21198     }
21199   return 0;
21200 }
21201
21202 static int
21203 value_sort_cmp (void *a1, void *a2)
21204 {
21205   name_sort_t *n1 = a1;
21206   name_sort_t *n2 = a2;
21207
21208   if (n1->value < n2->value)
21209     return -1;
21210   if (n1->value > n2->value)
21211     return 1;
21212   return 0;
21213 }
21214
21215
21216 static int
21217 dump_msg_api_table (vat_main_t * vam)
21218 {
21219   api_main_t *am = &api_main;
21220   name_sort_t *nses = 0, *ns;
21221   hash_pair_t *hp;
21222   int i;
21223
21224   /* *INDENT-OFF* */
21225   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
21226   ({
21227     vec_add2 (nses, ns, 1);
21228     ns->name = (u8 *)(hp->key);
21229     ns->value = (u32) hp->value[0];
21230   }));
21231   /* *INDENT-ON* */
21232
21233   vec_sort_with_function (nses, value_sort_cmp);
21234
21235   for (i = 0; i < vec_len (nses); i++)
21236     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
21237   vec_free (nses);
21238   return 0;
21239 }
21240
21241 static int
21242 get_msg_id (vat_main_t * vam)
21243 {
21244   u8 *name_and_crc;
21245   u32 message_index;
21246
21247   if (unformat (vam->input, "%s", &name_and_crc))
21248     {
21249       message_index = vl_msg_api_get_msg_index (name_and_crc);
21250       if (message_index == ~0)
21251         {
21252           print (vam->ofp, " '%s' not found", name_and_crc);
21253           return 0;
21254         }
21255       print (vam->ofp, " '%s' has message index %d",
21256              name_and_crc, message_index);
21257       return 0;
21258     }
21259   errmsg ("name_and_crc required...");
21260   return 0;
21261 }
21262
21263 static int
21264 search_node_table (vat_main_t * vam)
21265 {
21266   unformat_input_t *line_input = vam->input;
21267   u8 *node_to_find;
21268   int j;
21269   vlib_node_t *node, *next_node;
21270   uword *p;
21271
21272   if (vam->graph_node_index_by_name == 0)
21273     {
21274       print (vam->ofp, "Node table empty, issue get_node_graph...");
21275       return 0;
21276     }
21277
21278   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
21279     {
21280       if (unformat (line_input, "%s", &node_to_find))
21281         {
21282           vec_add1 (node_to_find, 0);
21283           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
21284           if (p == 0)
21285             {
21286               print (vam->ofp, "%s not found...", node_to_find);
21287               goto out;
21288             }
21289           node = vam->graph_nodes[0][p[0]];
21290           print (vam->ofp, "[%d] %s", p[0], node->name);
21291           for (j = 0; j < vec_len (node->next_nodes); j++)
21292             {
21293               if (node->next_nodes[j] != ~0)
21294                 {
21295                   next_node = vam->graph_nodes[0][node->next_nodes[j]];
21296                   print (vam->ofp, "  [%d] %s", j, next_node->name);
21297                 }
21298             }
21299         }
21300
21301       else
21302         {
21303           clib_warning ("parse error '%U'", format_unformat_error,
21304                         line_input);
21305           return -99;
21306         }
21307
21308     out:
21309       vec_free (node_to_find);
21310
21311     }
21312
21313   return 0;
21314 }
21315
21316
21317 static int
21318 script (vat_main_t * vam)
21319 {
21320 #if (VPP_API_TEST_BUILTIN==0)
21321   u8 *s = 0;
21322   char *save_current_file;
21323   unformat_input_t save_input;
21324   jmp_buf save_jump_buf;
21325   u32 save_line_number;
21326
21327   FILE *new_fp, *save_ifp;
21328
21329   if (unformat (vam->input, "%s", &s))
21330     {
21331       new_fp = fopen ((char *) s, "r");
21332       if (new_fp == 0)
21333         {
21334           errmsg ("Couldn't open script file %s", s);
21335           vec_free (s);
21336           return -99;
21337         }
21338     }
21339   else
21340     {
21341       errmsg ("Missing script name");
21342       return -99;
21343     }
21344
21345   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
21346   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
21347   save_ifp = vam->ifp;
21348   save_line_number = vam->input_line_number;
21349   save_current_file = (char *) vam->current_file;
21350
21351   vam->input_line_number = 0;
21352   vam->ifp = new_fp;
21353   vam->current_file = s;
21354   do_one_file (vam);
21355
21356   clib_memcpy (&vam->input, &save_input, sizeof (save_input));
21357   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
21358   vam->ifp = save_ifp;
21359   vam->input_line_number = save_line_number;
21360   vam->current_file = (u8 *) save_current_file;
21361   vec_free (s);
21362
21363   return 0;
21364 #else
21365   clib_warning ("use the exec command...");
21366   return -99;
21367 #endif
21368 }
21369
21370 static int
21371 echo (vat_main_t * vam)
21372 {
21373   print (vam->ofp, "%v", vam->input->buffer);
21374   return 0;
21375 }
21376
21377 /* List of API message constructors, CLI names map to api_xxx */
21378 #define foreach_vpe_api_msg                                             \
21379 _(create_loopback,"[mac <mac-addr>] [instance <instance>]")             \
21380 _(sw_interface_dump,"")                                                 \
21381 _(sw_interface_set_flags,                                               \
21382   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
21383 _(sw_interface_add_del_address,                                         \
21384   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
21385 _(sw_interface_set_rx_mode,                                             \
21386   "<intfc> | sw_if_index <id> [queue <id>] <polling | interrupt | adaptive>") \
21387 _(sw_interface_set_rx_placement,                                        \
21388   "<intfc> | sw_if_index <id> [queue <id>] [worker <id> | main]")       \
21389 _(sw_interface_rx_placement_dump,                                       \
21390   "[<intfc> | sw_if_index <id>]")                                         \
21391 _(sw_interface_set_table,                                               \
21392   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
21393 _(sw_interface_set_mpls_enable,                                         \
21394   "<intfc> | sw_if_index [disable | dis]")                              \
21395 _(sw_interface_set_vpath,                                               \
21396   "<intfc> | sw_if_index <id> enable | disable")                        \
21397 _(sw_interface_set_vxlan_bypass,                                        \
21398   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
21399 _(sw_interface_set_geneve_bypass,                                       \
21400   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
21401 _(sw_interface_set_l2_xconnect,                                         \
21402   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
21403   "enable | disable")                                                   \
21404 _(sw_interface_set_l2_bridge,                                           \
21405   "{<intfc> | sw_if_index <id>} bd_id <bridge-domain-id>\n"             \
21406   "[shg <split-horizon-group>] [bvi]\n"                                 \
21407   "enable | disable")                                                   \
21408 _(bridge_domain_set_mac_age, "bd_id <bridge-domain-id> mac-age 0-255")  \
21409 _(bridge_domain_add_del,                                                \
21410   "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") \
21411 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
21412 _(l2fib_add_del,                                                        \
21413   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
21414 _(l2fib_flush_bd, "bd_id <bridge-domain-id>")                           \
21415 _(l2fib_flush_int, "<intfc> | sw_if_index <id>")                        \
21416 _(l2_flags,                                                             \
21417   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
21418 _(bridge_flags,                                                         \
21419   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
21420 _(tap_create_v2,                                                        \
21421   "id <num> [hw-addr <mac-addr>] [host-ns <name>] [rx-ring-size <num> [tx-ring-size <num>] [host-mtu-size <mtu>] [gso | no-gso]") \
21422 _(tap_delete_v2,                                                        \
21423   "<vpp-if-name> | sw_if_index <id>")                                   \
21424 _(sw_interface_tap_v2_dump, "")                                         \
21425 _(virtio_pci_create,                                                    \
21426   "pci-addr <pci-address> [use_random_mac | hw-addr <mac-addr>] [features <hex-value>] [gso-enabled]") \
21427 _(virtio_pci_delete,                                                    \
21428   "<vpp-if-name> | sw_if_index <id>")                                   \
21429 _(sw_interface_virtio_pci_dump, "")                                     \
21430 _(bond_create,                                                          \
21431   "[hw-addr <mac-addr>] {round-robin | active-backup | "                \
21432   "broadcast | {lacp | xor} [load-balance { l2 | l23 | l34 }]} "        \
21433   "[id <if-id>]")                                                       \
21434 _(bond_delete,                                                          \
21435   "<vpp-if-name> | sw_if_index <id>")                                   \
21436 _(bond_enslave,                                                         \
21437   "sw_if_index <n> bond <sw_if_index> [is_passive] [is_long_timeout]")  \
21438 _(bond_detach_slave,                                                    \
21439   "sw_if_index <n>")                                                    \
21440  _(sw_interface_set_bond_weight, "<intfc> | sw_if_index <nn> weight <value>") \
21441 _(sw_interface_bond_dump, "")                                           \
21442 _(sw_interface_slave_dump,                                              \
21443   "<vpp-if-name> | sw_if_index <id>")                                   \
21444 _(ip_table_add_del,                                                     \
21445   "table <n> [ipv6] [add | del]\n")                                     \
21446 _(ip_route_add_del,                                                     \
21447   "<addr>/<mask> via <<addr>|<intfc>|sw_if_index <id>|via-label <n>>\n" \
21448   "[table-id <n>] [<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"\
21449   "[weight <n>] [drop] [local] [classify <n>]  [out-label <n>]\n"       \
21450   "[multipath] [count <n>] [del]")                                      \
21451 _(ip_mroute_add_del,                                                    \
21452   "<src> <grp>/<mask> [table-id <n>]\n"                                 \
21453   "[<intfc> | sw_if_index <id>] [local] [del]")                         \
21454 _(mpls_table_add_del,                                                   \
21455   "table <n> [add | del]\n")                                            \
21456 _(mpls_route_add_del,                                                   \
21457   "<label> <eos> via <addr | next-hop-table <n> | via-label <n> |\n"    \
21458   "lookup-ip4-table <n> | lookup-in-ip6-table <n> |\n"                  \
21459   "l2-input-on <intfc> | l2-input-on sw_if_index <id>>\n"               \
21460   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>] [weight <n>]\n"  \
21461   "[drop] [local] [classify <n>] [out-label <n>] [multipath]\n"         \
21462   "[count <n>] [del]")                                                  \
21463 _(mpls_ip_bind_unbind,                                                  \
21464   "<label> <addr/len>")                                                 \
21465 _(mpls_tunnel_add_del,                                                  \
21466   "[add | del <intfc | sw_if_index <id>>] via <addr | via-label <n>>\n" \
21467   "[<intfc> | sw_if_index <id> | next-hop-table <id>]\n"                \
21468   "[l2-only]  [out-label <n>]")                                         \
21469 _(sr_mpls_policy_add,                                                   \
21470   "bsid <id> [weight <n>] [spray] next <sid> [next <sid>]")             \
21471 _(sr_mpls_policy_del,                                                   \
21472   "bsid <id>")                                                          \
21473 _(bier_table_add_del,                                                   \
21474   "<label> <sub-domain> <set> <bsl> [del]")                             \
21475 _(bier_route_add_del,                                                   \
21476   "<bit-position> <sub-domain> <set> <bsl> via <addr> [table-id <n>]\n" \
21477   "[<intfc> | sw_if_index <id>]"                                        \
21478   "[weight <n>] [del] [multipath]")                                     \
21479 _(proxy_arp_add_del,                                                    \
21480   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
21481 _(proxy_arp_intfc_enable_disable,                                       \
21482   "<intfc> | sw_if_index <id> enable | disable")                        \
21483 _(sw_interface_set_unnumbered,                                          \
21484   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
21485 _(ip_neighbor_add_del,                                                  \
21486   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
21487   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
21488 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
21489 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
21490   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
21491   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
21492   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
21493 _(reset_fib, "vrf <n> [ipv6]")                                          \
21494 _(set_ip_flow_hash,                                                     \
21495   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
21496 _(sw_interface_ip6_enable_disable,                                      \
21497   "<intfc> | sw_if_index <id> enable | disable")                        \
21498 _(ip6nd_proxy_add_del,                                                  \
21499   "<intfc> | sw_if_index <id> <ip6-address>")                           \
21500 _(ip6nd_proxy_dump, "")                                                 \
21501 _(sw_interface_ip6nd_ra_prefix,                                         \
21502   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
21503   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
21504   "[nolink] [isno]")                                                    \
21505 _(sw_interface_ip6nd_ra_config,                                         \
21506   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
21507   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
21508   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
21509 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
21510 _(l2_patch_add_del,                                                     \
21511   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
21512   "enable | disable")                                                   \
21513 _(sr_localsid_add_del,                                                  \
21514   "(del) address <addr> next_hop <addr> behavior <beh>\n"               \
21515   "fib-table <num> (end.psp) sw_if_index <num>")                        \
21516 _(classify_add_del_table,                                               \
21517   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
21518   " [del] [del-chain] mask <mask-value>\n"                              \
21519   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
21520   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
21521 _(classify_add_del_session,                                             \
21522   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
21523   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
21524   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
21525   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
21526 _(classify_set_interface_ip_table,                                      \
21527   "<intfc> | sw_if_index <nn> table <nn>")                              \
21528 _(classify_set_interface_l2_tables,                                     \
21529   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
21530   "  [other-table <nn>]")                                               \
21531 _(get_node_index, "node <node-name")                                    \
21532 _(add_node_next, "node <node-name> next <next-node-name>")              \
21533 _(l2tpv3_create_tunnel,                                                 \
21534   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
21535   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
21536   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
21537 _(l2tpv3_set_tunnel_cookies,                                            \
21538   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
21539   "[new_remote_cookie <nn>]\n")                                         \
21540 _(l2tpv3_interface_enable_disable,                                      \
21541   "<intfc> | sw_if_index <nn> enable | disable")                        \
21542 _(l2tpv3_set_lookup_key,                                                \
21543   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
21544 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
21545 _(vxlan_offload_rx,                                                     \
21546   "hw { <interface name> | hw_if_index <nn>} "                          \
21547   "rx { <vxlan tunnel name> | sw_if_index <nn> } [del]")                \
21548 _(vxlan_add_del_tunnel,                                                 \
21549   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
21550   "{ <intfc> | mcast_sw_if_index <nn> } [instance <id>]}\n"             \
21551   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
21552 _(geneve_add_del_tunnel,                                                \
21553   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
21554   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
21555   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
21556 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
21557 _(geneve_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                   \
21558 _(gre_tunnel_add_del,                                                   \
21559   "src <ip-addr> dst <ip-addr> [outer-fib-id <nn>] [instance <n>]\n"    \
21560   "[teb | erspan <session-id>] [del]")                                  \
21561 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
21562 _(l2_fib_clear_table, "")                                               \
21563 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
21564 _(l2_interface_vlan_tag_rewrite,                                        \
21565   "<intfc> | sw_if_index <nn> \n"                                       \
21566   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
21567   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
21568 _(create_vhost_user_if,                                                 \
21569         "socket <filename> [server] [renumber <dev_instance>] "         \
21570         "[disable_mrg_rxbuf] [disable_indirect_desc] [gso] "            \
21571         "[mac <mac_address>]")                                          \
21572 _(modify_vhost_user_if,                                                 \
21573         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
21574         "[server] [renumber <dev_instance>] [gso]")                     \
21575 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
21576 _(sw_interface_vhost_user_dump, "")                                     \
21577 _(show_version, "")                                                     \
21578 _(show_threads, "")                                                     \
21579 _(vxlan_gpe_add_del_tunnel,                                             \
21580   "local <addr> remote <addr>  | group <mcast-ip-addr>\n"               \
21581   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
21582   "vni <nn> [encap-vrf-id <nn>] [decap-vrf-id <nn>]\n"                  \
21583   "[next-ip4][next-ip6][next-ethernet] [next-nsh] [del]\n")             \
21584 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
21585 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
21586 _(interface_name_renumber,                                              \
21587   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
21588 _(input_acl_set_interface,                                              \
21589   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
21590   "  [l2-table <nn>] [del]")                                            \
21591 _(ip_probe_neighbor, "(<intc> | sw_if_index <nn>) address <ip4|ip6-addr>") \
21592 _(ip_scan_neighbor_enable_disable, "[ip4|ip6|both|disable] [interval <n-min>]\n" \
21593   "  [max-time <n-usec>] [max-update <n>] [delay <n-msec>] [stale <n-min>]") \
21594 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
21595 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
21596 _(want_l2_macs_events, "[disable] [learn-limit <n>] [scan-delay <n>] [max-entries <n>]") \
21597 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
21598 _(ip_dump, "ipv4 | ipv6")                                               \
21599 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
21600 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
21601   "  spid_id <n> ")                                                     \
21602 _(ipsec_sad_entry_add_del, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
21603   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
21604   "  integ_alg <alg> integ_key <hex>")                                  \
21605 _(ipsec_spd_entry_add_del, "spd_id <n> priority <n> action <action>\n"  \
21606   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
21607   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
21608   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
21609 _(ipsec_tunnel_if_add_del, "local_spi <n> remote_spi <n>\n"             \
21610   "  crypto_alg <alg> local_crypto_key <hex> remote_crypto_key <hex>\n" \
21611   "  integ_alg <alg> local_integ_key <hex> remote_integ_key <hex>\n"    \
21612   "  local_ip <addr> remote_ip <addr> [esn] [anti_replay] [del]\n"      \
21613   "  [instance <n>]")     \
21614 _(ipsec_sa_dump, "[sa_id <n>]")                                         \
21615 _(ipsec_tunnel_if_set_sa, "<intfc> sa_id <n> <inbound|outbound>\n")     \
21616 _(delete_loopback,"sw_if_index <nn>")                                   \
21617 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
21618 _(bd_ip_mac_flush, "bd_id <bridge-domain-id>")                          \
21619 _(bd_ip_mac_dump, "[bd_id] <bridge-domain-id>")                         \
21620 _(want_interface_events,  "enable|disable")                             \
21621 _(get_first_msg_id, "client <name>")                                    \
21622 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
21623 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
21624   "fib-id <nn> [ip4][ip6][default]")                                    \
21625 _(get_node_graph, " ")                                                  \
21626 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
21627 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
21628 _(ioam_disable, "")                                                     \
21629 _(one_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
21630                             " sw_if_index <sw_if_index> p <priority> "  \
21631                             "w <weight>] [del]")                        \
21632 _(one_add_del_locator, "locator-set <locator_name> "                    \
21633                         "iface <intf> | sw_if_index <sw_if_index> "     \
21634                         "p <priority> w <weight> [del]")                \
21635 _(one_add_del_local_eid,"vni <vni> eid "                                \
21636                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
21637                          "locator-set <locator_name> [del]"             \
21638                          "[key-id sha1|sha256 secret-key <secret-key>]")\
21639 _(one_add_del_map_resolver, "<ip4|6-addr> [del]")                       \
21640 _(one_add_del_map_server, "<ip4|6-addr> [del]")                         \
21641 _(one_enable_disable, "enable|disable")                                 \
21642 _(one_map_register_enable_disable, "enable|disable")                    \
21643 _(one_map_register_fallback_threshold, "<value>")                       \
21644 _(one_rloc_probe_enable_disable, "enable|disable")                      \
21645 _(one_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "       \
21646                                "[seid <seid>] "                         \
21647                                "rloc <locator> p <prio> "               \
21648                                "w <weight> [rloc <loc> ... ] "          \
21649                                "action <action> [del-all]")             \
21650 _(one_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "    \
21651                           "<local-eid>")                                \
21652 _(one_pitr_set_locator_set, "locator-set <loc-set-name> | del")         \
21653 _(one_use_petr, "ip-address> | disable")                                \
21654 _(one_map_request_mode, "src-dst|dst-only")                             \
21655 _(one_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")            \
21656 _(one_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")               \
21657 _(one_locator_set_dump, "[local | remote]")                             \
21658 _(one_locator_dump, "ls_index <index> | ls_name <name>")                \
21659 _(one_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "       \
21660                        "[local] | [remote]")                            \
21661 _(one_add_del_ndp_entry, "[del] mac <mac> bd <bd> ip6 <ip6>")           \
21662 _(one_ndp_bd_get, "")                                                   \
21663 _(one_ndp_entries_get, "bd <bridge-domain>")                            \
21664 _(one_add_del_l2_arp_entry, "[del] mac <mac> bd <bd> ip4 <ip4>")        \
21665 _(one_l2_arp_bd_get, "")                                                \
21666 _(one_l2_arp_entries_get, "bd <bridge-domain>")                         \
21667 _(one_stats_enable_disable, "enable|disable")                           \
21668 _(show_one_stats_enable_disable, "")                                    \
21669 _(one_eid_table_vni_dump, "")                                           \
21670 _(one_eid_table_map_dump, "l2|l3")                                      \
21671 _(one_map_resolver_dump, "")                                            \
21672 _(one_map_server_dump, "")                                              \
21673 _(one_adjacencies_get, "vni <vni>")                                     \
21674 _(one_nsh_set_locator_set, "[del] ls <locator-set-name>")               \
21675 _(show_one_rloc_probe_state, "")                                        \
21676 _(show_one_map_register_state, "")                                      \
21677 _(show_one_status, "")                                                  \
21678 _(one_stats_dump, "")                                                   \
21679 _(one_stats_flush, "")                                                  \
21680 _(one_get_map_request_itr_rlocs, "")                                    \
21681 _(one_map_register_set_ttl, "<ttl>")                                    \
21682 _(one_set_transport_protocol, "udp|api")                                \
21683 _(one_get_transport_protocol, "")                                       \
21684 _(one_enable_disable_xtr_mode, "enable|disable")                        \
21685 _(one_show_xtr_mode, "")                                                \
21686 _(one_enable_disable_pitr_mode, "enable|disable")                       \
21687 _(one_show_pitr_mode, "")                                               \
21688 _(one_enable_disable_petr_mode, "enable|disable")                       \
21689 _(one_show_petr_mode, "")                                               \
21690 _(show_one_nsh_mapping, "")                                             \
21691 _(show_one_pitr, "")                                                    \
21692 _(show_one_use_petr, "")                                                \
21693 _(show_one_map_request_mode, "")                                        \
21694 _(show_one_map_register_ttl, "")                                        \
21695 _(show_one_map_register_fallback_threshold, "")                         \
21696 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
21697                             " sw_if_index <sw_if_index> p <priority> "  \
21698                             "w <weight>] [del]")                        \
21699 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
21700                         "iface <intf> | sw_if_index <sw_if_index> "     \
21701                         "p <priority> w <weight> [del]")                \
21702 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
21703                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
21704                          "locator-set <locator_name> [del]"             \
21705                          "[key-id sha1|sha256 secret-key <secret-key>]") \
21706 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
21707 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
21708 _(lisp_enable_disable, "enable|disable")                                \
21709 _(lisp_map_register_enable_disable, "enable|disable")                   \
21710 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
21711 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
21712                                "[seid <seid>] "                         \
21713                                "rloc <locator> p <prio> "               \
21714                                "w <weight> [rloc <loc> ... ] "          \
21715                                "action <action> [del-all]")             \
21716 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
21717                           "<local-eid>")                                \
21718 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
21719 _(lisp_use_petr, "<ip-address> | disable")                              \
21720 _(lisp_map_request_mode, "src-dst|dst-only")                            \
21721 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
21722 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
21723 _(lisp_locator_set_dump, "[local | remote]")                            \
21724 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
21725 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
21726                        "[local] | [remote]")                            \
21727 _(lisp_eid_table_vni_dump, "")                                          \
21728 _(lisp_eid_table_map_dump, "l2|l3")                                     \
21729 _(lisp_map_resolver_dump, "")                                           \
21730 _(lisp_map_server_dump, "")                                             \
21731 _(lisp_adjacencies_get, "vni <vni>")                                    \
21732 _(gpe_fwd_entry_vnis_get, "")                                           \
21733 _(gpe_native_fwd_rpaths_get, "ip4 | ip6")                               \
21734 _(gpe_add_del_native_fwd_rpath, "[del] via <nh-ip-addr> [iface] "       \
21735                                 "[table <table-id>]")                   \
21736 _(lisp_gpe_fwd_entries_get, "vni <vni>")                                \
21737 _(lisp_gpe_fwd_entry_path_dump, "index <fwd_entry_index>")              \
21738 _(gpe_set_encap_mode, "lisp|vxlan")                                     \
21739 _(gpe_get_encap_mode, "")                                               \
21740 _(lisp_gpe_add_del_iface, "up|down")                                    \
21741 _(lisp_gpe_enable_disable, "enable|disable")                            \
21742 _(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>"       \
21743   "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
21744 _(show_lisp_rloc_probe_state, "")                                       \
21745 _(show_lisp_map_register_state, "")                                     \
21746 _(show_lisp_status, "")                                                 \
21747 _(lisp_get_map_request_itr_rlocs, "")                                   \
21748 _(show_lisp_pitr, "")                                                   \
21749 _(show_lisp_use_petr, "")                                               \
21750 _(show_lisp_map_request_mode, "")                                       \
21751 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
21752 _(af_packet_delete, "name <host interface name>")                       \
21753 _(af_packet_dump, "")                                                   \
21754 _(policer_add_del, "name <policer name> <params> [del]")                \
21755 _(policer_dump, "[name <policer name>]")                                \
21756 _(policer_classify_set_interface,                                       \
21757   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
21758   "  [l2-table <nn>] [del]")                                            \
21759 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
21760 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
21761     "[master|slave]")                                                   \
21762 _(netmap_delete, "name <interface name>")                               \
21763 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
21764 _(mpls_table_dump, "")                                                  \
21765 _(mpls_route_dump, "table-id <ID>")                                     \
21766 _(classify_table_ids, "")                                               \
21767 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
21768 _(classify_table_info, "table_id <nn>")                                 \
21769 _(classify_session_dump, "table_id <nn>")                               \
21770 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
21771     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
21772     "[template_interval <nn>] [udp_checksum]")                          \
21773 _(ipfix_exporter_dump, "")                                              \
21774 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
21775 _(ipfix_classify_stream_dump, "")                                       \
21776 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
21777 _(ipfix_classify_table_dump, "")                                        \
21778 _(sw_interface_span_enable_disable, "[l2] [src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
21779 _(sw_interface_span_dump, "[l2]")                                           \
21780 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
21781 _(pg_create_interface, "if_id <nn> [gso-enabled gso-size <size>]")      \
21782 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
21783 _(pg_enable_disable, "[stream <id>] disable")                           \
21784 _(ip_source_and_port_range_check_add_del,                               \
21785   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
21786 _(ip_source_and_port_range_check_interface_add_del,                     \
21787   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
21788   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
21789 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
21790 _(l2_interface_pbb_tag_rewrite,                                         \
21791   "<intfc> | sw_if_index <nn> \n"                                       \
21792   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
21793   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
21794 _(set_punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
21795 _(flow_classify_set_interface,                                          \
21796   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
21797 _(flow_classify_dump, "type [ip4|ip6]")                                 \
21798 _(ip_table_dump, "")                                                    \
21799 _(ip_route_dump, "table-id [ip4|ip6]")                                  \
21800 _(ip_mtable_dump, "")                                                   \
21801 _(ip_mroute_dump, "table-id [ip4|ip6]")                                 \
21802 _(feature_enable_disable, "arc_name <arc_name> "                        \
21803   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
21804 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
21805 "[disable]")                                                            \
21806 _(sw_interface_add_del_mac_address, "<intfc> | sw_if_index <nn> "       \
21807   "mac <mac-address> [del]")                                            \
21808 _(l2_xconnect_dump, "")                                                 \
21809 _(hw_interface_set_mtu, "<intfc> | hw_if_index <nn> mtu <nn>")        \
21810 _(ip_neighbor_dump, "[ip6] <intfc> | sw_if_index <nn>")                 \
21811 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")          \
21812 _(p2p_ethernet_add, "<intfc> | sw_if_index <nn> remote_mac <mac-address> sub_id <id>") \
21813 _(p2p_ethernet_del, "<intfc> | sw_if_index <nn> remote_mac <mac-address>") \
21814 _(lldp_config, "system-name <name> tx-hold <nn> tx-interval <nn>") \
21815 _(sw_interface_set_lldp, "<intfc> | sw_if_index <nn> [port-desc <description>]\n" \
21816   " [mgmt-ip4 <ip4>] [mgmt-ip6 <ip6>] [mgmt-oid <object id>] [disable]") \
21817 _(tcp_configure_src_addresses, "<ip4|6>first-<ip4|6>last [vrf <id>]")   \
21818 _(sock_init_shm, "size <nnn>")                                          \
21819 _(app_namespace_add_del, "[add] id <ns-id> secret <nn> sw_if_index <nn>")\
21820 _(session_rule_add_del, "[add|del] proto <tcp/udp> <lcl-ip>/<plen> "    \
21821   "<lcl-port> <rmt-ip>/<plen> <rmt-port> action <nn>")                  \
21822 _(session_rules_dump, "")                                               \
21823 _(ip_container_proxy_add_del, "[add|del] <address> <sw_if_index>")      \
21824 _(output_acl_set_interface,                                             \
21825   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
21826   "  [l2-table <nn>] [del]")                                            \
21827 _(qos_record_enable_disable, "<record-source> <intfc> | sw_if_index <id> [disable]")
21828
21829 /* List of command functions, CLI names map directly to functions */
21830 #define foreach_cli_function                                    \
21831 _(comment, "usage: comment <ignore-rest-of-line>")              \
21832 _(dump_interface_table, "usage: dump_interface_table")          \
21833 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
21834 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
21835 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
21836 _(dump_macro_table, "usage: dump_macro_table ")                 \
21837 _(dump_node_table, "usage: dump_node_table")                    \
21838 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
21839 _(elog_setup, "usage: elog_setup [nevents, default 128K]")      \
21840 _(elog_disable, "usage: elog_disable")                          \
21841 _(elog_enable, "usage: elog_enable")                            \
21842 _(elog_save, "usage: elog_save <filename>")                     \
21843 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
21844 _(echo, "usage: echo <message>")                                \
21845 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
21846 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
21847 _(help, "usage: help")                                          \
21848 _(q, "usage: quit")                                             \
21849 _(quit, "usage: quit")                                          \
21850 _(search_node_table, "usage: search_node_table <name>...")      \
21851 _(set, "usage: set <variable-name> <value>")                    \
21852 _(script, "usage: script <file-name>")                          \
21853 _(statseg, "usage: statseg")                                    \
21854 _(unset, "usage: unset <variable-name>")
21855
21856 #define _(N,n)                                  \
21857     static void vl_api_##n##_t_handler_uni      \
21858     (vl_api_##n##_t * mp)                       \
21859     {                                           \
21860         vat_main_t * vam = &vat_main;           \
21861         if (vam->json_output) {                 \
21862             vl_api_##n##_t_handler_json(mp);    \
21863         } else {                                \
21864             vl_api_##n##_t_handler(mp);         \
21865         }                                       \
21866     }
21867 foreach_vpe_api_reply_msg;
21868 #if VPP_API_TEST_BUILTIN == 0
21869 foreach_standalone_reply_msg;
21870 #endif
21871 #undef _
21872
21873 void
21874 vat_api_hookup (vat_main_t * vam)
21875 {
21876 #define _(N,n)                                                  \
21877     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
21878                            vl_api_##n##_t_handler_uni,          \
21879                            vl_noop_handler,                     \
21880                            vl_api_##n##_t_endian,               \
21881                            vl_api_##n##_t_print,                \
21882                            sizeof(vl_api_##n##_t), 1);
21883   foreach_vpe_api_reply_msg;
21884 #if VPP_API_TEST_BUILTIN == 0
21885   foreach_standalone_reply_msg;
21886 #endif
21887 #undef _
21888
21889 #if (VPP_API_TEST_BUILTIN==0)
21890   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
21891
21892   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
21893
21894   vam->function_by_name = hash_create_string (0, sizeof (uword));
21895
21896   vam->help_by_name = hash_create_string (0, sizeof (uword));
21897 #endif
21898
21899   /* API messages we can send */
21900 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
21901   foreach_vpe_api_msg;
21902 #undef _
21903
21904   /* Help strings */
21905 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
21906   foreach_vpe_api_msg;
21907 #undef _
21908
21909   /* CLI functions */
21910 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
21911   foreach_cli_function;
21912 #undef _
21913
21914   /* Help strings */
21915 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
21916   foreach_cli_function;
21917 #undef _
21918 }
21919
21920 #if VPP_API_TEST_BUILTIN
21921 static clib_error_t *
21922 vat_api_hookup_shim (vlib_main_t * vm)
21923 {
21924   vat_api_hookup (&vat_main);
21925   return 0;
21926 }
21927
21928 VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
21929 #endif
21930
21931 /*
21932  * fd.io coding-style-patch-verification: ON
21933  *
21934  * Local Variables:
21935  * eval: (c-set-style "gnu")
21936  * End:
21937  */