dhcp: Move to plugin
[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 _(hw_interface_set_mtu_reply)                           \
5177 _(p2p_ethernet_add_reply)                               \
5178 _(p2p_ethernet_del_reply)                               \
5179 _(lldp_config_reply)                                    \
5180 _(sw_interface_set_lldp_reply)                          \
5181 _(tcp_configure_src_addresses_reply)                    \
5182 _(session_rule_add_del_reply)                           \
5183 _(ip_container_proxy_add_del_reply)                     \
5184 _(output_acl_set_interface_reply)                       \
5185 _(qos_record_enable_disable_reply)
5186
5187 #define _(n)                                    \
5188     static void vl_api_##n##_t_handler          \
5189     (vl_api_##n##_t * mp)                       \
5190     {                                           \
5191         vat_main_t * vam = &vat_main;           \
5192         i32 retval = ntohl(mp->retval);         \
5193         if (vam->async_mode) {                  \
5194             vam->async_errors += (retval < 0);  \
5195         } else {                                \
5196             vam->retval = retval;               \
5197             vam->result_ready = 1;              \
5198         }                                       \
5199     }
5200 foreach_standard_reply_retval_handler;
5201 #undef _
5202
5203 #define _(n)                                    \
5204     static void vl_api_##n##_t_handler_json     \
5205     (vl_api_##n##_t * mp)                       \
5206     {                                           \
5207         vat_main_t * vam = &vat_main;           \
5208         vat_json_node_t node;                   \
5209         vat_json_init_object(&node);            \
5210         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
5211         vat_json_print(vam->ofp, &node);        \
5212         vam->retval = ntohl(mp->retval);        \
5213         vam->result_ready = 1;                  \
5214     }
5215 foreach_standard_reply_retval_handler;
5216 #undef _
5217
5218 /*
5219  * Table of message reply handlers, must include boilerplate handlers
5220  * we just generated
5221  */
5222
5223 #define foreach_vpe_api_reply_msg                                       \
5224 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
5225 _(CREATE_LOOPBACK_INSTANCE_REPLY, create_loopback_instance_reply)       \
5226 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
5227 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
5228 _(CONTROL_PING_REPLY, control_ping_reply)                               \
5229 _(CLI_REPLY, cli_reply)                                                 \
5230 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
5231 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
5232   sw_interface_add_del_address_reply)                                   \
5233 _(SW_INTERFACE_SET_RX_MODE_REPLY, sw_interface_set_rx_mode_reply)       \
5234 _(SW_INTERFACE_SET_RX_PLACEMENT_REPLY, sw_interface_set_rx_placement_reply)     \
5235 _(SW_INTERFACE_RX_PLACEMENT_DETAILS, sw_interface_rx_placement_details) \
5236 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
5237 _(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
5238 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
5239 _(SW_INTERFACE_SET_VXLAN_BYPASS_REPLY, sw_interface_set_vxlan_bypass_reply) \
5240 _(SW_INTERFACE_SET_GENEVE_BYPASS_REPLY, sw_interface_set_geneve_bypass_reply) \
5241 _(SW_INTERFACE_SET_VXLAN_GPE_BYPASS_REPLY, sw_interface_set_vxlan_gpe_bypass_reply) \
5242 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
5243   sw_interface_set_l2_xconnect_reply)                                   \
5244 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
5245   sw_interface_set_l2_bridge_reply)                                     \
5246 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
5247 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
5248 _(BRIDGE_DOMAIN_SET_MAC_AGE_REPLY, bridge_domain_set_mac_age_reply)     \
5249 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
5250 _(L2FIB_FLUSH_INT_REPLY, l2fib_flush_int_reply)                         \
5251 _(L2FIB_FLUSH_BD_REPLY, l2fib_flush_bd_reply)                           \
5252 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
5253 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
5254 _(TAP_CREATE_V2_REPLY, tap_create_v2_reply)                             \
5255 _(TAP_DELETE_V2_REPLY, tap_delete_v2_reply)                             \
5256 _(SW_INTERFACE_TAP_V2_DETAILS, sw_interface_tap_v2_details)             \
5257 _(VIRTIO_PCI_CREATE_REPLY, virtio_pci_create_reply)                     \
5258 _(VIRTIO_PCI_DELETE_REPLY, virtio_pci_delete_reply)                     \
5259 _(SW_INTERFACE_VIRTIO_PCI_DETAILS, sw_interface_virtio_pci_details)     \
5260 _(BOND_CREATE_REPLY, bond_create_reply)                                 \
5261 _(BOND_DELETE_REPLY, bond_delete_reply)                                 \
5262 _(BOND_ENSLAVE_REPLY, bond_enslave_reply)                               \
5263 _(BOND_DETACH_SLAVE_REPLY, bond_detach_slave_reply)                     \
5264 _(SW_INTERFACE_SET_BOND_WEIGHT_REPLY, sw_interface_set_bond_weight_reply) \
5265 _(SW_INTERFACE_BOND_DETAILS, sw_interface_bond_details)                 \
5266 _(SW_INTERFACE_SLAVE_DETAILS, sw_interface_slave_details)               \
5267 _(IP_ROUTE_ADD_DEL_REPLY, ip_route_add_del_reply)                       \
5268 _(IP_TABLE_ADD_DEL_REPLY, ip_table_add_del_reply)                       \
5269 _(IP_MROUTE_ADD_DEL_REPLY, ip_mroute_add_del_reply)                     \
5270 _(MPLS_TABLE_ADD_DEL_REPLY, mpls_table_add_del_reply)                   \
5271 _(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply)                   \
5272 _(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply)                 \
5273 _(BIER_ROUTE_ADD_DEL_REPLY, bier_route_add_del_reply)                   \
5274 _(BIER_TABLE_ADD_DEL_REPLY, bier_table_add_del_reply)                   \
5275 _(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply)                     \
5276 _(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY,                                 \
5277   proxy_arp_intfc_enable_disable_reply)                                 \
5278 _(MPLS_TUNNEL_ADD_DEL_REPLY, mpls_tunnel_add_del_reply)                 \
5279 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
5280   sw_interface_set_unnumbered_reply)                                    \
5281 _(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply)                 \
5282 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
5283 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
5284 _(RESET_FIB_REPLY, reset_fib_reply)                                     \
5285 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
5286 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
5287   sw_interface_ip6_enable_disable_reply)                                \
5288 _(IP6ND_PROXY_ADD_DEL_REPLY, ip6nd_proxy_add_del_reply)                 \
5289 _(IP6ND_PROXY_DETAILS, ip6nd_proxy_details)                             \
5290 _(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY,                                   \
5291   sw_interface_ip6nd_ra_prefix_reply)                                   \
5292 _(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY,                                   \
5293   sw_interface_ip6nd_ra_config_reply)                                   \
5294 _(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply)           \
5295 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
5296 _(SR_MPLS_POLICY_ADD_REPLY, sr_mpls_policy_add_reply)                   \
5297 _(SR_MPLS_POLICY_MOD_REPLY, sr_mpls_policy_mod_reply)                   \
5298 _(SR_MPLS_POLICY_DEL_REPLY, sr_mpls_policy_del_reply)                   \
5299 _(SR_POLICY_ADD_REPLY, sr_policy_add_reply)                             \
5300 _(SR_POLICY_MOD_REPLY, sr_policy_mod_reply)                             \
5301 _(SR_POLICY_DEL_REPLY, sr_policy_del_reply)                             \
5302 _(SR_LOCALSID_ADD_DEL_REPLY, sr_localsid_add_del_reply)                 \
5303 _(SR_STEERING_ADD_DEL_REPLY, sr_steering_add_del_reply)                 \
5304 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
5305 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
5306 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
5307 classify_set_interface_ip_table_reply)                                  \
5308 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
5309   classify_set_interface_l2_tables_reply)                               \
5310 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
5311 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
5312 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
5313 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
5314 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
5315   l2tpv3_interface_enable_disable_reply)                                \
5316 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
5317 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
5318 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
5319 _(VXLAN_OFFLOAD_RX_REPLY, vxlan_offload_rx_reply)               \
5320 _(GENEVE_ADD_DEL_TUNNEL_REPLY, geneve_add_del_tunnel_reply)             \
5321 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
5322 _(GENEVE_TUNNEL_DETAILS, geneve_tunnel_details)                         \
5323 _(GRE_TUNNEL_ADD_DEL_REPLY, gre_tunnel_add_del_reply)                   \
5324 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
5325 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
5326 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
5327 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
5328 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
5329 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
5330 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
5331 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
5332 _(SHOW_VERSION_REPLY, show_version_reply)                               \
5333 _(SHOW_THREADS_REPLY, show_threads_reply)                               \
5334 _(L2_FIB_TABLE_DETAILS, l2_fib_table_details)                           \
5335 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)       \
5336 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
5337 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
5338 _(IP_PROBE_NEIGHBOR_REPLY, ip_probe_neighbor_reply)                     \
5339 _(IP_SCAN_NEIGHBOR_ENABLE_DISABLE_REPLY, ip_scan_neighbor_enable_disable_reply) \
5340 _(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply)                 \
5341 _(IP4_ARP_EVENT, ip4_arp_event)                                         \
5342 _(WANT_IP6_ND_EVENTS_REPLY, want_ip6_nd_events_reply)                   \
5343 _(IP6_ND_EVENT, ip6_nd_event)                                           \
5344 _(WANT_L2_MACS_EVENTS_REPLY, want_l2_macs_events_reply)                 \
5345 _(L2_MACS_EVENT, l2_macs_event)                                         \
5346 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
5347 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
5348 _(IP_DETAILS, ip_details)                                               \
5349 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
5350 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
5351 _(IPSEC_SPD_ENTRY_ADD_DEL_REPLY, ipsec_spd_entry_add_del_reply)         \
5352 _(IPSEC_SAD_ENTRY_ADD_DEL_REPLY, ipsec_sad_entry_add_del_reply)         \
5353 _(IPSEC_SA_DETAILS, ipsec_sa_details)                                   \
5354 _(IPSEC_TUNNEL_IF_ADD_DEL_REPLY, ipsec_tunnel_if_add_del_reply)         \
5355 _(IPSEC_TUNNEL_IF_SET_SA_REPLY, ipsec_tunnel_if_set_sa_reply)           \
5356 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
5357 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
5358 _(BD_IP_MAC_FLUSH_REPLY, bd_ip_mac_flush_reply)                         \
5359 _(BD_IP_MAC_DETAILS, bd_ip_mac_details)                                 \
5360 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
5361 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
5362 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
5363 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
5364 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
5365 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
5366 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
5367 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
5368 _(ONE_ADD_DEL_LOCATOR_SET_REPLY, one_add_del_locator_set_reply)         \
5369 _(ONE_ADD_DEL_LOCATOR_REPLY, one_add_del_locator_reply)                 \
5370 _(ONE_ADD_DEL_LOCAL_EID_REPLY, one_add_del_local_eid_reply)             \
5371 _(ONE_ADD_DEL_REMOTE_MAPPING_REPLY, one_add_del_remote_mapping_reply)   \
5372 _(ONE_ADD_DEL_ADJACENCY_REPLY, one_add_del_adjacency_reply)             \
5373 _(ONE_ADD_DEL_MAP_RESOLVER_REPLY, one_add_del_map_resolver_reply)       \
5374 _(ONE_ADD_DEL_MAP_SERVER_REPLY, one_add_del_map_server_reply)           \
5375 _(ONE_ENABLE_DISABLE_REPLY, one_enable_disable_reply)                   \
5376 _(ONE_MAP_REGISTER_ENABLE_DISABLE_REPLY,                                \
5377   one_map_register_enable_disable_reply)                                \
5378 _(ONE_MAP_REGISTER_SET_TTL_REPLY, one_map_register_set_ttl_reply)       \
5379 _(ONE_SET_TRANSPORT_PROTOCOL_REPLY, one_set_transport_protocol_reply)   \
5380 _(ONE_GET_TRANSPORT_PROTOCOL_REPLY, one_get_transport_protocol_reply)   \
5381 _(ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                            \
5382   one_map_register_fallback_threshold_reply)                            \
5383 _(ONE_RLOC_PROBE_ENABLE_DISABLE_REPLY,                                  \
5384   one_rloc_probe_enable_disable_reply)                                  \
5385 _(ONE_PITR_SET_LOCATOR_SET_REPLY, one_pitr_set_locator_set_reply)       \
5386 _(ONE_USE_PETR_REPLY, one_use_petr_reply)                               \
5387 _(ONE_MAP_REQUEST_MODE_REPLY, one_map_request_mode_reply)               \
5388 _(ONE_EID_TABLE_ADD_DEL_MAP_REPLY, one_eid_table_add_del_map_reply)     \
5389 _(ONE_LOCATOR_SET_DETAILS, one_locator_set_details)                     \
5390 _(ONE_LOCATOR_DETAILS, one_locator_details)                             \
5391 _(ONE_EID_TABLE_DETAILS, one_eid_table_details)                         \
5392 _(ONE_EID_TABLE_MAP_DETAILS, one_eid_table_map_details)                 \
5393 _(ONE_EID_TABLE_VNI_DETAILS, one_eid_table_vni_details)                 \
5394 _(ONE_MAP_RESOLVER_DETAILS, one_map_resolver_details)                   \
5395 _(ONE_MAP_SERVER_DETAILS, one_map_server_details)                       \
5396 _(ONE_ADJACENCIES_GET_REPLY, one_adjacencies_get_reply)                 \
5397 _(ONE_STATS_DETAILS, one_stats_details)                                 \
5398 _(ONE_STATS_FLUSH_REPLY, one_stats_flush_reply)                         \
5399 _(ONE_STATS_ENABLE_DISABLE_REPLY, one_stats_enable_disable_reply)       \
5400 _(SHOW_ONE_STATS_ENABLE_DISABLE_REPLY,                                  \
5401   show_one_stats_enable_disable_reply)                                  \
5402 _(ONE_ADD_DEL_NDP_ENTRY_REPLY, one_add_del_ndp_entry_reply)             \
5403 _(ONE_NDP_BD_GET_REPLY, one_ndp_bd_get_reply)                           \
5404 _(ONE_NDP_ENTRIES_GET_REPLY, one_ndp_entries_get_reply)                 \
5405 _(ONE_ADD_DEL_L2_ARP_ENTRY_REPLY, one_add_del_l2_arp_entry_reply)       \
5406 _(ONE_L2_ARP_BD_GET_REPLY, one_l2_arp_bd_get_reply)                     \
5407 _(ONE_L2_ARP_ENTRIES_GET_REPLY, one_l2_arp_entries_get_reply)           \
5408 _(ONE_ENABLE_DISABLE_XTR_MODE_REPLY, one_enable_disable_xtr_mode_reply) \
5409 _(ONE_ENABLE_DISABLE_PITR_MODE_REPLY,                                   \
5410   one_enable_disable_pitr_mode_reply)                                   \
5411 _(ONE_ENABLE_DISABLE_PETR_MODE_REPLY,                                   \
5412   one_enable_disable_petr_mode_reply)                                   \
5413 _(ONE_SHOW_XTR_MODE_REPLY, one_show_xtr_mode_reply)                     \
5414 _(ONE_SHOW_PITR_MODE_REPLY, one_show_pitr_mode_reply)                   \
5415 _(ONE_SHOW_PETR_MODE_REPLY, one_show_petr_mode_reply)                   \
5416 _(GPE_SET_ENCAP_MODE_REPLY, gpe_set_encap_mode_reply)                   \
5417 _(GPE_GET_ENCAP_MODE_REPLY, gpe_get_encap_mode_reply)                   \
5418 _(GPE_ADD_DEL_IFACE_REPLY, gpe_add_del_iface_reply)                     \
5419 _(GPE_ENABLE_DISABLE_REPLY, gpe_enable_disable_reply)                   \
5420 _(GPE_ADD_DEL_FWD_ENTRY_REPLY, gpe_add_del_fwd_entry_reply)             \
5421 _(GPE_FWD_ENTRY_VNIS_GET_REPLY, gpe_fwd_entry_vnis_get_reply)           \
5422 _(GPE_FWD_ENTRIES_GET_REPLY, gpe_fwd_entries_get_reply)                 \
5423 _(GPE_NATIVE_FWD_RPATHS_GET_REPLY, gpe_native_fwd_rpaths_get_reply)     \
5424 _(GPE_ADD_DEL_NATIVE_FWD_RPATH_REPLY,                                   \
5425   gpe_add_del_native_fwd_rpath_reply)                                   \
5426 _(GPE_FWD_ENTRY_PATH_DETAILS,                                           \
5427   gpe_fwd_entry_path_details)                                           \
5428 _(SHOW_ONE_STATUS_REPLY, show_one_status_reply)                         \
5429 _(ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                              \
5430   one_add_del_map_request_itr_rlocs_reply)                              \
5431 _(ONE_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                  \
5432   one_get_map_request_itr_rlocs_reply)                                  \
5433 _(SHOW_ONE_NSH_MAPPING_REPLY, show_one_nsh_mapping_reply)               \
5434 _(SHOW_ONE_PITR_REPLY, show_one_pitr_reply)                             \
5435 _(SHOW_ONE_USE_PETR_REPLY, show_one_use_petr_reply)                     \
5436 _(SHOW_ONE_MAP_REQUEST_MODE_REPLY, show_one_map_request_mode_reply)     \
5437 _(SHOW_ONE_RLOC_PROBE_STATE_REPLY, show_one_rloc_probe_state_reply)     \
5438 _(SHOW_ONE_MAP_REGISTER_STATE_REPLY,                                    \
5439   show_one_map_register_state_reply)                                    \
5440 _(SHOW_ONE_MAP_REGISTER_TTL_REPLY, show_one_map_register_ttl_reply)     \
5441 _(SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                       \
5442   show_one_map_register_fallback_threshold_reply)                       \
5443 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
5444 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
5445 _(AF_PACKET_DETAILS, af_packet_details)                                 \
5446 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
5447 _(POLICER_DETAILS, policer_details)                                     \
5448 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
5449 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
5450 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
5451 _(NETMAP_DELETE_REPLY, netmap_delete_reply)                             \
5452 _(MPLS_TUNNEL_DETAILS, mpls_tunnel_details)                             \
5453 _(MPLS_TABLE_DETAILS, mpls_table_details)                               \
5454 _(MPLS_ROUTE_DETAILS, mpls_route_details)                               \
5455 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
5456 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
5457 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
5458 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
5459 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
5460 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
5461 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
5462 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
5463 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
5464 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
5465 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
5466 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
5467 _(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
5468 _(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details)                 \
5469 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
5470 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
5471 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
5472 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
5473 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
5474  ip_source_and_port_range_check_add_del_reply)                          \
5475 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
5476  ip_source_and_port_range_check_interface_add_del_reply)                \
5477 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
5478 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
5479 _(SET_PUNT_REPLY, set_punt_reply)                                       \
5480 _(IP_TABLE_DETAILS, ip_table_details)                                   \
5481 _(IP_ROUTE_DETAILS, ip_route_details)                                   \
5482 _(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply)           \
5483 _(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply)       \
5484 _(L2_XCONNECT_DETAILS, l2_xconnect_details)                             \
5485 _(HW_INTERFACE_SET_MTU_REPLY, hw_interface_set_mtu_reply)               \
5486 _(IP_NEIGHBOR_DETAILS, ip_neighbor_details)                             \
5487 _(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply)           \
5488 _(P2P_ETHERNET_ADD_REPLY, p2p_ethernet_add_reply)                       \
5489 _(P2P_ETHERNET_DEL_REPLY, p2p_ethernet_del_reply)                       \
5490 _(LLDP_CONFIG_REPLY, lldp_config_reply)                                 \
5491 _(SW_INTERFACE_SET_LLDP_REPLY, sw_interface_set_lldp_reply)             \
5492 _(TCP_CONFIGURE_SRC_ADDRESSES_REPLY, tcp_configure_src_addresses_reply) \
5493 _(APP_NAMESPACE_ADD_DEL_REPLY, app_namespace_add_del_reply)             \
5494 _(SESSION_RULE_ADD_DEL_REPLY, session_rule_add_del_reply)               \
5495 _(SESSION_RULES_DETAILS, session_rules_details)                         \
5496 _(IP_CONTAINER_PROXY_ADD_DEL_REPLY, ip_container_proxy_add_del_reply)   \
5497 _(OUTPUT_ACL_SET_INTERFACE_REPLY, output_acl_set_interface_reply)       \
5498 _(QOS_RECORD_ENABLE_DISABLE_REPLY, qos_record_enable_disable_reply)
5499
5500 #define foreach_standalone_reply_msg                                    \
5501 _(SW_INTERFACE_EVENT, sw_interface_event)
5502
5503 typedef struct
5504 {
5505   u8 *name;
5506   u32 value;
5507 } name_sort_t;
5508
5509 #define STR_VTR_OP_CASE(op)     \
5510     case L2_VTR_ ## op:         \
5511         return "" # op;
5512
5513 static const char *
5514 str_vtr_op (u32 vtr_op)
5515 {
5516   switch (vtr_op)
5517     {
5518       STR_VTR_OP_CASE (DISABLED);
5519       STR_VTR_OP_CASE (PUSH_1);
5520       STR_VTR_OP_CASE (PUSH_2);
5521       STR_VTR_OP_CASE (POP_1);
5522       STR_VTR_OP_CASE (POP_2);
5523       STR_VTR_OP_CASE (TRANSLATE_1_1);
5524       STR_VTR_OP_CASE (TRANSLATE_1_2);
5525       STR_VTR_OP_CASE (TRANSLATE_2_1);
5526       STR_VTR_OP_CASE (TRANSLATE_2_2);
5527     }
5528
5529   return "UNKNOWN";
5530 }
5531
5532 static int
5533 dump_sub_interface_table (vat_main_t * vam)
5534 {
5535   const sw_interface_subif_t *sub = NULL;
5536
5537   if (vam->json_output)
5538     {
5539       clib_warning
5540         ("JSON output supported only for VPE API calls and dump_stats_table");
5541       return -99;
5542     }
5543
5544   print (vam->ofp,
5545          "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
5546          "Interface", "sw_if_index",
5547          "sub id", "dot1ad", "tags", "outer id",
5548          "inner id", "exact", "default", "outer any", "inner any");
5549
5550   vec_foreach (sub, vam->sw_if_subif_table)
5551   {
5552     print (vam->ofp,
5553            "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
5554            sub->interface_name,
5555            sub->sw_if_index,
5556            sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
5557            sub->sub_number_of_tags, sub->sub_outer_vlan_id,
5558            sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
5559            sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
5560     if (sub->vtr_op != L2_VTR_DISABLED)
5561       {
5562         print (vam->ofp,
5563                "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
5564                "tag1: %d tag2: %d ]",
5565                str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
5566                sub->vtr_tag1, sub->vtr_tag2);
5567       }
5568   }
5569
5570   return 0;
5571 }
5572
5573 static int
5574 name_sort_cmp (void *a1, void *a2)
5575 {
5576   name_sort_t *n1 = a1;
5577   name_sort_t *n2 = a2;
5578
5579   return strcmp ((char *) n1->name, (char *) n2->name);
5580 }
5581
5582 static int
5583 dump_interface_table (vat_main_t * vam)
5584 {
5585   hash_pair_t *p;
5586   name_sort_t *nses = 0, *ns;
5587
5588   if (vam->json_output)
5589     {
5590       clib_warning
5591         ("JSON output supported only for VPE API calls and dump_stats_table");
5592       return -99;
5593     }
5594
5595   /* *INDENT-OFF* */
5596   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5597   ({
5598     vec_add2 (nses, ns, 1);
5599     ns->name = (u8 *)(p->key);
5600     ns->value = (u32) p->value[0];
5601   }));
5602   /* *INDENT-ON* */
5603
5604   vec_sort_with_function (nses, name_sort_cmp);
5605
5606   print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
5607   vec_foreach (ns, nses)
5608   {
5609     print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
5610   }
5611   vec_free (nses);
5612   return 0;
5613 }
5614
5615 static int
5616 dump_ip_table (vat_main_t * vam, int is_ipv6)
5617 {
5618   const ip_details_t *det = NULL;
5619   const ip_address_details_t *address = NULL;
5620   u32 i = ~0;
5621
5622   print (vam->ofp, "%-12s", "sw_if_index");
5623
5624   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
5625   {
5626     i++;
5627     if (!det->present)
5628       {
5629         continue;
5630       }
5631     print (vam->ofp, "%-12d", i);
5632     print (vam->ofp, "            %-30s%-13s", "Address", "Prefix length");
5633     if (!det->addr)
5634       {
5635         continue;
5636       }
5637     vec_foreach (address, det->addr)
5638     {
5639       print (vam->ofp,
5640              "            %-30U%-13d",
5641              is_ipv6 ? format_ip6_address : format_ip4_address,
5642              address->ip, address->prefix_length);
5643     }
5644   }
5645
5646   return 0;
5647 }
5648
5649 static int
5650 dump_ipv4_table (vat_main_t * vam)
5651 {
5652   if (vam->json_output)
5653     {
5654       clib_warning
5655         ("JSON output supported only for VPE API calls and dump_stats_table");
5656       return -99;
5657     }
5658
5659   return dump_ip_table (vam, 0);
5660 }
5661
5662 static int
5663 dump_ipv6_table (vat_main_t * vam)
5664 {
5665   if (vam->json_output)
5666     {
5667       clib_warning
5668         ("JSON output supported only for VPE API calls and dump_stats_table");
5669       return -99;
5670     }
5671
5672   return dump_ip_table (vam, 1);
5673 }
5674
5675 /*
5676  * Pass CLI buffers directly in the CLI_INBAND API message,
5677  * instead of an additional shared memory area.
5678  */
5679 static int
5680 exec_inband (vat_main_t * vam)
5681 {
5682   vl_api_cli_inband_t *mp;
5683   unformat_input_t *i = vam->input;
5684   int ret;
5685
5686   if (vec_len (i->buffer) == 0)
5687     return -1;
5688
5689   if (vam->exec_mode == 0 && unformat (i, "mode"))
5690     {
5691       vam->exec_mode = 1;
5692       return 0;
5693     }
5694   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
5695     {
5696       vam->exec_mode = 0;
5697       return 0;
5698     }
5699
5700   /*
5701    * In order for the CLI command to work, it
5702    * must be a vector ending in \n, not a C-string ending
5703    * in \n\0.
5704    */
5705   u32 len = vec_len (vam->input->buffer);
5706   M2 (CLI_INBAND, mp, len);
5707   vl_api_to_api_string (len - 1, (const char *) vam->input->buffer, &mp->cmd);
5708
5709   S (mp);
5710   W (ret);
5711   /* json responses may or may not include a useful reply... */
5712   if (vec_len (vam->cmd_reply))
5713     print (vam->ofp, "%v", (char *) (vam->cmd_reply));
5714   return ret;
5715 }
5716
5717 int
5718 exec (vat_main_t * vam)
5719 {
5720   return exec_inband (vam);
5721 }
5722
5723 static int
5724 api_create_loopback (vat_main_t * vam)
5725 {
5726   unformat_input_t *i = vam->input;
5727   vl_api_create_loopback_t *mp;
5728   vl_api_create_loopback_instance_t *mp_lbi;
5729   u8 mac_address[6];
5730   u8 mac_set = 0;
5731   u8 is_specified = 0;
5732   u32 user_instance = 0;
5733   int ret;
5734
5735   clib_memset (mac_address, 0, sizeof (mac_address));
5736
5737   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5738     {
5739       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5740         mac_set = 1;
5741       if (unformat (i, "instance %d", &user_instance))
5742         is_specified = 1;
5743       else
5744         break;
5745     }
5746
5747   if (is_specified)
5748     {
5749       M (CREATE_LOOPBACK_INSTANCE, mp_lbi);
5750       mp_lbi->is_specified = is_specified;
5751       if (is_specified)
5752         mp_lbi->user_instance = htonl (user_instance);
5753       if (mac_set)
5754         clib_memcpy (mp_lbi->mac_address, mac_address, sizeof (mac_address));
5755       S (mp_lbi);
5756     }
5757   else
5758     {
5759       /* Construct the API message */
5760       M (CREATE_LOOPBACK, mp);
5761       if (mac_set)
5762         clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
5763       S (mp);
5764     }
5765
5766   W (ret);
5767   return ret;
5768 }
5769
5770 static int
5771 api_delete_loopback (vat_main_t * vam)
5772 {
5773   unformat_input_t *i = vam->input;
5774   vl_api_delete_loopback_t *mp;
5775   u32 sw_if_index = ~0;
5776   int ret;
5777
5778   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5779     {
5780       if (unformat (i, "sw_if_index %d", &sw_if_index))
5781         ;
5782       else
5783         break;
5784     }
5785
5786   if (sw_if_index == ~0)
5787     {
5788       errmsg ("missing sw_if_index");
5789       return -99;
5790     }
5791
5792   /* Construct the API message */
5793   M (DELETE_LOOPBACK, mp);
5794   mp->sw_if_index = ntohl (sw_if_index);
5795
5796   S (mp);
5797   W (ret);
5798   return ret;
5799 }
5800
5801 static int
5802 api_want_interface_events (vat_main_t * vam)
5803 {
5804   unformat_input_t *i = vam->input;
5805   vl_api_want_interface_events_t *mp;
5806   int enable = -1;
5807   int ret;
5808
5809   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5810     {
5811       if (unformat (i, "enable"))
5812         enable = 1;
5813       else if (unformat (i, "disable"))
5814         enable = 0;
5815       else
5816         break;
5817     }
5818
5819   if (enable == -1)
5820     {
5821       errmsg ("missing enable|disable");
5822       return -99;
5823     }
5824
5825   M (WANT_INTERFACE_EVENTS, mp);
5826   mp->enable_disable = enable;
5827
5828   vam->interface_event_display = enable;
5829
5830   S (mp);
5831   W (ret);
5832   return ret;
5833 }
5834
5835
5836 /* Note: non-static, called once to set up the initial intfc table */
5837 int
5838 api_sw_interface_dump (vat_main_t * vam)
5839 {
5840   vl_api_sw_interface_dump_t *mp;
5841   vl_api_control_ping_t *mp_ping;
5842   hash_pair_t *p;
5843   name_sort_t *nses = 0, *ns;
5844   sw_interface_subif_t *sub = NULL;
5845   int ret;
5846
5847   /* Toss the old name table */
5848   /* *INDENT-OFF* */
5849   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5850   ({
5851     vec_add2 (nses, ns, 1);
5852     ns->name = (u8 *)(p->key);
5853     ns->value = (u32) p->value[0];
5854   }));
5855   /* *INDENT-ON* */
5856
5857   hash_free (vam->sw_if_index_by_interface_name);
5858
5859   vec_foreach (ns, nses) vec_free (ns->name);
5860
5861   vec_free (nses);
5862
5863   vec_foreach (sub, vam->sw_if_subif_table)
5864   {
5865     vec_free (sub->interface_name);
5866   }
5867   vec_free (vam->sw_if_subif_table);
5868
5869   /* recreate the interface name hash table */
5870   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
5871
5872   /*
5873    * Ask for all interface names. Otherwise, the epic catalog of
5874    * name filters becomes ridiculously long, and vat ends up needing
5875    * to be taught about new interface types.
5876    */
5877   M (SW_INTERFACE_DUMP, mp);
5878   S (mp);
5879
5880   /* Use a control ping for synchronization */
5881   MPING (CONTROL_PING, mp_ping);
5882   S (mp_ping);
5883
5884   W (ret);
5885   return ret;
5886 }
5887
5888 static int
5889 api_sw_interface_set_flags (vat_main_t * vam)
5890 {
5891   unformat_input_t *i = vam->input;
5892   vl_api_sw_interface_set_flags_t *mp;
5893   u32 sw_if_index;
5894   u8 sw_if_index_set = 0;
5895   u8 admin_up = 0;
5896   int ret;
5897
5898   /* Parse args required to build the message */
5899   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5900     {
5901       if (unformat (i, "admin-up"))
5902         admin_up = 1;
5903       else if (unformat (i, "admin-down"))
5904         admin_up = 0;
5905       else
5906         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5907         sw_if_index_set = 1;
5908       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5909         sw_if_index_set = 1;
5910       else
5911         break;
5912     }
5913
5914   if (sw_if_index_set == 0)
5915     {
5916       errmsg ("missing interface name or sw_if_index");
5917       return -99;
5918     }
5919
5920   /* Construct the API message */
5921   M (SW_INTERFACE_SET_FLAGS, mp);
5922   mp->sw_if_index = ntohl (sw_if_index);
5923   mp->flags = ntohl ((admin_up) ? IF_STATUS_API_FLAG_ADMIN_UP : 0);
5924
5925   /* send it... */
5926   S (mp);
5927
5928   /* Wait for a reply, return the good/bad news... */
5929   W (ret);
5930   return ret;
5931 }
5932
5933 static int
5934 api_sw_interface_set_rx_mode (vat_main_t * vam)
5935 {
5936   unformat_input_t *i = vam->input;
5937   vl_api_sw_interface_set_rx_mode_t *mp;
5938   u32 sw_if_index;
5939   u8 sw_if_index_set = 0;
5940   int ret;
5941   u8 queue_id_valid = 0;
5942   u32 queue_id;
5943   vnet_hw_interface_rx_mode mode = VNET_HW_INTERFACE_RX_MODE_UNKNOWN;
5944
5945   /* Parse args required to build the message */
5946   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5947     {
5948       if (unformat (i, "queue %d", &queue_id))
5949         queue_id_valid = 1;
5950       else if (unformat (i, "polling"))
5951         mode = VNET_HW_INTERFACE_RX_MODE_POLLING;
5952       else if (unformat (i, "interrupt"))
5953         mode = VNET_HW_INTERFACE_RX_MODE_INTERRUPT;
5954       else if (unformat (i, "adaptive"))
5955         mode = VNET_HW_INTERFACE_RX_MODE_ADAPTIVE;
5956       else
5957         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5958         sw_if_index_set = 1;
5959       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5960         sw_if_index_set = 1;
5961       else
5962         break;
5963     }
5964
5965   if (sw_if_index_set == 0)
5966     {
5967       errmsg ("missing interface name or sw_if_index");
5968       return -99;
5969     }
5970   if (mode == VNET_HW_INTERFACE_RX_MODE_UNKNOWN)
5971     {
5972       errmsg ("missing rx-mode");
5973       return -99;
5974     }
5975
5976   /* Construct the API message */
5977   M (SW_INTERFACE_SET_RX_MODE, mp);
5978   mp->sw_if_index = ntohl (sw_if_index);
5979   mp->mode = (vl_api_rx_mode_t) mode;
5980   mp->queue_id_valid = queue_id_valid;
5981   mp->queue_id = queue_id_valid ? ntohl (queue_id) : ~0;
5982
5983   /* send it... */
5984   S (mp);
5985
5986   /* Wait for a reply, return the good/bad news... */
5987   W (ret);
5988   return ret;
5989 }
5990
5991 static int
5992 api_sw_interface_set_rx_placement (vat_main_t * vam)
5993 {
5994   unformat_input_t *i = vam->input;
5995   vl_api_sw_interface_set_rx_placement_t *mp;
5996   u32 sw_if_index;
5997   u8 sw_if_index_set = 0;
5998   int ret;
5999   u8 is_main = 0;
6000   u32 queue_id, thread_index;
6001
6002   /* Parse args required to build the message */
6003   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6004     {
6005       if (unformat (i, "queue %d", &queue_id))
6006         ;
6007       else if (unformat (i, "main"))
6008         is_main = 1;
6009       else if (unformat (i, "worker %d", &thread_index))
6010         ;
6011       else
6012         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6013         sw_if_index_set = 1;
6014       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6015         sw_if_index_set = 1;
6016       else
6017         break;
6018     }
6019
6020   if (sw_if_index_set == 0)
6021     {
6022       errmsg ("missing interface name or sw_if_index");
6023       return -99;
6024     }
6025
6026   if (is_main)
6027     thread_index = 0;
6028   /* Construct the API message */
6029   M (SW_INTERFACE_SET_RX_PLACEMENT, mp);
6030   mp->sw_if_index = ntohl (sw_if_index);
6031   mp->worker_id = ntohl (thread_index);
6032   mp->queue_id = ntohl (queue_id);
6033   mp->is_main = is_main;
6034
6035   /* send it... */
6036   S (mp);
6037   /* Wait for a reply, return the good/bad news... */
6038   W (ret);
6039   return ret;
6040 }
6041
6042 static void vl_api_sw_interface_rx_placement_details_t_handler
6043   (vl_api_sw_interface_rx_placement_details_t * mp)
6044 {
6045   vat_main_t *vam = &vat_main;
6046   u32 worker_id = ntohl (mp->worker_id);
6047
6048   print (vam->ofp,
6049          "\n%-11d %-11s %-6d %-5d %-9s",
6050          ntohl (mp->sw_if_index), (worker_id == 0) ? "main" : "worker",
6051          worker_id, ntohl (mp->queue_id),
6052          (mp->mode ==
6053           1) ? "polling" : ((mp->mode == 2) ? "interrupt" : "adaptive"));
6054 }
6055
6056 static void vl_api_sw_interface_rx_placement_details_t_handler_json
6057   (vl_api_sw_interface_rx_placement_details_t * mp)
6058 {
6059   vat_main_t *vam = &vat_main;
6060   vat_json_node_t *node = NULL;
6061
6062   if (VAT_JSON_ARRAY != vam->json_tree.type)
6063     {
6064       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
6065       vat_json_init_array (&vam->json_tree);
6066     }
6067   node = vat_json_array_add (&vam->json_tree);
6068
6069   vat_json_init_object (node);
6070   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
6071   vat_json_object_add_uint (node, "worker_id", ntohl (mp->worker_id));
6072   vat_json_object_add_uint (node, "queue_id", ntohl (mp->queue_id));
6073   vat_json_object_add_uint (node, "mode", mp->mode);
6074 }
6075
6076 static int
6077 api_sw_interface_rx_placement_dump (vat_main_t * vam)
6078 {
6079   unformat_input_t *i = vam->input;
6080   vl_api_sw_interface_rx_placement_dump_t *mp;
6081   vl_api_control_ping_t *mp_ping;
6082   int ret;
6083   u32 sw_if_index;
6084   u8 sw_if_index_set = 0;
6085
6086   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6087     {
6088       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6089         sw_if_index_set++;
6090       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6091         sw_if_index_set++;
6092       else
6093         break;
6094     }
6095
6096   print (vam->ofp,
6097          "\n%-11s %-11s %-6s %-5s %-4s",
6098          "sw_if_index", "main/worker", "thread", "queue", "mode");
6099
6100   /* Dump Interface rx placement */
6101   M (SW_INTERFACE_RX_PLACEMENT_DUMP, mp);
6102
6103   if (sw_if_index_set)
6104     mp->sw_if_index = htonl (sw_if_index);
6105   else
6106     mp->sw_if_index = ~0;
6107
6108   S (mp);
6109
6110   /* Use a control ping for synchronization */
6111   MPING (CONTROL_PING, mp_ping);
6112   S (mp_ping);
6113
6114   W (ret);
6115   return ret;
6116 }
6117
6118 static int
6119 api_sw_interface_clear_stats (vat_main_t * vam)
6120 {
6121   unformat_input_t *i = vam->input;
6122   vl_api_sw_interface_clear_stats_t *mp;
6123   u32 sw_if_index;
6124   u8 sw_if_index_set = 0;
6125   int ret;
6126
6127   /* Parse args required to build the message */
6128   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6129     {
6130       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6131         sw_if_index_set = 1;
6132       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6133         sw_if_index_set = 1;
6134       else
6135         break;
6136     }
6137
6138   /* Construct the API message */
6139   M (SW_INTERFACE_CLEAR_STATS, mp);
6140
6141   if (sw_if_index_set == 1)
6142     mp->sw_if_index = ntohl (sw_if_index);
6143   else
6144     mp->sw_if_index = ~0;
6145
6146   /* send it... */
6147   S (mp);
6148
6149   /* Wait for a reply, return the good/bad news... */
6150   W (ret);
6151   return ret;
6152 }
6153
6154 static int
6155 api_sw_interface_add_del_address (vat_main_t * vam)
6156 {
6157   unformat_input_t *i = vam->input;
6158   vl_api_sw_interface_add_del_address_t *mp;
6159   u32 sw_if_index;
6160   u8 sw_if_index_set = 0;
6161   u8 is_add = 1, del_all = 0;
6162   u32 address_length = 0;
6163   u8 v4_address_set = 0;
6164   u8 v6_address_set = 0;
6165   ip4_address_t v4address;
6166   ip6_address_t v6address;
6167   int ret;
6168
6169   /* Parse args required to build the message */
6170   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6171     {
6172       if (unformat (i, "del-all"))
6173         del_all = 1;
6174       else if (unformat (i, "del"))
6175         is_add = 0;
6176       else
6177         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6178         sw_if_index_set = 1;
6179       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6180         sw_if_index_set = 1;
6181       else if (unformat (i, "%U/%d",
6182                          unformat_ip4_address, &v4address, &address_length))
6183         v4_address_set = 1;
6184       else if (unformat (i, "%U/%d",
6185                          unformat_ip6_address, &v6address, &address_length))
6186         v6_address_set = 1;
6187       else
6188         break;
6189     }
6190
6191   if (sw_if_index_set == 0)
6192     {
6193       errmsg ("missing interface name or sw_if_index");
6194       return -99;
6195     }
6196   if (v4_address_set && v6_address_set)
6197     {
6198       errmsg ("both v4 and v6 addresses set");
6199       return -99;
6200     }
6201   if (!v4_address_set && !v6_address_set && !del_all)
6202     {
6203       errmsg ("no addresses set");
6204       return -99;
6205     }
6206
6207   /* Construct the API message */
6208   M (SW_INTERFACE_ADD_DEL_ADDRESS, mp);
6209
6210   mp->sw_if_index = ntohl (sw_if_index);
6211   mp->is_add = is_add;
6212   mp->del_all = del_all;
6213   if (v6_address_set)
6214     {
6215       mp->prefix.address.af = ADDRESS_IP6;
6216       clib_memcpy (mp->prefix.address.un.ip6, &v6address, sizeof (v6address));
6217     }
6218   else
6219     {
6220       mp->prefix.address.af = ADDRESS_IP4;
6221       clib_memcpy (mp->prefix.address.un.ip4, &v4address, sizeof (v4address));
6222     }
6223   mp->prefix.len = address_length;
6224
6225   /* send it... */
6226   S (mp);
6227
6228   /* Wait for a reply, return good/bad news  */
6229   W (ret);
6230   return ret;
6231 }
6232
6233 static int
6234 api_sw_interface_set_mpls_enable (vat_main_t * vam)
6235 {
6236   unformat_input_t *i = vam->input;
6237   vl_api_sw_interface_set_mpls_enable_t *mp;
6238   u32 sw_if_index;
6239   u8 sw_if_index_set = 0;
6240   u8 enable = 1;
6241   int ret;
6242
6243   /* Parse args required to build the message */
6244   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6245     {
6246       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6247         sw_if_index_set = 1;
6248       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6249         sw_if_index_set = 1;
6250       else if (unformat (i, "disable"))
6251         enable = 0;
6252       else if (unformat (i, "dis"))
6253         enable = 0;
6254       else
6255         break;
6256     }
6257
6258   if (sw_if_index_set == 0)
6259     {
6260       errmsg ("missing interface name or sw_if_index");
6261       return -99;
6262     }
6263
6264   /* Construct the API message */
6265   M (SW_INTERFACE_SET_MPLS_ENABLE, mp);
6266
6267   mp->sw_if_index = ntohl (sw_if_index);
6268   mp->enable = enable;
6269
6270   /* send it... */
6271   S (mp);
6272
6273   /* Wait for a reply... */
6274   W (ret);
6275   return ret;
6276 }
6277
6278 static int
6279 api_sw_interface_set_table (vat_main_t * vam)
6280 {
6281   unformat_input_t *i = vam->input;
6282   vl_api_sw_interface_set_table_t *mp;
6283   u32 sw_if_index, vrf_id = 0;
6284   u8 sw_if_index_set = 0;
6285   u8 is_ipv6 = 0;
6286   int ret;
6287
6288   /* Parse args required to build the message */
6289   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6290     {
6291       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6292         sw_if_index_set = 1;
6293       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6294         sw_if_index_set = 1;
6295       else if (unformat (i, "vrf %d", &vrf_id))
6296         ;
6297       else if (unformat (i, "ipv6"))
6298         is_ipv6 = 1;
6299       else
6300         break;
6301     }
6302
6303   if (sw_if_index_set == 0)
6304     {
6305       errmsg ("missing interface name or sw_if_index");
6306       return -99;
6307     }
6308
6309   /* Construct the API message */
6310   M (SW_INTERFACE_SET_TABLE, mp);
6311
6312   mp->sw_if_index = ntohl (sw_if_index);
6313   mp->is_ipv6 = is_ipv6;
6314   mp->vrf_id = ntohl (vrf_id);
6315
6316   /* send it... */
6317   S (mp);
6318
6319   /* Wait for a reply... */
6320   W (ret);
6321   return ret;
6322 }
6323
6324 static void vl_api_sw_interface_get_table_reply_t_handler
6325   (vl_api_sw_interface_get_table_reply_t * mp)
6326 {
6327   vat_main_t *vam = &vat_main;
6328
6329   print (vam->ofp, "%d", ntohl (mp->vrf_id));
6330
6331   vam->retval = ntohl (mp->retval);
6332   vam->result_ready = 1;
6333
6334 }
6335
6336 static void vl_api_sw_interface_get_table_reply_t_handler_json
6337   (vl_api_sw_interface_get_table_reply_t * mp)
6338 {
6339   vat_main_t *vam = &vat_main;
6340   vat_json_node_t node;
6341
6342   vat_json_init_object (&node);
6343   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
6344   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
6345
6346   vat_json_print (vam->ofp, &node);
6347   vat_json_free (&node);
6348
6349   vam->retval = ntohl (mp->retval);
6350   vam->result_ready = 1;
6351 }
6352
6353 static int
6354 api_sw_interface_get_table (vat_main_t * vam)
6355 {
6356   unformat_input_t *i = vam->input;
6357   vl_api_sw_interface_get_table_t *mp;
6358   u32 sw_if_index;
6359   u8 sw_if_index_set = 0;
6360   u8 is_ipv6 = 0;
6361   int ret;
6362
6363   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6364     {
6365       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6366         sw_if_index_set = 1;
6367       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6368         sw_if_index_set = 1;
6369       else if (unformat (i, "ipv6"))
6370         is_ipv6 = 1;
6371       else
6372         break;
6373     }
6374
6375   if (sw_if_index_set == 0)
6376     {
6377       errmsg ("missing interface name or sw_if_index");
6378       return -99;
6379     }
6380
6381   M (SW_INTERFACE_GET_TABLE, mp);
6382   mp->sw_if_index = htonl (sw_if_index);
6383   mp->is_ipv6 = is_ipv6;
6384
6385   S (mp);
6386   W (ret);
6387   return ret;
6388 }
6389
6390 static int
6391 api_sw_interface_set_vpath (vat_main_t * vam)
6392 {
6393   unformat_input_t *i = vam->input;
6394   vl_api_sw_interface_set_vpath_t *mp;
6395   u32 sw_if_index = 0;
6396   u8 sw_if_index_set = 0;
6397   u8 is_enable = 0;
6398   int ret;
6399
6400   /* Parse args required to build the message */
6401   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6402     {
6403       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6404         sw_if_index_set = 1;
6405       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6406         sw_if_index_set = 1;
6407       else if (unformat (i, "enable"))
6408         is_enable = 1;
6409       else if (unformat (i, "disable"))
6410         is_enable = 0;
6411       else
6412         break;
6413     }
6414
6415   if (sw_if_index_set == 0)
6416     {
6417       errmsg ("missing interface name or sw_if_index");
6418       return -99;
6419     }
6420
6421   /* Construct the API message */
6422   M (SW_INTERFACE_SET_VPATH, mp);
6423
6424   mp->sw_if_index = ntohl (sw_if_index);
6425   mp->enable = is_enable;
6426
6427   /* send it... */
6428   S (mp);
6429
6430   /* Wait for a reply... */
6431   W (ret);
6432   return ret;
6433 }
6434
6435 static int
6436 api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
6437 {
6438   unformat_input_t *i = vam->input;
6439   vl_api_sw_interface_set_vxlan_bypass_t *mp;
6440   u32 sw_if_index = 0;
6441   u8 sw_if_index_set = 0;
6442   u8 is_enable = 1;
6443   u8 is_ipv6 = 0;
6444   int ret;
6445
6446   /* Parse args required to build the message */
6447   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6448     {
6449       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6450         sw_if_index_set = 1;
6451       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6452         sw_if_index_set = 1;
6453       else if (unformat (i, "enable"))
6454         is_enable = 1;
6455       else if (unformat (i, "disable"))
6456         is_enable = 0;
6457       else if (unformat (i, "ip4"))
6458         is_ipv6 = 0;
6459       else if (unformat (i, "ip6"))
6460         is_ipv6 = 1;
6461       else
6462         break;
6463     }
6464
6465   if (sw_if_index_set == 0)
6466     {
6467       errmsg ("missing interface name or sw_if_index");
6468       return -99;
6469     }
6470
6471   /* Construct the API message */
6472   M (SW_INTERFACE_SET_VXLAN_BYPASS, mp);
6473
6474   mp->sw_if_index = ntohl (sw_if_index);
6475   mp->enable = is_enable;
6476   mp->is_ipv6 = is_ipv6;
6477
6478   /* send it... */
6479   S (mp);
6480
6481   /* Wait for a reply... */
6482   W (ret);
6483   return ret;
6484 }
6485
6486 static int
6487 api_sw_interface_set_geneve_bypass (vat_main_t * vam)
6488 {
6489   unformat_input_t *i = vam->input;
6490   vl_api_sw_interface_set_geneve_bypass_t *mp;
6491   u32 sw_if_index = 0;
6492   u8 sw_if_index_set = 0;
6493   u8 is_enable = 1;
6494   u8 is_ipv6 = 0;
6495   int ret;
6496
6497   /* Parse args required to build the message */
6498   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6499     {
6500       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6501         sw_if_index_set = 1;
6502       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6503         sw_if_index_set = 1;
6504       else if (unformat (i, "enable"))
6505         is_enable = 1;
6506       else if (unformat (i, "disable"))
6507         is_enable = 0;
6508       else if (unformat (i, "ip4"))
6509         is_ipv6 = 0;
6510       else if (unformat (i, "ip6"))
6511         is_ipv6 = 1;
6512       else
6513         break;
6514     }
6515
6516   if (sw_if_index_set == 0)
6517     {
6518       errmsg ("missing interface name or sw_if_index");
6519       return -99;
6520     }
6521
6522   /* Construct the API message */
6523   M (SW_INTERFACE_SET_GENEVE_BYPASS, mp);
6524
6525   mp->sw_if_index = ntohl (sw_if_index);
6526   mp->enable = is_enable;
6527   mp->is_ipv6 = is_ipv6;
6528
6529   /* send it... */
6530   S (mp);
6531
6532   /* Wait for a reply... */
6533   W (ret);
6534   return ret;
6535 }
6536
6537 static int
6538 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
6539 {
6540   unformat_input_t *i = vam->input;
6541   vl_api_sw_interface_set_l2_xconnect_t *mp;
6542   u32 rx_sw_if_index;
6543   u8 rx_sw_if_index_set = 0;
6544   u32 tx_sw_if_index;
6545   u8 tx_sw_if_index_set = 0;
6546   u8 enable = 1;
6547   int ret;
6548
6549   /* Parse args required to build the message */
6550   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6551     {
6552       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
6553         rx_sw_if_index_set = 1;
6554       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
6555         tx_sw_if_index_set = 1;
6556       else if (unformat (i, "rx"))
6557         {
6558           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6559             {
6560               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6561                             &rx_sw_if_index))
6562                 rx_sw_if_index_set = 1;
6563             }
6564           else
6565             break;
6566         }
6567       else if (unformat (i, "tx"))
6568         {
6569           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6570             {
6571               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6572                             &tx_sw_if_index))
6573                 tx_sw_if_index_set = 1;
6574             }
6575           else
6576             break;
6577         }
6578       else if (unformat (i, "enable"))
6579         enable = 1;
6580       else if (unformat (i, "disable"))
6581         enable = 0;
6582       else
6583         break;
6584     }
6585
6586   if (rx_sw_if_index_set == 0)
6587     {
6588       errmsg ("missing rx interface name or rx_sw_if_index");
6589       return -99;
6590     }
6591
6592   if (enable && (tx_sw_if_index_set == 0))
6593     {
6594       errmsg ("missing tx interface name or tx_sw_if_index");
6595       return -99;
6596     }
6597
6598   M (SW_INTERFACE_SET_L2_XCONNECT, mp);
6599
6600   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6601   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
6602   mp->enable = enable;
6603
6604   S (mp);
6605   W (ret);
6606   return ret;
6607 }
6608
6609 static int
6610 api_sw_interface_set_l2_bridge (vat_main_t * vam)
6611 {
6612   unformat_input_t *i = vam->input;
6613   vl_api_sw_interface_set_l2_bridge_t *mp;
6614   vl_api_l2_port_type_t port_type;
6615   u32 rx_sw_if_index;
6616   u8 rx_sw_if_index_set = 0;
6617   u32 bd_id;
6618   u8 bd_id_set = 0;
6619   u32 shg = 0;
6620   u8 enable = 1;
6621   int ret;
6622
6623   port_type = L2_API_PORT_TYPE_NORMAL;
6624
6625   /* Parse args required to build the message */
6626   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6627     {
6628       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
6629         rx_sw_if_index_set = 1;
6630       else if (unformat (i, "bd_id %d", &bd_id))
6631         bd_id_set = 1;
6632       else
6633         if (unformat
6634             (i, "%U", api_unformat_sw_if_index, vam, &rx_sw_if_index))
6635         rx_sw_if_index_set = 1;
6636       else if (unformat (i, "shg %d", &shg))
6637         ;
6638       else if (unformat (i, "bvi"))
6639         port_type = L2_API_PORT_TYPE_BVI;
6640       else if (unformat (i, "uu-fwd"))
6641         port_type = L2_API_PORT_TYPE_UU_FWD;
6642       else if (unformat (i, "enable"))
6643         enable = 1;
6644       else if (unformat (i, "disable"))
6645         enable = 0;
6646       else
6647         break;
6648     }
6649
6650   if (rx_sw_if_index_set == 0)
6651     {
6652       errmsg ("missing rx interface name or sw_if_index");
6653       return -99;
6654     }
6655
6656   if (enable && (bd_id_set == 0))
6657     {
6658       errmsg ("missing bridge domain");
6659       return -99;
6660     }
6661
6662   M (SW_INTERFACE_SET_L2_BRIDGE, mp);
6663
6664   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6665   mp->bd_id = ntohl (bd_id);
6666   mp->shg = (u8) shg;
6667   mp->port_type = ntohl (port_type);
6668   mp->enable = enable;
6669
6670   S (mp);
6671   W (ret);
6672   return ret;
6673 }
6674
6675 static int
6676 api_bridge_domain_dump (vat_main_t * vam)
6677 {
6678   unformat_input_t *i = vam->input;
6679   vl_api_bridge_domain_dump_t *mp;
6680   vl_api_control_ping_t *mp_ping;
6681   u32 bd_id = ~0;
6682   int ret;
6683
6684   /* Parse args required to build the message */
6685   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6686     {
6687       if (unformat (i, "bd_id %d", &bd_id))
6688         ;
6689       else
6690         break;
6691     }
6692
6693   M (BRIDGE_DOMAIN_DUMP, mp);
6694   mp->bd_id = ntohl (bd_id);
6695   S (mp);
6696
6697   /* Use a control ping for synchronization */
6698   MPING (CONTROL_PING, mp_ping);
6699   S (mp_ping);
6700
6701   W (ret);
6702   return ret;
6703 }
6704
6705 static int
6706 api_bridge_domain_add_del (vat_main_t * vam)
6707 {
6708   unformat_input_t *i = vam->input;
6709   vl_api_bridge_domain_add_del_t *mp;
6710   u32 bd_id = ~0;
6711   u8 is_add = 1;
6712   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
6713   u8 *bd_tag = NULL;
6714   u32 mac_age = 0;
6715   int ret;
6716
6717   /* Parse args required to build the message */
6718   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6719     {
6720       if (unformat (i, "bd_id %d", &bd_id))
6721         ;
6722       else if (unformat (i, "flood %d", &flood))
6723         ;
6724       else if (unformat (i, "uu-flood %d", &uu_flood))
6725         ;
6726       else if (unformat (i, "forward %d", &forward))
6727         ;
6728       else if (unformat (i, "learn %d", &learn))
6729         ;
6730       else if (unformat (i, "arp-term %d", &arp_term))
6731         ;
6732       else if (unformat (i, "mac-age %d", &mac_age))
6733         ;
6734       else if (unformat (i, "bd-tag %s", &bd_tag))
6735         ;
6736       else if (unformat (i, "del"))
6737         {
6738           is_add = 0;
6739           flood = uu_flood = forward = learn = 0;
6740         }
6741       else
6742         break;
6743     }
6744
6745   if (bd_id == ~0)
6746     {
6747       errmsg ("missing bridge domain");
6748       ret = -99;
6749       goto done;
6750     }
6751
6752   if (mac_age > 255)
6753     {
6754       errmsg ("mac age must be less than 256 ");
6755       ret = -99;
6756       goto done;
6757     }
6758
6759   if ((bd_tag) && (vec_len (bd_tag) > 63))
6760     {
6761       errmsg ("bd-tag cannot be longer than 63");
6762       ret = -99;
6763       goto done;
6764     }
6765
6766   M (BRIDGE_DOMAIN_ADD_DEL, mp);
6767
6768   mp->bd_id = ntohl (bd_id);
6769   mp->flood = flood;
6770   mp->uu_flood = uu_flood;
6771   mp->forward = forward;
6772   mp->learn = learn;
6773   mp->arp_term = arp_term;
6774   mp->is_add = is_add;
6775   mp->mac_age = (u8) mac_age;
6776   if (bd_tag)
6777     {
6778       clib_memcpy (mp->bd_tag, bd_tag, vec_len (bd_tag));
6779       mp->bd_tag[vec_len (bd_tag)] = 0;
6780     }
6781   S (mp);
6782   W (ret);
6783
6784 done:
6785   vec_free (bd_tag);
6786   return ret;
6787 }
6788
6789 static int
6790 api_l2fib_flush_bd (vat_main_t * vam)
6791 {
6792   unformat_input_t *i = vam->input;
6793   vl_api_l2fib_flush_bd_t *mp;
6794   u32 bd_id = ~0;
6795   int ret;
6796
6797   /* Parse args required to build the message */
6798   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6799     {
6800       if (unformat (i, "bd_id %d", &bd_id));
6801       else
6802         break;
6803     }
6804
6805   if (bd_id == ~0)
6806     {
6807       errmsg ("missing bridge domain");
6808       return -99;
6809     }
6810
6811   M (L2FIB_FLUSH_BD, mp);
6812
6813   mp->bd_id = htonl (bd_id);
6814
6815   S (mp);
6816   W (ret);
6817   return ret;
6818 }
6819
6820 static int
6821 api_l2fib_flush_int (vat_main_t * vam)
6822 {
6823   unformat_input_t *i = vam->input;
6824   vl_api_l2fib_flush_int_t *mp;
6825   u32 sw_if_index = ~0;
6826   int ret;
6827
6828   /* Parse args required to build the message */
6829   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6830     {
6831       if (unformat (i, "sw_if_index %d", &sw_if_index));
6832       else
6833         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index));
6834       else
6835         break;
6836     }
6837
6838   if (sw_if_index == ~0)
6839     {
6840       errmsg ("missing interface name or sw_if_index");
6841       return -99;
6842     }
6843
6844   M (L2FIB_FLUSH_INT, mp);
6845
6846   mp->sw_if_index = ntohl (sw_if_index);
6847
6848   S (mp);
6849   W (ret);
6850   return ret;
6851 }
6852
6853 static int
6854 api_l2fib_add_del (vat_main_t * vam)
6855 {
6856   unformat_input_t *i = vam->input;
6857   vl_api_l2fib_add_del_t *mp;
6858   f64 timeout;
6859   u8 mac[6] = { 0 };
6860   u8 mac_set = 0;
6861   u32 bd_id;
6862   u8 bd_id_set = 0;
6863   u32 sw_if_index = 0;
6864   u8 sw_if_index_set = 0;
6865   u8 is_add = 1;
6866   u8 static_mac = 0;
6867   u8 filter_mac = 0;
6868   u8 bvi_mac = 0;
6869   int count = 1;
6870   f64 before = 0;
6871   int j;
6872
6873   /* Parse args required to build the message */
6874   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6875     {
6876       if (unformat (i, "mac %U", unformat_ethernet_address, mac))
6877         mac_set = 1;
6878       else if (unformat (i, "bd_id %d", &bd_id))
6879         bd_id_set = 1;
6880       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6881         sw_if_index_set = 1;
6882       else if (unformat (i, "sw_if"))
6883         {
6884           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6885             {
6886               if (unformat
6887                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6888                 sw_if_index_set = 1;
6889             }
6890           else
6891             break;
6892         }
6893       else if (unformat (i, "static"))
6894         static_mac = 1;
6895       else if (unformat (i, "filter"))
6896         {
6897           filter_mac = 1;
6898           static_mac = 1;
6899         }
6900       else if (unformat (i, "bvi"))
6901         {
6902           bvi_mac = 1;
6903           static_mac = 1;
6904         }
6905       else if (unformat (i, "del"))
6906         is_add = 0;
6907       else if (unformat (i, "count %d", &count))
6908         ;
6909       else
6910         break;
6911     }
6912
6913   if (mac_set == 0)
6914     {
6915       errmsg ("missing mac address");
6916       return -99;
6917     }
6918
6919   if (bd_id_set == 0)
6920     {
6921       errmsg ("missing bridge domain");
6922       return -99;
6923     }
6924
6925   if (is_add && sw_if_index_set == 0 && filter_mac == 0)
6926     {
6927       errmsg ("missing interface name or sw_if_index");
6928       return -99;
6929     }
6930
6931   if (count > 1)
6932     {
6933       /* Turn on async mode */
6934       vam->async_mode = 1;
6935       vam->async_errors = 0;
6936       before = vat_time_now (vam);
6937     }
6938
6939   for (j = 0; j < count; j++)
6940     {
6941       M (L2FIB_ADD_DEL, mp);
6942
6943       clib_memcpy (mp->mac, mac, 6);
6944       mp->bd_id = ntohl (bd_id);
6945       mp->is_add = is_add;
6946       mp->sw_if_index = ntohl (sw_if_index);
6947
6948       if (is_add)
6949         {
6950           mp->static_mac = static_mac;
6951           mp->filter_mac = filter_mac;
6952           mp->bvi_mac = bvi_mac;
6953         }
6954       increment_mac_address (mac);
6955       /* send it... */
6956       S (mp);
6957     }
6958
6959   if (count > 1)
6960     {
6961       vl_api_control_ping_t *mp_ping;
6962       f64 after;
6963
6964       /* Shut off async mode */
6965       vam->async_mode = 0;
6966
6967       MPING (CONTROL_PING, mp_ping);
6968       S (mp_ping);
6969
6970       timeout = vat_time_now (vam) + 1.0;
6971       while (vat_time_now (vam) < timeout)
6972         if (vam->result_ready == 1)
6973           goto out;
6974       vam->retval = -99;
6975
6976     out:
6977       if (vam->retval == -99)
6978         errmsg ("timeout");
6979
6980       if (vam->async_errors > 0)
6981         {
6982           errmsg ("%d asynchronous errors", vam->async_errors);
6983           vam->retval = -98;
6984         }
6985       vam->async_errors = 0;
6986       after = vat_time_now (vam);
6987
6988       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
6989              count, after - before, count / (after - before));
6990     }
6991   else
6992     {
6993       int ret;
6994
6995       /* Wait for a reply... */
6996       W (ret);
6997       return ret;
6998     }
6999   /* Return the good/bad news */
7000   return (vam->retval);
7001 }
7002
7003 static int
7004 api_bridge_domain_set_mac_age (vat_main_t * vam)
7005 {
7006   unformat_input_t *i = vam->input;
7007   vl_api_bridge_domain_set_mac_age_t *mp;
7008   u32 bd_id = ~0;
7009   u32 mac_age = 0;
7010   int ret;
7011
7012   /* Parse args required to build the message */
7013   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7014     {
7015       if (unformat (i, "bd_id %d", &bd_id));
7016       else if (unformat (i, "mac-age %d", &mac_age));
7017       else
7018         break;
7019     }
7020
7021   if (bd_id == ~0)
7022     {
7023       errmsg ("missing bridge domain");
7024       return -99;
7025     }
7026
7027   if (mac_age > 255)
7028     {
7029       errmsg ("mac age must be less than 256 ");
7030       return -99;
7031     }
7032
7033   M (BRIDGE_DOMAIN_SET_MAC_AGE, mp);
7034
7035   mp->bd_id = htonl (bd_id);
7036   mp->mac_age = (u8) mac_age;
7037
7038   S (mp);
7039   W (ret);
7040   return ret;
7041 }
7042
7043 static int
7044 api_l2_flags (vat_main_t * vam)
7045 {
7046   unformat_input_t *i = vam->input;
7047   vl_api_l2_flags_t *mp;
7048   u32 sw_if_index;
7049   u32 flags = 0;
7050   u8 sw_if_index_set = 0;
7051   u8 is_set = 0;
7052   int ret;
7053
7054   /* Parse args required to build the message */
7055   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7056     {
7057       if (unformat (i, "sw_if_index %d", &sw_if_index))
7058         sw_if_index_set = 1;
7059       else if (unformat (i, "sw_if"))
7060         {
7061           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7062             {
7063               if (unformat
7064                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7065                 sw_if_index_set = 1;
7066             }
7067           else
7068             break;
7069         }
7070       else if (unformat (i, "learn"))
7071         flags |= L2_LEARN;
7072       else if (unformat (i, "forward"))
7073         flags |= L2_FWD;
7074       else if (unformat (i, "flood"))
7075         flags |= L2_FLOOD;
7076       else if (unformat (i, "uu-flood"))
7077         flags |= L2_UU_FLOOD;
7078       else if (unformat (i, "arp-term"))
7079         flags |= L2_ARP_TERM;
7080       else if (unformat (i, "off"))
7081         is_set = 0;
7082       else if (unformat (i, "disable"))
7083         is_set = 0;
7084       else
7085         break;
7086     }
7087
7088   if (sw_if_index_set == 0)
7089     {
7090       errmsg ("missing interface name or sw_if_index");
7091       return -99;
7092     }
7093
7094   M (L2_FLAGS, mp);
7095
7096   mp->sw_if_index = ntohl (sw_if_index);
7097   mp->feature_bitmap = ntohl (flags);
7098   mp->is_set = is_set;
7099
7100   S (mp);
7101   W (ret);
7102   return ret;
7103 }
7104
7105 static int
7106 api_bridge_flags (vat_main_t * vam)
7107 {
7108   unformat_input_t *i = vam->input;
7109   vl_api_bridge_flags_t *mp;
7110   u32 bd_id;
7111   u8 bd_id_set = 0;
7112   u8 is_set = 1;
7113   bd_flags_t flags = 0;
7114   int ret;
7115
7116   /* Parse args required to build the message */
7117   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7118     {
7119       if (unformat (i, "bd_id %d", &bd_id))
7120         bd_id_set = 1;
7121       else if (unformat (i, "learn"))
7122         flags |= BRIDGE_API_FLAG_LEARN;
7123       else if (unformat (i, "forward"))
7124         flags |= BRIDGE_API_FLAG_FWD;
7125       else if (unformat (i, "flood"))
7126         flags |= BRIDGE_API_FLAG_FLOOD;
7127       else if (unformat (i, "uu-flood"))
7128         flags |= BRIDGE_API_FLAG_UU_FLOOD;
7129       else if (unformat (i, "arp-term"))
7130         flags |= BRIDGE_API_FLAG_ARP_TERM;
7131       else if (unformat (i, "off"))
7132         is_set = 0;
7133       else if (unformat (i, "disable"))
7134         is_set = 0;
7135       else
7136         break;
7137     }
7138
7139   if (bd_id_set == 0)
7140     {
7141       errmsg ("missing bridge domain");
7142       return -99;
7143     }
7144
7145   M (BRIDGE_FLAGS, mp);
7146
7147   mp->bd_id = ntohl (bd_id);
7148   mp->flags = ntohl (flags);
7149   mp->is_set = is_set;
7150
7151   S (mp);
7152   W (ret);
7153   return ret;
7154 }
7155
7156 static int
7157 api_bd_ip_mac_add_del (vat_main_t * vam)
7158 {
7159   vl_api_address_t ip = VL_API_ZERO_ADDRESS;
7160   vl_api_mac_address_t mac = { 0 };
7161   unformat_input_t *i = vam->input;
7162   vl_api_bd_ip_mac_add_del_t *mp;
7163   u32 bd_id;
7164   u8 is_add = 1;
7165   u8 bd_id_set = 0;
7166   u8 ip_set = 0;
7167   u8 mac_set = 0;
7168   int ret;
7169
7170
7171   /* Parse args required to build the message */
7172   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7173     {
7174       if (unformat (i, "bd_id %d", &bd_id))
7175         {
7176           bd_id_set++;
7177         }
7178       else if (unformat (i, "%U", unformat_vl_api_address, &ip))
7179         {
7180           ip_set++;
7181         }
7182       else if (unformat (i, "%U", unformat_vl_api_mac_address, &mac))
7183         {
7184           mac_set++;
7185         }
7186       else if (unformat (i, "del"))
7187         is_add = 0;
7188       else
7189         break;
7190     }
7191
7192   if (bd_id_set == 0)
7193     {
7194       errmsg ("missing bridge domain");
7195       return -99;
7196     }
7197   else if (ip_set == 0)
7198     {
7199       errmsg ("missing IP address");
7200       return -99;
7201     }
7202   else if (mac_set == 0)
7203     {
7204       errmsg ("missing MAC address");
7205       return -99;
7206     }
7207
7208   M (BD_IP_MAC_ADD_DEL, mp);
7209
7210   mp->entry.bd_id = ntohl (bd_id);
7211   mp->is_add = is_add;
7212
7213   clib_memcpy (&mp->entry.ip, &ip, sizeof (ip));
7214   clib_memcpy (&mp->entry.mac, &mac, sizeof (mac));
7215
7216   S (mp);
7217   W (ret);
7218   return ret;
7219 }
7220
7221 static int
7222 api_bd_ip_mac_flush (vat_main_t * vam)
7223 {
7224   unformat_input_t *i = vam->input;
7225   vl_api_bd_ip_mac_flush_t *mp;
7226   u32 bd_id;
7227   u8 bd_id_set = 0;
7228   int ret;
7229
7230   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7231     {
7232       if (unformat (i, "bd_id %d", &bd_id))
7233         {
7234           bd_id_set++;
7235         }
7236       else
7237         break;
7238     }
7239
7240   if (bd_id_set == 0)
7241     {
7242       errmsg ("missing bridge domain");
7243       return -99;
7244     }
7245
7246   M (BD_IP_MAC_FLUSH, mp);
7247
7248   mp->bd_id = ntohl (bd_id);
7249
7250   S (mp);
7251   W (ret);
7252   return ret;
7253 }
7254
7255 static void vl_api_bd_ip_mac_details_t_handler
7256   (vl_api_bd_ip_mac_details_t * mp)
7257 {
7258   vat_main_t *vam = &vat_main;
7259
7260   print (vam->ofp,
7261          "\n%-5d %U %U",
7262          ntohl (mp->entry.bd_id),
7263          format_vl_api_mac_address, mp->entry.mac,
7264          format_vl_api_address, &mp->entry.ip);
7265 }
7266
7267 static void vl_api_bd_ip_mac_details_t_handler_json
7268   (vl_api_bd_ip_mac_details_t * mp)
7269 {
7270   vat_main_t *vam = &vat_main;
7271   vat_json_node_t *node = NULL;
7272
7273   if (VAT_JSON_ARRAY != vam->json_tree.type)
7274     {
7275       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
7276       vat_json_init_array (&vam->json_tree);
7277     }
7278   node = vat_json_array_add (&vam->json_tree);
7279
7280   vat_json_init_object (node);
7281   vat_json_object_add_uint (node, "bd_id", ntohl (mp->entry.bd_id));
7282   vat_json_object_add_string_copy (node, "mac_address",
7283                                    format (0, "%U", format_vl_api_mac_address,
7284                                            &mp->entry.mac));
7285   u8 *ip = 0;
7286
7287   ip = format (0, "%U", format_vl_api_address, &mp->entry.ip);
7288   vat_json_object_add_string_copy (node, "ip_address", ip);
7289   vec_free (ip);
7290 }
7291
7292 static int
7293 api_bd_ip_mac_dump (vat_main_t * vam)
7294 {
7295   unformat_input_t *i = vam->input;
7296   vl_api_bd_ip_mac_dump_t *mp;
7297   vl_api_control_ping_t *mp_ping;
7298   int ret;
7299   u32 bd_id;
7300   u8 bd_id_set = 0;
7301
7302   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7303     {
7304       if (unformat (i, "bd_id %d", &bd_id))
7305         {
7306           bd_id_set++;
7307         }
7308       else
7309         break;
7310     }
7311
7312   print (vam->ofp,
7313          "\n%-5s %-7s %-20s %-30s",
7314          "bd_id", "is_ipv6", "mac_address", "ip_address");
7315
7316   /* Dump Bridge Domain Ip to Mac entries */
7317   M (BD_IP_MAC_DUMP, mp);
7318
7319   if (bd_id_set)
7320     mp->bd_id = htonl (bd_id);
7321   else
7322     mp->bd_id = ~0;
7323
7324   S (mp);
7325
7326   /* Use a control ping for synchronization */
7327   MPING (CONTROL_PING, mp_ping);
7328   S (mp_ping);
7329
7330   W (ret);
7331   return ret;
7332 }
7333
7334 static int
7335 api_tap_create_v2 (vat_main_t * vam)
7336 {
7337   unformat_input_t *i = vam->input;
7338   vl_api_tap_create_v2_t *mp;
7339 #define TAP_FLAG_GSO (1 << 0)
7340   u8 mac_address[6];
7341   u8 random_mac = 1;
7342   u32 id = ~0;
7343   u8 *host_if_name = 0;
7344   u8 *host_ns = 0;
7345   u8 host_mac_addr[6];
7346   u8 host_mac_addr_set = 0;
7347   u8 *host_bridge = 0;
7348   ip4_address_t host_ip4_addr;
7349   ip4_address_t host_ip4_gw;
7350   u8 host_ip4_gw_set = 0;
7351   u32 host_ip4_prefix_len = 0;
7352   ip6_address_t host_ip6_addr;
7353   ip6_address_t host_ip6_gw;
7354   u8 host_ip6_gw_set = 0;
7355   u32 host_ip6_prefix_len = 0;
7356   u8 host_mtu_set = 0;
7357   u32 host_mtu_size = 0;
7358   u32 tap_flags = 0;
7359   int ret;
7360   u32 rx_ring_sz = 0, tx_ring_sz = 0;
7361
7362   clib_memset (mac_address, 0, sizeof (mac_address));
7363
7364   /* Parse args required to build the message */
7365   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7366     {
7367       if (unformat (i, "hw-addr %U", unformat_ethernet_address, mac_address))
7368         {
7369           random_mac = 0;
7370         }
7371       else if (unformat (i, "id %u", &id))
7372         ;
7373       else if (unformat (i, "host-if-name %s", &host_if_name))
7374         ;
7375       else if (unformat (i, "host-ns %s", &host_ns))
7376         ;
7377       else if (unformat (i, "host-mac-addr %U", unformat_ethernet_address,
7378                          host_mac_addr))
7379         host_mac_addr_set = 1;
7380       else if (unformat (i, "host-bridge %s", &host_bridge))
7381         ;
7382       else if (unformat (i, "host-ip4-addr %U/%d", unformat_ip4_address,
7383                          &host_ip4_addr, &host_ip4_prefix_len))
7384         ;
7385       else if (unformat (i, "host-ip6-addr %U/%d", unformat_ip6_address,
7386                          &host_ip6_addr, &host_ip6_prefix_len))
7387         ;
7388       else if (unformat (i, "host-ip4-gw %U", unformat_ip4_address,
7389                          &host_ip4_gw))
7390         host_ip4_gw_set = 1;
7391       else if (unformat (i, "host-ip6-gw %U", unformat_ip6_address,
7392                          &host_ip6_gw))
7393         host_ip6_gw_set = 1;
7394       else if (unformat (i, "rx-ring-size %d", &rx_ring_sz))
7395         ;
7396       else if (unformat (i, "tx-ring-size %d", &tx_ring_sz))
7397         ;
7398       else if (unformat (i, "host-mtu-size %d", &host_mtu_size))
7399         host_mtu_set = 1;
7400       else if (unformat (i, "no-gso"))
7401         tap_flags &= ~TAP_FLAG_GSO;
7402       else if (unformat (i, "gso"))
7403         tap_flags |= TAP_FLAG_GSO;
7404       else
7405         break;
7406     }
7407
7408   if (vec_len (host_if_name) > 63)
7409     {
7410       errmsg ("tap name too long. ");
7411       return -99;
7412     }
7413   if (vec_len (host_ns) > 63)
7414     {
7415       errmsg ("host name space too long. ");
7416       return -99;
7417     }
7418   if (vec_len (host_bridge) > 63)
7419     {
7420       errmsg ("host bridge name too long. ");
7421       return -99;
7422     }
7423   if (host_ip4_prefix_len > 32)
7424     {
7425       errmsg ("host ip4 prefix length not valid. ");
7426       return -99;
7427     }
7428   if (host_ip6_prefix_len > 128)
7429     {
7430       errmsg ("host ip6 prefix length not valid. ");
7431       return -99;
7432     }
7433   if (!is_pow2 (rx_ring_sz))
7434     {
7435       errmsg ("rx ring size must be power of 2. ");
7436       return -99;
7437     }
7438   if (rx_ring_sz > 32768)
7439     {
7440       errmsg ("rx ring size must be 32768 or lower. ");
7441       return -99;
7442     }
7443   if (!is_pow2 (tx_ring_sz))
7444     {
7445       errmsg ("tx ring size must be power of 2. ");
7446       return -99;
7447     }
7448   if (tx_ring_sz > 32768)
7449     {
7450       errmsg ("tx ring size must be 32768 or lower. ");
7451       return -99;
7452     }
7453   if (host_mtu_set && (host_mtu_size < 64 || host_mtu_size > 65355))
7454     {
7455       errmsg ("host MTU size must be in between 64 and 65355. ");
7456       return -99;
7457     }
7458
7459   /* Construct the API message */
7460   M (TAP_CREATE_V2, mp);
7461
7462   mp->use_random_mac = random_mac;
7463
7464   mp->id = ntohl (id);
7465   mp->host_namespace_set = host_ns != 0;
7466   mp->host_bridge_set = host_bridge != 0;
7467   mp->host_ip4_addr_set = host_ip4_prefix_len != 0;
7468   mp->host_ip6_addr_set = host_ip6_prefix_len != 0;
7469   mp->rx_ring_sz = ntohs (rx_ring_sz);
7470   mp->tx_ring_sz = ntohs (tx_ring_sz);
7471   mp->host_mtu_set = host_mtu_set;
7472   mp->host_mtu_size = ntohl (host_mtu_size);
7473   mp->tap_flags = ntohl (tap_flags);
7474
7475   if (random_mac == 0)
7476     clib_memcpy (mp->mac_address, mac_address, 6);
7477   if (host_mac_addr_set)
7478     clib_memcpy (mp->host_mac_addr, host_mac_addr, 6);
7479   if (host_if_name)
7480     clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
7481   if (host_ns)
7482     clib_memcpy (mp->host_namespace, host_ns, vec_len (host_ns));
7483   if (host_bridge)
7484     clib_memcpy (mp->host_bridge, host_bridge, vec_len (host_bridge));
7485   if (host_ip4_prefix_len)
7486     clib_memcpy (mp->host_ip4_addr, &host_ip4_addr, 4);
7487   if (host_ip6_prefix_len)
7488     clib_memcpy (mp->host_ip6_addr, &host_ip6_addr, 16);
7489   if (host_ip4_gw_set)
7490     clib_memcpy (mp->host_ip4_gw, &host_ip4_gw, 4);
7491   if (host_ip6_gw_set)
7492     clib_memcpy (mp->host_ip6_gw, &host_ip6_gw, 16);
7493
7494   vec_free (host_ns);
7495   vec_free (host_if_name);
7496   vec_free (host_bridge);
7497
7498   /* send it... */
7499   S (mp);
7500
7501   /* Wait for a reply... */
7502   W (ret);
7503   return ret;
7504 }
7505
7506 static int
7507 api_tap_delete_v2 (vat_main_t * vam)
7508 {
7509   unformat_input_t *i = vam->input;
7510   vl_api_tap_delete_v2_t *mp;
7511   u32 sw_if_index = ~0;
7512   u8 sw_if_index_set = 0;
7513   int ret;
7514
7515   /* Parse args required to build the message */
7516   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7517     {
7518       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7519         sw_if_index_set = 1;
7520       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7521         sw_if_index_set = 1;
7522       else
7523         break;
7524     }
7525
7526   if (sw_if_index_set == 0)
7527     {
7528       errmsg ("missing vpp interface name. ");
7529       return -99;
7530     }
7531
7532   /* Construct the API message */
7533   M (TAP_DELETE_V2, mp);
7534
7535   mp->sw_if_index = ntohl (sw_if_index);
7536
7537   /* send it... */
7538   S (mp);
7539
7540   /* Wait for a reply... */
7541   W (ret);
7542   return ret;
7543 }
7544
7545 uword
7546 unformat_vlib_pci_addr (unformat_input_t * input, va_list * args)
7547 {
7548   vlib_pci_addr_t *addr = va_arg (*args, vlib_pci_addr_t *);
7549   u32 x[4];
7550
7551   if (!unformat (input, "%x:%x:%x.%x", &x[0], &x[1], &x[2], &x[3]))
7552     return 0;
7553
7554   addr->domain = x[0];
7555   addr->bus = x[1];
7556   addr->slot = x[2];
7557   addr->function = x[3];
7558
7559   return 1;
7560 }
7561
7562 static int
7563 api_virtio_pci_create (vat_main_t * vam)
7564 {
7565   unformat_input_t *i = vam->input;
7566   vl_api_virtio_pci_create_t *mp;
7567   u8 mac_address[6];
7568   u8 random_mac = 1;
7569   u8 gso_enabled = 0;
7570   u32 pci_addr = 0;
7571   u64 features = (u64) ~ (0ULL);
7572   int ret;
7573
7574   clib_memset (mac_address, 0, sizeof (mac_address));
7575
7576   /* Parse args required to build the message */
7577   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7578     {
7579       if (unformat (i, "hw-addr %U", unformat_ethernet_address, mac_address))
7580         {
7581           random_mac = 0;
7582         }
7583       else if (unformat (i, "pci-addr %U", unformat_vlib_pci_addr, &pci_addr))
7584         ;
7585       else if (unformat (i, "features 0x%llx", &features))
7586         ;
7587       else if (unformat (i, "gso-enabled"))
7588         gso_enabled = 1;
7589       else
7590         break;
7591     }
7592
7593   if (pci_addr == 0)
7594     {
7595       errmsg ("pci address must be non zero. ");
7596       return -99;
7597     }
7598
7599   /* Construct the API message */
7600   M (VIRTIO_PCI_CREATE, mp);
7601
7602   mp->use_random_mac = random_mac;
7603
7604   mp->pci_addr = htonl (pci_addr);
7605   mp->features = clib_host_to_net_u64 (features);
7606   mp->gso_enabled = gso_enabled;
7607
7608   if (random_mac == 0)
7609     clib_memcpy (mp->mac_address, mac_address, 6);
7610
7611   /* send it... */
7612   S (mp);
7613
7614   /* Wait for a reply... */
7615   W (ret);
7616   return ret;
7617 }
7618
7619 static int
7620 api_virtio_pci_delete (vat_main_t * vam)
7621 {
7622   unformat_input_t *i = vam->input;
7623   vl_api_virtio_pci_delete_t *mp;
7624   u32 sw_if_index = ~0;
7625   u8 sw_if_index_set = 0;
7626   int ret;
7627
7628   /* Parse args required to build the message */
7629   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7630     {
7631       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7632         sw_if_index_set = 1;
7633       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7634         sw_if_index_set = 1;
7635       else
7636         break;
7637     }
7638
7639   if (sw_if_index_set == 0)
7640     {
7641       errmsg ("missing vpp interface name. ");
7642       return -99;
7643     }
7644
7645   /* Construct the API message */
7646   M (VIRTIO_PCI_DELETE, mp);
7647
7648   mp->sw_if_index = htonl (sw_if_index);
7649
7650   /* send it... */
7651   S (mp);
7652
7653   /* Wait for a reply... */
7654   W (ret);
7655   return ret;
7656 }
7657
7658 static int
7659 api_bond_create (vat_main_t * vam)
7660 {
7661   unformat_input_t *i = vam->input;
7662   vl_api_bond_create_t *mp;
7663   u8 mac_address[6];
7664   u8 custom_mac = 0;
7665   int ret;
7666   u8 mode;
7667   u8 lb;
7668   u8 mode_is_set = 0;
7669   u32 id = ~0;
7670   u8 numa_only = 0;
7671
7672   clib_memset (mac_address, 0, sizeof (mac_address));
7673   lb = BOND_LB_L2;
7674
7675   /* Parse args required to build the message */
7676   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7677     {
7678       if (unformat (i, "mode %U", unformat_bond_mode, &mode))
7679         mode_is_set = 1;
7680       else if (((mode == BOND_MODE_LACP) || (mode == BOND_MODE_XOR))
7681                && unformat (i, "lb %U", unformat_bond_load_balance, &lb))
7682         ;
7683       else if (unformat (i, "hw-addr %U", unformat_ethernet_address,
7684                          mac_address))
7685         custom_mac = 1;
7686       else if (unformat (i, "numa-only"))
7687         numa_only = 1;
7688       else if (unformat (i, "id %u", &id))
7689         ;
7690       else
7691         break;
7692     }
7693
7694   if (mode_is_set == 0)
7695     {
7696       errmsg ("Missing bond mode. ");
7697       return -99;
7698     }
7699
7700   /* Construct the API message */
7701   M (BOND_CREATE, mp);
7702
7703   mp->use_custom_mac = custom_mac;
7704
7705   mp->mode = htonl (mode);
7706   mp->lb = htonl (lb);
7707   mp->id = htonl (id);
7708   mp->numa_only = numa_only;
7709
7710   if (custom_mac)
7711     clib_memcpy (mp->mac_address, mac_address, 6);
7712
7713   /* send it... */
7714   S (mp);
7715
7716   /* Wait for a reply... */
7717   W (ret);
7718   return ret;
7719 }
7720
7721 static int
7722 api_bond_delete (vat_main_t * vam)
7723 {
7724   unformat_input_t *i = vam->input;
7725   vl_api_bond_delete_t *mp;
7726   u32 sw_if_index = ~0;
7727   u8 sw_if_index_set = 0;
7728   int ret;
7729
7730   /* Parse args required to build the message */
7731   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7732     {
7733       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7734         sw_if_index_set = 1;
7735       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7736         sw_if_index_set = 1;
7737       else
7738         break;
7739     }
7740
7741   if (sw_if_index_set == 0)
7742     {
7743       errmsg ("missing vpp interface name. ");
7744       return -99;
7745     }
7746
7747   /* Construct the API message */
7748   M (BOND_DELETE, mp);
7749
7750   mp->sw_if_index = ntohl (sw_if_index);
7751
7752   /* send it... */
7753   S (mp);
7754
7755   /* Wait for a reply... */
7756   W (ret);
7757   return ret;
7758 }
7759
7760 static int
7761 api_bond_enslave (vat_main_t * vam)
7762 {
7763   unformat_input_t *i = vam->input;
7764   vl_api_bond_enslave_t *mp;
7765   u32 bond_sw_if_index;
7766   int ret;
7767   u8 is_passive;
7768   u8 is_long_timeout;
7769   u32 bond_sw_if_index_is_set = 0;
7770   u32 sw_if_index;
7771   u8 sw_if_index_is_set = 0;
7772
7773   /* Parse args required to build the message */
7774   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7775     {
7776       if (unformat (i, "sw_if_index %d", &sw_if_index))
7777         sw_if_index_is_set = 1;
7778       else if (unformat (i, "bond %u", &bond_sw_if_index))
7779         bond_sw_if_index_is_set = 1;
7780       else if (unformat (i, "passive %d", &is_passive))
7781         ;
7782       else if (unformat (i, "long-timeout %d", &is_long_timeout))
7783         ;
7784       else
7785         break;
7786     }
7787
7788   if (bond_sw_if_index_is_set == 0)
7789     {
7790       errmsg ("Missing bond sw_if_index. ");
7791       return -99;
7792     }
7793   if (sw_if_index_is_set == 0)
7794     {
7795       errmsg ("Missing slave sw_if_index. ");
7796       return -99;
7797     }
7798
7799   /* Construct the API message */
7800   M (BOND_ENSLAVE, mp);
7801
7802   mp->bond_sw_if_index = ntohl (bond_sw_if_index);
7803   mp->sw_if_index = ntohl (sw_if_index);
7804   mp->is_long_timeout = is_long_timeout;
7805   mp->is_passive = is_passive;
7806
7807   /* send it... */
7808   S (mp);
7809
7810   /* Wait for a reply... */
7811   W (ret);
7812   return ret;
7813 }
7814
7815 static int
7816 api_bond_detach_slave (vat_main_t * vam)
7817 {
7818   unformat_input_t *i = vam->input;
7819   vl_api_bond_detach_slave_t *mp;
7820   u32 sw_if_index = ~0;
7821   u8 sw_if_index_set = 0;
7822   int ret;
7823
7824   /* Parse args required to build the message */
7825   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7826     {
7827       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7828         sw_if_index_set = 1;
7829       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7830         sw_if_index_set = 1;
7831       else
7832         break;
7833     }
7834
7835   if (sw_if_index_set == 0)
7836     {
7837       errmsg ("missing vpp interface name. ");
7838       return -99;
7839     }
7840
7841   /* Construct the API message */
7842   M (BOND_DETACH_SLAVE, mp);
7843
7844   mp->sw_if_index = ntohl (sw_if_index);
7845
7846   /* send it... */
7847   S (mp);
7848
7849   /* Wait for a reply... */
7850   W (ret);
7851   return ret;
7852 }
7853
7854 static int
7855 api_ip_table_add_del (vat_main_t * vam)
7856 {
7857   unformat_input_t *i = vam->input;
7858   vl_api_ip_table_add_del_t *mp;
7859   u32 table_id = ~0;
7860   u8 is_ipv6 = 0;
7861   u8 is_add = 1;
7862   int ret = 0;
7863
7864   /* Parse args required to build the message */
7865   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7866     {
7867       if (unformat (i, "ipv6"))
7868         is_ipv6 = 1;
7869       else if (unformat (i, "del"))
7870         is_add = 0;
7871       else if (unformat (i, "add"))
7872         is_add = 1;
7873       else if (unformat (i, "table %d", &table_id))
7874         ;
7875       else
7876         {
7877           clib_warning ("parse error '%U'", format_unformat_error, i);
7878           return -99;
7879         }
7880     }
7881
7882   if (~0 == table_id)
7883     {
7884       errmsg ("missing table-ID");
7885       return -99;
7886     }
7887
7888   /* Construct the API message */
7889   M (IP_TABLE_ADD_DEL, mp);
7890
7891   mp->table.table_id = ntohl (table_id);
7892   mp->table.is_ip6 = is_ipv6;
7893   mp->is_add = is_add;
7894
7895   /* send it... */
7896   S (mp);
7897
7898   /* Wait for a reply... */
7899   W (ret);
7900
7901   return ret;
7902 }
7903
7904 uword
7905 unformat_fib_path (unformat_input_t * input, va_list * args)
7906 {
7907   vat_main_t *vam = va_arg (*args, vat_main_t *);
7908   vl_api_fib_path_t *path = va_arg (*args, vl_api_fib_path_t *);
7909   u32 weight, preference;
7910   mpls_label_t out_label;
7911
7912   clib_memset (path, 0, sizeof (*path));
7913   path->weight = 1;
7914   path->sw_if_index = ~0;
7915   path->rpf_id = ~0;
7916   path->n_labels = 0;
7917
7918   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7919     {
7920       if (unformat (input, "%U %U",
7921                     unformat_vl_api_ip4_address,
7922                     &path->nh.address.ip4,
7923                     api_unformat_sw_if_index, vam, &path->sw_if_index))
7924         {
7925           path->proto = FIB_API_PATH_NH_PROTO_IP4;
7926         }
7927       else if (unformat (input, "%U %U",
7928                          unformat_vl_api_ip6_address,
7929                          &path->nh.address.ip6,
7930                          api_unformat_sw_if_index, vam, &path->sw_if_index))
7931         {
7932           path->proto = FIB_API_PATH_NH_PROTO_IP6;
7933         }
7934       else if (unformat (input, "weight %u", &weight))
7935         {
7936           path->weight = weight;
7937         }
7938       else if (unformat (input, "preference %u", &preference))
7939         {
7940           path->preference = preference;
7941         }
7942       else if (unformat (input, "%U next-hop-table %d",
7943                          unformat_vl_api_ip4_address,
7944                          &path->nh.address.ip4, &path->table_id))
7945         {
7946           path->proto = FIB_API_PATH_NH_PROTO_IP4;
7947         }
7948       else if (unformat (input, "%U next-hop-table %d",
7949                          unformat_vl_api_ip6_address,
7950                          &path->nh.address.ip6, &path->table_id))
7951         {
7952           path->proto = FIB_API_PATH_NH_PROTO_IP6;
7953         }
7954       else if (unformat (input, "%U",
7955                          unformat_vl_api_ip4_address, &path->nh.address.ip4))
7956         {
7957           /*
7958            * the recursive next-hops are by default in the default table
7959            */
7960           path->table_id = 0;
7961           path->sw_if_index = ~0;
7962           path->proto = FIB_API_PATH_NH_PROTO_IP4;
7963         }
7964       else if (unformat (input, "%U",
7965                          unformat_vl_api_ip6_address, &path->nh.address.ip6))
7966         {
7967           /*
7968            * the recursive next-hops are by default in the default table
7969            */
7970           path->table_id = 0;
7971           path->sw_if_index = ~0;
7972           path->proto = FIB_API_PATH_NH_PROTO_IP6;
7973         }
7974       else if (unformat (input, "resolve-via-host"))
7975         {
7976           path->flags |= FIB_API_PATH_FLAG_RESOLVE_VIA_HOST;
7977         }
7978       else if (unformat (input, "resolve-via-attached"))
7979         {
7980           path->flags |= FIB_API_PATH_FLAG_RESOLVE_VIA_ATTACHED;
7981         }
7982       else if (unformat (input, "ip4-lookup-in-table %d", &path->table_id))
7983         {
7984           path->type = FIB_API_PATH_TYPE_LOCAL;
7985           path->sw_if_index = ~0;
7986           path->proto = FIB_API_PATH_NH_PROTO_IP4;
7987         }
7988       else if (unformat (input, "ip6-lookup-in-table %d", &path->table_id))
7989         {
7990           path->type = FIB_API_PATH_TYPE_LOCAL;
7991           path->sw_if_index = ~0;
7992           path->proto = FIB_API_PATH_NH_PROTO_IP6;
7993         }
7994       else if (unformat (input, "sw_if_index %d", &path->sw_if_index))
7995         ;
7996       else if (unformat (input, "via-label %d", &path->nh.via_label))
7997         {
7998           path->proto = FIB_API_PATH_NH_PROTO_MPLS;
7999           path->sw_if_index = ~0;
8000         }
8001       else if (unformat (input, "l2-input-on %d", &path->sw_if_index))
8002         {
8003           path->proto = FIB_API_PATH_NH_PROTO_ETHERNET;
8004           path->type = FIB_API_PATH_TYPE_INTERFACE_RX;
8005         }
8006       else if (unformat (input, "local"))
8007         {
8008           path->type = FIB_API_PATH_TYPE_LOCAL;
8009         }
8010       else if (unformat (input, "out-labels"))
8011         {
8012           while (unformat (input, "%d", &out_label))
8013             {
8014               path->label_stack[path->n_labels].label = out_label;
8015               path->label_stack[path->n_labels].is_uniform = 0;
8016               path->label_stack[path->n_labels].ttl = 64;
8017               path->n_labels++;
8018             }
8019         }
8020       else if (unformat (input, "via"))
8021         {
8022           /* new path, back up and return */
8023           unformat_put_input (input);
8024           unformat_put_input (input);
8025           unformat_put_input (input);
8026           unformat_put_input (input);
8027           break;
8028         }
8029       else
8030         {
8031           return (0);
8032         }
8033     }
8034
8035   path->proto = ntohl (path->proto);
8036   path->type = ntohl (path->type);
8037   path->flags = ntohl (path->flags);
8038   path->table_id = ntohl (path->table_id);
8039   path->sw_if_index = ntohl (path->sw_if_index);
8040
8041   return (1);
8042 }
8043
8044 static int
8045 api_ip_route_add_del (vat_main_t * vam)
8046 {
8047   unformat_input_t *i = vam->input;
8048   vl_api_ip_route_add_del_t *mp;
8049   u32 vrf_id = 0;
8050   u8 is_add = 1;
8051   u8 is_multipath = 0;
8052   u8 prefix_set = 0;
8053   u8 path_count = 0;
8054   vl_api_prefix_t pfx = { };
8055   vl_api_fib_path_t paths[8];
8056   int count = 1;
8057   int j;
8058   f64 before = 0;
8059   u32 random_add_del = 0;
8060   u32 *random_vector = 0;
8061   u32 random_seed = 0xdeaddabe;
8062
8063   /* Parse args required to build the message */
8064   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8065     {
8066       if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
8067         prefix_set = 1;
8068       else if (unformat (i, "del"))
8069         is_add = 0;
8070       else if (unformat (i, "add"))
8071         is_add = 1;
8072       else if (unformat (i, "vrf %d", &vrf_id))
8073         ;
8074       else if (unformat (i, "count %d", &count))
8075         ;
8076       else if (unformat (i, "random"))
8077         random_add_del = 1;
8078       else if (unformat (i, "multipath"))
8079         is_multipath = 1;
8080       else if (unformat (i, "seed %d", &random_seed))
8081         ;
8082       else
8083         if (unformat
8084             (i, "via %U", unformat_fib_path, vam, &paths[path_count]))
8085         {
8086           path_count++;
8087           if (8 == path_count)
8088             {
8089               errmsg ("max 8 paths");
8090               return -99;
8091             }
8092         }
8093       else
8094         {
8095           clib_warning ("parse error '%U'", format_unformat_error, i);
8096           return -99;
8097         }
8098     }
8099
8100   if (!path_count)
8101     {
8102       errmsg ("specify a path; via ...");
8103       return -99;
8104     }
8105   if (prefix_set == 0)
8106     {
8107       errmsg ("missing prefix");
8108       return -99;
8109     }
8110
8111   /* Generate a pile of unique, random routes */
8112   if (random_add_del)
8113     {
8114       ip4_address_t *i = (ip4_address_t *) & paths[0].nh.address.ip4;
8115       u32 this_random_address;
8116       uword *random_hash;
8117
8118       random_hash = hash_create (count, sizeof (uword));
8119
8120       hash_set (random_hash, i->as_u32, 1);
8121       for (j = 0; j <= count; j++)
8122         {
8123           do
8124             {
8125               this_random_address = random_u32 (&random_seed);
8126               this_random_address =
8127                 clib_host_to_net_u32 (this_random_address);
8128             }
8129           while (hash_get (random_hash, this_random_address));
8130           vec_add1 (random_vector, this_random_address);
8131           hash_set (random_hash, this_random_address, 1);
8132         }
8133       hash_free (random_hash);
8134       set_ip4_address (&pfx.address, random_vector[0]);
8135     }
8136
8137   if (count > 1)
8138     {
8139       /* Turn on async mode */
8140       vam->async_mode = 1;
8141       vam->async_errors = 0;
8142       before = vat_time_now (vam);
8143     }
8144
8145   for (j = 0; j < count; j++)
8146     {
8147       /* Construct the API message */
8148       M2 (IP_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t) * path_count);
8149
8150       mp->is_add = is_add;
8151       mp->is_multipath = is_multipath;
8152
8153       clib_memcpy (&mp->route.prefix, &pfx, sizeof (pfx));
8154       mp->route.table_id = ntohl (vrf_id);
8155       mp->route.n_paths = path_count;
8156
8157       clib_memcpy (&mp->route.paths, &paths, sizeof (paths[0]) * path_count);
8158
8159       if (random_add_del)
8160         set_ip4_address (&pfx.address, random_vector[j + 1]);
8161       else
8162         increment_address (&pfx.address);
8163       /* send it... */
8164       S (mp);
8165       /* If we receive SIGTERM, stop now... */
8166       if (vam->do_exit)
8167         break;
8168     }
8169
8170   /* When testing multiple add/del ops, use a control-ping to sync */
8171   if (count > 1)
8172     {
8173       vl_api_control_ping_t *mp_ping;
8174       f64 after;
8175       f64 timeout;
8176
8177       /* Shut off async mode */
8178       vam->async_mode = 0;
8179
8180       MPING (CONTROL_PING, mp_ping);
8181       S (mp_ping);
8182
8183       timeout = vat_time_now (vam) + 1.0;
8184       while (vat_time_now (vam) < timeout)
8185         if (vam->result_ready == 1)
8186           goto out;
8187       vam->retval = -99;
8188
8189     out:
8190       if (vam->retval == -99)
8191         errmsg ("timeout");
8192
8193       if (vam->async_errors > 0)
8194         {
8195           errmsg ("%d asynchronous errors", vam->async_errors);
8196           vam->retval = -98;
8197         }
8198       vam->async_errors = 0;
8199       after = vat_time_now (vam);
8200
8201       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8202       if (j > 0)
8203         count = j;
8204
8205       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8206              count, after - before, count / (after - before));
8207     }
8208   else
8209     {
8210       int ret;
8211
8212       /* Wait for a reply... */
8213       W (ret);
8214       return ret;
8215     }
8216
8217   /* Return the good/bad news */
8218   return (vam->retval);
8219 }
8220
8221 static int
8222 api_ip_mroute_add_del (vat_main_t * vam)
8223 {
8224   unformat_input_t *i = vam->input;
8225   u8 path_set = 0, prefix_set = 0, is_add = 1;
8226   vl_api_ip_mroute_add_del_t *mp;
8227   mfib_entry_flags_t eflags = 0;
8228   vl_api_mfib_path_t path;
8229   vl_api_mprefix_t pfx = { };
8230   u32 vrf_id = 0;
8231   int ret;
8232
8233   /* Parse args required to build the message */
8234   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8235     {
8236       if (unformat (i, "%U", unformat_vl_api_mprefix, &pfx))
8237         {
8238           prefix_set = 1;
8239           pfx.grp_address_length = htons (pfx.grp_address_length);
8240         }
8241       else if (unformat (i, "del"))
8242         is_add = 0;
8243       else if (unformat (i, "add"))
8244         is_add = 1;
8245       else if (unformat (i, "vrf %d", &vrf_id))
8246         ;
8247       else if (unformat (i, "%U", unformat_mfib_itf_flags, &path.itf_flags))
8248         path.itf_flags = htonl (path.itf_flags);
8249       else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
8250         ;
8251       else if (unformat (i, "via %U", unformat_fib_path, vam, &path.path))
8252         path_set = 1;
8253       else
8254         {
8255           clib_warning ("parse error '%U'", format_unformat_error, i);
8256           return -99;
8257         }
8258     }
8259
8260   if (prefix_set == 0)
8261     {
8262       errmsg ("missing addresses\n");
8263       return -99;
8264     }
8265   if (path_set == 0)
8266     {
8267       errmsg ("missing path\n");
8268       return -99;
8269     }
8270
8271   /* Construct the API message */
8272   M (IP_MROUTE_ADD_DEL, mp);
8273
8274   mp->is_add = is_add;
8275   mp->is_multipath = 1;
8276
8277   clib_memcpy (&mp->route.prefix, &pfx, sizeof (pfx));
8278   mp->route.table_id = htonl (vrf_id);
8279   mp->route.n_paths = 1;
8280   mp->route.entry_flags = htonl (eflags);
8281
8282   clib_memcpy (&mp->route.paths, &path, sizeof (path));
8283
8284   /* send it... */
8285   S (mp);
8286   /* Wait for a reply... */
8287   W (ret);
8288   return ret;
8289 }
8290
8291 static int
8292 api_mpls_table_add_del (vat_main_t * vam)
8293 {
8294   unformat_input_t *i = vam->input;
8295   vl_api_mpls_table_add_del_t *mp;
8296   u32 table_id = ~0;
8297   u8 is_add = 1;
8298   int ret = 0;
8299
8300   /* Parse args required to build the message */
8301   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8302     {
8303       if (unformat (i, "table %d", &table_id))
8304         ;
8305       else if (unformat (i, "del"))
8306         is_add = 0;
8307       else if (unformat (i, "add"))
8308         is_add = 1;
8309       else
8310         {
8311           clib_warning ("parse error '%U'", format_unformat_error, i);
8312           return -99;
8313         }
8314     }
8315
8316   if (~0 == table_id)
8317     {
8318       errmsg ("missing table-ID");
8319       return -99;
8320     }
8321
8322   /* Construct the API message */
8323   M (MPLS_TABLE_ADD_DEL, mp);
8324
8325   mp->mt_table.mt_table_id = ntohl (table_id);
8326   mp->mt_is_add = is_add;
8327
8328   /* send it... */
8329   S (mp);
8330
8331   /* Wait for a reply... */
8332   W (ret);
8333
8334   return ret;
8335 }
8336
8337 static int
8338 api_mpls_route_add_del (vat_main_t * vam)
8339 {
8340   u8 is_add = 1, path_count = 0, is_multipath = 0, is_eos = 0;
8341   mpls_label_t local_label = MPLS_LABEL_INVALID;
8342   unformat_input_t *i = vam->input;
8343   vl_api_mpls_route_add_del_t *mp;
8344   vl_api_fib_path_t paths[8];
8345   int count = 1, j;
8346   f64 before = 0;
8347
8348   /* Parse args required to build the message */
8349   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8350     {
8351       if (unformat (i, "%d", &local_label))
8352         ;
8353       else if (unformat (i, "eos"))
8354         is_eos = 1;
8355       else if (unformat (i, "non-eos"))
8356         is_eos = 0;
8357       else if (unformat (i, "del"))
8358         is_add = 0;
8359       else if (unformat (i, "add"))
8360         is_add = 1;
8361       else if (unformat (i, "multipath"))
8362         is_multipath = 1;
8363       else if (unformat (i, "count %d", &count))
8364         ;
8365       else
8366         if (unformat
8367             (i, "via %U", unformat_fib_path, vam, &paths[path_count]))
8368         {
8369           path_count++;
8370           if (8 == path_count)
8371             {
8372               errmsg ("max 8 paths");
8373               return -99;
8374             }
8375         }
8376       else
8377         {
8378           clib_warning ("parse error '%U'", format_unformat_error, i);
8379           return -99;
8380         }
8381     }
8382
8383   if (!path_count)
8384     {
8385       errmsg ("specify a path; via ...");
8386       return -99;
8387     }
8388
8389   if (MPLS_LABEL_INVALID == local_label)
8390     {
8391       errmsg ("missing label");
8392       return -99;
8393     }
8394
8395   if (count > 1)
8396     {
8397       /* Turn on async mode */
8398       vam->async_mode = 1;
8399       vam->async_errors = 0;
8400       before = vat_time_now (vam);
8401     }
8402
8403   for (j = 0; j < count; j++)
8404     {
8405       /* Construct the API message */
8406       M2 (MPLS_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t) * path_count);
8407
8408       mp->mr_is_add = is_add;
8409       mp->mr_is_multipath = is_multipath;
8410
8411       mp->mr_route.mr_label = local_label;
8412       mp->mr_route.mr_eos = is_eos;
8413       mp->mr_route.mr_table_id = 0;
8414       mp->mr_route.mr_n_paths = path_count;
8415
8416       clib_memcpy (&mp->mr_route.mr_paths, paths,
8417                    sizeof (paths[0]) * path_count);
8418
8419       local_label++;
8420
8421       /* send it... */
8422       S (mp);
8423       /* If we receive SIGTERM, stop now... */
8424       if (vam->do_exit)
8425         break;
8426     }
8427
8428   /* When testing multiple add/del ops, use a control-ping to sync */
8429   if (count > 1)
8430     {
8431       vl_api_control_ping_t *mp_ping;
8432       f64 after;
8433       f64 timeout;
8434
8435       /* Shut off async mode */
8436       vam->async_mode = 0;
8437
8438       MPING (CONTROL_PING, mp_ping);
8439       S (mp_ping);
8440
8441       timeout = vat_time_now (vam) + 1.0;
8442       while (vat_time_now (vam) < timeout)
8443         if (vam->result_ready == 1)
8444           goto out;
8445       vam->retval = -99;
8446
8447     out:
8448       if (vam->retval == -99)
8449         errmsg ("timeout");
8450
8451       if (vam->async_errors > 0)
8452         {
8453           errmsg ("%d asynchronous errors", vam->async_errors);
8454           vam->retval = -98;
8455         }
8456       vam->async_errors = 0;
8457       after = vat_time_now (vam);
8458
8459       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8460       if (j > 0)
8461         count = j;
8462
8463       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8464              count, after - before, count / (after - before));
8465     }
8466   else
8467     {
8468       int ret;
8469
8470       /* Wait for a reply... */
8471       W (ret);
8472       return ret;
8473     }
8474
8475   /* Return the good/bad news */
8476   return (vam->retval);
8477   return (0);
8478 }
8479
8480 static int
8481 api_mpls_ip_bind_unbind (vat_main_t * vam)
8482 {
8483   unformat_input_t *i = vam->input;
8484   vl_api_mpls_ip_bind_unbind_t *mp;
8485   u32 ip_table_id = 0;
8486   u8 is_bind = 1;
8487   vl_api_prefix_t pfx;
8488   u8 prefix_set = 0;
8489   mpls_label_t local_label = MPLS_LABEL_INVALID;
8490   int ret;
8491
8492   /* Parse args required to build the message */
8493   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8494     {
8495       if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
8496         prefix_set = 1;
8497       else if (unformat (i, "%d", &local_label))
8498         ;
8499       else if (unformat (i, "table-id %d", &ip_table_id))
8500         ;
8501       else if (unformat (i, "unbind"))
8502         is_bind = 0;
8503       else if (unformat (i, "bind"))
8504         is_bind = 1;
8505       else
8506         {
8507           clib_warning ("parse error '%U'", format_unformat_error, i);
8508           return -99;
8509         }
8510     }
8511
8512   if (!prefix_set)
8513     {
8514       errmsg ("IP prefix not set");
8515       return -99;
8516     }
8517
8518   if (MPLS_LABEL_INVALID == local_label)
8519     {
8520       errmsg ("missing label");
8521       return -99;
8522     }
8523
8524   /* Construct the API message */
8525   M (MPLS_IP_BIND_UNBIND, mp);
8526
8527   mp->mb_is_bind = is_bind;
8528   mp->mb_ip_table_id = ntohl (ip_table_id);
8529   mp->mb_mpls_table_id = 0;
8530   mp->mb_label = ntohl (local_label);
8531   clib_memcpy (&mp->mb_prefix, &pfx, sizeof (pfx));
8532
8533   /* send it... */
8534   S (mp);
8535
8536   /* Wait for a reply... */
8537   W (ret);
8538   return ret;
8539   return (0);
8540 }
8541
8542 static int
8543 api_sr_mpls_policy_add (vat_main_t * vam)
8544 {
8545   unformat_input_t *i = vam->input;
8546   vl_api_sr_mpls_policy_add_t *mp;
8547   u32 bsid = 0;
8548   u32 weight = 1;
8549   u8 type = 0;
8550   u8 n_segments = 0;
8551   u32 sid;
8552   u32 *segments = NULL;
8553   int ret;
8554
8555   /* Parse args required to build the message */
8556   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8557     {
8558       if (unformat (i, "bsid %d", &bsid))
8559         ;
8560       else if (unformat (i, "weight %d", &weight))
8561         ;
8562       else if (unformat (i, "spray"))
8563         type = 1;
8564       else if (unformat (i, "next %d", &sid))
8565         {
8566           n_segments += 1;
8567           vec_add1 (segments, htonl (sid));
8568         }
8569       else
8570         {
8571           clib_warning ("parse error '%U'", format_unformat_error, i);
8572           return -99;
8573         }
8574     }
8575
8576   if (bsid == 0)
8577     {
8578       errmsg ("bsid not set");
8579       return -99;
8580     }
8581
8582   if (n_segments == 0)
8583     {
8584       errmsg ("no sid in segment stack");
8585       return -99;
8586     }
8587
8588   /* Construct the API message */
8589   M2 (SR_MPLS_POLICY_ADD, mp, sizeof (u32) * n_segments);
8590
8591   mp->bsid = htonl (bsid);
8592   mp->weight = htonl (weight);
8593   mp->type = type;
8594   mp->n_segments = n_segments;
8595   memcpy (mp->segments, segments, sizeof (u32) * n_segments);
8596   vec_free (segments);
8597
8598   /* send it... */
8599   S (mp);
8600
8601   /* Wait for a reply... */
8602   W (ret);
8603   return ret;
8604 }
8605
8606 static int
8607 api_sr_mpls_policy_del (vat_main_t * vam)
8608 {
8609   unformat_input_t *i = vam->input;
8610   vl_api_sr_mpls_policy_del_t *mp;
8611   u32 bsid = 0;
8612   int ret;
8613
8614   /* Parse args required to build the message */
8615   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8616     {
8617       if (unformat (i, "bsid %d", &bsid))
8618         ;
8619       else
8620         {
8621           clib_warning ("parse error '%U'", format_unformat_error, i);
8622           return -99;
8623         }
8624     }
8625
8626   if (bsid == 0)
8627     {
8628       errmsg ("bsid not set");
8629       return -99;
8630     }
8631
8632   /* Construct the API message */
8633   M (SR_MPLS_POLICY_DEL, mp);
8634
8635   mp->bsid = htonl (bsid);
8636
8637   /* send it... */
8638   S (mp);
8639
8640   /* Wait for a reply... */
8641   W (ret);
8642   return ret;
8643 }
8644
8645 static int
8646 api_bier_table_add_del (vat_main_t * vam)
8647 {
8648   unformat_input_t *i = vam->input;
8649   vl_api_bier_table_add_del_t *mp;
8650   u8 is_add = 1;
8651   u32 set = 0, sub_domain = 0, hdr_len = 3;
8652   mpls_label_t local_label = MPLS_LABEL_INVALID;
8653   int ret;
8654
8655   /* Parse args required to build the message */
8656   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8657     {
8658       if (unformat (i, "sub-domain %d", &sub_domain))
8659         ;
8660       else if (unformat (i, "set %d", &set))
8661         ;
8662       else if (unformat (i, "label %d", &local_label))
8663         ;
8664       else if (unformat (i, "hdr-len %d", &hdr_len))
8665         ;
8666       else if (unformat (i, "add"))
8667         is_add = 1;
8668       else if (unformat (i, "del"))
8669         is_add = 0;
8670       else
8671         {
8672           clib_warning ("parse error '%U'", format_unformat_error, i);
8673           return -99;
8674         }
8675     }
8676
8677   if (MPLS_LABEL_INVALID == local_label)
8678     {
8679       errmsg ("missing label\n");
8680       return -99;
8681     }
8682
8683   /* Construct the API message */
8684   M (BIER_TABLE_ADD_DEL, mp);
8685
8686   mp->bt_is_add = is_add;
8687   mp->bt_label = ntohl (local_label);
8688   mp->bt_tbl_id.bt_set = set;
8689   mp->bt_tbl_id.bt_sub_domain = sub_domain;
8690   mp->bt_tbl_id.bt_hdr_len_id = hdr_len;
8691
8692   /* send it... */
8693   S (mp);
8694
8695   /* Wait for a reply... */
8696   W (ret);
8697
8698   return (ret);
8699 }
8700
8701 static int
8702 api_bier_route_add_del (vat_main_t * vam)
8703 {
8704   unformat_input_t *i = vam->input;
8705   vl_api_bier_route_add_del_t *mp;
8706   u8 is_add = 1;
8707   u32 set = 0, sub_domain = 0, hdr_len = 3, bp = 0;
8708   ip4_address_t v4_next_hop_address;
8709   ip6_address_t v6_next_hop_address;
8710   u8 next_hop_set = 0;
8711   u8 next_hop_proto_is_ip4 = 1;
8712   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8713   int ret;
8714
8715   /* Parse args required to build the message */
8716   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8717     {
8718       if (unformat (i, "%U", unformat_ip4_address, &v4_next_hop_address))
8719         {
8720           next_hop_proto_is_ip4 = 1;
8721           next_hop_set = 1;
8722         }
8723       else if (unformat (i, "%U", unformat_ip6_address, &v6_next_hop_address))
8724         {
8725           next_hop_proto_is_ip4 = 0;
8726           next_hop_set = 1;
8727         }
8728       if (unformat (i, "sub-domain %d", &sub_domain))
8729         ;
8730       else if (unformat (i, "set %d", &set))
8731         ;
8732       else if (unformat (i, "hdr-len %d", &hdr_len))
8733         ;
8734       else if (unformat (i, "bp %d", &bp))
8735         ;
8736       else if (unformat (i, "add"))
8737         is_add = 1;
8738       else if (unformat (i, "del"))
8739         is_add = 0;
8740       else if (unformat (i, "out-label %d", &next_hop_out_label))
8741         ;
8742       else
8743         {
8744           clib_warning ("parse error '%U'", format_unformat_error, i);
8745           return -99;
8746         }
8747     }
8748
8749   if (!next_hop_set || (MPLS_LABEL_INVALID == next_hop_out_label))
8750     {
8751       errmsg ("next hop / label set\n");
8752       return -99;
8753     }
8754   if (0 == bp)
8755     {
8756       errmsg ("bit=position not set\n");
8757       return -99;
8758     }
8759
8760   /* Construct the API message */
8761   M2 (BIER_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t));
8762
8763   mp->br_is_add = is_add;
8764   mp->br_route.br_tbl_id.bt_set = set;
8765   mp->br_route.br_tbl_id.bt_sub_domain = sub_domain;
8766   mp->br_route.br_tbl_id.bt_hdr_len_id = hdr_len;
8767   mp->br_route.br_bp = ntohs (bp);
8768   mp->br_route.br_n_paths = 1;
8769   mp->br_route.br_paths[0].n_labels = 1;
8770   mp->br_route.br_paths[0].label_stack[0].label = ntohl (next_hop_out_label);
8771   mp->br_route.br_paths[0].proto = (next_hop_proto_is_ip4 ?
8772                                     FIB_API_PATH_NH_PROTO_IP4 :
8773                                     FIB_API_PATH_NH_PROTO_IP6);
8774
8775   if (next_hop_proto_is_ip4)
8776     {
8777       clib_memcpy (&mp->br_route.br_paths[0].nh.address.ip4,
8778                    &v4_next_hop_address, sizeof (v4_next_hop_address));
8779     }
8780   else
8781     {
8782       clib_memcpy (&mp->br_route.br_paths[0].nh.address.ip6,
8783                    &v6_next_hop_address, sizeof (v6_next_hop_address));
8784     }
8785
8786   /* send it... */
8787   S (mp);
8788
8789   /* Wait for a reply... */
8790   W (ret);
8791
8792   return (ret);
8793 }
8794
8795 static int
8796 api_proxy_arp_add_del (vat_main_t * vam)
8797 {
8798   unformat_input_t *i = vam->input;
8799   vl_api_proxy_arp_add_del_t *mp;
8800   u32 vrf_id = 0;
8801   u8 is_add = 1;
8802   vl_api_ip4_address_t lo, hi;
8803   u8 range_set = 0;
8804   int ret;
8805
8806   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8807     {
8808       if (unformat (i, "vrf %d", &vrf_id))
8809         ;
8810       else if (unformat (i, "%U - %U", unformat_vl_api_ip4_address, &lo,
8811                          unformat_vl_api_ip4_address, &hi))
8812         range_set = 1;
8813       else if (unformat (i, "del"))
8814         is_add = 0;
8815       else
8816         {
8817           clib_warning ("parse error '%U'", format_unformat_error, i);
8818           return -99;
8819         }
8820     }
8821
8822   if (range_set == 0)
8823     {
8824       errmsg ("address range not set");
8825       return -99;
8826     }
8827
8828   M (PROXY_ARP_ADD_DEL, mp);
8829
8830   mp->proxy.table_id = ntohl (vrf_id);
8831   mp->is_add = is_add;
8832   clib_memcpy (mp->proxy.low, &lo, sizeof (lo));
8833   clib_memcpy (mp->proxy.hi, &hi, sizeof (hi));
8834
8835   S (mp);
8836   W (ret);
8837   return ret;
8838 }
8839
8840 static int
8841 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
8842 {
8843   unformat_input_t *i = vam->input;
8844   vl_api_proxy_arp_intfc_enable_disable_t *mp;
8845   u32 sw_if_index;
8846   u8 enable = 1;
8847   u8 sw_if_index_set = 0;
8848   int ret;
8849
8850   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8851     {
8852       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8853         sw_if_index_set = 1;
8854       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8855         sw_if_index_set = 1;
8856       else if (unformat (i, "enable"))
8857         enable = 1;
8858       else if (unformat (i, "disable"))
8859         enable = 0;
8860       else
8861         {
8862           clib_warning ("parse error '%U'", format_unformat_error, i);
8863           return -99;
8864         }
8865     }
8866
8867   if (sw_if_index_set == 0)
8868     {
8869       errmsg ("missing interface name or sw_if_index");
8870       return -99;
8871     }
8872
8873   M (PROXY_ARP_INTFC_ENABLE_DISABLE, mp);
8874
8875   mp->sw_if_index = ntohl (sw_if_index);
8876   mp->enable_disable = enable;
8877
8878   S (mp);
8879   W (ret);
8880   return ret;
8881 }
8882
8883 static int
8884 api_mpls_tunnel_add_del (vat_main_t * vam)
8885 {
8886   unformat_input_t *i = vam->input;
8887   vl_api_mpls_tunnel_add_del_t *mp;
8888
8889   vl_api_fib_path_t paths[8];
8890   u32 sw_if_index = ~0;
8891   u8 path_count = 0;
8892   u8 l2_only = 0;
8893   u8 is_add = 1;
8894   int ret;
8895
8896   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8897     {
8898       if (unformat (i, "add"))
8899         is_add = 1;
8900       else
8901         if (unformat
8902             (i, "del %U", api_unformat_sw_if_index, vam, &sw_if_index))
8903         is_add = 0;
8904       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
8905         is_add = 0;
8906       else if (unformat (i, "l2-only"))
8907         l2_only = 1;
8908       else
8909         if (unformat
8910             (i, "via %U", unformat_fib_path, vam, &paths[path_count]))
8911         {
8912           path_count++;
8913           if (8 == path_count)
8914             {
8915               errmsg ("max 8 paths");
8916               return -99;
8917             }
8918         }
8919       else
8920         {
8921           clib_warning ("parse error '%U'", format_unformat_error, i);
8922           return -99;
8923         }
8924     }
8925
8926   M2 (MPLS_TUNNEL_ADD_DEL, mp, sizeof (vl_api_fib_path_t) * path_count);
8927
8928   mp->mt_is_add = is_add;
8929   mp->mt_tunnel.mt_sw_if_index = ntohl (sw_if_index);
8930   mp->mt_tunnel.mt_l2_only = l2_only;
8931   mp->mt_tunnel.mt_is_multicast = 0;
8932   mp->mt_tunnel.mt_n_paths = path_count;
8933
8934   clib_memcpy (&mp->mt_tunnel.mt_paths, &paths,
8935                sizeof (paths[0]) * path_count);
8936
8937   S (mp);
8938   W (ret);
8939   return ret;
8940 }
8941
8942 static int
8943 api_sw_interface_set_unnumbered (vat_main_t * vam)
8944 {
8945   unformat_input_t *i = vam->input;
8946   vl_api_sw_interface_set_unnumbered_t *mp;
8947   u32 sw_if_index;
8948   u32 unnum_sw_index = ~0;
8949   u8 is_add = 1;
8950   u8 sw_if_index_set = 0;
8951   int ret;
8952
8953   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8954     {
8955       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8956         sw_if_index_set = 1;
8957       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8958         sw_if_index_set = 1;
8959       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
8960         ;
8961       else if (unformat (i, "del"))
8962         is_add = 0;
8963       else
8964         {
8965           clib_warning ("parse error '%U'", format_unformat_error, i);
8966           return -99;
8967         }
8968     }
8969
8970   if (sw_if_index_set == 0)
8971     {
8972       errmsg ("missing interface name or sw_if_index");
8973       return -99;
8974     }
8975
8976   M (SW_INTERFACE_SET_UNNUMBERED, mp);
8977
8978   mp->sw_if_index = ntohl (sw_if_index);
8979   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
8980   mp->is_add = is_add;
8981
8982   S (mp);
8983   W (ret);
8984   return ret;
8985 }
8986
8987 static int
8988 api_ip_neighbor_add_del (vat_main_t * vam)
8989 {
8990   vl_api_mac_address_t mac_address;
8991   unformat_input_t *i = vam->input;
8992   vl_api_ip_neighbor_add_del_t *mp;
8993   vl_api_address_t ip_address;
8994   u32 sw_if_index;
8995   u8 sw_if_index_set = 0;
8996   u8 is_add = 1;
8997   u8 mac_set = 0;
8998   u8 address_set = 0;
8999   int ret;
9000   ip_neighbor_flags_t flags;
9001
9002   flags = IP_NEIGHBOR_FLAG_NONE;
9003   clib_memset (&ip_address, 0, sizeof (ip_address));
9004   clib_memset (&mac_address, 0, sizeof (mac_address));
9005
9006   /* Parse args required to build the message */
9007   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9008     {
9009       if (unformat (i, "mac %U", unformat_vl_api_mac_address, &mac_address))
9010         {
9011           mac_set = 1;
9012         }
9013       else if (unformat (i, "del"))
9014         is_add = 0;
9015       else
9016         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9017         sw_if_index_set = 1;
9018       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9019         sw_if_index_set = 1;
9020       else if (unformat (i, "static"))
9021         flags |= IP_NEIGHBOR_FLAG_STATIC;
9022       else if (unformat (i, "no-fib-entry"))
9023         flags |= IP_NEIGHBOR_FLAG_NO_FIB_ENTRY;
9024       else if (unformat (i, "dst %U", unformat_vl_api_address, &ip_address))
9025         address_set = 1;
9026       else
9027         {
9028           clib_warning ("parse error '%U'", format_unformat_error, i);
9029           return -99;
9030         }
9031     }
9032
9033   if (sw_if_index_set == 0)
9034     {
9035       errmsg ("missing interface name or sw_if_index");
9036       return -99;
9037     }
9038   if (!address_set)
9039     {
9040       errmsg ("no address set");
9041       return -99;
9042     }
9043
9044   /* Construct the API message */
9045   M (IP_NEIGHBOR_ADD_DEL, mp);
9046
9047   mp->neighbor.sw_if_index = ntohl (sw_if_index);
9048   mp->is_add = is_add;
9049   mp->neighbor.flags = htonl (flags);
9050   if (mac_set)
9051     clib_memcpy (&mp->neighbor.mac_address, &mac_address,
9052                  sizeof (mac_address));
9053   if (address_set)
9054     clib_memcpy (&mp->neighbor.ip_address, &ip_address, sizeof (ip_address));
9055
9056   /* send it... */
9057   S (mp);
9058
9059   /* Wait for a reply, return good/bad news  */
9060   W (ret);
9061   return ret;
9062 }
9063
9064 static int
9065 api_create_vlan_subif (vat_main_t * vam)
9066 {
9067   unformat_input_t *i = vam->input;
9068   vl_api_create_vlan_subif_t *mp;
9069   u32 sw_if_index;
9070   u8 sw_if_index_set = 0;
9071   u32 vlan_id;
9072   u8 vlan_id_set = 0;
9073   int ret;
9074
9075   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9076     {
9077       if (unformat (i, "sw_if_index %d", &sw_if_index))
9078         sw_if_index_set = 1;
9079       else
9080         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9081         sw_if_index_set = 1;
9082       else if (unformat (i, "vlan %d", &vlan_id))
9083         vlan_id_set = 1;
9084       else
9085         {
9086           clib_warning ("parse error '%U'", format_unformat_error, i);
9087           return -99;
9088         }
9089     }
9090
9091   if (sw_if_index_set == 0)
9092     {
9093       errmsg ("missing interface name or sw_if_index");
9094       return -99;
9095     }
9096
9097   if (vlan_id_set == 0)
9098     {
9099       errmsg ("missing vlan_id");
9100       return -99;
9101     }
9102   M (CREATE_VLAN_SUBIF, mp);
9103
9104   mp->sw_if_index = ntohl (sw_if_index);
9105   mp->vlan_id = ntohl (vlan_id);
9106
9107   S (mp);
9108   W (ret);
9109   return ret;
9110 }
9111
9112 #define foreach_create_subif_bit                \
9113 _(no_tags)                                      \
9114 _(one_tag)                                      \
9115 _(two_tags)                                     \
9116 _(dot1ad)                                       \
9117 _(exact_match)                                  \
9118 _(default_sub)                                  \
9119 _(outer_vlan_id_any)                            \
9120 _(inner_vlan_id_any)
9121
9122 #define foreach_create_subif_flag               \
9123 _(0, "no_tags")                                 \
9124 _(1, "one_tag")                                 \
9125 _(2, "two_tags")                                \
9126 _(3, "dot1ad")                                  \
9127 _(4, "exact_match")                             \
9128 _(5, "default_sub")                             \
9129 _(6, "outer_vlan_id_any")                       \
9130 _(7, "inner_vlan_id_any")
9131
9132 static int
9133 api_create_subif (vat_main_t * vam)
9134 {
9135   unformat_input_t *i = vam->input;
9136   vl_api_create_subif_t *mp;
9137   u32 sw_if_index;
9138   u8 sw_if_index_set = 0;
9139   u32 sub_id;
9140   u8 sub_id_set = 0;
9141   u32 __attribute__ ((unused)) no_tags = 0;
9142   u32 __attribute__ ((unused)) one_tag = 0;
9143   u32 __attribute__ ((unused)) two_tags = 0;
9144   u32 __attribute__ ((unused)) dot1ad = 0;
9145   u32 __attribute__ ((unused)) exact_match = 0;
9146   u32 __attribute__ ((unused)) default_sub = 0;
9147   u32 __attribute__ ((unused)) outer_vlan_id_any = 0;
9148   u32 __attribute__ ((unused)) inner_vlan_id_any = 0;
9149   u32 tmp;
9150   u16 outer_vlan_id = 0;
9151   u16 inner_vlan_id = 0;
9152   int ret;
9153
9154   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9155     {
9156       if (unformat (i, "sw_if_index %d", &sw_if_index))
9157         sw_if_index_set = 1;
9158       else
9159         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9160         sw_if_index_set = 1;
9161       else if (unformat (i, "sub_id %d", &sub_id))
9162         sub_id_set = 1;
9163       else if (unformat (i, "outer_vlan_id %d", &tmp))
9164         outer_vlan_id = tmp;
9165       else if (unformat (i, "inner_vlan_id %d", &tmp))
9166         inner_vlan_id = tmp;
9167
9168 #define _(a) else if (unformat (i, #a)) a = 1 ;
9169       foreach_create_subif_bit
9170 #undef _
9171         else
9172         {
9173           clib_warning ("parse error '%U'", format_unformat_error, i);
9174           return -99;
9175         }
9176     }
9177
9178   if (sw_if_index_set == 0)
9179     {
9180       errmsg ("missing interface name or sw_if_index");
9181       return -99;
9182     }
9183
9184   if (sub_id_set == 0)
9185     {
9186       errmsg ("missing sub_id");
9187       return -99;
9188     }
9189   M (CREATE_SUBIF, mp);
9190
9191   mp->sw_if_index = ntohl (sw_if_index);
9192   mp->sub_id = ntohl (sub_id);
9193
9194 #define _(a,b) mp->sub_if_flags |= (1 << a);
9195   foreach_create_subif_flag;
9196 #undef _
9197
9198   mp->outer_vlan_id = ntohs (outer_vlan_id);
9199   mp->inner_vlan_id = ntohs (inner_vlan_id);
9200
9201   S (mp);
9202   W (ret);
9203   return ret;
9204 }
9205
9206 static int
9207 api_reset_fib (vat_main_t * vam)
9208 {
9209   unformat_input_t *i = vam->input;
9210   vl_api_reset_fib_t *mp;
9211   u32 vrf_id = 0;
9212   u8 is_ipv6 = 0;
9213   u8 vrf_id_set = 0;
9214
9215   int ret;
9216   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9217     {
9218       if (unformat (i, "vrf %d", &vrf_id))
9219         vrf_id_set = 1;
9220       else if (unformat (i, "ipv6"))
9221         is_ipv6 = 1;
9222       else
9223         {
9224           clib_warning ("parse error '%U'", format_unformat_error, i);
9225           return -99;
9226         }
9227     }
9228
9229   if (vrf_id_set == 0)
9230     {
9231       errmsg ("missing vrf id");
9232       return -99;
9233     }
9234
9235   M (RESET_FIB, mp);
9236
9237   mp->vrf_id = ntohl (vrf_id);
9238   mp->is_ipv6 = is_ipv6;
9239
9240   S (mp);
9241   W (ret);
9242   return ret;
9243 }
9244
9245 static int
9246 api_set_ip_flow_hash (vat_main_t * vam)
9247 {
9248   unformat_input_t *i = vam->input;
9249   vl_api_set_ip_flow_hash_t *mp;
9250   u32 vrf_id = 0;
9251   u8 is_ipv6 = 0;
9252   u8 vrf_id_set = 0;
9253   u8 src = 0;
9254   u8 dst = 0;
9255   u8 sport = 0;
9256   u8 dport = 0;
9257   u8 proto = 0;
9258   u8 reverse = 0;
9259   int ret;
9260
9261   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9262     {
9263       if (unformat (i, "vrf %d", &vrf_id))
9264         vrf_id_set = 1;
9265       else if (unformat (i, "ipv6"))
9266         is_ipv6 = 1;
9267       else if (unformat (i, "src"))
9268         src = 1;
9269       else if (unformat (i, "dst"))
9270         dst = 1;
9271       else if (unformat (i, "sport"))
9272         sport = 1;
9273       else if (unformat (i, "dport"))
9274         dport = 1;
9275       else if (unformat (i, "proto"))
9276         proto = 1;
9277       else if (unformat (i, "reverse"))
9278         reverse = 1;
9279
9280       else
9281         {
9282           clib_warning ("parse error '%U'", format_unformat_error, i);
9283           return -99;
9284         }
9285     }
9286
9287   if (vrf_id_set == 0)
9288     {
9289       errmsg ("missing vrf id");
9290       return -99;
9291     }
9292
9293   M (SET_IP_FLOW_HASH, mp);
9294   mp->src = src;
9295   mp->dst = dst;
9296   mp->sport = sport;
9297   mp->dport = dport;
9298   mp->proto = proto;
9299   mp->reverse = reverse;
9300   mp->vrf_id = ntohl (vrf_id);
9301   mp->is_ipv6 = is_ipv6;
9302
9303   S (mp);
9304   W (ret);
9305   return ret;
9306 }
9307
9308 static int
9309 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
9310 {
9311   unformat_input_t *i = vam->input;
9312   vl_api_sw_interface_ip6_enable_disable_t *mp;
9313   u32 sw_if_index;
9314   u8 sw_if_index_set = 0;
9315   u8 enable = 0;
9316   int ret;
9317
9318   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9319     {
9320       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9321         sw_if_index_set = 1;
9322       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9323         sw_if_index_set = 1;
9324       else if (unformat (i, "enable"))
9325         enable = 1;
9326       else if (unformat (i, "disable"))
9327         enable = 0;
9328       else
9329         {
9330           clib_warning ("parse error '%U'", format_unformat_error, i);
9331           return -99;
9332         }
9333     }
9334
9335   if (sw_if_index_set == 0)
9336     {
9337       errmsg ("missing interface name or sw_if_index");
9338       return -99;
9339     }
9340
9341   M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
9342
9343   mp->sw_if_index = ntohl (sw_if_index);
9344   mp->enable = enable;
9345
9346   S (mp);
9347   W (ret);
9348   return ret;
9349 }
9350
9351 static int
9352 api_ip6nd_proxy_add_del (vat_main_t * vam)
9353 {
9354   unformat_input_t *i = vam->input;
9355   vl_api_ip6nd_proxy_add_del_t *mp;
9356   u32 sw_if_index = ~0;
9357   u8 v6_address_set = 0;
9358   vl_api_ip6_address_t v6address;
9359   u8 is_del = 0;
9360   int ret;
9361
9362   /* Parse args required to build the message */
9363   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9364     {
9365       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9366         ;
9367       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9368         ;
9369       else if (unformat (i, "%U", unformat_vl_api_ip6_address, &v6address))
9370         v6_address_set = 1;
9371       if (unformat (i, "del"))
9372         is_del = 1;
9373       else
9374         {
9375           clib_warning ("parse error '%U'", format_unformat_error, i);
9376           return -99;
9377         }
9378     }
9379
9380   if (sw_if_index == ~0)
9381     {
9382       errmsg ("missing interface name or sw_if_index");
9383       return -99;
9384     }
9385   if (!v6_address_set)
9386     {
9387       errmsg ("no address set");
9388       return -99;
9389     }
9390
9391   /* Construct the API message */
9392   M (IP6ND_PROXY_ADD_DEL, mp);
9393
9394   mp->is_del = is_del;
9395   mp->sw_if_index = ntohl (sw_if_index);
9396   clib_memcpy (mp->ip, v6address, sizeof (v6address));
9397
9398   /* send it... */
9399   S (mp);
9400
9401   /* Wait for a reply, return good/bad news  */
9402   W (ret);
9403   return ret;
9404 }
9405
9406 static int
9407 api_ip6nd_proxy_dump (vat_main_t * vam)
9408 {
9409   vl_api_ip6nd_proxy_dump_t *mp;
9410   vl_api_control_ping_t *mp_ping;
9411   int ret;
9412
9413   M (IP6ND_PROXY_DUMP, mp);
9414
9415   S (mp);
9416
9417   /* Use a control ping for synchronization */
9418   MPING (CONTROL_PING, mp_ping);
9419   S (mp_ping);
9420
9421   W (ret);
9422   return ret;
9423 }
9424
9425 static void vl_api_ip6nd_proxy_details_t_handler
9426   (vl_api_ip6nd_proxy_details_t * mp)
9427 {
9428   vat_main_t *vam = &vat_main;
9429
9430   print (vam->ofp, "host %U sw_if_index %d",
9431          format_vl_api_ip6_address, mp->ip, ntohl (mp->sw_if_index));
9432 }
9433
9434 static void vl_api_ip6nd_proxy_details_t_handler_json
9435   (vl_api_ip6nd_proxy_details_t * mp)
9436 {
9437   vat_main_t *vam = &vat_main;
9438   struct in6_addr ip6;
9439   vat_json_node_t *node = NULL;
9440
9441   if (VAT_JSON_ARRAY != vam->json_tree.type)
9442     {
9443       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9444       vat_json_init_array (&vam->json_tree);
9445     }
9446   node = vat_json_array_add (&vam->json_tree);
9447
9448   vat_json_init_object (node);
9449   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
9450
9451   clib_memcpy (&ip6, mp->ip, sizeof (ip6));
9452   vat_json_object_add_ip6 (node, "host", ip6);
9453 }
9454
9455 static int
9456 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
9457 {
9458   unformat_input_t *i = vam->input;
9459   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
9460   u32 sw_if_index;
9461   u8 sw_if_index_set = 0;
9462   u8 v6_address_set = 0;
9463   vl_api_prefix_t pfx;
9464   u8 use_default = 0;
9465   u8 no_advertise = 0;
9466   u8 off_link = 0;
9467   u8 no_autoconfig = 0;
9468   u8 no_onlink = 0;
9469   u8 is_no = 0;
9470   u32 val_lifetime = 0;
9471   u32 pref_lifetime = 0;
9472   int ret;
9473
9474   /* Parse args required to build the message */
9475   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9476     {
9477       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9478         sw_if_index_set = 1;
9479       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9480         sw_if_index_set = 1;
9481       else if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
9482         v6_address_set = 1;
9483       else if (unformat (i, "val_life %d", &val_lifetime))
9484         ;
9485       else if (unformat (i, "pref_life %d", &pref_lifetime))
9486         ;
9487       else if (unformat (i, "def"))
9488         use_default = 1;
9489       else if (unformat (i, "noadv"))
9490         no_advertise = 1;
9491       else if (unformat (i, "offl"))
9492         off_link = 1;
9493       else if (unformat (i, "noauto"))
9494         no_autoconfig = 1;
9495       else if (unformat (i, "nolink"))
9496         no_onlink = 1;
9497       else if (unformat (i, "isno"))
9498         is_no = 1;
9499       else
9500         {
9501           clib_warning ("parse error '%U'", format_unformat_error, i);
9502           return -99;
9503         }
9504     }
9505
9506   if (sw_if_index_set == 0)
9507     {
9508       errmsg ("missing interface name or sw_if_index");
9509       return -99;
9510     }
9511   if (!v6_address_set)
9512     {
9513       errmsg ("no address set");
9514       return -99;
9515     }
9516
9517   /* Construct the API message */
9518   M (SW_INTERFACE_IP6ND_RA_PREFIX, mp);
9519
9520   mp->sw_if_index = ntohl (sw_if_index);
9521   clib_memcpy (&mp->prefix, &pfx, sizeof (pfx));
9522   mp->use_default = use_default;
9523   mp->no_advertise = no_advertise;
9524   mp->off_link = off_link;
9525   mp->no_autoconfig = no_autoconfig;
9526   mp->no_onlink = no_onlink;
9527   mp->is_no = is_no;
9528   mp->val_lifetime = ntohl (val_lifetime);
9529   mp->pref_lifetime = ntohl (pref_lifetime);
9530
9531   /* send it... */
9532   S (mp);
9533
9534   /* Wait for a reply, return good/bad news  */
9535   W (ret);
9536   return ret;
9537 }
9538
9539 static int
9540 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
9541 {
9542   unformat_input_t *i = vam->input;
9543   vl_api_sw_interface_ip6nd_ra_config_t *mp;
9544   u32 sw_if_index;
9545   u8 sw_if_index_set = 0;
9546   u8 suppress = 0;
9547   u8 managed = 0;
9548   u8 other = 0;
9549   u8 ll_option = 0;
9550   u8 send_unicast = 0;
9551   u8 cease = 0;
9552   u8 is_no = 0;
9553   u8 default_router = 0;
9554   u32 max_interval = 0;
9555   u32 min_interval = 0;
9556   u32 lifetime = 0;
9557   u32 initial_count = 0;
9558   u32 initial_interval = 0;
9559   int ret;
9560
9561
9562   /* Parse args required to build the message */
9563   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9564     {
9565       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9566         sw_if_index_set = 1;
9567       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9568         sw_if_index_set = 1;
9569       else if (unformat (i, "maxint %d", &max_interval))
9570         ;
9571       else if (unformat (i, "minint %d", &min_interval))
9572         ;
9573       else if (unformat (i, "life %d", &lifetime))
9574         ;
9575       else if (unformat (i, "count %d", &initial_count))
9576         ;
9577       else if (unformat (i, "interval %d", &initial_interval))
9578         ;
9579       else if (unformat (i, "suppress") || unformat (i, "surpress"))
9580         suppress = 1;
9581       else if (unformat (i, "managed"))
9582         managed = 1;
9583       else if (unformat (i, "other"))
9584         other = 1;
9585       else if (unformat (i, "ll"))
9586         ll_option = 1;
9587       else if (unformat (i, "send"))
9588         send_unicast = 1;
9589       else if (unformat (i, "cease"))
9590         cease = 1;
9591       else if (unformat (i, "isno"))
9592         is_no = 1;
9593       else if (unformat (i, "def"))
9594         default_router = 1;
9595       else
9596         {
9597           clib_warning ("parse error '%U'", format_unformat_error, i);
9598           return -99;
9599         }
9600     }
9601
9602   if (sw_if_index_set == 0)
9603     {
9604       errmsg ("missing interface name or sw_if_index");
9605       return -99;
9606     }
9607
9608   /* Construct the API message */
9609   M (SW_INTERFACE_IP6ND_RA_CONFIG, mp);
9610
9611   mp->sw_if_index = ntohl (sw_if_index);
9612   mp->max_interval = ntohl (max_interval);
9613   mp->min_interval = ntohl (min_interval);
9614   mp->lifetime = ntohl (lifetime);
9615   mp->initial_count = ntohl (initial_count);
9616   mp->initial_interval = ntohl (initial_interval);
9617   mp->suppress = suppress;
9618   mp->managed = managed;
9619   mp->other = other;
9620   mp->ll_option = ll_option;
9621   mp->send_unicast = send_unicast;
9622   mp->cease = cease;
9623   mp->is_no = is_no;
9624   mp->default_router = default_router;
9625
9626   /* send it... */
9627   S (mp);
9628
9629   /* Wait for a reply, return good/bad news  */
9630   W (ret);
9631   return ret;
9632 }
9633
9634 static int
9635 api_set_arp_neighbor_limit (vat_main_t * vam)
9636 {
9637   unformat_input_t *i = vam->input;
9638   vl_api_set_arp_neighbor_limit_t *mp;
9639   u32 arp_nbr_limit;
9640   u8 limit_set = 0;
9641   u8 is_ipv6 = 0;
9642   int ret;
9643
9644   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9645     {
9646       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
9647         limit_set = 1;
9648       else if (unformat (i, "ipv6"))
9649         is_ipv6 = 1;
9650       else
9651         {
9652           clib_warning ("parse error '%U'", format_unformat_error, i);
9653           return -99;
9654         }
9655     }
9656
9657   if (limit_set == 0)
9658     {
9659       errmsg ("missing limit value");
9660       return -99;
9661     }
9662
9663   M (SET_ARP_NEIGHBOR_LIMIT, mp);
9664
9665   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
9666   mp->is_ipv6 = is_ipv6;
9667
9668   S (mp);
9669   W (ret);
9670   return ret;
9671 }
9672
9673 static int
9674 api_l2_patch_add_del (vat_main_t * vam)
9675 {
9676   unformat_input_t *i = vam->input;
9677   vl_api_l2_patch_add_del_t *mp;
9678   u32 rx_sw_if_index;
9679   u8 rx_sw_if_index_set = 0;
9680   u32 tx_sw_if_index;
9681   u8 tx_sw_if_index_set = 0;
9682   u8 is_add = 1;
9683   int ret;
9684
9685   /* Parse args required to build the message */
9686   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9687     {
9688       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
9689         rx_sw_if_index_set = 1;
9690       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
9691         tx_sw_if_index_set = 1;
9692       else if (unformat (i, "rx"))
9693         {
9694           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9695             {
9696               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
9697                             &rx_sw_if_index))
9698                 rx_sw_if_index_set = 1;
9699             }
9700           else
9701             break;
9702         }
9703       else if (unformat (i, "tx"))
9704         {
9705           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9706             {
9707               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
9708                             &tx_sw_if_index))
9709                 tx_sw_if_index_set = 1;
9710             }
9711           else
9712             break;
9713         }
9714       else if (unformat (i, "del"))
9715         is_add = 0;
9716       else
9717         break;
9718     }
9719
9720   if (rx_sw_if_index_set == 0)
9721     {
9722       errmsg ("missing rx interface name or rx_sw_if_index");
9723       return -99;
9724     }
9725
9726   if (tx_sw_if_index_set == 0)
9727     {
9728       errmsg ("missing tx interface name or tx_sw_if_index");
9729       return -99;
9730     }
9731
9732   M (L2_PATCH_ADD_DEL, mp);
9733
9734   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
9735   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
9736   mp->is_add = is_add;
9737
9738   S (mp);
9739   W (ret);
9740   return ret;
9741 }
9742
9743 u8 is_del;
9744 u8 localsid_addr[16];
9745 u8 end_psp;
9746 u8 behavior;
9747 u32 sw_if_index;
9748 u32 vlan_index;
9749 u32 fib_table;
9750 u8 nh_addr[16];
9751
9752 static int
9753 api_sr_localsid_add_del (vat_main_t * vam)
9754 {
9755   unformat_input_t *i = vam->input;
9756   vl_api_sr_localsid_add_del_t *mp;
9757
9758   u8 is_del;
9759   ip6_address_t localsid;
9760   u8 end_psp = 0;
9761   u8 behavior = ~0;
9762   u32 sw_if_index;
9763   u32 fib_table = ~(u32) 0;
9764   ip6_address_t nh_addr6;
9765   ip4_address_t nh_addr4;
9766   clib_memset (&nh_addr6, 0, sizeof (ip6_address_t));
9767   clib_memset (&nh_addr4, 0, sizeof (ip4_address_t));
9768
9769   bool nexthop_set = 0;
9770
9771   int ret;
9772
9773   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9774     {
9775       if (unformat (i, "del"))
9776         is_del = 1;
9777       else if (unformat (i, "address %U", unformat_ip6_address, &localsid));
9778       else if (unformat (i, "next-hop %U", unformat_ip4_address, &nh_addr4))
9779         nexthop_set = 1;
9780       else if (unformat (i, "next-hop %U", unformat_ip6_address, &nh_addr6))
9781         nexthop_set = 1;
9782       else if (unformat (i, "behavior %u", &behavior));
9783       else if (unformat (i, "sw_if_index %u", &sw_if_index));
9784       else if (unformat (i, "fib-table %u", &fib_table));
9785       else if (unformat (i, "end.psp %u", &behavior));
9786       else
9787         break;
9788     }
9789
9790   M (SR_LOCALSID_ADD_DEL, mp);
9791
9792   clib_memcpy (mp->localsid.addr, &localsid, sizeof (mp->localsid));
9793   if (nexthop_set)
9794     {
9795       clib_memcpy (mp->nh_addr6, &nh_addr6, sizeof (mp->nh_addr6));
9796       clib_memcpy (mp->nh_addr4, &nh_addr4, sizeof (mp->nh_addr4));
9797     }
9798   mp->behavior = behavior;
9799   mp->sw_if_index = ntohl (sw_if_index);
9800   mp->fib_table = ntohl (fib_table);
9801   mp->end_psp = end_psp;
9802   mp->is_del = is_del;
9803
9804   S (mp);
9805   W (ret);
9806   return ret;
9807 }
9808
9809 static int
9810 api_ioam_enable (vat_main_t * vam)
9811 {
9812   unformat_input_t *input = vam->input;
9813   vl_api_ioam_enable_t *mp;
9814   u32 id = 0;
9815   int has_trace_option = 0;
9816   int has_pot_option = 0;
9817   int has_seqno_option = 0;
9818   int has_analyse_option = 0;
9819   int ret;
9820
9821   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9822     {
9823       if (unformat (input, "trace"))
9824         has_trace_option = 1;
9825       else if (unformat (input, "pot"))
9826         has_pot_option = 1;
9827       else if (unformat (input, "seqno"))
9828         has_seqno_option = 1;
9829       else if (unformat (input, "analyse"))
9830         has_analyse_option = 1;
9831       else
9832         break;
9833     }
9834   M (IOAM_ENABLE, mp);
9835   mp->id = htons (id);
9836   mp->seqno = has_seqno_option;
9837   mp->analyse = has_analyse_option;
9838   mp->pot_enable = has_pot_option;
9839   mp->trace_enable = has_trace_option;
9840
9841   S (mp);
9842   W (ret);
9843   return ret;
9844 }
9845
9846
9847 static int
9848 api_ioam_disable (vat_main_t * vam)
9849 {
9850   vl_api_ioam_disable_t *mp;
9851   int ret;
9852
9853   M (IOAM_DISABLE, mp);
9854   S (mp);
9855   W (ret);
9856   return ret;
9857 }
9858
9859 #define foreach_tcp_proto_field                 \
9860 _(src_port)                                     \
9861 _(dst_port)
9862
9863 #define foreach_udp_proto_field                 \
9864 _(src_port)                                     \
9865 _(dst_port)
9866
9867 #define foreach_ip4_proto_field                 \
9868 _(src_address)                                  \
9869 _(dst_address)                                  \
9870 _(tos)                                          \
9871 _(length)                                       \
9872 _(fragment_id)                                  \
9873 _(ttl)                                          \
9874 _(protocol)                                     \
9875 _(checksum)
9876
9877 typedef struct
9878 {
9879   u16 src_port, dst_port;
9880 } tcpudp_header_t;
9881
9882 #if VPP_API_TEST_BUILTIN == 0
9883 uword
9884 unformat_tcp_mask (unformat_input_t * input, va_list * args)
9885 {
9886   u8 **maskp = va_arg (*args, u8 **);
9887   u8 *mask = 0;
9888   u8 found_something = 0;
9889   tcp_header_t *tcp;
9890
9891 #define _(a) u8 a=0;
9892   foreach_tcp_proto_field;
9893 #undef _
9894
9895   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9896     {
9897       if (0);
9898 #define _(a) else if (unformat (input, #a)) a=1;
9899       foreach_tcp_proto_field
9900 #undef _
9901         else
9902         break;
9903     }
9904
9905 #define _(a) found_something += a;
9906   foreach_tcp_proto_field;
9907 #undef _
9908
9909   if (found_something == 0)
9910     return 0;
9911
9912   vec_validate (mask, sizeof (*tcp) - 1);
9913
9914   tcp = (tcp_header_t *) mask;
9915
9916 #define _(a) if (a) clib_memset (&tcp->a, 0xff, sizeof (tcp->a));
9917   foreach_tcp_proto_field;
9918 #undef _
9919
9920   *maskp = mask;
9921   return 1;
9922 }
9923
9924 uword
9925 unformat_udp_mask (unformat_input_t * input, va_list * args)
9926 {
9927   u8 **maskp = va_arg (*args, u8 **);
9928   u8 *mask = 0;
9929   u8 found_something = 0;
9930   udp_header_t *udp;
9931
9932 #define _(a) u8 a=0;
9933   foreach_udp_proto_field;
9934 #undef _
9935
9936   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9937     {
9938       if (0);
9939 #define _(a) else if (unformat (input, #a)) a=1;
9940       foreach_udp_proto_field
9941 #undef _
9942         else
9943         break;
9944     }
9945
9946 #define _(a) found_something += a;
9947   foreach_udp_proto_field;
9948 #undef _
9949
9950   if (found_something == 0)
9951     return 0;
9952
9953   vec_validate (mask, sizeof (*udp) - 1);
9954
9955   udp = (udp_header_t *) mask;
9956
9957 #define _(a) if (a) clib_memset (&udp->a, 0xff, sizeof (udp->a));
9958   foreach_udp_proto_field;
9959 #undef _
9960
9961   *maskp = mask;
9962   return 1;
9963 }
9964
9965 uword
9966 unformat_l4_mask (unformat_input_t * input, va_list * args)
9967 {
9968   u8 **maskp = va_arg (*args, u8 **);
9969   u16 src_port = 0, dst_port = 0;
9970   tcpudp_header_t *tcpudp;
9971
9972   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9973     {
9974       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
9975         return 1;
9976       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
9977         return 1;
9978       else if (unformat (input, "src_port"))
9979         src_port = 0xFFFF;
9980       else if (unformat (input, "dst_port"))
9981         dst_port = 0xFFFF;
9982       else
9983         return 0;
9984     }
9985
9986   if (!src_port && !dst_port)
9987     return 0;
9988
9989   u8 *mask = 0;
9990   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
9991
9992   tcpudp = (tcpudp_header_t *) mask;
9993   tcpudp->src_port = src_port;
9994   tcpudp->dst_port = dst_port;
9995
9996   *maskp = mask;
9997
9998   return 1;
9999 }
10000
10001 uword
10002 unformat_ip4_mask (unformat_input_t * input, va_list * args)
10003 {
10004   u8 **maskp = va_arg (*args, u8 **);
10005   u8 *mask = 0;
10006   u8 found_something = 0;
10007   ip4_header_t *ip;
10008
10009 #define _(a) u8 a=0;
10010   foreach_ip4_proto_field;
10011 #undef _
10012   u8 version = 0;
10013   u8 hdr_length = 0;
10014
10015
10016   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10017     {
10018       if (unformat (input, "version"))
10019         version = 1;
10020       else if (unformat (input, "hdr_length"))
10021         hdr_length = 1;
10022       else if (unformat (input, "src"))
10023         src_address = 1;
10024       else if (unformat (input, "dst"))
10025         dst_address = 1;
10026       else if (unformat (input, "proto"))
10027         protocol = 1;
10028
10029 #define _(a) else if (unformat (input, #a)) a=1;
10030       foreach_ip4_proto_field
10031 #undef _
10032         else
10033         break;
10034     }
10035
10036 #define _(a) found_something += a;
10037   foreach_ip4_proto_field;
10038 #undef _
10039
10040   if (found_something == 0)
10041     return 0;
10042
10043   vec_validate (mask, sizeof (*ip) - 1);
10044
10045   ip = (ip4_header_t *) mask;
10046
10047 #define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
10048   foreach_ip4_proto_field;
10049 #undef _
10050
10051   ip->ip_version_and_header_length = 0;
10052
10053   if (version)
10054     ip->ip_version_and_header_length |= 0xF0;
10055
10056   if (hdr_length)
10057     ip->ip_version_and_header_length |= 0x0F;
10058
10059   *maskp = mask;
10060   return 1;
10061 }
10062
10063 #define foreach_ip6_proto_field                 \
10064 _(src_address)                                  \
10065 _(dst_address)                                  \
10066 _(payload_length)                               \
10067 _(hop_limit)                                    \
10068 _(protocol)
10069
10070 uword
10071 unformat_ip6_mask (unformat_input_t * input, va_list * args)
10072 {
10073   u8 **maskp = va_arg (*args, u8 **);
10074   u8 *mask = 0;
10075   u8 found_something = 0;
10076   ip6_header_t *ip;
10077   u32 ip_version_traffic_class_and_flow_label;
10078
10079 #define _(a) u8 a=0;
10080   foreach_ip6_proto_field;
10081 #undef _
10082   u8 version = 0;
10083   u8 traffic_class = 0;
10084   u8 flow_label = 0;
10085
10086   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10087     {
10088       if (unformat (input, "version"))
10089         version = 1;
10090       else if (unformat (input, "traffic-class"))
10091         traffic_class = 1;
10092       else if (unformat (input, "flow-label"))
10093         flow_label = 1;
10094       else if (unformat (input, "src"))
10095         src_address = 1;
10096       else if (unformat (input, "dst"))
10097         dst_address = 1;
10098       else if (unformat (input, "proto"))
10099         protocol = 1;
10100
10101 #define _(a) else if (unformat (input, #a)) a=1;
10102       foreach_ip6_proto_field
10103 #undef _
10104         else
10105         break;
10106     }
10107
10108 #define _(a) found_something += a;
10109   foreach_ip6_proto_field;
10110 #undef _
10111
10112   if (found_something == 0)
10113     return 0;
10114
10115   vec_validate (mask, sizeof (*ip) - 1);
10116
10117   ip = (ip6_header_t *) mask;
10118
10119 #define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
10120   foreach_ip6_proto_field;
10121 #undef _
10122
10123   ip_version_traffic_class_and_flow_label = 0;
10124
10125   if (version)
10126     ip_version_traffic_class_and_flow_label |= 0xF0000000;
10127
10128   if (traffic_class)
10129     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
10130
10131   if (flow_label)
10132     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
10133
10134   ip->ip_version_traffic_class_and_flow_label =
10135     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
10136
10137   *maskp = mask;
10138   return 1;
10139 }
10140
10141 uword
10142 unformat_l3_mask (unformat_input_t * input, va_list * args)
10143 {
10144   u8 **maskp = va_arg (*args, u8 **);
10145
10146   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10147     {
10148       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
10149         return 1;
10150       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
10151         return 1;
10152       else
10153         break;
10154     }
10155   return 0;
10156 }
10157
10158 uword
10159 unformat_l2_mask (unformat_input_t * input, va_list * args)
10160 {
10161   u8 **maskp = va_arg (*args, u8 **);
10162   u8 *mask = 0;
10163   u8 src = 0;
10164   u8 dst = 0;
10165   u8 proto = 0;
10166   u8 tag1 = 0;
10167   u8 tag2 = 0;
10168   u8 ignore_tag1 = 0;
10169   u8 ignore_tag2 = 0;
10170   u8 cos1 = 0;
10171   u8 cos2 = 0;
10172   u8 dot1q = 0;
10173   u8 dot1ad = 0;
10174   int len = 14;
10175
10176   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10177     {
10178       if (unformat (input, "src"))
10179         src = 1;
10180       else if (unformat (input, "dst"))
10181         dst = 1;
10182       else if (unformat (input, "proto"))
10183         proto = 1;
10184       else if (unformat (input, "tag1"))
10185         tag1 = 1;
10186       else if (unformat (input, "tag2"))
10187         tag2 = 1;
10188       else if (unformat (input, "ignore-tag1"))
10189         ignore_tag1 = 1;
10190       else if (unformat (input, "ignore-tag2"))
10191         ignore_tag2 = 1;
10192       else if (unformat (input, "cos1"))
10193         cos1 = 1;
10194       else if (unformat (input, "cos2"))
10195         cos2 = 1;
10196       else if (unformat (input, "dot1q"))
10197         dot1q = 1;
10198       else if (unformat (input, "dot1ad"))
10199         dot1ad = 1;
10200       else
10201         break;
10202     }
10203   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
10204        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
10205     return 0;
10206
10207   if (tag1 || ignore_tag1 || cos1 || dot1q)
10208     len = 18;
10209   if (tag2 || ignore_tag2 || cos2 || dot1ad)
10210     len = 22;
10211
10212   vec_validate (mask, len - 1);
10213
10214   if (dst)
10215     clib_memset (mask, 0xff, 6);
10216
10217   if (src)
10218     clib_memset (mask + 6, 0xff, 6);
10219
10220   if (tag2 || dot1ad)
10221     {
10222       /* inner vlan tag */
10223       if (tag2)
10224         {
10225           mask[19] = 0xff;
10226           mask[18] = 0x0f;
10227         }
10228       if (cos2)
10229         mask[18] |= 0xe0;
10230       if (proto)
10231         mask[21] = mask[20] = 0xff;
10232       if (tag1)
10233         {
10234           mask[15] = 0xff;
10235           mask[14] = 0x0f;
10236         }
10237       if (cos1)
10238         mask[14] |= 0xe0;
10239       *maskp = mask;
10240       return 1;
10241     }
10242   if (tag1 | dot1q)
10243     {
10244       if (tag1)
10245         {
10246           mask[15] = 0xff;
10247           mask[14] = 0x0f;
10248         }
10249       if (cos1)
10250         mask[14] |= 0xe0;
10251       if (proto)
10252         mask[16] = mask[17] = 0xff;
10253
10254       *maskp = mask;
10255       return 1;
10256     }
10257   if (cos2)
10258     mask[18] |= 0xe0;
10259   if (cos1)
10260     mask[14] |= 0xe0;
10261   if (proto)
10262     mask[12] = mask[13] = 0xff;
10263
10264   *maskp = mask;
10265   return 1;
10266 }
10267
10268 uword
10269 unformat_classify_mask (unformat_input_t * input, va_list * args)
10270 {
10271   u8 **maskp = va_arg (*args, u8 **);
10272   u32 *skipp = va_arg (*args, u32 *);
10273   u32 *matchp = va_arg (*args, u32 *);
10274   u32 match;
10275   u8 *mask = 0;
10276   u8 *l2 = 0;
10277   u8 *l3 = 0;
10278   u8 *l4 = 0;
10279   int i;
10280
10281   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10282     {
10283       if (unformat (input, "hex %U", unformat_hex_string, &mask))
10284         ;
10285       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
10286         ;
10287       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
10288         ;
10289       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
10290         ;
10291       else
10292         break;
10293     }
10294
10295   if (l4 && !l3)
10296     {
10297       vec_free (mask);
10298       vec_free (l2);
10299       vec_free (l4);
10300       return 0;
10301     }
10302
10303   if (mask || l2 || l3 || l4)
10304     {
10305       if (l2 || l3 || l4)
10306         {
10307           /* "With a free Ethernet header in every package" */
10308           if (l2 == 0)
10309             vec_validate (l2, 13);
10310           mask = l2;
10311           if (vec_len (l3))
10312             {
10313               vec_append (mask, l3);
10314               vec_free (l3);
10315             }
10316           if (vec_len (l4))
10317             {
10318               vec_append (mask, l4);
10319               vec_free (l4);
10320             }
10321         }
10322
10323       /* Scan forward looking for the first significant mask octet */
10324       for (i = 0; i < vec_len (mask); i++)
10325         if (mask[i])
10326           break;
10327
10328       /* compute (skip, match) params */
10329       *skipp = i / sizeof (u32x4);
10330       vec_delete (mask, *skipp * sizeof (u32x4), 0);
10331
10332       /* Pad mask to an even multiple of the vector size */
10333       while (vec_len (mask) % sizeof (u32x4))
10334         vec_add1 (mask, 0);
10335
10336       match = vec_len (mask) / sizeof (u32x4);
10337
10338       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
10339         {
10340           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
10341           if (*tmp || *(tmp + 1))
10342             break;
10343           match--;
10344         }
10345       if (match == 0)
10346         clib_warning ("BUG: match 0");
10347
10348       _vec_len (mask) = match * sizeof (u32x4);
10349
10350       *matchp = match;
10351       *maskp = mask;
10352
10353       return 1;
10354     }
10355
10356   return 0;
10357 }
10358 #endif /* VPP_API_TEST_BUILTIN */
10359
10360 #define foreach_l2_next                         \
10361 _(drop, DROP)                                   \
10362 _(ethernet, ETHERNET_INPUT)                     \
10363 _(ip4, IP4_INPUT)                               \
10364 _(ip6, IP6_INPUT)
10365
10366 uword
10367 unformat_l2_next_index (unformat_input_t * input, va_list * args)
10368 {
10369   u32 *miss_next_indexp = va_arg (*args, u32 *);
10370   u32 next_index = 0;
10371   u32 tmp;
10372
10373 #define _(n,N) \
10374   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
10375   foreach_l2_next;
10376 #undef _
10377
10378   if (unformat (input, "%d", &tmp))
10379     {
10380       next_index = tmp;
10381       goto out;
10382     }
10383
10384   return 0;
10385
10386 out:
10387   *miss_next_indexp = next_index;
10388   return 1;
10389 }
10390
10391 #define foreach_ip_next                         \
10392 _(drop, DROP)                                   \
10393 _(local, LOCAL)                                 \
10394 _(rewrite, REWRITE)
10395
10396 uword
10397 api_unformat_ip_next_index (unformat_input_t * input, va_list * args)
10398 {
10399   u32 *miss_next_indexp = va_arg (*args, u32 *);
10400   u32 next_index = 0;
10401   u32 tmp;
10402
10403 #define _(n,N) \
10404   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
10405   foreach_ip_next;
10406 #undef _
10407
10408   if (unformat (input, "%d", &tmp))
10409     {
10410       next_index = tmp;
10411       goto out;
10412     }
10413
10414   return 0;
10415
10416 out:
10417   *miss_next_indexp = next_index;
10418   return 1;
10419 }
10420
10421 #define foreach_acl_next                        \
10422 _(deny, DENY)
10423
10424 uword
10425 api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
10426 {
10427   u32 *miss_next_indexp = va_arg (*args, u32 *);
10428   u32 next_index = 0;
10429   u32 tmp;
10430
10431 #define _(n,N) \
10432   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
10433   foreach_acl_next;
10434 #undef _
10435
10436   if (unformat (input, "permit"))
10437     {
10438       next_index = ~0;
10439       goto out;
10440     }
10441   else if (unformat (input, "%d", &tmp))
10442     {
10443       next_index = tmp;
10444       goto out;
10445     }
10446
10447   return 0;
10448
10449 out:
10450   *miss_next_indexp = next_index;
10451   return 1;
10452 }
10453
10454 uword
10455 unformat_policer_precolor (unformat_input_t * input, va_list * args)
10456 {
10457   u32 *r = va_arg (*args, u32 *);
10458
10459   if (unformat (input, "conform-color"))
10460     *r = POLICE_CONFORM;
10461   else if (unformat (input, "exceed-color"))
10462     *r = POLICE_EXCEED;
10463   else
10464     return 0;
10465
10466   return 1;
10467 }
10468
10469 static int
10470 api_classify_add_del_table (vat_main_t * vam)
10471 {
10472   unformat_input_t *i = vam->input;
10473   vl_api_classify_add_del_table_t *mp;
10474
10475   u32 nbuckets = 2;
10476   u32 skip = ~0;
10477   u32 match = ~0;
10478   int is_add = 1;
10479   int del_chain = 0;
10480   u32 table_index = ~0;
10481   u32 next_table_index = ~0;
10482   u32 miss_next_index = ~0;
10483   u32 memory_size = 32 << 20;
10484   u8 *mask = 0;
10485   u32 current_data_flag = 0;
10486   int current_data_offset = 0;
10487   int ret;
10488
10489   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10490     {
10491       if (unformat (i, "del"))
10492         is_add = 0;
10493       else if (unformat (i, "del-chain"))
10494         {
10495           is_add = 0;
10496           del_chain = 1;
10497         }
10498       else if (unformat (i, "buckets %d", &nbuckets))
10499         ;
10500       else if (unformat (i, "memory_size %d", &memory_size))
10501         ;
10502       else if (unformat (i, "skip %d", &skip))
10503         ;
10504       else if (unformat (i, "match %d", &match))
10505         ;
10506       else if (unformat (i, "table %d", &table_index))
10507         ;
10508       else if (unformat (i, "mask %U", unformat_classify_mask,
10509                          &mask, &skip, &match))
10510         ;
10511       else if (unformat (i, "next-table %d", &next_table_index))
10512         ;
10513       else if (unformat (i, "miss-next %U", api_unformat_ip_next_index,
10514                          &miss_next_index))
10515         ;
10516       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
10517                          &miss_next_index))
10518         ;
10519       else if (unformat (i, "acl-miss-next %U", api_unformat_acl_next_index,
10520                          &miss_next_index))
10521         ;
10522       else if (unformat (i, "current-data-flag %d", &current_data_flag))
10523         ;
10524       else if (unformat (i, "current-data-offset %d", &current_data_offset))
10525         ;
10526       else
10527         break;
10528     }
10529
10530   if (is_add && mask == 0)
10531     {
10532       errmsg ("Mask required");
10533       return -99;
10534     }
10535
10536   if (is_add && skip == ~0)
10537     {
10538       errmsg ("skip count required");
10539       return -99;
10540     }
10541
10542   if (is_add && match == ~0)
10543     {
10544       errmsg ("match count required");
10545       return -99;
10546     }
10547
10548   if (!is_add && table_index == ~0)
10549     {
10550       errmsg ("table index required for delete");
10551       return -99;
10552     }
10553
10554   M2 (CLASSIFY_ADD_DEL_TABLE, mp, vec_len (mask));
10555
10556   mp->is_add = is_add;
10557   mp->del_chain = del_chain;
10558   mp->table_index = ntohl (table_index);
10559   mp->nbuckets = ntohl (nbuckets);
10560   mp->memory_size = ntohl (memory_size);
10561   mp->skip_n_vectors = ntohl (skip);
10562   mp->match_n_vectors = ntohl (match);
10563   mp->next_table_index = ntohl (next_table_index);
10564   mp->miss_next_index = ntohl (miss_next_index);
10565   mp->current_data_flag = ntohl (current_data_flag);
10566   mp->current_data_offset = ntohl (current_data_offset);
10567   mp->mask_len = ntohl (vec_len (mask));
10568   clib_memcpy (mp->mask, mask, vec_len (mask));
10569
10570   vec_free (mask);
10571
10572   S (mp);
10573   W (ret);
10574   return ret;
10575 }
10576
10577 #if VPP_API_TEST_BUILTIN == 0
10578 uword
10579 unformat_l4_match (unformat_input_t * input, va_list * args)
10580 {
10581   u8 **matchp = va_arg (*args, u8 **);
10582
10583   u8 *proto_header = 0;
10584   int src_port = 0;
10585   int dst_port = 0;
10586
10587   tcpudp_header_t h;
10588
10589   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10590     {
10591       if (unformat (input, "src_port %d", &src_port))
10592         ;
10593       else if (unformat (input, "dst_port %d", &dst_port))
10594         ;
10595       else
10596         return 0;
10597     }
10598
10599   h.src_port = clib_host_to_net_u16 (src_port);
10600   h.dst_port = clib_host_to_net_u16 (dst_port);
10601   vec_validate (proto_header, sizeof (h) - 1);
10602   memcpy (proto_header, &h, sizeof (h));
10603
10604   *matchp = proto_header;
10605
10606   return 1;
10607 }
10608
10609 uword
10610 unformat_ip4_match (unformat_input_t * input, va_list * args)
10611 {
10612   u8 **matchp = va_arg (*args, u8 **);
10613   u8 *match = 0;
10614   ip4_header_t *ip;
10615   int version = 0;
10616   u32 version_val;
10617   int hdr_length = 0;
10618   u32 hdr_length_val;
10619   int src = 0, dst = 0;
10620   ip4_address_t src_val, dst_val;
10621   int proto = 0;
10622   u32 proto_val;
10623   int tos = 0;
10624   u32 tos_val;
10625   int length = 0;
10626   u32 length_val;
10627   int fragment_id = 0;
10628   u32 fragment_id_val;
10629   int ttl = 0;
10630   int ttl_val;
10631   int checksum = 0;
10632   u32 checksum_val;
10633
10634   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10635     {
10636       if (unformat (input, "version %d", &version_val))
10637         version = 1;
10638       else if (unformat (input, "hdr_length %d", &hdr_length_val))
10639         hdr_length = 1;
10640       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
10641         src = 1;
10642       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
10643         dst = 1;
10644       else if (unformat (input, "proto %d", &proto_val))
10645         proto = 1;
10646       else if (unformat (input, "tos %d", &tos_val))
10647         tos = 1;
10648       else if (unformat (input, "length %d", &length_val))
10649         length = 1;
10650       else if (unformat (input, "fragment_id %d", &fragment_id_val))
10651         fragment_id = 1;
10652       else if (unformat (input, "ttl %d", &ttl_val))
10653         ttl = 1;
10654       else if (unformat (input, "checksum %d", &checksum_val))
10655         checksum = 1;
10656       else
10657         break;
10658     }
10659
10660   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
10661       + ttl + checksum == 0)
10662     return 0;
10663
10664   /*
10665    * Aligned because we use the real comparison functions
10666    */
10667   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
10668
10669   ip = (ip4_header_t *) match;
10670
10671   /* These are realistically matched in practice */
10672   if (src)
10673     ip->src_address.as_u32 = src_val.as_u32;
10674
10675   if (dst)
10676     ip->dst_address.as_u32 = dst_val.as_u32;
10677
10678   if (proto)
10679     ip->protocol = proto_val;
10680
10681
10682   /* These are not, but they're included for completeness */
10683   if (version)
10684     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
10685
10686   if (hdr_length)
10687     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
10688
10689   if (tos)
10690     ip->tos = tos_val;
10691
10692   if (length)
10693     ip->length = clib_host_to_net_u16 (length_val);
10694
10695   if (ttl)
10696     ip->ttl = ttl_val;
10697
10698   if (checksum)
10699     ip->checksum = clib_host_to_net_u16 (checksum_val);
10700
10701   *matchp = match;
10702   return 1;
10703 }
10704
10705 uword
10706 unformat_ip6_match (unformat_input_t * input, va_list * args)
10707 {
10708   u8 **matchp = va_arg (*args, u8 **);
10709   u8 *match = 0;
10710   ip6_header_t *ip;
10711   int version = 0;
10712   u32 version_val;
10713   u8 traffic_class = 0;
10714   u32 traffic_class_val = 0;
10715   u8 flow_label = 0;
10716   u8 flow_label_val;
10717   int src = 0, dst = 0;
10718   ip6_address_t src_val, dst_val;
10719   int proto = 0;
10720   u32 proto_val;
10721   int payload_length = 0;
10722   u32 payload_length_val;
10723   int hop_limit = 0;
10724   int hop_limit_val;
10725   u32 ip_version_traffic_class_and_flow_label;
10726
10727   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10728     {
10729       if (unformat (input, "version %d", &version_val))
10730         version = 1;
10731       else if (unformat (input, "traffic_class %d", &traffic_class_val))
10732         traffic_class = 1;
10733       else if (unformat (input, "flow_label %d", &flow_label_val))
10734         flow_label = 1;
10735       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
10736         src = 1;
10737       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
10738         dst = 1;
10739       else if (unformat (input, "proto %d", &proto_val))
10740         proto = 1;
10741       else if (unformat (input, "payload_length %d", &payload_length_val))
10742         payload_length = 1;
10743       else if (unformat (input, "hop_limit %d", &hop_limit_val))
10744         hop_limit = 1;
10745       else
10746         break;
10747     }
10748
10749   if (version + traffic_class + flow_label + src + dst + proto +
10750       payload_length + hop_limit == 0)
10751     return 0;
10752
10753   /*
10754    * Aligned because we use the real comparison functions
10755    */
10756   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
10757
10758   ip = (ip6_header_t *) match;
10759
10760   if (src)
10761     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
10762
10763   if (dst)
10764     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
10765
10766   if (proto)
10767     ip->protocol = proto_val;
10768
10769   ip_version_traffic_class_and_flow_label = 0;
10770
10771   if (version)
10772     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
10773
10774   if (traffic_class)
10775     ip_version_traffic_class_and_flow_label |=
10776       (traffic_class_val & 0xFF) << 20;
10777
10778   if (flow_label)
10779     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
10780
10781   ip->ip_version_traffic_class_and_flow_label =
10782     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
10783
10784   if (payload_length)
10785     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
10786
10787   if (hop_limit)
10788     ip->hop_limit = hop_limit_val;
10789
10790   *matchp = match;
10791   return 1;
10792 }
10793
10794 uword
10795 unformat_l3_match (unformat_input_t * input, va_list * args)
10796 {
10797   u8 **matchp = va_arg (*args, u8 **);
10798
10799   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10800     {
10801       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
10802         return 1;
10803       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
10804         return 1;
10805       else
10806         break;
10807     }
10808   return 0;
10809 }
10810
10811 uword
10812 unformat_vlan_tag (unformat_input_t * input, va_list * args)
10813 {
10814   u8 *tagp = va_arg (*args, u8 *);
10815   u32 tag;
10816
10817   if (unformat (input, "%d", &tag))
10818     {
10819       tagp[0] = (tag >> 8) & 0x0F;
10820       tagp[1] = tag & 0xFF;
10821       return 1;
10822     }
10823
10824   return 0;
10825 }
10826
10827 uword
10828 unformat_l2_match (unformat_input_t * input, va_list * args)
10829 {
10830   u8 **matchp = va_arg (*args, u8 **);
10831   u8 *match = 0;
10832   u8 src = 0;
10833   u8 src_val[6];
10834   u8 dst = 0;
10835   u8 dst_val[6];
10836   u8 proto = 0;
10837   u16 proto_val;
10838   u8 tag1 = 0;
10839   u8 tag1_val[2];
10840   u8 tag2 = 0;
10841   u8 tag2_val[2];
10842   int len = 14;
10843   u8 ignore_tag1 = 0;
10844   u8 ignore_tag2 = 0;
10845   u8 cos1 = 0;
10846   u8 cos2 = 0;
10847   u32 cos1_val = 0;
10848   u32 cos2_val = 0;
10849
10850   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10851     {
10852       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
10853         src = 1;
10854       else
10855         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
10856         dst = 1;
10857       else if (unformat (input, "proto %U",
10858                          unformat_ethernet_type_host_byte_order, &proto_val))
10859         proto = 1;
10860       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
10861         tag1 = 1;
10862       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
10863         tag2 = 1;
10864       else if (unformat (input, "ignore-tag1"))
10865         ignore_tag1 = 1;
10866       else if (unformat (input, "ignore-tag2"))
10867         ignore_tag2 = 1;
10868       else if (unformat (input, "cos1 %d", &cos1_val))
10869         cos1 = 1;
10870       else if (unformat (input, "cos2 %d", &cos2_val))
10871         cos2 = 1;
10872       else
10873         break;
10874     }
10875   if ((src + dst + proto + tag1 + tag2 +
10876        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
10877     return 0;
10878
10879   if (tag1 || ignore_tag1 || cos1)
10880     len = 18;
10881   if (tag2 || ignore_tag2 || cos2)
10882     len = 22;
10883
10884   vec_validate_aligned (match, len - 1, sizeof (u32x4));
10885
10886   if (dst)
10887     clib_memcpy (match, dst_val, 6);
10888
10889   if (src)
10890     clib_memcpy (match + 6, src_val, 6);
10891
10892   if (tag2)
10893     {
10894       /* inner vlan tag */
10895       match[19] = tag2_val[1];
10896       match[18] = tag2_val[0];
10897       if (cos2)
10898         match[18] |= (cos2_val & 0x7) << 5;
10899       if (proto)
10900         {
10901           match[21] = proto_val & 0xff;
10902           match[20] = proto_val >> 8;
10903         }
10904       if (tag1)
10905         {
10906           match[15] = tag1_val[1];
10907           match[14] = tag1_val[0];
10908         }
10909       if (cos1)
10910         match[14] |= (cos1_val & 0x7) << 5;
10911       *matchp = match;
10912       return 1;
10913     }
10914   if (tag1)
10915     {
10916       match[15] = tag1_val[1];
10917       match[14] = tag1_val[0];
10918       if (proto)
10919         {
10920           match[17] = proto_val & 0xff;
10921           match[16] = proto_val >> 8;
10922         }
10923       if (cos1)
10924         match[14] |= (cos1_val & 0x7) << 5;
10925
10926       *matchp = match;
10927       return 1;
10928     }
10929   if (cos2)
10930     match[18] |= (cos2_val & 0x7) << 5;
10931   if (cos1)
10932     match[14] |= (cos1_val & 0x7) << 5;
10933   if (proto)
10934     {
10935       match[13] = proto_val & 0xff;
10936       match[12] = proto_val >> 8;
10937     }
10938
10939   *matchp = match;
10940   return 1;
10941 }
10942
10943 uword
10944 unformat_qos_source (unformat_input_t * input, va_list * args)
10945 {
10946   int *qs = va_arg (*args, int *);
10947
10948   if (unformat (input, "ip"))
10949     *qs = QOS_SOURCE_IP;
10950   else if (unformat (input, "mpls"))
10951     *qs = QOS_SOURCE_MPLS;
10952   else if (unformat (input, "ext"))
10953     *qs = QOS_SOURCE_EXT;
10954   else if (unformat (input, "vlan"))
10955     *qs = QOS_SOURCE_VLAN;
10956   else
10957     return 0;
10958
10959   return 1;
10960 }
10961 #endif
10962
10963 uword
10964 api_unformat_classify_match (unformat_input_t * input, va_list * args)
10965 {
10966   u8 **matchp = va_arg (*args, u8 **);
10967   u32 skip_n_vectors = va_arg (*args, u32);
10968   u32 match_n_vectors = va_arg (*args, u32);
10969
10970   u8 *match = 0;
10971   u8 *l2 = 0;
10972   u8 *l3 = 0;
10973   u8 *l4 = 0;
10974
10975   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10976     {
10977       if (unformat (input, "hex %U", unformat_hex_string, &match))
10978         ;
10979       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
10980         ;
10981       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
10982         ;
10983       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
10984         ;
10985       else
10986         break;
10987     }
10988
10989   if (l4 && !l3)
10990     {
10991       vec_free (match);
10992       vec_free (l2);
10993       vec_free (l4);
10994       return 0;
10995     }
10996
10997   if (match || l2 || l3 || l4)
10998     {
10999       if (l2 || l3 || l4)
11000         {
11001           /* "Win a free Ethernet header in every packet" */
11002           if (l2 == 0)
11003             vec_validate_aligned (l2, 13, sizeof (u32x4));
11004           match = l2;
11005           if (vec_len (l3))
11006             {
11007               vec_append_aligned (match, l3, sizeof (u32x4));
11008               vec_free (l3);
11009             }
11010           if (vec_len (l4))
11011             {
11012               vec_append_aligned (match, l4, sizeof (u32x4));
11013               vec_free (l4);
11014             }
11015         }
11016
11017       /* Make sure the vector is big enough even if key is all 0's */
11018       vec_validate_aligned
11019         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
11020          sizeof (u32x4));
11021
11022       /* Set size, include skipped vectors */
11023       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
11024
11025       *matchp = match;
11026
11027       return 1;
11028     }
11029
11030   return 0;
11031 }
11032
11033 static int
11034 api_classify_add_del_session (vat_main_t * vam)
11035 {
11036   unformat_input_t *i = vam->input;
11037   vl_api_classify_add_del_session_t *mp;
11038   int is_add = 1;
11039   u32 table_index = ~0;
11040   u32 hit_next_index = ~0;
11041   u32 opaque_index = ~0;
11042   u8 *match = 0;
11043   i32 advance = 0;
11044   u32 skip_n_vectors = 0;
11045   u32 match_n_vectors = 0;
11046   u32 action = 0;
11047   u32 metadata = 0;
11048   int ret;
11049
11050   /*
11051    * Warning: you have to supply skip_n and match_n
11052    * because the API client cant simply look at the classify
11053    * table object.
11054    */
11055
11056   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11057     {
11058       if (unformat (i, "del"))
11059         is_add = 0;
11060       else if (unformat (i, "hit-next %U", api_unformat_ip_next_index,
11061                          &hit_next_index))
11062         ;
11063       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
11064                          &hit_next_index))
11065         ;
11066       else if (unformat (i, "acl-hit-next %U", api_unformat_acl_next_index,
11067                          &hit_next_index))
11068         ;
11069       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
11070         ;
11071       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
11072         ;
11073       else if (unformat (i, "opaque-index %d", &opaque_index))
11074         ;
11075       else if (unformat (i, "skip_n %d", &skip_n_vectors))
11076         ;
11077       else if (unformat (i, "match_n %d", &match_n_vectors))
11078         ;
11079       else if (unformat (i, "match %U", api_unformat_classify_match,
11080                          &match, skip_n_vectors, match_n_vectors))
11081         ;
11082       else if (unformat (i, "advance %d", &advance))
11083         ;
11084       else if (unformat (i, "table-index %d", &table_index))
11085         ;
11086       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
11087         action = 1;
11088       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
11089         action = 2;
11090       else if (unformat (i, "action %d", &action))
11091         ;
11092       else if (unformat (i, "metadata %d", &metadata))
11093         ;
11094       else
11095         break;
11096     }
11097
11098   if (table_index == ~0)
11099     {
11100       errmsg ("Table index required");
11101       return -99;
11102     }
11103
11104   if (is_add && match == 0)
11105     {
11106       errmsg ("Match value required");
11107       return -99;
11108     }
11109
11110   M2 (CLASSIFY_ADD_DEL_SESSION, mp, vec_len (match));
11111
11112   mp->is_add = is_add;
11113   mp->table_index = ntohl (table_index);
11114   mp->hit_next_index = ntohl (hit_next_index);
11115   mp->opaque_index = ntohl (opaque_index);
11116   mp->advance = ntohl (advance);
11117   mp->action = action;
11118   mp->metadata = ntohl (metadata);
11119   mp->match_len = ntohl (vec_len (match));
11120   clib_memcpy (mp->match, match, vec_len (match));
11121   vec_free (match);
11122
11123   S (mp);
11124   W (ret);
11125   return ret;
11126 }
11127
11128 static int
11129 api_classify_set_interface_ip_table (vat_main_t * vam)
11130 {
11131   unformat_input_t *i = vam->input;
11132   vl_api_classify_set_interface_ip_table_t *mp;
11133   u32 sw_if_index;
11134   int sw_if_index_set;
11135   u32 table_index = ~0;
11136   u8 is_ipv6 = 0;
11137   int ret;
11138
11139   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11140     {
11141       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11142         sw_if_index_set = 1;
11143       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11144         sw_if_index_set = 1;
11145       else if (unformat (i, "table %d", &table_index))
11146         ;
11147       else
11148         {
11149           clib_warning ("parse error '%U'", format_unformat_error, i);
11150           return -99;
11151         }
11152     }
11153
11154   if (sw_if_index_set == 0)
11155     {
11156       errmsg ("missing interface name or sw_if_index");
11157       return -99;
11158     }
11159
11160
11161   M (CLASSIFY_SET_INTERFACE_IP_TABLE, mp);
11162
11163   mp->sw_if_index = ntohl (sw_if_index);
11164   mp->table_index = ntohl (table_index);
11165   mp->is_ipv6 = is_ipv6;
11166
11167   S (mp);
11168   W (ret);
11169   return ret;
11170 }
11171
11172 static int
11173 api_classify_set_interface_l2_tables (vat_main_t * vam)
11174 {
11175   unformat_input_t *i = vam->input;
11176   vl_api_classify_set_interface_l2_tables_t *mp;
11177   u32 sw_if_index;
11178   int sw_if_index_set;
11179   u32 ip4_table_index = ~0;
11180   u32 ip6_table_index = ~0;
11181   u32 other_table_index = ~0;
11182   u32 is_input = 1;
11183   int ret;
11184
11185   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11186     {
11187       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11188         sw_if_index_set = 1;
11189       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11190         sw_if_index_set = 1;
11191       else if (unformat (i, "ip4-table %d", &ip4_table_index))
11192         ;
11193       else if (unformat (i, "ip6-table %d", &ip6_table_index))
11194         ;
11195       else if (unformat (i, "other-table %d", &other_table_index))
11196         ;
11197       else if (unformat (i, "is-input %d", &is_input))
11198         ;
11199       else
11200         {
11201           clib_warning ("parse error '%U'", format_unformat_error, i);
11202           return -99;
11203         }
11204     }
11205
11206   if (sw_if_index_set == 0)
11207     {
11208       errmsg ("missing interface name or sw_if_index");
11209       return -99;
11210     }
11211
11212
11213   M (CLASSIFY_SET_INTERFACE_L2_TABLES, mp);
11214
11215   mp->sw_if_index = ntohl (sw_if_index);
11216   mp->ip4_table_index = ntohl (ip4_table_index);
11217   mp->ip6_table_index = ntohl (ip6_table_index);
11218   mp->other_table_index = ntohl (other_table_index);
11219   mp->is_input = (u8) is_input;
11220
11221   S (mp);
11222   W (ret);
11223   return ret;
11224 }
11225
11226 static int
11227 api_set_ipfix_exporter (vat_main_t * vam)
11228 {
11229   unformat_input_t *i = vam->input;
11230   vl_api_set_ipfix_exporter_t *mp;
11231   ip4_address_t collector_address;
11232   u8 collector_address_set = 0;
11233   u32 collector_port = ~0;
11234   ip4_address_t src_address;
11235   u8 src_address_set = 0;
11236   u32 vrf_id = ~0;
11237   u32 path_mtu = ~0;
11238   u32 template_interval = ~0;
11239   u8 udp_checksum = 0;
11240   int ret;
11241
11242   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11243     {
11244       if (unformat (i, "collector_address %U", unformat_ip4_address,
11245                     &collector_address))
11246         collector_address_set = 1;
11247       else if (unformat (i, "collector_port %d", &collector_port))
11248         ;
11249       else if (unformat (i, "src_address %U", unformat_ip4_address,
11250                          &src_address))
11251         src_address_set = 1;
11252       else if (unformat (i, "vrf_id %d", &vrf_id))
11253         ;
11254       else if (unformat (i, "path_mtu %d", &path_mtu))
11255         ;
11256       else if (unformat (i, "template_interval %d", &template_interval))
11257         ;
11258       else if (unformat (i, "udp_checksum"))
11259         udp_checksum = 1;
11260       else
11261         break;
11262     }
11263
11264   if (collector_address_set == 0)
11265     {
11266       errmsg ("collector_address required");
11267       return -99;
11268     }
11269
11270   if (src_address_set == 0)
11271     {
11272       errmsg ("src_address required");
11273       return -99;
11274     }
11275
11276   M (SET_IPFIX_EXPORTER, mp);
11277
11278   memcpy (mp->collector_address, collector_address.data,
11279           sizeof (collector_address.data));
11280   mp->collector_port = htons ((u16) collector_port);
11281   memcpy (mp->src_address, src_address.data, sizeof (src_address.data));
11282   mp->vrf_id = htonl (vrf_id);
11283   mp->path_mtu = htonl (path_mtu);
11284   mp->template_interval = htonl (template_interval);
11285   mp->udp_checksum = udp_checksum;
11286
11287   S (mp);
11288   W (ret);
11289   return ret;
11290 }
11291
11292 static int
11293 api_set_ipfix_classify_stream (vat_main_t * vam)
11294 {
11295   unformat_input_t *i = vam->input;
11296   vl_api_set_ipfix_classify_stream_t *mp;
11297   u32 domain_id = 0;
11298   u32 src_port = UDP_DST_PORT_ipfix;
11299   int ret;
11300
11301   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11302     {
11303       if (unformat (i, "domain %d", &domain_id))
11304         ;
11305       else if (unformat (i, "src_port %d", &src_port))
11306         ;
11307       else
11308         {
11309           errmsg ("unknown input `%U'", format_unformat_error, i);
11310           return -99;
11311         }
11312     }
11313
11314   M (SET_IPFIX_CLASSIFY_STREAM, mp);
11315
11316   mp->domain_id = htonl (domain_id);
11317   mp->src_port = htons ((u16) src_port);
11318
11319   S (mp);
11320   W (ret);
11321   return ret;
11322 }
11323
11324 static int
11325 api_ipfix_classify_table_add_del (vat_main_t * vam)
11326 {
11327   unformat_input_t *i = vam->input;
11328   vl_api_ipfix_classify_table_add_del_t *mp;
11329   int is_add = -1;
11330   u32 classify_table_index = ~0;
11331   u8 ip_version = 0;
11332   u8 transport_protocol = 255;
11333   int ret;
11334
11335   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11336     {
11337       if (unformat (i, "add"))
11338         is_add = 1;
11339       else if (unformat (i, "del"))
11340         is_add = 0;
11341       else if (unformat (i, "table %d", &classify_table_index))
11342         ;
11343       else if (unformat (i, "ip4"))
11344         ip_version = 4;
11345       else if (unformat (i, "ip6"))
11346         ip_version = 6;
11347       else if (unformat (i, "tcp"))
11348         transport_protocol = 6;
11349       else if (unformat (i, "udp"))
11350         transport_protocol = 17;
11351       else
11352         {
11353           errmsg ("unknown input `%U'", format_unformat_error, i);
11354           return -99;
11355         }
11356     }
11357
11358   if (is_add == -1)
11359     {
11360       errmsg ("expecting: add|del");
11361       return -99;
11362     }
11363   if (classify_table_index == ~0)
11364     {
11365       errmsg ("classifier table not specified");
11366       return -99;
11367     }
11368   if (ip_version == 0)
11369     {
11370       errmsg ("IP version not specified");
11371       return -99;
11372     }
11373
11374   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, mp);
11375
11376   mp->is_add = is_add;
11377   mp->table_id = htonl (classify_table_index);
11378   mp->ip_version = ip_version;
11379   mp->transport_protocol = transport_protocol;
11380
11381   S (mp);
11382   W (ret);
11383   return ret;
11384 }
11385
11386 static int
11387 api_get_node_index (vat_main_t * vam)
11388 {
11389   unformat_input_t *i = vam->input;
11390   vl_api_get_node_index_t *mp;
11391   u8 *name = 0;
11392   int ret;
11393
11394   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11395     {
11396       if (unformat (i, "node %s", &name))
11397         ;
11398       else
11399         break;
11400     }
11401   if (name == 0)
11402     {
11403       errmsg ("node name required");
11404       return -99;
11405     }
11406   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
11407     {
11408       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11409       return -99;
11410     }
11411
11412   M (GET_NODE_INDEX, mp);
11413   clib_memcpy (mp->node_name, name, vec_len (name));
11414   vec_free (name);
11415
11416   S (mp);
11417   W (ret);
11418   return ret;
11419 }
11420
11421 static int
11422 api_get_next_index (vat_main_t * vam)
11423 {
11424   unformat_input_t *i = vam->input;
11425   vl_api_get_next_index_t *mp;
11426   u8 *node_name = 0, *next_node_name = 0;
11427   int ret;
11428
11429   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11430     {
11431       if (unformat (i, "node-name %s", &node_name))
11432         ;
11433       else if (unformat (i, "next-node-name %s", &next_node_name))
11434         break;
11435     }
11436
11437   if (node_name == 0)
11438     {
11439       errmsg ("node name required");
11440       return -99;
11441     }
11442   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
11443     {
11444       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11445       return -99;
11446     }
11447
11448   if (next_node_name == 0)
11449     {
11450       errmsg ("next node name required");
11451       return -99;
11452     }
11453   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
11454     {
11455       errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
11456       return -99;
11457     }
11458
11459   M (GET_NEXT_INDEX, mp);
11460   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
11461   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
11462   vec_free (node_name);
11463   vec_free (next_node_name);
11464
11465   S (mp);
11466   W (ret);
11467   return ret;
11468 }
11469
11470 static int
11471 api_add_node_next (vat_main_t * vam)
11472 {
11473   unformat_input_t *i = vam->input;
11474   vl_api_add_node_next_t *mp;
11475   u8 *name = 0;
11476   u8 *next = 0;
11477   int ret;
11478
11479   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11480     {
11481       if (unformat (i, "node %s", &name))
11482         ;
11483       else if (unformat (i, "next %s", &next))
11484         ;
11485       else
11486         break;
11487     }
11488   if (name == 0)
11489     {
11490       errmsg ("node name required");
11491       return -99;
11492     }
11493   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
11494     {
11495       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11496       return -99;
11497     }
11498   if (next == 0)
11499     {
11500       errmsg ("next node required");
11501       return -99;
11502     }
11503   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
11504     {
11505       errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
11506       return -99;
11507     }
11508
11509   M (ADD_NODE_NEXT, mp);
11510   clib_memcpy (mp->node_name, name, vec_len (name));
11511   clib_memcpy (mp->next_name, next, vec_len (next));
11512   vec_free (name);
11513   vec_free (next);
11514
11515   S (mp);
11516   W (ret);
11517   return ret;
11518 }
11519
11520 static int
11521 api_l2tpv3_create_tunnel (vat_main_t * vam)
11522 {
11523   unformat_input_t *i = vam->input;
11524   ip6_address_t client_address, our_address;
11525   int client_address_set = 0;
11526   int our_address_set = 0;
11527   u32 local_session_id = 0;
11528   u32 remote_session_id = 0;
11529   u64 local_cookie = 0;
11530   u64 remote_cookie = 0;
11531   u8 l2_sublayer_present = 0;
11532   vl_api_l2tpv3_create_tunnel_t *mp;
11533   int ret;
11534
11535   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11536     {
11537       if (unformat (i, "client_address %U", unformat_ip6_address,
11538                     &client_address))
11539         client_address_set = 1;
11540       else if (unformat (i, "our_address %U", unformat_ip6_address,
11541                          &our_address))
11542         our_address_set = 1;
11543       else if (unformat (i, "local_session_id %d", &local_session_id))
11544         ;
11545       else if (unformat (i, "remote_session_id %d", &remote_session_id))
11546         ;
11547       else if (unformat (i, "local_cookie %lld", &local_cookie))
11548         ;
11549       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
11550         ;
11551       else if (unformat (i, "l2-sublayer-present"))
11552         l2_sublayer_present = 1;
11553       else
11554         break;
11555     }
11556
11557   if (client_address_set == 0)
11558     {
11559       errmsg ("client_address required");
11560       return -99;
11561     }
11562
11563   if (our_address_set == 0)
11564     {
11565       errmsg ("our_address required");
11566       return -99;
11567     }
11568
11569   M (L2TPV3_CREATE_TUNNEL, mp);
11570
11571   clib_memcpy (mp->client_address, client_address.as_u8,
11572                sizeof (mp->client_address));
11573
11574   clib_memcpy (mp->our_address, our_address.as_u8, sizeof (mp->our_address));
11575
11576   mp->local_session_id = ntohl (local_session_id);
11577   mp->remote_session_id = ntohl (remote_session_id);
11578   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
11579   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
11580   mp->l2_sublayer_present = l2_sublayer_present;
11581   mp->is_ipv6 = 1;
11582
11583   S (mp);
11584   W (ret);
11585   return ret;
11586 }
11587
11588 static int
11589 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
11590 {
11591   unformat_input_t *i = vam->input;
11592   u32 sw_if_index;
11593   u8 sw_if_index_set = 0;
11594   u64 new_local_cookie = 0;
11595   u64 new_remote_cookie = 0;
11596   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
11597   int ret;
11598
11599   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11600     {
11601       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11602         sw_if_index_set = 1;
11603       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11604         sw_if_index_set = 1;
11605       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
11606         ;
11607       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
11608         ;
11609       else
11610         break;
11611     }
11612
11613   if (sw_if_index_set == 0)
11614     {
11615       errmsg ("missing interface name or sw_if_index");
11616       return -99;
11617     }
11618
11619   M (L2TPV3_SET_TUNNEL_COOKIES, mp);
11620
11621   mp->sw_if_index = ntohl (sw_if_index);
11622   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
11623   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
11624
11625   S (mp);
11626   W (ret);
11627   return ret;
11628 }
11629
11630 static int
11631 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
11632 {
11633   unformat_input_t *i = vam->input;
11634   vl_api_l2tpv3_interface_enable_disable_t *mp;
11635   u32 sw_if_index;
11636   u8 sw_if_index_set = 0;
11637   u8 enable_disable = 1;
11638   int ret;
11639
11640   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11641     {
11642       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11643         sw_if_index_set = 1;
11644       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11645         sw_if_index_set = 1;
11646       else if (unformat (i, "enable"))
11647         enable_disable = 1;
11648       else if (unformat (i, "disable"))
11649         enable_disable = 0;
11650       else
11651         break;
11652     }
11653
11654   if (sw_if_index_set == 0)
11655     {
11656       errmsg ("missing interface name or sw_if_index");
11657       return -99;
11658     }
11659
11660   M (L2TPV3_INTERFACE_ENABLE_DISABLE, mp);
11661
11662   mp->sw_if_index = ntohl (sw_if_index);
11663   mp->enable_disable = enable_disable;
11664
11665   S (mp);
11666   W (ret);
11667   return ret;
11668 }
11669
11670 static int
11671 api_l2tpv3_set_lookup_key (vat_main_t * vam)
11672 {
11673   unformat_input_t *i = vam->input;
11674   vl_api_l2tpv3_set_lookup_key_t *mp;
11675   u8 key = ~0;
11676   int ret;
11677
11678   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11679     {
11680       if (unformat (i, "lookup_v6_src"))
11681         key = L2T_LOOKUP_SRC_ADDRESS;
11682       else if (unformat (i, "lookup_v6_dst"))
11683         key = L2T_LOOKUP_DST_ADDRESS;
11684       else if (unformat (i, "lookup_session_id"))
11685         key = L2T_LOOKUP_SESSION_ID;
11686       else
11687         break;
11688     }
11689
11690   if (key == (u8) ~ 0)
11691     {
11692       errmsg ("l2tp session lookup key unset");
11693       return -99;
11694     }
11695
11696   M (L2TPV3_SET_LOOKUP_KEY, mp);
11697
11698   mp->key = key;
11699
11700   S (mp);
11701   W (ret);
11702   return ret;
11703 }
11704
11705 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
11706   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
11707 {
11708   vat_main_t *vam = &vat_main;
11709
11710   print (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)",
11711          format_ip6_address, mp->our_address,
11712          format_ip6_address, mp->client_address,
11713          clib_net_to_host_u32 (mp->sw_if_index));
11714
11715   print (vam->ofp,
11716          "   local cookies %016llx %016llx remote cookie %016llx",
11717          clib_net_to_host_u64 (mp->local_cookie[0]),
11718          clib_net_to_host_u64 (mp->local_cookie[1]),
11719          clib_net_to_host_u64 (mp->remote_cookie));
11720
11721   print (vam->ofp, "   local session-id %d remote session-id %d",
11722          clib_net_to_host_u32 (mp->local_session_id),
11723          clib_net_to_host_u32 (mp->remote_session_id));
11724
11725   print (vam->ofp, "   l2 specific sublayer %s\n",
11726          mp->l2_sublayer_present ? "preset" : "absent");
11727
11728 }
11729
11730 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
11731   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
11732 {
11733   vat_main_t *vam = &vat_main;
11734   vat_json_node_t *node = NULL;
11735   struct in6_addr addr;
11736
11737   if (VAT_JSON_ARRAY != vam->json_tree.type)
11738     {
11739       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11740       vat_json_init_array (&vam->json_tree);
11741     }
11742   node = vat_json_array_add (&vam->json_tree);
11743
11744   vat_json_init_object (node);
11745
11746   clib_memcpy (&addr, mp->our_address, sizeof (addr));
11747   vat_json_object_add_ip6 (node, "our_address", addr);
11748   clib_memcpy (&addr, mp->client_address, sizeof (addr));
11749   vat_json_object_add_ip6 (node, "client_address", addr);
11750
11751   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
11752   vat_json_init_array (lc);
11753   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
11754   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
11755   vat_json_object_add_uint (node, "remote_cookie",
11756                             clib_net_to_host_u64 (mp->remote_cookie));
11757
11758   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
11759   vat_json_object_add_uint (node, "local_session_id",
11760                             clib_net_to_host_u32 (mp->local_session_id));
11761   vat_json_object_add_uint (node, "remote_session_id",
11762                             clib_net_to_host_u32 (mp->remote_session_id));
11763   vat_json_object_add_string_copy (node, "l2_sublayer",
11764                                    mp->l2_sublayer_present ? (u8 *) "present"
11765                                    : (u8 *) "absent");
11766 }
11767
11768 static int
11769 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
11770 {
11771   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
11772   vl_api_control_ping_t *mp_ping;
11773   int ret;
11774
11775   /* Get list of l2tpv3-tunnel interfaces */
11776   M (SW_IF_L2TPV3_TUNNEL_DUMP, mp);
11777   S (mp);
11778
11779   /* Use a control ping for synchronization */
11780   MPING (CONTROL_PING, mp_ping);
11781   S (mp_ping);
11782
11783   W (ret);
11784   return ret;
11785 }
11786
11787
11788 static void vl_api_sw_interface_tap_v2_details_t_handler
11789   (vl_api_sw_interface_tap_v2_details_t * mp)
11790 {
11791   vat_main_t *vam = &vat_main;
11792
11793   u8 *ip4 = format (0, "%U/%d", format_ip4_address, mp->host_ip4_addr,
11794                     mp->host_ip4_prefix_len);
11795   u8 *ip6 = format (0, "%U/%d", format_ip6_address, mp->host_ip6_addr,
11796                     mp->host_ip6_prefix_len);
11797
11798   print (vam->ofp,
11799          "\n%-16s %-12d %-5d %-12d %-12d %-14U %-30s %-20s %-20s %-30s 0x%-08x",
11800          mp->dev_name, ntohl (mp->sw_if_index), ntohl (mp->id),
11801          ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
11802          format_ethernet_address, mp->host_mac_addr, mp->host_namespace,
11803          mp->host_bridge, ip4, ip6, ntohl (mp->tap_flags));
11804
11805   vec_free (ip4);
11806   vec_free (ip6);
11807 }
11808
11809 static void vl_api_sw_interface_tap_v2_details_t_handler_json
11810   (vl_api_sw_interface_tap_v2_details_t * mp)
11811 {
11812   vat_main_t *vam = &vat_main;
11813   vat_json_node_t *node = NULL;
11814
11815   if (VAT_JSON_ARRAY != vam->json_tree.type)
11816     {
11817       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11818       vat_json_init_array (&vam->json_tree);
11819     }
11820   node = vat_json_array_add (&vam->json_tree);
11821
11822   vat_json_init_object (node);
11823   vat_json_object_add_uint (node, "id", ntohl (mp->id));
11824   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11825   vat_json_object_add_uint (node, "tap_flags", ntohl (mp->tap_flags));
11826   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
11827   vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
11828   vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
11829   vat_json_object_add_string_copy (node, "host_mac_addr",
11830                                    format (0, "%U", format_ethernet_address,
11831                                            &mp->host_mac_addr));
11832   vat_json_object_add_string_copy (node, "host_namespace",
11833                                    mp->host_namespace);
11834   vat_json_object_add_string_copy (node, "host_bridge", mp->host_bridge);
11835   vat_json_object_add_string_copy (node, "host_ip4_addr",
11836                                    format (0, "%U/%d", format_ip4_address,
11837                                            mp->host_ip4_addr,
11838                                            mp->host_ip4_prefix_len));
11839   vat_json_object_add_string_copy (node, "host_ip6_addr",
11840                                    format (0, "%U/%d", format_ip6_address,
11841                                            mp->host_ip6_addr,
11842                                            mp->host_ip6_prefix_len));
11843
11844 }
11845
11846 static int
11847 api_sw_interface_tap_v2_dump (vat_main_t * vam)
11848 {
11849   vl_api_sw_interface_tap_v2_dump_t *mp;
11850   vl_api_control_ping_t *mp_ping;
11851   int ret;
11852
11853   print (vam->ofp,
11854          "\n%-16s %-12s %-5s %-12s %-12s %-14s %-30s %-20s %-20s %-30s",
11855          "dev_name", "sw_if_index", "id", "rx_ring_sz", "tx_ring_sz",
11856          "host_mac_addr", "host_namespace", "host_bridge", "host_ip4_addr",
11857          "host_ip6_addr");
11858
11859   /* Get list of tap interfaces */
11860   M (SW_INTERFACE_TAP_V2_DUMP, mp);
11861   S (mp);
11862
11863   /* Use a control ping for synchronization */
11864   MPING (CONTROL_PING, mp_ping);
11865   S (mp_ping);
11866
11867   W (ret);
11868   return ret;
11869 }
11870
11871 static void vl_api_sw_interface_virtio_pci_details_t_handler
11872   (vl_api_sw_interface_virtio_pci_details_t * mp)
11873 {
11874   vat_main_t *vam = &vat_main;
11875
11876   typedef union
11877   {
11878     struct
11879     {
11880       u16 domain;
11881       u8 bus;
11882       u8 slot:5;
11883       u8 function:3;
11884     };
11885     u32 as_u32;
11886   } pci_addr_t;
11887   pci_addr_t addr;
11888   addr.as_u32 = ntohl (mp->pci_addr);
11889   u8 *pci_addr = format (0, "%04x:%02x:%02x.%x", addr.domain, addr.bus,
11890                          addr.slot, addr.function);
11891
11892   print (vam->ofp,
11893          "\n%-12s %-12d %-12d %-12d %-17U 0x%-08llx",
11894          pci_addr, ntohl (mp->sw_if_index),
11895          ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
11896          format_ethernet_address, mp->mac_addr,
11897          clib_net_to_host_u64 (mp->features));
11898   vec_free (pci_addr);
11899 }
11900
11901 static void vl_api_sw_interface_virtio_pci_details_t_handler_json
11902   (vl_api_sw_interface_virtio_pci_details_t * mp)
11903 {
11904   vat_main_t *vam = &vat_main;
11905   vat_json_node_t *node = NULL;
11906
11907   if (VAT_JSON_ARRAY != vam->json_tree.type)
11908     {
11909       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11910       vat_json_init_array (&vam->json_tree);
11911     }
11912   node = vat_json_array_add (&vam->json_tree);
11913
11914   vat_json_init_object (node);
11915   vat_json_object_add_uint (node, "pci-addr", ntohl (mp->pci_addr));
11916   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11917   vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
11918   vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
11919   vat_json_object_add_uint (node, "features",
11920                             clib_net_to_host_u64 (mp->features));
11921   vat_json_object_add_string_copy (node, "mac_addr",
11922                                    format (0, "%U", format_ethernet_address,
11923                                            &mp->mac_addr));
11924 }
11925
11926 static int
11927 api_sw_interface_virtio_pci_dump (vat_main_t * vam)
11928 {
11929   vl_api_sw_interface_virtio_pci_dump_t *mp;
11930   vl_api_control_ping_t *mp_ping;
11931   int ret;
11932
11933   print (vam->ofp,
11934          "\n%-12s %-12s %-12s %-12s %-17s %-08s",
11935          "pci_addr", "sw_if_index", "rx_ring_sz", "tx_ring_sz",
11936          "mac_addr", "features");
11937
11938   /* Get list of tap interfaces */
11939   M (SW_INTERFACE_VIRTIO_PCI_DUMP, mp);
11940   S (mp);
11941
11942   /* Use a control ping for synchronization */
11943   MPING (CONTROL_PING, mp_ping);
11944   S (mp_ping);
11945
11946   W (ret);
11947   return ret;
11948 }
11949
11950 static int
11951 api_vxlan_offload_rx (vat_main_t * vam)
11952 {
11953   unformat_input_t *line_input = vam->input;
11954   vl_api_vxlan_offload_rx_t *mp;
11955   u32 hw_if_index = ~0, rx_if_index = ~0;
11956   u8 is_add = 1;
11957   int ret;
11958
11959   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11960     {
11961       if (unformat (line_input, "del"))
11962         is_add = 0;
11963       else if (unformat (line_input, "hw %U", api_unformat_hw_if_index, vam,
11964                          &hw_if_index))
11965         ;
11966       else if (unformat (line_input, "hw hw_if_index %u", &hw_if_index))
11967         ;
11968       else if (unformat (line_input, "rx %U", api_unformat_sw_if_index, vam,
11969                          &rx_if_index))
11970         ;
11971       else if (unformat (line_input, "rx sw_if_index %u", &rx_if_index))
11972         ;
11973       else
11974         {
11975           errmsg ("parse error '%U'", format_unformat_error, line_input);
11976           return -99;
11977         }
11978     }
11979
11980   if (hw_if_index == ~0)
11981     {
11982       errmsg ("no hw interface");
11983       return -99;
11984     }
11985
11986   if (rx_if_index == ~0)
11987     {
11988       errmsg ("no rx tunnel");
11989       return -99;
11990     }
11991
11992   M (VXLAN_OFFLOAD_RX, mp);
11993
11994   mp->hw_if_index = ntohl (hw_if_index);
11995   mp->sw_if_index = ntohl (rx_if_index);
11996   mp->enable = is_add;
11997
11998   S (mp);
11999   W (ret);
12000   return ret;
12001 }
12002
12003 static uword unformat_vxlan_decap_next
12004   (unformat_input_t * input, va_list * args)
12005 {
12006   u32 *result = va_arg (*args, u32 *);
12007   u32 tmp;
12008
12009   if (unformat (input, "l2"))
12010     *result = VXLAN_INPUT_NEXT_L2_INPUT;
12011   else if (unformat (input, "%d", &tmp))
12012     *result = tmp;
12013   else
12014     return 0;
12015   return 1;
12016 }
12017
12018 static int
12019 api_vxlan_add_del_tunnel (vat_main_t * vam)
12020 {
12021   unformat_input_t *line_input = vam->input;
12022   vl_api_vxlan_add_del_tunnel_t *mp;
12023   ip46_address_t src, dst;
12024   u8 is_add = 1;
12025   u8 ipv4_set = 0, ipv6_set = 0;
12026   u8 src_set = 0;
12027   u8 dst_set = 0;
12028   u8 grp_set = 0;
12029   u32 instance = ~0;
12030   u32 mcast_sw_if_index = ~0;
12031   u32 encap_vrf_id = 0;
12032   u32 decap_next_index = ~0;
12033   u32 vni = 0;
12034   int ret;
12035
12036   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
12037   clib_memset (&src, 0, sizeof src);
12038   clib_memset (&dst, 0, sizeof dst);
12039
12040   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12041     {
12042       if (unformat (line_input, "del"))
12043         is_add = 0;
12044       else if (unformat (line_input, "instance %d", &instance))
12045         ;
12046       else
12047         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
12048         {
12049           ipv4_set = 1;
12050           src_set = 1;
12051         }
12052       else
12053         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
12054         {
12055           ipv4_set = 1;
12056           dst_set = 1;
12057         }
12058       else
12059         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
12060         {
12061           ipv6_set = 1;
12062           src_set = 1;
12063         }
12064       else
12065         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
12066         {
12067           ipv6_set = 1;
12068           dst_set = 1;
12069         }
12070       else if (unformat (line_input, "group %U %U",
12071                          unformat_ip4_address, &dst.ip4,
12072                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12073         {
12074           grp_set = dst_set = 1;
12075           ipv4_set = 1;
12076         }
12077       else if (unformat (line_input, "group %U",
12078                          unformat_ip4_address, &dst.ip4))
12079         {
12080           grp_set = dst_set = 1;
12081           ipv4_set = 1;
12082         }
12083       else if (unformat (line_input, "group %U %U",
12084                          unformat_ip6_address, &dst.ip6,
12085                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12086         {
12087           grp_set = dst_set = 1;
12088           ipv6_set = 1;
12089         }
12090       else if (unformat (line_input, "group %U",
12091                          unformat_ip6_address, &dst.ip6))
12092         {
12093           grp_set = dst_set = 1;
12094           ipv6_set = 1;
12095         }
12096       else
12097         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
12098         ;
12099       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
12100         ;
12101       else if (unformat (line_input, "decap-next %U",
12102                          unformat_vxlan_decap_next, &decap_next_index))
12103         ;
12104       else if (unformat (line_input, "vni %d", &vni))
12105         ;
12106       else
12107         {
12108           errmsg ("parse error '%U'", format_unformat_error, line_input);
12109           return -99;
12110         }
12111     }
12112
12113   if (src_set == 0)
12114     {
12115       errmsg ("tunnel src address not specified");
12116       return -99;
12117     }
12118   if (dst_set == 0)
12119     {
12120       errmsg ("tunnel dst address not specified");
12121       return -99;
12122     }
12123
12124   if (grp_set && !ip46_address_is_multicast (&dst))
12125     {
12126       errmsg ("tunnel group address not multicast");
12127       return -99;
12128     }
12129   if (grp_set && mcast_sw_if_index == ~0)
12130     {
12131       errmsg ("tunnel nonexistent multicast device");
12132       return -99;
12133     }
12134   if (grp_set == 0 && ip46_address_is_multicast (&dst))
12135     {
12136       errmsg ("tunnel dst address must be unicast");
12137       return -99;
12138     }
12139
12140
12141   if (ipv4_set && ipv6_set)
12142     {
12143       errmsg ("both IPv4 and IPv6 addresses specified");
12144       return -99;
12145     }
12146
12147   if ((vni == 0) || (vni >> 24))
12148     {
12149       errmsg ("vni not specified or out of range");
12150       return -99;
12151     }
12152
12153   M (VXLAN_ADD_DEL_TUNNEL, mp);
12154
12155   if (ipv6_set)
12156     {
12157       clib_memcpy (mp->src_address, &src.ip6, sizeof (src.ip6));
12158       clib_memcpy (mp->dst_address, &dst.ip6, sizeof (dst.ip6));
12159     }
12160   else
12161     {
12162       clib_memcpy (mp->src_address, &src.ip4, sizeof (src.ip4));
12163       clib_memcpy (mp->dst_address, &dst.ip4, sizeof (dst.ip4));
12164     }
12165
12166   mp->instance = htonl (instance);
12167   mp->encap_vrf_id = ntohl (encap_vrf_id);
12168   mp->decap_next_index = ntohl (decap_next_index);
12169   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
12170   mp->vni = ntohl (vni);
12171   mp->is_add = is_add;
12172   mp->is_ipv6 = ipv6_set;
12173
12174   S (mp);
12175   W (ret);
12176   return ret;
12177 }
12178
12179 static void vl_api_vxlan_tunnel_details_t_handler
12180   (vl_api_vxlan_tunnel_details_t * mp)
12181 {
12182   vat_main_t *vam = &vat_main;
12183   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
12184   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
12185
12186   print (vam->ofp, "%11d%11d%24U%24U%14d%18d%13d%19d",
12187          ntohl (mp->sw_if_index),
12188          ntohl (mp->instance),
12189          format_ip46_address, &src, IP46_TYPE_ANY,
12190          format_ip46_address, &dst, IP46_TYPE_ANY,
12191          ntohl (mp->encap_vrf_id),
12192          ntohl (mp->decap_next_index), ntohl (mp->vni),
12193          ntohl (mp->mcast_sw_if_index));
12194 }
12195
12196 static void vl_api_vxlan_tunnel_details_t_handler_json
12197   (vl_api_vxlan_tunnel_details_t * mp)
12198 {
12199   vat_main_t *vam = &vat_main;
12200   vat_json_node_t *node = NULL;
12201
12202   if (VAT_JSON_ARRAY != vam->json_tree.type)
12203     {
12204       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12205       vat_json_init_array (&vam->json_tree);
12206     }
12207   node = vat_json_array_add (&vam->json_tree);
12208
12209   vat_json_init_object (node);
12210   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12211
12212   vat_json_object_add_uint (node, "instance", ntohl (mp->instance));
12213
12214   if (mp->is_ipv6)
12215     {
12216       struct in6_addr ip6;
12217
12218       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
12219       vat_json_object_add_ip6 (node, "src_address", ip6);
12220       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
12221       vat_json_object_add_ip6 (node, "dst_address", ip6);
12222     }
12223   else
12224     {
12225       struct in_addr ip4;
12226
12227       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
12228       vat_json_object_add_ip4 (node, "src_address", ip4);
12229       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
12230       vat_json_object_add_ip4 (node, "dst_address", ip4);
12231     }
12232   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
12233   vat_json_object_add_uint (node, "decap_next_index",
12234                             ntohl (mp->decap_next_index));
12235   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
12236   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
12237   vat_json_object_add_uint (node, "mcast_sw_if_index",
12238                             ntohl (mp->mcast_sw_if_index));
12239 }
12240
12241 static int
12242 api_vxlan_tunnel_dump (vat_main_t * vam)
12243 {
12244   unformat_input_t *i = vam->input;
12245   vl_api_vxlan_tunnel_dump_t *mp;
12246   vl_api_control_ping_t *mp_ping;
12247   u32 sw_if_index;
12248   u8 sw_if_index_set = 0;
12249   int ret;
12250
12251   /* Parse args required to build the message */
12252   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12253     {
12254       if (unformat (i, "sw_if_index %d", &sw_if_index))
12255         sw_if_index_set = 1;
12256       else
12257         break;
12258     }
12259
12260   if (sw_if_index_set == 0)
12261     {
12262       sw_if_index = ~0;
12263     }
12264
12265   if (!vam->json_output)
12266     {
12267       print (vam->ofp, "%11s%11s%24s%24s%14s%18s%13s%19s",
12268              "sw_if_index", "instance", "src_address", "dst_address",
12269              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
12270     }
12271
12272   /* Get list of vxlan-tunnel interfaces */
12273   M (VXLAN_TUNNEL_DUMP, mp);
12274
12275   mp->sw_if_index = htonl (sw_if_index);
12276
12277   S (mp);
12278
12279   /* Use a control ping for synchronization */
12280   MPING (CONTROL_PING, mp_ping);
12281   S (mp_ping);
12282
12283   W (ret);
12284   return ret;
12285 }
12286
12287 static uword unformat_geneve_decap_next
12288   (unformat_input_t * input, va_list * args)
12289 {
12290   u32 *result = va_arg (*args, u32 *);
12291   u32 tmp;
12292
12293   if (unformat (input, "l2"))
12294     *result = GENEVE_INPUT_NEXT_L2_INPUT;
12295   else if (unformat (input, "%d", &tmp))
12296     *result = tmp;
12297   else
12298     return 0;
12299   return 1;
12300 }
12301
12302 static int
12303 api_geneve_add_del_tunnel (vat_main_t * vam)
12304 {
12305   unformat_input_t *line_input = vam->input;
12306   vl_api_geneve_add_del_tunnel_t *mp;
12307   ip46_address_t src, dst;
12308   u8 is_add = 1;
12309   u8 ipv4_set = 0, ipv6_set = 0;
12310   u8 src_set = 0;
12311   u8 dst_set = 0;
12312   u8 grp_set = 0;
12313   u32 mcast_sw_if_index = ~0;
12314   u32 encap_vrf_id = 0;
12315   u32 decap_next_index = ~0;
12316   u32 vni = 0;
12317   int ret;
12318
12319   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
12320   clib_memset (&src, 0, sizeof src);
12321   clib_memset (&dst, 0, sizeof dst);
12322
12323   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12324     {
12325       if (unformat (line_input, "del"))
12326         is_add = 0;
12327       else
12328         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
12329         {
12330           ipv4_set = 1;
12331           src_set = 1;
12332         }
12333       else
12334         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
12335         {
12336           ipv4_set = 1;
12337           dst_set = 1;
12338         }
12339       else
12340         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
12341         {
12342           ipv6_set = 1;
12343           src_set = 1;
12344         }
12345       else
12346         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
12347         {
12348           ipv6_set = 1;
12349           dst_set = 1;
12350         }
12351       else if (unformat (line_input, "group %U %U",
12352                          unformat_ip4_address, &dst.ip4,
12353                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12354         {
12355           grp_set = dst_set = 1;
12356           ipv4_set = 1;
12357         }
12358       else if (unformat (line_input, "group %U",
12359                          unformat_ip4_address, &dst.ip4))
12360         {
12361           grp_set = dst_set = 1;
12362           ipv4_set = 1;
12363         }
12364       else if (unformat (line_input, "group %U %U",
12365                          unformat_ip6_address, &dst.ip6,
12366                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12367         {
12368           grp_set = dst_set = 1;
12369           ipv6_set = 1;
12370         }
12371       else if (unformat (line_input, "group %U",
12372                          unformat_ip6_address, &dst.ip6))
12373         {
12374           grp_set = dst_set = 1;
12375           ipv6_set = 1;
12376         }
12377       else
12378         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
12379         ;
12380       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
12381         ;
12382       else if (unformat (line_input, "decap-next %U",
12383                          unformat_geneve_decap_next, &decap_next_index))
12384         ;
12385       else if (unformat (line_input, "vni %d", &vni))
12386         ;
12387       else
12388         {
12389           errmsg ("parse error '%U'", format_unformat_error, line_input);
12390           return -99;
12391         }
12392     }
12393
12394   if (src_set == 0)
12395     {
12396       errmsg ("tunnel src address not specified");
12397       return -99;
12398     }
12399   if (dst_set == 0)
12400     {
12401       errmsg ("tunnel dst address not specified");
12402       return -99;
12403     }
12404
12405   if (grp_set && !ip46_address_is_multicast (&dst))
12406     {
12407       errmsg ("tunnel group address not multicast");
12408       return -99;
12409     }
12410   if (grp_set && mcast_sw_if_index == ~0)
12411     {
12412       errmsg ("tunnel nonexistent multicast device");
12413       return -99;
12414     }
12415   if (grp_set == 0 && ip46_address_is_multicast (&dst))
12416     {
12417       errmsg ("tunnel dst address must be unicast");
12418       return -99;
12419     }
12420
12421
12422   if (ipv4_set && ipv6_set)
12423     {
12424       errmsg ("both IPv4 and IPv6 addresses specified");
12425       return -99;
12426     }
12427
12428   if ((vni == 0) || (vni >> 24))
12429     {
12430       errmsg ("vni not specified or out of range");
12431       return -99;
12432     }
12433
12434   M (GENEVE_ADD_DEL_TUNNEL, mp);
12435
12436   if (ipv6_set)
12437     {
12438       clib_memcpy (mp->local_address, &src.ip6, sizeof (src.ip6));
12439       clib_memcpy (mp->remote_address, &dst.ip6, sizeof (dst.ip6));
12440     }
12441   else
12442     {
12443       clib_memcpy (mp->local_address, &src.ip4, sizeof (src.ip4));
12444       clib_memcpy (mp->remote_address, &dst.ip4, sizeof (dst.ip4));
12445     }
12446   mp->encap_vrf_id = ntohl (encap_vrf_id);
12447   mp->decap_next_index = ntohl (decap_next_index);
12448   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
12449   mp->vni = ntohl (vni);
12450   mp->is_add = is_add;
12451   mp->is_ipv6 = ipv6_set;
12452
12453   S (mp);
12454   W (ret);
12455   return ret;
12456 }
12457
12458 static void vl_api_geneve_tunnel_details_t_handler
12459   (vl_api_geneve_tunnel_details_t * mp)
12460 {
12461   vat_main_t *vam = &vat_main;
12462   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
12463   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
12464
12465   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
12466          ntohl (mp->sw_if_index),
12467          format_ip46_address, &src, IP46_TYPE_ANY,
12468          format_ip46_address, &dst, IP46_TYPE_ANY,
12469          ntohl (mp->encap_vrf_id),
12470          ntohl (mp->decap_next_index), ntohl (mp->vni),
12471          ntohl (mp->mcast_sw_if_index));
12472 }
12473
12474 static void vl_api_geneve_tunnel_details_t_handler_json
12475   (vl_api_geneve_tunnel_details_t * mp)
12476 {
12477   vat_main_t *vam = &vat_main;
12478   vat_json_node_t *node = NULL;
12479
12480   if (VAT_JSON_ARRAY != vam->json_tree.type)
12481     {
12482       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12483       vat_json_init_array (&vam->json_tree);
12484     }
12485   node = vat_json_array_add (&vam->json_tree);
12486
12487   vat_json_init_object (node);
12488   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12489   if (mp->is_ipv6)
12490     {
12491       struct in6_addr ip6;
12492
12493       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
12494       vat_json_object_add_ip6 (node, "src_address", ip6);
12495       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
12496       vat_json_object_add_ip6 (node, "dst_address", ip6);
12497     }
12498   else
12499     {
12500       struct in_addr ip4;
12501
12502       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
12503       vat_json_object_add_ip4 (node, "src_address", ip4);
12504       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
12505       vat_json_object_add_ip4 (node, "dst_address", ip4);
12506     }
12507   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
12508   vat_json_object_add_uint (node, "decap_next_index",
12509                             ntohl (mp->decap_next_index));
12510   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
12511   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
12512   vat_json_object_add_uint (node, "mcast_sw_if_index",
12513                             ntohl (mp->mcast_sw_if_index));
12514 }
12515
12516 static int
12517 api_geneve_tunnel_dump (vat_main_t * vam)
12518 {
12519   unformat_input_t *i = vam->input;
12520   vl_api_geneve_tunnel_dump_t *mp;
12521   vl_api_control_ping_t *mp_ping;
12522   u32 sw_if_index;
12523   u8 sw_if_index_set = 0;
12524   int ret;
12525
12526   /* Parse args required to build the message */
12527   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12528     {
12529       if (unformat (i, "sw_if_index %d", &sw_if_index))
12530         sw_if_index_set = 1;
12531       else
12532         break;
12533     }
12534
12535   if (sw_if_index_set == 0)
12536     {
12537       sw_if_index = ~0;
12538     }
12539
12540   if (!vam->json_output)
12541     {
12542       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
12543              "sw_if_index", "local_address", "remote_address",
12544              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
12545     }
12546
12547   /* Get list of geneve-tunnel interfaces */
12548   M (GENEVE_TUNNEL_DUMP, mp);
12549
12550   mp->sw_if_index = htonl (sw_if_index);
12551
12552   S (mp);
12553
12554   /* Use a control ping for synchronization */
12555   M (CONTROL_PING, mp_ping);
12556   S (mp_ping);
12557
12558   W (ret);
12559   return ret;
12560 }
12561
12562 static int
12563 api_gre_tunnel_add_del (vat_main_t * vam)
12564 {
12565   unformat_input_t *line_input = vam->input;
12566   vl_api_address_t src = { }, dst =
12567   {
12568   };
12569   vl_api_gre_tunnel_add_del_t *mp;
12570   vl_api_gre_tunnel_type_t t_type;
12571   u8 is_add = 1;
12572   u8 src_set = 0;
12573   u8 dst_set = 0;
12574   u32 outer_fib_id = 0;
12575   u32 session_id = 0;
12576   u32 instance = ~0;
12577   int ret;
12578
12579   t_type = GRE_API_TUNNEL_TYPE_L3;
12580
12581   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12582     {
12583       if (unformat (line_input, "del"))
12584         is_add = 0;
12585       else if (unformat (line_input, "instance %d", &instance))
12586         ;
12587       else if (unformat (line_input, "src %U", unformat_vl_api_address, &src))
12588         {
12589           src_set = 1;
12590         }
12591       else if (unformat (line_input, "dst %U", unformat_vl_api_address, &dst))
12592         {
12593           dst_set = 1;
12594         }
12595       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
12596         ;
12597       else if (unformat (line_input, "teb"))
12598         t_type = GRE_API_TUNNEL_TYPE_TEB;
12599       else if (unformat (line_input, "erspan %d", &session_id))
12600         t_type = GRE_API_TUNNEL_TYPE_ERSPAN;
12601       else
12602         {
12603           errmsg ("parse error '%U'", format_unformat_error, line_input);
12604           return -99;
12605         }
12606     }
12607
12608   if (src_set == 0)
12609     {
12610       errmsg ("tunnel src address not specified");
12611       return -99;
12612     }
12613   if (dst_set == 0)
12614     {
12615       errmsg ("tunnel dst address not specified");
12616       return -99;
12617     }
12618
12619   M (GRE_TUNNEL_ADD_DEL, mp);
12620
12621   clib_memcpy (&mp->tunnel.src, &src, sizeof (mp->tunnel.src));
12622   clib_memcpy (&mp->tunnel.dst, &dst, sizeof (mp->tunnel.dst));
12623
12624   mp->tunnel.instance = htonl (instance);
12625   mp->tunnel.outer_fib_id = htonl (outer_fib_id);
12626   mp->is_add = is_add;
12627   mp->tunnel.session_id = htons ((u16) session_id);
12628   mp->tunnel.type = htonl (t_type);
12629
12630   S (mp);
12631   W (ret);
12632   return ret;
12633 }
12634
12635 static void vl_api_gre_tunnel_details_t_handler
12636   (vl_api_gre_tunnel_details_t * mp)
12637 {
12638   vat_main_t *vam = &vat_main;
12639
12640   print (vam->ofp, "%11d%11d%24U%24U%13d%14d%12d",
12641          ntohl (mp->tunnel.sw_if_index),
12642          ntohl (mp->tunnel.instance),
12643          format_vl_api_address, &mp->tunnel.src,
12644          format_vl_api_address, &mp->tunnel.dst,
12645          mp->tunnel.type, ntohl (mp->tunnel.outer_fib_id),
12646          ntohl (mp->tunnel.session_id));
12647 }
12648
12649 static void vl_api_gre_tunnel_details_t_handler_json
12650   (vl_api_gre_tunnel_details_t * mp)
12651 {
12652   vat_main_t *vam = &vat_main;
12653   vat_json_node_t *node = NULL;
12654
12655   if (VAT_JSON_ARRAY != vam->json_tree.type)
12656     {
12657       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12658       vat_json_init_array (&vam->json_tree);
12659     }
12660   node = vat_json_array_add (&vam->json_tree);
12661
12662   vat_json_init_object (node);
12663   vat_json_object_add_uint (node, "sw_if_index",
12664                             ntohl (mp->tunnel.sw_if_index));
12665   vat_json_object_add_uint (node, "instance", ntohl (mp->tunnel.instance));
12666
12667   vat_json_object_add_address (node, "src", &mp->tunnel.src);
12668   vat_json_object_add_address (node, "dst", &mp->tunnel.dst);
12669   vat_json_object_add_uint (node, "tunnel_type", mp->tunnel.type);
12670   vat_json_object_add_uint (node, "outer_fib_id",
12671                             ntohl (mp->tunnel.outer_fib_id));
12672   vat_json_object_add_uint (node, "session_id", mp->tunnel.session_id);
12673 }
12674
12675 static int
12676 api_gre_tunnel_dump (vat_main_t * vam)
12677 {
12678   unformat_input_t *i = vam->input;
12679   vl_api_gre_tunnel_dump_t *mp;
12680   vl_api_control_ping_t *mp_ping;
12681   u32 sw_if_index;
12682   u8 sw_if_index_set = 0;
12683   int ret;
12684
12685   /* Parse args required to build the message */
12686   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12687     {
12688       if (unformat (i, "sw_if_index %d", &sw_if_index))
12689         sw_if_index_set = 1;
12690       else
12691         break;
12692     }
12693
12694   if (sw_if_index_set == 0)
12695     {
12696       sw_if_index = ~0;
12697     }
12698
12699   if (!vam->json_output)
12700     {
12701       print (vam->ofp, "%11s%11s%24s%24s%13s%14s%12s",
12702              "sw_if_index", "instance", "src_address", "dst_address",
12703              "tunnel_type", "outer_fib_id", "session_id");
12704     }
12705
12706   /* Get list of gre-tunnel interfaces */
12707   M (GRE_TUNNEL_DUMP, mp);
12708
12709   mp->sw_if_index = htonl (sw_if_index);
12710
12711   S (mp);
12712
12713   /* Use a control ping for synchronization */
12714   MPING (CONTROL_PING, mp_ping);
12715   S (mp_ping);
12716
12717   W (ret);
12718   return ret;
12719 }
12720
12721 static int
12722 api_l2_fib_clear_table (vat_main_t * vam)
12723 {
12724 //  unformat_input_t * i = vam->input;
12725   vl_api_l2_fib_clear_table_t *mp;
12726   int ret;
12727
12728   M (L2_FIB_CLEAR_TABLE, mp);
12729
12730   S (mp);
12731   W (ret);
12732   return ret;
12733 }
12734
12735 static int
12736 api_l2_interface_efp_filter (vat_main_t * vam)
12737 {
12738   unformat_input_t *i = vam->input;
12739   vl_api_l2_interface_efp_filter_t *mp;
12740   u32 sw_if_index;
12741   u8 enable = 1;
12742   u8 sw_if_index_set = 0;
12743   int ret;
12744
12745   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12746     {
12747       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12748         sw_if_index_set = 1;
12749       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12750         sw_if_index_set = 1;
12751       else if (unformat (i, "enable"))
12752         enable = 1;
12753       else if (unformat (i, "disable"))
12754         enable = 0;
12755       else
12756         {
12757           clib_warning ("parse error '%U'", format_unformat_error, i);
12758           return -99;
12759         }
12760     }
12761
12762   if (sw_if_index_set == 0)
12763     {
12764       errmsg ("missing sw_if_index");
12765       return -99;
12766     }
12767
12768   M (L2_INTERFACE_EFP_FILTER, mp);
12769
12770   mp->sw_if_index = ntohl (sw_if_index);
12771   mp->enable_disable = enable;
12772
12773   S (mp);
12774   W (ret);
12775   return ret;
12776 }
12777
12778 #define foreach_vtr_op                          \
12779 _("disable",  L2_VTR_DISABLED)                  \
12780 _("push-1",  L2_VTR_PUSH_1)                     \
12781 _("push-2",  L2_VTR_PUSH_2)                     \
12782 _("pop-1",  L2_VTR_POP_1)                       \
12783 _("pop-2",  L2_VTR_POP_2)                       \
12784 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
12785 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
12786 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
12787 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
12788
12789 static int
12790 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
12791 {
12792   unformat_input_t *i = vam->input;
12793   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
12794   u32 sw_if_index;
12795   u8 sw_if_index_set = 0;
12796   u8 vtr_op_set = 0;
12797   u32 vtr_op = 0;
12798   u32 push_dot1q = 1;
12799   u32 tag1 = ~0;
12800   u32 tag2 = ~0;
12801   int ret;
12802
12803   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12804     {
12805       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12806         sw_if_index_set = 1;
12807       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12808         sw_if_index_set = 1;
12809       else if (unformat (i, "vtr_op %d", &vtr_op))
12810         vtr_op_set = 1;
12811 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
12812       foreach_vtr_op
12813 #undef _
12814         else if (unformat (i, "push_dot1q %d", &push_dot1q))
12815         ;
12816       else if (unformat (i, "tag1 %d", &tag1))
12817         ;
12818       else if (unformat (i, "tag2 %d", &tag2))
12819         ;
12820       else
12821         {
12822           clib_warning ("parse error '%U'", format_unformat_error, i);
12823           return -99;
12824         }
12825     }
12826
12827   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
12828     {
12829       errmsg ("missing vtr operation or sw_if_index");
12830       return -99;
12831     }
12832
12833   M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
12834   mp->sw_if_index = ntohl (sw_if_index);
12835   mp->vtr_op = ntohl (vtr_op);
12836   mp->push_dot1q = ntohl (push_dot1q);
12837   mp->tag1 = ntohl (tag1);
12838   mp->tag2 = ntohl (tag2);
12839
12840   S (mp);
12841   W (ret);
12842   return ret;
12843 }
12844
12845 static int
12846 api_create_vhost_user_if (vat_main_t * vam)
12847 {
12848   unformat_input_t *i = vam->input;
12849   vl_api_create_vhost_user_if_t *mp;
12850   u8 *file_name;
12851   u8 is_server = 0;
12852   u8 file_name_set = 0;
12853   u32 custom_dev_instance = ~0;
12854   u8 hwaddr[6];
12855   u8 use_custom_mac = 0;
12856   u8 disable_mrg_rxbuf = 0;
12857   u8 disable_indirect_desc = 0;
12858   u8 *tag = 0;
12859   u8 enable_gso = 0;
12860   int ret;
12861
12862   /* Shut up coverity */
12863   clib_memset (hwaddr, 0, sizeof (hwaddr));
12864
12865   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12866     {
12867       if (unformat (i, "socket %s", &file_name))
12868         {
12869           file_name_set = 1;
12870         }
12871       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
12872         ;
12873       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
12874         use_custom_mac = 1;
12875       else if (unformat (i, "server"))
12876         is_server = 1;
12877       else if (unformat (i, "disable_mrg_rxbuf"))
12878         disable_mrg_rxbuf = 1;
12879       else if (unformat (i, "disable_indirect_desc"))
12880         disable_indirect_desc = 1;
12881       else if (unformat (i, "gso"))
12882         enable_gso = 1;
12883       else if (unformat (i, "tag %s", &tag))
12884         ;
12885       else
12886         break;
12887     }
12888
12889   if (file_name_set == 0)
12890     {
12891       errmsg ("missing socket file name");
12892       return -99;
12893     }
12894
12895   if (vec_len (file_name) > 255)
12896     {
12897       errmsg ("socket file name too long");
12898       return -99;
12899     }
12900   vec_add1 (file_name, 0);
12901
12902   M (CREATE_VHOST_USER_IF, mp);
12903
12904   mp->is_server = is_server;
12905   mp->disable_mrg_rxbuf = disable_mrg_rxbuf;
12906   mp->disable_indirect_desc = disable_indirect_desc;
12907   mp->enable_gso = enable_gso;
12908   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
12909   vec_free (file_name);
12910   if (custom_dev_instance != ~0)
12911     {
12912       mp->renumber = 1;
12913       mp->custom_dev_instance = ntohl (custom_dev_instance);
12914     }
12915
12916   mp->use_custom_mac = use_custom_mac;
12917   clib_memcpy (mp->mac_address, hwaddr, 6);
12918   if (tag)
12919     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
12920   vec_free (tag);
12921
12922   S (mp);
12923   W (ret);
12924   return ret;
12925 }
12926
12927 static int
12928 api_modify_vhost_user_if (vat_main_t * vam)
12929 {
12930   unformat_input_t *i = vam->input;
12931   vl_api_modify_vhost_user_if_t *mp;
12932   u8 *file_name;
12933   u8 is_server = 0;
12934   u8 file_name_set = 0;
12935   u32 custom_dev_instance = ~0;
12936   u8 sw_if_index_set = 0;
12937   u32 sw_if_index = (u32) ~ 0;
12938   u8 enable_gso = 0;
12939   int ret;
12940
12941   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12942     {
12943       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12944         sw_if_index_set = 1;
12945       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12946         sw_if_index_set = 1;
12947       else if (unformat (i, "socket %s", &file_name))
12948         {
12949           file_name_set = 1;
12950         }
12951       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
12952         ;
12953       else if (unformat (i, "server"))
12954         is_server = 1;
12955       else if (unformat (i, "gso"))
12956         enable_gso = 1;
12957       else
12958         break;
12959     }
12960
12961   if (sw_if_index_set == 0)
12962     {
12963       errmsg ("missing sw_if_index or interface name");
12964       return -99;
12965     }
12966
12967   if (file_name_set == 0)
12968     {
12969       errmsg ("missing socket file name");
12970       return -99;
12971     }
12972
12973   if (vec_len (file_name) > 255)
12974     {
12975       errmsg ("socket file name too long");
12976       return -99;
12977     }
12978   vec_add1 (file_name, 0);
12979
12980   M (MODIFY_VHOST_USER_IF, mp);
12981
12982   mp->sw_if_index = ntohl (sw_if_index);
12983   mp->is_server = is_server;
12984   mp->enable_gso = enable_gso;
12985   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
12986   vec_free (file_name);
12987   if (custom_dev_instance != ~0)
12988     {
12989       mp->renumber = 1;
12990       mp->custom_dev_instance = ntohl (custom_dev_instance);
12991     }
12992
12993   S (mp);
12994   W (ret);
12995   return ret;
12996 }
12997
12998 static int
12999 api_delete_vhost_user_if (vat_main_t * vam)
13000 {
13001   unformat_input_t *i = vam->input;
13002   vl_api_delete_vhost_user_if_t *mp;
13003   u32 sw_if_index = ~0;
13004   u8 sw_if_index_set = 0;
13005   int ret;
13006
13007   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13008     {
13009       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13010         sw_if_index_set = 1;
13011       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13012         sw_if_index_set = 1;
13013       else
13014         break;
13015     }
13016
13017   if (sw_if_index_set == 0)
13018     {
13019       errmsg ("missing sw_if_index or interface name");
13020       return -99;
13021     }
13022
13023
13024   M (DELETE_VHOST_USER_IF, mp);
13025
13026   mp->sw_if_index = ntohl (sw_if_index);
13027
13028   S (mp);
13029   W (ret);
13030   return ret;
13031 }
13032
13033 static void vl_api_sw_interface_vhost_user_details_t_handler
13034   (vl_api_sw_interface_vhost_user_details_t * mp)
13035 {
13036   vat_main_t *vam = &vat_main;
13037
13038   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s",
13039          (char *) mp->interface_name,
13040          ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
13041          clib_net_to_host_u64 (mp->features), mp->is_server,
13042          ntohl (mp->num_regions), (char *) mp->sock_filename);
13043   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
13044 }
13045
13046 static void vl_api_sw_interface_vhost_user_details_t_handler_json
13047   (vl_api_sw_interface_vhost_user_details_t * mp)
13048 {
13049   vat_main_t *vam = &vat_main;
13050   vat_json_node_t *node = NULL;
13051
13052   if (VAT_JSON_ARRAY != vam->json_tree.type)
13053     {
13054       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13055       vat_json_init_array (&vam->json_tree);
13056     }
13057   node = vat_json_array_add (&vam->json_tree);
13058
13059   vat_json_init_object (node);
13060   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13061   vat_json_object_add_string_copy (node, "interface_name",
13062                                    mp->interface_name);
13063   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
13064                             ntohl (mp->virtio_net_hdr_sz));
13065   vat_json_object_add_uint (node, "features",
13066                             clib_net_to_host_u64 (mp->features));
13067   vat_json_object_add_uint (node, "is_server", mp->is_server);
13068   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
13069   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
13070   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
13071 }
13072
13073 static int
13074 api_sw_interface_vhost_user_dump (vat_main_t * vam)
13075 {
13076   vl_api_sw_interface_vhost_user_dump_t *mp;
13077   vl_api_control_ping_t *mp_ping;
13078   int ret;
13079   print (vam->ofp,
13080          "Interface name            idx hdr_sz features server regions filename");
13081
13082   /* Get list of vhost-user interfaces */
13083   M (SW_INTERFACE_VHOST_USER_DUMP, mp);
13084   S (mp);
13085
13086   /* Use a control ping for synchronization */
13087   MPING (CONTROL_PING, mp_ping);
13088   S (mp_ping);
13089
13090   W (ret);
13091   return ret;
13092 }
13093
13094 static int
13095 api_show_version (vat_main_t * vam)
13096 {
13097   vl_api_show_version_t *mp;
13098   int ret;
13099
13100   M (SHOW_VERSION, mp);
13101
13102   S (mp);
13103   W (ret);
13104   return ret;
13105 }
13106
13107
13108 static int
13109 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
13110 {
13111   unformat_input_t *line_input = vam->input;
13112   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
13113   ip4_address_t local4, remote4;
13114   ip6_address_t local6, remote6;
13115   u8 is_add = 1;
13116   u8 ipv4_set = 0, ipv6_set = 0;
13117   u8 local_set = 0;
13118   u8 remote_set = 0;
13119   u8 grp_set = 0;
13120   u32 mcast_sw_if_index = ~0;
13121   u32 encap_vrf_id = 0;
13122   u32 decap_vrf_id = 0;
13123   u8 protocol = ~0;
13124   u32 vni;
13125   u8 vni_set = 0;
13126   int ret;
13127
13128   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
13129   clib_memset (&local4, 0, sizeof local4);
13130   clib_memset (&remote4, 0, sizeof remote4);
13131   clib_memset (&local6, 0, sizeof local6);
13132   clib_memset (&remote6, 0, sizeof remote6);
13133
13134   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13135     {
13136       if (unformat (line_input, "del"))
13137         is_add = 0;
13138       else if (unformat (line_input, "local %U",
13139                          unformat_ip4_address, &local4))
13140         {
13141           local_set = 1;
13142           ipv4_set = 1;
13143         }
13144       else if (unformat (line_input, "remote %U",
13145                          unformat_ip4_address, &remote4))
13146         {
13147           remote_set = 1;
13148           ipv4_set = 1;
13149         }
13150       else if (unformat (line_input, "local %U",
13151                          unformat_ip6_address, &local6))
13152         {
13153           local_set = 1;
13154           ipv6_set = 1;
13155         }
13156       else if (unformat (line_input, "remote %U",
13157                          unformat_ip6_address, &remote6))
13158         {
13159           remote_set = 1;
13160           ipv6_set = 1;
13161         }
13162       else if (unformat (line_input, "group %U %U",
13163                          unformat_ip4_address, &remote4,
13164                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13165         {
13166           grp_set = remote_set = 1;
13167           ipv4_set = 1;
13168         }
13169       else if (unformat (line_input, "group %U",
13170                          unformat_ip4_address, &remote4))
13171         {
13172           grp_set = remote_set = 1;
13173           ipv4_set = 1;
13174         }
13175       else if (unformat (line_input, "group %U %U",
13176                          unformat_ip6_address, &remote6,
13177                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13178         {
13179           grp_set = remote_set = 1;
13180           ipv6_set = 1;
13181         }
13182       else if (unformat (line_input, "group %U",
13183                          unformat_ip6_address, &remote6))
13184         {
13185           grp_set = remote_set = 1;
13186           ipv6_set = 1;
13187         }
13188       else
13189         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
13190         ;
13191       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
13192         ;
13193       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
13194         ;
13195       else if (unformat (line_input, "vni %d", &vni))
13196         vni_set = 1;
13197       else if (unformat (line_input, "next-ip4"))
13198         protocol = 1;
13199       else if (unformat (line_input, "next-ip6"))
13200         protocol = 2;
13201       else if (unformat (line_input, "next-ethernet"))
13202         protocol = 3;
13203       else if (unformat (line_input, "next-nsh"))
13204         protocol = 4;
13205       else
13206         {
13207           errmsg ("parse error '%U'", format_unformat_error, line_input);
13208           return -99;
13209         }
13210     }
13211
13212   if (local_set == 0)
13213     {
13214       errmsg ("tunnel local address not specified");
13215       return -99;
13216     }
13217   if (remote_set == 0)
13218     {
13219       errmsg ("tunnel remote address not specified");
13220       return -99;
13221     }
13222   if (grp_set && mcast_sw_if_index == ~0)
13223     {
13224       errmsg ("tunnel nonexistent multicast device");
13225       return -99;
13226     }
13227   if (ipv4_set && ipv6_set)
13228     {
13229       errmsg ("both IPv4 and IPv6 addresses specified");
13230       return -99;
13231     }
13232
13233   if (vni_set == 0)
13234     {
13235       errmsg ("vni not specified");
13236       return -99;
13237     }
13238
13239   M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
13240
13241
13242   if (ipv6_set)
13243     {
13244       clib_memcpy (&mp->local, &local6, sizeof (local6));
13245       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
13246     }
13247   else
13248     {
13249       clib_memcpy (&mp->local, &local4, sizeof (local4));
13250       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
13251     }
13252
13253   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
13254   mp->encap_vrf_id = ntohl (encap_vrf_id);
13255   mp->decap_vrf_id = ntohl (decap_vrf_id);
13256   mp->protocol = protocol;
13257   mp->vni = ntohl (vni);
13258   mp->is_add = is_add;
13259   mp->is_ipv6 = ipv6_set;
13260
13261   S (mp);
13262   W (ret);
13263   return ret;
13264 }
13265
13266 static void vl_api_vxlan_gpe_tunnel_details_t_handler
13267   (vl_api_vxlan_gpe_tunnel_details_t * mp)
13268 {
13269   vat_main_t *vam = &vat_main;
13270   ip46_address_t local = to_ip46 (mp->is_ipv6, mp->local);
13271   ip46_address_t remote = to_ip46 (mp->is_ipv6, mp->remote);
13272
13273   print (vam->ofp, "%11d%24U%24U%13d%12d%19d%14d%14d",
13274          ntohl (mp->sw_if_index),
13275          format_ip46_address, &local, IP46_TYPE_ANY,
13276          format_ip46_address, &remote, IP46_TYPE_ANY,
13277          ntohl (mp->vni), mp->protocol,
13278          ntohl (mp->mcast_sw_if_index),
13279          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
13280 }
13281
13282
13283 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
13284   (vl_api_vxlan_gpe_tunnel_details_t * mp)
13285 {
13286   vat_main_t *vam = &vat_main;
13287   vat_json_node_t *node = NULL;
13288   struct in_addr ip4;
13289   struct in6_addr ip6;
13290
13291   if (VAT_JSON_ARRAY != vam->json_tree.type)
13292     {
13293       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13294       vat_json_init_array (&vam->json_tree);
13295     }
13296   node = vat_json_array_add (&vam->json_tree);
13297
13298   vat_json_init_object (node);
13299   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13300   if (mp->is_ipv6)
13301     {
13302       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
13303       vat_json_object_add_ip6 (node, "local", ip6);
13304       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
13305       vat_json_object_add_ip6 (node, "remote", ip6);
13306     }
13307   else
13308     {
13309       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
13310       vat_json_object_add_ip4 (node, "local", ip4);
13311       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
13312       vat_json_object_add_ip4 (node, "remote", ip4);
13313     }
13314   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
13315   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
13316   vat_json_object_add_uint (node, "mcast_sw_if_index",
13317                             ntohl (mp->mcast_sw_if_index));
13318   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
13319   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
13320   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
13321 }
13322
13323 static int
13324 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
13325 {
13326   unformat_input_t *i = vam->input;
13327   vl_api_vxlan_gpe_tunnel_dump_t *mp;
13328   vl_api_control_ping_t *mp_ping;
13329   u32 sw_if_index;
13330   u8 sw_if_index_set = 0;
13331   int ret;
13332
13333   /* Parse args required to build the message */
13334   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13335     {
13336       if (unformat (i, "sw_if_index %d", &sw_if_index))
13337         sw_if_index_set = 1;
13338       else
13339         break;
13340     }
13341
13342   if (sw_if_index_set == 0)
13343     {
13344       sw_if_index = ~0;
13345     }
13346
13347   if (!vam->json_output)
13348     {
13349       print (vam->ofp, "%11s%24s%24s%13s%15s%19s%14s%14s",
13350              "sw_if_index", "local", "remote", "vni",
13351              "protocol", "mcast_sw_if_index", "encap_vrf_id", "decap_vrf_id");
13352     }
13353
13354   /* Get list of vxlan-tunnel interfaces */
13355   M (VXLAN_GPE_TUNNEL_DUMP, mp);
13356
13357   mp->sw_if_index = htonl (sw_if_index);
13358
13359   S (mp);
13360
13361   /* Use a control ping for synchronization */
13362   MPING (CONTROL_PING, mp_ping);
13363   S (mp_ping);
13364
13365   W (ret);
13366   return ret;
13367 }
13368
13369 static void vl_api_l2_fib_table_details_t_handler
13370   (vl_api_l2_fib_table_details_t * mp)
13371 {
13372   vat_main_t *vam = &vat_main;
13373
13374   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
13375          "       %d       %d     %d",
13376          ntohl (mp->bd_id), format_ethernet_address, mp->mac,
13377          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
13378          mp->bvi_mac);
13379 }
13380
13381 static void vl_api_l2_fib_table_details_t_handler_json
13382   (vl_api_l2_fib_table_details_t * mp)
13383 {
13384   vat_main_t *vam = &vat_main;
13385   vat_json_node_t *node = NULL;
13386
13387   if (VAT_JSON_ARRAY != vam->json_tree.type)
13388     {
13389       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13390       vat_json_init_array (&vam->json_tree);
13391     }
13392   node = vat_json_array_add (&vam->json_tree);
13393
13394   vat_json_init_object (node);
13395   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
13396   vat_json_object_add_bytes (node, "mac", mp->mac, 6);
13397   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13398   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
13399   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
13400   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
13401 }
13402
13403 static int
13404 api_l2_fib_table_dump (vat_main_t * vam)
13405 {
13406   unformat_input_t *i = vam->input;
13407   vl_api_l2_fib_table_dump_t *mp;
13408   vl_api_control_ping_t *mp_ping;
13409   u32 bd_id;
13410   u8 bd_id_set = 0;
13411   int ret;
13412
13413   /* Parse args required to build the message */
13414   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13415     {
13416       if (unformat (i, "bd_id %d", &bd_id))
13417         bd_id_set = 1;
13418       else
13419         break;
13420     }
13421
13422   if (bd_id_set == 0)
13423     {
13424       errmsg ("missing bridge domain");
13425       return -99;
13426     }
13427
13428   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
13429
13430   /* Get list of l2 fib entries */
13431   M (L2_FIB_TABLE_DUMP, mp);
13432
13433   mp->bd_id = ntohl (bd_id);
13434   S (mp);
13435
13436   /* Use a control ping for synchronization */
13437   MPING (CONTROL_PING, mp_ping);
13438   S (mp_ping);
13439
13440   W (ret);
13441   return ret;
13442 }
13443
13444
13445 static int
13446 api_interface_name_renumber (vat_main_t * vam)
13447 {
13448   unformat_input_t *line_input = vam->input;
13449   vl_api_interface_name_renumber_t *mp;
13450   u32 sw_if_index = ~0;
13451   u32 new_show_dev_instance = ~0;
13452   int ret;
13453
13454   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13455     {
13456       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
13457                     &sw_if_index))
13458         ;
13459       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
13460         ;
13461       else if (unformat (line_input, "new_show_dev_instance %d",
13462                          &new_show_dev_instance))
13463         ;
13464       else
13465         break;
13466     }
13467
13468   if (sw_if_index == ~0)
13469     {
13470       errmsg ("missing interface name or sw_if_index");
13471       return -99;
13472     }
13473
13474   if (new_show_dev_instance == ~0)
13475     {
13476       errmsg ("missing new_show_dev_instance");
13477       return -99;
13478     }
13479
13480   M (INTERFACE_NAME_RENUMBER, mp);
13481
13482   mp->sw_if_index = ntohl (sw_if_index);
13483   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
13484
13485   S (mp);
13486   W (ret);
13487   return ret;
13488 }
13489
13490 static int
13491 api_ip_probe_neighbor (vat_main_t * vam)
13492 {
13493   unformat_input_t *i = vam->input;
13494   vl_api_ip_probe_neighbor_t *mp;
13495   vl_api_address_t dst_adr = { };
13496   u8 int_set = 0;
13497   u8 adr_set = 0;
13498   u32 sw_if_index;
13499   int ret;
13500
13501   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13502     {
13503       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13504         int_set = 1;
13505       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13506         int_set = 1;
13507       else if (unformat (i, "address %U", unformat_vl_api_address, &dst_adr))
13508         adr_set = 1;
13509       else
13510         break;
13511     }
13512
13513   if (int_set == 0)
13514     {
13515       errmsg ("missing interface");
13516       return -99;
13517     }
13518
13519   if (adr_set == 0)
13520     {
13521       errmsg ("missing addresses");
13522       return -99;
13523     }
13524
13525   M (IP_PROBE_NEIGHBOR, mp);
13526
13527   mp->sw_if_index = ntohl (sw_if_index);
13528   clib_memcpy (&mp->dst, &dst_adr, sizeof (dst_adr));
13529
13530   S (mp);
13531   W (ret);
13532   return ret;
13533 }
13534
13535 static int
13536 api_ip_scan_neighbor_enable_disable (vat_main_t * vam)
13537 {
13538   unformat_input_t *i = vam->input;
13539   vl_api_ip_scan_neighbor_enable_disable_t *mp;
13540   u8 mode = IP_SCAN_V46_NEIGHBORS;
13541   u32 interval = 0, time = 0, update = 0, delay = 0, stale = 0;
13542   int ret;
13543
13544   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13545     {
13546       if (unformat (i, "ip4"))
13547         mode = IP_SCAN_V4_NEIGHBORS;
13548       else if (unformat (i, "ip6"))
13549         mode = IP_SCAN_V6_NEIGHBORS;
13550       if (unformat (i, "both"))
13551         mode = IP_SCAN_V46_NEIGHBORS;
13552       else if (unformat (i, "disable"))
13553         mode = IP_SCAN_DISABLED;
13554       else if (unformat (i, "interval %d", &interval))
13555         ;
13556       else if (unformat (i, "max-time %d", &time))
13557         ;
13558       else if (unformat (i, "max-update %d", &update))
13559         ;
13560       else if (unformat (i, "delay %d", &delay))
13561         ;
13562       else if (unformat (i, "stale %d", &stale))
13563         ;
13564       else
13565         break;
13566     }
13567
13568   if (interval > 255)
13569     {
13570       errmsg ("interval cannot exceed 255 minutes.");
13571       return -99;
13572     }
13573   if (time > 255)
13574     {
13575       errmsg ("max-time cannot exceed 255 usec.");
13576       return -99;
13577     }
13578   if (update > 255)
13579     {
13580       errmsg ("max-update cannot exceed 255.");
13581       return -99;
13582     }
13583   if (delay > 255)
13584     {
13585       errmsg ("delay cannot exceed 255 msec.");
13586       return -99;
13587     }
13588   if (stale > 255)
13589     {
13590       errmsg ("stale cannot exceed 255 minutes.");
13591       return -99;
13592     }
13593
13594   M (IP_SCAN_NEIGHBOR_ENABLE_DISABLE, mp);
13595   mp->mode = mode;
13596   mp->scan_interval = interval;
13597   mp->max_proc_time = time;
13598   mp->max_update = update;
13599   mp->scan_int_delay = delay;
13600   mp->stale_threshold = stale;
13601
13602   S (mp);
13603   W (ret);
13604   return ret;
13605 }
13606
13607 static int
13608 api_want_ip4_arp_events (vat_main_t * vam)
13609 {
13610   unformat_input_t *line_input = vam->input;
13611   vl_api_want_ip4_arp_events_t *mp;
13612   ip4_address_t address;
13613   int address_set = 0;
13614   u32 enable_disable = 1;
13615   int ret;
13616
13617   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13618     {
13619       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
13620         address_set = 1;
13621       else if (unformat (line_input, "del"))
13622         enable_disable = 0;
13623       else
13624         break;
13625     }
13626
13627   if (address_set == 0)
13628     {
13629       errmsg ("missing addresses");
13630       return -99;
13631     }
13632
13633   M (WANT_IP4_ARP_EVENTS, mp);
13634   mp->enable_disable = enable_disable;
13635   mp->pid = htonl (getpid ());
13636   clib_memcpy (mp->ip, &address, sizeof (address));
13637
13638   S (mp);
13639   W (ret);
13640   return ret;
13641 }
13642
13643 static int
13644 api_want_ip6_nd_events (vat_main_t * vam)
13645 {
13646   unformat_input_t *line_input = vam->input;
13647   vl_api_want_ip6_nd_events_t *mp;
13648   vl_api_ip6_address_t address;
13649   int address_set = 0;
13650   u32 enable_disable = 1;
13651   int ret;
13652
13653   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13654     {
13655       if (unformat
13656           (line_input, "address %U", unformat_vl_api_ip6_address, &address))
13657         address_set = 1;
13658       else if (unformat (line_input, "del"))
13659         enable_disable = 0;
13660       else
13661         break;
13662     }
13663
13664   if (address_set == 0)
13665     {
13666       errmsg ("missing addresses");
13667       return -99;
13668     }
13669
13670   M (WANT_IP6_ND_EVENTS, mp);
13671   mp->enable_disable = enable_disable;
13672   mp->pid = htonl (getpid ());
13673   clib_memcpy (&mp->ip, &address, sizeof (address));
13674
13675   S (mp);
13676   W (ret);
13677   return ret;
13678 }
13679
13680 static int
13681 api_want_l2_macs_events (vat_main_t * vam)
13682 {
13683   unformat_input_t *line_input = vam->input;
13684   vl_api_want_l2_macs_events_t *mp;
13685   u8 enable_disable = 1;
13686   u32 scan_delay = 0;
13687   u32 max_macs_in_event = 0;
13688   u32 learn_limit = 0;
13689   int ret;
13690
13691   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13692     {
13693       if (unformat (line_input, "learn-limit %d", &learn_limit))
13694         ;
13695       else if (unformat (line_input, "scan-delay %d", &scan_delay))
13696         ;
13697       else if (unformat (line_input, "max-entries %d", &max_macs_in_event))
13698         ;
13699       else if (unformat (line_input, "disable"))
13700         enable_disable = 0;
13701       else
13702         break;
13703     }
13704
13705   M (WANT_L2_MACS_EVENTS, mp);
13706   mp->enable_disable = enable_disable;
13707   mp->pid = htonl (getpid ());
13708   mp->learn_limit = htonl (learn_limit);
13709   mp->scan_delay = (u8) scan_delay;
13710   mp->max_macs_in_event = (u8) (max_macs_in_event / 10);
13711   S (mp);
13712   W (ret);
13713   return ret;
13714 }
13715
13716 static int
13717 api_input_acl_set_interface (vat_main_t * vam)
13718 {
13719   unformat_input_t *i = vam->input;
13720   vl_api_input_acl_set_interface_t *mp;
13721   u32 sw_if_index;
13722   int sw_if_index_set;
13723   u32 ip4_table_index = ~0;
13724   u32 ip6_table_index = ~0;
13725   u32 l2_table_index = ~0;
13726   u8 is_add = 1;
13727   int ret;
13728
13729   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13730     {
13731       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13732         sw_if_index_set = 1;
13733       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13734         sw_if_index_set = 1;
13735       else if (unformat (i, "del"))
13736         is_add = 0;
13737       else if (unformat (i, "ip4-table %d", &ip4_table_index))
13738         ;
13739       else if (unformat (i, "ip6-table %d", &ip6_table_index))
13740         ;
13741       else if (unformat (i, "l2-table %d", &l2_table_index))
13742         ;
13743       else
13744         {
13745           clib_warning ("parse error '%U'", format_unformat_error, i);
13746           return -99;
13747         }
13748     }
13749
13750   if (sw_if_index_set == 0)
13751     {
13752       errmsg ("missing interface name or sw_if_index");
13753       return -99;
13754     }
13755
13756   M (INPUT_ACL_SET_INTERFACE, mp);
13757
13758   mp->sw_if_index = ntohl (sw_if_index);
13759   mp->ip4_table_index = ntohl (ip4_table_index);
13760   mp->ip6_table_index = ntohl (ip6_table_index);
13761   mp->l2_table_index = ntohl (l2_table_index);
13762   mp->is_add = is_add;
13763
13764   S (mp);
13765   W (ret);
13766   return ret;
13767 }
13768
13769 static int
13770 api_output_acl_set_interface (vat_main_t * vam)
13771 {
13772   unformat_input_t *i = vam->input;
13773   vl_api_output_acl_set_interface_t *mp;
13774   u32 sw_if_index;
13775   int sw_if_index_set;
13776   u32 ip4_table_index = ~0;
13777   u32 ip6_table_index = ~0;
13778   u32 l2_table_index = ~0;
13779   u8 is_add = 1;
13780   int ret;
13781
13782   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13783     {
13784       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13785         sw_if_index_set = 1;
13786       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13787         sw_if_index_set = 1;
13788       else if (unformat (i, "del"))
13789         is_add = 0;
13790       else if (unformat (i, "ip4-table %d", &ip4_table_index))
13791         ;
13792       else if (unformat (i, "ip6-table %d", &ip6_table_index))
13793         ;
13794       else if (unformat (i, "l2-table %d", &l2_table_index))
13795         ;
13796       else
13797         {
13798           clib_warning ("parse error '%U'", format_unformat_error, i);
13799           return -99;
13800         }
13801     }
13802
13803   if (sw_if_index_set == 0)
13804     {
13805       errmsg ("missing interface name or sw_if_index");
13806       return -99;
13807     }
13808
13809   M (OUTPUT_ACL_SET_INTERFACE, mp);
13810
13811   mp->sw_if_index = ntohl (sw_if_index);
13812   mp->ip4_table_index = ntohl (ip4_table_index);
13813   mp->ip6_table_index = ntohl (ip6_table_index);
13814   mp->l2_table_index = ntohl (l2_table_index);
13815   mp->is_add = is_add;
13816
13817   S (mp);
13818   W (ret);
13819   return ret;
13820 }
13821
13822 static int
13823 api_ip_address_dump (vat_main_t * vam)
13824 {
13825   unformat_input_t *i = vam->input;
13826   vl_api_ip_address_dump_t *mp;
13827   vl_api_control_ping_t *mp_ping;
13828   u32 sw_if_index = ~0;
13829   u8 sw_if_index_set = 0;
13830   u8 ipv4_set = 0;
13831   u8 ipv6_set = 0;
13832   int ret;
13833
13834   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13835     {
13836       if (unformat (i, "sw_if_index %d", &sw_if_index))
13837         sw_if_index_set = 1;
13838       else
13839         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13840         sw_if_index_set = 1;
13841       else if (unformat (i, "ipv4"))
13842         ipv4_set = 1;
13843       else if (unformat (i, "ipv6"))
13844         ipv6_set = 1;
13845       else
13846         break;
13847     }
13848
13849   if (ipv4_set && ipv6_set)
13850     {
13851       errmsg ("ipv4 and ipv6 flags cannot be both set");
13852       return -99;
13853     }
13854
13855   if ((!ipv4_set) && (!ipv6_set))
13856     {
13857       errmsg ("no ipv4 nor ipv6 flag set");
13858       return -99;
13859     }
13860
13861   if (sw_if_index_set == 0)
13862     {
13863       errmsg ("missing interface name or sw_if_index");
13864       return -99;
13865     }
13866
13867   vam->current_sw_if_index = sw_if_index;
13868   vam->is_ipv6 = ipv6_set;
13869
13870   M (IP_ADDRESS_DUMP, mp);
13871   mp->sw_if_index = ntohl (sw_if_index);
13872   mp->is_ipv6 = ipv6_set;
13873   S (mp);
13874
13875   /* Use a control ping for synchronization */
13876   MPING (CONTROL_PING, mp_ping);
13877   S (mp_ping);
13878
13879   W (ret);
13880   return ret;
13881 }
13882
13883 static int
13884 api_ip_dump (vat_main_t * vam)
13885 {
13886   vl_api_ip_dump_t *mp;
13887   vl_api_control_ping_t *mp_ping;
13888   unformat_input_t *in = vam->input;
13889   int ipv4_set = 0;
13890   int ipv6_set = 0;
13891   int is_ipv6;
13892   int i;
13893   int ret;
13894
13895   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
13896     {
13897       if (unformat (in, "ipv4"))
13898         ipv4_set = 1;
13899       else if (unformat (in, "ipv6"))
13900         ipv6_set = 1;
13901       else
13902         break;
13903     }
13904
13905   if (ipv4_set && ipv6_set)
13906     {
13907       errmsg ("ipv4 and ipv6 flags cannot be both set");
13908       return -99;
13909     }
13910
13911   if ((!ipv4_set) && (!ipv6_set))
13912     {
13913       errmsg ("no ipv4 nor ipv6 flag set");
13914       return -99;
13915     }
13916
13917   is_ipv6 = ipv6_set;
13918   vam->is_ipv6 = is_ipv6;
13919
13920   /* free old data */
13921   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
13922     {
13923       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
13924     }
13925   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
13926
13927   M (IP_DUMP, mp);
13928   mp->is_ipv6 = ipv6_set;
13929   S (mp);
13930
13931   /* Use a control ping for synchronization */
13932   MPING (CONTROL_PING, mp_ping);
13933   S (mp_ping);
13934
13935   W (ret);
13936   return ret;
13937 }
13938
13939 static int
13940 api_ipsec_spd_add_del (vat_main_t * vam)
13941 {
13942   unformat_input_t *i = vam->input;
13943   vl_api_ipsec_spd_add_del_t *mp;
13944   u32 spd_id = ~0;
13945   u8 is_add = 1;
13946   int ret;
13947
13948   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13949     {
13950       if (unformat (i, "spd_id %d", &spd_id))
13951         ;
13952       else if (unformat (i, "del"))
13953         is_add = 0;
13954       else
13955         {
13956           clib_warning ("parse error '%U'", format_unformat_error, i);
13957           return -99;
13958         }
13959     }
13960   if (spd_id == ~0)
13961     {
13962       errmsg ("spd_id must be set");
13963       return -99;
13964     }
13965
13966   M (IPSEC_SPD_ADD_DEL, mp);
13967
13968   mp->spd_id = ntohl (spd_id);
13969   mp->is_add = is_add;
13970
13971   S (mp);
13972   W (ret);
13973   return ret;
13974 }
13975
13976 static int
13977 api_ipsec_interface_add_del_spd (vat_main_t * vam)
13978 {
13979   unformat_input_t *i = vam->input;
13980   vl_api_ipsec_interface_add_del_spd_t *mp;
13981   u32 sw_if_index;
13982   u8 sw_if_index_set = 0;
13983   u32 spd_id = (u32) ~ 0;
13984   u8 is_add = 1;
13985   int ret;
13986
13987   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13988     {
13989       if (unformat (i, "del"))
13990         is_add = 0;
13991       else if (unformat (i, "spd_id %d", &spd_id))
13992         ;
13993       else
13994         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13995         sw_if_index_set = 1;
13996       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13997         sw_if_index_set = 1;
13998       else
13999         {
14000           clib_warning ("parse error '%U'", format_unformat_error, i);
14001           return -99;
14002         }
14003
14004     }
14005
14006   if (spd_id == (u32) ~ 0)
14007     {
14008       errmsg ("spd_id must be set");
14009       return -99;
14010     }
14011
14012   if (sw_if_index_set == 0)
14013     {
14014       errmsg ("missing interface name or sw_if_index");
14015       return -99;
14016     }
14017
14018   M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
14019
14020   mp->spd_id = ntohl (spd_id);
14021   mp->sw_if_index = ntohl (sw_if_index);
14022   mp->is_add = is_add;
14023
14024   S (mp);
14025   W (ret);
14026   return ret;
14027 }
14028
14029 static int
14030 api_ipsec_spd_entry_add_del (vat_main_t * vam)
14031 {
14032   unformat_input_t *i = vam->input;
14033   vl_api_ipsec_spd_entry_add_del_t *mp;
14034   u8 is_add = 1, is_outbound = 0;
14035   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
14036   i32 priority = 0;
14037   u32 rport_start = 0, rport_stop = (u32) ~ 0;
14038   u32 lport_start = 0, lport_stop = (u32) ~ 0;
14039   vl_api_address_t laddr_start = { }, laddr_stop =
14040   {
14041   }, raddr_start =
14042   {
14043   }, raddr_stop =
14044   {
14045   };
14046   int ret;
14047
14048   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14049     {
14050       if (unformat (i, "del"))
14051         is_add = 0;
14052       if (unformat (i, "outbound"))
14053         is_outbound = 1;
14054       if (unformat (i, "inbound"))
14055         is_outbound = 0;
14056       else if (unformat (i, "spd_id %d", &spd_id))
14057         ;
14058       else if (unformat (i, "sa_id %d", &sa_id))
14059         ;
14060       else if (unformat (i, "priority %d", &priority))
14061         ;
14062       else if (unformat (i, "protocol %d", &protocol))
14063         ;
14064       else if (unformat (i, "lport_start %d", &lport_start))
14065         ;
14066       else if (unformat (i, "lport_stop %d", &lport_stop))
14067         ;
14068       else if (unformat (i, "rport_start %d", &rport_start))
14069         ;
14070       else if (unformat (i, "rport_stop %d", &rport_stop))
14071         ;
14072       else if (unformat (i, "laddr_start %U",
14073                          unformat_vl_api_address, &laddr_start))
14074         ;
14075       else if (unformat (i, "laddr_stop %U", unformat_vl_api_address,
14076                          &laddr_stop))
14077         ;
14078       else if (unformat (i, "raddr_start %U", unformat_vl_api_address,
14079                          &raddr_start))
14080         ;
14081       else if (unformat (i, "raddr_stop %U", unformat_vl_api_address,
14082                          &raddr_stop))
14083         ;
14084       else
14085         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
14086         {
14087           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
14088             {
14089               clib_warning ("unsupported action: 'resolve'");
14090               return -99;
14091             }
14092         }
14093       else
14094         {
14095           clib_warning ("parse error '%U'", format_unformat_error, i);
14096           return -99;
14097         }
14098
14099     }
14100
14101   M (IPSEC_SPD_ENTRY_ADD_DEL, mp);
14102
14103   mp->is_add = is_add;
14104
14105   mp->entry.spd_id = ntohl (spd_id);
14106   mp->entry.priority = ntohl (priority);
14107   mp->entry.is_outbound = is_outbound;
14108
14109   clib_memcpy (&mp->entry.remote_address_start, &raddr_start,
14110                sizeof (vl_api_address_t));
14111   clib_memcpy (&mp->entry.remote_address_stop, &raddr_stop,
14112                sizeof (vl_api_address_t));
14113   clib_memcpy (&mp->entry.local_address_start, &laddr_start,
14114                sizeof (vl_api_address_t));
14115   clib_memcpy (&mp->entry.local_address_stop, &laddr_stop,
14116                sizeof (vl_api_address_t));
14117
14118   mp->entry.protocol = (u8) protocol;
14119   mp->entry.local_port_start = ntohs ((u16) lport_start);
14120   mp->entry.local_port_stop = ntohs ((u16) lport_stop);
14121   mp->entry.remote_port_start = ntohs ((u16) rport_start);
14122   mp->entry.remote_port_stop = ntohs ((u16) rport_stop);
14123   mp->entry.policy = (u8) policy;
14124   mp->entry.sa_id = ntohl (sa_id);
14125
14126   S (mp);
14127   W (ret);
14128   return ret;
14129 }
14130
14131 static int
14132 api_ipsec_sad_entry_add_del (vat_main_t * vam)
14133 {
14134   unformat_input_t *i = vam->input;
14135   vl_api_ipsec_sad_entry_add_del_t *mp;
14136   u32 sad_id = 0, spi = 0;
14137   u8 *ck = 0, *ik = 0;
14138   u8 is_add = 1;
14139
14140   vl_api_ipsec_crypto_alg_t crypto_alg = IPSEC_API_CRYPTO_ALG_NONE;
14141   vl_api_ipsec_integ_alg_t integ_alg = IPSEC_API_INTEG_ALG_NONE;
14142   vl_api_ipsec_sad_flags_t flags = IPSEC_API_SAD_FLAG_NONE;
14143   vl_api_ipsec_proto_t protocol = IPSEC_API_PROTO_AH;
14144   vl_api_address_t tun_src, tun_dst;
14145   int ret;
14146
14147   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14148     {
14149       if (unformat (i, "del"))
14150         is_add = 0;
14151       else if (unformat (i, "sad_id %d", &sad_id))
14152         ;
14153       else if (unformat (i, "spi %d", &spi))
14154         ;
14155       else if (unformat (i, "esp"))
14156         protocol = IPSEC_API_PROTO_ESP;
14157       else
14158         if (unformat (i, "tunnel_src %U", unformat_vl_api_address, &tun_src))
14159         {
14160           flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL;
14161           if (ADDRESS_IP6 == tun_src.af)
14162             flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL_V6;
14163         }
14164       else
14165         if (unformat (i, "tunnel_dst %U", unformat_vl_api_address, &tun_dst))
14166         {
14167           flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL;
14168           if (ADDRESS_IP6 == tun_src.af)
14169             flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL_V6;
14170         }
14171       else
14172         if (unformat (i, "crypto_alg %U",
14173                       unformat_ipsec_api_crypto_alg, &crypto_alg))
14174         ;
14175       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
14176         ;
14177       else if (unformat (i, "integ_alg %U",
14178                          unformat_ipsec_api_integ_alg, &integ_alg))
14179         ;
14180       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
14181         ;
14182       else
14183         {
14184           clib_warning ("parse error '%U'", format_unformat_error, i);
14185           return -99;
14186         }
14187
14188     }
14189
14190   M (IPSEC_SAD_ENTRY_ADD_DEL, mp);
14191
14192   mp->is_add = is_add;
14193   mp->entry.sad_id = ntohl (sad_id);
14194   mp->entry.protocol = protocol;
14195   mp->entry.spi = ntohl (spi);
14196   mp->entry.flags = flags;
14197
14198   mp->entry.crypto_algorithm = crypto_alg;
14199   mp->entry.integrity_algorithm = integ_alg;
14200   mp->entry.crypto_key.length = vec_len (ck);
14201   mp->entry.integrity_key.length = vec_len (ik);
14202
14203   if (mp->entry.crypto_key.length > sizeof (mp->entry.crypto_key.data))
14204     mp->entry.crypto_key.length = sizeof (mp->entry.crypto_key.data);
14205
14206   if (mp->entry.integrity_key.length > sizeof (mp->entry.integrity_key.data))
14207     mp->entry.integrity_key.length = sizeof (mp->entry.integrity_key.data);
14208
14209   if (ck)
14210     clib_memcpy (mp->entry.crypto_key.data, ck, mp->entry.crypto_key.length);
14211   if (ik)
14212     clib_memcpy (mp->entry.integrity_key.data, ik,
14213                  mp->entry.integrity_key.length);
14214
14215   if (flags & IPSEC_API_SAD_FLAG_IS_TUNNEL)
14216     {
14217       clib_memcpy (&mp->entry.tunnel_src, &tun_src,
14218                    sizeof (mp->entry.tunnel_src));
14219       clib_memcpy (&mp->entry.tunnel_dst, &tun_dst,
14220                    sizeof (mp->entry.tunnel_dst));
14221     }
14222
14223   S (mp);
14224   W (ret);
14225   return ret;
14226 }
14227
14228 static int
14229 api_ipsec_tunnel_if_add_del (vat_main_t * vam)
14230 {
14231   unformat_input_t *i = vam->input;
14232   vl_api_ipsec_tunnel_if_add_del_t *mp;
14233   u32 local_spi = 0, remote_spi = 0;
14234   u32 crypto_alg = 0, integ_alg = 0;
14235   u8 *lck = NULL, *rck = NULL;
14236   u8 *lik = NULL, *rik = NULL;
14237   vl_api_address_t local_ip = { 0 };
14238   vl_api_address_t remote_ip = { 0 };
14239   f64 before = 0;
14240   u8 is_add = 1;
14241   u8 esn = 0;
14242   u8 anti_replay = 0;
14243   u8 renumber = 0;
14244   u32 instance = ~0;
14245   u32 count = 1, jj;
14246   int ret = -1;
14247
14248   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14249     {
14250       if (unformat (i, "del"))
14251         is_add = 0;
14252       else if (unformat (i, "esn"))
14253         esn = 1;
14254       else if (unformat (i, "anti-replay"))
14255         anti_replay = 1;
14256       else if (unformat (i, "count %d", &count))
14257         ;
14258       else if (unformat (i, "local_spi %d", &local_spi))
14259         ;
14260       else if (unformat (i, "remote_spi %d", &remote_spi))
14261         ;
14262       else
14263         if (unformat (i, "local_ip %U", unformat_vl_api_address, &local_ip))
14264         ;
14265       else
14266         if (unformat (i, "remote_ip %U", unformat_vl_api_address, &remote_ip))
14267         ;
14268       else if (unformat (i, "local_crypto_key %U", unformat_hex_string, &lck))
14269         ;
14270       else
14271         if (unformat (i, "remote_crypto_key %U", unformat_hex_string, &rck))
14272         ;
14273       else if (unformat (i, "local_integ_key %U", unformat_hex_string, &lik))
14274         ;
14275       else if (unformat (i, "remote_integ_key %U", unformat_hex_string, &rik))
14276         ;
14277       else
14278         if (unformat
14279             (i, "crypto_alg %U", unformat_ipsec_api_crypto_alg, &crypto_alg))
14280         {
14281           if (crypto_alg >= IPSEC_CRYPTO_N_ALG)
14282             {
14283               errmsg ("unsupported crypto-alg: '%U'\n",
14284                       format_ipsec_crypto_alg, crypto_alg);
14285               return -99;
14286             }
14287         }
14288       else
14289         if (unformat
14290             (i, "integ_alg %U", unformat_ipsec_api_integ_alg, &integ_alg))
14291         {
14292           if (integ_alg >= IPSEC_INTEG_N_ALG)
14293             {
14294               errmsg ("unsupported integ-alg: '%U'\n",
14295                       format_ipsec_integ_alg, integ_alg);
14296               return -99;
14297             }
14298         }
14299       else if (unformat (i, "instance %u", &instance))
14300         renumber = 1;
14301       else
14302         {
14303           errmsg ("parse error '%U'\n", format_unformat_error, i);
14304           return -99;
14305         }
14306     }
14307
14308   if (count > 1)
14309     {
14310       /* Turn on async mode */
14311       vam->async_mode = 1;
14312       vam->async_errors = 0;
14313       before = vat_time_now (vam);
14314     }
14315
14316   for (jj = 0; jj < count; jj++)
14317     {
14318       M (IPSEC_TUNNEL_IF_ADD_DEL, mp);
14319
14320       mp->is_add = is_add;
14321       mp->esn = esn;
14322       mp->anti_replay = anti_replay;
14323
14324       if (jj > 0)
14325         increment_address (&remote_ip);
14326
14327       clib_memcpy (&mp->local_ip, &local_ip, sizeof (local_ip));
14328       clib_memcpy (&mp->remote_ip, &remote_ip, sizeof (remote_ip));
14329
14330       mp->local_spi = htonl (local_spi + jj);
14331       mp->remote_spi = htonl (remote_spi + jj);
14332       mp->crypto_alg = (u8) crypto_alg;
14333
14334       mp->local_crypto_key_len = 0;
14335       if (lck)
14336         {
14337           mp->local_crypto_key_len = vec_len (lck);
14338           if (mp->local_crypto_key_len > sizeof (mp->local_crypto_key))
14339             mp->local_crypto_key_len = sizeof (mp->local_crypto_key);
14340           clib_memcpy (mp->local_crypto_key, lck, mp->local_crypto_key_len);
14341         }
14342
14343       mp->remote_crypto_key_len = 0;
14344       if (rck)
14345         {
14346           mp->remote_crypto_key_len = vec_len (rck);
14347           if (mp->remote_crypto_key_len > sizeof (mp->remote_crypto_key))
14348             mp->remote_crypto_key_len = sizeof (mp->remote_crypto_key);
14349           clib_memcpy (mp->remote_crypto_key, rck, mp->remote_crypto_key_len);
14350         }
14351
14352       mp->integ_alg = (u8) integ_alg;
14353
14354       mp->local_integ_key_len = 0;
14355       if (lik)
14356         {
14357           mp->local_integ_key_len = vec_len (lik);
14358           if (mp->local_integ_key_len > sizeof (mp->local_integ_key))
14359             mp->local_integ_key_len = sizeof (mp->local_integ_key);
14360           clib_memcpy (mp->local_integ_key, lik, mp->local_integ_key_len);
14361         }
14362
14363       mp->remote_integ_key_len = 0;
14364       if (rik)
14365         {
14366           mp->remote_integ_key_len = vec_len (rik);
14367           if (mp->remote_integ_key_len > sizeof (mp->remote_integ_key))
14368             mp->remote_integ_key_len = sizeof (mp->remote_integ_key);
14369           clib_memcpy (mp->remote_integ_key, rik, mp->remote_integ_key_len);
14370         }
14371
14372       if (renumber)
14373         {
14374           mp->renumber = renumber;
14375           mp->show_instance = ntohl (instance);
14376         }
14377       S (mp);
14378     }
14379
14380   /* When testing multiple add/del ops, use a control-ping to sync */
14381   if (count > 1)
14382     {
14383       vl_api_control_ping_t *mp_ping;
14384       f64 after;
14385       f64 timeout;
14386
14387       /* Shut off async mode */
14388       vam->async_mode = 0;
14389
14390       MPING (CONTROL_PING, mp_ping);
14391       S (mp_ping);
14392
14393       timeout = vat_time_now (vam) + 1.0;
14394       while (vat_time_now (vam) < timeout)
14395         if (vam->result_ready == 1)
14396           goto out;
14397       vam->retval = -99;
14398
14399     out:
14400       if (vam->retval == -99)
14401         errmsg ("timeout");
14402
14403       if (vam->async_errors > 0)
14404         {
14405           errmsg ("%d asynchronous errors", vam->async_errors);
14406           vam->retval = -98;
14407         }
14408       vam->async_errors = 0;
14409       after = vat_time_now (vam);
14410
14411       /* slim chance, but we might have eaten SIGTERM on the first iteration */
14412       if (jj > 0)
14413         count = jj;
14414
14415       print (vam->ofp, "%d tunnels in %.6f secs, %.2f tunnels/sec",
14416              count, after - before, count / (after - before));
14417     }
14418   else
14419     {
14420       /* Wait for a reply... */
14421       W (ret);
14422       return ret;
14423     }
14424
14425   return ret;
14426 }
14427
14428 static void
14429 vl_api_ipsec_sa_details_t_handler (vl_api_ipsec_sa_details_t * mp)
14430 {
14431   vat_main_t *vam = &vat_main;
14432
14433   print (vam->ofp, "sa_id %u sw_if_index %u spi %u proto %u crypto_alg %u "
14434          "crypto_key %U integ_alg %u integ_key %U flags %x "
14435          "tunnel_src_addr %U tunnel_dst_addr %U "
14436          "salt %u seq_outbound %lu last_seq_inbound %lu "
14437          "replay_window %lu\n",
14438          ntohl (mp->entry.sad_id),
14439          ntohl (mp->sw_if_index),
14440          ntohl (mp->entry.spi),
14441          ntohl (mp->entry.protocol),
14442          ntohl (mp->entry.crypto_algorithm),
14443          format_hex_bytes, mp->entry.crypto_key.data,
14444          mp->entry.crypto_key.length, ntohl (mp->entry.integrity_algorithm),
14445          format_hex_bytes, mp->entry.integrity_key.data,
14446          mp->entry.integrity_key.length, ntohl (mp->entry.flags),
14447          format_vl_api_address, &mp->entry.tunnel_src, format_vl_api_address,
14448          &mp->entry.tunnel_dst, ntohl (mp->salt),
14449          clib_net_to_host_u64 (mp->seq_outbound),
14450          clib_net_to_host_u64 (mp->last_seq_inbound),
14451          clib_net_to_host_u64 (mp->replay_window));
14452 }
14453
14454 #define vl_api_ipsec_sa_details_t_endian vl_noop_handler
14455 #define vl_api_ipsec_sa_details_t_print vl_noop_handler
14456
14457 static void vl_api_ipsec_sa_details_t_handler_json
14458   (vl_api_ipsec_sa_details_t * mp)
14459 {
14460   vat_main_t *vam = &vat_main;
14461   vat_json_node_t *node = NULL;
14462   vl_api_ipsec_sad_flags_t flags;
14463
14464   if (VAT_JSON_ARRAY != vam->json_tree.type)
14465     {
14466       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14467       vat_json_init_array (&vam->json_tree);
14468     }
14469   node = vat_json_array_add (&vam->json_tree);
14470
14471   vat_json_init_object (node);
14472   vat_json_object_add_uint (node, "sa_id", ntohl (mp->entry.sad_id));
14473   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
14474   vat_json_object_add_uint (node, "spi", ntohl (mp->entry.spi));
14475   vat_json_object_add_uint (node, "proto", ntohl (mp->entry.protocol));
14476   vat_json_object_add_uint (node, "crypto_alg",
14477                             ntohl (mp->entry.crypto_algorithm));
14478   vat_json_object_add_uint (node, "integ_alg",
14479                             ntohl (mp->entry.integrity_algorithm));
14480   flags = ntohl (mp->entry.flags);
14481   vat_json_object_add_uint (node, "use_esn",
14482                             ! !(flags & IPSEC_API_SAD_FLAG_USE_ESN));
14483   vat_json_object_add_uint (node, "use_anti_replay",
14484                             ! !(flags & IPSEC_API_SAD_FLAG_USE_ANTI_REPLAY));
14485   vat_json_object_add_uint (node, "is_tunnel",
14486                             ! !(flags & IPSEC_API_SAD_FLAG_IS_TUNNEL));
14487   vat_json_object_add_uint (node, "is_tunnel_ip6",
14488                             ! !(flags & IPSEC_API_SAD_FLAG_IS_TUNNEL_V6));
14489   vat_json_object_add_uint (node, "udp_encap",
14490                             ! !(flags & IPSEC_API_SAD_FLAG_UDP_ENCAP));
14491   vat_json_object_add_bytes (node, "crypto_key", mp->entry.crypto_key.data,
14492                              mp->entry.crypto_key.length);
14493   vat_json_object_add_bytes (node, "integ_key", mp->entry.integrity_key.data,
14494                              mp->entry.integrity_key.length);
14495   vat_json_object_add_address (node, "src", &mp->entry.tunnel_src);
14496   vat_json_object_add_address (node, "dst", &mp->entry.tunnel_dst);
14497   vat_json_object_add_uint (node, "replay_window",
14498                             clib_net_to_host_u64 (mp->replay_window));
14499 }
14500
14501 static int
14502 api_ipsec_sa_dump (vat_main_t * vam)
14503 {
14504   unformat_input_t *i = vam->input;
14505   vl_api_ipsec_sa_dump_t *mp;
14506   vl_api_control_ping_t *mp_ping;
14507   u32 sa_id = ~0;
14508   int ret;
14509
14510   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14511     {
14512       if (unformat (i, "sa_id %d", &sa_id))
14513         ;
14514       else
14515         {
14516           clib_warning ("parse error '%U'", format_unformat_error, i);
14517           return -99;
14518         }
14519     }
14520
14521   M (IPSEC_SA_DUMP, mp);
14522
14523   mp->sa_id = ntohl (sa_id);
14524
14525   S (mp);
14526
14527   /* Use a control ping for synchronization */
14528   M (CONTROL_PING, mp_ping);
14529   S (mp_ping);
14530
14531   W (ret);
14532   return ret;
14533 }
14534
14535 static int
14536 api_ipsec_tunnel_if_set_sa (vat_main_t * vam)
14537 {
14538   unformat_input_t *i = vam->input;
14539   vl_api_ipsec_tunnel_if_set_sa_t *mp;
14540   u32 sw_if_index = ~0;
14541   u32 sa_id = ~0;
14542   u8 is_outbound = (u8) ~ 0;
14543   int ret;
14544
14545   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14546     {
14547       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14548         ;
14549       else if (unformat (i, "sa_id %d", &sa_id))
14550         ;
14551       else if (unformat (i, "outbound"))
14552         is_outbound = 1;
14553       else if (unformat (i, "inbound"))
14554         is_outbound = 0;
14555       else
14556         {
14557           clib_warning ("parse error '%U'", format_unformat_error, i);
14558           return -99;
14559         }
14560     }
14561
14562   if (sw_if_index == ~0)
14563     {
14564       errmsg ("interface must be specified");
14565       return -99;
14566     }
14567
14568   if (sa_id == ~0)
14569     {
14570       errmsg ("SA ID must be specified");
14571       return -99;
14572     }
14573
14574   M (IPSEC_TUNNEL_IF_SET_SA, mp);
14575
14576   mp->sw_if_index = htonl (sw_if_index);
14577   mp->sa_id = htonl (sa_id);
14578   mp->is_outbound = is_outbound;
14579
14580   S (mp);
14581   W (ret);
14582
14583   return ret;
14584 }
14585
14586 static int
14587 api_get_first_msg_id (vat_main_t * vam)
14588 {
14589   vl_api_get_first_msg_id_t *mp;
14590   unformat_input_t *i = vam->input;
14591   u8 *name;
14592   u8 name_set = 0;
14593   int ret;
14594
14595   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14596     {
14597       if (unformat (i, "client %s", &name))
14598         name_set = 1;
14599       else
14600         break;
14601     }
14602
14603   if (name_set == 0)
14604     {
14605       errmsg ("missing client name");
14606       return -99;
14607     }
14608   vec_add1 (name, 0);
14609
14610   if (vec_len (name) > 63)
14611     {
14612       errmsg ("client name too long");
14613       return -99;
14614     }
14615
14616   M (GET_FIRST_MSG_ID, mp);
14617   clib_memcpy (mp->name, name, vec_len (name));
14618   S (mp);
14619   W (ret);
14620   return ret;
14621 }
14622
14623 static int
14624 api_cop_interface_enable_disable (vat_main_t * vam)
14625 {
14626   unformat_input_t *line_input = vam->input;
14627   vl_api_cop_interface_enable_disable_t *mp;
14628   u32 sw_if_index = ~0;
14629   u8 enable_disable = 1;
14630   int ret;
14631
14632   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14633     {
14634       if (unformat (line_input, "disable"))
14635         enable_disable = 0;
14636       if (unformat (line_input, "enable"))
14637         enable_disable = 1;
14638       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
14639                          vam, &sw_if_index))
14640         ;
14641       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
14642         ;
14643       else
14644         break;
14645     }
14646
14647   if (sw_if_index == ~0)
14648     {
14649       errmsg ("missing interface name or sw_if_index");
14650       return -99;
14651     }
14652
14653   /* Construct the API message */
14654   M (COP_INTERFACE_ENABLE_DISABLE, mp);
14655   mp->sw_if_index = ntohl (sw_if_index);
14656   mp->enable_disable = enable_disable;
14657
14658   /* send it... */
14659   S (mp);
14660   /* Wait for the reply */
14661   W (ret);
14662   return ret;
14663 }
14664
14665 static int
14666 api_cop_whitelist_enable_disable (vat_main_t * vam)
14667 {
14668   unformat_input_t *line_input = vam->input;
14669   vl_api_cop_whitelist_enable_disable_t *mp;
14670   u32 sw_if_index = ~0;
14671   u8 ip4 = 0, ip6 = 0, default_cop = 0;
14672   u32 fib_id = 0;
14673   int ret;
14674
14675   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14676     {
14677       if (unformat (line_input, "ip4"))
14678         ip4 = 1;
14679       else if (unformat (line_input, "ip6"))
14680         ip6 = 1;
14681       else if (unformat (line_input, "default"))
14682         default_cop = 1;
14683       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
14684                          vam, &sw_if_index))
14685         ;
14686       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
14687         ;
14688       else if (unformat (line_input, "fib-id %d", &fib_id))
14689         ;
14690       else
14691         break;
14692     }
14693
14694   if (sw_if_index == ~0)
14695     {
14696       errmsg ("missing interface name or sw_if_index");
14697       return -99;
14698     }
14699
14700   /* Construct the API message */
14701   M (COP_WHITELIST_ENABLE_DISABLE, mp);
14702   mp->sw_if_index = ntohl (sw_if_index);
14703   mp->fib_id = ntohl (fib_id);
14704   mp->ip4 = ip4;
14705   mp->ip6 = ip6;
14706   mp->default_cop = default_cop;
14707
14708   /* send it... */
14709   S (mp);
14710   /* Wait for the reply */
14711   W (ret);
14712   return ret;
14713 }
14714
14715 static int
14716 api_get_node_graph (vat_main_t * vam)
14717 {
14718   vl_api_get_node_graph_t *mp;
14719   int ret;
14720
14721   M (GET_NODE_GRAPH, mp);
14722
14723   /* send it... */
14724   S (mp);
14725   /* Wait for the reply */
14726   W (ret);
14727   return ret;
14728 }
14729
14730 /* *INDENT-OFF* */
14731 /** Used for parsing LISP eids */
14732 typedef CLIB_PACKED(struct{
14733   u8 addr[16];   /**< eid address */
14734   u32 len;       /**< prefix length if IP */
14735   u8 type;      /**< type of eid */
14736 }) lisp_eid_vat_t;
14737 /* *INDENT-ON* */
14738
14739 static uword
14740 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
14741 {
14742   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
14743
14744   clib_memset (a, 0, sizeof (a[0]));
14745
14746   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
14747     {
14748       a->type = 0;              /* ipv4 type */
14749     }
14750   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
14751     {
14752       a->type = 1;              /* ipv6 type */
14753     }
14754   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
14755     {
14756       a->type = 2;              /* mac type */
14757     }
14758   else if (unformat (input, "%U", unformat_nsh_address, a->addr))
14759     {
14760       a->type = 3;              /* NSH type */
14761       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) a->addr;
14762       nsh->spi = clib_host_to_net_u32 (nsh->spi);
14763     }
14764   else
14765     {
14766       return 0;
14767     }
14768
14769   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
14770     {
14771       return 0;
14772     }
14773
14774   return 1;
14775 }
14776
14777 static int
14778 lisp_eid_size_vat (u8 type)
14779 {
14780   switch (type)
14781     {
14782     case 0:
14783       return 4;
14784     case 1:
14785       return 16;
14786     case 2:
14787       return 6;
14788     case 3:
14789       return 5;
14790     }
14791   return 0;
14792 }
14793
14794 static void
14795 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
14796 {
14797   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
14798 }
14799
14800 static int
14801 api_one_add_del_locator_set (vat_main_t * vam)
14802 {
14803   unformat_input_t *input = vam->input;
14804   vl_api_one_add_del_locator_set_t *mp;
14805   u8 is_add = 1;
14806   u8 *locator_set_name = NULL;
14807   u8 locator_set_name_set = 0;
14808   vl_api_local_locator_t locator, *locators = 0;
14809   u32 sw_if_index, priority, weight;
14810   u32 data_len = 0;
14811
14812   int ret;
14813   /* Parse args required to build the message */
14814   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14815     {
14816       if (unformat (input, "del"))
14817         {
14818           is_add = 0;
14819         }
14820       else if (unformat (input, "locator-set %s", &locator_set_name))
14821         {
14822           locator_set_name_set = 1;
14823         }
14824       else if (unformat (input, "sw_if_index %u p %u w %u",
14825                          &sw_if_index, &priority, &weight))
14826         {
14827           locator.sw_if_index = htonl (sw_if_index);
14828           locator.priority = priority;
14829           locator.weight = weight;
14830           vec_add1 (locators, locator);
14831         }
14832       else
14833         if (unformat
14834             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
14835              &sw_if_index, &priority, &weight))
14836         {
14837           locator.sw_if_index = htonl (sw_if_index);
14838           locator.priority = priority;
14839           locator.weight = weight;
14840           vec_add1 (locators, locator);
14841         }
14842       else
14843         break;
14844     }
14845
14846   if (locator_set_name_set == 0)
14847     {
14848       errmsg ("missing locator-set name");
14849       vec_free (locators);
14850       return -99;
14851     }
14852
14853   if (vec_len (locator_set_name) > 64)
14854     {
14855       errmsg ("locator-set name too long");
14856       vec_free (locator_set_name);
14857       vec_free (locators);
14858       return -99;
14859     }
14860   vec_add1 (locator_set_name, 0);
14861
14862   data_len = sizeof (vl_api_local_locator_t) * vec_len (locators);
14863
14864   /* Construct the API message */
14865   M2 (ONE_ADD_DEL_LOCATOR_SET, mp, data_len);
14866
14867   mp->is_add = is_add;
14868   clib_memcpy (mp->locator_set_name, locator_set_name,
14869                vec_len (locator_set_name));
14870   vec_free (locator_set_name);
14871
14872   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
14873   if (locators)
14874     clib_memcpy (mp->locators, locators, data_len);
14875   vec_free (locators);
14876
14877   /* send it... */
14878   S (mp);
14879
14880   /* Wait for a reply... */
14881   W (ret);
14882   return ret;
14883 }
14884
14885 #define api_lisp_add_del_locator_set api_one_add_del_locator_set
14886
14887 static int
14888 api_one_add_del_locator (vat_main_t * vam)
14889 {
14890   unformat_input_t *input = vam->input;
14891   vl_api_one_add_del_locator_t *mp;
14892   u32 tmp_if_index = ~0;
14893   u32 sw_if_index = ~0;
14894   u8 sw_if_index_set = 0;
14895   u8 sw_if_index_if_name_set = 0;
14896   u32 priority = ~0;
14897   u8 priority_set = 0;
14898   u32 weight = ~0;
14899   u8 weight_set = 0;
14900   u8 is_add = 1;
14901   u8 *locator_set_name = NULL;
14902   u8 locator_set_name_set = 0;
14903   int ret;
14904
14905   /* Parse args required to build the message */
14906   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14907     {
14908       if (unformat (input, "del"))
14909         {
14910           is_add = 0;
14911         }
14912       else if (unformat (input, "locator-set %s", &locator_set_name))
14913         {
14914           locator_set_name_set = 1;
14915         }
14916       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
14917                          &tmp_if_index))
14918         {
14919           sw_if_index_if_name_set = 1;
14920           sw_if_index = tmp_if_index;
14921         }
14922       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
14923         {
14924           sw_if_index_set = 1;
14925           sw_if_index = tmp_if_index;
14926         }
14927       else if (unformat (input, "p %d", &priority))
14928         {
14929           priority_set = 1;
14930         }
14931       else if (unformat (input, "w %d", &weight))
14932         {
14933           weight_set = 1;
14934         }
14935       else
14936         break;
14937     }
14938
14939   if (locator_set_name_set == 0)
14940     {
14941       errmsg ("missing locator-set name");
14942       return -99;
14943     }
14944
14945   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
14946     {
14947       errmsg ("missing sw_if_index");
14948       vec_free (locator_set_name);
14949       return -99;
14950     }
14951
14952   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
14953     {
14954       errmsg ("cannot use both params interface name and sw_if_index");
14955       vec_free (locator_set_name);
14956       return -99;
14957     }
14958
14959   if (priority_set == 0)
14960     {
14961       errmsg ("missing locator-set priority");
14962       vec_free (locator_set_name);
14963       return -99;
14964     }
14965
14966   if (weight_set == 0)
14967     {
14968       errmsg ("missing locator-set weight");
14969       vec_free (locator_set_name);
14970       return -99;
14971     }
14972
14973   if (vec_len (locator_set_name) > 64)
14974     {
14975       errmsg ("locator-set name too long");
14976       vec_free (locator_set_name);
14977       return -99;
14978     }
14979   vec_add1 (locator_set_name, 0);
14980
14981   /* Construct the API message */
14982   M (ONE_ADD_DEL_LOCATOR, mp);
14983
14984   mp->is_add = is_add;
14985   mp->sw_if_index = ntohl (sw_if_index);
14986   mp->priority = priority;
14987   mp->weight = weight;
14988   clib_memcpy (mp->locator_set_name, locator_set_name,
14989                vec_len (locator_set_name));
14990   vec_free (locator_set_name);
14991
14992   /* send it... */
14993   S (mp);
14994
14995   /* Wait for a reply... */
14996   W (ret);
14997   return ret;
14998 }
14999
15000 #define api_lisp_add_del_locator api_one_add_del_locator
15001
15002 uword
15003 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
15004 {
15005   u32 *key_id = va_arg (*args, u32 *);
15006   u8 *s = 0;
15007
15008   if (unformat (input, "%s", &s))
15009     {
15010       if (!strcmp ((char *) s, "sha1"))
15011         key_id[0] = HMAC_SHA_1_96;
15012       else if (!strcmp ((char *) s, "sha256"))
15013         key_id[0] = HMAC_SHA_256_128;
15014       else
15015         {
15016           clib_warning ("invalid key_id: '%s'", s);
15017           key_id[0] = HMAC_NO_KEY;
15018         }
15019     }
15020   else
15021     return 0;
15022
15023   vec_free (s);
15024   return 1;
15025 }
15026
15027 static int
15028 api_one_add_del_local_eid (vat_main_t * vam)
15029 {
15030   unformat_input_t *input = vam->input;
15031   vl_api_one_add_del_local_eid_t *mp;
15032   u8 is_add = 1;
15033   u8 eid_set = 0;
15034   lisp_eid_vat_t _eid, *eid = &_eid;
15035   u8 *locator_set_name = 0;
15036   u8 locator_set_name_set = 0;
15037   u32 vni = 0;
15038   u16 key_id = 0;
15039   u8 *key = 0;
15040   int ret;
15041
15042   /* Parse args required to build the message */
15043   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15044     {
15045       if (unformat (input, "del"))
15046         {
15047           is_add = 0;
15048         }
15049       else if (unformat (input, "vni %d", &vni))
15050         {
15051           ;
15052         }
15053       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
15054         {
15055           eid_set = 1;
15056         }
15057       else if (unformat (input, "locator-set %s", &locator_set_name))
15058         {
15059           locator_set_name_set = 1;
15060         }
15061       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
15062         ;
15063       else if (unformat (input, "secret-key %_%v%_", &key))
15064         ;
15065       else
15066         break;
15067     }
15068
15069   if (locator_set_name_set == 0)
15070     {
15071       errmsg ("missing locator-set name");
15072       return -99;
15073     }
15074
15075   if (0 == eid_set)
15076     {
15077       errmsg ("EID address not set!");
15078       vec_free (locator_set_name);
15079       return -99;
15080     }
15081
15082   if (key && (0 == key_id))
15083     {
15084       errmsg ("invalid key_id!");
15085       return -99;
15086     }
15087
15088   if (vec_len (key) > 64)
15089     {
15090       errmsg ("key too long");
15091       vec_free (key);
15092       return -99;
15093     }
15094
15095   if (vec_len (locator_set_name) > 64)
15096     {
15097       errmsg ("locator-set name too long");
15098       vec_free (locator_set_name);
15099       return -99;
15100     }
15101   vec_add1 (locator_set_name, 0);
15102
15103   /* Construct the API message */
15104   M (ONE_ADD_DEL_LOCAL_EID, mp);
15105
15106   mp->is_add = is_add;
15107   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
15108   mp->eid_type = eid->type;
15109   mp->prefix_len = eid->len;
15110   mp->vni = clib_host_to_net_u32 (vni);
15111   mp->key_id = clib_host_to_net_u16 (key_id);
15112   clib_memcpy (mp->locator_set_name, locator_set_name,
15113                vec_len (locator_set_name));
15114   clib_memcpy (mp->key, key, vec_len (key));
15115
15116   vec_free (locator_set_name);
15117   vec_free (key);
15118
15119   /* send it... */
15120   S (mp);
15121
15122   /* Wait for a reply... */
15123   W (ret);
15124   return ret;
15125 }
15126
15127 #define api_lisp_add_del_local_eid api_one_add_del_local_eid
15128
15129 static int
15130 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
15131 {
15132   u32 dp_table = 0, vni = 0;;
15133   unformat_input_t *input = vam->input;
15134   vl_api_gpe_add_del_fwd_entry_t *mp;
15135   u8 is_add = 1;
15136   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
15137   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
15138   u8 rmt_eid_set = 0, lcl_eid_set = 0;
15139   u32 action = ~0, w;
15140   ip4_address_t rmt_rloc4, lcl_rloc4;
15141   ip6_address_t rmt_rloc6, lcl_rloc6;
15142   vl_api_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
15143   int ret;
15144
15145   clib_memset (&rloc, 0, sizeof (rloc));
15146
15147   /* Parse args required to build the message */
15148   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15149     {
15150       if (unformat (input, "del"))
15151         is_add = 0;
15152       else if (unformat (input, "add"))
15153         is_add = 1;
15154       else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
15155         {
15156           rmt_eid_set = 1;
15157         }
15158       else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
15159         {
15160           lcl_eid_set = 1;
15161         }
15162       else if (unformat (input, "vrf %d", &dp_table))
15163         ;
15164       else if (unformat (input, "bd %d", &dp_table))
15165         ;
15166       else if (unformat (input, "vni %d", &vni))
15167         ;
15168       else if (unformat (input, "w %d", &w))
15169         {
15170           if (!curr_rloc)
15171             {
15172               errmsg ("No RLOC configured for setting priority/weight!");
15173               return -99;
15174             }
15175           curr_rloc->weight = w;
15176         }
15177       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
15178                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
15179         {
15180           rloc.is_ip4 = 1;
15181
15182           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
15183           rloc.weight = 0;
15184           vec_add1 (lcl_locs, rloc);
15185
15186           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
15187           vec_add1 (rmt_locs, rloc);
15188           /* weight saved in rmt loc */
15189           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
15190         }
15191       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
15192                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
15193         {
15194           rloc.is_ip4 = 0;
15195           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
15196           rloc.weight = 0;
15197           vec_add1 (lcl_locs, rloc);
15198
15199           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
15200           vec_add1 (rmt_locs, rloc);
15201           /* weight saved in rmt loc */
15202           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
15203         }
15204       else if (unformat (input, "action %d", &action))
15205         {
15206           ;
15207         }
15208       else
15209         {
15210           clib_warning ("parse error '%U'", format_unformat_error, input);
15211           return -99;
15212         }
15213     }
15214
15215   if (!rmt_eid_set)
15216     {
15217       errmsg ("remote eid addresses not set");
15218       return -99;
15219     }
15220
15221   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
15222     {
15223       errmsg ("eid types don't match");
15224       return -99;
15225     }
15226
15227   if (0 == rmt_locs && (u32) ~ 0 == action)
15228     {
15229       errmsg ("action not set for negative mapping");
15230       return -99;
15231     }
15232
15233   /* Construct the API message */
15234   M2 (GPE_ADD_DEL_FWD_ENTRY, mp,
15235       sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs) * 2);
15236
15237   mp->is_add = is_add;
15238   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
15239   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
15240   mp->eid_type = rmt_eid->type;
15241   mp->dp_table = clib_host_to_net_u32 (dp_table);
15242   mp->vni = clib_host_to_net_u32 (vni);
15243   mp->rmt_len = rmt_eid->len;
15244   mp->lcl_len = lcl_eid->len;
15245   mp->action = action;
15246
15247   if (0 != rmt_locs && 0 != lcl_locs)
15248     {
15249       mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
15250       clib_memcpy (mp->locs, lcl_locs,
15251                    (sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs)));
15252
15253       u32 offset = sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs);
15254       clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
15255                    (sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs)));
15256     }
15257   vec_free (lcl_locs);
15258   vec_free (rmt_locs);
15259
15260   /* send it... */
15261   S (mp);
15262
15263   /* Wait for a reply... */
15264   W (ret);
15265   return ret;
15266 }
15267
15268 static int
15269 api_one_add_del_map_server (vat_main_t * vam)
15270 {
15271   unformat_input_t *input = vam->input;
15272   vl_api_one_add_del_map_server_t *mp;
15273   u8 is_add = 1;
15274   u8 ipv4_set = 0;
15275   u8 ipv6_set = 0;
15276   ip4_address_t ipv4;
15277   ip6_address_t ipv6;
15278   int ret;
15279
15280   /* Parse args required to build the message */
15281   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15282     {
15283       if (unformat (input, "del"))
15284         {
15285           is_add = 0;
15286         }
15287       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
15288         {
15289           ipv4_set = 1;
15290         }
15291       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
15292         {
15293           ipv6_set = 1;
15294         }
15295       else
15296         break;
15297     }
15298
15299   if (ipv4_set && ipv6_set)
15300     {
15301       errmsg ("both eid v4 and v6 addresses set");
15302       return -99;
15303     }
15304
15305   if (!ipv4_set && !ipv6_set)
15306     {
15307       errmsg ("eid addresses not set");
15308       return -99;
15309     }
15310
15311   /* Construct the API message */
15312   M (ONE_ADD_DEL_MAP_SERVER, mp);
15313
15314   mp->is_add = is_add;
15315   if (ipv6_set)
15316     {
15317       mp->is_ipv6 = 1;
15318       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
15319     }
15320   else
15321     {
15322       mp->is_ipv6 = 0;
15323       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
15324     }
15325
15326   /* send it... */
15327   S (mp);
15328
15329   /* Wait for a reply... */
15330   W (ret);
15331   return ret;
15332 }
15333
15334 #define api_lisp_add_del_map_server api_one_add_del_map_server
15335
15336 static int
15337 api_one_add_del_map_resolver (vat_main_t * vam)
15338 {
15339   unformat_input_t *input = vam->input;
15340   vl_api_one_add_del_map_resolver_t *mp;
15341   u8 is_add = 1;
15342   u8 ipv4_set = 0;
15343   u8 ipv6_set = 0;
15344   ip4_address_t ipv4;
15345   ip6_address_t ipv6;
15346   int ret;
15347
15348   /* Parse args required to build the message */
15349   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15350     {
15351       if (unformat (input, "del"))
15352         {
15353           is_add = 0;
15354         }
15355       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
15356         {
15357           ipv4_set = 1;
15358         }
15359       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
15360         {
15361           ipv6_set = 1;
15362         }
15363       else
15364         break;
15365     }
15366
15367   if (ipv4_set && ipv6_set)
15368     {
15369       errmsg ("both eid v4 and v6 addresses set");
15370       return -99;
15371     }
15372
15373   if (!ipv4_set && !ipv6_set)
15374     {
15375       errmsg ("eid addresses not set");
15376       return -99;
15377     }
15378
15379   /* Construct the API message */
15380   M (ONE_ADD_DEL_MAP_RESOLVER, mp);
15381
15382   mp->is_add = is_add;
15383   if (ipv6_set)
15384     {
15385       mp->is_ipv6 = 1;
15386       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
15387     }
15388   else
15389     {
15390       mp->is_ipv6 = 0;
15391       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
15392     }
15393
15394   /* send it... */
15395   S (mp);
15396
15397   /* Wait for a reply... */
15398   W (ret);
15399   return ret;
15400 }
15401
15402 #define api_lisp_add_del_map_resolver api_one_add_del_map_resolver
15403
15404 static int
15405 api_lisp_gpe_enable_disable (vat_main_t * vam)
15406 {
15407   unformat_input_t *input = vam->input;
15408   vl_api_gpe_enable_disable_t *mp;
15409   u8 is_set = 0;
15410   u8 is_en = 1;
15411   int ret;
15412
15413   /* Parse args required to build the message */
15414   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15415     {
15416       if (unformat (input, "enable"))
15417         {
15418           is_set = 1;
15419           is_en = 1;
15420         }
15421       else if (unformat (input, "disable"))
15422         {
15423           is_set = 1;
15424           is_en = 0;
15425         }
15426       else
15427         break;
15428     }
15429
15430   if (is_set == 0)
15431     {
15432       errmsg ("Value not set");
15433       return -99;
15434     }
15435
15436   /* Construct the API message */
15437   M (GPE_ENABLE_DISABLE, mp);
15438
15439   mp->is_en = is_en;
15440
15441   /* send it... */
15442   S (mp);
15443
15444   /* Wait for a reply... */
15445   W (ret);
15446   return ret;
15447 }
15448
15449 static int
15450 api_one_rloc_probe_enable_disable (vat_main_t * vam)
15451 {
15452   unformat_input_t *input = vam->input;
15453   vl_api_one_rloc_probe_enable_disable_t *mp;
15454   u8 is_set = 0;
15455   u8 is_en = 0;
15456   int ret;
15457
15458   /* Parse args required to build the message */
15459   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15460     {
15461       if (unformat (input, "enable"))
15462         {
15463           is_set = 1;
15464           is_en = 1;
15465         }
15466       else if (unformat (input, "disable"))
15467         is_set = 1;
15468       else
15469         break;
15470     }
15471
15472   if (!is_set)
15473     {
15474       errmsg ("Value not set");
15475       return -99;
15476     }
15477
15478   /* Construct the API message */
15479   M (ONE_RLOC_PROBE_ENABLE_DISABLE, mp);
15480
15481   mp->is_enabled = is_en;
15482
15483   /* send it... */
15484   S (mp);
15485
15486   /* Wait for a reply... */
15487   W (ret);
15488   return ret;
15489 }
15490
15491 #define api_lisp_rloc_probe_enable_disable api_one_rloc_probe_enable_disable
15492
15493 static int
15494 api_one_map_register_enable_disable (vat_main_t * vam)
15495 {
15496   unformat_input_t *input = vam->input;
15497   vl_api_one_map_register_enable_disable_t *mp;
15498   u8 is_set = 0;
15499   u8 is_en = 0;
15500   int ret;
15501
15502   /* Parse args required to build the message */
15503   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15504     {
15505       if (unformat (input, "enable"))
15506         {
15507           is_set = 1;
15508           is_en = 1;
15509         }
15510       else if (unformat (input, "disable"))
15511         is_set = 1;
15512       else
15513         break;
15514     }
15515
15516   if (!is_set)
15517     {
15518       errmsg ("Value not set");
15519       return -99;
15520     }
15521
15522   /* Construct the API message */
15523   M (ONE_MAP_REGISTER_ENABLE_DISABLE, mp);
15524
15525   mp->is_enabled = is_en;
15526
15527   /* send it... */
15528   S (mp);
15529
15530   /* Wait for a reply... */
15531   W (ret);
15532   return ret;
15533 }
15534
15535 #define api_lisp_map_register_enable_disable api_one_map_register_enable_disable
15536
15537 static int
15538 api_one_enable_disable (vat_main_t * vam)
15539 {
15540   unformat_input_t *input = vam->input;
15541   vl_api_one_enable_disable_t *mp;
15542   u8 is_set = 0;
15543   u8 is_en = 0;
15544   int ret;
15545
15546   /* Parse args required to build the message */
15547   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15548     {
15549       if (unformat (input, "enable"))
15550         {
15551           is_set = 1;
15552           is_en = 1;
15553         }
15554       else if (unformat (input, "disable"))
15555         {
15556           is_set = 1;
15557         }
15558       else
15559         break;
15560     }
15561
15562   if (!is_set)
15563     {
15564       errmsg ("Value not set");
15565       return -99;
15566     }
15567
15568   /* Construct the API message */
15569   M (ONE_ENABLE_DISABLE, mp);
15570
15571   mp->is_en = is_en;
15572
15573   /* send it... */
15574   S (mp);
15575
15576   /* Wait for a reply... */
15577   W (ret);
15578   return ret;
15579 }
15580
15581 #define api_lisp_enable_disable api_one_enable_disable
15582
15583 static int
15584 api_one_enable_disable_xtr_mode (vat_main_t * vam)
15585 {
15586   unformat_input_t *input = vam->input;
15587   vl_api_one_enable_disable_xtr_mode_t *mp;
15588   u8 is_set = 0;
15589   u8 is_en = 0;
15590   int ret;
15591
15592   /* Parse args required to build the message */
15593   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15594     {
15595       if (unformat (input, "enable"))
15596         {
15597           is_set = 1;
15598           is_en = 1;
15599         }
15600       else if (unformat (input, "disable"))
15601         {
15602           is_set = 1;
15603         }
15604       else
15605         break;
15606     }
15607
15608   if (!is_set)
15609     {
15610       errmsg ("Value not set");
15611       return -99;
15612     }
15613
15614   /* Construct the API message */
15615   M (ONE_ENABLE_DISABLE_XTR_MODE, mp);
15616
15617   mp->is_en = is_en;
15618
15619   /* send it... */
15620   S (mp);
15621
15622   /* Wait for a reply... */
15623   W (ret);
15624   return ret;
15625 }
15626
15627 static int
15628 api_one_show_xtr_mode (vat_main_t * vam)
15629 {
15630   vl_api_one_show_xtr_mode_t *mp;
15631   int ret;
15632
15633   /* Construct the API message */
15634   M (ONE_SHOW_XTR_MODE, mp);
15635
15636   /* send it... */
15637   S (mp);
15638
15639   /* Wait for a reply... */
15640   W (ret);
15641   return ret;
15642 }
15643
15644 static int
15645 api_one_enable_disable_pitr_mode (vat_main_t * vam)
15646 {
15647   unformat_input_t *input = vam->input;
15648   vl_api_one_enable_disable_pitr_mode_t *mp;
15649   u8 is_set = 0;
15650   u8 is_en = 0;
15651   int ret;
15652
15653   /* Parse args required to build the message */
15654   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15655     {
15656       if (unformat (input, "enable"))
15657         {
15658           is_set = 1;
15659           is_en = 1;
15660         }
15661       else if (unformat (input, "disable"))
15662         {
15663           is_set = 1;
15664         }
15665       else
15666         break;
15667     }
15668
15669   if (!is_set)
15670     {
15671       errmsg ("Value not set");
15672       return -99;
15673     }
15674
15675   /* Construct the API message */
15676   M (ONE_ENABLE_DISABLE_PITR_MODE, mp);
15677
15678   mp->is_en = is_en;
15679
15680   /* send it... */
15681   S (mp);
15682
15683   /* Wait for a reply... */
15684   W (ret);
15685   return ret;
15686 }
15687
15688 static int
15689 api_one_show_pitr_mode (vat_main_t * vam)
15690 {
15691   vl_api_one_show_pitr_mode_t *mp;
15692   int ret;
15693
15694   /* Construct the API message */
15695   M (ONE_SHOW_PITR_MODE, mp);
15696
15697   /* send it... */
15698   S (mp);
15699
15700   /* Wait for a reply... */
15701   W (ret);
15702   return ret;
15703 }
15704
15705 static int
15706 api_one_enable_disable_petr_mode (vat_main_t * vam)
15707 {
15708   unformat_input_t *input = vam->input;
15709   vl_api_one_enable_disable_petr_mode_t *mp;
15710   u8 is_set = 0;
15711   u8 is_en = 0;
15712   int ret;
15713
15714   /* Parse args required to build the message */
15715   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15716     {
15717       if (unformat (input, "enable"))
15718         {
15719           is_set = 1;
15720           is_en = 1;
15721         }
15722       else if (unformat (input, "disable"))
15723         {
15724           is_set = 1;
15725         }
15726       else
15727         break;
15728     }
15729
15730   if (!is_set)
15731     {
15732       errmsg ("Value not set");
15733       return -99;
15734     }
15735
15736   /* Construct the API message */
15737   M (ONE_ENABLE_DISABLE_PETR_MODE, mp);
15738
15739   mp->is_en = is_en;
15740
15741   /* send it... */
15742   S (mp);
15743
15744   /* Wait for a reply... */
15745   W (ret);
15746   return ret;
15747 }
15748
15749 static int
15750 api_one_show_petr_mode (vat_main_t * vam)
15751 {
15752   vl_api_one_show_petr_mode_t *mp;
15753   int ret;
15754
15755   /* Construct the API message */
15756   M (ONE_SHOW_PETR_MODE, mp);
15757
15758   /* send it... */
15759   S (mp);
15760
15761   /* Wait for a reply... */
15762   W (ret);
15763   return ret;
15764 }
15765
15766 static int
15767 api_show_one_map_register_state (vat_main_t * vam)
15768 {
15769   vl_api_show_one_map_register_state_t *mp;
15770   int ret;
15771
15772   M (SHOW_ONE_MAP_REGISTER_STATE, mp);
15773
15774   /* send */
15775   S (mp);
15776
15777   /* wait for reply */
15778   W (ret);
15779   return ret;
15780 }
15781
15782 #define api_show_lisp_map_register_state api_show_one_map_register_state
15783
15784 static int
15785 api_show_one_rloc_probe_state (vat_main_t * vam)
15786 {
15787   vl_api_show_one_rloc_probe_state_t *mp;
15788   int ret;
15789
15790   M (SHOW_ONE_RLOC_PROBE_STATE, mp);
15791
15792   /* send */
15793   S (mp);
15794
15795   /* wait for reply */
15796   W (ret);
15797   return ret;
15798 }
15799
15800 #define api_show_lisp_rloc_probe_state api_show_one_rloc_probe_state
15801
15802 static int
15803 api_one_add_del_ndp_entry (vat_main_t * vam)
15804 {
15805   vl_api_one_add_del_ndp_entry_t *mp;
15806   unformat_input_t *input = vam->input;
15807   u8 is_add = 1;
15808   u8 mac_set = 0;
15809   u8 bd_set = 0;
15810   u8 ip_set = 0;
15811   u8 mac[6] = { 0, };
15812   u8 ip6[16] = { 0, };
15813   u32 bd = ~0;
15814   int ret;
15815
15816   /* Parse args required to build the message */
15817   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15818     {
15819       if (unformat (input, "del"))
15820         is_add = 0;
15821       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
15822         mac_set = 1;
15823       else if (unformat (input, "ip %U", unformat_ip6_address, ip6))
15824         ip_set = 1;
15825       else if (unformat (input, "bd %d", &bd))
15826         bd_set = 1;
15827       else
15828         {
15829           errmsg ("parse error '%U'", format_unformat_error, input);
15830           return -99;
15831         }
15832     }
15833
15834   if (!bd_set || !ip_set || (!mac_set && is_add))
15835     {
15836       errmsg ("Missing BD, IP or MAC!");
15837       return -99;
15838     }
15839
15840   M (ONE_ADD_DEL_NDP_ENTRY, mp);
15841   mp->is_add = is_add;
15842   clib_memcpy (mp->mac, mac, 6);
15843   mp->bd = clib_host_to_net_u32 (bd);
15844   clib_memcpy (mp->ip6, ip6, sizeof (mp->ip6));
15845
15846   /* send */
15847   S (mp);
15848
15849   /* wait for reply */
15850   W (ret);
15851   return ret;
15852 }
15853
15854 static int
15855 api_one_add_del_l2_arp_entry (vat_main_t * vam)
15856 {
15857   vl_api_one_add_del_l2_arp_entry_t *mp;
15858   unformat_input_t *input = vam->input;
15859   u8 is_add = 1;
15860   u8 mac_set = 0;
15861   u8 bd_set = 0;
15862   u8 ip_set = 0;
15863   u8 mac[6] = { 0, };
15864   u32 ip4 = 0, bd = ~0;
15865   int ret;
15866
15867   /* Parse args required to build the message */
15868   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15869     {
15870       if (unformat (input, "del"))
15871         is_add = 0;
15872       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
15873         mac_set = 1;
15874       else if (unformat (input, "ip %U", unformat_ip4_address, &ip4))
15875         ip_set = 1;
15876       else if (unformat (input, "bd %d", &bd))
15877         bd_set = 1;
15878       else
15879         {
15880           errmsg ("parse error '%U'", format_unformat_error, input);
15881           return -99;
15882         }
15883     }
15884
15885   if (!bd_set || !ip_set || (!mac_set && is_add))
15886     {
15887       errmsg ("Missing BD, IP or MAC!");
15888       return -99;
15889     }
15890
15891   M (ONE_ADD_DEL_L2_ARP_ENTRY, mp);
15892   mp->is_add = is_add;
15893   clib_memcpy (mp->mac, mac, 6);
15894   mp->bd = clib_host_to_net_u32 (bd);
15895   mp->ip4 = ip4;
15896
15897   /* send */
15898   S (mp);
15899
15900   /* wait for reply */
15901   W (ret);
15902   return ret;
15903 }
15904
15905 static int
15906 api_one_ndp_bd_get (vat_main_t * vam)
15907 {
15908   vl_api_one_ndp_bd_get_t *mp;
15909   int ret;
15910
15911   M (ONE_NDP_BD_GET, mp);
15912
15913   /* send */
15914   S (mp);
15915
15916   /* wait for reply */
15917   W (ret);
15918   return ret;
15919 }
15920
15921 static int
15922 api_one_ndp_entries_get (vat_main_t * vam)
15923 {
15924   vl_api_one_ndp_entries_get_t *mp;
15925   unformat_input_t *input = vam->input;
15926   u8 bd_set = 0;
15927   u32 bd = ~0;
15928   int ret;
15929
15930   /* Parse args required to build the message */
15931   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15932     {
15933       if (unformat (input, "bd %d", &bd))
15934         bd_set = 1;
15935       else
15936         {
15937           errmsg ("parse error '%U'", format_unformat_error, input);
15938           return -99;
15939         }
15940     }
15941
15942   if (!bd_set)
15943     {
15944       errmsg ("Expected bridge domain!");
15945       return -99;
15946     }
15947
15948   M (ONE_NDP_ENTRIES_GET, mp);
15949   mp->bd = clib_host_to_net_u32 (bd);
15950
15951   /* send */
15952   S (mp);
15953
15954   /* wait for reply */
15955   W (ret);
15956   return ret;
15957 }
15958
15959 static int
15960 api_one_l2_arp_bd_get (vat_main_t * vam)
15961 {
15962   vl_api_one_l2_arp_bd_get_t *mp;
15963   int ret;
15964
15965   M (ONE_L2_ARP_BD_GET, mp);
15966
15967   /* send */
15968   S (mp);
15969
15970   /* wait for reply */
15971   W (ret);
15972   return ret;
15973 }
15974
15975 static int
15976 api_one_l2_arp_entries_get (vat_main_t * vam)
15977 {
15978   vl_api_one_l2_arp_entries_get_t *mp;
15979   unformat_input_t *input = vam->input;
15980   u8 bd_set = 0;
15981   u32 bd = ~0;
15982   int ret;
15983
15984   /* Parse args required to build the message */
15985   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15986     {
15987       if (unformat (input, "bd %d", &bd))
15988         bd_set = 1;
15989       else
15990         {
15991           errmsg ("parse error '%U'", format_unformat_error, input);
15992           return -99;
15993         }
15994     }
15995
15996   if (!bd_set)
15997     {
15998       errmsg ("Expected bridge domain!");
15999       return -99;
16000     }
16001
16002   M (ONE_L2_ARP_ENTRIES_GET, mp);
16003   mp->bd = clib_host_to_net_u32 (bd);
16004
16005   /* send */
16006   S (mp);
16007
16008   /* wait for reply */
16009   W (ret);
16010   return ret;
16011 }
16012
16013 static int
16014 api_one_stats_enable_disable (vat_main_t * vam)
16015 {
16016   vl_api_one_stats_enable_disable_t *mp;
16017   unformat_input_t *input = vam->input;
16018   u8 is_set = 0;
16019   u8 is_en = 0;
16020   int ret;
16021
16022   /* Parse args required to build the message */
16023   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16024     {
16025       if (unformat (input, "enable"))
16026         {
16027           is_set = 1;
16028           is_en = 1;
16029         }
16030       else if (unformat (input, "disable"))
16031         {
16032           is_set = 1;
16033         }
16034       else
16035         break;
16036     }
16037
16038   if (!is_set)
16039     {
16040       errmsg ("Value not set");
16041       return -99;
16042     }
16043
16044   M (ONE_STATS_ENABLE_DISABLE, mp);
16045   mp->is_en = is_en;
16046
16047   /* send */
16048   S (mp);
16049
16050   /* wait for reply */
16051   W (ret);
16052   return ret;
16053 }
16054
16055 static int
16056 api_show_one_stats_enable_disable (vat_main_t * vam)
16057 {
16058   vl_api_show_one_stats_enable_disable_t *mp;
16059   int ret;
16060
16061   M (SHOW_ONE_STATS_ENABLE_DISABLE, mp);
16062
16063   /* send */
16064   S (mp);
16065
16066   /* wait for reply */
16067   W (ret);
16068   return ret;
16069 }
16070
16071 static int
16072 api_show_one_map_request_mode (vat_main_t * vam)
16073 {
16074   vl_api_show_one_map_request_mode_t *mp;
16075   int ret;
16076
16077   M (SHOW_ONE_MAP_REQUEST_MODE, mp);
16078
16079   /* send */
16080   S (mp);
16081
16082   /* wait for reply */
16083   W (ret);
16084   return ret;
16085 }
16086
16087 #define api_show_lisp_map_request_mode api_show_one_map_request_mode
16088
16089 static int
16090 api_one_map_request_mode (vat_main_t * vam)
16091 {
16092   unformat_input_t *input = vam->input;
16093   vl_api_one_map_request_mode_t *mp;
16094   u8 mode = 0;
16095   int ret;
16096
16097   /* Parse args required to build the message */
16098   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16099     {
16100       if (unformat (input, "dst-only"))
16101         mode = 0;
16102       else if (unformat (input, "src-dst"))
16103         mode = 1;
16104       else
16105         {
16106           errmsg ("parse error '%U'", format_unformat_error, input);
16107           return -99;
16108         }
16109     }
16110
16111   M (ONE_MAP_REQUEST_MODE, mp);
16112
16113   mp->mode = mode;
16114
16115   /* send */
16116   S (mp);
16117
16118   /* wait for reply */
16119   W (ret);
16120   return ret;
16121 }
16122
16123 #define api_lisp_map_request_mode api_one_map_request_mode
16124
16125 /**
16126  * Enable/disable ONE proxy ITR.
16127  *
16128  * @param vam vpp API test context
16129  * @return return code
16130  */
16131 static int
16132 api_one_pitr_set_locator_set (vat_main_t * vam)
16133 {
16134   u8 ls_name_set = 0;
16135   unformat_input_t *input = vam->input;
16136   vl_api_one_pitr_set_locator_set_t *mp;
16137   u8 is_add = 1;
16138   u8 *ls_name = 0;
16139   int ret;
16140
16141   /* Parse args required to build the message */
16142   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16143     {
16144       if (unformat (input, "del"))
16145         is_add = 0;
16146       else if (unformat (input, "locator-set %s", &ls_name))
16147         ls_name_set = 1;
16148       else
16149         {
16150           errmsg ("parse error '%U'", format_unformat_error, input);
16151           return -99;
16152         }
16153     }
16154
16155   if (!ls_name_set)
16156     {
16157       errmsg ("locator-set name not set!");
16158       return -99;
16159     }
16160
16161   M (ONE_PITR_SET_LOCATOR_SET, mp);
16162
16163   mp->is_add = is_add;
16164   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
16165   vec_free (ls_name);
16166
16167   /* send */
16168   S (mp);
16169
16170   /* wait for reply */
16171   W (ret);
16172   return ret;
16173 }
16174
16175 #define api_lisp_pitr_set_locator_set api_one_pitr_set_locator_set
16176
16177 static int
16178 api_one_nsh_set_locator_set (vat_main_t * vam)
16179 {
16180   u8 ls_name_set = 0;
16181   unformat_input_t *input = vam->input;
16182   vl_api_one_nsh_set_locator_set_t *mp;
16183   u8 is_add = 1;
16184   u8 *ls_name = 0;
16185   int ret;
16186
16187   /* Parse args required to build the message */
16188   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16189     {
16190       if (unformat (input, "del"))
16191         is_add = 0;
16192       else if (unformat (input, "ls %s", &ls_name))
16193         ls_name_set = 1;
16194       else
16195         {
16196           errmsg ("parse error '%U'", format_unformat_error, input);
16197           return -99;
16198         }
16199     }
16200
16201   if (!ls_name_set && is_add)
16202     {
16203       errmsg ("locator-set name not set!");
16204       return -99;
16205     }
16206
16207   M (ONE_NSH_SET_LOCATOR_SET, mp);
16208
16209   mp->is_add = is_add;
16210   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
16211   vec_free (ls_name);
16212
16213   /* send */
16214   S (mp);
16215
16216   /* wait for reply */
16217   W (ret);
16218   return ret;
16219 }
16220
16221 static int
16222 api_show_one_pitr (vat_main_t * vam)
16223 {
16224   vl_api_show_one_pitr_t *mp;
16225   int ret;
16226
16227   if (!vam->json_output)
16228     {
16229       print (vam->ofp, "%=20s", "lisp status:");
16230     }
16231
16232   M (SHOW_ONE_PITR, mp);
16233   /* send it... */
16234   S (mp);
16235
16236   /* Wait for a reply... */
16237   W (ret);
16238   return ret;
16239 }
16240
16241 #define api_show_lisp_pitr api_show_one_pitr
16242
16243 static int
16244 api_one_use_petr (vat_main_t * vam)
16245 {
16246   unformat_input_t *input = vam->input;
16247   vl_api_one_use_petr_t *mp;
16248   u8 is_add = 0;
16249   ip_address_t ip;
16250   int ret;
16251
16252   clib_memset (&ip, 0, sizeof (ip));
16253
16254   /* Parse args required to build the message */
16255   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16256     {
16257       if (unformat (input, "disable"))
16258         is_add = 0;
16259       else
16260         if (unformat (input, "%U", unformat_ip4_address, &ip_addr_v4 (&ip)))
16261         {
16262           is_add = 1;
16263           ip_addr_version (&ip) = IP4;
16264         }
16265       else
16266         if (unformat (input, "%U", unformat_ip6_address, &ip_addr_v6 (&ip)))
16267         {
16268           is_add = 1;
16269           ip_addr_version (&ip) = IP6;
16270         }
16271       else
16272         {
16273           errmsg ("parse error '%U'", format_unformat_error, input);
16274           return -99;
16275         }
16276     }
16277
16278   M (ONE_USE_PETR, mp);
16279
16280   mp->is_add = is_add;
16281   if (is_add)
16282     {
16283       mp->is_ip4 = ip_addr_version (&ip) == IP4 ? 1 : 0;
16284       if (mp->is_ip4)
16285         clib_memcpy (mp->address, &ip, 4);
16286       else
16287         clib_memcpy (mp->address, &ip, 16);
16288     }
16289
16290   /* send */
16291   S (mp);
16292
16293   /* wait for reply */
16294   W (ret);
16295   return ret;
16296 }
16297
16298 #define api_lisp_use_petr api_one_use_petr
16299
16300 static int
16301 api_show_one_nsh_mapping (vat_main_t * vam)
16302 {
16303   vl_api_show_one_use_petr_t *mp;
16304   int ret;
16305
16306   if (!vam->json_output)
16307     {
16308       print (vam->ofp, "%=20s", "local ONE NSH mapping:");
16309     }
16310
16311   M (SHOW_ONE_NSH_MAPPING, mp);
16312   /* send it... */
16313   S (mp);
16314
16315   /* Wait for a reply... */
16316   W (ret);
16317   return ret;
16318 }
16319
16320 static int
16321 api_show_one_use_petr (vat_main_t * vam)
16322 {
16323   vl_api_show_one_use_petr_t *mp;
16324   int ret;
16325
16326   if (!vam->json_output)
16327     {
16328       print (vam->ofp, "%=20s", "Proxy-ETR status:");
16329     }
16330
16331   M (SHOW_ONE_USE_PETR, mp);
16332   /* send it... */
16333   S (mp);
16334
16335   /* Wait for a reply... */
16336   W (ret);
16337   return ret;
16338 }
16339
16340 #define api_show_lisp_use_petr api_show_one_use_petr
16341
16342 /**
16343  * Add/delete mapping between vni and vrf
16344  */
16345 static int
16346 api_one_eid_table_add_del_map (vat_main_t * vam)
16347 {
16348   unformat_input_t *input = vam->input;
16349   vl_api_one_eid_table_add_del_map_t *mp;
16350   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
16351   u32 vni, vrf, bd_index;
16352   int ret;
16353
16354   /* Parse args required to build the message */
16355   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16356     {
16357       if (unformat (input, "del"))
16358         is_add = 0;
16359       else if (unformat (input, "vrf %d", &vrf))
16360         vrf_set = 1;
16361       else if (unformat (input, "bd_index %d", &bd_index))
16362         bd_index_set = 1;
16363       else if (unformat (input, "vni %d", &vni))
16364         vni_set = 1;
16365       else
16366         break;
16367     }
16368
16369   if (!vni_set || (!vrf_set && !bd_index_set))
16370     {
16371       errmsg ("missing arguments!");
16372       return -99;
16373     }
16374
16375   if (vrf_set && bd_index_set)
16376     {
16377       errmsg ("error: both vrf and bd entered!");
16378       return -99;
16379     }
16380
16381   M (ONE_EID_TABLE_ADD_DEL_MAP, mp);
16382
16383   mp->is_add = is_add;
16384   mp->vni = htonl (vni);
16385   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
16386   mp->is_l2 = bd_index_set;
16387
16388   /* send */
16389   S (mp);
16390
16391   /* wait for reply */
16392   W (ret);
16393   return ret;
16394 }
16395
16396 #define api_lisp_eid_table_add_del_map api_one_eid_table_add_del_map
16397
16398 uword
16399 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
16400 {
16401   u32 *action = va_arg (*args, u32 *);
16402   u8 *s = 0;
16403
16404   if (unformat (input, "%s", &s))
16405     {
16406       if (!strcmp ((char *) s, "no-action"))
16407         action[0] = 0;
16408       else if (!strcmp ((char *) s, "natively-forward"))
16409         action[0] = 1;
16410       else if (!strcmp ((char *) s, "send-map-request"))
16411         action[0] = 2;
16412       else if (!strcmp ((char *) s, "drop"))
16413         action[0] = 3;
16414       else
16415         {
16416           clib_warning ("invalid action: '%s'", s);
16417           action[0] = 3;
16418         }
16419     }
16420   else
16421     return 0;
16422
16423   vec_free (s);
16424   return 1;
16425 }
16426
16427 /**
16428  * Add/del remote mapping to/from ONE control plane
16429  *
16430  * @param vam vpp API test context
16431  * @return return code
16432  */
16433 static int
16434 api_one_add_del_remote_mapping (vat_main_t * vam)
16435 {
16436   unformat_input_t *input = vam->input;
16437   vl_api_one_add_del_remote_mapping_t *mp;
16438   u32 vni = 0;
16439   lisp_eid_vat_t _eid, *eid = &_eid;
16440   lisp_eid_vat_t _seid, *seid = &_seid;
16441   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
16442   u32 action = ~0, p, w, data_len;
16443   ip4_address_t rloc4;
16444   ip6_address_t rloc6;
16445   vl_api_remote_locator_t *rlocs = 0, rloc, *curr_rloc = 0;
16446   int ret;
16447
16448   clib_memset (&rloc, 0, sizeof (rloc));
16449
16450   /* Parse args required to build the message */
16451   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16452     {
16453       if (unformat (input, "del-all"))
16454         {
16455           del_all = 1;
16456         }
16457       else if (unformat (input, "del"))
16458         {
16459           is_add = 0;
16460         }
16461       else if (unformat (input, "add"))
16462         {
16463           is_add = 1;
16464         }
16465       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
16466         {
16467           eid_set = 1;
16468         }
16469       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
16470         {
16471           seid_set = 1;
16472         }
16473       else if (unformat (input, "vni %d", &vni))
16474         {
16475           ;
16476         }
16477       else if (unformat (input, "p %d w %d", &p, &w))
16478         {
16479           if (!curr_rloc)
16480             {
16481               errmsg ("No RLOC configured for setting priority/weight!");
16482               return -99;
16483             }
16484           curr_rloc->priority = p;
16485           curr_rloc->weight = w;
16486         }
16487       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
16488         {
16489           rloc.is_ip4 = 1;
16490           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
16491           vec_add1 (rlocs, rloc);
16492           curr_rloc = &rlocs[vec_len (rlocs) - 1];
16493         }
16494       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
16495         {
16496           rloc.is_ip4 = 0;
16497           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
16498           vec_add1 (rlocs, rloc);
16499           curr_rloc = &rlocs[vec_len (rlocs) - 1];
16500         }
16501       else if (unformat (input, "action %U",
16502                          unformat_negative_mapping_action, &action))
16503         {
16504           ;
16505         }
16506       else
16507         {
16508           clib_warning ("parse error '%U'", format_unformat_error, input);
16509           return -99;
16510         }
16511     }
16512
16513   if (0 == eid_set)
16514     {
16515       errmsg ("missing params!");
16516       return -99;
16517     }
16518
16519   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
16520     {
16521       errmsg ("no action set for negative map-reply!");
16522       return -99;
16523     }
16524
16525   data_len = vec_len (rlocs) * sizeof (vl_api_remote_locator_t);
16526
16527   M2 (ONE_ADD_DEL_REMOTE_MAPPING, mp, data_len);
16528   mp->is_add = is_add;
16529   mp->vni = htonl (vni);
16530   mp->action = (u8) action;
16531   mp->is_src_dst = seid_set;
16532   mp->eid_len = eid->len;
16533   mp->seid_len = seid->len;
16534   mp->del_all = del_all;
16535   mp->eid_type = eid->type;
16536   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
16537   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
16538
16539   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
16540   clib_memcpy (mp->rlocs, rlocs, data_len);
16541   vec_free (rlocs);
16542
16543   /* send it... */
16544   S (mp);
16545
16546   /* Wait for a reply... */
16547   W (ret);
16548   return ret;
16549 }
16550
16551 #define api_lisp_add_del_remote_mapping api_one_add_del_remote_mapping
16552
16553 /**
16554  * Add/del ONE adjacency. Saves mapping in ONE control plane and updates
16555  * forwarding entries in data-plane accordingly.
16556  *
16557  * @param vam vpp API test context
16558  * @return return code
16559  */
16560 static int
16561 api_one_add_del_adjacency (vat_main_t * vam)
16562 {
16563   unformat_input_t *input = vam->input;
16564   vl_api_one_add_del_adjacency_t *mp;
16565   u32 vni = 0;
16566   ip4_address_t leid4, reid4;
16567   ip6_address_t leid6, reid6;
16568   u8 reid_mac[6] = { 0 };
16569   u8 leid_mac[6] = { 0 };
16570   u8 reid_type, leid_type;
16571   u32 leid_len = 0, reid_len = 0, len;
16572   u8 is_add = 1;
16573   int ret;
16574
16575   leid_type = reid_type = (u8) ~ 0;
16576
16577   /* Parse args required to build the message */
16578   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16579     {
16580       if (unformat (input, "del"))
16581         {
16582           is_add = 0;
16583         }
16584       else if (unformat (input, "add"))
16585         {
16586           is_add = 1;
16587         }
16588       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
16589                          &reid4, &len))
16590         {
16591           reid_type = 0;        /* ipv4 */
16592           reid_len = len;
16593         }
16594       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
16595                          &reid6, &len))
16596         {
16597           reid_type = 1;        /* ipv6 */
16598           reid_len = len;
16599         }
16600       else if (unformat (input, "reid %U", unformat_ethernet_address,
16601                          reid_mac))
16602         {
16603           reid_type = 2;        /* mac */
16604         }
16605       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
16606                          &leid4, &len))
16607         {
16608           leid_type = 0;        /* ipv4 */
16609           leid_len = len;
16610         }
16611       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
16612                          &leid6, &len))
16613         {
16614           leid_type = 1;        /* ipv6 */
16615           leid_len = len;
16616         }
16617       else if (unformat (input, "leid %U", unformat_ethernet_address,
16618                          leid_mac))
16619         {
16620           leid_type = 2;        /* mac */
16621         }
16622       else if (unformat (input, "vni %d", &vni))
16623         {
16624           ;
16625         }
16626       else
16627         {
16628           errmsg ("parse error '%U'", format_unformat_error, input);
16629           return -99;
16630         }
16631     }
16632
16633   if ((u8) ~ 0 == reid_type)
16634     {
16635       errmsg ("missing params!");
16636       return -99;
16637     }
16638
16639   if (leid_type != reid_type)
16640     {
16641       errmsg ("remote and local EIDs are of different types!");
16642       return -99;
16643     }
16644
16645   M (ONE_ADD_DEL_ADJACENCY, mp);
16646   mp->is_add = is_add;
16647   mp->vni = htonl (vni);
16648   mp->leid_len = leid_len;
16649   mp->reid_len = reid_len;
16650   mp->eid_type = reid_type;
16651
16652   switch (mp->eid_type)
16653     {
16654     case 0:
16655       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
16656       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
16657       break;
16658     case 1:
16659       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
16660       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
16661       break;
16662     case 2:
16663       clib_memcpy (mp->leid, leid_mac, 6);
16664       clib_memcpy (mp->reid, reid_mac, 6);
16665       break;
16666     default:
16667       errmsg ("unknown EID type %d!", mp->eid_type);
16668       return 0;
16669     }
16670
16671   /* send it... */
16672   S (mp);
16673
16674   /* Wait for a reply... */
16675   W (ret);
16676   return ret;
16677 }
16678
16679 #define api_lisp_add_del_adjacency api_one_add_del_adjacency
16680
16681 uword
16682 unformat_gpe_encap_mode (unformat_input_t * input, va_list * args)
16683 {
16684   u32 *mode = va_arg (*args, u32 *);
16685
16686   if (unformat (input, "lisp"))
16687     *mode = 0;
16688   else if (unformat (input, "vxlan"))
16689     *mode = 1;
16690   else
16691     return 0;
16692
16693   return 1;
16694 }
16695
16696 static int
16697 api_gpe_get_encap_mode (vat_main_t * vam)
16698 {
16699   vl_api_gpe_get_encap_mode_t *mp;
16700   int ret;
16701
16702   /* Construct the API message */
16703   M (GPE_GET_ENCAP_MODE, mp);
16704
16705   /* send it... */
16706   S (mp);
16707
16708   /* Wait for a reply... */
16709   W (ret);
16710   return ret;
16711 }
16712
16713 static int
16714 api_gpe_set_encap_mode (vat_main_t * vam)
16715 {
16716   unformat_input_t *input = vam->input;
16717   vl_api_gpe_set_encap_mode_t *mp;
16718   int ret;
16719   u32 mode = 0;
16720
16721   /* Parse args required to build the message */
16722   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16723     {
16724       if (unformat (input, "%U", unformat_gpe_encap_mode, &mode))
16725         ;
16726       else
16727         break;
16728     }
16729
16730   /* Construct the API message */
16731   M (GPE_SET_ENCAP_MODE, mp);
16732
16733   mp->mode = mode;
16734
16735   /* send it... */
16736   S (mp);
16737
16738   /* Wait for a reply... */
16739   W (ret);
16740   return ret;
16741 }
16742
16743 static int
16744 api_lisp_gpe_add_del_iface (vat_main_t * vam)
16745 {
16746   unformat_input_t *input = vam->input;
16747   vl_api_gpe_add_del_iface_t *mp;
16748   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
16749   u32 dp_table = 0, vni = 0;
16750   int ret;
16751
16752   /* Parse args required to build the message */
16753   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16754     {
16755       if (unformat (input, "up"))
16756         {
16757           action_set = 1;
16758           is_add = 1;
16759         }
16760       else if (unformat (input, "down"))
16761         {
16762           action_set = 1;
16763           is_add = 0;
16764         }
16765       else if (unformat (input, "table_id %d", &dp_table))
16766         {
16767           dp_table_set = 1;
16768         }
16769       else if (unformat (input, "bd_id %d", &dp_table))
16770         {
16771           dp_table_set = 1;
16772           is_l2 = 1;
16773         }
16774       else if (unformat (input, "vni %d", &vni))
16775         {
16776           vni_set = 1;
16777         }
16778       else
16779         break;
16780     }
16781
16782   if (action_set == 0)
16783     {
16784       errmsg ("Action not set");
16785       return -99;
16786     }
16787   if (dp_table_set == 0 || vni_set == 0)
16788     {
16789       errmsg ("vni and dp_table must be set");
16790       return -99;
16791     }
16792
16793   /* Construct the API message */
16794   M (GPE_ADD_DEL_IFACE, mp);
16795
16796   mp->is_add = is_add;
16797   mp->dp_table = clib_host_to_net_u32 (dp_table);
16798   mp->is_l2 = is_l2;
16799   mp->vni = clib_host_to_net_u32 (vni);
16800
16801   /* send it... */
16802   S (mp);
16803
16804   /* Wait for a reply... */
16805   W (ret);
16806   return ret;
16807 }
16808
16809 static int
16810 api_one_map_register_fallback_threshold (vat_main_t * vam)
16811 {
16812   unformat_input_t *input = vam->input;
16813   vl_api_one_map_register_fallback_threshold_t *mp;
16814   u32 value = 0;
16815   u8 is_set = 0;
16816   int ret;
16817
16818   /* Parse args required to build the message */
16819   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16820     {
16821       if (unformat (input, "%u", &value))
16822         is_set = 1;
16823       else
16824         {
16825           clib_warning ("parse error '%U'", format_unformat_error, input);
16826           return -99;
16827         }
16828     }
16829
16830   if (!is_set)
16831     {
16832       errmsg ("fallback threshold value is missing!");
16833       return -99;
16834     }
16835
16836   M (ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
16837   mp->value = clib_host_to_net_u32 (value);
16838
16839   /* send it... */
16840   S (mp);
16841
16842   /* Wait for a reply... */
16843   W (ret);
16844   return ret;
16845 }
16846
16847 static int
16848 api_show_one_map_register_fallback_threshold (vat_main_t * vam)
16849 {
16850   vl_api_show_one_map_register_fallback_threshold_t *mp;
16851   int ret;
16852
16853   M (SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
16854
16855   /* send it... */
16856   S (mp);
16857
16858   /* Wait for a reply... */
16859   W (ret);
16860   return ret;
16861 }
16862
16863 uword
16864 unformat_lisp_transport_protocol (unformat_input_t * input, va_list * args)
16865 {
16866   u32 *proto = va_arg (*args, u32 *);
16867
16868   if (unformat (input, "udp"))
16869     *proto = 1;
16870   else if (unformat (input, "api"))
16871     *proto = 2;
16872   else
16873     return 0;
16874
16875   return 1;
16876 }
16877
16878 static int
16879 api_one_set_transport_protocol (vat_main_t * vam)
16880 {
16881   unformat_input_t *input = vam->input;
16882   vl_api_one_set_transport_protocol_t *mp;
16883   u8 is_set = 0;
16884   u32 protocol = 0;
16885   int ret;
16886
16887   /* Parse args required to build the message */
16888   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16889     {
16890       if (unformat (input, "%U", unformat_lisp_transport_protocol, &protocol))
16891         is_set = 1;
16892       else
16893         {
16894           clib_warning ("parse error '%U'", format_unformat_error, input);
16895           return -99;
16896         }
16897     }
16898
16899   if (!is_set)
16900     {
16901       errmsg ("Transport protocol missing!");
16902       return -99;
16903     }
16904
16905   M (ONE_SET_TRANSPORT_PROTOCOL, mp);
16906   mp->protocol = (u8) protocol;
16907
16908   /* send it... */
16909   S (mp);
16910
16911   /* Wait for a reply... */
16912   W (ret);
16913   return ret;
16914 }
16915
16916 static int
16917 api_one_get_transport_protocol (vat_main_t * vam)
16918 {
16919   vl_api_one_get_transport_protocol_t *mp;
16920   int ret;
16921
16922   M (ONE_GET_TRANSPORT_PROTOCOL, mp);
16923
16924   /* send it... */
16925   S (mp);
16926
16927   /* Wait for a reply... */
16928   W (ret);
16929   return ret;
16930 }
16931
16932 static int
16933 api_one_map_register_set_ttl (vat_main_t * vam)
16934 {
16935   unformat_input_t *input = vam->input;
16936   vl_api_one_map_register_set_ttl_t *mp;
16937   u32 ttl = 0;
16938   u8 is_set = 0;
16939   int ret;
16940
16941   /* Parse args required to build the message */
16942   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16943     {
16944       if (unformat (input, "%u", &ttl))
16945         is_set = 1;
16946       else
16947         {
16948           clib_warning ("parse error '%U'", format_unformat_error, input);
16949           return -99;
16950         }
16951     }
16952
16953   if (!is_set)
16954     {
16955       errmsg ("TTL value missing!");
16956       return -99;
16957     }
16958
16959   M (ONE_MAP_REGISTER_SET_TTL, mp);
16960   mp->ttl = clib_host_to_net_u32 (ttl);
16961
16962   /* send it... */
16963   S (mp);
16964
16965   /* Wait for a reply... */
16966   W (ret);
16967   return ret;
16968 }
16969
16970 static int
16971 api_show_one_map_register_ttl (vat_main_t * vam)
16972 {
16973   vl_api_show_one_map_register_ttl_t *mp;
16974   int ret;
16975
16976   M (SHOW_ONE_MAP_REGISTER_TTL, mp);
16977
16978   /* send it... */
16979   S (mp);
16980
16981   /* Wait for a reply... */
16982   W (ret);
16983   return ret;
16984 }
16985
16986 /**
16987  * Add/del map request itr rlocs from ONE control plane and updates
16988  *
16989  * @param vam vpp API test context
16990  * @return return code
16991  */
16992 static int
16993 api_one_add_del_map_request_itr_rlocs (vat_main_t * vam)
16994 {
16995   unformat_input_t *input = vam->input;
16996   vl_api_one_add_del_map_request_itr_rlocs_t *mp;
16997   u8 *locator_set_name = 0;
16998   u8 locator_set_name_set = 0;
16999   u8 is_add = 1;
17000   int ret;
17001
17002   /* Parse args required to build the message */
17003   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17004     {
17005       if (unformat (input, "del"))
17006         {
17007           is_add = 0;
17008         }
17009       else if (unformat (input, "%_%v%_", &locator_set_name))
17010         {
17011           locator_set_name_set = 1;
17012         }
17013       else
17014         {
17015           clib_warning ("parse error '%U'", format_unformat_error, input);
17016           return -99;
17017         }
17018     }
17019
17020   if (is_add && !locator_set_name_set)
17021     {
17022       errmsg ("itr-rloc is not set!");
17023       return -99;
17024     }
17025
17026   if (is_add && vec_len (locator_set_name) > 64)
17027     {
17028       errmsg ("itr-rloc locator-set name too long");
17029       vec_free (locator_set_name);
17030       return -99;
17031     }
17032
17033   M (ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS, mp);
17034   mp->is_add = is_add;
17035   if (is_add)
17036     {
17037       clib_memcpy (mp->locator_set_name, locator_set_name,
17038                    vec_len (locator_set_name));
17039     }
17040   else
17041     {
17042       clib_memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
17043     }
17044   vec_free (locator_set_name);
17045
17046   /* send it... */
17047   S (mp);
17048
17049   /* Wait for a reply... */
17050   W (ret);
17051   return ret;
17052 }
17053
17054 #define api_lisp_add_del_map_request_itr_rlocs api_one_add_del_map_request_itr_rlocs
17055
17056 static int
17057 api_one_locator_dump (vat_main_t * vam)
17058 {
17059   unformat_input_t *input = vam->input;
17060   vl_api_one_locator_dump_t *mp;
17061   vl_api_control_ping_t *mp_ping;
17062   u8 is_index_set = 0, is_name_set = 0;
17063   u8 *ls_name = 0;
17064   u32 ls_index = ~0;
17065   int ret;
17066
17067   /* Parse args required to build the message */
17068   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17069     {
17070       if (unformat (input, "ls_name %_%v%_", &ls_name))
17071         {
17072           is_name_set = 1;
17073         }
17074       else if (unformat (input, "ls_index %d", &ls_index))
17075         {
17076           is_index_set = 1;
17077         }
17078       else
17079         {
17080           errmsg ("parse error '%U'", format_unformat_error, input);
17081           return -99;
17082         }
17083     }
17084
17085   if (!is_index_set && !is_name_set)
17086     {
17087       errmsg ("error: expected one of index or name!");
17088       return -99;
17089     }
17090
17091   if (is_index_set && is_name_set)
17092     {
17093       errmsg ("error: only one param expected!");
17094       return -99;
17095     }
17096
17097   if (vec_len (ls_name) > 62)
17098     {
17099       errmsg ("error: locator set name too long!");
17100       return -99;
17101     }
17102
17103   if (!vam->json_output)
17104     {
17105       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
17106     }
17107
17108   M (ONE_LOCATOR_DUMP, mp);
17109   mp->is_index_set = is_index_set;
17110
17111   if (is_index_set)
17112     mp->ls_index = clib_host_to_net_u32 (ls_index);
17113   else
17114     {
17115       vec_add1 (ls_name, 0);
17116       strncpy ((char *) mp->ls_name, (char *) ls_name,
17117                sizeof (mp->ls_name) - 1);
17118     }
17119
17120   /* send it... */
17121   S (mp);
17122
17123   /* Use a control ping for synchronization */
17124   MPING (CONTROL_PING, mp_ping);
17125   S (mp_ping);
17126
17127   /* Wait for a reply... */
17128   W (ret);
17129   return ret;
17130 }
17131
17132 #define api_lisp_locator_dump api_one_locator_dump
17133
17134 static int
17135 api_one_locator_set_dump (vat_main_t * vam)
17136 {
17137   vl_api_one_locator_set_dump_t *mp;
17138   vl_api_control_ping_t *mp_ping;
17139   unformat_input_t *input = vam->input;
17140   u8 filter = 0;
17141   int ret;
17142
17143   /* Parse args required to build the message */
17144   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17145     {
17146       if (unformat (input, "local"))
17147         {
17148           filter = 1;
17149         }
17150       else if (unformat (input, "remote"))
17151         {
17152           filter = 2;
17153         }
17154       else
17155         {
17156           errmsg ("parse error '%U'", format_unformat_error, input);
17157           return -99;
17158         }
17159     }
17160
17161   if (!vam->json_output)
17162     {
17163       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
17164     }
17165
17166   M (ONE_LOCATOR_SET_DUMP, mp);
17167
17168   mp->filter = filter;
17169
17170   /* send it... */
17171   S (mp);
17172
17173   /* Use a control ping for synchronization */
17174   MPING (CONTROL_PING, mp_ping);
17175   S (mp_ping);
17176
17177   /* Wait for a reply... */
17178   W (ret);
17179   return ret;
17180 }
17181
17182 #define api_lisp_locator_set_dump api_one_locator_set_dump
17183
17184 static int
17185 api_one_eid_table_map_dump (vat_main_t * vam)
17186 {
17187   u8 is_l2 = 0;
17188   u8 mode_set = 0;
17189   unformat_input_t *input = vam->input;
17190   vl_api_one_eid_table_map_dump_t *mp;
17191   vl_api_control_ping_t *mp_ping;
17192   int ret;
17193
17194   /* Parse args required to build the message */
17195   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17196     {
17197       if (unformat (input, "l2"))
17198         {
17199           is_l2 = 1;
17200           mode_set = 1;
17201         }
17202       else if (unformat (input, "l3"))
17203         {
17204           is_l2 = 0;
17205           mode_set = 1;
17206         }
17207       else
17208         {
17209           errmsg ("parse error '%U'", format_unformat_error, input);
17210           return -99;
17211         }
17212     }
17213
17214   if (!mode_set)
17215     {
17216       errmsg ("expected one of 'l2' or 'l3' parameter!");
17217       return -99;
17218     }
17219
17220   if (!vam->json_output)
17221     {
17222       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
17223     }
17224
17225   M (ONE_EID_TABLE_MAP_DUMP, mp);
17226   mp->is_l2 = is_l2;
17227
17228   /* send it... */
17229   S (mp);
17230
17231   /* Use a control ping for synchronization */
17232   MPING (CONTROL_PING, mp_ping);
17233   S (mp_ping);
17234
17235   /* Wait for a reply... */
17236   W (ret);
17237   return ret;
17238 }
17239
17240 #define api_lisp_eid_table_map_dump api_one_eid_table_map_dump
17241
17242 static int
17243 api_one_eid_table_vni_dump (vat_main_t * vam)
17244 {
17245   vl_api_one_eid_table_vni_dump_t *mp;
17246   vl_api_control_ping_t *mp_ping;
17247   int ret;
17248
17249   if (!vam->json_output)
17250     {
17251       print (vam->ofp, "VNI");
17252     }
17253
17254   M (ONE_EID_TABLE_VNI_DUMP, mp);
17255
17256   /* send it... */
17257   S (mp);
17258
17259   /* Use a control ping for synchronization */
17260   MPING (CONTROL_PING, mp_ping);
17261   S (mp_ping);
17262
17263   /* Wait for a reply... */
17264   W (ret);
17265   return ret;
17266 }
17267
17268 #define api_lisp_eid_table_vni_dump api_one_eid_table_vni_dump
17269
17270 static int
17271 api_one_eid_table_dump (vat_main_t * vam)
17272 {
17273   unformat_input_t *i = vam->input;
17274   vl_api_one_eid_table_dump_t *mp;
17275   vl_api_control_ping_t *mp_ping;
17276   struct in_addr ip4;
17277   struct in6_addr ip6;
17278   u8 mac[6];
17279   u8 eid_type = ~0, eid_set = 0;
17280   u32 prefix_length = ~0, t, vni = 0;
17281   u8 filter = 0;
17282   int ret;
17283   lisp_nsh_api_t nsh;
17284
17285   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17286     {
17287       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
17288         {
17289           eid_set = 1;
17290           eid_type = 0;
17291           prefix_length = t;
17292         }
17293       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
17294         {
17295           eid_set = 1;
17296           eid_type = 1;
17297           prefix_length = t;
17298         }
17299       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
17300         {
17301           eid_set = 1;
17302           eid_type = 2;
17303         }
17304       else if (unformat (i, "eid %U", unformat_nsh_address, &nsh))
17305         {
17306           eid_set = 1;
17307           eid_type = 3;
17308         }
17309       else if (unformat (i, "vni %d", &t))
17310         {
17311           vni = t;
17312         }
17313       else if (unformat (i, "local"))
17314         {
17315           filter = 1;
17316         }
17317       else if (unformat (i, "remote"))
17318         {
17319           filter = 2;
17320         }
17321       else
17322         {
17323           errmsg ("parse error '%U'", format_unformat_error, i);
17324           return -99;
17325         }
17326     }
17327
17328   if (!vam->json_output)
17329     {
17330       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
17331              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
17332     }
17333
17334   M (ONE_EID_TABLE_DUMP, mp);
17335
17336   mp->filter = filter;
17337   if (eid_set)
17338     {
17339       mp->eid_set = 1;
17340       mp->vni = htonl (vni);
17341       mp->eid_type = eid_type;
17342       switch (eid_type)
17343         {
17344         case 0:
17345           mp->prefix_length = prefix_length;
17346           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
17347           break;
17348         case 1:
17349           mp->prefix_length = prefix_length;
17350           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
17351           break;
17352         case 2:
17353           clib_memcpy (mp->eid, mac, sizeof (mac));
17354           break;
17355         case 3:
17356           clib_memcpy (mp->eid, &nsh, sizeof (nsh));
17357           break;
17358         default:
17359           errmsg ("unknown EID type %d!", eid_type);
17360           return -99;
17361         }
17362     }
17363
17364   /* send it... */
17365   S (mp);
17366
17367   /* Use a control ping for synchronization */
17368   MPING (CONTROL_PING, mp_ping);
17369   S (mp_ping);
17370
17371   /* Wait for a reply... */
17372   W (ret);
17373   return ret;
17374 }
17375
17376 #define api_lisp_eid_table_dump api_one_eid_table_dump
17377
17378 static int
17379 api_lisp_gpe_fwd_entries_get (vat_main_t * vam)
17380 {
17381   unformat_input_t *i = vam->input;
17382   vl_api_gpe_fwd_entries_get_t *mp;
17383   u8 vni_set = 0;
17384   u32 vni = ~0;
17385   int ret;
17386
17387   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17388     {
17389       if (unformat (i, "vni %d", &vni))
17390         {
17391           vni_set = 1;
17392         }
17393       else
17394         {
17395           errmsg ("parse error '%U'", format_unformat_error, i);
17396           return -99;
17397         }
17398     }
17399
17400   if (!vni_set)
17401     {
17402       errmsg ("vni not set!");
17403       return -99;
17404     }
17405
17406   if (!vam->json_output)
17407     {
17408       print (vam->ofp, "%10s %10s %s %40s", "fwd_index", "dp_table",
17409              "leid", "reid");
17410     }
17411
17412   M (GPE_FWD_ENTRIES_GET, mp);
17413   mp->vni = clib_host_to_net_u32 (vni);
17414
17415   /* send it... */
17416   S (mp);
17417
17418   /* Wait for a reply... */
17419   W (ret);
17420   return ret;
17421 }
17422
17423 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_endian vl_noop_handler
17424 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_print vl_noop_handler
17425 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_endian vl_noop_handler
17426 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_print vl_noop_handler
17427 #define vl_api_gpe_fwd_entries_get_reply_t_endian vl_noop_handler
17428 #define vl_api_gpe_fwd_entries_get_reply_t_print vl_noop_handler
17429 #define vl_api_gpe_fwd_entry_path_details_t_endian vl_noop_handler
17430 #define vl_api_gpe_fwd_entry_path_details_t_print vl_noop_handler
17431
17432 static int
17433 api_one_adjacencies_get (vat_main_t * vam)
17434 {
17435   unformat_input_t *i = vam->input;
17436   vl_api_one_adjacencies_get_t *mp;
17437   u8 vni_set = 0;
17438   u32 vni = ~0;
17439   int ret;
17440
17441   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17442     {
17443       if (unformat (i, "vni %d", &vni))
17444         {
17445           vni_set = 1;
17446         }
17447       else
17448         {
17449           errmsg ("parse error '%U'", format_unformat_error, i);
17450           return -99;
17451         }
17452     }
17453
17454   if (!vni_set)
17455     {
17456       errmsg ("vni not set!");
17457       return -99;
17458     }
17459
17460   if (!vam->json_output)
17461     {
17462       print (vam->ofp, "%s %40s", "leid", "reid");
17463     }
17464
17465   M (ONE_ADJACENCIES_GET, mp);
17466   mp->vni = clib_host_to_net_u32 (vni);
17467
17468   /* send it... */
17469   S (mp);
17470
17471   /* Wait for a reply... */
17472   W (ret);
17473   return ret;
17474 }
17475
17476 #define api_lisp_adjacencies_get api_one_adjacencies_get
17477
17478 static int
17479 api_gpe_native_fwd_rpaths_get (vat_main_t * vam)
17480 {
17481   unformat_input_t *i = vam->input;
17482   vl_api_gpe_native_fwd_rpaths_get_t *mp;
17483   int ret;
17484   u8 ip_family_set = 0, is_ip4 = 1;
17485
17486   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17487     {
17488       if (unformat (i, "ip4"))
17489         {
17490           ip_family_set = 1;
17491           is_ip4 = 1;
17492         }
17493       else if (unformat (i, "ip6"))
17494         {
17495           ip_family_set = 1;
17496           is_ip4 = 0;
17497         }
17498       else
17499         {
17500           errmsg ("parse error '%U'", format_unformat_error, i);
17501           return -99;
17502         }
17503     }
17504
17505   if (!ip_family_set)
17506     {
17507       errmsg ("ip family not set!");
17508       return -99;
17509     }
17510
17511   M (GPE_NATIVE_FWD_RPATHS_GET, mp);
17512   mp->is_ip4 = is_ip4;
17513
17514   /* send it... */
17515   S (mp);
17516
17517   /* Wait for a reply... */
17518   W (ret);
17519   return ret;
17520 }
17521
17522 static int
17523 api_gpe_fwd_entry_vnis_get (vat_main_t * vam)
17524 {
17525   vl_api_gpe_fwd_entry_vnis_get_t *mp;
17526   int ret;
17527
17528   if (!vam->json_output)
17529     {
17530       print (vam->ofp, "VNIs");
17531     }
17532
17533   M (GPE_FWD_ENTRY_VNIS_GET, mp);
17534
17535   /* send it... */
17536   S (mp);
17537
17538   /* Wait for a reply... */
17539   W (ret);
17540   return ret;
17541 }
17542
17543 static int
17544 api_gpe_add_del_native_fwd_rpath (vat_main_t * vam)
17545 {
17546   unformat_input_t *i = vam->input;
17547   vl_api_gpe_add_del_native_fwd_rpath_t *mp;
17548   int ret = 0;
17549   u8 is_add = 1, ip_set = 0, is_ip4 = 1;
17550   struct in_addr ip4;
17551   struct in6_addr ip6;
17552   u32 table_id = 0, nh_sw_if_index = ~0;
17553
17554   clib_memset (&ip4, 0, sizeof (ip4));
17555   clib_memset (&ip6, 0, sizeof (ip6));
17556
17557   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17558     {
17559       if (unformat (i, "del"))
17560         is_add = 0;
17561       else if (unformat (i, "via %U %U", unformat_ip4_address, &ip4,
17562                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
17563         {
17564           ip_set = 1;
17565           is_ip4 = 1;
17566         }
17567       else if (unformat (i, "via %U %U", unformat_ip6_address, &ip6,
17568                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
17569         {
17570           ip_set = 1;
17571           is_ip4 = 0;
17572         }
17573       else if (unformat (i, "via %U", unformat_ip4_address, &ip4))
17574         {
17575           ip_set = 1;
17576           is_ip4 = 1;
17577           nh_sw_if_index = ~0;
17578         }
17579       else if (unformat (i, "via %U", unformat_ip6_address, &ip6))
17580         {
17581           ip_set = 1;
17582           is_ip4 = 0;
17583           nh_sw_if_index = ~0;
17584         }
17585       else if (unformat (i, "table %d", &table_id))
17586         ;
17587       else
17588         {
17589           errmsg ("parse error '%U'", format_unformat_error, i);
17590           return -99;
17591         }
17592     }
17593
17594   if (!ip_set)
17595     {
17596       errmsg ("nh addr not set!");
17597       return -99;
17598     }
17599
17600   M (GPE_ADD_DEL_NATIVE_FWD_RPATH, mp);
17601   mp->is_add = is_add;
17602   mp->table_id = clib_host_to_net_u32 (table_id);
17603   mp->nh_sw_if_index = clib_host_to_net_u32 (nh_sw_if_index);
17604   mp->is_ip4 = is_ip4;
17605   if (is_ip4)
17606     clib_memcpy (mp->nh_addr, &ip4, sizeof (ip4));
17607   else
17608     clib_memcpy (mp->nh_addr, &ip6, sizeof (ip6));
17609
17610   /* send it... */
17611   S (mp);
17612
17613   /* Wait for a reply... */
17614   W (ret);
17615   return ret;
17616 }
17617
17618 static int
17619 api_one_map_server_dump (vat_main_t * vam)
17620 {
17621   vl_api_one_map_server_dump_t *mp;
17622   vl_api_control_ping_t *mp_ping;
17623   int ret;
17624
17625   if (!vam->json_output)
17626     {
17627       print (vam->ofp, "%=20s", "Map server");
17628     }
17629
17630   M (ONE_MAP_SERVER_DUMP, mp);
17631   /* send it... */
17632   S (mp);
17633
17634   /* Use a control ping for synchronization */
17635   MPING (CONTROL_PING, mp_ping);
17636   S (mp_ping);
17637
17638   /* Wait for a reply... */
17639   W (ret);
17640   return ret;
17641 }
17642
17643 #define api_lisp_map_server_dump api_one_map_server_dump
17644
17645 static int
17646 api_one_map_resolver_dump (vat_main_t * vam)
17647 {
17648   vl_api_one_map_resolver_dump_t *mp;
17649   vl_api_control_ping_t *mp_ping;
17650   int ret;
17651
17652   if (!vam->json_output)
17653     {
17654       print (vam->ofp, "%=20s", "Map resolver");
17655     }
17656
17657   M (ONE_MAP_RESOLVER_DUMP, mp);
17658   /* send it... */
17659   S (mp);
17660
17661   /* Use a control ping for synchronization */
17662   MPING (CONTROL_PING, mp_ping);
17663   S (mp_ping);
17664
17665   /* Wait for a reply... */
17666   W (ret);
17667   return ret;
17668 }
17669
17670 #define api_lisp_map_resolver_dump api_one_map_resolver_dump
17671
17672 static int
17673 api_one_stats_flush (vat_main_t * vam)
17674 {
17675   vl_api_one_stats_flush_t *mp;
17676   int ret = 0;
17677
17678   M (ONE_STATS_FLUSH, mp);
17679   S (mp);
17680   W (ret);
17681   return ret;
17682 }
17683
17684 static int
17685 api_one_stats_dump (vat_main_t * vam)
17686 {
17687   vl_api_one_stats_dump_t *mp;
17688   vl_api_control_ping_t *mp_ping;
17689   int ret;
17690
17691   M (ONE_STATS_DUMP, mp);
17692   /* send it... */
17693   S (mp);
17694
17695   /* Use a control ping for synchronization */
17696   MPING (CONTROL_PING, mp_ping);
17697   S (mp_ping);
17698
17699   /* Wait for a reply... */
17700   W (ret);
17701   return ret;
17702 }
17703
17704 static int
17705 api_show_one_status (vat_main_t * vam)
17706 {
17707   vl_api_show_one_status_t *mp;
17708   int ret;
17709
17710   if (!vam->json_output)
17711     {
17712       print (vam->ofp, "%-20s%-16s", "ONE status", "locator-set");
17713     }
17714
17715   M (SHOW_ONE_STATUS, mp);
17716   /* send it... */
17717   S (mp);
17718   /* Wait for a reply... */
17719   W (ret);
17720   return ret;
17721 }
17722
17723 #define api_show_lisp_status api_show_one_status
17724
17725 static int
17726 api_lisp_gpe_fwd_entry_path_dump (vat_main_t * vam)
17727 {
17728   vl_api_gpe_fwd_entry_path_dump_t *mp;
17729   vl_api_control_ping_t *mp_ping;
17730   unformat_input_t *i = vam->input;
17731   u32 fwd_entry_index = ~0;
17732   int ret;
17733
17734   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17735     {
17736       if (unformat (i, "index %d", &fwd_entry_index))
17737         ;
17738       else
17739         break;
17740     }
17741
17742   if (~0 == fwd_entry_index)
17743     {
17744       errmsg ("no index specified!");
17745       return -99;
17746     }
17747
17748   if (!vam->json_output)
17749     {
17750       print (vam->ofp, "first line");
17751     }
17752
17753   M (GPE_FWD_ENTRY_PATH_DUMP, mp);
17754
17755   /* send it... */
17756   S (mp);
17757   /* Use a control ping for synchronization */
17758   MPING (CONTROL_PING, mp_ping);
17759   S (mp_ping);
17760
17761   /* Wait for a reply... */
17762   W (ret);
17763   return ret;
17764 }
17765
17766 static int
17767 api_one_get_map_request_itr_rlocs (vat_main_t * vam)
17768 {
17769   vl_api_one_get_map_request_itr_rlocs_t *mp;
17770   int ret;
17771
17772   if (!vam->json_output)
17773     {
17774       print (vam->ofp, "%=20s", "itr-rlocs:");
17775     }
17776
17777   M (ONE_GET_MAP_REQUEST_ITR_RLOCS, mp);
17778   /* send it... */
17779   S (mp);
17780   /* Wait for a reply... */
17781   W (ret);
17782   return ret;
17783 }
17784
17785 #define api_lisp_get_map_request_itr_rlocs api_one_get_map_request_itr_rlocs
17786
17787 static int
17788 api_af_packet_create (vat_main_t * vam)
17789 {
17790   unformat_input_t *i = vam->input;
17791   vl_api_af_packet_create_t *mp;
17792   u8 *host_if_name = 0;
17793   u8 hw_addr[6];
17794   u8 random_hw_addr = 1;
17795   int ret;
17796
17797   clib_memset (hw_addr, 0, sizeof (hw_addr));
17798
17799   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17800     {
17801       if (unformat (i, "name %s", &host_if_name))
17802         vec_add1 (host_if_name, 0);
17803       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
17804         random_hw_addr = 0;
17805       else
17806         break;
17807     }
17808
17809   if (!vec_len (host_if_name))
17810     {
17811       errmsg ("host-interface name must be specified");
17812       return -99;
17813     }
17814
17815   if (vec_len (host_if_name) > 64)
17816     {
17817       errmsg ("host-interface name too long");
17818       return -99;
17819     }
17820
17821   M (AF_PACKET_CREATE, mp);
17822
17823   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
17824   clib_memcpy (mp->hw_addr, hw_addr, 6);
17825   mp->use_random_hw_addr = random_hw_addr;
17826   vec_free (host_if_name);
17827
17828   S (mp);
17829
17830   /* *INDENT-OFF* */
17831   W2 (ret,
17832       ({
17833         if (ret == 0)
17834           fprintf (vam->ofp ? vam->ofp : stderr,
17835                    " new sw_if_index = %d\n", vam->sw_if_index);
17836       }));
17837   /* *INDENT-ON* */
17838   return ret;
17839 }
17840
17841 static int
17842 api_af_packet_delete (vat_main_t * vam)
17843 {
17844   unformat_input_t *i = vam->input;
17845   vl_api_af_packet_delete_t *mp;
17846   u8 *host_if_name = 0;
17847   int ret;
17848
17849   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17850     {
17851       if (unformat (i, "name %s", &host_if_name))
17852         vec_add1 (host_if_name, 0);
17853       else
17854         break;
17855     }
17856
17857   if (!vec_len (host_if_name))
17858     {
17859       errmsg ("host-interface name must be specified");
17860       return -99;
17861     }
17862
17863   if (vec_len (host_if_name) > 64)
17864     {
17865       errmsg ("host-interface name too long");
17866       return -99;
17867     }
17868
17869   M (AF_PACKET_DELETE, mp);
17870
17871   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
17872   vec_free (host_if_name);
17873
17874   S (mp);
17875   W (ret);
17876   return ret;
17877 }
17878
17879 static void vl_api_af_packet_details_t_handler
17880   (vl_api_af_packet_details_t * mp)
17881 {
17882   vat_main_t *vam = &vat_main;
17883
17884   print (vam->ofp, "%-16s %d",
17885          mp->host_if_name, clib_net_to_host_u32 (mp->sw_if_index));
17886 }
17887
17888 static void vl_api_af_packet_details_t_handler_json
17889   (vl_api_af_packet_details_t * mp)
17890 {
17891   vat_main_t *vam = &vat_main;
17892   vat_json_node_t *node = NULL;
17893
17894   if (VAT_JSON_ARRAY != vam->json_tree.type)
17895     {
17896       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17897       vat_json_init_array (&vam->json_tree);
17898     }
17899   node = vat_json_array_add (&vam->json_tree);
17900
17901   vat_json_init_object (node);
17902   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
17903   vat_json_object_add_string_copy (node, "dev_name", mp->host_if_name);
17904 }
17905
17906 static int
17907 api_af_packet_dump (vat_main_t * vam)
17908 {
17909   vl_api_af_packet_dump_t *mp;
17910   vl_api_control_ping_t *mp_ping;
17911   int ret;
17912
17913   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
17914   /* Get list of tap interfaces */
17915   M (AF_PACKET_DUMP, mp);
17916   S (mp);
17917
17918   /* Use a control ping for synchronization */
17919   MPING (CONTROL_PING, mp_ping);
17920   S (mp_ping);
17921
17922   W (ret);
17923   return ret;
17924 }
17925
17926 static int
17927 api_policer_add_del (vat_main_t * vam)
17928 {
17929   unformat_input_t *i = vam->input;
17930   vl_api_policer_add_del_t *mp;
17931   u8 is_add = 1;
17932   u8 *name = 0;
17933   u32 cir = 0;
17934   u32 eir = 0;
17935   u64 cb = 0;
17936   u64 eb = 0;
17937   u8 rate_type = 0;
17938   u8 round_type = 0;
17939   u8 type = 0;
17940   u8 color_aware = 0;
17941   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
17942   int ret;
17943
17944   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
17945   conform_action.dscp = 0;
17946   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
17947   exceed_action.dscp = 0;
17948   violate_action.action_type = SSE2_QOS_ACTION_DROP;
17949   violate_action.dscp = 0;
17950
17951   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17952     {
17953       if (unformat (i, "del"))
17954         is_add = 0;
17955       else if (unformat (i, "name %s", &name))
17956         vec_add1 (name, 0);
17957       else if (unformat (i, "cir %u", &cir))
17958         ;
17959       else if (unformat (i, "eir %u", &eir))
17960         ;
17961       else if (unformat (i, "cb %u", &cb))
17962         ;
17963       else if (unformat (i, "eb %u", &eb))
17964         ;
17965       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
17966                          &rate_type))
17967         ;
17968       else if (unformat (i, "round_type %U", unformat_policer_round_type,
17969                          &round_type))
17970         ;
17971       else if (unformat (i, "type %U", unformat_policer_type, &type))
17972         ;
17973       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
17974                          &conform_action))
17975         ;
17976       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
17977                          &exceed_action))
17978         ;
17979       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
17980                          &violate_action))
17981         ;
17982       else if (unformat (i, "color-aware"))
17983         color_aware = 1;
17984       else
17985         break;
17986     }
17987
17988   if (!vec_len (name))
17989     {
17990       errmsg ("policer name must be specified");
17991       return -99;
17992     }
17993
17994   if (vec_len (name) > 64)
17995     {
17996       errmsg ("policer name too long");
17997       return -99;
17998     }
17999
18000   M (POLICER_ADD_DEL, mp);
18001
18002   clib_memcpy (mp->name, name, vec_len (name));
18003   vec_free (name);
18004   mp->is_add = is_add;
18005   mp->cir = ntohl (cir);
18006   mp->eir = ntohl (eir);
18007   mp->cb = clib_net_to_host_u64 (cb);
18008   mp->eb = clib_net_to_host_u64 (eb);
18009   mp->rate_type = rate_type;
18010   mp->round_type = round_type;
18011   mp->type = type;
18012   mp->conform_action_type = conform_action.action_type;
18013   mp->conform_dscp = conform_action.dscp;
18014   mp->exceed_action_type = exceed_action.action_type;
18015   mp->exceed_dscp = exceed_action.dscp;
18016   mp->violate_action_type = violate_action.action_type;
18017   mp->violate_dscp = violate_action.dscp;
18018   mp->color_aware = color_aware;
18019
18020   S (mp);
18021   W (ret);
18022   return ret;
18023 }
18024
18025 static int
18026 api_policer_dump (vat_main_t * vam)
18027 {
18028   unformat_input_t *i = vam->input;
18029   vl_api_policer_dump_t *mp;
18030   vl_api_control_ping_t *mp_ping;
18031   u8 *match_name = 0;
18032   u8 match_name_valid = 0;
18033   int ret;
18034
18035   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18036     {
18037       if (unformat (i, "name %s", &match_name))
18038         {
18039           vec_add1 (match_name, 0);
18040           match_name_valid = 1;
18041         }
18042       else
18043         break;
18044     }
18045
18046   M (POLICER_DUMP, mp);
18047   mp->match_name_valid = match_name_valid;
18048   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
18049   vec_free (match_name);
18050   /* send it... */
18051   S (mp);
18052
18053   /* Use a control ping for synchronization */
18054   MPING (CONTROL_PING, mp_ping);
18055   S (mp_ping);
18056
18057   /* Wait for a reply... */
18058   W (ret);
18059   return ret;
18060 }
18061
18062 static int
18063 api_policer_classify_set_interface (vat_main_t * vam)
18064 {
18065   unformat_input_t *i = vam->input;
18066   vl_api_policer_classify_set_interface_t *mp;
18067   u32 sw_if_index;
18068   int sw_if_index_set;
18069   u32 ip4_table_index = ~0;
18070   u32 ip6_table_index = ~0;
18071   u32 l2_table_index = ~0;
18072   u8 is_add = 1;
18073   int ret;
18074
18075   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18076     {
18077       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18078         sw_if_index_set = 1;
18079       else if (unformat (i, "sw_if_index %d", &sw_if_index))
18080         sw_if_index_set = 1;
18081       else if (unformat (i, "del"))
18082         is_add = 0;
18083       else if (unformat (i, "ip4-table %d", &ip4_table_index))
18084         ;
18085       else if (unformat (i, "ip6-table %d", &ip6_table_index))
18086         ;
18087       else if (unformat (i, "l2-table %d", &l2_table_index))
18088         ;
18089       else
18090         {
18091           clib_warning ("parse error '%U'", format_unformat_error, i);
18092           return -99;
18093         }
18094     }
18095
18096   if (sw_if_index_set == 0)
18097     {
18098       errmsg ("missing interface name or sw_if_index");
18099       return -99;
18100     }
18101
18102   M (POLICER_CLASSIFY_SET_INTERFACE, mp);
18103
18104   mp->sw_if_index = ntohl (sw_if_index);
18105   mp->ip4_table_index = ntohl (ip4_table_index);
18106   mp->ip6_table_index = ntohl (ip6_table_index);
18107   mp->l2_table_index = ntohl (l2_table_index);
18108   mp->is_add = is_add;
18109
18110   S (mp);
18111   W (ret);
18112   return ret;
18113 }
18114
18115 static int
18116 api_policer_classify_dump (vat_main_t * vam)
18117 {
18118   unformat_input_t *i = vam->input;
18119   vl_api_policer_classify_dump_t *mp;
18120   vl_api_control_ping_t *mp_ping;
18121   u8 type = POLICER_CLASSIFY_N_TABLES;
18122   int ret;
18123
18124   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
18125     ;
18126   else
18127     {
18128       errmsg ("classify table type must be specified");
18129       return -99;
18130     }
18131
18132   if (!vam->json_output)
18133     {
18134       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
18135     }
18136
18137   M (POLICER_CLASSIFY_DUMP, mp);
18138   mp->type = type;
18139   /* send it... */
18140   S (mp);
18141
18142   /* Use a control ping for synchronization */
18143   MPING (CONTROL_PING, mp_ping);
18144   S (mp_ping);
18145
18146   /* Wait for a reply... */
18147   W (ret);
18148   return ret;
18149 }
18150
18151 static int
18152 api_netmap_create (vat_main_t * vam)
18153 {
18154   unformat_input_t *i = vam->input;
18155   vl_api_netmap_create_t *mp;
18156   u8 *if_name = 0;
18157   u8 hw_addr[6];
18158   u8 random_hw_addr = 1;
18159   u8 is_pipe = 0;
18160   u8 is_master = 0;
18161   int ret;
18162
18163   clib_memset (hw_addr, 0, sizeof (hw_addr));
18164
18165   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18166     {
18167       if (unformat (i, "name %s", &if_name))
18168         vec_add1 (if_name, 0);
18169       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
18170         random_hw_addr = 0;
18171       else if (unformat (i, "pipe"))
18172         is_pipe = 1;
18173       else if (unformat (i, "master"))
18174         is_master = 1;
18175       else if (unformat (i, "slave"))
18176         is_master = 0;
18177       else
18178         break;
18179     }
18180
18181   if (!vec_len (if_name))
18182     {
18183       errmsg ("interface name must be specified");
18184       return -99;
18185     }
18186
18187   if (vec_len (if_name) > 64)
18188     {
18189       errmsg ("interface name too long");
18190       return -99;
18191     }
18192
18193   M (NETMAP_CREATE, mp);
18194
18195   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
18196   clib_memcpy (mp->hw_addr, hw_addr, 6);
18197   mp->use_random_hw_addr = random_hw_addr;
18198   mp->is_pipe = is_pipe;
18199   mp->is_master = is_master;
18200   vec_free (if_name);
18201
18202   S (mp);
18203   W (ret);
18204   return ret;
18205 }
18206
18207 static int
18208 api_netmap_delete (vat_main_t * vam)
18209 {
18210   unformat_input_t *i = vam->input;
18211   vl_api_netmap_delete_t *mp;
18212   u8 *if_name = 0;
18213   int ret;
18214
18215   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18216     {
18217       if (unformat (i, "name %s", &if_name))
18218         vec_add1 (if_name, 0);
18219       else
18220         break;
18221     }
18222
18223   if (!vec_len (if_name))
18224     {
18225       errmsg ("interface name must be specified");
18226       return -99;
18227     }
18228
18229   if (vec_len (if_name) > 64)
18230     {
18231       errmsg ("interface name too long");
18232       return -99;
18233     }
18234
18235   M (NETMAP_DELETE, mp);
18236
18237   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
18238   vec_free (if_name);
18239
18240   S (mp);
18241   W (ret);
18242   return ret;
18243 }
18244
18245 static u8 *
18246 format_fib_api_path_nh_proto (u8 * s, va_list * args)
18247 {
18248   vl_api_fib_path_nh_proto_t proto =
18249     va_arg (*args, vl_api_fib_path_nh_proto_t);
18250
18251   switch (proto)
18252     {
18253     case FIB_API_PATH_NH_PROTO_IP4:
18254       s = format (s, "ip4");
18255       break;
18256     case FIB_API_PATH_NH_PROTO_IP6:
18257       s = format (s, "ip6");
18258       break;
18259     case FIB_API_PATH_NH_PROTO_MPLS:
18260       s = format (s, "mpls");
18261       break;
18262     case FIB_API_PATH_NH_PROTO_BIER:
18263       s = format (s, "bier");
18264       break;
18265     case FIB_API_PATH_NH_PROTO_ETHERNET:
18266       s = format (s, "ethernet");
18267       break;
18268     }
18269
18270   return (s);
18271 }
18272
18273 static u8 *
18274 format_vl_api_ip_address_union (u8 * s, va_list * args)
18275 {
18276   vl_api_address_family_t af = va_arg (*args, vl_api_address_family_t);
18277   const vl_api_address_union_t *u = va_arg (*args, vl_api_address_union_t *);
18278
18279   switch (af)
18280     {
18281     case ADDRESS_IP4:
18282       s = format (s, "%U", format_ip4_address, u->ip4);
18283       break;
18284     case ADDRESS_IP6:
18285       s = format (s, "%U", format_ip6_address, u->ip6);
18286       break;
18287     }
18288   return (s);
18289 }
18290
18291 static u8 *
18292 format_vl_api_fib_path_type (u8 * s, va_list * args)
18293 {
18294   vl_api_fib_path_type_t t = va_arg (*args, vl_api_fib_path_type_t);
18295
18296   switch (t)
18297     {
18298     case FIB_API_PATH_TYPE_NORMAL:
18299       s = format (s, "normal");
18300       break;
18301     case FIB_API_PATH_TYPE_LOCAL:
18302       s = format (s, "local");
18303       break;
18304     case FIB_API_PATH_TYPE_DROP:
18305       s = format (s, "drop");
18306       break;
18307     case FIB_API_PATH_TYPE_UDP_ENCAP:
18308       s = format (s, "udp-encap");
18309       break;
18310     case FIB_API_PATH_TYPE_BIER_IMP:
18311       s = format (s, "bier-imp");
18312       break;
18313     case FIB_API_PATH_TYPE_ICMP_UNREACH:
18314       s = format (s, "unreach");
18315       break;
18316     case FIB_API_PATH_TYPE_ICMP_PROHIBIT:
18317       s = format (s, "prohibit");
18318       break;
18319     case FIB_API_PATH_TYPE_SOURCE_LOOKUP:
18320       s = format (s, "src-lookup");
18321       break;
18322     case FIB_API_PATH_TYPE_DVR:
18323       s = format (s, "dvr");
18324       break;
18325     case FIB_API_PATH_TYPE_INTERFACE_RX:
18326       s = format (s, "interface-rx");
18327       break;
18328     case FIB_API_PATH_TYPE_CLASSIFY:
18329       s = format (s, "classify");
18330       break;
18331     }
18332
18333   return (s);
18334 }
18335
18336 static void
18337 vl_api_fib_path_print (vat_main_t * vam, vl_api_fib_path_t * fp)
18338 {
18339   print (vam->ofp,
18340          "  weight %d, sw_if_index %d, type %U, afi %U, next_hop %U",
18341          ntohl (fp->weight), ntohl (fp->sw_if_index),
18342          format_vl_api_fib_path_type, fp->type,
18343          format_fib_api_path_nh_proto, fp->proto,
18344          format_vl_api_ip_address_union, &fp->nh.address);
18345 }
18346
18347 static void
18348 vl_api_mpls_fib_path_json_print (vat_json_node_t * node,
18349                                  vl_api_fib_path_t * fp)
18350 {
18351   struct in_addr ip4;
18352   struct in6_addr ip6;
18353
18354   vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
18355   vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
18356   vat_json_object_add_uint (node, "type", fp->type);
18357   vat_json_object_add_uint (node, "next_hop_proto", fp->proto);
18358   if (fp->proto == FIB_API_PATH_NH_PROTO_IP4)
18359     {
18360       clib_memcpy (&ip4, &fp->nh.address.ip4, sizeof (ip4));
18361       vat_json_object_add_ip4 (node, "next_hop", ip4);
18362     }
18363   else if (fp->proto == FIB_API_PATH_NH_PROTO_IP4)
18364     {
18365       clib_memcpy (&ip6, &fp->nh.address.ip6, sizeof (ip6));
18366       vat_json_object_add_ip6 (node, "next_hop", ip6);
18367     }
18368 }
18369
18370 static void
18371 vl_api_mpls_tunnel_details_t_handler (vl_api_mpls_tunnel_details_t * mp)
18372 {
18373   vat_main_t *vam = &vat_main;
18374   int count = ntohl (mp->mt_tunnel.mt_n_paths);
18375   vl_api_fib_path_t *fp;
18376   i32 i;
18377
18378   print (vam->ofp, "sw_if_index %d via:",
18379          ntohl (mp->mt_tunnel.mt_sw_if_index));
18380   fp = mp->mt_tunnel.mt_paths;
18381   for (i = 0; i < count; i++)
18382     {
18383       vl_api_fib_path_print (vam, fp);
18384       fp++;
18385     }
18386
18387   print (vam->ofp, "");
18388 }
18389
18390 #define vl_api_mpls_tunnel_details_t_endian vl_noop_handler
18391 #define vl_api_mpls_tunnel_details_t_print vl_noop_handler
18392
18393 static void
18394 vl_api_mpls_tunnel_details_t_handler_json (vl_api_mpls_tunnel_details_t * mp)
18395 {
18396   vat_main_t *vam = &vat_main;
18397   vat_json_node_t *node = NULL;
18398   int count = ntohl (mp->mt_tunnel.mt_n_paths);
18399   vl_api_fib_path_t *fp;
18400   i32 i;
18401
18402   if (VAT_JSON_ARRAY != vam->json_tree.type)
18403     {
18404       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18405       vat_json_init_array (&vam->json_tree);
18406     }
18407   node = vat_json_array_add (&vam->json_tree);
18408
18409   vat_json_init_object (node);
18410   vat_json_object_add_uint (node, "sw_if_index",
18411                             ntohl (mp->mt_tunnel.mt_sw_if_index));
18412
18413   vat_json_object_add_uint (node, "l2_only", mp->mt_tunnel.mt_l2_only);
18414
18415   fp = mp->mt_tunnel.mt_paths;
18416   for (i = 0; i < count; i++)
18417     {
18418       vl_api_mpls_fib_path_json_print (node, fp);
18419       fp++;
18420     }
18421 }
18422
18423 static int
18424 api_mpls_tunnel_dump (vat_main_t * vam)
18425 {
18426   vl_api_mpls_tunnel_dump_t *mp;
18427   vl_api_control_ping_t *mp_ping;
18428   int ret;
18429
18430   M (MPLS_TUNNEL_DUMP, mp);
18431
18432   S (mp);
18433
18434   /* Use a control ping for synchronization */
18435   MPING (CONTROL_PING, mp_ping);
18436   S (mp_ping);
18437
18438   W (ret);
18439   return ret;
18440 }
18441
18442 #define vl_api_mpls_table_details_t_endian vl_noop_handler
18443 #define vl_api_mpls_table_details_t_print vl_noop_handler
18444
18445
18446 static void
18447 vl_api_mpls_table_details_t_handler (vl_api_mpls_table_details_t * mp)
18448 {
18449   vat_main_t *vam = &vat_main;
18450
18451   print (vam->ofp, "table-id %d,", ntohl (mp->mt_table.mt_table_id));
18452 }
18453
18454 static void vl_api_mpls_table_details_t_handler_json
18455   (vl_api_mpls_table_details_t * mp)
18456 {
18457   vat_main_t *vam = &vat_main;
18458   vat_json_node_t *node = NULL;
18459
18460   if (VAT_JSON_ARRAY != vam->json_tree.type)
18461     {
18462       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18463       vat_json_init_array (&vam->json_tree);
18464     }
18465   node = vat_json_array_add (&vam->json_tree);
18466
18467   vat_json_init_object (node);
18468   vat_json_object_add_uint (node, "table", ntohl (mp->mt_table.mt_table_id));
18469 }
18470
18471 static int
18472 api_mpls_table_dump (vat_main_t * vam)
18473 {
18474   vl_api_mpls_table_dump_t *mp;
18475   vl_api_control_ping_t *mp_ping;
18476   int ret;
18477
18478   M (MPLS_TABLE_DUMP, mp);
18479   S (mp);
18480
18481   /* Use a control ping for synchronization */
18482   MPING (CONTROL_PING, mp_ping);
18483   S (mp_ping);
18484
18485   W (ret);
18486   return ret;
18487 }
18488
18489 #define vl_api_mpls_route_details_t_endian vl_noop_handler
18490 #define vl_api_mpls_route_details_t_print vl_noop_handler
18491
18492 static void
18493 vl_api_mpls_route_details_t_handler (vl_api_mpls_route_details_t * mp)
18494 {
18495   vat_main_t *vam = &vat_main;
18496   int count = (int) clib_net_to_host_u32 (mp->mr_route.mr_n_paths);
18497   vl_api_fib_path_t *fp;
18498   int i;
18499
18500   print (vam->ofp,
18501          "table-id %d, label %u, ess_bit %u",
18502          ntohl (mp->mr_route.mr_table_id),
18503          ntohl (mp->mr_route.mr_label), mp->mr_route.mr_eos);
18504   fp = mp->mr_route.mr_paths;
18505   for (i = 0; i < count; i++)
18506     {
18507       vl_api_fib_path_print (vam, fp);
18508       fp++;
18509     }
18510 }
18511
18512 static void vl_api_mpls_route_details_t_handler_json
18513   (vl_api_mpls_route_details_t * mp)
18514 {
18515   vat_main_t *vam = &vat_main;
18516   int count = (int) clib_host_to_net_u32 (mp->mr_route.mr_n_paths);
18517   vat_json_node_t *node = NULL;
18518   vl_api_fib_path_t *fp;
18519   int i;
18520
18521   if (VAT_JSON_ARRAY != vam->json_tree.type)
18522     {
18523       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18524       vat_json_init_array (&vam->json_tree);
18525     }
18526   node = vat_json_array_add (&vam->json_tree);
18527
18528   vat_json_init_object (node);
18529   vat_json_object_add_uint (node, "table", ntohl (mp->mr_route.mr_table_id));
18530   vat_json_object_add_uint (node, "s_bit", mp->mr_route.mr_eos);
18531   vat_json_object_add_uint (node, "label", ntohl (mp->mr_route.mr_label));
18532   vat_json_object_add_uint (node, "path_count", count);
18533   fp = mp->mr_route.mr_paths;
18534   for (i = 0; i < count; i++)
18535     {
18536       vl_api_mpls_fib_path_json_print (node, fp);
18537       fp++;
18538     }
18539 }
18540
18541 static int
18542 api_mpls_route_dump (vat_main_t * vam)
18543 {
18544   unformat_input_t *input = vam->input;
18545   vl_api_mpls_route_dump_t *mp;
18546   vl_api_control_ping_t *mp_ping;
18547   u32 table_id;
18548   int ret;
18549
18550   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18551     {
18552       if (unformat (input, "table_id %d", &table_id))
18553         ;
18554       else
18555         break;
18556     }
18557   if (table_id == ~0)
18558     {
18559       errmsg ("missing table id");
18560       return -99;
18561     }
18562
18563   M (MPLS_ROUTE_DUMP, mp);
18564
18565   mp->table.mt_table_id = ntohl (table_id);
18566   S (mp);
18567
18568   /* Use a control ping for synchronization */
18569   MPING (CONTROL_PING, mp_ping);
18570   S (mp_ping);
18571
18572   W (ret);
18573   return ret;
18574 }
18575
18576 #define vl_api_ip_table_details_t_endian vl_noop_handler
18577 #define vl_api_ip_table_details_t_print vl_noop_handler
18578
18579 static void
18580 vl_api_ip_table_details_t_handler (vl_api_ip_table_details_t * mp)
18581 {
18582   vat_main_t *vam = &vat_main;
18583
18584   print (vam->ofp,
18585          "%s; table-id %d, prefix %U/%d",
18586          mp->table.name, ntohl (mp->table.table_id));
18587 }
18588
18589
18590 static void vl_api_ip_table_details_t_handler_json
18591   (vl_api_ip_table_details_t * mp)
18592 {
18593   vat_main_t *vam = &vat_main;
18594   vat_json_node_t *node = NULL;
18595
18596   if (VAT_JSON_ARRAY != vam->json_tree.type)
18597     {
18598       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18599       vat_json_init_array (&vam->json_tree);
18600     }
18601   node = vat_json_array_add (&vam->json_tree);
18602
18603   vat_json_init_object (node);
18604   vat_json_object_add_uint (node, "table", ntohl (mp->table.table_id));
18605 }
18606
18607 static int
18608 api_ip_table_dump (vat_main_t * vam)
18609 {
18610   vl_api_ip_table_dump_t *mp;
18611   vl_api_control_ping_t *mp_ping;
18612   int ret;
18613
18614   M (IP_TABLE_DUMP, mp);
18615   S (mp);
18616
18617   /* Use a control ping for synchronization */
18618   MPING (CONTROL_PING, mp_ping);
18619   S (mp_ping);
18620
18621   W (ret);
18622   return ret;
18623 }
18624
18625 static int
18626 api_ip_mtable_dump (vat_main_t * vam)
18627 {
18628   vl_api_ip_mtable_dump_t *mp;
18629   vl_api_control_ping_t *mp_ping;
18630   int ret;
18631
18632   M (IP_MTABLE_DUMP, mp);
18633   S (mp);
18634
18635   /* Use a control ping for synchronization */
18636   MPING (CONTROL_PING, mp_ping);
18637   S (mp_ping);
18638
18639   W (ret);
18640   return ret;
18641 }
18642
18643 static int
18644 api_ip_mroute_dump (vat_main_t * vam)
18645 {
18646   unformat_input_t *input = vam->input;
18647   vl_api_control_ping_t *mp_ping;
18648   vl_api_ip_mroute_dump_t *mp;
18649   int ret, is_ip6;
18650   u32 table_id;
18651
18652   is_ip6 = 0;
18653   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18654     {
18655       if (unformat (input, "table_id %d", &table_id))
18656         ;
18657       else if (unformat (input, "ip6"))
18658         is_ip6 = 1;
18659       else if (unformat (input, "ip4"))
18660         is_ip6 = 0;
18661       else
18662         break;
18663     }
18664   if (table_id == ~0)
18665     {
18666       errmsg ("missing table id");
18667       return -99;
18668     }
18669
18670   M (IP_MROUTE_DUMP, mp);
18671   mp->table.table_id = table_id;
18672   mp->table.is_ip6 = is_ip6;
18673   S (mp);
18674
18675   /* Use a control ping for synchronization */
18676   MPING (CONTROL_PING, mp_ping);
18677   S (mp_ping);
18678
18679   W (ret);
18680   return ret;
18681 }
18682
18683 static void vl_api_ip_neighbor_details_t_handler
18684   (vl_api_ip_neighbor_details_t * mp)
18685 {
18686   vat_main_t *vam = &vat_main;
18687
18688   print (vam->ofp, "%c %U %U",
18689          (ntohl (mp->neighbor.flags) & IP_NEIGHBOR_FLAG_STATIC) ? 'S' : 'D',
18690          format_vl_api_mac_address, &mp->neighbor.mac_address,
18691          format_vl_api_address, &mp->neighbor.ip_address);
18692 }
18693
18694 static void vl_api_ip_neighbor_details_t_handler_json
18695   (vl_api_ip_neighbor_details_t * mp)
18696 {
18697
18698   vat_main_t *vam = &vat_main;
18699   vat_json_node_t *node;
18700
18701   if (VAT_JSON_ARRAY != vam->json_tree.type)
18702     {
18703       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18704       vat_json_init_array (&vam->json_tree);
18705     }
18706   node = vat_json_array_add (&vam->json_tree);
18707
18708   vat_json_init_object (node);
18709   vat_json_object_add_string_copy
18710     (node, "flag",
18711      ((ntohl (mp->neighbor.flags) & IP_NEIGHBOR_FLAG_STATIC) ?
18712       (u8 *) "static" : (u8 *) "dynamic"));
18713
18714   vat_json_object_add_string_copy (node, "link_layer",
18715                                    format (0, "%U", format_vl_api_mac_address,
18716                                            &mp->neighbor.mac_address));
18717   vat_json_object_add_address (node, "ip", &mp->neighbor.ip_address);
18718 }
18719
18720 static int
18721 api_ip_neighbor_dump (vat_main_t * vam)
18722 {
18723   unformat_input_t *i = vam->input;
18724   vl_api_ip_neighbor_dump_t *mp;
18725   vl_api_control_ping_t *mp_ping;
18726   u8 is_ipv6 = 0;
18727   u32 sw_if_index = ~0;
18728   int ret;
18729
18730   /* Parse args required to build the message */
18731   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18732     {
18733       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18734         ;
18735       else if (unformat (i, "sw_if_index %d", &sw_if_index))
18736         ;
18737       else if (unformat (i, "ip6"))
18738         is_ipv6 = 1;
18739       else
18740         break;
18741     }
18742
18743   if (sw_if_index == ~0)
18744     {
18745       errmsg ("missing interface name or sw_if_index");
18746       return -99;
18747     }
18748
18749   M (IP_NEIGHBOR_DUMP, mp);
18750   mp->is_ipv6 = (u8) is_ipv6;
18751   mp->sw_if_index = ntohl (sw_if_index);
18752   S (mp);
18753
18754   /* Use a control ping for synchronization */
18755   MPING (CONTROL_PING, mp_ping);
18756   S (mp_ping);
18757
18758   W (ret);
18759   return ret;
18760 }
18761
18762 #define vl_api_ip_route_details_t_endian vl_noop_handler
18763 #define vl_api_ip_route_details_t_print vl_noop_handler
18764
18765 static void
18766 vl_api_ip_route_details_t_handler (vl_api_ip_route_details_t * mp)
18767 {
18768   vat_main_t *vam = &vat_main;
18769   u8 count = mp->route.n_paths;
18770   vl_api_fib_path_t *fp;
18771   int i;
18772
18773   print (vam->ofp,
18774          "table-id %d, prefix %U/%d",
18775          ntohl (mp->route.table_id),
18776          format_ip46_address, mp->route.prefix.address, mp->route.prefix.len);
18777   for (i = 0; i < count; i++)
18778     {
18779       fp = &mp->route.paths[i];
18780
18781       vl_api_fib_path_print (vam, fp);
18782       fp++;
18783     }
18784 }
18785
18786 static void vl_api_ip_route_details_t_handler_json
18787   (vl_api_ip_route_details_t * mp)
18788 {
18789   vat_main_t *vam = &vat_main;
18790   u8 count = mp->route.n_paths;
18791   vat_json_node_t *node = NULL;
18792   struct in_addr ip4;
18793   struct in6_addr ip6;
18794   vl_api_fib_path_t *fp;
18795   int i;
18796
18797   if (VAT_JSON_ARRAY != vam->json_tree.type)
18798     {
18799       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18800       vat_json_init_array (&vam->json_tree);
18801     }
18802   node = vat_json_array_add (&vam->json_tree);
18803
18804   vat_json_init_object (node);
18805   vat_json_object_add_uint (node, "table", ntohl (mp->route.table_id));
18806   if (ADDRESS_IP6 == mp->route.prefix.address.af)
18807     {
18808       clib_memcpy (&ip6, &mp->route.prefix.address.un.ip6, sizeof (ip6));
18809       vat_json_object_add_ip6 (node, "prefix", ip6);
18810     }
18811   else
18812     {
18813       clib_memcpy (&ip4, &mp->route.prefix.address.un.ip4, sizeof (ip4));
18814       vat_json_object_add_ip4 (node, "prefix", ip4);
18815     }
18816   vat_json_object_add_uint (node, "mask_length", mp->route.prefix.len);
18817   vat_json_object_add_uint (node, "path_count", count);
18818   for (i = 0; i < count; i++)
18819     {
18820       fp = &mp->route.paths[i];
18821       vl_api_mpls_fib_path_json_print (node, fp);
18822     }
18823 }
18824
18825 static int
18826 api_ip_route_dump (vat_main_t * vam)
18827 {
18828   unformat_input_t *input = vam->input;
18829   vl_api_ip_route_dump_t *mp;
18830   vl_api_control_ping_t *mp_ping;
18831   u32 table_id;
18832   u8 is_ip6;
18833   int ret;
18834
18835   is_ip6 = 0;
18836   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18837     {
18838       if (unformat (input, "table_id %d", &table_id))
18839         ;
18840       else if (unformat (input, "ip6"))
18841         is_ip6 = 1;
18842       else if (unformat (input, "ip4"))
18843         is_ip6 = 0;
18844       else
18845         break;
18846     }
18847   if (table_id == ~0)
18848     {
18849       errmsg ("missing table id");
18850       return -99;
18851     }
18852
18853   M (IP_ROUTE_DUMP, mp);
18854
18855   mp->table.table_id = table_id;
18856   mp->table.is_ip6 = is_ip6;
18857
18858   S (mp);
18859
18860   /* Use a control ping for synchronization */
18861   MPING (CONTROL_PING, mp_ping);
18862   S (mp_ping);
18863
18864   W (ret);
18865   return ret;
18866 }
18867
18868 int
18869 api_classify_table_ids (vat_main_t * vam)
18870 {
18871   vl_api_classify_table_ids_t *mp;
18872   int ret;
18873
18874   /* Construct the API message */
18875   M (CLASSIFY_TABLE_IDS, mp);
18876   mp->context = 0;
18877
18878   S (mp);
18879   W (ret);
18880   return ret;
18881 }
18882
18883 int
18884 api_classify_table_by_interface (vat_main_t * vam)
18885 {
18886   unformat_input_t *input = vam->input;
18887   vl_api_classify_table_by_interface_t *mp;
18888
18889   u32 sw_if_index = ~0;
18890   int ret;
18891   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18892     {
18893       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18894         ;
18895       else if (unformat (input, "sw_if_index %d", &sw_if_index))
18896         ;
18897       else
18898         break;
18899     }
18900   if (sw_if_index == ~0)
18901     {
18902       errmsg ("missing interface name or sw_if_index");
18903       return -99;
18904     }
18905
18906   /* Construct the API message */
18907   M (CLASSIFY_TABLE_BY_INTERFACE, mp);
18908   mp->context = 0;
18909   mp->sw_if_index = ntohl (sw_if_index);
18910
18911   S (mp);
18912   W (ret);
18913   return ret;
18914 }
18915
18916 int
18917 api_classify_table_info (vat_main_t * vam)
18918 {
18919   unformat_input_t *input = vam->input;
18920   vl_api_classify_table_info_t *mp;
18921
18922   u32 table_id = ~0;
18923   int ret;
18924   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18925     {
18926       if (unformat (input, "table_id %d", &table_id))
18927         ;
18928       else
18929         break;
18930     }
18931   if (table_id == ~0)
18932     {
18933       errmsg ("missing table id");
18934       return -99;
18935     }
18936
18937   /* Construct the API message */
18938   M (CLASSIFY_TABLE_INFO, mp);
18939   mp->context = 0;
18940   mp->table_id = ntohl (table_id);
18941
18942   S (mp);
18943   W (ret);
18944   return ret;
18945 }
18946
18947 int
18948 api_classify_session_dump (vat_main_t * vam)
18949 {
18950   unformat_input_t *input = vam->input;
18951   vl_api_classify_session_dump_t *mp;
18952   vl_api_control_ping_t *mp_ping;
18953
18954   u32 table_id = ~0;
18955   int ret;
18956   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18957     {
18958       if (unformat (input, "table_id %d", &table_id))
18959         ;
18960       else
18961         break;
18962     }
18963   if (table_id == ~0)
18964     {
18965       errmsg ("missing table id");
18966       return -99;
18967     }
18968
18969   /* Construct the API message */
18970   M (CLASSIFY_SESSION_DUMP, mp);
18971   mp->context = 0;
18972   mp->table_id = ntohl (table_id);
18973   S (mp);
18974
18975   /* Use a control ping for synchronization */
18976   MPING (CONTROL_PING, mp_ping);
18977   S (mp_ping);
18978
18979   W (ret);
18980   return ret;
18981 }
18982
18983 static void
18984 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
18985 {
18986   vat_main_t *vam = &vat_main;
18987
18988   print (vam->ofp, "collector_address %U, collector_port %d, "
18989          "src_address %U, vrf_id %d, path_mtu %u, "
18990          "template_interval %u, udp_checksum %d",
18991          format_ip4_address, mp->collector_address,
18992          ntohs (mp->collector_port),
18993          format_ip4_address, mp->src_address,
18994          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
18995          ntohl (mp->template_interval), mp->udp_checksum);
18996
18997   vam->retval = 0;
18998   vam->result_ready = 1;
18999 }
19000
19001 static void
19002   vl_api_ipfix_exporter_details_t_handler_json
19003   (vl_api_ipfix_exporter_details_t * mp)
19004 {
19005   vat_main_t *vam = &vat_main;
19006   vat_json_node_t node;
19007   struct in_addr collector_address;
19008   struct in_addr src_address;
19009
19010   vat_json_init_object (&node);
19011   clib_memcpy (&collector_address, &mp->collector_address,
19012                sizeof (collector_address));
19013   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
19014   vat_json_object_add_uint (&node, "collector_port",
19015                             ntohs (mp->collector_port));
19016   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
19017   vat_json_object_add_ip4 (&node, "src_address", src_address);
19018   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
19019   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
19020   vat_json_object_add_uint (&node, "template_interval",
19021                             ntohl (mp->template_interval));
19022   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
19023
19024   vat_json_print (vam->ofp, &node);
19025   vat_json_free (&node);
19026   vam->retval = 0;
19027   vam->result_ready = 1;
19028 }
19029
19030 int
19031 api_ipfix_exporter_dump (vat_main_t * vam)
19032 {
19033   vl_api_ipfix_exporter_dump_t *mp;
19034   int ret;
19035
19036   /* Construct the API message */
19037   M (IPFIX_EXPORTER_DUMP, mp);
19038   mp->context = 0;
19039
19040   S (mp);
19041   W (ret);
19042   return ret;
19043 }
19044
19045 static int
19046 api_ipfix_classify_stream_dump (vat_main_t * vam)
19047 {
19048   vl_api_ipfix_classify_stream_dump_t *mp;
19049   int ret;
19050
19051   /* Construct the API message */
19052   M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
19053   mp->context = 0;
19054
19055   S (mp);
19056   W (ret);
19057   return ret;
19058   /* NOTREACHED */
19059   return 0;
19060 }
19061
19062 static void
19063   vl_api_ipfix_classify_stream_details_t_handler
19064   (vl_api_ipfix_classify_stream_details_t * mp)
19065 {
19066   vat_main_t *vam = &vat_main;
19067   print (vam->ofp, "domain_id %d, src_port %d",
19068          ntohl (mp->domain_id), ntohs (mp->src_port));
19069   vam->retval = 0;
19070   vam->result_ready = 1;
19071 }
19072
19073 static void
19074   vl_api_ipfix_classify_stream_details_t_handler_json
19075   (vl_api_ipfix_classify_stream_details_t * mp)
19076 {
19077   vat_main_t *vam = &vat_main;
19078   vat_json_node_t node;
19079
19080   vat_json_init_object (&node);
19081   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
19082   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
19083
19084   vat_json_print (vam->ofp, &node);
19085   vat_json_free (&node);
19086   vam->retval = 0;
19087   vam->result_ready = 1;
19088 }
19089
19090 static int
19091 api_ipfix_classify_table_dump (vat_main_t * vam)
19092 {
19093   vl_api_ipfix_classify_table_dump_t *mp;
19094   vl_api_control_ping_t *mp_ping;
19095   int ret;
19096
19097   if (!vam->json_output)
19098     {
19099       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
19100              "transport_protocol");
19101     }
19102
19103   /* Construct the API message */
19104   M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
19105
19106   /* send it... */
19107   S (mp);
19108
19109   /* Use a control ping for synchronization */
19110   MPING (CONTROL_PING, mp_ping);
19111   S (mp_ping);
19112
19113   W (ret);
19114   return ret;
19115 }
19116
19117 static void
19118   vl_api_ipfix_classify_table_details_t_handler
19119   (vl_api_ipfix_classify_table_details_t * mp)
19120 {
19121   vat_main_t *vam = &vat_main;
19122   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
19123          mp->transport_protocol);
19124 }
19125
19126 static void
19127   vl_api_ipfix_classify_table_details_t_handler_json
19128   (vl_api_ipfix_classify_table_details_t * mp)
19129 {
19130   vat_json_node_t *node = NULL;
19131   vat_main_t *vam = &vat_main;
19132
19133   if (VAT_JSON_ARRAY != vam->json_tree.type)
19134     {
19135       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19136       vat_json_init_array (&vam->json_tree);
19137     }
19138
19139   node = vat_json_array_add (&vam->json_tree);
19140   vat_json_init_object (node);
19141
19142   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
19143   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
19144   vat_json_object_add_uint (node, "transport_protocol",
19145                             mp->transport_protocol);
19146 }
19147
19148 static int
19149 api_sw_interface_span_enable_disable (vat_main_t * vam)
19150 {
19151   unformat_input_t *i = vam->input;
19152   vl_api_sw_interface_span_enable_disable_t *mp;
19153   u32 src_sw_if_index = ~0;
19154   u32 dst_sw_if_index = ~0;
19155   u8 state = 3;
19156   int ret;
19157   u8 is_l2 = 0;
19158
19159   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19160     {
19161       if (unformat
19162           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
19163         ;
19164       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
19165         ;
19166       else
19167         if (unformat
19168             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
19169         ;
19170       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
19171         ;
19172       else if (unformat (i, "disable"))
19173         state = 0;
19174       else if (unformat (i, "rx"))
19175         state = 1;
19176       else if (unformat (i, "tx"))
19177         state = 2;
19178       else if (unformat (i, "both"))
19179         state = 3;
19180       else if (unformat (i, "l2"))
19181         is_l2 = 1;
19182       else
19183         break;
19184     }
19185
19186   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
19187
19188   mp->sw_if_index_from = htonl (src_sw_if_index);
19189   mp->sw_if_index_to = htonl (dst_sw_if_index);
19190   mp->state = state;
19191   mp->is_l2 = is_l2;
19192
19193   S (mp);
19194   W (ret);
19195   return ret;
19196 }
19197
19198 static void
19199 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
19200                                             * mp)
19201 {
19202   vat_main_t *vam = &vat_main;
19203   u8 *sw_if_from_name = 0;
19204   u8 *sw_if_to_name = 0;
19205   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
19206   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
19207   char *states[] = { "none", "rx", "tx", "both" };
19208   hash_pair_t *p;
19209
19210   /* *INDENT-OFF* */
19211   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
19212   ({
19213     if ((u32) p->value[0] == sw_if_index_from)
19214       {
19215         sw_if_from_name = (u8 *)(p->key);
19216         if (sw_if_to_name)
19217           break;
19218       }
19219     if ((u32) p->value[0] == sw_if_index_to)
19220       {
19221         sw_if_to_name = (u8 *)(p->key);
19222         if (sw_if_from_name)
19223           break;
19224       }
19225   }));
19226   /* *INDENT-ON* */
19227   print (vam->ofp, "%20s => %20s (%s) %s",
19228          sw_if_from_name, sw_if_to_name, states[mp->state],
19229          mp->is_l2 ? "l2" : "device");
19230 }
19231
19232 static void
19233   vl_api_sw_interface_span_details_t_handler_json
19234   (vl_api_sw_interface_span_details_t * mp)
19235 {
19236   vat_main_t *vam = &vat_main;
19237   vat_json_node_t *node = NULL;
19238   u8 *sw_if_from_name = 0;
19239   u8 *sw_if_to_name = 0;
19240   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
19241   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
19242   hash_pair_t *p;
19243
19244   /* *INDENT-OFF* */
19245   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
19246   ({
19247     if ((u32) p->value[0] == sw_if_index_from)
19248       {
19249         sw_if_from_name = (u8 *)(p->key);
19250         if (sw_if_to_name)
19251           break;
19252       }
19253     if ((u32) p->value[0] == sw_if_index_to)
19254       {
19255         sw_if_to_name = (u8 *)(p->key);
19256         if (sw_if_from_name)
19257           break;
19258       }
19259   }));
19260   /* *INDENT-ON* */
19261
19262   if (VAT_JSON_ARRAY != vam->json_tree.type)
19263     {
19264       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19265       vat_json_init_array (&vam->json_tree);
19266     }
19267   node = vat_json_array_add (&vam->json_tree);
19268
19269   vat_json_init_object (node);
19270   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
19271   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
19272   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
19273   if (0 != sw_if_to_name)
19274     {
19275       vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
19276     }
19277   vat_json_object_add_uint (node, "state", mp->state);
19278   vat_json_object_add_uint (node, "is-l2", mp->is_l2);
19279 }
19280
19281 static int
19282 api_sw_interface_span_dump (vat_main_t * vam)
19283 {
19284   unformat_input_t *input = vam->input;
19285   vl_api_sw_interface_span_dump_t *mp;
19286   vl_api_control_ping_t *mp_ping;
19287   u8 is_l2 = 0;
19288   int ret;
19289
19290   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19291     {
19292       if (unformat (input, "l2"))
19293         is_l2 = 1;
19294       else
19295         break;
19296     }
19297
19298   M (SW_INTERFACE_SPAN_DUMP, mp);
19299   mp->is_l2 = is_l2;
19300   S (mp);
19301
19302   /* Use a control ping for synchronization */
19303   MPING (CONTROL_PING, mp_ping);
19304   S (mp_ping);
19305
19306   W (ret);
19307   return ret;
19308 }
19309
19310 int
19311 api_pg_create_interface (vat_main_t * vam)
19312 {
19313   unformat_input_t *input = vam->input;
19314   vl_api_pg_create_interface_t *mp;
19315
19316   u32 if_id = ~0, gso_size = 0;
19317   u8 gso_enabled = 0;
19318   int ret;
19319   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19320     {
19321       if (unformat (input, "if_id %d", &if_id))
19322         ;
19323       else if (unformat (input, "gso-enabled"))
19324         {
19325           gso_enabled = 1;
19326           if (unformat (input, "gso-size %u", &gso_size))
19327             ;
19328           else
19329             {
19330               errmsg ("missing gso-size");
19331               return -99;
19332             }
19333         }
19334       else
19335         break;
19336     }
19337   if (if_id == ~0)
19338     {
19339       errmsg ("missing pg interface index");
19340       return -99;
19341     }
19342
19343   /* Construct the API message */
19344   M (PG_CREATE_INTERFACE, mp);
19345   mp->context = 0;
19346   mp->interface_id = ntohl (if_id);
19347   mp->gso_enabled = gso_enabled;
19348
19349   S (mp);
19350   W (ret);
19351   return ret;
19352 }
19353
19354 int
19355 api_pg_capture (vat_main_t * vam)
19356 {
19357   unformat_input_t *input = vam->input;
19358   vl_api_pg_capture_t *mp;
19359
19360   u32 if_id = ~0;
19361   u8 enable = 1;
19362   u32 count = 1;
19363   u8 pcap_file_set = 0;
19364   u8 *pcap_file = 0;
19365   int ret;
19366   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19367     {
19368       if (unformat (input, "if_id %d", &if_id))
19369         ;
19370       else if (unformat (input, "pcap %s", &pcap_file))
19371         pcap_file_set = 1;
19372       else if (unformat (input, "count %d", &count))
19373         ;
19374       else if (unformat (input, "disable"))
19375         enable = 0;
19376       else
19377         break;
19378     }
19379   if (if_id == ~0)
19380     {
19381       errmsg ("missing pg interface index");
19382       return -99;
19383     }
19384   if (pcap_file_set > 0)
19385     {
19386       if (vec_len (pcap_file) > 255)
19387         {
19388           errmsg ("pcap file name is too long");
19389           return -99;
19390         }
19391     }
19392
19393   u32 name_len = vec_len (pcap_file);
19394   /* Construct the API message */
19395   M (PG_CAPTURE, mp);
19396   mp->context = 0;
19397   mp->interface_id = ntohl (if_id);
19398   mp->is_enabled = enable;
19399   mp->count = ntohl (count);
19400   mp->pcap_name_length = ntohl (name_len);
19401   if (pcap_file_set != 0)
19402     {
19403       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
19404     }
19405   vec_free (pcap_file);
19406
19407   S (mp);
19408   W (ret);
19409   return ret;
19410 }
19411
19412 int
19413 api_pg_enable_disable (vat_main_t * vam)
19414 {
19415   unformat_input_t *input = vam->input;
19416   vl_api_pg_enable_disable_t *mp;
19417
19418   u8 enable = 1;
19419   u8 stream_name_set = 0;
19420   u8 *stream_name = 0;
19421   int ret;
19422   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19423     {
19424       if (unformat (input, "stream %s", &stream_name))
19425         stream_name_set = 1;
19426       else if (unformat (input, "disable"))
19427         enable = 0;
19428       else
19429         break;
19430     }
19431
19432   if (stream_name_set > 0)
19433     {
19434       if (vec_len (stream_name) > 255)
19435         {
19436           errmsg ("stream name too long");
19437           return -99;
19438         }
19439     }
19440
19441   u32 name_len = vec_len (stream_name);
19442   /* Construct the API message */
19443   M (PG_ENABLE_DISABLE, mp);
19444   mp->context = 0;
19445   mp->is_enabled = enable;
19446   if (stream_name_set != 0)
19447     {
19448       mp->stream_name_length = ntohl (name_len);
19449       clib_memcpy (mp->stream_name, stream_name, name_len);
19450     }
19451   vec_free (stream_name);
19452
19453   S (mp);
19454   W (ret);
19455   return ret;
19456 }
19457
19458 int
19459 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
19460 {
19461   unformat_input_t *input = vam->input;
19462   vl_api_ip_source_and_port_range_check_add_del_t *mp;
19463
19464   u16 *low_ports = 0;
19465   u16 *high_ports = 0;
19466   u16 this_low;
19467   u16 this_hi;
19468   vl_api_prefix_t prefix;
19469   u32 tmp, tmp2;
19470   u8 prefix_set = 0;
19471   u32 vrf_id = ~0;
19472   u8 is_add = 1;
19473   int ret;
19474
19475   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19476     {
19477       if (unformat (input, "%U", unformat_vl_api_prefix, &prefix))
19478         prefix_set = 1;
19479       else if (unformat (input, "vrf %d", &vrf_id))
19480         ;
19481       else if (unformat (input, "del"))
19482         is_add = 0;
19483       else if (unformat (input, "port %d", &tmp))
19484         {
19485           if (tmp == 0 || tmp > 65535)
19486             {
19487               errmsg ("port %d out of range", tmp);
19488               return -99;
19489             }
19490           this_low = tmp;
19491           this_hi = this_low + 1;
19492           vec_add1 (low_ports, this_low);
19493           vec_add1 (high_ports, this_hi);
19494         }
19495       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
19496         {
19497           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
19498             {
19499               errmsg ("incorrect range parameters");
19500               return -99;
19501             }
19502           this_low = tmp;
19503           /* Note: in debug CLI +1 is added to high before
19504              passing to real fn that does "the work"
19505              (ip_source_and_port_range_check_add_del).
19506              This fn is a wrapper around the binary API fn a
19507              control plane will call, which expects this increment
19508              to have occurred. Hence letting the binary API control
19509              plane fn do the increment for consistency between VAT
19510              and other control planes.
19511            */
19512           this_hi = tmp2;
19513           vec_add1 (low_ports, this_low);
19514           vec_add1 (high_ports, this_hi);
19515         }
19516       else
19517         break;
19518     }
19519
19520   if (prefix_set == 0)
19521     {
19522       errmsg ("<address>/<mask> not specified");
19523       return -99;
19524     }
19525
19526   if (vrf_id == ~0)
19527     {
19528       errmsg ("VRF ID required, not specified");
19529       return -99;
19530     }
19531
19532   if (vrf_id == 0)
19533     {
19534       errmsg
19535         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
19536       return -99;
19537     }
19538
19539   if (vec_len (low_ports) == 0)
19540     {
19541       errmsg ("At least one port or port range required");
19542       return -99;
19543     }
19544
19545   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
19546
19547   mp->is_add = is_add;
19548
19549   clib_memcpy (&mp->prefix, &prefix, sizeof (prefix));
19550
19551   mp->number_of_ranges = vec_len (low_ports);
19552
19553   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
19554   vec_free (low_ports);
19555
19556   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
19557   vec_free (high_ports);
19558
19559   mp->vrf_id = ntohl (vrf_id);
19560
19561   S (mp);
19562   W (ret);
19563   return ret;
19564 }
19565
19566 int
19567 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
19568 {
19569   unformat_input_t *input = vam->input;
19570   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
19571   u32 sw_if_index = ~0;
19572   int vrf_set = 0;
19573   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
19574   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
19575   u8 is_add = 1;
19576   int ret;
19577
19578   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19579     {
19580       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19581         ;
19582       else if (unformat (input, "sw_if_index %d", &sw_if_index))
19583         ;
19584       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
19585         vrf_set = 1;
19586       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
19587         vrf_set = 1;
19588       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
19589         vrf_set = 1;
19590       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
19591         vrf_set = 1;
19592       else if (unformat (input, "del"))
19593         is_add = 0;
19594       else
19595         break;
19596     }
19597
19598   if (sw_if_index == ~0)
19599     {
19600       errmsg ("Interface required but not specified");
19601       return -99;
19602     }
19603
19604   if (vrf_set == 0)
19605     {
19606       errmsg ("VRF ID required but not specified");
19607       return -99;
19608     }
19609
19610   if (tcp_out_vrf_id == 0
19611       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
19612     {
19613       errmsg
19614         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
19615       return -99;
19616     }
19617
19618   /* Construct the API message */
19619   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
19620
19621   mp->sw_if_index = ntohl (sw_if_index);
19622   mp->is_add = is_add;
19623   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
19624   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
19625   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
19626   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
19627
19628   /* send it... */
19629   S (mp);
19630
19631   /* Wait for a reply... */
19632   W (ret);
19633   return ret;
19634 }
19635
19636 static int
19637 api_set_punt (vat_main_t * vam)
19638 {
19639   unformat_input_t *i = vam->input;
19640   vl_api_address_family_t af;
19641   vl_api_set_punt_t *mp;
19642   u32 protocol = ~0;
19643   u32 port = ~0;
19644   int is_add = 1;
19645   int ret;
19646
19647   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19648     {
19649       if (unformat (i, "%U", unformat_vl_api_address_family, &af))
19650         ;
19651       else if (unformat (i, "protocol %d", &protocol))
19652         ;
19653       else if (unformat (i, "port %d", &port))
19654         ;
19655       else if (unformat (i, "del"))
19656         is_add = 0;
19657       else
19658         {
19659           clib_warning ("parse error '%U'", format_unformat_error, i);
19660           return -99;
19661         }
19662     }
19663
19664   M (SET_PUNT, mp);
19665
19666   mp->is_add = (u8) is_add;
19667   mp->punt.type = PUNT_API_TYPE_L4;
19668   mp->punt.punt.l4.af = af;
19669   mp->punt.punt.l4.protocol = (u8) protocol;
19670   mp->punt.punt.l4.port = htons ((u16) port);
19671
19672   S (mp);
19673   W (ret);
19674   return ret;
19675 }
19676
19677 static int
19678 api_delete_subif (vat_main_t * vam)
19679 {
19680   unformat_input_t *i = vam->input;
19681   vl_api_delete_subif_t *mp;
19682   u32 sw_if_index = ~0;
19683   int ret;
19684
19685   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19686     {
19687       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19688         ;
19689       if (unformat (i, "sw_if_index %d", &sw_if_index))
19690         ;
19691       else
19692         break;
19693     }
19694
19695   if (sw_if_index == ~0)
19696     {
19697       errmsg ("missing sw_if_index");
19698       return -99;
19699     }
19700
19701   /* Construct the API message */
19702   M (DELETE_SUBIF, mp);
19703   mp->sw_if_index = ntohl (sw_if_index);
19704
19705   S (mp);
19706   W (ret);
19707   return ret;
19708 }
19709
19710 #define foreach_pbb_vtr_op      \
19711 _("disable",  L2_VTR_DISABLED)  \
19712 _("pop",  L2_VTR_POP_2)         \
19713 _("push",  L2_VTR_PUSH_2)
19714
19715 static int
19716 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
19717 {
19718   unformat_input_t *i = vam->input;
19719   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
19720   u32 sw_if_index = ~0, vtr_op = ~0;
19721   u16 outer_tag = ~0;
19722   u8 dmac[6], smac[6];
19723   u8 dmac_set = 0, smac_set = 0;
19724   u16 vlanid = 0;
19725   u32 sid = ~0;
19726   u32 tmp;
19727   int ret;
19728
19729   /* Shut up coverity */
19730   clib_memset (dmac, 0, sizeof (dmac));
19731   clib_memset (smac, 0, sizeof (smac));
19732
19733   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19734     {
19735       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19736         ;
19737       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19738         ;
19739       else if (unformat (i, "vtr_op %d", &vtr_op))
19740         ;
19741 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
19742       foreach_pbb_vtr_op
19743 #undef _
19744         else if (unformat (i, "translate_pbb_stag"))
19745         {
19746           if (unformat (i, "%d", &tmp))
19747             {
19748               vtr_op = L2_VTR_TRANSLATE_2_1;
19749               outer_tag = tmp;
19750             }
19751           else
19752             {
19753               errmsg
19754                 ("translate_pbb_stag operation requires outer tag definition");
19755               return -99;
19756             }
19757         }
19758       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
19759         dmac_set++;
19760       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
19761         smac_set++;
19762       else if (unformat (i, "sid %d", &sid))
19763         ;
19764       else if (unformat (i, "vlanid %d", &tmp))
19765         vlanid = tmp;
19766       else
19767         {
19768           clib_warning ("parse error '%U'", format_unformat_error, i);
19769           return -99;
19770         }
19771     }
19772
19773   if ((sw_if_index == ~0) || (vtr_op == ~0))
19774     {
19775       errmsg ("missing sw_if_index or vtr operation");
19776       return -99;
19777     }
19778   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
19779       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
19780     {
19781       errmsg
19782         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
19783       return -99;
19784     }
19785
19786   M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
19787   mp->sw_if_index = ntohl (sw_if_index);
19788   mp->vtr_op = ntohl (vtr_op);
19789   mp->outer_tag = ntohs (outer_tag);
19790   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
19791   clib_memcpy (mp->b_smac, smac, sizeof (smac));
19792   mp->b_vlanid = ntohs (vlanid);
19793   mp->i_sid = ntohl (sid);
19794
19795   S (mp);
19796   W (ret);
19797   return ret;
19798 }
19799
19800 static int
19801 api_flow_classify_set_interface (vat_main_t * vam)
19802 {
19803   unformat_input_t *i = vam->input;
19804   vl_api_flow_classify_set_interface_t *mp;
19805   u32 sw_if_index;
19806   int sw_if_index_set;
19807   u32 ip4_table_index = ~0;
19808   u32 ip6_table_index = ~0;
19809   u8 is_add = 1;
19810   int ret;
19811
19812   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19813     {
19814       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19815         sw_if_index_set = 1;
19816       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19817         sw_if_index_set = 1;
19818       else if (unformat (i, "del"))
19819         is_add = 0;
19820       else if (unformat (i, "ip4-table %d", &ip4_table_index))
19821         ;
19822       else if (unformat (i, "ip6-table %d", &ip6_table_index))
19823         ;
19824       else
19825         {
19826           clib_warning ("parse error '%U'", format_unformat_error, i);
19827           return -99;
19828         }
19829     }
19830
19831   if (sw_if_index_set == 0)
19832     {
19833       errmsg ("missing interface name or sw_if_index");
19834       return -99;
19835     }
19836
19837   M (FLOW_CLASSIFY_SET_INTERFACE, mp);
19838
19839   mp->sw_if_index = ntohl (sw_if_index);
19840   mp->ip4_table_index = ntohl (ip4_table_index);
19841   mp->ip6_table_index = ntohl (ip6_table_index);
19842   mp->is_add = is_add;
19843
19844   S (mp);
19845   W (ret);
19846   return ret;
19847 }
19848
19849 static int
19850 api_flow_classify_dump (vat_main_t * vam)
19851 {
19852   unformat_input_t *i = vam->input;
19853   vl_api_flow_classify_dump_t *mp;
19854   vl_api_control_ping_t *mp_ping;
19855   u8 type = FLOW_CLASSIFY_N_TABLES;
19856   int ret;
19857
19858   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
19859     ;
19860   else
19861     {
19862       errmsg ("classify table type must be specified");
19863       return -99;
19864     }
19865
19866   if (!vam->json_output)
19867     {
19868       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
19869     }
19870
19871   M (FLOW_CLASSIFY_DUMP, mp);
19872   mp->type = type;
19873   /* send it... */
19874   S (mp);
19875
19876   /* Use a control ping for synchronization */
19877   MPING (CONTROL_PING, mp_ping);
19878   S (mp_ping);
19879
19880   /* Wait for a reply... */
19881   W (ret);
19882   return ret;
19883 }
19884
19885 static int
19886 api_feature_enable_disable (vat_main_t * vam)
19887 {
19888   unformat_input_t *i = vam->input;
19889   vl_api_feature_enable_disable_t *mp;
19890   u8 *arc_name = 0;
19891   u8 *feature_name = 0;
19892   u32 sw_if_index = ~0;
19893   u8 enable = 1;
19894   int ret;
19895
19896   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19897     {
19898       if (unformat (i, "arc_name %s", &arc_name))
19899         ;
19900       else if (unformat (i, "feature_name %s", &feature_name))
19901         ;
19902       else
19903         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19904         ;
19905       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19906         ;
19907       else if (unformat (i, "disable"))
19908         enable = 0;
19909       else
19910         break;
19911     }
19912
19913   if (arc_name == 0)
19914     {
19915       errmsg ("missing arc name");
19916       return -99;
19917     }
19918   if (vec_len (arc_name) > 63)
19919     {
19920       errmsg ("arc name too long");
19921     }
19922
19923   if (feature_name == 0)
19924     {
19925       errmsg ("missing feature name");
19926       return -99;
19927     }
19928   if (vec_len (feature_name) > 63)
19929     {
19930       errmsg ("feature name too long");
19931     }
19932
19933   if (sw_if_index == ~0)
19934     {
19935       errmsg ("missing interface name or sw_if_index");
19936       return -99;
19937     }
19938
19939   /* Construct the API message */
19940   M (FEATURE_ENABLE_DISABLE, mp);
19941   mp->sw_if_index = ntohl (sw_if_index);
19942   mp->enable = enable;
19943   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
19944   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
19945   vec_free (arc_name);
19946   vec_free (feature_name);
19947
19948   S (mp);
19949   W (ret);
19950   return ret;
19951 }
19952
19953 static int
19954 api_sw_interface_tag_add_del (vat_main_t * vam)
19955 {
19956   unformat_input_t *i = vam->input;
19957   vl_api_sw_interface_tag_add_del_t *mp;
19958   u32 sw_if_index = ~0;
19959   u8 *tag = 0;
19960   u8 enable = 1;
19961   int ret;
19962
19963   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19964     {
19965       if (unformat (i, "tag %s", &tag))
19966         ;
19967       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19968         ;
19969       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19970         ;
19971       else if (unformat (i, "del"))
19972         enable = 0;
19973       else
19974         break;
19975     }
19976
19977   if (sw_if_index == ~0)
19978     {
19979       errmsg ("missing interface name or sw_if_index");
19980       return -99;
19981     }
19982
19983   if (enable && (tag == 0))
19984     {
19985       errmsg ("no tag specified");
19986       return -99;
19987     }
19988
19989   /* Construct the API message */
19990   M (SW_INTERFACE_TAG_ADD_DEL, mp);
19991   mp->sw_if_index = ntohl (sw_if_index);
19992   mp->is_add = enable;
19993   if (enable)
19994     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
19995   vec_free (tag);
19996
19997   S (mp);
19998   W (ret);
19999   return ret;
20000 }
20001
20002 static void vl_api_l2_xconnect_details_t_handler
20003   (vl_api_l2_xconnect_details_t * mp)
20004 {
20005   vat_main_t *vam = &vat_main;
20006
20007   print (vam->ofp, "%15d%15d",
20008          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
20009 }
20010
20011 static void vl_api_l2_xconnect_details_t_handler_json
20012   (vl_api_l2_xconnect_details_t * mp)
20013 {
20014   vat_main_t *vam = &vat_main;
20015   vat_json_node_t *node = NULL;
20016
20017   if (VAT_JSON_ARRAY != vam->json_tree.type)
20018     {
20019       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20020       vat_json_init_array (&vam->json_tree);
20021     }
20022   node = vat_json_array_add (&vam->json_tree);
20023
20024   vat_json_init_object (node);
20025   vat_json_object_add_uint (node, "rx_sw_if_index",
20026                             ntohl (mp->rx_sw_if_index));
20027   vat_json_object_add_uint (node, "tx_sw_if_index",
20028                             ntohl (mp->tx_sw_if_index));
20029 }
20030
20031 static int
20032 api_l2_xconnect_dump (vat_main_t * vam)
20033 {
20034   vl_api_l2_xconnect_dump_t *mp;
20035   vl_api_control_ping_t *mp_ping;
20036   int ret;
20037
20038   if (!vam->json_output)
20039     {
20040       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
20041     }
20042
20043   M (L2_XCONNECT_DUMP, mp);
20044
20045   S (mp);
20046
20047   /* Use a control ping for synchronization */
20048   MPING (CONTROL_PING, mp_ping);
20049   S (mp_ping);
20050
20051   W (ret);
20052   return ret;
20053 }
20054
20055 static int
20056 api_hw_interface_set_mtu (vat_main_t * vam)
20057 {
20058   unformat_input_t *i = vam->input;
20059   vl_api_hw_interface_set_mtu_t *mp;
20060   u32 sw_if_index = ~0;
20061   u32 mtu = 0;
20062   int ret;
20063
20064   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20065     {
20066       if (unformat (i, "mtu %d", &mtu))
20067         ;
20068       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20069         ;
20070       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20071         ;
20072       else
20073         break;
20074     }
20075
20076   if (sw_if_index == ~0)
20077     {
20078       errmsg ("missing interface name or sw_if_index");
20079       return -99;
20080     }
20081
20082   if (mtu == 0)
20083     {
20084       errmsg ("no mtu specified");
20085       return -99;
20086     }
20087
20088   /* Construct the API message */
20089   M (HW_INTERFACE_SET_MTU, mp);
20090   mp->sw_if_index = ntohl (sw_if_index);
20091   mp->mtu = ntohs ((u16) mtu);
20092
20093   S (mp);
20094   W (ret);
20095   return ret;
20096 }
20097
20098 static int
20099 api_p2p_ethernet_add (vat_main_t * vam)
20100 {
20101   unformat_input_t *i = vam->input;
20102   vl_api_p2p_ethernet_add_t *mp;
20103   u32 parent_if_index = ~0;
20104   u32 sub_id = ~0;
20105   u8 remote_mac[6];
20106   u8 mac_set = 0;
20107   int ret;
20108
20109   clib_memset (remote_mac, 0, sizeof (remote_mac));
20110   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20111     {
20112       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
20113         ;
20114       else if (unformat (i, "sw_if_index %d", &parent_if_index))
20115         ;
20116       else
20117         if (unformat
20118             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
20119         mac_set++;
20120       else if (unformat (i, "sub_id %d", &sub_id))
20121         ;
20122       else
20123         {
20124           clib_warning ("parse error '%U'", format_unformat_error, i);
20125           return -99;
20126         }
20127     }
20128
20129   if (parent_if_index == ~0)
20130     {
20131       errmsg ("missing interface name or sw_if_index");
20132       return -99;
20133     }
20134   if (mac_set == 0)
20135     {
20136       errmsg ("missing remote mac address");
20137       return -99;
20138     }
20139   if (sub_id == ~0)
20140     {
20141       errmsg ("missing sub-interface id");
20142       return -99;
20143     }
20144
20145   M (P2P_ETHERNET_ADD, mp);
20146   mp->parent_if_index = ntohl (parent_if_index);
20147   mp->subif_id = ntohl (sub_id);
20148   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
20149
20150   S (mp);
20151   W (ret);
20152   return ret;
20153 }
20154
20155 static int
20156 api_p2p_ethernet_del (vat_main_t * vam)
20157 {
20158   unformat_input_t *i = vam->input;
20159   vl_api_p2p_ethernet_del_t *mp;
20160   u32 parent_if_index = ~0;
20161   u8 remote_mac[6];
20162   u8 mac_set = 0;
20163   int ret;
20164
20165   clib_memset (remote_mac, 0, sizeof (remote_mac));
20166   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20167     {
20168       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
20169         ;
20170       else if (unformat (i, "sw_if_index %d", &parent_if_index))
20171         ;
20172       else
20173         if (unformat
20174             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
20175         mac_set++;
20176       else
20177         {
20178           clib_warning ("parse error '%U'", format_unformat_error, i);
20179           return -99;
20180         }
20181     }
20182
20183   if (parent_if_index == ~0)
20184     {
20185       errmsg ("missing interface name or sw_if_index");
20186       return -99;
20187     }
20188   if (mac_set == 0)
20189     {
20190       errmsg ("missing remote mac address");
20191       return -99;
20192     }
20193
20194   M (P2P_ETHERNET_DEL, mp);
20195   mp->parent_if_index = ntohl (parent_if_index);
20196   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
20197
20198   S (mp);
20199   W (ret);
20200   return ret;
20201 }
20202
20203 static int
20204 api_lldp_config (vat_main_t * vam)
20205 {
20206   unformat_input_t *i = vam->input;
20207   vl_api_lldp_config_t *mp;
20208   int tx_hold = 0;
20209   int tx_interval = 0;
20210   u8 *sys_name = NULL;
20211   int ret;
20212
20213   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20214     {
20215       if (unformat (i, "system-name %s", &sys_name))
20216         ;
20217       else if (unformat (i, "tx-hold %d", &tx_hold))
20218         ;
20219       else if (unformat (i, "tx-interval %d", &tx_interval))
20220         ;
20221       else
20222         {
20223           clib_warning ("parse error '%U'", format_unformat_error, i);
20224           return -99;
20225         }
20226     }
20227
20228   vec_add1 (sys_name, 0);
20229
20230   M (LLDP_CONFIG, mp);
20231   mp->tx_hold = htonl (tx_hold);
20232   mp->tx_interval = htonl (tx_interval);
20233   clib_memcpy (mp->system_name, sys_name, vec_len (sys_name));
20234   vec_free (sys_name);
20235
20236   S (mp);
20237   W (ret);
20238   return ret;
20239 }
20240
20241 static int
20242 api_sw_interface_set_lldp (vat_main_t * vam)
20243 {
20244   unformat_input_t *i = vam->input;
20245   vl_api_sw_interface_set_lldp_t *mp;
20246   u32 sw_if_index = ~0;
20247   u32 enable = 1;
20248   u8 *port_desc = NULL, *mgmt_oid = NULL;
20249   ip4_address_t ip4_addr;
20250   ip6_address_t ip6_addr;
20251   int ret;
20252
20253   clib_memset (&ip4_addr, 0, sizeof (ip4_addr));
20254   clib_memset (&ip6_addr, 0, sizeof (ip6_addr));
20255
20256   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20257     {
20258       if (unformat (i, "disable"))
20259         enable = 0;
20260       else
20261         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20262         ;
20263       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20264         ;
20265       else if (unformat (i, "port-desc %s", &port_desc))
20266         ;
20267       else if (unformat (i, "mgmt-ip4 %U", unformat_ip4_address, &ip4_addr))
20268         ;
20269       else if (unformat (i, "mgmt-ip6 %U", unformat_ip6_address, &ip6_addr))
20270         ;
20271       else if (unformat (i, "mgmt-oid %s", &mgmt_oid))
20272         ;
20273       else
20274         break;
20275     }
20276
20277   if (sw_if_index == ~0)
20278     {
20279       errmsg ("missing interface name or sw_if_index");
20280       return -99;
20281     }
20282
20283   /* Construct the API message */
20284   vec_add1 (port_desc, 0);
20285   vec_add1 (mgmt_oid, 0);
20286   M (SW_INTERFACE_SET_LLDP, mp);
20287   mp->sw_if_index = ntohl (sw_if_index);
20288   mp->enable = enable;
20289   clib_memcpy (mp->port_desc, port_desc, vec_len (port_desc));
20290   clib_memcpy (mp->mgmt_oid, mgmt_oid, vec_len (mgmt_oid));
20291   clib_memcpy (mp->mgmt_ip4, &ip4_addr, sizeof (ip4_addr));
20292   clib_memcpy (mp->mgmt_ip6, &ip6_addr, sizeof (ip6_addr));
20293   vec_free (port_desc);
20294   vec_free (mgmt_oid);
20295
20296   S (mp);
20297   W (ret);
20298   return ret;
20299 }
20300
20301 static int
20302 api_tcp_configure_src_addresses (vat_main_t * vam)
20303 {
20304   vl_api_tcp_configure_src_addresses_t *mp;
20305   unformat_input_t *i = vam->input;
20306   ip4_address_t v4first, v4last;
20307   ip6_address_t v6first, v6last;
20308   u8 range_set = 0;
20309   u32 vrf_id = 0;
20310   int ret;
20311
20312   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20313     {
20314       if (unformat (i, "%U - %U",
20315                     unformat_ip4_address, &v4first,
20316                     unformat_ip4_address, &v4last))
20317         {
20318           if (range_set)
20319             {
20320               errmsg ("one range per message (range already set)");
20321               return -99;
20322             }
20323           range_set = 1;
20324         }
20325       else if (unformat (i, "%U - %U",
20326                          unformat_ip6_address, &v6first,
20327                          unformat_ip6_address, &v6last))
20328         {
20329           if (range_set)
20330             {
20331               errmsg ("one range per message (range already set)");
20332               return -99;
20333             }
20334           range_set = 2;
20335         }
20336       else if (unformat (i, "vrf %d", &vrf_id))
20337         ;
20338       else
20339         break;
20340     }
20341
20342   if (range_set == 0)
20343     {
20344       errmsg ("address range not set");
20345       return -99;
20346     }
20347
20348   M (TCP_CONFIGURE_SRC_ADDRESSES, mp);
20349   mp->vrf_id = ntohl (vrf_id);
20350   /* ipv6? */
20351   if (range_set == 2)
20352     {
20353       mp->is_ipv6 = 1;
20354       clib_memcpy (mp->first_address, &v6first, sizeof (v6first));
20355       clib_memcpy (mp->last_address, &v6last, sizeof (v6last));
20356     }
20357   else
20358     {
20359       mp->is_ipv6 = 0;
20360       clib_memcpy (mp->first_address, &v4first, sizeof (v4first));
20361       clib_memcpy (mp->last_address, &v4last, sizeof (v4last));
20362     }
20363   S (mp);
20364   W (ret);
20365   return ret;
20366 }
20367
20368 static void vl_api_app_namespace_add_del_reply_t_handler
20369   (vl_api_app_namespace_add_del_reply_t * mp)
20370 {
20371   vat_main_t *vam = &vat_main;
20372   i32 retval = ntohl (mp->retval);
20373   if (vam->async_mode)
20374     {
20375       vam->async_errors += (retval < 0);
20376     }
20377   else
20378     {
20379       vam->retval = retval;
20380       if (retval == 0)
20381         errmsg ("app ns index %d\n", ntohl (mp->appns_index));
20382       vam->result_ready = 1;
20383     }
20384 }
20385
20386 static void vl_api_app_namespace_add_del_reply_t_handler_json
20387   (vl_api_app_namespace_add_del_reply_t * mp)
20388 {
20389   vat_main_t *vam = &vat_main;
20390   vat_json_node_t node;
20391
20392   vat_json_init_object (&node);
20393   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
20394   vat_json_object_add_uint (&node, "appns_index", ntohl (mp->appns_index));
20395
20396   vat_json_print (vam->ofp, &node);
20397   vat_json_free (&node);
20398
20399   vam->retval = ntohl (mp->retval);
20400   vam->result_ready = 1;
20401 }
20402
20403 static int
20404 api_app_namespace_add_del (vat_main_t * vam)
20405 {
20406   vl_api_app_namespace_add_del_t *mp;
20407   unformat_input_t *i = vam->input;
20408   u8 *ns_id = 0, secret_set = 0, sw_if_index_set = 0;
20409   u32 sw_if_index, ip4_fib_id, ip6_fib_id;
20410   u64 secret;
20411   int ret;
20412
20413   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20414     {
20415       if (unformat (i, "id %_%v%_", &ns_id))
20416         ;
20417       else if (unformat (i, "secret %lu", &secret))
20418         secret_set = 1;
20419       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20420         sw_if_index_set = 1;
20421       else if (unformat (i, "ip4_fib_id %d", &ip4_fib_id))
20422         ;
20423       else if (unformat (i, "ip6_fib_id %d", &ip6_fib_id))
20424         ;
20425       else
20426         break;
20427     }
20428   if (!ns_id || !secret_set || !sw_if_index_set)
20429     {
20430       errmsg ("namespace id, secret and sw_if_index must be set");
20431       return -99;
20432     }
20433   if (vec_len (ns_id) > 64)
20434     {
20435       errmsg ("namespace id too long");
20436       return -99;
20437     }
20438   M (APP_NAMESPACE_ADD_DEL, mp);
20439
20440   clib_memcpy (mp->namespace_id, ns_id, vec_len (ns_id));
20441   mp->namespace_id_len = vec_len (ns_id);
20442   mp->secret = clib_host_to_net_u64 (secret);
20443   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
20444   mp->ip4_fib_id = clib_host_to_net_u32 (ip4_fib_id);
20445   mp->ip6_fib_id = clib_host_to_net_u32 (ip6_fib_id);
20446   vec_free (ns_id);
20447   S (mp);
20448   W (ret);
20449   return ret;
20450 }
20451
20452 static int
20453 api_sock_init_shm (vat_main_t * vam)
20454 {
20455 #if VPP_API_TEST_BUILTIN == 0
20456   unformat_input_t *i = vam->input;
20457   vl_api_shm_elem_config_t *config = 0;
20458   u64 size = 64 << 20;
20459   int rv;
20460
20461   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20462     {
20463       if (unformat (i, "size %U", unformat_memory_size, &size))
20464         ;
20465       else
20466         break;
20467     }
20468
20469   /*
20470    * Canned custom ring allocator config.
20471    * Should probably parse all of this
20472    */
20473   vec_validate (config, 6);
20474   config[0].type = VL_API_VLIB_RING;
20475   config[0].size = 256;
20476   config[0].count = 32;
20477
20478   config[1].type = VL_API_VLIB_RING;
20479   config[1].size = 1024;
20480   config[1].count = 16;
20481
20482   config[2].type = VL_API_VLIB_RING;
20483   config[2].size = 4096;
20484   config[2].count = 2;
20485
20486   config[3].type = VL_API_CLIENT_RING;
20487   config[3].size = 256;
20488   config[3].count = 32;
20489
20490   config[4].type = VL_API_CLIENT_RING;
20491   config[4].size = 1024;
20492   config[4].count = 16;
20493
20494   config[5].type = VL_API_CLIENT_RING;
20495   config[5].size = 4096;
20496   config[5].count = 2;
20497
20498   config[6].type = VL_API_QUEUE;
20499   config[6].count = 128;
20500   config[6].size = sizeof (uword);
20501
20502   rv = vl_socket_client_init_shm (config, 1 /* want_pthread */ );
20503   if (!rv)
20504     vam->client_index_invalid = 1;
20505   return rv;
20506 #else
20507   return -99;
20508 #endif
20509 }
20510
20511 static void
20512 vl_api_session_rules_details_t_handler (vl_api_session_rules_details_t * mp)
20513 {
20514   vat_main_t *vam = &vat_main;
20515
20516   if (mp->is_ip4)
20517     {
20518       print (vam->ofp,
20519              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
20520              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
20521              mp->scope, format_ip4_address, &mp->lcl_ip, mp->lcl_plen,
20522              clib_net_to_host_u16 (mp->lcl_port), format_ip4_address,
20523              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
20524              clib_net_to_host_u32 (mp->action_index), mp->tag);
20525     }
20526   else
20527     {
20528       print (vam->ofp,
20529              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
20530              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
20531              mp->scope, format_ip6_address, &mp->lcl_ip, mp->lcl_plen,
20532              clib_net_to_host_u16 (mp->lcl_port), format_ip6_address,
20533              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
20534              clib_net_to_host_u32 (mp->action_index), mp->tag);
20535     }
20536 }
20537
20538 static void
20539 vl_api_session_rules_details_t_handler_json (vl_api_session_rules_details_t *
20540                                              mp)
20541 {
20542   vat_main_t *vam = &vat_main;
20543   vat_json_node_t *node = NULL;
20544   struct in6_addr ip6;
20545   struct in_addr ip4;
20546
20547   if (VAT_JSON_ARRAY != vam->json_tree.type)
20548     {
20549       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20550       vat_json_init_array (&vam->json_tree);
20551     }
20552   node = vat_json_array_add (&vam->json_tree);
20553   vat_json_init_object (node);
20554
20555   vat_json_object_add_uint (node, "is_ip4", mp->is_ip4 ? 1 : 0);
20556   vat_json_object_add_uint (node, "appns_index",
20557                             clib_net_to_host_u32 (mp->appns_index));
20558   vat_json_object_add_uint (node, "transport_proto", mp->transport_proto);
20559   vat_json_object_add_uint (node, "scope", mp->scope);
20560   vat_json_object_add_uint (node, "action_index",
20561                             clib_net_to_host_u32 (mp->action_index));
20562   vat_json_object_add_uint (node, "lcl_port",
20563                             clib_net_to_host_u16 (mp->lcl_port));
20564   vat_json_object_add_uint (node, "rmt_port",
20565                             clib_net_to_host_u16 (mp->rmt_port));
20566   vat_json_object_add_uint (node, "lcl_plen", mp->lcl_plen);
20567   vat_json_object_add_uint (node, "rmt_plen", mp->rmt_plen);
20568   vat_json_object_add_string_copy (node, "tag", mp->tag);
20569   if (mp->is_ip4)
20570     {
20571       clib_memcpy (&ip4, mp->lcl_ip, sizeof (ip4));
20572       vat_json_object_add_ip4 (node, "lcl_ip", ip4);
20573       clib_memcpy (&ip4, mp->rmt_ip, sizeof (ip4));
20574       vat_json_object_add_ip4 (node, "rmt_ip", ip4);
20575     }
20576   else
20577     {
20578       clib_memcpy (&ip6, mp->lcl_ip, sizeof (ip6));
20579       vat_json_object_add_ip6 (node, "lcl_ip", ip6);
20580       clib_memcpy (&ip6, mp->rmt_ip, sizeof (ip6));
20581       vat_json_object_add_ip6 (node, "rmt_ip", ip6);
20582     }
20583 }
20584
20585 static int
20586 api_session_rule_add_del (vat_main_t * vam)
20587 {
20588   vl_api_session_rule_add_del_t *mp;
20589   unformat_input_t *i = vam->input;
20590   u32 proto = ~0, lcl_port, rmt_port, action = 0, lcl_plen, rmt_plen;
20591   u32 appns_index = 0, scope = 0;
20592   ip4_address_t lcl_ip4, rmt_ip4;
20593   ip6_address_t lcl_ip6, rmt_ip6;
20594   u8 is_ip4 = 1, conn_set = 0;
20595   u8 is_add = 1, *tag = 0;
20596   int ret;
20597
20598   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20599     {
20600       if (unformat (i, "del"))
20601         is_add = 0;
20602       else if (unformat (i, "add"))
20603         ;
20604       else if (unformat (i, "proto tcp"))
20605         proto = 0;
20606       else if (unformat (i, "proto udp"))
20607         proto = 1;
20608       else if (unformat (i, "appns %d", &appns_index))
20609         ;
20610       else if (unformat (i, "scope %d", &scope))
20611         ;
20612       else if (unformat (i, "tag %_%v%_", &tag))
20613         ;
20614       else
20615         if (unformat
20616             (i, "%U/%d %d %U/%d %d", unformat_ip4_address, &lcl_ip4,
20617              &lcl_plen, &lcl_port, unformat_ip4_address, &rmt_ip4, &rmt_plen,
20618              &rmt_port))
20619         {
20620           is_ip4 = 1;
20621           conn_set = 1;
20622         }
20623       else
20624         if (unformat
20625             (i, "%U/%d %d %U/%d %d", unformat_ip6_address, &lcl_ip6,
20626              &lcl_plen, &lcl_port, unformat_ip6_address, &rmt_ip6, &rmt_plen,
20627              &rmt_port))
20628         {
20629           is_ip4 = 0;
20630           conn_set = 1;
20631         }
20632       else if (unformat (i, "action %d", &action))
20633         ;
20634       else
20635         break;
20636     }
20637   if (proto == ~0 || !conn_set || action == ~0)
20638     {
20639       errmsg ("transport proto, connection and action must be set");
20640       return -99;
20641     }
20642
20643   if (scope > 3)
20644     {
20645       errmsg ("scope should be 0-3");
20646       return -99;
20647     }
20648
20649   M (SESSION_RULE_ADD_DEL, mp);
20650
20651   mp->is_ip4 = is_ip4;
20652   mp->transport_proto = proto;
20653   mp->lcl_port = clib_host_to_net_u16 ((u16) lcl_port);
20654   mp->rmt_port = clib_host_to_net_u16 ((u16) rmt_port);
20655   mp->lcl_plen = lcl_plen;
20656   mp->rmt_plen = rmt_plen;
20657   mp->action_index = clib_host_to_net_u32 (action);
20658   mp->appns_index = clib_host_to_net_u32 (appns_index);
20659   mp->scope = scope;
20660   mp->is_add = is_add;
20661   if (is_ip4)
20662     {
20663       clib_memcpy (mp->lcl_ip, &lcl_ip4, sizeof (lcl_ip4));
20664       clib_memcpy (mp->rmt_ip, &rmt_ip4, sizeof (rmt_ip4));
20665     }
20666   else
20667     {
20668       clib_memcpy (mp->lcl_ip, &lcl_ip6, sizeof (lcl_ip6));
20669       clib_memcpy (mp->rmt_ip, &rmt_ip6, sizeof (rmt_ip6));
20670     }
20671   if (tag)
20672     {
20673       clib_memcpy (mp->tag, tag, vec_len (tag));
20674       vec_free (tag);
20675     }
20676
20677   S (mp);
20678   W (ret);
20679   return ret;
20680 }
20681
20682 static int
20683 api_session_rules_dump (vat_main_t * vam)
20684 {
20685   vl_api_session_rules_dump_t *mp;
20686   vl_api_control_ping_t *mp_ping;
20687   int ret;
20688
20689   if (!vam->json_output)
20690     {
20691       print (vam->ofp, "%=20s", "Session Rules");
20692     }
20693
20694   M (SESSION_RULES_DUMP, mp);
20695   /* send it... */
20696   S (mp);
20697
20698   /* Use a control ping for synchronization */
20699   MPING (CONTROL_PING, mp_ping);
20700   S (mp_ping);
20701
20702   /* Wait for a reply... */
20703   W (ret);
20704   return ret;
20705 }
20706
20707 static int
20708 api_ip_container_proxy_add_del (vat_main_t * vam)
20709 {
20710   vl_api_ip_container_proxy_add_del_t *mp;
20711   unformat_input_t *i = vam->input;
20712   u32 sw_if_index = ~0;
20713   vl_api_prefix_t pfx = { };
20714   u8 is_add = 1;
20715   int ret;
20716
20717   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20718     {
20719       if (unformat (i, "del"))
20720         is_add = 0;
20721       else if (unformat (i, "add"))
20722         ;
20723       if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
20724         ;
20725       else if (unformat (i, "sw_if_index %u", &sw_if_index))
20726         ;
20727       else
20728         break;
20729     }
20730   if (sw_if_index == ~0 || pfx.len == 0)
20731     {
20732       errmsg ("address and sw_if_index must be set");
20733       return -99;
20734     }
20735
20736   M (IP_CONTAINER_PROXY_ADD_DEL, mp);
20737
20738   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
20739   mp->is_add = is_add;
20740   clib_memcpy (&mp->pfx, &pfx, sizeof (pfx));
20741
20742   S (mp);
20743   W (ret);
20744   return ret;
20745 }
20746
20747 static int
20748 api_qos_record_enable_disable (vat_main_t * vam)
20749 {
20750   unformat_input_t *i = vam->input;
20751   vl_api_qos_record_enable_disable_t *mp;
20752   u32 sw_if_index, qs = 0xff;
20753   u8 sw_if_index_set = 0;
20754   u8 enable = 1;
20755   int ret;
20756
20757   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20758     {
20759       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20760         sw_if_index_set = 1;
20761       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20762         sw_if_index_set = 1;
20763       else if (unformat (i, "%U", unformat_qos_source, &qs))
20764         ;
20765       else if (unformat (i, "disable"))
20766         enable = 0;
20767       else
20768         {
20769           clib_warning ("parse error '%U'", format_unformat_error, i);
20770           return -99;
20771         }
20772     }
20773
20774   if (sw_if_index_set == 0)
20775     {
20776       errmsg ("missing interface name or sw_if_index");
20777       return -99;
20778     }
20779   if (qs == 0xff)
20780     {
20781       errmsg ("input location must be specified");
20782       return -99;
20783     }
20784
20785   M (QOS_RECORD_ENABLE_DISABLE, mp);
20786
20787   mp->record.sw_if_index = ntohl (sw_if_index);
20788   mp->record.input_source = qs;
20789   mp->enable = enable;
20790
20791   S (mp);
20792   W (ret);
20793   return ret;
20794 }
20795
20796
20797 static int
20798 q_or_quit (vat_main_t * vam)
20799 {
20800 #if VPP_API_TEST_BUILTIN == 0
20801   longjmp (vam->jump_buf, 1);
20802 #endif
20803   return 0;                     /* not so much */
20804 }
20805
20806 static int
20807 q (vat_main_t * vam)
20808 {
20809   return q_or_quit (vam);
20810 }
20811
20812 static int
20813 quit (vat_main_t * vam)
20814 {
20815   return q_or_quit (vam);
20816 }
20817
20818 static int
20819 comment (vat_main_t * vam)
20820 {
20821   return 0;
20822 }
20823
20824 static int
20825 elog_save (vat_main_t * vam)
20826 {
20827 #if VPP_API_TEST_BUILTIN == 0
20828   elog_main_t *em = &vam->elog_main;
20829   unformat_input_t *i = vam->input;
20830   char *file, *chroot_file;
20831   clib_error_t *error;
20832
20833   if (!unformat (i, "%s", &file))
20834     {
20835       errmsg ("expected file name, got `%U'", format_unformat_error, i);
20836       return 0;
20837     }
20838
20839   /* It's fairly hard to get "../oopsie" through unformat; just in case */
20840   if (strstr (file, "..") || index (file, '/'))
20841     {
20842       errmsg ("illegal characters in filename '%s'", file);
20843       return 0;
20844     }
20845
20846   chroot_file = (char *) format (0, "/tmp/%s%c", file, 0);
20847
20848   vec_free (file);
20849
20850   errmsg ("Saving %wd of %wd events to %s",
20851           elog_n_events_in_buffer (em),
20852           elog_buffer_capacity (em), chroot_file);
20853
20854   error = elog_write_file (em, chroot_file, 1 /* flush ring */ );
20855   vec_free (chroot_file);
20856
20857   if (error)
20858     clib_error_report (error);
20859 #else
20860   errmsg ("Use the vpp event loger...");
20861 #endif
20862
20863   return 0;
20864 }
20865
20866 static int
20867 elog_setup (vat_main_t * vam)
20868 {
20869 #if VPP_API_TEST_BUILTIN == 0
20870   elog_main_t *em = &vam->elog_main;
20871   unformat_input_t *i = vam->input;
20872   u32 nevents = 128 << 10;
20873
20874   (void) unformat (i, "nevents %d", &nevents);
20875
20876   elog_init (em, nevents);
20877   vl_api_set_elog_main (em);
20878   vl_api_set_elog_trace_api_messages (1);
20879   errmsg ("Event logger initialized with %u events", nevents);
20880 #else
20881   errmsg ("Use the vpp event loger...");
20882 #endif
20883   return 0;
20884 }
20885
20886 static int
20887 elog_enable (vat_main_t * vam)
20888 {
20889 #if VPP_API_TEST_BUILTIN == 0
20890   elog_main_t *em = &vam->elog_main;
20891
20892   elog_enable_disable (em, 1 /* enable */ );
20893   vl_api_set_elog_trace_api_messages (1);
20894   errmsg ("Event logger enabled...");
20895 #else
20896   errmsg ("Use the vpp event loger...");
20897 #endif
20898   return 0;
20899 }
20900
20901 static int
20902 elog_disable (vat_main_t * vam)
20903 {
20904 #if VPP_API_TEST_BUILTIN == 0
20905   elog_main_t *em = &vam->elog_main;
20906
20907   elog_enable_disable (em, 0 /* enable */ );
20908   vl_api_set_elog_trace_api_messages (1);
20909   errmsg ("Event logger disabled...");
20910 #else
20911   errmsg ("Use the vpp event loger...");
20912 #endif
20913   return 0;
20914 }
20915
20916 static int
20917 statseg (vat_main_t * vam)
20918 {
20919   ssvm_private_t *ssvmp = &vam->stat_segment;
20920   ssvm_shared_header_t *shared_header = ssvmp->sh;
20921   vlib_counter_t **counters;
20922   u64 thread0_index1_packets;
20923   u64 thread0_index1_bytes;
20924   f64 vector_rate, input_rate;
20925   uword *p;
20926
20927   uword *counter_vector_by_name;
20928   if (vam->stat_segment_lockp == 0)
20929     {
20930       errmsg ("Stat segment not mapped...");
20931       return -99;
20932     }
20933
20934   /* look up "/if/rx for sw_if_index 1 as a test */
20935
20936   clib_spinlock_lock (vam->stat_segment_lockp);
20937
20938   counter_vector_by_name = (uword *) shared_header->opaque[1];
20939
20940   p = hash_get_mem (counter_vector_by_name, "/if/rx");
20941   if (p == 0)
20942     {
20943       clib_spinlock_unlock (vam->stat_segment_lockp);
20944       errmsg ("/if/tx not found?");
20945       return -99;
20946     }
20947
20948   /* Fish per-thread vector of combined counters from shared memory */
20949   counters = (vlib_counter_t **) p[0];
20950
20951   if (vec_len (counters[0]) < 2)
20952     {
20953       clib_spinlock_unlock (vam->stat_segment_lockp);
20954       errmsg ("/if/tx vector length %d", vec_len (counters[0]));
20955       return -99;
20956     }
20957
20958   /* Read thread 0 sw_if_index 1 counter */
20959   thread0_index1_packets = counters[0][1].packets;
20960   thread0_index1_bytes = counters[0][1].bytes;
20961
20962   p = hash_get_mem (counter_vector_by_name, "vector_rate");
20963   if (p == 0)
20964     {
20965       clib_spinlock_unlock (vam->stat_segment_lockp);
20966       errmsg ("vector_rate not found?");
20967       return -99;
20968     }
20969
20970   vector_rate = *(f64 *) (p[0]);
20971   p = hash_get_mem (counter_vector_by_name, "input_rate");
20972   if (p == 0)
20973     {
20974       clib_spinlock_unlock (vam->stat_segment_lockp);
20975       errmsg ("input_rate not found?");
20976       return -99;
20977     }
20978   input_rate = *(f64 *) (p[0]);
20979
20980   clib_spinlock_unlock (vam->stat_segment_lockp);
20981
20982   print (vam->ofp, "vector_rate %.2f input_rate %.2f",
20983          vector_rate, input_rate);
20984   print (vam->ofp, "thread 0 sw_if_index 1 rx pkts %lld, bytes %lld",
20985          thread0_index1_packets, thread0_index1_bytes);
20986
20987   return 0;
20988 }
20989
20990 static int
20991 cmd_cmp (void *a1, void *a2)
20992 {
20993   u8 **c1 = a1;
20994   u8 **c2 = a2;
20995
20996   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
20997 }
20998
20999 static int
21000 help (vat_main_t * vam)
21001 {
21002   u8 **cmds = 0;
21003   u8 *name = 0;
21004   hash_pair_t *p;
21005   unformat_input_t *i = vam->input;
21006   int j;
21007
21008   if (unformat (i, "%s", &name))
21009     {
21010       uword *hs;
21011
21012       vec_add1 (name, 0);
21013
21014       hs = hash_get_mem (vam->help_by_name, name);
21015       if (hs)
21016         print (vam->ofp, "usage: %s %s", name, hs[0]);
21017       else
21018         print (vam->ofp, "No such msg / command '%s'", name);
21019       vec_free (name);
21020       return 0;
21021     }
21022
21023   print (vam->ofp, "Help is available for the following:");
21024
21025     /* *INDENT-OFF* */
21026     hash_foreach_pair (p, vam->function_by_name,
21027     ({
21028       vec_add1 (cmds, (u8 *)(p->key));
21029     }));
21030     /* *INDENT-ON* */
21031
21032   vec_sort_with_function (cmds, cmd_cmp);
21033
21034   for (j = 0; j < vec_len (cmds); j++)
21035     print (vam->ofp, "%s", cmds[j]);
21036
21037   vec_free (cmds);
21038   return 0;
21039 }
21040
21041 static int
21042 set (vat_main_t * vam)
21043 {
21044   u8 *name = 0, *value = 0;
21045   unformat_input_t *i = vam->input;
21046
21047   if (unformat (i, "%s", &name))
21048     {
21049       /* The input buffer is a vector, not a string. */
21050       value = vec_dup (i->buffer);
21051       vec_delete (value, i->index, 0);
21052       /* Almost certainly has a trailing newline */
21053       if (value[vec_len (value) - 1] == '\n')
21054         value[vec_len (value) - 1] = 0;
21055       /* Make sure it's a proper string, one way or the other */
21056       vec_add1 (value, 0);
21057       (void) clib_macro_set_value (&vam->macro_main,
21058                                    (char *) name, (char *) value);
21059     }
21060   else
21061     errmsg ("usage: set <name> <value>");
21062
21063   vec_free (name);
21064   vec_free (value);
21065   return 0;
21066 }
21067
21068 static int
21069 unset (vat_main_t * vam)
21070 {
21071   u8 *name = 0;
21072
21073   if (unformat (vam->input, "%s", &name))
21074     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
21075       errmsg ("unset: %s wasn't set", name);
21076   vec_free (name);
21077   return 0;
21078 }
21079
21080 typedef struct
21081 {
21082   u8 *name;
21083   u8 *value;
21084 } macro_sort_t;
21085
21086
21087 static int
21088 macro_sort_cmp (void *a1, void *a2)
21089 {
21090   macro_sort_t *s1 = a1;
21091   macro_sort_t *s2 = a2;
21092
21093   return strcmp ((char *) (s1->name), (char *) (s2->name));
21094 }
21095
21096 static int
21097 dump_macro_table (vat_main_t * vam)
21098 {
21099   macro_sort_t *sort_me = 0, *sm;
21100   int i;
21101   hash_pair_t *p;
21102
21103     /* *INDENT-OFF* */
21104     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
21105     ({
21106       vec_add2 (sort_me, sm, 1);
21107       sm->name = (u8 *)(p->key);
21108       sm->value = (u8 *) (p->value[0]);
21109     }));
21110     /* *INDENT-ON* */
21111
21112   vec_sort_with_function (sort_me, macro_sort_cmp);
21113
21114   if (vec_len (sort_me))
21115     print (vam->ofp, "%-15s%s", "Name", "Value");
21116   else
21117     print (vam->ofp, "The macro table is empty...");
21118
21119   for (i = 0; i < vec_len (sort_me); i++)
21120     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
21121   return 0;
21122 }
21123
21124 static int
21125 dump_node_table (vat_main_t * vam)
21126 {
21127   int i, j;
21128   vlib_node_t *node, *next_node;
21129
21130   if (vec_len (vam->graph_nodes) == 0)
21131     {
21132       print (vam->ofp, "Node table empty, issue get_node_graph...");
21133       return 0;
21134     }
21135
21136   for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
21137     {
21138       node = vam->graph_nodes[0][i];
21139       print (vam->ofp, "[%d] %s", i, node->name);
21140       for (j = 0; j < vec_len (node->next_nodes); j++)
21141         {
21142           if (node->next_nodes[j] != ~0)
21143             {
21144               next_node = vam->graph_nodes[0][node->next_nodes[j]];
21145               print (vam->ofp, "  [%d] %s", j, next_node->name);
21146             }
21147         }
21148     }
21149   return 0;
21150 }
21151
21152 static int
21153 value_sort_cmp (void *a1, void *a2)
21154 {
21155   name_sort_t *n1 = a1;
21156   name_sort_t *n2 = a2;
21157
21158   if (n1->value < n2->value)
21159     return -1;
21160   if (n1->value > n2->value)
21161     return 1;
21162   return 0;
21163 }
21164
21165
21166 static int
21167 dump_msg_api_table (vat_main_t * vam)
21168 {
21169   api_main_t *am = &api_main;
21170   name_sort_t *nses = 0, *ns;
21171   hash_pair_t *hp;
21172   int i;
21173
21174   /* *INDENT-OFF* */
21175   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
21176   ({
21177     vec_add2 (nses, ns, 1);
21178     ns->name = (u8 *)(hp->key);
21179     ns->value = (u32) hp->value[0];
21180   }));
21181   /* *INDENT-ON* */
21182
21183   vec_sort_with_function (nses, value_sort_cmp);
21184
21185   for (i = 0; i < vec_len (nses); i++)
21186     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
21187   vec_free (nses);
21188   return 0;
21189 }
21190
21191 static int
21192 get_msg_id (vat_main_t * vam)
21193 {
21194   u8 *name_and_crc;
21195   u32 message_index;
21196
21197   if (unformat (vam->input, "%s", &name_and_crc))
21198     {
21199       message_index = vl_msg_api_get_msg_index (name_and_crc);
21200       if (message_index == ~0)
21201         {
21202           print (vam->ofp, " '%s' not found", name_and_crc);
21203           return 0;
21204         }
21205       print (vam->ofp, " '%s' has message index %d",
21206              name_and_crc, message_index);
21207       return 0;
21208     }
21209   errmsg ("name_and_crc required...");
21210   return 0;
21211 }
21212
21213 static int
21214 search_node_table (vat_main_t * vam)
21215 {
21216   unformat_input_t *line_input = vam->input;
21217   u8 *node_to_find;
21218   int j;
21219   vlib_node_t *node, *next_node;
21220   uword *p;
21221
21222   if (vam->graph_node_index_by_name == 0)
21223     {
21224       print (vam->ofp, "Node table empty, issue get_node_graph...");
21225       return 0;
21226     }
21227
21228   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
21229     {
21230       if (unformat (line_input, "%s", &node_to_find))
21231         {
21232           vec_add1 (node_to_find, 0);
21233           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
21234           if (p == 0)
21235             {
21236               print (vam->ofp, "%s not found...", node_to_find);
21237               goto out;
21238             }
21239           node = vam->graph_nodes[0][p[0]];
21240           print (vam->ofp, "[%d] %s", p[0], node->name);
21241           for (j = 0; j < vec_len (node->next_nodes); j++)
21242             {
21243               if (node->next_nodes[j] != ~0)
21244                 {
21245                   next_node = vam->graph_nodes[0][node->next_nodes[j]];
21246                   print (vam->ofp, "  [%d] %s", j, next_node->name);
21247                 }
21248             }
21249         }
21250
21251       else
21252         {
21253           clib_warning ("parse error '%U'", format_unformat_error,
21254                         line_input);
21255           return -99;
21256         }
21257
21258     out:
21259       vec_free (node_to_find);
21260
21261     }
21262
21263   return 0;
21264 }
21265
21266
21267 static int
21268 script (vat_main_t * vam)
21269 {
21270 #if (VPP_API_TEST_BUILTIN==0)
21271   u8 *s = 0;
21272   char *save_current_file;
21273   unformat_input_t save_input;
21274   jmp_buf save_jump_buf;
21275   u32 save_line_number;
21276
21277   FILE *new_fp, *save_ifp;
21278
21279   if (unformat (vam->input, "%s", &s))
21280     {
21281       new_fp = fopen ((char *) s, "r");
21282       if (new_fp == 0)
21283         {
21284           errmsg ("Couldn't open script file %s", s);
21285           vec_free (s);
21286           return -99;
21287         }
21288     }
21289   else
21290     {
21291       errmsg ("Missing script name");
21292       return -99;
21293     }
21294
21295   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
21296   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
21297   save_ifp = vam->ifp;
21298   save_line_number = vam->input_line_number;
21299   save_current_file = (char *) vam->current_file;
21300
21301   vam->input_line_number = 0;
21302   vam->ifp = new_fp;
21303   vam->current_file = s;
21304   do_one_file (vam);
21305
21306   clib_memcpy (&vam->input, &save_input, sizeof (save_input));
21307   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
21308   vam->ifp = save_ifp;
21309   vam->input_line_number = save_line_number;
21310   vam->current_file = (u8 *) save_current_file;
21311   vec_free (s);
21312
21313   return 0;
21314 #else
21315   clib_warning ("use the exec command...");
21316   return -99;
21317 #endif
21318 }
21319
21320 static int
21321 echo (vat_main_t * vam)
21322 {
21323   print (vam->ofp, "%v", vam->input->buffer);
21324   return 0;
21325 }
21326
21327 /* List of API message constructors, CLI names map to api_xxx */
21328 #define foreach_vpe_api_msg                                             \
21329 _(create_loopback,"[mac <mac-addr>] [instance <instance>]")             \
21330 _(sw_interface_dump,"")                                                 \
21331 _(sw_interface_set_flags,                                               \
21332   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
21333 _(sw_interface_add_del_address,                                         \
21334   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
21335 _(sw_interface_set_rx_mode,                                             \
21336   "<intfc> | sw_if_index <id> [queue <id>] <polling | interrupt | adaptive>") \
21337 _(sw_interface_set_rx_placement,                                        \
21338   "<intfc> | sw_if_index <id> [queue <id>] [worker <id> | main]")       \
21339 _(sw_interface_rx_placement_dump,                                       \
21340   "[<intfc> | sw_if_index <id>]")                                         \
21341 _(sw_interface_set_table,                                               \
21342   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
21343 _(sw_interface_set_mpls_enable,                                         \
21344   "<intfc> | sw_if_index [disable | dis]")                              \
21345 _(sw_interface_set_vpath,                                               \
21346   "<intfc> | sw_if_index <id> enable | disable")                        \
21347 _(sw_interface_set_vxlan_bypass,                                        \
21348   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
21349 _(sw_interface_set_geneve_bypass,                                       \
21350   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
21351 _(sw_interface_set_l2_xconnect,                                         \
21352   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
21353   "enable | disable")                                                   \
21354 _(sw_interface_set_l2_bridge,                                           \
21355   "{<intfc> | sw_if_index <id>} bd_id <bridge-domain-id>\n"             \
21356   "[shg <split-horizon-group>] [bvi]\n"                                 \
21357   "enable | disable")                                                   \
21358 _(bridge_domain_set_mac_age, "bd_id <bridge-domain-id> mac-age 0-255")  \
21359 _(bridge_domain_add_del,                                                \
21360   "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") \
21361 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
21362 _(l2fib_add_del,                                                        \
21363   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
21364 _(l2fib_flush_bd, "bd_id <bridge-domain-id>")                           \
21365 _(l2fib_flush_int, "<intfc> | sw_if_index <id>")                        \
21366 _(l2_flags,                                                             \
21367   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
21368 _(bridge_flags,                                                         \
21369   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
21370 _(tap_create_v2,                                                        \
21371   "id <num> [hw-addr <mac-addr>] [host-ns <name>] [rx-ring-size <num> [tx-ring-size <num>] [host-mtu-size <mtu>] [gso | no-gso]") \
21372 _(tap_delete_v2,                                                        \
21373   "<vpp-if-name> | sw_if_index <id>")                                   \
21374 _(sw_interface_tap_v2_dump, "")                                         \
21375 _(virtio_pci_create,                                                    \
21376   "pci-addr <pci-address> [use_random_mac | hw-addr <mac-addr>] [features <hex-value>] [gso-enabled]") \
21377 _(virtio_pci_delete,                                                    \
21378   "<vpp-if-name> | sw_if_index <id>")                                   \
21379 _(sw_interface_virtio_pci_dump, "")                                     \
21380 _(bond_create,                                                          \
21381   "[hw-addr <mac-addr>] {round-robin | active-backup | "                \
21382   "broadcast | {lacp | xor} [load-balance { l2 | l23 | l34 }]} "        \
21383   "[id <if-id>]")                                                       \
21384 _(bond_delete,                                                          \
21385   "<vpp-if-name> | sw_if_index <id>")                                   \
21386 _(bond_enslave,                                                         \
21387   "sw_if_index <n> bond <sw_if_index> [is_passive] [is_long_timeout]")  \
21388 _(bond_detach_slave,                                                    \
21389   "sw_if_index <n>")                                                    \
21390  _(sw_interface_set_bond_weight, "<intfc> | sw_if_index <nn> weight <value>") \
21391 _(sw_interface_bond_dump, "")                                           \
21392 _(sw_interface_slave_dump,                                              \
21393   "<vpp-if-name> | sw_if_index <id>")                                   \
21394 _(ip_table_add_del,                                                     \
21395   "table <n> [ipv6] [add | del]\n")                                     \
21396 _(ip_route_add_del,                                                     \
21397   "<addr>/<mask> via <<addr>|<intfc>|sw_if_index <id>|via-label <n>>\n" \
21398   "[table-id <n>] [<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"\
21399   "[weight <n>] [drop] [local] [classify <n>]  [out-label <n>]\n"       \
21400   "[multipath] [count <n>] [del]")                                      \
21401 _(ip_mroute_add_del,                                                    \
21402   "<src> <grp>/<mask> [table-id <n>]\n"                                 \
21403   "[<intfc> | sw_if_index <id>] [local] [del]")                         \
21404 _(mpls_table_add_del,                                                   \
21405   "table <n> [add | del]\n")                                            \
21406 _(mpls_route_add_del,                                                   \
21407   "<label> <eos> via <addr | next-hop-table <n> | via-label <n> |\n"    \
21408   "lookup-ip4-table <n> | lookup-in-ip6-table <n> |\n"                  \
21409   "l2-input-on <intfc> | l2-input-on sw_if_index <id>>\n"               \
21410   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>] [weight <n>]\n"  \
21411   "[drop] [local] [classify <n>] [out-label <n>] [multipath]\n"         \
21412   "[count <n>] [del]")                                                  \
21413 _(mpls_ip_bind_unbind,                                                  \
21414   "<label> <addr/len>")                                                 \
21415 _(mpls_tunnel_add_del,                                                  \
21416   "[add | del <intfc | sw_if_index <id>>] via <addr | via-label <n>>\n" \
21417   "[<intfc> | sw_if_index <id> | next-hop-table <id>]\n"                \
21418   "[l2-only]  [out-label <n>]")                                         \
21419 _(sr_mpls_policy_add,                                                   \
21420   "bsid <id> [weight <n>] [spray] next <sid> [next <sid>]")             \
21421 _(sr_mpls_policy_del,                                                   \
21422   "bsid <id>")                                                          \
21423 _(bier_table_add_del,                                                   \
21424   "<label> <sub-domain> <set> <bsl> [del]")                             \
21425 _(bier_route_add_del,                                                   \
21426   "<bit-position> <sub-domain> <set> <bsl> via <addr> [table-id <n>]\n" \
21427   "[<intfc> | sw_if_index <id>]"                                        \
21428   "[weight <n>] [del] [multipath]")                                     \
21429 _(proxy_arp_add_del,                                                    \
21430   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
21431 _(proxy_arp_intfc_enable_disable,                                       \
21432   "<intfc> | sw_if_index <id> enable | disable")                        \
21433 _(sw_interface_set_unnumbered,                                          \
21434   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
21435 _(ip_neighbor_add_del,                                                  \
21436   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
21437   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
21438 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
21439 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
21440   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
21441   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
21442   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
21443 _(reset_fib, "vrf <n> [ipv6]")                                          \
21444 _(set_ip_flow_hash,                                                     \
21445   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
21446 _(sw_interface_ip6_enable_disable,                                      \
21447   "<intfc> | sw_if_index <id> enable | disable")                        \
21448 _(ip6nd_proxy_add_del,                                                  \
21449   "<intfc> | sw_if_index <id> <ip6-address>")                           \
21450 _(ip6nd_proxy_dump, "")                                                 \
21451 _(sw_interface_ip6nd_ra_prefix,                                         \
21452   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
21453   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
21454   "[nolink] [isno]")                                                    \
21455 _(sw_interface_ip6nd_ra_config,                                         \
21456   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
21457   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
21458   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
21459 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
21460 _(l2_patch_add_del,                                                     \
21461   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
21462   "enable | disable")                                                   \
21463 _(sr_localsid_add_del,                                                  \
21464   "(del) address <addr> next_hop <addr> behavior <beh>\n"               \
21465   "fib-table <num> (end.psp) sw_if_index <num>")                        \
21466 _(classify_add_del_table,                                               \
21467   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
21468   " [del] [del-chain] mask <mask-value>\n"                              \
21469   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
21470   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
21471 _(classify_add_del_session,                                             \
21472   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
21473   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
21474   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
21475   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
21476 _(classify_set_interface_ip_table,                                      \
21477   "<intfc> | sw_if_index <nn> table <nn>")                              \
21478 _(classify_set_interface_l2_tables,                                     \
21479   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
21480   "  [other-table <nn>]")                                               \
21481 _(get_node_index, "node <node-name")                                    \
21482 _(add_node_next, "node <node-name> next <next-node-name>")              \
21483 _(l2tpv3_create_tunnel,                                                 \
21484   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
21485   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
21486   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
21487 _(l2tpv3_set_tunnel_cookies,                                            \
21488   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
21489   "[new_remote_cookie <nn>]\n")                                         \
21490 _(l2tpv3_interface_enable_disable,                                      \
21491   "<intfc> | sw_if_index <nn> enable | disable")                        \
21492 _(l2tpv3_set_lookup_key,                                                \
21493   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
21494 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
21495 _(vxlan_offload_rx,                                                     \
21496   "hw { <interface name> | hw_if_index <nn>} "                          \
21497   "rx { <vxlan tunnel name> | sw_if_index <nn> } [del]")                \
21498 _(vxlan_add_del_tunnel,                                                 \
21499   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
21500   "{ <intfc> | mcast_sw_if_index <nn> } [instance <id>]}\n"             \
21501   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
21502 _(geneve_add_del_tunnel,                                                \
21503   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
21504   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
21505   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
21506 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
21507 _(geneve_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                   \
21508 _(gre_tunnel_add_del,                                                   \
21509   "src <ip-addr> dst <ip-addr> [outer-fib-id <nn>] [instance <n>]\n"    \
21510   "[teb | erspan <session-id>] [del]")                                  \
21511 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
21512 _(l2_fib_clear_table, "")                                               \
21513 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
21514 _(l2_interface_vlan_tag_rewrite,                                        \
21515   "<intfc> | sw_if_index <nn> \n"                                       \
21516   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
21517   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
21518 _(create_vhost_user_if,                                                 \
21519         "socket <filename> [server] [renumber <dev_instance>] "         \
21520         "[disable_mrg_rxbuf] [disable_indirect_desc] [gso] "            \
21521         "[mac <mac_address>]")                                          \
21522 _(modify_vhost_user_if,                                                 \
21523         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
21524         "[server] [renumber <dev_instance>] [gso]")                     \
21525 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
21526 _(sw_interface_vhost_user_dump, "")                                     \
21527 _(show_version, "")                                                     \
21528 _(show_threads, "")                                                     \
21529 _(vxlan_gpe_add_del_tunnel,                                             \
21530   "local <addr> remote <addr>  | group <mcast-ip-addr>\n"               \
21531   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
21532   "vni <nn> [encap-vrf-id <nn>] [decap-vrf-id <nn>]\n"                  \
21533   "[next-ip4][next-ip6][next-ethernet] [next-nsh] [del]\n")             \
21534 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
21535 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
21536 _(interface_name_renumber,                                              \
21537   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
21538 _(input_acl_set_interface,                                              \
21539   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
21540   "  [l2-table <nn>] [del]")                                            \
21541 _(ip_probe_neighbor, "(<intc> | sw_if_index <nn>) address <ip4|ip6-addr>") \
21542 _(ip_scan_neighbor_enable_disable, "[ip4|ip6|both|disable] [interval <n-min>]\n" \
21543   "  [max-time <n-usec>] [max-update <n>] [delay <n-msec>] [stale <n-min>]") \
21544 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
21545 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
21546 _(want_l2_macs_events, "[disable] [learn-limit <n>] [scan-delay <n>] [max-entries <n>]") \
21547 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
21548 _(ip_dump, "ipv4 | ipv6")                                               \
21549 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
21550 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
21551   "  spid_id <n> ")                                                     \
21552 _(ipsec_sad_entry_add_del, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
21553   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
21554   "  integ_alg <alg> integ_key <hex>")                                  \
21555 _(ipsec_spd_entry_add_del, "spd_id <n> priority <n> action <action>\n"  \
21556   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
21557   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
21558   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
21559 _(ipsec_tunnel_if_add_del, "local_spi <n> remote_spi <n>\n"             \
21560   "  crypto_alg <alg> local_crypto_key <hex> remote_crypto_key <hex>\n" \
21561   "  integ_alg <alg> local_integ_key <hex> remote_integ_key <hex>\n"    \
21562   "  local_ip <addr> remote_ip <addr> [esn] [anti_replay] [del]\n"      \
21563   "  [instance <n>]")     \
21564 _(ipsec_sa_dump, "[sa_id <n>]")                                         \
21565 _(ipsec_tunnel_if_set_sa, "<intfc> sa_id <n> <inbound|outbound>\n")     \
21566 _(delete_loopback,"sw_if_index <nn>")                                   \
21567 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
21568 _(bd_ip_mac_flush, "bd_id <bridge-domain-id>")                          \
21569 _(bd_ip_mac_dump, "[bd_id] <bridge-domain-id>")                         \
21570 _(want_interface_events,  "enable|disable")                             \
21571 _(get_first_msg_id, "client <name>")                                    \
21572 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
21573 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
21574   "fib-id <nn> [ip4][ip6][default]")                                    \
21575 _(get_node_graph, " ")                                                  \
21576 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
21577 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
21578 _(ioam_disable, "")                                                     \
21579 _(one_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
21580                             " sw_if_index <sw_if_index> p <priority> "  \
21581                             "w <weight>] [del]")                        \
21582 _(one_add_del_locator, "locator-set <locator_name> "                    \
21583                         "iface <intf> | sw_if_index <sw_if_index> "     \
21584                         "p <priority> w <weight> [del]")                \
21585 _(one_add_del_local_eid,"vni <vni> eid "                                \
21586                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
21587                          "locator-set <locator_name> [del]"             \
21588                          "[key-id sha1|sha256 secret-key <secret-key>]")\
21589 _(one_add_del_map_resolver, "<ip4|6-addr> [del]")                       \
21590 _(one_add_del_map_server, "<ip4|6-addr> [del]")                         \
21591 _(one_enable_disable, "enable|disable")                                 \
21592 _(one_map_register_enable_disable, "enable|disable")                    \
21593 _(one_map_register_fallback_threshold, "<value>")                       \
21594 _(one_rloc_probe_enable_disable, "enable|disable")                      \
21595 _(one_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "       \
21596                                "[seid <seid>] "                         \
21597                                "rloc <locator> p <prio> "               \
21598                                "w <weight> [rloc <loc> ... ] "          \
21599                                "action <action> [del-all]")             \
21600 _(one_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "    \
21601                           "<local-eid>")                                \
21602 _(one_pitr_set_locator_set, "locator-set <loc-set-name> | del")         \
21603 _(one_use_petr, "ip-address> | disable")                                \
21604 _(one_map_request_mode, "src-dst|dst-only")                             \
21605 _(one_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")            \
21606 _(one_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")               \
21607 _(one_locator_set_dump, "[local | remote]")                             \
21608 _(one_locator_dump, "ls_index <index> | ls_name <name>")                \
21609 _(one_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "       \
21610                        "[local] | [remote]")                            \
21611 _(one_add_del_ndp_entry, "[del] mac <mac> bd <bd> ip6 <ip6>")           \
21612 _(one_ndp_bd_get, "")                                                   \
21613 _(one_ndp_entries_get, "bd <bridge-domain>")                            \
21614 _(one_add_del_l2_arp_entry, "[del] mac <mac> bd <bd> ip4 <ip4>")        \
21615 _(one_l2_arp_bd_get, "")                                                \
21616 _(one_l2_arp_entries_get, "bd <bridge-domain>")                         \
21617 _(one_stats_enable_disable, "enable|disable")                           \
21618 _(show_one_stats_enable_disable, "")                                    \
21619 _(one_eid_table_vni_dump, "")                                           \
21620 _(one_eid_table_map_dump, "l2|l3")                                      \
21621 _(one_map_resolver_dump, "")                                            \
21622 _(one_map_server_dump, "")                                              \
21623 _(one_adjacencies_get, "vni <vni>")                                     \
21624 _(one_nsh_set_locator_set, "[del] ls <locator-set-name>")               \
21625 _(show_one_rloc_probe_state, "")                                        \
21626 _(show_one_map_register_state, "")                                      \
21627 _(show_one_status, "")                                                  \
21628 _(one_stats_dump, "")                                                   \
21629 _(one_stats_flush, "")                                                  \
21630 _(one_get_map_request_itr_rlocs, "")                                    \
21631 _(one_map_register_set_ttl, "<ttl>")                                    \
21632 _(one_set_transport_protocol, "udp|api")                                \
21633 _(one_get_transport_protocol, "")                                       \
21634 _(one_enable_disable_xtr_mode, "enable|disable")                        \
21635 _(one_show_xtr_mode, "")                                                \
21636 _(one_enable_disable_pitr_mode, "enable|disable")                       \
21637 _(one_show_pitr_mode, "")                                               \
21638 _(one_enable_disable_petr_mode, "enable|disable")                       \
21639 _(one_show_petr_mode, "")                                               \
21640 _(show_one_nsh_mapping, "")                                             \
21641 _(show_one_pitr, "")                                                    \
21642 _(show_one_use_petr, "")                                                \
21643 _(show_one_map_request_mode, "")                                        \
21644 _(show_one_map_register_ttl, "")                                        \
21645 _(show_one_map_register_fallback_threshold, "")                         \
21646 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
21647                             " sw_if_index <sw_if_index> p <priority> "  \
21648                             "w <weight>] [del]")                        \
21649 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
21650                         "iface <intf> | sw_if_index <sw_if_index> "     \
21651                         "p <priority> w <weight> [del]")                \
21652 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
21653                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
21654                          "locator-set <locator_name> [del]"             \
21655                          "[key-id sha1|sha256 secret-key <secret-key>]") \
21656 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
21657 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
21658 _(lisp_enable_disable, "enable|disable")                                \
21659 _(lisp_map_register_enable_disable, "enable|disable")                   \
21660 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
21661 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
21662                                "[seid <seid>] "                         \
21663                                "rloc <locator> p <prio> "               \
21664                                "w <weight> [rloc <loc> ... ] "          \
21665                                "action <action> [del-all]")             \
21666 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
21667                           "<local-eid>")                                \
21668 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
21669 _(lisp_use_petr, "<ip-address> | disable")                              \
21670 _(lisp_map_request_mode, "src-dst|dst-only")                            \
21671 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
21672 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
21673 _(lisp_locator_set_dump, "[local | remote]")                            \
21674 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
21675 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
21676                        "[local] | [remote]")                            \
21677 _(lisp_eid_table_vni_dump, "")                                          \
21678 _(lisp_eid_table_map_dump, "l2|l3")                                     \
21679 _(lisp_map_resolver_dump, "")                                           \
21680 _(lisp_map_server_dump, "")                                             \
21681 _(lisp_adjacencies_get, "vni <vni>")                                    \
21682 _(gpe_fwd_entry_vnis_get, "")                                           \
21683 _(gpe_native_fwd_rpaths_get, "ip4 | ip6")                               \
21684 _(gpe_add_del_native_fwd_rpath, "[del] via <nh-ip-addr> [iface] "       \
21685                                 "[table <table-id>]")                   \
21686 _(lisp_gpe_fwd_entries_get, "vni <vni>")                                \
21687 _(lisp_gpe_fwd_entry_path_dump, "index <fwd_entry_index>")              \
21688 _(gpe_set_encap_mode, "lisp|vxlan")                                     \
21689 _(gpe_get_encap_mode, "")                                               \
21690 _(lisp_gpe_add_del_iface, "up|down")                                    \
21691 _(lisp_gpe_enable_disable, "enable|disable")                            \
21692 _(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>"       \
21693   "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
21694 _(show_lisp_rloc_probe_state, "")                                       \
21695 _(show_lisp_map_register_state, "")                                     \
21696 _(show_lisp_status, "")                                                 \
21697 _(lisp_get_map_request_itr_rlocs, "")                                   \
21698 _(show_lisp_pitr, "")                                                   \
21699 _(show_lisp_use_petr, "")                                               \
21700 _(show_lisp_map_request_mode, "")                                       \
21701 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
21702 _(af_packet_delete, "name <host interface name>")                       \
21703 _(af_packet_dump, "")                                                   \
21704 _(policer_add_del, "name <policer name> <params> [del]")                \
21705 _(policer_dump, "[name <policer name>]")                                \
21706 _(policer_classify_set_interface,                                       \
21707   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
21708   "  [l2-table <nn>] [del]")                                            \
21709 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
21710 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
21711     "[master|slave]")                                                   \
21712 _(netmap_delete, "name <interface name>")                               \
21713 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
21714 _(mpls_table_dump, "")                                                  \
21715 _(mpls_route_dump, "table-id <ID>")                                     \
21716 _(classify_table_ids, "")                                               \
21717 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
21718 _(classify_table_info, "table_id <nn>")                                 \
21719 _(classify_session_dump, "table_id <nn>")                               \
21720 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
21721     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
21722     "[template_interval <nn>] [udp_checksum]")                          \
21723 _(ipfix_exporter_dump, "")                                              \
21724 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
21725 _(ipfix_classify_stream_dump, "")                                       \
21726 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
21727 _(ipfix_classify_table_dump, "")                                        \
21728 _(sw_interface_span_enable_disable, "[l2] [src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
21729 _(sw_interface_span_dump, "[l2]")                                           \
21730 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
21731 _(pg_create_interface, "if_id <nn> [gso-enabled gso-size <size>]")      \
21732 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
21733 _(pg_enable_disable, "[stream <id>] disable")                           \
21734 _(ip_source_and_port_range_check_add_del,                               \
21735   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
21736 _(ip_source_and_port_range_check_interface_add_del,                     \
21737   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
21738   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
21739 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
21740 _(l2_interface_pbb_tag_rewrite,                                         \
21741   "<intfc> | sw_if_index <nn> \n"                                       \
21742   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
21743   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
21744 _(set_punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
21745 _(flow_classify_set_interface,                                          \
21746   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
21747 _(flow_classify_dump, "type [ip4|ip6]")                                 \
21748 _(ip_table_dump, "")                                                    \
21749 _(ip_route_dump, "table-id [ip4|ip6]")                                  \
21750 _(ip_mtable_dump, "")                                                   \
21751 _(ip_mroute_dump, "table-id [ip4|ip6]")                                 \
21752 _(feature_enable_disable, "arc_name <arc_name> "                        \
21753   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
21754 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
21755 "[disable]")                                                            \
21756 _(l2_xconnect_dump, "")                                                 \
21757 _(hw_interface_set_mtu, "<intfc> | hw_if_index <nn> mtu <nn>")        \
21758 _(ip_neighbor_dump, "[ip6] <intfc> | sw_if_index <nn>")                 \
21759 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")          \
21760 _(p2p_ethernet_add, "<intfc> | sw_if_index <nn> remote_mac <mac-address> sub_id <id>") \
21761 _(p2p_ethernet_del, "<intfc> | sw_if_index <nn> remote_mac <mac-address>") \
21762 _(lldp_config, "system-name <name> tx-hold <nn> tx-interval <nn>") \
21763 _(sw_interface_set_lldp, "<intfc> | sw_if_index <nn> [port-desc <description>]\n" \
21764   " [mgmt-ip4 <ip4>] [mgmt-ip6 <ip6>] [mgmt-oid <object id>] [disable]") \
21765 _(tcp_configure_src_addresses, "<ip4|6>first-<ip4|6>last [vrf <id>]")   \
21766 _(sock_init_shm, "size <nnn>")                                          \
21767 _(app_namespace_add_del, "[add] id <ns-id> secret <nn> sw_if_index <nn>")\
21768 _(session_rule_add_del, "[add|del] proto <tcp/udp> <lcl-ip>/<plen> "    \
21769   "<lcl-port> <rmt-ip>/<plen> <rmt-port> action <nn>")                  \
21770 _(session_rules_dump, "")                                               \
21771 _(ip_container_proxy_add_del, "[add|del] <address> <sw_if_index>")      \
21772 _(output_acl_set_interface,                                             \
21773   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
21774   "  [l2-table <nn>] [del]")                                            \
21775 _(qos_record_enable_disable, "<record-source> <intfc> | sw_if_index <id> [disable]")
21776
21777 /* List of command functions, CLI names map directly to functions */
21778 #define foreach_cli_function                                    \
21779 _(comment, "usage: comment <ignore-rest-of-line>")              \
21780 _(dump_interface_table, "usage: dump_interface_table")          \
21781 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
21782 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
21783 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
21784 _(dump_macro_table, "usage: dump_macro_table ")                 \
21785 _(dump_node_table, "usage: dump_node_table")                    \
21786 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
21787 _(elog_setup, "usage: elog_setup [nevents, default 128K]")      \
21788 _(elog_disable, "usage: elog_disable")                          \
21789 _(elog_enable, "usage: elog_enable")                            \
21790 _(elog_save, "usage: elog_save <filename>")                     \
21791 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
21792 _(echo, "usage: echo <message>")                                \
21793 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
21794 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
21795 _(help, "usage: help")                                          \
21796 _(q, "usage: quit")                                             \
21797 _(quit, "usage: quit")                                          \
21798 _(search_node_table, "usage: search_node_table <name>...")      \
21799 _(set, "usage: set <variable-name> <value>")                    \
21800 _(script, "usage: script <file-name>")                          \
21801 _(statseg, "usage: statseg")                                    \
21802 _(unset, "usage: unset <variable-name>")
21803
21804 #define _(N,n)                                  \
21805     static void vl_api_##n##_t_handler_uni      \
21806     (vl_api_##n##_t * mp)                       \
21807     {                                           \
21808         vat_main_t * vam = &vat_main;           \
21809         if (vam->json_output) {                 \
21810             vl_api_##n##_t_handler_json(mp);    \
21811         } else {                                \
21812             vl_api_##n##_t_handler(mp);         \
21813         }                                       \
21814     }
21815 foreach_vpe_api_reply_msg;
21816 #if VPP_API_TEST_BUILTIN == 0
21817 foreach_standalone_reply_msg;
21818 #endif
21819 #undef _
21820
21821 void
21822 vat_api_hookup (vat_main_t * vam)
21823 {
21824 #define _(N,n)                                                  \
21825     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
21826                            vl_api_##n##_t_handler_uni,          \
21827                            vl_noop_handler,                     \
21828                            vl_api_##n##_t_endian,               \
21829                            vl_api_##n##_t_print,                \
21830                            sizeof(vl_api_##n##_t), 1);
21831   foreach_vpe_api_reply_msg;
21832 #if VPP_API_TEST_BUILTIN == 0
21833   foreach_standalone_reply_msg;
21834 #endif
21835 #undef _
21836
21837 #if (VPP_API_TEST_BUILTIN==0)
21838   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
21839
21840   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
21841
21842   vam->function_by_name = hash_create_string (0, sizeof (uword));
21843
21844   vam->help_by_name = hash_create_string (0, sizeof (uword));
21845 #endif
21846
21847   /* API messages we can send */
21848 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
21849   foreach_vpe_api_msg;
21850 #undef _
21851
21852   /* Help strings */
21853 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
21854   foreach_vpe_api_msg;
21855 #undef _
21856
21857   /* CLI functions */
21858 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
21859   foreach_cli_function;
21860 #undef _
21861
21862   /* Help strings */
21863 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
21864   foreach_cli_function;
21865 #undef _
21866 }
21867
21868 #if VPP_API_TEST_BUILTIN
21869 static clib_error_t *
21870 vat_api_hookup_shim (vlib_main_t * vm)
21871 {
21872   vat_api_hookup (&vat_main);
21873   return 0;
21874 }
21875
21876 VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
21877 #endif
21878
21879 /*
21880  * fd.io coding-style-patch-verification: ON
21881  *
21882  * Local Variables:
21883  * eval: (c-set-style "gnu")
21884  * End:
21885  */