srv6-mobile
[vpp.git] / src / vat / api_format.c
1 /*
2  *------------------------------------------------------------------
3  * api_format.c
4  *
5  * Copyright (c) 2014-2016 Cisco and/or its affiliates.
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at:
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *------------------------------------------------------------------
18  */
19
20 #include <vat/vat.h>
21 #include <vlib/pci/pci.h>
22 #include <vpp/api/types.h>
23 #include <vppinfra/socket.h>
24 #include <vlibapi/api.h>
25 #include <vlibmemory/api.h>
26 #include <vnet/ip/ip.h>
27 #include <vnet/ip/ip_neighbor.h>
28 #include <vnet/ip/ip_types_api.h>
29 #include <vnet/l2/l2_input.h>
30 #include <vnet/l2tp/l2tp.h>
31 #include <vnet/vxlan/vxlan.h>
32 #include <vnet/geneve/geneve.h>
33 #include <vnet/gre/gre.h>
34 #include <vnet/vxlan-gpe/vxlan_gpe.h>
35 #include <vnet/lisp-gpe/lisp_gpe.h>
36
37 #include <vpp/api/vpe_msg_enum.h>
38 #include <vnet/l2/l2_classify.h>
39 #include <vnet/l2/l2_vtr.h>
40 #include <vnet/classify/in_out_acl.h>
41 #include <vnet/classify/policer_classify.h>
42 #include <vnet/classify/flow_classify.h>
43 #include <vnet/mpls/mpls.h>
44 #include <vnet/ipsec/ipsec.h>
45 #include <inttypes.h>
46 #include <vnet/cop/cop.h>
47 #include <vnet/ip/ip6_hop_by_hop.h>
48 #include <vnet/ip/ip_source_and_port_range_check.h>
49 #include <vnet/policer/xlate.h>
50 #include <vnet/span/span.h>
51 #include <vnet/policer/policer.h>
52 #include <vnet/policer/police.h>
53 #include <vnet/mfib/mfib_types.h>
54 #include <vnet/bonding/node.h>
55 #include <vnet/qos/qos_types.h>
56 #include <vnet/ethernet/ethernet_types_api.h>
57 #include <vnet/ip/ip_types_api.h>
58 #include "vat/json_format.h"
59 #include <vnet/ip/ip_types_api.h>
60 #include <vnet/ethernet/ethernet_types_api.h>
61
62 #include <inttypes.h>
63 #include <sys/stat.h>
64
65 #define vl_typedefs             /* define message structures */
66 #include <vpp/api/vpe_all_api_h.h>
67 #undef vl_typedefs
68
69 /* declare message handlers for each api */
70
71 #define vl_endianfun            /* define message structures */
72 #include <vpp/api/vpe_all_api_h.h>
73 #undef vl_endianfun
74
75 /* instantiate all the print functions we know about */
76 #if VPP_API_TEST_BUILTIN == 0
77 #define vl_print(handle, ...)
78 #else
79 #define vl_print(handle, ...) vlib_cli_output (handle, __VA_ARGS__)
80 #endif
81 #define vl_printfun
82 #include <vpp/api/vpe_all_api_h.h>
83 #undef vl_printfun
84
85 #define __plugin_msg_base 0
86 #include <vlibapi/vat_helper_macros.h>
87
88 #include <vnet/format_fns.h>
89
90 void vl_api_set_elog_main (elog_main_t * m);
91 int vl_api_set_elog_trace_api_messages (int enable);
92
93 #if VPP_API_TEST_BUILTIN == 0
94 #include <netdb.h>
95
96 u32
97 vl (void *p)
98 {
99   return vec_len (p);
100 }
101
102 int
103 vat_socket_connect (vat_main_t * vam)
104 {
105   int rv;
106   vam->socket_client_main = &socket_client_main;
107   if ((rv = vl_socket_client_connect ((char *) vam->socket_name,
108                                       "vpp_api_test",
109                                       0 /* default socket rx, tx buffer */ )))
110     return rv;
111   /* vpp expects the client index in network order */
112   vam->my_client_index = htonl (socket_client_main.client_index);
113   return 0;
114 }
115 #else /* vpp built-in case, we don't do sockets... */
116 int
117 vat_socket_connect (vat_main_t * vam)
118 {
119   return 0;
120 }
121
122 int
123 vl_socket_client_read (int wait)
124 {
125   return -1;
126 };
127
128 int
129 vl_socket_client_write ()
130 {
131   return -1;
132 };
133
134 void *
135 vl_socket_client_msg_alloc (int nbytes)
136 {
137   return 0;
138 }
139 #endif
140
141
142 f64
143 vat_time_now (vat_main_t * vam)
144 {
145 #if VPP_API_TEST_BUILTIN
146   return vlib_time_now (vam->vlib_main);
147 #else
148   return clib_time_now (&vam->clib_time);
149 #endif
150 }
151
152 void
153 errmsg (char *fmt, ...)
154 {
155   vat_main_t *vam = &vat_main;
156   va_list va;
157   u8 *s;
158
159   va_start (va, fmt);
160   s = va_format (0, fmt, &va);
161   va_end (va);
162
163   vec_add1 (s, 0);
164
165 #if VPP_API_TEST_BUILTIN
166   vlib_cli_output (vam->vlib_main, (char *) s);
167 #else
168   {
169     if (vam->ifp != stdin)
170       fformat (vam->ofp, "%s(%d): \n", vam->current_file,
171                vam->input_line_number);
172     else
173       fformat (vam->ofp, "%s\n", (char *) s);
174     fflush (vam->ofp);
175   }
176 #endif
177
178   vec_free (s);
179 }
180
181 #if VPP_API_TEST_BUILTIN == 0
182 static uword
183 api_unformat_sw_if_index (unformat_input_t * input, va_list * args)
184 {
185   vat_main_t *vam = va_arg (*args, vat_main_t *);
186   u32 *result = va_arg (*args, u32 *);
187   u8 *if_name;
188   uword *p;
189
190   if (!unformat (input, "%s", &if_name))
191     return 0;
192
193   p = hash_get_mem (vam->sw_if_index_by_interface_name, if_name);
194   if (p == 0)
195     return 0;
196   *result = p[0];
197   return 1;
198 }
199
200 static uword
201 api_unformat_hw_if_index (unformat_input_t * input, va_list * args)
202 {
203   return 0;
204 }
205
206 /* Parse an IP4 address %d.%d.%d.%d. */
207 uword
208 unformat_ip4_address (unformat_input_t * input, va_list * args)
209 {
210   u8 *result = va_arg (*args, u8 *);
211   unsigned a[4];
212
213   if (!unformat (input, "%d.%d.%d.%d", &a[0], &a[1], &a[2], &a[3]))
214     return 0;
215
216   if (a[0] >= 256 || a[1] >= 256 || a[2] >= 256 || a[3] >= 256)
217     return 0;
218
219   result[0] = a[0];
220   result[1] = a[1];
221   result[2] = a[2];
222   result[3] = a[3];
223
224   return 1;
225 }
226
227 uword
228 unformat_ethernet_address (unformat_input_t * input, va_list * args)
229 {
230   u8 *result = va_arg (*args, u8 *);
231   u32 i, a[6];
232
233   if (!unformat (input, "%_%x:%x:%x:%x:%x:%x%_",
234                  &a[0], &a[1], &a[2], &a[3], &a[4], &a[5]))
235     return 0;
236
237   /* Check range. */
238   for (i = 0; i < 6; i++)
239     if (a[i] >= (1 << 8))
240       return 0;
241
242   for (i = 0; i < 6; i++)
243     result[i] = a[i];
244
245   return 1;
246 }
247
248 /* Returns ethernet type as an int in host byte order. */
249 uword
250 unformat_ethernet_type_host_byte_order (unformat_input_t * input,
251                                         va_list * args)
252 {
253   u16 *result = va_arg (*args, u16 *);
254   int type;
255
256   /* Numeric type. */
257   if (unformat (input, "0x%x", &type) || unformat (input, "%d", &type))
258     {
259       if (type >= (1 << 16))
260         return 0;
261       *result = type;
262       return 1;
263     }
264   return 0;
265 }
266
267 /* Parse an IP6 address. */
268 uword
269 unformat_ip6_address (unformat_input_t * input, va_list * args)
270 {
271   ip6_address_t *result = va_arg (*args, ip6_address_t *);
272   u16 hex_quads[8];
273   uword hex_quad, n_hex_quads, hex_digit, n_hex_digits;
274   uword c, n_colon, double_colon_index;
275
276   n_hex_quads = hex_quad = n_hex_digits = n_colon = 0;
277   double_colon_index = ARRAY_LEN (hex_quads);
278   while ((c = unformat_get_input (input)) != UNFORMAT_END_OF_INPUT)
279     {
280       hex_digit = 16;
281       if (c >= '0' && c <= '9')
282         hex_digit = c - '0';
283       else if (c >= 'a' && c <= 'f')
284         hex_digit = c + 10 - 'a';
285       else if (c >= 'A' && c <= 'F')
286         hex_digit = c + 10 - 'A';
287       else if (c == ':' && n_colon < 2)
288         n_colon++;
289       else
290         {
291           unformat_put_input (input);
292           break;
293         }
294
295       /* Too many hex quads. */
296       if (n_hex_quads >= ARRAY_LEN (hex_quads))
297         return 0;
298
299       if (hex_digit < 16)
300         {
301           hex_quad = (hex_quad << 4) | hex_digit;
302
303           /* Hex quad must fit in 16 bits. */
304           if (n_hex_digits >= 4)
305             return 0;
306
307           n_colon = 0;
308           n_hex_digits++;
309         }
310
311       /* Save position of :: */
312       if (n_colon == 2)
313         {
314           /* More than one :: ? */
315           if (double_colon_index < ARRAY_LEN (hex_quads))
316             return 0;
317           double_colon_index = n_hex_quads;
318         }
319
320       if (n_colon > 0 && n_hex_digits > 0)
321         {
322           hex_quads[n_hex_quads++] = hex_quad;
323           hex_quad = 0;
324           n_hex_digits = 0;
325         }
326     }
327
328   if (n_hex_digits > 0)
329     hex_quads[n_hex_quads++] = hex_quad;
330
331   {
332     word i;
333
334     /* Expand :: to appropriate number of zero hex quads. */
335     if (double_colon_index < ARRAY_LEN (hex_quads))
336       {
337         word n_zero = ARRAY_LEN (hex_quads) - n_hex_quads;
338
339         for (i = n_hex_quads - 1; i >= (signed) double_colon_index; i--)
340           hex_quads[n_zero + i] = hex_quads[i];
341
342         for (i = 0; i < n_zero; i++)
343           hex_quads[double_colon_index + i] = 0;
344
345         n_hex_quads = ARRAY_LEN (hex_quads);
346       }
347
348     /* Too few hex quads given. */
349     if (n_hex_quads < ARRAY_LEN (hex_quads))
350       return 0;
351
352     for (i = 0; i < ARRAY_LEN (hex_quads); i++)
353       result->as_u16[i] = clib_host_to_net_u16 (hex_quads[i]);
354
355     return 1;
356   }
357 }
358
359 uword
360 unformat_ipsec_policy_action (unformat_input_t * input, va_list * args)
361 {
362   u32 *r = va_arg (*args, u32 *);
363
364   if (0);
365 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_POLICY_ACTION_##f;
366   foreach_ipsec_policy_action
367 #undef _
368     else
369     return 0;
370   return 1;
371 }
372
373 u8 *
374 format_ipsec_crypto_alg (u8 * s, va_list * args)
375 {
376   u32 i = va_arg (*args, u32);
377   u8 *t = 0;
378
379   switch (i)
380     {
381 #define _(v,f,str) case IPSEC_CRYPTO_ALG_##f: t = (u8 *) str; break;
382       foreach_ipsec_crypto_alg
383 #undef _
384     default:
385       return format (s, "unknown");
386     }
387   return format (s, "%s", t);
388 }
389
390 u8 *
391 format_ipsec_integ_alg (u8 * s, va_list * args)
392 {
393   u32 i = va_arg (*args, u32);
394   u8 *t = 0;
395
396   switch (i)
397     {
398 #define _(v,f,str) case IPSEC_INTEG_ALG_##f: t = (u8 *) str; break;
399       foreach_ipsec_integ_alg
400 #undef _
401     default:
402       return format (s, "unknown");
403     }
404   return format (s, "%s", t);
405 }
406
407 #else /* VPP_API_TEST_BUILTIN == 1 */
408 static uword
409 api_unformat_sw_if_index (unformat_input_t * input, va_list * args)
410 {
411   vat_main_t *vam __clib_unused = va_arg (*args, vat_main_t *);
412   vnet_main_t *vnm = vnet_get_main ();
413   u32 *result = va_arg (*args, u32 *);
414
415   return unformat (input, "%U", unformat_vnet_sw_interface, vnm, result);
416 }
417
418 static uword
419 api_unformat_hw_if_index (unformat_input_t * input, va_list * args)
420 {
421   vat_main_t *vam __clib_unused = va_arg (*args, vat_main_t *);
422   vnet_main_t *vnm = vnet_get_main ();
423   u32 *result = va_arg (*args, u32 *);
424
425   return unformat (input, "%U", unformat_vnet_hw_interface, vnm, result);
426 }
427
428 #endif /* VPP_API_TEST_BUILTIN */
429
430 uword
431 unformat_ipsec_api_crypto_alg (unformat_input_t * input, va_list * args)
432 {
433   u32 *r = va_arg (*args, u32 *);
434
435   if (0);
436 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_API_CRYPTO_ALG_##f;
437   foreach_ipsec_crypto_alg
438 #undef _
439     else
440     return 0;
441   return 1;
442 }
443
444 uword
445 unformat_ipsec_api_integ_alg (unformat_input_t * input, va_list * args)
446 {
447   u32 *r = va_arg (*args, u32 *);
448
449   if (0);
450 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_API_INTEG_ALG_##f;
451   foreach_ipsec_integ_alg
452 #undef _
453     else
454     return 0;
455   return 1;
456 }
457
458 static uword
459 unformat_policer_rate_type (unformat_input_t * input, va_list * args)
460 {
461   u8 *r = va_arg (*args, u8 *);
462
463   if (unformat (input, "kbps"))
464     *r = SSE2_QOS_RATE_KBPS;
465   else if (unformat (input, "pps"))
466     *r = SSE2_QOS_RATE_PPS;
467   else
468     return 0;
469   return 1;
470 }
471
472 static uword
473 unformat_policer_round_type (unformat_input_t * input, va_list * args)
474 {
475   u8 *r = va_arg (*args, u8 *);
476
477   if (unformat (input, "closest"))
478     *r = SSE2_QOS_ROUND_TO_CLOSEST;
479   else if (unformat (input, "up"))
480     *r = SSE2_QOS_ROUND_TO_UP;
481   else if (unformat (input, "down"))
482     *r = SSE2_QOS_ROUND_TO_DOWN;
483   else
484     return 0;
485   return 1;
486 }
487
488 static uword
489 unformat_policer_type (unformat_input_t * input, va_list * args)
490 {
491   u8 *r = va_arg (*args, u8 *);
492
493   if (unformat (input, "1r2c"))
494     *r = SSE2_QOS_POLICER_TYPE_1R2C;
495   else if (unformat (input, "1r3c"))
496     *r = SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697;
497   else if (unformat (input, "2r3c-2698"))
498     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698;
499   else if (unformat (input, "2r3c-4115"))
500     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115;
501   else if (unformat (input, "2r3c-mef5cf1"))
502     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1;
503   else
504     return 0;
505   return 1;
506 }
507
508 static uword
509 unformat_dscp (unformat_input_t * input, va_list * va)
510 {
511   u8 *r = va_arg (*va, u8 *);
512
513   if (0);
514 #define _(v,f,str) else if (unformat (input, str)) *r = VNET_DSCP_##f;
515   foreach_vnet_dscp
516 #undef _
517     else
518     return 0;
519   return 1;
520 }
521
522 static uword
523 unformat_policer_action_type (unformat_input_t * input, va_list * va)
524 {
525   sse2_qos_pol_action_params_st *a
526     = va_arg (*va, sse2_qos_pol_action_params_st *);
527
528   if (unformat (input, "drop"))
529     a->action_type = SSE2_QOS_ACTION_DROP;
530   else if (unformat (input, "transmit"))
531     a->action_type = SSE2_QOS_ACTION_TRANSMIT;
532   else if (unformat (input, "mark-and-transmit %U", unformat_dscp, &a->dscp))
533     a->action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
534   else
535     return 0;
536   return 1;
537 }
538
539 static uword
540 unformat_policer_classify_table_type (unformat_input_t * input, va_list * va)
541 {
542   u32 *r = va_arg (*va, u32 *);
543   u32 tid;
544
545   if (unformat (input, "ip4"))
546     tid = POLICER_CLASSIFY_TABLE_IP4;
547   else if (unformat (input, "ip6"))
548     tid = POLICER_CLASSIFY_TABLE_IP6;
549   else if (unformat (input, "l2"))
550     tid = POLICER_CLASSIFY_TABLE_L2;
551   else
552     return 0;
553
554   *r = tid;
555   return 1;
556 }
557
558 static uword
559 unformat_flow_classify_table_type (unformat_input_t * input, va_list * va)
560 {
561   u32 *r = va_arg (*va, u32 *);
562   u32 tid;
563
564   if (unformat (input, "ip4"))
565     tid = FLOW_CLASSIFY_TABLE_IP4;
566   else if (unformat (input, "ip6"))
567     tid = FLOW_CLASSIFY_TABLE_IP6;
568   else
569     return 0;
570
571   *r = tid;
572   return 1;
573 }
574
575 #if (VPP_API_TEST_BUILTIN==0)
576
577 static const char *mfib_flag_names[] = MFIB_ENTRY_NAMES_SHORT;
578 static const char *mfib_flag_long_names[] = MFIB_ENTRY_NAMES_LONG;
579 static const char *mfib_itf_flag_long_names[] = MFIB_ITF_NAMES_LONG;
580 static const char *mfib_itf_flag_names[] = MFIB_ITF_NAMES_SHORT;
581
582 uword
583 unformat_mfib_itf_flags (unformat_input_t * input, va_list * args)
584 {
585   mfib_itf_flags_t old, *iflags = va_arg (*args, mfib_itf_flags_t *);
586   mfib_itf_attribute_t attr;
587
588   old = *iflags;
589   FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
590   {
591     if (unformat (input, mfib_itf_flag_long_names[attr]))
592       *iflags |= (1 << attr);
593   }
594   FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
595   {
596     if (unformat (input, mfib_itf_flag_names[attr]))
597       *iflags |= (1 << attr);
598   }
599
600   return (old == *iflags ? 0 : 1);
601 }
602
603 uword
604 unformat_mfib_entry_flags (unformat_input_t * input, va_list * args)
605 {
606   mfib_entry_flags_t old, *eflags = va_arg (*args, mfib_entry_flags_t *);
607   mfib_entry_attribute_t attr;
608
609   old = *eflags;
610   FOR_EACH_MFIB_ATTRIBUTE (attr)
611   {
612     if (unformat (input, mfib_flag_long_names[attr]))
613       *eflags |= (1 << attr);
614   }
615   FOR_EACH_MFIB_ATTRIBUTE (attr)
616   {
617     if (unformat (input, mfib_flag_names[attr]))
618       *eflags |= (1 << attr);
619   }
620
621   return (old == *eflags ? 0 : 1);
622 }
623
624 u8 *
625 format_ip4_address (u8 * s, va_list * args)
626 {
627   u8 *a = va_arg (*args, u8 *);
628   return format (s, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]);
629 }
630
631 u8 *
632 format_ip6_address (u8 * s, va_list * args)
633 {
634   ip6_address_t *a = va_arg (*args, ip6_address_t *);
635   u32 i, i_max_n_zero, max_n_zeros, i_first_zero, n_zeros, last_double_colon;
636
637   i_max_n_zero = ARRAY_LEN (a->as_u16);
638   max_n_zeros = 0;
639   i_first_zero = i_max_n_zero;
640   n_zeros = 0;
641   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
642     {
643       u32 is_zero = a->as_u16[i] == 0;
644       if (is_zero && i_first_zero >= ARRAY_LEN (a->as_u16))
645         {
646           i_first_zero = i;
647           n_zeros = 0;
648         }
649       n_zeros += is_zero;
650       if ((!is_zero && n_zeros > max_n_zeros)
651           || (i + 1 >= ARRAY_LEN (a->as_u16) && n_zeros > max_n_zeros))
652         {
653           i_max_n_zero = i_first_zero;
654           max_n_zeros = n_zeros;
655           i_first_zero = ARRAY_LEN (a->as_u16);
656           n_zeros = 0;
657         }
658     }
659
660   last_double_colon = 0;
661   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
662     {
663       if (i == i_max_n_zero && max_n_zeros > 1)
664         {
665           s = format (s, "::");
666           i += max_n_zeros - 1;
667           last_double_colon = 1;
668         }
669       else
670         {
671           s = format (s, "%s%x",
672                       (last_double_colon || i == 0) ? "" : ":",
673                       clib_net_to_host_u16 (a->as_u16[i]));
674           last_double_colon = 0;
675         }
676     }
677
678   return s;
679 }
680
681 /* Format an IP46 address. */
682 u8 *
683 format_ip46_address (u8 * s, va_list * args)
684 {
685   ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
686   ip46_type_t type = va_arg (*args, ip46_type_t);
687   int is_ip4 = 1;
688
689   switch (type)
690     {
691     case IP46_TYPE_ANY:
692       is_ip4 = ip46_address_is_ip4 (ip46);
693       break;
694     case IP46_TYPE_IP4:
695       is_ip4 = 1;
696       break;
697     case IP46_TYPE_IP6:
698       is_ip4 = 0;
699       break;
700     }
701
702   return is_ip4 ?
703     format (s, "%U", format_ip4_address, &ip46->ip4) :
704     format (s, "%U", format_ip6_address, &ip46->ip6);
705 }
706
707 u8 *
708 format_ethernet_address (u8 * s, va_list * args)
709 {
710   u8 *a = va_arg (*args, u8 *);
711
712   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
713                  a[0], a[1], a[2], a[3], a[4], a[5]);
714 }
715 #endif
716
717 static void
718 increment_v4_address (vl_api_ip4_address_t * i)
719 {
720   ip4_address_t *a = (ip4_address_t *) i;
721   u32 v;
722
723   v = ntohl (a->as_u32) + 1;
724   a->as_u32 = ntohl (v);
725 }
726
727 static void
728 increment_v6_address (vl_api_ip6_address_t * i)
729 {
730   ip6_address_t *a = (ip6_address_t *) i;
731   u64 v0, v1;
732
733   v0 = clib_net_to_host_u64 (a->as_u64[0]);
734   v1 = clib_net_to_host_u64 (a->as_u64[1]);
735
736   v1 += 1;
737   if (v1 == 0)
738     v0 += 1;
739   a->as_u64[0] = clib_net_to_host_u64 (v0);
740   a->as_u64[1] = clib_net_to_host_u64 (v1);
741 }
742
743 static void
744 increment_address (vl_api_address_t * a)
745 {
746   if (clib_net_to_host_u32 (a->af) == ADDRESS_IP4)
747     increment_v4_address (&a->un.ip4);
748   else if (clib_net_to_host_u32 (a->af) == ADDRESS_IP6)
749     increment_v6_address (&a->un.ip6);
750 }
751
752 static void
753 set_ip4_address (vl_api_address_t * a, u32 v)
754 {
755   if (a->af == ADDRESS_IP4)
756     {
757       ip4_address_t *i = (ip4_address_t *) & a->un.ip4;
758       i->as_u32 = v;
759     }
760 }
761
762 static void
763 increment_mac_address (u8 * mac)
764 {
765   u64 tmp = *((u64 *) mac);
766   tmp = clib_net_to_host_u64 (tmp);
767   tmp += 1 << 16;               /* skip unused (least significant) octets */
768   tmp = clib_host_to_net_u64 (tmp);
769
770   clib_memcpy (mac, &tmp, 6);
771 }
772
773 static void
774 vat_json_object_add_address (vat_json_node_t * node,
775                              const char *str, const vl_api_address_t * addr)
776 {
777   if (ADDRESS_IP6 == addr->af)
778     {
779       struct in6_addr ip6;
780
781       clib_memcpy (&ip6, &addr->un.ip6, sizeof (ip6));
782       vat_json_object_add_ip6 (node, str, ip6);
783     }
784   else
785     {
786       struct in_addr ip4;
787
788       clib_memcpy (&ip4, &addr->un.ip4, sizeof (ip4));
789       vat_json_object_add_ip4 (node, str, ip4);
790     }
791 }
792
793 static void
794 vat_json_object_add_prefix (vat_json_node_t * node,
795                             const vl_api_prefix_t * prefix)
796 {
797   vat_json_object_add_uint (node, "len", prefix->len);
798   vat_json_object_add_address (node, "address", &prefix->address);
799 }
800
801 static void vl_api_create_loopback_reply_t_handler
802   (vl_api_create_loopback_reply_t * mp)
803 {
804   vat_main_t *vam = &vat_main;
805   i32 retval = ntohl (mp->retval);
806
807   vam->retval = retval;
808   vam->regenerate_interface_table = 1;
809   vam->sw_if_index = ntohl (mp->sw_if_index);
810   vam->result_ready = 1;
811 }
812
813 static void vl_api_create_loopback_reply_t_handler_json
814   (vl_api_create_loopback_reply_t * mp)
815 {
816   vat_main_t *vam = &vat_main;
817   vat_json_node_t node;
818
819   vat_json_init_object (&node);
820   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
821   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
822
823   vat_json_print (vam->ofp, &node);
824   vat_json_free (&node);
825   vam->retval = ntohl (mp->retval);
826   vam->result_ready = 1;
827 }
828
829 static void vl_api_create_loopback_instance_reply_t_handler
830   (vl_api_create_loopback_instance_reply_t * mp)
831 {
832   vat_main_t *vam = &vat_main;
833   i32 retval = ntohl (mp->retval);
834
835   vam->retval = retval;
836   vam->regenerate_interface_table = 1;
837   vam->sw_if_index = ntohl (mp->sw_if_index);
838   vam->result_ready = 1;
839 }
840
841 static void vl_api_create_loopback_instance_reply_t_handler_json
842   (vl_api_create_loopback_instance_reply_t * mp)
843 {
844   vat_main_t *vam = &vat_main;
845   vat_json_node_t node;
846
847   vat_json_init_object (&node);
848   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
849   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
850
851   vat_json_print (vam->ofp, &node);
852   vat_json_free (&node);
853   vam->retval = ntohl (mp->retval);
854   vam->result_ready = 1;
855 }
856
857 static void vl_api_af_packet_create_reply_t_handler
858   (vl_api_af_packet_create_reply_t * mp)
859 {
860   vat_main_t *vam = &vat_main;
861   i32 retval = ntohl (mp->retval);
862
863   vam->retval = retval;
864   vam->regenerate_interface_table = 1;
865   vam->sw_if_index = ntohl (mp->sw_if_index);
866   vam->result_ready = 1;
867 }
868
869 static void vl_api_af_packet_create_reply_t_handler_json
870   (vl_api_af_packet_create_reply_t * mp)
871 {
872   vat_main_t *vam = &vat_main;
873   vat_json_node_t node;
874
875   vat_json_init_object (&node);
876   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
877   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
878
879   vat_json_print (vam->ofp, &node);
880   vat_json_free (&node);
881
882   vam->retval = ntohl (mp->retval);
883   vam->result_ready = 1;
884 }
885
886 static void vl_api_create_vlan_subif_reply_t_handler
887   (vl_api_create_vlan_subif_reply_t * mp)
888 {
889   vat_main_t *vam = &vat_main;
890   i32 retval = ntohl (mp->retval);
891
892   vam->retval = retval;
893   vam->regenerate_interface_table = 1;
894   vam->sw_if_index = ntohl (mp->sw_if_index);
895   vam->result_ready = 1;
896 }
897
898 static void vl_api_create_vlan_subif_reply_t_handler_json
899   (vl_api_create_vlan_subif_reply_t * mp)
900 {
901   vat_main_t *vam = &vat_main;
902   vat_json_node_t node;
903
904   vat_json_init_object (&node);
905   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
906   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
907
908   vat_json_print (vam->ofp, &node);
909   vat_json_free (&node);
910
911   vam->retval = ntohl (mp->retval);
912   vam->result_ready = 1;
913 }
914
915 static void vl_api_create_subif_reply_t_handler
916   (vl_api_create_subif_reply_t * mp)
917 {
918   vat_main_t *vam = &vat_main;
919   i32 retval = ntohl (mp->retval);
920
921   vam->retval = retval;
922   vam->regenerate_interface_table = 1;
923   vam->sw_if_index = ntohl (mp->sw_if_index);
924   vam->result_ready = 1;
925 }
926
927 static void vl_api_create_subif_reply_t_handler_json
928   (vl_api_create_subif_reply_t * mp)
929 {
930   vat_main_t *vam = &vat_main;
931   vat_json_node_t node;
932
933   vat_json_init_object (&node);
934   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
935   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
936
937   vat_json_print (vam->ofp, &node);
938   vat_json_free (&node);
939
940   vam->retval = ntohl (mp->retval);
941   vam->result_ready = 1;
942 }
943
944 static void vl_api_interface_name_renumber_reply_t_handler
945   (vl_api_interface_name_renumber_reply_t * mp)
946 {
947   vat_main_t *vam = &vat_main;
948   i32 retval = ntohl (mp->retval);
949
950   vam->retval = retval;
951   vam->regenerate_interface_table = 1;
952   vam->result_ready = 1;
953 }
954
955 static void vl_api_interface_name_renumber_reply_t_handler_json
956   (vl_api_interface_name_renumber_reply_t * mp)
957 {
958   vat_main_t *vam = &vat_main;
959   vat_json_node_t node;
960
961   vat_json_init_object (&node);
962   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
963
964   vat_json_print (vam->ofp, &node);
965   vat_json_free (&node);
966
967   vam->retval = ntohl (mp->retval);
968   vam->result_ready = 1;
969 }
970
971 /*
972  * Special-case: build the interface table, maintain
973  * the next loopback sw_if_index vbl.
974  */
975 static void vl_api_sw_interface_details_t_handler
976   (vl_api_sw_interface_details_t * mp)
977 {
978   vat_main_t *vam = &vat_main;
979   u8 *s = format (0, "%s%c", mp->interface_name, 0);
980
981   hash_set_mem (vam->sw_if_index_by_interface_name, s,
982                 ntohl (mp->sw_if_index));
983
984   /* In sub interface case, fill the sub interface table entry */
985   if (mp->sw_if_index != mp->sup_sw_if_index)
986     {
987       sw_interface_subif_t *sub = NULL;
988
989       vec_add2 (vam->sw_if_subif_table, sub, 1);
990
991       vec_validate (sub->interface_name, strlen ((char *) s) + 1);
992       strncpy ((char *) sub->interface_name, (char *) s,
993                vec_len (sub->interface_name));
994       sub->sw_if_index = ntohl (mp->sw_if_index);
995       sub->sub_id = ntohl (mp->sub_id);
996
997       sub->raw_flags = ntohl (mp->sub_if_flags & SUB_IF_API_FLAG_MASK_VNET);
998
999       sub->sub_number_of_tags = mp->sub_number_of_tags;
1000       sub->sub_outer_vlan_id = ntohs (mp->sub_outer_vlan_id);
1001       sub->sub_inner_vlan_id = ntohs (mp->sub_inner_vlan_id);
1002
1003       /* vlan tag rewrite */
1004       sub->vtr_op = ntohl (mp->vtr_op);
1005       sub->vtr_push_dot1q = ntohl (mp->vtr_push_dot1q);
1006       sub->vtr_tag1 = ntohl (mp->vtr_tag1);
1007       sub->vtr_tag2 = ntohl (mp->vtr_tag2);
1008     }
1009 }
1010
1011 static void vl_api_sw_interface_details_t_handler_json
1012   (vl_api_sw_interface_details_t * mp)
1013 {
1014   vat_main_t *vam = &vat_main;
1015   vat_json_node_t *node = NULL;
1016
1017   if (VAT_JSON_ARRAY != vam->json_tree.type)
1018     {
1019       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1020       vat_json_init_array (&vam->json_tree);
1021     }
1022   node = vat_json_array_add (&vam->json_tree);
1023
1024   vat_json_init_object (node);
1025   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
1026   vat_json_object_add_uint (node, "sup_sw_if_index",
1027                             ntohl (mp->sup_sw_if_index));
1028   vat_json_object_add_bytes (node, "l2_address", mp->l2_address,
1029                              sizeof (mp->l2_address));
1030   vat_json_object_add_string_copy (node, "interface_name",
1031                                    mp->interface_name);
1032   vat_json_object_add_string_copy (node, "interface_dev_type",
1033                                    mp->interface_dev_type);
1034   vat_json_object_add_uint (node, "flags", mp->flags);
1035   vat_json_object_add_uint (node, "link_duplex", mp->link_duplex);
1036   vat_json_object_add_uint (node, "link_speed", mp->link_speed);
1037   vat_json_object_add_uint (node, "mtu", ntohs (mp->link_mtu));
1038   vat_json_object_add_uint (node, "sub_id", ntohl (mp->sub_id));
1039   vat_json_object_add_uint (node, "sub_number_of_tags",
1040                             mp->sub_number_of_tags);
1041   vat_json_object_add_uint (node, "sub_outer_vlan_id",
1042                             ntohs (mp->sub_outer_vlan_id));
1043   vat_json_object_add_uint (node, "sub_inner_vlan_id",
1044                             ntohs (mp->sub_inner_vlan_id));
1045   vat_json_object_add_uint (node, "sub_if_flags", ntohl (mp->sub_if_flags));
1046   vat_json_object_add_uint (node, "vtr_op", ntohl (mp->vtr_op));
1047   vat_json_object_add_uint (node, "vtr_push_dot1q",
1048                             ntohl (mp->vtr_push_dot1q));
1049   vat_json_object_add_uint (node, "vtr_tag1", ntohl (mp->vtr_tag1));
1050   vat_json_object_add_uint (node, "vtr_tag2", ntohl (mp->vtr_tag2));
1051   if (ntohl (mp->sub_if_flags) & SUB_IF_API_FLAG_DOT1AH)
1052     {
1053       vat_json_object_add_string_copy (node, "pbb_vtr_dmac",
1054                                        format (0, "%U",
1055                                                format_ethernet_address,
1056                                                &mp->b_dmac));
1057       vat_json_object_add_string_copy (node, "pbb_vtr_smac",
1058                                        format (0, "%U",
1059                                                format_ethernet_address,
1060                                                &mp->b_smac));
1061       vat_json_object_add_uint (node, "pbb_vtr_b_vlanid", mp->b_vlanid);
1062       vat_json_object_add_uint (node, "pbb_vtr_i_sid", mp->i_sid);
1063     }
1064 }
1065
1066 #if VPP_API_TEST_BUILTIN == 0
1067 static void vl_api_sw_interface_event_t_handler
1068   (vl_api_sw_interface_event_t * mp)
1069 {
1070   vat_main_t *vam = &vat_main;
1071   if (vam->interface_event_display)
1072     errmsg ("interface flags: sw_if_index %d %s %s",
1073             ntohl (mp->sw_if_index),
1074             ((ntohl (mp->flags)) & IF_STATUS_API_FLAG_ADMIN_UP) ?
1075             "admin-up" : "admin-down",
1076             ((ntohl (mp->flags)) & IF_STATUS_API_FLAG_LINK_UP) ?
1077             "link-up" : "link-down");
1078 }
1079 #endif
1080
1081 __clib_unused static void
1082 vl_api_sw_interface_event_t_handler_json (vl_api_sw_interface_event_t * mp)
1083 {
1084   /* JSON output not supported */
1085 }
1086
1087 static void
1088 vl_api_cli_reply_t_handler (vl_api_cli_reply_t * mp)
1089 {
1090   vat_main_t *vam = &vat_main;
1091   i32 retval = ntohl (mp->retval);
1092
1093   vam->retval = retval;
1094   vam->shmem_result = uword_to_pointer (mp->reply_in_shmem, u8 *);
1095   vam->result_ready = 1;
1096 }
1097
1098 static void
1099 vl_api_cli_reply_t_handler_json (vl_api_cli_reply_t * mp)
1100 {
1101   vat_main_t *vam = &vat_main;
1102   vat_json_node_t node;
1103   api_main_t *am = &api_main;
1104   void *oldheap;
1105   u8 *reply;
1106
1107   vat_json_init_object (&node);
1108   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1109   vat_json_object_add_uint (&node, "reply_in_shmem",
1110                             ntohl (mp->reply_in_shmem));
1111   /* Toss the shared-memory original... */
1112   pthread_mutex_lock (&am->vlib_rp->mutex);
1113   oldheap = svm_push_data_heap (am->vlib_rp);
1114
1115   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
1116   vec_free (reply);
1117
1118   svm_pop_heap (oldheap);
1119   pthread_mutex_unlock (&am->vlib_rp->mutex);
1120
1121   vat_json_print (vam->ofp, &node);
1122   vat_json_free (&node);
1123
1124   vam->retval = ntohl (mp->retval);
1125   vam->result_ready = 1;
1126 }
1127
1128 static void
1129 vl_api_cli_inband_reply_t_handler (vl_api_cli_inband_reply_t * mp)
1130 {
1131   vat_main_t *vam = &vat_main;
1132   i32 retval = ntohl (mp->retval);
1133   u32 length = vl_api_string_len (&mp->reply);
1134
1135   vec_reset_length (vam->cmd_reply);
1136
1137   vam->retval = retval;
1138   if (retval == 0)
1139     {
1140       vec_validate (vam->cmd_reply, length);
1141       clib_memcpy ((char *) (vam->cmd_reply),
1142                    vl_api_from_api_string (&mp->reply), length);
1143       vam->cmd_reply[length] = 0;
1144     }
1145   vam->result_ready = 1;
1146 }
1147
1148 static void
1149 vl_api_cli_inband_reply_t_handler_json (vl_api_cli_inband_reply_t * mp)
1150 {
1151   vat_main_t *vam = &vat_main;
1152   vat_json_node_t node;
1153
1154   vec_reset_length (vam->cmd_reply);
1155
1156   vat_json_init_object (&node);
1157   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1158   vat_json_object_add_string_copy (&node, "reply",
1159                                    vl_api_from_api_string (&mp->reply));
1160
1161   vat_json_print (vam->ofp, &node);
1162   vat_json_free (&node);
1163
1164   vam->retval = ntohl (mp->retval);
1165   vam->result_ready = 1;
1166 }
1167
1168 static void vl_api_classify_add_del_table_reply_t_handler
1169   (vl_api_classify_add_del_table_reply_t * mp)
1170 {
1171   vat_main_t *vam = &vat_main;
1172   i32 retval = ntohl (mp->retval);
1173   if (vam->async_mode)
1174     {
1175       vam->async_errors += (retval < 0);
1176     }
1177   else
1178     {
1179       vam->retval = retval;
1180       if (retval == 0 &&
1181           ((mp->new_table_index != 0xFFFFFFFF) ||
1182            (mp->skip_n_vectors != 0xFFFFFFFF) ||
1183            (mp->match_n_vectors != 0xFFFFFFFF)))
1184         /*
1185          * Note: this is just barely thread-safe, depends on
1186          * the main thread spinning waiting for an answer...
1187          */
1188         errmsg ("new index %d, skip_n_vectors %d, match_n_vectors %d",
1189                 ntohl (mp->new_table_index),
1190                 ntohl (mp->skip_n_vectors), ntohl (mp->match_n_vectors));
1191       vam->result_ready = 1;
1192     }
1193 }
1194
1195 static void vl_api_classify_add_del_table_reply_t_handler_json
1196   (vl_api_classify_add_del_table_reply_t * mp)
1197 {
1198   vat_main_t *vam = &vat_main;
1199   vat_json_node_t node;
1200
1201   vat_json_init_object (&node);
1202   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1203   vat_json_object_add_uint (&node, "new_table_index",
1204                             ntohl (mp->new_table_index));
1205   vat_json_object_add_uint (&node, "skip_n_vectors",
1206                             ntohl (mp->skip_n_vectors));
1207   vat_json_object_add_uint (&node, "match_n_vectors",
1208                             ntohl (mp->match_n_vectors));
1209
1210   vat_json_print (vam->ofp, &node);
1211   vat_json_free (&node);
1212
1213   vam->retval = ntohl (mp->retval);
1214   vam->result_ready = 1;
1215 }
1216
1217 static void vl_api_get_node_index_reply_t_handler
1218   (vl_api_get_node_index_reply_t * mp)
1219 {
1220   vat_main_t *vam = &vat_main;
1221   i32 retval = ntohl (mp->retval);
1222   if (vam->async_mode)
1223     {
1224       vam->async_errors += (retval < 0);
1225     }
1226   else
1227     {
1228       vam->retval = retval;
1229       if (retval == 0)
1230         errmsg ("node index %d", ntohl (mp->node_index));
1231       vam->result_ready = 1;
1232     }
1233 }
1234
1235 static void vl_api_get_node_index_reply_t_handler_json
1236   (vl_api_get_node_index_reply_t * mp)
1237 {
1238   vat_main_t *vam = &vat_main;
1239   vat_json_node_t node;
1240
1241   vat_json_init_object (&node);
1242   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1243   vat_json_object_add_uint (&node, "node_index", ntohl (mp->node_index));
1244
1245   vat_json_print (vam->ofp, &node);
1246   vat_json_free (&node);
1247
1248   vam->retval = ntohl (mp->retval);
1249   vam->result_ready = 1;
1250 }
1251
1252 static void vl_api_get_next_index_reply_t_handler
1253   (vl_api_get_next_index_reply_t * mp)
1254 {
1255   vat_main_t *vam = &vat_main;
1256   i32 retval = ntohl (mp->retval);
1257   if (vam->async_mode)
1258     {
1259       vam->async_errors += (retval < 0);
1260     }
1261   else
1262     {
1263       vam->retval = retval;
1264       if (retval == 0)
1265         errmsg ("next node index %d", ntohl (mp->next_index));
1266       vam->result_ready = 1;
1267     }
1268 }
1269
1270 static void vl_api_get_next_index_reply_t_handler_json
1271   (vl_api_get_next_index_reply_t * mp)
1272 {
1273   vat_main_t *vam = &vat_main;
1274   vat_json_node_t node;
1275
1276   vat_json_init_object (&node);
1277   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1278   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1279
1280   vat_json_print (vam->ofp, &node);
1281   vat_json_free (&node);
1282
1283   vam->retval = ntohl (mp->retval);
1284   vam->result_ready = 1;
1285 }
1286
1287 static void vl_api_add_node_next_reply_t_handler
1288   (vl_api_add_node_next_reply_t * mp)
1289 {
1290   vat_main_t *vam = &vat_main;
1291   i32 retval = ntohl (mp->retval);
1292   if (vam->async_mode)
1293     {
1294       vam->async_errors += (retval < 0);
1295     }
1296   else
1297     {
1298       vam->retval = retval;
1299       if (retval == 0)
1300         errmsg ("next index %d", ntohl (mp->next_index));
1301       vam->result_ready = 1;
1302     }
1303 }
1304
1305 static void vl_api_add_node_next_reply_t_handler_json
1306   (vl_api_add_node_next_reply_t * mp)
1307 {
1308   vat_main_t *vam = &vat_main;
1309   vat_json_node_t node;
1310
1311   vat_json_init_object (&node);
1312   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1313   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1314
1315   vat_json_print (vam->ofp, &node);
1316   vat_json_free (&node);
1317
1318   vam->retval = ntohl (mp->retval);
1319   vam->result_ready = 1;
1320 }
1321
1322 static void vl_api_show_version_reply_t_handler
1323   (vl_api_show_version_reply_t * mp)
1324 {
1325   vat_main_t *vam = &vat_main;
1326   i32 retval = ntohl (mp->retval);
1327
1328   if (retval >= 0)
1329     {
1330       errmsg ("        program: %s", mp->program);
1331       errmsg ("        version: %s", mp->version);
1332       errmsg ("     build date: %s", mp->build_date);
1333       errmsg ("build directory: %s", mp->build_directory);
1334     }
1335   vam->retval = retval;
1336   vam->result_ready = 1;
1337 }
1338
1339 static void vl_api_show_version_reply_t_handler_json
1340   (vl_api_show_version_reply_t * mp)
1341 {
1342   vat_main_t *vam = &vat_main;
1343   vat_json_node_t node;
1344
1345   vat_json_init_object (&node);
1346   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1347   vat_json_object_add_string_copy (&node, "program", mp->program);
1348   vat_json_object_add_string_copy (&node, "version", mp->version);
1349   vat_json_object_add_string_copy (&node, "build_date", mp->build_date);
1350   vat_json_object_add_string_copy (&node, "build_directory",
1351                                    mp->build_directory);
1352
1353   vat_json_print (vam->ofp, &node);
1354   vat_json_free (&node);
1355
1356   vam->retval = ntohl (mp->retval);
1357   vam->result_ready = 1;
1358 }
1359
1360 static void vl_api_show_threads_reply_t_handler
1361   (vl_api_show_threads_reply_t * mp)
1362 {
1363   vat_main_t *vam = &vat_main;
1364   i32 retval = ntohl (mp->retval);
1365   int i, count = 0;
1366
1367   if (retval >= 0)
1368     count = ntohl (mp->count);
1369
1370   for (i = 0; i < count; i++)
1371     print (vam->ofp,
1372            "\n%-2d %-11s %-11s %-5d %-6d %-4d %-6d",
1373            ntohl (mp->thread_data[i].id), mp->thread_data[i].name,
1374            mp->thread_data[i].type, ntohl (mp->thread_data[i].pid),
1375            ntohl (mp->thread_data[i].cpu_id), ntohl (mp->thread_data[i].core),
1376            ntohl (mp->thread_data[i].cpu_socket));
1377
1378   vam->retval = retval;
1379   vam->result_ready = 1;
1380 }
1381
1382 static void vl_api_show_threads_reply_t_handler_json
1383   (vl_api_show_threads_reply_t * mp)
1384 {
1385   vat_main_t *vam = &vat_main;
1386   vat_json_node_t node;
1387   vl_api_thread_data_t *td;
1388   i32 retval = ntohl (mp->retval);
1389   int i, count = 0;
1390
1391   if (retval >= 0)
1392     count = ntohl (mp->count);
1393
1394   vat_json_init_object (&node);
1395   vat_json_object_add_int (&node, "retval", retval);
1396   vat_json_object_add_uint (&node, "count", count);
1397
1398   for (i = 0; i < count; i++)
1399     {
1400       td = &mp->thread_data[i];
1401       vat_json_object_add_uint (&node, "id", ntohl (td->id));
1402       vat_json_object_add_string_copy (&node, "name", td->name);
1403       vat_json_object_add_string_copy (&node, "type", td->type);
1404       vat_json_object_add_uint (&node, "pid", ntohl (td->pid));
1405       vat_json_object_add_int (&node, "cpu_id", ntohl (td->cpu_id));
1406       vat_json_object_add_int (&node, "core", ntohl (td->id));
1407       vat_json_object_add_int (&node, "cpu_socket", ntohl (td->cpu_socket));
1408     }
1409
1410   vat_json_print (vam->ofp, &node);
1411   vat_json_free (&node);
1412
1413   vam->retval = retval;
1414   vam->result_ready = 1;
1415 }
1416
1417 static int
1418 api_show_threads (vat_main_t * vam)
1419 {
1420   vl_api_show_threads_t *mp;
1421   int ret;
1422
1423   print (vam->ofp,
1424          "\n%-2s %-11s %-11s %-5s %-6s %-4s %-6s",
1425          "ID", "Name", "Type", "LWP", "cpu_id", "Core", "Socket");
1426
1427   M (SHOW_THREADS, mp);
1428
1429   S (mp);
1430   W (ret);
1431   return ret;
1432 }
1433
1434 static void
1435 vl_api_ip4_arp_event_t_handler (vl_api_ip4_arp_event_t * mp)
1436 {
1437   u32 sw_if_index = ntohl (mp->sw_if_index);
1438   errmsg ("arp %s event: pid %d address %U new mac %U sw_if_index %d\n",
1439           mp->mac_ip ? "mac/ip binding" : "address resolution",
1440           ntohl (mp->pid), format_ip4_address, mp->ip,
1441           format_vl_api_mac_address, &mp->mac, sw_if_index);
1442 }
1443
1444 static void
1445 vl_api_ip4_arp_event_t_handler_json (vl_api_ip4_arp_event_t * mp)
1446 {
1447   /* JSON output not supported */
1448 }
1449
1450 static void
1451 vl_api_ip6_nd_event_t_handler (vl_api_ip6_nd_event_t * mp)
1452 {
1453   u32 sw_if_index = ntohl (mp->sw_if_index);
1454   errmsg ("ip6 nd %s event: pid %d address %U new mac %U sw_if_index %d\n",
1455           mp->mac_ip ? "mac/ip binding" : "address resolution",
1456           ntohl (mp->pid), format_vl_api_ip6_address, mp->ip,
1457           format_vl_api_mac_address, mp->mac, sw_if_index);
1458 }
1459
1460 static void
1461 vl_api_ip6_nd_event_t_handler_json (vl_api_ip6_nd_event_t * mp)
1462 {
1463   /* JSON output not supported */
1464 }
1465
1466 static void
1467 vl_api_l2_macs_event_t_handler (vl_api_l2_macs_event_t * mp)
1468 {
1469   u32 n_macs = ntohl (mp->n_macs);
1470   errmsg ("L2MAC event received with pid %d cl-idx %d for %d macs: \n",
1471           ntohl (mp->pid), mp->client_index, n_macs);
1472   int i;
1473   for (i = 0; i < n_macs; i++)
1474     {
1475       vl_api_mac_entry_t *mac = &mp->mac[i];
1476       errmsg (" [%d] sw_if_index %d  mac_addr %U  action %d \n",
1477               i + 1, ntohl (mac->sw_if_index),
1478               format_ethernet_address, mac->mac_addr, mac->action);
1479       if (i == 1000)
1480         break;
1481     }
1482 }
1483
1484 static void
1485 vl_api_l2_macs_event_t_handler_json (vl_api_l2_macs_event_t * mp)
1486 {
1487   /* JSON output not supported */
1488 }
1489
1490 #define vl_api_bridge_domain_details_t_endian vl_noop_handler
1491 #define vl_api_bridge_domain_details_t_print vl_noop_handler
1492
1493 /*
1494  * Special-case: build the bridge domain table, maintain
1495  * the next bd id vbl.
1496  */
1497 static void vl_api_bridge_domain_details_t_handler
1498   (vl_api_bridge_domain_details_t * mp)
1499 {
1500   vat_main_t *vam = &vat_main;
1501   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1502   int i;
1503
1504   print (vam->ofp, "\n%-3s %-3s %-3s %-3s %-3s %-6s %-3s",
1505          " ID", "LRN", "FWD", "FLD", "BVI", "UU-FWD", "#IF");
1506
1507   print (vam->ofp, "%3d %3d %3d %3d %3d %6d %3d",
1508          ntohl (mp->bd_id), mp->learn, mp->forward,
1509          mp->flood, ntohl (mp->bvi_sw_if_index),
1510          ntohl (mp->uu_fwd_sw_if_index), n_sw_ifs);
1511
1512   if (n_sw_ifs)
1513     {
1514       vl_api_bridge_domain_sw_if_t *sw_ifs;
1515       print (vam->ofp, "\n\n%s %s  %s", "sw_if_index", "SHG",
1516              "Interface Name");
1517
1518       sw_ifs = mp->sw_if_details;
1519       for (i = 0; i < n_sw_ifs; i++)
1520         {
1521           u8 *sw_if_name = 0;
1522           u32 sw_if_index;
1523           hash_pair_t *p;
1524
1525           sw_if_index = ntohl (sw_ifs->sw_if_index);
1526
1527           /* *INDENT-OFF* */
1528           hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
1529                              ({
1530                                if ((u32) p->value[0] == sw_if_index)
1531                                  {
1532                                    sw_if_name = (u8 *)(p->key);
1533                                    break;
1534                                  }
1535                              }));
1536           /* *INDENT-ON* */
1537           print (vam->ofp, "%7d     %3d  %s", sw_if_index,
1538                  sw_ifs->shg, sw_if_name ? (char *) sw_if_name :
1539                  "sw_if_index not found!");
1540
1541           sw_ifs++;
1542         }
1543     }
1544 }
1545
1546 static void vl_api_bridge_domain_details_t_handler_json
1547   (vl_api_bridge_domain_details_t * mp)
1548 {
1549   vat_main_t *vam = &vat_main;
1550   vat_json_node_t *node, *array = NULL;
1551   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1552
1553   if (VAT_JSON_ARRAY != vam->json_tree.type)
1554     {
1555       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1556       vat_json_init_array (&vam->json_tree);
1557     }
1558   node = vat_json_array_add (&vam->json_tree);
1559
1560   vat_json_init_object (node);
1561   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1562   vat_json_object_add_uint (node, "flood", mp->flood);
1563   vat_json_object_add_uint (node, "forward", mp->forward);
1564   vat_json_object_add_uint (node, "learn", mp->learn);
1565   vat_json_object_add_uint (node, "bvi_sw_if_index",
1566                             ntohl (mp->bvi_sw_if_index));
1567   vat_json_object_add_uint (node, "n_sw_ifs", n_sw_ifs);
1568   array = vat_json_object_add (node, "sw_if");
1569   vat_json_init_array (array);
1570
1571
1572
1573   if (n_sw_ifs)
1574     {
1575       vl_api_bridge_domain_sw_if_t *sw_ifs;
1576       int i;
1577
1578       sw_ifs = mp->sw_if_details;
1579       for (i = 0; i < n_sw_ifs; i++)
1580         {
1581           node = vat_json_array_add (array);
1582           vat_json_init_object (node);
1583           vat_json_object_add_uint (node, "sw_if_index",
1584                                     ntohl (sw_ifs->sw_if_index));
1585           vat_json_object_add_uint (node, "shg", sw_ifs->shg);
1586           sw_ifs++;
1587         }
1588     }
1589 }
1590
1591 static void vl_api_control_ping_reply_t_handler
1592   (vl_api_control_ping_reply_t * mp)
1593 {
1594   vat_main_t *vam = &vat_main;
1595   i32 retval = ntohl (mp->retval);
1596   if (vam->async_mode)
1597     {
1598       vam->async_errors += (retval < 0);
1599     }
1600   else
1601     {
1602       vam->retval = retval;
1603       vam->result_ready = 1;
1604     }
1605   if (vam->socket_client_main)
1606     vam->socket_client_main->control_pings_outstanding--;
1607 }
1608
1609 static void vl_api_control_ping_reply_t_handler_json
1610   (vl_api_control_ping_reply_t * mp)
1611 {
1612   vat_main_t *vam = &vat_main;
1613   i32 retval = ntohl (mp->retval);
1614
1615   if (VAT_JSON_NONE != vam->json_tree.type)
1616     {
1617       vat_json_print (vam->ofp, &vam->json_tree);
1618       vat_json_free (&vam->json_tree);
1619       vam->json_tree.type = VAT_JSON_NONE;
1620     }
1621   else
1622     {
1623       /* just print [] */
1624       vat_json_init_array (&vam->json_tree);
1625       vat_json_print (vam->ofp, &vam->json_tree);
1626       vam->json_tree.type = VAT_JSON_NONE;
1627     }
1628
1629   vam->retval = retval;
1630   vam->result_ready = 1;
1631 }
1632
1633 static void
1634   vl_api_bridge_domain_set_mac_age_reply_t_handler
1635   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1636 {
1637   vat_main_t *vam = &vat_main;
1638   i32 retval = ntohl (mp->retval);
1639   if (vam->async_mode)
1640     {
1641       vam->async_errors += (retval < 0);
1642     }
1643   else
1644     {
1645       vam->retval = retval;
1646       vam->result_ready = 1;
1647     }
1648 }
1649
1650 static void vl_api_bridge_domain_set_mac_age_reply_t_handler_json
1651   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1652 {
1653   vat_main_t *vam = &vat_main;
1654   vat_json_node_t node;
1655
1656   vat_json_init_object (&node);
1657   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1658
1659   vat_json_print (vam->ofp, &node);
1660   vat_json_free (&node);
1661
1662   vam->retval = ntohl (mp->retval);
1663   vam->result_ready = 1;
1664 }
1665
1666 static void
1667 vl_api_l2_flags_reply_t_handler (vl_api_l2_flags_reply_t * mp)
1668 {
1669   vat_main_t *vam = &vat_main;
1670   i32 retval = ntohl (mp->retval);
1671   if (vam->async_mode)
1672     {
1673       vam->async_errors += (retval < 0);
1674     }
1675   else
1676     {
1677       vam->retval = retval;
1678       vam->result_ready = 1;
1679     }
1680 }
1681
1682 static void vl_api_l2_flags_reply_t_handler_json
1683   (vl_api_l2_flags_reply_t * mp)
1684 {
1685   vat_main_t *vam = &vat_main;
1686   vat_json_node_t node;
1687
1688   vat_json_init_object (&node);
1689   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1690   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1691                             ntohl (mp->resulting_feature_bitmap));
1692
1693   vat_json_print (vam->ofp, &node);
1694   vat_json_free (&node);
1695
1696   vam->retval = ntohl (mp->retval);
1697   vam->result_ready = 1;
1698 }
1699
1700 static void vl_api_bridge_flags_reply_t_handler
1701   (vl_api_bridge_flags_reply_t * mp)
1702 {
1703   vat_main_t *vam = &vat_main;
1704   i32 retval = ntohl (mp->retval);
1705   if (vam->async_mode)
1706     {
1707       vam->async_errors += (retval < 0);
1708     }
1709   else
1710     {
1711       vam->retval = retval;
1712       vam->result_ready = 1;
1713     }
1714 }
1715
1716 static void vl_api_bridge_flags_reply_t_handler_json
1717   (vl_api_bridge_flags_reply_t * mp)
1718 {
1719   vat_main_t *vam = &vat_main;
1720   vat_json_node_t node;
1721
1722   vat_json_init_object (&node);
1723   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1724   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1725                             ntohl (mp->resulting_feature_bitmap));
1726
1727   vat_json_print (vam->ofp, &node);
1728   vat_json_free (&node);
1729
1730   vam->retval = ntohl (mp->retval);
1731   vam->result_ready = 1;
1732 }
1733
1734 static void
1735 vl_api_tap_create_v2_reply_t_handler (vl_api_tap_create_v2_reply_t * mp)
1736 {
1737   vat_main_t *vam = &vat_main;
1738   i32 retval = ntohl (mp->retval);
1739   if (vam->async_mode)
1740     {
1741       vam->async_errors += (retval < 0);
1742     }
1743   else
1744     {
1745       vam->retval = retval;
1746       vam->sw_if_index = ntohl (mp->sw_if_index);
1747       vam->result_ready = 1;
1748     }
1749
1750 }
1751
1752 static void vl_api_tap_create_v2_reply_t_handler_json
1753   (vl_api_tap_create_v2_reply_t * mp)
1754 {
1755   vat_main_t *vam = &vat_main;
1756   vat_json_node_t node;
1757
1758   vat_json_init_object (&node);
1759   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1760   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1761
1762   vat_json_print (vam->ofp, &node);
1763   vat_json_free (&node);
1764
1765   vam->retval = ntohl (mp->retval);
1766   vam->result_ready = 1;
1767
1768 }
1769
1770 static void
1771 vl_api_tap_delete_v2_reply_t_handler (vl_api_tap_delete_v2_reply_t * mp)
1772 {
1773   vat_main_t *vam = &vat_main;
1774   i32 retval = ntohl (mp->retval);
1775   if (vam->async_mode)
1776     {
1777       vam->async_errors += (retval < 0);
1778     }
1779   else
1780     {
1781       vam->retval = retval;
1782       vam->result_ready = 1;
1783     }
1784 }
1785
1786 static void vl_api_tap_delete_v2_reply_t_handler_json
1787   (vl_api_tap_delete_v2_reply_t * mp)
1788 {
1789   vat_main_t *vam = &vat_main;
1790   vat_json_node_t node;
1791
1792   vat_json_init_object (&node);
1793   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1794
1795   vat_json_print (vam->ofp, &node);
1796   vat_json_free (&node);
1797
1798   vam->retval = ntohl (mp->retval);
1799   vam->result_ready = 1;
1800 }
1801
1802 static void
1803 vl_api_virtio_pci_create_reply_t_handler (vl_api_virtio_pci_create_reply_t *
1804                                           mp)
1805 {
1806   vat_main_t *vam = &vat_main;
1807   i32 retval = ntohl (mp->retval);
1808   if (vam->async_mode)
1809     {
1810       vam->async_errors += (retval < 0);
1811     }
1812   else
1813     {
1814       vam->retval = retval;
1815       vam->sw_if_index = ntohl (mp->sw_if_index);
1816       vam->result_ready = 1;
1817     }
1818 }
1819
1820 static void vl_api_virtio_pci_create_reply_t_handler_json
1821   (vl_api_virtio_pci_create_reply_t * mp)
1822 {
1823   vat_main_t *vam = &vat_main;
1824   vat_json_node_t node;
1825
1826   vat_json_init_object (&node);
1827   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1828   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1829
1830   vat_json_print (vam->ofp, &node);
1831   vat_json_free (&node);
1832
1833   vam->retval = ntohl (mp->retval);
1834   vam->result_ready = 1;
1835
1836 }
1837
1838 static void
1839 vl_api_virtio_pci_delete_reply_t_handler (vl_api_virtio_pci_delete_reply_t *
1840                                           mp)
1841 {
1842   vat_main_t *vam = &vat_main;
1843   i32 retval = ntohl (mp->retval);
1844   if (vam->async_mode)
1845     {
1846       vam->async_errors += (retval < 0);
1847     }
1848   else
1849     {
1850       vam->retval = retval;
1851       vam->result_ready = 1;
1852     }
1853 }
1854
1855 static void vl_api_virtio_pci_delete_reply_t_handler_json
1856   (vl_api_virtio_pci_delete_reply_t * mp)
1857 {
1858   vat_main_t *vam = &vat_main;
1859   vat_json_node_t node;
1860
1861   vat_json_init_object (&node);
1862   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1863
1864   vat_json_print (vam->ofp, &node);
1865   vat_json_free (&node);
1866
1867   vam->retval = ntohl (mp->retval);
1868   vam->result_ready = 1;
1869 }
1870
1871 static void
1872 vl_api_bond_create_reply_t_handler (vl_api_bond_create_reply_t * mp)
1873 {
1874   vat_main_t *vam = &vat_main;
1875   i32 retval = ntohl (mp->retval);
1876
1877   if (vam->async_mode)
1878     {
1879       vam->async_errors += (retval < 0);
1880     }
1881   else
1882     {
1883       vam->retval = retval;
1884       vam->sw_if_index = ntohl (mp->sw_if_index);
1885       vam->result_ready = 1;
1886     }
1887 }
1888
1889 static void vl_api_bond_create_reply_t_handler_json
1890   (vl_api_bond_create_reply_t * mp)
1891 {
1892   vat_main_t *vam = &vat_main;
1893   vat_json_node_t node;
1894
1895   vat_json_init_object (&node);
1896   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1897   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1898
1899   vat_json_print (vam->ofp, &node);
1900   vat_json_free (&node);
1901
1902   vam->retval = ntohl (mp->retval);
1903   vam->result_ready = 1;
1904 }
1905
1906 static void
1907 vl_api_bond_delete_reply_t_handler (vl_api_bond_delete_reply_t * mp)
1908 {
1909   vat_main_t *vam = &vat_main;
1910   i32 retval = ntohl (mp->retval);
1911
1912   if (vam->async_mode)
1913     {
1914       vam->async_errors += (retval < 0);
1915     }
1916   else
1917     {
1918       vam->retval = retval;
1919       vam->result_ready = 1;
1920     }
1921 }
1922
1923 static void vl_api_bond_delete_reply_t_handler_json
1924   (vl_api_bond_delete_reply_t * mp)
1925 {
1926   vat_main_t *vam = &vat_main;
1927   vat_json_node_t node;
1928
1929   vat_json_init_object (&node);
1930   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1931
1932   vat_json_print (vam->ofp, &node);
1933   vat_json_free (&node);
1934
1935   vam->retval = ntohl (mp->retval);
1936   vam->result_ready = 1;
1937 }
1938
1939 static void
1940 vl_api_bond_enslave_reply_t_handler (vl_api_bond_enslave_reply_t * mp)
1941 {
1942   vat_main_t *vam = &vat_main;
1943   i32 retval = ntohl (mp->retval);
1944
1945   if (vam->async_mode)
1946     {
1947       vam->async_errors += (retval < 0);
1948     }
1949   else
1950     {
1951       vam->retval = retval;
1952       vam->result_ready = 1;
1953     }
1954 }
1955
1956 static void vl_api_bond_enslave_reply_t_handler_json
1957   (vl_api_bond_enslave_reply_t * mp)
1958 {
1959   vat_main_t *vam = &vat_main;
1960   vat_json_node_t node;
1961
1962   vat_json_init_object (&node);
1963   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1964
1965   vat_json_print (vam->ofp, &node);
1966   vat_json_free (&node);
1967
1968   vam->retval = ntohl (mp->retval);
1969   vam->result_ready = 1;
1970 }
1971
1972 static void
1973 vl_api_bond_detach_slave_reply_t_handler (vl_api_bond_detach_slave_reply_t *
1974                                           mp)
1975 {
1976   vat_main_t *vam = &vat_main;
1977   i32 retval = ntohl (mp->retval);
1978
1979   if (vam->async_mode)
1980     {
1981       vam->async_errors += (retval < 0);
1982     }
1983   else
1984     {
1985       vam->retval = retval;
1986       vam->result_ready = 1;
1987     }
1988 }
1989
1990 static void vl_api_bond_detach_slave_reply_t_handler_json
1991   (vl_api_bond_detach_slave_reply_t * mp)
1992 {
1993   vat_main_t *vam = &vat_main;
1994   vat_json_node_t node;
1995
1996   vat_json_init_object (&node);
1997   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1998
1999   vat_json_print (vam->ofp, &node);
2000   vat_json_free (&node);
2001
2002   vam->retval = ntohl (mp->retval);
2003   vam->result_ready = 1;
2004 }
2005
2006 static int
2007 api_sw_interface_set_bond_weight (vat_main_t * vam)
2008 {
2009   unformat_input_t *i = vam->input;
2010   vl_api_sw_interface_set_bond_weight_t *mp;
2011   u32 sw_if_index = ~0;
2012   u32 weight = 0;
2013   u8 weight_enter = 0;
2014   int ret;
2015
2016   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2017     {
2018       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
2019         ;
2020       else if (unformat (i, "sw_if_index %d", &sw_if_index))
2021         ;
2022       else if (unformat (i, "weight %u", &weight))
2023         weight_enter = 1;
2024       else
2025         break;
2026     }
2027
2028   if (sw_if_index == ~0)
2029     {
2030       errmsg ("missing interface name or sw_if_index");
2031       return -99;
2032     }
2033   if (weight_enter == 0)
2034     {
2035       errmsg ("missing valid weight");
2036       return -99;
2037     }
2038
2039   /* Construct the API message */
2040   M (SW_INTERFACE_SET_BOND_WEIGHT, mp);
2041   mp->sw_if_index = ntohl (sw_if_index);
2042   mp->weight = ntohl (weight);
2043
2044   S (mp);
2045   W (ret);
2046   return ret;
2047 }
2048
2049 static void vl_api_sw_interface_bond_details_t_handler
2050   (vl_api_sw_interface_bond_details_t * mp)
2051 {
2052   vat_main_t *vam = &vat_main;
2053
2054   print (vam->ofp,
2055          "%-16s %-12d %-12U %-13U %-14u %-14u",
2056          mp->interface_name, ntohl (mp->sw_if_index),
2057          format_bond_mode, ntohl (mp->mode), format_bond_load_balance,
2058          ntohl (mp->lb), ntohl (mp->active_slaves), ntohl (mp->slaves));
2059 }
2060
2061 static void vl_api_sw_interface_bond_details_t_handler_json
2062   (vl_api_sw_interface_bond_details_t * mp)
2063 {
2064   vat_main_t *vam = &vat_main;
2065   vat_json_node_t *node = NULL;
2066
2067   if (VAT_JSON_ARRAY != vam->json_tree.type)
2068     {
2069       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2070       vat_json_init_array (&vam->json_tree);
2071     }
2072   node = vat_json_array_add (&vam->json_tree);
2073
2074   vat_json_init_object (node);
2075   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
2076   vat_json_object_add_string_copy (node, "interface_name",
2077                                    mp->interface_name);
2078   vat_json_object_add_uint (node, "mode", ntohl (mp->mode));
2079   vat_json_object_add_uint (node, "load_balance", ntohl (mp->lb));
2080   vat_json_object_add_uint (node, "active_slaves", ntohl (mp->active_slaves));
2081   vat_json_object_add_uint (node, "slaves", ntohl (mp->slaves));
2082 }
2083
2084 static int
2085 api_sw_interface_bond_dump (vat_main_t * vam)
2086 {
2087   vl_api_sw_interface_bond_dump_t *mp;
2088   vl_api_control_ping_t *mp_ping;
2089   int ret;
2090
2091   print (vam->ofp,
2092          "\n%-16s %-12s %-12s %-13s %-14s %-14s",
2093          "interface name", "sw_if_index", "mode", "load balance",
2094          "active slaves", "slaves");
2095
2096   /* Get list of bond interfaces */
2097   M (SW_INTERFACE_BOND_DUMP, mp);
2098   S (mp);
2099
2100   /* Use a control ping for synchronization */
2101   MPING (CONTROL_PING, mp_ping);
2102   S (mp_ping);
2103
2104   W (ret);
2105   return ret;
2106 }
2107
2108 static void vl_api_sw_interface_slave_details_t_handler
2109   (vl_api_sw_interface_slave_details_t * mp)
2110 {
2111   vat_main_t *vam = &vat_main;
2112
2113   print (vam->ofp,
2114          "%-25s %-12d %-7d %-12d %-10d %-10d", mp->interface_name,
2115          ntohl (mp->sw_if_index), mp->is_passive, mp->is_long_timeout,
2116          ntohl (mp->weight), mp->is_local_numa);
2117 }
2118
2119 static void vl_api_sw_interface_slave_details_t_handler_json
2120   (vl_api_sw_interface_slave_details_t * mp)
2121 {
2122   vat_main_t *vam = &vat_main;
2123   vat_json_node_t *node = NULL;
2124
2125   if (VAT_JSON_ARRAY != vam->json_tree.type)
2126     {
2127       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2128       vat_json_init_array (&vam->json_tree);
2129     }
2130   node = vat_json_array_add (&vam->json_tree);
2131
2132   vat_json_init_object (node);
2133   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
2134   vat_json_object_add_string_copy (node, "interface_name",
2135                                    mp->interface_name);
2136   vat_json_object_add_uint (node, "passive", mp->is_passive);
2137   vat_json_object_add_uint (node, "long_timeout", mp->is_long_timeout);
2138   vat_json_object_add_uint (node, "weight", ntohl (mp->weight));
2139   vat_json_object_add_uint (node, "is_local_numa", mp->is_local_numa);
2140 }
2141
2142 static int
2143 api_sw_interface_slave_dump (vat_main_t * vam)
2144 {
2145   unformat_input_t *i = vam->input;
2146   vl_api_sw_interface_slave_dump_t *mp;
2147   vl_api_control_ping_t *mp_ping;
2148   u32 sw_if_index = ~0;
2149   u8 sw_if_index_set = 0;
2150   int ret;
2151
2152   /* Parse args required to build the message */
2153   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2154     {
2155       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
2156         sw_if_index_set = 1;
2157       else if (unformat (i, "sw_if_index %d", &sw_if_index))
2158         sw_if_index_set = 1;
2159       else
2160         break;
2161     }
2162
2163   if (sw_if_index_set == 0)
2164     {
2165       errmsg ("missing vpp interface name. ");
2166       return -99;
2167     }
2168
2169   print (vam->ofp,
2170          "\n%-25s %-12s %-7s %-12s %-10s %-10s",
2171          "slave interface name", "sw_if_index", "passive", "long_timeout",
2172          "weight", "local numa");
2173
2174   /* Get list of bond interfaces */
2175   M (SW_INTERFACE_SLAVE_DUMP, mp);
2176   mp->sw_if_index = ntohl (sw_if_index);
2177   S (mp);
2178
2179   /* Use a control ping for synchronization */
2180   MPING (CONTROL_PING, mp_ping);
2181   S (mp_ping);
2182
2183   W (ret);
2184   return ret;
2185 }
2186
2187 static void vl_api_mpls_tunnel_add_del_reply_t_handler
2188   (vl_api_mpls_tunnel_add_del_reply_t * mp)
2189 {
2190   vat_main_t *vam = &vat_main;
2191   i32 retval = ntohl (mp->retval);
2192   if (vam->async_mode)
2193     {
2194       vam->async_errors += (retval < 0);
2195     }
2196   else
2197     {
2198       vam->retval = retval;
2199       vam->sw_if_index = ntohl (mp->sw_if_index);
2200       vam->result_ready = 1;
2201     }
2202   vam->regenerate_interface_table = 1;
2203 }
2204
2205 static void vl_api_mpls_tunnel_add_del_reply_t_handler_json
2206   (vl_api_mpls_tunnel_add_del_reply_t * mp)
2207 {
2208   vat_main_t *vam = &vat_main;
2209   vat_json_node_t node;
2210
2211   vat_json_init_object (&node);
2212   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2213   vat_json_object_add_uint (&node, "tunnel_sw_if_index",
2214                             ntohl (mp->sw_if_index));
2215
2216   vat_json_print (vam->ofp, &node);
2217   vat_json_free (&node);
2218
2219   vam->retval = ntohl (mp->retval);
2220   vam->result_ready = 1;
2221 }
2222
2223 static void vl_api_l2tpv3_create_tunnel_reply_t_handler
2224   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
2225 {
2226   vat_main_t *vam = &vat_main;
2227   i32 retval = ntohl (mp->retval);
2228   if (vam->async_mode)
2229     {
2230       vam->async_errors += (retval < 0);
2231     }
2232   else
2233     {
2234       vam->retval = retval;
2235       vam->sw_if_index = ntohl (mp->sw_if_index);
2236       vam->result_ready = 1;
2237     }
2238 }
2239
2240 static void vl_api_l2tpv3_create_tunnel_reply_t_handler_json
2241   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
2242 {
2243   vat_main_t *vam = &vat_main;
2244   vat_json_node_t node;
2245
2246   vat_json_init_object (&node);
2247   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2248   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2249
2250   vat_json_print (vam->ofp, &node);
2251   vat_json_free (&node);
2252
2253   vam->retval = ntohl (mp->retval);
2254   vam->result_ready = 1;
2255 }
2256
2257 static void vl_api_gpe_add_del_fwd_entry_reply_t_handler
2258   (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
2259 {
2260   vat_main_t *vam = &vat_main;
2261   i32 retval = ntohl (mp->retval);
2262   if (vam->async_mode)
2263     {
2264       vam->async_errors += (retval < 0);
2265     }
2266   else
2267     {
2268       vam->retval = retval;
2269       vam->result_ready = 1;
2270     }
2271 }
2272
2273 static void vl_api_gpe_add_del_fwd_entry_reply_t_handler_json
2274   (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
2275 {
2276   vat_main_t *vam = &vat_main;
2277   vat_json_node_t node;
2278
2279   vat_json_init_object (&node);
2280   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2281   vat_json_object_add_uint (&node, "fwd_entry_index",
2282                             clib_net_to_host_u32 (mp->fwd_entry_index));
2283
2284   vat_json_print (vam->ofp, &node);
2285   vat_json_free (&node);
2286
2287   vam->retval = ntohl (mp->retval);
2288   vam->result_ready = 1;
2289 }
2290
2291 u8 *
2292 format_lisp_transport_protocol (u8 * s, va_list * args)
2293 {
2294   u32 proto = va_arg (*args, u32);
2295
2296   switch (proto)
2297     {
2298     case 1:
2299       return format (s, "udp");
2300     case 2:
2301       return format (s, "api");
2302     default:
2303       return 0;
2304     }
2305   return 0;
2306 }
2307
2308 static void vl_api_one_get_transport_protocol_reply_t_handler
2309   (vl_api_one_get_transport_protocol_reply_t * mp)
2310 {
2311   vat_main_t *vam = &vat_main;
2312   i32 retval = ntohl (mp->retval);
2313   if (vam->async_mode)
2314     {
2315       vam->async_errors += (retval < 0);
2316     }
2317   else
2318     {
2319       u32 proto = mp->protocol;
2320       print (vam->ofp, "Transport protocol: %U",
2321              format_lisp_transport_protocol, proto);
2322       vam->retval = retval;
2323       vam->result_ready = 1;
2324     }
2325 }
2326
2327 static void vl_api_one_get_transport_protocol_reply_t_handler_json
2328   (vl_api_one_get_transport_protocol_reply_t * mp)
2329 {
2330   vat_main_t *vam = &vat_main;
2331   vat_json_node_t node;
2332   u8 *s;
2333
2334   s = format (0, "%U", format_lisp_transport_protocol, mp->protocol);
2335   vec_add1 (s, 0);
2336
2337   vat_json_init_object (&node);
2338   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2339   vat_json_object_add_string_copy (&node, "transport-protocol", s);
2340
2341   vec_free (s);
2342   vat_json_print (vam->ofp, &node);
2343   vat_json_free (&node);
2344
2345   vam->retval = ntohl (mp->retval);
2346   vam->result_ready = 1;
2347 }
2348
2349 static void vl_api_one_add_del_locator_set_reply_t_handler
2350   (vl_api_one_add_del_locator_set_reply_t * mp)
2351 {
2352   vat_main_t *vam = &vat_main;
2353   i32 retval = ntohl (mp->retval);
2354   if (vam->async_mode)
2355     {
2356       vam->async_errors += (retval < 0);
2357     }
2358   else
2359     {
2360       vam->retval = retval;
2361       vam->result_ready = 1;
2362     }
2363 }
2364
2365 static void vl_api_one_add_del_locator_set_reply_t_handler_json
2366   (vl_api_one_add_del_locator_set_reply_t * mp)
2367 {
2368   vat_main_t *vam = &vat_main;
2369   vat_json_node_t node;
2370
2371   vat_json_init_object (&node);
2372   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2373   vat_json_object_add_uint (&node, "locator_set_index", ntohl (mp->ls_index));
2374
2375   vat_json_print (vam->ofp, &node);
2376   vat_json_free (&node);
2377
2378   vam->retval = ntohl (mp->retval);
2379   vam->result_ready = 1;
2380 }
2381
2382 static void vl_api_vxlan_add_del_tunnel_reply_t_handler
2383   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
2384 {
2385   vat_main_t *vam = &vat_main;
2386   i32 retval = ntohl (mp->retval);
2387   if (vam->async_mode)
2388     {
2389       vam->async_errors += (retval < 0);
2390     }
2391   else
2392     {
2393       vam->retval = retval;
2394       vam->sw_if_index = ntohl (mp->sw_if_index);
2395       vam->result_ready = 1;
2396     }
2397   vam->regenerate_interface_table = 1;
2398 }
2399
2400 static void vl_api_vxlan_add_del_tunnel_reply_t_handler_json
2401   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
2402 {
2403   vat_main_t *vam = &vat_main;
2404   vat_json_node_t node;
2405
2406   vat_json_init_object (&node);
2407   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2408   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2409
2410   vat_json_print (vam->ofp, &node);
2411   vat_json_free (&node);
2412
2413   vam->retval = ntohl (mp->retval);
2414   vam->result_ready = 1;
2415 }
2416
2417 static void vl_api_vxlan_offload_rx_reply_t_handler
2418   (vl_api_vxlan_offload_rx_reply_t * mp)
2419 {
2420   vat_main_t *vam = &vat_main;
2421   i32 retval = ntohl (mp->retval);
2422   if (vam->async_mode)
2423     {
2424       vam->async_errors += (retval < 0);
2425     }
2426   else
2427     {
2428       vam->retval = retval;
2429       vam->result_ready = 1;
2430     }
2431 }
2432
2433 static void vl_api_vxlan_offload_rx_reply_t_handler_json
2434   (vl_api_vxlan_offload_rx_reply_t * mp)
2435 {
2436   vat_main_t *vam = &vat_main;
2437   vat_json_node_t node;
2438
2439   vat_json_init_object (&node);
2440   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2441
2442   vat_json_print (vam->ofp, &node);
2443   vat_json_free (&node);
2444
2445   vam->retval = ntohl (mp->retval);
2446   vam->result_ready = 1;
2447 }
2448
2449 static void vl_api_geneve_add_del_tunnel_reply_t_handler
2450   (vl_api_geneve_add_del_tunnel_reply_t * mp)
2451 {
2452   vat_main_t *vam = &vat_main;
2453   i32 retval = ntohl (mp->retval);
2454   if (vam->async_mode)
2455     {
2456       vam->async_errors += (retval < 0);
2457     }
2458   else
2459     {
2460       vam->retval = retval;
2461       vam->sw_if_index = ntohl (mp->sw_if_index);
2462       vam->result_ready = 1;
2463     }
2464 }
2465
2466 static void vl_api_geneve_add_del_tunnel_reply_t_handler_json
2467   (vl_api_geneve_add_del_tunnel_reply_t * mp)
2468 {
2469   vat_main_t *vam = &vat_main;
2470   vat_json_node_t node;
2471
2472   vat_json_init_object (&node);
2473   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2474   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2475
2476   vat_json_print (vam->ofp, &node);
2477   vat_json_free (&node);
2478
2479   vam->retval = ntohl (mp->retval);
2480   vam->result_ready = 1;
2481 }
2482
2483 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler
2484   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
2485 {
2486   vat_main_t *vam = &vat_main;
2487   i32 retval = ntohl (mp->retval);
2488   if (vam->async_mode)
2489     {
2490       vam->async_errors += (retval < 0);
2491     }
2492   else
2493     {
2494       vam->retval = retval;
2495       vam->sw_if_index = ntohl (mp->sw_if_index);
2496       vam->result_ready = 1;
2497     }
2498   vam->regenerate_interface_table = 1;
2499 }
2500
2501 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler_json
2502   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
2503 {
2504   vat_main_t *vam = &vat_main;
2505   vat_json_node_t node;
2506
2507   vat_json_init_object (&node);
2508   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2509   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2510
2511   vat_json_print (vam->ofp, &node);
2512   vat_json_free (&node);
2513
2514   vam->retval = ntohl (mp->retval);
2515   vam->result_ready = 1;
2516 }
2517
2518 static void vl_api_gre_tunnel_add_del_reply_t_handler
2519   (vl_api_gre_tunnel_add_del_reply_t * mp)
2520 {
2521   vat_main_t *vam = &vat_main;
2522   i32 retval = ntohl (mp->retval);
2523   if (vam->async_mode)
2524     {
2525       vam->async_errors += (retval < 0);
2526     }
2527   else
2528     {
2529       vam->retval = retval;
2530       vam->sw_if_index = ntohl (mp->sw_if_index);
2531       vam->result_ready = 1;
2532     }
2533 }
2534
2535 static void vl_api_gre_tunnel_add_del_reply_t_handler_json
2536   (vl_api_gre_tunnel_add_del_reply_t * mp)
2537 {
2538   vat_main_t *vam = &vat_main;
2539   vat_json_node_t node;
2540
2541   vat_json_init_object (&node);
2542   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2543   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2544
2545   vat_json_print (vam->ofp, &node);
2546   vat_json_free (&node);
2547
2548   vam->retval = ntohl (mp->retval);
2549   vam->result_ready = 1;
2550 }
2551
2552 static void vl_api_create_vhost_user_if_reply_t_handler
2553   (vl_api_create_vhost_user_if_reply_t * mp)
2554 {
2555   vat_main_t *vam = &vat_main;
2556   i32 retval = ntohl (mp->retval);
2557   if (vam->async_mode)
2558     {
2559       vam->async_errors += (retval < 0);
2560     }
2561   else
2562     {
2563       vam->retval = retval;
2564       vam->sw_if_index = ntohl (mp->sw_if_index);
2565       vam->result_ready = 1;
2566     }
2567   vam->regenerate_interface_table = 1;
2568 }
2569
2570 static void vl_api_create_vhost_user_if_reply_t_handler_json
2571   (vl_api_create_vhost_user_if_reply_t * mp)
2572 {
2573   vat_main_t *vam = &vat_main;
2574   vat_json_node_t node;
2575
2576   vat_json_init_object (&node);
2577   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2578   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2579
2580   vat_json_print (vam->ofp, &node);
2581   vat_json_free (&node);
2582
2583   vam->retval = ntohl (mp->retval);
2584   vam->result_ready = 1;
2585 }
2586
2587 static void vl_api_ip_address_details_t_handler
2588   (vl_api_ip_address_details_t * mp)
2589 {
2590   vat_main_t *vam = &vat_main;
2591   static ip_address_details_t empty_ip_address_details = { {0} };
2592   ip_address_details_t *address = NULL;
2593   ip_details_t *current_ip_details = NULL;
2594   ip_details_t *details = NULL;
2595
2596   details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
2597
2598   if (!details || vam->current_sw_if_index >= vec_len (details)
2599       || !details[vam->current_sw_if_index].present)
2600     {
2601       errmsg ("ip address details arrived but not stored");
2602       errmsg ("ip_dump should be called first");
2603       return;
2604     }
2605
2606   current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
2607
2608 #define addresses (current_ip_details->addr)
2609
2610   vec_validate_init_empty (addresses, vec_len (addresses),
2611                            empty_ip_address_details);
2612
2613   address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
2614
2615   clib_memcpy (&address->ip, &mp->prefix.address.un, sizeof (address->ip));
2616   address->prefix_length = mp->prefix.len;
2617 #undef addresses
2618 }
2619
2620 static void vl_api_ip_address_details_t_handler_json
2621   (vl_api_ip_address_details_t * mp)
2622 {
2623   vat_main_t *vam = &vat_main;
2624   vat_json_node_t *node = NULL;
2625
2626   if (VAT_JSON_ARRAY != vam->json_tree.type)
2627     {
2628       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2629       vat_json_init_array (&vam->json_tree);
2630     }
2631   node = vat_json_array_add (&vam->json_tree);
2632
2633   vat_json_init_object (node);
2634   vat_json_object_add_prefix (node, &mp->prefix);
2635 }
2636
2637 static void
2638 vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
2639 {
2640   vat_main_t *vam = &vat_main;
2641   static ip_details_t empty_ip_details = { 0 };
2642   ip_details_t *ip = NULL;
2643   u32 sw_if_index = ~0;
2644
2645   sw_if_index = ntohl (mp->sw_if_index);
2646
2647   vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2648                            sw_if_index, empty_ip_details);
2649
2650   ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2651                          sw_if_index);
2652
2653   ip->present = 1;
2654 }
2655
2656 static void
2657 vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
2658 {
2659   vat_main_t *vam = &vat_main;
2660
2661   if (VAT_JSON_ARRAY != vam->json_tree.type)
2662     {
2663       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2664       vat_json_init_array (&vam->json_tree);
2665     }
2666   vat_json_array_add_uint (&vam->json_tree,
2667                            clib_net_to_host_u32 (mp->sw_if_index));
2668 }
2669
2670 static void vl_api_get_first_msg_id_reply_t_handler
2671   (vl_api_get_first_msg_id_reply_t * mp)
2672 {
2673   vat_main_t *vam = &vat_main;
2674   i32 retval = ntohl (mp->retval);
2675
2676   if (vam->async_mode)
2677     {
2678       vam->async_errors += (retval < 0);
2679     }
2680   else
2681     {
2682       vam->retval = retval;
2683       vam->result_ready = 1;
2684     }
2685   if (retval >= 0)
2686     {
2687       errmsg ("first message id %d", ntohs (mp->first_msg_id));
2688     }
2689 }
2690
2691 static void vl_api_get_first_msg_id_reply_t_handler_json
2692   (vl_api_get_first_msg_id_reply_t * mp)
2693 {
2694   vat_main_t *vam = &vat_main;
2695   vat_json_node_t node;
2696
2697   vat_json_init_object (&node);
2698   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2699   vat_json_object_add_uint (&node, "first_msg_id",
2700                             (uint) ntohs (mp->first_msg_id));
2701
2702   vat_json_print (vam->ofp, &node);
2703   vat_json_free (&node);
2704
2705   vam->retval = ntohl (mp->retval);
2706   vam->result_ready = 1;
2707 }
2708
2709 static void vl_api_get_node_graph_reply_t_handler
2710   (vl_api_get_node_graph_reply_t * mp)
2711 {
2712   vat_main_t *vam = &vat_main;
2713   api_main_t *am = &api_main;
2714   i32 retval = ntohl (mp->retval);
2715   u8 *pvt_copy, *reply;
2716   void *oldheap;
2717   vlib_node_t *node;
2718   int i;
2719
2720   if (vam->async_mode)
2721     {
2722       vam->async_errors += (retval < 0);
2723     }
2724   else
2725     {
2726       vam->retval = retval;
2727       vam->result_ready = 1;
2728     }
2729
2730   /* "Should never happen..." */
2731   if (retval != 0)
2732     return;
2733
2734   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2735   pvt_copy = vec_dup (reply);
2736
2737   /* Toss the shared-memory original... */
2738   pthread_mutex_lock (&am->vlib_rp->mutex);
2739   oldheap = svm_push_data_heap (am->vlib_rp);
2740
2741   vec_free (reply);
2742
2743   svm_pop_heap (oldheap);
2744   pthread_mutex_unlock (&am->vlib_rp->mutex);
2745
2746   if (vam->graph_nodes)
2747     {
2748       hash_free (vam->graph_node_index_by_name);
2749
2750       for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
2751         {
2752           node = vam->graph_nodes[0][i];
2753           vec_free (node->name);
2754           vec_free (node->next_nodes);
2755           vec_free (node);
2756         }
2757       vec_free (vam->graph_nodes[0]);
2758       vec_free (vam->graph_nodes);
2759     }
2760
2761   vam->graph_node_index_by_name = hash_create_string (0, sizeof (uword));
2762   vam->graph_nodes = vlib_node_unserialize (pvt_copy);
2763   vec_free (pvt_copy);
2764
2765   for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
2766     {
2767       node = vam->graph_nodes[0][i];
2768       hash_set_mem (vam->graph_node_index_by_name, node->name, i);
2769     }
2770 }
2771
2772 static void vl_api_get_node_graph_reply_t_handler_json
2773   (vl_api_get_node_graph_reply_t * mp)
2774 {
2775   vat_main_t *vam = &vat_main;
2776   api_main_t *am = &api_main;
2777   void *oldheap;
2778   vat_json_node_t node;
2779   u8 *reply;
2780
2781   /* $$$$ make this real? */
2782   vat_json_init_object (&node);
2783   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2784   vat_json_object_add_uint (&node, "reply_in_shmem", mp->reply_in_shmem);
2785
2786   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2787
2788   /* Toss the shared-memory original... */
2789   pthread_mutex_lock (&am->vlib_rp->mutex);
2790   oldheap = svm_push_data_heap (am->vlib_rp);
2791
2792   vec_free (reply);
2793
2794   svm_pop_heap (oldheap);
2795   pthread_mutex_unlock (&am->vlib_rp->mutex);
2796
2797   vat_json_print (vam->ofp, &node);
2798   vat_json_free (&node);
2799
2800   vam->retval = ntohl (mp->retval);
2801   vam->result_ready = 1;
2802 }
2803
2804 static void
2805 vl_api_one_locator_details_t_handler (vl_api_one_locator_details_t * mp)
2806 {
2807   vat_main_t *vam = &vat_main;
2808   u8 *s = 0;
2809
2810   if (mp->local)
2811     {
2812       s = format (s, "%=16d%=16d%=16d",
2813                   ntohl (mp->sw_if_index), mp->priority, mp->weight);
2814     }
2815   else
2816     {
2817       s = format (s, "%=16U%=16d%=16d",
2818                   mp->is_ipv6 ? format_ip6_address :
2819                   format_ip4_address,
2820                   mp->ip_address, mp->priority, mp->weight);
2821     }
2822
2823   print (vam->ofp, "%v", s);
2824   vec_free (s);
2825 }
2826
2827 static void
2828 vl_api_one_locator_details_t_handler_json (vl_api_one_locator_details_t * mp)
2829 {
2830   vat_main_t *vam = &vat_main;
2831   vat_json_node_t *node = NULL;
2832   struct in6_addr ip6;
2833   struct in_addr ip4;
2834
2835   if (VAT_JSON_ARRAY != vam->json_tree.type)
2836     {
2837       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2838       vat_json_init_array (&vam->json_tree);
2839     }
2840   node = vat_json_array_add (&vam->json_tree);
2841   vat_json_init_object (node);
2842
2843   vat_json_object_add_uint (node, "local", mp->local ? 1 : 0);
2844   vat_json_object_add_uint (node, "priority", mp->priority);
2845   vat_json_object_add_uint (node, "weight", mp->weight);
2846
2847   if (mp->local)
2848     vat_json_object_add_uint (node, "sw_if_index",
2849                               clib_net_to_host_u32 (mp->sw_if_index));
2850   else
2851     {
2852       if (mp->is_ipv6)
2853         {
2854           clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2855           vat_json_object_add_ip6 (node, "address", ip6);
2856         }
2857       else
2858         {
2859           clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2860           vat_json_object_add_ip4 (node, "address", ip4);
2861         }
2862     }
2863 }
2864
2865 static void
2866 vl_api_one_locator_set_details_t_handler (vl_api_one_locator_set_details_t *
2867                                           mp)
2868 {
2869   vat_main_t *vam = &vat_main;
2870   u8 *ls_name = 0;
2871
2872   ls_name = format (0, "%s", mp->ls_name);
2873
2874   print (vam->ofp, "%=10d%=15v", clib_net_to_host_u32 (mp->ls_index),
2875          ls_name);
2876   vec_free (ls_name);
2877 }
2878
2879 static void
2880   vl_api_one_locator_set_details_t_handler_json
2881   (vl_api_one_locator_set_details_t * mp)
2882 {
2883   vat_main_t *vam = &vat_main;
2884   vat_json_node_t *node = 0;
2885   u8 *ls_name = 0;
2886
2887   ls_name = format (0, "%s", mp->ls_name);
2888   vec_add1 (ls_name, 0);
2889
2890   if (VAT_JSON_ARRAY != vam->json_tree.type)
2891     {
2892       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2893       vat_json_init_array (&vam->json_tree);
2894     }
2895   node = vat_json_array_add (&vam->json_tree);
2896
2897   vat_json_init_object (node);
2898   vat_json_object_add_string_copy (node, "ls_name", ls_name);
2899   vat_json_object_add_uint (node, "ls_index",
2900                             clib_net_to_host_u32 (mp->ls_index));
2901   vec_free (ls_name);
2902 }
2903
2904 typedef struct
2905 {
2906   u32 spi;
2907   u8 si;
2908 } __attribute__ ((__packed__)) lisp_nsh_api_t;
2909
2910 uword
2911 unformat_nsh_address (unformat_input_t * input, va_list * args)
2912 {
2913   lisp_nsh_api_t *nsh = va_arg (*args, lisp_nsh_api_t *);
2914   return unformat (input, "SPI:%d SI:%d", &nsh->spi, &nsh->si);
2915 }
2916
2917 u8 *
2918 format_nsh_address_vat (u8 * s, va_list * args)
2919 {
2920   nsh_t *a = va_arg (*args, nsh_t *);
2921   return format (s, "SPI:%d SI:%d", clib_net_to_host_u32 (a->spi), a->si);
2922 }
2923
2924 static u8 *
2925 format_lisp_flat_eid (u8 * s, va_list * args)
2926 {
2927   u32 type = va_arg (*args, u32);
2928   u8 *eid = va_arg (*args, u8 *);
2929   u32 eid_len = va_arg (*args, u32);
2930
2931   switch (type)
2932     {
2933     case 0:
2934       return format (s, "%U/%d", format_ip4_address, eid, eid_len);
2935     case 1:
2936       return format (s, "%U/%d", format_ip6_address, eid, eid_len);
2937     case 2:
2938       return format (s, "%U", format_ethernet_address, eid);
2939     case 3:
2940       return format (s, "%U", format_nsh_address_vat, eid);
2941     }
2942   return 0;
2943 }
2944
2945 static u8 *
2946 format_lisp_eid_vat (u8 * s, va_list * args)
2947 {
2948   u32 type = va_arg (*args, u32);
2949   u8 *eid = va_arg (*args, u8 *);
2950   u32 eid_len = va_arg (*args, u32);
2951   u8 *seid = va_arg (*args, u8 *);
2952   u32 seid_len = va_arg (*args, u32);
2953   u32 is_src_dst = va_arg (*args, u32);
2954
2955   if (is_src_dst)
2956     s = format (s, "%U|", format_lisp_flat_eid, type, seid, seid_len);
2957
2958   s = format (s, "%U", format_lisp_flat_eid, type, eid, eid_len);
2959
2960   return s;
2961 }
2962
2963 static void
2964 vl_api_one_eid_table_details_t_handler (vl_api_one_eid_table_details_t * mp)
2965 {
2966   vat_main_t *vam = &vat_main;
2967   u8 *s = 0, *eid = 0;
2968
2969   if (~0 == mp->locator_set_index)
2970     s = format (0, "action: %d", mp->action);
2971   else
2972     s = format (0, "%d", clib_net_to_host_u32 (mp->locator_set_index));
2973
2974   eid = format (0, "%U", format_lisp_eid_vat,
2975                 mp->eid_type,
2976                 mp->eid,
2977                 mp->eid_prefix_len,
2978                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
2979   vec_add1 (eid, 0);
2980
2981   print (vam->ofp, "[%d] %-35s%-20s%-30s%-20d%-20d%-10d%-20s",
2982          clib_net_to_host_u32 (mp->vni),
2983          eid,
2984          mp->is_local ? "local" : "remote",
2985          s, clib_net_to_host_u32 (mp->ttl), mp->authoritative,
2986          clib_net_to_host_u16 (mp->key_id), mp->key);
2987
2988   vec_free (s);
2989   vec_free (eid);
2990 }
2991
2992 static void
2993 vl_api_one_eid_table_details_t_handler_json (vl_api_one_eid_table_details_t
2994                                              * mp)
2995 {
2996   vat_main_t *vam = &vat_main;
2997   vat_json_node_t *node = 0;
2998   u8 *eid = 0;
2999
3000   if (VAT_JSON_ARRAY != vam->json_tree.type)
3001     {
3002       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3003       vat_json_init_array (&vam->json_tree);
3004     }
3005   node = vat_json_array_add (&vam->json_tree);
3006
3007   vat_json_init_object (node);
3008   if (~0 == mp->locator_set_index)
3009     vat_json_object_add_uint (node, "action", mp->action);
3010   else
3011     vat_json_object_add_uint (node, "locator_set_index",
3012                               clib_net_to_host_u32 (mp->locator_set_index));
3013
3014   vat_json_object_add_uint (node, "is_local", mp->is_local ? 1 : 0);
3015   if (mp->eid_type == 3)
3016     {
3017       vat_json_node_t *nsh_json = vat_json_object_add (node, "eid");
3018       vat_json_init_object (nsh_json);
3019       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) mp->eid;
3020       vat_json_object_add_uint (nsh_json, "spi",
3021                                 clib_net_to_host_u32 (nsh->spi));
3022       vat_json_object_add_uint (nsh_json, "si", nsh->si);
3023     }
3024   else
3025     {
3026       eid = format (0, "%U", format_lisp_eid_vat,
3027                     mp->eid_type,
3028                     mp->eid,
3029                     mp->eid_prefix_len,
3030                     mp->seid, mp->seid_prefix_len, mp->is_src_dst);
3031       vec_add1 (eid, 0);
3032       vat_json_object_add_string_copy (node, "eid", eid);
3033       vec_free (eid);
3034     }
3035   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3036   vat_json_object_add_uint (node, "ttl", clib_net_to_host_u32 (mp->ttl));
3037   vat_json_object_add_uint (node, "authoritative", (mp->authoritative));
3038
3039   if (mp->key_id)
3040     {
3041       vat_json_object_add_uint (node, "key_id",
3042                                 clib_net_to_host_u16 (mp->key_id));
3043       vat_json_object_add_string_copy (node, "key", mp->key);
3044     }
3045 }
3046
3047 static void
3048 vl_api_one_stats_details_t_handler (vl_api_one_stats_details_t * mp)
3049 {
3050   vat_main_t *vam = &vat_main;
3051   u8 *seid = 0, *deid = 0;
3052   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3053
3054   deid = format (0, "%U", format_lisp_eid_vat,
3055                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
3056
3057   seid = format (0, "%U", format_lisp_eid_vat,
3058                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
3059
3060   vec_add1 (deid, 0);
3061   vec_add1 (seid, 0);
3062
3063   if (mp->is_ip4)
3064     format_ip_address_fcn = format_ip4_address;
3065   else
3066     format_ip_address_fcn = format_ip6_address;
3067
3068
3069   print (vam->ofp, "([%d] %s %s) (%U %U) %u %u",
3070          clib_net_to_host_u32 (mp->vni),
3071          seid, deid,
3072          format_ip_address_fcn, mp->lloc,
3073          format_ip_address_fcn, mp->rloc,
3074          clib_net_to_host_u32 (mp->pkt_count),
3075          clib_net_to_host_u32 (mp->bytes));
3076
3077   vec_free (deid);
3078   vec_free (seid);
3079 }
3080
3081 static void
3082 vl_api_one_stats_details_t_handler_json (vl_api_one_stats_details_t * mp)
3083 {
3084   struct in6_addr ip6;
3085   struct in_addr ip4;
3086   vat_main_t *vam = &vat_main;
3087   vat_json_node_t *node = 0;
3088   u8 *deid = 0, *seid = 0;
3089
3090   if (VAT_JSON_ARRAY != vam->json_tree.type)
3091     {
3092       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3093       vat_json_init_array (&vam->json_tree);
3094     }
3095   node = vat_json_array_add (&vam->json_tree);
3096
3097   vat_json_init_object (node);
3098   deid = format (0, "%U", format_lisp_eid_vat,
3099                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
3100
3101   seid = format (0, "%U", format_lisp_eid_vat,
3102                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
3103
3104   vec_add1 (deid, 0);
3105   vec_add1 (seid, 0);
3106
3107   vat_json_object_add_string_copy (node, "seid", seid);
3108   vat_json_object_add_string_copy (node, "deid", deid);
3109   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3110
3111   if (mp->is_ip4)
3112     {
3113       clib_memcpy (&ip4, mp->lloc, sizeof (ip4));
3114       vat_json_object_add_ip4 (node, "lloc", ip4);
3115       clib_memcpy (&ip4, mp->rloc, sizeof (ip4));
3116       vat_json_object_add_ip4 (node, "rloc", ip4);
3117     }
3118   else
3119     {
3120       clib_memcpy (&ip6, mp->lloc, sizeof (ip6));
3121       vat_json_object_add_ip6 (node, "lloc", ip6);
3122       clib_memcpy (&ip6, mp->rloc, sizeof (ip6));
3123       vat_json_object_add_ip6 (node, "rloc", ip6);
3124     }
3125   vat_json_object_add_uint (node, "pkt_count",
3126                             clib_net_to_host_u32 (mp->pkt_count));
3127   vat_json_object_add_uint (node, "bytes", clib_net_to_host_u32 (mp->bytes));
3128
3129   vec_free (deid);
3130   vec_free (seid);
3131 }
3132
3133 static void
3134   vl_api_one_eid_table_map_details_t_handler
3135   (vl_api_one_eid_table_map_details_t * mp)
3136 {
3137   vat_main_t *vam = &vat_main;
3138
3139   u8 *line = format (0, "%=10d%=10d",
3140                      clib_net_to_host_u32 (mp->vni),
3141                      clib_net_to_host_u32 (mp->dp_table));
3142   print (vam->ofp, "%v", line);
3143   vec_free (line);
3144 }
3145
3146 static void
3147   vl_api_one_eid_table_map_details_t_handler_json
3148   (vl_api_one_eid_table_map_details_t * mp)
3149 {
3150   vat_main_t *vam = &vat_main;
3151   vat_json_node_t *node = NULL;
3152
3153   if (VAT_JSON_ARRAY != vam->json_tree.type)
3154     {
3155       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3156       vat_json_init_array (&vam->json_tree);
3157     }
3158   node = vat_json_array_add (&vam->json_tree);
3159   vat_json_init_object (node);
3160   vat_json_object_add_uint (node, "dp_table",
3161                             clib_net_to_host_u32 (mp->dp_table));
3162   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3163 }
3164
3165 static void
3166   vl_api_one_eid_table_vni_details_t_handler
3167   (vl_api_one_eid_table_vni_details_t * mp)
3168 {
3169   vat_main_t *vam = &vat_main;
3170
3171   u8 *line = format (0, "%d", clib_net_to_host_u32 (mp->vni));
3172   print (vam->ofp, "%v", line);
3173   vec_free (line);
3174 }
3175
3176 static void
3177   vl_api_one_eid_table_vni_details_t_handler_json
3178   (vl_api_one_eid_table_vni_details_t * mp)
3179 {
3180   vat_main_t *vam = &vat_main;
3181   vat_json_node_t *node = NULL;
3182
3183   if (VAT_JSON_ARRAY != vam->json_tree.type)
3184     {
3185       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3186       vat_json_init_array (&vam->json_tree);
3187     }
3188   node = vat_json_array_add (&vam->json_tree);
3189   vat_json_init_object (node);
3190   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3191 }
3192
3193 static void
3194   vl_api_show_one_map_register_fallback_threshold_reply_t_handler
3195   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
3196 {
3197   vat_main_t *vam = &vat_main;
3198   int retval = clib_net_to_host_u32 (mp->retval);
3199
3200   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
3201   print (vam->ofp, "fallback threshold value: %d", mp->value);
3202
3203   vam->retval = retval;
3204   vam->result_ready = 1;
3205 }
3206
3207 static void
3208   vl_api_show_one_map_register_fallback_threshold_reply_t_handler_json
3209   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
3210 {
3211   vat_main_t *vam = &vat_main;
3212   vat_json_node_t _node, *node = &_node;
3213   int retval = clib_net_to_host_u32 (mp->retval);
3214
3215   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
3216   vat_json_init_object (node);
3217   vat_json_object_add_uint (node, "value", mp->value);
3218
3219   vat_json_print (vam->ofp, node);
3220   vat_json_free (node);
3221
3222   vam->retval = retval;
3223   vam->result_ready = 1;
3224 }
3225
3226 static void
3227   vl_api_show_one_map_register_state_reply_t_handler
3228   (vl_api_show_one_map_register_state_reply_t * mp)
3229 {
3230   vat_main_t *vam = &vat_main;
3231   int retval = clib_net_to_host_u32 (mp->retval);
3232
3233   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
3234
3235   vam->retval = retval;
3236   vam->result_ready = 1;
3237 }
3238
3239 static void
3240   vl_api_show_one_map_register_state_reply_t_handler_json
3241   (vl_api_show_one_map_register_state_reply_t * mp)
3242 {
3243   vat_main_t *vam = &vat_main;
3244   vat_json_node_t _node, *node = &_node;
3245   int retval = clib_net_to_host_u32 (mp->retval);
3246
3247   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
3248
3249   vat_json_init_object (node);
3250   vat_json_object_add_string_copy (node, "state", s);
3251
3252   vat_json_print (vam->ofp, node);
3253   vat_json_free (node);
3254
3255   vam->retval = retval;
3256   vam->result_ready = 1;
3257   vec_free (s);
3258 }
3259
3260 static void
3261   vl_api_show_one_rloc_probe_state_reply_t_handler
3262   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3263 {
3264   vat_main_t *vam = &vat_main;
3265   int retval = clib_net_to_host_u32 (mp->retval);
3266
3267   if (retval)
3268     goto end;
3269
3270   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
3271 end:
3272   vam->retval = retval;
3273   vam->result_ready = 1;
3274 }
3275
3276 static void
3277   vl_api_show_one_rloc_probe_state_reply_t_handler_json
3278   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3279 {
3280   vat_main_t *vam = &vat_main;
3281   vat_json_node_t _node, *node = &_node;
3282   int retval = clib_net_to_host_u32 (mp->retval);
3283
3284   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
3285   vat_json_init_object (node);
3286   vat_json_object_add_string_copy (node, "state", s);
3287
3288   vat_json_print (vam->ofp, node);
3289   vat_json_free (node);
3290
3291   vam->retval = retval;
3292   vam->result_ready = 1;
3293   vec_free (s);
3294 }
3295
3296 static void
3297   vl_api_show_one_stats_enable_disable_reply_t_handler
3298   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3299 {
3300   vat_main_t *vam = &vat_main;
3301   int retval = clib_net_to_host_u32 (mp->retval);
3302
3303   if (retval)
3304     goto end;
3305
3306   print (vam->ofp, "%s", mp->is_en ? "enabled" : "disabled");
3307 end:
3308   vam->retval = retval;
3309   vam->result_ready = 1;
3310 }
3311
3312 static void
3313   vl_api_show_one_stats_enable_disable_reply_t_handler_json
3314   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3315 {
3316   vat_main_t *vam = &vat_main;
3317   vat_json_node_t _node, *node = &_node;
3318   int retval = clib_net_to_host_u32 (mp->retval);
3319
3320   u8 *s = format (0, "%s", mp->is_en ? "enabled" : "disabled");
3321   vat_json_init_object (node);
3322   vat_json_object_add_string_copy (node, "state", s);
3323
3324   vat_json_print (vam->ofp, node);
3325   vat_json_free (node);
3326
3327   vam->retval = retval;
3328   vam->result_ready = 1;
3329   vec_free (s);
3330 }
3331
3332 static void
3333 api_gpe_fwd_entry_net_to_host (vl_api_gpe_fwd_entry_t * e)
3334 {
3335   e->dp_table = clib_net_to_host_u32 (e->dp_table);
3336   e->fwd_entry_index = clib_net_to_host_u32 (e->fwd_entry_index);
3337   e->vni = clib_net_to_host_u32 (e->vni);
3338 }
3339
3340 static void
3341   gpe_fwd_entries_get_reply_t_net_to_host
3342   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3343 {
3344   u32 i;
3345
3346   mp->count = clib_net_to_host_u32 (mp->count);
3347   for (i = 0; i < mp->count; i++)
3348     {
3349       api_gpe_fwd_entry_net_to_host (&mp->entries[i]);
3350     }
3351 }
3352
3353 static u8 *
3354 format_gpe_encap_mode (u8 * s, va_list * args)
3355 {
3356   u32 mode = va_arg (*args, u32);
3357
3358   switch (mode)
3359     {
3360     case 0:
3361       return format (s, "lisp");
3362     case 1:
3363       return format (s, "vxlan");
3364     }
3365   return 0;
3366 }
3367
3368 static void
3369   vl_api_gpe_get_encap_mode_reply_t_handler
3370   (vl_api_gpe_get_encap_mode_reply_t * mp)
3371 {
3372   vat_main_t *vam = &vat_main;
3373
3374   print (vam->ofp, "gpe mode: %U", format_gpe_encap_mode, mp->encap_mode);
3375   vam->retval = ntohl (mp->retval);
3376   vam->result_ready = 1;
3377 }
3378
3379 static void
3380   vl_api_gpe_get_encap_mode_reply_t_handler_json
3381   (vl_api_gpe_get_encap_mode_reply_t * mp)
3382 {
3383   vat_main_t *vam = &vat_main;
3384   vat_json_node_t node;
3385
3386   u8 *encap_mode = format (0, "%U", format_gpe_encap_mode, mp->encap_mode);
3387   vec_add1 (encap_mode, 0);
3388
3389   vat_json_init_object (&node);
3390   vat_json_object_add_string_copy (&node, "gpe_mode", encap_mode);
3391
3392   vec_free (encap_mode);
3393   vat_json_print (vam->ofp, &node);
3394   vat_json_free (&node);
3395
3396   vam->retval = ntohl (mp->retval);
3397   vam->result_ready = 1;
3398 }
3399
3400 static void
3401   vl_api_gpe_fwd_entry_path_details_t_handler
3402   (vl_api_gpe_fwd_entry_path_details_t * mp)
3403 {
3404   vat_main_t *vam = &vat_main;
3405   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3406
3407   if (mp->lcl_loc.is_ip4)
3408     format_ip_address_fcn = format_ip4_address;
3409   else
3410     format_ip_address_fcn = format_ip6_address;
3411
3412   print (vam->ofp, "w:%d %30U %30U", mp->rmt_loc.weight,
3413          format_ip_address_fcn, &mp->lcl_loc,
3414          format_ip_address_fcn, &mp->rmt_loc);
3415 }
3416
3417 static void
3418 lisp_fill_locator_node (vat_json_node_t * n, vl_api_gpe_locator_t * loc)
3419 {
3420   struct in6_addr ip6;
3421   struct in_addr ip4;
3422
3423   if (loc->is_ip4)
3424     {
3425       clib_memcpy (&ip4, loc->addr, sizeof (ip4));
3426       vat_json_object_add_ip4 (n, "address", ip4);
3427     }
3428   else
3429     {
3430       clib_memcpy (&ip6, loc->addr, sizeof (ip6));
3431       vat_json_object_add_ip6 (n, "address", ip6);
3432     }
3433   vat_json_object_add_uint (n, "weight", loc->weight);
3434 }
3435
3436 static void
3437   vl_api_gpe_fwd_entry_path_details_t_handler_json
3438   (vl_api_gpe_fwd_entry_path_details_t * mp)
3439 {
3440   vat_main_t *vam = &vat_main;
3441   vat_json_node_t *node = NULL;
3442   vat_json_node_t *loc_node;
3443
3444   if (VAT_JSON_ARRAY != vam->json_tree.type)
3445     {
3446       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3447       vat_json_init_array (&vam->json_tree);
3448     }
3449   node = vat_json_array_add (&vam->json_tree);
3450   vat_json_init_object (node);
3451
3452   loc_node = vat_json_object_add (node, "local_locator");
3453   vat_json_init_object (loc_node);
3454   lisp_fill_locator_node (loc_node, &mp->lcl_loc);
3455
3456   loc_node = vat_json_object_add (node, "remote_locator");
3457   vat_json_init_object (loc_node);
3458   lisp_fill_locator_node (loc_node, &mp->rmt_loc);
3459 }
3460
3461 static void
3462   vl_api_gpe_fwd_entries_get_reply_t_handler
3463   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3464 {
3465   vat_main_t *vam = &vat_main;
3466   u32 i;
3467   int retval = clib_net_to_host_u32 (mp->retval);
3468   vl_api_gpe_fwd_entry_t *e;
3469
3470   if (retval)
3471     goto end;
3472
3473   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3474
3475   for (i = 0; i < mp->count; i++)
3476     {
3477       e = &mp->entries[i];
3478       print (vam->ofp, "%10d %10d %U %40U", e->fwd_entry_index, e->dp_table,
3479              format_lisp_flat_eid, e->eid_type, e->leid, e->leid_prefix_len,
3480              format_lisp_flat_eid, e->eid_type, e->reid, e->reid_prefix_len);
3481     }
3482
3483 end:
3484   vam->retval = retval;
3485   vam->result_ready = 1;
3486 }
3487
3488 static void
3489   vl_api_gpe_fwd_entries_get_reply_t_handler_json
3490   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3491 {
3492   u8 *s = 0;
3493   vat_main_t *vam = &vat_main;
3494   vat_json_node_t *e = 0, root;
3495   u32 i;
3496   int retval = clib_net_to_host_u32 (mp->retval);
3497   vl_api_gpe_fwd_entry_t *fwd;
3498
3499   if (retval)
3500     goto end;
3501
3502   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3503   vat_json_init_array (&root);
3504
3505   for (i = 0; i < mp->count; i++)
3506     {
3507       e = vat_json_array_add (&root);
3508       fwd = &mp->entries[i];
3509
3510       vat_json_init_object (e);
3511       vat_json_object_add_int (e, "fwd_entry_index", fwd->fwd_entry_index);
3512       vat_json_object_add_int (e, "dp_table", fwd->dp_table);
3513       vat_json_object_add_int (e, "vni", fwd->vni);
3514       vat_json_object_add_int (e, "action", fwd->action);
3515
3516       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->leid,
3517                   fwd->leid_prefix_len);
3518       vec_add1 (s, 0);
3519       vat_json_object_add_string_copy (e, "leid", s);
3520       vec_free (s);
3521
3522       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->reid,
3523                   fwd->reid_prefix_len);
3524       vec_add1 (s, 0);
3525       vat_json_object_add_string_copy (e, "reid", s);
3526       vec_free (s);
3527     }
3528
3529   vat_json_print (vam->ofp, &root);
3530   vat_json_free (&root);
3531
3532 end:
3533   vam->retval = retval;
3534   vam->result_ready = 1;
3535 }
3536
3537 static void
3538   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler
3539   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3540 {
3541   vat_main_t *vam = &vat_main;
3542   u32 i, n;
3543   int retval = clib_net_to_host_u32 (mp->retval);
3544   vl_api_gpe_native_fwd_rpath_t *r;
3545
3546   if (retval)
3547     goto end;
3548
3549   n = clib_net_to_host_u32 (mp->count);
3550
3551   for (i = 0; i < n; i++)
3552     {
3553       r = &mp->entries[i];
3554       print (vam->ofp, "fib_index: %d sw_if_index %d nh %U",
3555              clib_net_to_host_u32 (r->fib_index),
3556              clib_net_to_host_u32 (r->nh_sw_if_index),
3557              r->is_ip4 ? format_ip4_address : format_ip6_address, r->nh_addr);
3558     }
3559
3560 end:
3561   vam->retval = retval;
3562   vam->result_ready = 1;
3563 }
3564
3565 static void
3566   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler_json
3567   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3568 {
3569   vat_main_t *vam = &vat_main;
3570   vat_json_node_t root, *e;
3571   u32 i, n;
3572   int retval = clib_net_to_host_u32 (mp->retval);
3573   vl_api_gpe_native_fwd_rpath_t *r;
3574   u8 *s;
3575
3576   if (retval)
3577     goto end;
3578
3579   n = clib_net_to_host_u32 (mp->count);
3580   vat_json_init_array (&root);
3581
3582   for (i = 0; i < n; i++)
3583     {
3584       e = vat_json_array_add (&root);
3585       vat_json_init_object (e);
3586       r = &mp->entries[i];
3587       s =
3588         format (0, "%U", r->is_ip4 ? format_ip4_address : format_ip6_address,
3589                 r->nh_addr);
3590       vec_add1 (s, 0);
3591       vat_json_object_add_string_copy (e, "ip4", s);
3592       vec_free (s);
3593
3594       vat_json_object_add_uint (e, "fib_index",
3595                                 clib_net_to_host_u32 (r->fib_index));
3596       vat_json_object_add_uint (e, "nh_sw_if_index",
3597                                 clib_net_to_host_u32 (r->nh_sw_if_index));
3598     }
3599
3600   vat_json_print (vam->ofp, &root);
3601   vat_json_free (&root);
3602
3603 end:
3604   vam->retval = retval;
3605   vam->result_ready = 1;
3606 }
3607
3608 static void
3609   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler
3610   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3611 {
3612   vat_main_t *vam = &vat_main;
3613   u32 i, n;
3614   int retval = clib_net_to_host_u32 (mp->retval);
3615
3616   if (retval)
3617     goto end;
3618
3619   n = clib_net_to_host_u32 (mp->count);
3620
3621   for (i = 0; i < n; i++)
3622     print (vam->ofp, "%d", clib_net_to_host_u32 (mp->vnis[i]));
3623
3624 end:
3625   vam->retval = retval;
3626   vam->result_ready = 1;
3627 }
3628
3629 static void
3630   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler_json
3631   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3632 {
3633   vat_main_t *vam = &vat_main;
3634   vat_json_node_t root;
3635   u32 i, n;
3636   int retval = clib_net_to_host_u32 (mp->retval);
3637
3638   if (retval)
3639     goto end;
3640
3641   n = clib_net_to_host_u32 (mp->count);
3642   vat_json_init_array (&root);
3643
3644   for (i = 0; i < n; i++)
3645     vat_json_array_add_uint (&root, clib_net_to_host_u32 (mp->vnis[i]));
3646
3647   vat_json_print (vam->ofp, &root);
3648   vat_json_free (&root);
3649
3650 end:
3651   vam->retval = retval;
3652   vam->result_ready = 1;
3653 }
3654
3655 static void
3656   vl_api_one_ndp_entries_get_reply_t_handler
3657   (vl_api_one_ndp_entries_get_reply_t * mp)
3658 {
3659   vat_main_t *vam = &vat_main;
3660   u32 i, n;
3661   int retval = clib_net_to_host_u32 (mp->retval);
3662
3663   if (retval)
3664     goto end;
3665
3666   n = clib_net_to_host_u32 (mp->count);
3667
3668   for (i = 0; i < n; i++)
3669     print (vam->ofp, "%U -> %U", format_ip6_address, &mp->entries[i].ip6,
3670            format_ethernet_address, mp->entries[i].mac);
3671
3672 end:
3673   vam->retval = retval;
3674   vam->result_ready = 1;
3675 }
3676
3677 static void
3678   vl_api_one_ndp_entries_get_reply_t_handler_json
3679   (vl_api_one_ndp_entries_get_reply_t * mp)
3680 {
3681   u8 *s = 0;
3682   vat_main_t *vam = &vat_main;
3683   vat_json_node_t *e = 0, root;
3684   u32 i, n;
3685   int retval = clib_net_to_host_u32 (mp->retval);
3686   vl_api_one_ndp_entry_t *arp_entry;
3687
3688   if (retval)
3689     goto end;
3690
3691   n = clib_net_to_host_u32 (mp->count);
3692   vat_json_init_array (&root);
3693
3694   for (i = 0; i < n; i++)
3695     {
3696       e = vat_json_array_add (&root);
3697       arp_entry = &mp->entries[i];
3698
3699       vat_json_init_object (e);
3700       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
3701       vec_add1 (s, 0);
3702
3703       vat_json_object_add_string_copy (e, "mac", s);
3704       vec_free (s);
3705
3706       s = format (0, "%U", format_ip6_address, &arp_entry->ip6);
3707       vec_add1 (s, 0);
3708       vat_json_object_add_string_copy (e, "ip6", s);
3709       vec_free (s);
3710     }
3711
3712   vat_json_print (vam->ofp, &root);
3713   vat_json_free (&root);
3714
3715 end:
3716   vam->retval = retval;
3717   vam->result_ready = 1;
3718 }
3719
3720 static void
3721   vl_api_one_l2_arp_entries_get_reply_t_handler
3722   (vl_api_one_l2_arp_entries_get_reply_t * mp)
3723 {
3724   vat_main_t *vam = &vat_main;
3725   u32 i, n;
3726   int retval = clib_net_to_host_u32 (mp->retval);
3727
3728   if (retval)
3729     goto end;
3730
3731   n = clib_net_to_host_u32 (mp->count);
3732
3733   for (i = 0; i < n; i++)
3734     print (vam->ofp, "%U -> %U", format_ip4_address, &mp->entries[i].ip4,
3735            format_ethernet_address, mp->entries[i].mac);
3736
3737 end:
3738   vam->retval = retval;
3739   vam->result_ready = 1;
3740 }
3741
3742 static void
3743   vl_api_one_l2_arp_entries_get_reply_t_handler_json
3744   (vl_api_one_l2_arp_entries_get_reply_t * mp)
3745 {
3746   u8 *s = 0;
3747   vat_main_t *vam = &vat_main;
3748   vat_json_node_t *e = 0, root;
3749   u32 i, n;
3750   int retval = clib_net_to_host_u32 (mp->retval);
3751   vl_api_one_l2_arp_entry_t *arp_entry;
3752
3753   if (retval)
3754     goto end;
3755
3756   n = clib_net_to_host_u32 (mp->count);
3757   vat_json_init_array (&root);
3758
3759   for (i = 0; i < n; i++)
3760     {
3761       e = vat_json_array_add (&root);
3762       arp_entry = &mp->entries[i];
3763
3764       vat_json_init_object (e);
3765       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
3766       vec_add1 (s, 0);
3767
3768       vat_json_object_add_string_copy (e, "mac", s);
3769       vec_free (s);
3770
3771       s = format (0, "%U", format_ip4_address, &arp_entry->ip4);
3772       vec_add1 (s, 0);
3773       vat_json_object_add_string_copy (e, "ip4", s);
3774       vec_free (s);
3775     }
3776
3777   vat_json_print (vam->ofp, &root);
3778   vat_json_free (&root);
3779
3780 end:
3781   vam->retval = retval;
3782   vam->result_ready = 1;
3783 }
3784
3785 static void
3786 vl_api_one_ndp_bd_get_reply_t_handler (vl_api_one_ndp_bd_get_reply_t * mp)
3787 {
3788   vat_main_t *vam = &vat_main;
3789   u32 i, n;
3790   int retval = clib_net_to_host_u32 (mp->retval);
3791
3792   if (retval)
3793     goto end;
3794
3795   n = clib_net_to_host_u32 (mp->count);
3796
3797   for (i = 0; i < n; i++)
3798     {
3799       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
3800     }
3801
3802 end:
3803   vam->retval = retval;
3804   vam->result_ready = 1;
3805 }
3806
3807 static void
3808   vl_api_one_ndp_bd_get_reply_t_handler_json
3809   (vl_api_one_ndp_bd_get_reply_t * mp)
3810 {
3811   vat_main_t *vam = &vat_main;
3812   vat_json_node_t root;
3813   u32 i, n;
3814   int retval = clib_net_to_host_u32 (mp->retval);
3815
3816   if (retval)
3817     goto end;
3818
3819   n = clib_net_to_host_u32 (mp->count);
3820   vat_json_init_array (&root);
3821
3822   for (i = 0; i < n; i++)
3823     {
3824       vat_json_array_add_uint (&root,
3825                                clib_net_to_host_u32 (mp->bridge_domains[i]));
3826     }
3827
3828   vat_json_print (vam->ofp, &root);
3829   vat_json_free (&root);
3830
3831 end:
3832   vam->retval = retval;
3833   vam->result_ready = 1;
3834 }
3835
3836 static void
3837   vl_api_one_l2_arp_bd_get_reply_t_handler
3838   (vl_api_one_l2_arp_bd_get_reply_t * mp)
3839 {
3840   vat_main_t *vam = &vat_main;
3841   u32 i, n;
3842   int retval = clib_net_to_host_u32 (mp->retval);
3843
3844   if (retval)
3845     goto end;
3846
3847   n = clib_net_to_host_u32 (mp->count);
3848
3849   for (i = 0; i < n; i++)
3850     {
3851       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
3852     }
3853
3854 end:
3855   vam->retval = retval;
3856   vam->result_ready = 1;
3857 }
3858
3859 static void
3860   vl_api_one_l2_arp_bd_get_reply_t_handler_json
3861   (vl_api_one_l2_arp_bd_get_reply_t * mp)
3862 {
3863   vat_main_t *vam = &vat_main;
3864   vat_json_node_t root;
3865   u32 i, n;
3866   int retval = clib_net_to_host_u32 (mp->retval);
3867
3868   if (retval)
3869     goto end;
3870
3871   n = clib_net_to_host_u32 (mp->count);
3872   vat_json_init_array (&root);
3873
3874   for (i = 0; i < n; i++)
3875     {
3876       vat_json_array_add_uint (&root,
3877                                clib_net_to_host_u32 (mp->bridge_domains[i]));
3878     }
3879
3880   vat_json_print (vam->ofp, &root);
3881   vat_json_free (&root);
3882
3883 end:
3884   vam->retval = retval;
3885   vam->result_ready = 1;
3886 }
3887
3888 static void
3889   vl_api_one_adjacencies_get_reply_t_handler
3890   (vl_api_one_adjacencies_get_reply_t * mp)
3891 {
3892   vat_main_t *vam = &vat_main;
3893   u32 i, n;
3894   int retval = clib_net_to_host_u32 (mp->retval);
3895   vl_api_one_adjacency_t *a;
3896
3897   if (retval)
3898     goto end;
3899
3900   n = clib_net_to_host_u32 (mp->count);
3901
3902   for (i = 0; i < n; i++)
3903     {
3904       a = &mp->adjacencies[i];
3905       print (vam->ofp, "%U %40U",
3906              format_lisp_flat_eid, a->eid_type, a->leid, a->leid_prefix_len,
3907              format_lisp_flat_eid, a->eid_type, a->reid, a->reid_prefix_len);
3908     }
3909
3910 end:
3911   vam->retval = retval;
3912   vam->result_ready = 1;
3913 }
3914
3915 static void
3916   vl_api_one_adjacencies_get_reply_t_handler_json
3917   (vl_api_one_adjacencies_get_reply_t * mp)
3918 {
3919   u8 *s = 0;
3920   vat_main_t *vam = &vat_main;
3921   vat_json_node_t *e = 0, root;
3922   u32 i, n;
3923   int retval = clib_net_to_host_u32 (mp->retval);
3924   vl_api_one_adjacency_t *a;
3925
3926   if (retval)
3927     goto end;
3928
3929   n = clib_net_to_host_u32 (mp->count);
3930   vat_json_init_array (&root);
3931
3932   for (i = 0; i < n; i++)
3933     {
3934       e = vat_json_array_add (&root);
3935       a = &mp->adjacencies[i];
3936
3937       vat_json_init_object (e);
3938       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->leid,
3939                   a->leid_prefix_len);
3940       vec_add1 (s, 0);
3941       vat_json_object_add_string_copy (e, "leid", s);
3942       vec_free (s);
3943
3944       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->reid,
3945                   a->reid_prefix_len);
3946       vec_add1 (s, 0);
3947       vat_json_object_add_string_copy (e, "reid", s);
3948       vec_free (s);
3949     }
3950
3951   vat_json_print (vam->ofp, &root);
3952   vat_json_free (&root);
3953
3954 end:
3955   vam->retval = retval;
3956   vam->result_ready = 1;
3957 }
3958
3959 static void
3960 vl_api_one_map_server_details_t_handler (vl_api_one_map_server_details_t * mp)
3961 {
3962   vat_main_t *vam = &vat_main;
3963
3964   print (vam->ofp, "%=20U",
3965          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
3966          mp->ip_address);
3967 }
3968
3969 static void
3970   vl_api_one_map_server_details_t_handler_json
3971   (vl_api_one_map_server_details_t * mp)
3972 {
3973   vat_main_t *vam = &vat_main;
3974   vat_json_node_t *node = NULL;
3975   struct in6_addr ip6;
3976   struct in_addr ip4;
3977
3978   if (VAT_JSON_ARRAY != vam->json_tree.type)
3979     {
3980       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3981       vat_json_init_array (&vam->json_tree);
3982     }
3983   node = vat_json_array_add (&vam->json_tree);
3984
3985   vat_json_init_object (node);
3986   if (mp->is_ipv6)
3987     {
3988       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
3989       vat_json_object_add_ip6 (node, "map-server", ip6);
3990     }
3991   else
3992     {
3993       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
3994       vat_json_object_add_ip4 (node, "map-server", ip4);
3995     }
3996 }
3997
3998 static void
3999 vl_api_one_map_resolver_details_t_handler (vl_api_one_map_resolver_details_t
4000                                            * mp)
4001 {
4002   vat_main_t *vam = &vat_main;
4003
4004   print (vam->ofp, "%=20U",
4005          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
4006          mp->ip_address);
4007 }
4008
4009 static void
4010   vl_api_one_map_resolver_details_t_handler_json
4011   (vl_api_one_map_resolver_details_t * mp)
4012 {
4013   vat_main_t *vam = &vat_main;
4014   vat_json_node_t *node = NULL;
4015   struct in6_addr ip6;
4016   struct in_addr ip4;
4017
4018   if (VAT_JSON_ARRAY != vam->json_tree.type)
4019     {
4020       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4021       vat_json_init_array (&vam->json_tree);
4022     }
4023   node = vat_json_array_add (&vam->json_tree);
4024
4025   vat_json_init_object (node);
4026   if (mp->is_ipv6)
4027     {
4028       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
4029       vat_json_object_add_ip6 (node, "map resolver", ip6);
4030     }
4031   else
4032     {
4033       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
4034       vat_json_object_add_ip4 (node, "map resolver", ip4);
4035     }
4036 }
4037
4038 static void
4039 vl_api_show_one_status_reply_t_handler (vl_api_show_one_status_reply_t * mp)
4040 {
4041   vat_main_t *vam = &vat_main;
4042   i32 retval = ntohl (mp->retval);
4043
4044   if (0 <= retval)
4045     {
4046       print (vam->ofp, "feature: %s\ngpe: %s",
4047              mp->feature_status ? "enabled" : "disabled",
4048              mp->gpe_status ? "enabled" : "disabled");
4049     }
4050
4051   vam->retval = retval;
4052   vam->result_ready = 1;
4053 }
4054
4055 static void
4056   vl_api_show_one_status_reply_t_handler_json
4057   (vl_api_show_one_status_reply_t * mp)
4058 {
4059   vat_main_t *vam = &vat_main;
4060   vat_json_node_t node;
4061   u8 *gpe_status = NULL;
4062   u8 *feature_status = NULL;
4063
4064   gpe_status = format (0, "%s", mp->gpe_status ? "enabled" : "disabled");
4065   feature_status = format (0, "%s",
4066                            mp->feature_status ? "enabled" : "disabled");
4067   vec_add1 (gpe_status, 0);
4068   vec_add1 (feature_status, 0);
4069
4070   vat_json_init_object (&node);
4071   vat_json_object_add_string_copy (&node, "gpe_status", gpe_status);
4072   vat_json_object_add_string_copy (&node, "feature_status", feature_status);
4073
4074   vec_free (gpe_status);
4075   vec_free (feature_status);
4076
4077   vat_json_print (vam->ofp, &node);
4078   vat_json_free (&node);
4079
4080   vam->retval = ntohl (mp->retval);
4081   vam->result_ready = 1;
4082 }
4083
4084 static void
4085   vl_api_one_get_map_request_itr_rlocs_reply_t_handler
4086   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
4087 {
4088   vat_main_t *vam = &vat_main;
4089   i32 retval = ntohl (mp->retval);
4090
4091   if (retval >= 0)
4092     {
4093       print (vam->ofp, "%=20s", mp->locator_set_name);
4094     }
4095
4096   vam->retval = retval;
4097   vam->result_ready = 1;
4098 }
4099
4100 static void
4101   vl_api_one_get_map_request_itr_rlocs_reply_t_handler_json
4102   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
4103 {
4104   vat_main_t *vam = &vat_main;
4105   vat_json_node_t *node = NULL;
4106
4107   if (VAT_JSON_ARRAY != vam->json_tree.type)
4108     {
4109       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4110       vat_json_init_array (&vam->json_tree);
4111     }
4112   node = vat_json_array_add (&vam->json_tree);
4113
4114   vat_json_init_object (node);
4115   vat_json_object_add_string_copy (node, "itr-rlocs", mp->locator_set_name);
4116
4117   vat_json_print (vam->ofp, node);
4118   vat_json_free (node);
4119
4120   vam->retval = ntohl (mp->retval);
4121   vam->result_ready = 1;
4122 }
4123
4124 static u8 *
4125 format_lisp_map_request_mode (u8 * s, va_list * args)
4126 {
4127   u32 mode = va_arg (*args, u32);
4128
4129   switch (mode)
4130     {
4131     case 0:
4132       return format (0, "dst-only");
4133     case 1:
4134       return format (0, "src-dst");
4135     }
4136   return 0;
4137 }
4138
4139 static void
4140   vl_api_show_one_map_request_mode_reply_t_handler
4141   (vl_api_show_one_map_request_mode_reply_t * mp)
4142 {
4143   vat_main_t *vam = &vat_main;
4144   i32 retval = ntohl (mp->retval);
4145
4146   if (0 <= retval)
4147     {
4148       u32 mode = mp->mode;
4149       print (vam->ofp, "map_request_mode: %U",
4150              format_lisp_map_request_mode, mode);
4151     }
4152
4153   vam->retval = retval;
4154   vam->result_ready = 1;
4155 }
4156
4157 static void
4158   vl_api_show_one_map_request_mode_reply_t_handler_json
4159   (vl_api_show_one_map_request_mode_reply_t * mp)
4160 {
4161   vat_main_t *vam = &vat_main;
4162   vat_json_node_t node;
4163   u8 *s = 0;
4164   u32 mode;
4165
4166   mode = mp->mode;
4167   s = format (0, "%U", format_lisp_map_request_mode, mode);
4168   vec_add1 (s, 0);
4169
4170   vat_json_init_object (&node);
4171   vat_json_object_add_string_copy (&node, "map_request_mode", s);
4172   vat_json_print (vam->ofp, &node);
4173   vat_json_free (&node);
4174
4175   vec_free (s);
4176   vam->retval = ntohl (mp->retval);
4177   vam->result_ready = 1;
4178 }
4179
4180 static void
4181   vl_api_one_show_xtr_mode_reply_t_handler
4182   (vl_api_one_show_xtr_mode_reply_t * mp)
4183 {
4184   vat_main_t *vam = &vat_main;
4185   i32 retval = ntohl (mp->retval);
4186
4187   if (0 <= retval)
4188     {
4189       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4190     }
4191
4192   vam->retval = retval;
4193   vam->result_ready = 1;
4194 }
4195
4196 static void
4197   vl_api_one_show_xtr_mode_reply_t_handler_json
4198   (vl_api_one_show_xtr_mode_reply_t * mp)
4199 {
4200   vat_main_t *vam = &vat_main;
4201   vat_json_node_t node;
4202   u8 *status = 0;
4203
4204   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4205   vec_add1 (status, 0);
4206
4207   vat_json_init_object (&node);
4208   vat_json_object_add_string_copy (&node, "status", status);
4209
4210   vec_free (status);
4211
4212   vat_json_print (vam->ofp, &node);
4213   vat_json_free (&node);
4214
4215   vam->retval = ntohl (mp->retval);
4216   vam->result_ready = 1;
4217 }
4218
4219 static void
4220   vl_api_one_show_pitr_mode_reply_t_handler
4221   (vl_api_one_show_pitr_mode_reply_t * mp)
4222 {
4223   vat_main_t *vam = &vat_main;
4224   i32 retval = ntohl (mp->retval);
4225
4226   if (0 <= retval)
4227     {
4228       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4229     }
4230
4231   vam->retval = retval;
4232   vam->result_ready = 1;
4233 }
4234
4235 static void
4236   vl_api_one_show_pitr_mode_reply_t_handler_json
4237   (vl_api_one_show_pitr_mode_reply_t * mp)
4238 {
4239   vat_main_t *vam = &vat_main;
4240   vat_json_node_t node;
4241   u8 *status = 0;
4242
4243   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4244   vec_add1 (status, 0);
4245
4246   vat_json_init_object (&node);
4247   vat_json_object_add_string_copy (&node, "status", status);
4248
4249   vec_free (status);
4250
4251   vat_json_print (vam->ofp, &node);
4252   vat_json_free (&node);
4253
4254   vam->retval = ntohl (mp->retval);
4255   vam->result_ready = 1;
4256 }
4257
4258 static void
4259   vl_api_one_show_petr_mode_reply_t_handler
4260   (vl_api_one_show_petr_mode_reply_t * mp)
4261 {
4262   vat_main_t *vam = &vat_main;
4263   i32 retval = ntohl (mp->retval);
4264
4265   if (0 <= retval)
4266     {
4267       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4268     }
4269
4270   vam->retval = retval;
4271   vam->result_ready = 1;
4272 }
4273
4274 static void
4275   vl_api_one_show_petr_mode_reply_t_handler_json
4276   (vl_api_one_show_petr_mode_reply_t * mp)
4277 {
4278   vat_main_t *vam = &vat_main;
4279   vat_json_node_t node;
4280   u8 *status = 0;
4281
4282   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4283   vec_add1 (status, 0);
4284
4285   vat_json_init_object (&node);
4286   vat_json_object_add_string_copy (&node, "status", status);
4287
4288   vec_free (status);
4289
4290   vat_json_print (vam->ofp, &node);
4291   vat_json_free (&node);
4292
4293   vam->retval = ntohl (mp->retval);
4294   vam->result_ready = 1;
4295 }
4296
4297 static void
4298   vl_api_show_one_use_petr_reply_t_handler
4299   (vl_api_show_one_use_petr_reply_t * mp)
4300 {
4301   vat_main_t *vam = &vat_main;
4302   i32 retval = ntohl (mp->retval);
4303
4304   if (0 <= retval)
4305     {
4306       print (vam->ofp, "%s\n", mp->status ? "enabled" : "disabled");
4307       if (mp->status)
4308         {
4309           print (vam->ofp, "Proxy-ETR address; %U",
4310                  mp->is_ip4 ? format_ip4_address : format_ip6_address,
4311                  mp->address);
4312         }
4313     }
4314
4315   vam->retval = retval;
4316   vam->result_ready = 1;
4317 }
4318
4319 static void
4320   vl_api_show_one_use_petr_reply_t_handler_json
4321   (vl_api_show_one_use_petr_reply_t * mp)
4322 {
4323   vat_main_t *vam = &vat_main;
4324   vat_json_node_t node;
4325   u8 *status = 0;
4326   struct in_addr ip4;
4327   struct in6_addr ip6;
4328
4329   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4330   vec_add1 (status, 0);
4331
4332   vat_json_init_object (&node);
4333   vat_json_object_add_string_copy (&node, "status", status);
4334   if (mp->status)
4335     {
4336       if (mp->is_ip4)
4337         {
4338           clib_memcpy (&ip6, mp->address, sizeof (ip6));
4339           vat_json_object_add_ip6 (&node, "address", ip6);
4340         }
4341       else
4342         {
4343           clib_memcpy (&ip4, mp->address, sizeof (ip4));
4344           vat_json_object_add_ip4 (&node, "address", ip4);
4345         }
4346     }
4347
4348   vec_free (status);
4349
4350   vat_json_print (vam->ofp, &node);
4351   vat_json_free (&node);
4352
4353   vam->retval = ntohl (mp->retval);
4354   vam->result_ready = 1;
4355 }
4356
4357 static void
4358   vl_api_show_one_nsh_mapping_reply_t_handler
4359   (vl_api_show_one_nsh_mapping_reply_t * mp)
4360 {
4361   vat_main_t *vam = &vat_main;
4362   i32 retval = ntohl (mp->retval);
4363
4364   if (0 <= retval)
4365     {
4366       print (vam->ofp, "%-20s%-16s",
4367              mp->is_set ? "set" : "not-set",
4368              mp->is_set ? (char *) mp->locator_set_name : "");
4369     }
4370
4371   vam->retval = retval;
4372   vam->result_ready = 1;
4373 }
4374
4375 static void
4376   vl_api_show_one_nsh_mapping_reply_t_handler_json
4377   (vl_api_show_one_nsh_mapping_reply_t * mp)
4378 {
4379   vat_main_t *vam = &vat_main;
4380   vat_json_node_t node;
4381   u8 *status = 0;
4382
4383   status = format (0, "%s", mp->is_set ? "yes" : "no");
4384   vec_add1 (status, 0);
4385
4386   vat_json_init_object (&node);
4387   vat_json_object_add_string_copy (&node, "is_set", status);
4388   if (mp->is_set)
4389     {
4390       vat_json_object_add_string_copy (&node, "locator_set",
4391                                        mp->locator_set_name);
4392     }
4393
4394   vec_free (status);
4395
4396   vat_json_print (vam->ofp, &node);
4397   vat_json_free (&node);
4398
4399   vam->retval = ntohl (mp->retval);
4400   vam->result_ready = 1;
4401 }
4402
4403 static void
4404   vl_api_show_one_map_register_ttl_reply_t_handler
4405   (vl_api_show_one_map_register_ttl_reply_t * mp)
4406 {
4407   vat_main_t *vam = &vat_main;
4408   i32 retval = ntohl (mp->retval);
4409
4410   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4411
4412   if (0 <= retval)
4413     {
4414       print (vam->ofp, "ttl: %u", mp->ttl);
4415     }
4416
4417   vam->retval = retval;
4418   vam->result_ready = 1;
4419 }
4420
4421 static void
4422   vl_api_show_one_map_register_ttl_reply_t_handler_json
4423   (vl_api_show_one_map_register_ttl_reply_t * mp)
4424 {
4425   vat_main_t *vam = &vat_main;
4426   vat_json_node_t node;
4427
4428   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4429   vat_json_init_object (&node);
4430   vat_json_object_add_uint (&node, "ttl", mp->ttl);
4431
4432   vat_json_print (vam->ofp, &node);
4433   vat_json_free (&node);
4434
4435   vam->retval = ntohl (mp->retval);
4436   vam->result_ready = 1;
4437 }
4438
4439 static void
4440 vl_api_show_one_pitr_reply_t_handler (vl_api_show_one_pitr_reply_t * mp)
4441 {
4442   vat_main_t *vam = &vat_main;
4443   i32 retval = ntohl (mp->retval);
4444
4445   if (0 <= retval)
4446     {
4447       print (vam->ofp, "%-20s%-16s",
4448              mp->status ? "enabled" : "disabled",
4449              mp->status ? (char *) mp->locator_set_name : "");
4450     }
4451
4452   vam->retval = retval;
4453   vam->result_ready = 1;
4454 }
4455
4456 static void
4457 vl_api_show_one_pitr_reply_t_handler_json (vl_api_show_one_pitr_reply_t * mp)
4458 {
4459   vat_main_t *vam = &vat_main;
4460   vat_json_node_t node;
4461   u8 *status = 0;
4462
4463   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4464   vec_add1 (status, 0);
4465
4466   vat_json_init_object (&node);
4467   vat_json_object_add_string_copy (&node, "status", status);
4468   if (mp->status)
4469     {
4470       vat_json_object_add_string_copy (&node, "locator_set",
4471                                        mp->locator_set_name);
4472     }
4473
4474   vec_free (status);
4475
4476   vat_json_print (vam->ofp, &node);
4477   vat_json_free (&node);
4478
4479   vam->retval = ntohl (mp->retval);
4480   vam->result_ready = 1;
4481 }
4482
4483 static u8 *
4484 format_policer_type (u8 * s, va_list * va)
4485 {
4486   u32 i = va_arg (*va, u32);
4487
4488   if (i == SSE2_QOS_POLICER_TYPE_1R2C)
4489     s = format (s, "1r2c");
4490   else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
4491     s = format (s, "1r3c");
4492   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
4493     s = format (s, "2r3c-2698");
4494   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
4495     s = format (s, "2r3c-4115");
4496   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
4497     s = format (s, "2r3c-mef5cf1");
4498   else
4499     s = format (s, "ILLEGAL");
4500   return s;
4501 }
4502
4503 static u8 *
4504 format_policer_rate_type (u8 * s, va_list * va)
4505 {
4506   u32 i = va_arg (*va, u32);
4507
4508   if (i == SSE2_QOS_RATE_KBPS)
4509     s = format (s, "kbps");
4510   else if (i == SSE2_QOS_RATE_PPS)
4511     s = format (s, "pps");
4512   else
4513     s = format (s, "ILLEGAL");
4514   return s;
4515 }
4516
4517 static u8 *
4518 format_policer_round_type (u8 * s, va_list * va)
4519 {
4520   u32 i = va_arg (*va, u32);
4521
4522   if (i == SSE2_QOS_ROUND_TO_CLOSEST)
4523     s = format (s, "closest");
4524   else if (i == SSE2_QOS_ROUND_TO_UP)
4525     s = format (s, "up");
4526   else if (i == SSE2_QOS_ROUND_TO_DOWN)
4527     s = format (s, "down");
4528   else
4529     s = format (s, "ILLEGAL");
4530   return s;
4531 }
4532
4533 static u8 *
4534 format_policer_action_type (u8 * s, va_list * va)
4535 {
4536   u32 i = va_arg (*va, u32);
4537
4538   if (i == SSE2_QOS_ACTION_DROP)
4539     s = format (s, "drop");
4540   else if (i == SSE2_QOS_ACTION_TRANSMIT)
4541     s = format (s, "transmit");
4542   else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4543     s = format (s, "mark-and-transmit");
4544   else
4545     s = format (s, "ILLEGAL");
4546   return s;
4547 }
4548
4549 static u8 *
4550 format_dscp (u8 * s, va_list * va)
4551 {
4552   u32 i = va_arg (*va, u32);
4553   char *t = 0;
4554
4555   switch (i)
4556     {
4557 #define _(v,f,str) case VNET_DSCP_##f: t = str; break;
4558       foreach_vnet_dscp
4559 #undef _
4560     default:
4561       return format (s, "ILLEGAL");
4562     }
4563   s = format (s, "%s", t);
4564   return s;
4565 }
4566
4567 static void
4568 vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
4569 {
4570   vat_main_t *vam = &vat_main;
4571   u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
4572
4573   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4574     conform_dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
4575   else
4576     conform_dscp_str = format (0, "");
4577
4578   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4579     exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
4580   else
4581     exceed_dscp_str = format (0, "");
4582
4583   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4584     violate_dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
4585   else
4586     violate_dscp_str = format (0, "");
4587
4588   print (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
4589          "rate type %U, round type %U, %s rate, %s color-aware, "
4590          "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
4591          "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
4592          "conform action %U%s, exceed action %U%s, violate action %U%s",
4593          mp->name,
4594          format_policer_type, mp->type,
4595          ntohl (mp->cir),
4596          ntohl (mp->eir),
4597          clib_net_to_host_u64 (mp->cb),
4598          clib_net_to_host_u64 (mp->eb),
4599          format_policer_rate_type, mp->rate_type,
4600          format_policer_round_type, mp->round_type,
4601          mp->single_rate ? "single" : "dual",
4602          mp->color_aware ? "is" : "not",
4603          ntohl (mp->cir_tokens_per_period),
4604          ntohl (mp->pir_tokens_per_period),
4605          ntohl (mp->scale),
4606          ntohl (mp->current_limit),
4607          ntohl (mp->current_bucket),
4608          ntohl (mp->extended_limit),
4609          ntohl (mp->extended_bucket),
4610          clib_net_to_host_u64 (mp->last_update_time),
4611          format_policer_action_type, mp->conform_action_type,
4612          conform_dscp_str,
4613          format_policer_action_type, mp->exceed_action_type,
4614          exceed_dscp_str,
4615          format_policer_action_type, mp->violate_action_type,
4616          violate_dscp_str);
4617
4618   vec_free (conform_dscp_str);
4619   vec_free (exceed_dscp_str);
4620   vec_free (violate_dscp_str);
4621 }
4622
4623 static void vl_api_policer_details_t_handler_json
4624   (vl_api_policer_details_t * mp)
4625 {
4626   vat_main_t *vam = &vat_main;
4627   vat_json_node_t *node;
4628   u8 *rate_type_str, *round_type_str, *type_str;
4629   u8 *conform_action_str, *exceed_action_str, *violate_action_str;
4630
4631   rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
4632   round_type_str =
4633     format (0, "%U", format_policer_round_type, mp->round_type);
4634   type_str = format (0, "%U", format_policer_type, mp->type);
4635   conform_action_str = format (0, "%U", format_policer_action_type,
4636                                mp->conform_action_type);
4637   exceed_action_str = format (0, "%U", format_policer_action_type,
4638                               mp->exceed_action_type);
4639   violate_action_str = format (0, "%U", format_policer_action_type,
4640                                mp->violate_action_type);
4641
4642   if (VAT_JSON_ARRAY != vam->json_tree.type)
4643     {
4644       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4645       vat_json_init_array (&vam->json_tree);
4646     }
4647   node = vat_json_array_add (&vam->json_tree);
4648
4649   vat_json_init_object (node);
4650   vat_json_object_add_string_copy (node, "name", mp->name);
4651   vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
4652   vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
4653   vat_json_object_add_uint (node, "cb", clib_net_to_host_u64 (mp->cb));
4654   vat_json_object_add_uint (node, "eb", clib_net_to_host_u64 (mp->eb));
4655   vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
4656   vat_json_object_add_string_copy (node, "round_type", round_type_str);
4657   vat_json_object_add_string_copy (node, "type", type_str);
4658   vat_json_object_add_uint (node, "single_rate", mp->single_rate);
4659   vat_json_object_add_uint (node, "color_aware", mp->color_aware);
4660   vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
4661   vat_json_object_add_uint (node, "cir_tokens_per_period",
4662                             ntohl (mp->cir_tokens_per_period));
4663   vat_json_object_add_uint (node, "eir_tokens_per_period",
4664                             ntohl (mp->pir_tokens_per_period));
4665   vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
4666   vat_json_object_add_uint (node, "current_bucket",
4667                             ntohl (mp->current_bucket));
4668   vat_json_object_add_uint (node, "extended_limit",
4669                             ntohl (mp->extended_limit));
4670   vat_json_object_add_uint (node, "extended_bucket",
4671                             ntohl (mp->extended_bucket));
4672   vat_json_object_add_uint (node, "last_update_time",
4673                             ntohl (mp->last_update_time));
4674   vat_json_object_add_string_copy (node, "conform_action",
4675                                    conform_action_str);
4676   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4677     {
4678       u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
4679       vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
4680       vec_free (dscp_str);
4681     }
4682   vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
4683   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4684     {
4685       u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
4686       vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
4687       vec_free (dscp_str);
4688     }
4689   vat_json_object_add_string_copy (node, "violate_action",
4690                                    violate_action_str);
4691   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4692     {
4693       u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
4694       vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
4695       vec_free (dscp_str);
4696     }
4697
4698   vec_free (rate_type_str);
4699   vec_free (round_type_str);
4700   vec_free (type_str);
4701   vec_free (conform_action_str);
4702   vec_free (exceed_action_str);
4703   vec_free (violate_action_str);
4704 }
4705
4706 static void
4707 vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
4708                                            mp)
4709 {
4710   vat_main_t *vam = &vat_main;
4711   int i, count = ntohl (mp->count);
4712
4713   if (count > 0)
4714     print (vam->ofp, "classify table ids (%d) : ", count);
4715   for (i = 0; i < count; i++)
4716     {
4717       print (vam->ofp, "%d", ntohl (mp->ids[i]));
4718       print (vam->ofp, (i < count - 1) ? "," : "");
4719     }
4720   vam->retval = ntohl (mp->retval);
4721   vam->result_ready = 1;
4722 }
4723
4724 static void
4725   vl_api_classify_table_ids_reply_t_handler_json
4726   (vl_api_classify_table_ids_reply_t * mp)
4727 {
4728   vat_main_t *vam = &vat_main;
4729   int i, count = ntohl (mp->count);
4730
4731   if (count > 0)
4732     {
4733       vat_json_node_t node;
4734
4735       vat_json_init_object (&node);
4736       for (i = 0; i < count; i++)
4737         {
4738           vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
4739         }
4740       vat_json_print (vam->ofp, &node);
4741       vat_json_free (&node);
4742     }
4743   vam->retval = ntohl (mp->retval);
4744   vam->result_ready = 1;
4745 }
4746
4747 static void
4748   vl_api_classify_table_by_interface_reply_t_handler
4749   (vl_api_classify_table_by_interface_reply_t * mp)
4750 {
4751   vat_main_t *vam = &vat_main;
4752   u32 table_id;
4753
4754   table_id = ntohl (mp->l2_table_id);
4755   if (table_id != ~0)
4756     print (vam->ofp, "l2 table id : %d", table_id);
4757   else
4758     print (vam->ofp, "l2 table id : No input ACL tables configured");
4759   table_id = ntohl (mp->ip4_table_id);
4760   if (table_id != ~0)
4761     print (vam->ofp, "ip4 table id : %d", table_id);
4762   else
4763     print (vam->ofp, "ip4 table id : No input ACL tables configured");
4764   table_id = ntohl (mp->ip6_table_id);
4765   if (table_id != ~0)
4766     print (vam->ofp, "ip6 table id : %d", table_id);
4767   else
4768     print (vam->ofp, "ip6 table id : No input ACL tables configured");
4769   vam->retval = ntohl (mp->retval);
4770   vam->result_ready = 1;
4771 }
4772
4773 static void
4774   vl_api_classify_table_by_interface_reply_t_handler_json
4775   (vl_api_classify_table_by_interface_reply_t * mp)
4776 {
4777   vat_main_t *vam = &vat_main;
4778   vat_json_node_t node;
4779
4780   vat_json_init_object (&node);
4781
4782   vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
4783   vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
4784   vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
4785
4786   vat_json_print (vam->ofp, &node);
4787   vat_json_free (&node);
4788
4789   vam->retval = ntohl (mp->retval);
4790   vam->result_ready = 1;
4791 }
4792
4793 static void vl_api_policer_add_del_reply_t_handler
4794   (vl_api_policer_add_del_reply_t * mp)
4795 {
4796   vat_main_t *vam = &vat_main;
4797   i32 retval = ntohl (mp->retval);
4798   if (vam->async_mode)
4799     {
4800       vam->async_errors += (retval < 0);
4801     }
4802   else
4803     {
4804       vam->retval = retval;
4805       vam->result_ready = 1;
4806       if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
4807         /*
4808          * Note: this is just barely thread-safe, depends on
4809          * the main thread spinning waiting for an answer...
4810          */
4811         errmsg ("policer index %d", ntohl (mp->policer_index));
4812     }
4813 }
4814
4815 static void vl_api_policer_add_del_reply_t_handler_json
4816   (vl_api_policer_add_del_reply_t * mp)
4817 {
4818   vat_main_t *vam = &vat_main;
4819   vat_json_node_t node;
4820
4821   vat_json_init_object (&node);
4822   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
4823   vat_json_object_add_uint (&node, "policer_index",
4824                             ntohl (mp->policer_index));
4825
4826   vat_json_print (vam->ofp, &node);
4827   vat_json_free (&node);
4828
4829   vam->retval = ntohl (mp->retval);
4830   vam->result_ready = 1;
4831 }
4832
4833 /* Format hex dump. */
4834 u8 *
4835 format_hex_bytes (u8 * s, va_list * va)
4836 {
4837   u8 *bytes = va_arg (*va, u8 *);
4838   int n_bytes = va_arg (*va, int);
4839   uword i;
4840
4841   /* Print short or long form depending on byte count. */
4842   uword short_form = n_bytes <= 32;
4843   u32 indent = format_get_indent (s);
4844
4845   if (n_bytes == 0)
4846     return s;
4847
4848   for (i = 0; i < n_bytes; i++)
4849     {
4850       if (!short_form && (i % 32) == 0)
4851         s = format (s, "%08x: ", i);
4852       s = format (s, "%02x", bytes[i]);
4853       if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
4854         s = format (s, "\n%U", format_white_space, indent);
4855     }
4856
4857   return s;
4858 }
4859
4860 static void
4861 vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
4862                                             * mp)
4863 {
4864   vat_main_t *vam = &vat_main;
4865   i32 retval = ntohl (mp->retval);
4866   if (retval == 0)
4867     {
4868       print (vam->ofp, "classify table info :");
4869       print (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d",
4870              ntohl (mp->active_sessions), ntohl (mp->next_table_index),
4871              ntohl (mp->miss_next_index));
4872       print (vam->ofp, "nbuckets: %d skip: %d match: %d",
4873              ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
4874              ntohl (mp->match_n_vectors));
4875       print (vam->ofp, "mask: %U", format_hex_bytes, mp->mask,
4876              ntohl (mp->mask_length));
4877     }
4878   vam->retval = retval;
4879   vam->result_ready = 1;
4880 }
4881
4882 static void
4883   vl_api_classify_table_info_reply_t_handler_json
4884   (vl_api_classify_table_info_reply_t * mp)
4885 {
4886   vat_main_t *vam = &vat_main;
4887   vat_json_node_t node;
4888
4889   i32 retval = ntohl (mp->retval);
4890   if (retval == 0)
4891     {
4892       vat_json_init_object (&node);
4893
4894       vat_json_object_add_int (&node, "sessions",
4895                                ntohl (mp->active_sessions));
4896       vat_json_object_add_int (&node, "nexttbl",
4897                                ntohl (mp->next_table_index));
4898       vat_json_object_add_int (&node, "nextnode",
4899                                ntohl (mp->miss_next_index));
4900       vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
4901       vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
4902       vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
4903       u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
4904                       ntohl (mp->mask_length), 0);
4905       vat_json_object_add_string_copy (&node, "mask", s);
4906
4907       vat_json_print (vam->ofp, &node);
4908       vat_json_free (&node);
4909     }
4910   vam->retval = ntohl (mp->retval);
4911   vam->result_ready = 1;
4912 }
4913
4914 static void
4915 vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
4916                                            mp)
4917 {
4918   vat_main_t *vam = &vat_main;
4919
4920   print (vam->ofp, "next_index: %d advance: %d opaque: %d ",
4921          ntohl (mp->hit_next_index), ntohl (mp->advance),
4922          ntohl (mp->opaque_index));
4923   print (vam->ofp, "mask: %U", format_hex_bytes, mp->match,
4924          ntohl (mp->match_length));
4925 }
4926
4927 static void
4928   vl_api_classify_session_details_t_handler_json
4929   (vl_api_classify_session_details_t * mp)
4930 {
4931   vat_main_t *vam = &vat_main;
4932   vat_json_node_t *node = NULL;
4933
4934   if (VAT_JSON_ARRAY != vam->json_tree.type)
4935     {
4936       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4937       vat_json_init_array (&vam->json_tree);
4938     }
4939   node = vat_json_array_add (&vam->json_tree);
4940
4941   vat_json_init_object (node);
4942   vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
4943   vat_json_object_add_int (node, "advance", ntohl (mp->advance));
4944   vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
4945   u8 *s =
4946     format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
4947             0);
4948   vat_json_object_add_string_copy (node, "match", s);
4949 }
4950
4951 static void vl_api_pg_create_interface_reply_t_handler
4952   (vl_api_pg_create_interface_reply_t * mp)
4953 {
4954   vat_main_t *vam = &vat_main;
4955
4956   vam->retval = ntohl (mp->retval);
4957   vam->result_ready = 1;
4958 }
4959
4960 static void vl_api_pg_create_interface_reply_t_handler_json
4961   (vl_api_pg_create_interface_reply_t * mp)
4962 {
4963   vat_main_t *vam = &vat_main;
4964   vat_json_node_t node;
4965
4966   i32 retval = ntohl (mp->retval);
4967   if (retval == 0)
4968     {
4969       vat_json_init_object (&node);
4970
4971       vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
4972
4973       vat_json_print (vam->ofp, &node);
4974       vat_json_free (&node);
4975     }
4976   vam->retval = ntohl (mp->retval);
4977   vam->result_ready = 1;
4978 }
4979
4980 static void vl_api_policer_classify_details_t_handler
4981   (vl_api_policer_classify_details_t * mp)
4982 {
4983   vat_main_t *vam = &vat_main;
4984
4985   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
4986          ntohl (mp->table_index));
4987 }
4988
4989 static void vl_api_policer_classify_details_t_handler_json
4990   (vl_api_policer_classify_details_t * mp)
4991 {
4992   vat_main_t *vam = &vat_main;
4993   vat_json_node_t *node;
4994
4995   if (VAT_JSON_ARRAY != vam->json_tree.type)
4996     {
4997       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4998       vat_json_init_array (&vam->json_tree);
4999     }
5000   node = vat_json_array_add (&vam->json_tree);
5001
5002   vat_json_init_object (node);
5003   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
5004   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
5005 }
5006
5007 static void vl_api_flow_classify_details_t_handler
5008   (vl_api_flow_classify_details_t * mp)
5009 {
5010   vat_main_t *vam = &vat_main;
5011
5012   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
5013          ntohl (mp->table_index));
5014 }
5015
5016 static void vl_api_flow_classify_details_t_handler_json
5017   (vl_api_flow_classify_details_t * mp)
5018 {
5019   vat_main_t *vam = &vat_main;
5020   vat_json_node_t *node;
5021
5022   if (VAT_JSON_ARRAY != vam->json_tree.type)
5023     {
5024       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5025       vat_json_init_array (&vam->json_tree);
5026     }
5027   node = vat_json_array_add (&vam->json_tree);
5028
5029   vat_json_init_object (node);
5030   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
5031   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
5032 }
5033
5034 #define vl_api_one_adjacencies_get_reply_t_endian vl_noop_handler
5035 #define vl_api_one_adjacencies_get_reply_t_print vl_noop_handler
5036 #define vl_api_one_l2_arp_bd_get_reply_t_print vl_noop_handler
5037 #define vl_api_one_l2_arp_entries_get_reply_t_endian vl_noop_handler
5038 #define vl_api_one_l2_arp_entries_get_reply_t_print vl_noop_handler
5039 #define vl_api_one_l2_arp_bd_get_reply_t_endian vl_noop_handler
5040 #define vl_api_one_ndp_bd_get_reply_t_endian vl_noop_handler
5041 #define vl_api_one_ndp_bd_get_reply_t_print vl_noop_handler
5042 #define vl_api_one_ndp_entries_get_reply_t_print vl_noop_handler
5043 #define vl_api_one_ndp_entries_get_reply_t_endian vl_noop_handler
5044
5045 /*
5046  * Generate boilerplate reply handlers, which
5047  * dig the return value out of the xxx_reply_t API message,
5048  * stick it into vam->retval, and set vam->result_ready
5049  *
5050  * Could also do this by pointing N message decode slots at
5051  * a single function, but that could break in subtle ways.
5052  */
5053
5054 #define foreach_standard_reply_retval_handler           \
5055 _(sw_interface_set_flags_reply)                         \
5056 _(sw_interface_add_del_address_reply)                   \
5057 _(sw_interface_set_rx_mode_reply)                       \
5058 _(sw_interface_set_rx_placement_reply)                  \
5059 _(sw_interface_set_table_reply)                         \
5060 _(sw_interface_set_mpls_enable_reply)                   \
5061 _(sw_interface_set_vpath_reply)                         \
5062 _(sw_interface_set_vxlan_bypass_reply)                  \
5063 _(sw_interface_set_geneve_bypass_reply)                 \
5064 _(sw_interface_set_vxlan_gpe_bypass_reply)              \
5065 _(sw_interface_set_l2_bridge_reply)                     \
5066 _(sw_interface_set_bond_weight_reply)                   \
5067 _(bridge_domain_add_del_reply)                          \
5068 _(sw_interface_set_l2_xconnect_reply)                   \
5069 _(l2fib_add_del_reply)                                  \
5070 _(l2fib_flush_int_reply)                                \
5071 _(l2fib_flush_bd_reply)                                 \
5072 _(ip_route_add_del_reply)                               \
5073 _(ip_table_add_del_reply)                               \
5074 _(ip_mroute_add_del_reply)                              \
5075 _(mpls_route_add_del_reply)                             \
5076 _(mpls_table_add_del_reply)                             \
5077 _(mpls_ip_bind_unbind_reply)                            \
5078 _(bier_route_add_del_reply)                             \
5079 _(bier_table_add_del_reply)                             \
5080 _(proxy_arp_add_del_reply)                              \
5081 _(proxy_arp_intfc_enable_disable_reply)                 \
5082 _(sw_interface_set_unnumbered_reply)                    \
5083 _(ip_neighbor_add_del_reply)                            \
5084 _(reset_fib_reply)                                      \
5085 _(set_ip_flow_hash_reply)                               \
5086 _(sw_interface_ip6_enable_disable_reply)                \
5087 _(ip6nd_proxy_add_del_reply)                            \
5088 _(sw_interface_ip6nd_ra_prefix_reply)                   \
5089 _(sw_interface_ip6nd_ra_config_reply)                   \
5090 _(set_arp_neighbor_limit_reply)                         \
5091 _(l2_patch_add_del_reply)                               \
5092 _(sr_mpls_policy_add_reply)                             \
5093 _(sr_mpls_policy_mod_reply)                             \
5094 _(sr_mpls_policy_del_reply)                             \
5095 _(sr_policy_add_reply)                                  \
5096 _(sr_policy_mod_reply)                                  \
5097 _(sr_policy_del_reply)                                  \
5098 _(sr_localsid_add_del_reply)                            \
5099 _(sr_steering_add_del_reply)                            \
5100 _(classify_add_del_session_reply)                       \
5101 _(classify_set_interface_ip_table_reply)                \
5102 _(classify_set_interface_l2_tables_reply)               \
5103 _(l2tpv3_set_tunnel_cookies_reply)                      \
5104 _(l2tpv3_interface_enable_disable_reply)                \
5105 _(l2tpv3_set_lookup_key_reply)                          \
5106 _(l2_fib_clear_table_reply)                             \
5107 _(l2_interface_efp_filter_reply)                        \
5108 _(l2_interface_vlan_tag_rewrite_reply)                  \
5109 _(modify_vhost_user_if_reply)                           \
5110 _(delete_vhost_user_if_reply)                           \
5111 _(ip_probe_neighbor_reply)                              \
5112 _(ip_scan_neighbor_enable_disable_reply)                \
5113 _(want_ip4_arp_events_reply)                            \
5114 _(want_ip6_nd_events_reply)                             \
5115 _(want_l2_macs_events_reply)                            \
5116 _(input_acl_set_interface_reply)                        \
5117 _(ipsec_spd_add_del_reply)                              \
5118 _(ipsec_interface_add_del_spd_reply)                    \
5119 _(ipsec_spd_entry_add_del_reply)                        \
5120 _(ipsec_sad_entry_add_del_reply)                        \
5121 _(ipsec_tunnel_if_add_del_reply)                        \
5122 _(ipsec_tunnel_if_set_sa_reply)                         \
5123 _(delete_loopback_reply)                                \
5124 _(bd_ip_mac_add_del_reply)                              \
5125 _(bd_ip_mac_flush_reply)                                \
5126 _(want_interface_events_reply)                          \
5127 _(cop_interface_enable_disable_reply)                   \
5128 _(cop_whitelist_enable_disable_reply)                   \
5129 _(sw_interface_clear_stats_reply)                       \
5130 _(ioam_enable_reply)                                    \
5131 _(ioam_disable_reply)                                   \
5132 _(one_add_del_locator_reply)                            \
5133 _(one_add_del_local_eid_reply)                          \
5134 _(one_add_del_remote_mapping_reply)                     \
5135 _(one_add_del_adjacency_reply)                          \
5136 _(one_add_del_map_resolver_reply)                       \
5137 _(one_add_del_map_server_reply)                         \
5138 _(one_enable_disable_reply)                             \
5139 _(one_rloc_probe_enable_disable_reply)                  \
5140 _(one_map_register_enable_disable_reply)                \
5141 _(one_map_register_set_ttl_reply)                       \
5142 _(one_set_transport_protocol_reply)                     \
5143 _(one_map_register_fallback_threshold_reply)            \
5144 _(one_pitr_set_locator_set_reply)                       \
5145 _(one_map_request_mode_reply)                           \
5146 _(one_add_del_map_request_itr_rlocs_reply)              \
5147 _(one_eid_table_add_del_map_reply)                      \
5148 _(one_use_petr_reply)                                   \
5149 _(one_stats_enable_disable_reply)                       \
5150 _(one_add_del_l2_arp_entry_reply)                       \
5151 _(one_add_del_ndp_entry_reply)                          \
5152 _(one_stats_flush_reply)                                \
5153 _(one_enable_disable_xtr_mode_reply)                    \
5154 _(one_enable_disable_pitr_mode_reply)                   \
5155 _(one_enable_disable_petr_mode_reply)                   \
5156 _(gpe_enable_disable_reply)                             \
5157 _(gpe_set_encap_mode_reply)                             \
5158 _(gpe_add_del_iface_reply)                              \
5159 _(gpe_add_del_native_fwd_rpath_reply)                   \
5160 _(af_packet_delete_reply)                               \
5161 _(policer_classify_set_interface_reply)                 \
5162 _(netmap_create_reply)                                  \
5163 _(netmap_delete_reply)                                  \
5164 _(set_ipfix_exporter_reply)                             \
5165 _(set_ipfix_classify_stream_reply)                      \
5166 _(ipfix_classify_table_add_del_reply)                   \
5167 _(flow_classify_set_interface_reply)                    \
5168 _(sw_interface_span_enable_disable_reply)               \
5169 _(pg_capture_reply)                                     \
5170 _(pg_enable_disable_reply)                              \
5171 _(ip_source_and_port_range_check_add_del_reply)         \
5172 _(ip_source_and_port_range_check_interface_add_del_reply)\
5173 _(delete_subif_reply)                                   \
5174 _(l2_interface_pbb_tag_rewrite_reply)                   \
5175 _(set_punt_reply)                                       \
5176 _(feature_enable_disable_reply)                         \
5177 _(feature_gso_enable_disable_reply)                     \
5178 _(sw_interface_tag_add_del_reply)                       \
5179 _(sw_interface_add_del_mac_address_reply)               \
5180 _(hw_interface_set_mtu_reply)                           \
5181 _(p2p_ethernet_add_reply)                               \
5182 _(p2p_ethernet_del_reply)                               \
5183 _(lldp_config_reply)                                    \
5184 _(sw_interface_set_lldp_reply)                          \
5185 _(tcp_configure_src_addresses_reply)                    \
5186 _(session_rule_add_del_reply)                           \
5187 _(ip_container_proxy_add_del_reply)                     \
5188 _(output_acl_set_interface_reply)                       \
5189 _(qos_record_enable_disable_reply)
5190
5191 #define _(n)                                    \
5192     static void vl_api_##n##_t_handler          \
5193     (vl_api_##n##_t * mp)                       \
5194     {                                           \
5195         vat_main_t * vam = &vat_main;           \
5196         i32 retval = ntohl(mp->retval);         \
5197         if (vam->async_mode) {                  \
5198             vam->async_errors += (retval < 0);  \
5199         } else {                                \
5200             vam->retval = retval;               \
5201             vam->result_ready = 1;              \
5202         }                                       \
5203     }
5204 foreach_standard_reply_retval_handler;
5205 #undef _
5206
5207 #define _(n)                                    \
5208     static void vl_api_##n##_t_handler_json     \
5209     (vl_api_##n##_t * mp)                       \
5210     {                                           \
5211         vat_main_t * vam = &vat_main;           \
5212         vat_json_node_t node;                   \
5213         vat_json_init_object(&node);            \
5214         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
5215         vat_json_print(vam->ofp, &node);        \
5216         vam->retval = ntohl(mp->retval);        \
5217         vam->result_ready = 1;                  \
5218     }
5219 foreach_standard_reply_retval_handler;
5220 #undef _
5221
5222 /*
5223  * Table of message reply handlers, must include boilerplate handlers
5224  * we just generated
5225  */
5226
5227 #define foreach_vpe_api_reply_msg                                       \
5228 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
5229 _(CREATE_LOOPBACK_INSTANCE_REPLY, create_loopback_instance_reply)       \
5230 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
5231 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
5232 _(CONTROL_PING_REPLY, control_ping_reply)                               \
5233 _(CLI_REPLY, cli_reply)                                                 \
5234 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
5235 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
5236   sw_interface_add_del_address_reply)                                   \
5237 _(SW_INTERFACE_SET_RX_MODE_REPLY, sw_interface_set_rx_mode_reply)       \
5238 _(SW_INTERFACE_SET_RX_PLACEMENT_REPLY, sw_interface_set_rx_placement_reply)     \
5239 _(SW_INTERFACE_RX_PLACEMENT_DETAILS, sw_interface_rx_placement_details) \
5240 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
5241 _(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
5242 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
5243 _(SW_INTERFACE_SET_VXLAN_BYPASS_REPLY, sw_interface_set_vxlan_bypass_reply) \
5244 _(SW_INTERFACE_SET_GENEVE_BYPASS_REPLY, sw_interface_set_geneve_bypass_reply) \
5245 _(SW_INTERFACE_SET_VXLAN_GPE_BYPASS_REPLY, sw_interface_set_vxlan_gpe_bypass_reply) \
5246 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
5247   sw_interface_set_l2_xconnect_reply)                                   \
5248 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
5249   sw_interface_set_l2_bridge_reply)                                     \
5250 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
5251 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
5252 _(BRIDGE_DOMAIN_SET_MAC_AGE_REPLY, bridge_domain_set_mac_age_reply)     \
5253 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
5254 _(L2FIB_FLUSH_INT_REPLY, l2fib_flush_int_reply)                         \
5255 _(L2FIB_FLUSH_BD_REPLY, l2fib_flush_bd_reply)                           \
5256 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
5257 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
5258 _(TAP_CREATE_V2_REPLY, tap_create_v2_reply)                             \
5259 _(TAP_DELETE_V2_REPLY, tap_delete_v2_reply)                             \
5260 _(SW_INTERFACE_TAP_V2_DETAILS, sw_interface_tap_v2_details)             \
5261 _(VIRTIO_PCI_CREATE_REPLY, virtio_pci_create_reply)                     \
5262 _(VIRTIO_PCI_DELETE_REPLY, virtio_pci_delete_reply)                     \
5263 _(SW_INTERFACE_VIRTIO_PCI_DETAILS, sw_interface_virtio_pci_details)     \
5264 _(BOND_CREATE_REPLY, bond_create_reply)                                 \
5265 _(BOND_DELETE_REPLY, bond_delete_reply)                                 \
5266 _(BOND_ENSLAVE_REPLY, bond_enslave_reply)                               \
5267 _(BOND_DETACH_SLAVE_REPLY, bond_detach_slave_reply)                     \
5268 _(SW_INTERFACE_SET_BOND_WEIGHT_REPLY, sw_interface_set_bond_weight_reply) \
5269 _(SW_INTERFACE_BOND_DETAILS, sw_interface_bond_details)                 \
5270 _(SW_INTERFACE_SLAVE_DETAILS, sw_interface_slave_details)               \
5271 _(IP_ROUTE_ADD_DEL_REPLY, ip_route_add_del_reply)                       \
5272 _(IP_TABLE_ADD_DEL_REPLY, ip_table_add_del_reply)                       \
5273 _(IP_MROUTE_ADD_DEL_REPLY, ip_mroute_add_del_reply)                     \
5274 _(MPLS_TABLE_ADD_DEL_REPLY, mpls_table_add_del_reply)                   \
5275 _(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply)                   \
5276 _(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply)                 \
5277 _(BIER_ROUTE_ADD_DEL_REPLY, bier_route_add_del_reply)                   \
5278 _(BIER_TABLE_ADD_DEL_REPLY, bier_table_add_del_reply)                   \
5279 _(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply)                     \
5280 _(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY,                                 \
5281   proxy_arp_intfc_enable_disable_reply)                                 \
5282 _(MPLS_TUNNEL_ADD_DEL_REPLY, mpls_tunnel_add_del_reply)                 \
5283 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
5284   sw_interface_set_unnumbered_reply)                                    \
5285 _(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply)                 \
5286 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
5287 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
5288 _(RESET_FIB_REPLY, reset_fib_reply)                                     \
5289 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
5290 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
5291   sw_interface_ip6_enable_disable_reply)                                \
5292 _(IP6ND_PROXY_ADD_DEL_REPLY, ip6nd_proxy_add_del_reply)                 \
5293 _(IP6ND_PROXY_DETAILS, ip6nd_proxy_details)                             \
5294 _(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY,                                   \
5295   sw_interface_ip6nd_ra_prefix_reply)                                   \
5296 _(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY,                                   \
5297   sw_interface_ip6nd_ra_config_reply)                                   \
5298 _(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply)           \
5299 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
5300 _(SR_MPLS_POLICY_ADD_REPLY, sr_mpls_policy_add_reply)                   \
5301 _(SR_MPLS_POLICY_MOD_REPLY, sr_mpls_policy_mod_reply)                   \
5302 _(SR_MPLS_POLICY_DEL_REPLY, sr_mpls_policy_del_reply)                   \
5303 _(SR_POLICY_ADD_REPLY, sr_policy_add_reply)                             \
5304 _(SR_POLICY_MOD_REPLY, sr_policy_mod_reply)                             \
5305 _(SR_POLICY_DEL_REPLY, sr_policy_del_reply)                             \
5306 _(SR_LOCALSID_ADD_DEL_REPLY, sr_localsid_add_del_reply)                 \
5307 _(SR_STEERING_ADD_DEL_REPLY, sr_steering_add_del_reply)                 \
5308 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
5309 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
5310 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
5311 classify_set_interface_ip_table_reply)                                  \
5312 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
5313   classify_set_interface_l2_tables_reply)                               \
5314 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
5315 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
5316 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
5317 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
5318 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
5319   l2tpv3_interface_enable_disable_reply)                                \
5320 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
5321 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
5322 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
5323 _(VXLAN_OFFLOAD_RX_REPLY, vxlan_offload_rx_reply)               \
5324 _(GENEVE_ADD_DEL_TUNNEL_REPLY, geneve_add_del_tunnel_reply)             \
5325 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
5326 _(GENEVE_TUNNEL_DETAILS, geneve_tunnel_details)                         \
5327 _(GRE_TUNNEL_ADD_DEL_REPLY, gre_tunnel_add_del_reply)                   \
5328 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
5329 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
5330 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
5331 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
5332 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
5333 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
5334 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
5335 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
5336 _(SHOW_VERSION_REPLY, show_version_reply)                               \
5337 _(SHOW_THREADS_REPLY, show_threads_reply)                               \
5338 _(L2_FIB_TABLE_DETAILS, l2_fib_table_details)                           \
5339 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)       \
5340 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
5341 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
5342 _(IP_PROBE_NEIGHBOR_REPLY, ip_probe_neighbor_reply)                     \
5343 _(IP_SCAN_NEIGHBOR_ENABLE_DISABLE_REPLY, ip_scan_neighbor_enable_disable_reply) \
5344 _(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply)                 \
5345 _(IP4_ARP_EVENT, ip4_arp_event)                                         \
5346 _(WANT_IP6_ND_EVENTS_REPLY, want_ip6_nd_events_reply)                   \
5347 _(IP6_ND_EVENT, ip6_nd_event)                                           \
5348 _(WANT_L2_MACS_EVENTS_REPLY, want_l2_macs_events_reply)                 \
5349 _(L2_MACS_EVENT, l2_macs_event)                                         \
5350 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
5351 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
5352 _(IP_DETAILS, ip_details)                                               \
5353 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
5354 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
5355 _(IPSEC_SPD_ENTRY_ADD_DEL_REPLY, ipsec_spd_entry_add_del_reply)         \
5356 _(IPSEC_SAD_ENTRY_ADD_DEL_REPLY, ipsec_sad_entry_add_del_reply)         \
5357 _(IPSEC_SA_DETAILS, ipsec_sa_details)                                   \
5358 _(IPSEC_TUNNEL_IF_ADD_DEL_REPLY, ipsec_tunnel_if_add_del_reply)         \
5359 _(IPSEC_TUNNEL_IF_SET_SA_REPLY, ipsec_tunnel_if_set_sa_reply)           \
5360 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
5361 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
5362 _(BD_IP_MAC_FLUSH_REPLY, bd_ip_mac_flush_reply)                         \
5363 _(BD_IP_MAC_DETAILS, bd_ip_mac_details)                                 \
5364 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
5365 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
5366 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
5367 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
5368 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
5369 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
5370 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
5371 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
5372 _(ONE_ADD_DEL_LOCATOR_SET_REPLY, one_add_del_locator_set_reply)         \
5373 _(ONE_ADD_DEL_LOCATOR_REPLY, one_add_del_locator_reply)                 \
5374 _(ONE_ADD_DEL_LOCAL_EID_REPLY, one_add_del_local_eid_reply)             \
5375 _(ONE_ADD_DEL_REMOTE_MAPPING_REPLY, one_add_del_remote_mapping_reply)   \
5376 _(ONE_ADD_DEL_ADJACENCY_REPLY, one_add_del_adjacency_reply)             \
5377 _(ONE_ADD_DEL_MAP_RESOLVER_REPLY, one_add_del_map_resolver_reply)       \
5378 _(ONE_ADD_DEL_MAP_SERVER_REPLY, one_add_del_map_server_reply)           \
5379 _(ONE_ENABLE_DISABLE_REPLY, one_enable_disable_reply)                   \
5380 _(ONE_MAP_REGISTER_ENABLE_DISABLE_REPLY,                                \
5381   one_map_register_enable_disable_reply)                                \
5382 _(ONE_MAP_REGISTER_SET_TTL_REPLY, one_map_register_set_ttl_reply)       \
5383 _(ONE_SET_TRANSPORT_PROTOCOL_REPLY, one_set_transport_protocol_reply)   \
5384 _(ONE_GET_TRANSPORT_PROTOCOL_REPLY, one_get_transport_protocol_reply)   \
5385 _(ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                            \
5386   one_map_register_fallback_threshold_reply)                            \
5387 _(ONE_RLOC_PROBE_ENABLE_DISABLE_REPLY,                                  \
5388   one_rloc_probe_enable_disable_reply)                                  \
5389 _(ONE_PITR_SET_LOCATOR_SET_REPLY, one_pitr_set_locator_set_reply)       \
5390 _(ONE_USE_PETR_REPLY, one_use_petr_reply)                               \
5391 _(ONE_MAP_REQUEST_MODE_REPLY, one_map_request_mode_reply)               \
5392 _(ONE_EID_TABLE_ADD_DEL_MAP_REPLY, one_eid_table_add_del_map_reply)     \
5393 _(ONE_LOCATOR_SET_DETAILS, one_locator_set_details)                     \
5394 _(ONE_LOCATOR_DETAILS, one_locator_details)                             \
5395 _(ONE_EID_TABLE_DETAILS, one_eid_table_details)                         \
5396 _(ONE_EID_TABLE_MAP_DETAILS, one_eid_table_map_details)                 \
5397 _(ONE_EID_TABLE_VNI_DETAILS, one_eid_table_vni_details)                 \
5398 _(ONE_MAP_RESOLVER_DETAILS, one_map_resolver_details)                   \
5399 _(ONE_MAP_SERVER_DETAILS, one_map_server_details)                       \
5400 _(ONE_ADJACENCIES_GET_REPLY, one_adjacencies_get_reply)                 \
5401 _(ONE_STATS_DETAILS, one_stats_details)                                 \
5402 _(ONE_STATS_FLUSH_REPLY, one_stats_flush_reply)                         \
5403 _(ONE_STATS_ENABLE_DISABLE_REPLY, one_stats_enable_disable_reply)       \
5404 _(SHOW_ONE_STATS_ENABLE_DISABLE_REPLY,                                  \
5405   show_one_stats_enable_disable_reply)                                  \
5406 _(ONE_ADD_DEL_NDP_ENTRY_REPLY, one_add_del_ndp_entry_reply)             \
5407 _(ONE_NDP_BD_GET_REPLY, one_ndp_bd_get_reply)                           \
5408 _(ONE_NDP_ENTRIES_GET_REPLY, one_ndp_entries_get_reply)                 \
5409 _(ONE_ADD_DEL_L2_ARP_ENTRY_REPLY, one_add_del_l2_arp_entry_reply)       \
5410 _(ONE_L2_ARP_BD_GET_REPLY, one_l2_arp_bd_get_reply)                     \
5411 _(ONE_L2_ARP_ENTRIES_GET_REPLY, one_l2_arp_entries_get_reply)           \
5412 _(ONE_ENABLE_DISABLE_XTR_MODE_REPLY, one_enable_disable_xtr_mode_reply) \
5413 _(ONE_ENABLE_DISABLE_PITR_MODE_REPLY,                                   \
5414   one_enable_disable_pitr_mode_reply)                                   \
5415 _(ONE_ENABLE_DISABLE_PETR_MODE_REPLY,                                   \
5416   one_enable_disable_petr_mode_reply)                                   \
5417 _(ONE_SHOW_XTR_MODE_REPLY, one_show_xtr_mode_reply)                     \
5418 _(ONE_SHOW_PITR_MODE_REPLY, one_show_pitr_mode_reply)                   \
5419 _(ONE_SHOW_PETR_MODE_REPLY, one_show_petr_mode_reply)                   \
5420 _(GPE_SET_ENCAP_MODE_REPLY, gpe_set_encap_mode_reply)                   \
5421 _(GPE_GET_ENCAP_MODE_REPLY, gpe_get_encap_mode_reply)                   \
5422 _(GPE_ADD_DEL_IFACE_REPLY, gpe_add_del_iface_reply)                     \
5423 _(GPE_ENABLE_DISABLE_REPLY, gpe_enable_disable_reply)                   \
5424 _(GPE_ADD_DEL_FWD_ENTRY_REPLY, gpe_add_del_fwd_entry_reply)             \
5425 _(GPE_FWD_ENTRY_VNIS_GET_REPLY, gpe_fwd_entry_vnis_get_reply)           \
5426 _(GPE_FWD_ENTRIES_GET_REPLY, gpe_fwd_entries_get_reply)                 \
5427 _(GPE_NATIVE_FWD_RPATHS_GET_REPLY, gpe_native_fwd_rpaths_get_reply)     \
5428 _(GPE_ADD_DEL_NATIVE_FWD_RPATH_REPLY,                                   \
5429   gpe_add_del_native_fwd_rpath_reply)                                   \
5430 _(GPE_FWD_ENTRY_PATH_DETAILS,                                           \
5431   gpe_fwd_entry_path_details)                                           \
5432 _(SHOW_ONE_STATUS_REPLY, show_one_status_reply)                         \
5433 _(ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                              \
5434   one_add_del_map_request_itr_rlocs_reply)                              \
5435 _(ONE_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                  \
5436   one_get_map_request_itr_rlocs_reply)                                  \
5437 _(SHOW_ONE_NSH_MAPPING_REPLY, show_one_nsh_mapping_reply)               \
5438 _(SHOW_ONE_PITR_REPLY, show_one_pitr_reply)                             \
5439 _(SHOW_ONE_USE_PETR_REPLY, show_one_use_petr_reply)                     \
5440 _(SHOW_ONE_MAP_REQUEST_MODE_REPLY, show_one_map_request_mode_reply)     \
5441 _(SHOW_ONE_RLOC_PROBE_STATE_REPLY, show_one_rloc_probe_state_reply)     \
5442 _(SHOW_ONE_MAP_REGISTER_STATE_REPLY,                                    \
5443   show_one_map_register_state_reply)                                    \
5444 _(SHOW_ONE_MAP_REGISTER_TTL_REPLY, show_one_map_register_ttl_reply)     \
5445 _(SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                       \
5446   show_one_map_register_fallback_threshold_reply)                       \
5447 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
5448 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
5449 _(AF_PACKET_DETAILS, af_packet_details)                                 \
5450 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
5451 _(POLICER_DETAILS, policer_details)                                     \
5452 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
5453 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
5454 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
5455 _(NETMAP_DELETE_REPLY, netmap_delete_reply)                             \
5456 _(MPLS_TUNNEL_DETAILS, mpls_tunnel_details)                             \
5457 _(MPLS_TABLE_DETAILS, mpls_table_details)                               \
5458 _(MPLS_ROUTE_DETAILS, mpls_route_details)                               \
5459 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
5460 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
5461 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
5462 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
5463 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
5464 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
5465 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
5466 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
5467 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
5468 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
5469 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
5470 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
5471 _(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
5472 _(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details)                 \
5473 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
5474 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
5475 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
5476 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
5477 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
5478  ip_source_and_port_range_check_add_del_reply)                          \
5479 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
5480  ip_source_and_port_range_check_interface_add_del_reply)                \
5481 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
5482 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
5483 _(SET_PUNT_REPLY, set_punt_reply)                                       \
5484 _(IP_TABLE_DETAILS, ip_table_details)                                   \
5485 _(IP_ROUTE_DETAILS, ip_route_details)                                   \
5486 _(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply)           \
5487 _(FEATURE_GSO_ENABLE_DISABLE_REPLY, feature_gso_enable_disable_reply)   \
5488 _(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply)       \
5489 _(SW_INTERFACE_ADD_DEL_MAC_ADDRESS_REPLY, sw_interface_add_del_mac_address_reply) \
5490 _(L2_XCONNECT_DETAILS, l2_xconnect_details)                             \
5491 _(HW_INTERFACE_SET_MTU_REPLY, hw_interface_set_mtu_reply)               \
5492 _(IP_NEIGHBOR_DETAILS, ip_neighbor_details)                             \
5493 _(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply)           \
5494 _(P2P_ETHERNET_ADD_REPLY, p2p_ethernet_add_reply)                       \
5495 _(P2P_ETHERNET_DEL_REPLY, p2p_ethernet_del_reply)                       \
5496 _(LLDP_CONFIG_REPLY, lldp_config_reply)                                 \
5497 _(SW_INTERFACE_SET_LLDP_REPLY, sw_interface_set_lldp_reply)             \
5498 _(TCP_CONFIGURE_SRC_ADDRESSES_REPLY, tcp_configure_src_addresses_reply) \
5499 _(APP_NAMESPACE_ADD_DEL_REPLY, app_namespace_add_del_reply)             \
5500 _(SESSION_RULE_ADD_DEL_REPLY, session_rule_add_del_reply)               \
5501 _(SESSION_RULES_DETAILS, session_rules_details)                         \
5502 _(IP_CONTAINER_PROXY_ADD_DEL_REPLY, ip_container_proxy_add_del_reply)   \
5503 _(OUTPUT_ACL_SET_INTERFACE_REPLY, output_acl_set_interface_reply)       \
5504 _(QOS_RECORD_ENABLE_DISABLE_REPLY, qos_record_enable_disable_reply)
5505
5506 #define foreach_standalone_reply_msg                                    \
5507 _(SW_INTERFACE_EVENT, sw_interface_event)
5508
5509 typedef struct
5510 {
5511   u8 *name;
5512   u32 value;
5513 } name_sort_t;
5514
5515 #define STR_VTR_OP_CASE(op)     \
5516     case L2_VTR_ ## op:         \
5517         return "" # op;
5518
5519 static const char *
5520 str_vtr_op (u32 vtr_op)
5521 {
5522   switch (vtr_op)
5523     {
5524       STR_VTR_OP_CASE (DISABLED);
5525       STR_VTR_OP_CASE (PUSH_1);
5526       STR_VTR_OP_CASE (PUSH_2);
5527       STR_VTR_OP_CASE (POP_1);
5528       STR_VTR_OP_CASE (POP_2);
5529       STR_VTR_OP_CASE (TRANSLATE_1_1);
5530       STR_VTR_OP_CASE (TRANSLATE_1_2);
5531       STR_VTR_OP_CASE (TRANSLATE_2_1);
5532       STR_VTR_OP_CASE (TRANSLATE_2_2);
5533     }
5534
5535   return "UNKNOWN";
5536 }
5537
5538 static int
5539 dump_sub_interface_table (vat_main_t * vam)
5540 {
5541   const sw_interface_subif_t *sub = NULL;
5542
5543   if (vam->json_output)
5544     {
5545       clib_warning
5546         ("JSON output supported only for VPE API calls and dump_stats_table");
5547       return -99;
5548     }
5549
5550   print (vam->ofp,
5551          "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
5552          "Interface", "sw_if_index",
5553          "sub id", "dot1ad", "tags", "outer id",
5554          "inner id", "exact", "default", "outer any", "inner any");
5555
5556   vec_foreach (sub, vam->sw_if_subif_table)
5557   {
5558     print (vam->ofp,
5559            "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
5560            sub->interface_name,
5561            sub->sw_if_index,
5562            sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
5563            sub->sub_number_of_tags, sub->sub_outer_vlan_id,
5564            sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
5565            sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
5566     if (sub->vtr_op != L2_VTR_DISABLED)
5567       {
5568         print (vam->ofp,
5569                "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
5570                "tag1: %d tag2: %d ]",
5571                str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
5572                sub->vtr_tag1, sub->vtr_tag2);
5573       }
5574   }
5575
5576   return 0;
5577 }
5578
5579 static int
5580 name_sort_cmp (void *a1, void *a2)
5581 {
5582   name_sort_t *n1 = a1;
5583   name_sort_t *n2 = a2;
5584
5585   return strcmp ((char *) n1->name, (char *) n2->name);
5586 }
5587
5588 static int
5589 dump_interface_table (vat_main_t * vam)
5590 {
5591   hash_pair_t *p;
5592   name_sort_t *nses = 0, *ns;
5593
5594   if (vam->json_output)
5595     {
5596       clib_warning
5597         ("JSON output supported only for VPE API calls and dump_stats_table");
5598       return -99;
5599     }
5600
5601   /* *INDENT-OFF* */
5602   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5603   ({
5604     vec_add2 (nses, ns, 1);
5605     ns->name = (u8 *)(p->key);
5606     ns->value = (u32) p->value[0];
5607   }));
5608   /* *INDENT-ON* */
5609
5610   vec_sort_with_function (nses, name_sort_cmp);
5611
5612   print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
5613   vec_foreach (ns, nses)
5614   {
5615     print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
5616   }
5617   vec_free (nses);
5618   return 0;
5619 }
5620
5621 static int
5622 dump_ip_table (vat_main_t * vam, int is_ipv6)
5623 {
5624   const ip_details_t *det = NULL;
5625   const ip_address_details_t *address = NULL;
5626   u32 i = ~0;
5627
5628   print (vam->ofp, "%-12s", "sw_if_index");
5629
5630   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
5631   {
5632     i++;
5633     if (!det->present)
5634       {
5635         continue;
5636       }
5637     print (vam->ofp, "%-12d", i);
5638     print (vam->ofp, "            %-30s%-13s", "Address", "Prefix length");
5639     if (!det->addr)
5640       {
5641         continue;
5642       }
5643     vec_foreach (address, det->addr)
5644     {
5645       print (vam->ofp,
5646              "            %-30U%-13d",
5647              is_ipv6 ? format_ip6_address : format_ip4_address,
5648              address->ip, address->prefix_length);
5649     }
5650   }
5651
5652   return 0;
5653 }
5654
5655 static int
5656 dump_ipv4_table (vat_main_t * vam)
5657 {
5658   if (vam->json_output)
5659     {
5660       clib_warning
5661         ("JSON output supported only for VPE API calls and dump_stats_table");
5662       return -99;
5663     }
5664
5665   return dump_ip_table (vam, 0);
5666 }
5667
5668 static int
5669 dump_ipv6_table (vat_main_t * vam)
5670 {
5671   if (vam->json_output)
5672     {
5673       clib_warning
5674         ("JSON output supported only for VPE API calls and dump_stats_table");
5675       return -99;
5676     }
5677
5678   return dump_ip_table (vam, 1);
5679 }
5680
5681 /*
5682  * Pass CLI buffers directly in the CLI_INBAND API message,
5683  * instead of an additional shared memory area.
5684  */
5685 static int
5686 exec_inband (vat_main_t * vam)
5687 {
5688   vl_api_cli_inband_t *mp;
5689   unformat_input_t *i = vam->input;
5690   int ret;
5691
5692   if (vec_len (i->buffer) == 0)
5693     return -1;
5694
5695   if (vam->exec_mode == 0 && unformat (i, "mode"))
5696     {
5697       vam->exec_mode = 1;
5698       return 0;
5699     }
5700   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
5701     {
5702       vam->exec_mode = 0;
5703       return 0;
5704     }
5705
5706   /*
5707    * In order for the CLI command to work, it
5708    * must be a vector ending in \n, not a C-string ending
5709    * in \n\0.
5710    */
5711   u32 len = vec_len (vam->input->buffer);
5712   M2 (CLI_INBAND, mp, len);
5713   vl_api_to_api_string (len - 1, (const char *) vam->input->buffer, &mp->cmd);
5714
5715   S (mp);
5716   W (ret);
5717   /* json responses may or may not include a useful reply... */
5718   if (vec_len (vam->cmd_reply))
5719     print (vam->ofp, "%v", (char *) (vam->cmd_reply));
5720   return ret;
5721 }
5722
5723 int
5724 exec (vat_main_t * vam)
5725 {
5726   return exec_inband (vam);
5727 }
5728
5729 static int
5730 api_create_loopback (vat_main_t * vam)
5731 {
5732   unformat_input_t *i = vam->input;
5733   vl_api_create_loopback_t *mp;
5734   vl_api_create_loopback_instance_t *mp_lbi;
5735   u8 mac_address[6];
5736   u8 mac_set = 0;
5737   u8 is_specified = 0;
5738   u32 user_instance = 0;
5739   int ret;
5740
5741   clib_memset (mac_address, 0, sizeof (mac_address));
5742
5743   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5744     {
5745       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5746         mac_set = 1;
5747       if (unformat (i, "instance %d", &user_instance))
5748         is_specified = 1;
5749       else
5750         break;
5751     }
5752
5753   if (is_specified)
5754     {
5755       M (CREATE_LOOPBACK_INSTANCE, mp_lbi);
5756       mp_lbi->is_specified = is_specified;
5757       if (is_specified)
5758         mp_lbi->user_instance = htonl (user_instance);
5759       if (mac_set)
5760         clib_memcpy (mp_lbi->mac_address, mac_address, sizeof (mac_address));
5761       S (mp_lbi);
5762     }
5763   else
5764     {
5765       /* Construct the API message */
5766       M (CREATE_LOOPBACK, mp);
5767       if (mac_set)
5768         clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
5769       S (mp);
5770     }
5771
5772   W (ret);
5773   return ret;
5774 }
5775
5776 static int
5777 api_delete_loopback (vat_main_t * vam)
5778 {
5779   unformat_input_t *i = vam->input;
5780   vl_api_delete_loopback_t *mp;
5781   u32 sw_if_index = ~0;
5782   int ret;
5783
5784   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5785     {
5786       if (unformat (i, "sw_if_index %d", &sw_if_index))
5787         ;
5788       else
5789         break;
5790     }
5791
5792   if (sw_if_index == ~0)
5793     {
5794       errmsg ("missing sw_if_index");
5795       return -99;
5796     }
5797
5798   /* Construct the API message */
5799   M (DELETE_LOOPBACK, mp);
5800   mp->sw_if_index = ntohl (sw_if_index);
5801
5802   S (mp);
5803   W (ret);
5804   return ret;
5805 }
5806
5807 static int
5808 api_want_interface_events (vat_main_t * vam)
5809 {
5810   unformat_input_t *i = vam->input;
5811   vl_api_want_interface_events_t *mp;
5812   int enable = -1;
5813   int ret;
5814
5815   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5816     {
5817       if (unformat (i, "enable"))
5818         enable = 1;
5819       else if (unformat (i, "disable"))
5820         enable = 0;
5821       else
5822         break;
5823     }
5824
5825   if (enable == -1)
5826     {
5827       errmsg ("missing enable|disable");
5828       return -99;
5829     }
5830
5831   M (WANT_INTERFACE_EVENTS, mp);
5832   mp->enable_disable = enable;
5833
5834   vam->interface_event_display = enable;
5835
5836   S (mp);
5837   W (ret);
5838   return ret;
5839 }
5840
5841
5842 /* Note: non-static, called once to set up the initial intfc table */
5843 int
5844 api_sw_interface_dump (vat_main_t * vam)
5845 {
5846   vl_api_sw_interface_dump_t *mp;
5847   vl_api_control_ping_t *mp_ping;
5848   hash_pair_t *p;
5849   name_sort_t *nses = 0, *ns;
5850   sw_interface_subif_t *sub = NULL;
5851   int ret;
5852
5853   /* Toss the old name table */
5854   /* *INDENT-OFF* */
5855   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5856   ({
5857     vec_add2 (nses, ns, 1);
5858     ns->name = (u8 *)(p->key);
5859     ns->value = (u32) p->value[0];
5860   }));
5861   /* *INDENT-ON* */
5862
5863   hash_free (vam->sw_if_index_by_interface_name);
5864
5865   vec_foreach (ns, nses) vec_free (ns->name);
5866
5867   vec_free (nses);
5868
5869   vec_foreach (sub, vam->sw_if_subif_table)
5870   {
5871     vec_free (sub->interface_name);
5872   }
5873   vec_free (vam->sw_if_subif_table);
5874
5875   /* recreate the interface name hash table */
5876   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
5877
5878   /*
5879    * Ask for all interface names. Otherwise, the epic catalog of
5880    * name filters becomes ridiculously long, and vat ends up needing
5881    * to be taught about new interface types.
5882    */
5883   M (SW_INTERFACE_DUMP, mp);
5884   S (mp);
5885
5886   /* Use a control ping for synchronization */
5887   MPING (CONTROL_PING, mp_ping);
5888   S (mp_ping);
5889
5890   W (ret);
5891   return ret;
5892 }
5893
5894 static int
5895 api_sw_interface_set_flags (vat_main_t * vam)
5896 {
5897   unformat_input_t *i = vam->input;
5898   vl_api_sw_interface_set_flags_t *mp;
5899   u32 sw_if_index;
5900   u8 sw_if_index_set = 0;
5901   u8 admin_up = 0;
5902   int ret;
5903
5904   /* Parse args required to build the message */
5905   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5906     {
5907       if (unformat (i, "admin-up"))
5908         admin_up = 1;
5909       else if (unformat (i, "admin-down"))
5910         admin_up = 0;
5911       else
5912         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5913         sw_if_index_set = 1;
5914       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5915         sw_if_index_set = 1;
5916       else
5917         break;
5918     }
5919
5920   if (sw_if_index_set == 0)
5921     {
5922       errmsg ("missing interface name or sw_if_index");
5923       return -99;
5924     }
5925
5926   /* Construct the API message */
5927   M (SW_INTERFACE_SET_FLAGS, mp);
5928   mp->sw_if_index = ntohl (sw_if_index);
5929   mp->flags = ntohl ((admin_up) ? IF_STATUS_API_FLAG_ADMIN_UP : 0);
5930
5931   /* send it... */
5932   S (mp);
5933
5934   /* Wait for a reply, return the good/bad news... */
5935   W (ret);
5936   return ret;
5937 }
5938
5939 static int
5940 api_sw_interface_set_rx_mode (vat_main_t * vam)
5941 {
5942   unformat_input_t *i = vam->input;
5943   vl_api_sw_interface_set_rx_mode_t *mp;
5944   u32 sw_if_index;
5945   u8 sw_if_index_set = 0;
5946   int ret;
5947   u8 queue_id_valid = 0;
5948   u32 queue_id;
5949   vnet_hw_interface_rx_mode mode = VNET_HW_INTERFACE_RX_MODE_UNKNOWN;
5950
5951   /* Parse args required to build the message */
5952   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5953     {
5954       if (unformat (i, "queue %d", &queue_id))
5955         queue_id_valid = 1;
5956       else if (unformat (i, "polling"))
5957         mode = VNET_HW_INTERFACE_RX_MODE_POLLING;
5958       else if (unformat (i, "interrupt"))
5959         mode = VNET_HW_INTERFACE_RX_MODE_INTERRUPT;
5960       else if (unformat (i, "adaptive"))
5961         mode = VNET_HW_INTERFACE_RX_MODE_ADAPTIVE;
5962       else
5963         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5964         sw_if_index_set = 1;
5965       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5966         sw_if_index_set = 1;
5967       else
5968         break;
5969     }
5970
5971   if (sw_if_index_set == 0)
5972     {
5973       errmsg ("missing interface name or sw_if_index");
5974       return -99;
5975     }
5976   if (mode == VNET_HW_INTERFACE_RX_MODE_UNKNOWN)
5977     {
5978       errmsg ("missing rx-mode");
5979       return -99;
5980     }
5981
5982   /* Construct the API message */
5983   M (SW_INTERFACE_SET_RX_MODE, mp);
5984   mp->sw_if_index = ntohl (sw_if_index);
5985   mp->mode = (vl_api_rx_mode_t) mode;
5986   mp->queue_id_valid = queue_id_valid;
5987   mp->queue_id = queue_id_valid ? ntohl (queue_id) : ~0;
5988
5989   /* send it... */
5990   S (mp);
5991
5992   /* Wait for a reply, return the good/bad news... */
5993   W (ret);
5994   return ret;
5995 }
5996
5997 static int
5998 api_sw_interface_set_rx_placement (vat_main_t * vam)
5999 {
6000   unformat_input_t *i = vam->input;
6001   vl_api_sw_interface_set_rx_placement_t *mp;
6002   u32 sw_if_index;
6003   u8 sw_if_index_set = 0;
6004   int ret;
6005   u8 is_main = 0;
6006   u32 queue_id, thread_index;
6007
6008   /* Parse args required to build the message */
6009   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6010     {
6011       if (unformat (i, "queue %d", &queue_id))
6012         ;
6013       else if (unformat (i, "main"))
6014         is_main = 1;
6015       else if (unformat (i, "worker %d", &thread_index))
6016         ;
6017       else
6018         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6019         sw_if_index_set = 1;
6020       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6021         sw_if_index_set = 1;
6022       else
6023         break;
6024     }
6025
6026   if (sw_if_index_set == 0)
6027     {
6028       errmsg ("missing interface name or sw_if_index");
6029       return -99;
6030     }
6031
6032   if (is_main)
6033     thread_index = 0;
6034   /* Construct the API message */
6035   M (SW_INTERFACE_SET_RX_PLACEMENT, mp);
6036   mp->sw_if_index = ntohl (sw_if_index);
6037   mp->worker_id = ntohl (thread_index);
6038   mp->queue_id = ntohl (queue_id);
6039   mp->is_main = is_main;
6040
6041   /* send it... */
6042   S (mp);
6043   /* Wait for a reply, return the good/bad news... */
6044   W (ret);
6045   return ret;
6046 }
6047
6048 static void vl_api_sw_interface_rx_placement_details_t_handler
6049   (vl_api_sw_interface_rx_placement_details_t * mp)
6050 {
6051   vat_main_t *vam = &vat_main;
6052   u32 worker_id = ntohl (mp->worker_id);
6053
6054   print (vam->ofp,
6055          "\n%-11d %-11s %-6d %-5d %-9s",
6056          ntohl (mp->sw_if_index), (worker_id == 0) ? "main" : "worker",
6057          worker_id, ntohl (mp->queue_id),
6058          (mp->mode ==
6059           1) ? "polling" : ((mp->mode == 2) ? "interrupt" : "adaptive"));
6060 }
6061
6062 static void vl_api_sw_interface_rx_placement_details_t_handler_json
6063   (vl_api_sw_interface_rx_placement_details_t * mp)
6064 {
6065   vat_main_t *vam = &vat_main;
6066   vat_json_node_t *node = NULL;
6067
6068   if (VAT_JSON_ARRAY != vam->json_tree.type)
6069     {
6070       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
6071       vat_json_init_array (&vam->json_tree);
6072     }
6073   node = vat_json_array_add (&vam->json_tree);
6074
6075   vat_json_init_object (node);
6076   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
6077   vat_json_object_add_uint (node, "worker_id", ntohl (mp->worker_id));
6078   vat_json_object_add_uint (node, "queue_id", ntohl (mp->queue_id));
6079   vat_json_object_add_uint (node, "mode", mp->mode);
6080 }
6081
6082 static int
6083 api_sw_interface_rx_placement_dump (vat_main_t * vam)
6084 {
6085   unformat_input_t *i = vam->input;
6086   vl_api_sw_interface_rx_placement_dump_t *mp;
6087   vl_api_control_ping_t *mp_ping;
6088   int ret;
6089   u32 sw_if_index;
6090   u8 sw_if_index_set = 0;
6091
6092   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6093     {
6094       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6095         sw_if_index_set++;
6096       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6097         sw_if_index_set++;
6098       else
6099         break;
6100     }
6101
6102   print (vam->ofp,
6103          "\n%-11s %-11s %-6s %-5s %-4s",
6104          "sw_if_index", "main/worker", "thread", "queue", "mode");
6105
6106   /* Dump Interface rx placement */
6107   M (SW_INTERFACE_RX_PLACEMENT_DUMP, mp);
6108
6109   if (sw_if_index_set)
6110     mp->sw_if_index = htonl (sw_if_index);
6111   else
6112     mp->sw_if_index = ~0;
6113
6114   S (mp);
6115
6116   /* Use a control ping for synchronization */
6117   MPING (CONTROL_PING, mp_ping);
6118   S (mp_ping);
6119
6120   W (ret);
6121   return ret;
6122 }
6123
6124 static int
6125 api_sw_interface_clear_stats (vat_main_t * vam)
6126 {
6127   unformat_input_t *i = vam->input;
6128   vl_api_sw_interface_clear_stats_t *mp;
6129   u32 sw_if_index;
6130   u8 sw_if_index_set = 0;
6131   int ret;
6132
6133   /* Parse args required to build the message */
6134   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6135     {
6136       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6137         sw_if_index_set = 1;
6138       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6139         sw_if_index_set = 1;
6140       else
6141         break;
6142     }
6143
6144   /* Construct the API message */
6145   M (SW_INTERFACE_CLEAR_STATS, mp);
6146
6147   if (sw_if_index_set == 1)
6148     mp->sw_if_index = ntohl (sw_if_index);
6149   else
6150     mp->sw_if_index = ~0;
6151
6152   /* send it... */
6153   S (mp);
6154
6155   /* Wait for a reply, return the good/bad news... */
6156   W (ret);
6157   return ret;
6158 }
6159
6160 static int
6161 api_sw_interface_add_del_address (vat_main_t * vam)
6162 {
6163   unformat_input_t *i = vam->input;
6164   vl_api_sw_interface_add_del_address_t *mp;
6165   u32 sw_if_index;
6166   u8 sw_if_index_set = 0;
6167   u8 is_add = 1, del_all = 0;
6168   u32 address_length = 0;
6169   u8 v4_address_set = 0;
6170   u8 v6_address_set = 0;
6171   ip4_address_t v4address;
6172   ip6_address_t v6address;
6173   int ret;
6174
6175   /* Parse args required to build the message */
6176   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6177     {
6178       if (unformat (i, "del-all"))
6179         del_all = 1;
6180       else if (unformat (i, "del"))
6181         is_add = 0;
6182       else
6183         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6184         sw_if_index_set = 1;
6185       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6186         sw_if_index_set = 1;
6187       else if (unformat (i, "%U/%d",
6188                          unformat_ip4_address, &v4address, &address_length))
6189         v4_address_set = 1;
6190       else if (unformat (i, "%U/%d",
6191                          unformat_ip6_address, &v6address, &address_length))
6192         v6_address_set = 1;
6193       else
6194         break;
6195     }
6196
6197   if (sw_if_index_set == 0)
6198     {
6199       errmsg ("missing interface name or sw_if_index");
6200       return -99;
6201     }
6202   if (v4_address_set && v6_address_set)
6203     {
6204       errmsg ("both v4 and v6 addresses set");
6205       return -99;
6206     }
6207   if (!v4_address_set && !v6_address_set && !del_all)
6208     {
6209       errmsg ("no addresses set");
6210       return -99;
6211     }
6212
6213   /* Construct the API message */
6214   M (SW_INTERFACE_ADD_DEL_ADDRESS, mp);
6215
6216   mp->sw_if_index = ntohl (sw_if_index);
6217   mp->is_add = is_add;
6218   mp->del_all = del_all;
6219   if (v6_address_set)
6220     {
6221       mp->prefix.address.af = ADDRESS_IP6;
6222       clib_memcpy (mp->prefix.address.un.ip6, &v6address, sizeof (v6address));
6223     }
6224   else
6225     {
6226       mp->prefix.address.af = ADDRESS_IP4;
6227       clib_memcpy (mp->prefix.address.un.ip4, &v4address, sizeof (v4address));
6228     }
6229   mp->prefix.len = address_length;
6230
6231   /* send it... */
6232   S (mp);
6233
6234   /* Wait for a reply, return good/bad news  */
6235   W (ret);
6236   return ret;
6237 }
6238
6239 static int
6240 api_sw_interface_set_mpls_enable (vat_main_t * vam)
6241 {
6242   unformat_input_t *i = vam->input;
6243   vl_api_sw_interface_set_mpls_enable_t *mp;
6244   u32 sw_if_index;
6245   u8 sw_if_index_set = 0;
6246   u8 enable = 1;
6247   int ret;
6248
6249   /* Parse args required to build the message */
6250   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6251     {
6252       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6253         sw_if_index_set = 1;
6254       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6255         sw_if_index_set = 1;
6256       else if (unformat (i, "disable"))
6257         enable = 0;
6258       else if (unformat (i, "dis"))
6259         enable = 0;
6260       else
6261         break;
6262     }
6263
6264   if (sw_if_index_set == 0)
6265     {
6266       errmsg ("missing interface name or sw_if_index");
6267       return -99;
6268     }
6269
6270   /* Construct the API message */
6271   M (SW_INTERFACE_SET_MPLS_ENABLE, mp);
6272
6273   mp->sw_if_index = ntohl (sw_if_index);
6274   mp->enable = enable;
6275
6276   /* send it... */
6277   S (mp);
6278
6279   /* Wait for a reply... */
6280   W (ret);
6281   return ret;
6282 }
6283
6284 static int
6285 api_sw_interface_set_table (vat_main_t * vam)
6286 {
6287   unformat_input_t *i = vam->input;
6288   vl_api_sw_interface_set_table_t *mp;
6289   u32 sw_if_index, vrf_id = 0;
6290   u8 sw_if_index_set = 0;
6291   u8 is_ipv6 = 0;
6292   int ret;
6293
6294   /* Parse args required to build the message */
6295   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6296     {
6297       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6298         sw_if_index_set = 1;
6299       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6300         sw_if_index_set = 1;
6301       else if (unformat (i, "vrf %d", &vrf_id))
6302         ;
6303       else if (unformat (i, "ipv6"))
6304         is_ipv6 = 1;
6305       else
6306         break;
6307     }
6308
6309   if (sw_if_index_set == 0)
6310     {
6311       errmsg ("missing interface name or sw_if_index");
6312       return -99;
6313     }
6314
6315   /* Construct the API message */
6316   M (SW_INTERFACE_SET_TABLE, mp);
6317
6318   mp->sw_if_index = ntohl (sw_if_index);
6319   mp->is_ipv6 = is_ipv6;
6320   mp->vrf_id = ntohl (vrf_id);
6321
6322   /* send it... */
6323   S (mp);
6324
6325   /* Wait for a reply... */
6326   W (ret);
6327   return ret;
6328 }
6329
6330 static void vl_api_sw_interface_get_table_reply_t_handler
6331   (vl_api_sw_interface_get_table_reply_t * mp)
6332 {
6333   vat_main_t *vam = &vat_main;
6334
6335   print (vam->ofp, "%d", ntohl (mp->vrf_id));
6336
6337   vam->retval = ntohl (mp->retval);
6338   vam->result_ready = 1;
6339
6340 }
6341
6342 static void vl_api_sw_interface_get_table_reply_t_handler_json
6343   (vl_api_sw_interface_get_table_reply_t * mp)
6344 {
6345   vat_main_t *vam = &vat_main;
6346   vat_json_node_t node;
6347
6348   vat_json_init_object (&node);
6349   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
6350   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
6351
6352   vat_json_print (vam->ofp, &node);
6353   vat_json_free (&node);
6354
6355   vam->retval = ntohl (mp->retval);
6356   vam->result_ready = 1;
6357 }
6358
6359 static int
6360 api_sw_interface_get_table (vat_main_t * vam)
6361 {
6362   unformat_input_t *i = vam->input;
6363   vl_api_sw_interface_get_table_t *mp;
6364   u32 sw_if_index;
6365   u8 sw_if_index_set = 0;
6366   u8 is_ipv6 = 0;
6367   int ret;
6368
6369   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6370     {
6371       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6372         sw_if_index_set = 1;
6373       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6374         sw_if_index_set = 1;
6375       else if (unformat (i, "ipv6"))
6376         is_ipv6 = 1;
6377       else
6378         break;
6379     }
6380
6381   if (sw_if_index_set == 0)
6382     {
6383       errmsg ("missing interface name or sw_if_index");
6384       return -99;
6385     }
6386
6387   M (SW_INTERFACE_GET_TABLE, mp);
6388   mp->sw_if_index = htonl (sw_if_index);
6389   mp->is_ipv6 = is_ipv6;
6390
6391   S (mp);
6392   W (ret);
6393   return ret;
6394 }
6395
6396 static int
6397 api_sw_interface_set_vpath (vat_main_t * vam)
6398 {
6399   unformat_input_t *i = vam->input;
6400   vl_api_sw_interface_set_vpath_t *mp;
6401   u32 sw_if_index = 0;
6402   u8 sw_if_index_set = 0;
6403   u8 is_enable = 0;
6404   int ret;
6405
6406   /* Parse args required to build the message */
6407   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6408     {
6409       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6410         sw_if_index_set = 1;
6411       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6412         sw_if_index_set = 1;
6413       else if (unformat (i, "enable"))
6414         is_enable = 1;
6415       else if (unformat (i, "disable"))
6416         is_enable = 0;
6417       else
6418         break;
6419     }
6420
6421   if (sw_if_index_set == 0)
6422     {
6423       errmsg ("missing interface name or sw_if_index");
6424       return -99;
6425     }
6426
6427   /* Construct the API message */
6428   M (SW_INTERFACE_SET_VPATH, mp);
6429
6430   mp->sw_if_index = ntohl (sw_if_index);
6431   mp->enable = is_enable;
6432
6433   /* send it... */
6434   S (mp);
6435
6436   /* Wait for a reply... */
6437   W (ret);
6438   return ret;
6439 }
6440
6441 static int
6442 api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
6443 {
6444   unformat_input_t *i = vam->input;
6445   vl_api_sw_interface_set_vxlan_bypass_t *mp;
6446   u32 sw_if_index = 0;
6447   u8 sw_if_index_set = 0;
6448   u8 is_enable = 1;
6449   u8 is_ipv6 = 0;
6450   int ret;
6451
6452   /* Parse args required to build the message */
6453   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6454     {
6455       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6456         sw_if_index_set = 1;
6457       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6458         sw_if_index_set = 1;
6459       else if (unformat (i, "enable"))
6460         is_enable = 1;
6461       else if (unformat (i, "disable"))
6462         is_enable = 0;
6463       else if (unformat (i, "ip4"))
6464         is_ipv6 = 0;
6465       else if (unformat (i, "ip6"))
6466         is_ipv6 = 1;
6467       else
6468         break;
6469     }
6470
6471   if (sw_if_index_set == 0)
6472     {
6473       errmsg ("missing interface name or sw_if_index");
6474       return -99;
6475     }
6476
6477   /* Construct the API message */
6478   M (SW_INTERFACE_SET_VXLAN_BYPASS, mp);
6479
6480   mp->sw_if_index = ntohl (sw_if_index);
6481   mp->enable = is_enable;
6482   mp->is_ipv6 = is_ipv6;
6483
6484   /* send it... */
6485   S (mp);
6486
6487   /* Wait for a reply... */
6488   W (ret);
6489   return ret;
6490 }
6491
6492 static int
6493 api_sw_interface_set_geneve_bypass (vat_main_t * vam)
6494 {
6495   unformat_input_t *i = vam->input;
6496   vl_api_sw_interface_set_geneve_bypass_t *mp;
6497   u32 sw_if_index = 0;
6498   u8 sw_if_index_set = 0;
6499   u8 is_enable = 1;
6500   u8 is_ipv6 = 0;
6501   int ret;
6502
6503   /* Parse args required to build the message */
6504   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6505     {
6506       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6507         sw_if_index_set = 1;
6508       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6509         sw_if_index_set = 1;
6510       else if (unformat (i, "enable"))
6511         is_enable = 1;
6512       else if (unformat (i, "disable"))
6513         is_enable = 0;
6514       else if (unformat (i, "ip4"))
6515         is_ipv6 = 0;
6516       else if (unformat (i, "ip6"))
6517         is_ipv6 = 1;
6518       else
6519         break;
6520     }
6521
6522   if (sw_if_index_set == 0)
6523     {
6524       errmsg ("missing interface name or sw_if_index");
6525       return -99;
6526     }
6527
6528   /* Construct the API message */
6529   M (SW_INTERFACE_SET_GENEVE_BYPASS, mp);
6530
6531   mp->sw_if_index = ntohl (sw_if_index);
6532   mp->enable = is_enable;
6533   mp->is_ipv6 = is_ipv6;
6534
6535   /* send it... */
6536   S (mp);
6537
6538   /* Wait for a reply... */
6539   W (ret);
6540   return ret;
6541 }
6542
6543 static int
6544 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
6545 {
6546   unformat_input_t *i = vam->input;
6547   vl_api_sw_interface_set_l2_xconnect_t *mp;
6548   u32 rx_sw_if_index;
6549   u8 rx_sw_if_index_set = 0;
6550   u32 tx_sw_if_index;
6551   u8 tx_sw_if_index_set = 0;
6552   u8 enable = 1;
6553   int ret;
6554
6555   /* Parse args required to build the message */
6556   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6557     {
6558       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
6559         rx_sw_if_index_set = 1;
6560       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
6561         tx_sw_if_index_set = 1;
6562       else if (unformat (i, "rx"))
6563         {
6564           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6565             {
6566               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6567                             &rx_sw_if_index))
6568                 rx_sw_if_index_set = 1;
6569             }
6570           else
6571             break;
6572         }
6573       else if (unformat (i, "tx"))
6574         {
6575           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6576             {
6577               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6578                             &tx_sw_if_index))
6579                 tx_sw_if_index_set = 1;
6580             }
6581           else
6582             break;
6583         }
6584       else if (unformat (i, "enable"))
6585         enable = 1;
6586       else if (unformat (i, "disable"))
6587         enable = 0;
6588       else
6589         break;
6590     }
6591
6592   if (rx_sw_if_index_set == 0)
6593     {
6594       errmsg ("missing rx interface name or rx_sw_if_index");
6595       return -99;
6596     }
6597
6598   if (enable && (tx_sw_if_index_set == 0))
6599     {
6600       errmsg ("missing tx interface name or tx_sw_if_index");
6601       return -99;
6602     }
6603
6604   M (SW_INTERFACE_SET_L2_XCONNECT, mp);
6605
6606   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6607   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
6608   mp->enable = enable;
6609
6610   S (mp);
6611   W (ret);
6612   return ret;
6613 }
6614
6615 static int
6616 api_sw_interface_set_l2_bridge (vat_main_t * vam)
6617 {
6618   unformat_input_t *i = vam->input;
6619   vl_api_sw_interface_set_l2_bridge_t *mp;
6620   vl_api_l2_port_type_t port_type;
6621   u32 rx_sw_if_index;
6622   u8 rx_sw_if_index_set = 0;
6623   u32 bd_id;
6624   u8 bd_id_set = 0;
6625   u32 shg = 0;
6626   u8 enable = 1;
6627   int ret;
6628
6629   port_type = L2_API_PORT_TYPE_NORMAL;
6630
6631   /* Parse args required to build the message */
6632   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6633     {
6634       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
6635         rx_sw_if_index_set = 1;
6636       else if (unformat (i, "bd_id %d", &bd_id))
6637         bd_id_set = 1;
6638       else
6639         if (unformat
6640             (i, "%U", api_unformat_sw_if_index, vam, &rx_sw_if_index))
6641         rx_sw_if_index_set = 1;
6642       else if (unformat (i, "shg %d", &shg))
6643         ;
6644       else if (unformat (i, "bvi"))
6645         port_type = L2_API_PORT_TYPE_BVI;
6646       else if (unformat (i, "uu-fwd"))
6647         port_type = L2_API_PORT_TYPE_UU_FWD;
6648       else if (unformat (i, "enable"))
6649         enable = 1;
6650       else if (unformat (i, "disable"))
6651         enable = 0;
6652       else
6653         break;
6654     }
6655
6656   if (rx_sw_if_index_set == 0)
6657     {
6658       errmsg ("missing rx interface name or sw_if_index");
6659       return -99;
6660     }
6661
6662   if (enable && (bd_id_set == 0))
6663     {
6664       errmsg ("missing bridge domain");
6665       return -99;
6666     }
6667
6668   M (SW_INTERFACE_SET_L2_BRIDGE, mp);
6669
6670   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6671   mp->bd_id = ntohl (bd_id);
6672   mp->shg = (u8) shg;
6673   mp->port_type = ntohl (port_type);
6674   mp->enable = enable;
6675
6676   S (mp);
6677   W (ret);
6678   return ret;
6679 }
6680
6681 static int
6682 api_bridge_domain_dump (vat_main_t * vam)
6683 {
6684   unformat_input_t *i = vam->input;
6685   vl_api_bridge_domain_dump_t *mp;
6686   vl_api_control_ping_t *mp_ping;
6687   u32 bd_id = ~0;
6688   int ret;
6689
6690   /* Parse args required to build the message */
6691   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6692     {
6693       if (unformat (i, "bd_id %d", &bd_id))
6694         ;
6695       else
6696         break;
6697     }
6698
6699   M (BRIDGE_DOMAIN_DUMP, mp);
6700   mp->bd_id = ntohl (bd_id);
6701   S (mp);
6702
6703   /* Use a control ping for synchronization */
6704   MPING (CONTROL_PING, mp_ping);
6705   S (mp_ping);
6706
6707   W (ret);
6708   return ret;
6709 }
6710
6711 static int
6712 api_bridge_domain_add_del (vat_main_t * vam)
6713 {
6714   unformat_input_t *i = vam->input;
6715   vl_api_bridge_domain_add_del_t *mp;
6716   u32 bd_id = ~0;
6717   u8 is_add = 1;
6718   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
6719   u8 *bd_tag = NULL;
6720   u32 mac_age = 0;
6721   int ret;
6722
6723   /* Parse args required to build the message */
6724   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6725     {
6726       if (unformat (i, "bd_id %d", &bd_id))
6727         ;
6728       else if (unformat (i, "flood %d", &flood))
6729         ;
6730       else if (unformat (i, "uu-flood %d", &uu_flood))
6731         ;
6732       else if (unformat (i, "forward %d", &forward))
6733         ;
6734       else if (unformat (i, "learn %d", &learn))
6735         ;
6736       else if (unformat (i, "arp-term %d", &arp_term))
6737         ;
6738       else if (unformat (i, "mac-age %d", &mac_age))
6739         ;
6740       else if (unformat (i, "bd-tag %s", &bd_tag))
6741         ;
6742       else if (unformat (i, "del"))
6743         {
6744           is_add = 0;
6745           flood = uu_flood = forward = learn = 0;
6746         }
6747       else
6748         break;
6749     }
6750
6751   if (bd_id == ~0)
6752     {
6753       errmsg ("missing bridge domain");
6754       ret = -99;
6755       goto done;
6756     }
6757
6758   if (mac_age > 255)
6759     {
6760       errmsg ("mac age must be less than 256 ");
6761       ret = -99;
6762       goto done;
6763     }
6764
6765   if ((bd_tag) && (vec_len (bd_tag) > 63))
6766     {
6767       errmsg ("bd-tag cannot be longer than 63");
6768       ret = -99;
6769       goto done;
6770     }
6771
6772   M (BRIDGE_DOMAIN_ADD_DEL, mp);
6773
6774   mp->bd_id = ntohl (bd_id);
6775   mp->flood = flood;
6776   mp->uu_flood = uu_flood;
6777   mp->forward = forward;
6778   mp->learn = learn;
6779   mp->arp_term = arp_term;
6780   mp->is_add = is_add;
6781   mp->mac_age = (u8) mac_age;
6782   if (bd_tag)
6783     {
6784       clib_memcpy (mp->bd_tag, bd_tag, vec_len (bd_tag));
6785       mp->bd_tag[vec_len (bd_tag)] = 0;
6786     }
6787   S (mp);
6788   W (ret);
6789
6790 done:
6791   vec_free (bd_tag);
6792   return ret;
6793 }
6794
6795 static int
6796 api_l2fib_flush_bd (vat_main_t * vam)
6797 {
6798   unformat_input_t *i = vam->input;
6799   vl_api_l2fib_flush_bd_t *mp;
6800   u32 bd_id = ~0;
6801   int ret;
6802
6803   /* Parse args required to build the message */
6804   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6805     {
6806       if (unformat (i, "bd_id %d", &bd_id));
6807       else
6808         break;
6809     }
6810
6811   if (bd_id == ~0)
6812     {
6813       errmsg ("missing bridge domain");
6814       return -99;
6815     }
6816
6817   M (L2FIB_FLUSH_BD, mp);
6818
6819   mp->bd_id = htonl (bd_id);
6820
6821   S (mp);
6822   W (ret);
6823   return ret;
6824 }
6825
6826 static int
6827 api_l2fib_flush_int (vat_main_t * vam)
6828 {
6829   unformat_input_t *i = vam->input;
6830   vl_api_l2fib_flush_int_t *mp;
6831   u32 sw_if_index = ~0;
6832   int ret;
6833
6834   /* Parse args required to build the message */
6835   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6836     {
6837       if (unformat (i, "sw_if_index %d", &sw_if_index));
6838       else
6839         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index));
6840       else
6841         break;
6842     }
6843
6844   if (sw_if_index == ~0)
6845     {
6846       errmsg ("missing interface name or sw_if_index");
6847       return -99;
6848     }
6849
6850   M (L2FIB_FLUSH_INT, mp);
6851
6852   mp->sw_if_index = ntohl (sw_if_index);
6853
6854   S (mp);
6855   W (ret);
6856   return ret;
6857 }
6858
6859 static int
6860 api_l2fib_add_del (vat_main_t * vam)
6861 {
6862   unformat_input_t *i = vam->input;
6863   vl_api_l2fib_add_del_t *mp;
6864   f64 timeout;
6865   u8 mac[6] = { 0 };
6866   u8 mac_set = 0;
6867   u32 bd_id;
6868   u8 bd_id_set = 0;
6869   u32 sw_if_index = 0;
6870   u8 sw_if_index_set = 0;
6871   u8 is_add = 1;
6872   u8 static_mac = 0;
6873   u8 filter_mac = 0;
6874   u8 bvi_mac = 0;
6875   int count = 1;
6876   f64 before = 0;
6877   int j;
6878
6879   /* Parse args required to build the message */
6880   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6881     {
6882       if (unformat (i, "mac %U", unformat_ethernet_address, mac))
6883         mac_set = 1;
6884       else if (unformat (i, "bd_id %d", &bd_id))
6885         bd_id_set = 1;
6886       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6887         sw_if_index_set = 1;
6888       else if (unformat (i, "sw_if"))
6889         {
6890           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6891             {
6892               if (unformat
6893                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6894                 sw_if_index_set = 1;
6895             }
6896           else
6897             break;
6898         }
6899       else if (unformat (i, "static"))
6900         static_mac = 1;
6901       else if (unformat (i, "filter"))
6902         {
6903           filter_mac = 1;
6904           static_mac = 1;
6905         }
6906       else if (unformat (i, "bvi"))
6907         {
6908           bvi_mac = 1;
6909           static_mac = 1;
6910         }
6911       else if (unformat (i, "del"))
6912         is_add = 0;
6913       else if (unformat (i, "count %d", &count))
6914         ;
6915       else
6916         break;
6917     }
6918
6919   if (mac_set == 0)
6920     {
6921       errmsg ("missing mac address");
6922       return -99;
6923     }
6924
6925   if (bd_id_set == 0)
6926     {
6927       errmsg ("missing bridge domain");
6928       return -99;
6929     }
6930
6931   if (is_add && sw_if_index_set == 0 && filter_mac == 0)
6932     {
6933       errmsg ("missing interface name or sw_if_index");
6934       return -99;
6935     }
6936
6937   if (count > 1)
6938     {
6939       /* Turn on async mode */
6940       vam->async_mode = 1;
6941       vam->async_errors = 0;
6942       before = vat_time_now (vam);
6943     }
6944
6945   for (j = 0; j < count; j++)
6946     {
6947       M (L2FIB_ADD_DEL, mp);
6948
6949       clib_memcpy (mp->mac, mac, 6);
6950       mp->bd_id = ntohl (bd_id);
6951       mp->is_add = is_add;
6952       mp->sw_if_index = ntohl (sw_if_index);
6953
6954       if (is_add)
6955         {
6956           mp->static_mac = static_mac;
6957           mp->filter_mac = filter_mac;
6958           mp->bvi_mac = bvi_mac;
6959         }
6960       increment_mac_address (mac);
6961       /* send it... */
6962       S (mp);
6963     }
6964
6965   if (count > 1)
6966     {
6967       vl_api_control_ping_t *mp_ping;
6968       f64 after;
6969
6970       /* Shut off async mode */
6971       vam->async_mode = 0;
6972
6973       MPING (CONTROL_PING, mp_ping);
6974       S (mp_ping);
6975
6976       timeout = vat_time_now (vam) + 1.0;
6977       while (vat_time_now (vam) < timeout)
6978         if (vam->result_ready == 1)
6979           goto out;
6980       vam->retval = -99;
6981
6982     out:
6983       if (vam->retval == -99)
6984         errmsg ("timeout");
6985
6986       if (vam->async_errors > 0)
6987         {
6988           errmsg ("%d asynchronous errors", vam->async_errors);
6989           vam->retval = -98;
6990         }
6991       vam->async_errors = 0;
6992       after = vat_time_now (vam);
6993
6994       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
6995              count, after - before, count / (after - before));
6996     }
6997   else
6998     {
6999       int ret;
7000
7001       /* Wait for a reply... */
7002       W (ret);
7003       return ret;
7004     }
7005   /* Return the good/bad news */
7006   return (vam->retval);
7007 }
7008
7009 static int
7010 api_bridge_domain_set_mac_age (vat_main_t * vam)
7011 {
7012   unformat_input_t *i = vam->input;
7013   vl_api_bridge_domain_set_mac_age_t *mp;
7014   u32 bd_id = ~0;
7015   u32 mac_age = 0;
7016   int ret;
7017
7018   /* Parse args required to build the message */
7019   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7020     {
7021       if (unformat (i, "bd_id %d", &bd_id));
7022       else if (unformat (i, "mac-age %d", &mac_age));
7023       else
7024         break;
7025     }
7026
7027   if (bd_id == ~0)
7028     {
7029       errmsg ("missing bridge domain");
7030       return -99;
7031     }
7032
7033   if (mac_age > 255)
7034     {
7035       errmsg ("mac age must be less than 256 ");
7036       return -99;
7037     }
7038
7039   M (BRIDGE_DOMAIN_SET_MAC_AGE, mp);
7040
7041   mp->bd_id = htonl (bd_id);
7042   mp->mac_age = (u8) mac_age;
7043
7044   S (mp);
7045   W (ret);
7046   return ret;
7047 }
7048
7049 static int
7050 api_l2_flags (vat_main_t * vam)
7051 {
7052   unformat_input_t *i = vam->input;
7053   vl_api_l2_flags_t *mp;
7054   u32 sw_if_index;
7055   u32 flags = 0;
7056   u8 sw_if_index_set = 0;
7057   u8 is_set = 0;
7058   int ret;
7059
7060   /* Parse args required to build the message */
7061   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7062     {
7063       if (unformat (i, "sw_if_index %d", &sw_if_index))
7064         sw_if_index_set = 1;
7065       else if (unformat (i, "sw_if"))
7066         {
7067           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7068             {
7069               if (unformat
7070                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7071                 sw_if_index_set = 1;
7072             }
7073           else
7074             break;
7075         }
7076       else if (unformat (i, "learn"))
7077         flags |= L2_LEARN;
7078       else if (unformat (i, "forward"))
7079         flags |= L2_FWD;
7080       else if (unformat (i, "flood"))
7081         flags |= L2_FLOOD;
7082       else if (unformat (i, "uu-flood"))
7083         flags |= L2_UU_FLOOD;
7084       else if (unformat (i, "arp-term"))
7085         flags |= L2_ARP_TERM;
7086       else if (unformat (i, "off"))
7087         is_set = 0;
7088       else if (unformat (i, "disable"))
7089         is_set = 0;
7090       else
7091         break;
7092     }
7093
7094   if (sw_if_index_set == 0)
7095     {
7096       errmsg ("missing interface name or sw_if_index");
7097       return -99;
7098     }
7099
7100   M (L2_FLAGS, mp);
7101
7102   mp->sw_if_index = ntohl (sw_if_index);
7103   mp->feature_bitmap = ntohl (flags);
7104   mp->is_set = is_set;
7105
7106   S (mp);
7107   W (ret);
7108   return ret;
7109 }
7110
7111 static int
7112 api_bridge_flags (vat_main_t * vam)
7113 {
7114   unformat_input_t *i = vam->input;
7115   vl_api_bridge_flags_t *mp;
7116   u32 bd_id;
7117   u8 bd_id_set = 0;
7118   u8 is_set = 1;
7119   bd_flags_t flags = 0;
7120   int ret;
7121
7122   /* Parse args required to build the message */
7123   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7124     {
7125       if (unformat (i, "bd_id %d", &bd_id))
7126         bd_id_set = 1;
7127       else if (unformat (i, "learn"))
7128         flags |= BRIDGE_API_FLAG_LEARN;
7129       else if (unformat (i, "forward"))
7130         flags |= BRIDGE_API_FLAG_FWD;
7131       else if (unformat (i, "flood"))
7132         flags |= BRIDGE_API_FLAG_FLOOD;
7133       else if (unformat (i, "uu-flood"))
7134         flags |= BRIDGE_API_FLAG_UU_FLOOD;
7135       else if (unformat (i, "arp-term"))
7136         flags |= BRIDGE_API_FLAG_ARP_TERM;
7137       else if (unformat (i, "off"))
7138         is_set = 0;
7139       else if (unformat (i, "disable"))
7140         is_set = 0;
7141       else
7142         break;
7143     }
7144
7145   if (bd_id_set == 0)
7146     {
7147       errmsg ("missing bridge domain");
7148       return -99;
7149     }
7150
7151   M (BRIDGE_FLAGS, mp);
7152
7153   mp->bd_id = ntohl (bd_id);
7154   mp->flags = ntohl (flags);
7155   mp->is_set = is_set;
7156
7157   S (mp);
7158   W (ret);
7159   return ret;
7160 }
7161
7162 static int
7163 api_bd_ip_mac_add_del (vat_main_t * vam)
7164 {
7165   vl_api_address_t ip = VL_API_ZERO_ADDRESS;
7166   vl_api_mac_address_t mac = { 0 };
7167   unformat_input_t *i = vam->input;
7168   vl_api_bd_ip_mac_add_del_t *mp;
7169   u32 bd_id;
7170   u8 is_add = 1;
7171   u8 bd_id_set = 0;
7172   u8 ip_set = 0;
7173   u8 mac_set = 0;
7174   int ret;
7175
7176
7177   /* Parse args required to build the message */
7178   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7179     {
7180       if (unformat (i, "bd_id %d", &bd_id))
7181         {
7182           bd_id_set++;
7183         }
7184       else if (unformat (i, "%U", unformat_vl_api_address, &ip))
7185         {
7186           ip_set++;
7187         }
7188       else if (unformat (i, "%U", unformat_vl_api_mac_address, &mac))
7189         {
7190           mac_set++;
7191         }
7192       else if (unformat (i, "del"))
7193         is_add = 0;
7194       else
7195         break;
7196     }
7197
7198   if (bd_id_set == 0)
7199     {
7200       errmsg ("missing bridge domain");
7201       return -99;
7202     }
7203   else if (ip_set == 0)
7204     {
7205       errmsg ("missing IP address");
7206       return -99;
7207     }
7208   else if (mac_set == 0)
7209     {
7210       errmsg ("missing MAC address");
7211       return -99;
7212     }
7213
7214   M (BD_IP_MAC_ADD_DEL, mp);
7215
7216   mp->entry.bd_id = ntohl (bd_id);
7217   mp->is_add = is_add;
7218
7219   clib_memcpy (&mp->entry.ip, &ip, sizeof (ip));
7220   clib_memcpy (&mp->entry.mac, &mac, sizeof (mac));
7221
7222   S (mp);
7223   W (ret);
7224   return ret;
7225 }
7226
7227 static int
7228 api_bd_ip_mac_flush (vat_main_t * vam)
7229 {
7230   unformat_input_t *i = vam->input;
7231   vl_api_bd_ip_mac_flush_t *mp;
7232   u32 bd_id;
7233   u8 bd_id_set = 0;
7234   int ret;
7235
7236   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7237     {
7238       if (unformat (i, "bd_id %d", &bd_id))
7239         {
7240           bd_id_set++;
7241         }
7242       else
7243         break;
7244     }
7245
7246   if (bd_id_set == 0)
7247     {
7248       errmsg ("missing bridge domain");
7249       return -99;
7250     }
7251
7252   M (BD_IP_MAC_FLUSH, mp);
7253
7254   mp->bd_id = ntohl (bd_id);
7255
7256   S (mp);
7257   W (ret);
7258   return ret;
7259 }
7260
7261 static void vl_api_bd_ip_mac_details_t_handler
7262   (vl_api_bd_ip_mac_details_t * mp)
7263 {
7264   vat_main_t *vam = &vat_main;
7265
7266   print (vam->ofp,
7267          "\n%-5d %U %U",
7268          ntohl (mp->entry.bd_id),
7269          format_vl_api_mac_address, mp->entry.mac,
7270          format_vl_api_address, &mp->entry.ip);
7271 }
7272
7273 static void vl_api_bd_ip_mac_details_t_handler_json
7274   (vl_api_bd_ip_mac_details_t * mp)
7275 {
7276   vat_main_t *vam = &vat_main;
7277   vat_json_node_t *node = NULL;
7278
7279   if (VAT_JSON_ARRAY != vam->json_tree.type)
7280     {
7281       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
7282       vat_json_init_array (&vam->json_tree);
7283     }
7284   node = vat_json_array_add (&vam->json_tree);
7285
7286   vat_json_init_object (node);
7287   vat_json_object_add_uint (node, "bd_id", ntohl (mp->entry.bd_id));
7288   vat_json_object_add_string_copy (node, "mac_address",
7289                                    format (0, "%U", format_vl_api_mac_address,
7290                                            &mp->entry.mac));
7291   u8 *ip = 0;
7292
7293   ip = format (0, "%U", format_vl_api_address, &mp->entry.ip);
7294   vat_json_object_add_string_copy (node, "ip_address", ip);
7295   vec_free (ip);
7296 }
7297
7298 static int
7299 api_bd_ip_mac_dump (vat_main_t * vam)
7300 {
7301   unformat_input_t *i = vam->input;
7302   vl_api_bd_ip_mac_dump_t *mp;
7303   vl_api_control_ping_t *mp_ping;
7304   int ret;
7305   u32 bd_id;
7306   u8 bd_id_set = 0;
7307
7308   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7309     {
7310       if (unformat (i, "bd_id %d", &bd_id))
7311         {
7312           bd_id_set++;
7313         }
7314       else
7315         break;
7316     }
7317
7318   print (vam->ofp,
7319          "\n%-5s %-7s %-20s %-30s",
7320          "bd_id", "is_ipv6", "mac_address", "ip_address");
7321
7322   /* Dump Bridge Domain Ip to Mac entries */
7323   M (BD_IP_MAC_DUMP, mp);
7324
7325   if (bd_id_set)
7326     mp->bd_id = htonl (bd_id);
7327   else
7328     mp->bd_id = ~0;
7329
7330   S (mp);
7331
7332   /* Use a control ping for synchronization */
7333   MPING (CONTROL_PING, mp_ping);
7334   S (mp_ping);
7335
7336   W (ret);
7337   return ret;
7338 }
7339
7340 static int
7341 api_tap_create_v2 (vat_main_t * vam)
7342 {
7343   unformat_input_t *i = vam->input;
7344   vl_api_tap_create_v2_t *mp;
7345 #define TAP_FLAG_GSO (1 << 0)
7346   u8 mac_address[6];
7347   u8 random_mac = 1;
7348   u32 id = ~0;
7349   u8 *host_if_name = 0;
7350   u8 *host_ns = 0;
7351   u8 host_mac_addr[6];
7352   u8 host_mac_addr_set = 0;
7353   u8 *host_bridge = 0;
7354   ip4_address_t host_ip4_addr;
7355   ip4_address_t host_ip4_gw;
7356   u8 host_ip4_gw_set = 0;
7357   u32 host_ip4_prefix_len = 0;
7358   ip6_address_t host_ip6_addr;
7359   ip6_address_t host_ip6_gw;
7360   u8 host_ip6_gw_set = 0;
7361   u32 host_ip6_prefix_len = 0;
7362   u8 host_mtu_set = 0;
7363   u32 host_mtu_size = 0;
7364   u32 tap_flags = 0;
7365   int ret;
7366   u32 rx_ring_sz = 0, tx_ring_sz = 0;
7367
7368   clib_memset (mac_address, 0, sizeof (mac_address));
7369
7370   /* Parse args required to build the message */
7371   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7372     {
7373       if (unformat (i, "hw-addr %U", unformat_ethernet_address, mac_address))
7374         {
7375           random_mac = 0;
7376         }
7377       else if (unformat (i, "id %u", &id))
7378         ;
7379       else if (unformat (i, "host-if-name %s", &host_if_name))
7380         ;
7381       else if (unformat (i, "host-ns %s", &host_ns))
7382         ;
7383       else if (unformat (i, "host-mac-addr %U", unformat_ethernet_address,
7384                          host_mac_addr))
7385         host_mac_addr_set = 1;
7386       else if (unformat (i, "host-bridge %s", &host_bridge))
7387         ;
7388       else if (unformat (i, "host-ip4-addr %U/%d", unformat_ip4_address,
7389                          &host_ip4_addr, &host_ip4_prefix_len))
7390         ;
7391       else if (unformat (i, "host-ip6-addr %U/%d", unformat_ip6_address,
7392                          &host_ip6_addr, &host_ip6_prefix_len))
7393         ;
7394       else if (unformat (i, "host-ip4-gw %U", unformat_ip4_address,
7395                          &host_ip4_gw))
7396         host_ip4_gw_set = 1;
7397       else if (unformat (i, "host-ip6-gw %U", unformat_ip6_address,
7398                          &host_ip6_gw))
7399         host_ip6_gw_set = 1;
7400       else if (unformat (i, "rx-ring-size %d", &rx_ring_sz))
7401         ;
7402       else if (unformat (i, "tx-ring-size %d", &tx_ring_sz))
7403         ;
7404       else if (unformat (i, "host-mtu-size %d", &host_mtu_size))
7405         host_mtu_set = 1;
7406       else if (unformat (i, "no-gso"))
7407         tap_flags &= ~TAP_FLAG_GSO;
7408       else if (unformat (i, "gso"))
7409         tap_flags |= TAP_FLAG_GSO;
7410       else
7411         break;
7412     }
7413
7414   if (vec_len (host_if_name) > 63)
7415     {
7416       errmsg ("tap name too long. ");
7417       return -99;
7418     }
7419   if (vec_len (host_ns) > 63)
7420     {
7421       errmsg ("host name space too long. ");
7422       return -99;
7423     }
7424   if (vec_len (host_bridge) > 63)
7425     {
7426       errmsg ("host bridge name too long. ");
7427       return -99;
7428     }
7429   if (host_ip4_prefix_len > 32)
7430     {
7431       errmsg ("host ip4 prefix length not valid. ");
7432       return -99;
7433     }
7434   if (host_ip6_prefix_len > 128)
7435     {
7436       errmsg ("host ip6 prefix length not valid. ");
7437       return -99;
7438     }
7439   if (!is_pow2 (rx_ring_sz))
7440     {
7441       errmsg ("rx ring size must be power of 2. ");
7442       return -99;
7443     }
7444   if (rx_ring_sz > 32768)
7445     {
7446       errmsg ("rx ring size must be 32768 or lower. ");
7447       return -99;
7448     }
7449   if (!is_pow2 (tx_ring_sz))
7450     {
7451       errmsg ("tx ring size must be power of 2. ");
7452       return -99;
7453     }
7454   if (tx_ring_sz > 32768)
7455     {
7456       errmsg ("tx ring size must be 32768 or lower. ");
7457       return -99;
7458     }
7459   if (host_mtu_set && (host_mtu_size < 64 || host_mtu_size > 65355))
7460     {
7461       errmsg ("host MTU size must be in between 64 and 65355. ");
7462       return -99;
7463     }
7464
7465   /* Construct the API message */
7466   M (TAP_CREATE_V2, mp);
7467
7468   mp->use_random_mac = random_mac;
7469
7470   mp->id = ntohl (id);
7471   mp->host_namespace_set = host_ns != 0;
7472   mp->host_bridge_set = host_bridge != 0;
7473   mp->host_ip4_addr_set = host_ip4_prefix_len != 0;
7474   mp->host_ip6_addr_set = host_ip6_prefix_len != 0;
7475   mp->rx_ring_sz = ntohs (rx_ring_sz);
7476   mp->tx_ring_sz = ntohs (tx_ring_sz);
7477   mp->host_mtu_set = host_mtu_set;
7478   mp->host_mtu_size = ntohl (host_mtu_size);
7479   mp->tap_flags = ntohl (tap_flags);
7480
7481   if (random_mac == 0)
7482     clib_memcpy (mp->mac_address, mac_address, 6);
7483   if (host_mac_addr_set)
7484     clib_memcpy (mp->host_mac_addr, host_mac_addr, 6);
7485   if (host_if_name)
7486     clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
7487   if (host_ns)
7488     clib_memcpy (mp->host_namespace, host_ns, vec_len (host_ns));
7489   if (host_bridge)
7490     clib_memcpy (mp->host_bridge, host_bridge, vec_len (host_bridge));
7491   if (host_ip4_prefix_len)
7492     clib_memcpy (mp->host_ip4_addr, &host_ip4_addr, 4);
7493   if (host_ip6_prefix_len)
7494     clib_memcpy (mp->host_ip6_addr, &host_ip6_addr, 16);
7495   if (host_ip4_gw_set)
7496     clib_memcpy (mp->host_ip4_gw, &host_ip4_gw, 4);
7497   if (host_ip6_gw_set)
7498     clib_memcpy (mp->host_ip6_gw, &host_ip6_gw, 16);
7499
7500   vec_free (host_ns);
7501   vec_free (host_if_name);
7502   vec_free (host_bridge);
7503
7504   /* send it... */
7505   S (mp);
7506
7507   /* Wait for a reply... */
7508   W (ret);
7509   return ret;
7510 }
7511
7512 static int
7513 api_tap_delete_v2 (vat_main_t * vam)
7514 {
7515   unformat_input_t *i = vam->input;
7516   vl_api_tap_delete_v2_t *mp;
7517   u32 sw_if_index = ~0;
7518   u8 sw_if_index_set = 0;
7519   int ret;
7520
7521   /* Parse args required to build the message */
7522   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7523     {
7524       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7525         sw_if_index_set = 1;
7526       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7527         sw_if_index_set = 1;
7528       else
7529         break;
7530     }
7531
7532   if (sw_if_index_set == 0)
7533     {
7534       errmsg ("missing vpp interface name. ");
7535       return -99;
7536     }
7537
7538   /* Construct the API message */
7539   M (TAP_DELETE_V2, mp);
7540
7541   mp->sw_if_index = ntohl (sw_if_index);
7542
7543   /* send it... */
7544   S (mp);
7545
7546   /* Wait for a reply... */
7547   W (ret);
7548   return ret;
7549 }
7550
7551 uword
7552 unformat_vlib_pci_addr (unformat_input_t * input, va_list * args)
7553 {
7554   vlib_pci_addr_t *addr = va_arg (*args, vlib_pci_addr_t *);
7555   u32 x[4];
7556
7557   if (!unformat (input, "%x:%x:%x.%x", &x[0], &x[1], &x[2], &x[3]))
7558     return 0;
7559
7560   addr->domain = x[0];
7561   addr->bus = x[1];
7562   addr->slot = x[2];
7563   addr->function = x[3];
7564
7565   return 1;
7566 }
7567
7568 static int
7569 api_virtio_pci_create (vat_main_t * vam)
7570 {
7571   unformat_input_t *i = vam->input;
7572   vl_api_virtio_pci_create_t *mp;
7573   u8 mac_address[6];
7574   u8 random_mac = 1;
7575   u8 gso_enabled = 0;
7576   u32 pci_addr = 0;
7577   u64 features = (u64) ~ (0ULL);
7578   int ret;
7579
7580   clib_memset (mac_address, 0, sizeof (mac_address));
7581
7582   /* Parse args required to build the message */
7583   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7584     {
7585       if (unformat (i, "hw-addr %U", unformat_ethernet_address, mac_address))
7586         {
7587           random_mac = 0;
7588         }
7589       else if (unformat (i, "pci-addr %U", unformat_vlib_pci_addr, &pci_addr))
7590         ;
7591       else if (unformat (i, "features 0x%llx", &features))
7592         ;
7593       else if (unformat (i, "gso-enabled"))
7594         gso_enabled = 1;
7595       else
7596         break;
7597     }
7598
7599   if (pci_addr == 0)
7600     {
7601       errmsg ("pci address must be non zero. ");
7602       return -99;
7603     }
7604
7605   /* Construct the API message */
7606   M (VIRTIO_PCI_CREATE, mp);
7607
7608   mp->use_random_mac = random_mac;
7609
7610   mp->pci_addr = htonl (pci_addr);
7611   mp->features = clib_host_to_net_u64 (features);
7612   mp->gso_enabled = gso_enabled;
7613
7614   if (random_mac == 0)
7615     clib_memcpy (mp->mac_address, mac_address, 6);
7616
7617   /* send it... */
7618   S (mp);
7619
7620   /* Wait for a reply... */
7621   W (ret);
7622   return ret;
7623 }
7624
7625 static int
7626 api_virtio_pci_delete (vat_main_t * vam)
7627 {
7628   unformat_input_t *i = vam->input;
7629   vl_api_virtio_pci_delete_t *mp;
7630   u32 sw_if_index = ~0;
7631   u8 sw_if_index_set = 0;
7632   int ret;
7633
7634   /* Parse args required to build the message */
7635   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7636     {
7637       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7638         sw_if_index_set = 1;
7639       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7640         sw_if_index_set = 1;
7641       else
7642         break;
7643     }
7644
7645   if (sw_if_index_set == 0)
7646     {
7647       errmsg ("missing vpp interface name. ");
7648       return -99;
7649     }
7650
7651   /* Construct the API message */
7652   M (VIRTIO_PCI_DELETE, mp);
7653
7654   mp->sw_if_index = htonl (sw_if_index);
7655
7656   /* send it... */
7657   S (mp);
7658
7659   /* Wait for a reply... */
7660   W (ret);
7661   return ret;
7662 }
7663
7664 static int
7665 api_bond_create (vat_main_t * vam)
7666 {
7667   unformat_input_t *i = vam->input;
7668   vl_api_bond_create_t *mp;
7669   u8 mac_address[6];
7670   u8 custom_mac = 0;
7671   int ret;
7672   u8 mode;
7673   u8 lb;
7674   u8 mode_is_set = 0;
7675   u32 id = ~0;
7676   u8 numa_only = 0;
7677
7678   clib_memset (mac_address, 0, sizeof (mac_address));
7679   lb = BOND_LB_L2;
7680
7681   /* Parse args required to build the message */
7682   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7683     {
7684       if (unformat (i, "mode %U", unformat_bond_mode, &mode))
7685         mode_is_set = 1;
7686       else if (((mode == BOND_MODE_LACP) || (mode == BOND_MODE_XOR))
7687                && unformat (i, "lb %U", unformat_bond_load_balance, &lb))
7688         ;
7689       else if (unformat (i, "hw-addr %U", unformat_ethernet_address,
7690                          mac_address))
7691         custom_mac = 1;
7692       else if (unformat (i, "numa-only"))
7693         numa_only = 1;
7694       else if (unformat (i, "id %u", &id))
7695         ;
7696       else
7697         break;
7698     }
7699
7700   if (mode_is_set == 0)
7701     {
7702       errmsg ("Missing bond mode. ");
7703       return -99;
7704     }
7705
7706   /* Construct the API message */
7707   M (BOND_CREATE, mp);
7708
7709   mp->use_custom_mac = custom_mac;
7710
7711   mp->mode = htonl (mode);
7712   mp->lb = htonl (lb);
7713   mp->id = htonl (id);
7714   mp->numa_only = numa_only;
7715
7716   if (custom_mac)
7717     clib_memcpy (mp->mac_address, mac_address, 6);
7718
7719   /* send it... */
7720   S (mp);
7721
7722   /* Wait for a reply... */
7723   W (ret);
7724   return ret;
7725 }
7726
7727 static int
7728 api_bond_delete (vat_main_t * vam)
7729 {
7730   unformat_input_t *i = vam->input;
7731   vl_api_bond_delete_t *mp;
7732   u32 sw_if_index = ~0;
7733   u8 sw_if_index_set = 0;
7734   int ret;
7735
7736   /* Parse args required to build the message */
7737   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7738     {
7739       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7740         sw_if_index_set = 1;
7741       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7742         sw_if_index_set = 1;
7743       else
7744         break;
7745     }
7746
7747   if (sw_if_index_set == 0)
7748     {
7749       errmsg ("missing vpp interface name. ");
7750       return -99;
7751     }
7752
7753   /* Construct the API message */
7754   M (BOND_DELETE, mp);
7755
7756   mp->sw_if_index = ntohl (sw_if_index);
7757
7758   /* send it... */
7759   S (mp);
7760
7761   /* Wait for a reply... */
7762   W (ret);
7763   return ret;
7764 }
7765
7766 static int
7767 api_bond_enslave (vat_main_t * vam)
7768 {
7769   unformat_input_t *i = vam->input;
7770   vl_api_bond_enslave_t *mp;
7771   u32 bond_sw_if_index;
7772   int ret;
7773   u8 is_passive;
7774   u8 is_long_timeout;
7775   u32 bond_sw_if_index_is_set = 0;
7776   u32 sw_if_index;
7777   u8 sw_if_index_is_set = 0;
7778
7779   /* Parse args required to build the message */
7780   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7781     {
7782       if (unformat (i, "sw_if_index %d", &sw_if_index))
7783         sw_if_index_is_set = 1;
7784       else if (unformat (i, "bond %u", &bond_sw_if_index))
7785         bond_sw_if_index_is_set = 1;
7786       else if (unformat (i, "passive %d", &is_passive))
7787         ;
7788       else if (unformat (i, "long-timeout %d", &is_long_timeout))
7789         ;
7790       else
7791         break;
7792     }
7793
7794   if (bond_sw_if_index_is_set == 0)
7795     {
7796       errmsg ("Missing bond sw_if_index. ");
7797       return -99;
7798     }
7799   if (sw_if_index_is_set == 0)
7800     {
7801       errmsg ("Missing slave sw_if_index. ");
7802       return -99;
7803     }
7804
7805   /* Construct the API message */
7806   M (BOND_ENSLAVE, mp);
7807
7808   mp->bond_sw_if_index = ntohl (bond_sw_if_index);
7809   mp->sw_if_index = ntohl (sw_if_index);
7810   mp->is_long_timeout = is_long_timeout;
7811   mp->is_passive = is_passive;
7812
7813   /* send it... */
7814   S (mp);
7815
7816   /* Wait for a reply... */
7817   W (ret);
7818   return ret;
7819 }
7820
7821 static int
7822 api_bond_detach_slave (vat_main_t * vam)
7823 {
7824   unformat_input_t *i = vam->input;
7825   vl_api_bond_detach_slave_t *mp;
7826   u32 sw_if_index = ~0;
7827   u8 sw_if_index_set = 0;
7828   int ret;
7829
7830   /* Parse args required to build the message */
7831   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7832     {
7833       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7834         sw_if_index_set = 1;
7835       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7836         sw_if_index_set = 1;
7837       else
7838         break;
7839     }
7840
7841   if (sw_if_index_set == 0)
7842     {
7843       errmsg ("missing vpp interface name. ");
7844       return -99;
7845     }
7846
7847   /* Construct the API message */
7848   M (BOND_DETACH_SLAVE, mp);
7849
7850   mp->sw_if_index = ntohl (sw_if_index);
7851
7852   /* send it... */
7853   S (mp);
7854
7855   /* Wait for a reply... */
7856   W (ret);
7857   return ret;
7858 }
7859
7860 static int
7861 api_ip_table_add_del (vat_main_t * vam)
7862 {
7863   unformat_input_t *i = vam->input;
7864   vl_api_ip_table_add_del_t *mp;
7865   u32 table_id = ~0;
7866   u8 is_ipv6 = 0;
7867   u8 is_add = 1;
7868   int ret = 0;
7869
7870   /* Parse args required to build the message */
7871   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7872     {
7873       if (unformat (i, "ipv6"))
7874         is_ipv6 = 1;
7875       else if (unformat (i, "del"))
7876         is_add = 0;
7877       else if (unformat (i, "add"))
7878         is_add = 1;
7879       else if (unformat (i, "table %d", &table_id))
7880         ;
7881       else
7882         {
7883           clib_warning ("parse error '%U'", format_unformat_error, i);
7884           return -99;
7885         }
7886     }
7887
7888   if (~0 == table_id)
7889     {
7890       errmsg ("missing table-ID");
7891       return -99;
7892     }
7893
7894   /* Construct the API message */
7895   M (IP_TABLE_ADD_DEL, mp);
7896
7897   mp->table.table_id = ntohl (table_id);
7898   mp->table.is_ip6 = is_ipv6;
7899   mp->is_add = is_add;
7900
7901   /* send it... */
7902   S (mp);
7903
7904   /* Wait for a reply... */
7905   W (ret);
7906
7907   return ret;
7908 }
7909
7910 uword
7911 unformat_fib_path (unformat_input_t * input, va_list * args)
7912 {
7913   vat_main_t *vam = va_arg (*args, vat_main_t *);
7914   vl_api_fib_path_t *path = va_arg (*args, vl_api_fib_path_t *);
7915   u32 weight, preference;
7916   mpls_label_t out_label;
7917
7918   clib_memset (path, 0, sizeof (*path));
7919   path->weight = 1;
7920   path->sw_if_index = ~0;
7921   path->rpf_id = ~0;
7922   path->n_labels = 0;
7923
7924   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7925     {
7926       if (unformat (input, "%U %U",
7927                     unformat_vl_api_ip4_address,
7928                     &path->nh.address.ip4,
7929                     api_unformat_sw_if_index, vam, &path->sw_if_index))
7930         {
7931           path->proto = FIB_API_PATH_NH_PROTO_IP4;
7932         }
7933       else if (unformat (input, "%U %U",
7934                          unformat_vl_api_ip6_address,
7935                          &path->nh.address.ip6,
7936                          api_unformat_sw_if_index, vam, &path->sw_if_index))
7937         {
7938           path->proto = FIB_API_PATH_NH_PROTO_IP6;
7939         }
7940       else if (unformat (input, "weight %u", &weight))
7941         {
7942           path->weight = weight;
7943         }
7944       else if (unformat (input, "preference %u", &preference))
7945         {
7946           path->preference = preference;
7947         }
7948       else if (unformat (input, "%U next-hop-table %d",
7949                          unformat_vl_api_ip4_address,
7950                          &path->nh.address.ip4, &path->table_id))
7951         {
7952           path->proto = FIB_API_PATH_NH_PROTO_IP4;
7953         }
7954       else if (unformat (input, "%U next-hop-table %d",
7955                          unformat_vl_api_ip6_address,
7956                          &path->nh.address.ip6, &path->table_id))
7957         {
7958           path->proto = FIB_API_PATH_NH_PROTO_IP6;
7959         }
7960       else if (unformat (input, "%U",
7961                          unformat_vl_api_ip4_address, &path->nh.address.ip4))
7962         {
7963           /*
7964            * the recursive next-hops are by default in the default table
7965            */
7966           path->table_id = 0;
7967           path->sw_if_index = ~0;
7968           path->proto = FIB_API_PATH_NH_PROTO_IP4;
7969         }
7970       else if (unformat (input, "%U",
7971                          unformat_vl_api_ip6_address, &path->nh.address.ip6))
7972         {
7973           /*
7974            * the recursive next-hops are by default in the default table
7975            */
7976           path->table_id = 0;
7977           path->sw_if_index = ~0;
7978           path->proto = FIB_API_PATH_NH_PROTO_IP6;
7979         }
7980       else if (unformat (input, "resolve-via-host"))
7981         {
7982           path->flags |= FIB_API_PATH_FLAG_RESOLVE_VIA_HOST;
7983         }
7984       else if (unformat (input, "resolve-via-attached"))
7985         {
7986           path->flags |= FIB_API_PATH_FLAG_RESOLVE_VIA_ATTACHED;
7987         }
7988       else if (unformat (input, "ip4-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_IP4;
7993         }
7994       else if (unformat (input, "ip6-lookup-in-table %d", &path->table_id))
7995         {
7996           path->type = FIB_API_PATH_TYPE_LOCAL;
7997           path->sw_if_index = ~0;
7998           path->proto = FIB_API_PATH_NH_PROTO_IP6;
7999         }
8000       else if (unformat (input, "sw_if_index %d", &path->sw_if_index))
8001         ;
8002       else if (unformat (input, "via-label %d", &path->nh.via_label))
8003         {
8004           path->proto = FIB_API_PATH_NH_PROTO_MPLS;
8005           path->sw_if_index = ~0;
8006         }
8007       else if (unformat (input, "l2-input-on %d", &path->sw_if_index))
8008         {
8009           path->proto = FIB_API_PATH_NH_PROTO_ETHERNET;
8010           path->type = FIB_API_PATH_TYPE_INTERFACE_RX;
8011         }
8012       else if (unformat (input, "local"))
8013         {
8014           path->type = FIB_API_PATH_TYPE_LOCAL;
8015         }
8016       else if (unformat (input, "out-labels"))
8017         {
8018           while (unformat (input, "%d", &out_label))
8019             {
8020               path->label_stack[path->n_labels].label = out_label;
8021               path->label_stack[path->n_labels].is_uniform = 0;
8022               path->label_stack[path->n_labels].ttl = 64;
8023               path->n_labels++;
8024             }
8025         }
8026       else if (unformat (input, "via"))
8027         {
8028           /* new path, back up and return */
8029           unformat_put_input (input);
8030           unformat_put_input (input);
8031           unformat_put_input (input);
8032           unformat_put_input (input);
8033           break;
8034         }
8035       else
8036         {
8037           return (0);
8038         }
8039     }
8040
8041   path->proto = ntohl (path->proto);
8042   path->type = ntohl (path->type);
8043   path->flags = ntohl (path->flags);
8044   path->table_id = ntohl (path->table_id);
8045   path->sw_if_index = ntohl (path->sw_if_index);
8046
8047   return (1);
8048 }
8049
8050 static int
8051 api_ip_route_add_del (vat_main_t * vam)
8052 {
8053   unformat_input_t *i = vam->input;
8054   vl_api_ip_route_add_del_t *mp;
8055   u32 vrf_id = 0;
8056   u8 is_add = 1;
8057   u8 is_multipath = 0;
8058   u8 prefix_set = 0;
8059   u8 path_count = 0;
8060   vl_api_prefix_t pfx = { };
8061   vl_api_fib_path_t paths[8];
8062   int count = 1;
8063   int j;
8064   f64 before = 0;
8065   u32 random_add_del = 0;
8066   u32 *random_vector = 0;
8067   u32 random_seed = 0xdeaddabe;
8068
8069   /* Parse args required to build the message */
8070   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8071     {
8072       if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
8073         prefix_set = 1;
8074       else if (unformat (i, "del"))
8075         is_add = 0;
8076       else if (unformat (i, "add"))
8077         is_add = 1;
8078       else if (unformat (i, "vrf %d", &vrf_id))
8079         ;
8080       else if (unformat (i, "count %d", &count))
8081         ;
8082       else if (unformat (i, "random"))
8083         random_add_del = 1;
8084       else if (unformat (i, "multipath"))
8085         is_multipath = 1;
8086       else if (unformat (i, "seed %d", &random_seed))
8087         ;
8088       else
8089         if (unformat
8090             (i, "via %U", unformat_fib_path, vam, &paths[path_count]))
8091         {
8092           path_count++;
8093           if (8 == path_count)
8094             {
8095               errmsg ("max 8 paths");
8096               return -99;
8097             }
8098         }
8099       else
8100         {
8101           clib_warning ("parse error '%U'", format_unformat_error, i);
8102           return -99;
8103         }
8104     }
8105
8106   if (!path_count)
8107     {
8108       errmsg ("specify a path; via ...");
8109       return -99;
8110     }
8111   if (prefix_set == 0)
8112     {
8113       errmsg ("missing prefix");
8114       return -99;
8115     }
8116
8117   /* Generate a pile of unique, random routes */
8118   if (random_add_del)
8119     {
8120       ip4_address_t *i = (ip4_address_t *) & paths[0].nh.address.ip4;
8121       u32 this_random_address;
8122       uword *random_hash;
8123
8124       random_hash = hash_create (count, sizeof (uword));
8125
8126       hash_set (random_hash, i->as_u32, 1);
8127       for (j = 0; j <= count; j++)
8128         {
8129           do
8130             {
8131               this_random_address = random_u32 (&random_seed);
8132               this_random_address =
8133                 clib_host_to_net_u32 (this_random_address);
8134             }
8135           while (hash_get (random_hash, this_random_address));
8136           vec_add1 (random_vector, this_random_address);
8137           hash_set (random_hash, this_random_address, 1);
8138         }
8139       hash_free (random_hash);
8140       set_ip4_address (&pfx.address, random_vector[0]);
8141     }
8142
8143   if (count > 1)
8144     {
8145       /* Turn on async mode */
8146       vam->async_mode = 1;
8147       vam->async_errors = 0;
8148       before = vat_time_now (vam);
8149     }
8150
8151   for (j = 0; j < count; j++)
8152     {
8153       /* Construct the API message */
8154       M2 (IP_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t) * path_count);
8155
8156       mp->is_add = is_add;
8157       mp->is_multipath = is_multipath;
8158
8159       clib_memcpy (&mp->route.prefix, &pfx, sizeof (pfx));
8160       mp->route.table_id = ntohl (vrf_id);
8161       mp->route.n_paths = path_count;
8162
8163       clib_memcpy (&mp->route.paths, &paths, sizeof (paths[0]) * path_count);
8164
8165       if (random_add_del)
8166         set_ip4_address (&pfx.address, random_vector[j + 1]);
8167       else
8168         increment_address (&pfx.address);
8169       /* send it... */
8170       S (mp);
8171       /* If we receive SIGTERM, stop now... */
8172       if (vam->do_exit)
8173         break;
8174     }
8175
8176   /* When testing multiple add/del ops, use a control-ping to sync */
8177   if (count > 1)
8178     {
8179       vl_api_control_ping_t *mp_ping;
8180       f64 after;
8181       f64 timeout;
8182
8183       /* Shut off async mode */
8184       vam->async_mode = 0;
8185
8186       MPING (CONTROL_PING, mp_ping);
8187       S (mp_ping);
8188
8189       timeout = vat_time_now (vam) + 1.0;
8190       while (vat_time_now (vam) < timeout)
8191         if (vam->result_ready == 1)
8192           goto out;
8193       vam->retval = -99;
8194
8195     out:
8196       if (vam->retval == -99)
8197         errmsg ("timeout");
8198
8199       if (vam->async_errors > 0)
8200         {
8201           errmsg ("%d asynchronous errors", vam->async_errors);
8202           vam->retval = -98;
8203         }
8204       vam->async_errors = 0;
8205       after = vat_time_now (vam);
8206
8207       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8208       if (j > 0)
8209         count = j;
8210
8211       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8212              count, after - before, count / (after - before));
8213     }
8214   else
8215     {
8216       int ret;
8217
8218       /* Wait for a reply... */
8219       W (ret);
8220       return ret;
8221     }
8222
8223   /* Return the good/bad news */
8224   return (vam->retval);
8225 }
8226
8227 static int
8228 api_ip_mroute_add_del (vat_main_t * vam)
8229 {
8230   unformat_input_t *i = vam->input;
8231   u8 path_set = 0, prefix_set = 0, is_add = 1;
8232   vl_api_ip_mroute_add_del_t *mp;
8233   mfib_entry_flags_t eflags = 0;
8234   vl_api_mfib_path_t path;
8235   vl_api_mprefix_t pfx = { };
8236   u32 vrf_id = 0;
8237   int ret;
8238
8239   /* Parse args required to build the message */
8240   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8241     {
8242       if (unformat (i, "%U", unformat_vl_api_mprefix, &pfx))
8243         {
8244           prefix_set = 1;
8245           pfx.grp_address_length = htons (pfx.grp_address_length);
8246         }
8247       else if (unformat (i, "del"))
8248         is_add = 0;
8249       else if (unformat (i, "add"))
8250         is_add = 1;
8251       else if (unformat (i, "vrf %d", &vrf_id))
8252         ;
8253       else if (unformat (i, "%U", unformat_mfib_itf_flags, &path.itf_flags))
8254         path.itf_flags = htonl (path.itf_flags);
8255       else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
8256         ;
8257       else if (unformat (i, "via %U", unformat_fib_path, vam, &path.path))
8258         path_set = 1;
8259       else
8260         {
8261           clib_warning ("parse error '%U'", format_unformat_error, i);
8262           return -99;
8263         }
8264     }
8265
8266   if (prefix_set == 0)
8267     {
8268       errmsg ("missing addresses\n");
8269       return -99;
8270     }
8271   if (path_set == 0)
8272     {
8273       errmsg ("missing path\n");
8274       return -99;
8275     }
8276
8277   /* Construct the API message */
8278   M (IP_MROUTE_ADD_DEL, mp);
8279
8280   mp->is_add = is_add;
8281   mp->is_multipath = 1;
8282
8283   clib_memcpy (&mp->route.prefix, &pfx, sizeof (pfx));
8284   mp->route.table_id = htonl (vrf_id);
8285   mp->route.n_paths = 1;
8286   mp->route.entry_flags = htonl (eflags);
8287
8288   clib_memcpy (&mp->route.paths, &path, sizeof (path));
8289
8290   /* send it... */
8291   S (mp);
8292   /* Wait for a reply... */
8293   W (ret);
8294   return ret;
8295 }
8296
8297 static int
8298 api_mpls_table_add_del (vat_main_t * vam)
8299 {
8300   unformat_input_t *i = vam->input;
8301   vl_api_mpls_table_add_del_t *mp;
8302   u32 table_id = ~0;
8303   u8 is_add = 1;
8304   int ret = 0;
8305
8306   /* Parse args required to build the message */
8307   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8308     {
8309       if (unformat (i, "table %d", &table_id))
8310         ;
8311       else if (unformat (i, "del"))
8312         is_add = 0;
8313       else if (unformat (i, "add"))
8314         is_add = 1;
8315       else
8316         {
8317           clib_warning ("parse error '%U'", format_unformat_error, i);
8318           return -99;
8319         }
8320     }
8321
8322   if (~0 == table_id)
8323     {
8324       errmsg ("missing table-ID");
8325       return -99;
8326     }
8327
8328   /* Construct the API message */
8329   M (MPLS_TABLE_ADD_DEL, mp);
8330
8331   mp->mt_table.mt_table_id = ntohl (table_id);
8332   mp->mt_is_add = is_add;
8333
8334   /* send it... */
8335   S (mp);
8336
8337   /* Wait for a reply... */
8338   W (ret);
8339
8340   return ret;
8341 }
8342
8343 static int
8344 api_mpls_route_add_del (vat_main_t * vam)
8345 {
8346   u8 is_add = 1, path_count = 0, is_multipath = 0, is_eos = 0;
8347   mpls_label_t local_label = MPLS_LABEL_INVALID;
8348   unformat_input_t *i = vam->input;
8349   vl_api_mpls_route_add_del_t *mp;
8350   vl_api_fib_path_t paths[8];
8351   int count = 1, j;
8352   f64 before = 0;
8353
8354   /* Parse args required to build the message */
8355   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8356     {
8357       if (unformat (i, "%d", &local_label))
8358         ;
8359       else if (unformat (i, "eos"))
8360         is_eos = 1;
8361       else if (unformat (i, "non-eos"))
8362         is_eos = 0;
8363       else if (unformat (i, "del"))
8364         is_add = 0;
8365       else if (unformat (i, "add"))
8366         is_add = 1;
8367       else if (unformat (i, "multipath"))
8368         is_multipath = 1;
8369       else if (unformat (i, "count %d", &count))
8370         ;
8371       else
8372         if (unformat
8373             (i, "via %U", unformat_fib_path, vam, &paths[path_count]))
8374         {
8375           path_count++;
8376           if (8 == path_count)
8377             {
8378               errmsg ("max 8 paths");
8379               return -99;
8380             }
8381         }
8382       else
8383         {
8384           clib_warning ("parse error '%U'", format_unformat_error, i);
8385           return -99;
8386         }
8387     }
8388
8389   if (!path_count)
8390     {
8391       errmsg ("specify a path; via ...");
8392       return -99;
8393     }
8394
8395   if (MPLS_LABEL_INVALID == local_label)
8396     {
8397       errmsg ("missing label");
8398       return -99;
8399     }
8400
8401   if (count > 1)
8402     {
8403       /* Turn on async mode */
8404       vam->async_mode = 1;
8405       vam->async_errors = 0;
8406       before = vat_time_now (vam);
8407     }
8408
8409   for (j = 0; j < count; j++)
8410     {
8411       /* Construct the API message */
8412       M2 (MPLS_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t) * path_count);
8413
8414       mp->mr_is_add = is_add;
8415       mp->mr_is_multipath = is_multipath;
8416
8417       mp->mr_route.mr_label = local_label;
8418       mp->mr_route.mr_eos = is_eos;
8419       mp->mr_route.mr_table_id = 0;
8420       mp->mr_route.mr_n_paths = path_count;
8421
8422       clib_memcpy (&mp->mr_route.mr_paths, paths,
8423                    sizeof (paths[0]) * path_count);
8424
8425       local_label++;
8426
8427       /* send it... */
8428       S (mp);
8429       /* If we receive SIGTERM, stop now... */
8430       if (vam->do_exit)
8431         break;
8432     }
8433
8434   /* When testing multiple add/del ops, use a control-ping to sync */
8435   if (count > 1)
8436     {
8437       vl_api_control_ping_t *mp_ping;
8438       f64 after;
8439       f64 timeout;
8440
8441       /* Shut off async mode */
8442       vam->async_mode = 0;
8443
8444       MPING (CONTROL_PING, mp_ping);
8445       S (mp_ping);
8446
8447       timeout = vat_time_now (vam) + 1.0;
8448       while (vat_time_now (vam) < timeout)
8449         if (vam->result_ready == 1)
8450           goto out;
8451       vam->retval = -99;
8452
8453     out:
8454       if (vam->retval == -99)
8455         errmsg ("timeout");
8456
8457       if (vam->async_errors > 0)
8458         {
8459           errmsg ("%d asynchronous errors", vam->async_errors);
8460           vam->retval = -98;
8461         }
8462       vam->async_errors = 0;
8463       after = vat_time_now (vam);
8464
8465       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8466       if (j > 0)
8467         count = j;
8468
8469       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8470              count, after - before, count / (after - before));
8471     }
8472   else
8473     {
8474       int ret;
8475
8476       /* Wait for a reply... */
8477       W (ret);
8478       return ret;
8479     }
8480
8481   /* Return the good/bad news */
8482   return (vam->retval);
8483   return (0);
8484 }
8485
8486 static int
8487 api_mpls_ip_bind_unbind (vat_main_t * vam)
8488 {
8489   unformat_input_t *i = vam->input;
8490   vl_api_mpls_ip_bind_unbind_t *mp;
8491   u32 ip_table_id = 0;
8492   u8 is_bind = 1;
8493   vl_api_prefix_t pfx;
8494   u8 prefix_set = 0;
8495   mpls_label_t local_label = MPLS_LABEL_INVALID;
8496   int ret;
8497
8498   /* Parse args required to build the message */
8499   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8500     {
8501       if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
8502         prefix_set = 1;
8503       else if (unformat (i, "%d", &local_label))
8504         ;
8505       else if (unformat (i, "table-id %d", &ip_table_id))
8506         ;
8507       else if (unformat (i, "unbind"))
8508         is_bind = 0;
8509       else if (unformat (i, "bind"))
8510         is_bind = 1;
8511       else
8512         {
8513           clib_warning ("parse error '%U'", format_unformat_error, i);
8514           return -99;
8515         }
8516     }
8517
8518   if (!prefix_set)
8519     {
8520       errmsg ("IP prefix not set");
8521       return -99;
8522     }
8523
8524   if (MPLS_LABEL_INVALID == local_label)
8525     {
8526       errmsg ("missing label");
8527       return -99;
8528     }
8529
8530   /* Construct the API message */
8531   M (MPLS_IP_BIND_UNBIND, mp);
8532
8533   mp->mb_is_bind = is_bind;
8534   mp->mb_ip_table_id = ntohl (ip_table_id);
8535   mp->mb_mpls_table_id = 0;
8536   mp->mb_label = ntohl (local_label);
8537   clib_memcpy (&mp->mb_prefix, &pfx, sizeof (pfx));
8538
8539   /* send it... */
8540   S (mp);
8541
8542   /* Wait for a reply... */
8543   W (ret);
8544   return ret;
8545   return (0);
8546 }
8547
8548 static int
8549 api_sr_mpls_policy_add (vat_main_t * vam)
8550 {
8551   unformat_input_t *i = vam->input;
8552   vl_api_sr_mpls_policy_add_t *mp;
8553   u32 bsid = 0;
8554   u32 weight = 1;
8555   u8 type = 0;
8556   u8 n_segments = 0;
8557   u32 sid;
8558   u32 *segments = NULL;
8559   int ret;
8560
8561   /* Parse args required to build the message */
8562   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8563     {
8564       if (unformat (i, "bsid %d", &bsid))
8565         ;
8566       else if (unformat (i, "weight %d", &weight))
8567         ;
8568       else if (unformat (i, "spray"))
8569         type = 1;
8570       else if (unformat (i, "next %d", &sid))
8571         {
8572           n_segments += 1;
8573           vec_add1 (segments, htonl (sid));
8574         }
8575       else
8576         {
8577           clib_warning ("parse error '%U'", format_unformat_error, i);
8578           return -99;
8579         }
8580     }
8581
8582   if (bsid == 0)
8583     {
8584       errmsg ("bsid not set");
8585       return -99;
8586     }
8587
8588   if (n_segments == 0)
8589     {
8590       errmsg ("no sid in segment stack");
8591       return -99;
8592     }
8593
8594   /* Construct the API message */
8595   M2 (SR_MPLS_POLICY_ADD, mp, sizeof (u32) * n_segments);
8596
8597   mp->bsid = htonl (bsid);
8598   mp->weight = htonl (weight);
8599   mp->type = type;
8600   mp->n_segments = n_segments;
8601   memcpy (mp->segments, segments, sizeof (u32) * n_segments);
8602   vec_free (segments);
8603
8604   /* send it... */
8605   S (mp);
8606
8607   /* Wait for a reply... */
8608   W (ret);
8609   return ret;
8610 }
8611
8612 static int
8613 api_sr_mpls_policy_del (vat_main_t * vam)
8614 {
8615   unformat_input_t *i = vam->input;
8616   vl_api_sr_mpls_policy_del_t *mp;
8617   u32 bsid = 0;
8618   int ret;
8619
8620   /* Parse args required to build the message */
8621   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8622     {
8623       if (unformat (i, "bsid %d", &bsid))
8624         ;
8625       else
8626         {
8627           clib_warning ("parse error '%U'", format_unformat_error, i);
8628           return -99;
8629         }
8630     }
8631
8632   if (bsid == 0)
8633     {
8634       errmsg ("bsid not set");
8635       return -99;
8636     }
8637
8638   /* Construct the API message */
8639   M (SR_MPLS_POLICY_DEL, mp);
8640
8641   mp->bsid = htonl (bsid);
8642
8643   /* send it... */
8644   S (mp);
8645
8646   /* Wait for a reply... */
8647   W (ret);
8648   return ret;
8649 }
8650
8651 static int
8652 api_bier_table_add_del (vat_main_t * vam)
8653 {
8654   unformat_input_t *i = vam->input;
8655   vl_api_bier_table_add_del_t *mp;
8656   u8 is_add = 1;
8657   u32 set = 0, sub_domain = 0, hdr_len = 3;
8658   mpls_label_t local_label = MPLS_LABEL_INVALID;
8659   int ret;
8660
8661   /* Parse args required to build the message */
8662   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8663     {
8664       if (unformat (i, "sub-domain %d", &sub_domain))
8665         ;
8666       else if (unformat (i, "set %d", &set))
8667         ;
8668       else if (unformat (i, "label %d", &local_label))
8669         ;
8670       else if (unformat (i, "hdr-len %d", &hdr_len))
8671         ;
8672       else if (unformat (i, "add"))
8673         is_add = 1;
8674       else if (unformat (i, "del"))
8675         is_add = 0;
8676       else
8677         {
8678           clib_warning ("parse error '%U'", format_unformat_error, i);
8679           return -99;
8680         }
8681     }
8682
8683   if (MPLS_LABEL_INVALID == local_label)
8684     {
8685       errmsg ("missing label\n");
8686       return -99;
8687     }
8688
8689   /* Construct the API message */
8690   M (BIER_TABLE_ADD_DEL, mp);
8691
8692   mp->bt_is_add = is_add;
8693   mp->bt_label = ntohl (local_label);
8694   mp->bt_tbl_id.bt_set = set;
8695   mp->bt_tbl_id.bt_sub_domain = sub_domain;
8696   mp->bt_tbl_id.bt_hdr_len_id = hdr_len;
8697
8698   /* send it... */
8699   S (mp);
8700
8701   /* Wait for a reply... */
8702   W (ret);
8703
8704   return (ret);
8705 }
8706
8707 static int
8708 api_bier_route_add_del (vat_main_t * vam)
8709 {
8710   unformat_input_t *i = vam->input;
8711   vl_api_bier_route_add_del_t *mp;
8712   u8 is_add = 1;
8713   u32 set = 0, sub_domain = 0, hdr_len = 3, bp = 0;
8714   ip4_address_t v4_next_hop_address;
8715   ip6_address_t v6_next_hop_address;
8716   u8 next_hop_set = 0;
8717   u8 next_hop_proto_is_ip4 = 1;
8718   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8719   int ret;
8720
8721   /* Parse args required to build the message */
8722   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8723     {
8724       if (unformat (i, "%U", unformat_ip4_address, &v4_next_hop_address))
8725         {
8726           next_hop_proto_is_ip4 = 1;
8727           next_hop_set = 1;
8728         }
8729       else if (unformat (i, "%U", unformat_ip6_address, &v6_next_hop_address))
8730         {
8731           next_hop_proto_is_ip4 = 0;
8732           next_hop_set = 1;
8733         }
8734       if (unformat (i, "sub-domain %d", &sub_domain))
8735         ;
8736       else if (unformat (i, "set %d", &set))
8737         ;
8738       else if (unformat (i, "hdr-len %d", &hdr_len))
8739         ;
8740       else if (unformat (i, "bp %d", &bp))
8741         ;
8742       else if (unformat (i, "add"))
8743         is_add = 1;
8744       else if (unformat (i, "del"))
8745         is_add = 0;
8746       else if (unformat (i, "out-label %d", &next_hop_out_label))
8747         ;
8748       else
8749         {
8750           clib_warning ("parse error '%U'", format_unformat_error, i);
8751           return -99;
8752         }
8753     }
8754
8755   if (!next_hop_set || (MPLS_LABEL_INVALID == next_hop_out_label))
8756     {
8757       errmsg ("next hop / label set\n");
8758       return -99;
8759     }
8760   if (0 == bp)
8761     {
8762       errmsg ("bit=position not set\n");
8763       return -99;
8764     }
8765
8766   /* Construct the API message */
8767   M2 (BIER_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t));
8768
8769   mp->br_is_add = is_add;
8770   mp->br_route.br_tbl_id.bt_set = set;
8771   mp->br_route.br_tbl_id.bt_sub_domain = sub_domain;
8772   mp->br_route.br_tbl_id.bt_hdr_len_id = hdr_len;
8773   mp->br_route.br_bp = ntohs (bp);
8774   mp->br_route.br_n_paths = 1;
8775   mp->br_route.br_paths[0].n_labels = 1;
8776   mp->br_route.br_paths[0].label_stack[0].label = ntohl (next_hop_out_label);
8777   mp->br_route.br_paths[0].proto = (next_hop_proto_is_ip4 ?
8778                                     FIB_API_PATH_NH_PROTO_IP4 :
8779                                     FIB_API_PATH_NH_PROTO_IP6);
8780
8781   if (next_hop_proto_is_ip4)
8782     {
8783       clib_memcpy (&mp->br_route.br_paths[0].nh.address.ip4,
8784                    &v4_next_hop_address, sizeof (v4_next_hop_address));
8785     }
8786   else
8787     {
8788       clib_memcpy (&mp->br_route.br_paths[0].nh.address.ip6,
8789                    &v6_next_hop_address, sizeof (v6_next_hop_address));
8790     }
8791
8792   /* send it... */
8793   S (mp);
8794
8795   /* Wait for a reply... */
8796   W (ret);
8797
8798   return (ret);
8799 }
8800
8801 static int
8802 api_proxy_arp_add_del (vat_main_t * vam)
8803 {
8804   unformat_input_t *i = vam->input;
8805   vl_api_proxy_arp_add_del_t *mp;
8806   u32 vrf_id = 0;
8807   u8 is_add = 1;
8808   vl_api_ip4_address_t lo, hi;
8809   u8 range_set = 0;
8810   int ret;
8811
8812   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8813     {
8814       if (unformat (i, "vrf %d", &vrf_id))
8815         ;
8816       else if (unformat (i, "%U - %U", unformat_vl_api_ip4_address, &lo,
8817                          unformat_vl_api_ip4_address, &hi))
8818         range_set = 1;
8819       else if (unformat (i, "del"))
8820         is_add = 0;
8821       else
8822         {
8823           clib_warning ("parse error '%U'", format_unformat_error, i);
8824           return -99;
8825         }
8826     }
8827
8828   if (range_set == 0)
8829     {
8830       errmsg ("address range not set");
8831       return -99;
8832     }
8833
8834   M (PROXY_ARP_ADD_DEL, mp);
8835
8836   mp->proxy.table_id = ntohl (vrf_id);
8837   mp->is_add = is_add;
8838   clib_memcpy (mp->proxy.low, &lo, sizeof (lo));
8839   clib_memcpy (mp->proxy.hi, &hi, sizeof (hi));
8840
8841   S (mp);
8842   W (ret);
8843   return ret;
8844 }
8845
8846 static int
8847 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
8848 {
8849   unformat_input_t *i = vam->input;
8850   vl_api_proxy_arp_intfc_enable_disable_t *mp;
8851   u32 sw_if_index;
8852   u8 enable = 1;
8853   u8 sw_if_index_set = 0;
8854   int ret;
8855
8856   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8857     {
8858       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8859         sw_if_index_set = 1;
8860       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8861         sw_if_index_set = 1;
8862       else if (unformat (i, "enable"))
8863         enable = 1;
8864       else if (unformat (i, "disable"))
8865         enable = 0;
8866       else
8867         {
8868           clib_warning ("parse error '%U'", format_unformat_error, i);
8869           return -99;
8870         }
8871     }
8872
8873   if (sw_if_index_set == 0)
8874     {
8875       errmsg ("missing interface name or sw_if_index");
8876       return -99;
8877     }
8878
8879   M (PROXY_ARP_INTFC_ENABLE_DISABLE, mp);
8880
8881   mp->sw_if_index = ntohl (sw_if_index);
8882   mp->enable_disable = enable;
8883
8884   S (mp);
8885   W (ret);
8886   return ret;
8887 }
8888
8889 static int
8890 api_mpls_tunnel_add_del (vat_main_t * vam)
8891 {
8892   unformat_input_t *i = vam->input;
8893   vl_api_mpls_tunnel_add_del_t *mp;
8894
8895   vl_api_fib_path_t paths[8];
8896   u32 sw_if_index = ~0;
8897   u8 path_count = 0;
8898   u8 l2_only = 0;
8899   u8 is_add = 1;
8900   int ret;
8901
8902   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8903     {
8904       if (unformat (i, "add"))
8905         is_add = 1;
8906       else
8907         if (unformat
8908             (i, "del %U", api_unformat_sw_if_index, vam, &sw_if_index))
8909         is_add = 0;
8910       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
8911         is_add = 0;
8912       else if (unformat (i, "l2-only"))
8913         l2_only = 1;
8914       else
8915         if (unformat
8916             (i, "via %U", unformat_fib_path, vam, &paths[path_count]))
8917         {
8918           path_count++;
8919           if (8 == path_count)
8920             {
8921               errmsg ("max 8 paths");
8922               return -99;
8923             }
8924         }
8925       else
8926         {
8927           clib_warning ("parse error '%U'", format_unformat_error, i);
8928           return -99;
8929         }
8930     }
8931
8932   M2 (MPLS_TUNNEL_ADD_DEL, mp, sizeof (vl_api_fib_path_t) * path_count);
8933
8934   mp->mt_is_add = is_add;
8935   mp->mt_tunnel.mt_sw_if_index = ntohl (sw_if_index);
8936   mp->mt_tunnel.mt_l2_only = l2_only;
8937   mp->mt_tunnel.mt_is_multicast = 0;
8938   mp->mt_tunnel.mt_n_paths = path_count;
8939
8940   clib_memcpy (&mp->mt_tunnel.mt_paths, &paths,
8941                sizeof (paths[0]) * path_count);
8942
8943   S (mp);
8944   W (ret);
8945   return ret;
8946 }
8947
8948 static int
8949 api_sw_interface_set_unnumbered (vat_main_t * vam)
8950 {
8951   unformat_input_t *i = vam->input;
8952   vl_api_sw_interface_set_unnumbered_t *mp;
8953   u32 sw_if_index;
8954   u32 unnum_sw_index = ~0;
8955   u8 is_add = 1;
8956   u8 sw_if_index_set = 0;
8957   int ret;
8958
8959   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8960     {
8961       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8962         sw_if_index_set = 1;
8963       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8964         sw_if_index_set = 1;
8965       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
8966         ;
8967       else if (unformat (i, "del"))
8968         is_add = 0;
8969       else
8970         {
8971           clib_warning ("parse error '%U'", format_unformat_error, i);
8972           return -99;
8973         }
8974     }
8975
8976   if (sw_if_index_set == 0)
8977     {
8978       errmsg ("missing interface name or sw_if_index");
8979       return -99;
8980     }
8981
8982   M (SW_INTERFACE_SET_UNNUMBERED, mp);
8983
8984   mp->sw_if_index = ntohl (sw_if_index);
8985   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
8986   mp->is_add = is_add;
8987
8988   S (mp);
8989   W (ret);
8990   return ret;
8991 }
8992
8993 static int
8994 api_ip_neighbor_add_del (vat_main_t * vam)
8995 {
8996   vl_api_mac_address_t mac_address;
8997   unformat_input_t *i = vam->input;
8998   vl_api_ip_neighbor_add_del_t *mp;
8999   vl_api_address_t ip_address;
9000   u32 sw_if_index;
9001   u8 sw_if_index_set = 0;
9002   u8 is_add = 1;
9003   u8 mac_set = 0;
9004   u8 address_set = 0;
9005   int ret;
9006   ip_neighbor_flags_t flags;
9007
9008   flags = IP_NEIGHBOR_FLAG_NONE;
9009   clib_memset (&ip_address, 0, sizeof (ip_address));
9010   clib_memset (&mac_address, 0, sizeof (mac_address));
9011
9012   /* Parse args required to build the message */
9013   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9014     {
9015       if (unformat (i, "mac %U", unformat_vl_api_mac_address, &mac_address))
9016         {
9017           mac_set = 1;
9018         }
9019       else if (unformat (i, "del"))
9020         is_add = 0;
9021       else
9022         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9023         sw_if_index_set = 1;
9024       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9025         sw_if_index_set = 1;
9026       else if (unformat (i, "static"))
9027         flags |= IP_NEIGHBOR_FLAG_STATIC;
9028       else if (unformat (i, "no-fib-entry"))
9029         flags |= IP_NEIGHBOR_FLAG_NO_FIB_ENTRY;
9030       else if (unformat (i, "dst %U", unformat_vl_api_address, &ip_address))
9031         address_set = 1;
9032       else
9033         {
9034           clib_warning ("parse error '%U'", format_unformat_error, i);
9035           return -99;
9036         }
9037     }
9038
9039   if (sw_if_index_set == 0)
9040     {
9041       errmsg ("missing interface name or sw_if_index");
9042       return -99;
9043     }
9044   if (!address_set)
9045     {
9046       errmsg ("no address set");
9047       return -99;
9048     }
9049
9050   /* Construct the API message */
9051   M (IP_NEIGHBOR_ADD_DEL, mp);
9052
9053   mp->neighbor.sw_if_index = ntohl (sw_if_index);
9054   mp->is_add = is_add;
9055   mp->neighbor.flags = htonl (flags);
9056   if (mac_set)
9057     clib_memcpy (&mp->neighbor.mac_address, &mac_address,
9058                  sizeof (mac_address));
9059   if (address_set)
9060     clib_memcpy (&mp->neighbor.ip_address, &ip_address, sizeof (ip_address));
9061
9062   /* send it... */
9063   S (mp);
9064
9065   /* Wait for a reply, return good/bad news  */
9066   W (ret);
9067   return ret;
9068 }
9069
9070 static int
9071 api_create_vlan_subif (vat_main_t * vam)
9072 {
9073   unformat_input_t *i = vam->input;
9074   vl_api_create_vlan_subif_t *mp;
9075   u32 sw_if_index;
9076   u8 sw_if_index_set = 0;
9077   u32 vlan_id;
9078   u8 vlan_id_set = 0;
9079   int ret;
9080
9081   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9082     {
9083       if (unformat (i, "sw_if_index %d", &sw_if_index))
9084         sw_if_index_set = 1;
9085       else
9086         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9087         sw_if_index_set = 1;
9088       else if (unformat (i, "vlan %d", &vlan_id))
9089         vlan_id_set = 1;
9090       else
9091         {
9092           clib_warning ("parse error '%U'", format_unformat_error, i);
9093           return -99;
9094         }
9095     }
9096
9097   if (sw_if_index_set == 0)
9098     {
9099       errmsg ("missing interface name or sw_if_index");
9100       return -99;
9101     }
9102
9103   if (vlan_id_set == 0)
9104     {
9105       errmsg ("missing vlan_id");
9106       return -99;
9107     }
9108   M (CREATE_VLAN_SUBIF, mp);
9109
9110   mp->sw_if_index = ntohl (sw_if_index);
9111   mp->vlan_id = ntohl (vlan_id);
9112
9113   S (mp);
9114   W (ret);
9115   return ret;
9116 }
9117
9118 #define foreach_create_subif_bit                \
9119 _(no_tags)                                      \
9120 _(one_tag)                                      \
9121 _(two_tags)                                     \
9122 _(dot1ad)                                       \
9123 _(exact_match)                                  \
9124 _(default_sub)                                  \
9125 _(outer_vlan_id_any)                            \
9126 _(inner_vlan_id_any)
9127
9128 #define foreach_create_subif_flag               \
9129 _(0, "no_tags")                                 \
9130 _(1, "one_tag")                                 \
9131 _(2, "two_tags")                                \
9132 _(3, "dot1ad")                                  \
9133 _(4, "exact_match")                             \
9134 _(5, "default_sub")                             \
9135 _(6, "outer_vlan_id_any")                       \
9136 _(7, "inner_vlan_id_any")
9137
9138 static int
9139 api_create_subif (vat_main_t * vam)
9140 {
9141   unformat_input_t *i = vam->input;
9142   vl_api_create_subif_t *mp;
9143   u32 sw_if_index;
9144   u8 sw_if_index_set = 0;
9145   u32 sub_id;
9146   u8 sub_id_set = 0;
9147   u32 __attribute__ ((unused)) no_tags = 0;
9148   u32 __attribute__ ((unused)) one_tag = 0;
9149   u32 __attribute__ ((unused)) two_tags = 0;
9150   u32 __attribute__ ((unused)) dot1ad = 0;
9151   u32 __attribute__ ((unused)) exact_match = 0;
9152   u32 __attribute__ ((unused)) default_sub = 0;
9153   u32 __attribute__ ((unused)) outer_vlan_id_any = 0;
9154   u32 __attribute__ ((unused)) inner_vlan_id_any = 0;
9155   u32 tmp;
9156   u16 outer_vlan_id = 0;
9157   u16 inner_vlan_id = 0;
9158   int ret;
9159
9160   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9161     {
9162       if (unformat (i, "sw_if_index %d", &sw_if_index))
9163         sw_if_index_set = 1;
9164       else
9165         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9166         sw_if_index_set = 1;
9167       else if (unformat (i, "sub_id %d", &sub_id))
9168         sub_id_set = 1;
9169       else if (unformat (i, "outer_vlan_id %d", &tmp))
9170         outer_vlan_id = tmp;
9171       else if (unformat (i, "inner_vlan_id %d", &tmp))
9172         inner_vlan_id = tmp;
9173
9174 #define _(a) else if (unformat (i, #a)) a = 1 ;
9175       foreach_create_subif_bit
9176 #undef _
9177         else
9178         {
9179           clib_warning ("parse error '%U'", format_unformat_error, i);
9180           return -99;
9181         }
9182     }
9183
9184   if (sw_if_index_set == 0)
9185     {
9186       errmsg ("missing interface name or sw_if_index");
9187       return -99;
9188     }
9189
9190   if (sub_id_set == 0)
9191     {
9192       errmsg ("missing sub_id");
9193       return -99;
9194     }
9195   M (CREATE_SUBIF, mp);
9196
9197   mp->sw_if_index = ntohl (sw_if_index);
9198   mp->sub_id = ntohl (sub_id);
9199
9200 #define _(a,b) mp->sub_if_flags |= (1 << a);
9201   foreach_create_subif_flag;
9202 #undef _
9203
9204   mp->outer_vlan_id = ntohs (outer_vlan_id);
9205   mp->inner_vlan_id = ntohs (inner_vlan_id);
9206
9207   S (mp);
9208   W (ret);
9209   return ret;
9210 }
9211
9212 static int
9213 api_reset_fib (vat_main_t * vam)
9214 {
9215   unformat_input_t *i = vam->input;
9216   vl_api_reset_fib_t *mp;
9217   u32 vrf_id = 0;
9218   u8 is_ipv6 = 0;
9219   u8 vrf_id_set = 0;
9220
9221   int ret;
9222   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9223     {
9224       if (unformat (i, "vrf %d", &vrf_id))
9225         vrf_id_set = 1;
9226       else if (unformat (i, "ipv6"))
9227         is_ipv6 = 1;
9228       else
9229         {
9230           clib_warning ("parse error '%U'", format_unformat_error, i);
9231           return -99;
9232         }
9233     }
9234
9235   if (vrf_id_set == 0)
9236     {
9237       errmsg ("missing vrf id");
9238       return -99;
9239     }
9240
9241   M (RESET_FIB, mp);
9242
9243   mp->vrf_id = ntohl (vrf_id);
9244   mp->is_ipv6 = is_ipv6;
9245
9246   S (mp);
9247   W (ret);
9248   return ret;
9249 }
9250
9251 static int
9252 api_set_ip_flow_hash (vat_main_t * vam)
9253 {
9254   unformat_input_t *i = vam->input;
9255   vl_api_set_ip_flow_hash_t *mp;
9256   u32 vrf_id = 0;
9257   u8 is_ipv6 = 0;
9258   u8 vrf_id_set = 0;
9259   u8 src = 0;
9260   u8 dst = 0;
9261   u8 sport = 0;
9262   u8 dport = 0;
9263   u8 proto = 0;
9264   u8 reverse = 0;
9265   int ret;
9266
9267   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9268     {
9269       if (unformat (i, "vrf %d", &vrf_id))
9270         vrf_id_set = 1;
9271       else if (unformat (i, "ipv6"))
9272         is_ipv6 = 1;
9273       else if (unformat (i, "src"))
9274         src = 1;
9275       else if (unformat (i, "dst"))
9276         dst = 1;
9277       else if (unformat (i, "sport"))
9278         sport = 1;
9279       else if (unformat (i, "dport"))
9280         dport = 1;
9281       else if (unformat (i, "proto"))
9282         proto = 1;
9283       else if (unformat (i, "reverse"))
9284         reverse = 1;
9285
9286       else
9287         {
9288           clib_warning ("parse error '%U'", format_unformat_error, i);
9289           return -99;
9290         }
9291     }
9292
9293   if (vrf_id_set == 0)
9294     {
9295       errmsg ("missing vrf id");
9296       return -99;
9297     }
9298
9299   M (SET_IP_FLOW_HASH, mp);
9300   mp->src = src;
9301   mp->dst = dst;
9302   mp->sport = sport;
9303   mp->dport = dport;
9304   mp->proto = proto;
9305   mp->reverse = reverse;
9306   mp->vrf_id = ntohl (vrf_id);
9307   mp->is_ipv6 = is_ipv6;
9308
9309   S (mp);
9310   W (ret);
9311   return ret;
9312 }
9313
9314 static int
9315 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
9316 {
9317   unformat_input_t *i = vam->input;
9318   vl_api_sw_interface_ip6_enable_disable_t *mp;
9319   u32 sw_if_index;
9320   u8 sw_if_index_set = 0;
9321   u8 enable = 0;
9322   int ret;
9323
9324   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9325     {
9326       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9327         sw_if_index_set = 1;
9328       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9329         sw_if_index_set = 1;
9330       else if (unformat (i, "enable"))
9331         enable = 1;
9332       else if (unformat (i, "disable"))
9333         enable = 0;
9334       else
9335         {
9336           clib_warning ("parse error '%U'", format_unformat_error, i);
9337           return -99;
9338         }
9339     }
9340
9341   if (sw_if_index_set == 0)
9342     {
9343       errmsg ("missing interface name or sw_if_index");
9344       return -99;
9345     }
9346
9347   M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
9348
9349   mp->sw_if_index = ntohl (sw_if_index);
9350   mp->enable = enable;
9351
9352   S (mp);
9353   W (ret);
9354   return ret;
9355 }
9356
9357 static int
9358 api_ip6nd_proxy_add_del (vat_main_t * vam)
9359 {
9360   unformat_input_t *i = vam->input;
9361   vl_api_ip6nd_proxy_add_del_t *mp;
9362   u32 sw_if_index = ~0;
9363   u8 v6_address_set = 0;
9364   vl_api_ip6_address_t v6address;
9365   u8 is_del = 0;
9366   int ret;
9367
9368   /* Parse args required to build the message */
9369   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9370     {
9371       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9372         ;
9373       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9374         ;
9375       else if (unformat (i, "%U", unformat_vl_api_ip6_address, &v6address))
9376         v6_address_set = 1;
9377       if (unformat (i, "del"))
9378         is_del = 1;
9379       else
9380         {
9381           clib_warning ("parse error '%U'", format_unformat_error, i);
9382           return -99;
9383         }
9384     }
9385
9386   if (sw_if_index == ~0)
9387     {
9388       errmsg ("missing interface name or sw_if_index");
9389       return -99;
9390     }
9391   if (!v6_address_set)
9392     {
9393       errmsg ("no address set");
9394       return -99;
9395     }
9396
9397   /* Construct the API message */
9398   M (IP6ND_PROXY_ADD_DEL, mp);
9399
9400   mp->is_del = is_del;
9401   mp->sw_if_index = ntohl (sw_if_index);
9402   clib_memcpy (mp->ip, v6address, sizeof (v6address));
9403
9404   /* send it... */
9405   S (mp);
9406
9407   /* Wait for a reply, return good/bad news  */
9408   W (ret);
9409   return ret;
9410 }
9411
9412 static int
9413 api_ip6nd_proxy_dump (vat_main_t * vam)
9414 {
9415   vl_api_ip6nd_proxy_dump_t *mp;
9416   vl_api_control_ping_t *mp_ping;
9417   int ret;
9418
9419   M (IP6ND_PROXY_DUMP, mp);
9420
9421   S (mp);
9422
9423   /* Use a control ping for synchronization */
9424   MPING (CONTROL_PING, mp_ping);
9425   S (mp_ping);
9426
9427   W (ret);
9428   return ret;
9429 }
9430
9431 static void vl_api_ip6nd_proxy_details_t_handler
9432   (vl_api_ip6nd_proxy_details_t * mp)
9433 {
9434   vat_main_t *vam = &vat_main;
9435
9436   print (vam->ofp, "host %U sw_if_index %d",
9437          format_vl_api_ip6_address, mp->ip, ntohl (mp->sw_if_index));
9438 }
9439
9440 static void vl_api_ip6nd_proxy_details_t_handler_json
9441   (vl_api_ip6nd_proxy_details_t * mp)
9442 {
9443   vat_main_t *vam = &vat_main;
9444   struct in6_addr ip6;
9445   vat_json_node_t *node = NULL;
9446
9447   if (VAT_JSON_ARRAY != vam->json_tree.type)
9448     {
9449       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9450       vat_json_init_array (&vam->json_tree);
9451     }
9452   node = vat_json_array_add (&vam->json_tree);
9453
9454   vat_json_init_object (node);
9455   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
9456
9457   clib_memcpy (&ip6, mp->ip, sizeof (ip6));
9458   vat_json_object_add_ip6 (node, "host", ip6);
9459 }
9460
9461 static int
9462 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
9463 {
9464   unformat_input_t *i = vam->input;
9465   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
9466   u32 sw_if_index;
9467   u8 sw_if_index_set = 0;
9468   u8 v6_address_set = 0;
9469   vl_api_prefix_t pfx;
9470   u8 use_default = 0;
9471   u8 no_advertise = 0;
9472   u8 off_link = 0;
9473   u8 no_autoconfig = 0;
9474   u8 no_onlink = 0;
9475   u8 is_no = 0;
9476   u32 val_lifetime = 0;
9477   u32 pref_lifetime = 0;
9478   int ret;
9479
9480   /* Parse args required to build the message */
9481   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9482     {
9483       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9484         sw_if_index_set = 1;
9485       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9486         sw_if_index_set = 1;
9487       else if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
9488         v6_address_set = 1;
9489       else if (unformat (i, "val_life %d", &val_lifetime))
9490         ;
9491       else if (unformat (i, "pref_life %d", &pref_lifetime))
9492         ;
9493       else if (unformat (i, "def"))
9494         use_default = 1;
9495       else if (unformat (i, "noadv"))
9496         no_advertise = 1;
9497       else if (unformat (i, "offl"))
9498         off_link = 1;
9499       else if (unformat (i, "noauto"))
9500         no_autoconfig = 1;
9501       else if (unformat (i, "nolink"))
9502         no_onlink = 1;
9503       else if (unformat (i, "isno"))
9504         is_no = 1;
9505       else
9506         {
9507           clib_warning ("parse error '%U'", format_unformat_error, i);
9508           return -99;
9509         }
9510     }
9511
9512   if (sw_if_index_set == 0)
9513     {
9514       errmsg ("missing interface name or sw_if_index");
9515       return -99;
9516     }
9517   if (!v6_address_set)
9518     {
9519       errmsg ("no address set");
9520       return -99;
9521     }
9522
9523   /* Construct the API message */
9524   M (SW_INTERFACE_IP6ND_RA_PREFIX, mp);
9525
9526   mp->sw_if_index = ntohl (sw_if_index);
9527   clib_memcpy (&mp->prefix, &pfx, sizeof (pfx));
9528   mp->use_default = use_default;
9529   mp->no_advertise = no_advertise;
9530   mp->off_link = off_link;
9531   mp->no_autoconfig = no_autoconfig;
9532   mp->no_onlink = no_onlink;
9533   mp->is_no = is_no;
9534   mp->val_lifetime = ntohl (val_lifetime);
9535   mp->pref_lifetime = ntohl (pref_lifetime);
9536
9537   /* send it... */
9538   S (mp);
9539
9540   /* Wait for a reply, return good/bad news  */
9541   W (ret);
9542   return ret;
9543 }
9544
9545 static int
9546 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
9547 {
9548   unformat_input_t *i = vam->input;
9549   vl_api_sw_interface_ip6nd_ra_config_t *mp;
9550   u32 sw_if_index;
9551   u8 sw_if_index_set = 0;
9552   u8 suppress = 0;
9553   u8 managed = 0;
9554   u8 other = 0;
9555   u8 ll_option = 0;
9556   u8 send_unicast = 0;
9557   u8 cease = 0;
9558   u8 is_no = 0;
9559   u8 default_router = 0;
9560   u32 max_interval = 0;
9561   u32 min_interval = 0;
9562   u32 lifetime = 0;
9563   u32 initial_count = 0;
9564   u32 initial_interval = 0;
9565   int ret;
9566
9567
9568   /* Parse args required to build the message */
9569   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9570     {
9571       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9572         sw_if_index_set = 1;
9573       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9574         sw_if_index_set = 1;
9575       else if (unformat (i, "maxint %d", &max_interval))
9576         ;
9577       else if (unformat (i, "minint %d", &min_interval))
9578         ;
9579       else if (unformat (i, "life %d", &lifetime))
9580         ;
9581       else if (unformat (i, "count %d", &initial_count))
9582         ;
9583       else if (unformat (i, "interval %d", &initial_interval))
9584         ;
9585       else if (unformat (i, "suppress") || unformat (i, "surpress"))
9586         suppress = 1;
9587       else if (unformat (i, "managed"))
9588         managed = 1;
9589       else if (unformat (i, "other"))
9590         other = 1;
9591       else if (unformat (i, "ll"))
9592         ll_option = 1;
9593       else if (unformat (i, "send"))
9594         send_unicast = 1;
9595       else if (unformat (i, "cease"))
9596         cease = 1;
9597       else if (unformat (i, "isno"))
9598         is_no = 1;
9599       else if (unformat (i, "def"))
9600         default_router = 1;
9601       else
9602         {
9603           clib_warning ("parse error '%U'", format_unformat_error, i);
9604           return -99;
9605         }
9606     }
9607
9608   if (sw_if_index_set == 0)
9609     {
9610       errmsg ("missing interface name or sw_if_index");
9611       return -99;
9612     }
9613
9614   /* Construct the API message */
9615   M (SW_INTERFACE_IP6ND_RA_CONFIG, mp);
9616
9617   mp->sw_if_index = ntohl (sw_if_index);
9618   mp->max_interval = ntohl (max_interval);
9619   mp->min_interval = ntohl (min_interval);
9620   mp->lifetime = ntohl (lifetime);
9621   mp->initial_count = ntohl (initial_count);
9622   mp->initial_interval = ntohl (initial_interval);
9623   mp->suppress = suppress;
9624   mp->managed = managed;
9625   mp->other = other;
9626   mp->ll_option = ll_option;
9627   mp->send_unicast = send_unicast;
9628   mp->cease = cease;
9629   mp->is_no = is_no;
9630   mp->default_router = default_router;
9631
9632   /* send it... */
9633   S (mp);
9634
9635   /* Wait for a reply, return good/bad news  */
9636   W (ret);
9637   return ret;
9638 }
9639
9640 static int
9641 api_set_arp_neighbor_limit (vat_main_t * vam)
9642 {
9643   unformat_input_t *i = vam->input;
9644   vl_api_set_arp_neighbor_limit_t *mp;
9645   u32 arp_nbr_limit;
9646   u8 limit_set = 0;
9647   u8 is_ipv6 = 0;
9648   int ret;
9649
9650   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9651     {
9652       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
9653         limit_set = 1;
9654       else if (unformat (i, "ipv6"))
9655         is_ipv6 = 1;
9656       else
9657         {
9658           clib_warning ("parse error '%U'", format_unformat_error, i);
9659           return -99;
9660         }
9661     }
9662
9663   if (limit_set == 0)
9664     {
9665       errmsg ("missing limit value");
9666       return -99;
9667     }
9668
9669   M (SET_ARP_NEIGHBOR_LIMIT, mp);
9670
9671   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
9672   mp->is_ipv6 = is_ipv6;
9673
9674   S (mp);
9675   W (ret);
9676   return ret;
9677 }
9678
9679 static int
9680 api_l2_patch_add_del (vat_main_t * vam)
9681 {
9682   unformat_input_t *i = vam->input;
9683   vl_api_l2_patch_add_del_t *mp;
9684   u32 rx_sw_if_index;
9685   u8 rx_sw_if_index_set = 0;
9686   u32 tx_sw_if_index;
9687   u8 tx_sw_if_index_set = 0;
9688   u8 is_add = 1;
9689   int ret;
9690
9691   /* Parse args required to build the message */
9692   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9693     {
9694       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
9695         rx_sw_if_index_set = 1;
9696       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
9697         tx_sw_if_index_set = 1;
9698       else if (unformat (i, "rx"))
9699         {
9700           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9701             {
9702               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
9703                             &rx_sw_if_index))
9704                 rx_sw_if_index_set = 1;
9705             }
9706           else
9707             break;
9708         }
9709       else if (unformat (i, "tx"))
9710         {
9711           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9712             {
9713               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
9714                             &tx_sw_if_index))
9715                 tx_sw_if_index_set = 1;
9716             }
9717           else
9718             break;
9719         }
9720       else if (unformat (i, "del"))
9721         is_add = 0;
9722       else
9723         break;
9724     }
9725
9726   if (rx_sw_if_index_set == 0)
9727     {
9728       errmsg ("missing rx interface name or rx_sw_if_index");
9729       return -99;
9730     }
9731
9732   if (tx_sw_if_index_set == 0)
9733     {
9734       errmsg ("missing tx interface name or tx_sw_if_index");
9735       return -99;
9736     }
9737
9738   M (L2_PATCH_ADD_DEL, mp);
9739
9740   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
9741   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
9742   mp->is_add = is_add;
9743
9744   S (mp);
9745   W (ret);
9746   return ret;
9747 }
9748
9749 u8 is_del;
9750 u8 localsid_addr[16];
9751 u8 end_psp;
9752 u8 behavior;
9753 u32 sw_if_index;
9754 u32 vlan_index;
9755 u32 fib_table;
9756 u8 nh_addr[16];
9757
9758 static int
9759 api_sr_localsid_add_del (vat_main_t * vam)
9760 {
9761   unformat_input_t *i = vam->input;
9762   vl_api_sr_localsid_add_del_t *mp;
9763
9764   u8 is_del;
9765   ip6_address_t localsid;
9766   u8 end_psp = 0;
9767   u8 behavior = ~0;
9768   u32 sw_if_index;
9769   u32 fib_table = ~(u32) 0;
9770   ip6_address_t nh_addr6;
9771   ip4_address_t nh_addr4;
9772   clib_memset (&nh_addr6, 0, sizeof (ip6_address_t));
9773   clib_memset (&nh_addr4, 0, sizeof (ip4_address_t));
9774
9775   bool nexthop_set = 0;
9776
9777   int ret;
9778
9779   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9780     {
9781       if (unformat (i, "del"))
9782         is_del = 1;
9783       else if (unformat (i, "address %U", unformat_ip6_address, &localsid));
9784       else if (unformat (i, "next-hop %U", unformat_ip4_address, &nh_addr4))
9785         nexthop_set = 1;
9786       else if (unformat (i, "next-hop %U", unformat_ip6_address, &nh_addr6))
9787         nexthop_set = 1;
9788       else if (unformat (i, "behavior %u", &behavior));
9789       else if (unformat (i, "sw_if_index %u", &sw_if_index));
9790       else if (unformat (i, "fib-table %u", &fib_table));
9791       else if (unformat (i, "end.psp %u", &behavior));
9792       else
9793         break;
9794     }
9795
9796   M (SR_LOCALSID_ADD_DEL, mp);
9797
9798   clib_memcpy (mp->localsid.addr, &localsid, sizeof (mp->localsid));
9799
9800   if (nexthop_set)
9801     {
9802       clib_memcpy (mp->nh_addr6, &nh_addr6, sizeof (mp->nh_addr6));
9803       clib_memcpy (mp->nh_addr4, &nh_addr4, sizeof (mp->nh_addr4));
9804     }
9805   mp->behavior = behavior;
9806   mp->sw_if_index = ntohl (sw_if_index);
9807   mp->fib_table = ntohl (fib_table);
9808   mp->end_psp = end_psp;
9809   mp->is_del = is_del;
9810
9811   S (mp);
9812   W (ret);
9813   return ret;
9814 }
9815
9816 static int
9817 api_ioam_enable (vat_main_t * vam)
9818 {
9819   unformat_input_t *input = vam->input;
9820   vl_api_ioam_enable_t *mp;
9821   u32 id = 0;
9822   int has_trace_option = 0;
9823   int has_pot_option = 0;
9824   int has_seqno_option = 0;
9825   int has_analyse_option = 0;
9826   int ret;
9827
9828   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9829     {
9830       if (unformat (input, "trace"))
9831         has_trace_option = 1;
9832       else if (unformat (input, "pot"))
9833         has_pot_option = 1;
9834       else if (unformat (input, "seqno"))
9835         has_seqno_option = 1;
9836       else if (unformat (input, "analyse"))
9837         has_analyse_option = 1;
9838       else
9839         break;
9840     }
9841   M (IOAM_ENABLE, mp);
9842   mp->id = htons (id);
9843   mp->seqno = has_seqno_option;
9844   mp->analyse = has_analyse_option;
9845   mp->pot_enable = has_pot_option;
9846   mp->trace_enable = has_trace_option;
9847
9848   S (mp);
9849   W (ret);
9850   return ret;
9851 }
9852
9853
9854 static int
9855 api_ioam_disable (vat_main_t * vam)
9856 {
9857   vl_api_ioam_disable_t *mp;
9858   int ret;
9859
9860   M (IOAM_DISABLE, mp);
9861   S (mp);
9862   W (ret);
9863   return ret;
9864 }
9865
9866 #define foreach_tcp_proto_field                 \
9867 _(src_port)                                     \
9868 _(dst_port)
9869
9870 #define foreach_udp_proto_field                 \
9871 _(src_port)                                     \
9872 _(dst_port)
9873
9874 #define foreach_ip4_proto_field                 \
9875 _(src_address)                                  \
9876 _(dst_address)                                  \
9877 _(tos)                                          \
9878 _(length)                                       \
9879 _(fragment_id)                                  \
9880 _(ttl)                                          \
9881 _(protocol)                                     \
9882 _(checksum)
9883
9884 typedef struct
9885 {
9886   u16 src_port, dst_port;
9887 } tcpudp_header_t;
9888
9889 #if VPP_API_TEST_BUILTIN == 0
9890 uword
9891 unformat_tcp_mask (unformat_input_t * input, va_list * args)
9892 {
9893   u8 **maskp = va_arg (*args, u8 **);
9894   u8 *mask = 0;
9895   u8 found_something = 0;
9896   tcp_header_t *tcp;
9897
9898 #define _(a) u8 a=0;
9899   foreach_tcp_proto_field;
9900 #undef _
9901
9902   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9903     {
9904       if (0);
9905 #define _(a) else if (unformat (input, #a)) a=1;
9906       foreach_tcp_proto_field
9907 #undef _
9908         else
9909         break;
9910     }
9911
9912 #define _(a) found_something += a;
9913   foreach_tcp_proto_field;
9914 #undef _
9915
9916   if (found_something == 0)
9917     return 0;
9918
9919   vec_validate (mask, sizeof (*tcp) - 1);
9920
9921   tcp = (tcp_header_t *) mask;
9922
9923 #define _(a) if (a) clib_memset (&tcp->a, 0xff, sizeof (tcp->a));
9924   foreach_tcp_proto_field;
9925 #undef _
9926
9927   *maskp = mask;
9928   return 1;
9929 }
9930
9931 uword
9932 unformat_udp_mask (unformat_input_t * input, va_list * args)
9933 {
9934   u8 **maskp = va_arg (*args, u8 **);
9935   u8 *mask = 0;
9936   u8 found_something = 0;
9937   udp_header_t *udp;
9938
9939 #define _(a) u8 a=0;
9940   foreach_udp_proto_field;
9941 #undef _
9942
9943   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9944     {
9945       if (0);
9946 #define _(a) else if (unformat (input, #a)) a=1;
9947       foreach_udp_proto_field
9948 #undef _
9949         else
9950         break;
9951     }
9952
9953 #define _(a) found_something += a;
9954   foreach_udp_proto_field;
9955 #undef _
9956
9957   if (found_something == 0)
9958     return 0;
9959
9960   vec_validate (mask, sizeof (*udp) - 1);
9961
9962   udp = (udp_header_t *) mask;
9963
9964 #define _(a) if (a) clib_memset (&udp->a, 0xff, sizeof (udp->a));
9965   foreach_udp_proto_field;
9966 #undef _
9967
9968   *maskp = mask;
9969   return 1;
9970 }
9971
9972 uword
9973 unformat_l4_mask (unformat_input_t * input, va_list * args)
9974 {
9975   u8 **maskp = va_arg (*args, u8 **);
9976   u16 src_port = 0, dst_port = 0;
9977   tcpudp_header_t *tcpudp;
9978
9979   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9980     {
9981       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
9982         return 1;
9983       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
9984         return 1;
9985       else if (unformat (input, "src_port"))
9986         src_port = 0xFFFF;
9987       else if (unformat (input, "dst_port"))
9988         dst_port = 0xFFFF;
9989       else
9990         return 0;
9991     }
9992
9993   if (!src_port && !dst_port)
9994     return 0;
9995
9996   u8 *mask = 0;
9997   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
9998
9999   tcpudp = (tcpudp_header_t *) mask;
10000   tcpudp->src_port = src_port;
10001   tcpudp->dst_port = dst_port;
10002
10003   *maskp = mask;
10004
10005   return 1;
10006 }
10007
10008 uword
10009 unformat_ip4_mask (unformat_input_t * input, va_list * args)
10010 {
10011   u8 **maskp = va_arg (*args, u8 **);
10012   u8 *mask = 0;
10013   u8 found_something = 0;
10014   ip4_header_t *ip;
10015
10016 #define _(a) u8 a=0;
10017   foreach_ip4_proto_field;
10018 #undef _
10019   u8 version = 0;
10020   u8 hdr_length = 0;
10021
10022
10023   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10024     {
10025       if (unformat (input, "version"))
10026         version = 1;
10027       else if (unformat (input, "hdr_length"))
10028         hdr_length = 1;
10029       else if (unformat (input, "src"))
10030         src_address = 1;
10031       else if (unformat (input, "dst"))
10032         dst_address = 1;
10033       else if (unformat (input, "proto"))
10034         protocol = 1;
10035
10036 #define _(a) else if (unformat (input, #a)) a=1;
10037       foreach_ip4_proto_field
10038 #undef _
10039         else
10040         break;
10041     }
10042
10043 #define _(a) found_something += a;
10044   foreach_ip4_proto_field;
10045 #undef _
10046
10047   if (found_something == 0)
10048     return 0;
10049
10050   vec_validate (mask, sizeof (*ip) - 1);
10051
10052   ip = (ip4_header_t *) mask;
10053
10054 #define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
10055   foreach_ip4_proto_field;
10056 #undef _
10057
10058   ip->ip_version_and_header_length = 0;
10059
10060   if (version)
10061     ip->ip_version_and_header_length |= 0xF0;
10062
10063   if (hdr_length)
10064     ip->ip_version_and_header_length |= 0x0F;
10065
10066   *maskp = mask;
10067   return 1;
10068 }
10069
10070 #define foreach_ip6_proto_field                 \
10071 _(src_address)                                  \
10072 _(dst_address)                                  \
10073 _(payload_length)                               \
10074 _(hop_limit)                                    \
10075 _(protocol)
10076
10077 uword
10078 unformat_ip6_mask (unformat_input_t * input, va_list * args)
10079 {
10080   u8 **maskp = va_arg (*args, u8 **);
10081   u8 *mask = 0;
10082   u8 found_something = 0;
10083   ip6_header_t *ip;
10084   u32 ip_version_traffic_class_and_flow_label;
10085
10086 #define _(a) u8 a=0;
10087   foreach_ip6_proto_field;
10088 #undef _
10089   u8 version = 0;
10090   u8 traffic_class = 0;
10091   u8 flow_label = 0;
10092
10093   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10094     {
10095       if (unformat (input, "version"))
10096         version = 1;
10097       else if (unformat (input, "traffic-class"))
10098         traffic_class = 1;
10099       else if (unformat (input, "flow-label"))
10100         flow_label = 1;
10101       else if (unformat (input, "src"))
10102         src_address = 1;
10103       else if (unformat (input, "dst"))
10104         dst_address = 1;
10105       else if (unformat (input, "proto"))
10106         protocol = 1;
10107
10108 #define _(a) else if (unformat (input, #a)) a=1;
10109       foreach_ip6_proto_field
10110 #undef _
10111         else
10112         break;
10113     }
10114
10115 #define _(a) found_something += a;
10116   foreach_ip6_proto_field;
10117 #undef _
10118
10119   if (found_something == 0)
10120     return 0;
10121
10122   vec_validate (mask, sizeof (*ip) - 1);
10123
10124   ip = (ip6_header_t *) mask;
10125
10126 #define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
10127   foreach_ip6_proto_field;
10128 #undef _
10129
10130   ip_version_traffic_class_and_flow_label = 0;
10131
10132   if (version)
10133     ip_version_traffic_class_and_flow_label |= 0xF0000000;
10134
10135   if (traffic_class)
10136     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
10137
10138   if (flow_label)
10139     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
10140
10141   ip->ip_version_traffic_class_and_flow_label =
10142     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
10143
10144   *maskp = mask;
10145   return 1;
10146 }
10147
10148 uword
10149 unformat_l3_mask (unformat_input_t * input, va_list * args)
10150 {
10151   u8 **maskp = va_arg (*args, u8 **);
10152
10153   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10154     {
10155       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
10156         return 1;
10157       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
10158         return 1;
10159       else
10160         break;
10161     }
10162   return 0;
10163 }
10164
10165 uword
10166 unformat_l2_mask (unformat_input_t * input, va_list * args)
10167 {
10168   u8 **maskp = va_arg (*args, u8 **);
10169   u8 *mask = 0;
10170   u8 src = 0;
10171   u8 dst = 0;
10172   u8 proto = 0;
10173   u8 tag1 = 0;
10174   u8 tag2 = 0;
10175   u8 ignore_tag1 = 0;
10176   u8 ignore_tag2 = 0;
10177   u8 cos1 = 0;
10178   u8 cos2 = 0;
10179   u8 dot1q = 0;
10180   u8 dot1ad = 0;
10181   int len = 14;
10182
10183   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10184     {
10185       if (unformat (input, "src"))
10186         src = 1;
10187       else if (unformat (input, "dst"))
10188         dst = 1;
10189       else if (unformat (input, "proto"))
10190         proto = 1;
10191       else if (unformat (input, "tag1"))
10192         tag1 = 1;
10193       else if (unformat (input, "tag2"))
10194         tag2 = 1;
10195       else if (unformat (input, "ignore-tag1"))
10196         ignore_tag1 = 1;
10197       else if (unformat (input, "ignore-tag2"))
10198         ignore_tag2 = 1;
10199       else if (unformat (input, "cos1"))
10200         cos1 = 1;
10201       else if (unformat (input, "cos2"))
10202         cos2 = 1;
10203       else if (unformat (input, "dot1q"))
10204         dot1q = 1;
10205       else if (unformat (input, "dot1ad"))
10206         dot1ad = 1;
10207       else
10208         break;
10209     }
10210   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
10211        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
10212     return 0;
10213
10214   if (tag1 || ignore_tag1 || cos1 || dot1q)
10215     len = 18;
10216   if (tag2 || ignore_tag2 || cos2 || dot1ad)
10217     len = 22;
10218
10219   vec_validate (mask, len - 1);
10220
10221   if (dst)
10222     clib_memset (mask, 0xff, 6);
10223
10224   if (src)
10225     clib_memset (mask + 6, 0xff, 6);
10226
10227   if (tag2 || dot1ad)
10228     {
10229       /* inner vlan tag */
10230       if (tag2)
10231         {
10232           mask[19] = 0xff;
10233           mask[18] = 0x0f;
10234         }
10235       if (cos2)
10236         mask[18] |= 0xe0;
10237       if (proto)
10238         mask[21] = mask[20] = 0xff;
10239       if (tag1)
10240         {
10241           mask[15] = 0xff;
10242           mask[14] = 0x0f;
10243         }
10244       if (cos1)
10245         mask[14] |= 0xe0;
10246       *maskp = mask;
10247       return 1;
10248     }
10249   if (tag1 | dot1q)
10250     {
10251       if (tag1)
10252         {
10253           mask[15] = 0xff;
10254           mask[14] = 0x0f;
10255         }
10256       if (cos1)
10257         mask[14] |= 0xe0;
10258       if (proto)
10259         mask[16] = mask[17] = 0xff;
10260
10261       *maskp = mask;
10262       return 1;
10263     }
10264   if (cos2)
10265     mask[18] |= 0xe0;
10266   if (cos1)
10267     mask[14] |= 0xe0;
10268   if (proto)
10269     mask[12] = mask[13] = 0xff;
10270
10271   *maskp = mask;
10272   return 1;
10273 }
10274
10275 uword
10276 unformat_classify_mask (unformat_input_t * input, va_list * args)
10277 {
10278   u8 **maskp = va_arg (*args, u8 **);
10279   u32 *skipp = va_arg (*args, u32 *);
10280   u32 *matchp = va_arg (*args, u32 *);
10281   u32 match;
10282   u8 *mask = 0;
10283   u8 *l2 = 0;
10284   u8 *l3 = 0;
10285   u8 *l4 = 0;
10286   int i;
10287
10288   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10289     {
10290       if (unformat (input, "hex %U", unformat_hex_string, &mask))
10291         ;
10292       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
10293         ;
10294       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
10295         ;
10296       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
10297         ;
10298       else
10299         break;
10300     }
10301
10302   if (l4 && !l3)
10303     {
10304       vec_free (mask);
10305       vec_free (l2);
10306       vec_free (l4);
10307       return 0;
10308     }
10309
10310   if (mask || l2 || l3 || l4)
10311     {
10312       if (l2 || l3 || l4)
10313         {
10314           /* "With a free Ethernet header in every package" */
10315           if (l2 == 0)
10316             vec_validate (l2, 13);
10317           mask = l2;
10318           if (vec_len (l3))
10319             {
10320               vec_append (mask, l3);
10321               vec_free (l3);
10322             }
10323           if (vec_len (l4))
10324             {
10325               vec_append (mask, l4);
10326               vec_free (l4);
10327             }
10328         }
10329
10330       /* Scan forward looking for the first significant mask octet */
10331       for (i = 0; i < vec_len (mask); i++)
10332         if (mask[i])
10333           break;
10334
10335       /* compute (skip, match) params */
10336       *skipp = i / sizeof (u32x4);
10337       vec_delete (mask, *skipp * sizeof (u32x4), 0);
10338
10339       /* Pad mask to an even multiple of the vector size */
10340       while (vec_len (mask) % sizeof (u32x4))
10341         vec_add1 (mask, 0);
10342
10343       match = vec_len (mask) / sizeof (u32x4);
10344
10345       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
10346         {
10347           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
10348           if (*tmp || *(tmp + 1))
10349             break;
10350           match--;
10351         }
10352       if (match == 0)
10353         clib_warning ("BUG: match 0");
10354
10355       _vec_len (mask) = match * sizeof (u32x4);
10356
10357       *matchp = match;
10358       *maskp = mask;
10359
10360       return 1;
10361     }
10362
10363   return 0;
10364 }
10365 #endif /* VPP_API_TEST_BUILTIN */
10366
10367 #define foreach_l2_next                         \
10368 _(drop, DROP)                                   \
10369 _(ethernet, ETHERNET_INPUT)                     \
10370 _(ip4, IP4_INPUT)                               \
10371 _(ip6, IP6_INPUT)
10372
10373 uword
10374 unformat_l2_next_index (unformat_input_t * input, va_list * args)
10375 {
10376   u32 *miss_next_indexp = va_arg (*args, u32 *);
10377   u32 next_index = 0;
10378   u32 tmp;
10379
10380 #define _(n,N) \
10381   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
10382   foreach_l2_next;
10383 #undef _
10384
10385   if (unformat (input, "%d", &tmp))
10386     {
10387       next_index = tmp;
10388       goto out;
10389     }
10390
10391   return 0;
10392
10393 out:
10394   *miss_next_indexp = next_index;
10395   return 1;
10396 }
10397
10398 #define foreach_ip_next                         \
10399 _(drop, DROP)                                   \
10400 _(local, LOCAL)                                 \
10401 _(rewrite, REWRITE)
10402
10403 uword
10404 api_unformat_ip_next_index (unformat_input_t * input, va_list * args)
10405 {
10406   u32 *miss_next_indexp = va_arg (*args, u32 *);
10407   u32 next_index = 0;
10408   u32 tmp;
10409
10410 #define _(n,N) \
10411   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
10412   foreach_ip_next;
10413 #undef _
10414
10415   if (unformat (input, "%d", &tmp))
10416     {
10417       next_index = tmp;
10418       goto out;
10419     }
10420
10421   return 0;
10422
10423 out:
10424   *miss_next_indexp = next_index;
10425   return 1;
10426 }
10427
10428 #define foreach_acl_next                        \
10429 _(deny, DENY)
10430
10431 uword
10432 api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
10433 {
10434   u32 *miss_next_indexp = va_arg (*args, u32 *);
10435   u32 next_index = 0;
10436   u32 tmp;
10437
10438 #define _(n,N) \
10439   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
10440   foreach_acl_next;
10441 #undef _
10442
10443   if (unformat (input, "permit"))
10444     {
10445       next_index = ~0;
10446       goto out;
10447     }
10448   else if (unformat (input, "%d", &tmp))
10449     {
10450       next_index = tmp;
10451       goto out;
10452     }
10453
10454   return 0;
10455
10456 out:
10457   *miss_next_indexp = next_index;
10458   return 1;
10459 }
10460
10461 uword
10462 unformat_policer_precolor (unformat_input_t * input, va_list * args)
10463 {
10464   u32 *r = va_arg (*args, u32 *);
10465
10466   if (unformat (input, "conform-color"))
10467     *r = POLICE_CONFORM;
10468   else if (unformat (input, "exceed-color"))
10469     *r = POLICE_EXCEED;
10470   else
10471     return 0;
10472
10473   return 1;
10474 }
10475
10476 static int
10477 api_classify_add_del_table (vat_main_t * vam)
10478 {
10479   unformat_input_t *i = vam->input;
10480   vl_api_classify_add_del_table_t *mp;
10481
10482   u32 nbuckets = 2;
10483   u32 skip = ~0;
10484   u32 match = ~0;
10485   int is_add = 1;
10486   int del_chain = 0;
10487   u32 table_index = ~0;
10488   u32 next_table_index = ~0;
10489   u32 miss_next_index = ~0;
10490   u32 memory_size = 32 << 20;
10491   u8 *mask = 0;
10492   u32 current_data_flag = 0;
10493   int current_data_offset = 0;
10494   int ret;
10495
10496   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10497     {
10498       if (unformat (i, "del"))
10499         is_add = 0;
10500       else if (unformat (i, "del-chain"))
10501         {
10502           is_add = 0;
10503           del_chain = 1;
10504         }
10505       else if (unformat (i, "buckets %d", &nbuckets))
10506         ;
10507       else if (unformat (i, "memory_size %d", &memory_size))
10508         ;
10509       else if (unformat (i, "skip %d", &skip))
10510         ;
10511       else if (unformat (i, "match %d", &match))
10512         ;
10513       else if (unformat (i, "table %d", &table_index))
10514         ;
10515       else if (unformat (i, "mask %U", unformat_classify_mask,
10516                          &mask, &skip, &match))
10517         ;
10518       else if (unformat (i, "next-table %d", &next_table_index))
10519         ;
10520       else if (unformat (i, "miss-next %U", api_unformat_ip_next_index,
10521                          &miss_next_index))
10522         ;
10523       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
10524                          &miss_next_index))
10525         ;
10526       else if (unformat (i, "acl-miss-next %U", api_unformat_acl_next_index,
10527                          &miss_next_index))
10528         ;
10529       else if (unformat (i, "current-data-flag %d", &current_data_flag))
10530         ;
10531       else if (unformat (i, "current-data-offset %d", &current_data_offset))
10532         ;
10533       else
10534         break;
10535     }
10536
10537   if (is_add && mask == 0)
10538     {
10539       errmsg ("Mask required");
10540       return -99;
10541     }
10542
10543   if (is_add && skip == ~0)
10544     {
10545       errmsg ("skip count required");
10546       return -99;
10547     }
10548
10549   if (is_add && match == ~0)
10550     {
10551       errmsg ("match count required");
10552       return -99;
10553     }
10554
10555   if (!is_add && table_index == ~0)
10556     {
10557       errmsg ("table index required for delete");
10558       return -99;
10559     }
10560
10561   M2 (CLASSIFY_ADD_DEL_TABLE, mp, vec_len (mask));
10562
10563   mp->is_add = is_add;
10564   mp->del_chain = del_chain;
10565   mp->table_index = ntohl (table_index);
10566   mp->nbuckets = ntohl (nbuckets);
10567   mp->memory_size = ntohl (memory_size);
10568   mp->skip_n_vectors = ntohl (skip);
10569   mp->match_n_vectors = ntohl (match);
10570   mp->next_table_index = ntohl (next_table_index);
10571   mp->miss_next_index = ntohl (miss_next_index);
10572   mp->current_data_flag = ntohl (current_data_flag);
10573   mp->current_data_offset = ntohl (current_data_offset);
10574   mp->mask_len = ntohl (vec_len (mask));
10575   clib_memcpy (mp->mask, mask, vec_len (mask));
10576
10577   vec_free (mask);
10578
10579   S (mp);
10580   W (ret);
10581   return ret;
10582 }
10583
10584 #if VPP_API_TEST_BUILTIN == 0
10585 uword
10586 unformat_l4_match (unformat_input_t * input, va_list * args)
10587 {
10588   u8 **matchp = va_arg (*args, u8 **);
10589
10590   u8 *proto_header = 0;
10591   int src_port = 0;
10592   int dst_port = 0;
10593
10594   tcpudp_header_t h;
10595
10596   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10597     {
10598       if (unformat (input, "src_port %d", &src_port))
10599         ;
10600       else if (unformat (input, "dst_port %d", &dst_port))
10601         ;
10602       else
10603         return 0;
10604     }
10605
10606   h.src_port = clib_host_to_net_u16 (src_port);
10607   h.dst_port = clib_host_to_net_u16 (dst_port);
10608   vec_validate (proto_header, sizeof (h) - 1);
10609   memcpy (proto_header, &h, sizeof (h));
10610
10611   *matchp = proto_header;
10612
10613   return 1;
10614 }
10615
10616 uword
10617 unformat_ip4_match (unformat_input_t * input, va_list * args)
10618 {
10619   u8 **matchp = va_arg (*args, u8 **);
10620   u8 *match = 0;
10621   ip4_header_t *ip;
10622   int version = 0;
10623   u32 version_val;
10624   int hdr_length = 0;
10625   u32 hdr_length_val;
10626   int src = 0, dst = 0;
10627   ip4_address_t src_val, dst_val;
10628   int proto = 0;
10629   u32 proto_val;
10630   int tos = 0;
10631   u32 tos_val;
10632   int length = 0;
10633   u32 length_val;
10634   int fragment_id = 0;
10635   u32 fragment_id_val;
10636   int ttl = 0;
10637   int ttl_val;
10638   int checksum = 0;
10639   u32 checksum_val;
10640
10641   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10642     {
10643       if (unformat (input, "version %d", &version_val))
10644         version = 1;
10645       else if (unformat (input, "hdr_length %d", &hdr_length_val))
10646         hdr_length = 1;
10647       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
10648         src = 1;
10649       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
10650         dst = 1;
10651       else if (unformat (input, "proto %d", &proto_val))
10652         proto = 1;
10653       else if (unformat (input, "tos %d", &tos_val))
10654         tos = 1;
10655       else if (unformat (input, "length %d", &length_val))
10656         length = 1;
10657       else if (unformat (input, "fragment_id %d", &fragment_id_val))
10658         fragment_id = 1;
10659       else if (unformat (input, "ttl %d", &ttl_val))
10660         ttl = 1;
10661       else if (unformat (input, "checksum %d", &checksum_val))
10662         checksum = 1;
10663       else
10664         break;
10665     }
10666
10667   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
10668       + ttl + checksum == 0)
10669     return 0;
10670
10671   /*
10672    * Aligned because we use the real comparison functions
10673    */
10674   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
10675
10676   ip = (ip4_header_t *) match;
10677
10678   /* These are realistically matched in practice */
10679   if (src)
10680     ip->src_address.as_u32 = src_val.as_u32;
10681
10682   if (dst)
10683     ip->dst_address.as_u32 = dst_val.as_u32;
10684
10685   if (proto)
10686     ip->protocol = proto_val;
10687
10688
10689   /* These are not, but they're included for completeness */
10690   if (version)
10691     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
10692
10693   if (hdr_length)
10694     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
10695
10696   if (tos)
10697     ip->tos = tos_val;
10698
10699   if (length)
10700     ip->length = clib_host_to_net_u16 (length_val);
10701
10702   if (ttl)
10703     ip->ttl = ttl_val;
10704
10705   if (checksum)
10706     ip->checksum = clib_host_to_net_u16 (checksum_val);
10707
10708   *matchp = match;
10709   return 1;
10710 }
10711
10712 uword
10713 unformat_ip6_match (unformat_input_t * input, va_list * args)
10714 {
10715   u8 **matchp = va_arg (*args, u8 **);
10716   u8 *match = 0;
10717   ip6_header_t *ip;
10718   int version = 0;
10719   u32 version_val;
10720   u8 traffic_class = 0;
10721   u32 traffic_class_val = 0;
10722   u8 flow_label = 0;
10723   u8 flow_label_val;
10724   int src = 0, dst = 0;
10725   ip6_address_t src_val, dst_val;
10726   int proto = 0;
10727   u32 proto_val;
10728   int payload_length = 0;
10729   u32 payload_length_val;
10730   int hop_limit = 0;
10731   int hop_limit_val;
10732   u32 ip_version_traffic_class_and_flow_label;
10733
10734   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10735     {
10736       if (unformat (input, "version %d", &version_val))
10737         version = 1;
10738       else if (unformat (input, "traffic_class %d", &traffic_class_val))
10739         traffic_class = 1;
10740       else if (unformat (input, "flow_label %d", &flow_label_val))
10741         flow_label = 1;
10742       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
10743         src = 1;
10744       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
10745         dst = 1;
10746       else if (unformat (input, "proto %d", &proto_val))
10747         proto = 1;
10748       else if (unformat (input, "payload_length %d", &payload_length_val))
10749         payload_length = 1;
10750       else if (unformat (input, "hop_limit %d", &hop_limit_val))
10751         hop_limit = 1;
10752       else
10753         break;
10754     }
10755
10756   if (version + traffic_class + flow_label + src + dst + proto +
10757       payload_length + hop_limit == 0)
10758     return 0;
10759
10760   /*
10761    * Aligned because we use the real comparison functions
10762    */
10763   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
10764
10765   ip = (ip6_header_t *) match;
10766
10767   if (src)
10768     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
10769
10770   if (dst)
10771     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
10772
10773   if (proto)
10774     ip->protocol = proto_val;
10775
10776   ip_version_traffic_class_and_flow_label = 0;
10777
10778   if (version)
10779     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
10780
10781   if (traffic_class)
10782     ip_version_traffic_class_and_flow_label |=
10783       (traffic_class_val & 0xFF) << 20;
10784
10785   if (flow_label)
10786     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
10787
10788   ip->ip_version_traffic_class_and_flow_label =
10789     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
10790
10791   if (payload_length)
10792     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
10793
10794   if (hop_limit)
10795     ip->hop_limit = hop_limit_val;
10796
10797   *matchp = match;
10798   return 1;
10799 }
10800
10801 uword
10802 unformat_l3_match (unformat_input_t * input, va_list * args)
10803 {
10804   u8 **matchp = va_arg (*args, u8 **);
10805
10806   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10807     {
10808       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
10809         return 1;
10810       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
10811         return 1;
10812       else
10813         break;
10814     }
10815   return 0;
10816 }
10817
10818 uword
10819 unformat_vlan_tag (unformat_input_t * input, va_list * args)
10820 {
10821   u8 *tagp = va_arg (*args, u8 *);
10822   u32 tag;
10823
10824   if (unformat (input, "%d", &tag))
10825     {
10826       tagp[0] = (tag >> 8) & 0x0F;
10827       tagp[1] = tag & 0xFF;
10828       return 1;
10829     }
10830
10831   return 0;
10832 }
10833
10834 uword
10835 unformat_l2_match (unformat_input_t * input, va_list * args)
10836 {
10837   u8 **matchp = va_arg (*args, u8 **);
10838   u8 *match = 0;
10839   u8 src = 0;
10840   u8 src_val[6];
10841   u8 dst = 0;
10842   u8 dst_val[6];
10843   u8 proto = 0;
10844   u16 proto_val;
10845   u8 tag1 = 0;
10846   u8 tag1_val[2];
10847   u8 tag2 = 0;
10848   u8 tag2_val[2];
10849   int len = 14;
10850   u8 ignore_tag1 = 0;
10851   u8 ignore_tag2 = 0;
10852   u8 cos1 = 0;
10853   u8 cos2 = 0;
10854   u32 cos1_val = 0;
10855   u32 cos2_val = 0;
10856
10857   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10858     {
10859       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
10860         src = 1;
10861       else
10862         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
10863         dst = 1;
10864       else if (unformat (input, "proto %U",
10865                          unformat_ethernet_type_host_byte_order, &proto_val))
10866         proto = 1;
10867       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
10868         tag1 = 1;
10869       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
10870         tag2 = 1;
10871       else if (unformat (input, "ignore-tag1"))
10872         ignore_tag1 = 1;
10873       else if (unformat (input, "ignore-tag2"))
10874         ignore_tag2 = 1;
10875       else if (unformat (input, "cos1 %d", &cos1_val))
10876         cos1 = 1;
10877       else if (unformat (input, "cos2 %d", &cos2_val))
10878         cos2 = 1;
10879       else
10880         break;
10881     }
10882   if ((src + dst + proto + tag1 + tag2 +
10883        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
10884     return 0;
10885
10886   if (tag1 || ignore_tag1 || cos1)
10887     len = 18;
10888   if (tag2 || ignore_tag2 || cos2)
10889     len = 22;
10890
10891   vec_validate_aligned (match, len - 1, sizeof (u32x4));
10892
10893   if (dst)
10894     clib_memcpy (match, dst_val, 6);
10895
10896   if (src)
10897     clib_memcpy (match + 6, src_val, 6);
10898
10899   if (tag2)
10900     {
10901       /* inner vlan tag */
10902       match[19] = tag2_val[1];
10903       match[18] = tag2_val[0];
10904       if (cos2)
10905         match[18] |= (cos2_val & 0x7) << 5;
10906       if (proto)
10907         {
10908           match[21] = proto_val & 0xff;
10909           match[20] = proto_val >> 8;
10910         }
10911       if (tag1)
10912         {
10913           match[15] = tag1_val[1];
10914           match[14] = tag1_val[0];
10915         }
10916       if (cos1)
10917         match[14] |= (cos1_val & 0x7) << 5;
10918       *matchp = match;
10919       return 1;
10920     }
10921   if (tag1)
10922     {
10923       match[15] = tag1_val[1];
10924       match[14] = tag1_val[0];
10925       if (proto)
10926         {
10927           match[17] = proto_val & 0xff;
10928           match[16] = proto_val >> 8;
10929         }
10930       if (cos1)
10931         match[14] |= (cos1_val & 0x7) << 5;
10932
10933       *matchp = match;
10934       return 1;
10935     }
10936   if (cos2)
10937     match[18] |= (cos2_val & 0x7) << 5;
10938   if (cos1)
10939     match[14] |= (cos1_val & 0x7) << 5;
10940   if (proto)
10941     {
10942       match[13] = proto_val & 0xff;
10943       match[12] = proto_val >> 8;
10944     }
10945
10946   *matchp = match;
10947   return 1;
10948 }
10949
10950 uword
10951 unformat_qos_source (unformat_input_t * input, va_list * args)
10952 {
10953   int *qs = va_arg (*args, int *);
10954
10955   if (unformat (input, "ip"))
10956     *qs = QOS_SOURCE_IP;
10957   else if (unformat (input, "mpls"))
10958     *qs = QOS_SOURCE_MPLS;
10959   else if (unformat (input, "ext"))
10960     *qs = QOS_SOURCE_EXT;
10961   else if (unformat (input, "vlan"))
10962     *qs = QOS_SOURCE_VLAN;
10963   else
10964     return 0;
10965
10966   return 1;
10967 }
10968 #endif
10969
10970 uword
10971 api_unformat_classify_match (unformat_input_t * input, va_list * args)
10972 {
10973   u8 **matchp = va_arg (*args, u8 **);
10974   u32 skip_n_vectors = va_arg (*args, u32);
10975   u32 match_n_vectors = va_arg (*args, u32);
10976
10977   u8 *match = 0;
10978   u8 *l2 = 0;
10979   u8 *l3 = 0;
10980   u8 *l4 = 0;
10981
10982   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10983     {
10984       if (unformat (input, "hex %U", unformat_hex_string, &match))
10985         ;
10986       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
10987         ;
10988       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
10989         ;
10990       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
10991         ;
10992       else
10993         break;
10994     }
10995
10996   if (l4 && !l3)
10997     {
10998       vec_free (match);
10999       vec_free (l2);
11000       vec_free (l4);
11001       return 0;
11002     }
11003
11004   if (match || l2 || l3 || l4)
11005     {
11006       if (l2 || l3 || l4)
11007         {
11008           /* "Win a free Ethernet header in every packet" */
11009           if (l2 == 0)
11010             vec_validate_aligned (l2, 13, sizeof (u32x4));
11011           match = l2;
11012           if (vec_len (l3))
11013             {
11014               vec_append_aligned (match, l3, sizeof (u32x4));
11015               vec_free (l3);
11016             }
11017           if (vec_len (l4))
11018             {
11019               vec_append_aligned (match, l4, sizeof (u32x4));
11020               vec_free (l4);
11021             }
11022         }
11023
11024       /* Make sure the vector is big enough even if key is all 0's */
11025       vec_validate_aligned
11026         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
11027          sizeof (u32x4));
11028
11029       /* Set size, include skipped vectors */
11030       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
11031
11032       *matchp = match;
11033
11034       return 1;
11035     }
11036
11037   return 0;
11038 }
11039
11040 static int
11041 api_classify_add_del_session (vat_main_t * vam)
11042 {
11043   unformat_input_t *i = vam->input;
11044   vl_api_classify_add_del_session_t *mp;
11045   int is_add = 1;
11046   u32 table_index = ~0;
11047   u32 hit_next_index = ~0;
11048   u32 opaque_index = ~0;
11049   u8 *match = 0;
11050   i32 advance = 0;
11051   u32 skip_n_vectors = 0;
11052   u32 match_n_vectors = 0;
11053   u32 action = 0;
11054   u32 metadata = 0;
11055   int ret;
11056
11057   /*
11058    * Warning: you have to supply skip_n and match_n
11059    * because the API client cant simply look at the classify
11060    * table object.
11061    */
11062
11063   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11064     {
11065       if (unformat (i, "del"))
11066         is_add = 0;
11067       else if (unformat (i, "hit-next %U", api_unformat_ip_next_index,
11068                          &hit_next_index))
11069         ;
11070       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
11071                          &hit_next_index))
11072         ;
11073       else if (unformat (i, "acl-hit-next %U", api_unformat_acl_next_index,
11074                          &hit_next_index))
11075         ;
11076       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
11077         ;
11078       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
11079         ;
11080       else if (unformat (i, "opaque-index %d", &opaque_index))
11081         ;
11082       else if (unformat (i, "skip_n %d", &skip_n_vectors))
11083         ;
11084       else if (unformat (i, "match_n %d", &match_n_vectors))
11085         ;
11086       else if (unformat (i, "match %U", api_unformat_classify_match,
11087                          &match, skip_n_vectors, match_n_vectors))
11088         ;
11089       else if (unformat (i, "advance %d", &advance))
11090         ;
11091       else if (unformat (i, "table-index %d", &table_index))
11092         ;
11093       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
11094         action = 1;
11095       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
11096         action = 2;
11097       else if (unformat (i, "action %d", &action))
11098         ;
11099       else if (unformat (i, "metadata %d", &metadata))
11100         ;
11101       else
11102         break;
11103     }
11104
11105   if (table_index == ~0)
11106     {
11107       errmsg ("Table index required");
11108       return -99;
11109     }
11110
11111   if (is_add && match == 0)
11112     {
11113       errmsg ("Match value required");
11114       return -99;
11115     }
11116
11117   M2 (CLASSIFY_ADD_DEL_SESSION, mp, vec_len (match));
11118
11119   mp->is_add = is_add;
11120   mp->table_index = ntohl (table_index);
11121   mp->hit_next_index = ntohl (hit_next_index);
11122   mp->opaque_index = ntohl (opaque_index);
11123   mp->advance = ntohl (advance);
11124   mp->action = action;
11125   mp->metadata = ntohl (metadata);
11126   mp->match_len = ntohl (vec_len (match));
11127   clib_memcpy (mp->match, match, vec_len (match));
11128   vec_free (match);
11129
11130   S (mp);
11131   W (ret);
11132   return ret;
11133 }
11134
11135 static int
11136 api_classify_set_interface_ip_table (vat_main_t * vam)
11137 {
11138   unformat_input_t *i = vam->input;
11139   vl_api_classify_set_interface_ip_table_t *mp;
11140   u32 sw_if_index;
11141   int sw_if_index_set;
11142   u32 table_index = ~0;
11143   u8 is_ipv6 = 0;
11144   int ret;
11145
11146   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11147     {
11148       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11149         sw_if_index_set = 1;
11150       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11151         sw_if_index_set = 1;
11152       else if (unformat (i, "table %d", &table_index))
11153         ;
11154       else
11155         {
11156           clib_warning ("parse error '%U'", format_unformat_error, i);
11157           return -99;
11158         }
11159     }
11160
11161   if (sw_if_index_set == 0)
11162     {
11163       errmsg ("missing interface name or sw_if_index");
11164       return -99;
11165     }
11166
11167
11168   M (CLASSIFY_SET_INTERFACE_IP_TABLE, mp);
11169
11170   mp->sw_if_index = ntohl (sw_if_index);
11171   mp->table_index = ntohl (table_index);
11172   mp->is_ipv6 = is_ipv6;
11173
11174   S (mp);
11175   W (ret);
11176   return ret;
11177 }
11178
11179 static int
11180 api_classify_set_interface_l2_tables (vat_main_t * vam)
11181 {
11182   unformat_input_t *i = vam->input;
11183   vl_api_classify_set_interface_l2_tables_t *mp;
11184   u32 sw_if_index;
11185   int sw_if_index_set;
11186   u32 ip4_table_index = ~0;
11187   u32 ip6_table_index = ~0;
11188   u32 other_table_index = ~0;
11189   u32 is_input = 1;
11190   int ret;
11191
11192   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11193     {
11194       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11195         sw_if_index_set = 1;
11196       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11197         sw_if_index_set = 1;
11198       else if (unformat (i, "ip4-table %d", &ip4_table_index))
11199         ;
11200       else if (unformat (i, "ip6-table %d", &ip6_table_index))
11201         ;
11202       else if (unformat (i, "other-table %d", &other_table_index))
11203         ;
11204       else if (unformat (i, "is-input %d", &is_input))
11205         ;
11206       else
11207         {
11208           clib_warning ("parse error '%U'", format_unformat_error, i);
11209           return -99;
11210         }
11211     }
11212
11213   if (sw_if_index_set == 0)
11214     {
11215       errmsg ("missing interface name or sw_if_index");
11216       return -99;
11217     }
11218
11219
11220   M (CLASSIFY_SET_INTERFACE_L2_TABLES, mp);
11221
11222   mp->sw_if_index = ntohl (sw_if_index);
11223   mp->ip4_table_index = ntohl (ip4_table_index);
11224   mp->ip6_table_index = ntohl (ip6_table_index);
11225   mp->other_table_index = ntohl (other_table_index);
11226   mp->is_input = (u8) is_input;
11227
11228   S (mp);
11229   W (ret);
11230   return ret;
11231 }
11232
11233 static int
11234 api_set_ipfix_exporter (vat_main_t * vam)
11235 {
11236   unformat_input_t *i = vam->input;
11237   vl_api_set_ipfix_exporter_t *mp;
11238   ip4_address_t collector_address;
11239   u8 collector_address_set = 0;
11240   u32 collector_port = ~0;
11241   ip4_address_t src_address;
11242   u8 src_address_set = 0;
11243   u32 vrf_id = ~0;
11244   u32 path_mtu = ~0;
11245   u32 template_interval = ~0;
11246   u8 udp_checksum = 0;
11247   int ret;
11248
11249   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11250     {
11251       if (unformat (i, "collector_address %U", unformat_ip4_address,
11252                     &collector_address))
11253         collector_address_set = 1;
11254       else if (unformat (i, "collector_port %d", &collector_port))
11255         ;
11256       else if (unformat (i, "src_address %U", unformat_ip4_address,
11257                          &src_address))
11258         src_address_set = 1;
11259       else if (unformat (i, "vrf_id %d", &vrf_id))
11260         ;
11261       else if (unformat (i, "path_mtu %d", &path_mtu))
11262         ;
11263       else if (unformat (i, "template_interval %d", &template_interval))
11264         ;
11265       else if (unformat (i, "udp_checksum"))
11266         udp_checksum = 1;
11267       else
11268         break;
11269     }
11270
11271   if (collector_address_set == 0)
11272     {
11273       errmsg ("collector_address required");
11274       return -99;
11275     }
11276
11277   if (src_address_set == 0)
11278     {
11279       errmsg ("src_address required");
11280       return -99;
11281     }
11282
11283   M (SET_IPFIX_EXPORTER, mp);
11284
11285   memcpy (mp->collector_address.un.ip4, collector_address.data,
11286           sizeof (collector_address.data));
11287   mp->collector_port = htons ((u16) collector_port);
11288   memcpy (mp->src_address.un.ip4, src_address.data,
11289           sizeof (src_address.data));
11290   mp->vrf_id = htonl (vrf_id);
11291   mp->path_mtu = htonl (path_mtu);
11292   mp->template_interval = htonl (template_interval);
11293   mp->udp_checksum = udp_checksum;
11294
11295   S (mp);
11296   W (ret);
11297   return ret;
11298 }
11299
11300 static int
11301 api_set_ipfix_classify_stream (vat_main_t * vam)
11302 {
11303   unformat_input_t *i = vam->input;
11304   vl_api_set_ipfix_classify_stream_t *mp;
11305   u32 domain_id = 0;
11306   u32 src_port = UDP_DST_PORT_ipfix;
11307   int ret;
11308
11309   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11310     {
11311       if (unformat (i, "domain %d", &domain_id))
11312         ;
11313       else if (unformat (i, "src_port %d", &src_port))
11314         ;
11315       else
11316         {
11317           errmsg ("unknown input `%U'", format_unformat_error, i);
11318           return -99;
11319         }
11320     }
11321
11322   M (SET_IPFIX_CLASSIFY_STREAM, mp);
11323
11324   mp->domain_id = htonl (domain_id);
11325   mp->src_port = htons ((u16) src_port);
11326
11327   S (mp);
11328   W (ret);
11329   return ret;
11330 }
11331
11332 static int
11333 api_ipfix_classify_table_add_del (vat_main_t * vam)
11334 {
11335   unformat_input_t *i = vam->input;
11336   vl_api_ipfix_classify_table_add_del_t *mp;
11337   int is_add = -1;
11338   u32 classify_table_index = ~0;
11339   u8 ip_version = 0;
11340   u8 transport_protocol = 255;
11341   int ret;
11342
11343   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11344     {
11345       if (unformat (i, "add"))
11346         is_add = 1;
11347       else if (unformat (i, "del"))
11348         is_add = 0;
11349       else if (unformat (i, "table %d", &classify_table_index))
11350         ;
11351       else if (unformat (i, "ip4"))
11352         ip_version = 4;
11353       else if (unformat (i, "ip6"))
11354         ip_version = 6;
11355       else if (unformat (i, "tcp"))
11356         transport_protocol = 6;
11357       else if (unformat (i, "udp"))
11358         transport_protocol = 17;
11359       else
11360         {
11361           errmsg ("unknown input `%U'", format_unformat_error, i);
11362           return -99;
11363         }
11364     }
11365
11366   if (is_add == -1)
11367     {
11368       errmsg ("expecting: add|del");
11369       return -99;
11370     }
11371   if (classify_table_index == ~0)
11372     {
11373       errmsg ("classifier table not specified");
11374       return -99;
11375     }
11376   if (ip_version == 0)
11377     {
11378       errmsg ("IP version not specified");
11379       return -99;
11380     }
11381
11382   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, mp);
11383
11384   mp->is_add = is_add;
11385   mp->table_id = htonl (classify_table_index);
11386   mp->ip_version = ip_version;
11387   mp->transport_protocol = transport_protocol;
11388
11389   S (mp);
11390   W (ret);
11391   return ret;
11392 }
11393
11394 static int
11395 api_get_node_index (vat_main_t * vam)
11396 {
11397   unformat_input_t *i = vam->input;
11398   vl_api_get_node_index_t *mp;
11399   u8 *name = 0;
11400   int ret;
11401
11402   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11403     {
11404       if (unformat (i, "node %s", &name))
11405         ;
11406       else
11407         break;
11408     }
11409   if (name == 0)
11410     {
11411       errmsg ("node name required");
11412       return -99;
11413     }
11414   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
11415     {
11416       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11417       return -99;
11418     }
11419
11420   M (GET_NODE_INDEX, mp);
11421   clib_memcpy (mp->node_name, name, vec_len (name));
11422   vec_free (name);
11423
11424   S (mp);
11425   W (ret);
11426   return ret;
11427 }
11428
11429 static int
11430 api_get_next_index (vat_main_t * vam)
11431 {
11432   unformat_input_t *i = vam->input;
11433   vl_api_get_next_index_t *mp;
11434   u8 *node_name = 0, *next_node_name = 0;
11435   int ret;
11436
11437   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11438     {
11439       if (unformat (i, "node-name %s", &node_name))
11440         ;
11441       else if (unformat (i, "next-node-name %s", &next_node_name))
11442         break;
11443     }
11444
11445   if (node_name == 0)
11446     {
11447       errmsg ("node name required");
11448       return -99;
11449     }
11450   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
11451     {
11452       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11453       return -99;
11454     }
11455
11456   if (next_node_name == 0)
11457     {
11458       errmsg ("next node name required");
11459       return -99;
11460     }
11461   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
11462     {
11463       errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
11464       return -99;
11465     }
11466
11467   M (GET_NEXT_INDEX, mp);
11468   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
11469   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
11470   vec_free (node_name);
11471   vec_free (next_node_name);
11472
11473   S (mp);
11474   W (ret);
11475   return ret;
11476 }
11477
11478 static int
11479 api_add_node_next (vat_main_t * vam)
11480 {
11481   unformat_input_t *i = vam->input;
11482   vl_api_add_node_next_t *mp;
11483   u8 *name = 0;
11484   u8 *next = 0;
11485   int ret;
11486
11487   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11488     {
11489       if (unformat (i, "node %s", &name))
11490         ;
11491       else if (unformat (i, "next %s", &next))
11492         ;
11493       else
11494         break;
11495     }
11496   if (name == 0)
11497     {
11498       errmsg ("node name required");
11499       return -99;
11500     }
11501   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
11502     {
11503       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11504       return -99;
11505     }
11506   if (next == 0)
11507     {
11508       errmsg ("next node required");
11509       return -99;
11510     }
11511   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
11512     {
11513       errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
11514       return -99;
11515     }
11516
11517   M (ADD_NODE_NEXT, mp);
11518   clib_memcpy (mp->node_name, name, vec_len (name));
11519   clib_memcpy (mp->next_name, next, vec_len (next));
11520   vec_free (name);
11521   vec_free (next);
11522
11523   S (mp);
11524   W (ret);
11525   return ret;
11526 }
11527
11528 static int
11529 api_l2tpv3_create_tunnel (vat_main_t * vam)
11530 {
11531   unformat_input_t *i = vam->input;
11532   ip6_address_t client_address, our_address;
11533   int client_address_set = 0;
11534   int our_address_set = 0;
11535   u32 local_session_id = 0;
11536   u32 remote_session_id = 0;
11537   u64 local_cookie = 0;
11538   u64 remote_cookie = 0;
11539   u8 l2_sublayer_present = 0;
11540   vl_api_l2tpv3_create_tunnel_t *mp;
11541   int ret;
11542
11543   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11544     {
11545       if (unformat (i, "client_address %U", unformat_ip6_address,
11546                     &client_address))
11547         client_address_set = 1;
11548       else if (unformat (i, "our_address %U", unformat_ip6_address,
11549                          &our_address))
11550         our_address_set = 1;
11551       else if (unformat (i, "local_session_id %d", &local_session_id))
11552         ;
11553       else if (unformat (i, "remote_session_id %d", &remote_session_id))
11554         ;
11555       else if (unformat (i, "local_cookie %lld", &local_cookie))
11556         ;
11557       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
11558         ;
11559       else if (unformat (i, "l2-sublayer-present"))
11560         l2_sublayer_present = 1;
11561       else
11562         break;
11563     }
11564
11565   if (client_address_set == 0)
11566     {
11567       errmsg ("client_address required");
11568       return -99;
11569     }
11570
11571   if (our_address_set == 0)
11572     {
11573       errmsg ("our_address required");
11574       return -99;
11575     }
11576
11577   M (L2TPV3_CREATE_TUNNEL, mp);
11578
11579   clib_memcpy (mp->client_address.un.ip6, client_address.as_u8,
11580                sizeof (ip6_address_t));
11581
11582   clib_memcpy (mp->our_address.un.ip6, our_address.as_u8,
11583                sizeof (ip6_address_t));
11584
11585   mp->local_session_id = ntohl (local_session_id);
11586   mp->remote_session_id = ntohl (remote_session_id);
11587   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
11588   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
11589   mp->l2_sublayer_present = l2_sublayer_present;
11590
11591   S (mp);
11592   W (ret);
11593   return ret;
11594 }
11595
11596 static int
11597 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
11598 {
11599   unformat_input_t *i = vam->input;
11600   u32 sw_if_index;
11601   u8 sw_if_index_set = 0;
11602   u64 new_local_cookie = 0;
11603   u64 new_remote_cookie = 0;
11604   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
11605   int ret;
11606
11607   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11608     {
11609       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11610         sw_if_index_set = 1;
11611       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11612         sw_if_index_set = 1;
11613       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
11614         ;
11615       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
11616         ;
11617       else
11618         break;
11619     }
11620
11621   if (sw_if_index_set == 0)
11622     {
11623       errmsg ("missing interface name or sw_if_index");
11624       return -99;
11625     }
11626
11627   M (L2TPV3_SET_TUNNEL_COOKIES, mp);
11628
11629   mp->sw_if_index = ntohl (sw_if_index);
11630   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
11631   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
11632
11633   S (mp);
11634   W (ret);
11635   return ret;
11636 }
11637
11638 static int
11639 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
11640 {
11641   unformat_input_t *i = vam->input;
11642   vl_api_l2tpv3_interface_enable_disable_t *mp;
11643   u32 sw_if_index;
11644   u8 sw_if_index_set = 0;
11645   u8 enable_disable = 1;
11646   int ret;
11647
11648   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11649     {
11650       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11651         sw_if_index_set = 1;
11652       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11653         sw_if_index_set = 1;
11654       else if (unformat (i, "enable"))
11655         enable_disable = 1;
11656       else if (unformat (i, "disable"))
11657         enable_disable = 0;
11658       else
11659         break;
11660     }
11661
11662   if (sw_if_index_set == 0)
11663     {
11664       errmsg ("missing interface name or sw_if_index");
11665       return -99;
11666     }
11667
11668   M (L2TPV3_INTERFACE_ENABLE_DISABLE, mp);
11669
11670   mp->sw_if_index = ntohl (sw_if_index);
11671   mp->enable_disable = enable_disable;
11672
11673   S (mp);
11674   W (ret);
11675   return ret;
11676 }
11677
11678 static int
11679 api_l2tpv3_set_lookup_key (vat_main_t * vam)
11680 {
11681   unformat_input_t *i = vam->input;
11682   vl_api_l2tpv3_set_lookup_key_t *mp;
11683   u8 key = ~0;
11684   int ret;
11685
11686   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11687     {
11688       if (unformat (i, "lookup_v6_src"))
11689         key = L2T_LOOKUP_SRC_ADDRESS;
11690       else if (unformat (i, "lookup_v6_dst"))
11691         key = L2T_LOOKUP_DST_ADDRESS;
11692       else if (unformat (i, "lookup_session_id"))
11693         key = L2T_LOOKUP_SESSION_ID;
11694       else
11695         break;
11696     }
11697
11698   if (key == (u8) ~ 0)
11699     {
11700       errmsg ("l2tp session lookup key unset");
11701       return -99;
11702     }
11703
11704   M (L2TPV3_SET_LOOKUP_KEY, mp);
11705
11706   mp->key = key;
11707
11708   S (mp);
11709   W (ret);
11710   return ret;
11711 }
11712
11713 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
11714   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
11715 {
11716   vat_main_t *vam = &vat_main;
11717
11718   print (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)",
11719          format_ip6_address, mp->our_address,
11720          format_ip6_address, mp->client_address,
11721          clib_net_to_host_u32 (mp->sw_if_index));
11722
11723   print (vam->ofp,
11724          "   local cookies %016llx %016llx remote cookie %016llx",
11725          clib_net_to_host_u64 (mp->local_cookie[0]),
11726          clib_net_to_host_u64 (mp->local_cookie[1]),
11727          clib_net_to_host_u64 (mp->remote_cookie));
11728
11729   print (vam->ofp, "   local session-id %d remote session-id %d",
11730          clib_net_to_host_u32 (mp->local_session_id),
11731          clib_net_to_host_u32 (mp->remote_session_id));
11732
11733   print (vam->ofp, "   l2 specific sublayer %s\n",
11734          mp->l2_sublayer_present ? "preset" : "absent");
11735
11736 }
11737
11738 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
11739   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
11740 {
11741   vat_main_t *vam = &vat_main;
11742   vat_json_node_t *node = NULL;
11743   struct in6_addr addr;
11744
11745   if (VAT_JSON_ARRAY != vam->json_tree.type)
11746     {
11747       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11748       vat_json_init_array (&vam->json_tree);
11749     }
11750   node = vat_json_array_add (&vam->json_tree);
11751
11752   vat_json_init_object (node);
11753
11754   clib_memcpy (&addr, mp->our_address.un.ip6, sizeof (addr));
11755   vat_json_object_add_ip6 (node, "our_address", addr);
11756   clib_memcpy (&addr, mp->client_address.un.ip6, sizeof (addr));
11757   vat_json_object_add_ip6 (node, "client_address", addr);
11758
11759   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
11760   vat_json_init_array (lc);
11761   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
11762   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
11763   vat_json_object_add_uint (node, "remote_cookie",
11764                             clib_net_to_host_u64 (mp->remote_cookie));
11765
11766   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
11767   vat_json_object_add_uint (node, "local_session_id",
11768                             clib_net_to_host_u32 (mp->local_session_id));
11769   vat_json_object_add_uint (node, "remote_session_id",
11770                             clib_net_to_host_u32 (mp->remote_session_id));
11771   vat_json_object_add_string_copy (node, "l2_sublayer",
11772                                    mp->l2_sublayer_present ? (u8 *) "present"
11773                                    : (u8 *) "absent");
11774 }
11775
11776 static int
11777 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
11778 {
11779   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
11780   vl_api_control_ping_t *mp_ping;
11781   int ret;
11782
11783   /* Get list of l2tpv3-tunnel interfaces */
11784   M (SW_IF_L2TPV3_TUNNEL_DUMP, mp);
11785   S (mp);
11786
11787   /* Use a control ping for synchronization */
11788   MPING (CONTROL_PING, mp_ping);
11789   S (mp_ping);
11790
11791   W (ret);
11792   return ret;
11793 }
11794
11795
11796 static void vl_api_sw_interface_tap_v2_details_t_handler
11797   (vl_api_sw_interface_tap_v2_details_t * mp)
11798 {
11799   vat_main_t *vam = &vat_main;
11800
11801   u8 *ip4 = format (0, "%U/%d", format_ip4_address, mp->host_ip4_addr,
11802                     mp->host_ip4_prefix_len);
11803   u8 *ip6 = format (0, "%U/%d", format_ip6_address, mp->host_ip6_addr,
11804                     mp->host_ip6_prefix_len);
11805
11806   print (vam->ofp,
11807          "\n%-16s %-12d %-5d %-12d %-12d %-14U %-30s %-20s %-20s %-30s 0x%-08x",
11808          mp->dev_name, ntohl (mp->sw_if_index), ntohl (mp->id),
11809          ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
11810          format_ethernet_address, mp->host_mac_addr, mp->host_namespace,
11811          mp->host_bridge, ip4, ip6, ntohl (mp->tap_flags));
11812
11813   vec_free (ip4);
11814   vec_free (ip6);
11815 }
11816
11817 static void vl_api_sw_interface_tap_v2_details_t_handler_json
11818   (vl_api_sw_interface_tap_v2_details_t * mp)
11819 {
11820   vat_main_t *vam = &vat_main;
11821   vat_json_node_t *node = NULL;
11822
11823   if (VAT_JSON_ARRAY != vam->json_tree.type)
11824     {
11825       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11826       vat_json_init_array (&vam->json_tree);
11827     }
11828   node = vat_json_array_add (&vam->json_tree);
11829
11830   vat_json_init_object (node);
11831   vat_json_object_add_uint (node, "id", ntohl (mp->id));
11832   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11833   vat_json_object_add_uint (node, "tap_flags", ntohl (mp->tap_flags));
11834   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
11835   vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
11836   vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
11837   vat_json_object_add_string_copy (node, "host_mac_addr",
11838                                    format (0, "%U", format_ethernet_address,
11839                                            &mp->host_mac_addr));
11840   vat_json_object_add_string_copy (node, "host_namespace",
11841                                    mp->host_namespace);
11842   vat_json_object_add_string_copy (node, "host_bridge", mp->host_bridge);
11843   vat_json_object_add_string_copy (node, "host_ip4_addr",
11844                                    format (0, "%U/%d", format_ip4_address,
11845                                            mp->host_ip4_addr,
11846                                            mp->host_ip4_prefix_len));
11847   vat_json_object_add_string_copy (node, "host_ip6_addr",
11848                                    format (0, "%U/%d", format_ip6_address,
11849                                            mp->host_ip6_addr,
11850                                            mp->host_ip6_prefix_len));
11851
11852 }
11853
11854 static int
11855 api_sw_interface_tap_v2_dump (vat_main_t * vam)
11856 {
11857   vl_api_sw_interface_tap_v2_dump_t *mp;
11858   vl_api_control_ping_t *mp_ping;
11859   int ret;
11860
11861   print (vam->ofp,
11862          "\n%-16s %-12s %-5s %-12s %-12s %-14s %-30s %-20s %-20s %-30s",
11863          "dev_name", "sw_if_index", "id", "rx_ring_sz", "tx_ring_sz",
11864          "host_mac_addr", "host_namespace", "host_bridge", "host_ip4_addr",
11865          "host_ip6_addr");
11866
11867   /* Get list of tap interfaces */
11868   M (SW_INTERFACE_TAP_V2_DUMP, mp);
11869   S (mp);
11870
11871   /* Use a control ping for synchronization */
11872   MPING (CONTROL_PING, mp_ping);
11873   S (mp_ping);
11874
11875   W (ret);
11876   return ret;
11877 }
11878
11879 static void vl_api_sw_interface_virtio_pci_details_t_handler
11880   (vl_api_sw_interface_virtio_pci_details_t * mp)
11881 {
11882   vat_main_t *vam = &vat_main;
11883
11884   typedef union
11885   {
11886     struct
11887     {
11888       u16 domain;
11889       u8 bus;
11890       u8 slot:5;
11891       u8 function:3;
11892     };
11893     u32 as_u32;
11894   } pci_addr_t;
11895   pci_addr_t addr;
11896   addr.as_u32 = ntohl (mp->pci_addr);
11897   u8 *pci_addr = format (0, "%04x:%02x:%02x.%x", addr.domain, addr.bus,
11898                          addr.slot, addr.function);
11899
11900   print (vam->ofp,
11901          "\n%-12s %-12d %-12d %-12d %-17U 0x%-08llx",
11902          pci_addr, ntohl (mp->sw_if_index),
11903          ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
11904          format_ethernet_address, mp->mac_addr,
11905          clib_net_to_host_u64 (mp->features));
11906   vec_free (pci_addr);
11907 }
11908
11909 static void vl_api_sw_interface_virtio_pci_details_t_handler_json
11910   (vl_api_sw_interface_virtio_pci_details_t * mp)
11911 {
11912   vat_main_t *vam = &vat_main;
11913   vat_json_node_t *node = NULL;
11914
11915   if (VAT_JSON_ARRAY != vam->json_tree.type)
11916     {
11917       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11918       vat_json_init_array (&vam->json_tree);
11919     }
11920   node = vat_json_array_add (&vam->json_tree);
11921
11922   vat_json_init_object (node);
11923   vat_json_object_add_uint (node, "pci-addr", ntohl (mp->pci_addr));
11924   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11925   vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
11926   vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
11927   vat_json_object_add_uint (node, "features",
11928                             clib_net_to_host_u64 (mp->features));
11929   vat_json_object_add_string_copy (node, "mac_addr",
11930                                    format (0, "%U", format_ethernet_address,
11931                                            &mp->mac_addr));
11932 }
11933
11934 static int
11935 api_sw_interface_virtio_pci_dump (vat_main_t * vam)
11936 {
11937   vl_api_sw_interface_virtio_pci_dump_t *mp;
11938   vl_api_control_ping_t *mp_ping;
11939   int ret;
11940
11941   print (vam->ofp,
11942          "\n%-12s %-12s %-12s %-12s %-17s %-08s",
11943          "pci_addr", "sw_if_index", "rx_ring_sz", "tx_ring_sz",
11944          "mac_addr", "features");
11945
11946   /* Get list of tap interfaces */
11947   M (SW_INTERFACE_VIRTIO_PCI_DUMP, mp);
11948   S (mp);
11949
11950   /* Use a control ping for synchronization */
11951   MPING (CONTROL_PING, mp_ping);
11952   S (mp_ping);
11953
11954   W (ret);
11955   return ret;
11956 }
11957
11958 static int
11959 api_vxlan_offload_rx (vat_main_t * vam)
11960 {
11961   unformat_input_t *line_input = vam->input;
11962   vl_api_vxlan_offload_rx_t *mp;
11963   u32 hw_if_index = ~0, rx_if_index = ~0;
11964   u8 is_add = 1;
11965   int ret;
11966
11967   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11968     {
11969       if (unformat (line_input, "del"))
11970         is_add = 0;
11971       else if (unformat (line_input, "hw %U", api_unformat_hw_if_index, vam,
11972                          &hw_if_index))
11973         ;
11974       else if (unformat (line_input, "hw hw_if_index %u", &hw_if_index))
11975         ;
11976       else if (unformat (line_input, "rx %U", api_unformat_sw_if_index, vam,
11977                          &rx_if_index))
11978         ;
11979       else if (unformat (line_input, "rx sw_if_index %u", &rx_if_index))
11980         ;
11981       else
11982         {
11983           errmsg ("parse error '%U'", format_unformat_error, line_input);
11984           return -99;
11985         }
11986     }
11987
11988   if (hw_if_index == ~0)
11989     {
11990       errmsg ("no hw interface");
11991       return -99;
11992     }
11993
11994   if (rx_if_index == ~0)
11995     {
11996       errmsg ("no rx tunnel");
11997       return -99;
11998     }
11999
12000   M (VXLAN_OFFLOAD_RX, mp);
12001
12002   mp->hw_if_index = ntohl (hw_if_index);
12003   mp->sw_if_index = ntohl (rx_if_index);
12004   mp->enable = is_add;
12005
12006   S (mp);
12007   W (ret);
12008   return ret;
12009 }
12010
12011 static uword unformat_vxlan_decap_next
12012   (unformat_input_t * input, va_list * args)
12013 {
12014   u32 *result = va_arg (*args, u32 *);
12015   u32 tmp;
12016
12017   if (unformat (input, "l2"))
12018     *result = VXLAN_INPUT_NEXT_L2_INPUT;
12019   else if (unformat (input, "%d", &tmp))
12020     *result = tmp;
12021   else
12022     return 0;
12023   return 1;
12024 }
12025
12026 static int
12027 api_vxlan_add_del_tunnel (vat_main_t * vam)
12028 {
12029   unformat_input_t *line_input = vam->input;
12030   vl_api_vxlan_add_del_tunnel_t *mp;
12031   ip46_address_t src, dst;
12032   u8 is_add = 1;
12033   u8 ipv4_set = 0, ipv6_set = 0;
12034   u8 src_set = 0;
12035   u8 dst_set = 0;
12036   u8 grp_set = 0;
12037   u32 instance = ~0;
12038   u32 mcast_sw_if_index = ~0;
12039   u32 encap_vrf_id = 0;
12040   u32 decap_next_index = ~0;
12041   u32 vni = 0;
12042   int ret;
12043
12044   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
12045   clib_memset (&src, 0, sizeof src);
12046   clib_memset (&dst, 0, sizeof dst);
12047
12048   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12049     {
12050       if (unformat (line_input, "del"))
12051         is_add = 0;
12052       else if (unformat (line_input, "instance %d", &instance))
12053         ;
12054       else
12055         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
12056         {
12057           ipv4_set = 1;
12058           src_set = 1;
12059         }
12060       else
12061         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
12062         {
12063           ipv4_set = 1;
12064           dst_set = 1;
12065         }
12066       else
12067         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
12068         {
12069           ipv6_set = 1;
12070           src_set = 1;
12071         }
12072       else
12073         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
12074         {
12075           ipv6_set = 1;
12076           dst_set = 1;
12077         }
12078       else if (unformat (line_input, "group %U %U",
12079                          unformat_ip4_address, &dst.ip4,
12080                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12081         {
12082           grp_set = dst_set = 1;
12083           ipv4_set = 1;
12084         }
12085       else if (unformat (line_input, "group %U",
12086                          unformat_ip4_address, &dst.ip4))
12087         {
12088           grp_set = dst_set = 1;
12089           ipv4_set = 1;
12090         }
12091       else if (unformat (line_input, "group %U %U",
12092                          unformat_ip6_address, &dst.ip6,
12093                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12094         {
12095           grp_set = dst_set = 1;
12096           ipv6_set = 1;
12097         }
12098       else if (unformat (line_input, "group %U",
12099                          unformat_ip6_address, &dst.ip6))
12100         {
12101           grp_set = dst_set = 1;
12102           ipv6_set = 1;
12103         }
12104       else
12105         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
12106         ;
12107       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
12108         ;
12109       else if (unformat (line_input, "decap-next %U",
12110                          unformat_vxlan_decap_next, &decap_next_index))
12111         ;
12112       else if (unformat (line_input, "vni %d", &vni))
12113         ;
12114       else
12115         {
12116           errmsg ("parse error '%U'", format_unformat_error, line_input);
12117           return -99;
12118         }
12119     }
12120
12121   if (src_set == 0)
12122     {
12123       errmsg ("tunnel src address not specified");
12124       return -99;
12125     }
12126   if (dst_set == 0)
12127     {
12128       errmsg ("tunnel dst address not specified");
12129       return -99;
12130     }
12131
12132   if (grp_set && !ip46_address_is_multicast (&dst))
12133     {
12134       errmsg ("tunnel group address not multicast");
12135       return -99;
12136     }
12137   if (grp_set && mcast_sw_if_index == ~0)
12138     {
12139       errmsg ("tunnel nonexistent multicast device");
12140       return -99;
12141     }
12142   if (grp_set == 0 && ip46_address_is_multicast (&dst))
12143     {
12144       errmsg ("tunnel dst address must be unicast");
12145       return -99;
12146     }
12147
12148
12149   if (ipv4_set && ipv6_set)
12150     {
12151       errmsg ("both IPv4 and IPv6 addresses specified");
12152       return -99;
12153     }
12154
12155   if ((vni == 0) || (vni >> 24))
12156     {
12157       errmsg ("vni not specified or out of range");
12158       return -99;
12159     }
12160
12161   M (VXLAN_ADD_DEL_TUNNEL, mp);
12162
12163   if (ipv6_set)
12164     {
12165       clib_memcpy (mp->src_address, &src.ip6, sizeof (src.ip6));
12166       clib_memcpy (mp->dst_address, &dst.ip6, sizeof (dst.ip6));
12167     }
12168   else
12169     {
12170       clib_memcpy (mp->src_address, &src.ip4, sizeof (src.ip4));
12171       clib_memcpy (mp->dst_address, &dst.ip4, sizeof (dst.ip4));
12172     }
12173
12174   mp->instance = htonl (instance);
12175   mp->encap_vrf_id = ntohl (encap_vrf_id);
12176   mp->decap_next_index = ntohl (decap_next_index);
12177   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
12178   mp->vni = ntohl (vni);
12179   mp->is_add = is_add;
12180   mp->is_ipv6 = ipv6_set;
12181
12182   S (mp);
12183   W (ret);
12184   return ret;
12185 }
12186
12187 static void vl_api_vxlan_tunnel_details_t_handler
12188   (vl_api_vxlan_tunnel_details_t * mp)
12189 {
12190   vat_main_t *vam = &vat_main;
12191   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
12192   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
12193
12194   print (vam->ofp, "%11d%11d%24U%24U%14d%18d%13d%19d",
12195          ntohl (mp->sw_if_index),
12196          ntohl (mp->instance),
12197          format_ip46_address, &src, IP46_TYPE_ANY,
12198          format_ip46_address, &dst, IP46_TYPE_ANY,
12199          ntohl (mp->encap_vrf_id),
12200          ntohl (mp->decap_next_index), ntohl (mp->vni),
12201          ntohl (mp->mcast_sw_if_index));
12202 }
12203
12204 static void vl_api_vxlan_tunnel_details_t_handler_json
12205   (vl_api_vxlan_tunnel_details_t * mp)
12206 {
12207   vat_main_t *vam = &vat_main;
12208   vat_json_node_t *node = NULL;
12209
12210   if (VAT_JSON_ARRAY != vam->json_tree.type)
12211     {
12212       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12213       vat_json_init_array (&vam->json_tree);
12214     }
12215   node = vat_json_array_add (&vam->json_tree);
12216
12217   vat_json_init_object (node);
12218   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12219
12220   vat_json_object_add_uint (node, "instance", ntohl (mp->instance));
12221
12222   if (mp->is_ipv6)
12223     {
12224       struct in6_addr ip6;
12225
12226       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
12227       vat_json_object_add_ip6 (node, "src_address", ip6);
12228       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
12229       vat_json_object_add_ip6 (node, "dst_address", ip6);
12230     }
12231   else
12232     {
12233       struct in_addr ip4;
12234
12235       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
12236       vat_json_object_add_ip4 (node, "src_address", ip4);
12237       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
12238       vat_json_object_add_ip4 (node, "dst_address", ip4);
12239     }
12240   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
12241   vat_json_object_add_uint (node, "decap_next_index",
12242                             ntohl (mp->decap_next_index));
12243   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
12244   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
12245   vat_json_object_add_uint (node, "mcast_sw_if_index",
12246                             ntohl (mp->mcast_sw_if_index));
12247 }
12248
12249 static int
12250 api_vxlan_tunnel_dump (vat_main_t * vam)
12251 {
12252   unformat_input_t *i = vam->input;
12253   vl_api_vxlan_tunnel_dump_t *mp;
12254   vl_api_control_ping_t *mp_ping;
12255   u32 sw_if_index;
12256   u8 sw_if_index_set = 0;
12257   int ret;
12258
12259   /* Parse args required to build the message */
12260   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12261     {
12262       if (unformat (i, "sw_if_index %d", &sw_if_index))
12263         sw_if_index_set = 1;
12264       else
12265         break;
12266     }
12267
12268   if (sw_if_index_set == 0)
12269     {
12270       sw_if_index = ~0;
12271     }
12272
12273   if (!vam->json_output)
12274     {
12275       print (vam->ofp, "%11s%11s%24s%24s%14s%18s%13s%19s",
12276              "sw_if_index", "instance", "src_address", "dst_address",
12277              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
12278     }
12279
12280   /* Get list of vxlan-tunnel interfaces */
12281   M (VXLAN_TUNNEL_DUMP, mp);
12282
12283   mp->sw_if_index = htonl (sw_if_index);
12284
12285   S (mp);
12286
12287   /* Use a control ping for synchronization */
12288   MPING (CONTROL_PING, mp_ping);
12289   S (mp_ping);
12290
12291   W (ret);
12292   return ret;
12293 }
12294
12295 static uword unformat_geneve_decap_next
12296   (unformat_input_t * input, va_list * args)
12297 {
12298   u32 *result = va_arg (*args, u32 *);
12299   u32 tmp;
12300
12301   if (unformat (input, "l2"))
12302     *result = GENEVE_INPUT_NEXT_L2_INPUT;
12303   else if (unformat (input, "%d", &tmp))
12304     *result = tmp;
12305   else
12306     return 0;
12307   return 1;
12308 }
12309
12310 static int
12311 api_geneve_add_del_tunnel (vat_main_t * vam)
12312 {
12313   unformat_input_t *line_input = vam->input;
12314   vl_api_geneve_add_del_tunnel_t *mp;
12315   ip46_address_t src, dst;
12316   u8 is_add = 1;
12317   u8 ipv4_set = 0, ipv6_set = 0;
12318   u8 src_set = 0;
12319   u8 dst_set = 0;
12320   u8 grp_set = 0;
12321   u32 mcast_sw_if_index = ~0;
12322   u32 encap_vrf_id = 0;
12323   u32 decap_next_index = ~0;
12324   u32 vni = 0;
12325   int ret;
12326
12327   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
12328   clib_memset (&src, 0, sizeof src);
12329   clib_memset (&dst, 0, sizeof dst);
12330
12331   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12332     {
12333       if (unformat (line_input, "del"))
12334         is_add = 0;
12335       else
12336         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
12337         {
12338           ipv4_set = 1;
12339           src_set = 1;
12340         }
12341       else
12342         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
12343         {
12344           ipv4_set = 1;
12345           dst_set = 1;
12346         }
12347       else
12348         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
12349         {
12350           ipv6_set = 1;
12351           src_set = 1;
12352         }
12353       else
12354         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
12355         {
12356           ipv6_set = 1;
12357           dst_set = 1;
12358         }
12359       else if (unformat (line_input, "group %U %U",
12360                          unformat_ip4_address, &dst.ip4,
12361                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12362         {
12363           grp_set = dst_set = 1;
12364           ipv4_set = 1;
12365         }
12366       else if (unformat (line_input, "group %U",
12367                          unformat_ip4_address, &dst.ip4))
12368         {
12369           grp_set = dst_set = 1;
12370           ipv4_set = 1;
12371         }
12372       else if (unformat (line_input, "group %U %U",
12373                          unformat_ip6_address, &dst.ip6,
12374                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12375         {
12376           grp_set = dst_set = 1;
12377           ipv6_set = 1;
12378         }
12379       else if (unformat (line_input, "group %U",
12380                          unformat_ip6_address, &dst.ip6))
12381         {
12382           grp_set = dst_set = 1;
12383           ipv6_set = 1;
12384         }
12385       else
12386         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
12387         ;
12388       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
12389         ;
12390       else if (unformat (line_input, "decap-next %U",
12391                          unformat_geneve_decap_next, &decap_next_index))
12392         ;
12393       else if (unformat (line_input, "vni %d", &vni))
12394         ;
12395       else
12396         {
12397           errmsg ("parse error '%U'", format_unformat_error, line_input);
12398           return -99;
12399         }
12400     }
12401
12402   if (src_set == 0)
12403     {
12404       errmsg ("tunnel src address not specified");
12405       return -99;
12406     }
12407   if (dst_set == 0)
12408     {
12409       errmsg ("tunnel dst address not specified");
12410       return -99;
12411     }
12412
12413   if (grp_set && !ip46_address_is_multicast (&dst))
12414     {
12415       errmsg ("tunnel group address not multicast");
12416       return -99;
12417     }
12418   if (grp_set && mcast_sw_if_index == ~0)
12419     {
12420       errmsg ("tunnel nonexistent multicast device");
12421       return -99;
12422     }
12423   if (grp_set == 0 && ip46_address_is_multicast (&dst))
12424     {
12425       errmsg ("tunnel dst address must be unicast");
12426       return -99;
12427     }
12428
12429
12430   if (ipv4_set && ipv6_set)
12431     {
12432       errmsg ("both IPv4 and IPv6 addresses specified");
12433       return -99;
12434     }
12435
12436   if ((vni == 0) || (vni >> 24))
12437     {
12438       errmsg ("vni not specified or out of range");
12439       return -99;
12440     }
12441
12442   M (GENEVE_ADD_DEL_TUNNEL, mp);
12443
12444   if (ipv6_set)
12445     {
12446       clib_memcpy (&mp->local_address.un.ip6, &src.ip6, sizeof (src.ip6));
12447       clib_memcpy (&mp->remote_address.un.ip6, &dst.ip6, sizeof (dst.ip6));
12448     }
12449   else
12450     {
12451       clib_memcpy (&mp->local_address.un.ip4, &src.ip4, sizeof (src.ip4));
12452       clib_memcpy (&mp->remote_address.un.ip4, &dst.ip4, sizeof (dst.ip4));
12453     }
12454   mp->encap_vrf_id = ntohl (encap_vrf_id);
12455   mp->decap_next_index = ntohl (decap_next_index);
12456   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
12457   mp->vni = ntohl (vni);
12458   mp->is_add = is_add;
12459
12460   S (mp);
12461   W (ret);
12462   return ret;
12463 }
12464
12465 static void vl_api_geneve_tunnel_details_t_handler
12466   (vl_api_geneve_tunnel_details_t * mp)
12467 {
12468   vat_main_t *vam = &vat_main;
12469   ip46_address_t src = {.as_u64[0] = 0,.as_u64[1] = 0 };
12470   ip46_address_t dst = {.as_u64[0] = 0,.as_u64[1] = 0 };
12471
12472   if (mp->src_address.af == ADDRESS_IP6)
12473     {
12474       clib_memcpy (&src.ip6, &mp->src_address.un.ip6, sizeof (ip6_address_t));
12475       clib_memcpy (&dst.ip6, &mp->dst_address.un.ip6, sizeof (ip6_address_t));
12476     }
12477   else
12478     {
12479       clib_memcpy (&src.ip4, &mp->src_address.un.ip4, sizeof (ip4_address_t));
12480       clib_memcpy (&dst.ip4, &mp->dst_address.un.ip4, sizeof (ip4_address_t));
12481     }
12482
12483   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
12484          ntohl (mp->sw_if_index),
12485          format_ip46_address, &src, IP46_TYPE_ANY,
12486          format_ip46_address, &dst, IP46_TYPE_ANY,
12487          ntohl (mp->encap_vrf_id),
12488          ntohl (mp->decap_next_index), ntohl (mp->vni),
12489          ntohl (mp->mcast_sw_if_index));
12490 }
12491
12492 static void vl_api_geneve_tunnel_details_t_handler_json
12493   (vl_api_geneve_tunnel_details_t * mp)
12494 {
12495   vat_main_t *vam = &vat_main;
12496   vat_json_node_t *node = NULL;
12497   bool is_ipv6;
12498
12499   if (VAT_JSON_ARRAY != vam->json_tree.type)
12500     {
12501       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12502       vat_json_init_array (&vam->json_tree);
12503     }
12504   node = vat_json_array_add (&vam->json_tree);
12505
12506   vat_json_init_object (node);
12507   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12508   is_ipv6 = mp->src_address.af == ADDRESS_IP6;
12509   if (is_ipv6)
12510     {
12511       struct in6_addr ip6;
12512
12513       clib_memcpy (&ip6, &mp->src_address.un.ip6, sizeof (ip6));
12514       vat_json_object_add_ip6 (node, "src_address", ip6);
12515       clib_memcpy (&ip6, &mp->dst_address.un.ip6, sizeof (ip6));
12516       vat_json_object_add_ip6 (node, "dst_address", ip6);
12517     }
12518   else
12519     {
12520       struct in_addr ip4;
12521
12522       clib_memcpy (&ip4, &mp->src_address.un.ip4, sizeof (ip4));
12523       vat_json_object_add_ip4 (node, "src_address", ip4);
12524       clib_memcpy (&ip4, &mp->dst_address.un.ip4, sizeof (ip4));
12525       vat_json_object_add_ip4 (node, "dst_address", ip4);
12526     }
12527   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
12528   vat_json_object_add_uint (node, "decap_next_index",
12529                             ntohl (mp->decap_next_index));
12530   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
12531   vat_json_object_add_uint (node, "mcast_sw_if_index",
12532                             ntohl (mp->mcast_sw_if_index));
12533 }
12534
12535 static int
12536 api_geneve_tunnel_dump (vat_main_t * vam)
12537 {
12538   unformat_input_t *i = vam->input;
12539   vl_api_geneve_tunnel_dump_t *mp;
12540   vl_api_control_ping_t *mp_ping;
12541   u32 sw_if_index;
12542   u8 sw_if_index_set = 0;
12543   int ret;
12544
12545   /* Parse args required to build the message */
12546   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12547     {
12548       if (unformat (i, "sw_if_index %d", &sw_if_index))
12549         sw_if_index_set = 1;
12550       else
12551         break;
12552     }
12553
12554   if (sw_if_index_set == 0)
12555     {
12556       sw_if_index = ~0;
12557     }
12558
12559   if (!vam->json_output)
12560     {
12561       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
12562              "sw_if_index", "local_address", "remote_address",
12563              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
12564     }
12565
12566   /* Get list of geneve-tunnel interfaces */
12567   M (GENEVE_TUNNEL_DUMP, mp);
12568
12569   mp->sw_if_index = htonl (sw_if_index);
12570
12571   S (mp);
12572
12573   /* Use a control ping for synchronization */
12574   M (CONTROL_PING, mp_ping);
12575   S (mp_ping);
12576
12577   W (ret);
12578   return ret;
12579 }
12580
12581 static int
12582 api_gre_tunnel_add_del (vat_main_t * vam)
12583 {
12584   unformat_input_t *line_input = vam->input;
12585   vl_api_address_t src = { }, dst =
12586   {
12587   };
12588   vl_api_gre_tunnel_add_del_t *mp;
12589   vl_api_gre_tunnel_type_t t_type;
12590   u8 is_add = 1;
12591   u8 src_set = 0;
12592   u8 dst_set = 0;
12593   u32 outer_fib_id = 0;
12594   u32 session_id = 0;
12595   u32 instance = ~0;
12596   int ret;
12597
12598   t_type = GRE_API_TUNNEL_TYPE_L3;
12599
12600   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12601     {
12602       if (unformat (line_input, "del"))
12603         is_add = 0;
12604       else if (unformat (line_input, "instance %d", &instance))
12605         ;
12606       else if (unformat (line_input, "src %U", unformat_vl_api_address, &src))
12607         {
12608           src_set = 1;
12609         }
12610       else if (unformat (line_input, "dst %U", unformat_vl_api_address, &dst))
12611         {
12612           dst_set = 1;
12613         }
12614       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
12615         ;
12616       else if (unformat (line_input, "teb"))
12617         t_type = GRE_API_TUNNEL_TYPE_TEB;
12618       else if (unformat (line_input, "erspan %d", &session_id))
12619         t_type = GRE_API_TUNNEL_TYPE_ERSPAN;
12620       else
12621         {
12622           errmsg ("parse error '%U'", format_unformat_error, line_input);
12623           return -99;
12624         }
12625     }
12626
12627   if (src_set == 0)
12628     {
12629       errmsg ("tunnel src address not specified");
12630       return -99;
12631     }
12632   if (dst_set == 0)
12633     {
12634       errmsg ("tunnel dst address not specified");
12635       return -99;
12636     }
12637
12638   M (GRE_TUNNEL_ADD_DEL, mp);
12639
12640   clib_memcpy (&mp->tunnel.src, &src, sizeof (mp->tunnel.src));
12641   clib_memcpy (&mp->tunnel.dst, &dst, sizeof (mp->tunnel.dst));
12642
12643   mp->tunnel.instance = htonl (instance);
12644   mp->tunnel.outer_fib_id = htonl (outer_fib_id);
12645   mp->is_add = is_add;
12646   mp->tunnel.session_id = htons ((u16) session_id);
12647   mp->tunnel.type = htonl (t_type);
12648
12649   S (mp);
12650   W (ret);
12651   return ret;
12652 }
12653
12654 static void vl_api_gre_tunnel_details_t_handler
12655   (vl_api_gre_tunnel_details_t * mp)
12656 {
12657   vat_main_t *vam = &vat_main;
12658
12659   print (vam->ofp, "%11d%11d%24U%24U%13d%14d%12d",
12660          ntohl (mp->tunnel.sw_if_index),
12661          ntohl (mp->tunnel.instance),
12662          format_vl_api_address, &mp->tunnel.src,
12663          format_vl_api_address, &mp->tunnel.dst,
12664          mp->tunnel.type, ntohl (mp->tunnel.outer_fib_id),
12665          ntohl (mp->tunnel.session_id));
12666 }
12667
12668 static void vl_api_gre_tunnel_details_t_handler_json
12669   (vl_api_gre_tunnel_details_t * mp)
12670 {
12671   vat_main_t *vam = &vat_main;
12672   vat_json_node_t *node = NULL;
12673
12674   if (VAT_JSON_ARRAY != vam->json_tree.type)
12675     {
12676       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12677       vat_json_init_array (&vam->json_tree);
12678     }
12679   node = vat_json_array_add (&vam->json_tree);
12680
12681   vat_json_init_object (node);
12682   vat_json_object_add_uint (node, "sw_if_index",
12683                             ntohl (mp->tunnel.sw_if_index));
12684   vat_json_object_add_uint (node, "instance", ntohl (mp->tunnel.instance));
12685
12686   vat_json_object_add_address (node, "src", &mp->tunnel.src);
12687   vat_json_object_add_address (node, "dst", &mp->tunnel.dst);
12688   vat_json_object_add_uint (node, "tunnel_type", mp->tunnel.type);
12689   vat_json_object_add_uint (node, "outer_fib_id",
12690                             ntohl (mp->tunnel.outer_fib_id));
12691   vat_json_object_add_uint (node, "session_id", mp->tunnel.session_id);
12692 }
12693
12694 static int
12695 api_gre_tunnel_dump (vat_main_t * vam)
12696 {
12697   unformat_input_t *i = vam->input;
12698   vl_api_gre_tunnel_dump_t *mp;
12699   vl_api_control_ping_t *mp_ping;
12700   u32 sw_if_index;
12701   u8 sw_if_index_set = 0;
12702   int ret;
12703
12704   /* Parse args required to build the message */
12705   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12706     {
12707       if (unformat (i, "sw_if_index %d", &sw_if_index))
12708         sw_if_index_set = 1;
12709       else
12710         break;
12711     }
12712
12713   if (sw_if_index_set == 0)
12714     {
12715       sw_if_index = ~0;
12716     }
12717
12718   if (!vam->json_output)
12719     {
12720       print (vam->ofp, "%11s%11s%24s%24s%13s%14s%12s",
12721              "sw_if_index", "instance", "src_address", "dst_address",
12722              "tunnel_type", "outer_fib_id", "session_id");
12723     }
12724
12725   /* Get list of gre-tunnel interfaces */
12726   M (GRE_TUNNEL_DUMP, mp);
12727
12728   mp->sw_if_index = htonl (sw_if_index);
12729
12730   S (mp);
12731
12732   /* Use a control ping for synchronization */
12733   MPING (CONTROL_PING, mp_ping);
12734   S (mp_ping);
12735
12736   W (ret);
12737   return ret;
12738 }
12739
12740 static int
12741 api_l2_fib_clear_table (vat_main_t * vam)
12742 {
12743 //  unformat_input_t * i = vam->input;
12744   vl_api_l2_fib_clear_table_t *mp;
12745   int ret;
12746
12747   M (L2_FIB_CLEAR_TABLE, mp);
12748
12749   S (mp);
12750   W (ret);
12751   return ret;
12752 }
12753
12754 static int
12755 api_l2_interface_efp_filter (vat_main_t * vam)
12756 {
12757   unformat_input_t *i = vam->input;
12758   vl_api_l2_interface_efp_filter_t *mp;
12759   u32 sw_if_index;
12760   u8 enable = 1;
12761   u8 sw_if_index_set = 0;
12762   int ret;
12763
12764   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12765     {
12766       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12767         sw_if_index_set = 1;
12768       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12769         sw_if_index_set = 1;
12770       else if (unformat (i, "enable"))
12771         enable = 1;
12772       else if (unformat (i, "disable"))
12773         enable = 0;
12774       else
12775         {
12776           clib_warning ("parse error '%U'", format_unformat_error, i);
12777           return -99;
12778         }
12779     }
12780
12781   if (sw_if_index_set == 0)
12782     {
12783       errmsg ("missing sw_if_index");
12784       return -99;
12785     }
12786
12787   M (L2_INTERFACE_EFP_FILTER, mp);
12788
12789   mp->sw_if_index = ntohl (sw_if_index);
12790   mp->enable_disable = enable;
12791
12792   S (mp);
12793   W (ret);
12794   return ret;
12795 }
12796
12797 #define foreach_vtr_op                          \
12798 _("disable",  L2_VTR_DISABLED)                  \
12799 _("push-1",  L2_VTR_PUSH_1)                     \
12800 _("push-2",  L2_VTR_PUSH_2)                     \
12801 _("pop-1",  L2_VTR_POP_1)                       \
12802 _("pop-2",  L2_VTR_POP_2)                       \
12803 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
12804 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
12805 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
12806 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
12807
12808 static int
12809 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
12810 {
12811   unformat_input_t *i = vam->input;
12812   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
12813   u32 sw_if_index;
12814   u8 sw_if_index_set = 0;
12815   u8 vtr_op_set = 0;
12816   u32 vtr_op = 0;
12817   u32 push_dot1q = 1;
12818   u32 tag1 = ~0;
12819   u32 tag2 = ~0;
12820   int ret;
12821
12822   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12823     {
12824       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12825         sw_if_index_set = 1;
12826       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12827         sw_if_index_set = 1;
12828       else if (unformat (i, "vtr_op %d", &vtr_op))
12829         vtr_op_set = 1;
12830 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
12831       foreach_vtr_op
12832 #undef _
12833         else if (unformat (i, "push_dot1q %d", &push_dot1q))
12834         ;
12835       else if (unformat (i, "tag1 %d", &tag1))
12836         ;
12837       else if (unformat (i, "tag2 %d", &tag2))
12838         ;
12839       else
12840         {
12841           clib_warning ("parse error '%U'", format_unformat_error, i);
12842           return -99;
12843         }
12844     }
12845
12846   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
12847     {
12848       errmsg ("missing vtr operation or sw_if_index");
12849       return -99;
12850     }
12851
12852   M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
12853   mp->sw_if_index = ntohl (sw_if_index);
12854   mp->vtr_op = ntohl (vtr_op);
12855   mp->push_dot1q = ntohl (push_dot1q);
12856   mp->tag1 = ntohl (tag1);
12857   mp->tag2 = ntohl (tag2);
12858
12859   S (mp);
12860   W (ret);
12861   return ret;
12862 }
12863
12864 static int
12865 api_create_vhost_user_if (vat_main_t * vam)
12866 {
12867   unformat_input_t *i = vam->input;
12868   vl_api_create_vhost_user_if_t *mp;
12869   u8 *file_name;
12870   u8 is_server = 0;
12871   u8 file_name_set = 0;
12872   u32 custom_dev_instance = ~0;
12873   u8 hwaddr[6];
12874   u8 use_custom_mac = 0;
12875   u8 disable_mrg_rxbuf = 0;
12876   u8 disable_indirect_desc = 0;
12877   u8 *tag = 0;
12878   u8 enable_gso = 0;
12879   int ret;
12880
12881   /* Shut up coverity */
12882   clib_memset (hwaddr, 0, sizeof (hwaddr));
12883
12884   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12885     {
12886       if (unformat (i, "socket %s", &file_name))
12887         {
12888           file_name_set = 1;
12889         }
12890       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
12891         ;
12892       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
12893         use_custom_mac = 1;
12894       else if (unformat (i, "server"))
12895         is_server = 1;
12896       else if (unformat (i, "disable_mrg_rxbuf"))
12897         disable_mrg_rxbuf = 1;
12898       else if (unformat (i, "disable_indirect_desc"))
12899         disable_indirect_desc = 1;
12900       else if (unformat (i, "gso"))
12901         enable_gso = 1;
12902       else if (unformat (i, "tag %s", &tag))
12903         ;
12904       else
12905         break;
12906     }
12907
12908   if (file_name_set == 0)
12909     {
12910       errmsg ("missing socket file name");
12911       return -99;
12912     }
12913
12914   if (vec_len (file_name) > 255)
12915     {
12916       errmsg ("socket file name too long");
12917       return -99;
12918     }
12919   vec_add1 (file_name, 0);
12920
12921   M (CREATE_VHOST_USER_IF, mp);
12922
12923   mp->is_server = is_server;
12924   mp->disable_mrg_rxbuf = disable_mrg_rxbuf;
12925   mp->disable_indirect_desc = disable_indirect_desc;
12926   mp->enable_gso = enable_gso;
12927   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
12928   vec_free (file_name);
12929   if (custom_dev_instance != ~0)
12930     {
12931       mp->renumber = 1;
12932       mp->custom_dev_instance = ntohl (custom_dev_instance);
12933     }
12934
12935   mp->use_custom_mac = use_custom_mac;
12936   clib_memcpy (mp->mac_address, hwaddr, 6);
12937   if (tag)
12938     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
12939   vec_free (tag);
12940
12941   S (mp);
12942   W (ret);
12943   return ret;
12944 }
12945
12946 static int
12947 api_modify_vhost_user_if (vat_main_t * vam)
12948 {
12949   unformat_input_t *i = vam->input;
12950   vl_api_modify_vhost_user_if_t *mp;
12951   u8 *file_name;
12952   u8 is_server = 0;
12953   u8 file_name_set = 0;
12954   u32 custom_dev_instance = ~0;
12955   u8 sw_if_index_set = 0;
12956   u32 sw_if_index = (u32) ~ 0;
12957   u8 enable_gso = 0;
12958   int ret;
12959
12960   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12961     {
12962       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12963         sw_if_index_set = 1;
12964       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12965         sw_if_index_set = 1;
12966       else if (unformat (i, "socket %s", &file_name))
12967         {
12968           file_name_set = 1;
12969         }
12970       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
12971         ;
12972       else if (unformat (i, "server"))
12973         is_server = 1;
12974       else if (unformat (i, "gso"))
12975         enable_gso = 1;
12976       else
12977         break;
12978     }
12979
12980   if (sw_if_index_set == 0)
12981     {
12982       errmsg ("missing sw_if_index or interface name");
12983       return -99;
12984     }
12985
12986   if (file_name_set == 0)
12987     {
12988       errmsg ("missing socket file name");
12989       return -99;
12990     }
12991
12992   if (vec_len (file_name) > 255)
12993     {
12994       errmsg ("socket file name too long");
12995       return -99;
12996     }
12997   vec_add1 (file_name, 0);
12998
12999   M (MODIFY_VHOST_USER_IF, mp);
13000
13001   mp->sw_if_index = ntohl (sw_if_index);
13002   mp->is_server = is_server;
13003   mp->enable_gso = enable_gso;
13004   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
13005   vec_free (file_name);
13006   if (custom_dev_instance != ~0)
13007     {
13008       mp->renumber = 1;
13009       mp->custom_dev_instance = ntohl (custom_dev_instance);
13010     }
13011
13012   S (mp);
13013   W (ret);
13014   return ret;
13015 }
13016
13017 static int
13018 api_delete_vhost_user_if (vat_main_t * vam)
13019 {
13020   unformat_input_t *i = vam->input;
13021   vl_api_delete_vhost_user_if_t *mp;
13022   u32 sw_if_index = ~0;
13023   u8 sw_if_index_set = 0;
13024   int ret;
13025
13026   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13027     {
13028       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13029         sw_if_index_set = 1;
13030       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13031         sw_if_index_set = 1;
13032       else
13033         break;
13034     }
13035
13036   if (sw_if_index_set == 0)
13037     {
13038       errmsg ("missing sw_if_index or interface name");
13039       return -99;
13040     }
13041
13042
13043   M (DELETE_VHOST_USER_IF, mp);
13044
13045   mp->sw_if_index = ntohl (sw_if_index);
13046
13047   S (mp);
13048   W (ret);
13049   return ret;
13050 }
13051
13052 static void vl_api_sw_interface_vhost_user_details_t_handler
13053   (vl_api_sw_interface_vhost_user_details_t * mp)
13054 {
13055   vat_main_t *vam = &vat_main;
13056
13057   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s",
13058          (char *) mp->interface_name,
13059          ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
13060          clib_net_to_host_u64 (mp->features), mp->is_server,
13061          ntohl (mp->num_regions), (char *) mp->sock_filename);
13062   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
13063 }
13064
13065 static void vl_api_sw_interface_vhost_user_details_t_handler_json
13066   (vl_api_sw_interface_vhost_user_details_t * mp)
13067 {
13068   vat_main_t *vam = &vat_main;
13069   vat_json_node_t *node = NULL;
13070
13071   if (VAT_JSON_ARRAY != vam->json_tree.type)
13072     {
13073       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13074       vat_json_init_array (&vam->json_tree);
13075     }
13076   node = vat_json_array_add (&vam->json_tree);
13077
13078   vat_json_init_object (node);
13079   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13080   vat_json_object_add_string_copy (node, "interface_name",
13081                                    mp->interface_name);
13082   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
13083                             ntohl (mp->virtio_net_hdr_sz));
13084   vat_json_object_add_uint (node, "features",
13085                             clib_net_to_host_u64 (mp->features));
13086   vat_json_object_add_uint (node, "is_server", mp->is_server);
13087   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
13088   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
13089   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
13090 }
13091
13092 static int
13093 api_sw_interface_vhost_user_dump (vat_main_t * vam)
13094 {
13095   vl_api_sw_interface_vhost_user_dump_t *mp;
13096   vl_api_control_ping_t *mp_ping;
13097   int ret;
13098   print (vam->ofp,
13099          "Interface name            idx hdr_sz features server regions filename");
13100
13101   /* Get list of vhost-user interfaces */
13102   M (SW_INTERFACE_VHOST_USER_DUMP, mp);
13103   S (mp);
13104
13105   /* Use a control ping for synchronization */
13106   MPING (CONTROL_PING, mp_ping);
13107   S (mp_ping);
13108
13109   W (ret);
13110   return ret;
13111 }
13112
13113 static int
13114 api_show_version (vat_main_t * vam)
13115 {
13116   vl_api_show_version_t *mp;
13117   int ret;
13118
13119   M (SHOW_VERSION, mp);
13120
13121   S (mp);
13122   W (ret);
13123   return ret;
13124 }
13125
13126
13127 static int
13128 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
13129 {
13130   unformat_input_t *line_input = vam->input;
13131   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
13132   ip4_address_t local4, remote4;
13133   ip6_address_t local6, remote6;
13134   u8 is_add = 1;
13135   u8 ipv4_set = 0, ipv6_set = 0;
13136   u8 local_set = 0;
13137   u8 remote_set = 0;
13138   u8 grp_set = 0;
13139   u32 mcast_sw_if_index = ~0;
13140   u32 encap_vrf_id = 0;
13141   u32 decap_vrf_id = 0;
13142   u8 protocol = ~0;
13143   u32 vni;
13144   u8 vni_set = 0;
13145   int ret;
13146
13147   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
13148   clib_memset (&local4, 0, sizeof local4);
13149   clib_memset (&remote4, 0, sizeof remote4);
13150   clib_memset (&local6, 0, sizeof local6);
13151   clib_memset (&remote6, 0, sizeof remote6);
13152
13153   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13154     {
13155       if (unformat (line_input, "del"))
13156         is_add = 0;
13157       else if (unformat (line_input, "local %U",
13158                          unformat_ip4_address, &local4))
13159         {
13160           local_set = 1;
13161           ipv4_set = 1;
13162         }
13163       else if (unformat (line_input, "remote %U",
13164                          unformat_ip4_address, &remote4))
13165         {
13166           remote_set = 1;
13167           ipv4_set = 1;
13168         }
13169       else if (unformat (line_input, "local %U",
13170                          unformat_ip6_address, &local6))
13171         {
13172           local_set = 1;
13173           ipv6_set = 1;
13174         }
13175       else if (unformat (line_input, "remote %U",
13176                          unformat_ip6_address, &remote6))
13177         {
13178           remote_set = 1;
13179           ipv6_set = 1;
13180         }
13181       else if (unformat (line_input, "group %U %U",
13182                          unformat_ip4_address, &remote4,
13183                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13184         {
13185           grp_set = remote_set = 1;
13186           ipv4_set = 1;
13187         }
13188       else if (unformat (line_input, "group %U",
13189                          unformat_ip4_address, &remote4))
13190         {
13191           grp_set = remote_set = 1;
13192           ipv4_set = 1;
13193         }
13194       else if (unformat (line_input, "group %U %U",
13195                          unformat_ip6_address, &remote6,
13196                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13197         {
13198           grp_set = remote_set = 1;
13199           ipv6_set = 1;
13200         }
13201       else if (unformat (line_input, "group %U",
13202                          unformat_ip6_address, &remote6))
13203         {
13204           grp_set = remote_set = 1;
13205           ipv6_set = 1;
13206         }
13207       else
13208         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
13209         ;
13210       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
13211         ;
13212       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
13213         ;
13214       else if (unformat (line_input, "vni %d", &vni))
13215         vni_set = 1;
13216       else if (unformat (line_input, "next-ip4"))
13217         protocol = 1;
13218       else if (unformat (line_input, "next-ip6"))
13219         protocol = 2;
13220       else if (unformat (line_input, "next-ethernet"))
13221         protocol = 3;
13222       else if (unformat (line_input, "next-nsh"))
13223         protocol = 4;
13224       else
13225         {
13226           errmsg ("parse error '%U'", format_unformat_error, line_input);
13227           return -99;
13228         }
13229     }
13230
13231   if (local_set == 0)
13232     {
13233       errmsg ("tunnel local address not specified");
13234       return -99;
13235     }
13236   if (remote_set == 0)
13237     {
13238       errmsg ("tunnel remote address not specified");
13239       return -99;
13240     }
13241   if (grp_set && mcast_sw_if_index == ~0)
13242     {
13243       errmsg ("tunnel nonexistent multicast device");
13244       return -99;
13245     }
13246   if (ipv4_set && ipv6_set)
13247     {
13248       errmsg ("both IPv4 and IPv6 addresses specified");
13249       return -99;
13250     }
13251
13252   if (vni_set == 0)
13253     {
13254       errmsg ("vni not specified");
13255       return -99;
13256     }
13257
13258   M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
13259
13260
13261   if (ipv6_set)
13262     {
13263       clib_memcpy (&mp->local, &local6, sizeof (local6));
13264       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
13265     }
13266   else
13267     {
13268       clib_memcpy (&mp->local, &local4, sizeof (local4));
13269       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
13270     }
13271
13272   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
13273   mp->encap_vrf_id = ntohl (encap_vrf_id);
13274   mp->decap_vrf_id = ntohl (decap_vrf_id);
13275   mp->protocol = protocol;
13276   mp->vni = ntohl (vni);
13277   mp->is_add = is_add;
13278   mp->is_ipv6 = ipv6_set;
13279
13280   S (mp);
13281   W (ret);
13282   return ret;
13283 }
13284
13285 static void vl_api_vxlan_gpe_tunnel_details_t_handler
13286   (vl_api_vxlan_gpe_tunnel_details_t * mp)
13287 {
13288   vat_main_t *vam = &vat_main;
13289   ip46_address_t local = to_ip46 (mp->is_ipv6, mp->local);
13290   ip46_address_t remote = to_ip46 (mp->is_ipv6, mp->remote);
13291
13292   print (vam->ofp, "%11d%24U%24U%13d%12d%19d%14d%14d",
13293          ntohl (mp->sw_if_index),
13294          format_ip46_address, &local, IP46_TYPE_ANY,
13295          format_ip46_address, &remote, IP46_TYPE_ANY,
13296          ntohl (mp->vni), mp->protocol,
13297          ntohl (mp->mcast_sw_if_index),
13298          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
13299 }
13300
13301
13302 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
13303   (vl_api_vxlan_gpe_tunnel_details_t * mp)
13304 {
13305   vat_main_t *vam = &vat_main;
13306   vat_json_node_t *node = NULL;
13307   struct in_addr ip4;
13308   struct in6_addr ip6;
13309
13310   if (VAT_JSON_ARRAY != vam->json_tree.type)
13311     {
13312       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13313       vat_json_init_array (&vam->json_tree);
13314     }
13315   node = vat_json_array_add (&vam->json_tree);
13316
13317   vat_json_init_object (node);
13318   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13319   if (mp->is_ipv6)
13320     {
13321       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
13322       vat_json_object_add_ip6 (node, "local", ip6);
13323       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
13324       vat_json_object_add_ip6 (node, "remote", ip6);
13325     }
13326   else
13327     {
13328       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
13329       vat_json_object_add_ip4 (node, "local", ip4);
13330       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
13331       vat_json_object_add_ip4 (node, "remote", ip4);
13332     }
13333   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
13334   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
13335   vat_json_object_add_uint (node, "mcast_sw_if_index",
13336                             ntohl (mp->mcast_sw_if_index));
13337   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
13338   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
13339   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
13340 }
13341
13342 static int
13343 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
13344 {
13345   unformat_input_t *i = vam->input;
13346   vl_api_vxlan_gpe_tunnel_dump_t *mp;
13347   vl_api_control_ping_t *mp_ping;
13348   u32 sw_if_index;
13349   u8 sw_if_index_set = 0;
13350   int ret;
13351
13352   /* Parse args required to build the message */
13353   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13354     {
13355       if (unformat (i, "sw_if_index %d", &sw_if_index))
13356         sw_if_index_set = 1;
13357       else
13358         break;
13359     }
13360
13361   if (sw_if_index_set == 0)
13362     {
13363       sw_if_index = ~0;
13364     }
13365
13366   if (!vam->json_output)
13367     {
13368       print (vam->ofp, "%11s%24s%24s%13s%15s%19s%14s%14s",
13369              "sw_if_index", "local", "remote", "vni",
13370              "protocol", "mcast_sw_if_index", "encap_vrf_id", "decap_vrf_id");
13371     }
13372
13373   /* Get list of vxlan-tunnel interfaces */
13374   M (VXLAN_GPE_TUNNEL_DUMP, mp);
13375
13376   mp->sw_if_index = htonl (sw_if_index);
13377
13378   S (mp);
13379
13380   /* Use a control ping for synchronization */
13381   MPING (CONTROL_PING, mp_ping);
13382   S (mp_ping);
13383
13384   W (ret);
13385   return ret;
13386 }
13387
13388 static void vl_api_l2_fib_table_details_t_handler
13389   (vl_api_l2_fib_table_details_t * mp)
13390 {
13391   vat_main_t *vam = &vat_main;
13392
13393   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
13394          "       %d       %d     %d",
13395          ntohl (mp->bd_id), format_ethernet_address, mp->mac,
13396          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
13397          mp->bvi_mac);
13398 }
13399
13400 static void vl_api_l2_fib_table_details_t_handler_json
13401   (vl_api_l2_fib_table_details_t * mp)
13402 {
13403   vat_main_t *vam = &vat_main;
13404   vat_json_node_t *node = NULL;
13405
13406   if (VAT_JSON_ARRAY != vam->json_tree.type)
13407     {
13408       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13409       vat_json_init_array (&vam->json_tree);
13410     }
13411   node = vat_json_array_add (&vam->json_tree);
13412
13413   vat_json_init_object (node);
13414   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
13415   vat_json_object_add_bytes (node, "mac", mp->mac, 6);
13416   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13417   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
13418   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
13419   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
13420 }
13421
13422 static int
13423 api_l2_fib_table_dump (vat_main_t * vam)
13424 {
13425   unformat_input_t *i = vam->input;
13426   vl_api_l2_fib_table_dump_t *mp;
13427   vl_api_control_ping_t *mp_ping;
13428   u32 bd_id;
13429   u8 bd_id_set = 0;
13430   int ret;
13431
13432   /* Parse args required to build the message */
13433   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13434     {
13435       if (unformat (i, "bd_id %d", &bd_id))
13436         bd_id_set = 1;
13437       else
13438         break;
13439     }
13440
13441   if (bd_id_set == 0)
13442     {
13443       errmsg ("missing bridge domain");
13444       return -99;
13445     }
13446
13447   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
13448
13449   /* Get list of l2 fib entries */
13450   M (L2_FIB_TABLE_DUMP, mp);
13451
13452   mp->bd_id = ntohl (bd_id);
13453   S (mp);
13454
13455   /* Use a control ping for synchronization */
13456   MPING (CONTROL_PING, mp_ping);
13457   S (mp_ping);
13458
13459   W (ret);
13460   return ret;
13461 }
13462
13463
13464 static int
13465 api_interface_name_renumber (vat_main_t * vam)
13466 {
13467   unformat_input_t *line_input = vam->input;
13468   vl_api_interface_name_renumber_t *mp;
13469   u32 sw_if_index = ~0;
13470   u32 new_show_dev_instance = ~0;
13471   int ret;
13472
13473   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13474     {
13475       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
13476                     &sw_if_index))
13477         ;
13478       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
13479         ;
13480       else if (unformat (line_input, "new_show_dev_instance %d",
13481                          &new_show_dev_instance))
13482         ;
13483       else
13484         break;
13485     }
13486
13487   if (sw_if_index == ~0)
13488     {
13489       errmsg ("missing interface name or sw_if_index");
13490       return -99;
13491     }
13492
13493   if (new_show_dev_instance == ~0)
13494     {
13495       errmsg ("missing new_show_dev_instance");
13496       return -99;
13497     }
13498
13499   M (INTERFACE_NAME_RENUMBER, mp);
13500
13501   mp->sw_if_index = ntohl (sw_if_index);
13502   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
13503
13504   S (mp);
13505   W (ret);
13506   return ret;
13507 }
13508
13509 static int
13510 api_ip_probe_neighbor (vat_main_t * vam)
13511 {
13512   unformat_input_t *i = vam->input;
13513   vl_api_ip_probe_neighbor_t *mp;
13514   vl_api_address_t dst_adr = { };
13515   u8 int_set = 0;
13516   u8 adr_set = 0;
13517   u32 sw_if_index;
13518   int ret;
13519
13520   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13521     {
13522       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13523         int_set = 1;
13524       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13525         int_set = 1;
13526       else if (unformat (i, "address %U", unformat_vl_api_address, &dst_adr))
13527         adr_set = 1;
13528       else
13529         break;
13530     }
13531
13532   if (int_set == 0)
13533     {
13534       errmsg ("missing interface");
13535       return -99;
13536     }
13537
13538   if (adr_set == 0)
13539     {
13540       errmsg ("missing addresses");
13541       return -99;
13542     }
13543
13544   M (IP_PROBE_NEIGHBOR, mp);
13545
13546   mp->sw_if_index = ntohl (sw_if_index);
13547   clib_memcpy (&mp->dst, &dst_adr, sizeof (dst_adr));
13548
13549   S (mp);
13550   W (ret);
13551   return ret;
13552 }
13553
13554 static int
13555 api_ip_scan_neighbor_enable_disable (vat_main_t * vam)
13556 {
13557   unformat_input_t *i = vam->input;
13558   vl_api_ip_scan_neighbor_enable_disable_t *mp;
13559   u8 mode = IP_SCAN_V46_NEIGHBORS;
13560   u32 interval = 0, time = 0, update = 0, delay = 0, stale = 0;
13561   int ret;
13562
13563   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13564     {
13565       if (unformat (i, "ip4"))
13566         mode = IP_SCAN_V4_NEIGHBORS;
13567       else if (unformat (i, "ip6"))
13568         mode = IP_SCAN_V6_NEIGHBORS;
13569       if (unformat (i, "both"))
13570         mode = IP_SCAN_V46_NEIGHBORS;
13571       else if (unformat (i, "disable"))
13572         mode = IP_SCAN_DISABLED;
13573       else if (unformat (i, "interval %d", &interval))
13574         ;
13575       else if (unformat (i, "max-time %d", &time))
13576         ;
13577       else if (unformat (i, "max-update %d", &update))
13578         ;
13579       else if (unformat (i, "delay %d", &delay))
13580         ;
13581       else if (unformat (i, "stale %d", &stale))
13582         ;
13583       else
13584         break;
13585     }
13586
13587   if (interval > 255)
13588     {
13589       errmsg ("interval cannot exceed 255 minutes.");
13590       return -99;
13591     }
13592   if (time > 255)
13593     {
13594       errmsg ("max-time cannot exceed 255 usec.");
13595       return -99;
13596     }
13597   if (update > 255)
13598     {
13599       errmsg ("max-update cannot exceed 255.");
13600       return -99;
13601     }
13602   if (delay > 255)
13603     {
13604       errmsg ("delay cannot exceed 255 msec.");
13605       return -99;
13606     }
13607   if (stale > 255)
13608     {
13609       errmsg ("stale cannot exceed 255 minutes.");
13610       return -99;
13611     }
13612
13613   M (IP_SCAN_NEIGHBOR_ENABLE_DISABLE, mp);
13614   mp->mode = mode;
13615   mp->scan_interval = interval;
13616   mp->max_proc_time = time;
13617   mp->max_update = update;
13618   mp->scan_int_delay = delay;
13619   mp->stale_threshold = stale;
13620
13621   S (mp);
13622   W (ret);
13623   return ret;
13624 }
13625
13626 static int
13627 api_want_ip4_arp_events (vat_main_t * vam)
13628 {
13629   unformat_input_t *line_input = vam->input;
13630   vl_api_want_ip4_arp_events_t *mp;
13631   ip4_address_t address;
13632   int address_set = 0;
13633   u32 enable_disable = 1;
13634   int ret;
13635
13636   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13637     {
13638       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
13639         address_set = 1;
13640       else if (unformat (line_input, "del"))
13641         enable_disable = 0;
13642       else
13643         break;
13644     }
13645
13646   if (address_set == 0)
13647     {
13648       errmsg ("missing addresses");
13649       return -99;
13650     }
13651
13652   M (WANT_IP4_ARP_EVENTS, mp);
13653   mp->enable_disable = enable_disable;
13654   mp->pid = htonl (getpid ());
13655   clib_memcpy (mp->ip, &address, sizeof (address));
13656
13657   S (mp);
13658   W (ret);
13659   return ret;
13660 }
13661
13662 static int
13663 api_want_ip6_nd_events (vat_main_t * vam)
13664 {
13665   unformat_input_t *line_input = vam->input;
13666   vl_api_want_ip6_nd_events_t *mp;
13667   vl_api_ip6_address_t address;
13668   int address_set = 0;
13669   u32 enable_disable = 1;
13670   int ret;
13671
13672   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13673     {
13674       if (unformat
13675           (line_input, "address %U", unformat_vl_api_ip6_address, &address))
13676         address_set = 1;
13677       else if (unformat (line_input, "del"))
13678         enable_disable = 0;
13679       else
13680         break;
13681     }
13682
13683   if (address_set == 0)
13684     {
13685       errmsg ("missing addresses");
13686       return -99;
13687     }
13688
13689   M (WANT_IP6_ND_EVENTS, mp);
13690   mp->enable_disable = enable_disable;
13691   mp->pid = htonl (getpid ());
13692   clib_memcpy (&mp->ip, &address, sizeof (address));
13693
13694   S (mp);
13695   W (ret);
13696   return ret;
13697 }
13698
13699 static int
13700 api_want_l2_macs_events (vat_main_t * vam)
13701 {
13702   unformat_input_t *line_input = vam->input;
13703   vl_api_want_l2_macs_events_t *mp;
13704   u8 enable_disable = 1;
13705   u32 scan_delay = 0;
13706   u32 max_macs_in_event = 0;
13707   u32 learn_limit = 0;
13708   int ret;
13709
13710   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13711     {
13712       if (unformat (line_input, "learn-limit %d", &learn_limit))
13713         ;
13714       else if (unformat (line_input, "scan-delay %d", &scan_delay))
13715         ;
13716       else if (unformat (line_input, "max-entries %d", &max_macs_in_event))
13717         ;
13718       else if (unformat (line_input, "disable"))
13719         enable_disable = 0;
13720       else
13721         break;
13722     }
13723
13724   M (WANT_L2_MACS_EVENTS, mp);
13725   mp->enable_disable = enable_disable;
13726   mp->pid = htonl (getpid ());
13727   mp->learn_limit = htonl (learn_limit);
13728   mp->scan_delay = (u8) scan_delay;
13729   mp->max_macs_in_event = (u8) (max_macs_in_event / 10);
13730   S (mp);
13731   W (ret);
13732   return ret;
13733 }
13734
13735 static int
13736 api_input_acl_set_interface (vat_main_t * vam)
13737 {
13738   unformat_input_t *i = vam->input;
13739   vl_api_input_acl_set_interface_t *mp;
13740   u32 sw_if_index;
13741   int sw_if_index_set;
13742   u32 ip4_table_index = ~0;
13743   u32 ip6_table_index = ~0;
13744   u32 l2_table_index = ~0;
13745   u8 is_add = 1;
13746   int ret;
13747
13748   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13749     {
13750       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13751         sw_if_index_set = 1;
13752       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13753         sw_if_index_set = 1;
13754       else if (unformat (i, "del"))
13755         is_add = 0;
13756       else if (unformat (i, "ip4-table %d", &ip4_table_index))
13757         ;
13758       else if (unformat (i, "ip6-table %d", &ip6_table_index))
13759         ;
13760       else if (unformat (i, "l2-table %d", &l2_table_index))
13761         ;
13762       else
13763         {
13764           clib_warning ("parse error '%U'", format_unformat_error, i);
13765           return -99;
13766         }
13767     }
13768
13769   if (sw_if_index_set == 0)
13770     {
13771       errmsg ("missing interface name or sw_if_index");
13772       return -99;
13773     }
13774
13775   M (INPUT_ACL_SET_INTERFACE, mp);
13776
13777   mp->sw_if_index = ntohl (sw_if_index);
13778   mp->ip4_table_index = ntohl (ip4_table_index);
13779   mp->ip6_table_index = ntohl (ip6_table_index);
13780   mp->l2_table_index = ntohl (l2_table_index);
13781   mp->is_add = is_add;
13782
13783   S (mp);
13784   W (ret);
13785   return ret;
13786 }
13787
13788 static int
13789 api_output_acl_set_interface (vat_main_t * vam)
13790 {
13791   unformat_input_t *i = vam->input;
13792   vl_api_output_acl_set_interface_t *mp;
13793   u32 sw_if_index;
13794   int sw_if_index_set;
13795   u32 ip4_table_index = ~0;
13796   u32 ip6_table_index = ~0;
13797   u32 l2_table_index = ~0;
13798   u8 is_add = 1;
13799   int ret;
13800
13801   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13802     {
13803       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13804         sw_if_index_set = 1;
13805       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13806         sw_if_index_set = 1;
13807       else if (unformat (i, "del"))
13808         is_add = 0;
13809       else if (unformat (i, "ip4-table %d", &ip4_table_index))
13810         ;
13811       else if (unformat (i, "ip6-table %d", &ip6_table_index))
13812         ;
13813       else if (unformat (i, "l2-table %d", &l2_table_index))
13814         ;
13815       else
13816         {
13817           clib_warning ("parse error '%U'", format_unformat_error, i);
13818           return -99;
13819         }
13820     }
13821
13822   if (sw_if_index_set == 0)
13823     {
13824       errmsg ("missing interface name or sw_if_index");
13825       return -99;
13826     }
13827
13828   M (OUTPUT_ACL_SET_INTERFACE, mp);
13829
13830   mp->sw_if_index = ntohl (sw_if_index);
13831   mp->ip4_table_index = ntohl (ip4_table_index);
13832   mp->ip6_table_index = ntohl (ip6_table_index);
13833   mp->l2_table_index = ntohl (l2_table_index);
13834   mp->is_add = is_add;
13835
13836   S (mp);
13837   W (ret);
13838   return ret;
13839 }
13840
13841 static int
13842 api_ip_address_dump (vat_main_t * vam)
13843 {
13844   unformat_input_t *i = vam->input;
13845   vl_api_ip_address_dump_t *mp;
13846   vl_api_control_ping_t *mp_ping;
13847   u32 sw_if_index = ~0;
13848   u8 sw_if_index_set = 0;
13849   u8 ipv4_set = 0;
13850   u8 ipv6_set = 0;
13851   int ret;
13852
13853   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13854     {
13855       if (unformat (i, "sw_if_index %d", &sw_if_index))
13856         sw_if_index_set = 1;
13857       else
13858         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13859         sw_if_index_set = 1;
13860       else if (unformat (i, "ipv4"))
13861         ipv4_set = 1;
13862       else if (unformat (i, "ipv6"))
13863         ipv6_set = 1;
13864       else
13865         break;
13866     }
13867
13868   if (ipv4_set && ipv6_set)
13869     {
13870       errmsg ("ipv4 and ipv6 flags cannot be both set");
13871       return -99;
13872     }
13873
13874   if ((!ipv4_set) && (!ipv6_set))
13875     {
13876       errmsg ("no ipv4 nor ipv6 flag set");
13877       return -99;
13878     }
13879
13880   if (sw_if_index_set == 0)
13881     {
13882       errmsg ("missing interface name or sw_if_index");
13883       return -99;
13884     }
13885
13886   vam->current_sw_if_index = sw_if_index;
13887   vam->is_ipv6 = ipv6_set;
13888
13889   M (IP_ADDRESS_DUMP, mp);
13890   mp->sw_if_index = ntohl (sw_if_index);
13891   mp->is_ipv6 = ipv6_set;
13892   S (mp);
13893
13894   /* Use a control ping for synchronization */
13895   MPING (CONTROL_PING, mp_ping);
13896   S (mp_ping);
13897
13898   W (ret);
13899   return ret;
13900 }
13901
13902 static int
13903 api_ip_dump (vat_main_t * vam)
13904 {
13905   vl_api_ip_dump_t *mp;
13906   vl_api_control_ping_t *mp_ping;
13907   unformat_input_t *in = vam->input;
13908   int ipv4_set = 0;
13909   int ipv6_set = 0;
13910   int is_ipv6;
13911   int i;
13912   int ret;
13913
13914   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
13915     {
13916       if (unformat (in, "ipv4"))
13917         ipv4_set = 1;
13918       else if (unformat (in, "ipv6"))
13919         ipv6_set = 1;
13920       else
13921         break;
13922     }
13923
13924   if (ipv4_set && ipv6_set)
13925     {
13926       errmsg ("ipv4 and ipv6 flags cannot be both set");
13927       return -99;
13928     }
13929
13930   if ((!ipv4_set) && (!ipv6_set))
13931     {
13932       errmsg ("no ipv4 nor ipv6 flag set");
13933       return -99;
13934     }
13935
13936   is_ipv6 = ipv6_set;
13937   vam->is_ipv6 = is_ipv6;
13938
13939   /* free old data */
13940   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
13941     {
13942       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
13943     }
13944   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
13945
13946   M (IP_DUMP, mp);
13947   mp->is_ipv6 = ipv6_set;
13948   S (mp);
13949
13950   /* Use a control ping for synchronization */
13951   MPING (CONTROL_PING, mp_ping);
13952   S (mp_ping);
13953
13954   W (ret);
13955   return ret;
13956 }
13957
13958 static int
13959 api_ipsec_spd_add_del (vat_main_t * vam)
13960 {
13961   unformat_input_t *i = vam->input;
13962   vl_api_ipsec_spd_add_del_t *mp;
13963   u32 spd_id = ~0;
13964   u8 is_add = 1;
13965   int ret;
13966
13967   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13968     {
13969       if (unformat (i, "spd_id %d", &spd_id))
13970         ;
13971       else if (unformat (i, "del"))
13972         is_add = 0;
13973       else
13974         {
13975           clib_warning ("parse error '%U'", format_unformat_error, i);
13976           return -99;
13977         }
13978     }
13979   if (spd_id == ~0)
13980     {
13981       errmsg ("spd_id must be set");
13982       return -99;
13983     }
13984
13985   M (IPSEC_SPD_ADD_DEL, mp);
13986
13987   mp->spd_id = ntohl (spd_id);
13988   mp->is_add = is_add;
13989
13990   S (mp);
13991   W (ret);
13992   return ret;
13993 }
13994
13995 static int
13996 api_ipsec_interface_add_del_spd (vat_main_t * vam)
13997 {
13998   unformat_input_t *i = vam->input;
13999   vl_api_ipsec_interface_add_del_spd_t *mp;
14000   u32 sw_if_index;
14001   u8 sw_if_index_set = 0;
14002   u32 spd_id = (u32) ~ 0;
14003   u8 is_add = 1;
14004   int ret;
14005
14006   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14007     {
14008       if (unformat (i, "del"))
14009         is_add = 0;
14010       else if (unformat (i, "spd_id %d", &spd_id))
14011         ;
14012       else
14013         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14014         sw_if_index_set = 1;
14015       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14016         sw_if_index_set = 1;
14017       else
14018         {
14019           clib_warning ("parse error '%U'", format_unformat_error, i);
14020           return -99;
14021         }
14022
14023     }
14024
14025   if (spd_id == (u32) ~ 0)
14026     {
14027       errmsg ("spd_id must be set");
14028       return -99;
14029     }
14030
14031   if (sw_if_index_set == 0)
14032     {
14033       errmsg ("missing interface name or sw_if_index");
14034       return -99;
14035     }
14036
14037   M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
14038
14039   mp->spd_id = ntohl (spd_id);
14040   mp->sw_if_index = ntohl (sw_if_index);
14041   mp->is_add = is_add;
14042
14043   S (mp);
14044   W (ret);
14045   return ret;
14046 }
14047
14048 static int
14049 api_ipsec_spd_entry_add_del (vat_main_t * vam)
14050 {
14051   unformat_input_t *i = vam->input;
14052   vl_api_ipsec_spd_entry_add_del_t *mp;
14053   u8 is_add = 1, is_outbound = 0;
14054   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
14055   i32 priority = 0;
14056   u32 rport_start = 0, rport_stop = (u32) ~ 0;
14057   u32 lport_start = 0, lport_stop = (u32) ~ 0;
14058   vl_api_address_t laddr_start = { }, laddr_stop =
14059   {
14060   }, raddr_start =
14061   {
14062   }, raddr_stop =
14063   {
14064   };
14065   int ret;
14066
14067   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14068     {
14069       if (unformat (i, "del"))
14070         is_add = 0;
14071       if (unformat (i, "outbound"))
14072         is_outbound = 1;
14073       if (unformat (i, "inbound"))
14074         is_outbound = 0;
14075       else if (unformat (i, "spd_id %d", &spd_id))
14076         ;
14077       else if (unformat (i, "sa_id %d", &sa_id))
14078         ;
14079       else if (unformat (i, "priority %d", &priority))
14080         ;
14081       else if (unformat (i, "protocol %d", &protocol))
14082         ;
14083       else if (unformat (i, "lport_start %d", &lport_start))
14084         ;
14085       else if (unformat (i, "lport_stop %d", &lport_stop))
14086         ;
14087       else if (unformat (i, "rport_start %d", &rport_start))
14088         ;
14089       else if (unformat (i, "rport_stop %d", &rport_stop))
14090         ;
14091       else if (unformat (i, "laddr_start %U",
14092                          unformat_vl_api_address, &laddr_start))
14093         ;
14094       else if (unformat (i, "laddr_stop %U", unformat_vl_api_address,
14095                          &laddr_stop))
14096         ;
14097       else if (unformat (i, "raddr_start %U", unformat_vl_api_address,
14098                          &raddr_start))
14099         ;
14100       else if (unformat (i, "raddr_stop %U", unformat_vl_api_address,
14101                          &raddr_stop))
14102         ;
14103       else
14104         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
14105         {
14106           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
14107             {
14108               clib_warning ("unsupported action: 'resolve'");
14109               return -99;
14110             }
14111         }
14112       else
14113         {
14114           clib_warning ("parse error '%U'", format_unformat_error, i);
14115           return -99;
14116         }
14117
14118     }
14119
14120   M (IPSEC_SPD_ENTRY_ADD_DEL, mp);
14121
14122   mp->is_add = is_add;
14123
14124   mp->entry.spd_id = ntohl (spd_id);
14125   mp->entry.priority = ntohl (priority);
14126   mp->entry.is_outbound = is_outbound;
14127
14128   clib_memcpy (&mp->entry.remote_address_start, &raddr_start,
14129                sizeof (vl_api_address_t));
14130   clib_memcpy (&mp->entry.remote_address_stop, &raddr_stop,
14131                sizeof (vl_api_address_t));
14132   clib_memcpy (&mp->entry.local_address_start, &laddr_start,
14133                sizeof (vl_api_address_t));
14134   clib_memcpy (&mp->entry.local_address_stop, &laddr_stop,
14135                sizeof (vl_api_address_t));
14136
14137   mp->entry.protocol = (u8) protocol;
14138   mp->entry.local_port_start = ntohs ((u16) lport_start);
14139   mp->entry.local_port_stop = ntohs ((u16) lport_stop);
14140   mp->entry.remote_port_start = ntohs ((u16) rport_start);
14141   mp->entry.remote_port_stop = ntohs ((u16) rport_stop);
14142   mp->entry.policy = (u8) policy;
14143   mp->entry.sa_id = ntohl (sa_id);
14144
14145   S (mp);
14146   W (ret);
14147   return ret;
14148 }
14149
14150 static int
14151 api_ipsec_sad_entry_add_del (vat_main_t * vam)
14152 {
14153   unformat_input_t *i = vam->input;
14154   vl_api_ipsec_sad_entry_add_del_t *mp;
14155   u32 sad_id = 0, spi = 0;
14156   u8 *ck = 0, *ik = 0;
14157   u8 is_add = 1;
14158
14159   vl_api_ipsec_crypto_alg_t crypto_alg = IPSEC_API_CRYPTO_ALG_NONE;
14160   vl_api_ipsec_integ_alg_t integ_alg = IPSEC_API_INTEG_ALG_NONE;
14161   vl_api_ipsec_sad_flags_t flags = IPSEC_API_SAD_FLAG_NONE;
14162   vl_api_ipsec_proto_t protocol = IPSEC_API_PROTO_AH;
14163   vl_api_address_t tun_src, tun_dst;
14164   int ret;
14165
14166   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14167     {
14168       if (unformat (i, "del"))
14169         is_add = 0;
14170       else if (unformat (i, "sad_id %d", &sad_id))
14171         ;
14172       else if (unformat (i, "spi %d", &spi))
14173         ;
14174       else if (unformat (i, "esp"))
14175         protocol = IPSEC_API_PROTO_ESP;
14176       else
14177         if (unformat (i, "tunnel_src %U", unformat_vl_api_address, &tun_src))
14178         {
14179           flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL;
14180           if (ADDRESS_IP6 == tun_src.af)
14181             flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL_V6;
14182         }
14183       else
14184         if (unformat (i, "tunnel_dst %U", unformat_vl_api_address, &tun_dst))
14185         {
14186           flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL;
14187           if (ADDRESS_IP6 == tun_src.af)
14188             flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL_V6;
14189         }
14190       else
14191         if (unformat (i, "crypto_alg %U",
14192                       unformat_ipsec_api_crypto_alg, &crypto_alg))
14193         ;
14194       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
14195         ;
14196       else if (unformat (i, "integ_alg %U",
14197                          unformat_ipsec_api_integ_alg, &integ_alg))
14198         ;
14199       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
14200         ;
14201       else
14202         {
14203           clib_warning ("parse error '%U'", format_unformat_error, i);
14204           return -99;
14205         }
14206
14207     }
14208
14209   M (IPSEC_SAD_ENTRY_ADD_DEL, mp);
14210
14211   mp->is_add = is_add;
14212   mp->entry.sad_id = ntohl (sad_id);
14213   mp->entry.protocol = protocol;
14214   mp->entry.spi = ntohl (spi);
14215   mp->entry.flags = flags;
14216
14217   mp->entry.crypto_algorithm = crypto_alg;
14218   mp->entry.integrity_algorithm = integ_alg;
14219   mp->entry.crypto_key.length = vec_len (ck);
14220   mp->entry.integrity_key.length = vec_len (ik);
14221
14222   if (mp->entry.crypto_key.length > sizeof (mp->entry.crypto_key.data))
14223     mp->entry.crypto_key.length = sizeof (mp->entry.crypto_key.data);
14224
14225   if (mp->entry.integrity_key.length > sizeof (mp->entry.integrity_key.data))
14226     mp->entry.integrity_key.length = sizeof (mp->entry.integrity_key.data);
14227
14228   if (ck)
14229     clib_memcpy (mp->entry.crypto_key.data, ck, mp->entry.crypto_key.length);
14230   if (ik)
14231     clib_memcpy (mp->entry.integrity_key.data, ik,
14232                  mp->entry.integrity_key.length);
14233
14234   if (flags & IPSEC_API_SAD_FLAG_IS_TUNNEL)
14235     {
14236       clib_memcpy (&mp->entry.tunnel_src, &tun_src,
14237                    sizeof (mp->entry.tunnel_src));
14238       clib_memcpy (&mp->entry.tunnel_dst, &tun_dst,
14239                    sizeof (mp->entry.tunnel_dst));
14240     }
14241
14242   S (mp);
14243   W (ret);
14244   return ret;
14245 }
14246
14247 static int
14248 api_ipsec_tunnel_if_add_del (vat_main_t * vam)
14249 {
14250   unformat_input_t *i = vam->input;
14251   vl_api_ipsec_tunnel_if_add_del_t *mp;
14252   u32 local_spi = 0, remote_spi = 0;
14253   u32 crypto_alg = 0, integ_alg = 0;
14254   u8 *lck = NULL, *rck = NULL;
14255   u8 *lik = NULL, *rik = NULL;
14256   vl_api_address_t local_ip = { 0 };
14257   vl_api_address_t remote_ip = { 0 };
14258   f64 before = 0;
14259   u8 is_add = 1;
14260   u8 esn = 0;
14261   u8 anti_replay = 0;
14262   u8 renumber = 0;
14263   u32 instance = ~0;
14264   u32 count = 1, jj;
14265   int ret = -1;
14266
14267   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14268     {
14269       if (unformat (i, "del"))
14270         is_add = 0;
14271       else if (unformat (i, "esn"))
14272         esn = 1;
14273       else if (unformat (i, "anti-replay"))
14274         anti_replay = 1;
14275       else if (unformat (i, "count %d", &count))
14276         ;
14277       else if (unformat (i, "local_spi %d", &local_spi))
14278         ;
14279       else if (unformat (i, "remote_spi %d", &remote_spi))
14280         ;
14281       else
14282         if (unformat (i, "local_ip %U", unformat_vl_api_address, &local_ip))
14283         ;
14284       else
14285         if (unformat (i, "remote_ip %U", unformat_vl_api_address, &remote_ip))
14286         ;
14287       else if (unformat (i, "local_crypto_key %U", unformat_hex_string, &lck))
14288         ;
14289       else
14290         if (unformat (i, "remote_crypto_key %U", unformat_hex_string, &rck))
14291         ;
14292       else if (unformat (i, "local_integ_key %U", unformat_hex_string, &lik))
14293         ;
14294       else if (unformat (i, "remote_integ_key %U", unformat_hex_string, &rik))
14295         ;
14296       else
14297         if (unformat
14298             (i, "crypto_alg %U", unformat_ipsec_api_crypto_alg, &crypto_alg))
14299         {
14300           if (crypto_alg >= IPSEC_CRYPTO_N_ALG)
14301             {
14302               errmsg ("unsupported crypto-alg: '%U'\n",
14303                       format_ipsec_crypto_alg, crypto_alg);
14304               return -99;
14305             }
14306         }
14307       else
14308         if (unformat
14309             (i, "integ_alg %U", unformat_ipsec_api_integ_alg, &integ_alg))
14310         {
14311           if (integ_alg >= IPSEC_INTEG_N_ALG)
14312             {
14313               errmsg ("unsupported integ-alg: '%U'\n",
14314                       format_ipsec_integ_alg, integ_alg);
14315               return -99;
14316             }
14317         }
14318       else if (unformat (i, "instance %u", &instance))
14319         renumber = 1;
14320       else
14321         {
14322           errmsg ("parse error '%U'\n", format_unformat_error, i);
14323           return -99;
14324         }
14325     }
14326
14327   if (count > 1)
14328     {
14329       /* Turn on async mode */
14330       vam->async_mode = 1;
14331       vam->async_errors = 0;
14332       before = vat_time_now (vam);
14333     }
14334
14335   for (jj = 0; jj < count; jj++)
14336     {
14337       M (IPSEC_TUNNEL_IF_ADD_DEL, mp);
14338
14339       mp->is_add = is_add;
14340       mp->esn = esn;
14341       mp->anti_replay = anti_replay;
14342
14343       if (jj > 0)
14344         increment_address (&remote_ip);
14345
14346       clib_memcpy (&mp->local_ip, &local_ip, sizeof (local_ip));
14347       clib_memcpy (&mp->remote_ip, &remote_ip, sizeof (remote_ip));
14348
14349       mp->local_spi = htonl (local_spi + jj);
14350       mp->remote_spi = htonl (remote_spi + jj);
14351       mp->crypto_alg = (u8) crypto_alg;
14352
14353       mp->local_crypto_key_len = 0;
14354       if (lck)
14355         {
14356           mp->local_crypto_key_len = vec_len (lck);
14357           if (mp->local_crypto_key_len > sizeof (mp->local_crypto_key))
14358             mp->local_crypto_key_len = sizeof (mp->local_crypto_key);
14359           clib_memcpy (mp->local_crypto_key, lck, mp->local_crypto_key_len);
14360         }
14361
14362       mp->remote_crypto_key_len = 0;
14363       if (rck)
14364         {
14365           mp->remote_crypto_key_len = vec_len (rck);
14366           if (mp->remote_crypto_key_len > sizeof (mp->remote_crypto_key))
14367             mp->remote_crypto_key_len = sizeof (mp->remote_crypto_key);
14368           clib_memcpy (mp->remote_crypto_key, rck, mp->remote_crypto_key_len);
14369         }
14370
14371       mp->integ_alg = (u8) integ_alg;
14372
14373       mp->local_integ_key_len = 0;
14374       if (lik)
14375         {
14376           mp->local_integ_key_len = vec_len (lik);
14377           if (mp->local_integ_key_len > sizeof (mp->local_integ_key))
14378             mp->local_integ_key_len = sizeof (mp->local_integ_key);
14379           clib_memcpy (mp->local_integ_key, lik, mp->local_integ_key_len);
14380         }
14381
14382       mp->remote_integ_key_len = 0;
14383       if (rik)
14384         {
14385           mp->remote_integ_key_len = vec_len (rik);
14386           if (mp->remote_integ_key_len > sizeof (mp->remote_integ_key))
14387             mp->remote_integ_key_len = sizeof (mp->remote_integ_key);
14388           clib_memcpy (mp->remote_integ_key, rik, mp->remote_integ_key_len);
14389         }
14390
14391       if (renumber)
14392         {
14393           mp->renumber = renumber;
14394           mp->show_instance = ntohl (instance);
14395         }
14396       S (mp);
14397     }
14398
14399   /* When testing multiple add/del ops, use a control-ping to sync */
14400   if (count > 1)
14401     {
14402       vl_api_control_ping_t *mp_ping;
14403       f64 after;
14404       f64 timeout;
14405
14406       /* Shut off async mode */
14407       vam->async_mode = 0;
14408
14409       MPING (CONTROL_PING, mp_ping);
14410       S (mp_ping);
14411
14412       timeout = vat_time_now (vam) + 1.0;
14413       while (vat_time_now (vam) < timeout)
14414         if (vam->result_ready == 1)
14415           goto out;
14416       vam->retval = -99;
14417
14418     out:
14419       if (vam->retval == -99)
14420         errmsg ("timeout");
14421
14422       if (vam->async_errors > 0)
14423         {
14424           errmsg ("%d asynchronous errors", vam->async_errors);
14425           vam->retval = -98;
14426         }
14427       vam->async_errors = 0;
14428       after = vat_time_now (vam);
14429
14430       /* slim chance, but we might have eaten SIGTERM on the first iteration */
14431       if (jj > 0)
14432         count = jj;
14433
14434       print (vam->ofp, "%d tunnels in %.6f secs, %.2f tunnels/sec",
14435              count, after - before, count / (after - before));
14436     }
14437   else
14438     {
14439       /* Wait for a reply... */
14440       W (ret);
14441       return ret;
14442     }
14443
14444   return ret;
14445 }
14446
14447 static void
14448 vl_api_ipsec_sa_details_t_handler (vl_api_ipsec_sa_details_t * mp)
14449 {
14450   vat_main_t *vam = &vat_main;
14451
14452   print (vam->ofp, "sa_id %u sw_if_index %u spi %u proto %u crypto_alg %u "
14453          "crypto_key %U integ_alg %u integ_key %U flags %x "
14454          "tunnel_src_addr %U tunnel_dst_addr %U "
14455          "salt %u seq_outbound %lu last_seq_inbound %lu "
14456          "replay_window %lu\n",
14457          ntohl (mp->entry.sad_id),
14458          ntohl (mp->sw_if_index),
14459          ntohl (mp->entry.spi),
14460          ntohl (mp->entry.protocol),
14461          ntohl (mp->entry.crypto_algorithm),
14462          format_hex_bytes, mp->entry.crypto_key.data,
14463          mp->entry.crypto_key.length, ntohl (mp->entry.integrity_algorithm),
14464          format_hex_bytes, mp->entry.integrity_key.data,
14465          mp->entry.integrity_key.length, ntohl (mp->entry.flags),
14466          format_vl_api_address, &mp->entry.tunnel_src, format_vl_api_address,
14467          &mp->entry.tunnel_dst, ntohl (mp->salt),
14468          clib_net_to_host_u64 (mp->seq_outbound),
14469          clib_net_to_host_u64 (mp->last_seq_inbound),
14470          clib_net_to_host_u64 (mp->replay_window));
14471 }
14472
14473 #define vl_api_ipsec_sa_details_t_endian vl_noop_handler
14474 #define vl_api_ipsec_sa_details_t_print vl_noop_handler
14475
14476 static void vl_api_ipsec_sa_details_t_handler_json
14477   (vl_api_ipsec_sa_details_t * mp)
14478 {
14479   vat_main_t *vam = &vat_main;
14480   vat_json_node_t *node = NULL;
14481   vl_api_ipsec_sad_flags_t flags;
14482
14483   if (VAT_JSON_ARRAY != vam->json_tree.type)
14484     {
14485       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14486       vat_json_init_array (&vam->json_tree);
14487     }
14488   node = vat_json_array_add (&vam->json_tree);
14489
14490   vat_json_init_object (node);
14491   vat_json_object_add_uint (node, "sa_id", ntohl (mp->entry.sad_id));
14492   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
14493   vat_json_object_add_uint (node, "spi", ntohl (mp->entry.spi));
14494   vat_json_object_add_uint (node, "proto", ntohl (mp->entry.protocol));
14495   vat_json_object_add_uint (node, "crypto_alg",
14496                             ntohl (mp->entry.crypto_algorithm));
14497   vat_json_object_add_uint (node, "integ_alg",
14498                             ntohl (mp->entry.integrity_algorithm));
14499   flags = ntohl (mp->entry.flags);
14500   vat_json_object_add_uint (node, "use_esn",
14501                             ! !(flags & IPSEC_API_SAD_FLAG_USE_ESN));
14502   vat_json_object_add_uint (node, "use_anti_replay",
14503                             ! !(flags & IPSEC_API_SAD_FLAG_USE_ANTI_REPLAY));
14504   vat_json_object_add_uint (node, "is_tunnel",
14505                             ! !(flags & IPSEC_API_SAD_FLAG_IS_TUNNEL));
14506   vat_json_object_add_uint (node, "is_tunnel_ip6",
14507                             ! !(flags & IPSEC_API_SAD_FLAG_IS_TUNNEL_V6));
14508   vat_json_object_add_uint (node, "udp_encap",
14509                             ! !(flags & IPSEC_API_SAD_FLAG_UDP_ENCAP));
14510   vat_json_object_add_bytes (node, "crypto_key", mp->entry.crypto_key.data,
14511                              mp->entry.crypto_key.length);
14512   vat_json_object_add_bytes (node, "integ_key", mp->entry.integrity_key.data,
14513                              mp->entry.integrity_key.length);
14514   vat_json_object_add_address (node, "src", &mp->entry.tunnel_src);
14515   vat_json_object_add_address (node, "dst", &mp->entry.tunnel_dst);
14516   vat_json_object_add_uint (node, "replay_window",
14517                             clib_net_to_host_u64 (mp->replay_window));
14518 }
14519
14520 static int
14521 api_ipsec_sa_dump (vat_main_t * vam)
14522 {
14523   unformat_input_t *i = vam->input;
14524   vl_api_ipsec_sa_dump_t *mp;
14525   vl_api_control_ping_t *mp_ping;
14526   u32 sa_id = ~0;
14527   int ret;
14528
14529   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14530     {
14531       if (unformat (i, "sa_id %d", &sa_id))
14532         ;
14533       else
14534         {
14535           clib_warning ("parse error '%U'", format_unformat_error, i);
14536           return -99;
14537         }
14538     }
14539
14540   M (IPSEC_SA_DUMP, mp);
14541
14542   mp->sa_id = ntohl (sa_id);
14543
14544   S (mp);
14545
14546   /* Use a control ping for synchronization */
14547   M (CONTROL_PING, mp_ping);
14548   S (mp_ping);
14549
14550   W (ret);
14551   return ret;
14552 }
14553
14554 static int
14555 api_ipsec_tunnel_if_set_sa (vat_main_t * vam)
14556 {
14557   unformat_input_t *i = vam->input;
14558   vl_api_ipsec_tunnel_if_set_sa_t *mp;
14559   u32 sw_if_index = ~0;
14560   u32 sa_id = ~0;
14561   u8 is_outbound = (u8) ~ 0;
14562   int ret;
14563
14564   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14565     {
14566       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14567         ;
14568       else if (unformat (i, "sa_id %d", &sa_id))
14569         ;
14570       else if (unformat (i, "outbound"))
14571         is_outbound = 1;
14572       else if (unformat (i, "inbound"))
14573         is_outbound = 0;
14574       else
14575         {
14576           clib_warning ("parse error '%U'", format_unformat_error, i);
14577           return -99;
14578         }
14579     }
14580
14581   if (sw_if_index == ~0)
14582     {
14583       errmsg ("interface must be specified");
14584       return -99;
14585     }
14586
14587   if (sa_id == ~0)
14588     {
14589       errmsg ("SA ID must be specified");
14590       return -99;
14591     }
14592
14593   M (IPSEC_TUNNEL_IF_SET_SA, mp);
14594
14595   mp->sw_if_index = htonl (sw_if_index);
14596   mp->sa_id = htonl (sa_id);
14597   mp->is_outbound = is_outbound;
14598
14599   S (mp);
14600   W (ret);
14601
14602   return ret;
14603 }
14604
14605 static int
14606 api_get_first_msg_id (vat_main_t * vam)
14607 {
14608   vl_api_get_first_msg_id_t *mp;
14609   unformat_input_t *i = vam->input;
14610   u8 *name;
14611   u8 name_set = 0;
14612   int ret;
14613
14614   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14615     {
14616       if (unformat (i, "client %s", &name))
14617         name_set = 1;
14618       else
14619         break;
14620     }
14621
14622   if (name_set == 0)
14623     {
14624       errmsg ("missing client name");
14625       return -99;
14626     }
14627   vec_add1 (name, 0);
14628
14629   if (vec_len (name) > 63)
14630     {
14631       errmsg ("client name too long");
14632       return -99;
14633     }
14634
14635   M (GET_FIRST_MSG_ID, mp);
14636   clib_memcpy (mp->name, name, vec_len (name));
14637   S (mp);
14638   W (ret);
14639   return ret;
14640 }
14641
14642 static int
14643 api_cop_interface_enable_disable (vat_main_t * vam)
14644 {
14645   unformat_input_t *line_input = vam->input;
14646   vl_api_cop_interface_enable_disable_t *mp;
14647   u32 sw_if_index = ~0;
14648   u8 enable_disable = 1;
14649   int ret;
14650
14651   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14652     {
14653       if (unformat (line_input, "disable"))
14654         enable_disable = 0;
14655       if (unformat (line_input, "enable"))
14656         enable_disable = 1;
14657       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
14658                          vam, &sw_if_index))
14659         ;
14660       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
14661         ;
14662       else
14663         break;
14664     }
14665
14666   if (sw_if_index == ~0)
14667     {
14668       errmsg ("missing interface name or sw_if_index");
14669       return -99;
14670     }
14671
14672   /* Construct the API message */
14673   M (COP_INTERFACE_ENABLE_DISABLE, mp);
14674   mp->sw_if_index = ntohl (sw_if_index);
14675   mp->enable_disable = enable_disable;
14676
14677   /* send it... */
14678   S (mp);
14679   /* Wait for the reply */
14680   W (ret);
14681   return ret;
14682 }
14683
14684 static int
14685 api_cop_whitelist_enable_disable (vat_main_t * vam)
14686 {
14687   unformat_input_t *line_input = vam->input;
14688   vl_api_cop_whitelist_enable_disable_t *mp;
14689   u32 sw_if_index = ~0;
14690   u8 ip4 = 0, ip6 = 0, default_cop = 0;
14691   u32 fib_id = 0;
14692   int ret;
14693
14694   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14695     {
14696       if (unformat (line_input, "ip4"))
14697         ip4 = 1;
14698       else if (unformat (line_input, "ip6"))
14699         ip6 = 1;
14700       else if (unformat (line_input, "default"))
14701         default_cop = 1;
14702       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
14703                          vam, &sw_if_index))
14704         ;
14705       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
14706         ;
14707       else if (unformat (line_input, "fib-id %d", &fib_id))
14708         ;
14709       else
14710         break;
14711     }
14712
14713   if (sw_if_index == ~0)
14714     {
14715       errmsg ("missing interface name or sw_if_index");
14716       return -99;
14717     }
14718
14719   /* Construct the API message */
14720   M (COP_WHITELIST_ENABLE_DISABLE, mp);
14721   mp->sw_if_index = ntohl (sw_if_index);
14722   mp->fib_id = ntohl (fib_id);
14723   mp->ip4 = ip4;
14724   mp->ip6 = ip6;
14725   mp->default_cop = default_cop;
14726
14727   /* send it... */
14728   S (mp);
14729   /* Wait for the reply */
14730   W (ret);
14731   return ret;
14732 }
14733
14734 static int
14735 api_get_node_graph (vat_main_t * vam)
14736 {
14737   vl_api_get_node_graph_t *mp;
14738   int ret;
14739
14740   M (GET_NODE_GRAPH, mp);
14741
14742   /* send it... */
14743   S (mp);
14744   /* Wait for the reply */
14745   W (ret);
14746   return ret;
14747 }
14748
14749 /* *INDENT-OFF* */
14750 /** Used for parsing LISP eids */
14751 typedef CLIB_PACKED(struct{
14752   u8 addr[16];   /**< eid address */
14753   u32 len;       /**< prefix length if IP */
14754   u8 type;      /**< type of eid */
14755 }) lisp_eid_vat_t;
14756 /* *INDENT-ON* */
14757
14758 static uword
14759 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
14760 {
14761   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
14762
14763   clib_memset (a, 0, sizeof (a[0]));
14764
14765   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
14766     {
14767       a->type = 0;              /* ipv4 type */
14768     }
14769   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
14770     {
14771       a->type = 1;              /* ipv6 type */
14772     }
14773   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
14774     {
14775       a->type = 2;              /* mac type */
14776     }
14777   else if (unformat (input, "%U", unformat_nsh_address, a->addr))
14778     {
14779       a->type = 3;              /* NSH type */
14780       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) a->addr;
14781       nsh->spi = clib_host_to_net_u32 (nsh->spi);
14782     }
14783   else
14784     {
14785       return 0;
14786     }
14787
14788   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
14789     {
14790       return 0;
14791     }
14792
14793   return 1;
14794 }
14795
14796 static int
14797 lisp_eid_size_vat (u8 type)
14798 {
14799   switch (type)
14800     {
14801     case 0:
14802       return 4;
14803     case 1:
14804       return 16;
14805     case 2:
14806       return 6;
14807     case 3:
14808       return 5;
14809     }
14810   return 0;
14811 }
14812
14813 static void
14814 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
14815 {
14816   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
14817 }
14818
14819 static int
14820 api_one_add_del_locator_set (vat_main_t * vam)
14821 {
14822   unformat_input_t *input = vam->input;
14823   vl_api_one_add_del_locator_set_t *mp;
14824   u8 is_add = 1;
14825   u8 *locator_set_name = NULL;
14826   u8 locator_set_name_set = 0;
14827   vl_api_local_locator_t locator, *locators = 0;
14828   u32 sw_if_index, priority, weight;
14829   u32 data_len = 0;
14830
14831   int ret;
14832   /* Parse args required to build the message */
14833   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14834     {
14835       if (unformat (input, "del"))
14836         {
14837           is_add = 0;
14838         }
14839       else if (unformat (input, "locator-set %s", &locator_set_name))
14840         {
14841           locator_set_name_set = 1;
14842         }
14843       else if (unformat (input, "sw_if_index %u p %u w %u",
14844                          &sw_if_index, &priority, &weight))
14845         {
14846           locator.sw_if_index = htonl (sw_if_index);
14847           locator.priority = priority;
14848           locator.weight = weight;
14849           vec_add1 (locators, locator);
14850         }
14851       else
14852         if (unformat
14853             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
14854              &sw_if_index, &priority, &weight))
14855         {
14856           locator.sw_if_index = htonl (sw_if_index);
14857           locator.priority = priority;
14858           locator.weight = weight;
14859           vec_add1 (locators, locator);
14860         }
14861       else
14862         break;
14863     }
14864
14865   if (locator_set_name_set == 0)
14866     {
14867       errmsg ("missing locator-set name");
14868       vec_free (locators);
14869       return -99;
14870     }
14871
14872   if (vec_len (locator_set_name) > 64)
14873     {
14874       errmsg ("locator-set name too long");
14875       vec_free (locator_set_name);
14876       vec_free (locators);
14877       return -99;
14878     }
14879   vec_add1 (locator_set_name, 0);
14880
14881   data_len = sizeof (vl_api_local_locator_t) * vec_len (locators);
14882
14883   /* Construct the API message */
14884   M2 (ONE_ADD_DEL_LOCATOR_SET, mp, data_len);
14885
14886   mp->is_add = is_add;
14887   clib_memcpy (mp->locator_set_name, locator_set_name,
14888                vec_len (locator_set_name));
14889   vec_free (locator_set_name);
14890
14891   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
14892   if (locators)
14893     clib_memcpy (mp->locators, locators, data_len);
14894   vec_free (locators);
14895
14896   /* send it... */
14897   S (mp);
14898
14899   /* Wait for a reply... */
14900   W (ret);
14901   return ret;
14902 }
14903
14904 #define api_lisp_add_del_locator_set api_one_add_del_locator_set
14905
14906 static int
14907 api_one_add_del_locator (vat_main_t * vam)
14908 {
14909   unformat_input_t *input = vam->input;
14910   vl_api_one_add_del_locator_t *mp;
14911   u32 tmp_if_index = ~0;
14912   u32 sw_if_index = ~0;
14913   u8 sw_if_index_set = 0;
14914   u8 sw_if_index_if_name_set = 0;
14915   u32 priority = ~0;
14916   u8 priority_set = 0;
14917   u32 weight = ~0;
14918   u8 weight_set = 0;
14919   u8 is_add = 1;
14920   u8 *locator_set_name = NULL;
14921   u8 locator_set_name_set = 0;
14922   int ret;
14923
14924   /* Parse args required to build the message */
14925   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14926     {
14927       if (unformat (input, "del"))
14928         {
14929           is_add = 0;
14930         }
14931       else if (unformat (input, "locator-set %s", &locator_set_name))
14932         {
14933           locator_set_name_set = 1;
14934         }
14935       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
14936                          &tmp_if_index))
14937         {
14938           sw_if_index_if_name_set = 1;
14939           sw_if_index = tmp_if_index;
14940         }
14941       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
14942         {
14943           sw_if_index_set = 1;
14944           sw_if_index = tmp_if_index;
14945         }
14946       else if (unformat (input, "p %d", &priority))
14947         {
14948           priority_set = 1;
14949         }
14950       else if (unformat (input, "w %d", &weight))
14951         {
14952           weight_set = 1;
14953         }
14954       else
14955         break;
14956     }
14957
14958   if (locator_set_name_set == 0)
14959     {
14960       errmsg ("missing locator-set name");
14961       return -99;
14962     }
14963
14964   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
14965     {
14966       errmsg ("missing sw_if_index");
14967       vec_free (locator_set_name);
14968       return -99;
14969     }
14970
14971   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
14972     {
14973       errmsg ("cannot use both params interface name and sw_if_index");
14974       vec_free (locator_set_name);
14975       return -99;
14976     }
14977
14978   if (priority_set == 0)
14979     {
14980       errmsg ("missing locator-set priority");
14981       vec_free (locator_set_name);
14982       return -99;
14983     }
14984
14985   if (weight_set == 0)
14986     {
14987       errmsg ("missing locator-set weight");
14988       vec_free (locator_set_name);
14989       return -99;
14990     }
14991
14992   if (vec_len (locator_set_name) > 64)
14993     {
14994       errmsg ("locator-set name too long");
14995       vec_free (locator_set_name);
14996       return -99;
14997     }
14998   vec_add1 (locator_set_name, 0);
14999
15000   /* Construct the API message */
15001   M (ONE_ADD_DEL_LOCATOR, mp);
15002
15003   mp->is_add = is_add;
15004   mp->sw_if_index = ntohl (sw_if_index);
15005   mp->priority = priority;
15006   mp->weight = weight;
15007   clib_memcpy (mp->locator_set_name, locator_set_name,
15008                vec_len (locator_set_name));
15009   vec_free (locator_set_name);
15010
15011   /* send it... */
15012   S (mp);
15013
15014   /* Wait for a reply... */
15015   W (ret);
15016   return ret;
15017 }
15018
15019 #define api_lisp_add_del_locator api_one_add_del_locator
15020
15021 uword
15022 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
15023 {
15024   u32 *key_id = va_arg (*args, u32 *);
15025   u8 *s = 0;
15026
15027   if (unformat (input, "%s", &s))
15028     {
15029       if (!strcmp ((char *) s, "sha1"))
15030         key_id[0] = HMAC_SHA_1_96;
15031       else if (!strcmp ((char *) s, "sha256"))
15032         key_id[0] = HMAC_SHA_256_128;
15033       else
15034         {
15035           clib_warning ("invalid key_id: '%s'", s);
15036           key_id[0] = HMAC_NO_KEY;
15037         }
15038     }
15039   else
15040     return 0;
15041
15042   vec_free (s);
15043   return 1;
15044 }
15045
15046 static int
15047 api_one_add_del_local_eid (vat_main_t * vam)
15048 {
15049   unformat_input_t *input = vam->input;
15050   vl_api_one_add_del_local_eid_t *mp;
15051   u8 is_add = 1;
15052   u8 eid_set = 0;
15053   lisp_eid_vat_t _eid, *eid = &_eid;
15054   u8 *locator_set_name = 0;
15055   u8 locator_set_name_set = 0;
15056   u32 vni = 0;
15057   u16 key_id = 0;
15058   u8 *key = 0;
15059   int ret;
15060
15061   /* Parse args required to build the message */
15062   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15063     {
15064       if (unformat (input, "del"))
15065         {
15066           is_add = 0;
15067         }
15068       else if (unformat (input, "vni %d", &vni))
15069         {
15070           ;
15071         }
15072       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
15073         {
15074           eid_set = 1;
15075         }
15076       else if (unformat (input, "locator-set %s", &locator_set_name))
15077         {
15078           locator_set_name_set = 1;
15079         }
15080       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
15081         ;
15082       else if (unformat (input, "secret-key %_%v%_", &key))
15083         ;
15084       else
15085         break;
15086     }
15087
15088   if (locator_set_name_set == 0)
15089     {
15090       errmsg ("missing locator-set name");
15091       return -99;
15092     }
15093
15094   if (0 == eid_set)
15095     {
15096       errmsg ("EID address not set!");
15097       vec_free (locator_set_name);
15098       return -99;
15099     }
15100
15101   if (key && (0 == key_id))
15102     {
15103       errmsg ("invalid key_id!");
15104       return -99;
15105     }
15106
15107   if (vec_len (key) > 64)
15108     {
15109       errmsg ("key too long");
15110       vec_free (key);
15111       return -99;
15112     }
15113
15114   if (vec_len (locator_set_name) > 64)
15115     {
15116       errmsg ("locator-set name too long");
15117       vec_free (locator_set_name);
15118       return -99;
15119     }
15120   vec_add1 (locator_set_name, 0);
15121
15122   /* Construct the API message */
15123   M (ONE_ADD_DEL_LOCAL_EID, mp);
15124
15125   mp->is_add = is_add;
15126   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
15127   mp->eid_type = eid->type;
15128   mp->prefix_len = eid->len;
15129   mp->vni = clib_host_to_net_u32 (vni);
15130   mp->key_id = clib_host_to_net_u16 (key_id);
15131   clib_memcpy (mp->locator_set_name, locator_set_name,
15132                vec_len (locator_set_name));
15133   clib_memcpy (mp->key, key, vec_len (key));
15134
15135   vec_free (locator_set_name);
15136   vec_free (key);
15137
15138   /* send it... */
15139   S (mp);
15140
15141   /* Wait for a reply... */
15142   W (ret);
15143   return ret;
15144 }
15145
15146 #define api_lisp_add_del_local_eid api_one_add_del_local_eid
15147
15148 static int
15149 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
15150 {
15151   u32 dp_table = 0, vni = 0;;
15152   unformat_input_t *input = vam->input;
15153   vl_api_gpe_add_del_fwd_entry_t *mp;
15154   u8 is_add = 1;
15155   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
15156   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
15157   u8 rmt_eid_set = 0, lcl_eid_set = 0;
15158   u32 action = ~0, w;
15159   ip4_address_t rmt_rloc4, lcl_rloc4;
15160   ip6_address_t rmt_rloc6, lcl_rloc6;
15161   vl_api_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
15162   int ret;
15163
15164   clib_memset (&rloc, 0, sizeof (rloc));
15165
15166   /* Parse args required to build the message */
15167   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15168     {
15169       if (unformat (input, "del"))
15170         is_add = 0;
15171       else if (unformat (input, "add"))
15172         is_add = 1;
15173       else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
15174         {
15175           rmt_eid_set = 1;
15176         }
15177       else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
15178         {
15179           lcl_eid_set = 1;
15180         }
15181       else if (unformat (input, "vrf %d", &dp_table))
15182         ;
15183       else if (unformat (input, "bd %d", &dp_table))
15184         ;
15185       else if (unformat (input, "vni %d", &vni))
15186         ;
15187       else if (unformat (input, "w %d", &w))
15188         {
15189           if (!curr_rloc)
15190             {
15191               errmsg ("No RLOC configured for setting priority/weight!");
15192               return -99;
15193             }
15194           curr_rloc->weight = w;
15195         }
15196       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
15197                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
15198         {
15199           rloc.is_ip4 = 1;
15200
15201           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
15202           rloc.weight = 0;
15203           vec_add1 (lcl_locs, rloc);
15204
15205           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
15206           vec_add1 (rmt_locs, rloc);
15207           /* weight saved in rmt loc */
15208           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
15209         }
15210       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
15211                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
15212         {
15213           rloc.is_ip4 = 0;
15214           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
15215           rloc.weight = 0;
15216           vec_add1 (lcl_locs, rloc);
15217
15218           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
15219           vec_add1 (rmt_locs, rloc);
15220           /* weight saved in rmt loc */
15221           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
15222         }
15223       else if (unformat (input, "action %d", &action))
15224         {
15225           ;
15226         }
15227       else
15228         {
15229           clib_warning ("parse error '%U'", format_unformat_error, input);
15230           return -99;
15231         }
15232     }
15233
15234   if (!rmt_eid_set)
15235     {
15236       errmsg ("remote eid addresses not set");
15237       return -99;
15238     }
15239
15240   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
15241     {
15242       errmsg ("eid types don't match");
15243       return -99;
15244     }
15245
15246   if (0 == rmt_locs && (u32) ~ 0 == action)
15247     {
15248       errmsg ("action not set for negative mapping");
15249       return -99;
15250     }
15251
15252   /* Construct the API message */
15253   M2 (GPE_ADD_DEL_FWD_ENTRY, mp,
15254       sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs) * 2);
15255
15256   mp->is_add = is_add;
15257   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
15258   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
15259   mp->eid_type = rmt_eid->type;
15260   mp->dp_table = clib_host_to_net_u32 (dp_table);
15261   mp->vni = clib_host_to_net_u32 (vni);
15262   mp->rmt_len = rmt_eid->len;
15263   mp->lcl_len = lcl_eid->len;
15264   mp->action = action;
15265
15266   if (0 != rmt_locs && 0 != lcl_locs)
15267     {
15268       mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
15269       clib_memcpy (mp->locs, lcl_locs,
15270                    (sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs)));
15271
15272       u32 offset = sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs);
15273       clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
15274                    (sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs)));
15275     }
15276   vec_free (lcl_locs);
15277   vec_free (rmt_locs);
15278
15279   /* send it... */
15280   S (mp);
15281
15282   /* Wait for a reply... */
15283   W (ret);
15284   return ret;
15285 }
15286
15287 static int
15288 api_one_add_del_map_server (vat_main_t * vam)
15289 {
15290   unformat_input_t *input = vam->input;
15291   vl_api_one_add_del_map_server_t *mp;
15292   u8 is_add = 1;
15293   u8 ipv4_set = 0;
15294   u8 ipv6_set = 0;
15295   ip4_address_t ipv4;
15296   ip6_address_t ipv6;
15297   int ret;
15298
15299   /* Parse args required to build the message */
15300   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15301     {
15302       if (unformat (input, "del"))
15303         {
15304           is_add = 0;
15305         }
15306       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
15307         {
15308           ipv4_set = 1;
15309         }
15310       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
15311         {
15312           ipv6_set = 1;
15313         }
15314       else
15315         break;
15316     }
15317
15318   if (ipv4_set && ipv6_set)
15319     {
15320       errmsg ("both eid v4 and v6 addresses set");
15321       return -99;
15322     }
15323
15324   if (!ipv4_set && !ipv6_set)
15325     {
15326       errmsg ("eid addresses not set");
15327       return -99;
15328     }
15329
15330   /* Construct the API message */
15331   M (ONE_ADD_DEL_MAP_SERVER, mp);
15332
15333   mp->is_add = is_add;
15334   if (ipv6_set)
15335     {
15336       mp->is_ipv6 = 1;
15337       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
15338     }
15339   else
15340     {
15341       mp->is_ipv6 = 0;
15342       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
15343     }
15344
15345   /* send it... */
15346   S (mp);
15347
15348   /* Wait for a reply... */
15349   W (ret);
15350   return ret;
15351 }
15352
15353 #define api_lisp_add_del_map_server api_one_add_del_map_server
15354
15355 static int
15356 api_one_add_del_map_resolver (vat_main_t * vam)
15357 {
15358   unformat_input_t *input = vam->input;
15359   vl_api_one_add_del_map_resolver_t *mp;
15360   u8 is_add = 1;
15361   u8 ipv4_set = 0;
15362   u8 ipv6_set = 0;
15363   ip4_address_t ipv4;
15364   ip6_address_t ipv6;
15365   int ret;
15366
15367   /* Parse args required to build the message */
15368   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15369     {
15370       if (unformat (input, "del"))
15371         {
15372           is_add = 0;
15373         }
15374       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
15375         {
15376           ipv4_set = 1;
15377         }
15378       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
15379         {
15380           ipv6_set = 1;
15381         }
15382       else
15383         break;
15384     }
15385
15386   if (ipv4_set && ipv6_set)
15387     {
15388       errmsg ("both eid v4 and v6 addresses set");
15389       return -99;
15390     }
15391
15392   if (!ipv4_set && !ipv6_set)
15393     {
15394       errmsg ("eid addresses not set");
15395       return -99;
15396     }
15397
15398   /* Construct the API message */
15399   M (ONE_ADD_DEL_MAP_RESOLVER, mp);
15400
15401   mp->is_add = is_add;
15402   if (ipv6_set)
15403     {
15404       mp->is_ipv6 = 1;
15405       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
15406     }
15407   else
15408     {
15409       mp->is_ipv6 = 0;
15410       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
15411     }
15412
15413   /* send it... */
15414   S (mp);
15415
15416   /* Wait for a reply... */
15417   W (ret);
15418   return ret;
15419 }
15420
15421 #define api_lisp_add_del_map_resolver api_one_add_del_map_resolver
15422
15423 static int
15424 api_lisp_gpe_enable_disable (vat_main_t * vam)
15425 {
15426   unformat_input_t *input = vam->input;
15427   vl_api_gpe_enable_disable_t *mp;
15428   u8 is_set = 0;
15429   u8 is_en = 1;
15430   int ret;
15431
15432   /* Parse args required to build the message */
15433   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15434     {
15435       if (unformat (input, "enable"))
15436         {
15437           is_set = 1;
15438           is_en = 1;
15439         }
15440       else if (unformat (input, "disable"))
15441         {
15442           is_set = 1;
15443           is_en = 0;
15444         }
15445       else
15446         break;
15447     }
15448
15449   if (is_set == 0)
15450     {
15451       errmsg ("Value not set");
15452       return -99;
15453     }
15454
15455   /* Construct the API message */
15456   M (GPE_ENABLE_DISABLE, mp);
15457
15458   mp->is_en = is_en;
15459
15460   /* send it... */
15461   S (mp);
15462
15463   /* Wait for a reply... */
15464   W (ret);
15465   return ret;
15466 }
15467
15468 static int
15469 api_one_rloc_probe_enable_disable (vat_main_t * vam)
15470 {
15471   unformat_input_t *input = vam->input;
15472   vl_api_one_rloc_probe_enable_disable_t *mp;
15473   u8 is_set = 0;
15474   u8 is_en = 0;
15475   int ret;
15476
15477   /* Parse args required to build the message */
15478   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15479     {
15480       if (unformat (input, "enable"))
15481         {
15482           is_set = 1;
15483           is_en = 1;
15484         }
15485       else if (unformat (input, "disable"))
15486         is_set = 1;
15487       else
15488         break;
15489     }
15490
15491   if (!is_set)
15492     {
15493       errmsg ("Value not set");
15494       return -99;
15495     }
15496
15497   /* Construct the API message */
15498   M (ONE_RLOC_PROBE_ENABLE_DISABLE, mp);
15499
15500   mp->is_enabled = is_en;
15501
15502   /* send it... */
15503   S (mp);
15504
15505   /* Wait for a reply... */
15506   W (ret);
15507   return ret;
15508 }
15509
15510 #define api_lisp_rloc_probe_enable_disable api_one_rloc_probe_enable_disable
15511
15512 static int
15513 api_one_map_register_enable_disable (vat_main_t * vam)
15514 {
15515   unformat_input_t *input = vam->input;
15516   vl_api_one_map_register_enable_disable_t *mp;
15517   u8 is_set = 0;
15518   u8 is_en = 0;
15519   int ret;
15520
15521   /* Parse args required to build the message */
15522   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15523     {
15524       if (unformat (input, "enable"))
15525         {
15526           is_set = 1;
15527           is_en = 1;
15528         }
15529       else if (unformat (input, "disable"))
15530         is_set = 1;
15531       else
15532         break;
15533     }
15534
15535   if (!is_set)
15536     {
15537       errmsg ("Value not set");
15538       return -99;
15539     }
15540
15541   /* Construct the API message */
15542   M (ONE_MAP_REGISTER_ENABLE_DISABLE, mp);
15543
15544   mp->is_enabled = is_en;
15545
15546   /* send it... */
15547   S (mp);
15548
15549   /* Wait for a reply... */
15550   W (ret);
15551   return ret;
15552 }
15553
15554 #define api_lisp_map_register_enable_disable api_one_map_register_enable_disable
15555
15556 static int
15557 api_one_enable_disable (vat_main_t * vam)
15558 {
15559   unformat_input_t *input = vam->input;
15560   vl_api_one_enable_disable_t *mp;
15561   u8 is_set = 0;
15562   u8 is_en = 0;
15563   int ret;
15564
15565   /* Parse args required to build the message */
15566   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15567     {
15568       if (unformat (input, "enable"))
15569         {
15570           is_set = 1;
15571           is_en = 1;
15572         }
15573       else if (unformat (input, "disable"))
15574         {
15575           is_set = 1;
15576         }
15577       else
15578         break;
15579     }
15580
15581   if (!is_set)
15582     {
15583       errmsg ("Value not set");
15584       return -99;
15585     }
15586
15587   /* Construct the API message */
15588   M (ONE_ENABLE_DISABLE, mp);
15589
15590   mp->is_en = is_en;
15591
15592   /* send it... */
15593   S (mp);
15594
15595   /* Wait for a reply... */
15596   W (ret);
15597   return ret;
15598 }
15599
15600 #define api_lisp_enable_disable api_one_enable_disable
15601
15602 static int
15603 api_one_enable_disable_xtr_mode (vat_main_t * vam)
15604 {
15605   unformat_input_t *input = vam->input;
15606   vl_api_one_enable_disable_xtr_mode_t *mp;
15607   u8 is_set = 0;
15608   u8 is_en = 0;
15609   int ret;
15610
15611   /* Parse args required to build the message */
15612   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15613     {
15614       if (unformat (input, "enable"))
15615         {
15616           is_set = 1;
15617           is_en = 1;
15618         }
15619       else if (unformat (input, "disable"))
15620         {
15621           is_set = 1;
15622         }
15623       else
15624         break;
15625     }
15626
15627   if (!is_set)
15628     {
15629       errmsg ("Value not set");
15630       return -99;
15631     }
15632
15633   /* Construct the API message */
15634   M (ONE_ENABLE_DISABLE_XTR_MODE, mp);
15635
15636   mp->is_en = is_en;
15637
15638   /* send it... */
15639   S (mp);
15640
15641   /* Wait for a reply... */
15642   W (ret);
15643   return ret;
15644 }
15645
15646 static int
15647 api_one_show_xtr_mode (vat_main_t * vam)
15648 {
15649   vl_api_one_show_xtr_mode_t *mp;
15650   int ret;
15651
15652   /* Construct the API message */
15653   M (ONE_SHOW_XTR_MODE, mp);
15654
15655   /* send it... */
15656   S (mp);
15657
15658   /* Wait for a reply... */
15659   W (ret);
15660   return ret;
15661 }
15662
15663 static int
15664 api_one_enable_disable_pitr_mode (vat_main_t * vam)
15665 {
15666   unformat_input_t *input = vam->input;
15667   vl_api_one_enable_disable_pitr_mode_t *mp;
15668   u8 is_set = 0;
15669   u8 is_en = 0;
15670   int ret;
15671
15672   /* Parse args required to build the message */
15673   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15674     {
15675       if (unformat (input, "enable"))
15676         {
15677           is_set = 1;
15678           is_en = 1;
15679         }
15680       else if (unformat (input, "disable"))
15681         {
15682           is_set = 1;
15683         }
15684       else
15685         break;
15686     }
15687
15688   if (!is_set)
15689     {
15690       errmsg ("Value not set");
15691       return -99;
15692     }
15693
15694   /* Construct the API message */
15695   M (ONE_ENABLE_DISABLE_PITR_MODE, mp);
15696
15697   mp->is_en = is_en;
15698
15699   /* send it... */
15700   S (mp);
15701
15702   /* Wait for a reply... */
15703   W (ret);
15704   return ret;
15705 }
15706
15707 static int
15708 api_one_show_pitr_mode (vat_main_t * vam)
15709 {
15710   vl_api_one_show_pitr_mode_t *mp;
15711   int ret;
15712
15713   /* Construct the API message */
15714   M (ONE_SHOW_PITR_MODE, mp);
15715
15716   /* send it... */
15717   S (mp);
15718
15719   /* Wait for a reply... */
15720   W (ret);
15721   return ret;
15722 }
15723
15724 static int
15725 api_one_enable_disable_petr_mode (vat_main_t * vam)
15726 {
15727   unformat_input_t *input = vam->input;
15728   vl_api_one_enable_disable_petr_mode_t *mp;
15729   u8 is_set = 0;
15730   u8 is_en = 0;
15731   int ret;
15732
15733   /* Parse args required to build the message */
15734   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15735     {
15736       if (unformat (input, "enable"))
15737         {
15738           is_set = 1;
15739           is_en = 1;
15740         }
15741       else if (unformat (input, "disable"))
15742         {
15743           is_set = 1;
15744         }
15745       else
15746         break;
15747     }
15748
15749   if (!is_set)
15750     {
15751       errmsg ("Value not set");
15752       return -99;
15753     }
15754
15755   /* Construct the API message */
15756   M (ONE_ENABLE_DISABLE_PETR_MODE, mp);
15757
15758   mp->is_en = is_en;
15759
15760   /* send it... */
15761   S (mp);
15762
15763   /* Wait for a reply... */
15764   W (ret);
15765   return ret;
15766 }
15767
15768 static int
15769 api_one_show_petr_mode (vat_main_t * vam)
15770 {
15771   vl_api_one_show_petr_mode_t *mp;
15772   int ret;
15773
15774   /* Construct the API message */
15775   M (ONE_SHOW_PETR_MODE, mp);
15776
15777   /* send it... */
15778   S (mp);
15779
15780   /* Wait for a reply... */
15781   W (ret);
15782   return ret;
15783 }
15784
15785 static int
15786 api_show_one_map_register_state (vat_main_t * vam)
15787 {
15788   vl_api_show_one_map_register_state_t *mp;
15789   int ret;
15790
15791   M (SHOW_ONE_MAP_REGISTER_STATE, mp);
15792
15793   /* send */
15794   S (mp);
15795
15796   /* wait for reply */
15797   W (ret);
15798   return ret;
15799 }
15800
15801 #define api_show_lisp_map_register_state api_show_one_map_register_state
15802
15803 static int
15804 api_show_one_rloc_probe_state (vat_main_t * vam)
15805 {
15806   vl_api_show_one_rloc_probe_state_t *mp;
15807   int ret;
15808
15809   M (SHOW_ONE_RLOC_PROBE_STATE, mp);
15810
15811   /* send */
15812   S (mp);
15813
15814   /* wait for reply */
15815   W (ret);
15816   return ret;
15817 }
15818
15819 #define api_show_lisp_rloc_probe_state api_show_one_rloc_probe_state
15820
15821 static int
15822 api_one_add_del_ndp_entry (vat_main_t * vam)
15823 {
15824   vl_api_one_add_del_ndp_entry_t *mp;
15825   unformat_input_t *input = vam->input;
15826   u8 is_add = 1;
15827   u8 mac_set = 0;
15828   u8 bd_set = 0;
15829   u8 ip_set = 0;
15830   u8 mac[6] = { 0, };
15831   u8 ip6[16] = { 0, };
15832   u32 bd = ~0;
15833   int ret;
15834
15835   /* Parse args required to build the message */
15836   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15837     {
15838       if (unformat (input, "del"))
15839         is_add = 0;
15840       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
15841         mac_set = 1;
15842       else if (unformat (input, "ip %U", unformat_ip6_address, ip6))
15843         ip_set = 1;
15844       else if (unformat (input, "bd %d", &bd))
15845         bd_set = 1;
15846       else
15847         {
15848           errmsg ("parse error '%U'", format_unformat_error, input);
15849           return -99;
15850         }
15851     }
15852
15853   if (!bd_set || !ip_set || (!mac_set && is_add))
15854     {
15855       errmsg ("Missing BD, IP or MAC!");
15856       return -99;
15857     }
15858
15859   M (ONE_ADD_DEL_NDP_ENTRY, mp);
15860   mp->is_add = is_add;
15861   clib_memcpy (mp->mac, mac, 6);
15862   mp->bd = clib_host_to_net_u32 (bd);
15863   clib_memcpy (mp->ip6, ip6, sizeof (mp->ip6));
15864
15865   /* send */
15866   S (mp);
15867
15868   /* wait for reply */
15869   W (ret);
15870   return ret;
15871 }
15872
15873 static int
15874 api_one_add_del_l2_arp_entry (vat_main_t * vam)
15875 {
15876   vl_api_one_add_del_l2_arp_entry_t *mp;
15877   unformat_input_t *input = vam->input;
15878   u8 is_add = 1;
15879   u8 mac_set = 0;
15880   u8 bd_set = 0;
15881   u8 ip_set = 0;
15882   u8 mac[6] = { 0, };
15883   u32 ip4 = 0, bd = ~0;
15884   int ret;
15885
15886   /* Parse args required to build the message */
15887   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15888     {
15889       if (unformat (input, "del"))
15890         is_add = 0;
15891       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
15892         mac_set = 1;
15893       else if (unformat (input, "ip %U", unformat_ip4_address, &ip4))
15894         ip_set = 1;
15895       else if (unformat (input, "bd %d", &bd))
15896         bd_set = 1;
15897       else
15898         {
15899           errmsg ("parse error '%U'", format_unformat_error, input);
15900           return -99;
15901         }
15902     }
15903
15904   if (!bd_set || !ip_set || (!mac_set && is_add))
15905     {
15906       errmsg ("Missing BD, IP or MAC!");
15907       return -99;
15908     }
15909
15910   M (ONE_ADD_DEL_L2_ARP_ENTRY, mp);
15911   mp->is_add = is_add;
15912   clib_memcpy (mp->mac, mac, 6);
15913   mp->bd = clib_host_to_net_u32 (bd);
15914   mp->ip4 = ip4;
15915
15916   /* send */
15917   S (mp);
15918
15919   /* wait for reply */
15920   W (ret);
15921   return ret;
15922 }
15923
15924 static int
15925 api_one_ndp_bd_get (vat_main_t * vam)
15926 {
15927   vl_api_one_ndp_bd_get_t *mp;
15928   int ret;
15929
15930   M (ONE_NDP_BD_GET, mp);
15931
15932   /* send */
15933   S (mp);
15934
15935   /* wait for reply */
15936   W (ret);
15937   return ret;
15938 }
15939
15940 static int
15941 api_one_ndp_entries_get (vat_main_t * vam)
15942 {
15943   vl_api_one_ndp_entries_get_t *mp;
15944   unformat_input_t *input = vam->input;
15945   u8 bd_set = 0;
15946   u32 bd = ~0;
15947   int ret;
15948
15949   /* Parse args required to build the message */
15950   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15951     {
15952       if (unformat (input, "bd %d", &bd))
15953         bd_set = 1;
15954       else
15955         {
15956           errmsg ("parse error '%U'", format_unformat_error, input);
15957           return -99;
15958         }
15959     }
15960
15961   if (!bd_set)
15962     {
15963       errmsg ("Expected bridge domain!");
15964       return -99;
15965     }
15966
15967   M (ONE_NDP_ENTRIES_GET, mp);
15968   mp->bd = clib_host_to_net_u32 (bd);
15969
15970   /* send */
15971   S (mp);
15972
15973   /* wait for reply */
15974   W (ret);
15975   return ret;
15976 }
15977
15978 static int
15979 api_one_l2_arp_bd_get (vat_main_t * vam)
15980 {
15981   vl_api_one_l2_arp_bd_get_t *mp;
15982   int ret;
15983
15984   M (ONE_L2_ARP_BD_GET, mp);
15985
15986   /* send */
15987   S (mp);
15988
15989   /* wait for reply */
15990   W (ret);
15991   return ret;
15992 }
15993
15994 static int
15995 api_one_l2_arp_entries_get (vat_main_t * vam)
15996 {
15997   vl_api_one_l2_arp_entries_get_t *mp;
15998   unformat_input_t *input = vam->input;
15999   u8 bd_set = 0;
16000   u32 bd = ~0;
16001   int ret;
16002
16003   /* Parse args required to build the message */
16004   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16005     {
16006       if (unformat (input, "bd %d", &bd))
16007         bd_set = 1;
16008       else
16009         {
16010           errmsg ("parse error '%U'", format_unformat_error, input);
16011           return -99;
16012         }
16013     }
16014
16015   if (!bd_set)
16016     {
16017       errmsg ("Expected bridge domain!");
16018       return -99;
16019     }
16020
16021   M (ONE_L2_ARP_ENTRIES_GET, mp);
16022   mp->bd = clib_host_to_net_u32 (bd);
16023
16024   /* send */
16025   S (mp);
16026
16027   /* wait for reply */
16028   W (ret);
16029   return ret;
16030 }
16031
16032 static int
16033 api_one_stats_enable_disable (vat_main_t * vam)
16034 {
16035   vl_api_one_stats_enable_disable_t *mp;
16036   unformat_input_t *input = vam->input;
16037   u8 is_set = 0;
16038   u8 is_en = 0;
16039   int ret;
16040
16041   /* Parse args required to build the message */
16042   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16043     {
16044       if (unformat (input, "enable"))
16045         {
16046           is_set = 1;
16047           is_en = 1;
16048         }
16049       else if (unformat (input, "disable"))
16050         {
16051           is_set = 1;
16052         }
16053       else
16054         break;
16055     }
16056
16057   if (!is_set)
16058     {
16059       errmsg ("Value not set");
16060       return -99;
16061     }
16062
16063   M (ONE_STATS_ENABLE_DISABLE, mp);
16064   mp->is_en = is_en;
16065
16066   /* send */
16067   S (mp);
16068
16069   /* wait for reply */
16070   W (ret);
16071   return ret;
16072 }
16073
16074 static int
16075 api_show_one_stats_enable_disable (vat_main_t * vam)
16076 {
16077   vl_api_show_one_stats_enable_disable_t *mp;
16078   int ret;
16079
16080   M (SHOW_ONE_STATS_ENABLE_DISABLE, mp);
16081
16082   /* send */
16083   S (mp);
16084
16085   /* wait for reply */
16086   W (ret);
16087   return ret;
16088 }
16089
16090 static int
16091 api_show_one_map_request_mode (vat_main_t * vam)
16092 {
16093   vl_api_show_one_map_request_mode_t *mp;
16094   int ret;
16095
16096   M (SHOW_ONE_MAP_REQUEST_MODE, mp);
16097
16098   /* send */
16099   S (mp);
16100
16101   /* wait for reply */
16102   W (ret);
16103   return ret;
16104 }
16105
16106 #define api_show_lisp_map_request_mode api_show_one_map_request_mode
16107
16108 static int
16109 api_one_map_request_mode (vat_main_t * vam)
16110 {
16111   unformat_input_t *input = vam->input;
16112   vl_api_one_map_request_mode_t *mp;
16113   u8 mode = 0;
16114   int ret;
16115
16116   /* Parse args required to build the message */
16117   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16118     {
16119       if (unformat (input, "dst-only"))
16120         mode = 0;
16121       else if (unformat (input, "src-dst"))
16122         mode = 1;
16123       else
16124         {
16125           errmsg ("parse error '%U'", format_unformat_error, input);
16126           return -99;
16127         }
16128     }
16129
16130   M (ONE_MAP_REQUEST_MODE, mp);
16131
16132   mp->mode = mode;
16133
16134   /* send */
16135   S (mp);
16136
16137   /* wait for reply */
16138   W (ret);
16139   return ret;
16140 }
16141
16142 #define api_lisp_map_request_mode api_one_map_request_mode
16143
16144 /**
16145  * Enable/disable ONE proxy ITR.
16146  *
16147  * @param vam vpp API test context
16148  * @return return code
16149  */
16150 static int
16151 api_one_pitr_set_locator_set (vat_main_t * vam)
16152 {
16153   u8 ls_name_set = 0;
16154   unformat_input_t *input = vam->input;
16155   vl_api_one_pitr_set_locator_set_t *mp;
16156   u8 is_add = 1;
16157   u8 *ls_name = 0;
16158   int ret;
16159
16160   /* Parse args required to build the message */
16161   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16162     {
16163       if (unformat (input, "del"))
16164         is_add = 0;
16165       else if (unformat (input, "locator-set %s", &ls_name))
16166         ls_name_set = 1;
16167       else
16168         {
16169           errmsg ("parse error '%U'", format_unformat_error, input);
16170           return -99;
16171         }
16172     }
16173
16174   if (!ls_name_set)
16175     {
16176       errmsg ("locator-set name not set!");
16177       return -99;
16178     }
16179
16180   M (ONE_PITR_SET_LOCATOR_SET, mp);
16181
16182   mp->is_add = is_add;
16183   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
16184   vec_free (ls_name);
16185
16186   /* send */
16187   S (mp);
16188
16189   /* wait for reply */
16190   W (ret);
16191   return ret;
16192 }
16193
16194 #define api_lisp_pitr_set_locator_set api_one_pitr_set_locator_set
16195
16196 static int
16197 api_one_nsh_set_locator_set (vat_main_t * vam)
16198 {
16199   u8 ls_name_set = 0;
16200   unformat_input_t *input = vam->input;
16201   vl_api_one_nsh_set_locator_set_t *mp;
16202   u8 is_add = 1;
16203   u8 *ls_name = 0;
16204   int ret;
16205
16206   /* Parse args required to build the message */
16207   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16208     {
16209       if (unformat (input, "del"))
16210         is_add = 0;
16211       else if (unformat (input, "ls %s", &ls_name))
16212         ls_name_set = 1;
16213       else
16214         {
16215           errmsg ("parse error '%U'", format_unformat_error, input);
16216           return -99;
16217         }
16218     }
16219
16220   if (!ls_name_set && is_add)
16221     {
16222       errmsg ("locator-set name not set!");
16223       return -99;
16224     }
16225
16226   M (ONE_NSH_SET_LOCATOR_SET, mp);
16227
16228   mp->is_add = is_add;
16229   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
16230   vec_free (ls_name);
16231
16232   /* send */
16233   S (mp);
16234
16235   /* wait for reply */
16236   W (ret);
16237   return ret;
16238 }
16239
16240 static int
16241 api_show_one_pitr (vat_main_t * vam)
16242 {
16243   vl_api_show_one_pitr_t *mp;
16244   int ret;
16245
16246   if (!vam->json_output)
16247     {
16248       print (vam->ofp, "%=20s", "lisp status:");
16249     }
16250
16251   M (SHOW_ONE_PITR, mp);
16252   /* send it... */
16253   S (mp);
16254
16255   /* Wait for a reply... */
16256   W (ret);
16257   return ret;
16258 }
16259
16260 #define api_show_lisp_pitr api_show_one_pitr
16261
16262 static int
16263 api_one_use_petr (vat_main_t * vam)
16264 {
16265   unformat_input_t *input = vam->input;
16266   vl_api_one_use_petr_t *mp;
16267   u8 is_add = 0;
16268   ip_address_t ip;
16269   int ret;
16270
16271   clib_memset (&ip, 0, sizeof (ip));
16272
16273   /* Parse args required to build the message */
16274   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16275     {
16276       if (unformat (input, "disable"))
16277         is_add = 0;
16278       else
16279         if (unformat (input, "%U", unformat_ip4_address, &ip_addr_v4 (&ip)))
16280         {
16281           is_add = 1;
16282           ip_addr_version (&ip) = AF_IP4;
16283         }
16284       else
16285         if (unformat (input, "%U", unformat_ip6_address, &ip_addr_v6 (&ip)))
16286         {
16287           is_add = 1;
16288           ip_addr_version (&ip) = AF_IP6;
16289         }
16290       else
16291         {
16292           errmsg ("parse error '%U'", format_unformat_error, input);
16293           return -99;
16294         }
16295     }
16296
16297   M (ONE_USE_PETR, mp);
16298
16299   mp->is_add = is_add;
16300   if (is_add)
16301     {
16302       mp->is_ip4 = ip_addr_version (&ip) == AF_IP4 ? 1 : 0;
16303       if (mp->is_ip4)
16304         clib_memcpy (mp->address, &ip, 4);
16305       else
16306         clib_memcpy (mp->address, &ip, 16);
16307     }
16308
16309   /* send */
16310   S (mp);
16311
16312   /* wait for reply */
16313   W (ret);
16314   return ret;
16315 }
16316
16317 #define api_lisp_use_petr api_one_use_petr
16318
16319 static int
16320 api_show_one_nsh_mapping (vat_main_t * vam)
16321 {
16322   vl_api_show_one_use_petr_t *mp;
16323   int ret;
16324
16325   if (!vam->json_output)
16326     {
16327       print (vam->ofp, "%=20s", "local ONE NSH mapping:");
16328     }
16329
16330   M (SHOW_ONE_NSH_MAPPING, mp);
16331   /* send it... */
16332   S (mp);
16333
16334   /* Wait for a reply... */
16335   W (ret);
16336   return ret;
16337 }
16338
16339 static int
16340 api_show_one_use_petr (vat_main_t * vam)
16341 {
16342   vl_api_show_one_use_petr_t *mp;
16343   int ret;
16344
16345   if (!vam->json_output)
16346     {
16347       print (vam->ofp, "%=20s", "Proxy-ETR status:");
16348     }
16349
16350   M (SHOW_ONE_USE_PETR, mp);
16351   /* send it... */
16352   S (mp);
16353
16354   /* Wait for a reply... */
16355   W (ret);
16356   return ret;
16357 }
16358
16359 #define api_show_lisp_use_petr api_show_one_use_petr
16360
16361 /**
16362  * Add/delete mapping between vni and vrf
16363  */
16364 static int
16365 api_one_eid_table_add_del_map (vat_main_t * vam)
16366 {
16367   unformat_input_t *input = vam->input;
16368   vl_api_one_eid_table_add_del_map_t *mp;
16369   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
16370   u32 vni, vrf, bd_index;
16371   int ret;
16372
16373   /* Parse args required to build the message */
16374   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16375     {
16376       if (unformat (input, "del"))
16377         is_add = 0;
16378       else if (unformat (input, "vrf %d", &vrf))
16379         vrf_set = 1;
16380       else if (unformat (input, "bd_index %d", &bd_index))
16381         bd_index_set = 1;
16382       else if (unformat (input, "vni %d", &vni))
16383         vni_set = 1;
16384       else
16385         break;
16386     }
16387
16388   if (!vni_set || (!vrf_set && !bd_index_set))
16389     {
16390       errmsg ("missing arguments!");
16391       return -99;
16392     }
16393
16394   if (vrf_set && bd_index_set)
16395     {
16396       errmsg ("error: both vrf and bd entered!");
16397       return -99;
16398     }
16399
16400   M (ONE_EID_TABLE_ADD_DEL_MAP, mp);
16401
16402   mp->is_add = is_add;
16403   mp->vni = htonl (vni);
16404   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
16405   mp->is_l2 = bd_index_set;
16406
16407   /* send */
16408   S (mp);
16409
16410   /* wait for reply */
16411   W (ret);
16412   return ret;
16413 }
16414
16415 #define api_lisp_eid_table_add_del_map api_one_eid_table_add_del_map
16416
16417 uword
16418 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
16419 {
16420   u32 *action = va_arg (*args, u32 *);
16421   u8 *s = 0;
16422
16423   if (unformat (input, "%s", &s))
16424     {
16425       if (!strcmp ((char *) s, "no-action"))
16426         action[0] = 0;
16427       else if (!strcmp ((char *) s, "natively-forward"))
16428         action[0] = 1;
16429       else if (!strcmp ((char *) s, "send-map-request"))
16430         action[0] = 2;
16431       else if (!strcmp ((char *) s, "drop"))
16432         action[0] = 3;
16433       else
16434         {
16435           clib_warning ("invalid action: '%s'", s);
16436           action[0] = 3;
16437         }
16438     }
16439   else
16440     return 0;
16441
16442   vec_free (s);
16443   return 1;
16444 }
16445
16446 /**
16447  * Add/del remote mapping to/from ONE control plane
16448  *
16449  * @param vam vpp API test context
16450  * @return return code
16451  */
16452 static int
16453 api_one_add_del_remote_mapping (vat_main_t * vam)
16454 {
16455   unformat_input_t *input = vam->input;
16456   vl_api_one_add_del_remote_mapping_t *mp;
16457   u32 vni = 0;
16458   lisp_eid_vat_t _eid, *eid = &_eid;
16459   lisp_eid_vat_t _seid, *seid = &_seid;
16460   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
16461   u32 action = ~0, p, w, data_len;
16462   ip4_address_t rloc4;
16463   ip6_address_t rloc6;
16464   vl_api_remote_locator_t *rlocs = 0, rloc, *curr_rloc = 0;
16465   int ret;
16466
16467   clib_memset (&rloc, 0, sizeof (rloc));
16468
16469   /* Parse args required to build the message */
16470   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16471     {
16472       if (unformat (input, "del-all"))
16473         {
16474           del_all = 1;
16475         }
16476       else if (unformat (input, "del"))
16477         {
16478           is_add = 0;
16479         }
16480       else if (unformat (input, "add"))
16481         {
16482           is_add = 1;
16483         }
16484       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
16485         {
16486           eid_set = 1;
16487         }
16488       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
16489         {
16490           seid_set = 1;
16491         }
16492       else if (unformat (input, "vni %d", &vni))
16493         {
16494           ;
16495         }
16496       else if (unformat (input, "p %d w %d", &p, &w))
16497         {
16498           if (!curr_rloc)
16499             {
16500               errmsg ("No RLOC configured for setting priority/weight!");
16501               return -99;
16502             }
16503           curr_rloc->priority = p;
16504           curr_rloc->weight = w;
16505         }
16506       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
16507         {
16508           rloc.is_ip4 = 1;
16509           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
16510           vec_add1 (rlocs, rloc);
16511           curr_rloc = &rlocs[vec_len (rlocs) - 1];
16512         }
16513       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
16514         {
16515           rloc.is_ip4 = 0;
16516           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
16517           vec_add1 (rlocs, rloc);
16518           curr_rloc = &rlocs[vec_len (rlocs) - 1];
16519         }
16520       else if (unformat (input, "action %U",
16521                          unformat_negative_mapping_action, &action))
16522         {
16523           ;
16524         }
16525       else
16526         {
16527           clib_warning ("parse error '%U'", format_unformat_error, input);
16528           return -99;
16529         }
16530     }
16531
16532   if (0 == eid_set)
16533     {
16534       errmsg ("missing params!");
16535       return -99;
16536     }
16537
16538   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
16539     {
16540       errmsg ("no action set for negative map-reply!");
16541       return -99;
16542     }
16543
16544   data_len = vec_len (rlocs) * sizeof (vl_api_remote_locator_t);
16545
16546   M2 (ONE_ADD_DEL_REMOTE_MAPPING, mp, data_len);
16547   mp->is_add = is_add;
16548   mp->vni = htonl (vni);
16549   mp->action = (u8) action;
16550   mp->is_src_dst = seid_set;
16551   mp->eid_len = eid->len;
16552   mp->seid_len = seid->len;
16553   mp->del_all = del_all;
16554   mp->eid_type = eid->type;
16555   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
16556   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
16557
16558   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
16559   clib_memcpy (mp->rlocs, rlocs, data_len);
16560   vec_free (rlocs);
16561
16562   /* send it... */
16563   S (mp);
16564
16565   /* Wait for a reply... */
16566   W (ret);
16567   return ret;
16568 }
16569
16570 #define api_lisp_add_del_remote_mapping api_one_add_del_remote_mapping
16571
16572 /**
16573  * Add/del ONE adjacency. Saves mapping in ONE control plane and updates
16574  * forwarding entries in data-plane accordingly.
16575  *
16576  * @param vam vpp API test context
16577  * @return return code
16578  */
16579 static int
16580 api_one_add_del_adjacency (vat_main_t * vam)
16581 {
16582   unformat_input_t *input = vam->input;
16583   vl_api_one_add_del_adjacency_t *mp;
16584   u32 vni = 0;
16585   ip4_address_t leid4, reid4;
16586   ip6_address_t leid6, reid6;
16587   u8 reid_mac[6] = { 0 };
16588   u8 leid_mac[6] = { 0 };
16589   u8 reid_type, leid_type;
16590   u32 leid_len = 0, reid_len = 0, len;
16591   u8 is_add = 1;
16592   int ret;
16593
16594   leid_type = reid_type = (u8) ~ 0;
16595
16596   /* Parse args required to build the message */
16597   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16598     {
16599       if (unformat (input, "del"))
16600         {
16601           is_add = 0;
16602         }
16603       else if (unformat (input, "add"))
16604         {
16605           is_add = 1;
16606         }
16607       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
16608                          &reid4, &len))
16609         {
16610           reid_type = 0;        /* ipv4 */
16611           reid_len = len;
16612         }
16613       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
16614                          &reid6, &len))
16615         {
16616           reid_type = 1;        /* ipv6 */
16617           reid_len = len;
16618         }
16619       else if (unformat (input, "reid %U", unformat_ethernet_address,
16620                          reid_mac))
16621         {
16622           reid_type = 2;        /* mac */
16623         }
16624       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
16625                          &leid4, &len))
16626         {
16627           leid_type = 0;        /* ipv4 */
16628           leid_len = len;
16629         }
16630       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
16631                          &leid6, &len))
16632         {
16633           leid_type = 1;        /* ipv6 */
16634           leid_len = len;
16635         }
16636       else if (unformat (input, "leid %U", unformat_ethernet_address,
16637                          leid_mac))
16638         {
16639           leid_type = 2;        /* mac */
16640         }
16641       else if (unformat (input, "vni %d", &vni))
16642         {
16643           ;
16644         }
16645       else
16646         {
16647           errmsg ("parse error '%U'", format_unformat_error, input);
16648           return -99;
16649         }
16650     }
16651
16652   if ((u8) ~ 0 == reid_type)
16653     {
16654       errmsg ("missing params!");
16655       return -99;
16656     }
16657
16658   if (leid_type != reid_type)
16659     {
16660       errmsg ("remote and local EIDs are of different types!");
16661       return -99;
16662     }
16663
16664   M (ONE_ADD_DEL_ADJACENCY, mp);
16665   mp->is_add = is_add;
16666   mp->vni = htonl (vni);
16667   mp->leid_len = leid_len;
16668   mp->reid_len = reid_len;
16669   mp->eid_type = reid_type;
16670
16671   switch (mp->eid_type)
16672     {
16673     case 0:
16674       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
16675       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
16676       break;
16677     case 1:
16678       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
16679       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
16680       break;
16681     case 2:
16682       clib_memcpy (mp->leid, leid_mac, 6);
16683       clib_memcpy (mp->reid, reid_mac, 6);
16684       break;
16685     default:
16686       errmsg ("unknown EID type %d!", mp->eid_type);
16687       return 0;
16688     }
16689
16690   /* send it... */
16691   S (mp);
16692
16693   /* Wait for a reply... */
16694   W (ret);
16695   return ret;
16696 }
16697
16698 #define api_lisp_add_del_adjacency api_one_add_del_adjacency
16699
16700 uword
16701 unformat_gpe_encap_mode (unformat_input_t * input, va_list * args)
16702 {
16703   u32 *mode = va_arg (*args, u32 *);
16704
16705   if (unformat (input, "lisp"))
16706     *mode = 0;
16707   else if (unformat (input, "vxlan"))
16708     *mode = 1;
16709   else
16710     return 0;
16711
16712   return 1;
16713 }
16714
16715 static int
16716 api_gpe_get_encap_mode (vat_main_t * vam)
16717 {
16718   vl_api_gpe_get_encap_mode_t *mp;
16719   int ret;
16720
16721   /* Construct the API message */
16722   M (GPE_GET_ENCAP_MODE, mp);
16723
16724   /* send it... */
16725   S (mp);
16726
16727   /* Wait for a reply... */
16728   W (ret);
16729   return ret;
16730 }
16731
16732 static int
16733 api_gpe_set_encap_mode (vat_main_t * vam)
16734 {
16735   unformat_input_t *input = vam->input;
16736   vl_api_gpe_set_encap_mode_t *mp;
16737   int ret;
16738   u32 mode = 0;
16739
16740   /* Parse args required to build the message */
16741   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16742     {
16743       if (unformat (input, "%U", unformat_gpe_encap_mode, &mode))
16744         ;
16745       else
16746         break;
16747     }
16748
16749   /* Construct the API message */
16750   M (GPE_SET_ENCAP_MODE, mp);
16751
16752   mp->mode = mode;
16753
16754   /* send it... */
16755   S (mp);
16756
16757   /* Wait for a reply... */
16758   W (ret);
16759   return ret;
16760 }
16761
16762 static int
16763 api_lisp_gpe_add_del_iface (vat_main_t * vam)
16764 {
16765   unformat_input_t *input = vam->input;
16766   vl_api_gpe_add_del_iface_t *mp;
16767   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
16768   u32 dp_table = 0, vni = 0;
16769   int ret;
16770
16771   /* Parse args required to build the message */
16772   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16773     {
16774       if (unformat (input, "up"))
16775         {
16776           action_set = 1;
16777           is_add = 1;
16778         }
16779       else if (unformat (input, "down"))
16780         {
16781           action_set = 1;
16782           is_add = 0;
16783         }
16784       else if (unformat (input, "table_id %d", &dp_table))
16785         {
16786           dp_table_set = 1;
16787         }
16788       else if (unformat (input, "bd_id %d", &dp_table))
16789         {
16790           dp_table_set = 1;
16791           is_l2 = 1;
16792         }
16793       else if (unformat (input, "vni %d", &vni))
16794         {
16795           vni_set = 1;
16796         }
16797       else
16798         break;
16799     }
16800
16801   if (action_set == 0)
16802     {
16803       errmsg ("Action not set");
16804       return -99;
16805     }
16806   if (dp_table_set == 0 || vni_set == 0)
16807     {
16808       errmsg ("vni and dp_table must be set");
16809       return -99;
16810     }
16811
16812   /* Construct the API message */
16813   M (GPE_ADD_DEL_IFACE, mp);
16814
16815   mp->is_add = is_add;
16816   mp->dp_table = clib_host_to_net_u32 (dp_table);
16817   mp->is_l2 = is_l2;
16818   mp->vni = clib_host_to_net_u32 (vni);
16819
16820   /* send it... */
16821   S (mp);
16822
16823   /* Wait for a reply... */
16824   W (ret);
16825   return ret;
16826 }
16827
16828 static int
16829 api_one_map_register_fallback_threshold (vat_main_t * vam)
16830 {
16831   unformat_input_t *input = vam->input;
16832   vl_api_one_map_register_fallback_threshold_t *mp;
16833   u32 value = 0;
16834   u8 is_set = 0;
16835   int ret;
16836
16837   /* Parse args required to build the message */
16838   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16839     {
16840       if (unformat (input, "%u", &value))
16841         is_set = 1;
16842       else
16843         {
16844           clib_warning ("parse error '%U'", format_unformat_error, input);
16845           return -99;
16846         }
16847     }
16848
16849   if (!is_set)
16850     {
16851       errmsg ("fallback threshold value is missing!");
16852       return -99;
16853     }
16854
16855   M (ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
16856   mp->value = clib_host_to_net_u32 (value);
16857
16858   /* send it... */
16859   S (mp);
16860
16861   /* Wait for a reply... */
16862   W (ret);
16863   return ret;
16864 }
16865
16866 static int
16867 api_show_one_map_register_fallback_threshold (vat_main_t * vam)
16868 {
16869   vl_api_show_one_map_register_fallback_threshold_t *mp;
16870   int ret;
16871
16872   M (SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
16873
16874   /* send it... */
16875   S (mp);
16876
16877   /* Wait for a reply... */
16878   W (ret);
16879   return ret;
16880 }
16881
16882 uword
16883 unformat_lisp_transport_protocol (unformat_input_t * input, va_list * args)
16884 {
16885   u32 *proto = va_arg (*args, u32 *);
16886
16887   if (unformat (input, "udp"))
16888     *proto = 1;
16889   else if (unformat (input, "api"))
16890     *proto = 2;
16891   else
16892     return 0;
16893
16894   return 1;
16895 }
16896
16897 static int
16898 api_one_set_transport_protocol (vat_main_t * vam)
16899 {
16900   unformat_input_t *input = vam->input;
16901   vl_api_one_set_transport_protocol_t *mp;
16902   u8 is_set = 0;
16903   u32 protocol = 0;
16904   int ret;
16905
16906   /* Parse args required to build the message */
16907   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16908     {
16909       if (unformat (input, "%U", unformat_lisp_transport_protocol, &protocol))
16910         is_set = 1;
16911       else
16912         {
16913           clib_warning ("parse error '%U'", format_unformat_error, input);
16914           return -99;
16915         }
16916     }
16917
16918   if (!is_set)
16919     {
16920       errmsg ("Transport protocol missing!");
16921       return -99;
16922     }
16923
16924   M (ONE_SET_TRANSPORT_PROTOCOL, mp);
16925   mp->protocol = (u8) protocol;
16926
16927   /* send it... */
16928   S (mp);
16929
16930   /* Wait for a reply... */
16931   W (ret);
16932   return ret;
16933 }
16934
16935 static int
16936 api_one_get_transport_protocol (vat_main_t * vam)
16937 {
16938   vl_api_one_get_transport_protocol_t *mp;
16939   int ret;
16940
16941   M (ONE_GET_TRANSPORT_PROTOCOL, mp);
16942
16943   /* send it... */
16944   S (mp);
16945
16946   /* Wait for a reply... */
16947   W (ret);
16948   return ret;
16949 }
16950
16951 static int
16952 api_one_map_register_set_ttl (vat_main_t * vam)
16953 {
16954   unformat_input_t *input = vam->input;
16955   vl_api_one_map_register_set_ttl_t *mp;
16956   u32 ttl = 0;
16957   u8 is_set = 0;
16958   int ret;
16959
16960   /* Parse args required to build the message */
16961   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16962     {
16963       if (unformat (input, "%u", &ttl))
16964         is_set = 1;
16965       else
16966         {
16967           clib_warning ("parse error '%U'", format_unformat_error, input);
16968           return -99;
16969         }
16970     }
16971
16972   if (!is_set)
16973     {
16974       errmsg ("TTL value missing!");
16975       return -99;
16976     }
16977
16978   M (ONE_MAP_REGISTER_SET_TTL, mp);
16979   mp->ttl = clib_host_to_net_u32 (ttl);
16980
16981   /* send it... */
16982   S (mp);
16983
16984   /* Wait for a reply... */
16985   W (ret);
16986   return ret;
16987 }
16988
16989 static int
16990 api_show_one_map_register_ttl (vat_main_t * vam)
16991 {
16992   vl_api_show_one_map_register_ttl_t *mp;
16993   int ret;
16994
16995   M (SHOW_ONE_MAP_REGISTER_TTL, mp);
16996
16997   /* send it... */
16998   S (mp);
16999
17000   /* Wait for a reply... */
17001   W (ret);
17002   return ret;
17003 }
17004
17005 /**
17006  * Add/del map request itr rlocs from ONE control plane and updates
17007  *
17008  * @param vam vpp API test context
17009  * @return return code
17010  */
17011 static int
17012 api_one_add_del_map_request_itr_rlocs (vat_main_t * vam)
17013 {
17014   unformat_input_t *input = vam->input;
17015   vl_api_one_add_del_map_request_itr_rlocs_t *mp;
17016   u8 *locator_set_name = 0;
17017   u8 locator_set_name_set = 0;
17018   u8 is_add = 1;
17019   int ret;
17020
17021   /* Parse args required to build the message */
17022   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17023     {
17024       if (unformat (input, "del"))
17025         {
17026           is_add = 0;
17027         }
17028       else if (unformat (input, "%_%v%_", &locator_set_name))
17029         {
17030           locator_set_name_set = 1;
17031         }
17032       else
17033         {
17034           clib_warning ("parse error '%U'", format_unformat_error, input);
17035           return -99;
17036         }
17037     }
17038
17039   if (is_add && !locator_set_name_set)
17040     {
17041       errmsg ("itr-rloc is not set!");
17042       return -99;
17043     }
17044
17045   if (is_add && vec_len (locator_set_name) > 64)
17046     {
17047       errmsg ("itr-rloc locator-set name too long");
17048       vec_free (locator_set_name);
17049       return -99;
17050     }
17051
17052   M (ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS, mp);
17053   mp->is_add = is_add;
17054   if (is_add)
17055     {
17056       clib_memcpy (mp->locator_set_name, locator_set_name,
17057                    vec_len (locator_set_name));
17058     }
17059   else
17060     {
17061       clib_memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
17062     }
17063   vec_free (locator_set_name);
17064
17065   /* send it... */
17066   S (mp);
17067
17068   /* Wait for a reply... */
17069   W (ret);
17070   return ret;
17071 }
17072
17073 #define api_lisp_add_del_map_request_itr_rlocs api_one_add_del_map_request_itr_rlocs
17074
17075 static int
17076 api_one_locator_dump (vat_main_t * vam)
17077 {
17078   unformat_input_t *input = vam->input;
17079   vl_api_one_locator_dump_t *mp;
17080   vl_api_control_ping_t *mp_ping;
17081   u8 is_index_set = 0, is_name_set = 0;
17082   u8 *ls_name = 0;
17083   u32 ls_index = ~0;
17084   int ret;
17085
17086   /* Parse args required to build the message */
17087   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17088     {
17089       if (unformat (input, "ls_name %_%v%_", &ls_name))
17090         {
17091           is_name_set = 1;
17092         }
17093       else if (unformat (input, "ls_index %d", &ls_index))
17094         {
17095           is_index_set = 1;
17096         }
17097       else
17098         {
17099           errmsg ("parse error '%U'", format_unformat_error, input);
17100           return -99;
17101         }
17102     }
17103
17104   if (!is_index_set && !is_name_set)
17105     {
17106       errmsg ("error: expected one of index or name!");
17107       return -99;
17108     }
17109
17110   if (is_index_set && is_name_set)
17111     {
17112       errmsg ("error: only one param expected!");
17113       return -99;
17114     }
17115
17116   if (vec_len (ls_name) > 62)
17117     {
17118       errmsg ("error: locator set name too long!");
17119       return -99;
17120     }
17121
17122   if (!vam->json_output)
17123     {
17124       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
17125     }
17126
17127   M (ONE_LOCATOR_DUMP, mp);
17128   mp->is_index_set = is_index_set;
17129
17130   if (is_index_set)
17131     mp->ls_index = clib_host_to_net_u32 (ls_index);
17132   else
17133     {
17134       vec_add1 (ls_name, 0);
17135       strncpy ((char *) mp->ls_name, (char *) ls_name,
17136                sizeof (mp->ls_name) - 1);
17137     }
17138
17139   /* send it... */
17140   S (mp);
17141
17142   /* Use a control ping for synchronization */
17143   MPING (CONTROL_PING, mp_ping);
17144   S (mp_ping);
17145
17146   /* Wait for a reply... */
17147   W (ret);
17148   return ret;
17149 }
17150
17151 #define api_lisp_locator_dump api_one_locator_dump
17152
17153 static int
17154 api_one_locator_set_dump (vat_main_t * vam)
17155 {
17156   vl_api_one_locator_set_dump_t *mp;
17157   vl_api_control_ping_t *mp_ping;
17158   unformat_input_t *input = vam->input;
17159   u8 filter = 0;
17160   int ret;
17161
17162   /* Parse args required to build the message */
17163   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17164     {
17165       if (unformat (input, "local"))
17166         {
17167           filter = 1;
17168         }
17169       else if (unformat (input, "remote"))
17170         {
17171           filter = 2;
17172         }
17173       else
17174         {
17175           errmsg ("parse error '%U'", format_unformat_error, input);
17176           return -99;
17177         }
17178     }
17179
17180   if (!vam->json_output)
17181     {
17182       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
17183     }
17184
17185   M (ONE_LOCATOR_SET_DUMP, mp);
17186
17187   mp->filter = filter;
17188
17189   /* send it... */
17190   S (mp);
17191
17192   /* Use a control ping for synchronization */
17193   MPING (CONTROL_PING, mp_ping);
17194   S (mp_ping);
17195
17196   /* Wait for a reply... */
17197   W (ret);
17198   return ret;
17199 }
17200
17201 #define api_lisp_locator_set_dump api_one_locator_set_dump
17202
17203 static int
17204 api_one_eid_table_map_dump (vat_main_t * vam)
17205 {
17206   u8 is_l2 = 0;
17207   u8 mode_set = 0;
17208   unformat_input_t *input = vam->input;
17209   vl_api_one_eid_table_map_dump_t *mp;
17210   vl_api_control_ping_t *mp_ping;
17211   int ret;
17212
17213   /* Parse args required to build the message */
17214   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17215     {
17216       if (unformat (input, "l2"))
17217         {
17218           is_l2 = 1;
17219           mode_set = 1;
17220         }
17221       else if (unformat (input, "l3"))
17222         {
17223           is_l2 = 0;
17224           mode_set = 1;
17225         }
17226       else
17227         {
17228           errmsg ("parse error '%U'", format_unformat_error, input);
17229           return -99;
17230         }
17231     }
17232
17233   if (!mode_set)
17234     {
17235       errmsg ("expected one of 'l2' or 'l3' parameter!");
17236       return -99;
17237     }
17238
17239   if (!vam->json_output)
17240     {
17241       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
17242     }
17243
17244   M (ONE_EID_TABLE_MAP_DUMP, mp);
17245   mp->is_l2 = is_l2;
17246
17247   /* send it... */
17248   S (mp);
17249
17250   /* Use a control ping for synchronization */
17251   MPING (CONTROL_PING, mp_ping);
17252   S (mp_ping);
17253
17254   /* Wait for a reply... */
17255   W (ret);
17256   return ret;
17257 }
17258
17259 #define api_lisp_eid_table_map_dump api_one_eid_table_map_dump
17260
17261 static int
17262 api_one_eid_table_vni_dump (vat_main_t * vam)
17263 {
17264   vl_api_one_eid_table_vni_dump_t *mp;
17265   vl_api_control_ping_t *mp_ping;
17266   int ret;
17267
17268   if (!vam->json_output)
17269     {
17270       print (vam->ofp, "VNI");
17271     }
17272
17273   M (ONE_EID_TABLE_VNI_DUMP, mp);
17274
17275   /* send it... */
17276   S (mp);
17277
17278   /* Use a control ping for synchronization */
17279   MPING (CONTROL_PING, mp_ping);
17280   S (mp_ping);
17281
17282   /* Wait for a reply... */
17283   W (ret);
17284   return ret;
17285 }
17286
17287 #define api_lisp_eid_table_vni_dump api_one_eid_table_vni_dump
17288
17289 static int
17290 api_one_eid_table_dump (vat_main_t * vam)
17291 {
17292   unformat_input_t *i = vam->input;
17293   vl_api_one_eid_table_dump_t *mp;
17294   vl_api_control_ping_t *mp_ping;
17295   struct in_addr ip4;
17296   struct in6_addr ip6;
17297   u8 mac[6];
17298   u8 eid_type = ~0, eid_set = 0;
17299   u32 prefix_length = ~0, t, vni = 0;
17300   u8 filter = 0;
17301   int ret;
17302   lisp_nsh_api_t nsh;
17303
17304   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17305     {
17306       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
17307         {
17308           eid_set = 1;
17309           eid_type = 0;
17310           prefix_length = t;
17311         }
17312       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
17313         {
17314           eid_set = 1;
17315           eid_type = 1;
17316           prefix_length = t;
17317         }
17318       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
17319         {
17320           eid_set = 1;
17321           eid_type = 2;
17322         }
17323       else if (unformat (i, "eid %U", unformat_nsh_address, &nsh))
17324         {
17325           eid_set = 1;
17326           eid_type = 3;
17327         }
17328       else if (unformat (i, "vni %d", &t))
17329         {
17330           vni = t;
17331         }
17332       else if (unformat (i, "local"))
17333         {
17334           filter = 1;
17335         }
17336       else if (unformat (i, "remote"))
17337         {
17338           filter = 2;
17339         }
17340       else
17341         {
17342           errmsg ("parse error '%U'", format_unformat_error, i);
17343           return -99;
17344         }
17345     }
17346
17347   if (!vam->json_output)
17348     {
17349       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
17350              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
17351     }
17352
17353   M (ONE_EID_TABLE_DUMP, mp);
17354
17355   mp->filter = filter;
17356   if (eid_set)
17357     {
17358       mp->eid_set = 1;
17359       mp->vni = htonl (vni);
17360       mp->eid_type = eid_type;
17361       switch (eid_type)
17362         {
17363         case 0:
17364           mp->prefix_length = prefix_length;
17365           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
17366           break;
17367         case 1:
17368           mp->prefix_length = prefix_length;
17369           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
17370           break;
17371         case 2:
17372           clib_memcpy (mp->eid, mac, sizeof (mac));
17373           break;
17374         case 3:
17375           clib_memcpy (mp->eid, &nsh, sizeof (nsh));
17376           break;
17377         default:
17378           errmsg ("unknown EID type %d!", eid_type);
17379           return -99;
17380         }
17381     }
17382
17383   /* send it... */
17384   S (mp);
17385
17386   /* Use a control ping for synchronization */
17387   MPING (CONTROL_PING, mp_ping);
17388   S (mp_ping);
17389
17390   /* Wait for a reply... */
17391   W (ret);
17392   return ret;
17393 }
17394
17395 #define api_lisp_eid_table_dump api_one_eid_table_dump
17396
17397 static int
17398 api_lisp_gpe_fwd_entries_get (vat_main_t * vam)
17399 {
17400   unformat_input_t *i = vam->input;
17401   vl_api_gpe_fwd_entries_get_t *mp;
17402   u8 vni_set = 0;
17403   u32 vni = ~0;
17404   int ret;
17405
17406   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17407     {
17408       if (unformat (i, "vni %d", &vni))
17409         {
17410           vni_set = 1;
17411         }
17412       else
17413         {
17414           errmsg ("parse error '%U'", format_unformat_error, i);
17415           return -99;
17416         }
17417     }
17418
17419   if (!vni_set)
17420     {
17421       errmsg ("vni not set!");
17422       return -99;
17423     }
17424
17425   if (!vam->json_output)
17426     {
17427       print (vam->ofp, "%10s %10s %s %40s", "fwd_index", "dp_table",
17428              "leid", "reid");
17429     }
17430
17431   M (GPE_FWD_ENTRIES_GET, mp);
17432   mp->vni = clib_host_to_net_u32 (vni);
17433
17434   /* send it... */
17435   S (mp);
17436
17437   /* Wait for a reply... */
17438   W (ret);
17439   return ret;
17440 }
17441
17442 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_endian vl_noop_handler
17443 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_print vl_noop_handler
17444 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_endian vl_noop_handler
17445 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_print vl_noop_handler
17446 #define vl_api_gpe_fwd_entries_get_reply_t_endian vl_noop_handler
17447 #define vl_api_gpe_fwd_entries_get_reply_t_print vl_noop_handler
17448 #define vl_api_gpe_fwd_entry_path_details_t_endian vl_noop_handler
17449 #define vl_api_gpe_fwd_entry_path_details_t_print vl_noop_handler
17450
17451 static int
17452 api_one_adjacencies_get (vat_main_t * vam)
17453 {
17454   unformat_input_t *i = vam->input;
17455   vl_api_one_adjacencies_get_t *mp;
17456   u8 vni_set = 0;
17457   u32 vni = ~0;
17458   int ret;
17459
17460   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17461     {
17462       if (unformat (i, "vni %d", &vni))
17463         {
17464           vni_set = 1;
17465         }
17466       else
17467         {
17468           errmsg ("parse error '%U'", format_unformat_error, i);
17469           return -99;
17470         }
17471     }
17472
17473   if (!vni_set)
17474     {
17475       errmsg ("vni not set!");
17476       return -99;
17477     }
17478
17479   if (!vam->json_output)
17480     {
17481       print (vam->ofp, "%s %40s", "leid", "reid");
17482     }
17483
17484   M (ONE_ADJACENCIES_GET, mp);
17485   mp->vni = clib_host_to_net_u32 (vni);
17486
17487   /* send it... */
17488   S (mp);
17489
17490   /* Wait for a reply... */
17491   W (ret);
17492   return ret;
17493 }
17494
17495 #define api_lisp_adjacencies_get api_one_adjacencies_get
17496
17497 static int
17498 api_gpe_native_fwd_rpaths_get (vat_main_t * vam)
17499 {
17500   unformat_input_t *i = vam->input;
17501   vl_api_gpe_native_fwd_rpaths_get_t *mp;
17502   int ret;
17503   u8 ip_family_set = 0, is_ip4 = 1;
17504
17505   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17506     {
17507       if (unformat (i, "ip4"))
17508         {
17509           ip_family_set = 1;
17510           is_ip4 = 1;
17511         }
17512       else if (unformat (i, "ip6"))
17513         {
17514           ip_family_set = 1;
17515           is_ip4 = 0;
17516         }
17517       else
17518         {
17519           errmsg ("parse error '%U'", format_unformat_error, i);
17520           return -99;
17521         }
17522     }
17523
17524   if (!ip_family_set)
17525     {
17526       errmsg ("ip family not set!");
17527       return -99;
17528     }
17529
17530   M (GPE_NATIVE_FWD_RPATHS_GET, mp);
17531   mp->is_ip4 = is_ip4;
17532
17533   /* send it... */
17534   S (mp);
17535
17536   /* Wait for a reply... */
17537   W (ret);
17538   return ret;
17539 }
17540
17541 static int
17542 api_gpe_fwd_entry_vnis_get (vat_main_t * vam)
17543 {
17544   vl_api_gpe_fwd_entry_vnis_get_t *mp;
17545   int ret;
17546
17547   if (!vam->json_output)
17548     {
17549       print (vam->ofp, "VNIs");
17550     }
17551
17552   M (GPE_FWD_ENTRY_VNIS_GET, mp);
17553
17554   /* send it... */
17555   S (mp);
17556
17557   /* Wait for a reply... */
17558   W (ret);
17559   return ret;
17560 }
17561
17562 static int
17563 api_gpe_add_del_native_fwd_rpath (vat_main_t * vam)
17564 {
17565   unformat_input_t *i = vam->input;
17566   vl_api_gpe_add_del_native_fwd_rpath_t *mp;
17567   int ret = 0;
17568   u8 is_add = 1, ip_set = 0, is_ip4 = 1;
17569   struct in_addr ip4;
17570   struct in6_addr ip6;
17571   u32 table_id = 0, nh_sw_if_index = ~0;
17572
17573   clib_memset (&ip4, 0, sizeof (ip4));
17574   clib_memset (&ip6, 0, sizeof (ip6));
17575
17576   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17577     {
17578       if (unformat (i, "del"))
17579         is_add = 0;
17580       else if (unformat (i, "via %U %U", unformat_ip4_address, &ip4,
17581                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
17582         {
17583           ip_set = 1;
17584           is_ip4 = 1;
17585         }
17586       else if (unformat (i, "via %U %U", unformat_ip6_address, &ip6,
17587                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
17588         {
17589           ip_set = 1;
17590           is_ip4 = 0;
17591         }
17592       else if (unformat (i, "via %U", unformat_ip4_address, &ip4))
17593         {
17594           ip_set = 1;
17595           is_ip4 = 1;
17596           nh_sw_if_index = ~0;
17597         }
17598       else if (unformat (i, "via %U", unformat_ip6_address, &ip6))
17599         {
17600           ip_set = 1;
17601           is_ip4 = 0;
17602           nh_sw_if_index = ~0;
17603         }
17604       else if (unformat (i, "table %d", &table_id))
17605         ;
17606       else
17607         {
17608           errmsg ("parse error '%U'", format_unformat_error, i);
17609           return -99;
17610         }
17611     }
17612
17613   if (!ip_set)
17614     {
17615       errmsg ("nh addr not set!");
17616       return -99;
17617     }
17618
17619   M (GPE_ADD_DEL_NATIVE_FWD_RPATH, mp);
17620   mp->is_add = is_add;
17621   mp->table_id = clib_host_to_net_u32 (table_id);
17622   mp->nh_sw_if_index = clib_host_to_net_u32 (nh_sw_if_index);
17623   mp->is_ip4 = is_ip4;
17624   if (is_ip4)
17625     clib_memcpy (mp->nh_addr, &ip4, sizeof (ip4));
17626   else
17627     clib_memcpy (mp->nh_addr, &ip6, sizeof (ip6));
17628
17629   /* send it... */
17630   S (mp);
17631
17632   /* Wait for a reply... */
17633   W (ret);
17634   return ret;
17635 }
17636
17637 static int
17638 api_one_map_server_dump (vat_main_t * vam)
17639 {
17640   vl_api_one_map_server_dump_t *mp;
17641   vl_api_control_ping_t *mp_ping;
17642   int ret;
17643
17644   if (!vam->json_output)
17645     {
17646       print (vam->ofp, "%=20s", "Map server");
17647     }
17648
17649   M (ONE_MAP_SERVER_DUMP, mp);
17650   /* send it... */
17651   S (mp);
17652
17653   /* Use a control ping for synchronization */
17654   MPING (CONTROL_PING, mp_ping);
17655   S (mp_ping);
17656
17657   /* Wait for a reply... */
17658   W (ret);
17659   return ret;
17660 }
17661
17662 #define api_lisp_map_server_dump api_one_map_server_dump
17663
17664 static int
17665 api_one_map_resolver_dump (vat_main_t * vam)
17666 {
17667   vl_api_one_map_resolver_dump_t *mp;
17668   vl_api_control_ping_t *mp_ping;
17669   int ret;
17670
17671   if (!vam->json_output)
17672     {
17673       print (vam->ofp, "%=20s", "Map resolver");
17674     }
17675
17676   M (ONE_MAP_RESOLVER_DUMP, mp);
17677   /* send it... */
17678   S (mp);
17679
17680   /* Use a control ping for synchronization */
17681   MPING (CONTROL_PING, mp_ping);
17682   S (mp_ping);
17683
17684   /* Wait for a reply... */
17685   W (ret);
17686   return ret;
17687 }
17688
17689 #define api_lisp_map_resolver_dump api_one_map_resolver_dump
17690
17691 static int
17692 api_one_stats_flush (vat_main_t * vam)
17693 {
17694   vl_api_one_stats_flush_t *mp;
17695   int ret = 0;
17696
17697   M (ONE_STATS_FLUSH, mp);
17698   S (mp);
17699   W (ret);
17700   return ret;
17701 }
17702
17703 static int
17704 api_one_stats_dump (vat_main_t * vam)
17705 {
17706   vl_api_one_stats_dump_t *mp;
17707   vl_api_control_ping_t *mp_ping;
17708   int ret;
17709
17710   M (ONE_STATS_DUMP, mp);
17711   /* send it... */
17712   S (mp);
17713
17714   /* Use a control ping for synchronization */
17715   MPING (CONTROL_PING, mp_ping);
17716   S (mp_ping);
17717
17718   /* Wait for a reply... */
17719   W (ret);
17720   return ret;
17721 }
17722
17723 static int
17724 api_show_one_status (vat_main_t * vam)
17725 {
17726   vl_api_show_one_status_t *mp;
17727   int ret;
17728
17729   if (!vam->json_output)
17730     {
17731       print (vam->ofp, "%-20s%-16s", "ONE status", "locator-set");
17732     }
17733
17734   M (SHOW_ONE_STATUS, mp);
17735   /* send it... */
17736   S (mp);
17737   /* Wait for a reply... */
17738   W (ret);
17739   return ret;
17740 }
17741
17742 #define api_show_lisp_status api_show_one_status
17743
17744 static int
17745 api_lisp_gpe_fwd_entry_path_dump (vat_main_t * vam)
17746 {
17747   vl_api_gpe_fwd_entry_path_dump_t *mp;
17748   vl_api_control_ping_t *mp_ping;
17749   unformat_input_t *i = vam->input;
17750   u32 fwd_entry_index = ~0;
17751   int ret;
17752
17753   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17754     {
17755       if (unformat (i, "index %d", &fwd_entry_index))
17756         ;
17757       else
17758         break;
17759     }
17760
17761   if (~0 == fwd_entry_index)
17762     {
17763       errmsg ("no index specified!");
17764       return -99;
17765     }
17766
17767   if (!vam->json_output)
17768     {
17769       print (vam->ofp, "first line");
17770     }
17771
17772   M (GPE_FWD_ENTRY_PATH_DUMP, mp);
17773
17774   /* send it... */
17775   S (mp);
17776   /* Use a control ping for synchronization */
17777   MPING (CONTROL_PING, mp_ping);
17778   S (mp_ping);
17779
17780   /* Wait for a reply... */
17781   W (ret);
17782   return ret;
17783 }
17784
17785 static int
17786 api_one_get_map_request_itr_rlocs (vat_main_t * vam)
17787 {
17788   vl_api_one_get_map_request_itr_rlocs_t *mp;
17789   int ret;
17790
17791   if (!vam->json_output)
17792     {
17793       print (vam->ofp, "%=20s", "itr-rlocs:");
17794     }
17795
17796   M (ONE_GET_MAP_REQUEST_ITR_RLOCS, mp);
17797   /* send it... */
17798   S (mp);
17799   /* Wait for a reply... */
17800   W (ret);
17801   return ret;
17802 }
17803
17804 #define api_lisp_get_map_request_itr_rlocs api_one_get_map_request_itr_rlocs
17805
17806 static int
17807 api_af_packet_create (vat_main_t * vam)
17808 {
17809   unformat_input_t *i = vam->input;
17810   vl_api_af_packet_create_t *mp;
17811   u8 *host_if_name = 0;
17812   u8 hw_addr[6];
17813   u8 random_hw_addr = 1;
17814   int ret;
17815
17816   clib_memset (hw_addr, 0, sizeof (hw_addr));
17817
17818   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17819     {
17820       if (unformat (i, "name %s", &host_if_name))
17821         vec_add1 (host_if_name, 0);
17822       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
17823         random_hw_addr = 0;
17824       else
17825         break;
17826     }
17827
17828   if (!vec_len (host_if_name))
17829     {
17830       errmsg ("host-interface name must be specified");
17831       return -99;
17832     }
17833
17834   if (vec_len (host_if_name) > 64)
17835     {
17836       errmsg ("host-interface name too long");
17837       return -99;
17838     }
17839
17840   M (AF_PACKET_CREATE, mp);
17841
17842   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
17843   clib_memcpy (mp->hw_addr, hw_addr, 6);
17844   mp->use_random_hw_addr = random_hw_addr;
17845   vec_free (host_if_name);
17846
17847   S (mp);
17848
17849   /* *INDENT-OFF* */
17850   W2 (ret,
17851       ({
17852         if (ret == 0)
17853           fprintf (vam->ofp ? vam->ofp : stderr,
17854                    " new sw_if_index = %d\n", vam->sw_if_index);
17855       }));
17856   /* *INDENT-ON* */
17857   return ret;
17858 }
17859
17860 static int
17861 api_af_packet_delete (vat_main_t * vam)
17862 {
17863   unformat_input_t *i = vam->input;
17864   vl_api_af_packet_delete_t *mp;
17865   u8 *host_if_name = 0;
17866   int ret;
17867
17868   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17869     {
17870       if (unformat (i, "name %s", &host_if_name))
17871         vec_add1 (host_if_name, 0);
17872       else
17873         break;
17874     }
17875
17876   if (!vec_len (host_if_name))
17877     {
17878       errmsg ("host-interface name must be specified");
17879       return -99;
17880     }
17881
17882   if (vec_len (host_if_name) > 64)
17883     {
17884       errmsg ("host-interface name too long");
17885       return -99;
17886     }
17887
17888   M (AF_PACKET_DELETE, mp);
17889
17890   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
17891   vec_free (host_if_name);
17892
17893   S (mp);
17894   W (ret);
17895   return ret;
17896 }
17897
17898 static void vl_api_af_packet_details_t_handler
17899   (vl_api_af_packet_details_t * mp)
17900 {
17901   vat_main_t *vam = &vat_main;
17902
17903   print (vam->ofp, "%-16s %d",
17904          mp->host_if_name, clib_net_to_host_u32 (mp->sw_if_index));
17905 }
17906
17907 static void vl_api_af_packet_details_t_handler_json
17908   (vl_api_af_packet_details_t * mp)
17909 {
17910   vat_main_t *vam = &vat_main;
17911   vat_json_node_t *node = NULL;
17912
17913   if (VAT_JSON_ARRAY != vam->json_tree.type)
17914     {
17915       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17916       vat_json_init_array (&vam->json_tree);
17917     }
17918   node = vat_json_array_add (&vam->json_tree);
17919
17920   vat_json_init_object (node);
17921   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
17922   vat_json_object_add_string_copy (node, "dev_name", mp->host_if_name);
17923 }
17924
17925 static int
17926 api_af_packet_dump (vat_main_t * vam)
17927 {
17928   vl_api_af_packet_dump_t *mp;
17929   vl_api_control_ping_t *mp_ping;
17930   int ret;
17931
17932   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
17933   /* Get list of tap interfaces */
17934   M (AF_PACKET_DUMP, mp);
17935   S (mp);
17936
17937   /* Use a control ping for synchronization */
17938   MPING (CONTROL_PING, mp_ping);
17939   S (mp_ping);
17940
17941   W (ret);
17942   return ret;
17943 }
17944
17945 static int
17946 api_policer_add_del (vat_main_t * vam)
17947 {
17948   unformat_input_t *i = vam->input;
17949   vl_api_policer_add_del_t *mp;
17950   u8 is_add = 1;
17951   u8 *name = 0;
17952   u32 cir = 0;
17953   u32 eir = 0;
17954   u64 cb = 0;
17955   u64 eb = 0;
17956   u8 rate_type = 0;
17957   u8 round_type = 0;
17958   u8 type = 0;
17959   u8 color_aware = 0;
17960   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
17961   int ret;
17962
17963   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
17964   conform_action.dscp = 0;
17965   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
17966   exceed_action.dscp = 0;
17967   violate_action.action_type = SSE2_QOS_ACTION_DROP;
17968   violate_action.dscp = 0;
17969
17970   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17971     {
17972       if (unformat (i, "del"))
17973         is_add = 0;
17974       else if (unformat (i, "name %s", &name))
17975         vec_add1 (name, 0);
17976       else if (unformat (i, "cir %u", &cir))
17977         ;
17978       else if (unformat (i, "eir %u", &eir))
17979         ;
17980       else if (unformat (i, "cb %u", &cb))
17981         ;
17982       else if (unformat (i, "eb %u", &eb))
17983         ;
17984       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
17985                          &rate_type))
17986         ;
17987       else if (unformat (i, "round_type %U", unformat_policer_round_type,
17988                          &round_type))
17989         ;
17990       else if (unformat (i, "type %U", unformat_policer_type, &type))
17991         ;
17992       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
17993                          &conform_action))
17994         ;
17995       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
17996                          &exceed_action))
17997         ;
17998       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
17999                          &violate_action))
18000         ;
18001       else if (unformat (i, "color-aware"))
18002         color_aware = 1;
18003       else
18004         break;
18005     }
18006
18007   if (!vec_len (name))
18008     {
18009       errmsg ("policer name must be specified");
18010       return -99;
18011     }
18012
18013   if (vec_len (name) > 64)
18014     {
18015       errmsg ("policer name too long");
18016       return -99;
18017     }
18018
18019   M (POLICER_ADD_DEL, mp);
18020
18021   clib_memcpy (mp->name, name, vec_len (name));
18022   vec_free (name);
18023   mp->is_add = is_add;
18024   mp->cir = ntohl (cir);
18025   mp->eir = ntohl (eir);
18026   mp->cb = clib_net_to_host_u64 (cb);
18027   mp->eb = clib_net_to_host_u64 (eb);
18028   mp->rate_type = rate_type;
18029   mp->round_type = round_type;
18030   mp->type = type;
18031   mp->conform_action_type = conform_action.action_type;
18032   mp->conform_dscp = conform_action.dscp;
18033   mp->exceed_action_type = exceed_action.action_type;
18034   mp->exceed_dscp = exceed_action.dscp;
18035   mp->violate_action_type = violate_action.action_type;
18036   mp->violate_dscp = violate_action.dscp;
18037   mp->color_aware = color_aware;
18038
18039   S (mp);
18040   W (ret);
18041   return ret;
18042 }
18043
18044 static int
18045 api_policer_dump (vat_main_t * vam)
18046 {
18047   unformat_input_t *i = vam->input;
18048   vl_api_policer_dump_t *mp;
18049   vl_api_control_ping_t *mp_ping;
18050   u8 *match_name = 0;
18051   u8 match_name_valid = 0;
18052   int ret;
18053
18054   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18055     {
18056       if (unformat (i, "name %s", &match_name))
18057         {
18058           vec_add1 (match_name, 0);
18059           match_name_valid = 1;
18060         }
18061       else
18062         break;
18063     }
18064
18065   M (POLICER_DUMP, mp);
18066   mp->match_name_valid = match_name_valid;
18067   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
18068   vec_free (match_name);
18069   /* send it... */
18070   S (mp);
18071
18072   /* Use a control ping for synchronization */
18073   MPING (CONTROL_PING, mp_ping);
18074   S (mp_ping);
18075
18076   /* Wait for a reply... */
18077   W (ret);
18078   return ret;
18079 }
18080
18081 static int
18082 api_policer_classify_set_interface (vat_main_t * vam)
18083 {
18084   unformat_input_t *i = vam->input;
18085   vl_api_policer_classify_set_interface_t *mp;
18086   u32 sw_if_index;
18087   int sw_if_index_set;
18088   u32 ip4_table_index = ~0;
18089   u32 ip6_table_index = ~0;
18090   u32 l2_table_index = ~0;
18091   u8 is_add = 1;
18092   int ret;
18093
18094   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18095     {
18096       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18097         sw_if_index_set = 1;
18098       else if (unformat (i, "sw_if_index %d", &sw_if_index))
18099         sw_if_index_set = 1;
18100       else if (unformat (i, "del"))
18101         is_add = 0;
18102       else if (unformat (i, "ip4-table %d", &ip4_table_index))
18103         ;
18104       else if (unformat (i, "ip6-table %d", &ip6_table_index))
18105         ;
18106       else if (unformat (i, "l2-table %d", &l2_table_index))
18107         ;
18108       else
18109         {
18110           clib_warning ("parse error '%U'", format_unformat_error, i);
18111           return -99;
18112         }
18113     }
18114
18115   if (sw_if_index_set == 0)
18116     {
18117       errmsg ("missing interface name or sw_if_index");
18118       return -99;
18119     }
18120
18121   M (POLICER_CLASSIFY_SET_INTERFACE, mp);
18122
18123   mp->sw_if_index = ntohl (sw_if_index);
18124   mp->ip4_table_index = ntohl (ip4_table_index);
18125   mp->ip6_table_index = ntohl (ip6_table_index);
18126   mp->l2_table_index = ntohl (l2_table_index);
18127   mp->is_add = is_add;
18128
18129   S (mp);
18130   W (ret);
18131   return ret;
18132 }
18133
18134 static int
18135 api_policer_classify_dump (vat_main_t * vam)
18136 {
18137   unformat_input_t *i = vam->input;
18138   vl_api_policer_classify_dump_t *mp;
18139   vl_api_control_ping_t *mp_ping;
18140   u8 type = POLICER_CLASSIFY_N_TABLES;
18141   int ret;
18142
18143   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
18144     ;
18145   else
18146     {
18147       errmsg ("classify table type must be specified");
18148       return -99;
18149     }
18150
18151   if (!vam->json_output)
18152     {
18153       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
18154     }
18155
18156   M (POLICER_CLASSIFY_DUMP, mp);
18157   mp->type = type;
18158   /* send it... */
18159   S (mp);
18160
18161   /* Use a control ping for synchronization */
18162   MPING (CONTROL_PING, mp_ping);
18163   S (mp_ping);
18164
18165   /* Wait for a reply... */
18166   W (ret);
18167   return ret;
18168 }
18169
18170 static int
18171 api_netmap_create (vat_main_t * vam)
18172 {
18173   unformat_input_t *i = vam->input;
18174   vl_api_netmap_create_t *mp;
18175   u8 *if_name = 0;
18176   u8 hw_addr[6];
18177   u8 random_hw_addr = 1;
18178   u8 is_pipe = 0;
18179   u8 is_master = 0;
18180   int ret;
18181
18182   clib_memset (hw_addr, 0, sizeof (hw_addr));
18183
18184   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18185     {
18186       if (unformat (i, "name %s", &if_name))
18187         vec_add1 (if_name, 0);
18188       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
18189         random_hw_addr = 0;
18190       else if (unformat (i, "pipe"))
18191         is_pipe = 1;
18192       else if (unformat (i, "master"))
18193         is_master = 1;
18194       else if (unformat (i, "slave"))
18195         is_master = 0;
18196       else
18197         break;
18198     }
18199
18200   if (!vec_len (if_name))
18201     {
18202       errmsg ("interface name must be specified");
18203       return -99;
18204     }
18205
18206   if (vec_len (if_name) > 64)
18207     {
18208       errmsg ("interface name too long");
18209       return -99;
18210     }
18211
18212   M (NETMAP_CREATE, mp);
18213
18214   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
18215   clib_memcpy (mp->hw_addr, hw_addr, 6);
18216   mp->use_random_hw_addr = random_hw_addr;
18217   mp->is_pipe = is_pipe;
18218   mp->is_master = is_master;
18219   vec_free (if_name);
18220
18221   S (mp);
18222   W (ret);
18223   return ret;
18224 }
18225
18226 static int
18227 api_netmap_delete (vat_main_t * vam)
18228 {
18229   unformat_input_t *i = vam->input;
18230   vl_api_netmap_delete_t *mp;
18231   u8 *if_name = 0;
18232   int ret;
18233
18234   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18235     {
18236       if (unformat (i, "name %s", &if_name))
18237         vec_add1 (if_name, 0);
18238       else
18239         break;
18240     }
18241
18242   if (!vec_len (if_name))
18243     {
18244       errmsg ("interface name must be specified");
18245       return -99;
18246     }
18247
18248   if (vec_len (if_name) > 64)
18249     {
18250       errmsg ("interface name too long");
18251       return -99;
18252     }
18253
18254   M (NETMAP_DELETE, mp);
18255
18256   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
18257   vec_free (if_name);
18258
18259   S (mp);
18260   W (ret);
18261   return ret;
18262 }
18263
18264 static u8 *
18265 format_fib_api_path_nh_proto (u8 * s, va_list * args)
18266 {
18267   vl_api_fib_path_nh_proto_t proto =
18268     va_arg (*args, vl_api_fib_path_nh_proto_t);
18269
18270   switch (proto)
18271     {
18272     case FIB_API_PATH_NH_PROTO_IP4:
18273       s = format (s, "ip4");
18274       break;
18275     case FIB_API_PATH_NH_PROTO_IP6:
18276       s = format (s, "ip6");
18277       break;
18278     case FIB_API_PATH_NH_PROTO_MPLS:
18279       s = format (s, "mpls");
18280       break;
18281     case FIB_API_PATH_NH_PROTO_BIER:
18282       s = format (s, "bier");
18283       break;
18284     case FIB_API_PATH_NH_PROTO_ETHERNET:
18285       s = format (s, "ethernet");
18286       break;
18287     }
18288
18289   return (s);
18290 }
18291
18292 static u8 *
18293 format_vl_api_ip_address_union (u8 * s, va_list * args)
18294 {
18295   vl_api_address_family_t af = va_arg (*args, vl_api_address_family_t);
18296   const vl_api_address_union_t *u = va_arg (*args, vl_api_address_union_t *);
18297
18298   switch (af)
18299     {
18300     case ADDRESS_IP4:
18301       s = format (s, "%U", format_ip4_address, u->ip4);
18302       break;
18303     case ADDRESS_IP6:
18304       s = format (s, "%U", format_ip6_address, u->ip6);
18305       break;
18306     }
18307   return (s);
18308 }
18309
18310 static u8 *
18311 format_vl_api_fib_path_type (u8 * s, va_list * args)
18312 {
18313   vl_api_fib_path_type_t t = va_arg (*args, vl_api_fib_path_type_t);
18314
18315   switch (t)
18316     {
18317     case FIB_API_PATH_TYPE_NORMAL:
18318       s = format (s, "normal");
18319       break;
18320     case FIB_API_PATH_TYPE_LOCAL:
18321       s = format (s, "local");
18322       break;
18323     case FIB_API_PATH_TYPE_DROP:
18324       s = format (s, "drop");
18325       break;
18326     case FIB_API_PATH_TYPE_UDP_ENCAP:
18327       s = format (s, "udp-encap");
18328       break;
18329     case FIB_API_PATH_TYPE_BIER_IMP:
18330       s = format (s, "bier-imp");
18331       break;
18332     case FIB_API_PATH_TYPE_ICMP_UNREACH:
18333       s = format (s, "unreach");
18334       break;
18335     case FIB_API_PATH_TYPE_ICMP_PROHIBIT:
18336       s = format (s, "prohibit");
18337       break;
18338     case FIB_API_PATH_TYPE_SOURCE_LOOKUP:
18339       s = format (s, "src-lookup");
18340       break;
18341     case FIB_API_PATH_TYPE_DVR:
18342       s = format (s, "dvr");
18343       break;
18344     case FIB_API_PATH_TYPE_INTERFACE_RX:
18345       s = format (s, "interface-rx");
18346       break;
18347     case FIB_API_PATH_TYPE_CLASSIFY:
18348       s = format (s, "classify");
18349       break;
18350     }
18351
18352   return (s);
18353 }
18354
18355 static void
18356 vl_api_fib_path_print (vat_main_t * vam, vl_api_fib_path_t * fp)
18357 {
18358   print (vam->ofp,
18359          "  weight %d, sw_if_index %d, type %U, afi %U, next_hop %U",
18360          ntohl (fp->weight), ntohl (fp->sw_if_index),
18361          format_vl_api_fib_path_type, fp->type,
18362          format_fib_api_path_nh_proto, fp->proto,
18363          format_vl_api_ip_address_union, &fp->nh.address);
18364 }
18365
18366 static void
18367 vl_api_mpls_fib_path_json_print (vat_json_node_t * node,
18368                                  vl_api_fib_path_t * fp)
18369 {
18370   struct in_addr ip4;
18371   struct in6_addr ip6;
18372
18373   vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
18374   vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
18375   vat_json_object_add_uint (node, "type", fp->type);
18376   vat_json_object_add_uint (node, "next_hop_proto", fp->proto);
18377   if (fp->proto == FIB_API_PATH_NH_PROTO_IP4)
18378     {
18379       clib_memcpy (&ip4, &fp->nh.address.ip4, sizeof (ip4));
18380       vat_json_object_add_ip4 (node, "next_hop", ip4);
18381     }
18382   else if (fp->proto == FIB_API_PATH_NH_PROTO_IP4)
18383     {
18384       clib_memcpy (&ip6, &fp->nh.address.ip6, sizeof (ip6));
18385       vat_json_object_add_ip6 (node, "next_hop", ip6);
18386     }
18387 }
18388
18389 static void
18390 vl_api_mpls_tunnel_details_t_handler (vl_api_mpls_tunnel_details_t * mp)
18391 {
18392   vat_main_t *vam = &vat_main;
18393   int count = ntohl (mp->mt_tunnel.mt_n_paths);
18394   vl_api_fib_path_t *fp;
18395   i32 i;
18396
18397   print (vam->ofp, "sw_if_index %d via:",
18398          ntohl (mp->mt_tunnel.mt_sw_if_index));
18399   fp = mp->mt_tunnel.mt_paths;
18400   for (i = 0; i < count; i++)
18401     {
18402       vl_api_fib_path_print (vam, fp);
18403       fp++;
18404     }
18405
18406   print (vam->ofp, "");
18407 }
18408
18409 #define vl_api_mpls_tunnel_details_t_endian vl_noop_handler
18410 #define vl_api_mpls_tunnel_details_t_print vl_noop_handler
18411
18412 static void
18413 vl_api_mpls_tunnel_details_t_handler_json (vl_api_mpls_tunnel_details_t * mp)
18414 {
18415   vat_main_t *vam = &vat_main;
18416   vat_json_node_t *node = NULL;
18417   int count = ntohl (mp->mt_tunnel.mt_n_paths);
18418   vl_api_fib_path_t *fp;
18419   i32 i;
18420
18421   if (VAT_JSON_ARRAY != vam->json_tree.type)
18422     {
18423       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18424       vat_json_init_array (&vam->json_tree);
18425     }
18426   node = vat_json_array_add (&vam->json_tree);
18427
18428   vat_json_init_object (node);
18429   vat_json_object_add_uint (node, "sw_if_index",
18430                             ntohl (mp->mt_tunnel.mt_sw_if_index));
18431
18432   vat_json_object_add_uint (node, "l2_only", mp->mt_tunnel.mt_l2_only);
18433
18434   fp = mp->mt_tunnel.mt_paths;
18435   for (i = 0; i < count; i++)
18436     {
18437       vl_api_mpls_fib_path_json_print (node, fp);
18438       fp++;
18439     }
18440 }
18441
18442 static int
18443 api_mpls_tunnel_dump (vat_main_t * vam)
18444 {
18445   vl_api_mpls_tunnel_dump_t *mp;
18446   vl_api_control_ping_t *mp_ping;
18447   int ret;
18448
18449   M (MPLS_TUNNEL_DUMP, mp);
18450
18451   S (mp);
18452
18453   /* Use a control ping for synchronization */
18454   MPING (CONTROL_PING, mp_ping);
18455   S (mp_ping);
18456
18457   W (ret);
18458   return ret;
18459 }
18460
18461 #define vl_api_mpls_table_details_t_endian vl_noop_handler
18462 #define vl_api_mpls_table_details_t_print vl_noop_handler
18463
18464
18465 static void
18466 vl_api_mpls_table_details_t_handler (vl_api_mpls_table_details_t * mp)
18467 {
18468   vat_main_t *vam = &vat_main;
18469
18470   print (vam->ofp, "table-id %d,", ntohl (mp->mt_table.mt_table_id));
18471 }
18472
18473 static void vl_api_mpls_table_details_t_handler_json
18474   (vl_api_mpls_table_details_t * mp)
18475 {
18476   vat_main_t *vam = &vat_main;
18477   vat_json_node_t *node = NULL;
18478
18479   if (VAT_JSON_ARRAY != vam->json_tree.type)
18480     {
18481       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18482       vat_json_init_array (&vam->json_tree);
18483     }
18484   node = vat_json_array_add (&vam->json_tree);
18485
18486   vat_json_init_object (node);
18487   vat_json_object_add_uint (node, "table", ntohl (mp->mt_table.mt_table_id));
18488 }
18489
18490 static int
18491 api_mpls_table_dump (vat_main_t * vam)
18492 {
18493   vl_api_mpls_table_dump_t *mp;
18494   vl_api_control_ping_t *mp_ping;
18495   int ret;
18496
18497   M (MPLS_TABLE_DUMP, mp);
18498   S (mp);
18499
18500   /* Use a control ping for synchronization */
18501   MPING (CONTROL_PING, mp_ping);
18502   S (mp_ping);
18503
18504   W (ret);
18505   return ret;
18506 }
18507
18508 #define vl_api_mpls_route_details_t_endian vl_noop_handler
18509 #define vl_api_mpls_route_details_t_print vl_noop_handler
18510
18511 static void
18512 vl_api_mpls_route_details_t_handler (vl_api_mpls_route_details_t * mp)
18513 {
18514   vat_main_t *vam = &vat_main;
18515   int count = (int) clib_net_to_host_u32 (mp->mr_route.mr_n_paths);
18516   vl_api_fib_path_t *fp;
18517   int i;
18518
18519   print (vam->ofp,
18520          "table-id %d, label %u, ess_bit %u",
18521          ntohl (mp->mr_route.mr_table_id),
18522          ntohl (mp->mr_route.mr_label), mp->mr_route.mr_eos);
18523   fp = mp->mr_route.mr_paths;
18524   for (i = 0; i < count; i++)
18525     {
18526       vl_api_fib_path_print (vam, fp);
18527       fp++;
18528     }
18529 }
18530
18531 static void vl_api_mpls_route_details_t_handler_json
18532   (vl_api_mpls_route_details_t * mp)
18533 {
18534   vat_main_t *vam = &vat_main;
18535   int count = (int) clib_host_to_net_u32 (mp->mr_route.mr_n_paths);
18536   vat_json_node_t *node = NULL;
18537   vl_api_fib_path_t *fp;
18538   int i;
18539
18540   if (VAT_JSON_ARRAY != vam->json_tree.type)
18541     {
18542       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18543       vat_json_init_array (&vam->json_tree);
18544     }
18545   node = vat_json_array_add (&vam->json_tree);
18546
18547   vat_json_init_object (node);
18548   vat_json_object_add_uint (node, "table", ntohl (mp->mr_route.mr_table_id));
18549   vat_json_object_add_uint (node, "s_bit", mp->mr_route.mr_eos);
18550   vat_json_object_add_uint (node, "label", ntohl (mp->mr_route.mr_label));
18551   vat_json_object_add_uint (node, "path_count", count);
18552   fp = mp->mr_route.mr_paths;
18553   for (i = 0; i < count; i++)
18554     {
18555       vl_api_mpls_fib_path_json_print (node, fp);
18556       fp++;
18557     }
18558 }
18559
18560 static int
18561 api_mpls_route_dump (vat_main_t * vam)
18562 {
18563   unformat_input_t *input = vam->input;
18564   vl_api_mpls_route_dump_t *mp;
18565   vl_api_control_ping_t *mp_ping;
18566   u32 table_id;
18567   int ret;
18568
18569   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18570     {
18571       if (unformat (input, "table_id %d", &table_id))
18572         ;
18573       else
18574         break;
18575     }
18576   if (table_id == ~0)
18577     {
18578       errmsg ("missing table id");
18579       return -99;
18580     }
18581
18582   M (MPLS_ROUTE_DUMP, mp);
18583
18584   mp->table.mt_table_id = ntohl (table_id);
18585   S (mp);
18586
18587   /* Use a control ping for synchronization */
18588   MPING (CONTROL_PING, mp_ping);
18589   S (mp_ping);
18590
18591   W (ret);
18592   return ret;
18593 }
18594
18595 #define vl_api_ip_table_details_t_endian vl_noop_handler
18596 #define vl_api_ip_table_details_t_print vl_noop_handler
18597
18598 static void
18599 vl_api_ip_table_details_t_handler (vl_api_ip_table_details_t * mp)
18600 {
18601   vat_main_t *vam = &vat_main;
18602
18603   print (vam->ofp,
18604          "%s; table-id %d, prefix %U/%d",
18605          mp->table.name, ntohl (mp->table.table_id));
18606 }
18607
18608
18609 static void vl_api_ip_table_details_t_handler_json
18610   (vl_api_ip_table_details_t * mp)
18611 {
18612   vat_main_t *vam = &vat_main;
18613   vat_json_node_t *node = NULL;
18614
18615   if (VAT_JSON_ARRAY != vam->json_tree.type)
18616     {
18617       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18618       vat_json_init_array (&vam->json_tree);
18619     }
18620   node = vat_json_array_add (&vam->json_tree);
18621
18622   vat_json_init_object (node);
18623   vat_json_object_add_uint (node, "table", ntohl (mp->table.table_id));
18624 }
18625
18626 static int
18627 api_ip_table_dump (vat_main_t * vam)
18628 {
18629   vl_api_ip_table_dump_t *mp;
18630   vl_api_control_ping_t *mp_ping;
18631   int ret;
18632
18633   M (IP_TABLE_DUMP, mp);
18634   S (mp);
18635
18636   /* Use a control ping for synchronization */
18637   MPING (CONTROL_PING, mp_ping);
18638   S (mp_ping);
18639
18640   W (ret);
18641   return ret;
18642 }
18643
18644 static int
18645 api_ip_mtable_dump (vat_main_t * vam)
18646 {
18647   vl_api_ip_mtable_dump_t *mp;
18648   vl_api_control_ping_t *mp_ping;
18649   int ret;
18650
18651   M (IP_MTABLE_DUMP, mp);
18652   S (mp);
18653
18654   /* Use a control ping for synchronization */
18655   MPING (CONTROL_PING, mp_ping);
18656   S (mp_ping);
18657
18658   W (ret);
18659   return ret;
18660 }
18661
18662 static int
18663 api_ip_mroute_dump (vat_main_t * vam)
18664 {
18665   unformat_input_t *input = vam->input;
18666   vl_api_control_ping_t *mp_ping;
18667   vl_api_ip_mroute_dump_t *mp;
18668   int ret, is_ip6;
18669   u32 table_id;
18670
18671   is_ip6 = 0;
18672   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18673     {
18674       if (unformat (input, "table_id %d", &table_id))
18675         ;
18676       else if (unformat (input, "ip6"))
18677         is_ip6 = 1;
18678       else if (unformat (input, "ip4"))
18679         is_ip6 = 0;
18680       else
18681         break;
18682     }
18683   if (table_id == ~0)
18684     {
18685       errmsg ("missing table id");
18686       return -99;
18687     }
18688
18689   M (IP_MROUTE_DUMP, mp);
18690   mp->table.table_id = table_id;
18691   mp->table.is_ip6 = is_ip6;
18692   S (mp);
18693
18694   /* Use a control ping for synchronization */
18695   MPING (CONTROL_PING, mp_ping);
18696   S (mp_ping);
18697
18698   W (ret);
18699   return ret;
18700 }
18701
18702 static void vl_api_ip_neighbor_details_t_handler
18703   (vl_api_ip_neighbor_details_t * mp)
18704 {
18705   vat_main_t *vam = &vat_main;
18706
18707   print (vam->ofp, "%c %U %U",
18708          (ntohl (mp->neighbor.flags) & IP_NEIGHBOR_FLAG_STATIC) ? 'S' : 'D',
18709          format_vl_api_mac_address, &mp->neighbor.mac_address,
18710          format_vl_api_address, &mp->neighbor.ip_address);
18711 }
18712
18713 static void vl_api_ip_neighbor_details_t_handler_json
18714   (vl_api_ip_neighbor_details_t * mp)
18715 {
18716
18717   vat_main_t *vam = &vat_main;
18718   vat_json_node_t *node;
18719
18720   if (VAT_JSON_ARRAY != vam->json_tree.type)
18721     {
18722       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18723       vat_json_init_array (&vam->json_tree);
18724     }
18725   node = vat_json_array_add (&vam->json_tree);
18726
18727   vat_json_init_object (node);
18728   vat_json_object_add_string_copy
18729     (node, "flag",
18730      ((ntohl (mp->neighbor.flags) & IP_NEIGHBOR_FLAG_STATIC) ?
18731       (u8 *) "static" : (u8 *) "dynamic"));
18732
18733   vat_json_object_add_string_copy (node, "link_layer",
18734                                    format (0, "%U", format_vl_api_mac_address,
18735                                            &mp->neighbor.mac_address));
18736   vat_json_object_add_address (node, "ip", &mp->neighbor.ip_address);
18737 }
18738
18739 static int
18740 api_ip_neighbor_dump (vat_main_t * vam)
18741 {
18742   unformat_input_t *i = vam->input;
18743   vl_api_ip_neighbor_dump_t *mp;
18744   vl_api_control_ping_t *mp_ping;
18745   u8 is_ipv6 = 0;
18746   u32 sw_if_index = ~0;
18747   int ret;
18748
18749   /* Parse args required to build the message */
18750   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18751     {
18752       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18753         ;
18754       else if (unformat (i, "sw_if_index %d", &sw_if_index))
18755         ;
18756       else if (unformat (i, "ip6"))
18757         is_ipv6 = 1;
18758       else
18759         break;
18760     }
18761
18762   if (sw_if_index == ~0)
18763     {
18764       errmsg ("missing interface name or sw_if_index");
18765       return -99;
18766     }
18767
18768   M (IP_NEIGHBOR_DUMP, mp);
18769   mp->is_ipv6 = (u8) is_ipv6;
18770   mp->sw_if_index = ntohl (sw_if_index);
18771   S (mp);
18772
18773   /* Use a control ping for synchronization */
18774   MPING (CONTROL_PING, mp_ping);
18775   S (mp_ping);
18776
18777   W (ret);
18778   return ret;
18779 }
18780
18781 #define vl_api_ip_route_details_t_endian vl_noop_handler
18782 #define vl_api_ip_route_details_t_print vl_noop_handler
18783
18784 static void
18785 vl_api_ip_route_details_t_handler (vl_api_ip_route_details_t * mp)
18786 {
18787   vat_main_t *vam = &vat_main;
18788   u8 count = mp->route.n_paths;
18789   vl_api_fib_path_t *fp;
18790   int i;
18791
18792   print (vam->ofp,
18793          "table-id %d, prefix %U/%d",
18794          ntohl (mp->route.table_id),
18795          format_ip46_address, mp->route.prefix.address, mp->route.prefix.len);
18796   for (i = 0; i < count; i++)
18797     {
18798       fp = &mp->route.paths[i];
18799
18800       vl_api_fib_path_print (vam, fp);
18801       fp++;
18802     }
18803 }
18804
18805 static void vl_api_ip_route_details_t_handler_json
18806   (vl_api_ip_route_details_t * mp)
18807 {
18808   vat_main_t *vam = &vat_main;
18809   u8 count = mp->route.n_paths;
18810   vat_json_node_t *node = NULL;
18811   struct in_addr ip4;
18812   struct in6_addr ip6;
18813   vl_api_fib_path_t *fp;
18814   int i;
18815
18816   if (VAT_JSON_ARRAY != vam->json_tree.type)
18817     {
18818       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18819       vat_json_init_array (&vam->json_tree);
18820     }
18821   node = vat_json_array_add (&vam->json_tree);
18822
18823   vat_json_init_object (node);
18824   vat_json_object_add_uint (node, "table", ntohl (mp->route.table_id));
18825   if (ADDRESS_IP6 == mp->route.prefix.address.af)
18826     {
18827       clib_memcpy (&ip6, &mp->route.prefix.address.un.ip6, sizeof (ip6));
18828       vat_json_object_add_ip6 (node, "prefix", ip6);
18829     }
18830   else
18831     {
18832       clib_memcpy (&ip4, &mp->route.prefix.address.un.ip4, sizeof (ip4));
18833       vat_json_object_add_ip4 (node, "prefix", ip4);
18834     }
18835   vat_json_object_add_uint (node, "mask_length", mp->route.prefix.len);
18836   vat_json_object_add_uint (node, "path_count", count);
18837   for (i = 0; i < count; i++)
18838     {
18839       fp = &mp->route.paths[i];
18840       vl_api_mpls_fib_path_json_print (node, fp);
18841     }
18842 }
18843
18844 static int
18845 api_ip_route_dump (vat_main_t * vam)
18846 {
18847   unformat_input_t *input = vam->input;
18848   vl_api_ip_route_dump_t *mp;
18849   vl_api_control_ping_t *mp_ping;
18850   u32 table_id;
18851   u8 is_ip6;
18852   int ret;
18853
18854   is_ip6 = 0;
18855   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18856     {
18857       if (unformat (input, "table_id %d", &table_id))
18858         ;
18859       else if (unformat (input, "ip6"))
18860         is_ip6 = 1;
18861       else if (unformat (input, "ip4"))
18862         is_ip6 = 0;
18863       else
18864         break;
18865     }
18866   if (table_id == ~0)
18867     {
18868       errmsg ("missing table id");
18869       return -99;
18870     }
18871
18872   M (IP_ROUTE_DUMP, mp);
18873
18874   mp->table.table_id = table_id;
18875   mp->table.is_ip6 = is_ip6;
18876
18877   S (mp);
18878
18879   /* Use a control ping for synchronization */
18880   MPING (CONTROL_PING, mp_ping);
18881   S (mp_ping);
18882
18883   W (ret);
18884   return ret;
18885 }
18886
18887 int
18888 api_classify_table_ids (vat_main_t * vam)
18889 {
18890   vl_api_classify_table_ids_t *mp;
18891   int ret;
18892
18893   /* Construct the API message */
18894   M (CLASSIFY_TABLE_IDS, mp);
18895   mp->context = 0;
18896
18897   S (mp);
18898   W (ret);
18899   return ret;
18900 }
18901
18902 int
18903 api_classify_table_by_interface (vat_main_t * vam)
18904 {
18905   unformat_input_t *input = vam->input;
18906   vl_api_classify_table_by_interface_t *mp;
18907
18908   u32 sw_if_index = ~0;
18909   int ret;
18910   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18911     {
18912       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18913         ;
18914       else if (unformat (input, "sw_if_index %d", &sw_if_index))
18915         ;
18916       else
18917         break;
18918     }
18919   if (sw_if_index == ~0)
18920     {
18921       errmsg ("missing interface name or sw_if_index");
18922       return -99;
18923     }
18924
18925   /* Construct the API message */
18926   M (CLASSIFY_TABLE_BY_INTERFACE, mp);
18927   mp->context = 0;
18928   mp->sw_if_index = ntohl (sw_if_index);
18929
18930   S (mp);
18931   W (ret);
18932   return ret;
18933 }
18934
18935 int
18936 api_classify_table_info (vat_main_t * vam)
18937 {
18938   unformat_input_t *input = vam->input;
18939   vl_api_classify_table_info_t *mp;
18940
18941   u32 table_id = ~0;
18942   int ret;
18943   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18944     {
18945       if (unformat (input, "table_id %d", &table_id))
18946         ;
18947       else
18948         break;
18949     }
18950   if (table_id == ~0)
18951     {
18952       errmsg ("missing table id");
18953       return -99;
18954     }
18955
18956   /* Construct the API message */
18957   M (CLASSIFY_TABLE_INFO, mp);
18958   mp->context = 0;
18959   mp->table_id = ntohl (table_id);
18960
18961   S (mp);
18962   W (ret);
18963   return ret;
18964 }
18965
18966 int
18967 api_classify_session_dump (vat_main_t * vam)
18968 {
18969   unformat_input_t *input = vam->input;
18970   vl_api_classify_session_dump_t *mp;
18971   vl_api_control_ping_t *mp_ping;
18972
18973   u32 table_id = ~0;
18974   int ret;
18975   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18976     {
18977       if (unformat (input, "table_id %d", &table_id))
18978         ;
18979       else
18980         break;
18981     }
18982   if (table_id == ~0)
18983     {
18984       errmsg ("missing table id");
18985       return -99;
18986     }
18987
18988   /* Construct the API message */
18989   M (CLASSIFY_SESSION_DUMP, mp);
18990   mp->context = 0;
18991   mp->table_id = ntohl (table_id);
18992   S (mp);
18993
18994   /* Use a control ping for synchronization */
18995   MPING (CONTROL_PING, mp_ping);
18996   S (mp_ping);
18997
18998   W (ret);
18999   return ret;
19000 }
19001
19002 static void
19003 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
19004 {
19005   vat_main_t *vam = &vat_main;
19006
19007   print (vam->ofp, "collector_address %U, collector_port %d, "
19008          "src_address %U, vrf_id %d, path_mtu %u, "
19009          "template_interval %u, udp_checksum %d",
19010          format_ip4_address, mp->collector_address,
19011          ntohs (mp->collector_port),
19012          format_ip4_address, mp->src_address,
19013          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
19014          ntohl (mp->template_interval), mp->udp_checksum);
19015
19016   vam->retval = 0;
19017   vam->result_ready = 1;
19018 }
19019
19020 static void
19021   vl_api_ipfix_exporter_details_t_handler_json
19022   (vl_api_ipfix_exporter_details_t * mp)
19023 {
19024   vat_main_t *vam = &vat_main;
19025   vat_json_node_t node;
19026   struct in_addr collector_address;
19027   struct in_addr src_address;
19028
19029   vat_json_init_object (&node);
19030   clib_memcpy (&collector_address, &mp->collector_address,
19031                sizeof (collector_address));
19032   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
19033   vat_json_object_add_uint (&node, "collector_port",
19034                             ntohs (mp->collector_port));
19035   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
19036   vat_json_object_add_ip4 (&node, "src_address", src_address);
19037   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
19038   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
19039   vat_json_object_add_uint (&node, "template_interval",
19040                             ntohl (mp->template_interval));
19041   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
19042
19043   vat_json_print (vam->ofp, &node);
19044   vat_json_free (&node);
19045   vam->retval = 0;
19046   vam->result_ready = 1;
19047 }
19048
19049 int
19050 api_ipfix_exporter_dump (vat_main_t * vam)
19051 {
19052   vl_api_ipfix_exporter_dump_t *mp;
19053   int ret;
19054
19055   /* Construct the API message */
19056   M (IPFIX_EXPORTER_DUMP, mp);
19057   mp->context = 0;
19058
19059   S (mp);
19060   W (ret);
19061   return ret;
19062 }
19063
19064 static int
19065 api_ipfix_classify_stream_dump (vat_main_t * vam)
19066 {
19067   vl_api_ipfix_classify_stream_dump_t *mp;
19068   int ret;
19069
19070   /* Construct the API message */
19071   M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
19072   mp->context = 0;
19073
19074   S (mp);
19075   W (ret);
19076   return ret;
19077   /* NOTREACHED */
19078   return 0;
19079 }
19080
19081 static void
19082   vl_api_ipfix_classify_stream_details_t_handler
19083   (vl_api_ipfix_classify_stream_details_t * mp)
19084 {
19085   vat_main_t *vam = &vat_main;
19086   print (vam->ofp, "domain_id %d, src_port %d",
19087          ntohl (mp->domain_id), ntohs (mp->src_port));
19088   vam->retval = 0;
19089   vam->result_ready = 1;
19090 }
19091
19092 static void
19093   vl_api_ipfix_classify_stream_details_t_handler_json
19094   (vl_api_ipfix_classify_stream_details_t * mp)
19095 {
19096   vat_main_t *vam = &vat_main;
19097   vat_json_node_t node;
19098
19099   vat_json_init_object (&node);
19100   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
19101   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
19102
19103   vat_json_print (vam->ofp, &node);
19104   vat_json_free (&node);
19105   vam->retval = 0;
19106   vam->result_ready = 1;
19107 }
19108
19109 static int
19110 api_ipfix_classify_table_dump (vat_main_t * vam)
19111 {
19112   vl_api_ipfix_classify_table_dump_t *mp;
19113   vl_api_control_ping_t *mp_ping;
19114   int ret;
19115
19116   if (!vam->json_output)
19117     {
19118       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
19119              "transport_protocol");
19120     }
19121
19122   /* Construct the API message */
19123   M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
19124
19125   /* send it... */
19126   S (mp);
19127
19128   /* Use a control ping for synchronization */
19129   MPING (CONTROL_PING, mp_ping);
19130   S (mp_ping);
19131
19132   W (ret);
19133   return ret;
19134 }
19135
19136 static void
19137   vl_api_ipfix_classify_table_details_t_handler
19138   (vl_api_ipfix_classify_table_details_t * mp)
19139 {
19140   vat_main_t *vam = &vat_main;
19141   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
19142          mp->transport_protocol);
19143 }
19144
19145 static void
19146   vl_api_ipfix_classify_table_details_t_handler_json
19147   (vl_api_ipfix_classify_table_details_t * mp)
19148 {
19149   vat_json_node_t *node = NULL;
19150   vat_main_t *vam = &vat_main;
19151
19152   if (VAT_JSON_ARRAY != vam->json_tree.type)
19153     {
19154       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19155       vat_json_init_array (&vam->json_tree);
19156     }
19157
19158   node = vat_json_array_add (&vam->json_tree);
19159   vat_json_init_object (node);
19160
19161   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
19162   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
19163   vat_json_object_add_uint (node, "transport_protocol",
19164                             mp->transport_protocol);
19165 }
19166
19167 static int
19168 api_sw_interface_span_enable_disable (vat_main_t * vam)
19169 {
19170   unformat_input_t *i = vam->input;
19171   vl_api_sw_interface_span_enable_disable_t *mp;
19172   u32 src_sw_if_index = ~0;
19173   u32 dst_sw_if_index = ~0;
19174   u8 state = 3;
19175   int ret;
19176   u8 is_l2 = 0;
19177
19178   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19179     {
19180       if (unformat
19181           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
19182         ;
19183       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
19184         ;
19185       else
19186         if (unformat
19187             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
19188         ;
19189       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
19190         ;
19191       else if (unformat (i, "disable"))
19192         state = 0;
19193       else if (unformat (i, "rx"))
19194         state = 1;
19195       else if (unformat (i, "tx"))
19196         state = 2;
19197       else if (unformat (i, "both"))
19198         state = 3;
19199       else if (unformat (i, "l2"))
19200         is_l2 = 1;
19201       else
19202         break;
19203     }
19204
19205   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
19206
19207   mp->sw_if_index_from = htonl (src_sw_if_index);
19208   mp->sw_if_index_to = htonl (dst_sw_if_index);
19209   mp->state = state;
19210   mp->is_l2 = is_l2;
19211
19212   S (mp);
19213   W (ret);
19214   return ret;
19215 }
19216
19217 static void
19218 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
19219                                             * mp)
19220 {
19221   vat_main_t *vam = &vat_main;
19222   u8 *sw_if_from_name = 0;
19223   u8 *sw_if_to_name = 0;
19224   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
19225   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
19226   char *states[] = { "none", "rx", "tx", "both" };
19227   hash_pair_t *p;
19228
19229   /* *INDENT-OFF* */
19230   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
19231   ({
19232     if ((u32) p->value[0] == sw_if_index_from)
19233       {
19234         sw_if_from_name = (u8 *)(p->key);
19235         if (sw_if_to_name)
19236           break;
19237       }
19238     if ((u32) p->value[0] == sw_if_index_to)
19239       {
19240         sw_if_to_name = (u8 *)(p->key);
19241         if (sw_if_from_name)
19242           break;
19243       }
19244   }));
19245   /* *INDENT-ON* */
19246   print (vam->ofp, "%20s => %20s (%s) %s",
19247          sw_if_from_name, sw_if_to_name, states[mp->state],
19248          mp->is_l2 ? "l2" : "device");
19249 }
19250
19251 static void
19252   vl_api_sw_interface_span_details_t_handler_json
19253   (vl_api_sw_interface_span_details_t * mp)
19254 {
19255   vat_main_t *vam = &vat_main;
19256   vat_json_node_t *node = NULL;
19257   u8 *sw_if_from_name = 0;
19258   u8 *sw_if_to_name = 0;
19259   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
19260   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
19261   hash_pair_t *p;
19262
19263   /* *INDENT-OFF* */
19264   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
19265   ({
19266     if ((u32) p->value[0] == sw_if_index_from)
19267       {
19268         sw_if_from_name = (u8 *)(p->key);
19269         if (sw_if_to_name)
19270           break;
19271       }
19272     if ((u32) p->value[0] == sw_if_index_to)
19273       {
19274         sw_if_to_name = (u8 *)(p->key);
19275         if (sw_if_from_name)
19276           break;
19277       }
19278   }));
19279   /* *INDENT-ON* */
19280
19281   if (VAT_JSON_ARRAY != vam->json_tree.type)
19282     {
19283       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19284       vat_json_init_array (&vam->json_tree);
19285     }
19286   node = vat_json_array_add (&vam->json_tree);
19287
19288   vat_json_init_object (node);
19289   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
19290   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
19291   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
19292   if (0 != sw_if_to_name)
19293     {
19294       vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
19295     }
19296   vat_json_object_add_uint (node, "state", mp->state);
19297   vat_json_object_add_uint (node, "is-l2", mp->is_l2);
19298 }
19299
19300 static int
19301 api_sw_interface_span_dump (vat_main_t * vam)
19302 {
19303   unformat_input_t *input = vam->input;
19304   vl_api_sw_interface_span_dump_t *mp;
19305   vl_api_control_ping_t *mp_ping;
19306   u8 is_l2 = 0;
19307   int ret;
19308
19309   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19310     {
19311       if (unformat (input, "l2"))
19312         is_l2 = 1;
19313       else
19314         break;
19315     }
19316
19317   M (SW_INTERFACE_SPAN_DUMP, mp);
19318   mp->is_l2 = is_l2;
19319   S (mp);
19320
19321   /* Use a control ping for synchronization */
19322   MPING (CONTROL_PING, mp_ping);
19323   S (mp_ping);
19324
19325   W (ret);
19326   return ret;
19327 }
19328
19329 int
19330 api_pg_create_interface (vat_main_t * vam)
19331 {
19332   unformat_input_t *input = vam->input;
19333   vl_api_pg_create_interface_t *mp;
19334
19335   u32 if_id = ~0, gso_size = 0;
19336   u8 gso_enabled = 0;
19337   int ret;
19338   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19339     {
19340       if (unformat (input, "if_id %d", &if_id))
19341         ;
19342       else if (unformat (input, "gso-enabled"))
19343         {
19344           gso_enabled = 1;
19345           if (unformat (input, "gso-size %u", &gso_size))
19346             ;
19347           else
19348             {
19349               errmsg ("missing gso-size");
19350               return -99;
19351             }
19352         }
19353       else
19354         break;
19355     }
19356   if (if_id == ~0)
19357     {
19358       errmsg ("missing pg interface index");
19359       return -99;
19360     }
19361
19362   /* Construct the API message */
19363   M (PG_CREATE_INTERFACE, mp);
19364   mp->context = 0;
19365   mp->interface_id = ntohl (if_id);
19366   mp->gso_enabled = gso_enabled;
19367
19368   S (mp);
19369   W (ret);
19370   return ret;
19371 }
19372
19373 int
19374 api_pg_capture (vat_main_t * vam)
19375 {
19376   unformat_input_t *input = vam->input;
19377   vl_api_pg_capture_t *mp;
19378
19379   u32 if_id = ~0;
19380   u8 enable = 1;
19381   u32 count = 1;
19382   u8 pcap_file_set = 0;
19383   u8 *pcap_file = 0;
19384   int ret;
19385   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19386     {
19387       if (unformat (input, "if_id %d", &if_id))
19388         ;
19389       else if (unformat (input, "pcap %s", &pcap_file))
19390         pcap_file_set = 1;
19391       else if (unformat (input, "count %d", &count))
19392         ;
19393       else if (unformat (input, "disable"))
19394         enable = 0;
19395       else
19396         break;
19397     }
19398   if (if_id == ~0)
19399     {
19400       errmsg ("missing pg interface index");
19401       return -99;
19402     }
19403   if (pcap_file_set > 0)
19404     {
19405       if (vec_len (pcap_file) > 255)
19406         {
19407           errmsg ("pcap file name is too long");
19408           return -99;
19409         }
19410     }
19411
19412   u32 name_len = vec_len (pcap_file);
19413   /* Construct the API message */
19414   M (PG_CAPTURE, mp);
19415   mp->context = 0;
19416   mp->interface_id = ntohl (if_id);
19417   mp->is_enabled = enable;
19418   mp->count = ntohl (count);
19419   mp->pcap_name_length = ntohl (name_len);
19420   if (pcap_file_set != 0)
19421     {
19422       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
19423     }
19424   vec_free (pcap_file);
19425
19426   S (mp);
19427   W (ret);
19428   return ret;
19429 }
19430
19431 int
19432 api_pg_enable_disable (vat_main_t * vam)
19433 {
19434   unformat_input_t *input = vam->input;
19435   vl_api_pg_enable_disable_t *mp;
19436
19437   u8 enable = 1;
19438   u8 stream_name_set = 0;
19439   u8 *stream_name = 0;
19440   int ret;
19441   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19442     {
19443       if (unformat (input, "stream %s", &stream_name))
19444         stream_name_set = 1;
19445       else if (unformat (input, "disable"))
19446         enable = 0;
19447       else
19448         break;
19449     }
19450
19451   if (stream_name_set > 0)
19452     {
19453       if (vec_len (stream_name) > 255)
19454         {
19455           errmsg ("stream name too long");
19456           return -99;
19457         }
19458     }
19459
19460   u32 name_len = vec_len (stream_name);
19461   /* Construct the API message */
19462   M (PG_ENABLE_DISABLE, mp);
19463   mp->context = 0;
19464   mp->is_enabled = enable;
19465   if (stream_name_set != 0)
19466     {
19467       mp->stream_name_length = ntohl (name_len);
19468       clib_memcpy (mp->stream_name, stream_name, name_len);
19469     }
19470   vec_free (stream_name);
19471
19472   S (mp);
19473   W (ret);
19474   return ret;
19475 }
19476
19477 int
19478 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
19479 {
19480   unformat_input_t *input = vam->input;
19481   vl_api_ip_source_and_port_range_check_add_del_t *mp;
19482
19483   u16 *low_ports = 0;
19484   u16 *high_ports = 0;
19485   u16 this_low;
19486   u16 this_hi;
19487   vl_api_prefix_t prefix;
19488   u32 tmp, tmp2;
19489   u8 prefix_set = 0;
19490   u32 vrf_id = ~0;
19491   u8 is_add = 1;
19492   int ret;
19493
19494   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19495     {
19496       if (unformat (input, "%U", unformat_vl_api_prefix, &prefix))
19497         prefix_set = 1;
19498       else if (unformat (input, "vrf %d", &vrf_id))
19499         ;
19500       else if (unformat (input, "del"))
19501         is_add = 0;
19502       else if (unformat (input, "port %d", &tmp))
19503         {
19504           if (tmp == 0 || tmp > 65535)
19505             {
19506               errmsg ("port %d out of range", tmp);
19507               return -99;
19508             }
19509           this_low = tmp;
19510           this_hi = this_low + 1;
19511           vec_add1 (low_ports, this_low);
19512           vec_add1 (high_ports, this_hi);
19513         }
19514       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
19515         {
19516           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
19517             {
19518               errmsg ("incorrect range parameters");
19519               return -99;
19520             }
19521           this_low = tmp;
19522           /* Note: in debug CLI +1 is added to high before
19523              passing to real fn that does "the work"
19524              (ip_source_and_port_range_check_add_del).
19525              This fn is a wrapper around the binary API fn a
19526              control plane will call, which expects this increment
19527              to have occurred. Hence letting the binary API control
19528              plane fn do the increment for consistency between VAT
19529              and other control planes.
19530            */
19531           this_hi = tmp2;
19532           vec_add1 (low_ports, this_low);
19533           vec_add1 (high_ports, this_hi);
19534         }
19535       else
19536         break;
19537     }
19538
19539   if (prefix_set == 0)
19540     {
19541       errmsg ("<address>/<mask> not specified");
19542       return -99;
19543     }
19544
19545   if (vrf_id == ~0)
19546     {
19547       errmsg ("VRF ID required, not specified");
19548       return -99;
19549     }
19550
19551   if (vrf_id == 0)
19552     {
19553       errmsg
19554         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
19555       return -99;
19556     }
19557
19558   if (vec_len (low_ports) == 0)
19559     {
19560       errmsg ("At least one port or port range required");
19561       return -99;
19562     }
19563
19564   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
19565
19566   mp->is_add = is_add;
19567
19568   clib_memcpy (&mp->prefix, &prefix, sizeof (prefix));
19569
19570   mp->number_of_ranges = vec_len (low_ports);
19571
19572   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
19573   vec_free (low_ports);
19574
19575   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
19576   vec_free (high_ports);
19577
19578   mp->vrf_id = ntohl (vrf_id);
19579
19580   S (mp);
19581   W (ret);
19582   return ret;
19583 }
19584
19585 int
19586 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
19587 {
19588   unformat_input_t *input = vam->input;
19589   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
19590   u32 sw_if_index = ~0;
19591   int vrf_set = 0;
19592   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
19593   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
19594   u8 is_add = 1;
19595   int ret;
19596
19597   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19598     {
19599       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19600         ;
19601       else if (unformat (input, "sw_if_index %d", &sw_if_index))
19602         ;
19603       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
19604         vrf_set = 1;
19605       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
19606         vrf_set = 1;
19607       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
19608         vrf_set = 1;
19609       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
19610         vrf_set = 1;
19611       else if (unformat (input, "del"))
19612         is_add = 0;
19613       else
19614         break;
19615     }
19616
19617   if (sw_if_index == ~0)
19618     {
19619       errmsg ("Interface required but not specified");
19620       return -99;
19621     }
19622
19623   if (vrf_set == 0)
19624     {
19625       errmsg ("VRF ID required but not specified");
19626       return -99;
19627     }
19628
19629   if (tcp_out_vrf_id == 0
19630       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
19631     {
19632       errmsg
19633         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
19634       return -99;
19635     }
19636
19637   /* Construct the API message */
19638   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
19639
19640   mp->sw_if_index = ntohl (sw_if_index);
19641   mp->is_add = is_add;
19642   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
19643   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
19644   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
19645   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
19646
19647   /* send it... */
19648   S (mp);
19649
19650   /* Wait for a reply... */
19651   W (ret);
19652   return ret;
19653 }
19654
19655 static int
19656 api_set_punt (vat_main_t * vam)
19657 {
19658   unformat_input_t *i = vam->input;
19659   vl_api_address_family_t af;
19660   vl_api_set_punt_t *mp;
19661   u32 protocol = ~0;
19662   u32 port = ~0;
19663   int is_add = 1;
19664   int ret;
19665
19666   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19667     {
19668       if (unformat (i, "%U", unformat_vl_api_address_family, &af))
19669         ;
19670       else if (unformat (i, "protocol %d", &protocol))
19671         ;
19672       else if (unformat (i, "port %d", &port))
19673         ;
19674       else if (unformat (i, "del"))
19675         is_add = 0;
19676       else
19677         {
19678           clib_warning ("parse error '%U'", format_unformat_error, i);
19679           return -99;
19680         }
19681     }
19682
19683   M (SET_PUNT, mp);
19684
19685   mp->is_add = (u8) is_add;
19686   mp->punt.type = PUNT_API_TYPE_L4;
19687   mp->punt.punt.l4.af = af;
19688   mp->punt.punt.l4.protocol = (u8) protocol;
19689   mp->punt.punt.l4.port = htons ((u16) port);
19690
19691   S (mp);
19692   W (ret);
19693   return ret;
19694 }
19695
19696 static int
19697 api_delete_subif (vat_main_t * vam)
19698 {
19699   unformat_input_t *i = vam->input;
19700   vl_api_delete_subif_t *mp;
19701   u32 sw_if_index = ~0;
19702   int ret;
19703
19704   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19705     {
19706       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19707         ;
19708       if (unformat (i, "sw_if_index %d", &sw_if_index))
19709         ;
19710       else
19711         break;
19712     }
19713
19714   if (sw_if_index == ~0)
19715     {
19716       errmsg ("missing sw_if_index");
19717       return -99;
19718     }
19719
19720   /* Construct the API message */
19721   M (DELETE_SUBIF, mp);
19722   mp->sw_if_index = ntohl (sw_if_index);
19723
19724   S (mp);
19725   W (ret);
19726   return ret;
19727 }
19728
19729 #define foreach_pbb_vtr_op      \
19730 _("disable",  L2_VTR_DISABLED)  \
19731 _("pop",  L2_VTR_POP_2)         \
19732 _("push",  L2_VTR_PUSH_2)
19733
19734 static int
19735 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
19736 {
19737   unformat_input_t *i = vam->input;
19738   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
19739   u32 sw_if_index = ~0, vtr_op = ~0;
19740   u16 outer_tag = ~0;
19741   u8 dmac[6], smac[6];
19742   u8 dmac_set = 0, smac_set = 0;
19743   u16 vlanid = 0;
19744   u32 sid = ~0;
19745   u32 tmp;
19746   int ret;
19747
19748   /* Shut up coverity */
19749   clib_memset (dmac, 0, sizeof (dmac));
19750   clib_memset (smac, 0, sizeof (smac));
19751
19752   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19753     {
19754       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19755         ;
19756       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19757         ;
19758       else if (unformat (i, "vtr_op %d", &vtr_op))
19759         ;
19760 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
19761       foreach_pbb_vtr_op
19762 #undef _
19763         else if (unformat (i, "translate_pbb_stag"))
19764         {
19765           if (unformat (i, "%d", &tmp))
19766             {
19767               vtr_op = L2_VTR_TRANSLATE_2_1;
19768               outer_tag = tmp;
19769             }
19770           else
19771             {
19772               errmsg
19773                 ("translate_pbb_stag operation requires outer tag definition");
19774               return -99;
19775             }
19776         }
19777       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
19778         dmac_set++;
19779       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
19780         smac_set++;
19781       else if (unformat (i, "sid %d", &sid))
19782         ;
19783       else if (unformat (i, "vlanid %d", &tmp))
19784         vlanid = tmp;
19785       else
19786         {
19787           clib_warning ("parse error '%U'", format_unformat_error, i);
19788           return -99;
19789         }
19790     }
19791
19792   if ((sw_if_index == ~0) || (vtr_op == ~0))
19793     {
19794       errmsg ("missing sw_if_index or vtr operation");
19795       return -99;
19796     }
19797   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
19798       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
19799     {
19800       errmsg
19801         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
19802       return -99;
19803     }
19804
19805   M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
19806   mp->sw_if_index = ntohl (sw_if_index);
19807   mp->vtr_op = ntohl (vtr_op);
19808   mp->outer_tag = ntohs (outer_tag);
19809   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
19810   clib_memcpy (mp->b_smac, smac, sizeof (smac));
19811   mp->b_vlanid = ntohs (vlanid);
19812   mp->i_sid = ntohl (sid);
19813
19814   S (mp);
19815   W (ret);
19816   return ret;
19817 }
19818
19819 static int
19820 api_flow_classify_set_interface (vat_main_t * vam)
19821 {
19822   unformat_input_t *i = vam->input;
19823   vl_api_flow_classify_set_interface_t *mp;
19824   u32 sw_if_index;
19825   int sw_if_index_set;
19826   u32 ip4_table_index = ~0;
19827   u32 ip6_table_index = ~0;
19828   u8 is_add = 1;
19829   int ret;
19830
19831   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19832     {
19833       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19834         sw_if_index_set = 1;
19835       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19836         sw_if_index_set = 1;
19837       else if (unformat (i, "del"))
19838         is_add = 0;
19839       else if (unformat (i, "ip4-table %d", &ip4_table_index))
19840         ;
19841       else if (unformat (i, "ip6-table %d", &ip6_table_index))
19842         ;
19843       else
19844         {
19845           clib_warning ("parse error '%U'", format_unformat_error, i);
19846           return -99;
19847         }
19848     }
19849
19850   if (sw_if_index_set == 0)
19851     {
19852       errmsg ("missing interface name or sw_if_index");
19853       return -99;
19854     }
19855
19856   M (FLOW_CLASSIFY_SET_INTERFACE, mp);
19857
19858   mp->sw_if_index = ntohl (sw_if_index);
19859   mp->ip4_table_index = ntohl (ip4_table_index);
19860   mp->ip6_table_index = ntohl (ip6_table_index);
19861   mp->is_add = is_add;
19862
19863   S (mp);
19864   W (ret);
19865   return ret;
19866 }
19867
19868 static int
19869 api_flow_classify_dump (vat_main_t * vam)
19870 {
19871   unformat_input_t *i = vam->input;
19872   vl_api_flow_classify_dump_t *mp;
19873   vl_api_control_ping_t *mp_ping;
19874   u8 type = FLOW_CLASSIFY_N_TABLES;
19875   int ret;
19876
19877   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
19878     ;
19879   else
19880     {
19881       errmsg ("classify table type must be specified");
19882       return -99;
19883     }
19884
19885   if (!vam->json_output)
19886     {
19887       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
19888     }
19889
19890   M (FLOW_CLASSIFY_DUMP, mp);
19891   mp->type = type;
19892   /* send it... */
19893   S (mp);
19894
19895   /* Use a control ping for synchronization */
19896   MPING (CONTROL_PING, mp_ping);
19897   S (mp_ping);
19898
19899   /* Wait for a reply... */
19900   W (ret);
19901   return ret;
19902 }
19903
19904 static int
19905 api_feature_enable_disable (vat_main_t * vam)
19906 {
19907   unformat_input_t *i = vam->input;
19908   vl_api_feature_enable_disable_t *mp;
19909   u8 *arc_name = 0;
19910   u8 *feature_name = 0;
19911   u32 sw_if_index = ~0;
19912   u8 enable = 1;
19913   int ret;
19914
19915   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19916     {
19917       if (unformat (i, "arc_name %s", &arc_name))
19918         ;
19919       else if (unformat (i, "feature_name %s", &feature_name))
19920         ;
19921       else
19922         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19923         ;
19924       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19925         ;
19926       else if (unformat (i, "disable"))
19927         enable = 0;
19928       else
19929         break;
19930     }
19931
19932   if (arc_name == 0)
19933     {
19934       errmsg ("missing arc name");
19935       return -99;
19936     }
19937   if (vec_len (arc_name) > 63)
19938     {
19939       errmsg ("arc name too long");
19940     }
19941
19942   if (feature_name == 0)
19943     {
19944       errmsg ("missing feature name");
19945       return -99;
19946     }
19947   if (vec_len (feature_name) > 63)
19948     {
19949       errmsg ("feature name too long");
19950     }
19951
19952   if (sw_if_index == ~0)
19953     {
19954       errmsg ("missing interface name or sw_if_index");
19955       return -99;
19956     }
19957
19958   /* Construct the API message */
19959   M (FEATURE_ENABLE_DISABLE, mp);
19960   mp->sw_if_index = ntohl (sw_if_index);
19961   mp->enable = enable;
19962   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
19963   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
19964   vec_free (arc_name);
19965   vec_free (feature_name);
19966
19967   S (mp);
19968   W (ret);
19969   return ret;
19970 }
19971
19972 static int
19973 api_feature_gso_enable_disable (vat_main_t * vam)
19974 {
19975   unformat_input_t *i = vam->input;
19976   vl_api_feature_gso_enable_disable_t *mp;
19977   u32 sw_if_index = ~0;
19978   u8 enable = 1;
19979   int ret;
19980
19981   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19982     {
19983       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19984         ;
19985       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19986         ;
19987       else if (unformat (i, "enable"))
19988         enable = 1;
19989       else if (unformat (i, "disable"))
19990         enable = 0;
19991       else
19992         break;
19993     }
19994
19995   if (sw_if_index == ~0)
19996     {
19997       errmsg ("missing interface name or sw_if_index");
19998       return -99;
19999     }
20000
20001   /* Construct the API message */
20002   M (FEATURE_GSO_ENABLE_DISABLE, mp);
20003   mp->sw_if_index = ntohl (sw_if_index);
20004   mp->enable_disable = enable;
20005
20006   S (mp);
20007   W (ret);
20008   return ret;
20009 }
20010
20011 static int
20012 api_sw_interface_tag_add_del (vat_main_t * vam)
20013 {
20014   unformat_input_t *i = vam->input;
20015   vl_api_sw_interface_tag_add_del_t *mp;
20016   u32 sw_if_index = ~0;
20017   u8 *tag = 0;
20018   u8 enable = 1;
20019   int ret;
20020
20021   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20022     {
20023       if (unformat (i, "tag %s", &tag))
20024         ;
20025       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20026         ;
20027       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20028         ;
20029       else if (unformat (i, "del"))
20030         enable = 0;
20031       else
20032         break;
20033     }
20034
20035   if (sw_if_index == ~0)
20036     {
20037       errmsg ("missing interface name or sw_if_index");
20038       return -99;
20039     }
20040
20041   if (enable && (tag == 0))
20042     {
20043       errmsg ("no tag specified");
20044       return -99;
20045     }
20046
20047   /* Construct the API message */
20048   M (SW_INTERFACE_TAG_ADD_DEL, mp);
20049   mp->sw_if_index = ntohl (sw_if_index);
20050   mp->is_add = enable;
20051   if (enable)
20052     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
20053   vec_free (tag);
20054
20055   S (mp);
20056   W (ret);
20057   return ret;
20058 }
20059
20060 static int
20061 api_sw_interface_add_del_mac_address (vat_main_t * vam)
20062 {
20063   unformat_input_t *i = vam->input;
20064   vl_api_mac_address_t mac = { 0 };
20065   vl_api_sw_interface_add_del_mac_address_t *mp;
20066   u32 sw_if_index = ~0;
20067   u8 is_add = 1;
20068   u8 mac_set = 0;
20069   int ret;
20070
20071   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20072     {
20073       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20074         ;
20075       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20076         ;
20077       else if (unformat (i, "%U", unformat_vl_api_mac_address, &mac))
20078         mac_set++;
20079       else if (unformat (i, "del"))
20080         is_add = 0;
20081       else
20082         break;
20083     }
20084
20085   if (sw_if_index == ~0)
20086     {
20087       errmsg ("missing interface name or sw_if_index");
20088       return -99;
20089     }
20090
20091   if (!mac_set)
20092     {
20093       errmsg ("missing MAC address");
20094       return -99;
20095     }
20096
20097   /* Construct the API message */
20098   M (SW_INTERFACE_ADD_DEL_MAC_ADDRESS, mp);
20099   mp->sw_if_index = ntohl (sw_if_index);
20100   mp->is_add = is_add;
20101   clib_memcpy (&mp->addr, &mac, sizeof (mac));
20102
20103   S (mp);
20104   W (ret);
20105   return ret;
20106 }
20107
20108 static void vl_api_l2_xconnect_details_t_handler
20109   (vl_api_l2_xconnect_details_t * mp)
20110 {
20111   vat_main_t *vam = &vat_main;
20112
20113   print (vam->ofp, "%15d%15d",
20114          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
20115 }
20116
20117 static void vl_api_l2_xconnect_details_t_handler_json
20118   (vl_api_l2_xconnect_details_t * mp)
20119 {
20120   vat_main_t *vam = &vat_main;
20121   vat_json_node_t *node = NULL;
20122
20123   if (VAT_JSON_ARRAY != vam->json_tree.type)
20124     {
20125       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20126       vat_json_init_array (&vam->json_tree);
20127     }
20128   node = vat_json_array_add (&vam->json_tree);
20129
20130   vat_json_init_object (node);
20131   vat_json_object_add_uint (node, "rx_sw_if_index",
20132                             ntohl (mp->rx_sw_if_index));
20133   vat_json_object_add_uint (node, "tx_sw_if_index",
20134                             ntohl (mp->tx_sw_if_index));
20135 }
20136
20137 static int
20138 api_l2_xconnect_dump (vat_main_t * vam)
20139 {
20140   vl_api_l2_xconnect_dump_t *mp;
20141   vl_api_control_ping_t *mp_ping;
20142   int ret;
20143
20144   if (!vam->json_output)
20145     {
20146       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
20147     }
20148
20149   M (L2_XCONNECT_DUMP, mp);
20150
20151   S (mp);
20152
20153   /* Use a control ping for synchronization */
20154   MPING (CONTROL_PING, mp_ping);
20155   S (mp_ping);
20156
20157   W (ret);
20158   return ret;
20159 }
20160
20161 static int
20162 api_hw_interface_set_mtu (vat_main_t * vam)
20163 {
20164   unformat_input_t *i = vam->input;
20165   vl_api_hw_interface_set_mtu_t *mp;
20166   u32 sw_if_index = ~0;
20167   u32 mtu = 0;
20168   int ret;
20169
20170   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20171     {
20172       if (unformat (i, "mtu %d", &mtu))
20173         ;
20174       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20175         ;
20176       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20177         ;
20178       else
20179         break;
20180     }
20181
20182   if (sw_if_index == ~0)
20183     {
20184       errmsg ("missing interface name or sw_if_index");
20185       return -99;
20186     }
20187
20188   if (mtu == 0)
20189     {
20190       errmsg ("no mtu specified");
20191       return -99;
20192     }
20193
20194   /* Construct the API message */
20195   M (HW_INTERFACE_SET_MTU, mp);
20196   mp->sw_if_index = ntohl (sw_if_index);
20197   mp->mtu = ntohs ((u16) mtu);
20198
20199   S (mp);
20200   W (ret);
20201   return ret;
20202 }
20203
20204 static int
20205 api_p2p_ethernet_add (vat_main_t * vam)
20206 {
20207   unformat_input_t *i = vam->input;
20208   vl_api_p2p_ethernet_add_t *mp;
20209   u32 parent_if_index = ~0;
20210   u32 sub_id = ~0;
20211   u8 remote_mac[6];
20212   u8 mac_set = 0;
20213   int ret;
20214
20215   clib_memset (remote_mac, 0, sizeof (remote_mac));
20216   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20217     {
20218       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
20219         ;
20220       else if (unformat (i, "sw_if_index %d", &parent_if_index))
20221         ;
20222       else
20223         if (unformat
20224             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
20225         mac_set++;
20226       else if (unformat (i, "sub_id %d", &sub_id))
20227         ;
20228       else
20229         {
20230           clib_warning ("parse error '%U'", format_unformat_error, i);
20231           return -99;
20232         }
20233     }
20234
20235   if (parent_if_index == ~0)
20236     {
20237       errmsg ("missing interface name or sw_if_index");
20238       return -99;
20239     }
20240   if (mac_set == 0)
20241     {
20242       errmsg ("missing remote mac address");
20243       return -99;
20244     }
20245   if (sub_id == ~0)
20246     {
20247       errmsg ("missing sub-interface id");
20248       return -99;
20249     }
20250
20251   M (P2P_ETHERNET_ADD, mp);
20252   mp->parent_if_index = ntohl (parent_if_index);
20253   mp->subif_id = ntohl (sub_id);
20254   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
20255
20256   S (mp);
20257   W (ret);
20258   return ret;
20259 }
20260
20261 static int
20262 api_p2p_ethernet_del (vat_main_t * vam)
20263 {
20264   unformat_input_t *i = vam->input;
20265   vl_api_p2p_ethernet_del_t *mp;
20266   u32 parent_if_index = ~0;
20267   u8 remote_mac[6];
20268   u8 mac_set = 0;
20269   int ret;
20270
20271   clib_memset (remote_mac, 0, sizeof (remote_mac));
20272   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20273     {
20274       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
20275         ;
20276       else if (unformat (i, "sw_if_index %d", &parent_if_index))
20277         ;
20278       else
20279         if (unformat
20280             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
20281         mac_set++;
20282       else
20283         {
20284           clib_warning ("parse error '%U'", format_unformat_error, i);
20285           return -99;
20286         }
20287     }
20288
20289   if (parent_if_index == ~0)
20290     {
20291       errmsg ("missing interface name or sw_if_index");
20292       return -99;
20293     }
20294   if (mac_set == 0)
20295     {
20296       errmsg ("missing remote mac address");
20297       return -99;
20298     }
20299
20300   M (P2P_ETHERNET_DEL, mp);
20301   mp->parent_if_index = ntohl (parent_if_index);
20302   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
20303
20304   S (mp);
20305   W (ret);
20306   return ret;
20307 }
20308
20309 static int
20310 api_lldp_config (vat_main_t * vam)
20311 {
20312   unformat_input_t *i = vam->input;
20313   vl_api_lldp_config_t *mp;
20314   int tx_hold = 0;
20315   int tx_interval = 0;
20316   u8 *sys_name = NULL;
20317   int ret;
20318
20319   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20320     {
20321       if (unformat (i, "system-name %s", &sys_name))
20322         ;
20323       else if (unformat (i, "tx-hold %d", &tx_hold))
20324         ;
20325       else if (unformat (i, "tx-interval %d", &tx_interval))
20326         ;
20327       else
20328         {
20329           clib_warning ("parse error '%U'", format_unformat_error, i);
20330           return -99;
20331         }
20332     }
20333
20334   vec_add1 (sys_name, 0);
20335
20336   M (LLDP_CONFIG, mp);
20337   mp->tx_hold = htonl (tx_hold);
20338   mp->tx_interval = htonl (tx_interval);
20339   clib_memcpy (mp->system_name, sys_name, vec_len (sys_name));
20340   vec_free (sys_name);
20341
20342   S (mp);
20343   W (ret);
20344   return ret;
20345 }
20346
20347 static int
20348 api_sw_interface_set_lldp (vat_main_t * vam)
20349 {
20350   unformat_input_t *i = vam->input;
20351   vl_api_sw_interface_set_lldp_t *mp;
20352   u32 sw_if_index = ~0;
20353   u32 enable = 1;
20354   u8 *port_desc = NULL, *mgmt_oid = NULL;
20355   ip4_address_t ip4_addr;
20356   ip6_address_t ip6_addr;
20357   int ret;
20358
20359   clib_memset (&ip4_addr, 0, sizeof (ip4_addr));
20360   clib_memset (&ip6_addr, 0, sizeof (ip6_addr));
20361
20362   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20363     {
20364       if (unformat (i, "disable"))
20365         enable = 0;
20366       else
20367         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20368         ;
20369       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20370         ;
20371       else if (unformat (i, "port-desc %s", &port_desc))
20372         ;
20373       else if (unformat (i, "mgmt-ip4 %U", unformat_ip4_address, &ip4_addr))
20374         ;
20375       else if (unformat (i, "mgmt-ip6 %U", unformat_ip6_address, &ip6_addr))
20376         ;
20377       else if (unformat (i, "mgmt-oid %s", &mgmt_oid))
20378         ;
20379       else
20380         break;
20381     }
20382
20383   if (sw_if_index == ~0)
20384     {
20385       errmsg ("missing interface name or sw_if_index");
20386       return -99;
20387     }
20388
20389   /* Construct the API message */
20390   vec_add1 (port_desc, 0);
20391   vec_add1 (mgmt_oid, 0);
20392   M (SW_INTERFACE_SET_LLDP, mp);
20393   mp->sw_if_index = ntohl (sw_if_index);
20394   mp->enable = enable;
20395   clib_memcpy (mp->port_desc, port_desc, vec_len (port_desc));
20396   clib_memcpy (mp->mgmt_oid, mgmt_oid, vec_len (mgmt_oid));
20397   clib_memcpy (mp->mgmt_ip4, &ip4_addr, sizeof (ip4_addr));
20398   clib_memcpy (mp->mgmt_ip6, &ip6_addr, sizeof (ip6_addr));
20399   vec_free (port_desc);
20400   vec_free (mgmt_oid);
20401
20402   S (mp);
20403   W (ret);
20404   return ret;
20405 }
20406
20407 static int
20408 api_tcp_configure_src_addresses (vat_main_t * vam)
20409 {
20410   vl_api_tcp_configure_src_addresses_t *mp;
20411   unformat_input_t *i = vam->input;
20412   ip4_address_t v4first, v4last;
20413   ip6_address_t v6first, v6last;
20414   u8 range_set = 0;
20415   u32 vrf_id = 0;
20416   int ret;
20417
20418   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20419     {
20420       if (unformat (i, "%U - %U",
20421                     unformat_ip4_address, &v4first,
20422                     unformat_ip4_address, &v4last))
20423         {
20424           if (range_set)
20425             {
20426               errmsg ("one range per message (range already set)");
20427               return -99;
20428             }
20429           range_set = 1;
20430         }
20431       else if (unformat (i, "%U - %U",
20432                          unformat_ip6_address, &v6first,
20433                          unformat_ip6_address, &v6last))
20434         {
20435           if (range_set)
20436             {
20437               errmsg ("one range per message (range already set)");
20438               return -99;
20439             }
20440           range_set = 2;
20441         }
20442       else if (unformat (i, "vrf %d", &vrf_id))
20443         ;
20444       else
20445         break;
20446     }
20447
20448   if (range_set == 0)
20449     {
20450       errmsg ("address range not set");
20451       return -99;
20452     }
20453
20454   M (TCP_CONFIGURE_SRC_ADDRESSES, mp);
20455   mp->vrf_id = ntohl (vrf_id);
20456   /* ipv6? */
20457   if (range_set == 2)
20458     {
20459       mp->is_ipv6 = 1;
20460       clib_memcpy (mp->first_address, &v6first, sizeof (v6first));
20461       clib_memcpy (mp->last_address, &v6last, sizeof (v6last));
20462     }
20463   else
20464     {
20465       mp->is_ipv6 = 0;
20466       clib_memcpy (mp->first_address, &v4first, sizeof (v4first));
20467       clib_memcpy (mp->last_address, &v4last, sizeof (v4last));
20468     }
20469   S (mp);
20470   W (ret);
20471   return ret;
20472 }
20473
20474 static void vl_api_app_namespace_add_del_reply_t_handler
20475   (vl_api_app_namespace_add_del_reply_t * mp)
20476 {
20477   vat_main_t *vam = &vat_main;
20478   i32 retval = ntohl (mp->retval);
20479   if (vam->async_mode)
20480     {
20481       vam->async_errors += (retval < 0);
20482     }
20483   else
20484     {
20485       vam->retval = retval;
20486       if (retval == 0)
20487         errmsg ("app ns index %d\n", ntohl (mp->appns_index));
20488       vam->result_ready = 1;
20489     }
20490 }
20491
20492 static void vl_api_app_namespace_add_del_reply_t_handler_json
20493   (vl_api_app_namespace_add_del_reply_t * mp)
20494 {
20495   vat_main_t *vam = &vat_main;
20496   vat_json_node_t node;
20497
20498   vat_json_init_object (&node);
20499   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
20500   vat_json_object_add_uint (&node, "appns_index", ntohl (mp->appns_index));
20501
20502   vat_json_print (vam->ofp, &node);
20503   vat_json_free (&node);
20504
20505   vam->retval = ntohl (mp->retval);
20506   vam->result_ready = 1;
20507 }
20508
20509 static int
20510 api_app_namespace_add_del (vat_main_t * vam)
20511 {
20512   vl_api_app_namespace_add_del_t *mp;
20513   unformat_input_t *i = vam->input;
20514   u8 *ns_id = 0, secret_set = 0, sw_if_index_set = 0;
20515   u32 sw_if_index, ip4_fib_id, ip6_fib_id;
20516   u64 secret;
20517   int ret;
20518
20519   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20520     {
20521       if (unformat (i, "id %_%v%_", &ns_id))
20522         ;
20523       else if (unformat (i, "secret %lu", &secret))
20524         secret_set = 1;
20525       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20526         sw_if_index_set = 1;
20527       else if (unformat (i, "ip4_fib_id %d", &ip4_fib_id))
20528         ;
20529       else if (unformat (i, "ip6_fib_id %d", &ip6_fib_id))
20530         ;
20531       else
20532         break;
20533     }
20534   if (!ns_id || !secret_set || !sw_if_index_set)
20535     {
20536       errmsg ("namespace id, secret and sw_if_index must be set");
20537       return -99;
20538     }
20539   if (vec_len (ns_id) > 64)
20540     {
20541       errmsg ("namespace id too long");
20542       return -99;
20543     }
20544   M (APP_NAMESPACE_ADD_DEL, mp);
20545
20546   clib_memcpy (mp->namespace_id, ns_id, vec_len (ns_id));
20547   mp->namespace_id_len = vec_len (ns_id);
20548   mp->secret = clib_host_to_net_u64 (secret);
20549   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
20550   mp->ip4_fib_id = clib_host_to_net_u32 (ip4_fib_id);
20551   mp->ip6_fib_id = clib_host_to_net_u32 (ip6_fib_id);
20552   vec_free (ns_id);
20553   S (mp);
20554   W (ret);
20555   return ret;
20556 }
20557
20558 static int
20559 api_sock_init_shm (vat_main_t * vam)
20560 {
20561 #if VPP_API_TEST_BUILTIN == 0
20562   unformat_input_t *i = vam->input;
20563   vl_api_shm_elem_config_t *config = 0;
20564   u64 size = 64 << 20;
20565   int rv;
20566
20567   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20568     {
20569       if (unformat (i, "size %U", unformat_memory_size, &size))
20570         ;
20571       else
20572         break;
20573     }
20574
20575   /*
20576    * Canned custom ring allocator config.
20577    * Should probably parse all of this
20578    */
20579   vec_validate (config, 6);
20580   config[0].type = VL_API_VLIB_RING;
20581   config[0].size = 256;
20582   config[0].count = 32;
20583
20584   config[1].type = VL_API_VLIB_RING;
20585   config[1].size = 1024;
20586   config[1].count = 16;
20587
20588   config[2].type = VL_API_VLIB_RING;
20589   config[2].size = 4096;
20590   config[2].count = 2;
20591
20592   config[3].type = VL_API_CLIENT_RING;
20593   config[3].size = 256;
20594   config[3].count = 32;
20595
20596   config[4].type = VL_API_CLIENT_RING;
20597   config[4].size = 1024;
20598   config[4].count = 16;
20599
20600   config[5].type = VL_API_CLIENT_RING;
20601   config[5].size = 4096;
20602   config[5].count = 2;
20603
20604   config[6].type = VL_API_QUEUE;
20605   config[6].count = 128;
20606   config[6].size = sizeof (uword);
20607
20608   rv = vl_socket_client_init_shm (config, 1 /* want_pthread */ );
20609   if (!rv)
20610     vam->client_index_invalid = 1;
20611   return rv;
20612 #else
20613   return -99;
20614 #endif
20615 }
20616
20617 static void
20618 vl_api_session_rules_details_t_handler (vl_api_session_rules_details_t * mp)
20619 {
20620   vat_main_t *vam = &vat_main;
20621
20622   if (mp->is_ip4)
20623     {
20624       print (vam->ofp,
20625              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
20626              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
20627              mp->scope, format_ip4_address, &mp->lcl_ip, mp->lcl_plen,
20628              clib_net_to_host_u16 (mp->lcl_port), format_ip4_address,
20629              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
20630              clib_net_to_host_u32 (mp->action_index), mp->tag);
20631     }
20632   else
20633     {
20634       print (vam->ofp,
20635              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
20636              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
20637              mp->scope, format_ip6_address, &mp->lcl_ip, mp->lcl_plen,
20638              clib_net_to_host_u16 (mp->lcl_port), format_ip6_address,
20639              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
20640              clib_net_to_host_u32 (mp->action_index), mp->tag);
20641     }
20642 }
20643
20644 static void
20645 vl_api_session_rules_details_t_handler_json (vl_api_session_rules_details_t *
20646                                              mp)
20647 {
20648   vat_main_t *vam = &vat_main;
20649   vat_json_node_t *node = NULL;
20650   struct in6_addr ip6;
20651   struct in_addr ip4;
20652
20653   if (VAT_JSON_ARRAY != vam->json_tree.type)
20654     {
20655       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20656       vat_json_init_array (&vam->json_tree);
20657     }
20658   node = vat_json_array_add (&vam->json_tree);
20659   vat_json_init_object (node);
20660
20661   vat_json_object_add_uint (node, "is_ip4", mp->is_ip4 ? 1 : 0);
20662   vat_json_object_add_uint (node, "appns_index",
20663                             clib_net_to_host_u32 (mp->appns_index));
20664   vat_json_object_add_uint (node, "transport_proto", mp->transport_proto);
20665   vat_json_object_add_uint (node, "scope", mp->scope);
20666   vat_json_object_add_uint (node, "action_index",
20667                             clib_net_to_host_u32 (mp->action_index));
20668   vat_json_object_add_uint (node, "lcl_port",
20669                             clib_net_to_host_u16 (mp->lcl_port));
20670   vat_json_object_add_uint (node, "rmt_port",
20671                             clib_net_to_host_u16 (mp->rmt_port));
20672   vat_json_object_add_uint (node, "lcl_plen", mp->lcl_plen);
20673   vat_json_object_add_uint (node, "rmt_plen", mp->rmt_plen);
20674   vat_json_object_add_string_copy (node, "tag", mp->tag);
20675   if (mp->is_ip4)
20676     {
20677       clib_memcpy (&ip4, mp->lcl_ip, sizeof (ip4));
20678       vat_json_object_add_ip4 (node, "lcl_ip", ip4);
20679       clib_memcpy (&ip4, mp->rmt_ip, sizeof (ip4));
20680       vat_json_object_add_ip4 (node, "rmt_ip", ip4);
20681     }
20682   else
20683     {
20684       clib_memcpy (&ip6, mp->lcl_ip, sizeof (ip6));
20685       vat_json_object_add_ip6 (node, "lcl_ip", ip6);
20686       clib_memcpy (&ip6, mp->rmt_ip, sizeof (ip6));
20687       vat_json_object_add_ip6 (node, "rmt_ip", ip6);
20688     }
20689 }
20690
20691 static int
20692 api_session_rule_add_del (vat_main_t * vam)
20693 {
20694   vl_api_session_rule_add_del_t *mp;
20695   unformat_input_t *i = vam->input;
20696   u32 proto = ~0, lcl_port, rmt_port, action = 0, lcl_plen, rmt_plen;
20697   u32 appns_index = 0, scope = 0;
20698   ip4_address_t lcl_ip4, rmt_ip4;
20699   ip6_address_t lcl_ip6, rmt_ip6;
20700   u8 is_ip4 = 1, conn_set = 0;
20701   u8 is_add = 1, *tag = 0;
20702   int ret;
20703
20704   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20705     {
20706       if (unformat (i, "del"))
20707         is_add = 0;
20708       else if (unformat (i, "add"))
20709         ;
20710       else if (unformat (i, "proto tcp"))
20711         proto = 0;
20712       else if (unformat (i, "proto udp"))
20713         proto = 1;
20714       else if (unformat (i, "appns %d", &appns_index))
20715         ;
20716       else if (unformat (i, "scope %d", &scope))
20717         ;
20718       else if (unformat (i, "tag %_%v%_", &tag))
20719         ;
20720       else
20721         if (unformat
20722             (i, "%U/%d %d %U/%d %d", unformat_ip4_address, &lcl_ip4,
20723              &lcl_plen, &lcl_port, unformat_ip4_address, &rmt_ip4, &rmt_plen,
20724              &rmt_port))
20725         {
20726           is_ip4 = 1;
20727           conn_set = 1;
20728         }
20729       else
20730         if (unformat
20731             (i, "%U/%d %d %U/%d %d", unformat_ip6_address, &lcl_ip6,
20732              &lcl_plen, &lcl_port, unformat_ip6_address, &rmt_ip6, &rmt_plen,
20733              &rmt_port))
20734         {
20735           is_ip4 = 0;
20736           conn_set = 1;
20737         }
20738       else if (unformat (i, "action %d", &action))
20739         ;
20740       else
20741         break;
20742     }
20743   if (proto == ~0 || !conn_set || action == ~0)
20744     {
20745       errmsg ("transport proto, connection and action must be set");
20746       return -99;
20747     }
20748
20749   if (scope > 3)
20750     {
20751       errmsg ("scope should be 0-3");
20752       return -99;
20753     }
20754
20755   M (SESSION_RULE_ADD_DEL, mp);
20756
20757   mp->is_ip4 = is_ip4;
20758   mp->transport_proto = proto;
20759   mp->lcl_port = clib_host_to_net_u16 ((u16) lcl_port);
20760   mp->rmt_port = clib_host_to_net_u16 ((u16) rmt_port);
20761   mp->lcl_plen = lcl_plen;
20762   mp->rmt_plen = rmt_plen;
20763   mp->action_index = clib_host_to_net_u32 (action);
20764   mp->appns_index = clib_host_to_net_u32 (appns_index);
20765   mp->scope = scope;
20766   mp->is_add = is_add;
20767   if (is_ip4)
20768     {
20769       clib_memcpy (mp->lcl_ip, &lcl_ip4, sizeof (lcl_ip4));
20770       clib_memcpy (mp->rmt_ip, &rmt_ip4, sizeof (rmt_ip4));
20771     }
20772   else
20773     {
20774       clib_memcpy (mp->lcl_ip, &lcl_ip6, sizeof (lcl_ip6));
20775       clib_memcpy (mp->rmt_ip, &rmt_ip6, sizeof (rmt_ip6));
20776     }
20777   if (tag)
20778     {
20779       clib_memcpy (mp->tag, tag, vec_len (tag));
20780       vec_free (tag);
20781     }
20782
20783   S (mp);
20784   W (ret);
20785   return ret;
20786 }
20787
20788 static int
20789 api_session_rules_dump (vat_main_t * vam)
20790 {
20791   vl_api_session_rules_dump_t *mp;
20792   vl_api_control_ping_t *mp_ping;
20793   int ret;
20794
20795   if (!vam->json_output)
20796     {
20797       print (vam->ofp, "%=20s", "Session Rules");
20798     }
20799
20800   M (SESSION_RULES_DUMP, mp);
20801   /* send it... */
20802   S (mp);
20803
20804   /* Use a control ping for synchronization */
20805   MPING (CONTROL_PING, mp_ping);
20806   S (mp_ping);
20807
20808   /* Wait for a reply... */
20809   W (ret);
20810   return ret;
20811 }
20812
20813 static int
20814 api_ip_container_proxy_add_del (vat_main_t * vam)
20815 {
20816   vl_api_ip_container_proxy_add_del_t *mp;
20817   unformat_input_t *i = vam->input;
20818   u32 sw_if_index = ~0;
20819   vl_api_prefix_t pfx = { };
20820   u8 is_add = 1;
20821   int ret;
20822
20823   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20824     {
20825       if (unformat (i, "del"))
20826         is_add = 0;
20827       else if (unformat (i, "add"))
20828         ;
20829       if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
20830         ;
20831       else if (unformat (i, "sw_if_index %u", &sw_if_index))
20832         ;
20833       else
20834         break;
20835     }
20836   if (sw_if_index == ~0 || pfx.len == 0)
20837     {
20838       errmsg ("address and sw_if_index must be set");
20839       return -99;
20840     }
20841
20842   M (IP_CONTAINER_PROXY_ADD_DEL, mp);
20843
20844   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
20845   mp->is_add = is_add;
20846   clib_memcpy (&mp->pfx, &pfx, sizeof (pfx));
20847
20848   S (mp);
20849   W (ret);
20850   return ret;
20851 }
20852
20853 static int
20854 api_qos_record_enable_disable (vat_main_t * vam)
20855 {
20856   unformat_input_t *i = vam->input;
20857   vl_api_qos_record_enable_disable_t *mp;
20858   u32 sw_if_index, qs = 0xff;
20859   u8 sw_if_index_set = 0;
20860   u8 enable = 1;
20861   int ret;
20862
20863   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20864     {
20865       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20866         sw_if_index_set = 1;
20867       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20868         sw_if_index_set = 1;
20869       else if (unformat (i, "%U", unformat_qos_source, &qs))
20870         ;
20871       else if (unformat (i, "disable"))
20872         enable = 0;
20873       else
20874         {
20875           clib_warning ("parse error '%U'", format_unformat_error, i);
20876           return -99;
20877         }
20878     }
20879
20880   if (sw_if_index_set == 0)
20881     {
20882       errmsg ("missing interface name or sw_if_index");
20883       return -99;
20884     }
20885   if (qs == 0xff)
20886     {
20887       errmsg ("input location must be specified");
20888       return -99;
20889     }
20890
20891   M (QOS_RECORD_ENABLE_DISABLE, mp);
20892
20893   mp->record.sw_if_index = ntohl (sw_if_index);
20894   mp->record.input_source = qs;
20895   mp->enable = enable;
20896
20897   S (mp);
20898   W (ret);
20899   return ret;
20900 }
20901
20902
20903 static int
20904 q_or_quit (vat_main_t * vam)
20905 {
20906 #if VPP_API_TEST_BUILTIN == 0
20907   longjmp (vam->jump_buf, 1);
20908 #endif
20909   return 0;                     /* not so much */
20910 }
20911
20912 static int
20913 q (vat_main_t * vam)
20914 {
20915   return q_or_quit (vam);
20916 }
20917
20918 static int
20919 quit (vat_main_t * vam)
20920 {
20921   return q_or_quit (vam);
20922 }
20923
20924 static int
20925 comment (vat_main_t * vam)
20926 {
20927   return 0;
20928 }
20929
20930 static int
20931 elog_save (vat_main_t * vam)
20932 {
20933 #if VPP_API_TEST_BUILTIN == 0
20934   elog_main_t *em = &vam->elog_main;
20935   unformat_input_t *i = vam->input;
20936   char *file, *chroot_file;
20937   clib_error_t *error;
20938
20939   if (!unformat (i, "%s", &file))
20940     {
20941       errmsg ("expected file name, got `%U'", format_unformat_error, i);
20942       return 0;
20943     }
20944
20945   /* It's fairly hard to get "../oopsie" through unformat; just in case */
20946   if (strstr (file, "..") || index (file, '/'))
20947     {
20948       errmsg ("illegal characters in filename '%s'", file);
20949       return 0;
20950     }
20951
20952   chroot_file = (char *) format (0, "/tmp/%s%c", file, 0);
20953
20954   vec_free (file);
20955
20956   errmsg ("Saving %wd of %wd events to %s",
20957           elog_n_events_in_buffer (em),
20958           elog_buffer_capacity (em), chroot_file);
20959
20960   error = elog_write_file (em, chroot_file, 1 /* flush ring */ );
20961   vec_free (chroot_file);
20962
20963   if (error)
20964     clib_error_report (error);
20965 #else
20966   errmsg ("Use the vpp event loger...");
20967 #endif
20968
20969   return 0;
20970 }
20971
20972 static int
20973 elog_setup (vat_main_t * vam)
20974 {
20975 #if VPP_API_TEST_BUILTIN == 0
20976   elog_main_t *em = &vam->elog_main;
20977   unformat_input_t *i = vam->input;
20978   u32 nevents = 128 << 10;
20979
20980   (void) unformat (i, "nevents %d", &nevents);
20981
20982   elog_init (em, nevents);
20983   vl_api_set_elog_main (em);
20984   vl_api_set_elog_trace_api_messages (1);
20985   errmsg ("Event logger initialized with %u events", nevents);
20986 #else
20987   errmsg ("Use the vpp event loger...");
20988 #endif
20989   return 0;
20990 }
20991
20992 static int
20993 elog_enable (vat_main_t * vam)
20994 {
20995 #if VPP_API_TEST_BUILTIN == 0
20996   elog_main_t *em = &vam->elog_main;
20997
20998   elog_enable_disable (em, 1 /* enable */ );
20999   vl_api_set_elog_trace_api_messages (1);
21000   errmsg ("Event logger enabled...");
21001 #else
21002   errmsg ("Use the vpp event loger...");
21003 #endif
21004   return 0;
21005 }
21006
21007 static int
21008 elog_disable (vat_main_t * vam)
21009 {
21010 #if VPP_API_TEST_BUILTIN == 0
21011   elog_main_t *em = &vam->elog_main;
21012
21013   elog_enable_disable (em, 0 /* enable */ );
21014   vl_api_set_elog_trace_api_messages (1);
21015   errmsg ("Event logger disabled...");
21016 #else
21017   errmsg ("Use the vpp event loger...");
21018 #endif
21019   return 0;
21020 }
21021
21022 static int
21023 statseg (vat_main_t * vam)
21024 {
21025   ssvm_private_t *ssvmp = &vam->stat_segment;
21026   ssvm_shared_header_t *shared_header = ssvmp->sh;
21027   vlib_counter_t **counters;
21028   u64 thread0_index1_packets;
21029   u64 thread0_index1_bytes;
21030   f64 vector_rate, input_rate;
21031   uword *p;
21032
21033   uword *counter_vector_by_name;
21034   if (vam->stat_segment_lockp == 0)
21035     {
21036       errmsg ("Stat segment not mapped...");
21037       return -99;
21038     }
21039
21040   /* look up "/if/rx for sw_if_index 1 as a test */
21041
21042   clib_spinlock_lock (vam->stat_segment_lockp);
21043
21044   counter_vector_by_name = (uword *) shared_header->opaque[1];
21045
21046   p = hash_get_mem (counter_vector_by_name, "/if/rx");
21047   if (p == 0)
21048     {
21049       clib_spinlock_unlock (vam->stat_segment_lockp);
21050       errmsg ("/if/tx not found?");
21051       return -99;
21052     }
21053
21054   /* Fish per-thread vector of combined counters from shared memory */
21055   counters = (vlib_counter_t **) p[0];
21056
21057   if (vec_len (counters[0]) < 2)
21058     {
21059       clib_spinlock_unlock (vam->stat_segment_lockp);
21060       errmsg ("/if/tx vector length %d", vec_len (counters[0]));
21061       return -99;
21062     }
21063
21064   /* Read thread 0 sw_if_index 1 counter */
21065   thread0_index1_packets = counters[0][1].packets;
21066   thread0_index1_bytes = counters[0][1].bytes;
21067
21068   p = hash_get_mem (counter_vector_by_name, "vector_rate");
21069   if (p == 0)
21070     {
21071       clib_spinlock_unlock (vam->stat_segment_lockp);
21072       errmsg ("vector_rate not found?");
21073       return -99;
21074     }
21075
21076   vector_rate = *(f64 *) (p[0]);
21077   p = hash_get_mem (counter_vector_by_name, "input_rate");
21078   if (p == 0)
21079     {
21080       clib_spinlock_unlock (vam->stat_segment_lockp);
21081       errmsg ("input_rate not found?");
21082       return -99;
21083     }
21084   input_rate = *(f64 *) (p[0]);
21085
21086   clib_spinlock_unlock (vam->stat_segment_lockp);
21087
21088   print (vam->ofp, "vector_rate %.2f input_rate %.2f",
21089          vector_rate, input_rate);
21090   print (vam->ofp, "thread 0 sw_if_index 1 rx pkts %lld, bytes %lld",
21091          thread0_index1_packets, thread0_index1_bytes);
21092
21093   return 0;
21094 }
21095
21096 static int
21097 cmd_cmp (void *a1, void *a2)
21098 {
21099   u8 **c1 = a1;
21100   u8 **c2 = a2;
21101
21102   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
21103 }
21104
21105 static int
21106 help (vat_main_t * vam)
21107 {
21108   u8 **cmds = 0;
21109   u8 *name = 0;
21110   hash_pair_t *p;
21111   unformat_input_t *i = vam->input;
21112   int j;
21113
21114   if (unformat (i, "%s", &name))
21115     {
21116       uword *hs;
21117
21118       vec_add1 (name, 0);
21119
21120       hs = hash_get_mem (vam->help_by_name, name);
21121       if (hs)
21122         print (vam->ofp, "usage: %s %s", name, hs[0]);
21123       else
21124         print (vam->ofp, "No such msg / command '%s'", name);
21125       vec_free (name);
21126       return 0;
21127     }
21128
21129   print (vam->ofp, "Help is available for the following:");
21130
21131     /* *INDENT-OFF* */
21132     hash_foreach_pair (p, vam->function_by_name,
21133     ({
21134       vec_add1 (cmds, (u8 *)(p->key));
21135     }));
21136     /* *INDENT-ON* */
21137
21138   vec_sort_with_function (cmds, cmd_cmp);
21139
21140   for (j = 0; j < vec_len (cmds); j++)
21141     print (vam->ofp, "%s", cmds[j]);
21142
21143   vec_free (cmds);
21144   return 0;
21145 }
21146
21147 static int
21148 set (vat_main_t * vam)
21149 {
21150   u8 *name = 0, *value = 0;
21151   unformat_input_t *i = vam->input;
21152
21153   if (unformat (i, "%s", &name))
21154     {
21155       /* The input buffer is a vector, not a string. */
21156       value = vec_dup (i->buffer);
21157       vec_delete (value, i->index, 0);
21158       /* Almost certainly has a trailing newline */
21159       if (value[vec_len (value) - 1] == '\n')
21160         value[vec_len (value) - 1] = 0;
21161       /* Make sure it's a proper string, one way or the other */
21162       vec_add1 (value, 0);
21163       (void) clib_macro_set_value (&vam->macro_main,
21164                                    (char *) name, (char *) value);
21165     }
21166   else
21167     errmsg ("usage: set <name> <value>");
21168
21169   vec_free (name);
21170   vec_free (value);
21171   return 0;
21172 }
21173
21174 static int
21175 unset (vat_main_t * vam)
21176 {
21177   u8 *name = 0;
21178
21179   if (unformat (vam->input, "%s", &name))
21180     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
21181       errmsg ("unset: %s wasn't set", name);
21182   vec_free (name);
21183   return 0;
21184 }
21185
21186 typedef struct
21187 {
21188   u8 *name;
21189   u8 *value;
21190 } macro_sort_t;
21191
21192
21193 static int
21194 macro_sort_cmp (void *a1, void *a2)
21195 {
21196   macro_sort_t *s1 = a1;
21197   macro_sort_t *s2 = a2;
21198
21199   return strcmp ((char *) (s1->name), (char *) (s2->name));
21200 }
21201
21202 static int
21203 dump_macro_table (vat_main_t * vam)
21204 {
21205   macro_sort_t *sort_me = 0, *sm;
21206   int i;
21207   hash_pair_t *p;
21208
21209     /* *INDENT-OFF* */
21210     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
21211     ({
21212       vec_add2 (sort_me, sm, 1);
21213       sm->name = (u8 *)(p->key);
21214       sm->value = (u8 *) (p->value[0]);
21215     }));
21216     /* *INDENT-ON* */
21217
21218   vec_sort_with_function (sort_me, macro_sort_cmp);
21219
21220   if (vec_len (sort_me))
21221     print (vam->ofp, "%-15s%s", "Name", "Value");
21222   else
21223     print (vam->ofp, "The macro table is empty...");
21224
21225   for (i = 0; i < vec_len (sort_me); i++)
21226     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
21227   return 0;
21228 }
21229
21230 static int
21231 dump_node_table (vat_main_t * vam)
21232 {
21233   int i, j;
21234   vlib_node_t *node, *next_node;
21235
21236   if (vec_len (vam->graph_nodes) == 0)
21237     {
21238       print (vam->ofp, "Node table empty, issue get_node_graph...");
21239       return 0;
21240     }
21241
21242   for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
21243     {
21244       node = vam->graph_nodes[0][i];
21245       print (vam->ofp, "[%d] %s", i, node->name);
21246       for (j = 0; j < vec_len (node->next_nodes); j++)
21247         {
21248           if (node->next_nodes[j] != ~0)
21249             {
21250               next_node = vam->graph_nodes[0][node->next_nodes[j]];
21251               print (vam->ofp, "  [%d] %s", j, next_node->name);
21252             }
21253         }
21254     }
21255   return 0;
21256 }
21257
21258 static int
21259 value_sort_cmp (void *a1, void *a2)
21260 {
21261   name_sort_t *n1 = a1;
21262   name_sort_t *n2 = a2;
21263
21264   if (n1->value < n2->value)
21265     return -1;
21266   if (n1->value > n2->value)
21267     return 1;
21268   return 0;
21269 }
21270
21271
21272 static int
21273 dump_msg_api_table (vat_main_t * vam)
21274 {
21275   api_main_t *am = &api_main;
21276   name_sort_t *nses = 0, *ns;
21277   hash_pair_t *hp;
21278   int i;
21279
21280   /* *INDENT-OFF* */
21281   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
21282   ({
21283     vec_add2 (nses, ns, 1);
21284     ns->name = (u8 *)(hp->key);
21285     ns->value = (u32) hp->value[0];
21286   }));
21287   /* *INDENT-ON* */
21288
21289   vec_sort_with_function (nses, value_sort_cmp);
21290
21291   for (i = 0; i < vec_len (nses); i++)
21292     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
21293   vec_free (nses);
21294   return 0;
21295 }
21296
21297 static int
21298 get_msg_id (vat_main_t * vam)
21299 {
21300   u8 *name_and_crc;
21301   u32 message_index;
21302
21303   if (unformat (vam->input, "%s", &name_and_crc))
21304     {
21305       message_index = vl_msg_api_get_msg_index (name_and_crc);
21306       if (message_index == ~0)
21307         {
21308           print (vam->ofp, " '%s' not found", name_and_crc);
21309           return 0;
21310         }
21311       print (vam->ofp, " '%s' has message index %d",
21312              name_and_crc, message_index);
21313       return 0;
21314     }
21315   errmsg ("name_and_crc required...");
21316   return 0;
21317 }
21318
21319 static int
21320 search_node_table (vat_main_t * vam)
21321 {
21322   unformat_input_t *line_input = vam->input;
21323   u8 *node_to_find;
21324   int j;
21325   vlib_node_t *node, *next_node;
21326   uword *p;
21327
21328   if (vam->graph_node_index_by_name == 0)
21329     {
21330       print (vam->ofp, "Node table empty, issue get_node_graph...");
21331       return 0;
21332     }
21333
21334   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
21335     {
21336       if (unformat (line_input, "%s", &node_to_find))
21337         {
21338           vec_add1 (node_to_find, 0);
21339           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
21340           if (p == 0)
21341             {
21342               print (vam->ofp, "%s not found...", node_to_find);
21343               goto out;
21344             }
21345           node = vam->graph_nodes[0][p[0]];
21346           print (vam->ofp, "[%d] %s", p[0], node->name);
21347           for (j = 0; j < vec_len (node->next_nodes); j++)
21348             {
21349               if (node->next_nodes[j] != ~0)
21350                 {
21351                   next_node = vam->graph_nodes[0][node->next_nodes[j]];
21352                   print (vam->ofp, "  [%d] %s", j, next_node->name);
21353                 }
21354             }
21355         }
21356
21357       else
21358         {
21359           clib_warning ("parse error '%U'", format_unformat_error,
21360                         line_input);
21361           return -99;
21362         }
21363
21364     out:
21365       vec_free (node_to_find);
21366
21367     }
21368
21369   return 0;
21370 }
21371
21372
21373 static int
21374 script (vat_main_t * vam)
21375 {
21376 #if (VPP_API_TEST_BUILTIN==0)
21377   u8 *s = 0;
21378   char *save_current_file;
21379   unformat_input_t save_input;
21380   jmp_buf save_jump_buf;
21381   u32 save_line_number;
21382
21383   FILE *new_fp, *save_ifp;
21384
21385   if (unformat (vam->input, "%s", &s))
21386     {
21387       new_fp = fopen ((char *) s, "r");
21388       if (new_fp == 0)
21389         {
21390           errmsg ("Couldn't open script file %s", s);
21391           vec_free (s);
21392           return -99;
21393         }
21394     }
21395   else
21396     {
21397       errmsg ("Missing script name");
21398       return -99;
21399     }
21400
21401   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
21402   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
21403   save_ifp = vam->ifp;
21404   save_line_number = vam->input_line_number;
21405   save_current_file = (char *) vam->current_file;
21406
21407   vam->input_line_number = 0;
21408   vam->ifp = new_fp;
21409   vam->current_file = s;
21410   do_one_file (vam);
21411
21412   clib_memcpy (&vam->input, &save_input, sizeof (save_input));
21413   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
21414   vam->ifp = save_ifp;
21415   vam->input_line_number = save_line_number;
21416   vam->current_file = (u8 *) save_current_file;
21417   vec_free (s);
21418
21419   return 0;
21420 #else
21421   clib_warning ("use the exec command...");
21422   return -99;
21423 #endif
21424 }
21425
21426 static int
21427 echo (vat_main_t * vam)
21428 {
21429   print (vam->ofp, "%v", vam->input->buffer);
21430   return 0;
21431 }
21432
21433 /* List of API message constructors, CLI names map to api_xxx */
21434 #define foreach_vpe_api_msg                                             \
21435 _(create_loopback,"[mac <mac-addr>] [instance <instance>]")             \
21436 _(sw_interface_dump,"")                                                 \
21437 _(sw_interface_set_flags,                                               \
21438   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
21439 _(sw_interface_add_del_address,                                         \
21440   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
21441 _(sw_interface_set_rx_mode,                                             \
21442   "<intfc> | sw_if_index <id> [queue <id>] <polling | interrupt | adaptive>") \
21443 _(sw_interface_set_rx_placement,                                        \
21444   "<intfc> | sw_if_index <id> [queue <id>] [worker <id> | main]")       \
21445 _(sw_interface_rx_placement_dump,                                       \
21446   "[<intfc> | sw_if_index <id>]")                                         \
21447 _(sw_interface_set_table,                                               \
21448   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
21449 _(sw_interface_set_mpls_enable,                                         \
21450   "<intfc> | sw_if_index [disable | dis]")                              \
21451 _(sw_interface_set_vpath,                                               \
21452   "<intfc> | sw_if_index <id> enable | disable")                        \
21453 _(sw_interface_set_vxlan_bypass,                                        \
21454   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
21455 _(sw_interface_set_geneve_bypass,                                       \
21456   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
21457 _(sw_interface_set_l2_xconnect,                                         \
21458   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
21459   "enable | disable")                                                   \
21460 _(sw_interface_set_l2_bridge,                                           \
21461   "{<intfc> | sw_if_index <id>} bd_id <bridge-domain-id>\n"             \
21462   "[shg <split-horizon-group>] [bvi]\n"                                 \
21463   "enable | disable")                                                   \
21464 _(bridge_domain_set_mac_age, "bd_id <bridge-domain-id> mac-age 0-255")  \
21465 _(bridge_domain_add_del,                                                \
21466   "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") \
21467 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
21468 _(l2fib_add_del,                                                        \
21469   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
21470 _(l2fib_flush_bd, "bd_id <bridge-domain-id>")                           \
21471 _(l2fib_flush_int, "<intfc> | sw_if_index <id>")                        \
21472 _(l2_flags,                                                             \
21473   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
21474 _(bridge_flags,                                                         \
21475   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
21476 _(tap_create_v2,                                                        \
21477   "id <num> [hw-addr <mac-addr>] [host-ns <name>] [rx-ring-size <num> [tx-ring-size <num>] [host-mtu-size <mtu>] [gso | no-gso]") \
21478 _(tap_delete_v2,                                                        \
21479   "<vpp-if-name> | sw_if_index <id>")                                   \
21480 _(sw_interface_tap_v2_dump, "")                                         \
21481 _(virtio_pci_create,                                                    \
21482   "pci-addr <pci-address> [use_random_mac | hw-addr <mac-addr>] [features <hex-value>] [gso-enabled]") \
21483 _(virtio_pci_delete,                                                    \
21484   "<vpp-if-name> | sw_if_index <id>")                                   \
21485 _(sw_interface_virtio_pci_dump, "")                                     \
21486 _(bond_create,                                                          \
21487   "[hw-addr <mac-addr>] {round-robin | active-backup | "                \
21488   "broadcast | {lacp | xor} [load-balance { l2 | l23 | l34 }]} "        \
21489   "[id <if-id>]")                                                       \
21490 _(bond_delete,                                                          \
21491   "<vpp-if-name> | sw_if_index <id>")                                   \
21492 _(bond_enslave,                                                         \
21493   "sw_if_index <n> bond <sw_if_index> [is_passive] [is_long_timeout]")  \
21494 _(bond_detach_slave,                                                    \
21495   "sw_if_index <n>")                                                    \
21496  _(sw_interface_set_bond_weight, "<intfc> | sw_if_index <nn> weight <value>") \
21497 _(sw_interface_bond_dump, "")                                           \
21498 _(sw_interface_slave_dump,                                              \
21499   "<vpp-if-name> | sw_if_index <id>")                                   \
21500 _(ip_table_add_del,                                                     \
21501   "table <n> [ipv6] [add | del]\n")                                     \
21502 _(ip_route_add_del,                                                     \
21503   "<addr>/<mask> via <<addr>|<intfc>|sw_if_index <id>|via-label <n>>\n" \
21504   "[table-id <n>] [<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"\
21505   "[weight <n>] [drop] [local] [classify <n>]  [out-label <n>]\n"       \
21506   "[multipath] [count <n>] [del]")                                      \
21507 _(ip_mroute_add_del,                                                    \
21508   "<src> <grp>/<mask> [table-id <n>]\n"                                 \
21509   "[<intfc> | sw_if_index <id>] [local] [del]")                         \
21510 _(mpls_table_add_del,                                                   \
21511   "table <n> [add | del]\n")                                            \
21512 _(mpls_route_add_del,                                                   \
21513   "<label> <eos> via <addr | next-hop-table <n> | via-label <n> |\n"    \
21514   "lookup-ip4-table <n> | lookup-in-ip6-table <n> |\n"                  \
21515   "l2-input-on <intfc> | l2-input-on sw_if_index <id>>\n"               \
21516   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>] [weight <n>]\n"  \
21517   "[drop] [local] [classify <n>] [out-label <n>] [multipath]\n"         \
21518   "[count <n>] [del]")                                                  \
21519 _(mpls_ip_bind_unbind,                                                  \
21520   "<label> <addr/len>")                                                 \
21521 _(mpls_tunnel_add_del,                                                  \
21522   "[add | del <intfc | sw_if_index <id>>] via <addr | via-label <n>>\n" \
21523   "[<intfc> | sw_if_index <id> | next-hop-table <id>]\n"                \
21524   "[l2-only]  [out-label <n>]")                                         \
21525 _(sr_mpls_policy_add,                                                   \
21526   "bsid <id> [weight <n>] [spray] next <sid> [next <sid>]")             \
21527 _(sr_mpls_policy_del,                                                   \
21528   "bsid <id>")                                                          \
21529 _(bier_table_add_del,                                                   \
21530   "<label> <sub-domain> <set> <bsl> [del]")                             \
21531 _(bier_route_add_del,                                                   \
21532   "<bit-position> <sub-domain> <set> <bsl> via <addr> [table-id <n>]\n" \
21533   "[<intfc> | sw_if_index <id>]"                                        \
21534   "[weight <n>] [del] [multipath]")                                     \
21535 _(proxy_arp_add_del,                                                    \
21536   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
21537 _(proxy_arp_intfc_enable_disable,                                       \
21538   "<intfc> | sw_if_index <id> enable | disable")                        \
21539 _(sw_interface_set_unnumbered,                                          \
21540   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
21541 _(ip_neighbor_add_del,                                                  \
21542   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
21543   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
21544 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
21545 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
21546   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
21547   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
21548   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
21549 _(reset_fib, "vrf <n> [ipv6]")                                          \
21550 _(set_ip_flow_hash,                                                     \
21551   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
21552 _(sw_interface_ip6_enable_disable,                                      \
21553   "<intfc> | sw_if_index <id> enable | disable")                        \
21554 _(ip6nd_proxy_add_del,                                                  \
21555   "<intfc> | sw_if_index <id> <ip6-address>")                           \
21556 _(ip6nd_proxy_dump, "")                                                 \
21557 _(sw_interface_ip6nd_ra_prefix,                                         \
21558   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
21559   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
21560   "[nolink] [isno]")                                                    \
21561 _(sw_interface_ip6nd_ra_config,                                         \
21562   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
21563   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
21564   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
21565 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
21566 _(l2_patch_add_del,                                                     \
21567   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
21568   "enable | disable")                                                   \
21569 _(sr_localsid_add_del,                                                  \
21570   "(del) address <addr> next_hop <addr> behavior <beh>\n"               \
21571   "fib-table <num> (end.psp) sw_if_index <num>")                        \
21572 _(classify_add_del_table,                                               \
21573   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
21574   " [del] [del-chain] mask <mask-value>\n"                              \
21575   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
21576   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
21577 _(classify_add_del_session,                                             \
21578   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
21579   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
21580   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
21581   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
21582 _(classify_set_interface_ip_table,                                      \
21583   "<intfc> | sw_if_index <nn> table <nn>")                              \
21584 _(classify_set_interface_l2_tables,                                     \
21585   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
21586   "  [other-table <nn>]")                                               \
21587 _(get_node_index, "node <node-name")                                    \
21588 _(add_node_next, "node <node-name> next <next-node-name>")              \
21589 _(l2tpv3_create_tunnel,                                                 \
21590   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
21591   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
21592   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
21593 _(l2tpv3_set_tunnel_cookies,                                            \
21594   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
21595   "[new_remote_cookie <nn>]\n")                                         \
21596 _(l2tpv3_interface_enable_disable,                                      \
21597   "<intfc> | sw_if_index <nn> enable | disable")                        \
21598 _(l2tpv3_set_lookup_key,                                                \
21599   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
21600 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
21601 _(vxlan_offload_rx,                                                     \
21602   "hw { <interface name> | hw_if_index <nn>} "                          \
21603   "rx { <vxlan tunnel name> | sw_if_index <nn> } [del]")                \
21604 _(vxlan_add_del_tunnel,                                                 \
21605   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
21606   "{ <intfc> | mcast_sw_if_index <nn> } [instance <id>]}\n"             \
21607   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
21608 _(geneve_add_del_tunnel,                                                \
21609   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
21610   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
21611   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
21612 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
21613 _(geneve_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                   \
21614 _(gre_tunnel_add_del,                                                   \
21615   "src <ip-addr> dst <ip-addr> [outer-fib-id <nn>] [instance <n>]\n"    \
21616   "[teb | erspan <session-id>] [del]")                                  \
21617 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
21618 _(l2_fib_clear_table, "")                                               \
21619 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
21620 _(l2_interface_vlan_tag_rewrite,                                        \
21621   "<intfc> | sw_if_index <nn> \n"                                       \
21622   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
21623   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
21624 _(create_vhost_user_if,                                                 \
21625         "socket <filename> [server] [renumber <dev_instance>] "         \
21626         "[disable_mrg_rxbuf] [disable_indirect_desc] [gso] "            \
21627         "[mac <mac_address>]")                                          \
21628 _(modify_vhost_user_if,                                                 \
21629         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
21630         "[server] [renumber <dev_instance>] [gso]")                     \
21631 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
21632 _(sw_interface_vhost_user_dump, "")                                     \
21633 _(show_version, "")                                                     \
21634 _(show_threads, "")                                                     \
21635 _(vxlan_gpe_add_del_tunnel,                                             \
21636   "local <addr> remote <addr>  | group <mcast-ip-addr>\n"               \
21637   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
21638   "vni <nn> [encap-vrf-id <nn>] [decap-vrf-id <nn>]\n"                  \
21639   "[next-ip4][next-ip6][next-ethernet] [next-nsh] [del]\n")             \
21640 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
21641 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
21642 _(interface_name_renumber,                                              \
21643   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
21644 _(input_acl_set_interface,                                              \
21645   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
21646   "  [l2-table <nn>] [del]")                                            \
21647 _(ip_probe_neighbor, "(<intc> | sw_if_index <nn>) address <ip4|ip6-addr>") \
21648 _(ip_scan_neighbor_enable_disable, "[ip4|ip6|both|disable] [interval <n-min>]\n" \
21649   "  [max-time <n-usec>] [max-update <n>] [delay <n-msec>] [stale <n-min>]") \
21650 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
21651 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
21652 _(want_l2_macs_events, "[disable] [learn-limit <n>] [scan-delay <n>] [max-entries <n>]") \
21653 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
21654 _(ip_dump, "ipv4 | ipv6")                                               \
21655 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
21656 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
21657   "  spid_id <n> ")                                                     \
21658 _(ipsec_sad_entry_add_del, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
21659   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
21660   "  integ_alg <alg> integ_key <hex>")                                  \
21661 _(ipsec_spd_entry_add_del, "spd_id <n> priority <n> action <action>\n"  \
21662   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
21663   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
21664   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
21665 _(ipsec_tunnel_if_add_del, "local_spi <n> remote_spi <n>\n"             \
21666   "  crypto_alg <alg> local_crypto_key <hex> remote_crypto_key <hex>\n" \
21667   "  integ_alg <alg> local_integ_key <hex> remote_integ_key <hex>\n"    \
21668   "  local_ip <addr> remote_ip <addr> [esn] [anti_replay] [del]\n"      \
21669   "  [instance <n>]")     \
21670 _(ipsec_sa_dump, "[sa_id <n>]")                                         \
21671 _(ipsec_tunnel_if_set_sa, "<intfc> sa_id <n> <inbound|outbound>\n")     \
21672 _(delete_loopback,"sw_if_index <nn>")                                   \
21673 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
21674 _(bd_ip_mac_flush, "bd_id <bridge-domain-id>")                          \
21675 _(bd_ip_mac_dump, "[bd_id] <bridge-domain-id>")                         \
21676 _(want_interface_events,  "enable|disable")                             \
21677 _(get_first_msg_id, "client <name>")                                    \
21678 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
21679 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
21680   "fib-id <nn> [ip4][ip6][default]")                                    \
21681 _(get_node_graph, " ")                                                  \
21682 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
21683 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
21684 _(ioam_disable, "")                                                     \
21685 _(one_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
21686                             " sw_if_index <sw_if_index> p <priority> "  \
21687                             "w <weight>] [del]")                        \
21688 _(one_add_del_locator, "locator-set <locator_name> "                    \
21689                         "iface <intf> | sw_if_index <sw_if_index> "     \
21690                         "p <priority> w <weight> [del]")                \
21691 _(one_add_del_local_eid,"vni <vni> eid "                                \
21692                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
21693                          "locator-set <locator_name> [del]"             \
21694                          "[key-id sha1|sha256 secret-key <secret-key>]")\
21695 _(one_add_del_map_resolver, "<ip4|6-addr> [del]")                       \
21696 _(one_add_del_map_server, "<ip4|6-addr> [del]")                         \
21697 _(one_enable_disable, "enable|disable")                                 \
21698 _(one_map_register_enable_disable, "enable|disable")                    \
21699 _(one_map_register_fallback_threshold, "<value>")                       \
21700 _(one_rloc_probe_enable_disable, "enable|disable")                      \
21701 _(one_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "       \
21702                                "[seid <seid>] "                         \
21703                                "rloc <locator> p <prio> "               \
21704                                "w <weight> [rloc <loc> ... ] "          \
21705                                "action <action> [del-all]")             \
21706 _(one_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "    \
21707                           "<local-eid>")                                \
21708 _(one_pitr_set_locator_set, "locator-set <loc-set-name> | del")         \
21709 _(one_use_petr, "ip-address> | disable")                                \
21710 _(one_map_request_mode, "src-dst|dst-only")                             \
21711 _(one_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")            \
21712 _(one_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")               \
21713 _(one_locator_set_dump, "[local | remote]")                             \
21714 _(one_locator_dump, "ls_index <index> | ls_name <name>")                \
21715 _(one_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "       \
21716                        "[local] | [remote]")                            \
21717 _(one_add_del_ndp_entry, "[del] mac <mac> bd <bd> ip6 <ip6>")           \
21718 _(one_ndp_bd_get, "")                                                   \
21719 _(one_ndp_entries_get, "bd <bridge-domain>")                            \
21720 _(one_add_del_l2_arp_entry, "[del] mac <mac> bd <bd> ip4 <ip4>")        \
21721 _(one_l2_arp_bd_get, "")                                                \
21722 _(one_l2_arp_entries_get, "bd <bridge-domain>")                         \
21723 _(one_stats_enable_disable, "enable|disable")                           \
21724 _(show_one_stats_enable_disable, "")                                    \
21725 _(one_eid_table_vni_dump, "")                                           \
21726 _(one_eid_table_map_dump, "l2|l3")                                      \
21727 _(one_map_resolver_dump, "")                                            \
21728 _(one_map_server_dump, "")                                              \
21729 _(one_adjacencies_get, "vni <vni>")                                     \
21730 _(one_nsh_set_locator_set, "[del] ls <locator-set-name>")               \
21731 _(show_one_rloc_probe_state, "")                                        \
21732 _(show_one_map_register_state, "")                                      \
21733 _(show_one_status, "")                                                  \
21734 _(one_stats_dump, "")                                                   \
21735 _(one_stats_flush, "")                                                  \
21736 _(one_get_map_request_itr_rlocs, "")                                    \
21737 _(one_map_register_set_ttl, "<ttl>")                                    \
21738 _(one_set_transport_protocol, "udp|api")                                \
21739 _(one_get_transport_protocol, "")                                       \
21740 _(one_enable_disable_xtr_mode, "enable|disable")                        \
21741 _(one_show_xtr_mode, "")                                                \
21742 _(one_enable_disable_pitr_mode, "enable|disable")                       \
21743 _(one_show_pitr_mode, "")                                               \
21744 _(one_enable_disable_petr_mode, "enable|disable")                       \
21745 _(one_show_petr_mode, "")                                               \
21746 _(show_one_nsh_mapping, "")                                             \
21747 _(show_one_pitr, "")                                                    \
21748 _(show_one_use_petr, "")                                                \
21749 _(show_one_map_request_mode, "")                                        \
21750 _(show_one_map_register_ttl, "")                                        \
21751 _(show_one_map_register_fallback_threshold, "")                         \
21752 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
21753                             " sw_if_index <sw_if_index> p <priority> "  \
21754                             "w <weight>] [del]")                        \
21755 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
21756                         "iface <intf> | sw_if_index <sw_if_index> "     \
21757                         "p <priority> w <weight> [del]")                \
21758 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
21759                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
21760                          "locator-set <locator_name> [del]"             \
21761                          "[key-id sha1|sha256 secret-key <secret-key>]") \
21762 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
21763 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
21764 _(lisp_enable_disable, "enable|disable")                                \
21765 _(lisp_map_register_enable_disable, "enable|disable")                   \
21766 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
21767 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
21768                                "[seid <seid>] "                         \
21769                                "rloc <locator> p <prio> "               \
21770                                "w <weight> [rloc <loc> ... ] "          \
21771                                "action <action> [del-all]")             \
21772 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
21773                           "<local-eid>")                                \
21774 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
21775 _(lisp_use_petr, "<ip-address> | disable")                              \
21776 _(lisp_map_request_mode, "src-dst|dst-only")                            \
21777 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
21778 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
21779 _(lisp_locator_set_dump, "[local | remote]")                            \
21780 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
21781 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
21782                        "[local] | [remote]")                            \
21783 _(lisp_eid_table_vni_dump, "")                                          \
21784 _(lisp_eid_table_map_dump, "l2|l3")                                     \
21785 _(lisp_map_resolver_dump, "")                                           \
21786 _(lisp_map_server_dump, "")                                             \
21787 _(lisp_adjacencies_get, "vni <vni>")                                    \
21788 _(gpe_fwd_entry_vnis_get, "")                                           \
21789 _(gpe_native_fwd_rpaths_get, "ip4 | ip6")                               \
21790 _(gpe_add_del_native_fwd_rpath, "[del] via <nh-ip-addr> [iface] "       \
21791                                 "[table <table-id>]")                   \
21792 _(lisp_gpe_fwd_entries_get, "vni <vni>")                                \
21793 _(lisp_gpe_fwd_entry_path_dump, "index <fwd_entry_index>")              \
21794 _(gpe_set_encap_mode, "lisp|vxlan")                                     \
21795 _(gpe_get_encap_mode, "")                                               \
21796 _(lisp_gpe_add_del_iface, "up|down")                                    \
21797 _(lisp_gpe_enable_disable, "enable|disable")                            \
21798 _(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>"       \
21799   "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
21800 _(show_lisp_rloc_probe_state, "")                                       \
21801 _(show_lisp_map_register_state, "")                                     \
21802 _(show_lisp_status, "")                                                 \
21803 _(lisp_get_map_request_itr_rlocs, "")                                   \
21804 _(show_lisp_pitr, "")                                                   \
21805 _(show_lisp_use_petr, "")                                               \
21806 _(show_lisp_map_request_mode, "")                                       \
21807 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
21808 _(af_packet_delete, "name <host interface name>")                       \
21809 _(af_packet_dump, "")                                                   \
21810 _(policer_add_del, "name <policer name> <params> [del]")                \
21811 _(policer_dump, "[name <policer name>]")                                \
21812 _(policer_classify_set_interface,                                       \
21813   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
21814   "  [l2-table <nn>] [del]")                                            \
21815 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
21816 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
21817     "[master|slave]")                                                   \
21818 _(netmap_delete, "name <interface name>")                               \
21819 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
21820 _(mpls_table_dump, "")                                                  \
21821 _(mpls_route_dump, "table-id <ID>")                                     \
21822 _(classify_table_ids, "")                                               \
21823 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
21824 _(classify_table_info, "table_id <nn>")                                 \
21825 _(classify_session_dump, "table_id <nn>")                               \
21826 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
21827     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
21828     "[template_interval <nn>] [udp_checksum]")                          \
21829 _(ipfix_exporter_dump, "")                                              \
21830 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
21831 _(ipfix_classify_stream_dump, "")                                       \
21832 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
21833 _(ipfix_classify_table_dump, "")                                        \
21834 _(sw_interface_span_enable_disable, "[l2] [src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
21835 _(sw_interface_span_dump, "[l2]")                                           \
21836 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
21837 _(pg_create_interface, "if_id <nn> [gso-enabled gso-size <size>]")      \
21838 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
21839 _(pg_enable_disable, "[stream <id>] disable")                           \
21840 _(ip_source_and_port_range_check_add_del,                               \
21841   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
21842 _(ip_source_and_port_range_check_interface_add_del,                     \
21843   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
21844   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
21845 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
21846 _(l2_interface_pbb_tag_rewrite,                                         \
21847   "<intfc> | sw_if_index <nn> \n"                                       \
21848   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
21849   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
21850 _(set_punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
21851 _(flow_classify_set_interface,                                          \
21852   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
21853 _(flow_classify_dump, "type [ip4|ip6]")                                 \
21854 _(ip_table_dump, "")                                                    \
21855 _(ip_route_dump, "table-id [ip4|ip6]")                                  \
21856 _(ip_mtable_dump, "")                                                   \
21857 _(ip_mroute_dump, "table-id [ip4|ip6]")                                 \
21858 _(feature_enable_disable, "arc_name <arc_name> "                        \
21859   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
21860 _(feature_gso_enable_disable, "<intfc> | sw_if_index <nn> "             \
21861   "[enable | disable] ")                                                \
21862 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
21863 "[disable]")                                                            \
21864 _(sw_interface_add_del_mac_address, "<intfc> | sw_if_index <nn> "       \
21865   "mac <mac-address> [del]")                                            \
21866 _(l2_xconnect_dump, "")                                                 \
21867 _(hw_interface_set_mtu, "<intfc> | hw_if_index <nn> mtu <nn>")        \
21868 _(ip_neighbor_dump, "[ip6] <intfc> | sw_if_index <nn>")                 \
21869 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")          \
21870 _(p2p_ethernet_add, "<intfc> | sw_if_index <nn> remote_mac <mac-address> sub_id <id>") \
21871 _(p2p_ethernet_del, "<intfc> | sw_if_index <nn> remote_mac <mac-address>") \
21872 _(lldp_config, "system-name <name> tx-hold <nn> tx-interval <nn>") \
21873 _(sw_interface_set_lldp, "<intfc> | sw_if_index <nn> [port-desc <description>]\n" \
21874   " [mgmt-ip4 <ip4>] [mgmt-ip6 <ip6>] [mgmt-oid <object id>] [disable]") \
21875 _(tcp_configure_src_addresses, "<ip4|6>first-<ip4|6>last [vrf <id>]")   \
21876 _(sock_init_shm, "size <nnn>")                                          \
21877 _(app_namespace_add_del, "[add] id <ns-id> secret <nn> sw_if_index <nn>")\
21878 _(session_rule_add_del, "[add|del] proto <tcp/udp> <lcl-ip>/<plen> "    \
21879   "<lcl-port> <rmt-ip>/<plen> <rmt-port> action <nn>")                  \
21880 _(session_rules_dump, "")                                               \
21881 _(ip_container_proxy_add_del, "[add|del] <address> <sw_if_index>")      \
21882 _(output_acl_set_interface,                                             \
21883   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
21884   "  [l2-table <nn>] [del]")                                            \
21885 _(qos_record_enable_disable, "<record-source> <intfc> | sw_if_index <id> [disable]")
21886
21887 /* List of command functions, CLI names map directly to functions */
21888 #define foreach_cli_function                                    \
21889 _(comment, "usage: comment <ignore-rest-of-line>")              \
21890 _(dump_interface_table, "usage: dump_interface_table")          \
21891 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
21892 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
21893 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
21894 _(dump_macro_table, "usage: dump_macro_table ")                 \
21895 _(dump_node_table, "usage: dump_node_table")                    \
21896 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
21897 _(elog_setup, "usage: elog_setup [nevents, default 128K]")      \
21898 _(elog_disable, "usage: elog_disable")                          \
21899 _(elog_enable, "usage: elog_enable")                            \
21900 _(elog_save, "usage: elog_save <filename>")                     \
21901 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
21902 _(echo, "usage: echo <message>")                                \
21903 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
21904 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
21905 _(help, "usage: help")                                          \
21906 _(q, "usage: quit")                                             \
21907 _(quit, "usage: quit")                                          \
21908 _(search_node_table, "usage: search_node_table <name>...")      \
21909 _(set, "usage: set <variable-name> <value>")                    \
21910 _(script, "usage: script <file-name>")                          \
21911 _(statseg, "usage: statseg")                                    \
21912 _(unset, "usage: unset <variable-name>")
21913
21914 #define _(N,n)                                  \
21915     static void vl_api_##n##_t_handler_uni      \
21916     (vl_api_##n##_t * mp)                       \
21917     {                                           \
21918         vat_main_t * vam = &vat_main;           \
21919         if (vam->json_output) {                 \
21920             vl_api_##n##_t_handler_json(mp);    \
21921         } else {                                \
21922             vl_api_##n##_t_handler(mp);         \
21923         }                                       \
21924     }
21925 foreach_vpe_api_reply_msg;
21926 #if VPP_API_TEST_BUILTIN == 0
21927 foreach_standalone_reply_msg;
21928 #endif
21929 #undef _
21930
21931 void
21932 vat_api_hookup (vat_main_t * vam)
21933 {
21934 #define _(N,n)                                                  \
21935     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
21936                            vl_api_##n##_t_handler_uni,          \
21937                            vl_noop_handler,                     \
21938                            vl_api_##n##_t_endian,               \
21939                            vl_api_##n##_t_print,                \
21940                            sizeof(vl_api_##n##_t), 1);
21941   foreach_vpe_api_reply_msg;
21942 #if VPP_API_TEST_BUILTIN == 0
21943   foreach_standalone_reply_msg;
21944 #endif
21945 #undef _
21946
21947 #if (VPP_API_TEST_BUILTIN==0)
21948   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
21949
21950   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
21951
21952   vam->function_by_name = hash_create_string (0, sizeof (uword));
21953
21954   vam->help_by_name = hash_create_string (0, sizeof (uword));
21955 #endif
21956
21957   /* API messages we can send */
21958 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
21959   foreach_vpe_api_msg;
21960 #undef _
21961
21962   /* Help strings */
21963 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
21964   foreach_vpe_api_msg;
21965 #undef _
21966
21967   /* CLI functions */
21968 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
21969   foreach_cli_function;
21970 #undef _
21971
21972   /* Help strings */
21973 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
21974   foreach_cli_function;
21975 #undef _
21976 }
21977
21978 #if VPP_API_TEST_BUILTIN
21979 static clib_error_t *
21980 vat_api_hookup_shim (vlib_main_t * vm)
21981 {
21982   vat_api_hookup (&vat_main);
21983   return 0;
21984 }
21985
21986 VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
21987 #endif
21988
21989 /*
21990  * fd.io coding-style-patch-verification: ON
21991  *
21992  * Local Variables:
21993  * eval: (c-set-style "gnu")
21994  * End:
21995  */