devices: tap API cleanup
[vpp.git] / src / vat / api_format.c
1 /*
2  *------------------------------------------------------------------
3  * api_format.c
4  *
5  * Copyright (c) 2014-2016 Cisco and/or its affiliates.
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at:
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *------------------------------------------------------------------
18  */
19
20 #include <vat/vat.h>
21 #include <vlib/pci/pci.h>
22 #include <vpp/api/types.h>
23 #include <vppinfra/socket.h>
24 #include <vlibapi/api.h>
25 #include <vlibmemory/api.h>
26 #include <vnet/ip/ip.h>
27 #include <vnet/ip/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 = vlibapi_get_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 = vlibapi_get_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 = vlibapi_get_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_table_replace_begin_reply)                         \
5075 _(ip_table_flush_reply)                                 \
5076 _(ip_table_replace_end_reply)                           \
5077 _(ip_mroute_add_del_reply)                              \
5078 _(mpls_route_add_del_reply)                             \
5079 _(mpls_table_add_del_reply)                             \
5080 _(mpls_ip_bind_unbind_reply)                            \
5081 _(bier_route_add_del_reply)                             \
5082 _(bier_table_add_del_reply)                             \
5083 _(proxy_arp_add_del_reply)                              \
5084 _(proxy_arp_intfc_enable_disable_reply)                 \
5085 _(sw_interface_set_unnumbered_reply)                    \
5086 _(ip_neighbor_add_del_reply)                            \
5087 _(set_ip_flow_hash_reply)                               \
5088 _(sw_interface_ip6_enable_disable_reply)                \
5089 _(ip6nd_proxy_add_del_reply)                            \
5090 _(sw_interface_ip6nd_ra_prefix_reply)                   \
5091 _(sw_interface_ip6nd_ra_config_reply)                   \
5092 _(set_arp_neighbor_limit_reply)                         \
5093 _(l2_patch_add_del_reply)                               \
5094 _(sr_mpls_policy_add_reply)                             \
5095 _(sr_mpls_policy_mod_reply)                             \
5096 _(sr_mpls_policy_del_reply)                             \
5097 _(sr_policy_add_reply)                                  \
5098 _(sr_policy_mod_reply)                                  \
5099 _(sr_policy_del_reply)                                  \
5100 _(sr_localsid_add_del_reply)                            \
5101 _(sr_steering_add_del_reply)                            \
5102 _(classify_add_del_session_reply)                       \
5103 _(classify_set_interface_ip_table_reply)                \
5104 _(classify_set_interface_l2_tables_reply)               \
5105 _(l2tpv3_set_tunnel_cookies_reply)                      \
5106 _(l2tpv3_interface_enable_disable_reply)                \
5107 _(l2tpv3_set_lookup_key_reply)                          \
5108 _(l2_fib_clear_table_reply)                             \
5109 _(l2_interface_efp_filter_reply)                        \
5110 _(l2_interface_vlan_tag_rewrite_reply)                  \
5111 _(modify_vhost_user_if_reply)                           \
5112 _(delete_vhost_user_if_reply)                           \
5113 _(ip_probe_neighbor_reply)                              \
5114 _(ip_scan_neighbor_enable_disable_reply)                \
5115 _(want_ip4_arp_events_reply)                            \
5116 _(want_ip6_nd_events_reply)                             \
5117 _(want_l2_macs_events_reply)                            \
5118 _(input_acl_set_interface_reply)                        \
5119 _(ipsec_spd_add_del_reply)                              \
5120 _(ipsec_interface_add_del_spd_reply)                    \
5121 _(ipsec_spd_entry_add_del_reply)                        \
5122 _(ipsec_sad_entry_add_del_reply)                        \
5123 _(ipsec_tunnel_if_add_del_reply)                        \
5124 _(ipsec_tunnel_if_set_sa_reply)                         \
5125 _(delete_loopback_reply)                                \
5126 _(bd_ip_mac_add_del_reply)                              \
5127 _(bd_ip_mac_flush_reply)                                \
5128 _(want_interface_events_reply)                          \
5129 _(cop_interface_enable_disable_reply)                   \
5130 _(cop_whitelist_enable_disable_reply)                   \
5131 _(sw_interface_clear_stats_reply)                       \
5132 _(ioam_enable_reply)                                    \
5133 _(ioam_disable_reply)                                   \
5134 _(one_add_del_locator_reply)                            \
5135 _(one_add_del_local_eid_reply)                          \
5136 _(one_add_del_remote_mapping_reply)                     \
5137 _(one_add_del_adjacency_reply)                          \
5138 _(one_add_del_map_resolver_reply)                       \
5139 _(one_add_del_map_server_reply)                         \
5140 _(one_enable_disable_reply)                             \
5141 _(one_rloc_probe_enable_disable_reply)                  \
5142 _(one_map_register_enable_disable_reply)                \
5143 _(one_map_register_set_ttl_reply)                       \
5144 _(one_set_transport_protocol_reply)                     \
5145 _(one_map_register_fallback_threshold_reply)            \
5146 _(one_pitr_set_locator_set_reply)                       \
5147 _(one_map_request_mode_reply)                           \
5148 _(one_add_del_map_request_itr_rlocs_reply)              \
5149 _(one_eid_table_add_del_map_reply)                      \
5150 _(one_use_petr_reply)                                   \
5151 _(one_stats_enable_disable_reply)                       \
5152 _(one_add_del_l2_arp_entry_reply)                       \
5153 _(one_add_del_ndp_entry_reply)                          \
5154 _(one_stats_flush_reply)                                \
5155 _(one_enable_disable_xtr_mode_reply)                    \
5156 _(one_enable_disable_pitr_mode_reply)                   \
5157 _(one_enable_disable_petr_mode_reply)                   \
5158 _(gpe_enable_disable_reply)                             \
5159 _(gpe_set_encap_mode_reply)                             \
5160 _(gpe_add_del_iface_reply)                              \
5161 _(gpe_add_del_native_fwd_rpath_reply)                   \
5162 _(af_packet_delete_reply)                               \
5163 _(policer_classify_set_interface_reply)                 \
5164 _(netmap_create_reply)                                  \
5165 _(netmap_delete_reply)                                  \
5166 _(set_ipfix_exporter_reply)                             \
5167 _(set_ipfix_classify_stream_reply)                      \
5168 _(ipfix_classify_table_add_del_reply)                   \
5169 _(flow_classify_set_interface_reply)                    \
5170 _(sw_interface_span_enable_disable_reply)               \
5171 _(pg_capture_reply)                                     \
5172 _(pg_enable_disable_reply)                              \
5173 _(ip_source_and_port_range_check_add_del_reply)         \
5174 _(ip_source_and_port_range_check_interface_add_del_reply)\
5175 _(delete_subif_reply)                                   \
5176 _(l2_interface_pbb_tag_rewrite_reply)                   \
5177 _(set_punt_reply)                                       \
5178 _(feature_enable_disable_reply)                         \
5179 _(feature_gso_enable_disable_reply)                     \
5180 _(sw_interface_tag_add_del_reply)                       \
5181 _(sw_interface_add_del_mac_address_reply)               \
5182 _(hw_interface_set_mtu_reply)                           \
5183 _(p2p_ethernet_add_reply)                               \
5184 _(p2p_ethernet_del_reply)                               \
5185 _(lldp_config_reply)                                    \
5186 _(sw_interface_set_lldp_reply)                          \
5187 _(tcp_configure_src_addresses_reply)                    \
5188 _(session_rule_add_del_reply)                           \
5189 _(ip_container_proxy_add_del_reply)                     \
5190 _(output_acl_set_interface_reply)                       \
5191 _(qos_record_enable_disable_reply)
5192
5193 #define _(n)                                    \
5194     static void vl_api_##n##_t_handler          \
5195     (vl_api_##n##_t * mp)                       \
5196     {                                           \
5197         vat_main_t * vam = &vat_main;           \
5198         i32 retval = ntohl(mp->retval);         \
5199         if (vam->async_mode) {                  \
5200             vam->async_errors += (retval < 0);  \
5201         } else {                                \
5202             vam->retval = retval;               \
5203             vam->result_ready = 1;              \
5204         }                                       \
5205     }
5206 foreach_standard_reply_retval_handler;
5207 #undef _
5208
5209 #define _(n)                                    \
5210     static void vl_api_##n##_t_handler_json     \
5211     (vl_api_##n##_t * mp)                       \
5212     {                                           \
5213         vat_main_t * vam = &vat_main;           \
5214         vat_json_node_t node;                   \
5215         vat_json_init_object(&node);            \
5216         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
5217         vat_json_print(vam->ofp, &node);        \
5218         vam->retval = ntohl(mp->retval);        \
5219         vam->result_ready = 1;                  \
5220     }
5221 foreach_standard_reply_retval_handler;
5222 #undef _
5223
5224 /*
5225  * Table of message reply handlers, must include boilerplate handlers
5226  * we just generated
5227  */
5228
5229 #define foreach_vpe_api_reply_msg                                       \
5230 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
5231 _(CREATE_LOOPBACK_INSTANCE_REPLY, create_loopback_instance_reply)       \
5232 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
5233 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
5234 _(CONTROL_PING_REPLY, control_ping_reply)                               \
5235 _(CLI_REPLY, cli_reply)                                                 \
5236 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
5237 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
5238   sw_interface_add_del_address_reply)                                   \
5239 _(SW_INTERFACE_SET_RX_MODE_REPLY, sw_interface_set_rx_mode_reply)       \
5240 _(SW_INTERFACE_SET_RX_PLACEMENT_REPLY, sw_interface_set_rx_placement_reply)     \
5241 _(SW_INTERFACE_RX_PLACEMENT_DETAILS, sw_interface_rx_placement_details) \
5242 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
5243 _(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
5244 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
5245 _(SW_INTERFACE_SET_VXLAN_BYPASS_REPLY, sw_interface_set_vxlan_bypass_reply) \
5246 _(SW_INTERFACE_SET_GENEVE_BYPASS_REPLY, sw_interface_set_geneve_bypass_reply) \
5247 _(SW_INTERFACE_SET_VXLAN_GPE_BYPASS_REPLY, sw_interface_set_vxlan_gpe_bypass_reply) \
5248 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
5249   sw_interface_set_l2_xconnect_reply)                                   \
5250 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
5251   sw_interface_set_l2_bridge_reply)                                     \
5252 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
5253 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
5254 _(BRIDGE_DOMAIN_SET_MAC_AGE_REPLY, bridge_domain_set_mac_age_reply)     \
5255 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
5256 _(L2FIB_FLUSH_INT_REPLY, l2fib_flush_int_reply)                         \
5257 _(L2FIB_FLUSH_BD_REPLY, l2fib_flush_bd_reply)                           \
5258 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
5259 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
5260 _(TAP_CREATE_V2_REPLY, tap_create_v2_reply)                             \
5261 _(TAP_DELETE_V2_REPLY, tap_delete_v2_reply)                             \
5262 _(SW_INTERFACE_TAP_V2_DETAILS, sw_interface_tap_v2_details)             \
5263 _(VIRTIO_PCI_CREATE_REPLY, virtio_pci_create_reply)                     \
5264 _(VIRTIO_PCI_DELETE_REPLY, virtio_pci_delete_reply)                     \
5265 _(SW_INTERFACE_VIRTIO_PCI_DETAILS, sw_interface_virtio_pci_details)     \
5266 _(BOND_CREATE_REPLY, bond_create_reply)                                 \
5267 _(BOND_DELETE_REPLY, bond_delete_reply)                                 \
5268 _(BOND_ENSLAVE_REPLY, bond_enslave_reply)                               \
5269 _(BOND_DETACH_SLAVE_REPLY, bond_detach_slave_reply)                     \
5270 _(SW_INTERFACE_SET_BOND_WEIGHT_REPLY, sw_interface_set_bond_weight_reply) \
5271 _(SW_INTERFACE_BOND_DETAILS, sw_interface_bond_details)                 \
5272 _(SW_INTERFACE_SLAVE_DETAILS, sw_interface_slave_details)               \
5273 _(IP_ROUTE_ADD_DEL_REPLY, ip_route_add_del_reply)                       \
5274 _(IP_TABLE_ADD_DEL_REPLY, ip_table_add_del_reply)                       \
5275 _(IP_TABLE_REPLACE_BEGIN_REPLY, ip_table_replace_begin_reply)           \
5276 _(IP_TABLE_FLUSH_REPLY, ip_table_flush_reply)                           \
5277 _(IP_TABLE_REPLACE_END_REPLY, ip_table_replace_end_reply)               \
5278 _(IP_MROUTE_ADD_DEL_REPLY, ip_mroute_add_del_reply)                     \
5279 _(MPLS_TABLE_ADD_DEL_REPLY, mpls_table_add_del_reply)                   \
5280 _(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply)                   \
5281 _(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply)                 \
5282 _(BIER_ROUTE_ADD_DEL_REPLY, bier_route_add_del_reply)                   \
5283 _(BIER_TABLE_ADD_DEL_REPLY, bier_table_add_del_reply)                   \
5284 _(PROXY_ARP_ADD_DEL_REPLY, proxy_arp_add_del_reply)                     \
5285 _(PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY,                                 \
5286   proxy_arp_intfc_enable_disable_reply)                                 \
5287 _(MPLS_TUNNEL_ADD_DEL_REPLY, mpls_tunnel_add_del_reply)                 \
5288 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
5289   sw_interface_set_unnumbered_reply)                                    \
5290 _(IP_NEIGHBOR_ADD_DEL_REPLY, ip_neighbor_add_del_reply)                 \
5291 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
5292 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
5293 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
5294 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
5295   sw_interface_ip6_enable_disable_reply)                                \
5296 _(IP6ND_PROXY_ADD_DEL_REPLY, ip6nd_proxy_add_del_reply)                 \
5297 _(IP6ND_PROXY_DETAILS, ip6nd_proxy_details)                             \
5298 _(SW_INTERFACE_IP6ND_RA_PREFIX_REPLY,                                   \
5299   sw_interface_ip6nd_ra_prefix_reply)                                   \
5300 _(SW_INTERFACE_IP6ND_RA_CONFIG_REPLY,                                   \
5301   sw_interface_ip6nd_ra_config_reply)                                   \
5302 _(SET_ARP_NEIGHBOR_LIMIT_REPLY, set_arp_neighbor_limit_reply)           \
5303 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
5304 _(SR_MPLS_POLICY_ADD_REPLY, sr_mpls_policy_add_reply)                   \
5305 _(SR_MPLS_POLICY_MOD_REPLY, sr_mpls_policy_mod_reply)                   \
5306 _(SR_MPLS_POLICY_DEL_REPLY, sr_mpls_policy_del_reply)                   \
5307 _(SR_POLICY_ADD_REPLY, sr_policy_add_reply)                             \
5308 _(SR_POLICY_MOD_REPLY, sr_policy_mod_reply)                             \
5309 _(SR_POLICY_DEL_REPLY, sr_policy_del_reply)                             \
5310 _(SR_LOCALSID_ADD_DEL_REPLY, sr_localsid_add_del_reply)                 \
5311 _(SR_STEERING_ADD_DEL_REPLY, sr_steering_add_del_reply)                 \
5312 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
5313 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
5314 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
5315 classify_set_interface_ip_table_reply)                                  \
5316 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
5317   classify_set_interface_l2_tables_reply)                               \
5318 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
5319 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
5320 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
5321 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
5322 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
5323   l2tpv3_interface_enable_disable_reply)                                \
5324 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
5325 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
5326 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
5327 _(VXLAN_OFFLOAD_RX_REPLY, vxlan_offload_rx_reply)               \
5328 _(GENEVE_ADD_DEL_TUNNEL_REPLY, geneve_add_del_tunnel_reply)             \
5329 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
5330 _(GENEVE_TUNNEL_DETAILS, geneve_tunnel_details)                         \
5331 _(GRE_TUNNEL_ADD_DEL_REPLY, gre_tunnel_add_del_reply)                   \
5332 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
5333 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
5334 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
5335 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
5336 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
5337 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
5338 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
5339 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
5340 _(SHOW_VERSION_REPLY, show_version_reply)                               \
5341 _(SHOW_THREADS_REPLY, show_threads_reply)                               \
5342 _(L2_FIB_TABLE_DETAILS, l2_fib_table_details)                           \
5343 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)       \
5344 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
5345 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
5346 _(IP_PROBE_NEIGHBOR_REPLY, ip_probe_neighbor_reply)                     \
5347 _(IP_SCAN_NEIGHBOR_ENABLE_DISABLE_REPLY, ip_scan_neighbor_enable_disable_reply) \
5348 _(WANT_IP4_ARP_EVENTS_REPLY, want_ip4_arp_events_reply)                 \
5349 _(IP4_ARP_EVENT, ip4_arp_event)                                         \
5350 _(WANT_IP6_ND_EVENTS_REPLY, want_ip6_nd_events_reply)                   \
5351 _(IP6_ND_EVENT, ip6_nd_event)                                           \
5352 _(WANT_L2_MACS_EVENTS_REPLY, want_l2_macs_events_reply)                 \
5353 _(L2_MACS_EVENT, l2_macs_event)                                         \
5354 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
5355 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
5356 _(IP_DETAILS, ip_details)                                               \
5357 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
5358 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
5359 _(IPSEC_SPD_ENTRY_ADD_DEL_REPLY, ipsec_spd_entry_add_del_reply)         \
5360 _(IPSEC_SAD_ENTRY_ADD_DEL_REPLY, ipsec_sad_entry_add_del_reply)         \
5361 _(IPSEC_SA_DETAILS, ipsec_sa_details)                                   \
5362 _(IPSEC_TUNNEL_IF_ADD_DEL_REPLY, ipsec_tunnel_if_add_del_reply)         \
5363 _(IPSEC_TUNNEL_IF_SET_SA_REPLY, ipsec_tunnel_if_set_sa_reply)           \
5364 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
5365 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
5366 _(BD_IP_MAC_FLUSH_REPLY, bd_ip_mac_flush_reply)                         \
5367 _(BD_IP_MAC_DETAILS, bd_ip_mac_details)                                 \
5368 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
5369 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
5370 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
5371 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
5372 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
5373 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
5374 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
5375 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
5376 _(ONE_ADD_DEL_LOCATOR_SET_REPLY, one_add_del_locator_set_reply)         \
5377 _(ONE_ADD_DEL_LOCATOR_REPLY, one_add_del_locator_reply)                 \
5378 _(ONE_ADD_DEL_LOCAL_EID_REPLY, one_add_del_local_eid_reply)             \
5379 _(ONE_ADD_DEL_REMOTE_MAPPING_REPLY, one_add_del_remote_mapping_reply)   \
5380 _(ONE_ADD_DEL_ADJACENCY_REPLY, one_add_del_adjacency_reply)             \
5381 _(ONE_ADD_DEL_MAP_RESOLVER_REPLY, one_add_del_map_resolver_reply)       \
5382 _(ONE_ADD_DEL_MAP_SERVER_REPLY, one_add_del_map_server_reply)           \
5383 _(ONE_ENABLE_DISABLE_REPLY, one_enable_disable_reply)                   \
5384 _(ONE_MAP_REGISTER_ENABLE_DISABLE_REPLY,                                \
5385   one_map_register_enable_disable_reply)                                \
5386 _(ONE_MAP_REGISTER_SET_TTL_REPLY, one_map_register_set_ttl_reply)       \
5387 _(ONE_SET_TRANSPORT_PROTOCOL_REPLY, one_set_transport_protocol_reply)   \
5388 _(ONE_GET_TRANSPORT_PROTOCOL_REPLY, one_get_transport_protocol_reply)   \
5389 _(ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                            \
5390   one_map_register_fallback_threshold_reply)                            \
5391 _(ONE_RLOC_PROBE_ENABLE_DISABLE_REPLY,                                  \
5392   one_rloc_probe_enable_disable_reply)                                  \
5393 _(ONE_PITR_SET_LOCATOR_SET_REPLY, one_pitr_set_locator_set_reply)       \
5394 _(ONE_USE_PETR_REPLY, one_use_petr_reply)                               \
5395 _(ONE_MAP_REQUEST_MODE_REPLY, one_map_request_mode_reply)               \
5396 _(ONE_EID_TABLE_ADD_DEL_MAP_REPLY, one_eid_table_add_del_map_reply)     \
5397 _(ONE_LOCATOR_SET_DETAILS, one_locator_set_details)                     \
5398 _(ONE_LOCATOR_DETAILS, one_locator_details)                             \
5399 _(ONE_EID_TABLE_DETAILS, one_eid_table_details)                         \
5400 _(ONE_EID_TABLE_MAP_DETAILS, one_eid_table_map_details)                 \
5401 _(ONE_EID_TABLE_VNI_DETAILS, one_eid_table_vni_details)                 \
5402 _(ONE_MAP_RESOLVER_DETAILS, one_map_resolver_details)                   \
5403 _(ONE_MAP_SERVER_DETAILS, one_map_server_details)                       \
5404 _(ONE_ADJACENCIES_GET_REPLY, one_adjacencies_get_reply)                 \
5405 _(ONE_STATS_DETAILS, one_stats_details)                                 \
5406 _(ONE_STATS_FLUSH_REPLY, one_stats_flush_reply)                         \
5407 _(ONE_STATS_ENABLE_DISABLE_REPLY, one_stats_enable_disable_reply)       \
5408 _(SHOW_ONE_STATS_ENABLE_DISABLE_REPLY,                                  \
5409   show_one_stats_enable_disable_reply)                                  \
5410 _(ONE_ADD_DEL_NDP_ENTRY_REPLY, one_add_del_ndp_entry_reply)             \
5411 _(ONE_NDP_BD_GET_REPLY, one_ndp_bd_get_reply)                           \
5412 _(ONE_NDP_ENTRIES_GET_REPLY, one_ndp_entries_get_reply)                 \
5413 _(ONE_ADD_DEL_L2_ARP_ENTRY_REPLY, one_add_del_l2_arp_entry_reply)       \
5414 _(ONE_L2_ARP_BD_GET_REPLY, one_l2_arp_bd_get_reply)                     \
5415 _(ONE_L2_ARP_ENTRIES_GET_REPLY, one_l2_arp_entries_get_reply)           \
5416 _(ONE_ENABLE_DISABLE_XTR_MODE_REPLY, one_enable_disable_xtr_mode_reply) \
5417 _(ONE_ENABLE_DISABLE_PITR_MODE_REPLY,                                   \
5418   one_enable_disable_pitr_mode_reply)                                   \
5419 _(ONE_ENABLE_DISABLE_PETR_MODE_REPLY,                                   \
5420   one_enable_disable_petr_mode_reply)                                   \
5421 _(ONE_SHOW_XTR_MODE_REPLY, one_show_xtr_mode_reply)                     \
5422 _(ONE_SHOW_PITR_MODE_REPLY, one_show_pitr_mode_reply)                   \
5423 _(ONE_SHOW_PETR_MODE_REPLY, one_show_petr_mode_reply)                   \
5424 _(GPE_SET_ENCAP_MODE_REPLY, gpe_set_encap_mode_reply)                   \
5425 _(GPE_GET_ENCAP_MODE_REPLY, gpe_get_encap_mode_reply)                   \
5426 _(GPE_ADD_DEL_IFACE_REPLY, gpe_add_del_iface_reply)                     \
5427 _(GPE_ENABLE_DISABLE_REPLY, gpe_enable_disable_reply)                   \
5428 _(GPE_ADD_DEL_FWD_ENTRY_REPLY, gpe_add_del_fwd_entry_reply)             \
5429 _(GPE_FWD_ENTRY_VNIS_GET_REPLY, gpe_fwd_entry_vnis_get_reply)           \
5430 _(GPE_FWD_ENTRIES_GET_REPLY, gpe_fwd_entries_get_reply)                 \
5431 _(GPE_NATIVE_FWD_RPATHS_GET_REPLY, gpe_native_fwd_rpaths_get_reply)     \
5432 _(GPE_ADD_DEL_NATIVE_FWD_RPATH_REPLY,                                   \
5433   gpe_add_del_native_fwd_rpath_reply)                                   \
5434 _(GPE_FWD_ENTRY_PATH_DETAILS,                                           \
5435   gpe_fwd_entry_path_details)                                           \
5436 _(SHOW_ONE_STATUS_REPLY, show_one_status_reply)                         \
5437 _(ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                              \
5438   one_add_del_map_request_itr_rlocs_reply)                              \
5439 _(ONE_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                  \
5440   one_get_map_request_itr_rlocs_reply)                                  \
5441 _(SHOW_ONE_NSH_MAPPING_REPLY, show_one_nsh_mapping_reply)               \
5442 _(SHOW_ONE_PITR_REPLY, show_one_pitr_reply)                             \
5443 _(SHOW_ONE_USE_PETR_REPLY, show_one_use_petr_reply)                     \
5444 _(SHOW_ONE_MAP_REQUEST_MODE_REPLY, show_one_map_request_mode_reply)     \
5445 _(SHOW_ONE_RLOC_PROBE_STATE_REPLY, show_one_rloc_probe_state_reply)     \
5446 _(SHOW_ONE_MAP_REGISTER_STATE_REPLY,                                    \
5447   show_one_map_register_state_reply)                                    \
5448 _(SHOW_ONE_MAP_REGISTER_TTL_REPLY, show_one_map_register_ttl_reply)     \
5449 _(SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                       \
5450   show_one_map_register_fallback_threshold_reply)                       \
5451 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
5452 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
5453 _(AF_PACKET_DETAILS, af_packet_details)                                 \
5454 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
5455 _(POLICER_DETAILS, policer_details)                                     \
5456 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
5457 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
5458 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
5459 _(NETMAP_DELETE_REPLY, netmap_delete_reply)                             \
5460 _(MPLS_TUNNEL_DETAILS, mpls_tunnel_details)                             \
5461 _(MPLS_TABLE_DETAILS, mpls_table_details)                               \
5462 _(MPLS_ROUTE_DETAILS, mpls_route_details)                               \
5463 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
5464 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
5465 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
5466 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
5467 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
5468 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
5469 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
5470 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
5471 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
5472 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
5473 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
5474 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
5475 _(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
5476 _(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details)                 \
5477 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
5478 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
5479 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
5480 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
5481 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
5482  ip_source_and_port_range_check_add_del_reply)                          \
5483 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
5484  ip_source_and_port_range_check_interface_add_del_reply)                \
5485 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
5486 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
5487 _(SET_PUNT_REPLY, set_punt_reply)                                       \
5488 _(IP_TABLE_DETAILS, ip_table_details)                                   \
5489 _(IP_ROUTE_DETAILS, ip_route_details)                                   \
5490 _(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply)           \
5491 _(FEATURE_GSO_ENABLE_DISABLE_REPLY, feature_gso_enable_disable_reply)   \
5492 _(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply)       \
5493 _(SW_INTERFACE_ADD_DEL_MAC_ADDRESS_REPLY, sw_interface_add_del_mac_address_reply) \
5494 _(L2_XCONNECT_DETAILS, l2_xconnect_details)                             \
5495 _(HW_INTERFACE_SET_MTU_REPLY, hw_interface_set_mtu_reply)               \
5496 _(IP_NEIGHBOR_DETAILS, ip_neighbor_details)                             \
5497 _(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply)           \
5498 _(P2P_ETHERNET_ADD_REPLY, p2p_ethernet_add_reply)                       \
5499 _(P2P_ETHERNET_DEL_REPLY, p2p_ethernet_del_reply)                       \
5500 _(LLDP_CONFIG_REPLY, lldp_config_reply)                                 \
5501 _(SW_INTERFACE_SET_LLDP_REPLY, sw_interface_set_lldp_reply)             \
5502 _(TCP_CONFIGURE_SRC_ADDRESSES_REPLY, tcp_configure_src_addresses_reply) \
5503 _(APP_NAMESPACE_ADD_DEL_REPLY, app_namespace_add_del_reply)             \
5504 _(SESSION_RULE_ADD_DEL_REPLY, session_rule_add_del_reply)               \
5505 _(SESSION_RULES_DETAILS, session_rules_details)                         \
5506 _(IP_CONTAINER_PROXY_ADD_DEL_REPLY, ip_container_proxy_add_del_reply)   \
5507 _(OUTPUT_ACL_SET_INTERFACE_REPLY, output_acl_set_interface_reply)       \
5508 _(QOS_RECORD_ENABLE_DISABLE_REPLY, qos_record_enable_disable_reply)
5509
5510 #define foreach_standalone_reply_msg                                    \
5511 _(SW_INTERFACE_EVENT, sw_interface_event)
5512
5513 typedef struct
5514 {
5515   u8 *name;
5516   u32 value;
5517 } name_sort_t;
5518
5519 #define STR_VTR_OP_CASE(op)     \
5520     case L2_VTR_ ## op:         \
5521         return "" # op;
5522
5523 static const char *
5524 str_vtr_op (u32 vtr_op)
5525 {
5526   switch (vtr_op)
5527     {
5528       STR_VTR_OP_CASE (DISABLED);
5529       STR_VTR_OP_CASE (PUSH_1);
5530       STR_VTR_OP_CASE (PUSH_2);
5531       STR_VTR_OP_CASE (POP_1);
5532       STR_VTR_OP_CASE (POP_2);
5533       STR_VTR_OP_CASE (TRANSLATE_1_1);
5534       STR_VTR_OP_CASE (TRANSLATE_1_2);
5535       STR_VTR_OP_CASE (TRANSLATE_2_1);
5536       STR_VTR_OP_CASE (TRANSLATE_2_2);
5537     }
5538
5539   return "UNKNOWN";
5540 }
5541
5542 static int
5543 dump_sub_interface_table (vat_main_t * vam)
5544 {
5545   const sw_interface_subif_t *sub = NULL;
5546
5547   if (vam->json_output)
5548     {
5549       clib_warning
5550         ("JSON output supported only for VPE API calls and dump_stats_table");
5551       return -99;
5552     }
5553
5554   print (vam->ofp,
5555          "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
5556          "Interface", "sw_if_index",
5557          "sub id", "dot1ad", "tags", "outer id",
5558          "inner id", "exact", "default", "outer any", "inner any");
5559
5560   vec_foreach (sub, vam->sw_if_subif_table)
5561   {
5562     print (vam->ofp,
5563            "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
5564            sub->interface_name,
5565            sub->sw_if_index,
5566            sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
5567            sub->sub_number_of_tags, sub->sub_outer_vlan_id,
5568            sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
5569            sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
5570     if (sub->vtr_op != L2_VTR_DISABLED)
5571       {
5572         print (vam->ofp,
5573                "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
5574                "tag1: %d tag2: %d ]",
5575                str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
5576                sub->vtr_tag1, sub->vtr_tag2);
5577       }
5578   }
5579
5580   return 0;
5581 }
5582
5583 static int
5584 name_sort_cmp (void *a1, void *a2)
5585 {
5586   name_sort_t *n1 = a1;
5587   name_sort_t *n2 = a2;
5588
5589   return strcmp ((char *) n1->name, (char *) n2->name);
5590 }
5591
5592 static int
5593 dump_interface_table (vat_main_t * vam)
5594 {
5595   hash_pair_t *p;
5596   name_sort_t *nses = 0, *ns;
5597
5598   if (vam->json_output)
5599     {
5600       clib_warning
5601         ("JSON output supported only for VPE API calls and dump_stats_table");
5602       return -99;
5603     }
5604
5605   /* *INDENT-OFF* */
5606   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5607   ({
5608     vec_add2 (nses, ns, 1);
5609     ns->name = (u8 *)(p->key);
5610     ns->value = (u32) p->value[0];
5611   }));
5612   /* *INDENT-ON* */
5613
5614   vec_sort_with_function (nses, name_sort_cmp);
5615
5616   print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
5617   vec_foreach (ns, nses)
5618   {
5619     print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
5620   }
5621   vec_free (nses);
5622   return 0;
5623 }
5624
5625 static int
5626 dump_ip_table (vat_main_t * vam, int is_ipv6)
5627 {
5628   const ip_details_t *det = NULL;
5629   const ip_address_details_t *address = NULL;
5630   u32 i = ~0;
5631
5632   print (vam->ofp, "%-12s", "sw_if_index");
5633
5634   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
5635   {
5636     i++;
5637     if (!det->present)
5638       {
5639         continue;
5640       }
5641     print (vam->ofp, "%-12d", i);
5642     print (vam->ofp, "            %-30s%-13s", "Address", "Prefix length");
5643     if (!det->addr)
5644       {
5645         continue;
5646       }
5647     vec_foreach (address, det->addr)
5648     {
5649       print (vam->ofp,
5650              "            %-30U%-13d",
5651              is_ipv6 ? format_ip6_address : format_ip4_address,
5652              address->ip, address->prefix_length);
5653     }
5654   }
5655
5656   return 0;
5657 }
5658
5659 static int
5660 dump_ipv4_table (vat_main_t * vam)
5661 {
5662   if (vam->json_output)
5663     {
5664       clib_warning
5665         ("JSON output supported only for VPE API calls and dump_stats_table");
5666       return -99;
5667     }
5668
5669   return dump_ip_table (vam, 0);
5670 }
5671
5672 static int
5673 dump_ipv6_table (vat_main_t * vam)
5674 {
5675   if (vam->json_output)
5676     {
5677       clib_warning
5678         ("JSON output supported only for VPE API calls and dump_stats_table");
5679       return -99;
5680     }
5681
5682   return dump_ip_table (vam, 1);
5683 }
5684
5685 /*
5686  * Pass CLI buffers directly in the CLI_INBAND API message,
5687  * instead of an additional shared memory area.
5688  */
5689 static int
5690 exec_inband (vat_main_t * vam)
5691 {
5692   vl_api_cli_inband_t *mp;
5693   unformat_input_t *i = vam->input;
5694   int ret;
5695
5696   if (vec_len (i->buffer) == 0)
5697     return -1;
5698
5699   if (vam->exec_mode == 0 && unformat (i, "mode"))
5700     {
5701       vam->exec_mode = 1;
5702       return 0;
5703     }
5704   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
5705     {
5706       vam->exec_mode = 0;
5707       return 0;
5708     }
5709
5710   /*
5711    * In order for the CLI command to work, it
5712    * must be a vector ending in \n, not a C-string ending
5713    * in \n\0.
5714    */
5715   u32 len = vec_len (vam->input->buffer);
5716   M2 (CLI_INBAND, mp, len);
5717   vl_api_to_api_string (len - 1, (const char *) vam->input->buffer, &mp->cmd);
5718
5719   S (mp);
5720   W (ret);
5721   /* json responses may or may not include a useful reply... */
5722   if (vec_len (vam->cmd_reply))
5723     print (vam->ofp, "%v", (char *) (vam->cmd_reply));
5724   return ret;
5725 }
5726
5727 int
5728 exec (vat_main_t * vam)
5729 {
5730   return exec_inband (vam);
5731 }
5732
5733 static int
5734 api_create_loopback (vat_main_t * vam)
5735 {
5736   unformat_input_t *i = vam->input;
5737   vl_api_create_loopback_t *mp;
5738   vl_api_create_loopback_instance_t *mp_lbi;
5739   u8 mac_address[6];
5740   u8 mac_set = 0;
5741   u8 is_specified = 0;
5742   u32 user_instance = 0;
5743   int ret;
5744
5745   clib_memset (mac_address, 0, sizeof (mac_address));
5746
5747   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5748     {
5749       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5750         mac_set = 1;
5751       if (unformat (i, "instance %d", &user_instance))
5752         is_specified = 1;
5753       else
5754         break;
5755     }
5756
5757   if (is_specified)
5758     {
5759       M (CREATE_LOOPBACK_INSTANCE, mp_lbi);
5760       mp_lbi->is_specified = is_specified;
5761       if (is_specified)
5762         mp_lbi->user_instance = htonl (user_instance);
5763       if (mac_set)
5764         clib_memcpy (mp_lbi->mac_address, mac_address, sizeof (mac_address));
5765       S (mp_lbi);
5766     }
5767   else
5768     {
5769       /* Construct the API message */
5770       M (CREATE_LOOPBACK, mp);
5771       if (mac_set)
5772         clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
5773       S (mp);
5774     }
5775
5776   W (ret);
5777   return ret;
5778 }
5779
5780 static int
5781 api_delete_loopback (vat_main_t * vam)
5782 {
5783   unformat_input_t *i = vam->input;
5784   vl_api_delete_loopback_t *mp;
5785   u32 sw_if_index = ~0;
5786   int ret;
5787
5788   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5789     {
5790       if (unformat (i, "sw_if_index %d", &sw_if_index))
5791         ;
5792       else
5793         break;
5794     }
5795
5796   if (sw_if_index == ~0)
5797     {
5798       errmsg ("missing sw_if_index");
5799       return -99;
5800     }
5801
5802   /* Construct the API message */
5803   M (DELETE_LOOPBACK, mp);
5804   mp->sw_if_index = ntohl (sw_if_index);
5805
5806   S (mp);
5807   W (ret);
5808   return ret;
5809 }
5810
5811 static int
5812 api_want_interface_events (vat_main_t * vam)
5813 {
5814   unformat_input_t *i = vam->input;
5815   vl_api_want_interface_events_t *mp;
5816   int enable = -1;
5817   int ret;
5818
5819   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5820     {
5821       if (unformat (i, "enable"))
5822         enable = 1;
5823       else if (unformat (i, "disable"))
5824         enable = 0;
5825       else
5826         break;
5827     }
5828
5829   if (enable == -1)
5830     {
5831       errmsg ("missing enable|disable");
5832       return -99;
5833     }
5834
5835   M (WANT_INTERFACE_EVENTS, mp);
5836   mp->enable_disable = enable;
5837
5838   vam->interface_event_display = enable;
5839
5840   S (mp);
5841   W (ret);
5842   return ret;
5843 }
5844
5845
5846 /* Note: non-static, called once to set up the initial intfc table */
5847 int
5848 api_sw_interface_dump (vat_main_t * vam)
5849 {
5850   vl_api_sw_interface_dump_t *mp;
5851   vl_api_control_ping_t *mp_ping;
5852   hash_pair_t *p;
5853   name_sort_t *nses = 0, *ns;
5854   sw_interface_subif_t *sub = NULL;
5855   int ret;
5856
5857   /* Toss the old name table */
5858   /* *INDENT-OFF* */
5859   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5860   ({
5861     vec_add2 (nses, ns, 1);
5862     ns->name = (u8 *)(p->key);
5863     ns->value = (u32) p->value[0];
5864   }));
5865   /* *INDENT-ON* */
5866
5867   hash_free (vam->sw_if_index_by_interface_name);
5868
5869   vec_foreach (ns, nses) vec_free (ns->name);
5870
5871   vec_free (nses);
5872
5873   vec_foreach (sub, vam->sw_if_subif_table)
5874   {
5875     vec_free (sub->interface_name);
5876   }
5877   vec_free (vam->sw_if_subif_table);
5878
5879   /* recreate the interface name hash table */
5880   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
5881
5882   /*
5883    * Ask for all interface names. Otherwise, the epic catalog of
5884    * name filters becomes ridiculously long, and vat ends up needing
5885    * to be taught about new interface types.
5886    */
5887   M (SW_INTERFACE_DUMP, mp);
5888   S (mp);
5889
5890   /* Use a control ping for synchronization */
5891   MPING (CONTROL_PING, mp_ping);
5892   S (mp_ping);
5893
5894   W (ret);
5895   return ret;
5896 }
5897
5898 static int
5899 api_sw_interface_set_flags (vat_main_t * vam)
5900 {
5901   unformat_input_t *i = vam->input;
5902   vl_api_sw_interface_set_flags_t *mp;
5903   u32 sw_if_index;
5904   u8 sw_if_index_set = 0;
5905   u8 admin_up = 0;
5906   int ret;
5907
5908   /* Parse args required to build the message */
5909   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5910     {
5911       if (unformat (i, "admin-up"))
5912         admin_up = 1;
5913       else if (unformat (i, "admin-down"))
5914         admin_up = 0;
5915       else
5916         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5917         sw_if_index_set = 1;
5918       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5919         sw_if_index_set = 1;
5920       else
5921         break;
5922     }
5923
5924   if (sw_if_index_set == 0)
5925     {
5926       errmsg ("missing interface name or sw_if_index");
5927       return -99;
5928     }
5929
5930   /* Construct the API message */
5931   M (SW_INTERFACE_SET_FLAGS, mp);
5932   mp->sw_if_index = ntohl (sw_if_index);
5933   mp->flags = ntohl ((admin_up) ? IF_STATUS_API_FLAG_ADMIN_UP : 0);
5934
5935   /* send it... */
5936   S (mp);
5937
5938   /* Wait for a reply, return the good/bad news... */
5939   W (ret);
5940   return ret;
5941 }
5942
5943 static int
5944 api_sw_interface_set_rx_mode (vat_main_t * vam)
5945 {
5946   unformat_input_t *i = vam->input;
5947   vl_api_sw_interface_set_rx_mode_t *mp;
5948   u32 sw_if_index;
5949   u8 sw_if_index_set = 0;
5950   int ret;
5951   u8 queue_id_valid = 0;
5952   u32 queue_id;
5953   vnet_hw_interface_rx_mode mode = VNET_HW_INTERFACE_RX_MODE_UNKNOWN;
5954
5955   /* Parse args required to build the message */
5956   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5957     {
5958       if (unformat (i, "queue %d", &queue_id))
5959         queue_id_valid = 1;
5960       else if (unformat (i, "polling"))
5961         mode = VNET_HW_INTERFACE_RX_MODE_POLLING;
5962       else if (unformat (i, "interrupt"))
5963         mode = VNET_HW_INTERFACE_RX_MODE_INTERRUPT;
5964       else if (unformat (i, "adaptive"))
5965         mode = VNET_HW_INTERFACE_RX_MODE_ADAPTIVE;
5966       else
5967         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5968         sw_if_index_set = 1;
5969       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5970         sw_if_index_set = 1;
5971       else
5972         break;
5973     }
5974
5975   if (sw_if_index_set == 0)
5976     {
5977       errmsg ("missing interface name or sw_if_index");
5978       return -99;
5979     }
5980   if (mode == VNET_HW_INTERFACE_RX_MODE_UNKNOWN)
5981     {
5982       errmsg ("missing rx-mode");
5983       return -99;
5984     }
5985
5986   /* Construct the API message */
5987   M (SW_INTERFACE_SET_RX_MODE, mp);
5988   mp->sw_if_index = ntohl (sw_if_index);
5989   mp->mode = (vl_api_rx_mode_t) mode;
5990   mp->queue_id_valid = queue_id_valid;
5991   mp->queue_id = queue_id_valid ? ntohl (queue_id) : ~0;
5992
5993   /* send it... */
5994   S (mp);
5995
5996   /* Wait for a reply, return the good/bad news... */
5997   W (ret);
5998   return ret;
5999 }
6000
6001 static int
6002 api_sw_interface_set_rx_placement (vat_main_t * vam)
6003 {
6004   unformat_input_t *i = vam->input;
6005   vl_api_sw_interface_set_rx_placement_t *mp;
6006   u32 sw_if_index;
6007   u8 sw_if_index_set = 0;
6008   int ret;
6009   u8 is_main = 0;
6010   u32 queue_id, thread_index;
6011
6012   /* Parse args required to build the message */
6013   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6014     {
6015       if (unformat (i, "queue %d", &queue_id))
6016         ;
6017       else if (unformat (i, "main"))
6018         is_main = 1;
6019       else if (unformat (i, "worker %d", &thread_index))
6020         ;
6021       else
6022         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6023         sw_if_index_set = 1;
6024       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6025         sw_if_index_set = 1;
6026       else
6027         break;
6028     }
6029
6030   if (sw_if_index_set == 0)
6031     {
6032       errmsg ("missing interface name or sw_if_index");
6033       return -99;
6034     }
6035
6036   if (is_main)
6037     thread_index = 0;
6038   /* Construct the API message */
6039   M (SW_INTERFACE_SET_RX_PLACEMENT, mp);
6040   mp->sw_if_index = ntohl (sw_if_index);
6041   mp->worker_id = ntohl (thread_index);
6042   mp->queue_id = ntohl (queue_id);
6043   mp->is_main = is_main;
6044
6045   /* send it... */
6046   S (mp);
6047   /* Wait for a reply, return the good/bad news... */
6048   W (ret);
6049   return ret;
6050 }
6051
6052 static void vl_api_sw_interface_rx_placement_details_t_handler
6053   (vl_api_sw_interface_rx_placement_details_t * mp)
6054 {
6055   vat_main_t *vam = &vat_main;
6056   u32 worker_id = ntohl (mp->worker_id);
6057
6058   print (vam->ofp,
6059          "\n%-11d %-11s %-6d %-5d %-9s",
6060          ntohl (mp->sw_if_index), (worker_id == 0) ? "main" : "worker",
6061          worker_id, ntohl (mp->queue_id),
6062          (mp->mode ==
6063           1) ? "polling" : ((mp->mode == 2) ? "interrupt" : "adaptive"));
6064 }
6065
6066 static void vl_api_sw_interface_rx_placement_details_t_handler_json
6067   (vl_api_sw_interface_rx_placement_details_t * mp)
6068 {
6069   vat_main_t *vam = &vat_main;
6070   vat_json_node_t *node = NULL;
6071
6072   if (VAT_JSON_ARRAY != vam->json_tree.type)
6073     {
6074       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
6075       vat_json_init_array (&vam->json_tree);
6076     }
6077   node = vat_json_array_add (&vam->json_tree);
6078
6079   vat_json_init_object (node);
6080   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
6081   vat_json_object_add_uint (node, "worker_id", ntohl (mp->worker_id));
6082   vat_json_object_add_uint (node, "queue_id", ntohl (mp->queue_id));
6083   vat_json_object_add_uint (node, "mode", mp->mode);
6084 }
6085
6086 static int
6087 api_sw_interface_rx_placement_dump (vat_main_t * vam)
6088 {
6089   unformat_input_t *i = vam->input;
6090   vl_api_sw_interface_rx_placement_dump_t *mp;
6091   vl_api_control_ping_t *mp_ping;
6092   int ret;
6093   u32 sw_if_index;
6094   u8 sw_if_index_set = 0;
6095
6096   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6097     {
6098       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6099         sw_if_index_set++;
6100       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6101         sw_if_index_set++;
6102       else
6103         break;
6104     }
6105
6106   print (vam->ofp,
6107          "\n%-11s %-11s %-6s %-5s %-4s",
6108          "sw_if_index", "main/worker", "thread", "queue", "mode");
6109
6110   /* Dump Interface rx placement */
6111   M (SW_INTERFACE_RX_PLACEMENT_DUMP, mp);
6112
6113   if (sw_if_index_set)
6114     mp->sw_if_index = htonl (sw_if_index);
6115   else
6116     mp->sw_if_index = ~0;
6117
6118   S (mp);
6119
6120   /* Use a control ping for synchronization */
6121   MPING (CONTROL_PING, mp_ping);
6122   S (mp_ping);
6123
6124   W (ret);
6125   return ret;
6126 }
6127
6128 static int
6129 api_sw_interface_clear_stats (vat_main_t * vam)
6130 {
6131   unformat_input_t *i = vam->input;
6132   vl_api_sw_interface_clear_stats_t *mp;
6133   u32 sw_if_index;
6134   u8 sw_if_index_set = 0;
6135   int ret;
6136
6137   /* Parse args required to build the message */
6138   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6139     {
6140       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6141         sw_if_index_set = 1;
6142       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6143         sw_if_index_set = 1;
6144       else
6145         break;
6146     }
6147
6148   /* Construct the API message */
6149   M (SW_INTERFACE_CLEAR_STATS, mp);
6150
6151   if (sw_if_index_set == 1)
6152     mp->sw_if_index = ntohl (sw_if_index);
6153   else
6154     mp->sw_if_index = ~0;
6155
6156   /* send it... */
6157   S (mp);
6158
6159   /* Wait for a reply, return the good/bad news... */
6160   W (ret);
6161   return ret;
6162 }
6163
6164 static int
6165 api_sw_interface_add_del_address (vat_main_t * vam)
6166 {
6167   unformat_input_t *i = vam->input;
6168   vl_api_sw_interface_add_del_address_t *mp;
6169   u32 sw_if_index;
6170   u8 sw_if_index_set = 0;
6171   u8 is_add = 1, del_all = 0;
6172   u32 address_length = 0;
6173   u8 v4_address_set = 0;
6174   u8 v6_address_set = 0;
6175   ip4_address_t v4address;
6176   ip6_address_t v6address;
6177   int ret;
6178
6179   /* Parse args required to build the message */
6180   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6181     {
6182       if (unformat (i, "del-all"))
6183         del_all = 1;
6184       else if (unformat (i, "del"))
6185         is_add = 0;
6186       else
6187         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6188         sw_if_index_set = 1;
6189       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6190         sw_if_index_set = 1;
6191       else if (unformat (i, "%U/%d",
6192                          unformat_ip4_address, &v4address, &address_length))
6193         v4_address_set = 1;
6194       else if (unformat (i, "%U/%d",
6195                          unformat_ip6_address, &v6address, &address_length))
6196         v6_address_set = 1;
6197       else
6198         break;
6199     }
6200
6201   if (sw_if_index_set == 0)
6202     {
6203       errmsg ("missing interface name or sw_if_index");
6204       return -99;
6205     }
6206   if (v4_address_set && v6_address_set)
6207     {
6208       errmsg ("both v4 and v6 addresses set");
6209       return -99;
6210     }
6211   if (!v4_address_set && !v6_address_set && !del_all)
6212     {
6213       errmsg ("no addresses set");
6214       return -99;
6215     }
6216
6217   /* Construct the API message */
6218   M (SW_INTERFACE_ADD_DEL_ADDRESS, mp);
6219
6220   mp->sw_if_index = ntohl (sw_if_index);
6221   mp->is_add = is_add;
6222   mp->del_all = del_all;
6223   if (v6_address_set)
6224     {
6225       mp->prefix.address.af = ADDRESS_IP6;
6226       clib_memcpy (mp->prefix.address.un.ip6, &v6address, sizeof (v6address));
6227     }
6228   else
6229     {
6230       mp->prefix.address.af = ADDRESS_IP4;
6231       clib_memcpy (mp->prefix.address.un.ip4, &v4address, sizeof (v4address));
6232     }
6233   mp->prefix.len = address_length;
6234
6235   /* send it... */
6236   S (mp);
6237
6238   /* Wait for a reply, return good/bad news  */
6239   W (ret);
6240   return ret;
6241 }
6242
6243 static int
6244 api_sw_interface_set_mpls_enable (vat_main_t * vam)
6245 {
6246   unformat_input_t *i = vam->input;
6247   vl_api_sw_interface_set_mpls_enable_t *mp;
6248   u32 sw_if_index;
6249   u8 sw_if_index_set = 0;
6250   u8 enable = 1;
6251   int ret;
6252
6253   /* Parse args required to build the message */
6254   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6255     {
6256       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6257         sw_if_index_set = 1;
6258       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6259         sw_if_index_set = 1;
6260       else if (unformat (i, "disable"))
6261         enable = 0;
6262       else if (unformat (i, "dis"))
6263         enable = 0;
6264       else
6265         break;
6266     }
6267
6268   if (sw_if_index_set == 0)
6269     {
6270       errmsg ("missing interface name or sw_if_index");
6271       return -99;
6272     }
6273
6274   /* Construct the API message */
6275   M (SW_INTERFACE_SET_MPLS_ENABLE, mp);
6276
6277   mp->sw_if_index = ntohl (sw_if_index);
6278   mp->enable = enable;
6279
6280   /* send it... */
6281   S (mp);
6282
6283   /* Wait for a reply... */
6284   W (ret);
6285   return ret;
6286 }
6287
6288 static int
6289 api_sw_interface_set_table (vat_main_t * vam)
6290 {
6291   unformat_input_t *i = vam->input;
6292   vl_api_sw_interface_set_table_t *mp;
6293   u32 sw_if_index, vrf_id = 0;
6294   u8 sw_if_index_set = 0;
6295   u8 is_ipv6 = 0;
6296   int ret;
6297
6298   /* Parse args required to build the message */
6299   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6300     {
6301       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6302         sw_if_index_set = 1;
6303       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6304         sw_if_index_set = 1;
6305       else if (unformat (i, "vrf %d", &vrf_id))
6306         ;
6307       else if (unformat (i, "ipv6"))
6308         is_ipv6 = 1;
6309       else
6310         break;
6311     }
6312
6313   if (sw_if_index_set == 0)
6314     {
6315       errmsg ("missing interface name or sw_if_index");
6316       return -99;
6317     }
6318
6319   /* Construct the API message */
6320   M (SW_INTERFACE_SET_TABLE, mp);
6321
6322   mp->sw_if_index = ntohl (sw_if_index);
6323   mp->is_ipv6 = is_ipv6;
6324   mp->vrf_id = ntohl (vrf_id);
6325
6326   /* send it... */
6327   S (mp);
6328
6329   /* Wait for a reply... */
6330   W (ret);
6331   return ret;
6332 }
6333
6334 static void vl_api_sw_interface_get_table_reply_t_handler
6335   (vl_api_sw_interface_get_table_reply_t * mp)
6336 {
6337   vat_main_t *vam = &vat_main;
6338
6339   print (vam->ofp, "%d", ntohl (mp->vrf_id));
6340
6341   vam->retval = ntohl (mp->retval);
6342   vam->result_ready = 1;
6343
6344 }
6345
6346 static void vl_api_sw_interface_get_table_reply_t_handler_json
6347   (vl_api_sw_interface_get_table_reply_t * mp)
6348 {
6349   vat_main_t *vam = &vat_main;
6350   vat_json_node_t node;
6351
6352   vat_json_init_object (&node);
6353   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
6354   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
6355
6356   vat_json_print (vam->ofp, &node);
6357   vat_json_free (&node);
6358
6359   vam->retval = ntohl (mp->retval);
6360   vam->result_ready = 1;
6361 }
6362
6363 static int
6364 api_sw_interface_get_table (vat_main_t * vam)
6365 {
6366   unformat_input_t *i = vam->input;
6367   vl_api_sw_interface_get_table_t *mp;
6368   u32 sw_if_index;
6369   u8 sw_if_index_set = 0;
6370   u8 is_ipv6 = 0;
6371   int ret;
6372
6373   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6374     {
6375       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6376         sw_if_index_set = 1;
6377       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6378         sw_if_index_set = 1;
6379       else if (unformat (i, "ipv6"))
6380         is_ipv6 = 1;
6381       else
6382         break;
6383     }
6384
6385   if (sw_if_index_set == 0)
6386     {
6387       errmsg ("missing interface name or sw_if_index");
6388       return -99;
6389     }
6390
6391   M (SW_INTERFACE_GET_TABLE, mp);
6392   mp->sw_if_index = htonl (sw_if_index);
6393   mp->is_ipv6 = is_ipv6;
6394
6395   S (mp);
6396   W (ret);
6397   return ret;
6398 }
6399
6400 static int
6401 api_sw_interface_set_vpath (vat_main_t * vam)
6402 {
6403   unformat_input_t *i = vam->input;
6404   vl_api_sw_interface_set_vpath_t *mp;
6405   u32 sw_if_index = 0;
6406   u8 sw_if_index_set = 0;
6407   u8 is_enable = 0;
6408   int ret;
6409
6410   /* Parse args required to build the message */
6411   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6412     {
6413       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6414         sw_if_index_set = 1;
6415       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6416         sw_if_index_set = 1;
6417       else if (unformat (i, "enable"))
6418         is_enable = 1;
6419       else if (unformat (i, "disable"))
6420         is_enable = 0;
6421       else
6422         break;
6423     }
6424
6425   if (sw_if_index_set == 0)
6426     {
6427       errmsg ("missing interface name or sw_if_index");
6428       return -99;
6429     }
6430
6431   /* Construct the API message */
6432   M (SW_INTERFACE_SET_VPATH, mp);
6433
6434   mp->sw_if_index = ntohl (sw_if_index);
6435   mp->enable = is_enable;
6436
6437   /* send it... */
6438   S (mp);
6439
6440   /* Wait for a reply... */
6441   W (ret);
6442   return ret;
6443 }
6444
6445 static int
6446 api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
6447 {
6448   unformat_input_t *i = vam->input;
6449   vl_api_sw_interface_set_vxlan_bypass_t *mp;
6450   u32 sw_if_index = 0;
6451   u8 sw_if_index_set = 0;
6452   u8 is_enable = 1;
6453   u8 is_ipv6 = 0;
6454   int ret;
6455
6456   /* Parse args required to build the message */
6457   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6458     {
6459       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6460         sw_if_index_set = 1;
6461       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6462         sw_if_index_set = 1;
6463       else if (unformat (i, "enable"))
6464         is_enable = 1;
6465       else if (unformat (i, "disable"))
6466         is_enable = 0;
6467       else if (unformat (i, "ip4"))
6468         is_ipv6 = 0;
6469       else if (unformat (i, "ip6"))
6470         is_ipv6 = 1;
6471       else
6472         break;
6473     }
6474
6475   if (sw_if_index_set == 0)
6476     {
6477       errmsg ("missing interface name or sw_if_index");
6478       return -99;
6479     }
6480
6481   /* Construct the API message */
6482   M (SW_INTERFACE_SET_VXLAN_BYPASS, mp);
6483
6484   mp->sw_if_index = ntohl (sw_if_index);
6485   mp->enable = is_enable;
6486   mp->is_ipv6 = is_ipv6;
6487
6488   /* send it... */
6489   S (mp);
6490
6491   /* Wait for a reply... */
6492   W (ret);
6493   return ret;
6494 }
6495
6496 static int
6497 api_sw_interface_set_geneve_bypass (vat_main_t * vam)
6498 {
6499   unformat_input_t *i = vam->input;
6500   vl_api_sw_interface_set_geneve_bypass_t *mp;
6501   u32 sw_if_index = 0;
6502   u8 sw_if_index_set = 0;
6503   u8 is_enable = 1;
6504   u8 is_ipv6 = 0;
6505   int ret;
6506
6507   /* Parse args required to build the message */
6508   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6509     {
6510       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6511         sw_if_index_set = 1;
6512       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6513         sw_if_index_set = 1;
6514       else if (unformat (i, "enable"))
6515         is_enable = 1;
6516       else if (unformat (i, "disable"))
6517         is_enable = 0;
6518       else if (unformat (i, "ip4"))
6519         is_ipv6 = 0;
6520       else if (unformat (i, "ip6"))
6521         is_ipv6 = 1;
6522       else
6523         break;
6524     }
6525
6526   if (sw_if_index_set == 0)
6527     {
6528       errmsg ("missing interface name or sw_if_index");
6529       return -99;
6530     }
6531
6532   /* Construct the API message */
6533   M (SW_INTERFACE_SET_GENEVE_BYPASS, mp);
6534
6535   mp->sw_if_index = ntohl (sw_if_index);
6536   mp->enable = is_enable;
6537   mp->is_ipv6 = is_ipv6;
6538
6539   /* send it... */
6540   S (mp);
6541
6542   /* Wait for a reply... */
6543   W (ret);
6544   return ret;
6545 }
6546
6547 static int
6548 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
6549 {
6550   unformat_input_t *i = vam->input;
6551   vl_api_sw_interface_set_l2_xconnect_t *mp;
6552   u32 rx_sw_if_index;
6553   u8 rx_sw_if_index_set = 0;
6554   u32 tx_sw_if_index;
6555   u8 tx_sw_if_index_set = 0;
6556   u8 enable = 1;
6557   int ret;
6558
6559   /* Parse args required to build the message */
6560   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6561     {
6562       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
6563         rx_sw_if_index_set = 1;
6564       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
6565         tx_sw_if_index_set = 1;
6566       else if (unformat (i, "rx"))
6567         {
6568           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6569             {
6570               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6571                             &rx_sw_if_index))
6572                 rx_sw_if_index_set = 1;
6573             }
6574           else
6575             break;
6576         }
6577       else if (unformat (i, "tx"))
6578         {
6579           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6580             {
6581               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6582                             &tx_sw_if_index))
6583                 tx_sw_if_index_set = 1;
6584             }
6585           else
6586             break;
6587         }
6588       else if (unformat (i, "enable"))
6589         enable = 1;
6590       else if (unformat (i, "disable"))
6591         enable = 0;
6592       else
6593         break;
6594     }
6595
6596   if (rx_sw_if_index_set == 0)
6597     {
6598       errmsg ("missing rx interface name or rx_sw_if_index");
6599       return -99;
6600     }
6601
6602   if (enable && (tx_sw_if_index_set == 0))
6603     {
6604       errmsg ("missing tx interface name or tx_sw_if_index");
6605       return -99;
6606     }
6607
6608   M (SW_INTERFACE_SET_L2_XCONNECT, mp);
6609
6610   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6611   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
6612   mp->enable = enable;
6613
6614   S (mp);
6615   W (ret);
6616   return ret;
6617 }
6618
6619 static int
6620 api_sw_interface_set_l2_bridge (vat_main_t * vam)
6621 {
6622   unformat_input_t *i = vam->input;
6623   vl_api_sw_interface_set_l2_bridge_t *mp;
6624   vl_api_l2_port_type_t port_type;
6625   u32 rx_sw_if_index;
6626   u8 rx_sw_if_index_set = 0;
6627   u32 bd_id;
6628   u8 bd_id_set = 0;
6629   u32 shg = 0;
6630   u8 enable = 1;
6631   int ret;
6632
6633   port_type = L2_API_PORT_TYPE_NORMAL;
6634
6635   /* Parse args required to build the message */
6636   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6637     {
6638       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
6639         rx_sw_if_index_set = 1;
6640       else if (unformat (i, "bd_id %d", &bd_id))
6641         bd_id_set = 1;
6642       else
6643         if (unformat
6644             (i, "%U", api_unformat_sw_if_index, vam, &rx_sw_if_index))
6645         rx_sw_if_index_set = 1;
6646       else if (unformat (i, "shg %d", &shg))
6647         ;
6648       else if (unformat (i, "bvi"))
6649         port_type = L2_API_PORT_TYPE_BVI;
6650       else if (unformat (i, "uu-fwd"))
6651         port_type = L2_API_PORT_TYPE_UU_FWD;
6652       else if (unformat (i, "enable"))
6653         enable = 1;
6654       else if (unformat (i, "disable"))
6655         enable = 0;
6656       else
6657         break;
6658     }
6659
6660   if (rx_sw_if_index_set == 0)
6661     {
6662       errmsg ("missing rx interface name or sw_if_index");
6663       return -99;
6664     }
6665
6666   if (enable && (bd_id_set == 0))
6667     {
6668       errmsg ("missing bridge domain");
6669       return -99;
6670     }
6671
6672   M (SW_INTERFACE_SET_L2_BRIDGE, mp);
6673
6674   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6675   mp->bd_id = ntohl (bd_id);
6676   mp->shg = (u8) shg;
6677   mp->port_type = ntohl (port_type);
6678   mp->enable = enable;
6679
6680   S (mp);
6681   W (ret);
6682   return ret;
6683 }
6684
6685 static int
6686 api_bridge_domain_dump (vat_main_t * vam)
6687 {
6688   unformat_input_t *i = vam->input;
6689   vl_api_bridge_domain_dump_t *mp;
6690   vl_api_control_ping_t *mp_ping;
6691   u32 bd_id = ~0;
6692   int ret;
6693
6694   /* Parse args required to build the message */
6695   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6696     {
6697       if (unformat (i, "bd_id %d", &bd_id))
6698         ;
6699       else
6700         break;
6701     }
6702
6703   M (BRIDGE_DOMAIN_DUMP, mp);
6704   mp->bd_id = ntohl (bd_id);
6705   S (mp);
6706
6707   /* Use a control ping for synchronization */
6708   MPING (CONTROL_PING, mp_ping);
6709   S (mp_ping);
6710
6711   W (ret);
6712   return ret;
6713 }
6714
6715 static int
6716 api_bridge_domain_add_del (vat_main_t * vam)
6717 {
6718   unformat_input_t *i = vam->input;
6719   vl_api_bridge_domain_add_del_t *mp;
6720   u32 bd_id = ~0;
6721   u8 is_add = 1;
6722   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
6723   u8 *bd_tag = NULL;
6724   u32 mac_age = 0;
6725   int ret;
6726
6727   /* Parse args required to build the message */
6728   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6729     {
6730       if (unformat (i, "bd_id %d", &bd_id))
6731         ;
6732       else if (unformat (i, "flood %d", &flood))
6733         ;
6734       else if (unformat (i, "uu-flood %d", &uu_flood))
6735         ;
6736       else if (unformat (i, "forward %d", &forward))
6737         ;
6738       else if (unformat (i, "learn %d", &learn))
6739         ;
6740       else if (unformat (i, "arp-term %d", &arp_term))
6741         ;
6742       else if (unformat (i, "mac-age %d", &mac_age))
6743         ;
6744       else if (unformat (i, "bd-tag %s", &bd_tag))
6745         ;
6746       else if (unformat (i, "del"))
6747         {
6748           is_add = 0;
6749           flood = uu_flood = forward = learn = 0;
6750         }
6751       else
6752         break;
6753     }
6754
6755   if (bd_id == ~0)
6756     {
6757       errmsg ("missing bridge domain");
6758       ret = -99;
6759       goto done;
6760     }
6761
6762   if (mac_age > 255)
6763     {
6764       errmsg ("mac age must be less than 256 ");
6765       ret = -99;
6766       goto done;
6767     }
6768
6769   if ((bd_tag) && (vec_len (bd_tag) > 63))
6770     {
6771       errmsg ("bd-tag cannot be longer than 63");
6772       ret = -99;
6773       goto done;
6774     }
6775
6776   M (BRIDGE_DOMAIN_ADD_DEL, mp);
6777
6778   mp->bd_id = ntohl (bd_id);
6779   mp->flood = flood;
6780   mp->uu_flood = uu_flood;
6781   mp->forward = forward;
6782   mp->learn = learn;
6783   mp->arp_term = arp_term;
6784   mp->is_add = is_add;
6785   mp->mac_age = (u8) mac_age;
6786   if (bd_tag)
6787     {
6788       clib_memcpy (mp->bd_tag, bd_tag, vec_len (bd_tag));
6789       mp->bd_tag[vec_len (bd_tag)] = 0;
6790     }
6791   S (mp);
6792   W (ret);
6793
6794 done:
6795   vec_free (bd_tag);
6796   return ret;
6797 }
6798
6799 static int
6800 api_l2fib_flush_bd (vat_main_t * vam)
6801 {
6802   unformat_input_t *i = vam->input;
6803   vl_api_l2fib_flush_bd_t *mp;
6804   u32 bd_id = ~0;
6805   int ret;
6806
6807   /* Parse args required to build the message */
6808   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6809     {
6810       if (unformat (i, "bd_id %d", &bd_id));
6811       else
6812         break;
6813     }
6814
6815   if (bd_id == ~0)
6816     {
6817       errmsg ("missing bridge domain");
6818       return -99;
6819     }
6820
6821   M (L2FIB_FLUSH_BD, mp);
6822
6823   mp->bd_id = htonl (bd_id);
6824
6825   S (mp);
6826   W (ret);
6827   return ret;
6828 }
6829
6830 static int
6831 api_l2fib_flush_int (vat_main_t * vam)
6832 {
6833   unformat_input_t *i = vam->input;
6834   vl_api_l2fib_flush_int_t *mp;
6835   u32 sw_if_index = ~0;
6836   int ret;
6837
6838   /* Parse args required to build the message */
6839   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6840     {
6841       if (unformat (i, "sw_if_index %d", &sw_if_index));
6842       else
6843         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index));
6844       else
6845         break;
6846     }
6847
6848   if (sw_if_index == ~0)
6849     {
6850       errmsg ("missing interface name or sw_if_index");
6851       return -99;
6852     }
6853
6854   M (L2FIB_FLUSH_INT, mp);
6855
6856   mp->sw_if_index = ntohl (sw_if_index);
6857
6858   S (mp);
6859   W (ret);
6860   return ret;
6861 }
6862
6863 static int
6864 api_l2fib_add_del (vat_main_t * vam)
6865 {
6866   unformat_input_t *i = vam->input;
6867   vl_api_l2fib_add_del_t *mp;
6868   f64 timeout;
6869   u8 mac[6] = { 0 };
6870   u8 mac_set = 0;
6871   u32 bd_id;
6872   u8 bd_id_set = 0;
6873   u32 sw_if_index = 0;
6874   u8 sw_if_index_set = 0;
6875   u8 is_add = 1;
6876   u8 static_mac = 0;
6877   u8 filter_mac = 0;
6878   u8 bvi_mac = 0;
6879   int count = 1;
6880   f64 before = 0;
6881   int j;
6882
6883   /* Parse args required to build the message */
6884   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6885     {
6886       if (unformat (i, "mac %U", unformat_ethernet_address, mac))
6887         mac_set = 1;
6888       else if (unformat (i, "bd_id %d", &bd_id))
6889         bd_id_set = 1;
6890       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6891         sw_if_index_set = 1;
6892       else if (unformat (i, "sw_if"))
6893         {
6894           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6895             {
6896               if (unformat
6897                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6898                 sw_if_index_set = 1;
6899             }
6900           else
6901             break;
6902         }
6903       else if (unformat (i, "static"))
6904         static_mac = 1;
6905       else if (unformat (i, "filter"))
6906         {
6907           filter_mac = 1;
6908           static_mac = 1;
6909         }
6910       else if (unformat (i, "bvi"))
6911         {
6912           bvi_mac = 1;
6913           static_mac = 1;
6914         }
6915       else if (unformat (i, "del"))
6916         is_add = 0;
6917       else if (unformat (i, "count %d", &count))
6918         ;
6919       else
6920         break;
6921     }
6922
6923   if (mac_set == 0)
6924     {
6925       errmsg ("missing mac address");
6926       return -99;
6927     }
6928
6929   if (bd_id_set == 0)
6930     {
6931       errmsg ("missing bridge domain");
6932       return -99;
6933     }
6934
6935   if (is_add && sw_if_index_set == 0 && filter_mac == 0)
6936     {
6937       errmsg ("missing interface name or sw_if_index");
6938       return -99;
6939     }
6940
6941   if (count > 1)
6942     {
6943       /* Turn on async mode */
6944       vam->async_mode = 1;
6945       vam->async_errors = 0;
6946       before = vat_time_now (vam);
6947     }
6948
6949   for (j = 0; j < count; j++)
6950     {
6951       M (L2FIB_ADD_DEL, mp);
6952
6953       clib_memcpy (mp->mac, mac, 6);
6954       mp->bd_id = ntohl (bd_id);
6955       mp->is_add = is_add;
6956       mp->sw_if_index = ntohl (sw_if_index);
6957
6958       if (is_add)
6959         {
6960           mp->static_mac = static_mac;
6961           mp->filter_mac = filter_mac;
6962           mp->bvi_mac = bvi_mac;
6963         }
6964       increment_mac_address (mac);
6965       /* send it... */
6966       S (mp);
6967     }
6968
6969   if (count > 1)
6970     {
6971       vl_api_control_ping_t *mp_ping;
6972       f64 after;
6973
6974       /* Shut off async mode */
6975       vam->async_mode = 0;
6976
6977       MPING (CONTROL_PING, mp_ping);
6978       S (mp_ping);
6979
6980       timeout = vat_time_now (vam) + 1.0;
6981       while (vat_time_now (vam) < timeout)
6982         if (vam->result_ready == 1)
6983           goto out;
6984       vam->retval = -99;
6985
6986     out:
6987       if (vam->retval == -99)
6988         errmsg ("timeout");
6989
6990       if (vam->async_errors > 0)
6991         {
6992           errmsg ("%d asynchronous errors", vam->async_errors);
6993           vam->retval = -98;
6994         }
6995       vam->async_errors = 0;
6996       after = vat_time_now (vam);
6997
6998       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
6999              count, after - before, count / (after - before));
7000     }
7001   else
7002     {
7003       int ret;
7004
7005       /* Wait for a reply... */
7006       W (ret);
7007       return ret;
7008     }
7009   /* Return the good/bad news */
7010   return (vam->retval);
7011 }
7012
7013 static int
7014 api_bridge_domain_set_mac_age (vat_main_t * vam)
7015 {
7016   unformat_input_t *i = vam->input;
7017   vl_api_bridge_domain_set_mac_age_t *mp;
7018   u32 bd_id = ~0;
7019   u32 mac_age = 0;
7020   int ret;
7021
7022   /* Parse args required to build the message */
7023   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7024     {
7025       if (unformat (i, "bd_id %d", &bd_id));
7026       else if (unformat (i, "mac-age %d", &mac_age));
7027       else
7028         break;
7029     }
7030
7031   if (bd_id == ~0)
7032     {
7033       errmsg ("missing bridge domain");
7034       return -99;
7035     }
7036
7037   if (mac_age > 255)
7038     {
7039       errmsg ("mac age must be less than 256 ");
7040       return -99;
7041     }
7042
7043   M (BRIDGE_DOMAIN_SET_MAC_AGE, mp);
7044
7045   mp->bd_id = htonl (bd_id);
7046   mp->mac_age = (u8) mac_age;
7047
7048   S (mp);
7049   W (ret);
7050   return ret;
7051 }
7052
7053 static int
7054 api_l2_flags (vat_main_t * vam)
7055 {
7056   unformat_input_t *i = vam->input;
7057   vl_api_l2_flags_t *mp;
7058   u32 sw_if_index;
7059   u32 flags = 0;
7060   u8 sw_if_index_set = 0;
7061   u8 is_set = 0;
7062   int ret;
7063
7064   /* Parse args required to build the message */
7065   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7066     {
7067       if (unformat (i, "sw_if_index %d", &sw_if_index))
7068         sw_if_index_set = 1;
7069       else if (unformat (i, "sw_if"))
7070         {
7071           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7072             {
7073               if (unformat
7074                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7075                 sw_if_index_set = 1;
7076             }
7077           else
7078             break;
7079         }
7080       else if (unformat (i, "learn"))
7081         flags |= L2_LEARN;
7082       else if (unformat (i, "forward"))
7083         flags |= L2_FWD;
7084       else if (unformat (i, "flood"))
7085         flags |= L2_FLOOD;
7086       else if (unformat (i, "uu-flood"))
7087         flags |= L2_UU_FLOOD;
7088       else if (unformat (i, "arp-term"))
7089         flags |= L2_ARP_TERM;
7090       else if (unformat (i, "off"))
7091         is_set = 0;
7092       else if (unformat (i, "disable"))
7093         is_set = 0;
7094       else
7095         break;
7096     }
7097
7098   if (sw_if_index_set == 0)
7099     {
7100       errmsg ("missing interface name or sw_if_index");
7101       return -99;
7102     }
7103
7104   M (L2_FLAGS, mp);
7105
7106   mp->sw_if_index = ntohl (sw_if_index);
7107   mp->feature_bitmap = ntohl (flags);
7108   mp->is_set = is_set;
7109
7110   S (mp);
7111   W (ret);
7112   return ret;
7113 }
7114
7115 static int
7116 api_bridge_flags (vat_main_t * vam)
7117 {
7118   unformat_input_t *i = vam->input;
7119   vl_api_bridge_flags_t *mp;
7120   u32 bd_id;
7121   u8 bd_id_set = 0;
7122   u8 is_set = 1;
7123   bd_flags_t flags = 0;
7124   int ret;
7125
7126   /* Parse args required to build the message */
7127   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7128     {
7129       if (unformat (i, "bd_id %d", &bd_id))
7130         bd_id_set = 1;
7131       else if (unformat (i, "learn"))
7132         flags |= BRIDGE_API_FLAG_LEARN;
7133       else if (unformat (i, "forward"))
7134         flags |= BRIDGE_API_FLAG_FWD;
7135       else if (unformat (i, "flood"))
7136         flags |= BRIDGE_API_FLAG_FLOOD;
7137       else if (unformat (i, "uu-flood"))
7138         flags |= BRIDGE_API_FLAG_UU_FLOOD;
7139       else if (unformat (i, "arp-term"))
7140         flags |= BRIDGE_API_FLAG_ARP_TERM;
7141       else if (unformat (i, "off"))
7142         is_set = 0;
7143       else if (unformat (i, "disable"))
7144         is_set = 0;
7145       else
7146         break;
7147     }
7148
7149   if (bd_id_set == 0)
7150     {
7151       errmsg ("missing bridge domain");
7152       return -99;
7153     }
7154
7155   M (BRIDGE_FLAGS, mp);
7156
7157   mp->bd_id = ntohl (bd_id);
7158   mp->flags = ntohl (flags);
7159   mp->is_set = is_set;
7160
7161   S (mp);
7162   W (ret);
7163   return ret;
7164 }
7165
7166 static int
7167 api_bd_ip_mac_add_del (vat_main_t * vam)
7168 {
7169   vl_api_address_t ip = VL_API_ZERO_ADDRESS;
7170   vl_api_mac_address_t mac = { 0 };
7171   unformat_input_t *i = vam->input;
7172   vl_api_bd_ip_mac_add_del_t *mp;
7173   u32 bd_id;
7174   u8 is_add = 1;
7175   u8 bd_id_set = 0;
7176   u8 ip_set = 0;
7177   u8 mac_set = 0;
7178   int ret;
7179
7180
7181   /* Parse args required to build the message */
7182   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7183     {
7184       if (unformat (i, "bd_id %d", &bd_id))
7185         {
7186           bd_id_set++;
7187         }
7188       else if (unformat (i, "%U", unformat_vl_api_address, &ip))
7189         {
7190           ip_set++;
7191         }
7192       else if (unformat (i, "%U", unformat_vl_api_mac_address, &mac))
7193         {
7194           mac_set++;
7195         }
7196       else if (unformat (i, "del"))
7197         is_add = 0;
7198       else
7199         break;
7200     }
7201
7202   if (bd_id_set == 0)
7203     {
7204       errmsg ("missing bridge domain");
7205       return -99;
7206     }
7207   else if (ip_set == 0)
7208     {
7209       errmsg ("missing IP address");
7210       return -99;
7211     }
7212   else if (mac_set == 0)
7213     {
7214       errmsg ("missing MAC address");
7215       return -99;
7216     }
7217
7218   M (BD_IP_MAC_ADD_DEL, mp);
7219
7220   mp->entry.bd_id = ntohl (bd_id);
7221   mp->is_add = is_add;
7222
7223   clib_memcpy (&mp->entry.ip, &ip, sizeof (ip));
7224   clib_memcpy (&mp->entry.mac, &mac, sizeof (mac));
7225
7226   S (mp);
7227   W (ret);
7228   return ret;
7229 }
7230
7231 static int
7232 api_bd_ip_mac_flush (vat_main_t * vam)
7233 {
7234   unformat_input_t *i = vam->input;
7235   vl_api_bd_ip_mac_flush_t *mp;
7236   u32 bd_id;
7237   u8 bd_id_set = 0;
7238   int ret;
7239
7240   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7241     {
7242       if (unformat (i, "bd_id %d", &bd_id))
7243         {
7244           bd_id_set++;
7245         }
7246       else
7247         break;
7248     }
7249
7250   if (bd_id_set == 0)
7251     {
7252       errmsg ("missing bridge domain");
7253       return -99;
7254     }
7255
7256   M (BD_IP_MAC_FLUSH, mp);
7257
7258   mp->bd_id = ntohl (bd_id);
7259
7260   S (mp);
7261   W (ret);
7262   return ret;
7263 }
7264
7265 static void vl_api_bd_ip_mac_details_t_handler
7266   (vl_api_bd_ip_mac_details_t * mp)
7267 {
7268   vat_main_t *vam = &vat_main;
7269
7270   print (vam->ofp,
7271          "\n%-5d %U %U",
7272          ntohl (mp->entry.bd_id),
7273          format_vl_api_mac_address, mp->entry.mac,
7274          format_vl_api_address, &mp->entry.ip);
7275 }
7276
7277 static void vl_api_bd_ip_mac_details_t_handler_json
7278   (vl_api_bd_ip_mac_details_t * mp)
7279 {
7280   vat_main_t *vam = &vat_main;
7281   vat_json_node_t *node = NULL;
7282
7283   if (VAT_JSON_ARRAY != vam->json_tree.type)
7284     {
7285       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
7286       vat_json_init_array (&vam->json_tree);
7287     }
7288   node = vat_json_array_add (&vam->json_tree);
7289
7290   vat_json_init_object (node);
7291   vat_json_object_add_uint (node, "bd_id", ntohl (mp->entry.bd_id));
7292   vat_json_object_add_string_copy (node, "mac_address",
7293                                    format (0, "%U", format_vl_api_mac_address,
7294                                            &mp->entry.mac));
7295   u8 *ip = 0;
7296
7297   ip = format (0, "%U", format_vl_api_address, &mp->entry.ip);
7298   vat_json_object_add_string_copy (node, "ip_address", ip);
7299   vec_free (ip);
7300 }
7301
7302 static int
7303 api_bd_ip_mac_dump (vat_main_t * vam)
7304 {
7305   unformat_input_t *i = vam->input;
7306   vl_api_bd_ip_mac_dump_t *mp;
7307   vl_api_control_ping_t *mp_ping;
7308   int ret;
7309   u32 bd_id;
7310   u8 bd_id_set = 0;
7311
7312   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7313     {
7314       if (unformat (i, "bd_id %d", &bd_id))
7315         {
7316           bd_id_set++;
7317         }
7318       else
7319         break;
7320     }
7321
7322   print (vam->ofp,
7323          "\n%-5s %-7s %-20s %-30s",
7324          "bd_id", "is_ipv6", "mac_address", "ip_address");
7325
7326   /* Dump Bridge Domain Ip to Mac entries */
7327   M (BD_IP_MAC_DUMP, mp);
7328
7329   if (bd_id_set)
7330     mp->bd_id = htonl (bd_id);
7331   else
7332     mp->bd_id = ~0;
7333
7334   S (mp);
7335
7336   /* Use a control ping for synchronization */
7337   MPING (CONTROL_PING, mp_ping);
7338   S (mp_ping);
7339
7340   W (ret);
7341   return ret;
7342 }
7343
7344 static int
7345 api_tap_create_v2 (vat_main_t * vam)
7346 {
7347   unformat_input_t *i = vam->input;
7348   vl_api_tap_create_v2_t *mp;
7349 #define TAP_FLAG_GSO (1 << 0)
7350   u8 mac_address[6];
7351   u8 random_mac = 1;
7352   u32 id = ~0;
7353   u8 *host_if_name = 0;
7354   u8 *host_ns = 0;
7355   u8 host_mac_addr[6];
7356   u8 host_mac_addr_set = 0;
7357   u8 *host_bridge = 0;
7358   ip4_address_t host_ip4_addr;
7359   ip4_address_t host_ip4_gw;
7360   u8 host_ip4_gw_set = 0;
7361   u32 host_ip4_prefix_len = 0;
7362   ip6_address_t host_ip6_addr;
7363   ip6_address_t host_ip6_gw;
7364   u8 host_ip6_gw_set = 0;
7365   u32 host_ip6_prefix_len = 0;
7366   u8 host_mtu_set = 0;
7367   u32 host_mtu_size = 0;
7368   u32 tap_flags = 0;
7369   int ret;
7370   u32 rx_ring_sz = 0, tx_ring_sz = 0;
7371
7372   clib_memset (mac_address, 0, sizeof (mac_address));
7373
7374   /* Parse args required to build the message */
7375   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7376     {
7377       if (unformat (i, "hw-addr %U", unformat_ethernet_address, mac_address))
7378         {
7379           random_mac = 0;
7380         }
7381       else if (unformat (i, "id %u", &id))
7382         ;
7383       else if (unformat (i, "host-if-name %s", &host_if_name))
7384         ;
7385       else if (unformat (i, "host-ns %s", &host_ns))
7386         ;
7387       else if (unformat (i, "host-mac-addr %U", unformat_ethernet_address,
7388                          host_mac_addr))
7389         host_mac_addr_set = 1;
7390       else if (unformat (i, "host-bridge %s", &host_bridge))
7391         ;
7392       else if (unformat (i, "host-ip4-addr %U/%d", unformat_ip4_address,
7393                          &host_ip4_addr, &host_ip4_prefix_len))
7394         ;
7395       else if (unformat (i, "host-ip6-addr %U/%d", unformat_ip6_address,
7396                          &host_ip6_addr, &host_ip6_prefix_len))
7397         ;
7398       else if (unformat (i, "host-ip4-gw %U", unformat_ip4_address,
7399                          &host_ip4_gw))
7400         host_ip4_gw_set = 1;
7401       else if (unformat (i, "host-ip6-gw %U", unformat_ip6_address,
7402                          &host_ip6_gw))
7403         host_ip6_gw_set = 1;
7404       else if (unformat (i, "rx-ring-size %d", &rx_ring_sz))
7405         ;
7406       else if (unformat (i, "tx-ring-size %d", &tx_ring_sz))
7407         ;
7408       else if (unformat (i, "host-mtu-size %d", &host_mtu_size))
7409         host_mtu_set = 1;
7410       else if (unformat (i, "no-gso"))
7411         tap_flags &= ~TAP_FLAG_GSO;
7412       else if (unformat (i, "gso"))
7413         tap_flags |= TAP_FLAG_GSO;
7414       else
7415         break;
7416     }
7417
7418   if (vec_len (host_if_name) > 63)
7419     {
7420       errmsg ("tap name too long. ");
7421       return -99;
7422     }
7423   if (vec_len (host_ns) > 63)
7424     {
7425       errmsg ("host name space too long. ");
7426       return -99;
7427     }
7428   if (vec_len (host_bridge) > 63)
7429     {
7430       errmsg ("host bridge name too long. ");
7431       return -99;
7432     }
7433   if (host_ip4_prefix_len > 32)
7434     {
7435       errmsg ("host ip4 prefix length not valid. ");
7436       return -99;
7437     }
7438   if (host_ip6_prefix_len > 128)
7439     {
7440       errmsg ("host ip6 prefix length not valid. ");
7441       return -99;
7442     }
7443   if (!is_pow2 (rx_ring_sz))
7444     {
7445       errmsg ("rx ring size must be power of 2. ");
7446       return -99;
7447     }
7448   if (rx_ring_sz > 32768)
7449     {
7450       errmsg ("rx ring size must be 32768 or lower. ");
7451       return -99;
7452     }
7453   if (!is_pow2 (tx_ring_sz))
7454     {
7455       errmsg ("tx ring size must be power of 2. ");
7456       return -99;
7457     }
7458   if (tx_ring_sz > 32768)
7459     {
7460       errmsg ("tx ring size must be 32768 or lower. ");
7461       return -99;
7462     }
7463   if (host_mtu_set && (host_mtu_size < 64 || host_mtu_size > 65355))
7464     {
7465       errmsg ("host MTU size must be in between 64 and 65355. ");
7466       return -99;
7467     }
7468
7469   /* Construct the API message */
7470   M (TAP_CREATE_V2, mp);
7471
7472   mp->use_random_mac = random_mac;
7473
7474   mp->id = ntohl (id);
7475   mp->host_namespace_set = host_ns != 0;
7476   mp->host_bridge_set = host_bridge != 0;
7477   mp->host_ip4_prefix_set = host_ip4_prefix_len != 0;
7478   mp->host_ip6_prefix_set = host_ip6_prefix_len != 0;
7479   mp->rx_ring_sz = ntohs (rx_ring_sz);
7480   mp->tx_ring_sz = ntohs (tx_ring_sz);
7481   mp->host_mtu_set = host_mtu_set;
7482   mp->host_mtu_size = ntohl (host_mtu_size);
7483   mp->tap_flags = ntohl (tap_flags);
7484
7485   if (random_mac == 0)
7486     clib_memcpy (mp->mac_address, mac_address, 6);
7487   if (host_mac_addr_set)
7488     clib_memcpy (mp->host_mac_addr, host_mac_addr, 6);
7489   if (host_if_name)
7490     clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
7491   if (host_ns)
7492     clib_memcpy (mp->host_namespace, host_ns, vec_len (host_ns));
7493   if (host_bridge)
7494     clib_memcpy (mp->host_bridge, host_bridge, vec_len (host_bridge));
7495   if (host_ip4_prefix_len)
7496     clib_memcpy (mp->host_ip4_prefix.address, &host_ip4_addr, 4);
7497   if (host_ip6_prefix_len)
7498     clib_memcpy (mp->host_ip6_prefix.address, &host_ip6_addr, 16);
7499   if (host_ip4_gw_set)
7500     clib_memcpy (mp->host_ip4_gw, &host_ip4_gw, 4);
7501   if (host_ip6_gw_set)
7502     clib_memcpy (mp->host_ip6_gw, &host_ip6_gw, 16);
7503
7504   vec_free (host_ns);
7505   vec_free (host_if_name);
7506   vec_free (host_bridge);
7507
7508   /* send it... */
7509   S (mp);
7510
7511   /* Wait for a reply... */
7512   W (ret);
7513   return ret;
7514 }
7515
7516 static int
7517 api_tap_delete_v2 (vat_main_t * vam)
7518 {
7519   unformat_input_t *i = vam->input;
7520   vl_api_tap_delete_v2_t *mp;
7521   u32 sw_if_index = ~0;
7522   u8 sw_if_index_set = 0;
7523   int ret;
7524
7525   /* Parse args required to build the message */
7526   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7527     {
7528       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7529         sw_if_index_set = 1;
7530       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7531         sw_if_index_set = 1;
7532       else
7533         break;
7534     }
7535
7536   if (sw_if_index_set == 0)
7537     {
7538       errmsg ("missing vpp interface name. ");
7539       return -99;
7540     }
7541
7542   /* Construct the API message */
7543   M (TAP_DELETE_V2, mp);
7544
7545   mp->sw_if_index = ntohl (sw_if_index);
7546
7547   /* send it... */
7548   S (mp);
7549
7550   /* Wait for a reply... */
7551   W (ret);
7552   return ret;
7553 }
7554
7555 uword
7556 unformat_vlib_pci_addr (unformat_input_t * input, va_list * args)
7557 {
7558   vlib_pci_addr_t *addr = va_arg (*args, vlib_pci_addr_t *);
7559   u32 x[4];
7560
7561   if (!unformat (input, "%x:%x:%x.%x", &x[0], &x[1], &x[2], &x[3]))
7562     return 0;
7563
7564   addr->domain = x[0];
7565   addr->bus = x[1];
7566   addr->slot = x[2];
7567   addr->function = x[3];
7568
7569   return 1;
7570 }
7571
7572 static int
7573 api_virtio_pci_create (vat_main_t * vam)
7574 {
7575   unformat_input_t *i = vam->input;
7576   vl_api_virtio_pci_create_t *mp;
7577   u8 mac_address[6];
7578   u8 random_mac = 1;
7579   u8 gso_enabled = 0;
7580   u32 pci_addr = 0;
7581   u64 features = (u64) ~ (0ULL);
7582   int ret;
7583
7584   clib_memset (mac_address, 0, sizeof (mac_address));
7585
7586   /* Parse args required to build the message */
7587   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7588     {
7589       if (unformat (i, "hw-addr %U", unformat_ethernet_address, mac_address))
7590         {
7591           random_mac = 0;
7592         }
7593       else if (unformat (i, "pci-addr %U", unformat_vlib_pci_addr, &pci_addr))
7594         ;
7595       else if (unformat (i, "features 0x%llx", &features))
7596         ;
7597       else if (unformat (i, "gso-enabled"))
7598         gso_enabled = 1;
7599       else
7600         break;
7601     }
7602
7603   if (pci_addr == 0)
7604     {
7605       errmsg ("pci address must be non zero. ");
7606       return -99;
7607     }
7608
7609   /* Construct the API message */
7610   M (VIRTIO_PCI_CREATE, mp);
7611
7612   mp->use_random_mac = random_mac;
7613
7614   mp->pci_addr = htonl (pci_addr);
7615   mp->features = clib_host_to_net_u64 (features);
7616   mp->gso_enabled = gso_enabled;
7617
7618   if (random_mac == 0)
7619     clib_memcpy (mp->mac_address, mac_address, 6);
7620
7621   /* send it... */
7622   S (mp);
7623
7624   /* Wait for a reply... */
7625   W (ret);
7626   return ret;
7627 }
7628
7629 static int
7630 api_virtio_pci_delete (vat_main_t * vam)
7631 {
7632   unformat_input_t *i = vam->input;
7633   vl_api_virtio_pci_delete_t *mp;
7634   u32 sw_if_index = ~0;
7635   u8 sw_if_index_set = 0;
7636   int ret;
7637
7638   /* Parse args required to build the message */
7639   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7640     {
7641       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7642         sw_if_index_set = 1;
7643       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7644         sw_if_index_set = 1;
7645       else
7646         break;
7647     }
7648
7649   if (sw_if_index_set == 0)
7650     {
7651       errmsg ("missing vpp interface name. ");
7652       return -99;
7653     }
7654
7655   /* Construct the API message */
7656   M (VIRTIO_PCI_DELETE, mp);
7657
7658   mp->sw_if_index = htonl (sw_if_index);
7659
7660   /* send it... */
7661   S (mp);
7662
7663   /* Wait for a reply... */
7664   W (ret);
7665   return ret;
7666 }
7667
7668 static int
7669 api_bond_create (vat_main_t * vam)
7670 {
7671   unformat_input_t *i = vam->input;
7672   vl_api_bond_create_t *mp;
7673   u8 mac_address[6];
7674   u8 custom_mac = 0;
7675   int ret;
7676   u8 mode;
7677   u8 lb;
7678   u8 mode_is_set = 0;
7679   u32 id = ~0;
7680   u8 numa_only = 0;
7681
7682   clib_memset (mac_address, 0, sizeof (mac_address));
7683   lb = BOND_LB_L2;
7684
7685   /* Parse args required to build the message */
7686   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7687     {
7688       if (unformat (i, "mode %U", unformat_bond_mode, &mode))
7689         mode_is_set = 1;
7690       else if (((mode == BOND_MODE_LACP) || (mode == BOND_MODE_XOR))
7691                && unformat (i, "lb %U", unformat_bond_load_balance, &lb))
7692         ;
7693       else if (unformat (i, "hw-addr %U", unformat_ethernet_address,
7694                          mac_address))
7695         custom_mac = 1;
7696       else if (unformat (i, "numa-only"))
7697         numa_only = 1;
7698       else if (unformat (i, "id %u", &id))
7699         ;
7700       else
7701         break;
7702     }
7703
7704   if (mode_is_set == 0)
7705     {
7706       errmsg ("Missing bond mode. ");
7707       return -99;
7708     }
7709
7710   /* Construct the API message */
7711   M (BOND_CREATE, mp);
7712
7713   mp->use_custom_mac = custom_mac;
7714
7715   mp->mode = htonl (mode);
7716   mp->lb = htonl (lb);
7717   mp->id = htonl (id);
7718   mp->numa_only = numa_only;
7719
7720   if (custom_mac)
7721     clib_memcpy (mp->mac_address, mac_address, 6);
7722
7723   /* send it... */
7724   S (mp);
7725
7726   /* Wait for a reply... */
7727   W (ret);
7728   return ret;
7729 }
7730
7731 static int
7732 api_bond_delete (vat_main_t * vam)
7733 {
7734   unformat_input_t *i = vam->input;
7735   vl_api_bond_delete_t *mp;
7736   u32 sw_if_index = ~0;
7737   u8 sw_if_index_set = 0;
7738   int ret;
7739
7740   /* Parse args required to build the message */
7741   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7742     {
7743       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7744         sw_if_index_set = 1;
7745       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7746         sw_if_index_set = 1;
7747       else
7748         break;
7749     }
7750
7751   if (sw_if_index_set == 0)
7752     {
7753       errmsg ("missing vpp interface name. ");
7754       return -99;
7755     }
7756
7757   /* Construct the API message */
7758   M (BOND_DELETE, mp);
7759
7760   mp->sw_if_index = ntohl (sw_if_index);
7761
7762   /* send it... */
7763   S (mp);
7764
7765   /* Wait for a reply... */
7766   W (ret);
7767   return ret;
7768 }
7769
7770 static int
7771 api_bond_enslave (vat_main_t * vam)
7772 {
7773   unformat_input_t *i = vam->input;
7774   vl_api_bond_enslave_t *mp;
7775   u32 bond_sw_if_index;
7776   int ret;
7777   u8 is_passive;
7778   u8 is_long_timeout;
7779   u32 bond_sw_if_index_is_set = 0;
7780   u32 sw_if_index;
7781   u8 sw_if_index_is_set = 0;
7782
7783   /* Parse args required to build the message */
7784   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7785     {
7786       if (unformat (i, "sw_if_index %d", &sw_if_index))
7787         sw_if_index_is_set = 1;
7788       else if (unformat (i, "bond %u", &bond_sw_if_index))
7789         bond_sw_if_index_is_set = 1;
7790       else if (unformat (i, "passive %d", &is_passive))
7791         ;
7792       else if (unformat (i, "long-timeout %d", &is_long_timeout))
7793         ;
7794       else
7795         break;
7796     }
7797
7798   if (bond_sw_if_index_is_set == 0)
7799     {
7800       errmsg ("Missing bond sw_if_index. ");
7801       return -99;
7802     }
7803   if (sw_if_index_is_set == 0)
7804     {
7805       errmsg ("Missing slave sw_if_index. ");
7806       return -99;
7807     }
7808
7809   /* Construct the API message */
7810   M (BOND_ENSLAVE, mp);
7811
7812   mp->bond_sw_if_index = ntohl (bond_sw_if_index);
7813   mp->sw_if_index = ntohl (sw_if_index);
7814   mp->is_long_timeout = is_long_timeout;
7815   mp->is_passive = is_passive;
7816
7817   /* send it... */
7818   S (mp);
7819
7820   /* Wait for a reply... */
7821   W (ret);
7822   return ret;
7823 }
7824
7825 static int
7826 api_bond_detach_slave (vat_main_t * vam)
7827 {
7828   unformat_input_t *i = vam->input;
7829   vl_api_bond_detach_slave_t *mp;
7830   u32 sw_if_index = ~0;
7831   u8 sw_if_index_set = 0;
7832   int ret;
7833
7834   /* Parse args required to build the message */
7835   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7836     {
7837       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7838         sw_if_index_set = 1;
7839       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7840         sw_if_index_set = 1;
7841       else
7842         break;
7843     }
7844
7845   if (sw_if_index_set == 0)
7846     {
7847       errmsg ("missing vpp interface name. ");
7848       return -99;
7849     }
7850
7851   /* Construct the API message */
7852   M (BOND_DETACH_SLAVE, mp);
7853
7854   mp->sw_if_index = ntohl (sw_if_index);
7855
7856   /* send it... */
7857   S (mp);
7858
7859   /* Wait for a reply... */
7860   W (ret);
7861   return ret;
7862 }
7863
7864 static int
7865 api_ip_table_add_del (vat_main_t * vam)
7866 {
7867   unformat_input_t *i = vam->input;
7868   vl_api_ip_table_add_del_t *mp;
7869   u32 table_id = ~0;
7870   u8 is_ipv6 = 0;
7871   u8 is_add = 1;
7872   int ret = 0;
7873
7874   /* Parse args required to build the message */
7875   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7876     {
7877       if (unformat (i, "ipv6"))
7878         is_ipv6 = 1;
7879       else if (unformat (i, "del"))
7880         is_add = 0;
7881       else if (unformat (i, "add"))
7882         is_add = 1;
7883       else if (unformat (i, "table %d", &table_id))
7884         ;
7885       else
7886         {
7887           clib_warning ("parse error '%U'", format_unformat_error, i);
7888           return -99;
7889         }
7890     }
7891
7892   if (~0 == table_id)
7893     {
7894       errmsg ("missing table-ID");
7895       return -99;
7896     }
7897
7898   /* Construct the API message */
7899   M (IP_TABLE_ADD_DEL, mp);
7900
7901   mp->table.table_id = ntohl (table_id);
7902   mp->table.is_ip6 = is_ipv6;
7903   mp->is_add = is_add;
7904
7905   /* send it... */
7906   S (mp);
7907
7908   /* Wait for a reply... */
7909   W (ret);
7910
7911   return ret;
7912 }
7913
7914 uword
7915 unformat_fib_path (unformat_input_t * input, va_list * args)
7916 {
7917   vat_main_t *vam = va_arg (*args, vat_main_t *);
7918   vl_api_fib_path_t *path = va_arg (*args, vl_api_fib_path_t *);
7919   u32 weight, preference;
7920   mpls_label_t out_label;
7921
7922   clib_memset (path, 0, sizeof (*path));
7923   path->weight = 1;
7924   path->sw_if_index = ~0;
7925   path->rpf_id = ~0;
7926   path->n_labels = 0;
7927
7928   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7929     {
7930       if (unformat (input, "%U %U",
7931                     unformat_vl_api_ip4_address,
7932                     &path->nh.address.ip4,
7933                     api_unformat_sw_if_index, vam, &path->sw_if_index))
7934         {
7935           path->proto = FIB_API_PATH_NH_PROTO_IP4;
7936         }
7937       else if (unformat (input, "%U %U",
7938                          unformat_vl_api_ip6_address,
7939                          &path->nh.address.ip6,
7940                          api_unformat_sw_if_index, vam, &path->sw_if_index))
7941         {
7942           path->proto = FIB_API_PATH_NH_PROTO_IP6;
7943         }
7944       else if (unformat (input, "weight %u", &weight))
7945         {
7946           path->weight = weight;
7947         }
7948       else if (unformat (input, "preference %u", &preference))
7949         {
7950           path->preference = preference;
7951         }
7952       else if (unformat (input, "%U next-hop-table %d",
7953                          unformat_vl_api_ip4_address,
7954                          &path->nh.address.ip4, &path->table_id))
7955         {
7956           path->proto = FIB_API_PATH_NH_PROTO_IP4;
7957         }
7958       else if (unformat (input, "%U next-hop-table %d",
7959                          unformat_vl_api_ip6_address,
7960                          &path->nh.address.ip6, &path->table_id))
7961         {
7962           path->proto = FIB_API_PATH_NH_PROTO_IP6;
7963         }
7964       else if (unformat (input, "%U",
7965                          unformat_vl_api_ip4_address, &path->nh.address.ip4))
7966         {
7967           /*
7968            * the recursive next-hops are by default in the default table
7969            */
7970           path->table_id = 0;
7971           path->sw_if_index = ~0;
7972           path->proto = FIB_API_PATH_NH_PROTO_IP4;
7973         }
7974       else if (unformat (input, "%U",
7975                          unformat_vl_api_ip6_address, &path->nh.address.ip6))
7976         {
7977           /*
7978            * the recursive next-hops are by default in the default table
7979            */
7980           path->table_id = 0;
7981           path->sw_if_index = ~0;
7982           path->proto = FIB_API_PATH_NH_PROTO_IP6;
7983         }
7984       else if (unformat (input, "resolve-via-host"))
7985         {
7986           path->flags |= FIB_API_PATH_FLAG_RESOLVE_VIA_HOST;
7987         }
7988       else if (unformat (input, "resolve-via-attached"))
7989         {
7990           path->flags |= FIB_API_PATH_FLAG_RESOLVE_VIA_ATTACHED;
7991         }
7992       else if (unformat (input, "ip4-lookup-in-table %d", &path->table_id))
7993         {
7994           path->type = FIB_API_PATH_TYPE_LOCAL;
7995           path->sw_if_index = ~0;
7996           path->proto = FIB_API_PATH_NH_PROTO_IP4;
7997         }
7998       else if (unformat (input, "ip6-lookup-in-table %d", &path->table_id))
7999         {
8000           path->type = FIB_API_PATH_TYPE_LOCAL;
8001           path->sw_if_index = ~0;
8002           path->proto = FIB_API_PATH_NH_PROTO_IP6;
8003         }
8004       else if (unformat (input, "sw_if_index %d", &path->sw_if_index))
8005         ;
8006       else if (unformat (input, "via-label %d", &path->nh.via_label))
8007         {
8008           path->proto = FIB_API_PATH_NH_PROTO_MPLS;
8009           path->sw_if_index = ~0;
8010         }
8011       else if (unformat (input, "l2-input-on %d", &path->sw_if_index))
8012         {
8013           path->proto = FIB_API_PATH_NH_PROTO_ETHERNET;
8014           path->type = FIB_API_PATH_TYPE_INTERFACE_RX;
8015         }
8016       else if (unformat (input, "local"))
8017         {
8018           path->type = FIB_API_PATH_TYPE_LOCAL;
8019         }
8020       else if (unformat (input, "out-labels"))
8021         {
8022           while (unformat (input, "%d", &out_label))
8023             {
8024               path->label_stack[path->n_labels].label = out_label;
8025               path->label_stack[path->n_labels].is_uniform = 0;
8026               path->label_stack[path->n_labels].ttl = 64;
8027               path->n_labels++;
8028             }
8029         }
8030       else if (unformat (input, "via"))
8031         {
8032           /* new path, back up and return */
8033           unformat_put_input (input);
8034           unformat_put_input (input);
8035           unformat_put_input (input);
8036           unformat_put_input (input);
8037           break;
8038         }
8039       else
8040         {
8041           return (0);
8042         }
8043     }
8044
8045   path->proto = ntohl (path->proto);
8046   path->type = ntohl (path->type);
8047   path->flags = ntohl (path->flags);
8048   path->table_id = ntohl (path->table_id);
8049   path->sw_if_index = ntohl (path->sw_if_index);
8050
8051   return (1);
8052 }
8053
8054 static int
8055 api_ip_route_add_del (vat_main_t * vam)
8056 {
8057   unformat_input_t *i = vam->input;
8058   vl_api_ip_route_add_del_t *mp;
8059   u32 vrf_id = 0;
8060   u8 is_add = 1;
8061   u8 is_multipath = 0;
8062   u8 prefix_set = 0;
8063   u8 path_count = 0;
8064   vl_api_prefix_t pfx = { };
8065   vl_api_fib_path_t paths[8];
8066   int count = 1;
8067   int j;
8068   f64 before = 0;
8069   u32 random_add_del = 0;
8070   u32 *random_vector = 0;
8071   u32 random_seed = 0xdeaddabe;
8072
8073   /* Parse args required to build the message */
8074   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8075     {
8076       if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
8077         prefix_set = 1;
8078       else if (unformat (i, "del"))
8079         is_add = 0;
8080       else if (unformat (i, "add"))
8081         is_add = 1;
8082       else if (unformat (i, "vrf %d", &vrf_id))
8083         ;
8084       else if (unformat (i, "count %d", &count))
8085         ;
8086       else if (unformat (i, "random"))
8087         random_add_del = 1;
8088       else if (unformat (i, "multipath"))
8089         is_multipath = 1;
8090       else if (unformat (i, "seed %d", &random_seed))
8091         ;
8092       else
8093         if (unformat
8094             (i, "via %U", unformat_fib_path, vam, &paths[path_count]))
8095         {
8096           path_count++;
8097           if (8 == path_count)
8098             {
8099               errmsg ("max 8 paths");
8100               return -99;
8101             }
8102         }
8103       else
8104         {
8105           clib_warning ("parse error '%U'", format_unformat_error, i);
8106           return -99;
8107         }
8108     }
8109
8110   if (!path_count)
8111     {
8112       errmsg ("specify a path; via ...");
8113       return -99;
8114     }
8115   if (prefix_set == 0)
8116     {
8117       errmsg ("missing prefix");
8118       return -99;
8119     }
8120
8121   /* Generate a pile of unique, random routes */
8122   if (random_add_del)
8123     {
8124       ip4_address_t *i = (ip4_address_t *) & paths[0].nh.address.ip4;
8125       u32 this_random_address;
8126       uword *random_hash;
8127
8128       random_hash = hash_create (count, sizeof (uword));
8129
8130       hash_set (random_hash, i->as_u32, 1);
8131       for (j = 0; j <= count; j++)
8132         {
8133           do
8134             {
8135               this_random_address = random_u32 (&random_seed);
8136               this_random_address =
8137                 clib_host_to_net_u32 (this_random_address);
8138             }
8139           while (hash_get (random_hash, this_random_address));
8140           vec_add1 (random_vector, this_random_address);
8141           hash_set (random_hash, this_random_address, 1);
8142         }
8143       hash_free (random_hash);
8144       set_ip4_address (&pfx.address, random_vector[0]);
8145     }
8146
8147   if (count > 1)
8148     {
8149       /* Turn on async mode */
8150       vam->async_mode = 1;
8151       vam->async_errors = 0;
8152       before = vat_time_now (vam);
8153     }
8154
8155   for (j = 0; j < count; j++)
8156     {
8157       /* Construct the API message */
8158       M2 (IP_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t) * path_count);
8159
8160       mp->is_add = is_add;
8161       mp->is_multipath = is_multipath;
8162
8163       clib_memcpy (&mp->route.prefix, &pfx, sizeof (pfx));
8164       mp->route.table_id = ntohl (vrf_id);
8165       mp->route.n_paths = path_count;
8166
8167       clib_memcpy (&mp->route.paths, &paths, sizeof (paths[0]) * path_count);
8168
8169       if (random_add_del)
8170         set_ip4_address (&pfx.address, random_vector[j + 1]);
8171       else
8172         increment_address (&pfx.address);
8173       /* send it... */
8174       S (mp);
8175       /* If we receive SIGTERM, stop now... */
8176       if (vam->do_exit)
8177         break;
8178     }
8179
8180   /* When testing multiple add/del ops, use a control-ping to sync */
8181   if (count > 1)
8182     {
8183       vl_api_control_ping_t *mp_ping;
8184       f64 after;
8185       f64 timeout;
8186
8187       /* Shut off async mode */
8188       vam->async_mode = 0;
8189
8190       MPING (CONTROL_PING, mp_ping);
8191       S (mp_ping);
8192
8193       timeout = vat_time_now (vam) + 1.0;
8194       while (vat_time_now (vam) < timeout)
8195         if (vam->result_ready == 1)
8196           goto out;
8197       vam->retval = -99;
8198
8199     out:
8200       if (vam->retval == -99)
8201         errmsg ("timeout");
8202
8203       if (vam->async_errors > 0)
8204         {
8205           errmsg ("%d asynchronous errors", vam->async_errors);
8206           vam->retval = -98;
8207         }
8208       vam->async_errors = 0;
8209       after = vat_time_now (vam);
8210
8211       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8212       if (j > 0)
8213         count = j;
8214
8215       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8216              count, after - before, count / (after - before));
8217     }
8218   else
8219     {
8220       int ret;
8221
8222       /* Wait for a reply... */
8223       W (ret);
8224       return ret;
8225     }
8226
8227   /* Return the good/bad news */
8228   return (vam->retval);
8229 }
8230
8231 static int
8232 api_ip_mroute_add_del (vat_main_t * vam)
8233 {
8234   unformat_input_t *i = vam->input;
8235   u8 path_set = 0, prefix_set = 0, is_add = 1;
8236   vl_api_ip_mroute_add_del_t *mp;
8237   mfib_entry_flags_t eflags = 0;
8238   vl_api_mfib_path_t path;
8239   vl_api_mprefix_t pfx = { };
8240   u32 vrf_id = 0;
8241   int ret;
8242
8243   /* Parse args required to build the message */
8244   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8245     {
8246       if (unformat (i, "%U", unformat_vl_api_mprefix, &pfx))
8247         {
8248           prefix_set = 1;
8249           pfx.grp_address_length = htons (pfx.grp_address_length);
8250         }
8251       else if (unformat (i, "del"))
8252         is_add = 0;
8253       else if (unformat (i, "add"))
8254         is_add = 1;
8255       else if (unformat (i, "vrf %d", &vrf_id))
8256         ;
8257       else if (unformat (i, "%U", unformat_mfib_itf_flags, &path.itf_flags))
8258         path.itf_flags = htonl (path.itf_flags);
8259       else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
8260         ;
8261       else if (unformat (i, "via %U", unformat_fib_path, vam, &path.path))
8262         path_set = 1;
8263       else
8264         {
8265           clib_warning ("parse error '%U'", format_unformat_error, i);
8266           return -99;
8267         }
8268     }
8269
8270   if (prefix_set == 0)
8271     {
8272       errmsg ("missing addresses\n");
8273       return -99;
8274     }
8275   if (path_set == 0)
8276     {
8277       errmsg ("missing path\n");
8278       return -99;
8279     }
8280
8281   /* Construct the API message */
8282   M (IP_MROUTE_ADD_DEL, mp);
8283
8284   mp->is_add = is_add;
8285   mp->is_multipath = 1;
8286
8287   clib_memcpy (&mp->route.prefix, &pfx, sizeof (pfx));
8288   mp->route.table_id = htonl (vrf_id);
8289   mp->route.n_paths = 1;
8290   mp->route.entry_flags = htonl (eflags);
8291
8292   clib_memcpy (&mp->route.paths, &path, sizeof (path));
8293
8294   /* send it... */
8295   S (mp);
8296   /* Wait for a reply... */
8297   W (ret);
8298   return ret;
8299 }
8300
8301 static int
8302 api_mpls_table_add_del (vat_main_t * vam)
8303 {
8304   unformat_input_t *i = vam->input;
8305   vl_api_mpls_table_add_del_t *mp;
8306   u32 table_id = ~0;
8307   u8 is_add = 1;
8308   int ret = 0;
8309
8310   /* Parse args required to build the message */
8311   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8312     {
8313       if (unformat (i, "table %d", &table_id))
8314         ;
8315       else if (unformat (i, "del"))
8316         is_add = 0;
8317       else if (unformat (i, "add"))
8318         is_add = 1;
8319       else
8320         {
8321           clib_warning ("parse error '%U'", format_unformat_error, i);
8322           return -99;
8323         }
8324     }
8325
8326   if (~0 == table_id)
8327     {
8328       errmsg ("missing table-ID");
8329       return -99;
8330     }
8331
8332   /* Construct the API message */
8333   M (MPLS_TABLE_ADD_DEL, mp);
8334
8335   mp->mt_table.mt_table_id = ntohl (table_id);
8336   mp->mt_is_add = is_add;
8337
8338   /* send it... */
8339   S (mp);
8340
8341   /* Wait for a reply... */
8342   W (ret);
8343
8344   return ret;
8345 }
8346
8347 static int
8348 api_mpls_route_add_del (vat_main_t * vam)
8349 {
8350   u8 is_add = 1, path_count = 0, is_multipath = 0, is_eos = 0;
8351   mpls_label_t local_label = MPLS_LABEL_INVALID;
8352   unformat_input_t *i = vam->input;
8353   vl_api_mpls_route_add_del_t *mp;
8354   vl_api_fib_path_t paths[8];
8355   int count = 1, j;
8356   f64 before = 0;
8357
8358   /* Parse args required to build the message */
8359   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8360     {
8361       if (unformat (i, "%d", &local_label))
8362         ;
8363       else if (unformat (i, "eos"))
8364         is_eos = 1;
8365       else if (unformat (i, "non-eos"))
8366         is_eos = 0;
8367       else if (unformat (i, "del"))
8368         is_add = 0;
8369       else if (unformat (i, "add"))
8370         is_add = 1;
8371       else if (unformat (i, "multipath"))
8372         is_multipath = 1;
8373       else if (unformat (i, "count %d", &count))
8374         ;
8375       else
8376         if (unformat
8377             (i, "via %U", unformat_fib_path, vam, &paths[path_count]))
8378         {
8379           path_count++;
8380           if (8 == path_count)
8381             {
8382               errmsg ("max 8 paths");
8383               return -99;
8384             }
8385         }
8386       else
8387         {
8388           clib_warning ("parse error '%U'", format_unformat_error, i);
8389           return -99;
8390         }
8391     }
8392
8393   if (!path_count)
8394     {
8395       errmsg ("specify a path; via ...");
8396       return -99;
8397     }
8398
8399   if (MPLS_LABEL_INVALID == local_label)
8400     {
8401       errmsg ("missing label");
8402       return -99;
8403     }
8404
8405   if (count > 1)
8406     {
8407       /* Turn on async mode */
8408       vam->async_mode = 1;
8409       vam->async_errors = 0;
8410       before = vat_time_now (vam);
8411     }
8412
8413   for (j = 0; j < count; j++)
8414     {
8415       /* Construct the API message */
8416       M2 (MPLS_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t) * path_count);
8417
8418       mp->mr_is_add = is_add;
8419       mp->mr_is_multipath = is_multipath;
8420
8421       mp->mr_route.mr_label = local_label;
8422       mp->mr_route.mr_eos = is_eos;
8423       mp->mr_route.mr_table_id = 0;
8424       mp->mr_route.mr_n_paths = path_count;
8425
8426       clib_memcpy (&mp->mr_route.mr_paths, paths,
8427                    sizeof (paths[0]) * path_count);
8428
8429       local_label++;
8430
8431       /* send it... */
8432       S (mp);
8433       /* If we receive SIGTERM, stop now... */
8434       if (vam->do_exit)
8435         break;
8436     }
8437
8438   /* When testing multiple add/del ops, use a control-ping to sync */
8439   if (count > 1)
8440     {
8441       vl_api_control_ping_t *mp_ping;
8442       f64 after;
8443       f64 timeout;
8444
8445       /* Shut off async mode */
8446       vam->async_mode = 0;
8447
8448       MPING (CONTROL_PING, mp_ping);
8449       S (mp_ping);
8450
8451       timeout = vat_time_now (vam) + 1.0;
8452       while (vat_time_now (vam) < timeout)
8453         if (vam->result_ready == 1)
8454           goto out;
8455       vam->retval = -99;
8456
8457     out:
8458       if (vam->retval == -99)
8459         errmsg ("timeout");
8460
8461       if (vam->async_errors > 0)
8462         {
8463           errmsg ("%d asynchronous errors", vam->async_errors);
8464           vam->retval = -98;
8465         }
8466       vam->async_errors = 0;
8467       after = vat_time_now (vam);
8468
8469       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8470       if (j > 0)
8471         count = j;
8472
8473       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8474              count, after - before, count / (after - before));
8475     }
8476   else
8477     {
8478       int ret;
8479
8480       /* Wait for a reply... */
8481       W (ret);
8482       return ret;
8483     }
8484
8485   /* Return the good/bad news */
8486   return (vam->retval);
8487   return (0);
8488 }
8489
8490 static int
8491 api_mpls_ip_bind_unbind (vat_main_t * vam)
8492 {
8493   unformat_input_t *i = vam->input;
8494   vl_api_mpls_ip_bind_unbind_t *mp;
8495   u32 ip_table_id = 0;
8496   u8 is_bind = 1;
8497   vl_api_prefix_t pfx;
8498   u8 prefix_set = 0;
8499   mpls_label_t local_label = MPLS_LABEL_INVALID;
8500   int ret;
8501
8502   /* Parse args required to build the message */
8503   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8504     {
8505       if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
8506         prefix_set = 1;
8507       else if (unformat (i, "%d", &local_label))
8508         ;
8509       else if (unformat (i, "table-id %d", &ip_table_id))
8510         ;
8511       else if (unformat (i, "unbind"))
8512         is_bind = 0;
8513       else if (unformat (i, "bind"))
8514         is_bind = 1;
8515       else
8516         {
8517           clib_warning ("parse error '%U'", format_unformat_error, i);
8518           return -99;
8519         }
8520     }
8521
8522   if (!prefix_set)
8523     {
8524       errmsg ("IP prefix not set");
8525       return -99;
8526     }
8527
8528   if (MPLS_LABEL_INVALID == local_label)
8529     {
8530       errmsg ("missing label");
8531       return -99;
8532     }
8533
8534   /* Construct the API message */
8535   M (MPLS_IP_BIND_UNBIND, mp);
8536
8537   mp->mb_is_bind = is_bind;
8538   mp->mb_ip_table_id = ntohl (ip_table_id);
8539   mp->mb_mpls_table_id = 0;
8540   mp->mb_label = ntohl (local_label);
8541   clib_memcpy (&mp->mb_prefix, &pfx, sizeof (pfx));
8542
8543   /* send it... */
8544   S (mp);
8545
8546   /* Wait for a reply... */
8547   W (ret);
8548   return ret;
8549   return (0);
8550 }
8551
8552 static int
8553 api_sr_mpls_policy_add (vat_main_t * vam)
8554 {
8555   unformat_input_t *i = vam->input;
8556   vl_api_sr_mpls_policy_add_t *mp;
8557   u32 bsid = 0;
8558   u32 weight = 1;
8559   u8 type = 0;
8560   u8 n_segments = 0;
8561   u32 sid;
8562   u32 *segments = NULL;
8563   int ret;
8564
8565   /* Parse args required to build the message */
8566   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8567     {
8568       if (unformat (i, "bsid %d", &bsid))
8569         ;
8570       else if (unformat (i, "weight %d", &weight))
8571         ;
8572       else if (unformat (i, "spray"))
8573         type = 1;
8574       else if (unformat (i, "next %d", &sid))
8575         {
8576           n_segments += 1;
8577           vec_add1 (segments, htonl (sid));
8578         }
8579       else
8580         {
8581           clib_warning ("parse error '%U'", format_unformat_error, i);
8582           return -99;
8583         }
8584     }
8585
8586   if (bsid == 0)
8587     {
8588       errmsg ("bsid not set");
8589       return -99;
8590     }
8591
8592   if (n_segments == 0)
8593     {
8594       errmsg ("no sid in segment stack");
8595       return -99;
8596     }
8597
8598   /* Construct the API message */
8599   M2 (SR_MPLS_POLICY_ADD, mp, sizeof (u32) * n_segments);
8600
8601   mp->bsid = htonl (bsid);
8602   mp->weight = htonl (weight);
8603   mp->type = type;
8604   mp->n_segments = n_segments;
8605   memcpy (mp->segments, segments, sizeof (u32) * n_segments);
8606   vec_free (segments);
8607
8608   /* send it... */
8609   S (mp);
8610
8611   /* Wait for a reply... */
8612   W (ret);
8613   return ret;
8614 }
8615
8616 static int
8617 api_sr_mpls_policy_del (vat_main_t * vam)
8618 {
8619   unformat_input_t *i = vam->input;
8620   vl_api_sr_mpls_policy_del_t *mp;
8621   u32 bsid = 0;
8622   int ret;
8623
8624   /* Parse args required to build the message */
8625   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8626     {
8627       if (unformat (i, "bsid %d", &bsid))
8628         ;
8629       else
8630         {
8631           clib_warning ("parse error '%U'", format_unformat_error, i);
8632           return -99;
8633         }
8634     }
8635
8636   if (bsid == 0)
8637     {
8638       errmsg ("bsid not set");
8639       return -99;
8640     }
8641
8642   /* Construct the API message */
8643   M (SR_MPLS_POLICY_DEL, mp);
8644
8645   mp->bsid = htonl (bsid);
8646
8647   /* send it... */
8648   S (mp);
8649
8650   /* Wait for a reply... */
8651   W (ret);
8652   return ret;
8653 }
8654
8655 static int
8656 api_bier_table_add_del (vat_main_t * vam)
8657 {
8658   unformat_input_t *i = vam->input;
8659   vl_api_bier_table_add_del_t *mp;
8660   u8 is_add = 1;
8661   u32 set = 0, sub_domain = 0, hdr_len = 3;
8662   mpls_label_t local_label = MPLS_LABEL_INVALID;
8663   int ret;
8664
8665   /* Parse args required to build the message */
8666   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8667     {
8668       if (unformat (i, "sub-domain %d", &sub_domain))
8669         ;
8670       else if (unformat (i, "set %d", &set))
8671         ;
8672       else if (unformat (i, "label %d", &local_label))
8673         ;
8674       else if (unformat (i, "hdr-len %d", &hdr_len))
8675         ;
8676       else if (unformat (i, "add"))
8677         is_add = 1;
8678       else if (unformat (i, "del"))
8679         is_add = 0;
8680       else
8681         {
8682           clib_warning ("parse error '%U'", format_unformat_error, i);
8683           return -99;
8684         }
8685     }
8686
8687   if (MPLS_LABEL_INVALID == local_label)
8688     {
8689       errmsg ("missing label\n");
8690       return -99;
8691     }
8692
8693   /* Construct the API message */
8694   M (BIER_TABLE_ADD_DEL, mp);
8695
8696   mp->bt_is_add = is_add;
8697   mp->bt_label = ntohl (local_label);
8698   mp->bt_tbl_id.bt_set = set;
8699   mp->bt_tbl_id.bt_sub_domain = sub_domain;
8700   mp->bt_tbl_id.bt_hdr_len_id = hdr_len;
8701
8702   /* send it... */
8703   S (mp);
8704
8705   /* Wait for a reply... */
8706   W (ret);
8707
8708   return (ret);
8709 }
8710
8711 static int
8712 api_bier_route_add_del (vat_main_t * vam)
8713 {
8714   unformat_input_t *i = vam->input;
8715   vl_api_bier_route_add_del_t *mp;
8716   u8 is_add = 1;
8717   u32 set = 0, sub_domain = 0, hdr_len = 3, bp = 0;
8718   ip4_address_t v4_next_hop_address;
8719   ip6_address_t v6_next_hop_address;
8720   u8 next_hop_set = 0;
8721   u8 next_hop_proto_is_ip4 = 1;
8722   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8723   int ret;
8724
8725   /* Parse args required to build the message */
8726   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8727     {
8728       if (unformat (i, "%U", unformat_ip4_address, &v4_next_hop_address))
8729         {
8730           next_hop_proto_is_ip4 = 1;
8731           next_hop_set = 1;
8732         }
8733       else if (unformat (i, "%U", unformat_ip6_address, &v6_next_hop_address))
8734         {
8735           next_hop_proto_is_ip4 = 0;
8736           next_hop_set = 1;
8737         }
8738       if (unformat (i, "sub-domain %d", &sub_domain))
8739         ;
8740       else if (unformat (i, "set %d", &set))
8741         ;
8742       else if (unformat (i, "hdr-len %d", &hdr_len))
8743         ;
8744       else if (unformat (i, "bp %d", &bp))
8745         ;
8746       else if (unformat (i, "add"))
8747         is_add = 1;
8748       else if (unformat (i, "del"))
8749         is_add = 0;
8750       else if (unformat (i, "out-label %d", &next_hop_out_label))
8751         ;
8752       else
8753         {
8754           clib_warning ("parse error '%U'", format_unformat_error, i);
8755           return -99;
8756         }
8757     }
8758
8759   if (!next_hop_set || (MPLS_LABEL_INVALID == next_hop_out_label))
8760     {
8761       errmsg ("next hop / label set\n");
8762       return -99;
8763     }
8764   if (0 == bp)
8765     {
8766       errmsg ("bit=position not set\n");
8767       return -99;
8768     }
8769
8770   /* Construct the API message */
8771   M2 (BIER_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t));
8772
8773   mp->br_is_add = is_add;
8774   mp->br_route.br_tbl_id.bt_set = set;
8775   mp->br_route.br_tbl_id.bt_sub_domain = sub_domain;
8776   mp->br_route.br_tbl_id.bt_hdr_len_id = hdr_len;
8777   mp->br_route.br_bp = ntohs (bp);
8778   mp->br_route.br_n_paths = 1;
8779   mp->br_route.br_paths[0].n_labels = 1;
8780   mp->br_route.br_paths[0].label_stack[0].label = ntohl (next_hop_out_label);
8781   mp->br_route.br_paths[0].proto = (next_hop_proto_is_ip4 ?
8782                                     FIB_API_PATH_NH_PROTO_IP4 :
8783                                     FIB_API_PATH_NH_PROTO_IP6);
8784
8785   if (next_hop_proto_is_ip4)
8786     {
8787       clib_memcpy (&mp->br_route.br_paths[0].nh.address.ip4,
8788                    &v4_next_hop_address, sizeof (v4_next_hop_address));
8789     }
8790   else
8791     {
8792       clib_memcpy (&mp->br_route.br_paths[0].nh.address.ip6,
8793                    &v6_next_hop_address, sizeof (v6_next_hop_address));
8794     }
8795
8796   /* send it... */
8797   S (mp);
8798
8799   /* Wait for a reply... */
8800   W (ret);
8801
8802   return (ret);
8803 }
8804
8805 static int
8806 api_proxy_arp_add_del (vat_main_t * vam)
8807 {
8808   unformat_input_t *i = vam->input;
8809   vl_api_proxy_arp_add_del_t *mp;
8810   u32 vrf_id = 0;
8811   u8 is_add = 1;
8812   vl_api_ip4_address_t lo, hi;
8813   u8 range_set = 0;
8814   int ret;
8815
8816   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8817     {
8818       if (unformat (i, "vrf %d", &vrf_id))
8819         ;
8820       else if (unformat (i, "%U - %U", unformat_vl_api_ip4_address, &lo,
8821                          unformat_vl_api_ip4_address, &hi))
8822         range_set = 1;
8823       else if (unformat (i, "del"))
8824         is_add = 0;
8825       else
8826         {
8827           clib_warning ("parse error '%U'", format_unformat_error, i);
8828           return -99;
8829         }
8830     }
8831
8832   if (range_set == 0)
8833     {
8834       errmsg ("address range not set");
8835       return -99;
8836     }
8837
8838   M (PROXY_ARP_ADD_DEL, mp);
8839
8840   mp->proxy.table_id = ntohl (vrf_id);
8841   mp->is_add = is_add;
8842   clib_memcpy (mp->proxy.low, &lo, sizeof (lo));
8843   clib_memcpy (mp->proxy.hi, &hi, sizeof (hi));
8844
8845   S (mp);
8846   W (ret);
8847   return ret;
8848 }
8849
8850 static int
8851 api_proxy_arp_intfc_enable_disable (vat_main_t * vam)
8852 {
8853   unformat_input_t *i = vam->input;
8854   vl_api_proxy_arp_intfc_enable_disable_t *mp;
8855   u32 sw_if_index;
8856   u8 enable = 1;
8857   u8 sw_if_index_set = 0;
8858   int ret;
8859
8860   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8861     {
8862       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8863         sw_if_index_set = 1;
8864       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8865         sw_if_index_set = 1;
8866       else if (unformat (i, "enable"))
8867         enable = 1;
8868       else if (unformat (i, "disable"))
8869         enable = 0;
8870       else
8871         {
8872           clib_warning ("parse error '%U'", format_unformat_error, i);
8873           return -99;
8874         }
8875     }
8876
8877   if (sw_if_index_set == 0)
8878     {
8879       errmsg ("missing interface name or sw_if_index");
8880       return -99;
8881     }
8882
8883   M (PROXY_ARP_INTFC_ENABLE_DISABLE, mp);
8884
8885   mp->sw_if_index = ntohl (sw_if_index);
8886   mp->enable_disable = enable;
8887
8888   S (mp);
8889   W (ret);
8890   return ret;
8891 }
8892
8893 static int
8894 api_mpls_tunnel_add_del (vat_main_t * vam)
8895 {
8896   unformat_input_t *i = vam->input;
8897   vl_api_mpls_tunnel_add_del_t *mp;
8898
8899   vl_api_fib_path_t paths[8];
8900   u32 sw_if_index = ~0;
8901   u8 path_count = 0;
8902   u8 l2_only = 0;
8903   u8 is_add = 1;
8904   int ret;
8905
8906   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8907     {
8908       if (unformat (i, "add"))
8909         is_add = 1;
8910       else
8911         if (unformat
8912             (i, "del %U", api_unformat_sw_if_index, vam, &sw_if_index))
8913         is_add = 0;
8914       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
8915         is_add = 0;
8916       else if (unformat (i, "l2-only"))
8917         l2_only = 1;
8918       else
8919         if (unformat
8920             (i, "via %U", unformat_fib_path, vam, &paths[path_count]))
8921         {
8922           path_count++;
8923           if (8 == path_count)
8924             {
8925               errmsg ("max 8 paths");
8926               return -99;
8927             }
8928         }
8929       else
8930         {
8931           clib_warning ("parse error '%U'", format_unformat_error, i);
8932           return -99;
8933         }
8934     }
8935
8936   M2 (MPLS_TUNNEL_ADD_DEL, mp, sizeof (vl_api_fib_path_t) * path_count);
8937
8938   mp->mt_is_add = is_add;
8939   mp->mt_tunnel.mt_sw_if_index = ntohl (sw_if_index);
8940   mp->mt_tunnel.mt_l2_only = l2_only;
8941   mp->mt_tunnel.mt_is_multicast = 0;
8942   mp->mt_tunnel.mt_n_paths = path_count;
8943
8944   clib_memcpy (&mp->mt_tunnel.mt_paths, &paths,
8945                sizeof (paths[0]) * path_count);
8946
8947   S (mp);
8948   W (ret);
8949   return ret;
8950 }
8951
8952 static int
8953 api_sw_interface_set_unnumbered (vat_main_t * vam)
8954 {
8955   unformat_input_t *i = vam->input;
8956   vl_api_sw_interface_set_unnumbered_t *mp;
8957   u32 sw_if_index;
8958   u32 unnum_sw_index = ~0;
8959   u8 is_add = 1;
8960   u8 sw_if_index_set = 0;
8961   int ret;
8962
8963   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8964     {
8965       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8966         sw_if_index_set = 1;
8967       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8968         sw_if_index_set = 1;
8969       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
8970         ;
8971       else if (unformat (i, "del"))
8972         is_add = 0;
8973       else
8974         {
8975           clib_warning ("parse error '%U'", format_unformat_error, i);
8976           return -99;
8977         }
8978     }
8979
8980   if (sw_if_index_set == 0)
8981     {
8982       errmsg ("missing interface name or sw_if_index");
8983       return -99;
8984     }
8985
8986   M (SW_INTERFACE_SET_UNNUMBERED, mp);
8987
8988   mp->sw_if_index = ntohl (sw_if_index);
8989   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
8990   mp->is_add = is_add;
8991
8992   S (mp);
8993   W (ret);
8994   return ret;
8995 }
8996
8997 static int
8998 api_ip_neighbor_add_del (vat_main_t * vam)
8999 {
9000   vl_api_mac_address_t mac_address;
9001   unformat_input_t *i = vam->input;
9002   vl_api_ip_neighbor_add_del_t *mp;
9003   vl_api_address_t ip_address;
9004   u32 sw_if_index;
9005   u8 sw_if_index_set = 0;
9006   u8 is_add = 1;
9007   u8 mac_set = 0;
9008   u8 address_set = 0;
9009   int ret;
9010   ip_neighbor_flags_t flags;
9011
9012   flags = IP_NEIGHBOR_FLAG_NONE;
9013   clib_memset (&ip_address, 0, sizeof (ip_address));
9014   clib_memset (&mac_address, 0, sizeof (mac_address));
9015
9016   /* Parse args required to build the message */
9017   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9018     {
9019       if (unformat (i, "mac %U", unformat_vl_api_mac_address, &mac_address))
9020         {
9021           mac_set = 1;
9022         }
9023       else if (unformat (i, "del"))
9024         is_add = 0;
9025       else
9026         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9027         sw_if_index_set = 1;
9028       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9029         sw_if_index_set = 1;
9030       else if (unformat (i, "static"))
9031         flags |= IP_NEIGHBOR_FLAG_STATIC;
9032       else if (unformat (i, "no-fib-entry"))
9033         flags |= IP_NEIGHBOR_FLAG_NO_FIB_ENTRY;
9034       else if (unformat (i, "dst %U", unformat_vl_api_address, &ip_address))
9035         address_set = 1;
9036       else
9037         {
9038           clib_warning ("parse error '%U'", format_unformat_error, i);
9039           return -99;
9040         }
9041     }
9042
9043   if (sw_if_index_set == 0)
9044     {
9045       errmsg ("missing interface name or sw_if_index");
9046       return -99;
9047     }
9048   if (!address_set)
9049     {
9050       errmsg ("no address set");
9051       return -99;
9052     }
9053
9054   /* Construct the API message */
9055   M (IP_NEIGHBOR_ADD_DEL, mp);
9056
9057   mp->neighbor.sw_if_index = ntohl (sw_if_index);
9058   mp->is_add = is_add;
9059   mp->neighbor.flags = htonl (flags);
9060   if (mac_set)
9061     clib_memcpy (&mp->neighbor.mac_address, &mac_address,
9062                  sizeof (mac_address));
9063   if (address_set)
9064     clib_memcpy (&mp->neighbor.ip_address, &ip_address, sizeof (ip_address));
9065
9066   /* send it... */
9067   S (mp);
9068
9069   /* Wait for a reply, return good/bad news  */
9070   W (ret);
9071   return ret;
9072 }
9073
9074 static int
9075 api_create_vlan_subif (vat_main_t * vam)
9076 {
9077   unformat_input_t *i = vam->input;
9078   vl_api_create_vlan_subif_t *mp;
9079   u32 sw_if_index;
9080   u8 sw_if_index_set = 0;
9081   u32 vlan_id;
9082   u8 vlan_id_set = 0;
9083   int ret;
9084
9085   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9086     {
9087       if (unformat (i, "sw_if_index %d", &sw_if_index))
9088         sw_if_index_set = 1;
9089       else
9090         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9091         sw_if_index_set = 1;
9092       else if (unformat (i, "vlan %d", &vlan_id))
9093         vlan_id_set = 1;
9094       else
9095         {
9096           clib_warning ("parse error '%U'", format_unformat_error, i);
9097           return -99;
9098         }
9099     }
9100
9101   if (sw_if_index_set == 0)
9102     {
9103       errmsg ("missing interface name or sw_if_index");
9104       return -99;
9105     }
9106
9107   if (vlan_id_set == 0)
9108     {
9109       errmsg ("missing vlan_id");
9110       return -99;
9111     }
9112   M (CREATE_VLAN_SUBIF, mp);
9113
9114   mp->sw_if_index = ntohl (sw_if_index);
9115   mp->vlan_id = ntohl (vlan_id);
9116
9117   S (mp);
9118   W (ret);
9119   return ret;
9120 }
9121
9122 #define foreach_create_subif_bit                \
9123 _(no_tags)                                      \
9124 _(one_tag)                                      \
9125 _(two_tags)                                     \
9126 _(dot1ad)                                       \
9127 _(exact_match)                                  \
9128 _(default_sub)                                  \
9129 _(outer_vlan_id_any)                            \
9130 _(inner_vlan_id_any)
9131
9132 #define foreach_create_subif_flag               \
9133 _(0, "no_tags")                                 \
9134 _(1, "one_tag")                                 \
9135 _(2, "two_tags")                                \
9136 _(3, "dot1ad")                                  \
9137 _(4, "exact_match")                             \
9138 _(5, "default_sub")                             \
9139 _(6, "outer_vlan_id_any")                       \
9140 _(7, "inner_vlan_id_any")
9141
9142 static int
9143 api_create_subif (vat_main_t * vam)
9144 {
9145   unformat_input_t *i = vam->input;
9146   vl_api_create_subif_t *mp;
9147   u32 sw_if_index;
9148   u8 sw_if_index_set = 0;
9149   u32 sub_id;
9150   u8 sub_id_set = 0;
9151   u32 __attribute__ ((unused)) no_tags = 0;
9152   u32 __attribute__ ((unused)) one_tag = 0;
9153   u32 __attribute__ ((unused)) two_tags = 0;
9154   u32 __attribute__ ((unused)) dot1ad = 0;
9155   u32 __attribute__ ((unused)) exact_match = 0;
9156   u32 __attribute__ ((unused)) default_sub = 0;
9157   u32 __attribute__ ((unused)) outer_vlan_id_any = 0;
9158   u32 __attribute__ ((unused)) inner_vlan_id_any = 0;
9159   u32 tmp;
9160   u16 outer_vlan_id = 0;
9161   u16 inner_vlan_id = 0;
9162   int ret;
9163
9164   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9165     {
9166       if (unformat (i, "sw_if_index %d", &sw_if_index))
9167         sw_if_index_set = 1;
9168       else
9169         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9170         sw_if_index_set = 1;
9171       else if (unformat (i, "sub_id %d", &sub_id))
9172         sub_id_set = 1;
9173       else if (unformat (i, "outer_vlan_id %d", &tmp))
9174         outer_vlan_id = tmp;
9175       else if (unformat (i, "inner_vlan_id %d", &tmp))
9176         inner_vlan_id = tmp;
9177
9178 #define _(a) else if (unformat (i, #a)) a = 1 ;
9179       foreach_create_subif_bit
9180 #undef _
9181         else
9182         {
9183           clib_warning ("parse error '%U'", format_unformat_error, i);
9184           return -99;
9185         }
9186     }
9187
9188   if (sw_if_index_set == 0)
9189     {
9190       errmsg ("missing interface name or sw_if_index");
9191       return -99;
9192     }
9193
9194   if (sub_id_set == 0)
9195     {
9196       errmsg ("missing sub_id");
9197       return -99;
9198     }
9199   M (CREATE_SUBIF, mp);
9200
9201   mp->sw_if_index = ntohl (sw_if_index);
9202   mp->sub_id = ntohl (sub_id);
9203
9204 #define _(a,b) mp->sub_if_flags |= (1 << a);
9205   foreach_create_subif_flag;
9206 #undef _
9207
9208   mp->outer_vlan_id = ntohs (outer_vlan_id);
9209   mp->inner_vlan_id = ntohs (inner_vlan_id);
9210
9211   S (mp);
9212   W (ret);
9213   return ret;
9214 }
9215
9216 static int
9217 api_ip_table_replace_begin (vat_main_t * vam)
9218 {
9219   unformat_input_t *i = vam->input;
9220   vl_api_ip_table_replace_begin_t *mp;
9221   u32 table_id = 0;
9222   u8 is_ipv6 = 0;
9223
9224   int ret;
9225   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9226     {
9227       if (unformat (i, "table %d", &table_id))
9228         ;
9229       else if (unformat (i, "ipv6"))
9230         is_ipv6 = 1;
9231       else
9232         {
9233           clib_warning ("parse error '%U'", format_unformat_error, i);
9234           return -99;
9235         }
9236     }
9237
9238   M (IP_TABLE_REPLACE_BEGIN, mp);
9239
9240   mp->table.table_id = ntohl (table_id);
9241   mp->table.is_ip6 = is_ipv6;
9242
9243   S (mp);
9244   W (ret);
9245   return ret;
9246 }
9247
9248 static int
9249 api_ip_table_flush (vat_main_t * vam)
9250 {
9251   unformat_input_t *i = vam->input;
9252   vl_api_ip_table_flush_t *mp;
9253   u32 table_id = 0;
9254   u8 is_ipv6 = 0;
9255
9256   int ret;
9257   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9258     {
9259       if (unformat (i, "table %d", &table_id))
9260         ;
9261       else if (unformat (i, "ipv6"))
9262         is_ipv6 = 1;
9263       else
9264         {
9265           clib_warning ("parse error '%U'", format_unformat_error, i);
9266           return -99;
9267         }
9268     }
9269
9270   M (IP_TABLE_FLUSH, mp);
9271
9272   mp->table.table_id = ntohl (table_id);
9273   mp->table.is_ip6 = is_ipv6;
9274
9275   S (mp);
9276   W (ret);
9277   return ret;
9278 }
9279
9280 static int
9281 api_ip_table_replace_end (vat_main_t * vam)
9282 {
9283   unformat_input_t *i = vam->input;
9284   vl_api_ip_table_replace_end_t *mp;
9285   u32 table_id = 0;
9286   u8 is_ipv6 = 0;
9287
9288   int ret;
9289   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9290     {
9291       if (unformat (i, "table %d", &table_id))
9292         ;
9293       else if (unformat (i, "ipv6"))
9294         is_ipv6 = 1;
9295       else
9296         {
9297           clib_warning ("parse error '%U'", format_unformat_error, i);
9298           return -99;
9299         }
9300     }
9301
9302   M (IP_TABLE_REPLACE_END, mp);
9303
9304   mp->table.table_id = ntohl (table_id);
9305   mp->table.is_ip6 = is_ipv6;
9306
9307   S (mp);
9308   W (ret);
9309   return ret;
9310 }
9311
9312 static int
9313 api_set_ip_flow_hash (vat_main_t * vam)
9314 {
9315   unformat_input_t *i = vam->input;
9316   vl_api_set_ip_flow_hash_t *mp;
9317   u32 vrf_id = 0;
9318   u8 is_ipv6 = 0;
9319   u8 vrf_id_set = 0;
9320   u8 src = 0;
9321   u8 dst = 0;
9322   u8 sport = 0;
9323   u8 dport = 0;
9324   u8 proto = 0;
9325   u8 reverse = 0;
9326   int ret;
9327
9328   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9329     {
9330       if (unformat (i, "vrf %d", &vrf_id))
9331         vrf_id_set = 1;
9332       else if (unformat (i, "ipv6"))
9333         is_ipv6 = 1;
9334       else if (unformat (i, "src"))
9335         src = 1;
9336       else if (unformat (i, "dst"))
9337         dst = 1;
9338       else if (unformat (i, "sport"))
9339         sport = 1;
9340       else if (unformat (i, "dport"))
9341         dport = 1;
9342       else if (unformat (i, "proto"))
9343         proto = 1;
9344       else if (unformat (i, "reverse"))
9345         reverse = 1;
9346
9347       else
9348         {
9349           clib_warning ("parse error '%U'", format_unformat_error, i);
9350           return -99;
9351         }
9352     }
9353
9354   if (vrf_id_set == 0)
9355     {
9356       errmsg ("missing vrf id");
9357       return -99;
9358     }
9359
9360   M (SET_IP_FLOW_HASH, mp);
9361   mp->src = src;
9362   mp->dst = dst;
9363   mp->sport = sport;
9364   mp->dport = dport;
9365   mp->proto = proto;
9366   mp->reverse = reverse;
9367   mp->vrf_id = ntohl (vrf_id);
9368   mp->is_ipv6 = is_ipv6;
9369
9370   S (mp);
9371   W (ret);
9372   return ret;
9373 }
9374
9375 static int
9376 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
9377 {
9378   unformat_input_t *i = vam->input;
9379   vl_api_sw_interface_ip6_enable_disable_t *mp;
9380   u32 sw_if_index;
9381   u8 sw_if_index_set = 0;
9382   u8 enable = 0;
9383   int ret;
9384
9385   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9386     {
9387       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9388         sw_if_index_set = 1;
9389       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9390         sw_if_index_set = 1;
9391       else if (unformat (i, "enable"))
9392         enable = 1;
9393       else if (unformat (i, "disable"))
9394         enable = 0;
9395       else
9396         {
9397           clib_warning ("parse error '%U'", format_unformat_error, i);
9398           return -99;
9399         }
9400     }
9401
9402   if (sw_if_index_set == 0)
9403     {
9404       errmsg ("missing interface name or sw_if_index");
9405       return -99;
9406     }
9407
9408   M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
9409
9410   mp->sw_if_index = ntohl (sw_if_index);
9411   mp->enable = enable;
9412
9413   S (mp);
9414   W (ret);
9415   return ret;
9416 }
9417
9418 static int
9419 api_ip6nd_proxy_add_del (vat_main_t * vam)
9420 {
9421   unformat_input_t *i = vam->input;
9422   vl_api_ip6nd_proxy_add_del_t *mp;
9423   u32 sw_if_index = ~0;
9424   u8 v6_address_set = 0;
9425   vl_api_ip6_address_t v6address;
9426   u8 is_del = 0;
9427   int ret;
9428
9429   /* Parse args required to build the message */
9430   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9431     {
9432       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9433         ;
9434       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9435         ;
9436       else if (unformat (i, "%U", unformat_vl_api_ip6_address, &v6address))
9437         v6_address_set = 1;
9438       if (unformat (i, "del"))
9439         is_del = 1;
9440       else
9441         {
9442           clib_warning ("parse error '%U'", format_unformat_error, i);
9443           return -99;
9444         }
9445     }
9446
9447   if (sw_if_index == ~0)
9448     {
9449       errmsg ("missing interface name or sw_if_index");
9450       return -99;
9451     }
9452   if (!v6_address_set)
9453     {
9454       errmsg ("no address set");
9455       return -99;
9456     }
9457
9458   /* Construct the API message */
9459   M (IP6ND_PROXY_ADD_DEL, mp);
9460
9461   mp->is_del = is_del;
9462   mp->sw_if_index = ntohl (sw_if_index);
9463   clib_memcpy (mp->ip, v6address, sizeof (v6address));
9464
9465   /* send it... */
9466   S (mp);
9467
9468   /* Wait for a reply, return good/bad news  */
9469   W (ret);
9470   return ret;
9471 }
9472
9473 static int
9474 api_ip6nd_proxy_dump (vat_main_t * vam)
9475 {
9476   vl_api_ip6nd_proxy_dump_t *mp;
9477   vl_api_control_ping_t *mp_ping;
9478   int ret;
9479
9480   M (IP6ND_PROXY_DUMP, mp);
9481
9482   S (mp);
9483
9484   /* Use a control ping for synchronization */
9485   MPING (CONTROL_PING, mp_ping);
9486   S (mp_ping);
9487
9488   W (ret);
9489   return ret;
9490 }
9491
9492 static void vl_api_ip6nd_proxy_details_t_handler
9493   (vl_api_ip6nd_proxy_details_t * mp)
9494 {
9495   vat_main_t *vam = &vat_main;
9496
9497   print (vam->ofp, "host %U sw_if_index %d",
9498          format_vl_api_ip6_address, mp->ip, ntohl (mp->sw_if_index));
9499 }
9500
9501 static void vl_api_ip6nd_proxy_details_t_handler_json
9502   (vl_api_ip6nd_proxy_details_t * mp)
9503 {
9504   vat_main_t *vam = &vat_main;
9505   struct in6_addr ip6;
9506   vat_json_node_t *node = NULL;
9507
9508   if (VAT_JSON_ARRAY != vam->json_tree.type)
9509     {
9510       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
9511       vat_json_init_array (&vam->json_tree);
9512     }
9513   node = vat_json_array_add (&vam->json_tree);
9514
9515   vat_json_init_object (node);
9516   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
9517
9518   clib_memcpy (&ip6, mp->ip, sizeof (ip6));
9519   vat_json_object_add_ip6 (node, "host", ip6);
9520 }
9521
9522 static int
9523 api_sw_interface_ip6nd_ra_prefix (vat_main_t * vam)
9524 {
9525   unformat_input_t *i = vam->input;
9526   vl_api_sw_interface_ip6nd_ra_prefix_t *mp;
9527   u32 sw_if_index;
9528   u8 sw_if_index_set = 0;
9529   u8 v6_address_set = 0;
9530   vl_api_prefix_t pfx;
9531   u8 use_default = 0;
9532   u8 no_advertise = 0;
9533   u8 off_link = 0;
9534   u8 no_autoconfig = 0;
9535   u8 no_onlink = 0;
9536   u8 is_no = 0;
9537   u32 val_lifetime = 0;
9538   u32 pref_lifetime = 0;
9539   int ret;
9540
9541   /* Parse args required to build the message */
9542   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9543     {
9544       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9545         sw_if_index_set = 1;
9546       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9547         sw_if_index_set = 1;
9548       else if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
9549         v6_address_set = 1;
9550       else if (unformat (i, "val_life %d", &val_lifetime))
9551         ;
9552       else if (unformat (i, "pref_life %d", &pref_lifetime))
9553         ;
9554       else if (unformat (i, "def"))
9555         use_default = 1;
9556       else if (unformat (i, "noadv"))
9557         no_advertise = 1;
9558       else if (unformat (i, "offl"))
9559         off_link = 1;
9560       else if (unformat (i, "noauto"))
9561         no_autoconfig = 1;
9562       else if (unformat (i, "nolink"))
9563         no_onlink = 1;
9564       else if (unformat (i, "isno"))
9565         is_no = 1;
9566       else
9567         {
9568           clib_warning ("parse error '%U'", format_unformat_error, i);
9569           return -99;
9570         }
9571     }
9572
9573   if (sw_if_index_set == 0)
9574     {
9575       errmsg ("missing interface name or sw_if_index");
9576       return -99;
9577     }
9578   if (!v6_address_set)
9579     {
9580       errmsg ("no address set");
9581       return -99;
9582     }
9583
9584   /* Construct the API message */
9585   M (SW_INTERFACE_IP6ND_RA_PREFIX, mp);
9586
9587   mp->sw_if_index = ntohl (sw_if_index);
9588   clib_memcpy (&mp->prefix, &pfx, sizeof (pfx));
9589   mp->use_default = use_default;
9590   mp->no_advertise = no_advertise;
9591   mp->off_link = off_link;
9592   mp->no_autoconfig = no_autoconfig;
9593   mp->no_onlink = no_onlink;
9594   mp->is_no = is_no;
9595   mp->val_lifetime = ntohl (val_lifetime);
9596   mp->pref_lifetime = ntohl (pref_lifetime);
9597
9598   /* send it... */
9599   S (mp);
9600
9601   /* Wait for a reply, return good/bad news  */
9602   W (ret);
9603   return ret;
9604 }
9605
9606 static int
9607 api_sw_interface_ip6nd_ra_config (vat_main_t * vam)
9608 {
9609   unformat_input_t *i = vam->input;
9610   vl_api_sw_interface_ip6nd_ra_config_t *mp;
9611   u32 sw_if_index;
9612   u8 sw_if_index_set = 0;
9613   u8 suppress = 0;
9614   u8 managed = 0;
9615   u8 other = 0;
9616   u8 ll_option = 0;
9617   u8 send_unicast = 0;
9618   u8 cease = 0;
9619   u8 is_no = 0;
9620   u8 default_router = 0;
9621   u32 max_interval = 0;
9622   u32 min_interval = 0;
9623   u32 lifetime = 0;
9624   u32 initial_count = 0;
9625   u32 initial_interval = 0;
9626   int ret;
9627
9628
9629   /* Parse args required to build the message */
9630   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9631     {
9632       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9633         sw_if_index_set = 1;
9634       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9635         sw_if_index_set = 1;
9636       else if (unformat (i, "maxint %d", &max_interval))
9637         ;
9638       else if (unformat (i, "minint %d", &min_interval))
9639         ;
9640       else if (unformat (i, "life %d", &lifetime))
9641         ;
9642       else if (unformat (i, "count %d", &initial_count))
9643         ;
9644       else if (unformat (i, "interval %d", &initial_interval))
9645         ;
9646       else if (unformat (i, "suppress") || unformat (i, "surpress"))
9647         suppress = 1;
9648       else if (unformat (i, "managed"))
9649         managed = 1;
9650       else if (unformat (i, "other"))
9651         other = 1;
9652       else if (unformat (i, "ll"))
9653         ll_option = 1;
9654       else if (unformat (i, "send"))
9655         send_unicast = 1;
9656       else if (unformat (i, "cease"))
9657         cease = 1;
9658       else if (unformat (i, "isno"))
9659         is_no = 1;
9660       else if (unformat (i, "def"))
9661         default_router = 1;
9662       else
9663         {
9664           clib_warning ("parse error '%U'", format_unformat_error, i);
9665           return -99;
9666         }
9667     }
9668
9669   if (sw_if_index_set == 0)
9670     {
9671       errmsg ("missing interface name or sw_if_index");
9672       return -99;
9673     }
9674
9675   /* Construct the API message */
9676   M (SW_INTERFACE_IP6ND_RA_CONFIG, mp);
9677
9678   mp->sw_if_index = ntohl (sw_if_index);
9679   mp->max_interval = ntohl (max_interval);
9680   mp->min_interval = ntohl (min_interval);
9681   mp->lifetime = ntohl (lifetime);
9682   mp->initial_count = ntohl (initial_count);
9683   mp->initial_interval = ntohl (initial_interval);
9684   mp->suppress = suppress;
9685   mp->managed = managed;
9686   mp->other = other;
9687   mp->ll_option = ll_option;
9688   mp->send_unicast = send_unicast;
9689   mp->cease = cease;
9690   mp->is_no = is_no;
9691   mp->default_router = default_router;
9692
9693   /* send it... */
9694   S (mp);
9695
9696   /* Wait for a reply, return good/bad news  */
9697   W (ret);
9698   return ret;
9699 }
9700
9701 static int
9702 api_set_arp_neighbor_limit (vat_main_t * vam)
9703 {
9704   unformat_input_t *i = vam->input;
9705   vl_api_set_arp_neighbor_limit_t *mp;
9706   u32 arp_nbr_limit;
9707   u8 limit_set = 0;
9708   u8 is_ipv6 = 0;
9709   int ret;
9710
9711   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9712     {
9713       if (unformat (i, "arp_nbr_limit %d", &arp_nbr_limit))
9714         limit_set = 1;
9715       else if (unformat (i, "ipv6"))
9716         is_ipv6 = 1;
9717       else
9718         {
9719           clib_warning ("parse error '%U'", format_unformat_error, i);
9720           return -99;
9721         }
9722     }
9723
9724   if (limit_set == 0)
9725     {
9726       errmsg ("missing limit value");
9727       return -99;
9728     }
9729
9730   M (SET_ARP_NEIGHBOR_LIMIT, mp);
9731
9732   mp->arp_neighbor_limit = ntohl (arp_nbr_limit);
9733   mp->is_ipv6 = is_ipv6;
9734
9735   S (mp);
9736   W (ret);
9737   return ret;
9738 }
9739
9740 static int
9741 api_l2_patch_add_del (vat_main_t * vam)
9742 {
9743   unformat_input_t *i = vam->input;
9744   vl_api_l2_patch_add_del_t *mp;
9745   u32 rx_sw_if_index;
9746   u8 rx_sw_if_index_set = 0;
9747   u32 tx_sw_if_index;
9748   u8 tx_sw_if_index_set = 0;
9749   u8 is_add = 1;
9750   int ret;
9751
9752   /* Parse args required to build the message */
9753   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9754     {
9755       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
9756         rx_sw_if_index_set = 1;
9757       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
9758         tx_sw_if_index_set = 1;
9759       else if (unformat (i, "rx"))
9760         {
9761           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9762             {
9763               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
9764                             &rx_sw_if_index))
9765                 rx_sw_if_index_set = 1;
9766             }
9767           else
9768             break;
9769         }
9770       else if (unformat (i, "tx"))
9771         {
9772           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9773             {
9774               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
9775                             &tx_sw_if_index))
9776                 tx_sw_if_index_set = 1;
9777             }
9778           else
9779             break;
9780         }
9781       else if (unformat (i, "del"))
9782         is_add = 0;
9783       else
9784         break;
9785     }
9786
9787   if (rx_sw_if_index_set == 0)
9788     {
9789       errmsg ("missing rx interface name or rx_sw_if_index");
9790       return -99;
9791     }
9792
9793   if (tx_sw_if_index_set == 0)
9794     {
9795       errmsg ("missing tx interface name or tx_sw_if_index");
9796       return -99;
9797     }
9798
9799   M (L2_PATCH_ADD_DEL, mp);
9800
9801   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
9802   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
9803   mp->is_add = is_add;
9804
9805   S (mp);
9806   W (ret);
9807   return ret;
9808 }
9809
9810 u8 is_del;
9811 u8 localsid_addr[16];
9812 u8 end_psp;
9813 u8 behavior;
9814 u32 sw_if_index;
9815 u32 vlan_index;
9816 u32 fib_table;
9817 u8 nh_addr[16];
9818
9819 static int
9820 api_sr_localsid_add_del (vat_main_t * vam)
9821 {
9822   unformat_input_t *i = vam->input;
9823   vl_api_sr_localsid_add_del_t *mp;
9824
9825   u8 is_del;
9826   ip6_address_t localsid;
9827   u8 end_psp = 0;
9828   u8 behavior = ~0;
9829   u32 sw_if_index;
9830   u32 fib_table = ~(u32) 0;
9831   ip6_address_t nh_addr6;
9832   ip4_address_t nh_addr4;
9833   clib_memset (&nh_addr6, 0, sizeof (ip6_address_t));
9834   clib_memset (&nh_addr4, 0, sizeof (ip4_address_t));
9835
9836   bool nexthop_set = 0;
9837
9838   int ret;
9839
9840   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9841     {
9842       if (unformat (i, "del"))
9843         is_del = 1;
9844       else if (unformat (i, "address %U", unformat_ip6_address, &localsid));
9845       else if (unformat (i, "next-hop %U", unformat_ip4_address, &nh_addr4))
9846         nexthop_set = 1;
9847       else if (unformat (i, "next-hop %U", unformat_ip6_address, &nh_addr6))
9848         nexthop_set = 1;
9849       else if (unformat (i, "behavior %u", &behavior));
9850       else if (unformat (i, "sw_if_index %u", &sw_if_index));
9851       else if (unformat (i, "fib-table %u", &fib_table));
9852       else if (unformat (i, "end.psp %u", &behavior));
9853       else
9854         break;
9855     }
9856
9857   M (SR_LOCALSID_ADD_DEL, mp);
9858
9859   clib_memcpy (mp->localsid.addr, &localsid, sizeof (mp->localsid));
9860
9861   if (nexthop_set)
9862     {
9863       clib_memcpy (mp->nh_addr6, &nh_addr6, sizeof (mp->nh_addr6));
9864       clib_memcpy (mp->nh_addr4, &nh_addr4, sizeof (mp->nh_addr4));
9865     }
9866   mp->behavior = behavior;
9867   mp->sw_if_index = ntohl (sw_if_index);
9868   mp->fib_table = ntohl (fib_table);
9869   mp->end_psp = end_psp;
9870   mp->is_del = is_del;
9871
9872   S (mp);
9873   W (ret);
9874   return ret;
9875 }
9876
9877 static int
9878 api_ioam_enable (vat_main_t * vam)
9879 {
9880   unformat_input_t *input = vam->input;
9881   vl_api_ioam_enable_t *mp;
9882   u32 id = 0;
9883   int has_trace_option = 0;
9884   int has_pot_option = 0;
9885   int has_seqno_option = 0;
9886   int has_analyse_option = 0;
9887   int ret;
9888
9889   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9890     {
9891       if (unformat (input, "trace"))
9892         has_trace_option = 1;
9893       else if (unformat (input, "pot"))
9894         has_pot_option = 1;
9895       else if (unformat (input, "seqno"))
9896         has_seqno_option = 1;
9897       else if (unformat (input, "analyse"))
9898         has_analyse_option = 1;
9899       else
9900         break;
9901     }
9902   M (IOAM_ENABLE, mp);
9903   mp->id = htons (id);
9904   mp->seqno = has_seqno_option;
9905   mp->analyse = has_analyse_option;
9906   mp->pot_enable = has_pot_option;
9907   mp->trace_enable = has_trace_option;
9908
9909   S (mp);
9910   W (ret);
9911   return ret;
9912 }
9913
9914
9915 static int
9916 api_ioam_disable (vat_main_t * vam)
9917 {
9918   vl_api_ioam_disable_t *mp;
9919   int ret;
9920
9921   M (IOAM_DISABLE, mp);
9922   S (mp);
9923   W (ret);
9924   return ret;
9925 }
9926
9927 #define foreach_tcp_proto_field                 \
9928 _(src_port)                                     \
9929 _(dst_port)
9930
9931 #define foreach_udp_proto_field                 \
9932 _(src_port)                                     \
9933 _(dst_port)
9934
9935 #define foreach_ip4_proto_field                 \
9936 _(src_address)                                  \
9937 _(dst_address)                                  \
9938 _(tos)                                          \
9939 _(length)                                       \
9940 _(fragment_id)                                  \
9941 _(ttl)                                          \
9942 _(protocol)                                     \
9943 _(checksum)
9944
9945 typedef struct
9946 {
9947   u16 src_port, dst_port;
9948 } tcpudp_header_t;
9949
9950 #if VPP_API_TEST_BUILTIN == 0
9951 uword
9952 unformat_tcp_mask (unformat_input_t * input, va_list * args)
9953 {
9954   u8 **maskp = va_arg (*args, u8 **);
9955   u8 *mask = 0;
9956   u8 found_something = 0;
9957   tcp_header_t *tcp;
9958
9959 #define _(a) u8 a=0;
9960   foreach_tcp_proto_field;
9961 #undef _
9962
9963   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9964     {
9965       if (0);
9966 #define _(a) else if (unformat (input, #a)) a=1;
9967       foreach_tcp_proto_field
9968 #undef _
9969         else
9970         break;
9971     }
9972
9973 #define _(a) found_something += a;
9974   foreach_tcp_proto_field;
9975 #undef _
9976
9977   if (found_something == 0)
9978     return 0;
9979
9980   vec_validate (mask, sizeof (*tcp) - 1);
9981
9982   tcp = (tcp_header_t *) mask;
9983
9984 #define _(a) if (a) clib_memset (&tcp->a, 0xff, sizeof (tcp->a));
9985   foreach_tcp_proto_field;
9986 #undef _
9987
9988   *maskp = mask;
9989   return 1;
9990 }
9991
9992 uword
9993 unformat_udp_mask (unformat_input_t * input, va_list * args)
9994 {
9995   u8 **maskp = va_arg (*args, u8 **);
9996   u8 *mask = 0;
9997   u8 found_something = 0;
9998   udp_header_t *udp;
9999
10000 #define _(a) u8 a=0;
10001   foreach_udp_proto_field;
10002 #undef _
10003
10004   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10005     {
10006       if (0);
10007 #define _(a) else if (unformat (input, #a)) a=1;
10008       foreach_udp_proto_field
10009 #undef _
10010         else
10011         break;
10012     }
10013
10014 #define _(a) found_something += a;
10015   foreach_udp_proto_field;
10016 #undef _
10017
10018   if (found_something == 0)
10019     return 0;
10020
10021   vec_validate (mask, sizeof (*udp) - 1);
10022
10023   udp = (udp_header_t *) mask;
10024
10025 #define _(a) if (a) clib_memset (&udp->a, 0xff, sizeof (udp->a));
10026   foreach_udp_proto_field;
10027 #undef _
10028
10029   *maskp = mask;
10030   return 1;
10031 }
10032
10033 uword
10034 unformat_l4_mask (unformat_input_t * input, va_list * args)
10035 {
10036   u8 **maskp = va_arg (*args, u8 **);
10037   u16 src_port = 0, dst_port = 0;
10038   tcpudp_header_t *tcpudp;
10039
10040   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10041     {
10042       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
10043         return 1;
10044       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
10045         return 1;
10046       else if (unformat (input, "src_port"))
10047         src_port = 0xFFFF;
10048       else if (unformat (input, "dst_port"))
10049         dst_port = 0xFFFF;
10050       else
10051         return 0;
10052     }
10053
10054   if (!src_port && !dst_port)
10055     return 0;
10056
10057   u8 *mask = 0;
10058   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
10059
10060   tcpudp = (tcpudp_header_t *) mask;
10061   tcpudp->src_port = src_port;
10062   tcpudp->dst_port = dst_port;
10063
10064   *maskp = mask;
10065
10066   return 1;
10067 }
10068
10069 uword
10070 unformat_ip4_mask (unformat_input_t * input, va_list * args)
10071 {
10072   u8 **maskp = va_arg (*args, u8 **);
10073   u8 *mask = 0;
10074   u8 found_something = 0;
10075   ip4_header_t *ip;
10076
10077 #define _(a) u8 a=0;
10078   foreach_ip4_proto_field;
10079 #undef _
10080   u8 version = 0;
10081   u8 hdr_length = 0;
10082
10083
10084   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10085     {
10086       if (unformat (input, "version"))
10087         version = 1;
10088       else if (unformat (input, "hdr_length"))
10089         hdr_length = 1;
10090       else if (unformat (input, "src"))
10091         src_address = 1;
10092       else if (unformat (input, "dst"))
10093         dst_address = 1;
10094       else if (unformat (input, "proto"))
10095         protocol = 1;
10096
10097 #define _(a) else if (unformat (input, #a)) a=1;
10098       foreach_ip4_proto_field
10099 #undef _
10100         else
10101         break;
10102     }
10103
10104 #define _(a) found_something += a;
10105   foreach_ip4_proto_field;
10106 #undef _
10107
10108   if (found_something == 0)
10109     return 0;
10110
10111   vec_validate (mask, sizeof (*ip) - 1);
10112
10113   ip = (ip4_header_t *) mask;
10114
10115 #define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
10116   foreach_ip4_proto_field;
10117 #undef _
10118
10119   ip->ip_version_and_header_length = 0;
10120
10121   if (version)
10122     ip->ip_version_and_header_length |= 0xF0;
10123
10124   if (hdr_length)
10125     ip->ip_version_and_header_length |= 0x0F;
10126
10127   *maskp = mask;
10128   return 1;
10129 }
10130
10131 #define foreach_ip6_proto_field                 \
10132 _(src_address)                                  \
10133 _(dst_address)                                  \
10134 _(payload_length)                               \
10135 _(hop_limit)                                    \
10136 _(protocol)
10137
10138 uword
10139 unformat_ip6_mask (unformat_input_t * input, va_list * args)
10140 {
10141   u8 **maskp = va_arg (*args, u8 **);
10142   u8 *mask = 0;
10143   u8 found_something = 0;
10144   ip6_header_t *ip;
10145   u32 ip_version_traffic_class_and_flow_label;
10146
10147 #define _(a) u8 a=0;
10148   foreach_ip6_proto_field;
10149 #undef _
10150   u8 version = 0;
10151   u8 traffic_class = 0;
10152   u8 flow_label = 0;
10153
10154   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10155     {
10156       if (unformat (input, "version"))
10157         version = 1;
10158       else if (unformat (input, "traffic-class"))
10159         traffic_class = 1;
10160       else if (unformat (input, "flow-label"))
10161         flow_label = 1;
10162       else if (unformat (input, "src"))
10163         src_address = 1;
10164       else if (unformat (input, "dst"))
10165         dst_address = 1;
10166       else if (unformat (input, "proto"))
10167         protocol = 1;
10168
10169 #define _(a) else if (unformat (input, #a)) a=1;
10170       foreach_ip6_proto_field
10171 #undef _
10172         else
10173         break;
10174     }
10175
10176 #define _(a) found_something += a;
10177   foreach_ip6_proto_field;
10178 #undef _
10179
10180   if (found_something == 0)
10181     return 0;
10182
10183   vec_validate (mask, sizeof (*ip) - 1);
10184
10185   ip = (ip6_header_t *) mask;
10186
10187 #define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
10188   foreach_ip6_proto_field;
10189 #undef _
10190
10191   ip_version_traffic_class_and_flow_label = 0;
10192
10193   if (version)
10194     ip_version_traffic_class_and_flow_label |= 0xF0000000;
10195
10196   if (traffic_class)
10197     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
10198
10199   if (flow_label)
10200     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
10201
10202   ip->ip_version_traffic_class_and_flow_label =
10203     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
10204
10205   *maskp = mask;
10206   return 1;
10207 }
10208
10209 uword
10210 unformat_l3_mask (unformat_input_t * input, va_list * args)
10211 {
10212   u8 **maskp = va_arg (*args, u8 **);
10213
10214   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10215     {
10216       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
10217         return 1;
10218       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
10219         return 1;
10220       else
10221         break;
10222     }
10223   return 0;
10224 }
10225
10226 uword
10227 unformat_l2_mask (unformat_input_t * input, va_list * args)
10228 {
10229   u8 **maskp = va_arg (*args, u8 **);
10230   u8 *mask = 0;
10231   u8 src = 0;
10232   u8 dst = 0;
10233   u8 proto = 0;
10234   u8 tag1 = 0;
10235   u8 tag2 = 0;
10236   u8 ignore_tag1 = 0;
10237   u8 ignore_tag2 = 0;
10238   u8 cos1 = 0;
10239   u8 cos2 = 0;
10240   u8 dot1q = 0;
10241   u8 dot1ad = 0;
10242   int len = 14;
10243
10244   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10245     {
10246       if (unformat (input, "src"))
10247         src = 1;
10248       else if (unformat (input, "dst"))
10249         dst = 1;
10250       else if (unformat (input, "proto"))
10251         proto = 1;
10252       else if (unformat (input, "tag1"))
10253         tag1 = 1;
10254       else if (unformat (input, "tag2"))
10255         tag2 = 1;
10256       else if (unformat (input, "ignore-tag1"))
10257         ignore_tag1 = 1;
10258       else if (unformat (input, "ignore-tag2"))
10259         ignore_tag2 = 1;
10260       else if (unformat (input, "cos1"))
10261         cos1 = 1;
10262       else if (unformat (input, "cos2"))
10263         cos2 = 1;
10264       else if (unformat (input, "dot1q"))
10265         dot1q = 1;
10266       else if (unformat (input, "dot1ad"))
10267         dot1ad = 1;
10268       else
10269         break;
10270     }
10271   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
10272        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
10273     return 0;
10274
10275   if (tag1 || ignore_tag1 || cos1 || dot1q)
10276     len = 18;
10277   if (tag2 || ignore_tag2 || cos2 || dot1ad)
10278     len = 22;
10279
10280   vec_validate (mask, len - 1);
10281
10282   if (dst)
10283     clib_memset (mask, 0xff, 6);
10284
10285   if (src)
10286     clib_memset (mask + 6, 0xff, 6);
10287
10288   if (tag2 || dot1ad)
10289     {
10290       /* inner vlan tag */
10291       if (tag2)
10292         {
10293           mask[19] = 0xff;
10294           mask[18] = 0x0f;
10295         }
10296       if (cos2)
10297         mask[18] |= 0xe0;
10298       if (proto)
10299         mask[21] = mask[20] = 0xff;
10300       if (tag1)
10301         {
10302           mask[15] = 0xff;
10303           mask[14] = 0x0f;
10304         }
10305       if (cos1)
10306         mask[14] |= 0xe0;
10307       *maskp = mask;
10308       return 1;
10309     }
10310   if (tag1 | dot1q)
10311     {
10312       if (tag1)
10313         {
10314           mask[15] = 0xff;
10315           mask[14] = 0x0f;
10316         }
10317       if (cos1)
10318         mask[14] |= 0xe0;
10319       if (proto)
10320         mask[16] = mask[17] = 0xff;
10321
10322       *maskp = mask;
10323       return 1;
10324     }
10325   if (cos2)
10326     mask[18] |= 0xe0;
10327   if (cos1)
10328     mask[14] |= 0xe0;
10329   if (proto)
10330     mask[12] = mask[13] = 0xff;
10331
10332   *maskp = mask;
10333   return 1;
10334 }
10335
10336 uword
10337 unformat_classify_mask (unformat_input_t * input, va_list * args)
10338 {
10339   u8 **maskp = va_arg (*args, u8 **);
10340   u32 *skipp = va_arg (*args, u32 *);
10341   u32 *matchp = va_arg (*args, u32 *);
10342   u32 match;
10343   u8 *mask = 0;
10344   u8 *l2 = 0;
10345   u8 *l3 = 0;
10346   u8 *l4 = 0;
10347   int i;
10348
10349   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10350     {
10351       if (unformat (input, "hex %U", unformat_hex_string, &mask))
10352         ;
10353       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
10354         ;
10355       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
10356         ;
10357       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
10358         ;
10359       else
10360         break;
10361     }
10362
10363   if (l4 && !l3)
10364     {
10365       vec_free (mask);
10366       vec_free (l2);
10367       vec_free (l4);
10368       return 0;
10369     }
10370
10371   if (mask || l2 || l3 || l4)
10372     {
10373       if (l2 || l3 || l4)
10374         {
10375           /* "With a free Ethernet header in every package" */
10376           if (l2 == 0)
10377             vec_validate (l2, 13);
10378           mask = l2;
10379           if (vec_len (l3))
10380             {
10381               vec_append (mask, l3);
10382               vec_free (l3);
10383             }
10384           if (vec_len (l4))
10385             {
10386               vec_append (mask, l4);
10387               vec_free (l4);
10388             }
10389         }
10390
10391       /* Scan forward looking for the first significant mask octet */
10392       for (i = 0; i < vec_len (mask); i++)
10393         if (mask[i])
10394           break;
10395
10396       /* compute (skip, match) params */
10397       *skipp = i / sizeof (u32x4);
10398       vec_delete (mask, *skipp * sizeof (u32x4), 0);
10399
10400       /* Pad mask to an even multiple of the vector size */
10401       while (vec_len (mask) % sizeof (u32x4))
10402         vec_add1 (mask, 0);
10403
10404       match = vec_len (mask) / sizeof (u32x4);
10405
10406       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
10407         {
10408           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
10409           if (*tmp || *(tmp + 1))
10410             break;
10411           match--;
10412         }
10413       if (match == 0)
10414         clib_warning ("BUG: match 0");
10415
10416       _vec_len (mask) = match * sizeof (u32x4);
10417
10418       *matchp = match;
10419       *maskp = mask;
10420
10421       return 1;
10422     }
10423
10424   return 0;
10425 }
10426 #endif /* VPP_API_TEST_BUILTIN */
10427
10428 #define foreach_l2_next                         \
10429 _(drop, DROP)                                   \
10430 _(ethernet, ETHERNET_INPUT)                     \
10431 _(ip4, IP4_INPUT)                               \
10432 _(ip6, IP6_INPUT)
10433
10434 uword
10435 unformat_l2_next_index (unformat_input_t * input, va_list * args)
10436 {
10437   u32 *miss_next_indexp = va_arg (*args, u32 *);
10438   u32 next_index = 0;
10439   u32 tmp;
10440
10441 #define _(n,N) \
10442   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
10443   foreach_l2_next;
10444 #undef _
10445
10446   if (unformat (input, "%d", &tmp))
10447     {
10448       next_index = tmp;
10449       goto out;
10450     }
10451
10452   return 0;
10453
10454 out:
10455   *miss_next_indexp = next_index;
10456   return 1;
10457 }
10458
10459 #define foreach_ip_next                         \
10460 _(drop, DROP)                                   \
10461 _(local, LOCAL)                                 \
10462 _(rewrite, REWRITE)
10463
10464 uword
10465 api_unformat_ip_next_index (unformat_input_t * input, va_list * args)
10466 {
10467   u32 *miss_next_indexp = va_arg (*args, u32 *);
10468   u32 next_index = 0;
10469   u32 tmp;
10470
10471 #define _(n,N) \
10472   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
10473   foreach_ip_next;
10474 #undef _
10475
10476   if (unformat (input, "%d", &tmp))
10477     {
10478       next_index = tmp;
10479       goto out;
10480     }
10481
10482   return 0;
10483
10484 out:
10485   *miss_next_indexp = next_index;
10486   return 1;
10487 }
10488
10489 #define foreach_acl_next                        \
10490 _(deny, DENY)
10491
10492 uword
10493 api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
10494 {
10495   u32 *miss_next_indexp = va_arg (*args, u32 *);
10496   u32 next_index = 0;
10497   u32 tmp;
10498
10499 #define _(n,N) \
10500   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
10501   foreach_acl_next;
10502 #undef _
10503
10504   if (unformat (input, "permit"))
10505     {
10506       next_index = ~0;
10507       goto out;
10508     }
10509   else if (unformat (input, "%d", &tmp))
10510     {
10511       next_index = tmp;
10512       goto out;
10513     }
10514
10515   return 0;
10516
10517 out:
10518   *miss_next_indexp = next_index;
10519   return 1;
10520 }
10521
10522 uword
10523 unformat_policer_precolor (unformat_input_t * input, va_list * args)
10524 {
10525   u32 *r = va_arg (*args, u32 *);
10526
10527   if (unformat (input, "conform-color"))
10528     *r = POLICE_CONFORM;
10529   else if (unformat (input, "exceed-color"))
10530     *r = POLICE_EXCEED;
10531   else
10532     return 0;
10533
10534   return 1;
10535 }
10536
10537 static int
10538 api_classify_add_del_table (vat_main_t * vam)
10539 {
10540   unformat_input_t *i = vam->input;
10541   vl_api_classify_add_del_table_t *mp;
10542
10543   u32 nbuckets = 2;
10544   u32 skip = ~0;
10545   u32 match = ~0;
10546   int is_add = 1;
10547   int del_chain = 0;
10548   u32 table_index = ~0;
10549   u32 next_table_index = ~0;
10550   u32 miss_next_index = ~0;
10551   u32 memory_size = 32 << 20;
10552   u8 *mask = 0;
10553   u32 current_data_flag = 0;
10554   int current_data_offset = 0;
10555   int ret;
10556
10557   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10558     {
10559       if (unformat (i, "del"))
10560         is_add = 0;
10561       else if (unformat (i, "del-chain"))
10562         {
10563           is_add = 0;
10564           del_chain = 1;
10565         }
10566       else if (unformat (i, "buckets %d", &nbuckets))
10567         ;
10568       else if (unformat (i, "memory_size %d", &memory_size))
10569         ;
10570       else if (unformat (i, "skip %d", &skip))
10571         ;
10572       else if (unformat (i, "match %d", &match))
10573         ;
10574       else if (unformat (i, "table %d", &table_index))
10575         ;
10576       else if (unformat (i, "mask %U", unformat_classify_mask,
10577                          &mask, &skip, &match))
10578         ;
10579       else if (unformat (i, "next-table %d", &next_table_index))
10580         ;
10581       else if (unformat (i, "miss-next %U", api_unformat_ip_next_index,
10582                          &miss_next_index))
10583         ;
10584       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
10585                          &miss_next_index))
10586         ;
10587       else if (unformat (i, "acl-miss-next %U", api_unformat_acl_next_index,
10588                          &miss_next_index))
10589         ;
10590       else if (unformat (i, "current-data-flag %d", &current_data_flag))
10591         ;
10592       else if (unformat (i, "current-data-offset %d", &current_data_offset))
10593         ;
10594       else
10595         break;
10596     }
10597
10598   if (is_add && mask == 0)
10599     {
10600       errmsg ("Mask required");
10601       return -99;
10602     }
10603
10604   if (is_add && skip == ~0)
10605     {
10606       errmsg ("skip count required");
10607       return -99;
10608     }
10609
10610   if (is_add && match == ~0)
10611     {
10612       errmsg ("match count required");
10613       return -99;
10614     }
10615
10616   if (!is_add && table_index == ~0)
10617     {
10618       errmsg ("table index required for delete");
10619       return -99;
10620     }
10621
10622   M2 (CLASSIFY_ADD_DEL_TABLE, mp, vec_len (mask));
10623
10624   mp->is_add = is_add;
10625   mp->del_chain = del_chain;
10626   mp->table_index = ntohl (table_index);
10627   mp->nbuckets = ntohl (nbuckets);
10628   mp->memory_size = ntohl (memory_size);
10629   mp->skip_n_vectors = ntohl (skip);
10630   mp->match_n_vectors = ntohl (match);
10631   mp->next_table_index = ntohl (next_table_index);
10632   mp->miss_next_index = ntohl (miss_next_index);
10633   mp->current_data_flag = ntohl (current_data_flag);
10634   mp->current_data_offset = ntohl (current_data_offset);
10635   mp->mask_len = ntohl (vec_len (mask));
10636   clib_memcpy (mp->mask, mask, vec_len (mask));
10637
10638   vec_free (mask);
10639
10640   S (mp);
10641   W (ret);
10642   return ret;
10643 }
10644
10645 #if VPP_API_TEST_BUILTIN == 0
10646 uword
10647 unformat_l4_match (unformat_input_t * input, va_list * args)
10648 {
10649   u8 **matchp = va_arg (*args, u8 **);
10650
10651   u8 *proto_header = 0;
10652   int src_port = 0;
10653   int dst_port = 0;
10654
10655   tcpudp_header_t h;
10656
10657   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10658     {
10659       if (unformat (input, "src_port %d", &src_port))
10660         ;
10661       else if (unformat (input, "dst_port %d", &dst_port))
10662         ;
10663       else
10664         return 0;
10665     }
10666
10667   h.src_port = clib_host_to_net_u16 (src_port);
10668   h.dst_port = clib_host_to_net_u16 (dst_port);
10669   vec_validate (proto_header, sizeof (h) - 1);
10670   memcpy (proto_header, &h, sizeof (h));
10671
10672   *matchp = proto_header;
10673
10674   return 1;
10675 }
10676
10677 uword
10678 unformat_ip4_match (unformat_input_t * input, va_list * args)
10679 {
10680   u8 **matchp = va_arg (*args, u8 **);
10681   u8 *match = 0;
10682   ip4_header_t *ip;
10683   int version = 0;
10684   u32 version_val;
10685   int hdr_length = 0;
10686   u32 hdr_length_val;
10687   int src = 0, dst = 0;
10688   ip4_address_t src_val, dst_val;
10689   int proto = 0;
10690   u32 proto_val;
10691   int tos = 0;
10692   u32 tos_val;
10693   int length = 0;
10694   u32 length_val;
10695   int fragment_id = 0;
10696   u32 fragment_id_val;
10697   int ttl = 0;
10698   int ttl_val;
10699   int checksum = 0;
10700   u32 checksum_val;
10701
10702   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10703     {
10704       if (unformat (input, "version %d", &version_val))
10705         version = 1;
10706       else if (unformat (input, "hdr_length %d", &hdr_length_val))
10707         hdr_length = 1;
10708       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
10709         src = 1;
10710       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
10711         dst = 1;
10712       else if (unformat (input, "proto %d", &proto_val))
10713         proto = 1;
10714       else if (unformat (input, "tos %d", &tos_val))
10715         tos = 1;
10716       else if (unformat (input, "length %d", &length_val))
10717         length = 1;
10718       else if (unformat (input, "fragment_id %d", &fragment_id_val))
10719         fragment_id = 1;
10720       else if (unformat (input, "ttl %d", &ttl_val))
10721         ttl = 1;
10722       else if (unformat (input, "checksum %d", &checksum_val))
10723         checksum = 1;
10724       else
10725         break;
10726     }
10727
10728   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
10729       + ttl + checksum == 0)
10730     return 0;
10731
10732   /*
10733    * Aligned because we use the real comparison functions
10734    */
10735   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
10736
10737   ip = (ip4_header_t *) match;
10738
10739   /* These are realistically matched in practice */
10740   if (src)
10741     ip->src_address.as_u32 = src_val.as_u32;
10742
10743   if (dst)
10744     ip->dst_address.as_u32 = dst_val.as_u32;
10745
10746   if (proto)
10747     ip->protocol = proto_val;
10748
10749
10750   /* These are not, but they're included for completeness */
10751   if (version)
10752     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
10753
10754   if (hdr_length)
10755     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
10756
10757   if (tos)
10758     ip->tos = tos_val;
10759
10760   if (length)
10761     ip->length = clib_host_to_net_u16 (length_val);
10762
10763   if (ttl)
10764     ip->ttl = ttl_val;
10765
10766   if (checksum)
10767     ip->checksum = clib_host_to_net_u16 (checksum_val);
10768
10769   *matchp = match;
10770   return 1;
10771 }
10772
10773 uword
10774 unformat_ip6_match (unformat_input_t * input, va_list * args)
10775 {
10776   u8 **matchp = va_arg (*args, u8 **);
10777   u8 *match = 0;
10778   ip6_header_t *ip;
10779   int version = 0;
10780   u32 version_val;
10781   u8 traffic_class = 0;
10782   u32 traffic_class_val = 0;
10783   u8 flow_label = 0;
10784   u8 flow_label_val;
10785   int src = 0, dst = 0;
10786   ip6_address_t src_val, dst_val;
10787   int proto = 0;
10788   u32 proto_val;
10789   int payload_length = 0;
10790   u32 payload_length_val;
10791   int hop_limit = 0;
10792   int hop_limit_val;
10793   u32 ip_version_traffic_class_and_flow_label;
10794
10795   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10796     {
10797       if (unformat (input, "version %d", &version_val))
10798         version = 1;
10799       else if (unformat (input, "traffic_class %d", &traffic_class_val))
10800         traffic_class = 1;
10801       else if (unformat (input, "flow_label %d", &flow_label_val))
10802         flow_label = 1;
10803       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
10804         src = 1;
10805       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
10806         dst = 1;
10807       else if (unformat (input, "proto %d", &proto_val))
10808         proto = 1;
10809       else if (unformat (input, "payload_length %d", &payload_length_val))
10810         payload_length = 1;
10811       else if (unformat (input, "hop_limit %d", &hop_limit_val))
10812         hop_limit = 1;
10813       else
10814         break;
10815     }
10816
10817   if (version + traffic_class + flow_label + src + dst + proto +
10818       payload_length + hop_limit == 0)
10819     return 0;
10820
10821   /*
10822    * Aligned because we use the real comparison functions
10823    */
10824   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
10825
10826   ip = (ip6_header_t *) match;
10827
10828   if (src)
10829     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
10830
10831   if (dst)
10832     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
10833
10834   if (proto)
10835     ip->protocol = proto_val;
10836
10837   ip_version_traffic_class_and_flow_label = 0;
10838
10839   if (version)
10840     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
10841
10842   if (traffic_class)
10843     ip_version_traffic_class_and_flow_label |=
10844       (traffic_class_val & 0xFF) << 20;
10845
10846   if (flow_label)
10847     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
10848
10849   ip->ip_version_traffic_class_and_flow_label =
10850     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
10851
10852   if (payload_length)
10853     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
10854
10855   if (hop_limit)
10856     ip->hop_limit = hop_limit_val;
10857
10858   *matchp = match;
10859   return 1;
10860 }
10861
10862 uword
10863 unformat_l3_match (unformat_input_t * input, va_list * args)
10864 {
10865   u8 **matchp = va_arg (*args, u8 **);
10866
10867   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10868     {
10869       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
10870         return 1;
10871       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
10872         return 1;
10873       else
10874         break;
10875     }
10876   return 0;
10877 }
10878
10879 uword
10880 unformat_vlan_tag (unformat_input_t * input, va_list * args)
10881 {
10882   u8 *tagp = va_arg (*args, u8 *);
10883   u32 tag;
10884
10885   if (unformat (input, "%d", &tag))
10886     {
10887       tagp[0] = (tag >> 8) & 0x0F;
10888       tagp[1] = tag & 0xFF;
10889       return 1;
10890     }
10891
10892   return 0;
10893 }
10894
10895 uword
10896 unformat_l2_match (unformat_input_t * input, va_list * args)
10897 {
10898   u8 **matchp = va_arg (*args, u8 **);
10899   u8 *match = 0;
10900   u8 src = 0;
10901   u8 src_val[6];
10902   u8 dst = 0;
10903   u8 dst_val[6];
10904   u8 proto = 0;
10905   u16 proto_val;
10906   u8 tag1 = 0;
10907   u8 tag1_val[2];
10908   u8 tag2 = 0;
10909   u8 tag2_val[2];
10910   int len = 14;
10911   u8 ignore_tag1 = 0;
10912   u8 ignore_tag2 = 0;
10913   u8 cos1 = 0;
10914   u8 cos2 = 0;
10915   u32 cos1_val = 0;
10916   u32 cos2_val = 0;
10917
10918   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10919     {
10920       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
10921         src = 1;
10922       else
10923         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
10924         dst = 1;
10925       else if (unformat (input, "proto %U",
10926                          unformat_ethernet_type_host_byte_order, &proto_val))
10927         proto = 1;
10928       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
10929         tag1 = 1;
10930       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
10931         tag2 = 1;
10932       else if (unformat (input, "ignore-tag1"))
10933         ignore_tag1 = 1;
10934       else if (unformat (input, "ignore-tag2"))
10935         ignore_tag2 = 1;
10936       else if (unformat (input, "cos1 %d", &cos1_val))
10937         cos1 = 1;
10938       else if (unformat (input, "cos2 %d", &cos2_val))
10939         cos2 = 1;
10940       else
10941         break;
10942     }
10943   if ((src + dst + proto + tag1 + tag2 +
10944        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
10945     return 0;
10946
10947   if (tag1 || ignore_tag1 || cos1)
10948     len = 18;
10949   if (tag2 || ignore_tag2 || cos2)
10950     len = 22;
10951
10952   vec_validate_aligned (match, len - 1, sizeof (u32x4));
10953
10954   if (dst)
10955     clib_memcpy (match, dst_val, 6);
10956
10957   if (src)
10958     clib_memcpy (match + 6, src_val, 6);
10959
10960   if (tag2)
10961     {
10962       /* inner vlan tag */
10963       match[19] = tag2_val[1];
10964       match[18] = tag2_val[0];
10965       if (cos2)
10966         match[18] |= (cos2_val & 0x7) << 5;
10967       if (proto)
10968         {
10969           match[21] = proto_val & 0xff;
10970           match[20] = proto_val >> 8;
10971         }
10972       if (tag1)
10973         {
10974           match[15] = tag1_val[1];
10975           match[14] = tag1_val[0];
10976         }
10977       if (cos1)
10978         match[14] |= (cos1_val & 0x7) << 5;
10979       *matchp = match;
10980       return 1;
10981     }
10982   if (tag1)
10983     {
10984       match[15] = tag1_val[1];
10985       match[14] = tag1_val[0];
10986       if (proto)
10987         {
10988           match[17] = proto_val & 0xff;
10989           match[16] = proto_val >> 8;
10990         }
10991       if (cos1)
10992         match[14] |= (cos1_val & 0x7) << 5;
10993
10994       *matchp = match;
10995       return 1;
10996     }
10997   if (cos2)
10998     match[18] |= (cos2_val & 0x7) << 5;
10999   if (cos1)
11000     match[14] |= (cos1_val & 0x7) << 5;
11001   if (proto)
11002     {
11003       match[13] = proto_val & 0xff;
11004       match[12] = proto_val >> 8;
11005     }
11006
11007   *matchp = match;
11008   return 1;
11009 }
11010
11011 uword
11012 unformat_qos_source (unformat_input_t * input, va_list * args)
11013 {
11014   int *qs = va_arg (*args, int *);
11015
11016   if (unformat (input, "ip"))
11017     *qs = QOS_SOURCE_IP;
11018   else if (unformat (input, "mpls"))
11019     *qs = QOS_SOURCE_MPLS;
11020   else if (unformat (input, "ext"))
11021     *qs = QOS_SOURCE_EXT;
11022   else if (unformat (input, "vlan"))
11023     *qs = QOS_SOURCE_VLAN;
11024   else
11025     return 0;
11026
11027   return 1;
11028 }
11029 #endif
11030
11031 uword
11032 api_unformat_classify_match (unformat_input_t * input, va_list * args)
11033 {
11034   u8 **matchp = va_arg (*args, u8 **);
11035   u32 skip_n_vectors = va_arg (*args, u32);
11036   u32 match_n_vectors = va_arg (*args, u32);
11037
11038   u8 *match = 0;
11039   u8 *l2 = 0;
11040   u8 *l3 = 0;
11041   u8 *l4 = 0;
11042
11043   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
11044     {
11045       if (unformat (input, "hex %U", unformat_hex_string, &match))
11046         ;
11047       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
11048         ;
11049       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
11050         ;
11051       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
11052         ;
11053       else
11054         break;
11055     }
11056
11057   if (l4 && !l3)
11058     {
11059       vec_free (match);
11060       vec_free (l2);
11061       vec_free (l4);
11062       return 0;
11063     }
11064
11065   if (match || l2 || l3 || l4)
11066     {
11067       if (l2 || l3 || l4)
11068         {
11069           /* "Win a free Ethernet header in every packet" */
11070           if (l2 == 0)
11071             vec_validate_aligned (l2, 13, sizeof (u32x4));
11072           match = l2;
11073           if (vec_len (l3))
11074             {
11075               vec_append_aligned (match, l3, sizeof (u32x4));
11076               vec_free (l3);
11077             }
11078           if (vec_len (l4))
11079             {
11080               vec_append_aligned (match, l4, sizeof (u32x4));
11081               vec_free (l4);
11082             }
11083         }
11084
11085       /* Make sure the vector is big enough even if key is all 0's */
11086       vec_validate_aligned
11087         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
11088          sizeof (u32x4));
11089
11090       /* Set size, include skipped vectors */
11091       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
11092
11093       *matchp = match;
11094
11095       return 1;
11096     }
11097
11098   return 0;
11099 }
11100
11101 static int
11102 api_classify_add_del_session (vat_main_t * vam)
11103 {
11104   unformat_input_t *i = vam->input;
11105   vl_api_classify_add_del_session_t *mp;
11106   int is_add = 1;
11107   u32 table_index = ~0;
11108   u32 hit_next_index = ~0;
11109   u32 opaque_index = ~0;
11110   u8 *match = 0;
11111   i32 advance = 0;
11112   u32 skip_n_vectors = 0;
11113   u32 match_n_vectors = 0;
11114   u32 action = 0;
11115   u32 metadata = 0;
11116   int ret;
11117
11118   /*
11119    * Warning: you have to supply skip_n and match_n
11120    * because the API client cant simply look at the classify
11121    * table object.
11122    */
11123
11124   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11125     {
11126       if (unformat (i, "del"))
11127         is_add = 0;
11128       else if (unformat (i, "hit-next %U", api_unformat_ip_next_index,
11129                          &hit_next_index))
11130         ;
11131       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
11132                          &hit_next_index))
11133         ;
11134       else if (unformat (i, "acl-hit-next %U", api_unformat_acl_next_index,
11135                          &hit_next_index))
11136         ;
11137       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
11138         ;
11139       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
11140         ;
11141       else if (unformat (i, "opaque-index %d", &opaque_index))
11142         ;
11143       else if (unformat (i, "skip_n %d", &skip_n_vectors))
11144         ;
11145       else if (unformat (i, "match_n %d", &match_n_vectors))
11146         ;
11147       else if (unformat (i, "match %U", api_unformat_classify_match,
11148                          &match, skip_n_vectors, match_n_vectors))
11149         ;
11150       else if (unformat (i, "advance %d", &advance))
11151         ;
11152       else if (unformat (i, "table-index %d", &table_index))
11153         ;
11154       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
11155         action = 1;
11156       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
11157         action = 2;
11158       else if (unformat (i, "action %d", &action))
11159         ;
11160       else if (unformat (i, "metadata %d", &metadata))
11161         ;
11162       else
11163         break;
11164     }
11165
11166   if (table_index == ~0)
11167     {
11168       errmsg ("Table index required");
11169       return -99;
11170     }
11171
11172   if (is_add && match == 0)
11173     {
11174       errmsg ("Match value required");
11175       return -99;
11176     }
11177
11178   M2 (CLASSIFY_ADD_DEL_SESSION, mp, vec_len (match));
11179
11180   mp->is_add = is_add;
11181   mp->table_index = ntohl (table_index);
11182   mp->hit_next_index = ntohl (hit_next_index);
11183   mp->opaque_index = ntohl (opaque_index);
11184   mp->advance = ntohl (advance);
11185   mp->action = action;
11186   mp->metadata = ntohl (metadata);
11187   mp->match_len = ntohl (vec_len (match));
11188   clib_memcpy (mp->match, match, vec_len (match));
11189   vec_free (match);
11190
11191   S (mp);
11192   W (ret);
11193   return ret;
11194 }
11195
11196 static int
11197 api_classify_set_interface_ip_table (vat_main_t * vam)
11198 {
11199   unformat_input_t *i = vam->input;
11200   vl_api_classify_set_interface_ip_table_t *mp;
11201   u32 sw_if_index;
11202   int sw_if_index_set;
11203   u32 table_index = ~0;
11204   u8 is_ipv6 = 0;
11205   int ret;
11206
11207   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11208     {
11209       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11210         sw_if_index_set = 1;
11211       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11212         sw_if_index_set = 1;
11213       else if (unformat (i, "table %d", &table_index))
11214         ;
11215       else
11216         {
11217           clib_warning ("parse error '%U'", format_unformat_error, i);
11218           return -99;
11219         }
11220     }
11221
11222   if (sw_if_index_set == 0)
11223     {
11224       errmsg ("missing interface name or sw_if_index");
11225       return -99;
11226     }
11227
11228
11229   M (CLASSIFY_SET_INTERFACE_IP_TABLE, mp);
11230
11231   mp->sw_if_index = ntohl (sw_if_index);
11232   mp->table_index = ntohl (table_index);
11233   mp->is_ipv6 = is_ipv6;
11234
11235   S (mp);
11236   W (ret);
11237   return ret;
11238 }
11239
11240 static int
11241 api_classify_set_interface_l2_tables (vat_main_t * vam)
11242 {
11243   unformat_input_t *i = vam->input;
11244   vl_api_classify_set_interface_l2_tables_t *mp;
11245   u32 sw_if_index;
11246   int sw_if_index_set;
11247   u32 ip4_table_index = ~0;
11248   u32 ip6_table_index = ~0;
11249   u32 other_table_index = ~0;
11250   u32 is_input = 1;
11251   int ret;
11252
11253   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11254     {
11255       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11256         sw_if_index_set = 1;
11257       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11258         sw_if_index_set = 1;
11259       else if (unformat (i, "ip4-table %d", &ip4_table_index))
11260         ;
11261       else if (unformat (i, "ip6-table %d", &ip6_table_index))
11262         ;
11263       else if (unformat (i, "other-table %d", &other_table_index))
11264         ;
11265       else if (unformat (i, "is-input %d", &is_input))
11266         ;
11267       else
11268         {
11269           clib_warning ("parse error '%U'", format_unformat_error, i);
11270           return -99;
11271         }
11272     }
11273
11274   if (sw_if_index_set == 0)
11275     {
11276       errmsg ("missing interface name or sw_if_index");
11277       return -99;
11278     }
11279
11280
11281   M (CLASSIFY_SET_INTERFACE_L2_TABLES, mp);
11282
11283   mp->sw_if_index = ntohl (sw_if_index);
11284   mp->ip4_table_index = ntohl (ip4_table_index);
11285   mp->ip6_table_index = ntohl (ip6_table_index);
11286   mp->other_table_index = ntohl (other_table_index);
11287   mp->is_input = (u8) is_input;
11288
11289   S (mp);
11290   W (ret);
11291   return ret;
11292 }
11293
11294 static int
11295 api_set_ipfix_exporter (vat_main_t * vam)
11296 {
11297   unformat_input_t *i = vam->input;
11298   vl_api_set_ipfix_exporter_t *mp;
11299   ip4_address_t collector_address;
11300   u8 collector_address_set = 0;
11301   u32 collector_port = ~0;
11302   ip4_address_t src_address;
11303   u8 src_address_set = 0;
11304   u32 vrf_id = ~0;
11305   u32 path_mtu = ~0;
11306   u32 template_interval = ~0;
11307   u8 udp_checksum = 0;
11308   int ret;
11309
11310   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11311     {
11312       if (unformat (i, "collector_address %U", unformat_ip4_address,
11313                     &collector_address))
11314         collector_address_set = 1;
11315       else if (unformat (i, "collector_port %d", &collector_port))
11316         ;
11317       else if (unformat (i, "src_address %U", unformat_ip4_address,
11318                          &src_address))
11319         src_address_set = 1;
11320       else if (unformat (i, "vrf_id %d", &vrf_id))
11321         ;
11322       else if (unformat (i, "path_mtu %d", &path_mtu))
11323         ;
11324       else if (unformat (i, "template_interval %d", &template_interval))
11325         ;
11326       else if (unformat (i, "udp_checksum"))
11327         udp_checksum = 1;
11328       else
11329         break;
11330     }
11331
11332   if (collector_address_set == 0)
11333     {
11334       errmsg ("collector_address required");
11335       return -99;
11336     }
11337
11338   if (src_address_set == 0)
11339     {
11340       errmsg ("src_address required");
11341       return -99;
11342     }
11343
11344   M (SET_IPFIX_EXPORTER, mp);
11345
11346   memcpy (mp->collector_address.un.ip4, collector_address.data,
11347           sizeof (collector_address.data));
11348   mp->collector_port = htons ((u16) collector_port);
11349   memcpy (mp->src_address.un.ip4, src_address.data,
11350           sizeof (src_address.data));
11351   mp->vrf_id = htonl (vrf_id);
11352   mp->path_mtu = htonl (path_mtu);
11353   mp->template_interval = htonl (template_interval);
11354   mp->udp_checksum = udp_checksum;
11355
11356   S (mp);
11357   W (ret);
11358   return ret;
11359 }
11360
11361 static int
11362 api_set_ipfix_classify_stream (vat_main_t * vam)
11363 {
11364   unformat_input_t *i = vam->input;
11365   vl_api_set_ipfix_classify_stream_t *mp;
11366   u32 domain_id = 0;
11367   u32 src_port = UDP_DST_PORT_ipfix;
11368   int ret;
11369
11370   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11371     {
11372       if (unformat (i, "domain %d", &domain_id))
11373         ;
11374       else if (unformat (i, "src_port %d", &src_port))
11375         ;
11376       else
11377         {
11378           errmsg ("unknown input `%U'", format_unformat_error, i);
11379           return -99;
11380         }
11381     }
11382
11383   M (SET_IPFIX_CLASSIFY_STREAM, mp);
11384
11385   mp->domain_id = htonl (domain_id);
11386   mp->src_port = htons ((u16) src_port);
11387
11388   S (mp);
11389   W (ret);
11390   return ret;
11391 }
11392
11393 static int
11394 api_ipfix_classify_table_add_del (vat_main_t * vam)
11395 {
11396   unformat_input_t *i = vam->input;
11397   vl_api_ipfix_classify_table_add_del_t *mp;
11398   int is_add = -1;
11399   u32 classify_table_index = ~0;
11400   u8 ip_version = 0;
11401   u8 transport_protocol = 255;
11402   int ret;
11403
11404   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11405     {
11406       if (unformat (i, "add"))
11407         is_add = 1;
11408       else if (unformat (i, "del"))
11409         is_add = 0;
11410       else if (unformat (i, "table %d", &classify_table_index))
11411         ;
11412       else if (unformat (i, "ip4"))
11413         ip_version = 4;
11414       else if (unformat (i, "ip6"))
11415         ip_version = 6;
11416       else if (unformat (i, "tcp"))
11417         transport_protocol = 6;
11418       else if (unformat (i, "udp"))
11419         transport_protocol = 17;
11420       else
11421         {
11422           errmsg ("unknown input `%U'", format_unformat_error, i);
11423           return -99;
11424         }
11425     }
11426
11427   if (is_add == -1)
11428     {
11429       errmsg ("expecting: add|del");
11430       return -99;
11431     }
11432   if (classify_table_index == ~0)
11433     {
11434       errmsg ("classifier table not specified");
11435       return -99;
11436     }
11437   if (ip_version == 0)
11438     {
11439       errmsg ("IP version not specified");
11440       return -99;
11441     }
11442
11443   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, mp);
11444
11445   mp->is_add = is_add;
11446   mp->table_id = htonl (classify_table_index);
11447   mp->ip_version = ip_version;
11448   mp->transport_protocol = transport_protocol;
11449
11450   S (mp);
11451   W (ret);
11452   return ret;
11453 }
11454
11455 static int
11456 api_get_node_index (vat_main_t * vam)
11457 {
11458   unformat_input_t *i = vam->input;
11459   vl_api_get_node_index_t *mp;
11460   u8 *name = 0;
11461   int ret;
11462
11463   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11464     {
11465       if (unformat (i, "node %s", &name))
11466         ;
11467       else
11468         break;
11469     }
11470   if (name == 0)
11471     {
11472       errmsg ("node name required");
11473       return -99;
11474     }
11475   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
11476     {
11477       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11478       return -99;
11479     }
11480
11481   M (GET_NODE_INDEX, mp);
11482   clib_memcpy (mp->node_name, name, vec_len (name));
11483   vec_free (name);
11484
11485   S (mp);
11486   W (ret);
11487   return ret;
11488 }
11489
11490 static int
11491 api_get_next_index (vat_main_t * vam)
11492 {
11493   unformat_input_t *i = vam->input;
11494   vl_api_get_next_index_t *mp;
11495   u8 *node_name = 0, *next_node_name = 0;
11496   int ret;
11497
11498   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11499     {
11500       if (unformat (i, "node-name %s", &node_name))
11501         ;
11502       else if (unformat (i, "next-node-name %s", &next_node_name))
11503         break;
11504     }
11505
11506   if (node_name == 0)
11507     {
11508       errmsg ("node name required");
11509       return -99;
11510     }
11511   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
11512     {
11513       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11514       return -99;
11515     }
11516
11517   if (next_node_name == 0)
11518     {
11519       errmsg ("next node name required");
11520       return -99;
11521     }
11522   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
11523     {
11524       errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
11525       return -99;
11526     }
11527
11528   M (GET_NEXT_INDEX, mp);
11529   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
11530   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
11531   vec_free (node_name);
11532   vec_free (next_node_name);
11533
11534   S (mp);
11535   W (ret);
11536   return ret;
11537 }
11538
11539 static int
11540 api_add_node_next (vat_main_t * vam)
11541 {
11542   unformat_input_t *i = vam->input;
11543   vl_api_add_node_next_t *mp;
11544   u8 *name = 0;
11545   u8 *next = 0;
11546   int ret;
11547
11548   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11549     {
11550       if (unformat (i, "node %s", &name))
11551         ;
11552       else if (unformat (i, "next %s", &next))
11553         ;
11554       else
11555         break;
11556     }
11557   if (name == 0)
11558     {
11559       errmsg ("node name required");
11560       return -99;
11561     }
11562   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
11563     {
11564       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11565       return -99;
11566     }
11567   if (next == 0)
11568     {
11569       errmsg ("next node required");
11570       return -99;
11571     }
11572   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
11573     {
11574       errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
11575       return -99;
11576     }
11577
11578   M (ADD_NODE_NEXT, mp);
11579   clib_memcpy (mp->node_name, name, vec_len (name));
11580   clib_memcpy (mp->next_name, next, vec_len (next));
11581   vec_free (name);
11582   vec_free (next);
11583
11584   S (mp);
11585   W (ret);
11586   return ret;
11587 }
11588
11589 static int
11590 api_l2tpv3_create_tunnel (vat_main_t * vam)
11591 {
11592   unformat_input_t *i = vam->input;
11593   ip6_address_t client_address, our_address;
11594   int client_address_set = 0;
11595   int our_address_set = 0;
11596   u32 local_session_id = 0;
11597   u32 remote_session_id = 0;
11598   u64 local_cookie = 0;
11599   u64 remote_cookie = 0;
11600   u8 l2_sublayer_present = 0;
11601   vl_api_l2tpv3_create_tunnel_t *mp;
11602   int ret;
11603
11604   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11605     {
11606       if (unformat (i, "client_address %U", unformat_ip6_address,
11607                     &client_address))
11608         client_address_set = 1;
11609       else if (unformat (i, "our_address %U", unformat_ip6_address,
11610                          &our_address))
11611         our_address_set = 1;
11612       else if (unformat (i, "local_session_id %d", &local_session_id))
11613         ;
11614       else if (unformat (i, "remote_session_id %d", &remote_session_id))
11615         ;
11616       else if (unformat (i, "local_cookie %lld", &local_cookie))
11617         ;
11618       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
11619         ;
11620       else if (unformat (i, "l2-sublayer-present"))
11621         l2_sublayer_present = 1;
11622       else
11623         break;
11624     }
11625
11626   if (client_address_set == 0)
11627     {
11628       errmsg ("client_address required");
11629       return -99;
11630     }
11631
11632   if (our_address_set == 0)
11633     {
11634       errmsg ("our_address required");
11635       return -99;
11636     }
11637
11638   M (L2TPV3_CREATE_TUNNEL, mp);
11639
11640   clib_memcpy (mp->client_address.un.ip6, client_address.as_u8,
11641                sizeof (ip6_address_t));
11642
11643   clib_memcpy (mp->our_address.un.ip6, our_address.as_u8,
11644                sizeof (ip6_address_t));
11645
11646   mp->local_session_id = ntohl (local_session_id);
11647   mp->remote_session_id = ntohl (remote_session_id);
11648   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
11649   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
11650   mp->l2_sublayer_present = l2_sublayer_present;
11651
11652   S (mp);
11653   W (ret);
11654   return ret;
11655 }
11656
11657 static int
11658 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
11659 {
11660   unformat_input_t *i = vam->input;
11661   u32 sw_if_index;
11662   u8 sw_if_index_set = 0;
11663   u64 new_local_cookie = 0;
11664   u64 new_remote_cookie = 0;
11665   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
11666   int ret;
11667
11668   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11669     {
11670       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11671         sw_if_index_set = 1;
11672       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11673         sw_if_index_set = 1;
11674       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
11675         ;
11676       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
11677         ;
11678       else
11679         break;
11680     }
11681
11682   if (sw_if_index_set == 0)
11683     {
11684       errmsg ("missing interface name or sw_if_index");
11685       return -99;
11686     }
11687
11688   M (L2TPV3_SET_TUNNEL_COOKIES, mp);
11689
11690   mp->sw_if_index = ntohl (sw_if_index);
11691   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
11692   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
11693
11694   S (mp);
11695   W (ret);
11696   return ret;
11697 }
11698
11699 static int
11700 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
11701 {
11702   unformat_input_t *i = vam->input;
11703   vl_api_l2tpv3_interface_enable_disable_t *mp;
11704   u32 sw_if_index;
11705   u8 sw_if_index_set = 0;
11706   u8 enable_disable = 1;
11707   int ret;
11708
11709   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11710     {
11711       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11712         sw_if_index_set = 1;
11713       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11714         sw_if_index_set = 1;
11715       else if (unformat (i, "enable"))
11716         enable_disable = 1;
11717       else if (unformat (i, "disable"))
11718         enable_disable = 0;
11719       else
11720         break;
11721     }
11722
11723   if (sw_if_index_set == 0)
11724     {
11725       errmsg ("missing interface name or sw_if_index");
11726       return -99;
11727     }
11728
11729   M (L2TPV3_INTERFACE_ENABLE_DISABLE, mp);
11730
11731   mp->sw_if_index = ntohl (sw_if_index);
11732   mp->enable_disable = enable_disable;
11733
11734   S (mp);
11735   W (ret);
11736   return ret;
11737 }
11738
11739 static int
11740 api_l2tpv3_set_lookup_key (vat_main_t * vam)
11741 {
11742   unformat_input_t *i = vam->input;
11743   vl_api_l2tpv3_set_lookup_key_t *mp;
11744   u8 key = ~0;
11745   int ret;
11746
11747   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11748     {
11749       if (unformat (i, "lookup_v6_src"))
11750         key = L2T_LOOKUP_SRC_ADDRESS;
11751       else if (unformat (i, "lookup_v6_dst"))
11752         key = L2T_LOOKUP_DST_ADDRESS;
11753       else if (unformat (i, "lookup_session_id"))
11754         key = L2T_LOOKUP_SESSION_ID;
11755       else
11756         break;
11757     }
11758
11759   if (key == (u8) ~ 0)
11760     {
11761       errmsg ("l2tp session lookup key unset");
11762       return -99;
11763     }
11764
11765   M (L2TPV3_SET_LOOKUP_KEY, mp);
11766
11767   mp->key = key;
11768
11769   S (mp);
11770   W (ret);
11771   return ret;
11772 }
11773
11774 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
11775   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
11776 {
11777   vat_main_t *vam = &vat_main;
11778
11779   print (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)",
11780          format_ip6_address, mp->our_address,
11781          format_ip6_address, mp->client_address,
11782          clib_net_to_host_u32 (mp->sw_if_index));
11783
11784   print (vam->ofp,
11785          "   local cookies %016llx %016llx remote cookie %016llx",
11786          clib_net_to_host_u64 (mp->local_cookie[0]),
11787          clib_net_to_host_u64 (mp->local_cookie[1]),
11788          clib_net_to_host_u64 (mp->remote_cookie));
11789
11790   print (vam->ofp, "   local session-id %d remote session-id %d",
11791          clib_net_to_host_u32 (mp->local_session_id),
11792          clib_net_to_host_u32 (mp->remote_session_id));
11793
11794   print (vam->ofp, "   l2 specific sublayer %s\n",
11795          mp->l2_sublayer_present ? "preset" : "absent");
11796
11797 }
11798
11799 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
11800   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
11801 {
11802   vat_main_t *vam = &vat_main;
11803   vat_json_node_t *node = NULL;
11804   struct in6_addr addr;
11805
11806   if (VAT_JSON_ARRAY != vam->json_tree.type)
11807     {
11808       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11809       vat_json_init_array (&vam->json_tree);
11810     }
11811   node = vat_json_array_add (&vam->json_tree);
11812
11813   vat_json_init_object (node);
11814
11815   clib_memcpy (&addr, mp->our_address.un.ip6, sizeof (addr));
11816   vat_json_object_add_ip6 (node, "our_address", addr);
11817   clib_memcpy (&addr, mp->client_address.un.ip6, sizeof (addr));
11818   vat_json_object_add_ip6 (node, "client_address", addr);
11819
11820   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
11821   vat_json_init_array (lc);
11822   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
11823   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
11824   vat_json_object_add_uint (node, "remote_cookie",
11825                             clib_net_to_host_u64 (mp->remote_cookie));
11826
11827   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
11828   vat_json_object_add_uint (node, "local_session_id",
11829                             clib_net_to_host_u32 (mp->local_session_id));
11830   vat_json_object_add_uint (node, "remote_session_id",
11831                             clib_net_to_host_u32 (mp->remote_session_id));
11832   vat_json_object_add_string_copy (node, "l2_sublayer",
11833                                    mp->l2_sublayer_present ? (u8 *) "present"
11834                                    : (u8 *) "absent");
11835 }
11836
11837 static int
11838 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
11839 {
11840   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
11841   vl_api_control_ping_t *mp_ping;
11842   int ret;
11843
11844   /* Get list of l2tpv3-tunnel interfaces */
11845   M (SW_IF_L2TPV3_TUNNEL_DUMP, mp);
11846   S (mp);
11847
11848   /* Use a control ping for synchronization */
11849   MPING (CONTROL_PING, mp_ping);
11850   S (mp_ping);
11851
11852   W (ret);
11853   return ret;
11854 }
11855
11856
11857 static void vl_api_sw_interface_tap_v2_details_t_handler
11858   (vl_api_sw_interface_tap_v2_details_t * mp)
11859 {
11860   vat_main_t *vam = &vat_main;
11861
11862   u8 *ip4 =
11863     format (0, "%U/%d", format_ip4_address, mp->host_ip4_prefix.address,
11864             mp->host_ip4_prefix.len);
11865   u8 *ip6 =
11866     format (0, "%U/%d", format_ip6_address, mp->host_ip6_prefix.address,
11867             mp->host_ip6_prefix.len);
11868
11869   print (vam->ofp,
11870          "\n%-16s %-12d %-5d %-12d %-12d %-14U %-30s %-20s %-20s %-30s 0x%-08x",
11871          mp->dev_name, ntohl (mp->sw_if_index), ntohl (mp->id),
11872          ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
11873          format_ethernet_address, mp->host_mac_addr, mp->host_namespace,
11874          mp->host_bridge, ip4, ip6, ntohl (mp->tap_flags));
11875
11876   vec_free (ip4);
11877   vec_free (ip6);
11878 }
11879
11880 static void vl_api_sw_interface_tap_v2_details_t_handler_json
11881   (vl_api_sw_interface_tap_v2_details_t * mp)
11882 {
11883   vat_main_t *vam = &vat_main;
11884   vat_json_node_t *node = NULL;
11885
11886   if (VAT_JSON_ARRAY != vam->json_tree.type)
11887     {
11888       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11889       vat_json_init_array (&vam->json_tree);
11890     }
11891   node = vat_json_array_add (&vam->json_tree);
11892
11893   vat_json_init_object (node);
11894   vat_json_object_add_uint (node, "id", ntohl (mp->id));
11895   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11896   vat_json_object_add_uint (node, "tap_flags", ntohl (mp->tap_flags));
11897   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
11898   vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
11899   vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
11900   vat_json_object_add_string_copy (node, "host_mac_addr",
11901                                    format (0, "%U", format_ethernet_address,
11902                                            &mp->host_mac_addr));
11903   vat_json_object_add_string_copy (node, "host_namespace",
11904                                    mp->host_namespace);
11905   vat_json_object_add_string_copy (node, "host_bridge", mp->host_bridge);
11906   vat_json_object_add_string_copy (node, "host_ip4_addr",
11907                                    format (0, "%U/%d", format_ip4_address,
11908                                            mp->host_ip4_prefix.address,
11909                                            mp->host_ip4_prefix.len));
11910   vat_json_object_add_string_copy (node, "host_ip6_prefix",
11911                                    format (0, "%U/%d", format_ip6_address,
11912                                            mp->host_ip6_prefix.address,
11913                                            mp->host_ip6_prefix.len));
11914
11915 }
11916
11917 static int
11918 api_sw_interface_tap_v2_dump (vat_main_t * vam)
11919 {
11920   vl_api_sw_interface_tap_v2_dump_t *mp;
11921   vl_api_control_ping_t *mp_ping;
11922   int ret;
11923
11924   print (vam->ofp,
11925          "\n%-16s %-12s %-5s %-12s %-12s %-14s %-30s %-20s %-20s %-30s",
11926          "dev_name", "sw_if_index", "id", "rx_ring_sz", "tx_ring_sz",
11927          "host_mac_addr", "host_namespace", "host_bridge", "host_ip4_addr",
11928          "host_ip6_addr");
11929
11930   /* Get list of tap interfaces */
11931   M (SW_INTERFACE_TAP_V2_DUMP, mp);
11932   S (mp);
11933
11934   /* Use a control ping for synchronization */
11935   MPING (CONTROL_PING, mp_ping);
11936   S (mp_ping);
11937
11938   W (ret);
11939   return ret;
11940 }
11941
11942 static void vl_api_sw_interface_virtio_pci_details_t_handler
11943   (vl_api_sw_interface_virtio_pci_details_t * mp)
11944 {
11945   vat_main_t *vam = &vat_main;
11946
11947   typedef union
11948   {
11949     struct
11950     {
11951       u16 domain;
11952       u8 bus;
11953       u8 slot:5;
11954       u8 function:3;
11955     };
11956     u32 as_u32;
11957   } pci_addr_t;
11958   pci_addr_t addr;
11959   addr.as_u32 = ntohl (mp->pci_addr);
11960   u8 *pci_addr = format (0, "%04x:%02x:%02x.%x", addr.domain, addr.bus,
11961                          addr.slot, addr.function);
11962
11963   print (vam->ofp,
11964          "\n%-12s %-12d %-12d %-12d %-17U 0x%-08llx",
11965          pci_addr, ntohl (mp->sw_if_index),
11966          ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
11967          format_ethernet_address, mp->mac_addr,
11968          clib_net_to_host_u64 (mp->features));
11969   vec_free (pci_addr);
11970 }
11971
11972 static void vl_api_sw_interface_virtio_pci_details_t_handler_json
11973   (vl_api_sw_interface_virtio_pci_details_t * mp)
11974 {
11975   vat_main_t *vam = &vat_main;
11976   vat_json_node_t *node = NULL;
11977
11978   if (VAT_JSON_ARRAY != vam->json_tree.type)
11979     {
11980       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11981       vat_json_init_array (&vam->json_tree);
11982     }
11983   node = vat_json_array_add (&vam->json_tree);
11984
11985   vat_json_init_object (node);
11986   vat_json_object_add_uint (node, "pci-addr", ntohl (mp->pci_addr));
11987   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11988   vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
11989   vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
11990   vat_json_object_add_uint (node, "features",
11991                             clib_net_to_host_u64 (mp->features));
11992   vat_json_object_add_string_copy (node, "mac_addr",
11993                                    format (0, "%U", format_ethernet_address,
11994                                            &mp->mac_addr));
11995 }
11996
11997 static int
11998 api_sw_interface_virtio_pci_dump (vat_main_t * vam)
11999 {
12000   vl_api_sw_interface_virtio_pci_dump_t *mp;
12001   vl_api_control_ping_t *mp_ping;
12002   int ret;
12003
12004   print (vam->ofp,
12005          "\n%-12s %-12s %-12s %-12s %-17s %-08s",
12006          "pci_addr", "sw_if_index", "rx_ring_sz", "tx_ring_sz",
12007          "mac_addr", "features");
12008
12009   /* Get list of tap interfaces */
12010   M (SW_INTERFACE_VIRTIO_PCI_DUMP, mp);
12011   S (mp);
12012
12013   /* Use a control ping for synchronization */
12014   MPING (CONTROL_PING, mp_ping);
12015   S (mp_ping);
12016
12017   W (ret);
12018   return ret;
12019 }
12020
12021 static int
12022 api_vxlan_offload_rx (vat_main_t * vam)
12023 {
12024   unformat_input_t *line_input = vam->input;
12025   vl_api_vxlan_offload_rx_t *mp;
12026   u32 hw_if_index = ~0, rx_if_index = ~0;
12027   u8 is_add = 1;
12028   int ret;
12029
12030   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12031     {
12032       if (unformat (line_input, "del"))
12033         is_add = 0;
12034       else if (unformat (line_input, "hw %U", api_unformat_hw_if_index, vam,
12035                          &hw_if_index))
12036         ;
12037       else if (unformat (line_input, "hw hw_if_index %u", &hw_if_index))
12038         ;
12039       else if (unformat (line_input, "rx %U", api_unformat_sw_if_index, vam,
12040                          &rx_if_index))
12041         ;
12042       else if (unformat (line_input, "rx sw_if_index %u", &rx_if_index))
12043         ;
12044       else
12045         {
12046           errmsg ("parse error '%U'", format_unformat_error, line_input);
12047           return -99;
12048         }
12049     }
12050
12051   if (hw_if_index == ~0)
12052     {
12053       errmsg ("no hw interface");
12054       return -99;
12055     }
12056
12057   if (rx_if_index == ~0)
12058     {
12059       errmsg ("no rx tunnel");
12060       return -99;
12061     }
12062
12063   M (VXLAN_OFFLOAD_RX, mp);
12064
12065   mp->hw_if_index = ntohl (hw_if_index);
12066   mp->sw_if_index = ntohl (rx_if_index);
12067   mp->enable = is_add;
12068
12069   S (mp);
12070   W (ret);
12071   return ret;
12072 }
12073
12074 static uword unformat_vxlan_decap_next
12075   (unformat_input_t * input, va_list * args)
12076 {
12077   u32 *result = va_arg (*args, u32 *);
12078   u32 tmp;
12079
12080   if (unformat (input, "l2"))
12081     *result = VXLAN_INPUT_NEXT_L2_INPUT;
12082   else if (unformat (input, "%d", &tmp))
12083     *result = tmp;
12084   else
12085     return 0;
12086   return 1;
12087 }
12088
12089 static int
12090 api_vxlan_add_del_tunnel (vat_main_t * vam)
12091 {
12092   unformat_input_t *line_input = vam->input;
12093   vl_api_vxlan_add_del_tunnel_t *mp;
12094   ip46_address_t src, dst;
12095   u8 is_add = 1;
12096   u8 ipv4_set = 0, ipv6_set = 0;
12097   u8 src_set = 0;
12098   u8 dst_set = 0;
12099   u8 grp_set = 0;
12100   u32 instance = ~0;
12101   u32 mcast_sw_if_index = ~0;
12102   u32 encap_vrf_id = 0;
12103   u32 decap_next_index = ~0;
12104   u32 vni = 0;
12105   int ret;
12106
12107   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
12108   clib_memset (&src, 0, sizeof src);
12109   clib_memset (&dst, 0, sizeof dst);
12110
12111   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12112     {
12113       if (unformat (line_input, "del"))
12114         is_add = 0;
12115       else if (unformat (line_input, "instance %d", &instance))
12116         ;
12117       else
12118         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
12119         {
12120           ipv4_set = 1;
12121           src_set = 1;
12122         }
12123       else
12124         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
12125         {
12126           ipv4_set = 1;
12127           dst_set = 1;
12128         }
12129       else
12130         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
12131         {
12132           ipv6_set = 1;
12133           src_set = 1;
12134         }
12135       else
12136         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
12137         {
12138           ipv6_set = 1;
12139           dst_set = 1;
12140         }
12141       else if (unformat (line_input, "group %U %U",
12142                          unformat_ip4_address, &dst.ip4,
12143                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12144         {
12145           grp_set = dst_set = 1;
12146           ipv4_set = 1;
12147         }
12148       else if (unformat (line_input, "group %U",
12149                          unformat_ip4_address, &dst.ip4))
12150         {
12151           grp_set = dst_set = 1;
12152           ipv4_set = 1;
12153         }
12154       else if (unformat (line_input, "group %U %U",
12155                          unformat_ip6_address, &dst.ip6,
12156                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12157         {
12158           grp_set = dst_set = 1;
12159           ipv6_set = 1;
12160         }
12161       else if (unformat (line_input, "group %U",
12162                          unformat_ip6_address, &dst.ip6))
12163         {
12164           grp_set = dst_set = 1;
12165           ipv6_set = 1;
12166         }
12167       else
12168         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
12169         ;
12170       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
12171         ;
12172       else if (unformat (line_input, "decap-next %U",
12173                          unformat_vxlan_decap_next, &decap_next_index))
12174         ;
12175       else if (unformat (line_input, "vni %d", &vni))
12176         ;
12177       else
12178         {
12179           errmsg ("parse error '%U'", format_unformat_error, line_input);
12180           return -99;
12181         }
12182     }
12183
12184   if (src_set == 0)
12185     {
12186       errmsg ("tunnel src address not specified");
12187       return -99;
12188     }
12189   if (dst_set == 0)
12190     {
12191       errmsg ("tunnel dst address not specified");
12192       return -99;
12193     }
12194
12195   if (grp_set && !ip46_address_is_multicast (&dst))
12196     {
12197       errmsg ("tunnel group address not multicast");
12198       return -99;
12199     }
12200   if (grp_set && mcast_sw_if_index == ~0)
12201     {
12202       errmsg ("tunnel nonexistent multicast device");
12203       return -99;
12204     }
12205   if (grp_set == 0 && ip46_address_is_multicast (&dst))
12206     {
12207       errmsg ("tunnel dst address must be unicast");
12208       return -99;
12209     }
12210
12211
12212   if (ipv4_set && ipv6_set)
12213     {
12214       errmsg ("both IPv4 and IPv6 addresses specified");
12215       return -99;
12216     }
12217
12218   if ((vni == 0) || (vni >> 24))
12219     {
12220       errmsg ("vni not specified or out of range");
12221       return -99;
12222     }
12223
12224   M (VXLAN_ADD_DEL_TUNNEL, mp);
12225
12226   if (ipv6_set)
12227     {
12228       clib_memcpy (mp->src_address, &src.ip6, sizeof (src.ip6));
12229       clib_memcpy (mp->dst_address, &dst.ip6, sizeof (dst.ip6));
12230     }
12231   else
12232     {
12233       clib_memcpy (mp->src_address, &src.ip4, sizeof (src.ip4));
12234       clib_memcpy (mp->dst_address, &dst.ip4, sizeof (dst.ip4));
12235     }
12236
12237   mp->instance = htonl (instance);
12238   mp->encap_vrf_id = ntohl (encap_vrf_id);
12239   mp->decap_next_index = ntohl (decap_next_index);
12240   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
12241   mp->vni = ntohl (vni);
12242   mp->is_add = is_add;
12243   mp->is_ipv6 = ipv6_set;
12244
12245   S (mp);
12246   W (ret);
12247   return ret;
12248 }
12249
12250 static void vl_api_vxlan_tunnel_details_t_handler
12251   (vl_api_vxlan_tunnel_details_t * mp)
12252 {
12253   vat_main_t *vam = &vat_main;
12254   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
12255   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
12256
12257   print (vam->ofp, "%11d%11d%24U%24U%14d%18d%13d%19d",
12258          ntohl (mp->sw_if_index),
12259          ntohl (mp->instance),
12260          format_ip46_address, &src, IP46_TYPE_ANY,
12261          format_ip46_address, &dst, IP46_TYPE_ANY,
12262          ntohl (mp->encap_vrf_id),
12263          ntohl (mp->decap_next_index), ntohl (mp->vni),
12264          ntohl (mp->mcast_sw_if_index));
12265 }
12266
12267 static void vl_api_vxlan_tunnel_details_t_handler_json
12268   (vl_api_vxlan_tunnel_details_t * mp)
12269 {
12270   vat_main_t *vam = &vat_main;
12271   vat_json_node_t *node = NULL;
12272
12273   if (VAT_JSON_ARRAY != vam->json_tree.type)
12274     {
12275       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12276       vat_json_init_array (&vam->json_tree);
12277     }
12278   node = vat_json_array_add (&vam->json_tree);
12279
12280   vat_json_init_object (node);
12281   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12282
12283   vat_json_object_add_uint (node, "instance", ntohl (mp->instance));
12284
12285   if (mp->is_ipv6)
12286     {
12287       struct in6_addr ip6;
12288
12289       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
12290       vat_json_object_add_ip6 (node, "src_address", ip6);
12291       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
12292       vat_json_object_add_ip6 (node, "dst_address", ip6);
12293     }
12294   else
12295     {
12296       struct in_addr ip4;
12297
12298       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
12299       vat_json_object_add_ip4 (node, "src_address", ip4);
12300       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
12301       vat_json_object_add_ip4 (node, "dst_address", ip4);
12302     }
12303   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
12304   vat_json_object_add_uint (node, "decap_next_index",
12305                             ntohl (mp->decap_next_index));
12306   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
12307   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
12308   vat_json_object_add_uint (node, "mcast_sw_if_index",
12309                             ntohl (mp->mcast_sw_if_index));
12310 }
12311
12312 static int
12313 api_vxlan_tunnel_dump (vat_main_t * vam)
12314 {
12315   unformat_input_t *i = vam->input;
12316   vl_api_vxlan_tunnel_dump_t *mp;
12317   vl_api_control_ping_t *mp_ping;
12318   u32 sw_if_index;
12319   u8 sw_if_index_set = 0;
12320   int ret;
12321
12322   /* Parse args required to build the message */
12323   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12324     {
12325       if (unformat (i, "sw_if_index %d", &sw_if_index))
12326         sw_if_index_set = 1;
12327       else
12328         break;
12329     }
12330
12331   if (sw_if_index_set == 0)
12332     {
12333       sw_if_index = ~0;
12334     }
12335
12336   if (!vam->json_output)
12337     {
12338       print (vam->ofp, "%11s%11s%24s%24s%14s%18s%13s%19s",
12339              "sw_if_index", "instance", "src_address", "dst_address",
12340              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
12341     }
12342
12343   /* Get list of vxlan-tunnel interfaces */
12344   M (VXLAN_TUNNEL_DUMP, mp);
12345
12346   mp->sw_if_index = htonl (sw_if_index);
12347
12348   S (mp);
12349
12350   /* Use a control ping for synchronization */
12351   MPING (CONTROL_PING, mp_ping);
12352   S (mp_ping);
12353
12354   W (ret);
12355   return ret;
12356 }
12357
12358 static uword unformat_geneve_decap_next
12359   (unformat_input_t * input, va_list * args)
12360 {
12361   u32 *result = va_arg (*args, u32 *);
12362   u32 tmp;
12363
12364   if (unformat (input, "l2"))
12365     *result = GENEVE_INPUT_NEXT_L2_INPUT;
12366   else if (unformat (input, "%d", &tmp))
12367     *result = tmp;
12368   else
12369     return 0;
12370   return 1;
12371 }
12372
12373 static int
12374 api_geneve_add_del_tunnel (vat_main_t * vam)
12375 {
12376   unformat_input_t *line_input = vam->input;
12377   vl_api_geneve_add_del_tunnel_t *mp;
12378   ip46_address_t src, dst;
12379   u8 is_add = 1;
12380   u8 ipv4_set = 0, ipv6_set = 0;
12381   u8 src_set = 0;
12382   u8 dst_set = 0;
12383   u8 grp_set = 0;
12384   u32 mcast_sw_if_index = ~0;
12385   u32 encap_vrf_id = 0;
12386   u32 decap_next_index = ~0;
12387   u32 vni = 0;
12388   int ret;
12389
12390   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
12391   clib_memset (&src, 0, sizeof src);
12392   clib_memset (&dst, 0, sizeof dst);
12393
12394   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12395     {
12396       if (unformat (line_input, "del"))
12397         is_add = 0;
12398       else
12399         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
12400         {
12401           ipv4_set = 1;
12402           src_set = 1;
12403         }
12404       else
12405         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
12406         {
12407           ipv4_set = 1;
12408           dst_set = 1;
12409         }
12410       else
12411         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
12412         {
12413           ipv6_set = 1;
12414           src_set = 1;
12415         }
12416       else
12417         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
12418         {
12419           ipv6_set = 1;
12420           dst_set = 1;
12421         }
12422       else if (unformat (line_input, "group %U %U",
12423                          unformat_ip4_address, &dst.ip4,
12424                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12425         {
12426           grp_set = dst_set = 1;
12427           ipv4_set = 1;
12428         }
12429       else if (unformat (line_input, "group %U",
12430                          unformat_ip4_address, &dst.ip4))
12431         {
12432           grp_set = dst_set = 1;
12433           ipv4_set = 1;
12434         }
12435       else if (unformat (line_input, "group %U %U",
12436                          unformat_ip6_address, &dst.ip6,
12437                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12438         {
12439           grp_set = dst_set = 1;
12440           ipv6_set = 1;
12441         }
12442       else if (unformat (line_input, "group %U",
12443                          unformat_ip6_address, &dst.ip6))
12444         {
12445           grp_set = dst_set = 1;
12446           ipv6_set = 1;
12447         }
12448       else
12449         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
12450         ;
12451       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
12452         ;
12453       else if (unformat (line_input, "decap-next %U",
12454                          unformat_geneve_decap_next, &decap_next_index))
12455         ;
12456       else if (unformat (line_input, "vni %d", &vni))
12457         ;
12458       else
12459         {
12460           errmsg ("parse error '%U'", format_unformat_error, line_input);
12461           return -99;
12462         }
12463     }
12464
12465   if (src_set == 0)
12466     {
12467       errmsg ("tunnel src address not specified");
12468       return -99;
12469     }
12470   if (dst_set == 0)
12471     {
12472       errmsg ("tunnel dst address not specified");
12473       return -99;
12474     }
12475
12476   if (grp_set && !ip46_address_is_multicast (&dst))
12477     {
12478       errmsg ("tunnel group address not multicast");
12479       return -99;
12480     }
12481   if (grp_set && mcast_sw_if_index == ~0)
12482     {
12483       errmsg ("tunnel nonexistent multicast device");
12484       return -99;
12485     }
12486   if (grp_set == 0 && ip46_address_is_multicast (&dst))
12487     {
12488       errmsg ("tunnel dst address must be unicast");
12489       return -99;
12490     }
12491
12492
12493   if (ipv4_set && ipv6_set)
12494     {
12495       errmsg ("both IPv4 and IPv6 addresses specified");
12496       return -99;
12497     }
12498
12499   if ((vni == 0) || (vni >> 24))
12500     {
12501       errmsg ("vni not specified or out of range");
12502       return -99;
12503     }
12504
12505   M (GENEVE_ADD_DEL_TUNNEL, mp);
12506
12507   if (ipv6_set)
12508     {
12509       clib_memcpy (&mp->local_address.un.ip6, &src.ip6, sizeof (src.ip6));
12510       clib_memcpy (&mp->remote_address.un.ip6, &dst.ip6, sizeof (dst.ip6));
12511     }
12512   else
12513     {
12514       clib_memcpy (&mp->local_address.un.ip4, &src.ip4, sizeof (src.ip4));
12515       clib_memcpy (&mp->remote_address.un.ip4, &dst.ip4, sizeof (dst.ip4));
12516     }
12517   mp->encap_vrf_id = ntohl (encap_vrf_id);
12518   mp->decap_next_index = ntohl (decap_next_index);
12519   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
12520   mp->vni = ntohl (vni);
12521   mp->is_add = is_add;
12522
12523   S (mp);
12524   W (ret);
12525   return ret;
12526 }
12527
12528 static void vl_api_geneve_tunnel_details_t_handler
12529   (vl_api_geneve_tunnel_details_t * mp)
12530 {
12531   vat_main_t *vam = &vat_main;
12532   ip46_address_t src = {.as_u64[0] = 0,.as_u64[1] = 0 };
12533   ip46_address_t dst = {.as_u64[0] = 0,.as_u64[1] = 0 };
12534
12535   if (mp->src_address.af == ADDRESS_IP6)
12536     {
12537       clib_memcpy (&src.ip6, &mp->src_address.un.ip6, sizeof (ip6_address_t));
12538       clib_memcpy (&dst.ip6, &mp->dst_address.un.ip6, sizeof (ip6_address_t));
12539     }
12540   else
12541     {
12542       clib_memcpy (&src.ip4, &mp->src_address.un.ip4, sizeof (ip4_address_t));
12543       clib_memcpy (&dst.ip4, &mp->dst_address.un.ip4, sizeof (ip4_address_t));
12544     }
12545
12546   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
12547          ntohl (mp->sw_if_index),
12548          format_ip46_address, &src, IP46_TYPE_ANY,
12549          format_ip46_address, &dst, IP46_TYPE_ANY,
12550          ntohl (mp->encap_vrf_id),
12551          ntohl (mp->decap_next_index), ntohl (mp->vni),
12552          ntohl (mp->mcast_sw_if_index));
12553 }
12554
12555 static void vl_api_geneve_tunnel_details_t_handler_json
12556   (vl_api_geneve_tunnel_details_t * mp)
12557 {
12558   vat_main_t *vam = &vat_main;
12559   vat_json_node_t *node = NULL;
12560   bool is_ipv6;
12561
12562   if (VAT_JSON_ARRAY != vam->json_tree.type)
12563     {
12564       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12565       vat_json_init_array (&vam->json_tree);
12566     }
12567   node = vat_json_array_add (&vam->json_tree);
12568
12569   vat_json_init_object (node);
12570   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12571   is_ipv6 = mp->src_address.af == ADDRESS_IP6;
12572   if (is_ipv6)
12573     {
12574       struct in6_addr ip6;
12575
12576       clib_memcpy (&ip6, &mp->src_address.un.ip6, sizeof (ip6));
12577       vat_json_object_add_ip6 (node, "src_address", ip6);
12578       clib_memcpy (&ip6, &mp->dst_address.un.ip6, sizeof (ip6));
12579       vat_json_object_add_ip6 (node, "dst_address", ip6);
12580     }
12581   else
12582     {
12583       struct in_addr ip4;
12584
12585       clib_memcpy (&ip4, &mp->src_address.un.ip4, sizeof (ip4));
12586       vat_json_object_add_ip4 (node, "src_address", ip4);
12587       clib_memcpy (&ip4, &mp->dst_address.un.ip4, sizeof (ip4));
12588       vat_json_object_add_ip4 (node, "dst_address", ip4);
12589     }
12590   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
12591   vat_json_object_add_uint (node, "decap_next_index",
12592                             ntohl (mp->decap_next_index));
12593   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
12594   vat_json_object_add_uint (node, "mcast_sw_if_index",
12595                             ntohl (mp->mcast_sw_if_index));
12596 }
12597
12598 static int
12599 api_geneve_tunnel_dump (vat_main_t * vam)
12600 {
12601   unformat_input_t *i = vam->input;
12602   vl_api_geneve_tunnel_dump_t *mp;
12603   vl_api_control_ping_t *mp_ping;
12604   u32 sw_if_index;
12605   u8 sw_if_index_set = 0;
12606   int ret;
12607
12608   /* Parse args required to build the message */
12609   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12610     {
12611       if (unformat (i, "sw_if_index %d", &sw_if_index))
12612         sw_if_index_set = 1;
12613       else
12614         break;
12615     }
12616
12617   if (sw_if_index_set == 0)
12618     {
12619       sw_if_index = ~0;
12620     }
12621
12622   if (!vam->json_output)
12623     {
12624       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
12625              "sw_if_index", "local_address", "remote_address",
12626              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
12627     }
12628
12629   /* Get list of geneve-tunnel interfaces */
12630   M (GENEVE_TUNNEL_DUMP, mp);
12631
12632   mp->sw_if_index = htonl (sw_if_index);
12633
12634   S (mp);
12635
12636   /* Use a control ping for synchronization */
12637   M (CONTROL_PING, mp_ping);
12638   S (mp_ping);
12639
12640   W (ret);
12641   return ret;
12642 }
12643
12644 static int
12645 api_gre_tunnel_add_del (vat_main_t * vam)
12646 {
12647   unformat_input_t *line_input = vam->input;
12648   vl_api_address_t src = { }, dst =
12649   {
12650   };
12651   vl_api_gre_tunnel_add_del_t *mp;
12652   vl_api_gre_tunnel_type_t t_type;
12653   u8 is_add = 1;
12654   u8 src_set = 0;
12655   u8 dst_set = 0;
12656   u32 outer_table_id = 0;
12657   u32 session_id = 0;
12658   u32 instance = ~0;
12659   int ret;
12660
12661   t_type = GRE_API_TUNNEL_TYPE_L3;
12662
12663   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12664     {
12665       if (unformat (line_input, "del"))
12666         is_add = 0;
12667       else if (unformat (line_input, "instance %d", &instance))
12668         ;
12669       else if (unformat (line_input, "src %U", unformat_vl_api_address, &src))
12670         {
12671           src_set = 1;
12672         }
12673       else if (unformat (line_input, "dst %U", unformat_vl_api_address, &dst))
12674         {
12675           dst_set = 1;
12676         }
12677       else if (unformat (line_input, "outer-table-id %d", &outer_table_id))
12678         ;
12679       else if (unformat (line_input, "teb"))
12680         t_type = GRE_API_TUNNEL_TYPE_TEB;
12681       else if (unformat (line_input, "erspan %d", &session_id))
12682         t_type = GRE_API_TUNNEL_TYPE_ERSPAN;
12683       else
12684         {
12685           errmsg ("parse error '%U'", format_unformat_error, line_input);
12686           return -99;
12687         }
12688     }
12689
12690   if (src_set == 0)
12691     {
12692       errmsg ("tunnel src address not specified");
12693       return -99;
12694     }
12695   if (dst_set == 0)
12696     {
12697       errmsg ("tunnel dst address not specified");
12698       return -99;
12699     }
12700
12701   M (GRE_TUNNEL_ADD_DEL, mp);
12702
12703   clib_memcpy (&mp->tunnel.src, &src, sizeof (mp->tunnel.src));
12704   clib_memcpy (&mp->tunnel.dst, &dst, sizeof (mp->tunnel.dst));
12705
12706   mp->tunnel.instance = htonl (instance);
12707   mp->tunnel.outer_table_id = htonl (outer_table_id);
12708   mp->is_add = is_add;
12709   mp->tunnel.session_id = htons ((u16) session_id);
12710   mp->tunnel.type = htonl (t_type);
12711
12712   S (mp);
12713   W (ret);
12714   return ret;
12715 }
12716
12717 static void vl_api_gre_tunnel_details_t_handler
12718   (vl_api_gre_tunnel_details_t * mp)
12719 {
12720   vat_main_t *vam = &vat_main;
12721
12722   print (vam->ofp, "%11d%11d%24U%24U%13d%14d%12d",
12723          ntohl (mp->tunnel.sw_if_index),
12724          ntohl (mp->tunnel.instance),
12725          format_vl_api_address, &mp->tunnel.src,
12726          format_vl_api_address, &mp->tunnel.dst,
12727          mp->tunnel.type, ntohl (mp->tunnel.outer_table_id),
12728          ntohl (mp->tunnel.session_id));
12729 }
12730
12731 static void vl_api_gre_tunnel_details_t_handler_json
12732   (vl_api_gre_tunnel_details_t * mp)
12733 {
12734   vat_main_t *vam = &vat_main;
12735   vat_json_node_t *node = NULL;
12736
12737   if (VAT_JSON_ARRAY != vam->json_tree.type)
12738     {
12739       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12740       vat_json_init_array (&vam->json_tree);
12741     }
12742   node = vat_json_array_add (&vam->json_tree);
12743
12744   vat_json_init_object (node);
12745   vat_json_object_add_uint (node, "sw_if_index",
12746                             ntohl (mp->tunnel.sw_if_index));
12747   vat_json_object_add_uint (node, "instance", ntohl (mp->tunnel.instance));
12748
12749   vat_json_object_add_address (node, "src", &mp->tunnel.src);
12750   vat_json_object_add_address (node, "dst", &mp->tunnel.dst);
12751   vat_json_object_add_uint (node, "tunnel_type", mp->tunnel.type);
12752   vat_json_object_add_uint (node, "outer_table_id",
12753                             ntohl (mp->tunnel.outer_table_id));
12754   vat_json_object_add_uint (node, "session_id", mp->tunnel.session_id);
12755 }
12756
12757 static int
12758 api_gre_tunnel_dump (vat_main_t * vam)
12759 {
12760   unformat_input_t *i = vam->input;
12761   vl_api_gre_tunnel_dump_t *mp;
12762   vl_api_control_ping_t *mp_ping;
12763   u32 sw_if_index;
12764   u8 sw_if_index_set = 0;
12765   int ret;
12766
12767   /* Parse args required to build the message */
12768   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12769     {
12770       if (unformat (i, "sw_if_index %d", &sw_if_index))
12771         sw_if_index_set = 1;
12772       else
12773         break;
12774     }
12775
12776   if (sw_if_index_set == 0)
12777     {
12778       sw_if_index = ~0;
12779     }
12780
12781   if (!vam->json_output)
12782     {
12783       print (vam->ofp, "%11s%11s%24s%24s%13s%14s%12s",
12784              "sw_if_index", "instance", "src_address", "dst_address",
12785              "tunnel_type", "outer_fib_id", "session_id");
12786     }
12787
12788   /* Get list of gre-tunnel interfaces */
12789   M (GRE_TUNNEL_DUMP, mp);
12790
12791   mp->sw_if_index = htonl (sw_if_index);
12792
12793   S (mp);
12794
12795   /* Use a control ping for synchronization */
12796   MPING (CONTROL_PING, mp_ping);
12797   S (mp_ping);
12798
12799   W (ret);
12800   return ret;
12801 }
12802
12803 static int
12804 api_l2_fib_clear_table (vat_main_t * vam)
12805 {
12806 //  unformat_input_t * i = vam->input;
12807   vl_api_l2_fib_clear_table_t *mp;
12808   int ret;
12809
12810   M (L2_FIB_CLEAR_TABLE, mp);
12811
12812   S (mp);
12813   W (ret);
12814   return ret;
12815 }
12816
12817 static int
12818 api_l2_interface_efp_filter (vat_main_t * vam)
12819 {
12820   unformat_input_t *i = vam->input;
12821   vl_api_l2_interface_efp_filter_t *mp;
12822   u32 sw_if_index;
12823   u8 enable = 1;
12824   u8 sw_if_index_set = 0;
12825   int ret;
12826
12827   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12828     {
12829       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12830         sw_if_index_set = 1;
12831       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12832         sw_if_index_set = 1;
12833       else if (unformat (i, "enable"))
12834         enable = 1;
12835       else if (unformat (i, "disable"))
12836         enable = 0;
12837       else
12838         {
12839           clib_warning ("parse error '%U'", format_unformat_error, i);
12840           return -99;
12841         }
12842     }
12843
12844   if (sw_if_index_set == 0)
12845     {
12846       errmsg ("missing sw_if_index");
12847       return -99;
12848     }
12849
12850   M (L2_INTERFACE_EFP_FILTER, mp);
12851
12852   mp->sw_if_index = ntohl (sw_if_index);
12853   mp->enable_disable = enable;
12854
12855   S (mp);
12856   W (ret);
12857   return ret;
12858 }
12859
12860 #define foreach_vtr_op                          \
12861 _("disable",  L2_VTR_DISABLED)                  \
12862 _("push-1",  L2_VTR_PUSH_1)                     \
12863 _("push-2",  L2_VTR_PUSH_2)                     \
12864 _("pop-1",  L2_VTR_POP_1)                       \
12865 _("pop-2",  L2_VTR_POP_2)                       \
12866 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
12867 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
12868 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
12869 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
12870
12871 static int
12872 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
12873 {
12874   unformat_input_t *i = vam->input;
12875   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
12876   u32 sw_if_index;
12877   u8 sw_if_index_set = 0;
12878   u8 vtr_op_set = 0;
12879   u32 vtr_op = 0;
12880   u32 push_dot1q = 1;
12881   u32 tag1 = ~0;
12882   u32 tag2 = ~0;
12883   int ret;
12884
12885   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12886     {
12887       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12888         sw_if_index_set = 1;
12889       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12890         sw_if_index_set = 1;
12891       else if (unformat (i, "vtr_op %d", &vtr_op))
12892         vtr_op_set = 1;
12893 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
12894       foreach_vtr_op
12895 #undef _
12896         else if (unformat (i, "push_dot1q %d", &push_dot1q))
12897         ;
12898       else if (unformat (i, "tag1 %d", &tag1))
12899         ;
12900       else if (unformat (i, "tag2 %d", &tag2))
12901         ;
12902       else
12903         {
12904           clib_warning ("parse error '%U'", format_unformat_error, i);
12905           return -99;
12906         }
12907     }
12908
12909   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
12910     {
12911       errmsg ("missing vtr operation or sw_if_index");
12912       return -99;
12913     }
12914
12915   M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
12916   mp->sw_if_index = ntohl (sw_if_index);
12917   mp->vtr_op = ntohl (vtr_op);
12918   mp->push_dot1q = ntohl (push_dot1q);
12919   mp->tag1 = ntohl (tag1);
12920   mp->tag2 = ntohl (tag2);
12921
12922   S (mp);
12923   W (ret);
12924   return ret;
12925 }
12926
12927 static int
12928 api_create_vhost_user_if (vat_main_t * vam)
12929 {
12930   unformat_input_t *i = vam->input;
12931   vl_api_create_vhost_user_if_t *mp;
12932   u8 *file_name;
12933   u8 is_server = 0;
12934   u8 file_name_set = 0;
12935   u32 custom_dev_instance = ~0;
12936   u8 hwaddr[6];
12937   u8 use_custom_mac = 0;
12938   u8 disable_mrg_rxbuf = 0;
12939   u8 disable_indirect_desc = 0;
12940   u8 *tag = 0;
12941   u8 enable_gso = 0;
12942   int ret;
12943
12944   /* Shut up coverity */
12945   clib_memset (hwaddr, 0, sizeof (hwaddr));
12946
12947   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12948     {
12949       if (unformat (i, "socket %s", &file_name))
12950         {
12951           file_name_set = 1;
12952         }
12953       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
12954         ;
12955       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
12956         use_custom_mac = 1;
12957       else if (unformat (i, "server"))
12958         is_server = 1;
12959       else if (unformat (i, "disable_mrg_rxbuf"))
12960         disable_mrg_rxbuf = 1;
12961       else if (unformat (i, "disable_indirect_desc"))
12962         disable_indirect_desc = 1;
12963       else if (unformat (i, "gso"))
12964         enable_gso = 1;
12965       else if (unformat (i, "tag %s", &tag))
12966         ;
12967       else
12968         break;
12969     }
12970
12971   if (file_name_set == 0)
12972     {
12973       errmsg ("missing socket file name");
12974       return -99;
12975     }
12976
12977   if (vec_len (file_name) > 255)
12978     {
12979       errmsg ("socket file name too long");
12980       return -99;
12981     }
12982   vec_add1 (file_name, 0);
12983
12984   M (CREATE_VHOST_USER_IF, mp);
12985
12986   mp->is_server = is_server;
12987   mp->disable_mrg_rxbuf = disable_mrg_rxbuf;
12988   mp->disable_indirect_desc = disable_indirect_desc;
12989   mp->enable_gso = enable_gso;
12990   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
12991   vec_free (file_name);
12992   if (custom_dev_instance != ~0)
12993     {
12994       mp->renumber = 1;
12995       mp->custom_dev_instance = ntohl (custom_dev_instance);
12996     }
12997
12998   mp->use_custom_mac = use_custom_mac;
12999   clib_memcpy (mp->mac_address, hwaddr, 6);
13000   if (tag)
13001     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
13002   vec_free (tag);
13003
13004   S (mp);
13005   W (ret);
13006   return ret;
13007 }
13008
13009 static int
13010 api_modify_vhost_user_if (vat_main_t * vam)
13011 {
13012   unformat_input_t *i = vam->input;
13013   vl_api_modify_vhost_user_if_t *mp;
13014   u8 *file_name;
13015   u8 is_server = 0;
13016   u8 file_name_set = 0;
13017   u32 custom_dev_instance = ~0;
13018   u8 sw_if_index_set = 0;
13019   u32 sw_if_index = (u32) ~ 0;
13020   u8 enable_gso = 0;
13021   int ret;
13022
13023   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13024     {
13025       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13026         sw_if_index_set = 1;
13027       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13028         sw_if_index_set = 1;
13029       else if (unformat (i, "socket %s", &file_name))
13030         {
13031           file_name_set = 1;
13032         }
13033       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
13034         ;
13035       else if (unformat (i, "server"))
13036         is_server = 1;
13037       else if (unformat (i, "gso"))
13038         enable_gso = 1;
13039       else
13040         break;
13041     }
13042
13043   if (sw_if_index_set == 0)
13044     {
13045       errmsg ("missing sw_if_index or interface name");
13046       return -99;
13047     }
13048
13049   if (file_name_set == 0)
13050     {
13051       errmsg ("missing socket file name");
13052       return -99;
13053     }
13054
13055   if (vec_len (file_name) > 255)
13056     {
13057       errmsg ("socket file name too long");
13058       return -99;
13059     }
13060   vec_add1 (file_name, 0);
13061
13062   M (MODIFY_VHOST_USER_IF, mp);
13063
13064   mp->sw_if_index = ntohl (sw_if_index);
13065   mp->is_server = is_server;
13066   mp->enable_gso = enable_gso;
13067   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
13068   vec_free (file_name);
13069   if (custom_dev_instance != ~0)
13070     {
13071       mp->renumber = 1;
13072       mp->custom_dev_instance = ntohl (custom_dev_instance);
13073     }
13074
13075   S (mp);
13076   W (ret);
13077   return ret;
13078 }
13079
13080 static int
13081 api_delete_vhost_user_if (vat_main_t * vam)
13082 {
13083   unformat_input_t *i = vam->input;
13084   vl_api_delete_vhost_user_if_t *mp;
13085   u32 sw_if_index = ~0;
13086   u8 sw_if_index_set = 0;
13087   int ret;
13088
13089   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13090     {
13091       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13092         sw_if_index_set = 1;
13093       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13094         sw_if_index_set = 1;
13095       else
13096         break;
13097     }
13098
13099   if (sw_if_index_set == 0)
13100     {
13101       errmsg ("missing sw_if_index or interface name");
13102       return -99;
13103     }
13104
13105
13106   M (DELETE_VHOST_USER_IF, mp);
13107
13108   mp->sw_if_index = ntohl (sw_if_index);
13109
13110   S (mp);
13111   W (ret);
13112   return ret;
13113 }
13114
13115 static void vl_api_sw_interface_vhost_user_details_t_handler
13116   (vl_api_sw_interface_vhost_user_details_t * mp)
13117 {
13118   vat_main_t *vam = &vat_main;
13119
13120   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s",
13121          (char *) mp->interface_name,
13122          ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
13123          clib_net_to_host_u64 (mp->features), mp->is_server,
13124          ntohl (mp->num_regions), (char *) mp->sock_filename);
13125   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
13126 }
13127
13128 static void vl_api_sw_interface_vhost_user_details_t_handler_json
13129   (vl_api_sw_interface_vhost_user_details_t * mp)
13130 {
13131   vat_main_t *vam = &vat_main;
13132   vat_json_node_t *node = NULL;
13133
13134   if (VAT_JSON_ARRAY != vam->json_tree.type)
13135     {
13136       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13137       vat_json_init_array (&vam->json_tree);
13138     }
13139   node = vat_json_array_add (&vam->json_tree);
13140
13141   vat_json_init_object (node);
13142   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13143   vat_json_object_add_string_copy (node, "interface_name",
13144                                    mp->interface_name);
13145   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
13146                             ntohl (mp->virtio_net_hdr_sz));
13147   vat_json_object_add_uint (node, "features",
13148                             clib_net_to_host_u64 (mp->features));
13149   vat_json_object_add_uint (node, "is_server", mp->is_server);
13150   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
13151   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
13152   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
13153 }
13154
13155 static int
13156 api_sw_interface_vhost_user_dump (vat_main_t * vam)
13157 {
13158   vl_api_sw_interface_vhost_user_dump_t *mp;
13159   vl_api_control_ping_t *mp_ping;
13160   int ret;
13161   print (vam->ofp,
13162          "Interface name            idx hdr_sz features server regions filename");
13163
13164   /* Get list of vhost-user interfaces */
13165   M (SW_INTERFACE_VHOST_USER_DUMP, mp);
13166   S (mp);
13167
13168   /* Use a control ping for synchronization */
13169   MPING (CONTROL_PING, mp_ping);
13170   S (mp_ping);
13171
13172   W (ret);
13173   return ret;
13174 }
13175
13176 static int
13177 api_show_version (vat_main_t * vam)
13178 {
13179   vl_api_show_version_t *mp;
13180   int ret;
13181
13182   M (SHOW_VERSION, mp);
13183
13184   S (mp);
13185   W (ret);
13186   return ret;
13187 }
13188
13189
13190 static int
13191 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
13192 {
13193   unformat_input_t *line_input = vam->input;
13194   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
13195   ip4_address_t local4, remote4;
13196   ip6_address_t local6, remote6;
13197   u8 is_add = 1;
13198   u8 ipv4_set = 0, ipv6_set = 0;
13199   u8 local_set = 0;
13200   u8 remote_set = 0;
13201   u8 grp_set = 0;
13202   u32 mcast_sw_if_index = ~0;
13203   u32 encap_vrf_id = 0;
13204   u32 decap_vrf_id = 0;
13205   u8 protocol = ~0;
13206   u32 vni;
13207   u8 vni_set = 0;
13208   int ret;
13209
13210   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
13211   clib_memset (&local4, 0, sizeof local4);
13212   clib_memset (&remote4, 0, sizeof remote4);
13213   clib_memset (&local6, 0, sizeof local6);
13214   clib_memset (&remote6, 0, sizeof remote6);
13215
13216   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13217     {
13218       if (unformat (line_input, "del"))
13219         is_add = 0;
13220       else if (unformat (line_input, "local %U",
13221                          unformat_ip4_address, &local4))
13222         {
13223           local_set = 1;
13224           ipv4_set = 1;
13225         }
13226       else if (unformat (line_input, "remote %U",
13227                          unformat_ip4_address, &remote4))
13228         {
13229           remote_set = 1;
13230           ipv4_set = 1;
13231         }
13232       else if (unformat (line_input, "local %U",
13233                          unformat_ip6_address, &local6))
13234         {
13235           local_set = 1;
13236           ipv6_set = 1;
13237         }
13238       else if (unformat (line_input, "remote %U",
13239                          unformat_ip6_address, &remote6))
13240         {
13241           remote_set = 1;
13242           ipv6_set = 1;
13243         }
13244       else if (unformat (line_input, "group %U %U",
13245                          unformat_ip4_address, &remote4,
13246                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13247         {
13248           grp_set = remote_set = 1;
13249           ipv4_set = 1;
13250         }
13251       else if (unformat (line_input, "group %U",
13252                          unformat_ip4_address, &remote4))
13253         {
13254           grp_set = remote_set = 1;
13255           ipv4_set = 1;
13256         }
13257       else if (unformat (line_input, "group %U %U",
13258                          unformat_ip6_address, &remote6,
13259                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13260         {
13261           grp_set = remote_set = 1;
13262           ipv6_set = 1;
13263         }
13264       else if (unformat (line_input, "group %U",
13265                          unformat_ip6_address, &remote6))
13266         {
13267           grp_set = remote_set = 1;
13268           ipv6_set = 1;
13269         }
13270       else
13271         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
13272         ;
13273       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
13274         ;
13275       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
13276         ;
13277       else if (unformat (line_input, "vni %d", &vni))
13278         vni_set = 1;
13279       else if (unformat (line_input, "next-ip4"))
13280         protocol = 1;
13281       else if (unformat (line_input, "next-ip6"))
13282         protocol = 2;
13283       else if (unformat (line_input, "next-ethernet"))
13284         protocol = 3;
13285       else if (unformat (line_input, "next-nsh"))
13286         protocol = 4;
13287       else
13288         {
13289           errmsg ("parse error '%U'", format_unformat_error, line_input);
13290           return -99;
13291         }
13292     }
13293
13294   if (local_set == 0)
13295     {
13296       errmsg ("tunnel local address not specified");
13297       return -99;
13298     }
13299   if (remote_set == 0)
13300     {
13301       errmsg ("tunnel remote address not specified");
13302       return -99;
13303     }
13304   if (grp_set && mcast_sw_if_index == ~0)
13305     {
13306       errmsg ("tunnel nonexistent multicast device");
13307       return -99;
13308     }
13309   if (ipv4_set && ipv6_set)
13310     {
13311       errmsg ("both IPv4 and IPv6 addresses specified");
13312       return -99;
13313     }
13314
13315   if (vni_set == 0)
13316     {
13317       errmsg ("vni not specified");
13318       return -99;
13319     }
13320
13321   M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
13322
13323
13324   if (ipv6_set)
13325     {
13326       clib_memcpy (&mp->local, &local6, sizeof (local6));
13327       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
13328     }
13329   else
13330     {
13331       clib_memcpy (&mp->local, &local4, sizeof (local4));
13332       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
13333     }
13334
13335   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
13336   mp->encap_vrf_id = ntohl (encap_vrf_id);
13337   mp->decap_vrf_id = ntohl (decap_vrf_id);
13338   mp->protocol = protocol;
13339   mp->vni = ntohl (vni);
13340   mp->is_add = is_add;
13341   mp->is_ipv6 = ipv6_set;
13342
13343   S (mp);
13344   W (ret);
13345   return ret;
13346 }
13347
13348 static void vl_api_vxlan_gpe_tunnel_details_t_handler
13349   (vl_api_vxlan_gpe_tunnel_details_t * mp)
13350 {
13351   vat_main_t *vam = &vat_main;
13352   ip46_address_t local = to_ip46 (mp->is_ipv6, mp->local);
13353   ip46_address_t remote = to_ip46 (mp->is_ipv6, mp->remote);
13354
13355   print (vam->ofp, "%11d%24U%24U%13d%12d%19d%14d%14d",
13356          ntohl (mp->sw_if_index),
13357          format_ip46_address, &local, IP46_TYPE_ANY,
13358          format_ip46_address, &remote, IP46_TYPE_ANY,
13359          ntohl (mp->vni), mp->protocol,
13360          ntohl (mp->mcast_sw_if_index),
13361          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
13362 }
13363
13364
13365 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
13366   (vl_api_vxlan_gpe_tunnel_details_t * mp)
13367 {
13368   vat_main_t *vam = &vat_main;
13369   vat_json_node_t *node = NULL;
13370   struct in_addr ip4;
13371   struct in6_addr ip6;
13372
13373   if (VAT_JSON_ARRAY != vam->json_tree.type)
13374     {
13375       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13376       vat_json_init_array (&vam->json_tree);
13377     }
13378   node = vat_json_array_add (&vam->json_tree);
13379
13380   vat_json_init_object (node);
13381   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13382   if (mp->is_ipv6)
13383     {
13384       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
13385       vat_json_object_add_ip6 (node, "local", ip6);
13386       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
13387       vat_json_object_add_ip6 (node, "remote", ip6);
13388     }
13389   else
13390     {
13391       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
13392       vat_json_object_add_ip4 (node, "local", ip4);
13393       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
13394       vat_json_object_add_ip4 (node, "remote", ip4);
13395     }
13396   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
13397   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
13398   vat_json_object_add_uint (node, "mcast_sw_if_index",
13399                             ntohl (mp->mcast_sw_if_index));
13400   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
13401   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
13402   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
13403 }
13404
13405 static int
13406 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
13407 {
13408   unformat_input_t *i = vam->input;
13409   vl_api_vxlan_gpe_tunnel_dump_t *mp;
13410   vl_api_control_ping_t *mp_ping;
13411   u32 sw_if_index;
13412   u8 sw_if_index_set = 0;
13413   int ret;
13414
13415   /* Parse args required to build the message */
13416   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13417     {
13418       if (unformat (i, "sw_if_index %d", &sw_if_index))
13419         sw_if_index_set = 1;
13420       else
13421         break;
13422     }
13423
13424   if (sw_if_index_set == 0)
13425     {
13426       sw_if_index = ~0;
13427     }
13428
13429   if (!vam->json_output)
13430     {
13431       print (vam->ofp, "%11s%24s%24s%13s%15s%19s%14s%14s",
13432              "sw_if_index", "local", "remote", "vni",
13433              "protocol", "mcast_sw_if_index", "encap_vrf_id", "decap_vrf_id");
13434     }
13435
13436   /* Get list of vxlan-tunnel interfaces */
13437   M (VXLAN_GPE_TUNNEL_DUMP, mp);
13438
13439   mp->sw_if_index = htonl (sw_if_index);
13440
13441   S (mp);
13442
13443   /* Use a control ping for synchronization */
13444   MPING (CONTROL_PING, mp_ping);
13445   S (mp_ping);
13446
13447   W (ret);
13448   return ret;
13449 }
13450
13451 static void vl_api_l2_fib_table_details_t_handler
13452   (vl_api_l2_fib_table_details_t * mp)
13453 {
13454   vat_main_t *vam = &vat_main;
13455
13456   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
13457          "       %d       %d     %d",
13458          ntohl (mp->bd_id), format_ethernet_address, mp->mac,
13459          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
13460          mp->bvi_mac);
13461 }
13462
13463 static void vl_api_l2_fib_table_details_t_handler_json
13464   (vl_api_l2_fib_table_details_t * mp)
13465 {
13466   vat_main_t *vam = &vat_main;
13467   vat_json_node_t *node = NULL;
13468
13469   if (VAT_JSON_ARRAY != vam->json_tree.type)
13470     {
13471       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13472       vat_json_init_array (&vam->json_tree);
13473     }
13474   node = vat_json_array_add (&vam->json_tree);
13475
13476   vat_json_init_object (node);
13477   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
13478   vat_json_object_add_bytes (node, "mac", mp->mac, 6);
13479   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13480   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
13481   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
13482   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
13483 }
13484
13485 static int
13486 api_l2_fib_table_dump (vat_main_t * vam)
13487 {
13488   unformat_input_t *i = vam->input;
13489   vl_api_l2_fib_table_dump_t *mp;
13490   vl_api_control_ping_t *mp_ping;
13491   u32 bd_id;
13492   u8 bd_id_set = 0;
13493   int ret;
13494
13495   /* Parse args required to build the message */
13496   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13497     {
13498       if (unformat (i, "bd_id %d", &bd_id))
13499         bd_id_set = 1;
13500       else
13501         break;
13502     }
13503
13504   if (bd_id_set == 0)
13505     {
13506       errmsg ("missing bridge domain");
13507       return -99;
13508     }
13509
13510   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
13511
13512   /* Get list of l2 fib entries */
13513   M (L2_FIB_TABLE_DUMP, mp);
13514
13515   mp->bd_id = ntohl (bd_id);
13516   S (mp);
13517
13518   /* Use a control ping for synchronization */
13519   MPING (CONTROL_PING, mp_ping);
13520   S (mp_ping);
13521
13522   W (ret);
13523   return ret;
13524 }
13525
13526
13527 static int
13528 api_interface_name_renumber (vat_main_t * vam)
13529 {
13530   unformat_input_t *line_input = vam->input;
13531   vl_api_interface_name_renumber_t *mp;
13532   u32 sw_if_index = ~0;
13533   u32 new_show_dev_instance = ~0;
13534   int ret;
13535
13536   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13537     {
13538       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
13539                     &sw_if_index))
13540         ;
13541       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
13542         ;
13543       else if (unformat (line_input, "new_show_dev_instance %d",
13544                          &new_show_dev_instance))
13545         ;
13546       else
13547         break;
13548     }
13549
13550   if (sw_if_index == ~0)
13551     {
13552       errmsg ("missing interface name or sw_if_index");
13553       return -99;
13554     }
13555
13556   if (new_show_dev_instance == ~0)
13557     {
13558       errmsg ("missing new_show_dev_instance");
13559       return -99;
13560     }
13561
13562   M (INTERFACE_NAME_RENUMBER, mp);
13563
13564   mp->sw_if_index = ntohl (sw_if_index);
13565   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
13566
13567   S (mp);
13568   W (ret);
13569   return ret;
13570 }
13571
13572 static int
13573 api_ip_probe_neighbor (vat_main_t * vam)
13574 {
13575   unformat_input_t *i = vam->input;
13576   vl_api_ip_probe_neighbor_t *mp;
13577   vl_api_address_t dst_adr = { };
13578   u8 int_set = 0;
13579   u8 adr_set = 0;
13580   u32 sw_if_index;
13581   int ret;
13582
13583   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13584     {
13585       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13586         int_set = 1;
13587       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13588         int_set = 1;
13589       else if (unformat (i, "address %U", unformat_vl_api_address, &dst_adr))
13590         adr_set = 1;
13591       else
13592         break;
13593     }
13594
13595   if (int_set == 0)
13596     {
13597       errmsg ("missing interface");
13598       return -99;
13599     }
13600
13601   if (adr_set == 0)
13602     {
13603       errmsg ("missing addresses");
13604       return -99;
13605     }
13606
13607   M (IP_PROBE_NEIGHBOR, mp);
13608
13609   mp->sw_if_index = ntohl (sw_if_index);
13610   clib_memcpy (&mp->dst, &dst_adr, sizeof (dst_adr));
13611
13612   S (mp);
13613   W (ret);
13614   return ret;
13615 }
13616
13617 static int
13618 api_ip_scan_neighbor_enable_disable (vat_main_t * vam)
13619 {
13620   unformat_input_t *i = vam->input;
13621   vl_api_ip_scan_neighbor_enable_disable_t *mp;
13622   u8 mode = IP_SCAN_V46_NEIGHBORS;
13623   u32 interval = 0, time = 0, update = 0, delay = 0, stale = 0;
13624   int ret;
13625
13626   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13627     {
13628       if (unformat (i, "ip4"))
13629         mode = IP_SCAN_V4_NEIGHBORS;
13630       else if (unformat (i, "ip6"))
13631         mode = IP_SCAN_V6_NEIGHBORS;
13632       if (unformat (i, "both"))
13633         mode = IP_SCAN_V46_NEIGHBORS;
13634       else if (unformat (i, "disable"))
13635         mode = IP_SCAN_DISABLED;
13636       else if (unformat (i, "interval %d", &interval))
13637         ;
13638       else if (unformat (i, "max-time %d", &time))
13639         ;
13640       else if (unformat (i, "max-update %d", &update))
13641         ;
13642       else if (unformat (i, "delay %d", &delay))
13643         ;
13644       else if (unformat (i, "stale %d", &stale))
13645         ;
13646       else
13647         break;
13648     }
13649
13650   if (interval > 255)
13651     {
13652       errmsg ("interval cannot exceed 255 minutes.");
13653       return -99;
13654     }
13655   if (time > 255)
13656     {
13657       errmsg ("max-time cannot exceed 255 usec.");
13658       return -99;
13659     }
13660   if (update > 255)
13661     {
13662       errmsg ("max-update cannot exceed 255.");
13663       return -99;
13664     }
13665   if (delay > 255)
13666     {
13667       errmsg ("delay cannot exceed 255 msec.");
13668       return -99;
13669     }
13670   if (stale > 255)
13671     {
13672       errmsg ("stale cannot exceed 255 minutes.");
13673       return -99;
13674     }
13675
13676   M (IP_SCAN_NEIGHBOR_ENABLE_DISABLE, mp);
13677   mp->mode = mode;
13678   mp->scan_interval = interval;
13679   mp->max_proc_time = time;
13680   mp->max_update = update;
13681   mp->scan_int_delay = delay;
13682   mp->stale_threshold = stale;
13683
13684   S (mp);
13685   W (ret);
13686   return ret;
13687 }
13688
13689 static int
13690 api_want_ip4_arp_events (vat_main_t * vam)
13691 {
13692   unformat_input_t *line_input = vam->input;
13693   vl_api_want_ip4_arp_events_t *mp;
13694   ip4_address_t address;
13695   int address_set = 0;
13696   u32 enable_disable = 1;
13697   int ret;
13698
13699   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13700     {
13701       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
13702         address_set = 1;
13703       else if (unformat (line_input, "del"))
13704         enable_disable = 0;
13705       else
13706         break;
13707     }
13708
13709   if (address_set == 0)
13710     {
13711       errmsg ("missing addresses");
13712       return -99;
13713     }
13714
13715   M (WANT_IP4_ARP_EVENTS, mp);
13716   mp->enable_disable = enable_disable;
13717   mp->pid = htonl (getpid ());
13718   clib_memcpy (mp->ip, &address, sizeof (address));
13719
13720   S (mp);
13721   W (ret);
13722   return ret;
13723 }
13724
13725 static int
13726 api_want_ip6_nd_events (vat_main_t * vam)
13727 {
13728   unformat_input_t *line_input = vam->input;
13729   vl_api_want_ip6_nd_events_t *mp;
13730   vl_api_ip6_address_t address;
13731   int address_set = 0;
13732   u32 enable_disable = 1;
13733   int ret;
13734
13735   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13736     {
13737       if (unformat
13738           (line_input, "address %U", unformat_vl_api_ip6_address, &address))
13739         address_set = 1;
13740       else if (unformat (line_input, "del"))
13741         enable_disable = 0;
13742       else
13743         break;
13744     }
13745
13746   if (address_set == 0)
13747     {
13748       errmsg ("missing addresses");
13749       return -99;
13750     }
13751
13752   M (WANT_IP6_ND_EVENTS, mp);
13753   mp->enable_disable = enable_disable;
13754   mp->pid = htonl (getpid ());
13755   clib_memcpy (&mp->ip, &address, sizeof (address));
13756
13757   S (mp);
13758   W (ret);
13759   return ret;
13760 }
13761
13762 static int
13763 api_want_l2_macs_events (vat_main_t * vam)
13764 {
13765   unformat_input_t *line_input = vam->input;
13766   vl_api_want_l2_macs_events_t *mp;
13767   u8 enable_disable = 1;
13768   u32 scan_delay = 0;
13769   u32 max_macs_in_event = 0;
13770   u32 learn_limit = 0;
13771   int ret;
13772
13773   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13774     {
13775       if (unformat (line_input, "learn-limit %d", &learn_limit))
13776         ;
13777       else if (unformat (line_input, "scan-delay %d", &scan_delay))
13778         ;
13779       else if (unformat (line_input, "max-entries %d", &max_macs_in_event))
13780         ;
13781       else if (unformat (line_input, "disable"))
13782         enable_disable = 0;
13783       else
13784         break;
13785     }
13786
13787   M (WANT_L2_MACS_EVENTS, mp);
13788   mp->enable_disable = enable_disable;
13789   mp->pid = htonl (getpid ());
13790   mp->learn_limit = htonl (learn_limit);
13791   mp->scan_delay = (u8) scan_delay;
13792   mp->max_macs_in_event = (u8) (max_macs_in_event / 10);
13793   S (mp);
13794   W (ret);
13795   return ret;
13796 }
13797
13798 static int
13799 api_input_acl_set_interface (vat_main_t * vam)
13800 {
13801   unformat_input_t *i = vam->input;
13802   vl_api_input_acl_set_interface_t *mp;
13803   u32 sw_if_index;
13804   int sw_if_index_set;
13805   u32 ip4_table_index = ~0;
13806   u32 ip6_table_index = ~0;
13807   u32 l2_table_index = ~0;
13808   u8 is_add = 1;
13809   int ret;
13810
13811   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13812     {
13813       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13814         sw_if_index_set = 1;
13815       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13816         sw_if_index_set = 1;
13817       else if (unformat (i, "del"))
13818         is_add = 0;
13819       else if (unformat (i, "ip4-table %d", &ip4_table_index))
13820         ;
13821       else if (unformat (i, "ip6-table %d", &ip6_table_index))
13822         ;
13823       else if (unformat (i, "l2-table %d", &l2_table_index))
13824         ;
13825       else
13826         {
13827           clib_warning ("parse error '%U'", format_unformat_error, i);
13828           return -99;
13829         }
13830     }
13831
13832   if (sw_if_index_set == 0)
13833     {
13834       errmsg ("missing interface name or sw_if_index");
13835       return -99;
13836     }
13837
13838   M (INPUT_ACL_SET_INTERFACE, mp);
13839
13840   mp->sw_if_index = ntohl (sw_if_index);
13841   mp->ip4_table_index = ntohl (ip4_table_index);
13842   mp->ip6_table_index = ntohl (ip6_table_index);
13843   mp->l2_table_index = ntohl (l2_table_index);
13844   mp->is_add = is_add;
13845
13846   S (mp);
13847   W (ret);
13848   return ret;
13849 }
13850
13851 static int
13852 api_output_acl_set_interface (vat_main_t * vam)
13853 {
13854   unformat_input_t *i = vam->input;
13855   vl_api_output_acl_set_interface_t *mp;
13856   u32 sw_if_index;
13857   int sw_if_index_set;
13858   u32 ip4_table_index = ~0;
13859   u32 ip6_table_index = ~0;
13860   u32 l2_table_index = ~0;
13861   u8 is_add = 1;
13862   int ret;
13863
13864   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13865     {
13866       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13867         sw_if_index_set = 1;
13868       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13869         sw_if_index_set = 1;
13870       else if (unformat (i, "del"))
13871         is_add = 0;
13872       else if (unformat (i, "ip4-table %d", &ip4_table_index))
13873         ;
13874       else if (unformat (i, "ip6-table %d", &ip6_table_index))
13875         ;
13876       else if (unformat (i, "l2-table %d", &l2_table_index))
13877         ;
13878       else
13879         {
13880           clib_warning ("parse error '%U'", format_unformat_error, i);
13881           return -99;
13882         }
13883     }
13884
13885   if (sw_if_index_set == 0)
13886     {
13887       errmsg ("missing interface name or sw_if_index");
13888       return -99;
13889     }
13890
13891   M (OUTPUT_ACL_SET_INTERFACE, mp);
13892
13893   mp->sw_if_index = ntohl (sw_if_index);
13894   mp->ip4_table_index = ntohl (ip4_table_index);
13895   mp->ip6_table_index = ntohl (ip6_table_index);
13896   mp->l2_table_index = ntohl (l2_table_index);
13897   mp->is_add = is_add;
13898
13899   S (mp);
13900   W (ret);
13901   return ret;
13902 }
13903
13904 static int
13905 api_ip_address_dump (vat_main_t * vam)
13906 {
13907   unformat_input_t *i = vam->input;
13908   vl_api_ip_address_dump_t *mp;
13909   vl_api_control_ping_t *mp_ping;
13910   u32 sw_if_index = ~0;
13911   u8 sw_if_index_set = 0;
13912   u8 ipv4_set = 0;
13913   u8 ipv6_set = 0;
13914   int ret;
13915
13916   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13917     {
13918       if (unformat (i, "sw_if_index %d", &sw_if_index))
13919         sw_if_index_set = 1;
13920       else
13921         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13922         sw_if_index_set = 1;
13923       else if (unformat (i, "ipv4"))
13924         ipv4_set = 1;
13925       else if (unformat (i, "ipv6"))
13926         ipv6_set = 1;
13927       else
13928         break;
13929     }
13930
13931   if (ipv4_set && ipv6_set)
13932     {
13933       errmsg ("ipv4 and ipv6 flags cannot be both set");
13934       return -99;
13935     }
13936
13937   if ((!ipv4_set) && (!ipv6_set))
13938     {
13939       errmsg ("no ipv4 nor ipv6 flag set");
13940       return -99;
13941     }
13942
13943   if (sw_if_index_set == 0)
13944     {
13945       errmsg ("missing interface name or sw_if_index");
13946       return -99;
13947     }
13948
13949   vam->current_sw_if_index = sw_if_index;
13950   vam->is_ipv6 = ipv6_set;
13951
13952   M (IP_ADDRESS_DUMP, mp);
13953   mp->sw_if_index = ntohl (sw_if_index);
13954   mp->is_ipv6 = ipv6_set;
13955   S (mp);
13956
13957   /* Use a control ping for synchronization */
13958   MPING (CONTROL_PING, mp_ping);
13959   S (mp_ping);
13960
13961   W (ret);
13962   return ret;
13963 }
13964
13965 static int
13966 api_ip_dump (vat_main_t * vam)
13967 {
13968   vl_api_ip_dump_t *mp;
13969   vl_api_control_ping_t *mp_ping;
13970   unformat_input_t *in = vam->input;
13971   int ipv4_set = 0;
13972   int ipv6_set = 0;
13973   int is_ipv6;
13974   int i;
13975   int ret;
13976
13977   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
13978     {
13979       if (unformat (in, "ipv4"))
13980         ipv4_set = 1;
13981       else if (unformat (in, "ipv6"))
13982         ipv6_set = 1;
13983       else
13984         break;
13985     }
13986
13987   if (ipv4_set && ipv6_set)
13988     {
13989       errmsg ("ipv4 and ipv6 flags cannot be both set");
13990       return -99;
13991     }
13992
13993   if ((!ipv4_set) && (!ipv6_set))
13994     {
13995       errmsg ("no ipv4 nor ipv6 flag set");
13996       return -99;
13997     }
13998
13999   is_ipv6 = ipv6_set;
14000   vam->is_ipv6 = is_ipv6;
14001
14002   /* free old data */
14003   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
14004     {
14005       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
14006     }
14007   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
14008
14009   M (IP_DUMP, mp);
14010   mp->is_ipv6 = ipv6_set;
14011   S (mp);
14012
14013   /* Use a control ping for synchronization */
14014   MPING (CONTROL_PING, mp_ping);
14015   S (mp_ping);
14016
14017   W (ret);
14018   return ret;
14019 }
14020
14021 static int
14022 api_ipsec_spd_add_del (vat_main_t * vam)
14023 {
14024   unformat_input_t *i = vam->input;
14025   vl_api_ipsec_spd_add_del_t *mp;
14026   u32 spd_id = ~0;
14027   u8 is_add = 1;
14028   int ret;
14029
14030   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14031     {
14032       if (unformat (i, "spd_id %d", &spd_id))
14033         ;
14034       else if (unformat (i, "del"))
14035         is_add = 0;
14036       else
14037         {
14038           clib_warning ("parse error '%U'", format_unformat_error, i);
14039           return -99;
14040         }
14041     }
14042   if (spd_id == ~0)
14043     {
14044       errmsg ("spd_id must be set");
14045       return -99;
14046     }
14047
14048   M (IPSEC_SPD_ADD_DEL, mp);
14049
14050   mp->spd_id = ntohl (spd_id);
14051   mp->is_add = is_add;
14052
14053   S (mp);
14054   W (ret);
14055   return ret;
14056 }
14057
14058 static int
14059 api_ipsec_interface_add_del_spd (vat_main_t * vam)
14060 {
14061   unformat_input_t *i = vam->input;
14062   vl_api_ipsec_interface_add_del_spd_t *mp;
14063   u32 sw_if_index;
14064   u8 sw_if_index_set = 0;
14065   u32 spd_id = (u32) ~ 0;
14066   u8 is_add = 1;
14067   int ret;
14068
14069   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14070     {
14071       if (unformat (i, "del"))
14072         is_add = 0;
14073       else if (unformat (i, "spd_id %d", &spd_id))
14074         ;
14075       else
14076         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14077         sw_if_index_set = 1;
14078       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14079         sw_if_index_set = 1;
14080       else
14081         {
14082           clib_warning ("parse error '%U'", format_unformat_error, i);
14083           return -99;
14084         }
14085
14086     }
14087
14088   if (spd_id == (u32) ~ 0)
14089     {
14090       errmsg ("spd_id must be set");
14091       return -99;
14092     }
14093
14094   if (sw_if_index_set == 0)
14095     {
14096       errmsg ("missing interface name or sw_if_index");
14097       return -99;
14098     }
14099
14100   M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
14101
14102   mp->spd_id = ntohl (spd_id);
14103   mp->sw_if_index = ntohl (sw_if_index);
14104   mp->is_add = is_add;
14105
14106   S (mp);
14107   W (ret);
14108   return ret;
14109 }
14110
14111 static int
14112 api_ipsec_spd_entry_add_del (vat_main_t * vam)
14113 {
14114   unformat_input_t *i = vam->input;
14115   vl_api_ipsec_spd_entry_add_del_t *mp;
14116   u8 is_add = 1, is_outbound = 0;
14117   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
14118   i32 priority = 0;
14119   u32 rport_start = 0, rport_stop = (u32) ~ 0;
14120   u32 lport_start = 0, lport_stop = (u32) ~ 0;
14121   vl_api_address_t laddr_start = { }, laddr_stop =
14122   {
14123   }, raddr_start =
14124   {
14125   }, raddr_stop =
14126   {
14127   };
14128   int ret;
14129
14130   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14131     {
14132       if (unformat (i, "del"))
14133         is_add = 0;
14134       if (unformat (i, "outbound"))
14135         is_outbound = 1;
14136       if (unformat (i, "inbound"))
14137         is_outbound = 0;
14138       else if (unformat (i, "spd_id %d", &spd_id))
14139         ;
14140       else if (unformat (i, "sa_id %d", &sa_id))
14141         ;
14142       else if (unformat (i, "priority %d", &priority))
14143         ;
14144       else if (unformat (i, "protocol %d", &protocol))
14145         ;
14146       else if (unformat (i, "lport_start %d", &lport_start))
14147         ;
14148       else if (unformat (i, "lport_stop %d", &lport_stop))
14149         ;
14150       else if (unformat (i, "rport_start %d", &rport_start))
14151         ;
14152       else if (unformat (i, "rport_stop %d", &rport_stop))
14153         ;
14154       else if (unformat (i, "laddr_start %U",
14155                          unformat_vl_api_address, &laddr_start))
14156         ;
14157       else if (unformat (i, "laddr_stop %U", unformat_vl_api_address,
14158                          &laddr_stop))
14159         ;
14160       else if (unformat (i, "raddr_start %U", unformat_vl_api_address,
14161                          &raddr_start))
14162         ;
14163       else if (unformat (i, "raddr_stop %U", unformat_vl_api_address,
14164                          &raddr_stop))
14165         ;
14166       else
14167         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
14168         {
14169           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
14170             {
14171               clib_warning ("unsupported action: 'resolve'");
14172               return -99;
14173             }
14174         }
14175       else
14176         {
14177           clib_warning ("parse error '%U'", format_unformat_error, i);
14178           return -99;
14179         }
14180
14181     }
14182
14183   M (IPSEC_SPD_ENTRY_ADD_DEL, mp);
14184
14185   mp->is_add = is_add;
14186
14187   mp->entry.spd_id = ntohl (spd_id);
14188   mp->entry.priority = ntohl (priority);
14189   mp->entry.is_outbound = is_outbound;
14190
14191   clib_memcpy (&mp->entry.remote_address_start, &raddr_start,
14192                sizeof (vl_api_address_t));
14193   clib_memcpy (&mp->entry.remote_address_stop, &raddr_stop,
14194                sizeof (vl_api_address_t));
14195   clib_memcpy (&mp->entry.local_address_start, &laddr_start,
14196                sizeof (vl_api_address_t));
14197   clib_memcpy (&mp->entry.local_address_stop, &laddr_stop,
14198                sizeof (vl_api_address_t));
14199
14200   mp->entry.protocol = (u8) protocol;
14201   mp->entry.local_port_start = ntohs ((u16) lport_start);
14202   mp->entry.local_port_stop = ntohs ((u16) lport_stop);
14203   mp->entry.remote_port_start = ntohs ((u16) rport_start);
14204   mp->entry.remote_port_stop = ntohs ((u16) rport_stop);
14205   mp->entry.policy = (u8) policy;
14206   mp->entry.sa_id = ntohl (sa_id);
14207
14208   S (mp);
14209   W (ret);
14210   return ret;
14211 }
14212
14213 static int
14214 api_ipsec_sad_entry_add_del (vat_main_t * vam)
14215 {
14216   unformat_input_t *i = vam->input;
14217   vl_api_ipsec_sad_entry_add_del_t *mp;
14218   u32 sad_id = 0, spi = 0;
14219   u8 *ck = 0, *ik = 0;
14220   u8 is_add = 1;
14221
14222   vl_api_ipsec_crypto_alg_t crypto_alg = IPSEC_API_CRYPTO_ALG_NONE;
14223   vl_api_ipsec_integ_alg_t integ_alg = IPSEC_API_INTEG_ALG_NONE;
14224   vl_api_ipsec_sad_flags_t flags = IPSEC_API_SAD_FLAG_NONE;
14225   vl_api_ipsec_proto_t protocol = IPSEC_API_PROTO_AH;
14226   vl_api_address_t tun_src, tun_dst;
14227   int ret;
14228
14229   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14230     {
14231       if (unformat (i, "del"))
14232         is_add = 0;
14233       else if (unformat (i, "sad_id %d", &sad_id))
14234         ;
14235       else if (unformat (i, "spi %d", &spi))
14236         ;
14237       else if (unformat (i, "esp"))
14238         protocol = IPSEC_API_PROTO_ESP;
14239       else
14240         if (unformat (i, "tunnel_src %U", unformat_vl_api_address, &tun_src))
14241         {
14242           flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL;
14243           if (ADDRESS_IP6 == tun_src.af)
14244             flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL_V6;
14245         }
14246       else
14247         if (unformat (i, "tunnel_dst %U", unformat_vl_api_address, &tun_dst))
14248         {
14249           flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL;
14250           if (ADDRESS_IP6 == tun_src.af)
14251             flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL_V6;
14252         }
14253       else
14254         if (unformat (i, "crypto_alg %U",
14255                       unformat_ipsec_api_crypto_alg, &crypto_alg))
14256         ;
14257       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
14258         ;
14259       else if (unformat (i, "integ_alg %U",
14260                          unformat_ipsec_api_integ_alg, &integ_alg))
14261         ;
14262       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
14263         ;
14264       else
14265         {
14266           clib_warning ("parse error '%U'", format_unformat_error, i);
14267           return -99;
14268         }
14269
14270     }
14271
14272   M (IPSEC_SAD_ENTRY_ADD_DEL, mp);
14273
14274   mp->is_add = is_add;
14275   mp->entry.sad_id = ntohl (sad_id);
14276   mp->entry.protocol = protocol;
14277   mp->entry.spi = ntohl (spi);
14278   mp->entry.flags = flags;
14279
14280   mp->entry.crypto_algorithm = crypto_alg;
14281   mp->entry.integrity_algorithm = integ_alg;
14282   mp->entry.crypto_key.length = vec_len (ck);
14283   mp->entry.integrity_key.length = vec_len (ik);
14284
14285   if (mp->entry.crypto_key.length > sizeof (mp->entry.crypto_key.data))
14286     mp->entry.crypto_key.length = sizeof (mp->entry.crypto_key.data);
14287
14288   if (mp->entry.integrity_key.length > sizeof (mp->entry.integrity_key.data))
14289     mp->entry.integrity_key.length = sizeof (mp->entry.integrity_key.data);
14290
14291   if (ck)
14292     clib_memcpy (mp->entry.crypto_key.data, ck, mp->entry.crypto_key.length);
14293   if (ik)
14294     clib_memcpy (mp->entry.integrity_key.data, ik,
14295                  mp->entry.integrity_key.length);
14296
14297   if (flags & IPSEC_API_SAD_FLAG_IS_TUNNEL)
14298     {
14299       clib_memcpy (&mp->entry.tunnel_src, &tun_src,
14300                    sizeof (mp->entry.tunnel_src));
14301       clib_memcpy (&mp->entry.tunnel_dst, &tun_dst,
14302                    sizeof (mp->entry.tunnel_dst));
14303     }
14304
14305   S (mp);
14306   W (ret);
14307   return ret;
14308 }
14309
14310 static int
14311 api_ipsec_tunnel_if_add_del (vat_main_t * vam)
14312 {
14313   unformat_input_t *i = vam->input;
14314   vl_api_ipsec_tunnel_if_add_del_t *mp;
14315   u32 local_spi = 0, remote_spi = 0;
14316   u32 crypto_alg = 0, integ_alg = 0;
14317   u8 *lck = NULL, *rck = NULL;
14318   u8 *lik = NULL, *rik = NULL;
14319   vl_api_address_t local_ip = { 0 };
14320   vl_api_address_t remote_ip = { 0 };
14321   f64 before = 0;
14322   u8 is_add = 1;
14323   u8 esn = 0;
14324   u8 anti_replay = 0;
14325   u8 renumber = 0;
14326   u32 instance = ~0;
14327   u32 count = 1, jj;
14328   int ret = -1;
14329
14330   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14331     {
14332       if (unformat (i, "del"))
14333         is_add = 0;
14334       else if (unformat (i, "esn"))
14335         esn = 1;
14336       else if (unformat (i, "anti-replay"))
14337         anti_replay = 1;
14338       else if (unformat (i, "count %d", &count))
14339         ;
14340       else if (unformat (i, "local_spi %d", &local_spi))
14341         ;
14342       else if (unformat (i, "remote_spi %d", &remote_spi))
14343         ;
14344       else
14345         if (unformat (i, "local_ip %U", unformat_vl_api_address, &local_ip))
14346         ;
14347       else
14348         if (unformat (i, "remote_ip %U", unformat_vl_api_address, &remote_ip))
14349         ;
14350       else if (unformat (i, "local_crypto_key %U", unformat_hex_string, &lck))
14351         ;
14352       else
14353         if (unformat (i, "remote_crypto_key %U", unformat_hex_string, &rck))
14354         ;
14355       else if (unformat (i, "local_integ_key %U", unformat_hex_string, &lik))
14356         ;
14357       else if (unformat (i, "remote_integ_key %U", unformat_hex_string, &rik))
14358         ;
14359       else
14360         if (unformat
14361             (i, "crypto_alg %U", unformat_ipsec_api_crypto_alg, &crypto_alg))
14362         {
14363           if (crypto_alg >= IPSEC_CRYPTO_N_ALG)
14364             {
14365               errmsg ("unsupported crypto-alg: '%U'\n",
14366                       format_ipsec_crypto_alg, crypto_alg);
14367               return -99;
14368             }
14369         }
14370       else
14371         if (unformat
14372             (i, "integ_alg %U", unformat_ipsec_api_integ_alg, &integ_alg))
14373         {
14374           if (integ_alg >= IPSEC_INTEG_N_ALG)
14375             {
14376               errmsg ("unsupported integ-alg: '%U'\n",
14377                       format_ipsec_integ_alg, integ_alg);
14378               return -99;
14379             }
14380         }
14381       else if (unformat (i, "instance %u", &instance))
14382         renumber = 1;
14383       else
14384         {
14385           errmsg ("parse error '%U'\n", format_unformat_error, i);
14386           return -99;
14387         }
14388     }
14389
14390   if (count > 1)
14391     {
14392       /* Turn on async mode */
14393       vam->async_mode = 1;
14394       vam->async_errors = 0;
14395       before = vat_time_now (vam);
14396     }
14397
14398   for (jj = 0; jj < count; jj++)
14399     {
14400       M (IPSEC_TUNNEL_IF_ADD_DEL, mp);
14401
14402       mp->is_add = is_add;
14403       mp->esn = esn;
14404       mp->anti_replay = anti_replay;
14405
14406       if (jj > 0)
14407         increment_address (&remote_ip);
14408
14409       clib_memcpy (&mp->local_ip, &local_ip, sizeof (local_ip));
14410       clib_memcpy (&mp->remote_ip, &remote_ip, sizeof (remote_ip));
14411
14412       mp->local_spi = htonl (local_spi + jj);
14413       mp->remote_spi = htonl (remote_spi + jj);
14414       mp->crypto_alg = (u8) crypto_alg;
14415
14416       mp->local_crypto_key_len = 0;
14417       if (lck)
14418         {
14419           mp->local_crypto_key_len = vec_len (lck);
14420           if (mp->local_crypto_key_len > sizeof (mp->local_crypto_key))
14421             mp->local_crypto_key_len = sizeof (mp->local_crypto_key);
14422           clib_memcpy (mp->local_crypto_key, lck, mp->local_crypto_key_len);
14423         }
14424
14425       mp->remote_crypto_key_len = 0;
14426       if (rck)
14427         {
14428           mp->remote_crypto_key_len = vec_len (rck);
14429           if (mp->remote_crypto_key_len > sizeof (mp->remote_crypto_key))
14430             mp->remote_crypto_key_len = sizeof (mp->remote_crypto_key);
14431           clib_memcpy (mp->remote_crypto_key, rck, mp->remote_crypto_key_len);
14432         }
14433
14434       mp->integ_alg = (u8) integ_alg;
14435
14436       mp->local_integ_key_len = 0;
14437       if (lik)
14438         {
14439           mp->local_integ_key_len = vec_len (lik);
14440           if (mp->local_integ_key_len > sizeof (mp->local_integ_key))
14441             mp->local_integ_key_len = sizeof (mp->local_integ_key);
14442           clib_memcpy (mp->local_integ_key, lik, mp->local_integ_key_len);
14443         }
14444
14445       mp->remote_integ_key_len = 0;
14446       if (rik)
14447         {
14448           mp->remote_integ_key_len = vec_len (rik);
14449           if (mp->remote_integ_key_len > sizeof (mp->remote_integ_key))
14450             mp->remote_integ_key_len = sizeof (mp->remote_integ_key);
14451           clib_memcpy (mp->remote_integ_key, rik, mp->remote_integ_key_len);
14452         }
14453
14454       if (renumber)
14455         {
14456           mp->renumber = renumber;
14457           mp->show_instance = ntohl (instance);
14458         }
14459       S (mp);
14460     }
14461
14462   /* When testing multiple add/del ops, use a control-ping to sync */
14463   if (count > 1)
14464     {
14465       vl_api_control_ping_t *mp_ping;
14466       f64 after;
14467       f64 timeout;
14468
14469       /* Shut off async mode */
14470       vam->async_mode = 0;
14471
14472       MPING (CONTROL_PING, mp_ping);
14473       S (mp_ping);
14474
14475       timeout = vat_time_now (vam) + 1.0;
14476       while (vat_time_now (vam) < timeout)
14477         if (vam->result_ready == 1)
14478           goto out;
14479       vam->retval = -99;
14480
14481     out:
14482       if (vam->retval == -99)
14483         errmsg ("timeout");
14484
14485       if (vam->async_errors > 0)
14486         {
14487           errmsg ("%d asynchronous errors", vam->async_errors);
14488           vam->retval = -98;
14489         }
14490       vam->async_errors = 0;
14491       after = vat_time_now (vam);
14492
14493       /* slim chance, but we might have eaten SIGTERM on the first iteration */
14494       if (jj > 0)
14495         count = jj;
14496
14497       print (vam->ofp, "%d tunnels in %.6f secs, %.2f tunnels/sec",
14498              count, after - before, count / (after - before));
14499     }
14500   else
14501     {
14502       /* Wait for a reply... */
14503       W (ret);
14504       return ret;
14505     }
14506
14507   return ret;
14508 }
14509
14510 static void
14511 vl_api_ipsec_sa_details_t_handler (vl_api_ipsec_sa_details_t * mp)
14512 {
14513   vat_main_t *vam = &vat_main;
14514
14515   print (vam->ofp, "sa_id %u sw_if_index %u spi %u proto %u crypto_alg %u "
14516          "crypto_key %U integ_alg %u integ_key %U flags %x "
14517          "tunnel_src_addr %U tunnel_dst_addr %U "
14518          "salt %u seq_outbound %lu last_seq_inbound %lu "
14519          "replay_window %lu\n",
14520          ntohl (mp->entry.sad_id),
14521          ntohl (mp->sw_if_index),
14522          ntohl (mp->entry.spi),
14523          ntohl (mp->entry.protocol),
14524          ntohl (mp->entry.crypto_algorithm),
14525          format_hex_bytes, mp->entry.crypto_key.data,
14526          mp->entry.crypto_key.length, ntohl (mp->entry.integrity_algorithm),
14527          format_hex_bytes, mp->entry.integrity_key.data,
14528          mp->entry.integrity_key.length, ntohl (mp->entry.flags),
14529          format_vl_api_address, &mp->entry.tunnel_src, format_vl_api_address,
14530          &mp->entry.tunnel_dst, ntohl (mp->salt),
14531          clib_net_to_host_u64 (mp->seq_outbound),
14532          clib_net_to_host_u64 (mp->last_seq_inbound),
14533          clib_net_to_host_u64 (mp->replay_window));
14534 }
14535
14536 #define vl_api_ipsec_sa_details_t_endian vl_noop_handler
14537 #define vl_api_ipsec_sa_details_t_print vl_noop_handler
14538
14539 static void vl_api_ipsec_sa_details_t_handler_json
14540   (vl_api_ipsec_sa_details_t * mp)
14541 {
14542   vat_main_t *vam = &vat_main;
14543   vat_json_node_t *node = NULL;
14544   vl_api_ipsec_sad_flags_t flags;
14545
14546   if (VAT_JSON_ARRAY != vam->json_tree.type)
14547     {
14548       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14549       vat_json_init_array (&vam->json_tree);
14550     }
14551   node = vat_json_array_add (&vam->json_tree);
14552
14553   vat_json_init_object (node);
14554   vat_json_object_add_uint (node, "sa_id", ntohl (mp->entry.sad_id));
14555   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
14556   vat_json_object_add_uint (node, "spi", ntohl (mp->entry.spi));
14557   vat_json_object_add_uint (node, "proto", ntohl (mp->entry.protocol));
14558   vat_json_object_add_uint (node, "crypto_alg",
14559                             ntohl (mp->entry.crypto_algorithm));
14560   vat_json_object_add_uint (node, "integ_alg",
14561                             ntohl (mp->entry.integrity_algorithm));
14562   flags = ntohl (mp->entry.flags);
14563   vat_json_object_add_uint (node, "use_esn",
14564                             ! !(flags & IPSEC_API_SAD_FLAG_USE_ESN));
14565   vat_json_object_add_uint (node, "use_anti_replay",
14566                             ! !(flags & IPSEC_API_SAD_FLAG_USE_ANTI_REPLAY));
14567   vat_json_object_add_uint (node, "is_tunnel",
14568                             ! !(flags & IPSEC_API_SAD_FLAG_IS_TUNNEL));
14569   vat_json_object_add_uint (node, "is_tunnel_ip6",
14570                             ! !(flags & IPSEC_API_SAD_FLAG_IS_TUNNEL_V6));
14571   vat_json_object_add_uint (node, "udp_encap",
14572                             ! !(flags & IPSEC_API_SAD_FLAG_UDP_ENCAP));
14573   vat_json_object_add_bytes (node, "crypto_key", mp->entry.crypto_key.data,
14574                              mp->entry.crypto_key.length);
14575   vat_json_object_add_bytes (node, "integ_key", mp->entry.integrity_key.data,
14576                              mp->entry.integrity_key.length);
14577   vat_json_object_add_address (node, "src", &mp->entry.tunnel_src);
14578   vat_json_object_add_address (node, "dst", &mp->entry.tunnel_dst);
14579   vat_json_object_add_uint (node, "replay_window",
14580                             clib_net_to_host_u64 (mp->replay_window));
14581 }
14582
14583 static int
14584 api_ipsec_sa_dump (vat_main_t * vam)
14585 {
14586   unformat_input_t *i = vam->input;
14587   vl_api_ipsec_sa_dump_t *mp;
14588   vl_api_control_ping_t *mp_ping;
14589   u32 sa_id = ~0;
14590   int ret;
14591
14592   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14593     {
14594       if (unformat (i, "sa_id %d", &sa_id))
14595         ;
14596       else
14597         {
14598           clib_warning ("parse error '%U'", format_unformat_error, i);
14599           return -99;
14600         }
14601     }
14602
14603   M (IPSEC_SA_DUMP, mp);
14604
14605   mp->sa_id = ntohl (sa_id);
14606
14607   S (mp);
14608
14609   /* Use a control ping for synchronization */
14610   M (CONTROL_PING, mp_ping);
14611   S (mp_ping);
14612
14613   W (ret);
14614   return ret;
14615 }
14616
14617 static int
14618 api_ipsec_tunnel_if_set_sa (vat_main_t * vam)
14619 {
14620   unformat_input_t *i = vam->input;
14621   vl_api_ipsec_tunnel_if_set_sa_t *mp;
14622   u32 sw_if_index = ~0;
14623   u32 sa_id = ~0;
14624   u8 is_outbound = (u8) ~ 0;
14625   int ret;
14626
14627   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14628     {
14629       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14630         ;
14631       else if (unformat (i, "sa_id %d", &sa_id))
14632         ;
14633       else if (unformat (i, "outbound"))
14634         is_outbound = 1;
14635       else if (unformat (i, "inbound"))
14636         is_outbound = 0;
14637       else
14638         {
14639           clib_warning ("parse error '%U'", format_unformat_error, i);
14640           return -99;
14641         }
14642     }
14643
14644   if (sw_if_index == ~0)
14645     {
14646       errmsg ("interface must be specified");
14647       return -99;
14648     }
14649
14650   if (sa_id == ~0)
14651     {
14652       errmsg ("SA ID must be specified");
14653       return -99;
14654     }
14655
14656   M (IPSEC_TUNNEL_IF_SET_SA, mp);
14657
14658   mp->sw_if_index = htonl (sw_if_index);
14659   mp->sa_id = htonl (sa_id);
14660   mp->is_outbound = is_outbound;
14661
14662   S (mp);
14663   W (ret);
14664
14665   return ret;
14666 }
14667
14668 static int
14669 api_get_first_msg_id (vat_main_t * vam)
14670 {
14671   vl_api_get_first_msg_id_t *mp;
14672   unformat_input_t *i = vam->input;
14673   u8 *name;
14674   u8 name_set = 0;
14675   int ret;
14676
14677   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14678     {
14679       if (unformat (i, "client %s", &name))
14680         name_set = 1;
14681       else
14682         break;
14683     }
14684
14685   if (name_set == 0)
14686     {
14687       errmsg ("missing client name");
14688       return -99;
14689     }
14690   vec_add1 (name, 0);
14691
14692   if (vec_len (name) > 63)
14693     {
14694       errmsg ("client name too long");
14695       return -99;
14696     }
14697
14698   M (GET_FIRST_MSG_ID, mp);
14699   clib_memcpy (mp->name, name, vec_len (name));
14700   S (mp);
14701   W (ret);
14702   return ret;
14703 }
14704
14705 static int
14706 api_cop_interface_enable_disable (vat_main_t * vam)
14707 {
14708   unformat_input_t *line_input = vam->input;
14709   vl_api_cop_interface_enable_disable_t *mp;
14710   u32 sw_if_index = ~0;
14711   u8 enable_disable = 1;
14712   int ret;
14713
14714   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14715     {
14716       if (unformat (line_input, "disable"))
14717         enable_disable = 0;
14718       if (unformat (line_input, "enable"))
14719         enable_disable = 1;
14720       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
14721                          vam, &sw_if_index))
14722         ;
14723       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
14724         ;
14725       else
14726         break;
14727     }
14728
14729   if (sw_if_index == ~0)
14730     {
14731       errmsg ("missing interface name or sw_if_index");
14732       return -99;
14733     }
14734
14735   /* Construct the API message */
14736   M (COP_INTERFACE_ENABLE_DISABLE, mp);
14737   mp->sw_if_index = ntohl (sw_if_index);
14738   mp->enable_disable = enable_disable;
14739
14740   /* send it... */
14741   S (mp);
14742   /* Wait for the reply */
14743   W (ret);
14744   return ret;
14745 }
14746
14747 static int
14748 api_cop_whitelist_enable_disable (vat_main_t * vam)
14749 {
14750   unformat_input_t *line_input = vam->input;
14751   vl_api_cop_whitelist_enable_disable_t *mp;
14752   u32 sw_if_index = ~0;
14753   u8 ip4 = 0, ip6 = 0, default_cop = 0;
14754   u32 fib_id = 0;
14755   int ret;
14756
14757   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14758     {
14759       if (unformat (line_input, "ip4"))
14760         ip4 = 1;
14761       else if (unformat (line_input, "ip6"))
14762         ip6 = 1;
14763       else if (unformat (line_input, "default"))
14764         default_cop = 1;
14765       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
14766                          vam, &sw_if_index))
14767         ;
14768       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
14769         ;
14770       else if (unformat (line_input, "fib-id %d", &fib_id))
14771         ;
14772       else
14773         break;
14774     }
14775
14776   if (sw_if_index == ~0)
14777     {
14778       errmsg ("missing interface name or sw_if_index");
14779       return -99;
14780     }
14781
14782   /* Construct the API message */
14783   M (COP_WHITELIST_ENABLE_DISABLE, mp);
14784   mp->sw_if_index = ntohl (sw_if_index);
14785   mp->fib_id = ntohl (fib_id);
14786   mp->ip4 = ip4;
14787   mp->ip6 = ip6;
14788   mp->default_cop = default_cop;
14789
14790   /* send it... */
14791   S (mp);
14792   /* Wait for the reply */
14793   W (ret);
14794   return ret;
14795 }
14796
14797 static int
14798 api_get_node_graph (vat_main_t * vam)
14799 {
14800   vl_api_get_node_graph_t *mp;
14801   int ret;
14802
14803   M (GET_NODE_GRAPH, mp);
14804
14805   /* send it... */
14806   S (mp);
14807   /* Wait for the reply */
14808   W (ret);
14809   return ret;
14810 }
14811
14812 /* *INDENT-OFF* */
14813 /** Used for parsing LISP eids */
14814 typedef CLIB_PACKED(struct{
14815   u8 addr[16];   /**< eid address */
14816   u32 len;       /**< prefix length if IP */
14817   u8 type;      /**< type of eid */
14818 }) lisp_eid_vat_t;
14819 /* *INDENT-ON* */
14820
14821 static uword
14822 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
14823 {
14824   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
14825
14826   clib_memset (a, 0, sizeof (a[0]));
14827
14828   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
14829     {
14830       a->type = 0;              /* ipv4 type */
14831     }
14832   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
14833     {
14834       a->type = 1;              /* ipv6 type */
14835     }
14836   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
14837     {
14838       a->type = 2;              /* mac type */
14839     }
14840   else if (unformat (input, "%U", unformat_nsh_address, a->addr))
14841     {
14842       a->type = 3;              /* NSH type */
14843       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) a->addr;
14844       nsh->spi = clib_host_to_net_u32 (nsh->spi);
14845     }
14846   else
14847     {
14848       return 0;
14849     }
14850
14851   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
14852     {
14853       return 0;
14854     }
14855
14856   return 1;
14857 }
14858
14859 static int
14860 lisp_eid_size_vat (u8 type)
14861 {
14862   switch (type)
14863     {
14864     case 0:
14865       return 4;
14866     case 1:
14867       return 16;
14868     case 2:
14869       return 6;
14870     case 3:
14871       return 5;
14872     }
14873   return 0;
14874 }
14875
14876 static void
14877 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
14878 {
14879   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
14880 }
14881
14882 static int
14883 api_one_add_del_locator_set (vat_main_t * vam)
14884 {
14885   unformat_input_t *input = vam->input;
14886   vl_api_one_add_del_locator_set_t *mp;
14887   u8 is_add = 1;
14888   u8 *locator_set_name = NULL;
14889   u8 locator_set_name_set = 0;
14890   vl_api_local_locator_t locator, *locators = 0;
14891   u32 sw_if_index, priority, weight;
14892   u32 data_len = 0;
14893
14894   int ret;
14895   /* Parse args required to build the message */
14896   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14897     {
14898       if (unformat (input, "del"))
14899         {
14900           is_add = 0;
14901         }
14902       else if (unformat (input, "locator-set %s", &locator_set_name))
14903         {
14904           locator_set_name_set = 1;
14905         }
14906       else if (unformat (input, "sw_if_index %u p %u w %u",
14907                          &sw_if_index, &priority, &weight))
14908         {
14909           locator.sw_if_index = htonl (sw_if_index);
14910           locator.priority = priority;
14911           locator.weight = weight;
14912           vec_add1 (locators, locator);
14913         }
14914       else
14915         if (unformat
14916             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
14917              &sw_if_index, &priority, &weight))
14918         {
14919           locator.sw_if_index = htonl (sw_if_index);
14920           locator.priority = priority;
14921           locator.weight = weight;
14922           vec_add1 (locators, locator);
14923         }
14924       else
14925         break;
14926     }
14927
14928   if (locator_set_name_set == 0)
14929     {
14930       errmsg ("missing locator-set name");
14931       vec_free (locators);
14932       return -99;
14933     }
14934
14935   if (vec_len (locator_set_name) > 64)
14936     {
14937       errmsg ("locator-set name too long");
14938       vec_free (locator_set_name);
14939       vec_free (locators);
14940       return -99;
14941     }
14942   vec_add1 (locator_set_name, 0);
14943
14944   data_len = sizeof (vl_api_local_locator_t) * vec_len (locators);
14945
14946   /* Construct the API message */
14947   M2 (ONE_ADD_DEL_LOCATOR_SET, mp, data_len);
14948
14949   mp->is_add = is_add;
14950   clib_memcpy (mp->locator_set_name, locator_set_name,
14951                vec_len (locator_set_name));
14952   vec_free (locator_set_name);
14953
14954   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
14955   if (locators)
14956     clib_memcpy (mp->locators, locators, data_len);
14957   vec_free (locators);
14958
14959   /* send it... */
14960   S (mp);
14961
14962   /* Wait for a reply... */
14963   W (ret);
14964   return ret;
14965 }
14966
14967 #define api_lisp_add_del_locator_set api_one_add_del_locator_set
14968
14969 static int
14970 api_one_add_del_locator (vat_main_t * vam)
14971 {
14972   unformat_input_t *input = vam->input;
14973   vl_api_one_add_del_locator_t *mp;
14974   u32 tmp_if_index = ~0;
14975   u32 sw_if_index = ~0;
14976   u8 sw_if_index_set = 0;
14977   u8 sw_if_index_if_name_set = 0;
14978   u32 priority = ~0;
14979   u8 priority_set = 0;
14980   u32 weight = ~0;
14981   u8 weight_set = 0;
14982   u8 is_add = 1;
14983   u8 *locator_set_name = NULL;
14984   u8 locator_set_name_set = 0;
14985   int ret;
14986
14987   /* Parse args required to build the message */
14988   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14989     {
14990       if (unformat (input, "del"))
14991         {
14992           is_add = 0;
14993         }
14994       else if (unformat (input, "locator-set %s", &locator_set_name))
14995         {
14996           locator_set_name_set = 1;
14997         }
14998       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
14999                          &tmp_if_index))
15000         {
15001           sw_if_index_if_name_set = 1;
15002           sw_if_index = tmp_if_index;
15003         }
15004       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
15005         {
15006           sw_if_index_set = 1;
15007           sw_if_index = tmp_if_index;
15008         }
15009       else if (unformat (input, "p %d", &priority))
15010         {
15011           priority_set = 1;
15012         }
15013       else if (unformat (input, "w %d", &weight))
15014         {
15015           weight_set = 1;
15016         }
15017       else
15018         break;
15019     }
15020
15021   if (locator_set_name_set == 0)
15022     {
15023       errmsg ("missing locator-set name");
15024       return -99;
15025     }
15026
15027   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
15028     {
15029       errmsg ("missing sw_if_index");
15030       vec_free (locator_set_name);
15031       return -99;
15032     }
15033
15034   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
15035     {
15036       errmsg ("cannot use both params interface name and sw_if_index");
15037       vec_free (locator_set_name);
15038       return -99;
15039     }
15040
15041   if (priority_set == 0)
15042     {
15043       errmsg ("missing locator-set priority");
15044       vec_free (locator_set_name);
15045       return -99;
15046     }
15047
15048   if (weight_set == 0)
15049     {
15050       errmsg ("missing locator-set weight");
15051       vec_free (locator_set_name);
15052       return -99;
15053     }
15054
15055   if (vec_len (locator_set_name) > 64)
15056     {
15057       errmsg ("locator-set name too long");
15058       vec_free (locator_set_name);
15059       return -99;
15060     }
15061   vec_add1 (locator_set_name, 0);
15062
15063   /* Construct the API message */
15064   M (ONE_ADD_DEL_LOCATOR, mp);
15065
15066   mp->is_add = is_add;
15067   mp->sw_if_index = ntohl (sw_if_index);
15068   mp->priority = priority;
15069   mp->weight = weight;
15070   clib_memcpy (mp->locator_set_name, locator_set_name,
15071                vec_len (locator_set_name));
15072   vec_free (locator_set_name);
15073
15074   /* send it... */
15075   S (mp);
15076
15077   /* Wait for a reply... */
15078   W (ret);
15079   return ret;
15080 }
15081
15082 #define api_lisp_add_del_locator api_one_add_del_locator
15083
15084 uword
15085 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
15086 {
15087   u32 *key_id = va_arg (*args, u32 *);
15088   u8 *s = 0;
15089
15090   if (unformat (input, "%s", &s))
15091     {
15092       if (!strcmp ((char *) s, "sha1"))
15093         key_id[0] = HMAC_SHA_1_96;
15094       else if (!strcmp ((char *) s, "sha256"))
15095         key_id[0] = HMAC_SHA_256_128;
15096       else
15097         {
15098           clib_warning ("invalid key_id: '%s'", s);
15099           key_id[0] = HMAC_NO_KEY;
15100         }
15101     }
15102   else
15103     return 0;
15104
15105   vec_free (s);
15106   return 1;
15107 }
15108
15109 static int
15110 api_one_add_del_local_eid (vat_main_t * vam)
15111 {
15112   unformat_input_t *input = vam->input;
15113   vl_api_one_add_del_local_eid_t *mp;
15114   u8 is_add = 1;
15115   u8 eid_set = 0;
15116   lisp_eid_vat_t _eid, *eid = &_eid;
15117   u8 *locator_set_name = 0;
15118   u8 locator_set_name_set = 0;
15119   u32 vni = 0;
15120   u16 key_id = 0;
15121   u8 *key = 0;
15122   int ret;
15123
15124   /* Parse args required to build the message */
15125   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15126     {
15127       if (unformat (input, "del"))
15128         {
15129           is_add = 0;
15130         }
15131       else if (unformat (input, "vni %d", &vni))
15132         {
15133           ;
15134         }
15135       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
15136         {
15137           eid_set = 1;
15138         }
15139       else if (unformat (input, "locator-set %s", &locator_set_name))
15140         {
15141           locator_set_name_set = 1;
15142         }
15143       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
15144         ;
15145       else if (unformat (input, "secret-key %_%v%_", &key))
15146         ;
15147       else
15148         break;
15149     }
15150
15151   if (locator_set_name_set == 0)
15152     {
15153       errmsg ("missing locator-set name");
15154       return -99;
15155     }
15156
15157   if (0 == eid_set)
15158     {
15159       errmsg ("EID address not set!");
15160       vec_free (locator_set_name);
15161       return -99;
15162     }
15163
15164   if (key && (0 == key_id))
15165     {
15166       errmsg ("invalid key_id!");
15167       return -99;
15168     }
15169
15170   if (vec_len (key) > 64)
15171     {
15172       errmsg ("key too long");
15173       vec_free (key);
15174       return -99;
15175     }
15176
15177   if (vec_len (locator_set_name) > 64)
15178     {
15179       errmsg ("locator-set name too long");
15180       vec_free (locator_set_name);
15181       return -99;
15182     }
15183   vec_add1 (locator_set_name, 0);
15184
15185   /* Construct the API message */
15186   M (ONE_ADD_DEL_LOCAL_EID, mp);
15187
15188   mp->is_add = is_add;
15189   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
15190   mp->eid_type = eid->type;
15191   mp->prefix_len = eid->len;
15192   mp->vni = clib_host_to_net_u32 (vni);
15193   mp->key_id = clib_host_to_net_u16 (key_id);
15194   clib_memcpy (mp->locator_set_name, locator_set_name,
15195                vec_len (locator_set_name));
15196   clib_memcpy (mp->key, key, vec_len (key));
15197
15198   vec_free (locator_set_name);
15199   vec_free (key);
15200
15201   /* send it... */
15202   S (mp);
15203
15204   /* Wait for a reply... */
15205   W (ret);
15206   return ret;
15207 }
15208
15209 #define api_lisp_add_del_local_eid api_one_add_del_local_eid
15210
15211 static int
15212 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
15213 {
15214   u32 dp_table = 0, vni = 0;;
15215   unformat_input_t *input = vam->input;
15216   vl_api_gpe_add_del_fwd_entry_t *mp;
15217   u8 is_add = 1;
15218   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
15219   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
15220   u8 rmt_eid_set = 0, lcl_eid_set = 0;
15221   u32 action = ~0, w;
15222   ip4_address_t rmt_rloc4, lcl_rloc4;
15223   ip6_address_t rmt_rloc6, lcl_rloc6;
15224   vl_api_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
15225   int ret;
15226
15227   clib_memset (&rloc, 0, sizeof (rloc));
15228
15229   /* Parse args required to build the message */
15230   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15231     {
15232       if (unformat (input, "del"))
15233         is_add = 0;
15234       else if (unformat (input, "add"))
15235         is_add = 1;
15236       else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
15237         {
15238           rmt_eid_set = 1;
15239         }
15240       else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
15241         {
15242           lcl_eid_set = 1;
15243         }
15244       else if (unformat (input, "vrf %d", &dp_table))
15245         ;
15246       else if (unformat (input, "bd %d", &dp_table))
15247         ;
15248       else if (unformat (input, "vni %d", &vni))
15249         ;
15250       else if (unformat (input, "w %d", &w))
15251         {
15252           if (!curr_rloc)
15253             {
15254               errmsg ("No RLOC configured for setting priority/weight!");
15255               return -99;
15256             }
15257           curr_rloc->weight = w;
15258         }
15259       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
15260                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
15261         {
15262           rloc.is_ip4 = 1;
15263
15264           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
15265           rloc.weight = 0;
15266           vec_add1 (lcl_locs, rloc);
15267
15268           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
15269           vec_add1 (rmt_locs, rloc);
15270           /* weight saved in rmt loc */
15271           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
15272         }
15273       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
15274                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
15275         {
15276           rloc.is_ip4 = 0;
15277           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
15278           rloc.weight = 0;
15279           vec_add1 (lcl_locs, rloc);
15280
15281           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
15282           vec_add1 (rmt_locs, rloc);
15283           /* weight saved in rmt loc */
15284           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
15285         }
15286       else if (unformat (input, "action %d", &action))
15287         {
15288           ;
15289         }
15290       else
15291         {
15292           clib_warning ("parse error '%U'", format_unformat_error, input);
15293           return -99;
15294         }
15295     }
15296
15297   if (!rmt_eid_set)
15298     {
15299       errmsg ("remote eid addresses not set");
15300       return -99;
15301     }
15302
15303   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
15304     {
15305       errmsg ("eid types don't match");
15306       return -99;
15307     }
15308
15309   if (0 == rmt_locs && (u32) ~ 0 == action)
15310     {
15311       errmsg ("action not set for negative mapping");
15312       return -99;
15313     }
15314
15315   /* Construct the API message */
15316   M2 (GPE_ADD_DEL_FWD_ENTRY, mp,
15317       sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs) * 2);
15318
15319   mp->is_add = is_add;
15320   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
15321   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
15322   mp->eid_type = rmt_eid->type;
15323   mp->dp_table = clib_host_to_net_u32 (dp_table);
15324   mp->vni = clib_host_to_net_u32 (vni);
15325   mp->rmt_len = rmt_eid->len;
15326   mp->lcl_len = lcl_eid->len;
15327   mp->action = action;
15328
15329   if (0 != rmt_locs && 0 != lcl_locs)
15330     {
15331       mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
15332       clib_memcpy (mp->locs, lcl_locs,
15333                    (sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs)));
15334
15335       u32 offset = sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs);
15336       clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
15337                    (sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs)));
15338     }
15339   vec_free (lcl_locs);
15340   vec_free (rmt_locs);
15341
15342   /* send it... */
15343   S (mp);
15344
15345   /* Wait for a reply... */
15346   W (ret);
15347   return ret;
15348 }
15349
15350 static int
15351 api_one_add_del_map_server (vat_main_t * vam)
15352 {
15353   unformat_input_t *input = vam->input;
15354   vl_api_one_add_del_map_server_t *mp;
15355   u8 is_add = 1;
15356   u8 ipv4_set = 0;
15357   u8 ipv6_set = 0;
15358   ip4_address_t ipv4;
15359   ip6_address_t ipv6;
15360   int ret;
15361
15362   /* Parse args required to build the message */
15363   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15364     {
15365       if (unformat (input, "del"))
15366         {
15367           is_add = 0;
15368         }
15369       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
15370         {
15371           ipv4_set = 1;
15372         }
15373       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
15374         {
15375           ipv6_set = 1;
15376         }
15377       else
15378         break;
15379     }
15380
15381   if (ipv4_set && ipv6_set)
15382     {
15383       errmsg ("both eid v4 and v6 addresses set");
15384       return -99;
15385     }
15386
15387   if (!ipv4_set && !ipv6_set)
15388     {
15389       errmsg ("eid addresses not set");
15390       return -99;
15391     }
15392
15393   /* Construct the API message */
15394   M (ONE_ADD_DEL_MAP_SERVER, mp);
15395
15396   mp->is_add = is_add;
15397   if (ipv6_set)
15398     {
15399       mp->is_ipv6 = 1;
15400       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
15401     }
15402   else
15403     {
15404       mp->is_ipv6 = 0;
15405       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
15406     }
15407
15408   /* send it... */
15409   S (mp);
15410
15411   /* Wait for a reply... */
15412   W (ret);
15413   return ret;
15414 }
15415
15416 #define api_lisp_add_del_map_server api_one_add_del_map_server
15417
15418 static int
15419 api_one_add_del_map_resolver (vat_main_t * vam)
15420 {
15421   unformat_input_t *input = vam->input;
15422   vl_api_one_add_del_map_resolver_t *mp;
15423   u8 is_add = 1;
15424   u8 ipv4_set = 0;
15425   u8 ipv6_set = 0;
15426   ip4_address_t ipv4;
15427   ip6_address_t ipv6;
15428   int ret;
15429
15430   /* Parse args required to build the message */
15431   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15432     {
15433       if (unformat (input, "del"))
15434         {
15435           is_add = 0;
15436         }
15437       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
15438         {
15439           ipv4_set = 1;
15440         }
15441       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
15442         {
15443           ipv6_set = 1;
15444         }
15445       else
15446         break;
15447     }
15448
15449   if (ipv4_set && ipv6_set)
15450     {
15451       errmsg ("both eid v4 and v6 addresses set");
15452       return -99;
15453     }
15454
15455   if (!ipv4_set && !ipv6_set)
15456     {
15457       errmsg ("eid addresses not set");
15458       return -99;
15459     }
15460
15461   /* Construct the API message */
15462   M (ONE_ADD_DEL_MAP_RESOLVER, mp);
15463
15464   mp->is_add = is_add;
15465   if (ipv6_set)
15466     {
15467       mp->is_ipv6 = 1;
15468       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
15469     }
15470   else
15471     {
15472       mp->is_ipv6 = 0;
15473       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
15474     }
15475
15476   /* send it... */
15477   S (mp);
15478
15479   /* Wait for a reply... */
15480   W (ret);
15481   return ret;
15482 }
15483
15484 #define api_lisp_add_del_map_resolver api_one_add_del_map_resolver
15485
15486 static int
15487 api_lisp_gpe_enable_disable (vat_main_t * vam)
15488 {
15489   unformat_input_t *input = vam->input;
15490   vl_api_gpe_enable_disable_t *mp;
15491   u8 is_set = 0;
15492   u8 is_en = 1;
15493   int ret;
15494
15495   /* Parse args required to build the message */
15496   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15497     {
15498       if (unformat (input, "enable"))
15499         {
15500           is_set = 1;
15501           is_en = 1;
15502         }
15503       else if (unformat (input, "disable"))
15504         {
15505           is_set = 1;
15506           is_en = 0;
15507         }
15508       else
15509         break;
15510     }
15511
15512   if (is_set == 0)
15513     {
15514       errmsg ("Value not set");
15515       return -99;
15516     }
15517
15518   /* Construct the API message */
15519   M (GPE_ENABLE_DISABLE, mp);
15520
15521   mp->is_en = is_en;
15522
15523   /* send it... */
15524   S (mp);
15525
15526   /* Wait for a reply... */
15527   W (ret);
15528   return ret;
15529 }
15530
15531 static int
15532 api_one_rloc_probe_enable_disable (vat_main_t * vam)
15533 {
15534   unformat_input_t *input = vam->input;
15535   vl_api_one_rloc_probe_enable_disable_t *mp;
15536   u8 is_set = 0;
15537   u8 is_en = 0;
15538   int ret;
15539
15540   /* Parse args required to build the message */
15541   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15542     {
15543       if (unformat (input, "enable"))
15544         {
15545           is_set = 1;
15546           is_en = 1;
15547         }
15548       else if (unformat (input, "disable"))
15549         is_set = 1;
15550       else
15551         break;
15552     }
15553
15554   if (!is_set)
15555     {
15556       errmsg ("Value not set");
15557       return -99;
15558     }
15559
15560   /* Construct the API message */
15561   M (ONE_RLOC_PROBE_ENABLE_DISABLE, mp);
15562
15563   mp->is_enabled = is_en;
15564
15565   /* send it... */
15566   S (mp);
15567
15568   /* Wait for a reply... */
15569   W (ret);
15570   return ret;
15571 }
15572
15573 #define api_lisp_rloc_probe_enable_disable api_one_rloc_probe_enable_disable
15574
15575 static int
15576 api_one_map_register_enable_disable (vat_main_t * vam)
15577 {
15578   unformat_input_t *input = vam->input;
15579   vl_api_one_map_register_enable_disable_t *mp;
15580   u8 is_set = 0;
15581   u8 is_en = 0;
15582   int ret;
15583
15584   /* Parse args required to build the message */
15585   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15586     {
15587       if (unformat (input, "enable"))
15588         {
15589           is_set = 1;
15590           is_en = 1;
15591         }
15592       else if (unformat (input, "disable"))
15593         is_set = 1;
15594       else
15595         break;
15596     }
15597
15598   if (!is_set)
15599     {
15600       errmsg ("Value not set");
15601       return -99;
15602     }
15603
15604   /* Construct the API message */
15605   M (ONE_MAP_REGISTER_ENABLE_DISABLE, mp);
15606
15607   mp->is_enabled = is_en;
15608
15609   /* send it... */
15610   S (mp);
15611
15612   /* Wait for a reply... */
15613   W (ret);
15614   return ret;
15615 }
15616
15617 #define api_lisp_map_register_enable_disable api_one_map_register_enable_disable
15618
15619 static int
15620 api_one_enable_disable (vat_main_t * vam)
15621 {
15622   unformat_input_t *input = vam->input;
15623   vl_api_one_enable_disable_t *mp;
15624   u8 is_set = 0;
15625   u8 is_en = 0;
15626   int ret;
15627
15628   /* Parse args required to build the message */
15629   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15630     {
15631       if (unformat (input, "enable"))
15632         {
15633           is_set = 1;
15634           is_en = 1;
15635         }
15636       else if (unformat (input, "disable"))
15637         {
15638           is_set = 1;
15639         }
15640       else
15641         break;
15642     }
15643
15644   if (!is_set)
15645     {
15646       errmsg ("Value not set");
15647       return -99;
15648     }
15649
15650   /* Construct the API message */
15651   M (ONE_ENABLE_DISABLE, mp);
15652
15653   mp->is_en = is_en;
15654
15655   /* send it... */
15656   S (mp);
15657
15658   /* Wait for a reply... */
15659   W (ret);
15660   return ret;
15661 }
15662
15663 #define api_lisp_enable_disable api_one_enable_disable
15664
15665 static int
15666 api_one_enable_disable_xtr_mode (vat_main_t * vam)
15667 {
15668   unformat_input_t *input = vam->input;
15669   vl_api_one_enable_disable_xtr_mode_t *mp;
15670   u8 is_set = 0;
15671   u8 is_en = 0;
15672   int ret;
15673
15674   /* Parse args required to build the message */
15675   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15676     {
15677       if (unformat (input, "enable"))
15678         {
15679           is_set = 1;
15680           is_en = 1;
15681         }
15682       else if (unformat (input, "disable"))
15683         {
15684           is_set = 1;
15685         }
15686       else
15687         break;
15688     }
15689
15690   if (!is_set)
15691     {
15692       errmsg ("Value not set");
15693       return -99;
15694     }
15695
15696   /* Construct the API message */
15697   M (ONE_ENABLE_DISABLE_XTR_MODE, mp);
15698
15699   mp->is_en = is_en;
15700
15701   /* send it... */
15702   S (mp);
15703
15704   /* Wait for a reply... */
15705   W (ret);
15706   return ret;
15707 }
15708
15709 static int
15710 api_one_show_xtr_mode (vat_main_t * vam)
15711 {
15712   vl_api_one_show_xtr_mode_t *mp;
15713   int ret;
15714
15715   /* Construct the API message */
15716   M (ONE_SHOW_XTR_MODE, mp);
15717
15718   /* send it... */
15719   S (mp);
15720
15721   /* Wait for a reply... */
15722   W (ret);
15723   return ret;
15724 }
15725
15726 static int
15727 api_one_enable_disable_pitr_mode (vat_main_t * vam)
15728 {
15729   unformat_input_t *input = vam->input;
15730   vl_api_one_enable_disable_pitr_mode_t *mp;
15731   u8 is_set = 0;
15732   u8 is_en = 0;
15733   int ret;
15734
15735   /* Parse args required to build the message */
15736   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15737     {
15738       if (unformat (input, "enable"))
15739         {
15740           is_set = 1;
15741           is_en = 1;
15742         }
15743       else if (unformat (input, "disable"))
15744         {
15745           is_set = 1;
15746         }
15747       else
15748         break;
15749     }
15750
15751   if (!is_set)
15752     {
15753       errmsg ("Value not set");
15754       return -99;
15755     }
15756
15757   /* Construct the API message */
15758   M (ONE_ENABLE_DISABLE_PITR_MODE, mp);
15759
15760   mp->is_en = is_en;
15761
15762   /* send it... */
15763   S (mp);
15764
15765   /* Wait for a reply... */
15766   W (ret);
15767   return ret;
15768 }
15769
15770 static int
15771 api_one_show_pitr_mode (vat_main_t * vam)
15772 {
15773   vl_api_one_show_pitr_mode_t *mp;
15774   int ret;
15775
15776   /* Construct the API message */
15777   M (ONE_SHOW_PITR_MODE, mp);
15778
15779   /* send it... */
15780   S (mp);
15781
15782   /* Wait for a reply... */
15783   W (ret);
15784   return ret;
15785 }
15786
15787 static int
15788 api_one_enable_disable_petr_mode (vat_main_t * vam)
15789 {
15790   unformat_input_t *input = vam->input;
15791   vl_api_one_enable_disable_petr_mode_t *mp;
15792   u8 is_set = 0;
15793   u8 is_en = 0;
15794   int ret;
15795
15796   /* Parse args required to build the message */
15797   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15798     {
15799       if (unformat (input, "enable"))
15800         {
15801           is_set = 1;
15802           is_en = 1;
15803         }
15804       else if (unformat (input, "disable"))
15805         {
15806           is_set = 1;
15807         }
15808       else
15809         break;
15810     }
15811
15812   if (!is_set)
15813     {
15814       errmsg ("Value not set");
15815       return -99;
15816     }
15817
15818   /* Construct the API message */
15819   M (ONE_ENABLE_DISABLE_PETR_MODE, mp);
15820
15821   mp->is_en = is_en;
15822
15823   /* send it... */
15824   S (mp);
15825
15826   /* Wait for a reply... */
15827   W (ret);
15828   return ret;
15829 }
15830
15831 static int
15832 api_one_show_petr_mode (vat_main_t * vam)
15833 {
15834   vl_api_one_show_petr_mode_t *mp;
15835   int ret;
15836
15837   /* Construct the API message */
15838   M (ONE_SHOW_PETR_MODE, mp);
15839
15840   /* send it... */
15841   S (mp);
15842
15843   /* Wait for a reply... */
15844   W (ret);
15845   return ret;
15846 }
15847
15848 static int
15849 api_show_one_map_register_state (vat_main_t * vam)
15850 {
15851   vl_api_show_one_map_register_state_t *mp;
15852   int ret;
15853
15854   M (SHOW_ONE_MAP_REGISTER_STATE, mp);
15855
15856   /* send */
15857   S (mp);
15858
15859   /* wait for reply */
15860   W (ret);
15861   return ret;
15862 }
15863
15864 #define api_show_lisp_map_register_state api_show_one_map_register_state
15865
15866 static int
15867 api_show_one_rloc_probe_state (vat_main_t * vam)
15868 {
15869   vl_api_show_one_rloc_probe_state_t *mp;
15870   int ret;
15871
15872   M (SHOW_ONE_RLOC_PROBE_STATE, mp);
15873
15874   /* send */
15875   S (mp);
15876
15877   /* wait for reply */
15878   W (ret);
15879   return ret;
15880 }
15881
15882 #define api_show_lisp_rloc_probe_state api_show_one_rloc_probe_state
15883
15884 static int
15885 api_one_add_del_ndp_entry (vat_main_t * vam)
15886 {
15887   vl_api_one_add_del_ndp_entry_t *mp;
15888   unformat_input_t *input = vam->input;
15889   u8 is_add = 1;
15890   u8 mac_set = 0;
15891   u8 bd_set = 0;
15892   u8 ip_set = 0;
15893   u8 mac[6] = { 0, };
15894   u8 ip6[16] = { 0, };
15895   u32 bd = ~0;
15896   int ret;
15897
15898   /* Parse args required to build the message */
15899   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15900     {
15901       if (unformat (input, "del"))
15902         is_add = 0;
15903       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
15904         mac_set = 1;
15905       else if (unformat (input, "ip %U", unformat_ip6_address, ip6))
15906         ip_set = 1;
15907       else if (unformat (input, "bd %d", &bd))
15908         bd_set = 1;
15909       else
15910         {
15911           errmsg ("parse error '%U'", format_unformat_error, input);
15912           return -99;
15913         }
15914     }
15915
15916   if (!bd_set || !ip_set || (!mac_set && is_add))
15917     {
15918       errmsg ("Missing BD, IP or MAC!");
15919       return -99;
15920     }
15921
15922   M (ONE_ADD_DEL_NDP_ENTRY, mp);
15923   mp->is_add = is_add;
15924   clib_memcpy (mp->mac, mac, 6);
15925   mp->bd = clib_host_to_net_u32 (bd);
15926   clib_memcpy (mp->ip6, ip6, sizeof (mp->ip6));
15927
15928   /* send */
15929   S (mp);
15930
15931   /* wait for reply */
15932   W (ret);
15933   return ret;
15934 }
15935
15936 static int
15937 api_one_add_del_l2_arp_entry (vat_main_t * vam)
15938 {
15939   vl_api_one_add_del_l2_arp_entry_t *mp;
15940   unformat_input_t *input = vam->input;
15941   u8 is_add = 1;
15942   u8 mac_set = 0;
15943   u8 bd_set = 0;
15944   u8 ip_set = 0;
15945   u8 mac[6] = { 0, };
15946   u32 ip4 = 0, bd = ~0;
15947   int ret;
15948
15949   /* Parse args required to build the message */
15950   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15951     {
15952       if (unformat (input, "del"))
15953         is_add = 0;
15954       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
15955         mac_set = 1;
15956       else if (unformat (input, "ip %U", unformat_ip4_address, &ip4))
15957         ip_set = 1;
15958       else if (unformat (input, "bd %d", &bd))
15959         bd_set = 1;
15960       else
15961         {
15962           errmsg ("parse error '%U'", format_unformat_error, input);
15963           return -99;
15964         }
15965     }
15966
15967   if (!bd_set || !ip_set || (!mac_set && is_add))
15968     {
15969       errmsg ("Missing BD, IP or MAC!");
15970       return -99;
15971     }
15972
15973   M (ONE_ADD_DEL_L2_ARP_ENTRY, mp);
15974   mp->is_add = is_add;
15975   clib_memcpy (mp->mac, mac, 6);
15976   mp->bd = clib_host_to_net_u32 (bd);
15977   mp->ip4 = ip4;
15978
15979   /* send */
15980   S (mp);
15981
15982   /* wait for reply */
15983   W (ret);
15984   return ret;
15985 }
15986
15987 static int
15988 api_one_ndp_bd_get (vat_main_t * vam)
15989 {
15990   vl_api_one_ndp_bd_get_t *mp;
15991   int ret;
15992
15993   M (ONE_NDP_BD_GET, mp);
15994
15995   /* send */
15996   S (mp);
15997
15998   /* wait for reply */
15999   W (ret);
16000   return ret;
16001 }
16002
16003 static int
16004 api_one_ndp_entries_get (vat_main_t * vam)
16005 {
16006   vl_api_one_ndp_entries_get_t *mp;
16007   unformat_input_t *input = vam->input;
16008   u8 bd_set = 0;
16009   u32 bd = ~0;
16010   int ret;
16011
16012   /* Parse args required to build the message */
16013   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16014     {
16015       if (unformat (input, "bd %d", &bd))
16016         bd_set = 1;
16017       else
16018         {
16019           errmsg ("parse error '%U'", format_unformat_error, input);
16020           return -99;
16021         }
16022     }
16023
16024   if (!bd_set)
16025     {
16026       errmsg ("Expected bridge domain!");
16027       return -99;
16028     }
16029
16030   M (ONE_NDP_ENTRIES_GET, mp);
16031   mp->bd = clib_host_to_net_u32 (bd);
16032
16033   /* send */
16034   S (mp);
16035
16036   /* wait for reply */
16037   W (ret);
16038   return ret;
16039 }
16040
16041 static int
16042 api_one_l2_arp_bd_get (vat_main_t * vam)
16043 {
16044   vl_api_one_l2_arp_bd_get_t *mp;
16045   int ret;
16046
16047   M (ONE_L2_ARP_BD_GET, mp);
16048
16049   /* send */
16050   S (mp);
16051
16052   /* wait for reply */
16053   W (ret);
16054   return ret;
16055 }
16056
16057 static int
16058 api_one_l2_arp_entries_get (vat_main_t * vam)
16059 {
16060   vl_api_one_l2_arp_entries_get_t *mp;
16061   unformat_input_t *input = vam->input;
16062   u8 bd_set = 0;
16063   u32 bd = ~0;
16064   int ret;
16065
16066   /* Parse args required to build the message */
16067   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16068     {
16069       if (unformat (input, "bd %d", &bd))
16070         bd_set = 1;
16071       else
16072         {
16073           errmsg ("parse error '%U'", format_unformat_error, input);
16074           return -99;
16075         }
16076     }
16077
16078   if (!bd_set)
16079     {
16080       errmsg ("Expected bridge domain!");
16081       return -99;
16082     }
16083
16084   M (ONE_L2_ARP_ENTRIES_GET, mp);
16085   mp->bd = clib_host_to_net_u32 (bd);
16086
16087   /* send */
16088   S (mp);
16089
16090   /* wait for reply */
16091   W (ret);
16092   return ret;
16093 }
16094
16095 static int
16096 api_one_stats_enable_disable (vat_main_t * vam)
16097 {
16098   vl_api_one_stats_enable_disable_t *mp;
16099   unformat_input_t *input = vam->input;
16100   u8 is_set = 0;
16101   u8 is_en = 0;
16102   int ret;
16103
16104   /* Parse args required to build the message */
16105   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16106     {
16107       if (unformat (input, "enable"))
16108         {
16109           is_set = 1;
16110           is_en = 1;
16111         }
16112       else if (unformat (input, "disable"))
16113         {
16114           is_set = 1;
16115         }
16116       else
16117         break;
16118     }
16119
16120   if (!is_set)
16121     {
16122       errmsg ("Value not set");
16123       return -99;
16124     }
16125
16126   M (ONE_STATS_ENABLE_DISABLE, mp);
16127   mp->is_en = is_en;
16128
16129   /* send */
16130   S (mp);
16131
16132   /* wait for reply */
16133   W (ret);
16134   return ret;
16135 }
16136
16137 static int
16138 api_show_one_stats_enable_disable (vat_main_t * vam)
16139 {
16140   vl_api_show_one_stats_enable_disable_t *mp;
16141   int ret;
16142
16143   M (SHOW_ONE_STATS_ENABLE_DISABLE, mp);
16144
16145   /* send */
16146   S (mp);
16147
16148   /* wait for reply */
16149   W (ret);
16150   return ret;
16151 }
16152
16153 static int
16154 api_show_one_map_request_mode (vat_main_t * vam)
16155 {
16156   vl_api_show_one_map_request_mode_t *mp;
16157   int ret;
16158
16159   M (SHOW_ONE_MAP_REQUEST_MODE, mp);
16160
16161   /* send */
16162   S (mp);
16163
16164   /* wait for reply */
16165   W (ret);
16166   return ret;
16167 }
16168
16169 #define api_show_lisp_map_request_mode api_show_one_map_request_mode
16170
16171 static int
16172 api_one_map_request_mode (vat_main_t * vam)
16173 {
16174   unformat_input_t *input = vam->input;
16175   vl_api_one_map_request_mode_t *mp;
16176   u8 mode = 0;
16177   int ret;
16178
16179   /* Parse args required to build the message */
16180   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16181     {
16182       if (unformat (input, "dst-only"))
16183         mode = 0;
16184       else if (unformat (input, "src-dst"))
16185         mode = 1;
16186       else
16187         {
16188           errmsg ("parse error '%U'", format_unformat_error, input);
16189           return -99;
16190         }
16191     }
16192
16193   M (ONE_MAP_REQUEST_MODE, mp);
16194
16195   mp->mode = mode;
16196
16197   /* send */
16198   S (mp);
16199
16200   /* wait for reply */
16201   W (ret);
16202   return ret;
16203 }
16204
16205 #define api_lisp_map_request_mode api_one_map_request_mode
16206
16207 /**
16208  * Enable/disable ONE proxy ITR.
16209  *
16210  * @param vam vpp API test context
16211  * @return return code
16212  */
16213 static int
16214 api_one_pitr_set_locator_set (vat_main_t * vam)
16215 {
16216   u8 ls_name_set = 0;
16217   unformat_input_t *input = vam->input;
16218   vl_api_one_pitr_set_locator_set_t *mp;
16219   u8 is_add = 1;
16220   u8 *ls_name = 0;
16221   int ret;
16222
16223   /* Parse args required to build the message */
16224   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16225     {
16226       if (unformat (input, "del"))
16227         is_add = 0;
16228       else if (unformat (input, "locator-set %s", &ls_name))
16229         ls_name_set = 1;
16230       else
16231         {
16232           errmsg ("parse error '%U'", format_unformat_error, input);
16233           return -99;
16234         }
16235     }
16236
16237   if (!ls_name_set)
16238     {
16239       errmsg ("locator-set name not set!");
16240       return -99;
16241     }
16242
16243   M (ONE_PITR_SET_LOCATOR_SET, mp);
16244
16245   mp->is_add = is_add;
16246   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
16247   vec_free (ls_name);
16248
16249   /* send */
16250   S (mp);
16251
16252   /* wait for reply */
16253   W (ret);
16254   return ret;
16255 }
16256
16257 #define api_lisp_pitr_set_locator_set api_one_pitr_set_locator_set
16258
16259 static int
16260 api_one_nsh_set_locator_set (vat_main_t * vam)
16261 {
16262   u8 ls_name_set = 0;
16263   unformat_input_t *input = vam->input;
16264   vl_api_one_nsh_set_locator_set_t *mp;
16265   u8 is_add = 1;
16266   u8 *ls_name = 0;
16267   int ret;
16268
16269   /* Parse args required to build the message */
16270   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16271     {
16272       if (unformat (input, "del"))
16273         is_add = 0;
16274       else if (unformat (input, "ls %s", &ls_name))
16275         ls_name_set = 1;
16276       else
16277         {
16278           errmsg ("parse error '%U'", format_unformat_error, input);
16279           return -99;
16280         }
16281     }
16282
16283   if (!ls_name_set && is_add)
16284     {
16285       errmsg ("locator-set name not set!");
16286       return -99;
16287     }
16288
16289   M (ONE_NSH_SET_LOCATOR_SET, mp);
16290
16291   mp->is_add = is_add;
16292   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
16293   vec_free (ls_name);
16294
16295   /* send */
16296   S (mp);
16297
16298   /* wait for reply */
16299   W (ret);
16300   return ret;
16301 }
16302
16303 static int
16304 api_show_one_pitr (vat_main_t * vam)
16305 {
16306   vl_api_show_one_pitr_t *mp;
16307   int ret;
16308
16309   if (!vam->json_output)
16310     {
16311       print (vam->ofp, "%=20s", "lisp status:");
16312     }
16313
16314   M (SHOW_ONE_PITR, mp);
16315   /* send it... */
16316   S (mp);
16317
16318   /* Wait for a reply... */
16319   W (ret);
16320   return ret;
16321 }
16322
16323 #define api_show_lisp_pitr api_show_one_pitr
16324
16325 static int
16326 api_one_use_petr (vat_main_t * vam)
16327 {
16328   unformat_input_t *input = vam->input;
16329   vl_api_one_use_petr_t *mp;
16330   u8 is_add = 0;
16331   ip_address_t ip;
16332   int ret;
16333
16334   clib_memset (&ip, 0, sizeof (ip));
16335
16336   /* Parse args required to build the message */
16337   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16338     {
16339       if (unformat (input, "disable"))
16340         is_add = 0;
16341       else
16342         if (unformat (input, "%U", unformat_ip4_address, &ip_addr_v4 (&ip)))
16343         {
16344           is_add = 1;
16345           ip_addr_version (&ip) = AF_IP4;
16346         }
16347       else
16348         if (unformat (input, "%U", unformat_ip6_address, &ip_addr_v6 (&ip)))
16349         {
16350           is_add = 1;
16351           ip_addr_version (&ip) = AF_IP6;
16352         }
16353       else
16354         {
16355           errmsg ("parse error '%U'", format_unformat_error, input);
16356           return -99;
16357         }
16358     }
16359
16360   M (ONE_USE_PETR, mp);
16361
16362   mp->is_add = is_add;
16363   if (is_add)
16364     {
16365       mp->is_ip4 = ip_addr_version (&ip) == AF_IP4 ? 1 : 0;
16366       if (mp->is_ip4)
16367         clib_memcpy (mp->address, &ip, 4);
16368       else
16369         clib_memcpy (mp->address, &ip, 16);
16370     }
16371
16372   /* send */
16373   S (mp);
16374
16375   /* wait for reply */
16376   W (ret);
16377   return ret;
16378 }
16379
16380 #define api_lisp_use_petr api_one_use_petr
16381
16382 static int
16383 api_show_one_nsh_mapping (vat_main_t * vam)
16384 {
16385   vl_api_show_one_use_petr_t *mp;
16386   int ret;
16387
16388   if (!vam->json_output)
16389     {
16390       print (vam->ofp, "%=20s", "local ONE NSH mapping:");
16391     }
16392
16393   M (SHOW_ONE_NSH_MAPPING, mp);
16394   /* send it... */
16395   S (mp);
16396
16397   /* Wait for a reply... */
16398   W (ret);
16399   return ret;
16400 }
16401
16402 static int
16403 api_show_one_use_petr (vat_main_t * vam)
16404 {
16405   vl_api_show_one_use_petr_t *mp;
16406   int ret;
16407
16408   if (!vam->json_output)
16409     {
16410       print (vam->ofp, "%=20s", "Proxy-ETR status:");
16411     }
16412
16413   M (SHOW_ONE_USE_PETR, mp);
16414   /* send it... */
16415   S (mp);
16416
16417   /* Wait for a reply... */
16418   W (ret);
16419   return ret;
16420 }
16421
16422 #define api_show_lisp_use_petr api_show_one_use_petr
16423
16424 /**
16425  * Add/delete mapping between vni and vrf
16426  */
16427 static int
16428 api_one_eid_table_add_del_map (vat_main_t * vam)
16429 {
16430   unformat_input_t *input = vam->input;
16431   vl_api_one_eid_table_add_del_map_t *mp;
16432   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
16433   u32 vni, vrf, bd_index;
16434   int ret;
16435
16436   /* Parse args required to build the message */
16437   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16438     {
16439       if (unformat (input, "del"))
16440         is_add = 0;
16441       else if (unformat (input, "vrf %d", &vrf))
16442         vrf_set = 1;
16443       else if (unformat (input, "bd_index %d", &bd_index))
16444         bd_index_set = 1;
16445       else if (unformat (input, "vni %d", &vni))
16446         vni_set = 1;
16447       else
16448         break;
16449     }
16450
16451   if (!vni_set || (!vrf_set && !bd_index_set))
16452     {
16453       errmsg ("missing arguments!");
16454       return -99;
16455     }
16456
16457   if (vrf_set && bd_index_set)
16458     {
16459       errmsg ("error: both vrf and bd entered!");
16460       return -99;
16461     }
16462
16463   M (ONE_EID_TABLE_ADD_DEL_MAP, mp);
16464
16465   mp->is_add = is_add;
16466   mp->vni = htonl (vni);
16467   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
16468   mp->is_l2 = bd_index_set;
16469
16470   /* send */
16471   S (mp);
16472
16473   /* wait for reply */
16474   W (ret);
16475   return ret;
16476 }
16477
16478 #define api_lisp_eid_table_add_del_map api_one_eid_table_add_del_map
16479
16480 uword
16481 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
16482 {
16483   u32 *action = va_arg (*args, u32 *);
16484   u8 *s = 0;
16485
16486   if (unformat (input, "%s", &s))
16487     {
16488       if (!strcmp ((char *) s, "no-action"))
16489         action[0] = 0;
16490       else if (!strcmp ((char *) s, "natively-forward"))
16491         action[0] = 1;
16492       else if (!strcmp ((char *) s, "send-map-request"))
16493         action[0] = 2;
16494       else if (!strcmp ((char *) s, "drop"))
16495         action[0] = 3;
16496       else
16497         {
16498           clib_warning ("invalid action: '%s'", s);
16499           action[0] = 3;
16500         }
16501     }
16502   else
16503     return 0;
16504
16505   vec_free (s);
16506   return 1;
16507 }
16508
16509 /**
16510  * Add/del remote mapping to/from ONE control plane
16511  *
16512  * @param vam vpp API test context
16513  * @return return code
16514  */
16515 static int
16516 api_one_add_del_remote_mapping (vat_main_t * vam)
16517 {
16518   unformat_input_t *input = vam->input;
16519   vl_api_one_add_del_remote_mapping_t *mp;
16520   u32 vni = 0;
16521   lisp_eid_vat_t _eid, *eid = &_eid;
16522   lisp_eid_vat_t _seid, *seid = &_seid;
16523   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
16524   u32 action = ~0, p, w, data_len;
16525   ip4_address_t rloc4;
16526   ip6_address_t rloc6;
16527   vl_api_remote_locator_t *rlocs = 0, rloc, *curr_rloc = 0;
16528   int ret;
16529
16530   clib_memset (&rloc, 0, sizeof (rloc));
16531
16532   /* Parse args required to build the message */
16533   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16534     {
16535       if (unformat (input, "del-all"))
16536         {
16537           del_all = 1;
16538         }
16539       else if (unformat (input, "del"))
16540         {
16541           is_add = 0;
16542         }
16543       else if (unformat (input, "add"))
16544         {
16545           is_add = 1;
16546         }
16547       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
16548         {
16549           eid_set = 1;
16550         }
16551       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
16552         {
16553           seid_set = 1;
16554         }
16555       else if (unformat (input, "vni %d", &vni))
16556         {
16557           ;
16558         }
16559       else if (unformat (input, "p %d w %d", &p, &w))
16560         {
16561           if (!curr_rloc)
16562             {
16563               errmsg ("No RLOC configured for setting priority/weight!");
16564               return -99;
16565             }
16566           curr_rloc->priority = p;
16567           curr_rloc->weight = w;
16568         }
16569       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
16570         {
16571           rloc.is_ip4 = 1;
16572           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
16573           vec_add1 (rlocs, rloc);
16574           curr_rloc = &rlocs[vec_len (rlocs) - 1];
16575         }
16576       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
16577         {
16578           rloc.is_ip4 = 0;
16579           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
16580           vec_add1 (rlocs, rloc);
16581           curr_rloc = &rlocs[vec_len (rlocs) - 1];
16582         }
16583       else if (unformat (input, "action %U",
16584                          unformat_negative_mapping_action, &action))
16585         {
16586           ;
16587         }
16588       else
16589         {
16590           clib_warning ("parse error '%U'", format_unformat_error, input);
16591           return -99;
16592         }
16593     }
16594
16595   if (0 == eid_set)
16596     {
16597       errmsg ("missing params!");
16598       return -99;
16599     }
16600
16601   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
16602     {
16603       errmsg ("no action set for negative map-reply!");
16604       return -99;
16605     }
16606
16607   data_len = vec_len (rlocs) * sizeof (vl_api_remote_locator_t);
16608
16609   M2 (ONE_ADD_DEL_REMOTE_MAPPING, mp, data_len);
16610   mp->is_add = is_add;
16611   mp->vni = htonl (vni);
16612   mp->action = (u8) action;
16613   mp->is_src_dst = seid_set;
16614   mp->eid_len = eid->len;
16615   mp->seid_len = seid->len;
16616   mp->del_all = del_all;
16617   mp->eid_type = eid->type;
16618   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
16619   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
16620
16621   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
16622   clib_memcpy (mp->rlocs, rlocs, data_len);
16623   vec_free (rlocs);
16624
16625   /* send it... */
16626   S (mp);
16627
16628   /* Wait for a reply... */
16629   W (ret);
16630   return ret;
16631 }
16632
16633 #define api_lisp_add_del_remote_mapping api_one_add_del_remote_mapping
16634
16635 /**
16636  * Add/del ONE adjacency. Saves mapping in ONE control plane and updates
16637  * forwarding entries in data-plane accordingly.
16638  *
16639  * @param vam vpp API test context
16640  * @return return code
16641  */
16642 static int
16643 api_one_add_del_adjacency (vat_main_t * vam)
16644 {
16645   unformat_input_t *input = vam->input;
16646   vl_api_one_add_del_adjacency_t *mp;
16647   u32 vni = 0;
16648   ip4_address_t leid4, reid4;
16649   ip6_address_t leid6, reid6;
16650   u8 reid_mac[6] = { 0 };
16651   u8 leid_mac[6] = { 0 };
16652   u8 reid_type, leid_type;
16653   u32 leid_len = 0, reid_len = 0, len;
16654   u8 is_add = 1;
16655   int ret;
16656
16657   leid_type = reid_type = (u8) ~ 0;
16658
16659   /* Parse args required to build the message */
16660   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16661     {
16662       if (unformat (input, "del"))
16663         {
16664           is_add = 0;
16665         }
16666       else if (unformat (input, "add"))
16667         {
16668           is_add = 1;
16669         }
16670       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
16671                          &reid4, &len))
16672         {
16673           reid_type = 0;        /* ipv4 */
16674           reid_len = len;
16675         }
16676       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
16677                          &reid6, &len))
16678         {
16679           reid_type = 1;        /* ipv6 */
16680           reid_len = len;
16681         }
16682       else if (unformat (input, "reid %U", unformat_ethernet_address,
16683                          reid_mac))
16684         {
16685           reid_type = 2;        /* mac */
16686         }
16687       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
16688                          &leid4, &len))
16689         {
16690           leid_type = 0;        /* ipv4 */
16691           leid_len = len;
16692         }
16693       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
16694                          &leid6, &len))
16695         {
16696           leid_type = 1;        /* ipv6 */
16697           leid_len = len;
16698         }
16699       else if (unformat (input, "leid %U", unformat_ethernet_address,
16700                          leid_mac))
16701         {
16702           leid_type = 2;        /* mac */
16703         }
16704       else if (unformat (input, "vni %d", &vni))
16705         {
16706           ;
16707         }
16708       else
16709         {
16710           errmsg ("parse error '%U'", format_unformat_error, input);
16711           return -99;
16712         }
16713     }
16714
16715   if ((u8) ~ 0 == reid_type)
16716     {
16717       errmsg ("missing params!");
16718       return -99;
16719     }
16720
16721   if (leid_type != reid_type)
16722     {
16723       errmsg ("remote and local EIDs are of different types!");
16724       return -99;
16725     }
16726
16727   M (ONE_ADD_DEL_ADJACENCY, mp);
16728   mp->is_add = is_add;
16729   mp->vni = htonl (vni);
16730   mp->leid_len = leid_len;
16731   mp->reid_len = reid_len;
16732   mp->eid_type = reid_type;
16733
16734   switch (mp->eid_type)
16735     {
16736     case 0:
16737       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
16738       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
16739       break;
16740     case 1:
16741       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
16742       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
16743       break;
16744     case 2:
16745       clib_memcpy (mp->leid, leid_mac, 6);
16746       clib_memcpy (mp->reid, reid_mac, 6);
16747       break;
16748     default:
16749       errmsg ("unknown EID type %d!", mp->eid_type);
16750       return 0;
16751     }
16752
16753   /* send it... */
16754   S (mp);
16755
16756   /* Wait for a reply... */
16757   W (ret);
16758   return ret;
16759 }
16760
16761 #define api_lisp_add_del_adjacency api_one_add_del_adjacency
16762
16763 uword
16764 unformat_gpe_encap_mode (unformat_input_t * input, va_list * args)
16765 {
16766   u32 *mode = va_arg (*args, u32 *);
16767
16768   if (unformat (input, "lisp"))
16769     *mode = 0;
16770   else if (unformat (input, "vxlan"))
16771     *mode = 1;
16772   else
16773     return 0;
16774
16775   return 1;
16776 }
16777
16778 static int
16779 api_gpe_get_encap_mode (vat_main_t * vam)
16780 {
16781   vl_api_gpe_get_encap_mode_t *mp;
16782   int ret;
16783
16784   /* Construct the API message */
16785   M (GPE_GET_ENCAP_MODE, mp);
16786
16787   /* send it... */
16788   S (mp);
16789
16790   /* Wait for a reply... */
16791   W (ret);
16792   return ret;
16793 }
16794
16795 static int
16796 api_gpe_set_encap_mode (vat_main_t * vam)
16797 {
16798   unformat_input_t *input = vam->input;
16799   vl_api_gpe_set_encap_mode_t *mp;
16800   int ret;
16801   u32 mode = 0;
16802
16803   /* Parse args required to build the message */
16804   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16805     {
16806       if (unformat (input, "%U", unformat_gpe_encap_mode, &mode))
16807         ;
16808       else
16809         break;
16810     }
16811
16812   /* Construct the API message */
16813   M (GPE_SET_ENCAP_MODE, mp);
16814
16815   mp->mode = mode;
16816
16817   /* send it... */
16818   S (mp);
16819
16820   /* Wait for a reply... */
16821   W (ret);
16822   return ret;
16823 }
16824
16825 static int
16826 api_lisp_gpe_add_del_iface (vat_main_t * vam)
16827 {
16828   unformat_input_t *input = vam->input;
16829   vl_api_gpe_add_del_iface_t *mp;
16830   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
16831   u32 dp_table = 0, vni = 0;
16832   int ret;
16833
16834   /* Parse args required to build the message */
16835   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16836     {
16837       if (unformat (input, "up"))
16838         {
16839           action_set = 1;
16840           is_add = 1;
16841         }
16842       else if (unformat (input, "down"))
16843         {
16844           action_set = 1;
16845           is_add = 0;
16846         }
16847       else if (unformat (input, "table_id %d", &dp_table))
16848         {
16849           dp_table_set = 1;
16850         }
16851       else if (unformat (input, "bd_id %d", &dp_table))
16852         {
16853           dp_table_set = 1;
16854           is_l2 = 1;
16855         }
16856       else if (unformat (input, "vni %d", &vni))
16857         {
16858           vni_set = 1;
16859         }
16860       else
16861         break;
16862     }
16863
16864   if (action_set == 0)
16865     {
16866       errmsg ("Action not set");
16867       return -99;
16868     }
16869   if (dp_table_set == 0 || vni_set == 0)
16870     {
16871       errmsg ("vni and dp_table must be set");
16872       return -99;
16873     }
16874
16875   /* Construct the API message */
16876   M (GPE_ADD_DEL_IFACE, mp);
16877
16878   mp->is_add = is_add;
16879   mp->dp_table = clib_host_to_net_u32 (dp_table);
16880   mp->is_l2 = is_l2;
16881   mp->vni = clib_host_to_net_u32 (vni);
16882
16883   /* send it... */
16884   S (mp);
16885
16886   /* Wait for a reply... */
16887   W (ret);
16888   return ret;
16889 }
16890
16891 static int
16892 api_one_map_register_fallback_threshold (vat_main_t * vam)
16893 {
16894   unformat_input_t *input = vam->input;
16895   vl_api_one_map_register_fallback_threshold_t *mp;
16896   u32 value = 0;
16897   u8 is_set = 0;
16898   int ret;
16899
16900   /* Parse args required to build the message */
16901   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16902     {
16903       if (unformat (input, "%u", &value))
16904         is_set = 1;
16905       else
16906         {
16907           clib_warning ("parse error '%U'", format_unformat_error, input);
16908           return -99;
16909         }
16910     }
16911
16912   if (!is_set)
16913     {
16914       errmsg ("fallback threshold value is missing!");
16915       return -99;
16916     }
16917
16918   M (ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
16919   mp->value = clib_host_to_net_u32 (value);
16920
16921   /* send it... */
16922   S (mp);
16923
16924   /* Wait for a reply... */
16925   W (ret);
16926   return ret;
16927 }
16928
16929 static int
16930 api_show_one_map_register_fallback_threshold (vat_main_t * vam)
16931 {
16932   vl_api_show_one_map_register_fallback_threshold_t *mp;
16933   int ret;
16934
16935   M (SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
16936
16937   /* send it... */
16938   S (mp);
16939
16940   /* Wait for a reply... */
16941   W (ret);
16942   return ret;
16943 }
16944
16945 uword
16946 unformat_lisp_transport_protocol (unformat_input_t * input, va_list * args)
16947 {
16948   u32 *proto = va_arg (*args, u32 *);
16949
16950   if (unformat (input, "udp"))
16951     *proto = 1;
16952   else if (unformat (input, "api"))
16953     *proto = 2;
16954   else
16955     return 0;
16956
16957   return 1;
16958 }
16959
16960 static int
16961 api_one_set_transport_protocol (vat_main_t * vam)
16962 {
16963   unformat_input_t *input = vam->input;
16964   vl_api_one_set_transport_protocol_t *mp;
16965   u8 is_set = 0;
16966   u32 protocol = 0;
16967   int ret;
16968
16969   /* Parse args required to build the message */
16970   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16971     {
16972       if (unformat (input, "%U", unformat_lisp_transport_protocol, &protocol))
16973         is_set = 1;
16974       else
16975         {
16976           clib_warning ("parse error '%U'", format_unformat_error, input);
16977           return -99;
16978         }
16979     }
16980
16981   if (!is_set)
16982     {
16983       errmsg ("Transport protocol missing!");
16984       return -99;
16985     }
16986
16987   M (ONE_SET_TRANSPORT_PROTOCOL, mp);
16988   mp->protocol = (u8) protocol;
16989
16990   /* send it... */
16991   S (mp);
16992
16993   /* Wait for a reply... */
16994   W (ret);
16995   return ret;
16996 }
16997
16998 static int
16999 api_one_get_transport_protocol (vat_main_t * vam)
17000 {
17001   vl_api_one_get_transport_protocol_t *mp;
17002   int ret;
17003
17004   M (ONE_GET_TRANSPORT_PROTOCOL, mp);
17005
17006   /* send it... */
17007   S (mp);
17008
17009   /* Wait for a reply... */
17010   W (ret);
17011   return ret;
17012 }
17013
17014 static int
17015 api_one_map_register_set_ttl (vat_main_t * vam)
17016 {
17017   unformat_input_t *input = vam->input;
17018   vl_api_one_map_register_set_ttl_t *mp;
17019   u32 ttl = 0;
17020   u8 is_set = 0;
17021   int ret;
17022
17023   /* Parse args required to build the message */
17024   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17025     {
17026       if (unformat (input, "%u", &ttl))
17027         is_set = 1;
17028       else
17029         {
17030           clib_warning ("parse error '%U'", format_unformat_error, input);
17031           return -99;
17032         }
17033     }
17034
17035   if (!is_set)
17036     {
17037       errmsg ("TTL value missing!");
17038       return -99;
17039     }
17040
17041   M (ONE_MAP_REGISTER_SET_TTL, mp);
17042   mp->ttl = clib_host_to_net_u32 (ttl);
17043
17044   /* send it... */
17045   S (mp);
17046
17047   /* Wait for a reply... */
17048   W (ret);
17049   return ret;
17050 }
17051
17052 static int
17053 api_show_one_map_register_ttl (vat_main_t * vam)
17054 {
17055   vl_api_show_one_map_register_ttl_t *mp;
17056   int ret;
17057
17058   M (SHOW_ONE_MAP_REGISTER_TTL, mp);
17059
17060   /* send it... */
17061   S (mp);
17062
17063   /* Wait for a reply... */
17064   W (ret);
17065   return ret;
17066 }
17067
17068 /**
17069  * Add/del map request itr rlocs from ONE control plane and updates
17070  *
17071  * @param vam vpp API test context
17072  * @return return code
17073  */
17074 static int
17075 api_one_add_del_map_request_itr_rlocs (vat_main_t * vam)
17076 {
17077   unformat_input_t *input = vam->input;
17078   vl_api_one_add_del_map_request_itr_rlocs_t *mp;
17079   u8 *locator_set_name = 0;
17080   u8 locator_set_name_set = 0;
17081   u8 is_add = 1;
17082   int ret;
17083
17084   /* Parse args required to build the message */
17085   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17086     {
17087       if (unformat (input, "del"))
17088         {
17089           is_add = 0;
17090         }
17091       else if (unformat (input, "%_%v%_", &locator_set_name))
17092         {
17093           locator_set_name_set = 1;
17094         }
17095       else
17096         {
17097           clib_warning ("parse error '%U'", format_unformat_error, input);
17098           return -99;
17099         }
17100     }
17101
17102   if (is_add && !locator_set_name_set)
17103     {
17104       errmsg ("itr-rloc is not set!");
17105       return -99;
17106     }
17107
17108   if (is_add && vec_len (locator_set_name) > 64)
17109     {
17110       errmsg ("itr-rloc locator-set name too long");
17111       vec_free (locator_set_name);
17112       return -99;
17113     }
17114
17115   M (ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS, mp);
17116   mp->is_add = is_add;
17117   if (is_add)
17118     {
17119       clib_memcpy (mp->locator_set_name, locator_set_name,
17120                    vec_len (locator_set_name));
17121     }
17122   else
17123     {
17124       clib_memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
17125     }
17126   vec_free (locator_set_name);
17127
17128   /* send it... */
17129   S (mp);
17130
17131   /* Wait for a reply... */
17132   W (ret);
17133   return ret;
17134 }
17135
17136 #define api_lisp_add_del_map_request_itr_rlocs api_one_add_del_map_request_itr_rlocs
17137
17138 static int
17139 api_one_locator_dump (vat_main_t * vam)
17140 {
17141   unformat_input_t *input = vam->input;
17142   vl_api_one_locator_dump_t *mp;
17143   vl_api_control_ping_t *mp_ping;
17144   u8 is_index_set = 0, is_name_set = 0;
17145   u8 *ls_name = 0;
17146   u32 ls_index = ~0;
17147   int ret;
17148
17149   /* Parse args required to build the message */
17150   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17151     {
17152       if (unformat (input, "ls_name %_%v%_", &ls_name))
17153         {
17154           is_name_set = 1;
17155         }
17156       else if (unformat (input, "ls_index %d", &ls_index))
17157         {
17158           is_index_set = 1;
17159         }
17160       else
17161         {
17162           errmsg ("parse error '%U'", format_unformat_error, input);
17163           return -99;
17164         }
17165     }
17166
17167   if (!is_index_set && !is_name_set)
17168     {
17169       errmsg ("error: expected one of index or name!");
17170       return -99;
17171     }
17172
17173   if (is_index_set && is_name_set)
17174     {
17175       errmsg ("error: only one param expected!");
17176       return -99;
17177     }
17178
17179   if (vec_len (ls_name) > 62)
17180     {
17181       errmsg ("error: locator set name too long!");
17182       return -99;
17183     }
17184
17185   if (!vam->json_output)
17186     {
17187       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
17188     }
17189
17190   M (ONE_LOCATOR_DUMP, mp);
17191   mp->is_index_set = is_index_set;
17192
17193   if (is_index_set)
17194     mp->ls_index = clib_host_to_net_u32 (ls_index);
17195   else
17196     {
17197       vec_add1 (ls_name, 0);
17198       strncpy ((char *) mp->ls_name, (char *) ls_name,
17199                sizeof (mp->ls_name) - 1);
17200     }
17201
17202   /* send it... */
17203   S (mp);
17204
17205   /* Use a control ping for synchronization */
17206   MPING (CONTROL_PING, mp_ping);
17207   S (mp_ping);
17208
17209   /* Wait for a reply... */
17210   W (ret);
17211   return ret;
17212 }
17213
17214 #define api_lisp_locator_dump api_one_locator_dump
17215
17216 static int
17217 api_one_locator_set_dump (vat_main_t * vam)
17218 {
17219   vl_api_one_locator_set_dump_t *mp;
17220   vl_api_control_ping_t *mp_ping;
17221   unformat_input_t *input = vam->input;
17222   u8 filter = 0;
17223   int ret;
17224
17225   /* Parse args required to build the message */
17226   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17227     {
17228       if (unformat (input, "local"))
17229         {
17230           filter = 1;
17231         }
17232       else if (unformat (input, "remote"))
17233         {
17234           filter = 2;
17235         }
17236       else
17237         {
17238           errmsg ("parse error '%U'", format_unformat_error, input);
17239           return -99;
17240         }
17241     }
17242
17243   if (!vam->json_output)
17244     {
17245       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
17246     }
17247
17248   M (ONE_LOCATOR_SET_DUMP, mp);
17249
17250   mp->filter = filter;
17251
17252   /* send it... */
17253   S (mp);
17254
17255   /* Use a control ping for synchronization */
17256   MPING (CONTROL_PING, mp_ping);
17257   S (mp_ping);
17258
17259   /* Wait for a reply... */
17260   W (ret);
17261   return ret;
17262 }
17263
17264 #define api_lisp_locator_set_dump api_one_locator_set_dump
17265
17266 static int
17267 api_one_eid_table_map_dump (vat_main_t * vam)
17268 {
17269   u8 is_l2 = 0;
17270   u8 mode_set = 0;
17271   unformat_input_t *input = vam->input;
17272   vl_api_one_eid_table_map_dump_t *mp;
17273   vl_api_control_ping_t *mp_ping;
17274   int ret;
17275
17276   /* Parse args required to build the message */
17277   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17278     {
17279       if (unformat (input, "l2"))
17280         {
17281           is_l2 = 1;
17282           mode_set = 1;
17283         }
17284       else if (unformat (input, "l3"))
17285         {
17286           is_l2 = 0;
17287           mode_set = 1;
17288         }
17289       else
17290         {
17291           errmsg ("parse error '%U'", format_unformat_error, input);
17292           return -99;
17293         }
17294     }
17295
17296   if (!mode_set)
17297     {
17298       errmsg ("expected one of 'l2' or 'l3' parameter!");
17299       return -99;
17300     }
17301
17302   if (!vam->json_output)
17303     {
17304       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
17305     }
17306
17307   M (ONE_EID_TABLE_MAP_DUMP, mp);
17308   mp->is_l2 = is_l2;
17309
17310   /* send it... */
17311   S (mp);
17312
17313   /* Use a control ping for synchronization */
17314   MPING (CONTROL_PING, mp_ping);
17315   S (mp_ping);
17316
17317   /* Wait for a reply... */
17318   W (ret);
17319   return ret;
17320 }
17321
17322 #define api_lisp_eid_table_map_dump api_one_eid_table_map_dump
17323
17324 static int
17325 api_one_eid_table_vni_dump (vat_main_t * vam)
17326 {
17327   vl_api_one_eid_table_vni_dump_t *mp;
17328   vl_api_control_ping_t *mp_ping;
17329   int ret;
17330
17331   if (!vam->json_output)
17332     {
17333       print (vam->ofp, "VNI");
17334     }
17335
17336   M (ONE_EID_TABLE_VNI_DUMP, mp);
17337
17338   /* send it... */
17339   S (mp);
17340
17341   /* Use a control ping for synchronization */
17342   MPING (CONTROL_PING, mp_ping);
17343   S (mp_ping);
17344
17345   /* Wait for a reply... */
17346   W (ret);
17347   return ret;
17348 }
17349
17350 #define api_lisp_eid_table_vni_dump api_one_eid_table_vni_dump
17351
17352 static int
17353 api_one_eid_table_dump (vat_main_t * vam)
17354 {
17355   unformat_input_t *i = vam->input;
17356   vl_api_one_eid_table_dump_t *mp;
17357   vl_api_control_ping_t *mp_ping;
17358   struct in_addr ip4;
17359   struct in6_addr ip6;
17360   u8 mac[6];
17361   u8 eid_type = ~0, eid_set = 0;
17362   u32 prefix_length = ~0, t, vni = 0;
17363   u8 filter = 0;
17364   int ret;
17365   lisp_nsh_api_t nsh;
17366
17367   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17368     {
17369       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
17370         {
17371           eid_set = 1;
17372           eid_type = 0;
17373           prefix_length = t;
17374         }
17375       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
17376         {
17377           eid_set = 1;
17378           eid_type = 1;
17379           prefix_length = t;
17380         }
17381       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
17382         {
17383           eid_set = 1;
17384           eid_type = 2;
17385         }
17386       else if (unformat (i, "eid %U", unformat_nsh_address, &nsh))
17387         {
17388           eid_set = 1;
17389           eid_type = 3;
17390         }
17391       else if (unformat (i, "vni %d", &t))
17392         {
17393           vni = t;
17394         }
17395       else if (unformat (i, "local"))
17396         {
17397           filter = 1;
17398         }
17399       else if (unformat (i, "remote"))
17400         {
17401           filter = 2;
17402         }
17403       else
17404         {
17405           errmsg ("parse error '%U'", format_unformat_error, i);
17406           return -99;
17407         }
17408     }
17409
17410   if (!vam->json_output)
17411     {
17412       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
17413              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
17414     }
17415
17416   M (ONE_EID_TABLE_DUMP, mp);
17417
17418   mp->filter = filter;
17419   if (eid_set)
17420     {
17421       mp->eid_set = 1;
17422       mp->vni = htonl (vni);
17423       mp->eid_type = eid_type;
17424       switch (eid_type)
17425         {
17426         case 0:
17427           mp->prefix_length = prefix_length;
17428           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
17429           break;
17430         case 1:
17431           mp->prefix_length = prefix_length;
17432           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
17433           break;
17434         case 2:
17435           clib_memcpy (mp->eid, mac, sizeof (mac));
17436           break;
17437         case 3:
17438           clib_memcpy (mp->eid, &nsh, sizeof (nsh));
17439           break;
17440         default:
17441           errmsg ("unknown EID type %d!", eid_type);
17442           return -99;
17443         }
17444     }
17445
17446   /* send it... */
17447   S (mp);
17448
17449   /* Use a control ping for synchronization */
17450   MPING (CONTROL_PING, mp_ping);
17451   S (mp_ping);
17452
17453   /* Wait for a reply... */
17454   W (ret);
17455   return ret;
17456 }
17457
17458 #define api_lisp_eid_table_dump api_one_eid_table_dump
17459
17460 static int
17461 api_lisp_gpe_fwd_entries_get (vat_main_t * vam)
17462 {
17463   unformat_input_t *i = vam->input;
17464   vl_api_gpe_fwd_entries_get_t *mp;
17465   u8 vni_set = 0;
17466   u32 vni = ~0;
17467   int ret;
17468
17469   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17470     {
17471       if (unformat (i, "vni %d", &vni))
17472         {
17473           vni_set = 1;
17474         }
17475       else
17476         {
17477           errmsg ("parse error '%U'", format_unformat_error, i);
17478           return -99;
17479         }
17480     }
17481
17482   if (!vni_set)
17483     {
17484       errmsg ("vni not set!");
17485       return -99;
17486     }
17487
17488   if (!vam->json_output)
17489     {
17490       print (vam->ofp, "%10s %10s %s %40s", "fwd_index", "dp_table",
17491              "leid", "reid");
17492     }
17493
17494   M (GPE_FWD_ENTRIES_GET, mp);
17495   mp->vni = clib_host_to_net_u32 (vni);
17496
17497   /* send it... */
17498   S (mp);
17499
17500   /* Wait for a reply... */
17501   W (ret);
17502   return ret;
17503 }
17504
17505 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_endian vl_noop_handler
17506 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_print vl_noop_handler
17507 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_endian vl_noop_handler
17508 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_print vl_noop_handler
17509 #define vl_api_gpe_fwd_entries_get_reply_t_endian vl_noop_handler
17510 #define vl_api_gpe_fwd_entries_get_reply_t_print vl_noop_handler
17511 #define vl_api_gpe_fwd_entry_path_details_t_endian vl_noop_handler
17512 #define vl_api_gpe_fwd_entry_path_details_t_print vl_noop_handler
17513
17514 static int
17515 api_one_adjacencies_get (vat_main_t * vam)
17516 {
17517   unformat_input_t *i = vam->input;
17518   vl_api_one_adjacencies_get_t *mp;
17519   u8 vni_set = 0;
17520   u32 vni = ~0;
17521   int ret;
17522
17523   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17524     {
17525       if (unformat (i, "vni %d", &vni))
17526         {
17527           vni_set = 1;
17528         }
17529       else
17530         {
17531           errmsg ("parse error '%U'", format_unformat_error, i);
17532           return -99;
17533         }
17534     }
17535
17536   if (!vni_set)
17537     {
17538       errmsg ("vni not set!");
17539       return -99;
17540     }
17541
17542   if (!vam->json_output)
17543     {
17544       print (vam->ofp, "%s %40s", "leid", "reid");
17545     }
17546
17547   M (ONE_ADJACENCIES_GET, mp);
17548   mp->vni = clib_host_to_net_u32 (vni);
17549
17550   /* send it... */
17551   S (mp);
17552
17553   /* Wait for a reply... */
17554   W (ret);
17555   return ret;
17556 }
17557
17558 #define api_lisp_adjacencies_get api_one_adjacencies_get
17559
17560 static int
17561 api_gpe_native_fwd_rpaths_get (vat_main_t * vam)
17562 {
17563   unformat_input_t *i = vam->input;
17564   vl_api_gpe_native_fwd_rpaths_get_t *mp;
17565   int ret;
17566   u8 ip_family_set = 0, is_ip4 = 1;
17567
17568   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17569     {
17570       if (unformat (i, "ip4"))
17571         {
17572           ip_family_set = 1;
17573           is_ip4 = 1;
17574         }
17575       else if (unformat (i, "ip6"))
17576         {
17577           ip_family_set = 1;
17578           is_ip4 = 0;
17579         }
17580       else
17581         {
17582           errmsg ("parse error '%U'", format_unformat_error, i);
17583           return -99;
17584         }
17585     }
17586
17587   if (!ip_family_set)
17588     {
17589       errmsg ("ip family not set!");
17590       return -99;
17591     }
17592
17593   M (GPE_NATIVE_FWD_RPATHS_GET, mp);
17594   mp->is_ip4 = is_ip4;
17595
17596   /* send it... */
17597   S (mp);
17598
17599   /* Wait for a reply... */
17600   W (ret);
17601   return ret;
17602 }
17603
17604 static int
17605 api_gpe_fwd_entry_vnis_get (vat_main_t * vam)
17606 {
17607   vl_api_gpe_fwd_entry_vnis_get_t *mp;
17608   int ret;
17609
17610   if (!vam->json_output)
17611     {
17612       print (vam->ofp, "VNIs");
17613     }
17614
17615   M (GPE_FWD_ENTRY_VNIS_GET, mp);
17616
17617   /* send it... */
17618   S (mp);
17619
17620   /* Wait for a reply... */
17621   W (ret);
17622   return ret;
17623 }
17624
17625 static int
17626 api_gpe_add_del_native_fwd_rpath (vat_main_t * vam)
17627 {
17628   unformat_input_t *i = vam->input;
17629   vl_api_gpe_add_del_native_fwd_rpath_t *mp;
17630   int ret = 0;
17631   u8 is_add = 1, ip_set = 0, is_ip4 = 1;
17632   struct in_addr ip4;
17633   struct in6_addr ip6;
17634   u32 table_id = 0, nh_sw_if_index = ~0;
17635
17636   clib_memset (&ip4, 0, sizeof (ip4));
17637   clib_memset (&ip6, 0, sizeof (ip6));
17638
17639   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17640     {
17641       if (unformat (i, "del"))
17642         is_add = 0;
17643       else if (unformat (i, "via %U %U", unformat_ip4_address, &ip4,
17644                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
17645         {
17646           ip_set = 1;
17647           is_ip4 = 1;
17648         }
17649       else if (unformat (i, "via %U %U", unformat_ip6_address, &ip6,
17650                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
17651         {
17652           ip_set = 1;
17653           is_ip4 = 0;
17654         }
17655       else if (unformat (i, "via %U", unformat_ip4_address, &ip4))
17656         {
17657           ip_set = 1;
17658           is_ip4 = 1;
17659           nh_sw_if_index = ~0;
17660         }
17661       else if (unformat (i, "via %U", unformat_ip6_address, &ip6))
17662         {
17663           ip_set = 1;
17664           is_ip4 = 0;
17665           nh_sw_if_index = ~0;
17666         }
17667       else if (unformat (i, "table %d", &table_id))
17668         ;
17669       else
17670         {
17671           errmsg ("parse error '%U'", format_unformat_error, i);
17672           return -99;
17673         }
17674     }
17675
17676   if (!ip_set)
17677     {
17678       errmsg ("nh addr not set!");
17679       return -99;
17680     }
17681
17682   M (GPE_ADD_DEL_NATIVE_FWD_RPATH, mp);
17683   mp->is_add = is_add;
17684   mp->table_id = clib_host_to_net_u32 (table_id);
17685   mp->nh_sw_if_index = clib_host_to_net_u32 (nh_sw_if_index);
17686   mp->is_ip4 = is_ip4;
17687   if (is_ip4)
17688     clib_memcpy (mp->nh_addr, &ip4, sizeof (ip4));
17689   else
17690     clib_memcpy (mp->nh_addr, &ip6, sizeof (ip6));
17691
17692   /* send it... */
17693   S (mp);
17694
17695   /* Wait for a reply... */
17696   W (ret);
17697   return ret;
17698 }
17699
17700 static int
17701 api_one_map_server_dump (vat_main_t * vam)
17702 {
17703   vl_api_one_map_server_dump_t *mp;
17704   vl_api_control_ping_t *mp_ping;
17705   int ret;
17706
17707   if (!vam->json_output)
17708     {
17709       print (vam->ofp, "%=20s", "Map server");
17710     }
17711
17712   M (ONE_MAP_SERVER_DUMP, mp);
17713   /* send it... */
17714   S (mp);
17715
17716   /* Use a control ping for synchronization */
17717   MPING (CONTROL_PING, mp_ping);
17718   S (mp_ping);
17719
17720   /* Wait for a reply... */
17721   W (ret);
17722   return ret;
17723 }
17724
17725 #define api_lisp_map_server_dump api_one_map_server_dump
17726
17727 static int
17728 api_one_map_resolver_dump (vat_main_t * vam)
17729 {
17730   vl_api_one_map_resolver_dump_t *mp;
17731   vl_api_control_ping_t *mp_ping;
17732   int ret;
17733
17734   if (!vam->json_output)
17735     {
17736       print (vam->ofp, "%=20s", "Map resolver");
17737     }
17738
17739   M (ONE_MAP_RESOLVER_DUMP, mp);
17740   /* send it... */
17741   S (mp);
17742
17743   /* Use a control ping for synchronization */
17744   MPING (CONTROL_PING, mp_ping);
17745   S (mp_ping);
17746
17747   /* Wait for a reply... */
17748   W (ret);
17749   return ret;
17750 }
17751
17752 #define api_lisp_map_resolver_dump api_one_map_resolver_dump
17753
17754 static int
17755 api_one_stats_flush (vat_main_t * vam)
17756 {
17757   vl_api_one_stats_flush_t *mp;
17758   int ret = 0;
17759
17760   M (ONE_STATS_FLUSH, mp);
17761   S (mp);
17762   W (ret);
17763   return ret;
17764 }
17765
17766 static int
17767 api_one_stats_dump (vat_main_t * vam)
17768 {
17769   vl_api_one_stats_dump_t *mp;
17770   vl_api_control_ping_t *mp_ping;
17771   int ret;
17772
17773   M (ONE_STATS_DUMP, mp);
17774   /* send it... */
17775   S (mp);
17776
17777   /* Use a control ping for synchronization */
17778   MPING (CONTROL_PING, mp_ping);
17779   S (mp_ping);
17780
17781   /* Wait for a reply... */
17782   W (ret);
17783   return ret;
17784 }
17785
17786 static int
17787 api_show_one_status (vat_main_t * vam)
17788 {
17789   vl_api_show_one_status_t *mp;
17790   int ret;
17791
17792   if (!vam->json_output)
17793     {
17794       print (vam->ofp, "%-20s%-16s", "ONE status", "locator-set");
17795     }
17796
17797   M (SHOW_ONE_STATUS, mp);
17798   /* send it... */
17799   S (mp);
17800   /* Wait for a reply... */
17801   W (ret);
17802   return ret;
17803 }
17804
17805 #define api_show_lisp_status api_show_one_status
17806
17807 static int
17808 api_lisp_gpe_fwd_entry_path_dump (vat_main_t * vam)
17809 {
17810   vl_api_gpe_fwd_entry_path_dump_t *mp;
17811   vl_api_control_ping_t *mp_ping;
17812   unformat_input_t *i = vam->input;
17813   u32 fwd_entry_index = ~0;
17814   int ret;
17815
17816   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17817     {
17818       if (unformat (i, "index %d", &fwd_entry_index))
17819         ;
17820       else
17821         break;
17822     }
17823
17824   if (~0 == fwd_entry_index)
17825     {
17826       errmsg ("no index specified!");
17827       return -99;
17828     }
17829
17830   if (!vam->json_output)
17831     {
17832       print (vam->ofp, "first line");
17833     }
17834
17835   M (GPE_FWD_ENTRY_PATH_DUMP, mp);
17836
17837   /* send it... */
17838   S (mp);
17839   /* Use a control ping for synchronization */
17840   MPING (CONTROL_PING, mp_ping);
17841   S (mp_ping);
17842
17843   /* Wait for a reply... */
17844   W (ret);
17845   return ret;
17846 }
17847
17848 static int
17849 api_one_get_map_request_itr_rlocs (vat_main_t * vam)
17850 {
17851   vl_api_one_get_map_request_itr_rlocs_t *mp;
17852   int ret;
17853
17854   if (!vam->json_output)
17855     {
17856       print (vam->ofp, "%=20s", "itr-rlocs:");
17857     }
17858
17859   M (ONE_GET_MAP_REQUEST_ITR_RLOCS, mp);
17860   /* send it... */
17861   S (mp);
17862   /* Wait for a reply... */
17863   W (ret);
17864   return ret;
17865 }
17866
17867 #define api_lisp_get_map_request_itr_rlocs api_one_get_map_request_itr_rlocs
17868
17869 static int
17870 api_af_packet_create (vat_main_t * vam)
17871 {
17872   unformat_input_t *i = vam->input;
17873   vl_api_af_packet_create_t *mp;
17874   u8 *host_if_name = 0;
17875   u8 hw_addr[6];
17876   u8 random_hw_addr = 1;
17877   int ret;
17878
17879   clib_memset (hw_addr, 0, sizeof (hw_addr));
17880
17881   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17882     {
17883       if (unformat (i, "name %s", &host_if_name))
17884         vec_add1 (host_if_name, 0);
17885       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
17886         random_hw_addr = 0;
17887       else
17888         break;
17889     }
17890
17891   if (!vec_len (host_if_name))
17892     {
17893       errmsg ("host-interface name must be specified");
17894       return -99;
17895     }
17896
17897   if (vec_len (host_if_name) > 64)
17898     {
17899       errmsg ("host-interface name too long");
17900       return -99;
17901     }
17902
17903   M (AF_PACKET_CREATE, mp);
17904
17905   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
17906   clib_memcpy (mp->hw_addr, hw_addr, 6);
17907   mp->use_random_hw_addr = random_hw_addr;
17908   vec_free (host_if_name);
17909
17910   S (mp);
17911
17912   /* *INDENT-OFF* */
17913   W2 (ret,
17914       ({
17915         if (ret == 0)
17916           fprintf (vam->ofp ? vam->ofp : stderr,
17917                    " new sw_if_index = %d\n", vam->sw_if_index);
17918       }));
17919   /* *INDENT-ON* */
17920   return ret;
17921 }
17922
17923 static int
17924 api_af_packet_delete (vat_main_t * vam)
17925 {
17926   unformat_input_t *i = vam->input;
17927   vl_api_af_packet_delete_t *mp;
17928   u8 *host_if_name = 0;
17929   int ret;
17930
17931   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17932     {
17933       if (unformat (i, "name %s", &host_if_name))
17934         vec_add1 (host_if_name, 0);
17935       else
17936         break;
17937     }
17938
17939   if (!vec_len (host_if_name))
17940     {
17941       errmsg ("host-interface name must be specified");
17942       return -99;
17943     }
17944
17945   if (vec_len (host_if_name) > 64)
17946     {
17947       errmsg ("host-interface name too long");
17948       return -99;
17949     }
17950
17951   M (AF_PACKET_DELETE, mp);
17952
17953   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
17954   vec_free (host_if_name);
17955
17956   S (mp);
17957   W (ret);
17958   return ret;
17959 }
17960
17961 static void vl_api_af_packet_details_t_handler
17962   (vl_api_af_packet_details_t * mp)
17963 {
17964   vat_main_t *vam = &vat_main;
17965
17966   print (vam->ofp, "%-16s %d",
17967          mp->host_if_name, clib_net_to_host_u32 (mp->sw_if_index));
17968 }
17969
17970 static void vl_api_af_packet_details_t_handler_json
17971   (vl_api_af_packet_details_t * mp)
17972 {
17973   vat_main_t *vam = &vat_main;
17974   vat_json_node_t *node = NULL;
17975
17976   if (VAT_JSON_ARRAY != vam->json_tree.type)
17977     {
17978       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17979       vat_json_init_array (&vam->json_tree);
17980     }
17981   node = vat_json_array_add (&vam->json_tree);
17982
17983   vat_json_init_object (node);
17984   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
17985   vat_json_object_add_string_copy (node, "dev_name", mp->host_if_name);
17986 }
17987
17988 static int
17989 api_af_packet_dump (vat_main_t * vam)
17990 {
17991   vl_api_af_packet_dump_t *mp;
17992   vl_api_control_ping_t *mp_ping;
17993   int ret;
17994
17995   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
17996   /* Get list of tap interfaces */
17997   M (AF_PACKET_DUMP, mp);
17998   S (mp);
17999
18000   /* Use a control ping for synchronization */
18001   MPING (CONTROL_PING, mp_ping);
18002   S (mp_ping);
18003
18004   W (ret);
18005   return ret;
18006 }
18007
18008 static int
18009 api_policer_add_del (vat_main_t * vam)
18010 {
18011   unformat_input_t *i = vam->input;
18012   vl_api_policer_add_del_t *mp;
18013   u8 is_add = 1;
18014   u8 *name = 0;
18015   u32 cir = 0;
18016   u32 eir = 0;
18017   u64 cb = 0;
18018   u64 eb = 0;
18019   u8 rate_type = 0;
18020   u8 round_type = 0;
18021   u8 type = 0;
18022   u8 color_aware = 0;
18023   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
18024   int ret;
18025
18026   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
18027   conform_action.dscp = 0;
18028   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
18029   exceed_action.dscp = 0;
18030   violate_action.action_type = SSE2_QOS_ACTION_DROP;
18031   violate_action.dscp = 0;
18032
18033   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18034     {
18035       if (unformat (i, "del"))
18036         is_add = 0;
18037       else if (unformat (i, "name %s", &name))
18038         vec_add1 (name, 0);
18039       else if (unformat (i, "cir %u", &cir))
18040         ;
18041       else if (unformat (i, "eir %u", &eir))
18042         ;
18043       else if (unformat (i, "cb %u", &cb))
18044         ;
18045       else if (unformat (i, "eb %u", &eb))
18046         ;
18047       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
18048                          &rate_type))
18049         ;
18050       else if (unformat (i, "round_type %U", unformat_policer_round_type,
18051                          &round_type))
18052         ;
18053       else if (unformat (i, "type %U", unformat_policer_type, &type))
18054         ;
18055       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
18056                          &conform_action))
18057         ;
18058       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
18059                          &exceed_action))
18060         ;
18061       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
18062                          &violate_action))
18063         ;
18064       else if (unformat (i, "color-aware"))
18065         color_aware = 1;
18066       else
18067         break;
18068     }
18069
18070   if (!vec_len (name))
18071     {
18072       errmsg ("policer name must be specified");
18073       return -99;
18074     }
18075
18076   if (vec_len (name) > 64)
18077     {
18078       errmsg ("policer name too long");
18079       return -99;
18080     }
18081
18082   M (POLICER_ADD_DEL, mp);
18083
18084   clib_memcpy (mp->name, name, vec_len (name));
18085   vec_free (name);
18086   mp->is_add = is_add;
18087   mp->cir = ntohl (cir);
18088   mp->eir = ntohl (eir);
18089   mp->cb = clib_net_to_host_u64 (cb);
18090   mp->eb = clib_net_to_host_u64 (eb);
18091   mp->rate_type = rate_type;
18092   mp->round_type = round_type;
18093   mp->type = type;
18094   mp->conform_action_type = conform_action.action_type;
18095   mp->conform_dscp = conform_action.dscp;
18096   mp->exceed_action_type = exceed_action.action_type;
18097   mp->exceed_dscp = exceed_action.dscp;
18098   mp->violate_action_type = violate_action.action_type;
18099   mp->violate_dscp = violate_action.dscp;
18100   mp->color_aware = color_aware;
18101
18102   S (mp);
18103   W (ret);
18104   return ret;
18105 }
18106
18107 static int
18108 api_policer_dump (vat_main_t * vam)
18109 {
18110   unformat_input_t *i = vam->input;
18111   vl_api_policer_dump_t *mp;
18112   vl_api_control_ping_t *mp_ping;
18113   u8 *match_name = 0;
18114   u8 match_name_valid = 0;
18115   int ret;
18116
18117   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18118     {
18119       if (unformat (i, "name %s", &match_name))
18120         {
18121           vec_add1 (match_name, 0);
18122           match_name_valid = 1;
18123         }
18124       else
18125         break;
18126     }
18127
18128   M (POLICER_DUMP, mp);
18129   mp->match_name_valid = match_name_valid;
18130   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
18131   vec_free (match_name);
18132   /* send it... */
18133   S (mp);
18134
18135   /* Use a control ping for synchronization */
18136   MPING (CONTROL_PING, mp_ping);
18137   S (mp_ping);
18138
18139   /* Wait for a reply... */
18140   W (ret);
18141   return ret;
18142 }
18143
18144 static int
18145 api_policer_classify_set_interface (vat_main_t * vam)
18146 {
18147   unformat_input_t *i = vam->input;
18148   vl_api_policer_classify_set_interface_t *mp;
18149   u32 sw_if_index;
18150   int sw_if_index_set;
18151   u32 ip4_table_index = ~0;
18152   u32 ip6_table_index = ~0;
18153   u32 l2_table_index = ~0;
18154   u8 is_add = 1;
18155   int ret;
18156
18157   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18158     {
18159       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18160         sw_if_index_set = 1;
18161       else if (unformat (i, "sw_if_index %d", &sw_if_index))
18162         sw_if_index_set = 1;
18163       else if (unformat (i, "del"))
18164         is_add = 0;
18165       else if (unformat (i, "ip4-table %d", &ip4_table_index))
18166         ;
18167       else if (unformat (i, "ip6-table %d", &ip6_table_index))
18168         ;
18169       else if (unformat (i, "l2-table %d", &l2_table_index))
18170         ;
18171       else
18172         {
18173           clib_warning ("parse error '%U'", format_unformat_error, i);
18174           return -99;
18175         }
18176     }
18177
18178   if (sw_if_index_set == 0)
18179     {
18180       errmsg ("missing interface name or sw_if_index");
18181       return -99;
18182     }
18183
18184   M (POLICER_CLASSIFY_SET_INTERFACE, mp);
18185
18186   mp->sw_if_index = ntohl (sw_if_index);
18187   mp->ip4_table_index = ntohl (ip4_table_index);
18188   mp->ip6_table_index = ntohl (ip6_table_index);
18189   mp->l2_table_index = ntohl (l2_table_index);
18190   mp->is_add = is_add;
18191
18192   S (mp);
18193   W (ret);
18194   return ret;
18195 }
18196
18197 static int
18198 api_policer_classify_dump (vat_main_t * vam)
18199 {
18200   unformat_input_t *i = vam->input;
18201   vl_api_policer_classify_dump_t *mp;
18202   vl_api_control_ping_t *mp_ping;
18203   u8 type = POLICER_CLASSIFY_N_TABLES;
18204   int ret;
18205
18206   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
18207     ;
18208   else
18209     {
18210       errmsg ("classify table type must be specified");
18211       return -99;
18212     }
18213
18214   if (!vam->json_output)
18215     {
18216       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
18217     }
18218
18219   M (POLICER_CLASSIFY_DUMP, mp);
18220   mp->type = type;
18221   /* send it... */
18222   S (mp);
18223
18224   /* Use a control ping for synchronization */
18225   MPING (CONTROL_PING, mp_ping);
18226   S (mp_ping);
18227
18228   /* Wait for a reply... */
18229   W (ret);
18230   return ret;
18231 }
18232
18233 static int
18234 api_netmap_create (vat_main_t * vam)
18235 {
18236   unformat_input_t *i = vam->input;
18237   vl_api_netmap_create_t *mp;
18238   u8 *if_name = 0;
18239   u8 hw_addr[6];
18240   u8 random_hw_addr = 1;
18241   u8 is_pipe = 0;
18242   u8 is_master = 0;
18243   int ret;
18244
18245   clib_memset (hw_addr, 0, sizeof (hw_addr));
18246
18247   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18248     {
18249       if (unformat (i, "name %s", &if_name))
18250         vec_add1 (if_name, 0);
18251       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
18252         random_hw_addr = 0;
18253       else if (unformat (i, "pipe"))
18254         is_pipe = 1;
18255       else if (unformat (i, "master"))
18256         is_master = 1;
18257       else if (unformat (i, "slave"))
18258         is_master = 0;
18259       else
18260         break;
18261     }
18262
18263   if (!vec_len (if_name))
18264     {
18265       errmsg ("interface name must be specified");
18266       return -99;
18267     }
18268
18269   if (vec_len (if_name) > 64)
18270     {
18271       errmsg ("interface name too long");
18272       return -99;
18273     }
18274
18275   M (NETMAP_CREATE, mp);
18276
18277   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
18278   clib_memcpy (mp->hw_addr, hw_addr, 6);
18279   mp->use_random_hw_addr = random_hw_addr;
18280   mp->is_pipe = is_pipe;
18281   mp->is_master = is_master;
18282   vec_free (if_name);
18283
18284   S (mp);
18285   W (ret);
18286   return ret;
18287 }
18288
18289 static int
18290 api_netmap_delete (vat_main_t * vam)
18291 {
18292   unformat_input_t *i = vam->input;
18293   vl_api_netmap_delete_t *mp;
18294   u8 *if_name = 0;
18295   int ret;
18296
18297   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18298     {
18299       if (unformat (i, "name %s", &if_name))
18300         vec_add1 (if_name, 0);
18301       else
18302         break;
18303     }
18304
18305   if (!vec_len (if_name))
18306     {
18307       errmsg ("interface name must be specified");
18308       return -99;
18309     }
18310
18311   if (vec_len (if_name) > 64)
18312     {
18313       errmsg ("interface name too long");
18314       return -99;
18315     }
18316
18317   M (NETMAP_DELETE, mp);
18318
18319   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
18320   vec_free (if_name);
18321
18322   S (mp);
18323   W (ret);
18324   return ret;
18325 }
18326
18327 static u8 *
18328 format_fib_api_path_nh_proto (u8 * s, va_list * args)
18329 {
18330   vl_api_fib_path_nh_proto_t proto =
18331     va_arg (*args, vl_api_fib_path_nh_proto_t);
18332
18333   switch (proto)
18334     {
18335     case FIB_API_PATH_NH_PROTO_IP4:
18336       s = format (s, "ip4");
18337       break;
18338     case FIB_API_PATH_NH_PROTO_IP6:
18339       s = format (s, "ip6");
18340       break;
18341     case FIB_API_PATH_NH_PROTO_MPLS:
18342       s = format (s, "mpls");
18343       break;
18344     case FIB_API_PATH_NH_PROTO_BIER:
18345       s = format (s, "bier");
18346       break;
18347     case FIB_API_PATH_NH_PROTO_ETHERNET:
18348       s = format (s, "ethernet");
18349       break;
18350     }
18351
18352   return (s);
18353 }
18354
18355 static u8 *
18356 format_vl_api_ip_address_union (u8 * s, va_list * args)
18357 {
18358   vl_api_address_family_t af = va_arg (*args, vl_api_address_family_t);
18359   const vl_api_address_union_t *u = va_arg (*args, vl_api_address_union_t *);
18360
18361   switch (af)
18362     {
18363     case ADDRESS_IP4:
18364       s = format (s, "%U", format_ip4_address, u->ip4);
18365       break;
18366     case ADDRESS_IP6:
18367       s = format (s, "%U", format_ip6_address, u->ip6);
18368       break;
18369     }
18370   return (s);
18371 }
18372
18373 static u8 *
18374 format_vl_api_fib_path_type (u8 * s, va_list * args)
18375 {
18376   vl_api_fib_path_type_t t = va_arg (*args, vl_api_fib_path_type_t);
18377
18378   switch (t)
18379     {
18380     case FIB_API_PATH_TYPE_NORMAL:
18381       s = format (s, "normal");
18382       break;
18383     case FIB_API_PATH_TYPE_LOCAL:
18384       s = format (s, "local");
18385       break;
18386     case FIB_API_PATH_TYPE_DROP:
18387       s = format (s, "drop");
18388       break;
18389     case FIB_API_PATH_TYPE_UDP_ENCAP:
18390       s = format (s, "udp-encap");
18391       break;
18392     case FIB_API_PATH_TYPE_BIER_IMP:
18393       s = format (s, "bier-imp");
18394       break;
18395     case FIB_API_PATH_TYPE_ICMP_UNREACH:
18396       s = format (s, "unreach");
18397       break;
18398     case FIB_API_PATH_TYPE_ICMP_PROHIBIT:
18399       s = format (s, "prohibit");
18400       break;
18401     case FIB_API_PATH_TYPE_SOURCE_LOOKUP:
18402       s = format (s, "src-lookup");
18403       break;
18404     case FIB_API_PATH_TYPE_DVR:
18405       s = format (s, "dvr");
18406       break;
18407     case FIB_API_PATH_TYPE_INTERFACE_RX:
18408       s = format (s, "interface-rx");
18409       break;
18410     case FIB_API_PATH_TYPE_CLASSIFY:
18411       s = format (s, "classify");
18412       break;
18413     }
18414
18415   return (s);
18416 }
18417
18418 static void
18419 vl_api_fib_path_print (vat_main_t * vam, vl_api_fib_path_t * fp)
18420 {
18421   print (vam->ofp,
18422          "  weight %d, sw_if_index %d, type %U, afi %U, next_hop %U",
18423          ntohl (fp->weight), ntohl (fp->sw_if_index),
18424          format_vl_api_fib_path_type, fp->type,
18425          format_fib_api_path_nh_proto, fp->proto,
18426          format_vl_api_ip_address_union, &fp->nh.address);
18427 }
18428
18429 static void
18430 vl_api_mpls_fib_path_json_print (vat_json_node_t * node,
18431                                  vl_api_fib_path_t * fp)
18432 {
18433   struct in_addr ip4;
18434   struct in6_addr ip6;
18435
18436   vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
18437   vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
18438   vat_json_object_add_uint (node, "type", fp->type);
18439   vat_json_object_add_uint (node, "next_hop_proto", fp->proto);
18440   if (fp->proto == FIB_API_PATH_NH_PROTO_IP4)
18441     {
18442       clib_memcpy (&ip4, &fp->nh.address.ip4, sizeof (ip4));
18443       vat_json_object_add_ip4 (node, "next_hop", ip4);
18444     }
18445   else if (fp->proto == FIB_API_PATH_NH_PROTO_IP4)
18446     {
18447       clib_memcpy (&ip6, &fp->nh.address.ip6, sizeof (ip6));
18448       vat_json_object_add_ip6 (node, "next_hop", ip6);
18449     }
18450 }
18451
18452 static void
18453 vl_api_mpls_tunnel_details_t_handler (vl_api_mpls_tunnel_details_t * mp)
18454 {
18455   vat_main_t *vam = &vat_main;
18456   int count = ntohl (mp->mt_tunnel.mt_n_paths);
18457   vl_api_fib_path_t *fp;
18458   i32 i;
18459
18460   print (vam->ofp, "sw_if_index %d via:",
18461          ntohl (mp->mt_tunnel.mt_sw_if_index));
18462   fp = mp->mt_tunnel.mt_paths;
18463   for (i = 0; i < count; i++)
18464     {
18465       vl_api_fib_path_print (vam, fp);
18466       fp++;
18467     }
18468
18469   print (vam->ofp, "");
18470 }
18471
18472 #define vl_api_mpls_tunnel_details_t_endian vl_noop_handler
18473 #define vl_api_mpls_tunnel_details_t_print vl_noop_handler
18474
18475 static void
18476 vl_api_mpls_tunnel_details_t_handler_json (vl_api_mpls_tunnel_details_t * mp)
18477 {
18478   vat_main_t *vam = &vat_main;
18479   vat_json_node_t *node = NULL;
18480   int count = ntohl (mp->mt_tunnel.mt_n_paths);
18481   vl_api_fib_path_t *fp;
18482   i32 i;
18483
18484   if (VAT_JSON_ARRAY != vam->json_tree.type)
18485     {
18486       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18487       vat_json_init_array (&vam->json_tree);
18488     }
18489   node = vat_json_array_add (&vam->json_tree);
18490
18491   vat_json_init_object (node);
18492   vat_json_object_add_uint (node, "sw_if_index",
18493                             ntohl (mp->mt_tunnel.mt_sw_if_index));
18494
18495   vat_json_object_add_uint (node, "l2_only", mp->mt_tunnel.mt_l2_only);
18496
18497   fp = mp->mt_tunnel.mt_paths;
18498   for (i = 0; i < count; i++)
18499     {
18500       vl_api_mpls_fib_path_json_print (node, fp);
18501       fp++;
18502     }
18503 }
18504
18505 static int
18506 api_mpls_tunnel_dump (vat_main_t * vam)
18507 {
18508   vl_api_mpls_tunnel_dump_t *mp;
18509   vl_api_control_ping_t *mp_ping;
18510   int ret;
18511
18512   M (MPLS_TUNNEL_DUMP, mp);
18513
18514   S (mp);
18515
18516   /* Use a control ping for synchronization */
18517   MPING (CONTROL_PING, mp_ping);
18518   S (mp_ping);
18519
18520   W (ret);
18521   return ret;
18522 }
18523
18524 #define vl_api_mpls_table_details_t_endian vl_noop_handler
18525 #define vl_api_mpls_table_details_t_print vl_noop_handler
18526
18527
18528 static void
18529 vl_api_mpls_table_details_t_handler (vl_api_mpls_table_details_t * mp)
18530 {
18531   vat_main_t *vam = &vat_main;
18532
18533   print (vam->ofp, "table-id %d,", ntohl (mp->mt_table.mt_table_id));
18534 }
18535
18536 static void vl_api_mpls_table_details_t_handler_json
18537   (vl_api_mpls_table_details_t * mp)
18538 {
18539   vat_main_t *vam = &vat_main;
18540   vat_json_node_t *node = NULL;
18541
18542   if (VAT_JSON_ARRAY != vam->json_tree.type)
18543     {
18544       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18545       vat_json_init_array (&vam->json_tree);
18546     }
18547   node = vat_json_array_add (&vam->json_tree);
18548
18549   vat_json_init_object (node);
18550   vat_json_object_add_uint (node, "table", ntohl (mp->mt_table.mt_table_id));
18551 }
18552
18553 static int
18554 api_mpls_table_dump (vat_main_t * vam)
18555 {
18556   vl_api_mpls_table_dump_t *mp;
18557   vl_api_control_ping_t *mp_ping;
18558   int ret;
18559
18560   M (MPLS_TABLE_DUMP, mp);
18561   S (mp);
18562
18563   /* Use a control ping for synchronization */
18564   MPING (CONTROL_PING, mp_ping);
18565   S (mp_ping);
18566
18567   W (ret);
18568   return ret;
18569 }
18570
18571 #define vl_api_mpls_route_details_t_endian vl_noop_handler
18572 #define vl_api_mpls_route_details_t_print vl_noop_handler
18573
18574 static void
18575 vl_api_mpls_route_details_t_handler (vl_api_mpls_route_details_t * mp)
18576 {
18577   vat_main_t *vam = &vat_main;
18578   int count = (int) clib_net_to_host_u32 (mp->mr_route.mr_n_paths);
18579   vl_api_fib_path_t *fp;
18580   int i;
18581
18582   print (vam->ofp,
18583          "table-id %d, label %u, ess_bit %u",
18584          ntohl (mp->mr_route.mr_table_id),
18585          ntohl (mp->mr_route.mr_label), mp->mr_route.mr_eos);
18586   fp = mp->mr_route.mr_paths;
18587   for (i = 0; i < count; i++)
18588     {
18589       vl_api_fib_path_print (vam, fp);
18590       fp++;
18591     }
18592 }
18593
18594 static void vl_api_mpls_route_details_t_handler_json
18595   (vl_api_mpls_route_details_t * mp)
18596 {
18597   vat_main_t *vam = &vat_main;
18598   int count = (int) clib_host_to_net_u32 (mp->mr_route.mr_n_paths);
18599   vat_json_node_t *node = NULL;
18600   vl_api_fib_path_t *fp;
18601   int i;
18602
18603   if (VAT_JSON_ARRAY != vam->json_tree.type)
18604     {
18605       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18606       vat_json_init_array (&vam->json_tree);
18607     }
18608   node = vat_json_array_add (&vam->json_tree);
18609
18610   vat_json_init_object (node);
18611   vat_json_object_add_uint (node, "table", ntohl (mp->mr_route.mr_table_id));
18612   vat_json_object_add_uint (node, "s_bit", mp->mr_route.mr_eos);
18613   vat_json_object_add_uint (node, "label", ntohl (mp->mr_route.mr_label));
18614   vat_json_object_add_uint (node, "path_count", count);
18615   fp = mp->mr_route.mr_paths;
18616   for (i = 0; i < count; i++)
18617     {
18618       vl_api_mpls_fib_path_json_print (node, fp);
18619       fp++;
18620     }
18621 }
18622
18623 static int
18624 api_mpls_route_dump (vat_main_t * vam)
18625 {
18626   unformat_input_t *input = vam->input;
18627   vl_api_mpls_route_dump_t *mp;
18628   vl_api_control_ping_t *mp_ping;
18629   u32 table_id;
18630   int ret;
18631
18632   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18633     {
18634       if (unformat (input, "table_id %d", &table_id))
18635         ;
18636       else
18637         break;
18638     }
18639   if (table_id == ~0)
18640     {
18641       errmsg ("missing table id");
18642       return -99;
18643     }
18644
18645   M (MPLS_ROUTE_DUMP, mp);
18646
18647   mp->table.mt_table_id = ntohl (table_id);
18648   S (mp);
18649
18650   /* Use a control ping for synchronization */
18651   MPING (CONTROL_PING, mp_ping);
18652   S (mp_ping);
18653
18654   W (ret);
18655   return ret;
18656 }
18657
18658 #define vl_api_ip_table_details_t_endian vl_noop_handler
18659 #define vl_api_ip_table_details_t_print vl_noop_handler
18660
18661 static void
18662 vl_api_ip_table_details_t_handler (vl_api_ip_table_details_t * mp)
18663 {
18664   vat_main_t *vam = &vat_main;
18665
18666   print (vam->ofp,
18667          "%s; table-id %d, prefix %U/%d",
18668          mp->table.name, ntohl (mp->table.table_id));
18669 }
18670
18671
18672 static void vl_api_ip_table_details_t_handler_json
18673   (vl_api_ip_table_details_t * mp)
18674 {
18675   vat_main_t *vam = &vat_main;
18676   vat_json_node_t *node = NULL;
18677
18678   if (VAT_JSON_ARRAY != vam->json_tree.type)
18679     {
18680       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18681       vat_json_init_array (&vam->json_tree);
18682     }
18683   node = vat_json_array_add (&vam->json_tree);
18684
18685   vat_json_init_object (node);
18686   vat_json_object_add_uint (node, "table", ntohl (mp->table.table_id));
18687 }
18688
18689 static int
18690 api_ip_table_dump (vat_main_t * vam)
18691 {
18692   vl_api_ip_table_dump_t *mp;
18693   vl_api_control_ping_t *mp_ping;
18694   int ret;
18695
18696   M (IP_TABLE_DUMP, mp);
18697   S (mp);
18698
18699   /* Use a control ping for synchronization */
18700   MPING (CONTROL_PING, mp_ping);
18701   S (mp_ping);
18702
18703   W (ret);
18704   return ret;
18705 }
18706
18707 static int
18708 api_ip_mtable_dump (vat_main_t * vam)
18709 {
18710   vl_api_ip_mtable_dump_t *mp;
18711   vl_api_control_ping_t *mp_ping;
18712   int ret;
18713
18714   M (IP_MTABLE_DUMP, mp);
18715   S (mp);
18716
18717   /* Use a control ping for synchronization */
18718   MPING (CONTROL_PING, mp_ping);
18719   S (mp_ping);
18720
18721   W (ret);
18722   return ret;
18723 }
18724
18725 static int
18726 api_ip_mroute_dump (vat_main_t * vam)
18727 {
18728   unformat_input_t *input = vam->input;
18729   vl_api_control_ping_t *mp_ping;
18730   vl_api_ip_mroute_dump_t *mp;
18731   int ret, is_ip6;
18732   u32 table_id;
18733
18734   is_ip6 = 0;
18735   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18736     {
18737       if (unformat (input, "table_id %d", &table_id))
18738         ;
18739       else if (unformat (input, "ip6"))
18740         is_ip6 = 1;
18741       else if (unformat (input, "ip4"))
18742         is_ip6 = 0;
18743       else
18744         break;
18745     }
18746   if (table_id == ~0)
18747     {
18748       errmsg ("missing table id");
18749       return -99;
18750     }
18751
18752   M (IP_MROUTE_DUMP, mp);
18753   mp->table.table_id = table_id;
18754   mp->table.is_ip6 = is_ip6;
18755   S (mp);
18756
18757   /* Use a control ping for synchronization */
18758   MPING (CONTROL_PING, mp_ping);
18759   S (mp_ping);
18760
18761   W (ret);
18762   return ret;
18763 }
18764
18765 static void vl_api_ip_neighbor_details_t_handler
18766   (vl_api_ip_neighbor_details_t * mp)
18767 {
18768   vat_main_t *vam = &vat_main;
18769
18770   print (vam->ofp, "%c %U %U",
18771          (ntohl (mp->neighbor.flags) & IP_NEIGHBOR_FLAG_STATIC) ? 'S' : 'D',
18772          format_vl_api_mac_address, &mp->neighbor.mac_address,
18773          format_vl_api_address, &mp->neighbor.ip_address);
18774 }
18775
18776 static void vl_api_ip_neighbor_details_t_handler_json
18777   (vl_api_ip_neighbor_details_t * mp)
18778 {
18779
18780   vat_main_t *vam = &vat_main;
18781   vat_json_node_t *node;
18782
18783   if (VAT_JSON_ARRAY != vam->json_tree.type)
18784     {
18785       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18786       vat_json_init_array (&vam->json_tree);
18787     }
18788   node = vat_json_array_add (&vam->json_tree);
18789
18790   vat_json_init_object (node);
18791   vat_json_object_add_string_copy
18792     (node, "flag",
18793      ((ntohl (mp->neighbor.flags) & IP_NEIGHBOR_FLAG_STATIC) ?
18794       (u8 *) "static" : (u8 *) "dynamic"));
18795
18796   vat_json_object_add_string_copy (node, "link_layer",
18797                                    format (0, "%U", format_vl_api_mac_address,
18798                                            &mp->neighbor.mac_address));
18799   vat_json_object_add_address (node, "ip", &mp->neighbor.ip_address);
18800 }
18801
18802 static int
18803 api_ip_neighbor_dump (vat_main_t * vam)
18804 {
18805   unformat_input_t *i = vam->input;
18806   vl_api_ip_neighbor_dump_t *mp;
18807   vl_api_control_ping_t *mp_ping;
18808   u8 is_ipv6 = 0;
18809   u32 sw_if_index = ~0;
18810   int ret;
18811
18812   /* Parse args required to build the message */
18813   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18814     {
18815       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18816         ;
18817       else if (unformat (i, "sw_if_index %d", &sw_if_index))
18818         ;
18819       else if (unformat (i, "ip6"))
18820         is_ipv6 = 1;
18821       else
18822         break;
18823     }
18824
18825   if (sw_if_index == ~0)
18826     {
18827       errmsg ("missing interface name or sw_if_index");
18828       return -99;
18829     }
18830
18831   M (IP_NEIGHBOR_DUMP, mp);
18832   mp->is_ipv6 = (u8) is_ipv6;
18833   mp->sw_if_index = ntohl (sw_if_index);
18834   S (mp);
18835
18836   /* Use a control ping for synchronization */
18837   MPING (CONTROL_PING, mp_ping);
18838   S (mp_ping);
18839
18840   W (ret);
18841   return ret;
18842 }
18843
18844 #define vl_api_ip_route_details_t_endian vl_noop_handler
18845 #define vl_api_ip_route_details_t_print vl_noop_handler
18846
18847 static void
18848 vl_api_ip_route_details_t_handler (vl_api_ip_route_details_t * mp)
18849 {
18850   vat_main_t *vam = &vat_main;
18851   u8 count = mp->route.n_paths;
18852   vl_api_fib_path_t *fp;
18853   int i;
18854
18855   print (vam->ofp,
18856          "table-id %d, prefix %U/%d",
18857          ntohl (mp->route.table_id),
18858          format_ip46_address, mp->route.prefix.address, mp->route.prefix.len);
18859   for (i = 0; i < count; i++)
18860     {
18861       fp = &mp->route.paths[i];
18862
18863       vl_api_fib_path_print (vam, fp);
18864       fp++;
18865     }
18866 }
18867
18868 static void vl_api_ip_route_details_t_handler_json
18869   (vl_api_ip_route_details_t * mp)
18870 {
18871   vat_main_t *vam = &vat_main;
18872   u8 count = mp->route.n_paths;
18873   vat_json_node_t *node = NULL;
18874   struct in_addr ip4;
18875   struct in6_addr ip6;
18876   vl_api_fib_path_t *fp;
18877   int i;
18878
18879   if (VAT_JSON_ARRAY != vam->json_tree.type)
18880     {
18881       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18882       vat_json_init_array (&vam->json_tree);
18883     }
18884   node = vat_json_array_add (&vam->json_tree);
18885
18886   vat_json_init_object (node);
18887   vat_json_object_add_uint (node, "table", ntohl (mp->route.table_id));
18888   if (ADDRESS_IP6 == mp->route.prefix.address.af)
18889     {
18890       clib_memcpy (&ip6, &mp->route.prefix.address.un.ip6, sizeof (ip6));
18891       vat_json_object_add_ip6 (node, "prefix", ip6);
18892     }
18893   else
18894     {
18895       clib_memcpy (&ip4, &mp->route.prefix.address.un.ip4, sizeof (ip4));
18896       vat_json_object_add_ip4 (node, "prefix", ip4);
18897     }
18898   vat_json_object_add_uint (node, "mask_length", mp->route.prefix.len);
18899   vat_json_object_add_uint (node, "path_count", count);
18900   for (i = 0; i < count; i++)
18901     {
18902       fp = &mp->route.paths[i];
18903       vl_api_mpls_fib_path_json_print (node, fp);
18904     }
18905 }
18906
18907 static int
18908 api_ip_route_dump (vat_main_t * vam)
18909 {
18910   unformat_input_t *input = vam->input;
18911   vl_api_ip_route_dump_t *mp;
18912   vl_api_control_ping_t *mp_ping;
18913   u32 table_id;
18914   u8 is_ip6;
18915   int ret;
18916
18917   is_ip6 = 0;
18918   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18919     {
18920       if (unformat (input, "table_id %d", &table_id))
18921         ;
18922       else if (unformat (input, "ip6"))
18923         is_ip6 = 1;
18924       else if (unformat (input, "ip4"))
18925         is_ip6 = 0;
18926       else
18927         break;
18928     }
18929   if (table_id == ~0)
18930     {
18931       errmsg ("missing table id");
18932       return -99;
18933     }
18934
18935   M (IP_ROUTE_DUMP, mp);
18936
18937   mp->table.table_id = table_id;
18938   mp->table.is_ip6 = is_ip6;
18939
18940   S (mp);
18941
18942   /* Use a control ping for synchronization */
18943   MPING (CONTROL_PING, mp_ping);
18944   S (mp_ping);
18945
18946   W (ret);
18947   return ret;
18948 }
18949
18950 int
18951 api_classify_table_ids (vat_main_t * vam)
18952 {
18953   vl_api_classify_table_ids_t *mp;
18954   int ret;
18955
18956   /* Construct the API message */
18957   M (CLASSIFY_TABLE_IDS, mp);
18958   mp->context = 0;
18959
18960   S (mp);
18961   W (ret);
18962   return ret;
18963 }
18964
18965 int
18966 api_classify_table_by_interface (vat_main_t * vam)
18967 {
18968   unformat_input_t *input = vam->input;
18969   vl_api_classify_table_by_interface_t *mp;
18970
18971   u32 sw_if_index = ~0;
18972   int ret;
18973   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18974     {
18975       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18976         ;
18977       else if (unformat (input, "sw_if_index %d", &sw_if_index))
18978         ;
18979       else
18980         break;
18981     }
18982   if (sw_if_index == ~0)
18983     {
18984       errmsg ("missing interface name or sw_if_index");
18985       return -99;
18986     }
18987
18988   /* Construct the API message */
18989   M (CLASSIFY_TABLE_BY_INTERFACE, mp);
18990   mp->context = 0;
18991   mp->sw_if_index = ntohl (sw_if_index);
18992
18993   S (mp);
18994   W (ret);
18995   return ret;
18996 }
18997
18998 int
18999 api_classify_table_info (vat_main_t * vam)
19000 {
19001   unformat_input_t *input = vam->input;
19002   vl_api_classify_table_info_t *mp;
19003
19004   u32 table_id = ~0;
19005   int ret;
19006   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19007     {
19008       if (unformat (input, "table_id %d", &table_id))
19009         ;
19010       else
19011         break;
19012     }
19013   if (table_id == ~0)
19014     {
19015       errmsg ("missing table id");
19016       return -99;
19017     }
19018
19019   /* Construct the API message */
19020   M (CLASSIFY_TABLE_INFO, mp);
19021   mp->context = 0;
19022   mp->table_id = ntohl (table_id);
19023
19024   S (mp);
19025   W (ret);
19026   return ret;
19027 }
19028
19029 int
19030 api_classify_session_dump (vat_main_t * vam)
19031 {
19032   unformat_input_t *input = vam->input;
19033   vl_api_classify_session_dump_t *mp;
19034   vl_api_control_ping_t *mp_ping;
19035
19036   u32 table_id = ~0;
19037   int ret;
19038   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19039     {
19040       if (unformat (input, "table_id %d", &table_id))
19041         ;
19042       else
19043         break;
19044     }
19045   if (table_id == ~0)
19046     {
19047       errmsg ("missing table id");
19048       return -99;
19049     }
19050
19051   /* Construct the API message */
19052   M (CLASSIFY_SESSION_DUMP, mp);
19053   mp->context = 0;
19054   mp->table_id = ntohl (table_id);
19055   S (mp);
19056
19057   /* Use a control ping for synchronization */
19058   MPING (CONTROL_PING, mp_ping);
19059   S (mp_ping);
19060
19061   W (ret);
19062   return ret;
19063 }
19064
19065 static void
19066 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
19067 {
19068   vat_main_t *vam = &vat_main;
19069
19070   print (vam->ofp, "collector_address %U, collector_port %d, "
19071          "src_address %U, vrf_id %d, path_mtu %u, "
19072          "template_interval %u, udp_checksum %d",
19073          format_ip4_address, mp->collector_address,
19074          ntohs (mp->collector_port),
19075          format_ip4_address, mp->src_address,
19076          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
19077          ntohl (mp->template_interval), mp->udp_checksum);
19078
19079   vam->retval = 0;
19080   vam->result_ready = 1;
19081 }
19082
19083 static void
19084   vl_api_ipfix_exporter_details_t_handler_json
19085   (vl_api_ipfix_exporter_details_t * mp)
19086 {
19087   vat_main_t *vam = &vat_main;
19088   vat_json_node_t node;
19089   struct in_addr collector_address;
19090   struct in_addr src_address;
19091
19092   vat_json_init_object (&node);
19093   clib_memcpy (&collector_address, &mp->collector_address,
19094                sizeof (collector_address));
19095   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
19096   vat_json_object_add_uint (&node, "collector_port",
19097                             ntohs (mp->collector_port));
19098   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
19099   vat_json_object_add_ip4 (&node, "src_address", src_address);
19100   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
19101   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
19102   vat_json_object_add_uint (&node, "template_interval",
19103                             ntohl (mp->template_interval));
19104   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
19105
19106   vat_json_print (vam->ofp, &node);
19107   vat_json_free (&node);
19108   vam->retval = 0;
19109   vam->result_ready = 1;
19110 }
19111
19112 int
19113 api_ipfix_exporter_dump (vat_main_t * vam)
19114 {
19115   vl_api_ipfix_exporter_dump_t *mp;
19116   int ret;
19117
19118   /* Construct the API message */
19119   M (IPFIX_EXPORTER_DUMP, mp);
19120   mp->context = 0;
19121
19122   S (mp);
19123   W (ret);
19124   return ret;
19125 }
19126
19127 static int
19128 api_ipfix_classify_stream_dump (vat_main_t * vam)
19129 {
19130   vl_api_ipfix_classify_stream_dump_t *mp;
19131   int ret;
19132
19133   /* Construct the API message */
19134   M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
19135   mp->context = 0;
19136
19137   S (mp);
19138   W (ret);
19139   return ret;
19140   /* NOTREACHED */
19141   return 0;
19142 }
19143
19144 static void
19145   vl_api_ipfix_classify_stream_details_t_handler
19146   (vl_api_ipfix_classify_stream_details_t * mp)
19147 {
19148   vat_main_t *vam = &vat_main;
19149   print (vam->ofp, "domain_id %d, src_port %d",
19150          ntohl (mp->domain_id), ntohs (mp->src_port));
19151   vam->retval = 0;
19152   vam->result_ready = 1;
19153 }
19154
19155 static void
19156   vl_api_ipfix_classify_stream_details_t_handler_json
19157   (vl_api_ipfix_classify_stream_details_t * mp)
19158 {
19159   vat_main_t *vam = &vat_main;
19160   vat_json_node_t node;
19161
19162   vat_json_init_object (&node);
19163   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
19164   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
19165
19166   vat_json_print (vam->ofp, &node);
19167   vat_json_free (&node);
19168   vam->retval = 0;
19169   vam->result_ready = 1;
19170 }
19171
19172 static int
19173 api_ipfix_classify_table_dump (vat_main_t * vam)
19174 {
19175   vl_api_ipfix_classify_table_dump_t *mp;
19176   vl_api_control_ping_t *mp_ping;
19177   int ret;
19178
19179   if (!vam->json_output)
19180     {
19181       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
19182              "transport_protocol");
19183     }
19184
19185   /* Construct the API message */
19186   M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
19187
19188   /* send it... */
19189   S (mp);
19190
19191   /* Use a control ping for synchronization */
19192   MPING (CONTROL_PING, mp_ping);
19193   S (mp_ping);
19194
19195   W (ret);
19196   return ret;
19197 }
19198
19199 static void
19200   vl_api_ipfix_classify_table_details_t_handler
19201   (vl_api_ipfix_classify_table_details_t * mp)
19202 {
19203   vat_main_t *vam = &vat_main;
19204   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
19205          mp->transport_protocol);
19206 }
19207
19208 static void
19209   vl_api_ipfix_classify_table_details_t_handler_json
19210   (vl_api_ipfix_classify_table_details_t * mp)
19211 {
19212   vat_json_node_t *node = NULL;
19213   vat_main_t *vam = &vat_main;
19214
19215   if (VAT_JSON_ARRAY != vam->json_tree.type)
19216     {
19217       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19218       vat_json_init_array (&vam->json_tree);
19219     }
19220
19221   node = vat_json_array_add (&vam->json_tree);
19222   vat_json_init_object (node);
19223
19224   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
19225   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
19226   vat_json_object_add_uint (node, "transport_protocol",
19227                             mp->transport_protocol);
19228 }
19229
19230 static int
19231 api_sw_interface_span_enable_disable (vat_main_t * vam)
19232 {
19233   unformat_input_t *i = vam->input;
19234   vl_api_sw_interface_span_enable_disable_t *mp;
19235   u32 src_sw_if_index = ~0;
19236   u32 dst_sw_if_index = ~0;
19237   u8 state = 3;
19238   int ret;
19239   u8 is_l2 = 0;
19240
19241   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19242     {
19243       if (unformat
19244           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
19245         ;
19246       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
19247         ;
19248       else
19249         if (unformat
19250             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
19251         ;
19252       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
19253         ;
19254       else if (unformat (i, "disable"))
19255         state = 0;
19256       else if (unformat (i, "rx"))
19257         state = 1;
19258       else if (unformat (i, "tx"))
19259         state = 2;
19260       else if (unformat (i, "both"))
19261         state = 3;
19262       else if (unformat (i, "l2"))
19263         is_l2 = 1;
19264       else
19265         break;
19266     }
19267
19268   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
19269
19270   mp->sw_if_index_from = htonl (src_sw_if_index);
19271   mp->sw_if_index_to = htonl (dst_sw_if_index);
19272   mp->state = state;
19273   mp->is_l2 = is_l2;
19274
19275   S (mp);
19276   W (ret);
19277   return ret;
19278 }
19279
19280 static void
19281 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
19282                                             * mp)
19283 {
19284   vat_main_t *vam = &vat_main;
19285   u8 *sw_if_from_name = 0;
19286   u8 *sw_if_to_name = 0;
19287   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
19288   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
19289   char *states[] = { "none", "rx", "tx", "both" };
19290   hash_pair_t *p;
19291
19292   /* *INDENT-OFF* */
19293   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
19294   ({
19295     if ((u32) p->value[0] == sw_if_index_from)
19296       {
19297         sw_if_from_name = (u8 *)(p->key);
19298         if (sw_if_to_name)
19299           break;
19300       }
19301     if ((u32) p->value[0] == sw_if_index_to)
19302       {
19303         sw_if_to_name = (u8 *)(p->key);
19304         if (sw_if_from_name)
19305           break;
19306       }
19307   }));
19308   /* *INDENT-ON* */
19309   print (vam->ofp, "%20s => %20s (%s) %s",
19310          sw_if_from_name, sw_if_to_name, states[mp->state],
19311          mp->is_l2 ? "l2" : "device");
19312 }
19313
19314 static void
19315   vl_api_sw_interface_span_details_t_handler_json
19316   (vl_api_sw_interface_span_details_t * mp)
19317 {
19318   vat_main_t *vam = &vat_main;
19319   vat_json_node_t *node = NULL;
19320   u8 *sw_if_from_name = 0;
19321   u8 *sw_if_to_name = 0;
19322   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
19323   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
19324   hash_pair_t *p;
19325
19326   /* *INDENT-OFF* */
19327   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
19328   ({
19329     if ((u32) p->value[0] == sw_if_index_from)
19330       {
19331         sw_if_from_name = (u8 *)(p->key);
19332         if (sw_if_to_name)
19333           break;
19334       }
19335     if ((u32) p->value[0] == sw_if_index_to)
19336       {
19337         sw_if_to_name = (u8 *)(p->key);
19338         if (sw_if_from_name)
19339           break;
19340       }
19341   }));
19342   /* *INDENT-ON* */
19343
19344   if (VAT_JSON_ARRAY != vam->json_tree.type)
19345     {
19346       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19347       vat_json_init_array (&vam->json_tree);
19348     }
19349   node = vat_json_array_add (&vam->json_tree);
19350
19351   vat_json_init_object (node);
19352   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
19353   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
19354   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
19355   if (0 != sw_if_to_name)
19356     {
19357       vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
19358     }
19359   vat_json_object_add_uint (node, "state", mp->state);
19360   vat_json_object_add_uint (node, "is-l2", mp->is_l2);
19361 }
19362
19363 static int
19364 api_sw_interface_span_dump (vat_main_t * vam)
19365 {
19366   unformat_input_t *input = vam->input;
19367   vl_api_sw_interface_span_dump_t *mp;
19368   vl_api_control_ping_t *mp_ping;
19369   u8 is_l2 = 0;
19370   int ret;
19371
19372   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19373     {
19374       if (unformat (input, "l2"))
19375         is_l2 = 1;
19376       else
19377         break;
19378     }
19379
19380   M (SW_INTERFACE_SPAN_DUMP, mp);
19381   mp->is_l2 = is_l2;
19382   S (mp);
19383
19384   /* Use a control ping for synchronization */
19385   MPING (CONTROL_PING, mp_ping);
19386   S (mp_ping);
19387
19388   W (ret);
19389   return ret;
19390 }
19391
19392 int
19393 api_pg_create_interface (vat_main_t * vam)
19394 {
19395   unformat_input_t *input = vam->input;
19396   vl_api_pg_create_interface_t *mp;
19397
19398   u32 if_id = ~0, gso_size = 0;
19399   u8 gso_enabled = 0;
19400   int ret;
19401   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19402     {
19403       if (unformat (input, "if_id %d", &if_id))
19404         ;
19405       else if (unformat (input, "gso-enabled"))
19406         {
19407           gso_enabled = 1;
19408           if (unformat (input, "gso-size %u", &gso_size))
19409             ;
19410           else
19411             {
19412               errmsg ("missing gso-size");
19413               return -99;
19414             }
19415         }
19416       else
19417         break;
19418     }
19419   if (if_id == ~0)
19420     {
19421       errmsg ("missing pg interface index");
19422       return -99;
19423     }
19424
19425   /* Construct the API message */
19426   M (PG_CREATE_INTERFACE, mp);
19427   mp->context = 0;
19428   mp->interface_id = ntohl (if_id);
19429   mp->gso_enabled = gso_enabled;
19430
19431   S (mp);
19432   W (ret);
19433   return ret;
19434 }
19435
19436 int
19437 api_pg_capture (vat_main_t * vam)
19438 {
19439   unformat_input_t *input = vam->input;
19440   vl_api_pg_capture_t *mp;
19441
19442   u32 if_id = ~0;
19443   u8 enable = 1;
19444   u32 count = 1;
19445   u8 pcap_file_set = 0;
19446   u8 *pcap_file = 0;
19447   int ret;
19448   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19449     {
19450       if (unformat (input, "if_id %d", &if_id))
19451         ;
19452       else if (unformat (input, "pcap %s", &pcap_file))
19453         pcap_file_set = 1;
19454       else if (unformat (input, "count %d", &count))
19455         ;
19456       else if (unformat (input, "disable"))
19457         enable = 0;
19458       else
19459         break;
19460     }
19461   if (if_id == ~0)
19462     {
19463       errmsg ("missing pg interface index");
19464       return -99;
19465     }
19466   if (pcap_file_set > 0)
19467     {
19468       if (vec_len (pcap_file) > 255)
19469         {
19470           errmsg ("pcap file name is too long");
19471           return -99;
19472         }
19473     }
19474
19475   u32 name_len = vec_len (pcap_file);
19476   /* Construct the API message */
19477   M (PG_CAPTURE, mp);
19478   mp->context = 0;
19479   mp->interface_id = ntohl (if_id);
19480   mp->is_enabled = enable;
19481   mp->count = ntohl (count);
19482   mp->pcap_name_length = ntohl (name_len);
19483   if (pcap_file_set != 0)
19484     {
19485       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
19486     }
19487   vec_free (pcap_file);
19488
19489   S (mp);
19490   W (ret);
19491   return ret;
19492 }
19493
19494 int
19495 api_pg_enable_disable (vat_main_t * vam)
19496 {
19497   unformat_input_t *input = vam->input;
19498   vl_api_pg_enable_disable_t *mp;
19499
19500   u8 enable = 1;
19501   u8 stream_name_set = 0;
19502   u8 *stream_name = 0;
19503   int ret;
19504   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19505     {
19506       if (unformat (input, "stream %s", &stream_name))
19507         stream_name_set = 1;
19508       else if (unformat (input, "disable"))
19509         enable = 0;
19510       else
19511         break;
19512     }
19513
19514   if (stream_name_set > 0)
19515     {
19516       if (vec_len (stream_name) > 255)
19517         {
19518           errmsg ("stream name too long");
19519           return -99;
19520         }
19521     }
19522
19523   u32 name_len = vec_len (stream_name);
19524   /* Construct the API message */
19525   M (PG_ENABLE_DISABLE, mp);
19526   mp->context = 0;
19527   mp->is_enabled = enable;
19528   if (stream_name_set != 0)
19529     {
19530       mp->stream_name_length = ntohl (name_len);
19531       clib_memcpy (mp->stream_name, stream_name, name_len);
19532     }
19533   vec_free (stream_name);
19534
19535   S (mp);
19536   W (ret);
19537   return ret;
19538 }
19539
19540 int
19541 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
19542 {
19543   unformat_input_t *input = vam->input;
19544   vl_api_ip_source_and_port_range_check_add_del_t *mp;
19545
19546   u16 *low_ports = 0;
19547   u16 *high_ports = 0;
19548   u16 this_low;
19549   u16 this_hi;
19550   vl_api_prefix_t prefix;
19551   u32 tmp, tmp2;
19552   u8 prefix_set = 0;
19553   u32 vrf_id = ~0;
19554   u8 is_add = 1;
19555   int ret;
19556
19557   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19558     {
19559       if (unformat (input, "%U", unformat_vl_api_prefix, &prefix))
19560         prefix_set = 1;
19561       else if (unformat (input, "vrf %d", &vrf_id))
19562         ;
19563       else if (unformat (input, "del"))
19564         is_add = 0;
19565       else if (unformat (input, "port %d", &tmp))
19566         {
19567           if (tmp == 0 || tmp > 65535)
19568             {
19569               errmsg ("port %d out of range", tmp);
19570               return -99;
19571             }
19572           this_low = tmp;
19573           this_hi = this_low + 1;
19574           vec_add1 (low_ports, this_low);
19575           vec_add1 (high_ports, this_hi);
19576         }
19577       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
19578         {
19579           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
19580             {
19581               errmsg ("incorrect range parameters");
19582               return -99;
19583             }
19584           this_low = tmp;
19585           /* Note: in debug CLI +1 is added to high before
19586              passing to real fn that does "the work"
19587              (ip_source_and_port_range_check_add_del).
19588              This fn is a wrapper around the binary API fn a
19589              control plane will call, which expects this increment
19590              to have occurred. Hence letting the binary API control
19591              plane fn do the increment for consistency between VAT
19592              and other control planes.
19593            */
19594           this_hi = tmp2;
19595           vec_add1 (low_ports, this_low);
19596           vec_add1 (high_ports, this_hi);
19597         }
19598       else
19599         break;
19600     }
19601
19602   if (prefix_set == 0)
19603     {
19604       errmsg ("<address>/<mask> not specified");
19605       return -99;
19606     }
19607
19608   if (vrf_id == ~0)
19609     {
19610       errmsg ("VRF ID required, not specified");
19611       return -99;
19612     }
19613
19614   if (vrf_id == 0)
19615     {
19616       errmsg
19617         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
19618       return -99;
19619     }
19620
19621   if (vec_len (low_ports) == 0)
19622     {
19623       errmsg ("At least one port or port range required");
19624       return -99;
19625     }
19626
19627   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
19628
19629   mp->is_add = is_add;
19630
19631   clib_memcpy (&mp->prefix, &prefix, sizeof (prefix));
19632
19633   mp->number_of_ranges = vec_len (low_ports);
19634
19635   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
19636   vec_free (low_ports);
19637
19638   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
19639   vec_free (high_ports);
19640
19641   mp->vrf_id = ntohl (vrf_id);
19642
19643   S (mp);
19644   W (ret);
19645   return ret;
19646 }
19647
19648 int
19649 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
19650 {
19651   unformat_input_t *input = vam->input;
19652   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
19653   u32 sw_if_index = ~0;
19654   int vrf_set = 0;
19655   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
19656   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
19657   u8 is_add = 1;
19658   int ret;
19659
19660   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19661     {
19662       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19663         ;
19664       else if (unformat (input, "sw_if_index %d", &sw_if_index))
19665         ;
19666       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
19667         vrf_set = 1;
19668       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
19669         vrf_set = 1;
19670       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
19671         vrf_set = 1;
19672       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
19673         vrf_set = 1;
19674       else if (unformat (input, "del"))
19675         is_add = 0;
19676       else
19677         break;
19678     }
19679
19680   if (sw_if_index == ~0)
19681     {
19682       errmsg ("Interface required but not specified");
19683       return -99;
19684     }
19685
19686   if (vrf_set == 0)
19687     {
19688       errmsg ("VRF ID required but not specified");
19689       return -99;
19690     }
19691
19692   if (tcp_out_vrf_id == 0
19693       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
19694     {
19695       errmsg
19696         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
19697       return -99;
19698     }
19699
19700   /* Construct the API message */
19701   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
19702
19703   mp->sw_if_index = ntohl (sw_if_index);
19704   mp->is_add = is_add;
19705   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
19706   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
19707   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
19708   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
19709
19710   /* send it... */
19711   S (mp);
19712
19713   /* Wait for a reply... */
19714   W (ret);
19715   return ret;
19716 }
19717
19718 static int
19719 api_set_punt (vat_main_t * vam)
19720 {
19721   unformat_input_t *i = vam->input;
19722   vl_api_address_family_t af;
19723   vl_api_set_punt_t *mp;
19724   u32 protocol = ~0;
19725   u32 port = ~0;
19726   int is_add = 1;
19727   int ret;
19728
19729   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19730     {
19731       if (unformat (i, "%U", unformat_vl_api_address_family, &af))
19732         ;
19733       else if (unformat (i, "protocol %d", &protocol))
19734         ;
19735       else if (unformat (i, "port %d", &port))
19736         ;
19737       else if (unformat (i, "del"))
19738         is_add = 0;
19739       else
19740         {
19741           clib_warning ("parse error '%U'", format_unformat_error, i);
19742           return -99;
19743         }
19744     }
19745
19746   M (SET_PUNT, mp);
19747
19748   mp->is_add = (u8) is_add;
19749   mp->punt.type = PUNT_API_TYPE_L4;
19750   mp->punt.punt.l4.af = af;
19751   mp->punt.punt.l4.protocol = (u8) protocol;
19752   mp->punt.punt.l4.port = htons ((u16) port);
19753
19754   S (mp);
19755   W (ret);
19756   return ret;
19757 }
19758
19759 static int
19760 api_delete_subif (vat_main_t * vam)
19761 {
19762   unformat_input_t *i = vam->input;
19763   vl_api_delete_subif_t *mp;
19764   u32 sw_if_index = ~0;
19765   int ret;
19766
19767   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19768     {
19769       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19770         ;
19771       if (unformat (i, "sw_if_index %d", &sw_if_index))
19772         ;
19773       else
19774         break;
19775     }
19776
19777   if (sw_if_index == ~0)
19778     {
19779       errmsg ("missing sw_if_index");
19780       return -99;
19781     }
19782
19783   /* Construct the API message */
19784   M (DELETE_SUBIF, mp);
19785   mp->sw_if_index = ntohl (sw_if_index);
19786
19787   S (mp);
19788   W (ret);
19789   return ret;
19790 }
19791
19792 #define foreach_pbb_vtr_op      \
19793 _("disable",  L2_VTR_DISABLED)  \
19794 _("pop",  L2_VTR_POP_2)         \
19795 _("push",  L2_VTR_PUSH_2)
19796
19797 static int
19798 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
19799 {
19800   unformat_input_t *i = vam->input;
19801   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
19802   u32 sw_if_index = ~0, vtr_op = ~0;
19803   u16 outer_tag = ~0;
19804   u8 dmac[6], smac[6];
19805   u8 dmac_set = 0, smac_set = 0;
19806   u16 vlanid = 0;
19807   u32 sid = ~0;
19808   u32 tmp;
19809   int ret;
19810
19811   /* Shut up coverity */
19812   clib_memset (dmac, 0, sizeof (dmac));
19813   clib_memset (smac, 0, sizeof (smac));
19814
19815   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19816     {
19817       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19818         ;
19819       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19820         ;
19821       else if (unformat (i, "vtr_op %d", &vtr_op))
19822         ;
19823 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
19824       foreach_pbb_vtr_op
19825 #undef _
19826         else if (unformat (i, "translate_pbb_stag"))
19827         {
19828           if (unformat (i, "%d", &tmp))
19829             {
19830               vtr_op = L2_VTR_TRANSLATE_2_1;
19831               outer_tag = tmp;
19832             }
19833           else
19834             {
19835               errmsg
19836                 ("translate_pbb_stag operation requires outer tag definition");
19837               return -99;
19838             }
19839         }
19840       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
19841         dmac_set++;
19842       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
19843         smac_set++;
19844       else if (unformat (i, "sid %d", &sid))
19845         ;
19846       else if (unformat (i, "vlanid %d", &tmp))
19847         vlanid = tmp;
19848       else
19849         {
19850           clib_warning ("parse error '%U'", format_unformat_error, i);
19851           return -99;
19852         }
19853     }
19854
19855   if ((sw_if_index == ~0) || (vtr_op == ~0))
19856     {
19857       errmsg ("missing sw_if_index or vtr operation");
19858       return -99;
19859     }
19860   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
19861       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
19862     {
19863       errmsg
19864         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
19865       return -99;
19866     }
19867
19868   M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
19869   mp->sw_if_index = ntohl (sw_if_index);
19870   mp->vtr_op = ntohl (vtr_op);
19871   mp->outer_tag = ntohs (outer_tag);
19872   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
19873   clib_memcpy (mp->b_smac, smac, sizeof (smac));
19874   mp->b_vlanid = ntohs (vlanid);
19875   mp->i_sid = ntohl (sid);
19876
19877   S (mp);
19878   W (ret);
19879   return ret;
19880 }
19881
19882 static int
19883 api_flow_classify_set_interface (vat_main_t * vam)
19884 {
19885   unformat_input_t *i = vam->input;
19886   vl_api_flow_classify_set_interface_t *mp;
19887   u32 sw_if_index;
19888   int sw_if_index_set;
19889   u32 ip4_table_index = ~0;
19890   u32 ip6_table_index = ~0;
19891   u8 is_add = 1;
19892   int ret;
19893
19894   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19895     {
19896       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19897         sw_if_index_set = 1;
19898       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19899         sw_if_index_set = 1;
19900       else if (unformat (i, "del"))
19901         is_add = 0;
19902       else if (unformat (i, "ip4-table %d", &ip4_table_index))
19903         ;
19904       else if (unformat (i, "ip6-table %d", &ip6_table_index))
19905         ;
19906       else
19907         {
19908           clib_warning ("parse error '%U'", format_unformat_error, i);
19909           return -99;
19910         }
19911     }
19912
19913   if (sw_if_index_set == 0)
19914     {
19915       errmsg ("missing interface name or sw_if_index");
19916       return -99;
19917     }
19918
19919   M (FLOW_CLASSIFY_SET_INTERFACE, mp);
19920
19921   mp->sw_if_index = ntohl (sw_if_index);
19922   mp->ip4_table_index = ntohl (ip4_table_index);
19923   mp->ip6_table_index = ntohl (ip6_table_index);
19924   mp->is_add = is_add;
19925
19926   S (mp);
19927   W (ret);
19928   return ret;
19929 }
19930
19931 static int
19932 api_flow_classify_dump (vat_main_t * vam)
19933 {
19934   unformat_input_t *i = vam->input;
19935   vl_api_flow_classify_dump_t *mp;
19936   vl_api_control_ping_t *mp_ping;
19937   u8 type = FLOW_CLASSIFY_N_TABLES;
19938   int ret;
19939
19940   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
19941     ;
19942   else
19943     {
19944       errmsg ("classify table type must be specified");
19945       return -99;
19946     }
19947
19948   if (!vam->json_output)
19949     {
19950       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
19951     }
19952
19953   M (FLOW_CLASSIFY_DUMP, mp);
19954   mp->type = type;
19955   /* send it... */
19956   S (mp);
19957
19958   /* Use a control ping for synchronization */
19959   MPING (CONTROL_PING, mp_ping);
19960   S (mp_ping);
19961
19962   /* Wait for a reply... */
19963   W (ret);
19964   return ret;
19965 }
19966
19967 static int
19968 api_feature_enable_disable (vat_main_t * vam)
19969 {
19970   unformat_input_t *i = vam->input;
19971   vl_api_feature_enable_disable_t *mp;
19972   u8 *arc_name = 0;
19973   u8 *feature_name = 0;
19974   u32 sw_if_index = ~0;
19975   u8 enable = 1;
19976   int ret;
19977
19978   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19979     {
19980       if (unformat (i, "arc_name %s", &arc_name))
19981         ;
19982       else if (unformat (i, "feature_name %s", &feature_name))
19983         ;
19984       else
19985         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19986         ;
19987       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19988         ;
19989       else if (unformat (i, "disable"))
19990         enable = 0;
19991       else
19992         break;
19993     }
19994
19995   if (arc_name == 0)
19996     {
19997       errmsg ("missing arc name");
19998       return -99;
19999     }
20000   if (vec_len (arc_name) > 63)
20001     {
20002       errmsg ("arc name too long");
20003     }
20004
20005   if (feature_name == 0)
20006     {
20007       errmsg ("missing feature name");
20008       return -99;
20009     }
20010   if (vec_len (feature_name) > 63)
20011     {
20012       errmsg ("feature name too long");
20013     }
20014
20015   if (sw_if_index == ~0)
20016     {
20017       errmsg ("missing interface name or sw_if_index");
20018       return -99;
20019     }
20020
20021   /* Construct the API message */
20022   M (FEATURE_ENABLE_DISABLE, mp);
20023   mp->sw_if_index = ntohl (sw_if_index);
20024   mp->enable = enable;
20025   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
20026   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
20027   vec_free (arc_name);
20028   vec_free (feature_name);
20029
20030   S (mp);
20031   W (ret);
20032   return ret;
20033 }
20034
20035 static int
20036 api_feature_gso_enable_disable (vat_main_t * vam)
20037 {
20038   unformat_input_t *i = vam->input;
20039   vl_api_feature_gso_enable_disable_t *mp;
20040   u32 sw_if_index = ~0;
20041   u8 enable = 1;
20042   int ret;
20043
20044   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20045     {
20046       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20047         ;
20048       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20049         ;
20050       else if (unformat (i, "enable"))
20051         enable = 1;
20052       else if (unformat (i, "disable"))
20053         enable = 0;
20054       else
20055         break;
20056     }
20057
20058   if (sw_if_index == ~0)
20059     {
20060       errmsg ("missing interface name or sw_if_index");
20061       return -99;
20062     }
20063
20064   /* Construct the API message */
20065   M (FEATURE_GSO_ENABLE_DISABLE, mp);
20066   mp->sw_if_index = ntohl (sw_if_index);
20067   mp->enable_disable = enable;
20068
20069   S (mp);
20070   W (ret);
20071   return ret;
20072 }
20073
20074 static int
20075 api_sw_interface_tag_add_del (vat_main_t * vam)
20076 {
20077   unformat_input_t *i = vam->input;
20078   vl_api_sw_interface_tag_add_del_t *mp;
20079   u32 sw_if_index = ~0;
20080   u8 *tag = 0;
20081   u8 enable = 1;
20082   int ret;
20083
20084   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20085     {
20086       if (unformat (i, "tag %s", &tag))
20087         ;
20088       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20089         ;
20090       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20091         ;
20092       else if (unformat (i, "del"))
20093         enable = 0;
20094       else
20095         break;
20096     }
20097
20098   if (sw_if_index == ~0)
20099     {
20100       errmsg ("missing interface name or sw_if_index");
20101       return -99;
20102     }
20103
20104   if (enable && (tag == 0))
20105     {
20106       errmsg ("no tag specified");
20107       return -99;
20108     }
20109
20110   /* Construct the API message */
20111   M (SW_INTERFACE_TAG_ADD_DEL, mp);
20112   mp->sw_if_index = ntohl (sw_if_index);
20113   mp->is_add = enable;
20114   if (enable)
20115     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
20116   vec_free (tag);
20117
20118   S (mp);
20119   W (ret);
20120   return ret;
20121 }
20122
20123 static int
20124 api_sw_interface_add_del_mac_address (vat_main_t * vam)
20125 {
20126   unformat_input_t *i = vam->input;
20127   vl_api_mac_address_t mac = { 0 };
20128   vl_api_sw_interface_add_del_mac_address_t *mp;
20129   u32 sw_if_index = ~0;
20130   u8 is_add = 1;
20131   u8 mac_set = 0;
20132   int ret;
20133
20134   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20135     {
20136       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20137         ;
20138       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20139         ;
20140       else if (unformat (i, "%U", unformat_vl_api_mac_address, &mac))
20141         mac_set++;
20142       else if (unformat (i, "del"))
20143         is_add = 0;
20144       else
20145         break;
20146     }
20147
20148   if (sw_if_index == ~0)
20149     {
20150       errmsg ("missing interface name or sw_if_index");
20151       return -99;
20152     }
20153
20154   if (!mac_set)
20155     {
20156       errmsg ("missing MAC address");
20157       return -99;
20158     }
20159
20160   /* Construct the API message */
20161   M (SW_INTERFACE_ADD_DEL_MAC_ADDRESS, mp);
20162   mp->sw_if_index = ntohl (sw_if_index);
20163   mp->is_add = is_add;
20164   clib_memcpy (&mp->addr, &mac, sizeof (mac));
20165
20166   S (mp);
20167   W (ret);
20168   return ret;
20169 }
20170
20171 static void vl_api_l2_xconnect_details_t_handler
20172   (vl_api_l2_xconnect_details_t * mp)
20173 {
20174   vat_main_t *vam = &vat_main;
20175
20176   print (vam->ofp, "%15d%15d",
20177          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
20178 }
20179
20180 static void vl_api_l2_xconnect_details_t_handler_json
20181   (vl_api_l2_xconnect_details_t * mp)
20182 {
20183   vat_main_t *vam = &vat_main;
20184   vat_json_node_t *node = NULL;
20185
20186   if (VAT_JSON_ARRAY != vam->json_tree.type)
20187     {
20188       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20189       vat_json_init_array (&vam->json_tree);
20190     }
20191   node = vat_json_array_add (&vam->json_tree);
20192
20193   vat_json_init_object (node);
20194   vat_json_object_add_uint (node, "rx_sw_if_index",
20195                             ntohl (mp->rx_sw_if_index));
20196   vat_json_object_add_uint (node, "tx_sw_if_index",
20197                             ntohl (mp->tx_sw_if_index));
20198 }
20199
20200 static int
20201 api_l2_xconnect_dump (vat_main_t * vam)
20202 {
20203   vl_api_l2_xconnect_dump_t *mp;
20204   vl_api_control_ping_t *mp_ping;
20205   int ret;
20206
20207   if (!vam->json_output)
20208     {
20209       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
20210     }
20211
20212   M (L2_XCONNECT_DUMP, mp);
20213
20214   S (mp);
20215
20216   /* Use a control ping for synchronization */
20217   MPING (CONTROL_PING, mp_ping);
20218   S (mp_ping);
20219
20220   W (ret);
20221   return ret;
20222 }
20223
20224 static int
20225 api_hw_interface_set_mtu (vat_main_t * vam)
20226 {
20227   unformat_input_t *i = vam->input;
20228   vl_api_hw_interface_set_mtu_t *mp;
20229   u32 sw_if_index = ~0;
20230   u32 mtu = 0;
20231   int ret;
20232
20233   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20234     {
20235       if (unformat (i, "mtu %d", &mtu))
20236         ;
20237       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20238         ;
20239       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20240         ;
20241       else
20242         break;
20243     }
20244
20245   if (sw_if_index == ~0)
20246     {
20247       errmsg ("missing interface name or sw_if_index");
20248       return -99;
20249     }
20250
20251   if (mtu == 0)
20252     {
20253       errmsg ("no mtu specified");
20254       return -99;
20255     }
20256
20257   /* Construct the API message */
20258   M (HW_INTERFACE_SET_MTU, mp);
20259   mp->sw_if_index = ntohl (sw_if_index);
20260   mp->mtu = ntohs ((u16) mtu);
20261
20262   S (mp);
20263   W (ret);
20264   return ret;
20265 }
20266
20267 static int
20268 api_p2p_ethernet_add (vat_main_t * vam)
20269 {
20270   unformat_input_t *i = vam->input;
20271   vl_api_p2p_ethernet_add_t *mp;
20272   u32 parent_if_index = ~0;
20273   u32 sub_id = ~0;
20274   u8 remote_mac[6];
20275   u8 mac_set = 0;
20276   int ret;
20277
20278   clib_memset (remote_mac, 0, sizeof (remote_mac));
20279   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20280     {
20281       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
20282         ;
20283       else if (unformat (i, "sw_if_index %d", &parent_if_index))
20284         ;
20285       else
20286         if (unformat
20287             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
20288         mac_set++;
20289       else if (unformat (i, "sub_id %d", &sub_id))
20290         ;
20291       else
20292         {
20293           clib_warning ("parse error '%U'", format_unformat_error, i);
20294           return -99;
20295         }
20296     }
20297
20298   if (parent_if_index == ~0)
20299     {
20300       errmsg ("missing interface name or sw_if_index");
20301       return -99;
20302     }
20303   if (mac_set == 0)
20304     {
20305       errmsg ("missing remote mac address");
20306       return -99;
20307     }
20308   if (sub_id == ~0)
20309     {
20310       errmsg ("missing sub-interface id");
20311       return -99;
20312     }
20313
20314   M (P2P_ETHERNET_ADD, mp);
20315   mp->parent_if_index = ntohl (parent_if_index);
20316   mp->subif_id = ntohl (sub_id);
20317   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
20318
20319   S (mp);
20320   W (ret);
20321   return ret;
20322 }
20323
20324 static int
20325 api_p2p_ethernet_del (vat_main_t * vam)
20326 {
20327   unformat_input_t *i = vam->input;
20328   vl_api_p2p_ethernet_del_t *mp;
20329   u32 parent_if_index = ~0;
20330   u8 remote_mac[6];
20331   u8 mac_set = 0;
20332   int ret;
20333
20334   clib_memset (remote_mac, 0, sizeof (remote_mac));
20335   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20336     {
20337       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
20338         ;
20339       else if (unformat (i, "sw_if_index %d", &parent_if_index))
20340         ;
20341       else
20342         if (unformat
20343             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
20344         mac_set++;
20345       else
20346         {
20347           clib_warning ("parse error '%U'", format_unformat_error, i);
20348           return -99;
20349         }
20350     }
20351
20352   if (parent_if_index == ~0)
20353     {
20354       errmsg ("missing interface name or sw_if_index");
20355       return -99;
20356     }
20357   if (mac_set == 0)
20358     {
20359       errmsg ("missing remote mac address");
20360       return -99;
20361     }
20362
20363   M (P2P_ETHERNET_DEL, mp);
20364   mp->parent_if_index = ntohl (parent_if_index);
20365   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
20366
20367   S (mp);
20368   W (ret);
20369   return ret;
20370 }
20371
20372 static int
20373 api_lldp_config (vat_main_t * vam)
20374 {
20375   unformat_input_t *i = vam->input;
20376   vl_api_lldp_config_t *mp;
20377   int tx_hold = 0;
20378   int tx_interval = 0;
20379   u8 *sys_name = NULL;
20380   int ret;
20381
20382   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20383     {
20384       if (unformat (i, "system-name %s", &sys_name))
20385         ;
20386       else if (unformat (i, "tx-hold %d", &tx_hold))
20387         ;
20388       else if (unformat (i, "tx-interval %d", &tx_interval))
20389         ;
20390       else
20391         {
20392           clib_warning ("parse error '%U'", format_unformat_error, i);
20393           return -99;
20394         }
20395     }
20396
20397   vec_add1 (sys_name, 0);
20398
20399   M (LLDP_CONFIG, mp);
20400   mp->tx_hold = htonl (tx_hold);
20401   mp->tx_interval = htonl (tx_interval);
20402   clib_memcpy (mp->system_name, sys_name, vec_len (sys_name));
20403   vec_free (sys_name);
20404
20405   S (mp);
20406   W (ret);
20407   return ret;
20408 }
20409
20410 static int
20411 api_sw_interface_set_lldp (vat_main_t * vam)
20412 {
20413   unformat_input_t *i = vam->input;
20414   vl_api_sw_interface_set_lldp_t *mp;
20415   u32 sw_if_index = ~0;
20416   u32 enable = 1;
20417   u8 *port_desc = NULL, *mgmt_oid = NULL;
20418   ip4_address_t ip4_addr;
20419   ip6_address_t ip6_addr;
20420   int ret;
20421
20422   clib_memset (&ip4_addr, 0, sizeof (ip4_addr));
20423   clib_memset (&ip6_addr, 0, sizeof (ip6_addr));
20424
20425   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20426     {
20427       if (unformat (i, "disable"))
20428         enable = 0;
20429       else
20430         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20431         ;
20432       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20433         ;
20434       else if (unformat (i, "port-desc %s", &port_desc))
20435         ;
20436       else if (unformat (i, "mgmt-ip4 %U", unformat_ip4_address, &ip4_addr))
20437         ;
20438       else if (unformat (i, "mgmt-ip6 %U", unformat_ip6_address, &ip6_addr))
20439         ;
20440       else if (unformat (i, "mgmt-oid %s", &mgmt_oid))
20441         ;
20442       else
20443         break;
20444     }
20445
20446   if (sw_if_index == ~0)
20447     {
20448       errmsg ("missing interface name or sw_if_index");
20449       return -99;
20450     }
20451
20452   /* Construct the API message */
20453   vec_add1 (port_desc, 0);
20454   vec_add1 (mgmt_oid, 0);
20455   M (SW_INTERFACE_SET_LLDP, mp);
20456   mp->sw_if_index = ntohl (sw_if_index);
20457   mp->enable = enable;
20458   clib_memcpy (mp->port_desc, port_desc, vec_len (port_desc));
20459   clib_memcpy (mp->mgmt_oid, mgmt_oid, vec_len (mgmt_oid));
20460   clib_memcpy (mp->mgmt_ip4, &ip4_addr, sizeof (ip4_addr));
20461   clib_memcpy (mp->mgmt_ip6, &ip6_addr, sizeof (ip6_addr));
20462   vec_free (port_desc);
20463   vec_free (mgmt_oid);
20464
20465   S (mp);
20466   W (ret);
20467   return ret;
20468 }
20469
20470 static int
20471 api_tcp_configure_src_addresses (vat_main_t * vam)
20472 {
20473   vl_api_tcp_configure_src_addresses_t *mp;
20474   unformat_input_t *i = vam->input;
20475   ip4_address_t v4first, v4last;
20476   ip6_address_t v6first, v6last;
20477   u8 range_set = 0;
20478   u32 vrf_id = 0;
20479   int ret;
20480
20481   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20482     {
20483       if (unformat (i, "%U - %U",
20484                     unformat_ip4_address, &v4first,
20485                     unformat_ip4_address, &v4last))
20486         {
20487           if (range_set)
20488             {
20489               errmsg ("one range per message (range already set)");
20490               return -99;
20491             }
20492           range_set = 1;
20493         }
20494       else if (unformat (i, "%U - %U",
20495                          unformat_ip6_address, &v6first,
20496                          unformat_ip6_address, &v6last))
20497         {
20498           if (range_set)
20499             {
20500               errmsg ("one range per message (range already set)");
20501               return -99;
20502             }
20503           range_set = 2;
20504         }
20505       else if (unformat (i, "vrf %d", &vrf_id))
20506         ;
20507       else
20508         break;
20509     }
20510
20511   if (range_set == 0)
20512     {
20513       errmsg ("address range not set");
20514       return -99;
20515     }
20516
20517   M (TCP_CONFIGURE_SRC_ADDRESSES, mp);
20518   mp->vrf_id = ntohl (vrf_id);
20519   /* ipv6? */
20520   if (range_set == 2)
20521     {
20522       mp->is_ipv6 = 1;
20523       clib_memcpy (mp->first_address, &v6first, sizeof (v6first));
20524       clib_memcpy (mp->last_address, &v6last, sizeof (v6last));
20525     }
20526   else
20527     {
20528       mp->is_ipv6 = 0;
20529       clib_memcpy (mp->first_address, &v4first, sizeof (v4first));
20530       clib_memcpy (mp->last_address, &v4last, sizeof (v4last));
20531     }
20532   S (mp);
20533   W (ret);
20534   return ret;
20535 }
20536
20537 static void vl_api_app_namespace_add_del_reply_t_handler
20538   (vl_api_app_namespace_add_del_reply_t * mp)
20539 {
20540   vat_main_t *vam = &vat_main;
20541   i32 retval = ntohl (mp->retval);
20542   if (vam->async_mode)
20543     {
20544       vam->async_errors += (retval < 0);
20545     }
20546   else
20547     {
20548       vam->retval = retval;
20549       if (retval == 0)
20550         errmsg ("app ns index %d\n", ntohl (mp->appns_index));
20551       vam->result_ready = 1;
20552     }
20553 }
20554
20555 static void vl_api_app_namespace_add_del_reply_t_handler_json
20556   (vl_api_app_namespace_add_del_reply_t * mp)
20557 {
20558   vat_main_t *vam = &vat_main;
20559   vat_json_node_t node;
20560
20561   vat_json_init_object (&node);
20562   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
20563   vat_json_object_add_uint (&node, "appns_index", ntohl (mp->appns_index));
20564
20565   vat_json_print (vam->ofp, &node);
20566   vat_json_free (&node);
20567
20568   vam->retval = ntohl (mp->retval);
20569   vam->result_ready = 1;
20570 }
20571
20572 static int
20573 api_app_namespace_add_del (vat_main_t * vam)
20574 {
20575   vl_api_app_namespace_add_del_t *mp;
20576   unformat_input_t *i = vam->input;
20577   u8 *ns_id = 0, secret_set = 0, sw_if_index_set = 0;
20578   u32 sw_if_index, ip4_fib_id, ip6_fib_id;
20579   u64 secret;
20580   int ret;
20581
20582   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20583     {
20584       if (unformat (i, "id %_%v%_", &ns_id))
20585         ;
20586       else if (unformat (i, "secret %lu", &secret))
20587         secret_set = 1;
20588       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20589         sw_if_index_set = 1;
20590       else if (unformat (i, "ip4_fib_id %d", &ip4_fib_id))
20591         ;
20592       else if (unformat (i, "ip6_fib_id %d", &ip6_fib_id))
20593         ;
20594       else
20595         break;
20596     }
20597   if (!ns_id || !secret_set || !sw_if_index_set)
20598     {
20599       errmsg ("namespace id, secret and sw_if_index must be set");
20600       return -99;
20601     }
20602   if (vec_len (ns_id) > 64)
20603     {
20604       errmsg ("namespace id too long");
20605       return -99;
20606     }
20607   M (APP_NAMESPACE_ADD_DEL, mp);
20608
20609   clib_memcpy (mp->namespace_id, ns_id, vec_len (ns_id));
20610   mp->namespace_id_len = vec_len (ns_id);
20611   mp->secret = clib_host_to_net_u64 (secret);
20612   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
20613   mp->ip4_fib_id = clib_host_to_net_u32 (ip4_fib_id);
20614   mp->ip6_fib_id = clib_host_to_net_u32 (ip6_fib_id);
20615   vec_free (ns_id);
20616   S (mp);
20617   W (ret);
20618   return ret;
20619 }
20620
20621 static int
20622 api_sock_init_shm (vat_main_t * vam)
20623 {
20624 #if VPP_API_TEST_BUILTIN == 0
20625   unformat_input_t *i = vam->input;
20626   vl_api_shm_elem_config_t *config = 0;
20627   u64 size = 64 << 20;
20628   int rv;
20629
20630   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20631     {
20632       if (unformat (i, "size %U", unformat_memory_size, &size))
20633         ;
20634       else
20635         break;
20636     }
20637
20638   /*
20639    * Canned custom ring allocator config.
20640    * Should probably parse all of this
20641    */
20642   vec_validate (config, 6);
20643   config[0].type = VL_API_VLIB_RING;
20644   config[0].size = 256;
20645   config[0].count = 32;
20646
20647   config[1].type = VL_API_VLIB_RING;
20648   config[1].size = 1024;
20649   config[1].count = 16;
20650
20651   config[2].type = VL_API_VLIB_RING;
20652   config[2].size = 4096;
20653   config[2].count = 2;
20654
20655   config[3].type = VL_API_CLIENT_RING;
20656   config[3].size = 256;
20657   config[3].count = 32;
20658
20659   config[4].type = VL_API_CLIENT_RING;
20660   config[4].size = 1024;
20661   config[4].count = 16;
20662
20663   config[5].type = VL_API_CLIENT_RING;
20664   config[5].size = 4096;
20665   config[5].count = 2;
20666
20667   config[6].type = VL_API_QUEUE;
20668   config[6].count = 128;
20669   config[6].size = sizeof (uword);
20670
20671   rv = vl_socket_client_init_shm (config, 1 /* want_pthread */ );
20672   if (!rv)
20673     vam->client_index_invalid = 1;
20674   return rv;
20675 #else
20676   return -99;
20677 #endif
20678 }
20679
20680 static void
20681 vl_api_session_rules_details_t_handler (vl_api_session_rules_details_t * mp)
20682 {
20683   vat_main_t *vam = &vat_main;
20684
20685   if (mp->is_ip4)
20686     {
20687       print (vam->ofp,
20688              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
20689              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
20690              mp->scope, format_ip4_address, &mp->lcl_ip, mp->lcl_plen,
20691              clib_net_to_host_u16 (mp->lcl_port), format_ip4_address,
20692              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
20693              clib_net_to_host_u32 (mp->action_index), mp->tag);
20694     }
20695   else
20696     {
20697       print (vam->ofp,
20698              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
20699              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
20700              mp->scope, format_ip6_address, &mp->lcl_ip, mp->lcl_plen,
20701              clib_net_to_host_u16 (mp->lcl_port), format_ip6_address,
20702              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
20703              clib_net_to_host_u32 (mp->action_index), mp->tag);
20704     }
20705 }
20706
20707 static void
20708 vl_api_session_rules_details_t_handler_json (vl_api_session_rules_details_t *
20709                                              mp)
20710 {
20711   vat_main_t *vam = &vat_main;
20712   vat_json_node_t *node = NULL;
20713   struct in6_addr ip6;
20714   struct in_addr ip4;
20715
20716   if (VAT_JSON_ARRAY != vam->json_tree.type)
20717     {
20718       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20719       vat_json_init_array (&vam->json_tree);
20720     }
20721   node = vat_json_array_add (&vam->json_tree);
20722   vat_json_init_object (node);
20723
20724   vat_json_object_add_uint (node, "is_ip4", mp->is_ip4 ? 1 : 0);
20725   vat_json_object_add_uint (node, "appns_index",
20726                             clib_net_to_host_u32 (mp->appns_index));
20727   vat_json_object_add_uint (node, "transport_proto", mp->transport_proto);
20728   vat_json_object_add_uint (node, "scope", mp->scope);
20729   vat_json_object_add_uint (node, "action_index",
20730                             clib_net_to_host_u32 (mp->action_index));
20731   vat_json_object_add_uint (node, "lcl_port",
20732                             clib_net_to_host_u16 (mp->lcl_port));
20733   vat_json_object_add_uint (node, "rmt_port",
20734                             clib_net_to_host_u16 (mp->rmt_port));
20735   vat_json_object_add_uint (node, "lcl_plen", mp->lcl_plen);
20736   vat_json_object_add_uint (node, "rmt_plen", mp->rmt_plen);
20737   vat_json_object_add_string_copy (node, "tag", mp->tag);
20738   if (mp->is_ip4)
20739     {
20740       clib_memcpy (&ip4, mp->lcl_ip, sizeof (ip4));
20741       vat_json_object_add_ip4 (node, "lcl_ip", ip4);
20742       clib_memcpy (&ip4, mp->rmt_ip, sizeof (ip4));
20743       vat_json_object_add_ip4 (node, "rmt_ip", ip4);
20744     }
20745   else
20746     {
20747       clib_memcpy (&ip6, mp->lcl_ip, sizeof (ip6));
20748       vat_json_object_add_ip6 (node, "lcl_ip", ip6);
20749       clib_memcpy (&ip6, mp->rmt_ip, sizeof (ip6));
20750       vat_json_object_add_ip6 (node, "rmt_ip", ip6);
20751     }
20752 }
20753
20754 static int
20755 api_session_rule_add_del (vat_main_t * vam)
20756 {
20757   vl_api_session_rule_add_del_t *mp;
20758   unformat_input_t *i = vam->input;
20759   u32 proto = ~0, lcl_port, rmt_port, action = 0, lcl_plen, rmt_plen;
20760   u32 appns_index = 0, scope = 0;
20761   ip4_address_t lcl_ip4, rmt_ip4;
20762   ip6_address_t lcl_ip6, rmt_ip6;
20763   u8 is_ip4 = 1, conn_set = 0;
20764   u8 is_add = 1, *tag = 0;
20765   int ret;
20766
20767   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20768     {
20769       if (unformat (i, "del"))
20770         is_add = 0;
20771       else if (unformat (i, "add"))
20772         ;
20773       else if (unformat (i, "proto tcp"))
20774         proto = 0;
20775       else if (unformat (i, "proto udp"))
20776         proto = 1;
20777       else if (unformat (i, "appns %d", &appns_index))
20778         ;
20779       else if (unformat (i, "scope %d", &scope))
20780         ;
20781       else if (unformat (i, "tag %_%v%_", &tag))
20782         ;
20783       else
20784         if (unformat
20785             (i, "%U/%d %d %U/%d %d", unformat_ip4_address, &lcl_ip4,
20786              &lcl_plen, &lcl_port, unformat_ip4_address, &rmt_ip4, &rmt_plen,
20787              &rmt_port))
20788         {
20789           is_ip4 = 1;
20790           conn_set = 1;
20791         }
20792       else
20793         if (unformat
20794             (i, "%U/%d %d %U/%d %d", unformat_ip6_address, &lcl_ip6,
20795              &lcl_plen, &lcl_port, unformat_ip6_address, &rmt_ip6, &rmt_plen,
20796              &rmt_port))
20797         {
20798           is_ip4 = 0;
20799           conn_set = 1;
20800         }
20801       else if (unformat (i, "action %d", &action))
20802         ;
20803       else
20804         break;
20805     }
20806   if (proto == ~0 || !conn_set || action == ~0)
20807     {
20808       errmsg ("transport proto, connection and action must be set");
20809       return -99;
20810     }
20811
20812   if (scope > 3)
20813     {
20814       errmsg ("scope should be 0-3");
20815       return -99;
20816     }
20817
20818   M (SESSION_RULE_ADD_DEL, mp);
20819
20820   mp->is_ip4 = is_ip4;
20821   mp->transport_proto = proto;
20822   mp->lcl_port = clib_host_to_net_u16 ((u16) lcl_port);
20823   mp->rmt_port = clib_host_to_net_u16 ((u16) rmt_port);
20824   mp->lcl_plen = lcl_plen;
20825   mp->rmt_plen = rmt_plen;
20826   mp->action_index = clib_host_to_net_u32 (action);
20827   mp->appns_index = clib_host_to_net_u32 (appns_index);
20828   mp->scope = scope;
20829   mp->is_add = is_add;
20830   if (is_ip4)
20831     {
20832       clib_memcpy (mp->lcl_ip, &lcl_ip4, sizeof (lcl_ip4));
20833       clib_memcpy (mp->rmt_ip, &rmt_ip4, sizeof (rmt_ip4));
20834     }
20835   else
20836     {
20837       clib_memcpy (mp->lcl_ip, &lcl_ip6, sizeof (lcl_ip6));
20838       clib_memcpy (mp->rmt_ip, &rmt_ip6, sizeof (rmt_ip6));
20839     }
20840   if (tag)
20841     {
20842       clib_memcpy (mp->tag, tag, vec_len (tag));
20843       vec_free (tag);
20844     }
20845
20846   S (mp);
20847   W (ret);
20848   return ret;
20849 }
20850
20851 static int
20852 api_session_rules_dump (vat_main_t * vam)
20853 {
20854   vl_api_session_rules_dump_t *mp;
20855   vl_api_control_ping_t *mp_ping;
20856   int ret;
20857
20858   if (!vam->json_output)
20859     {
20860       print (vam->ofp, "%=20s", "Session Rules");
20861     }
20862
20863   M (SESSION_RULES_DUMP, mp);
20864   /* send it... */
20865   S (mp);
20866
20867   /* Use a control ping for synchronization */
20868   MPING (CONTROL_PING, mp_ping);
20869   S (mp_ping);
20870
20871   /* Wait for a reply... */
20872   W (ret);
20873   return ret;
20874 }
20875
20876 static int
20877 api_ip_container_proxy_add_del (vat_main_t * vam)
20878 {
20879   vl_api_ip_container_proxy_add_del_t *mp;
20880   unformat_input_t *i = vam->input;
20881   u32 sw_if_index = ~0;
20882   vl_api_prefix_t pfx = { };
20883   u8 is_add = 1;
20884   int ret;
20885
20886   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20887     {
20888       if (unformat (i, "del"))
20889         is_add = 0;
20890       else if (unformat (i, "add"))
20891         ;
20892       if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
20893         ;
20894       else if (unformat (i, "sw_if_index %u", &sw_if_index))
20895         ;
20896       else
20897         break;
20898     }
20899   if (sw_if_index == ~0 || pfx.len == 0)
20900     {
20901       errmsg ("address and sw_if_index must be set");
20902       return -99;
20903     }
20904
20905   M (IP_CONTAINER_PROXY_ADD_DEL, mp);
20906
20907   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
20908   mp->is_add = is_add;
20909   clib_memcpy (&mp->pfx, &pfx, sizeof (pfx));
20910
20911   S (mp);
20912   W (ret);
20913   return ret;
20914 }
20915
20916 static int
20917 api_qos_record_enable_disable (vat_main_t * vam)
20918 {
20919   unformat_input_t *i = vam->input;
20920   vl_api_qos_record_enable_disable_t *mp;
20921   u32 sw_if_index, qs = 0xff;
20922   u8 sw_if_index_set = 0;
20923   u8 enable = 1;
20924   int ret;
20925
20926   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20927     {
20928       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20929         sw_if_index_set = 1;
20930       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20931         sw_if_index_set = 1;
20932       else if (unformat (i, "%U", unformat_qos_source, &qs))
20933         ;
20934       else if (unformat (i, "disable"))
20935         enable = 0;
20936       else
20937         {
20938           clib_warning ("parse error '%U'", format_unformat_error, i);
20939           return -99;
20940         }
20941     }
20942
20943   if (sw_if_index_set == 0)
20944     {
20945       errmsg ("missing interface name or sw_if_index");
20946       return -99;
20947     }
20948   if (qs == 0xff)
20949     {
20950       errmsg ("input location must be specified");
20951       return -99;
20952     }
20953
20954   M (QOS_RECORD_ENABLE_DISABLE, mp);
20955
20956   mp->record.sw_if_index = ntohl (sw_if_index);
20957   mp->record.input_source = qs;
20958   mp->enable = enable;
20959
20960   S (mp);
20961   W (ret);
20962   return ret;
20963 }
20964
20965
20966 static int
20967 q_or_quit (vat_main_t * vam)
20968 {
20969 #if VPP_API_TEST_BUILTIN == 0
20970   longjmp (vam->jump_buf, 1);
20971 #endif
20972   return 0;                     /* not so much */
20973 }
20974
20975 static int
20976 q (vat_main_t * vam)
20977 {
20978   return q_or_quit (vam);
20979 }
20980
20981 static int
20982 quit (vat_main_t * vam)
20983 {
20984   return q_or_quit (vam);
20985 }
20986
20987 static int
20988 comment (vat_main_t * vam)
20989 {
20990   return 0;
20991 }
20992
20993 static int
20994 elog_save (vat_main_t * vam)
20995 {
20996 #if VPP_API_TEST_BUILTIN == 0
20997   elog_main_t *em = &vam->elog_main;
20998   unformat_input_t *i = vam->input;
20999   char *file, *chroot_file;
21000   clib_error_t *error;
21001
21002   if (!unformat (i, "%s", &file))
21003     {
21004       errmsg ("expected file name, got `%U'", format_unformat_error, i);
21005       return 0;
21006     }
21007
21008   /* It's fairly hard to get "../oopsie" through unformat; just in case */
21009   if (strstr (file, "..") || index (file, '/'))
21010     {
21011       errmsg ("illegal characters in filename '%s'", file);
21012       return 0;
21013     }
21014
21015   chroot_file = (char *) format (0, "/tmp/%s%c", file, 0);
21016
21017   vec_free (file);
21018
21019   errmsg ("Saving %wd of %wd events to %s",
21020           elog_n_events_in_buffer (em),
21021           elog_buffer_capacity (em), chroot_file);
21022
21023   error = elog_write_file (em, chroot_file, 1 /* flush ring */ );
21024   vec_free (chroot_file);
21025
21026   if (error)
21027     clib_error_report (error);
21028 #else
21029   errmsg ("Use the vpp event loger...");
21030 #endif
21031
21032   return 0;
21033 }
21034
21035 static int
21036 elog_setup (vat_main_t * vam)
21037 {
21038 #if VPP_API_TEST_BUILTIN == 0
21039   elog_main_t *em = &vam->elog_main;
21040   unformat_input_t *i = vam->input;
21041   u32 nevents = 128 << 10;
21042
21043   (void) unformat (i, "nevents %d", &nevents);
21044
21045   elog_init (em, nevents);
21046   vl_api_set_elog_main (em);
21047   vl_api_set_elog_trace_api_messages (1);
21048   errmsg ("Event logger initialized with %u events", nevents);
21049 #else
21050   errmsg ("Use the vpp event loger...");
21051 #endif
21052   return 0;
21053 }
21054
21055 static int
21056 elog_enable (vat_main_t * vam)
21057 {
21058 #if VPP_API_TEST_BUILTIN == 0
21059   elog_main_t *em = &vam->elog_main;
21060
21061   elog_enable_disable (em, 1 /* enable */ );
21062   vl_api_set_elog_trace_api_messages (1);
21063   errmsg ("Event logger enabled...");
21064 #else
21065   errmsg ("Use the vpp event loger...");
21066 #endif
21067   return 0;
21068 }
21069
21070 static int
21071 elog_disable (vat_main_t * vam)
21072 {
21073 #if VPP_API_TEST_BUILTIN == 0
21074   elog_main_t *em = &vam->elog_main;
21075
21076   elog_enable_disable (em, 0 /* enable */ );
21077   vl_api_set_elog_trace_api_messages (1);
21078   errmsg ("Event logger disabled...");
21079 #else
21080   errmsg ("Use the vpp event loger...");
21081 #endif
21082   return 0;
21083 }
21084
21085 static int
21086 statseg (vat_main_t * vam)
21087 {
21088   ssvm_private_t *ssvmp = &vam->stat_segment;
21089   ssvm_shared_header_t *shared_header = ssvmp->sh;
21090   vlib_counter_t **counters;
21091   u64 thread0_index1_packets;
21092   u64 thread0_index1_bytes;
21093   f64 vector_rate, input_rate;
21094   uword *p;
21095
21096   uword *counter_vector_by_name;
21097   if (vam->stat_segment_lockp == 0)
21098     {
21099       errmsg ("Stat segment not mapped...");
21100       return -99;
21101     }
21102
21103   /* look up "/if/rx for sw_if_index 1 as a test */
21104
21105   clib_spinlock_lock (vam->stat_segment_lockp);
21106
21107   counter_vector_by_name = (uword *) shared_header->opaque[1];
21108
21109   p = hash_get_mem (counter_vector_by_name, "/if/rx");
21110   if (p == 0)
21111     {
21112       clib_spinlock_unlock (vam->stat_segment_lockp);
21113       errmsg ("/if/tx not found?");
21114       return -99;
21115     }
21116
21117   /* Fish per-thread vector of combined counters from shared memory */
21118   counters = (vlib_counter_t **) p[0];
21119
21120   if (vec_len (counters[0]) < 2)
21121     {
21122       clib_spinlock_unlock (vam->stat_segment_lockp);
21123       errmsg ("/if/tx vector length %d", vec_len (counters[0]));
21124       return -99;
21125     }
21126
21127   /* Read thread 0 sw_if_index 1 counter */
21128   thread0_index1_packets = counters[0][1].packets;
21129   thread0_index1_bytes = counters[0][1].bytes;
21130
21131   p = hash_get_mem (counter_vector_by_name, "vector_rate");
21132   if (p == 0)
21133     {
21134       clib_spinlock_unlock (vam->stat_segment_lockp);
21135       errmsg ("vector_rate not found?");
21136       return -99;
21137     }
21138
21139   vector_rate = *(f64 *) (p[0]);
21140   p = hash_get_mem (counter_vector_by_name, "input_rate");
21141   if (p == 0)
21142     {
21143       clib_spinlock_unlock (vam->stat_segment_lockp);
21144       errmsg ("input_rate not found?");
21145       return -99;
21146     }
21147   input_rate = *(f64 *) (p[0]);
21148
21149   clib_spinlock_unlock (vam->stat_segment_lockp);
21150
21151   print (vam->ofp, "vector_rate %.2f input_rate %.2f",
21152          vector_rate, input_rate);
21153   print (vam->ofp, "thread 0 sw_if_index 1 rx pkts %lld, bytes %lld",
21154          thread0_index1_packets, thread0_index1_bytes);
21155
21156   return 0;
21157 }
21158
21159 static int
21160 cmd_cmp (void *a1, void *a2)
21161 {
21162   u8 **c1 = a1;
21163   u8 **c2 = a2;
21164
21165   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
21166 }
21167
21168 static int
21169 help (vat_main_t * vam)
21170 {
21171   u8 **cmds = 0;
21172   u8 *name = 0;
21173   hash_pair_t *p;
21174   unformat_input_t *i = vam->input;
21175   int j;
21176
21177   if (unformat (i, "%s", &name))
21178     {
21179       uword *hs;
21180
21181       vec_add1 (name, 0);
21182
21183       hs = hash_get_mem (vam->help_by_name, name);
21184       if (hs)
21185         print (vam->ofp, "usage: %s %s", name, hs[0]);
21186       else
21187         print (vam->ofp, "No such msg / command '%s'", name);
21188       vec_free (name);
21189       return 0;
21190     }
21191
21192   print (vam->ofp, "Help is available for the following:");
21193
21194     /* *INDENT-OFF* */
21195     hash_foreach_pair (p, vam->function_by_name,
21196     ({
21197       vec_add1 (cmds, (u8 *)(p->key));
21198     }));
21199     /* *INDENT-ON* */
21200
21201   vec_sort_with_function (cmds, cmd_cmp);
21202
21203   for (j = 0; j < vec_len (cmds); j++)
21204     print (vam->ofp, "%s", cmds[j]);
21205
21206   vec_free (cmds);
21207   return 0;
21208 }
21209
21210 static int
21211 set (vat_main_t * vam)
21212 {
21213   u8 *name = 0, *value = 0;
21214   unformat_input_t *i = vam->input;
21215
21216   if (unformat (i, "%s", &name))
21217     {
21218       /* The input buffer is a vector, not a string. */
21219       value = vec_dup (i->buffer);
21220       vec_delete (value, i->index, 0);
21221       /* Almost certainly has a trailing newline */
21222       if (value[vec_len (value) - 1] == '\n')
21223         value[vec_len (value) - 1] = 0;
21224       /* Make sure it's a proper string, one way or the other */
21225       vec_add1 (value, 0);
21226       (void) clib_macro_set_value (&vam->macro_main,
21227                                    (char *) name, (char *) value);
21228     }
21229   else
21230     errmsg ("usage: set <name> <value>");
21231
21232   vec_free (name);
21233   vec_free (value);
21234   return 0;
21235 }
21236
21237 static int
21238 unset (vat_main_t * vam)
21239 {
21240   u8 *name = 0;
21241
21242   if (unformat (vam->input, "%s", &name))
21243     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
21244       errmsg ("unset: %s wasn't set", name);
21245   vec_free (name);
21246   return 0;
21247 }
21248
21249 typedef struct
21250 {
21251   u8 *name;
21252   u8 *value;
21253 } macro_sort_t;
21254
21255
21256 static int
21257 macro_sort_cmp (void *a1, void *a2)
21258 {
21259   macro_sort_t *s1 = a1;
21260   macro_sort_t *s2 = a2;
21261
21262   return strcmp ((char *) (s1->name), (char *) (s2->name));
21263 }
21264
21265 static int
21266 dump_macro_table (vat_main_t * vam)
21267 {
21268   macro_sort_t *sort_me = 0, *sm;
21269   int i;
21270   hash_pair_t *p;
21271
21272     /* *INDENT-OFF* */
21273     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
21274     ({
21275       vec_add2 (sort_me, sm, 1);
21276       sm->name = (u8 *)(p->key);
21277       sm->value = (u8 *) (p->value[0]);
21278     }));
21279     /* *INDENT-ON* */
21280
21281   vec_sort_with_function (sort_me, macro_sort_cmp);
21282
21283   if (vec_len (sort_me))
21284     print (vam->ofp, "%-15s%s", "Name", "Value");
21285   else
21286     print (vam->ofp, "The macro table is empty...");
21287
21288   for (i = 0; i < vec_len (sort_me); i++)
21289     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
21290   return 0;
21291 }
21292
21293 static int
21294 dump_node_table (vat_main_t * vam)
21295 {
21296   int i, j;
21297   vlib_node_t *node, *next_node;
21298
21299   if (vec_len (vam->graph_nodes) == 0)
21300     {
21301       print (vam->ofp, "Node table empty, issue get_node_graph...");
21302       return 0;
21303     }
21304
21305   for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
21306     {
21307       node = vam->graph_nodes[0][i];
21308       print (vam->ofp, "[%d] %s", i, node->name);
21309       for (j = 0; j < vec_len (node->next_nodes); j++)
21310         {
21311           if (node->next_nodes[j] != ~0)
21312             {
21313               next_node = vam->graph_nodes[0][node->next_nodes[j]];
21314               print (vam->ofp, "  [%d] %s", j, next_node->name);
21315             }
21316         }
21317     }
21318   return 0;
21319 }
21320
21321 static int
21322 value_sort_cmp (void *a1, void *a2)
21323 {
21324   name_sort_t *n1 = a1;
21325   name_sort_t *n2 = a2;
21326
21327   if (n1->value < n2->value)
21328     return -1;
21329   if (n1->value > n2->value)
21330     return 1;
21331   return 0;
21332 }
21333
21334
21335 static int
21336 dump_msg_api_table (vat_main_t * vam)
21337 {
21338   api_main_t *am = vlibapi_get_main ();
21339   name_sort_t *nses = 0, *ns;
21340   hash_pair_t *hp;
21341   int i;
21342
21343   /* *INDENT-OFF* */
21344   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
21345   ({
21346     vec_add2 (nses, ns, 1);
21347     ns->name = (u8 *)(hp->key);
21348     ns->value = (u32) hp->value[0];
21349   }));
21350   /* *INDENT-ON* */
21351
21352   vec_sort_with_function (nses, value_sort_cmp);
21353
21354   for (i = 0; i < vec_len (nses); i++)
21355     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
21356   vec_free (nses);
21357   return 0;
21358 }
21359
21360 static int
21361 get_msg_id (vat_main_t * vam)
21362 {
21363   u8 *name_and_crc;
21364   u32 message_index;
21365
21366   if (unformat (vam->input, "%s", &name_and_crc))
21367     {
21368       message_index = vl_msg_api_get_msg_index (name_and_crc);
21369       if (message_index == ~0)
21370         {
21371           print (vam->ofp, " '%s' not found", name_and_crc);
21372           return 0;
21373         }
21374       print (vam->ofp, " '%s' has message index %d",
21375              name_and_crc, message_index);
21376       return 0;
21377     }
21378   errmsg ("name_and_crc required...");
21379   return 0;
21380 }
21381
21382 static int
21383 search_node_table (vat_main_t * vam)
21384 {
21385   unformat_input_t *line_input = vam->input;
21386   u8 *node_to_find;
21387   int j;
21388   vlib_node_t *node, *next_node;
21389   uword *p;
21390
21391   if (vam->graph_node_index_by_name == 0)
21392     {
21393       print (vam->ofp, "Node table empty, issue get_node_graph...");
21394       return 0;
21395     }
21396
21397   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
21398     {
21399       if (unformat (line_input, "%s", &node_to_find))
21400         {
21401           vec_add1 (node_to_find, 0);
21402           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
21403           if (p == 0)
21404             {
21405               print (vam->ofp, "%s not found...", node_to_find);
21406               goto out;
21407             }
21408           node = vam->graph_nodes[0][p[0]];
21409           print (vam->ofp, "[%d] %s", p[0], node->name);
21410           for (j = 0; j < vec_len (node->next_nodes); j++)
21411             {
21412               if (node->next_nodes[j] != ~0)
21413                 {
21414                   next_node = vam->graph_nodes[0][node->next_nodes[j]];
21415                   print (vam->ofp, "  [%d] %s", j, next_node->name);
21416                 }
21417             }
21418         }
21419
21420       else
21421         {
21422           clib_warning ("parse error '%U'", format_unformat_error,
21423                         line_input);
21424           return -99;
21425         }
21426
21427     out:
21428       vec_free (node_to_find);
21429
21430     }
21431
21432   return 0;
21433 }
21434
21435
21436 static int
21437 script (vat_main_t * vam)
21438 {
21439 #if (VPP_API_TEST_BUILTIN==0)
21440   u8 *s = 0;
21441   char *save_current_file;
21442   unformat_input_t save_input;
21443   jmp_buf save_jump_buf;
21444   u32 save_line_number;
21445
21446   FILE *new_fp, *save_ifp;
21447
21448   if (unformat (vam->input, "%s", &s))
21449     {
21450       new_fp = fopen ((char *) s, "r");
21451       if (new_fp == 0)
21452         {
21453           errmsg ("Couldn't open script file %s", s);
21454           vec_free (s);
21455           return -99;
21456         }
21457     }
21458   else
21459     {
21460       errmsg ("Missing script name");
21461       return -99;
21462     }
21463
21464   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
21465   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
21466   save_ifp = vam->ifp;
21467   save_line_number = vam->input_line_number;
21468   save_current_file = (char *) vam->current_file;
21469
21470   vam->input_line_number = 0;
21471   vam->ifp = new_fp;
21472   vam->current_file = s;
21473   do_one_file (vam);
21474
21475   clib_memcpy (&vam->input, &save_input, sizeof (save_input));
21476   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
21477   vam->ifp = save_ifp;
21478   vam->input_line_number = save_line_number;
21479   vam->current_file = (u8 *) save_current_file;
21480   vec_free (s);
21481
21482   return 0;
21483 #else
21484   clib_warning ("use the exec command...");
21485   return -99;
21486 #endif
21487 }
21488
21489 static int
21490 echo (vat_main_t * vam)
21491 {
21492   print (vam->ofp, "%v", vam->input->buffer);
21493   return 0;
21494 }
21495
21496 /* List of API message constructors, CLI names map to api_xxx */
21497 #define foreach_vpe_api_msg                                             \
21498 _(create_loopback,"[mac <mac-addr>] [instance <instance>]")             \
21499 _(sw_interface_dump,"")                                                 \
21500 _(sw_interface_set_flags,                                               \
21501   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
21502 _(sw_interface_add_del_address,                                         \
21503   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
21504 _(sw_interface_set_rx_mode,                                             \
21505   "<intfc> | sw_if_index <id> [queue <id>] <polling | interrupt | adaptive>") \
21506 _(sw_interface_set_rx_placement,                                        \
21507   "<intfc> | sw_if_index <id> [queue <id>] [worker <id> | main]")       \
21508 _(sw_interface_rx_placement_dump,                                       \
21509   "[<intfc> | sw_if_index <id>]")                                         \
21510 _(sw_interface_set_table,                                               \
21511   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
21512 _(sw_interface_set_mpls_enable,                                         \
21513   "<intfc> | sw_if_index [disable | dis]")                              \
21514 _(sw_interface_set_vpath,                                               \
21515   "<intfc> | sw_if_index <id> enable | disable")                        \
21516 _(sw_interface_set_vxlan_bypass,                                        \
21517   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
21518 _(sw_interface_set_geneve_bypass,                                       \
21519   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
21520 _(sw_interface_set_l2_xconnect,                                         \
21521   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
21522   "enable | disable")                                                   \
21523 _(sw_interface_set_l2_bridge,                                           \
21524   "{<intfc> | sw_if_index <id>} bd_id <bridge-domain-id>\n"             \
21525   "[shg <split-horizon-group>] [bvi]\n"                                 \
21526   "enable | disable")                                                   \
21527 _(bridge_domain_set_mac_age, "bd_id <bridge-domain-id> mac-age 0-255")  \
21528 _(bridge_domain_add_del,                                                \
21529   "bd_id <bridge-domain-id> [flood 1|0] [uu-flood 1|0] [forward 1|0] [learn 1|0] [arp-term 1|0] [mac-age 0-255] [bd-tag <text>] [del]\n") \
21530 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
21531 _(l2fib_add_del,                                                        \
21532   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
21533 _(l2fib_flush_bd, "bd_id <bridge-domain-id>")                           \
21534 _(l2fib_flush_int, "<intfc> | sw_if_index <id>")                        \
21535 _(l2_flags,                                                             \
21536   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
21537 _(bridge_flags,                                                         \
21538   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
21539 _(tap_create_v2,                                                        \
21540   "id <num> [hw-addr <mac-addr>] [host-ns <name>] [rx-ring-size <num> [tx-ring-size <num>] [host-mtu-size <mtu>] [gso | no-gso]") \
21541 _(tap_delete_v2,                                                        \
21542   "<vpp-if-name> | sw_if_index <id>")                                   \
21543 _(sw_interface_tap_v2_dump, "")                                         \
21544 _(virtio_pci_create,                                                    \
21545   "pci-addr <pci-address> [use_random_mac | hw-addr <mac-addr>] [features <hex-value>] [gso-enabled]") \
21546 _(virtio_pci_delete,                                                    \
21547   "<vpp-if-name> | sw_if_index <id>")                                   \
21548 _(sw_interface_virtio_pci_dump, "")                                     \
21549 _(bond_create,                                                          \
21550   "[hw-addr <mac-addr>] {round-robin | active-backup | "                \
21551   "broadcast | {lacp | xor} [load-balance { l2 | l23 | l34 }]} "        \
21552   "[id <if-id>]")                                                       \
21553 _(bond_delete,                                                          \
21554   "<vpp-if-name> | sw_if_index <id>")                                   \
21555 _(bond_enslave,                                                         \
21556   "sw_if_index <n> bond <sw_if_index> [is_passive] [is_long_timeout]")  \
21557 _(bond_detach_slave,                                                    \
21558   "sw_if_index <n>")                                                    \
21559  _(sw_interface_set_bond_weight, "<intfc> | sw_if_index <nn> weight <value>") \
21560 _(sw_interface_bond_dump, "")                                           \
21561 _(sw_interface_slave_dump,                                              \
21562   "<vpp-if-name> | sw_if_index <id>")                                   \
21563 _(ip_table_add_del,                                                     \
21564   "table <n> [ipv6] [add | del]\n")                                     \
21565 _(ip_route_add_del,                                                     \
21566   "<addr>/<mask> via <<addr>|<intfc>|sw_if_index <id>|via-label <n>>\n" \
21567   "[table-id <n>] [<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"\
21568   "[weight <n>] [drop] [local] [classify <n>]  [out-label <n>]\n"       \
21569   "[multipath] [count <n>] [del]")                                      \
21570 _(ip_mroute_add_del,                                                    \
21571   "<src> <grp>/<mask> [table-id <n>]\n"                                 \
21572   "[<intfc> | sw_if_index <id>] [local] [del]")                         \
21573 _(mpls_table_add_del,                                                   \
21574   "table <n> [add | del]\n")                                            \
21575 _(mpls_route_add_del,                                                   \
21576   "<label> <eos> via <addr | next-hop-table <n> | via-label <n> |\n"    \
21577   "lookup-ip4-table <n> | lookup-in-ip6-table <n> |\n"                  \
21578   "l2-input-on <intfc> | l2-input-on sw_if_index <id>>\n"               \
21579   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>] [weight <n>]\n"  \
21580   "[drop] [local] [classify <n>] [out-label <n>] [multipath]\n"         \
21581   "[count <n>] [del]")                                                  \
21582 _(mpls_ip_bind_unbind,                                                  \
21583   "<label> <addr/len>")                                                 \
21584 _(mpls_tunnel_add_del,                                                  \
21585   "[add | del <intfc | sw_if_index <id>>] via <addr | via-label <n>>\n" \
21586   "[<intfc> | sw_if_index <id> | next-hop-table <id>]\n"                \
21587   "[l2-only]  [out-label <n>]")                                         \
21588 _(sr_mpls_policy_add,                                                   \
21589   "bsid <id> [weight <n>] [spray] next <sid> [next <sid>]")             \
21590 _(sr_mpls_policy_del,                                                   \
21591   "bsid <id>")                                                          \
21592 _(bier_table_add_del,                                                   \
21593   "<label> <sub-domain> <set> <bsl> [del]")                             \
21594 _(bier_route_add_del,                                                   \
21595   "<bit-position> <sub-domain> <set> <bsl> via <addr> [table-id <n>]\n" \
21596   "[<intfc> | sw_if_index <id>]"                                        \
21597   "[weight <n>] [del] [multipath]")                                     \
21598 _(proxy_arp_add_del,                                                    \
21599   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
21600 _(proxy_arp_intfc_enable_disable,                                       \
21601   "<intfc> | sw_if_index <id> enable | disable")                        \
21602 _(sw_interface_set_unnumbered,                                          \
21603   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
21604 _(ip_neighbor_add_del,                                                  \
21605   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
21606   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
21607 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
21608 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
21609   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
21610   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
21611   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
21612 _(ip_table_replace_begin, "table <n> [ipv6]")                           \
21613 _(ip_table_flush, "table <n> [ipv6]")                                   \
21614 _(ip_table_replace_end, "table <n> [ipv6]")                             \
21615 _(set_ip_flow_hash,                                                     \
21616   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
21617 _(sw_interface_ip6_enable_disable,                                      \
21618   "<intfc> | sw_if_index <id> enable | disable")                        \
21619 _(ip6nd_proxy_add_del,                                                  \
21620   "<intfc> | sw_if_index <id> <ip6-address>")                           \
21621 _(ip6nd_proxy_dump, "")                                                 \
21622 _(sw_interface_ip6nd_ra_prefix,                                         \
21623   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
21624   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
21625   "[nolink] [isno]")                                                    \
21626 _(sw_interface_ip6nd_ra_config,                                         \
21627   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
21628   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
21629   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
21630 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
21631 _(l2_patch_add_del,                                                     \
21632   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
21633   "enable | disable")                                                   \
21634 _(sr_localsid_add_del,                                                  \
21635   "(del) address <addr> next_hop <addr> behavior <beh>\n"               \
21636   "fib-table <num> (end.psp) sw_if_index <num>")                        \
21637 _(classify_add_del_table,                                               \
21638   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
21639   " [del] [del-chain] mask <mask-value>\n"                              \
21640   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
21641   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
21642 _(classify_add_del_session,                                             \
21643   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
21644   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
21645   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
21646   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
21647 _(classify_set_interface_ip_table,                                      \
21648   "<intfc> | sw_if_index <nn> table <nn>")                              \
21649 _(classify_set_interface_l2_tables,                                     \
21650   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
21651   "  [other-table <nn>]")                                               \
21652 _(get_node_index, "node <node-name")                                    \
21653 _(add_node_next, "node <node-name> next <next-node-name>")              \
21654 _(l2tpv3_create_tunnel,                                                 \
21655   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
21656   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
21657   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
21658 _(l2tpv3_set_tunnel_cookies,                                            \
21659   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
21660   "[new_remote_cookie <nn>]\n")                                         \
21661 _(l2tpv3_interface_enable_disable,                                      \
21662   "<intfc> | sw_if_index <nn> enable | disable")                        \
21663 _(l2tpv3_set_lookup_key,                                                \
21664   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
21665 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
21666 _(vxlan_offload_rx,                                                     \
21667   "hw { <interface name> | hw_if_index <nn>} "                          \
21668   "rx { <vxlan tunnel name> | sw_if_index <nn> } [del]")                \
21669 _(vxlan_add_del_tunnel,                                                 \
21670   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
21671   "{ <intfc> | mcast_sw_if_index <nn> } [instance <id>]}\n"             \
21672   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
21673 _(geneve_add_del_tunnel,                                                \
21674   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
21675   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
21676   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
21677 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
21678 _(geneve_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                   \
21679 _(gre_tunnel_add_del,                                                   \
21680   "src <ip-addr> dst <ip-addr> [outer-fib-id <nn>] [instance <n>]\n"    \
21681   "[teb | erspan <session-id>] [del]")                                  \
21682 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
21683 _(l2_fib_clear_table, "")                                               \
21684 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
21685 _(l2_interface_vlan_tag_rewrite,                                        \
21686   "<intfc> | sw_if_index <nn> \n"                                       \
21687   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
21688   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
21689 _(create_vhost_user_if,                                                 \
21690         "socket <filename> [server] [renumber <dev_instance>] "         \
21691         "[disable_mrg_rxbuf] [disable_indirect_desc] [gso] "            \
21692         "[mac <mac_address>]")                                          \
21693 _(modify_vhost_user_if,                                                 \
21694         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
21695         "[server] [renumber <dev_instance>] [gso]")                     \
21696 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
21697 _(sw_interface_vhost_user_dump, "")                                     \
21698 _(show_version, "")                                                     \
21699 _(show_threads, "")                                                     \
21700 _(vxlan_gpe_add_del_tunnel,                                             \
21701   "local <addr> remote <addr>  | group <mcast-ip-addr>\n"               \
21702   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
21703   "vni <nn> [encap-vrf-id <nn>] [decap-vrf-id <nn>]\n"                  \
21704   "[next-ip4][next-ip6][next-ethernet] [next-nsh] [del]\n")             \
21705 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
21706 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
21707 _(interface_name_renumber,                                              \
21708   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
21709 _(input_acl_set_interface,                                              \
21710   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
21711   "  [l2-table <nn>] [del]")                                            \
21712 _(ip_probe_neighbor, "(<intc> | sw_if_index <nn>) address <ip4|ip6-addr>") \
21713 _(ip_scan_neighbor_enable_disable, "[ip4|ip6|both|disable] [interval <n-min>]\n" \
21714   "  [max-time <n-usec>] [max-update <n>] [delay <n-msec>] [stale <n-min>]") \
21715 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
21716 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
21717 _(want_l2_macs_events, "[disable] [learn-limit <n>] [scan-delay <n>] [max-entries <n>]") \
21718 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
21719 _(ip_dump, "ipv4 | ipv6")                                               \
21720 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
21721 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
21722   "  spid_id <n> ")                                                     \
21723 _(ipsec_sad_entry_add_del, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
21724   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
21725   "  integ_alg <alg> integ_key <hex>")                                  \
21726 _(ipsec_spd_entry_add_del, "spd_id <n> priority <n> action <action>\n"  \
21727   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
21728   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
21729   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
21730 _(ipsec_tunnel_if_add_del, "local_spi <n> remote_spi <n>\n"             \
21731   "  crypto_alg <alg> local_crypto_key <hex> remote_crypto_key <hex>\n" \
21732   "  integ_alg <alg> local_integ_key <hex> remote_integ_key <hex>\n"    \
21733   "  local_ip <addr> remote_ip <addr> [esn] [anti_replay] [del]\n"      \
21734   "  [instance <n>]")     \
21735 _(ipsec_sa_dump, "[sa_id <n>]")                                         \
21736 _(ipsec_tunnel_if_set_sa, "<intfc> sa_id <n> <inbound|outbound>\n")     \
21737 _(delete_loopback,"sw_if_index <nn>")                                   \
21738 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
21739 _(bd_ip_mac_flush, "bd_id <bridge-domain-id>")                          \
21740 _(bd_ip_mac_dump, "[bd_id] <bridge-domain-id>")                         \
21741 _(want_interface_events,  "enable|disable")                             \
21742 _(get_first_msg_id, "client <name>")                                    \
21743 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
21744 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
21745   "fib-id <nn> [ip4][ip6][default]")                                    \
21746 _(get_node_graph, " ")                                                  \
21747 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
21748 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
21749 _(ioam_disable, "")                                                     \
21750 _(one_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
21751                             " sw_if_index <sw_if_index> p <priority> "  \
21752                             "w <weight>] [del]")                        \
21753 _(one_add_del_locator, "locator-set <locator_name> "                    \
21754                         "iface <intf> | sw_if_index <sw_if_index> "     \
21755                         "p <priority> w <weight> [del]")                \
21756 _(one_add_del_local_eid,"vni <vni> eid "                                \
21757                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
21758                          "locator-set <locator_name> [del]"             \
21759                          "[key-id sha1|sha256 secret-key <secret-key>]")\
21760 _(one_add_del_map_resolver, "<ip4|6-addr> [del]")                       \
21761 _(one_add_del_map_server, "<ip4|6-addr> [del]")                         \
21762 _(one_enable_disable, "enable|disable")                                 \
21763 _(one_map_register_enable_disable, "enable|disable")                    \
21764 _(one_map_register_fallback_threshold, "<value>")                       \
21765 _(one_rloc_probe_enable_disable, "enable|disable")                      \
21766 _(one_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "       \
21767                                "[seid <seid>] "                         \
21768                                "rloc <locator> p <prio> "               \
21769                                "w <weight> [rloc <loc> ... ] "          \
21770                                "action <action> [del-all]")             \
21771 _(one_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "    \
21772                           "<local-eid>")                                \
21773 _(one_pitr_set_locator_set, "locator-set <loc-set-name> | del")         \
21774 _(one_use_petr, "ip-address> | disable")                                \
21775 _(one_map_request_mode, "src-dst|dst-only")                             \
21776 _(one_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")            \
21777 _(one_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")               \
21778 _(one_locator_set_dump, "[local | remote]")                             \
21779 _(one_locator_dump, "ls_index <index> | ls_name <name>")                \
21780 _(one_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "       \
21781                        "[local] | [remote]")                            \
21782 _(one_add_del_ndp_entry, "[del] mac <mac> bd <bd> ip6 <ip6>")           \
21783 _(one_ndp_bd_get, "")                                                   \
21784 _(one_ndp_entries_get, "bd <bridge-domain>")                            \
21785 _(one_add_del_l2_arp_entry, "[del] mac <mac> bd <bd> ip4 <ip4>")        \
21786 _(one_l2_arp_bd_get, "")                                                \
21787 _(one_l2_arp_entries_get, "bd <bridge-domain>")                         \
21788 _(one_stats_enable_disable, "enable|disable")                           \
21789 _(show_one_stats_enable_disable, "")                                    \
21790 _(one_eid_table_vni_dump, "")                                           \
21791 _(one_eid_table_map_dump, "l2|l3")                                      \
21792 _(one_map_resolver_dump, "")                                            \
21793 _(one_map_server_dump, "")                                              \
21794 _(one_adjacencies_get, "vni <vni>")                                     \
21795 _(one_nsh_set_locator_set, "[del] ls <locator-set-name>")               \
21796 _(show_one_rloc_probe_state, "")                                        \
21797 _(show_one_map_register_state, "")                                      \
21798 _(show_one_status, "")                                                  \
21799 _(one_stats_dump, "")                                                   \
21800 _(one_stats_flush, "")                                                  \
21801 _(one_get_map_request_itr_rlocs, "")                                    \
21802 _(one_map_register_set_ttl, "<ttl>")                                    \
21803 _(one_set_transport_protocol, "udp|api")                                \
21804 _(one_get_transport_protocol, "")                                       \
21805 _(one_enable_disable_xtr_mode, "enable|disable")                        \
21806 _(one_show_xtr_mode, "")                                                \
21807 _(one_enable_disable_pitr_mode, "enable|disable")                       \
21808 _(one_show_pitr_mode, "")                                               \
21809 _(one_enable_disable_petr_mode, "enable|disable")                       \
21810 _(one_show_petr_mode, "")                                               \
21811 _(show_one_nsh_mapping, "")                                             \
21812 _(show_one_pitr, "")                                                    \
21813 _(show_one_use_petr, "")                                                \
21814 _(show_one_map_request_mode, "")                                        \
21815 _(show_one_map_register_ttl, "")                                        \
21816 _(show_one_map_register_fallback_threshold, "")                         \
21817 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
21818                             " sw_if_index <sw_if_index> p <priority> "  \
21819                             "w <weight>] [del]")                        \
21820 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
21821                         "iface <intf> | sw_if_index <sw_if_index> "     \
21822                         "p <priority> w <weight> [del]")                \
21823 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
21824                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
21825                          "locator-set <locator_name> [del]"             \
21826                          "[key-id sha1|sha256 secret-key <secret-key>]") \
21827 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
21828 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
21829 _(lisp_enable_disable, "enable|disable")                                \
21830 _(lisp_map_register_enable_disable, "enable|disable")                   \
21831 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
21832 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
21833                                "[seid <seid>] "                         \
21834                                "rloc <locator> p <prio> "               \
21835                                "w <weight> [rloc <loc> ... ] "          \
21836                                "action <action> [del-all]")             \
21837 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
21838                           "<local-eid>")                                \
21839 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
21840 _(lisp_use_petr, "<ip-address> | disable")                              \
21841 _(lisp_map_request_mode, "src-dst|dst-only")                            \
21842 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
21843 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
21844 _(lisp_locator_set_dump, "[local | remote]")                            \
21845 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
21846 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
21847                        "[local] | [remote]")                            \
21848 _(lisp_eid_table_vni_dump, "")                                          \
21849 _(lisp_eid_table_map_dump, "l2|l3")                                     \
21850 _(lisp_map_resolver_dump, "")                                           \
21851 _(lisp_map_server_dump, "")                                             \
21852 _(lisp_adjacencies_get, "vni <vni>")                                    \
21853 _(gpe_fwd_entry_vnis_get, "")                                           \
21854 _(gpe_native_fwd_rpaths_get, "ip4 | ip6")                               \
21855 _(gpe_add_del_native_fwd_rpath, "[del] via <nh-ip-addr> [iface] "       \
21856                                 "[table <table-id>]")                   \
21857 _(lisp_gpe_fwd_entries_get, "vni <vni>")                                \
21858 _(lisp_gpe_fwd_entry_path_dump, "index <fwd_entry_index>")              \
21859 _(gpe_set_encap_mode, "lisp|vxlan")                                     \
21860 _(gpe_get_encap_mode, "")                                               \
21861 _(lisp_gpe_add_del_iface, "up|down")                                    \
21862 _(lisp_gpe_enable_disable, "enable|disable")                            \
21863 _(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>"       \
21864   "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
21865 _(show_lisp_rloc_probe_state, "")                                       \
21866 _(show_lisp_map_register_state, "")                                     \
21867 _(show_lisp_status, "")                                                 \
21868 _(lisp_get_map_request_itr_rlocs, "")                                   \
21869 _(show_lisp_pitr, "")                                                   \
21870 _(show_lisp_use_petr, "")                                               \
21871 _(show_lisp_map_request_mode, "")                                       \
21872 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
21873 _(af_packet_delete, "name <host interface name>")                       \
21874 _(af_packet_dump, "")                                                   \
21875 _(policer_add_del, "name <policer name> <params> [del]")                \
21876 _(policer_dump, "[name <policer name>]")                                \
21877 _(policer_classify_set_interface,                                       \
21878   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
21879   "  [l2-table <nn>] [del]")                                            \
21880 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
21881 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
21882     "[master|slave]")                                                   \
21883 _(netmap_delete, "name <interface name>")                               \
21884 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
21885 _(mpls_table_dump, "")                                                  \
21886 _(mpls_route_dump, "table-id <ID>")                                     \
21887 _(classify_table_ids, "")                                               \
21888 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
21889 _(classify_table_info, "table_id <nn>")                                 \
21890 _(classify_session_dump, "table_id <nn>")                               \
21891 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
21892     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
21893     "[template_interval <nn>] [udp_checksum]")                          \
21894 _(ipfix_exporter_dump, "")                                              \
21895 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
21896 _(ipfix_classify_stream_dump, "")                                       \
21897 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
21898 _(ipfix_classify_table_dump, "")                                        \
21899 _(sw_interface_span_enable_disable, "[l2] [src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
21900 _(sw_interface_span_dump, "[l2]")                                           \
21901 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
21902 _(pg_create_interface, "if_id <nn> [gso-enabled gso-size <size>]")      \
21903 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
21904 _(pg_enable_disable, "[stream <id>] disable")                           \
21905 _(ip_source_and_port_range_check_add_del,                               \
21906   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
21907 _(ip_source_and_port_range_check_interface_add_del,                     \
21908   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
21909   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
21910 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
21911 _(l2_interface_pbb_tag_rewrite,                                         \
21912   "<intfc> | sw_if_index <nn> \n"                                       \
21913   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
21914   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
21915 _(set_punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
21916 _(flow_classify_set_interface,                                          \
21917   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
21918 _(flow_classify_dump, "type [ip4|ip6]")                                 \
21919 _(ip_table_dump, "")                                                    \
21920 _(ip_route_dump, "table-id [ip4|ip6]")                                  \
21921 _(ip_mtable_dump, "")                                                   \
21922 _(ip_mroute_dump, "table-id [ip4|ip6]")                                 \
21923 _(feature_enable_disable, "arc_name <arc_name> "                        \
21924   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
21925 _(feature_gso_enable_disable, "<intfc> | sw_if_index <nn> "             \
21926   "[enable | disable] ")                                                \
21927 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
21928 "[disable]")                                                            \
21929 _(sw_interface_add_del_mac_address, "<intfc> | sw_if_index <nn> "       \
21930   "mac <mac-address> [del]")                                            \
21931 _(l2_xconnect_dump, "")                                                 \
21932 _(hw_interface_set_mtu, "<intfc> | hw_if_index <nn> mtu <nn>")        \
21933 _(ip_neighbor_dump, "[ip6] <intfc> | sw_if_index <nn>")                 \
21934 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")          \
21935 _(p2p_ethernet_add, "<intfc> | sw_if_index <nn> remote_mac <mac-address> sub_id <id>") \
21936 _(p2p_ethernet_del, "<intfc> | sw_if_index <nn> remote_mac <mac-address>") \
21937 _(lldp_config, "system-name <name> tx-hold <nn> tx-interval <nn>") \
21938 _(sw_interface_set_lldp, "<intfc> | sw_if_index <nn> [port-desc <description>]\n" \
21939   " [mgmt-ip4 <ip4>] [mgmt-ip6 <ip6>] [mgmt-oid <object id>] [disable]") \
21940 _(tcp_configure_src_addresses, "<ip4|6>first-<ip4|6>last [vrf <id>]")   \
21941 _(sock_init_shm, "size <nnn>")                                          \
21942 _(app_namespace_add_del, "[add] id <ns-id> secret <nn> sw_if_index <nn>")\
21943 _(session_rule_add_del, "[add|del] proto <tcp/udp> <lcl-ip>/<plen> "    \
21944   "<lcl-port> <rmt-ip>/<plen> <rmt-port> action <nn>")                  \
21945 _(session_rules_dump, "")                                               \
21946 _(ip_container_proxy_add_del, "[add|del] <address> <sw_if_index>")      \
21947 _(output_acl_set_interface,                                             \
21948   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
21949   "  [l2-table <nn>] [del]")                                            \
21950 _(qos_record_enable_disable, "<record-source> <intfc> | sw_if_index <id> [disable]")
21951
21952 /* List of command functions, CLI names map directly to functions */
21953 #define foreach_cli_function                                    \
21954 _(comment, "usage: comment <ignore-rest-of-line>")              \
21955 _(dump_interface_table, "usage: dump_interface_table")          \
21956 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
21957 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
21958 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
21959 _(dump_macro_table, "usage: dump_macro_table ")                 \
21960 _(dump_node_table, "usage: dump_node_table")                    \
21961 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
21962 _(elog_setup, "usage: elog_setup [nevents, default 128K]")      \
21963 _(elog_disable, "usage: elog_disable")                          \
21964 _(elog_enable, "usage: elog_enable")                            \
21965 _(elog_save, "usage: elog_save <filename>")                     \
21966 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
21967 _(echo, "usage: echo <message>")                                \
21968 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
21969 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
21970 _(help, "usage: help")                                          \
21971 _(q, "usage: quit")                                             \
21972 _(quit, "usage: quit")                                          \
21973 _(search_node_table, "usage: search_node_table <name>...")      \
21974 _(set, "usage: set <variable-name> <value>")                    \
21975 _(script, "usage: script <file-name>")                          \
21976 _(statseg, "usage: statseg")                                    \
21977 _(unset, "usage: unset <variable-name>")
21978
21979 #define _(N,n)                                  \
21980     static void vl_api_##n##_t_handler_uni      \
21981     (vl_api_##n##_t * mp)                       \
21982     {                                           \
21983         vat_main_t * vam = &vat_main;           \
21984         if (vam->json_output) {                 \
21985             vl_api_##n##_t_handler_json(mp);    \
21986         } else {                                \
21987             vl_api_##n##_t_handler(mp);         \
21988         }                                       \
21989     }
21990 foreach_vpe_api_reply_msg;
21991 #if VPP_API_TEST_BUILTIN == 0
21992 foreach_standalone_reply_msg;
21993 #endif
21994 #undef _
21995
21996 void
21997 vat_api_hookup (vat_main_t * vam)
21998 {
21999 #define _(N,n)                                                  \
22000     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
22001                            vl_api_##n##_t_handler_uni,          \
22002                            vl_noop_handler,                     \
22003                            vl_api_##n##_t_endian,               \
22004                            vl_api_##n##_t_print,                \
22005                            sizeof(vl_api_##n##_t), 1);
22006   foreach_vpe_api_reply_msg;
22007 #if VPP_API_TEST_BUILTIN == 0
22008   foreach_standalone_reply_msg;
22009 #endif
22010 #undef _
22011
22012 #if (VPP_API_TEST_BUILTIN==0)
22013   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
22014
22015   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
22016
22017   vam->function_by_name = hash_create_string (0, sizeof (uword));
22018
22019   vam->help_by_name = hash_create_string (0, sizeof (uword));
22020 #endif
22021
22022   /* API messages we can send */
22023 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
22024   foreach_vpe_api_msg;
22025 #undef _
22026
22027   /* Help strings */
22028 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
22029   foreach_vpe_api_msg;
22030 #undef _
22031
22032   /* CLI functions */
22033 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
22034   foreach_cli_function;
22035 #undef _
22036
22037   /* Help strings */
22038 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
22039   foreach_cli_function;
22040 #undef _
22041 }
22042
22043 #if VPP_API_TEST_BUILTIN
22044 static clib_error_t *
22045 vat_api_hookup_shim (vlib_main_t * vm)
22046 {
22047   vat_api_hookup (&vat_main);
22048   return 0;
22049 }
22050
22051 VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
22052 #endif
22053
22054 /*
22055  * fd.io coding-style-patch-verification: ON
22056  *
22057  * Local Variables:
22058  * eval: (c-set-style "gnu")
22059  * End:
22060  */