devices: vhost 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   u64 features;
13120
13121   features =
13122     clib_net_to_host_u32 (mp->features_first_32) | ((u64)
13123                                                     clib_net_to_host_u32
13124                                                     (mp->features_last_32) <<
13125                                                     32);
13126
13127   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s",
13128          (char *) mp->interface_name,
13129          ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
13130          features, mp->is_server,
13131          ntohl (mp->num_regions), (char *) mp->sock_filename);
13132   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
13133 }
13134
13135 static void vl_api_sw_interface_vhost_user_details_t_handler_json
13136   (vl_api_sw_interface_vhost_user_details_t * mp)
13137 {
13138   vat_main_t *vam = &vat_main;
13139   vat_json_node_t *node = NULL;
13140
13141   if (VAT_JSON_ARRAY != vam->json_tree.type)
13142     {
13143       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13144       vat_json_init_array (&vam->json_tree);
13145     }
13146   node = vat_json_array_add (&vam->json_tree);
13147
13148   vat_json_init_object (node);
13149   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13150   vat_json_object_add_string_copy (node, "interface_name",
13151                                    mp->interface_name);
13152   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
13153                             ntohl (mp->virtio_net_hdr_sz));
13154   vat_json_object_add_uint (node, "features_first_32",
13155                             clib_net_to_host_u32 (mp->features_first_32));
13156   vat_json_object_add_uint (node, "features_last_32",
13157                             clib_net_to_host_u32 (mp->features_last_32));
13158   vat_json_object_add_uint (node, "is_server", mp->is_server);
13159   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
13160   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
13161   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
13162 }
13163
13164 static int
13165 api_sw_interface_vhost_user_dump (vat_main_t * vam)
13166 {
13167   vl_api_sw_interface_vhost_user_dump_t *mp;
13168   vl_api_control_ping_t *mp_ping;
13169   int ret;
13170   print (vam->ofp,
13171          "Interface name            idx hdr_sz features server regions filename");
13172
13173   /* Get list of vhost-user interfaces */
13174   M (SW_INTERFACE_VHOST_USER_DUMP, mp);
13175   S (mp);
13176
13177   /* Use a control ping for synchronization */
13178   MPING (CONTROL_PING, mp_ping);
13179   S (mp_ping);
13180
13181   W (ret);
13182   return ret;
13183 }
13184
13185 static int
13186 api_show_version (vat_main_t * vam)
13187 {
13188   vl_api_show_version_t *mp;
13189   int ret;
13190
13191   M (SHOW_VERSION, mp);
13192
13193   S (mp);
13194   W (ret);
13195   return ret;
13196 }
13197
13198
13199 static int
13200 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
13201 {
13202   unformat_input_t *line_input = vam->input;
13203   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
13204   ip4_address_t local4, remote4;
13205   ip6_address_t local6, remote6;
13206   u8 is_add = 1;
13207   u8 ipv4_set = 0, ipv6_set = 0;
13208   u8 local_set = 0;
13209   u8 remote_set = 0;
13210   u8 grp_set = 0;
13211   u32 mcast_sw_if_index = ~0;
13212   u32 encap_vrf_id = 0;
13213   u32 decap_vrf_id = 0;
13214   u8 protocol = ~0;
13215   u32 vni;
13216   u8 vni_set = 0;
13217   int ret;
13218
13219   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
13220   clib_memset (&local4, 0, sizeof local4);
13221   clib_memset (&remote4, 0, sizeof remote4);
13222   clib_memset (&local6, 0, sizeof local6);
13223   clib_memset (&remote6, 0, sizeof remote6);
13224
13225   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13226     {
13227       if (unformat (line_input, "del"))
13228         is_add = 0;
13229       else if (unformat (line_input, "local %U",
13230                          unformat_ip4_address, &local4))
13231         {
13232           local_set = 1;
13233           ipv4_set = 1;
13234         }
13235       else if (unformat (line_input, "remote %U",
13236                          unformat_ip4_address, &remote4))
13237         {
13238           remote_set = 1;
13239           ipv4_set = 1;
13240         }
13241       else if (unformat (line_input, "local %U",
13242                          unformat_ip6_address, &local6))
13243         {
13244           local_set = 1;
13245           ipv6_set = 1;
13246         }
13247       else if (unformat (line_input, "remote %U",
13248                          unformat_ip6_address, &remote6))
13249         {
13250           remote_set = 1;
13251           ipv6_set = 1;
13252         }
13253       else if (unformat (line_input, "group %U %U",
13254                          unformat_ip4_address, &remote4,
13255                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13256         {
13257           grp_set = remote_set = 1;
13258           ipv4_set = 1;
13259         }
13260       else if (unformat (line_input, "group %U",
13261                          unformat_ip4_address, &remote4))
13262         {
13263           grp_set = remote_set = 1;
13264           ipv4_set = 1;
13265         }
13266       else if (unformat (line_input, "group %U %U",
13267                          unformat_ip6_address, &remote6,
13268                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13269         {
13270           grp_set = remote_set = 1;
13271           ipv6_set = 1;
13272         }
13273       else if (unformat (line_input, "group %U",
13274                          unformat_ip6_address, &remote6))
13275         {
13276           grp_set = remote_set = 1;
13277           ipv6_set = 1;
13278         }
13279       else
13280         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
13281         ;
13282       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
13283         ;
13284       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
13285         ;
13286       else if (unformat (line_input, "vni %d", &vni))
13287         vni_set = 1;
13288       else if (unformat (line_input, "next-ip4"))
13289         protocol = 1;
13290       else if (unformat (line_input, "next-ip6"))
13291         protocol = 2;
13292       else if (unformat (line_input, "next-ethernet"))
13293         protocol = 3;
13294       else if (unformat (line_input, "next-nsh"))
13295         protocol = 4;
13296       else
13297         {
13298           errmsg ("parse error '%U'", format_unformat_error, line_input);
13299           return -99;
13300         }
13301     }
13302
13303   if (local_set == 0)
13304     {
13305       errmsg ("tunnel local address not specified");
13306       return -99;
13307     }
13308   if (remote_set == 0)
13309     {
13310       errmsg ("tunnel remote address not specified");
13311       return -99;
13312     }
13313   if (grp_set && mcast_sw_if_index == ~0)
13314     {
13315       errmsg ("tunnel nonexistent multicast device");
13316       return -99;
13317     }
13318   if (ipv4_set && ipv6_set)
13319     {
13320       errmsg ("both IPv4 and IPv6 addresses specified");
13321       return -99;
13322     }
13323
13324   if (vni_set == 0)
13325     {
13326       errmsg ("vni not specified");
13327       return -99;
13328     }
13329
13330   M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
13331
13332
13333   if (ipv6_set)
13334     {
13335       clib_memcpy (&mp->local, &local6, sizeof (local6));
13336       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
13337     }
13338   else
13339     {
13340       clib_memcpy (&mp->local, &local4, sizeof (local4));
13341       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
13342     }
13343
13344   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
13345   mp->encap_vrf_id = ntohl (encap_vrf_id);
13346   mp->decap_vrf_id = ntohl (decap_vrf_id);
13347   mp->protocol = protocol;
13348   mp->vni = ntohl (vni);
13349   mp->is_add = is_add;
13350   mp->is_ipv6 = ipv6_set;
13351
13352   S (mp);
13353   W (ret);
13354   return ret;
13355 }
13356
13357 static void vl_api_vxlan_gpe_tunnel_details_t_handler
13358   (vl_api_vxlan_gpe_tunnel_details_t * mp)
13359 {
13360   vat_main_t *vam = &vat_main;
13361   ip46_address_t local = to_ip46 (mp->is_ipv6, mp->local);
13362   ip46_address_t remote = to_ip46 (mp->is_ipv6, mp->remote);
13363
13364   print (vam->ofp, "%11d%24U%24U%13d%12d%19d%14d%14d",
13365          ntohl (mp->sw_if_index),
13366          format_ip46_address, &local, IP46_TYPE_ANY,
13367          format_ip46_address, &remote, IP46_TYPE_ANY,
13368          ntohl (mp->vni), mp->protocol,
13369          ntohl (mp->mcast_sw_if_index),
13370          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
13371 }
13372
13373
13374 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
13375   (vl_api_vxlan_gpe_tunnel_details_t * mp)
13376 {
13377   vat_main_t *vam = &vat_main;
13378   vat_json_node_t *node = NULL;
13379   struct in_addr ip4;
13380   struct in6_addr ip6;
13381
13382   if (VAT_JSON_ARRAY != vam->json_tree.type)
13383     {
13384       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13385       vat_json_init_array (&vam->json_tree);
13386     }
13387   node = vat_json_array_add (&vam->json_tree);
13388
13389   vat_json_init_object (node);
13390   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13391   if (mp->is_ipv6)
13392     {
13393       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
13394       vat_json_object_add_ip6 (node, "local", ip6);
13395       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
13396       vat_json_object_add_ip6 (node, "remote", ip6);
13397     }
13398   else
13399     {
13400       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
13401       vat_json_object_add_ip4 (node, "local", ip4);
13402       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
13403       vat_json_object_add_ip4 (node, "remote", ip4);
13404     }
13405   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
13406   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
13407   vat_json_object_add_uint (node, "mcast_sw_if_index",
13408                             ntohl (mp->mcast_sw_if_index));
13409   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
13410   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
13411   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
13412 }
13413
13414 static int
13415 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
13416 {
13417   unformat_input_t *i = vam->input;
13418   vl_api_vxlan_gpe_tunnel_dump_t *mp;
13419   vl_api_control_ping_t *mp_ping;
13420   u32 sw_if_index;
13421   u8 sw_if_index_set = 0;
13422   int ret;
13423
13424   /* Parse args required to build the message */
13425   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13426     {
13427       if (unformat (i, "sw_if_index %d", &sw_if_index))
13428         sw_if_index_set = 1;
13429       else
13430         break;
13431     }
13432
13433   if (sw_if_index_set == 0)
13434     {
13435       sw_if_index = ~0;
13436     }
13437
13438   if (!vam->json_output)
13439     {
13440       print (vam->ofp, "%11s%24s%24s%13s%15s%19s%14s%14s",
13441              "sw_if_index", "local", "remote", "vni",
13442              "protocol", "mcast_sw_if_index", "encap_vrf_id", "decap_vrf_id");
13443     }
13444
13445   /* Get list of vxlan-tunnel interfaces */
13446   M (VXLAN_GPE_TUNNEL_DUMP, mp);
13447
13448   mp->sw_if_index = htonl (sw_if_index);
13449
13450   S (mp);
13451
13452   /* Use a control ping for synchronization */
13453   MPING (CONTROL_PING, mp_ping);
13454   S (mp_ping);
13455
13456   W (ret);
13457   return ret;
13458 }
13459
13460 static void vl_api_l2_fib_table_details_t_handler
13461   (vl_api_l2_fib_table_details_t * mp)
13462 {
13463   vat_main_t *vam = &vat_main;
13464
13465   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
13466          "       %d       %d     %d",
13467          ntohl (mp->bd_id), format_ethernet_address, mp->mac,
13468          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
13469          mp->bvi_mac);
13470 }
13471
13472 static void vl_api_l2_fib_table_details_t_handler_json
13473   (vl_api_l2_fib_table_details_t * mp)
13474 {
13475   vat_main_t *vam = &vat_main;
13476   vat_json_node_t *node = NULL;
13477
13478   if (VAT_JSON_ARRAY != vam->json_tree.type)
13479     {
13480       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13481       vat_json_init_array (&vam->json_tree);
13482     }
13483   node = vat_json_array_add (&vam->json_tree);
13484
13485   vat_json_init_object (node);
13486   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
13487   vat_json_object_add_bytes (node, "mac", mp->mac, 6);
13488   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13489   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
13490   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
13491   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
13492 }
13493
13494 static int
13495 api_l2_fib_table_dump (vat_main_t * vam)
13496 {
13497   unformat_input_t *i = vam->input;
13498   vl_api_l2_fib_table_dump_t *mp;
13499   vl_api_control_ping_t *mp_ping;
13500   u32 bd_id;
13501   u8 bd_id_set = 0;
13502   int ret;
13503
13504   /* Parse args required to build the message */
13505   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13506     {
13507       if (unformat (i, "bd_id %d", &bd_id))
13508         bd_id_set = 1;
13509       else
13510         break;
13511     }
13512
13513   if (bd_id_set == 0)
13514     {
13515       errmsg ("missing bridge domain");
13516       return -99;
13517     }
13518
13519   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
13520
13521   /* Get list of l2 fib entries */
13522   M (L2_FIB_TABLE_DUMP, mp);
13523
13524   mp->bd_id = ntohl (bd_id);
13525   S (mp);
13526
13527   /* Use a control ping for synchronization */
13528   MPING (CONTROL_PING, mp_ping);
13529   S (mp_ping);
13530
13531   W (ret);
13532   return ret;
13533 }
13534
13535
13536 static int
13537 api_interface_name_renumber (vat_main_t * vam)
13538 {
13539   unformat_input_t *line_input = vam->input;
13540   vl_api_interface_name_renumber_t *mp;
13541   u32 sw_if_index = ~0;
13542   u32 new_show_dev_instance = ~0;
13543   int ret;
13544
13545   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13546     {
13547       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
13548                     &sw_if_index))
13549         ;
13550       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
13551         ;
13552       else if (unformat (line_input, "new_show_dev_instance %d",
13553                          &new_show_dev_instance))
13554         ;
13555       else
13556         break;
13557     }
13558
13559   if (sw_if_index == ~0)
13560     {
13561       errmsg ("missing interface name or sw_if_index");
13562       return -99;
13563     }
13564
13565   if (new_show_dev_instance == ~0)
13566     {
13567       errmsg ("missing new_show_dev_instance");
13568       return -99;
13569     }
13570
13571   M (INTERFACE_NAME_RENUMBER, mp);
13572
13573   mp->sw_if_index = ntohl (sw_if_index);
13574   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
13575
13576   S (mp);
13577   W (ret);
13578   return ret;
13579 }
13580
13581 static int
13582 api_ip_probe_neighbor (vat_main_t * vam)
13583 {
13584   unformat_input_t *i = vam->input;
13585   vl_api_ip_probe_neighbor_t *mp;
13586   vl_api_address_t dst_adr = { };
13587   u8 int_set = 0;
13588   u8 adr_set = 0;
13589   u32 sw_if_index;
13590   int ret;
13591
13592   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13593     {
13594       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13595         int_set = 1;
13596       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13597         int_set = 1;
13598       else if (unformat (i, "address %U", unformat_vl_api_address, &dst_adr))
13599         adr_set = 1;
13600       else
13601         break;
13602     }
13603
13604   if (int_set == 0)
13605     {
13606       errmsg ("missing interface");
13607       return -99;
13608     }
13609
13610   if (adr_set == 0)
13611     {
13612       errmsg ("missing addresses");
13613       return -99;
13614     }
13615
13616   M (IP_PROBE_NEIGHBOR, mp);
13617
13618   mp->sw_if_index = ntohl (sw_if_index);
13619   clib_memcpy (&mp->dst, &dst_adr, sizeof (dst_adr));
13620
13621   S (mp);
13622   W (ret);
13623   return ret;
13624 }
13625
13626 static int
13627 api_ip_scan_neighbor_enable_disable (vat_main_t * vam)
13628 {
13629   unformat_input_t *i = vam->input;
13630   vl_api_ip_scan_neighbor_enable_disable_t *mp;
13631   u8 mode = IP_SCAN_V46_NEIGHBORS;
13632   u32 interval = 0, time = 0, update = 0, delay = 0, stale = 0;
13633   int ret;
13634
13635   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13636     {
13637       if (unformat (i, "ip4"))
13638         mode = IP_SCAN_V4_NEIGHBORS;
13639       else if (unformat (i, "ip6"))
13640         mode = IP_SCAN_V6_NEIGHBORS;
13641       if (unformat (i, "both"))
13642         mode = IP_SCAN_V46_NEIGHBORS;
13643       else if (unformat (i, "disable"))
13644         mode = IP_SCAN_DISABLED;
13645       else if (unformat (i, "interval %d", &interval))
13646         ;
13647       else if (unformat (i, "max-time %d", &time))
13648         ;
13649       else if (unformat (i, "max-update %d", &update))
13650         ;
13651       else if (unformat (i, "delay %d", &delay))
13652         ;
13653       else if (unformat (i, "stale %d", &stale))
13654         ;
13655       else
13656         break;
13657     }
13658
13659   if (interval > 255)
13660     {
13661       errmsg ("interval cannot exceed 255 minutes.");
13662       return -99;
13663     }
13664   if (time > 255)
13665     {
13666       errmsg ("max-time cannot exceed 255 usec.");
13667       return -99;
13668     }
13669   if (update > 255)
13670     {
13671       errmsg ("max-update cannot exceed 255.");
13672       return -99;
13673     }
13674   if (delay > 255)
13675     {
13676       errmsg ("delay cannot exceed 255 msec.");
13677       return -99;
13678     }
13679   if (stale > 255)
13680     {
13681       errmsg ("stale cannot exceed 255 minutes.");
13682       return -99;
13683     }
13684
13685   M (IP_SCAN_NEIGHBOR_ENABLE_DISABLE, mp);
13686   mp->mode = mode;
13687   mp->scan_interval = interval;
13688   mp->max_proc_time = time;
13689   mp->max_update = update;
13690   mp->scan_int_delay = delay;
13691   mp->stale_threshold = stale;
13692
13693   S (mp);
13694   W (ret);
13695   return ret;
13696 }
13697
13698 static int
13699 api_want_ip4_arp_events (vat_main_t * vam)
13700 {
13701   unformat_input_t *line_input = vam->input;
13702   vl_api_want_ip4_arp_events_t *mp;
13703   ip4_address_t address;
13704   int address_set = 0;
13705   u32 enable_disable = 1;
13706   int ret;
13707
13708   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13709     {
13710       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
13711         address_set = 1;
13712       else if (unformat (line_input, "del"))
13713         enable_disable = 0;
13714       else
13715         break;
13716     }
13717
13718   if (address_set == 0)
13719     {
13720       errmsg ("missing addresses");
13721       return -99;
13722     }
13723
13724   M (WANT_IP4_ARP_EVENTS, mp);
13725   mp->enable_disable = enable_disable;
13726   mp->pid = htonl (getpid ());
13727   clib_memcpy (mp->ip, &address, sizeof (address));
13728
13729   S (mp);
13730   W (ret);
13731   return ret;
13732 }
13733
13734 static int
13735 api_want_ip6_nd_events (vat_main_t * vam)
13736 {
13737   unformat_input_t *line_input = vam->input;
13738   vl_api_want_ip6_nd_events_t *mp;
13739   vl_api_ip6_address_t address;
13740   int address_set = 0;
13741   u32 enable_disable = 1;
13742   int ret;
13743
13744   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13745     {
13746       if (unformat
13747           (line_input, "address %U", unformat_vl_api_ip6_address, &address))
13748         address_set = 1;
13749       else if (unformat (line_input, "del"))
13750         enable_disable = 0;
13751       else
13752         break;
13753     }
13754
13755   if (address_set == 0)
13756     {
13757       errmsg ("missing addresses");
13758       return -99;
13759     }
13760
13761   M (WANT_IP6_ND_EVENTS, mp);
13762   mp->enable_disable = enable_disable;
13763   mp->pid = htonl (getpid ());
13764   clib_memcpy (&mp->ip, &address, sizeof (address));
13765
13766   S (mp);
13767   W (ret);
13768   return ret;
13769 }
13770
13771 static int
13772 api_want_l2_macs_events (vat_main_t * vam)
13773 {
13774   unformat_input_t *line_input = vam->input;
13775   vl_api_want_l2_macs_events_t *mp;
13776   u8 enable_disable = 1;
13777   u32 scan_delay = 0;
13778   u32 max_macs_in_event = 0;
13779   u32 learn_limit = 0;
13780   int ret;
13781
13782   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13783     {
13784       if (unformat (line_input, "learn-limit %d", &learn_limit))
13785         ;
13786       else if (unformat (line_input, "scan-delay %d", &scan_delay))
13787         ;
13788       else if (unformat (line_input, "max-entries %d", &max_macs_in_event))
13789         ;
13790       else if (unformat (line_input, "disable"))
13791         enable_disable = 0;
13792       else
13793         break;
13794     }
13795
13796   M (WANT_L2_MACS_EVENTS, mp);
13797   mp->enable_disable = enable_disable;
13798   mp->pid = htonl (getpid ());
13799   mp->learn_limit = htonl (learn_limit);
13800   mp->scan_delay = (u8) scan_delay;
13801   mp->max_macs_in_event = (u8) (max_macs_in_event / 10);
13802   S (mp);
13803   W (ret);
13804   return ret;
13805 }
13806
13807 static int
13808 api_input_acl_set_interface (vat_main_t * vam)
13809 {
13810   unformat_input_t *i = vam->input;
13811   vl_api_input_acl_set_interface_t *mp;
13812   u32 sw_if_index;
13813   int sw_if_index_set;
13814   u32 ip4_table_index = ~0;
13815   u32 ip6_table_index = ~0;
13816   u32 l2_table_index = ~0;
13817   u8 is_add = 1;
13818   int ret;
13819
13820   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13821     {
13822       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13823         sw_if_index_set = 1;
13824       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13825         sw_if_index_set = 1;
13826       else if (unformat (i, "del"))
13827         is_add = 0;
13828       else if (unformat (i, "ip4-table %d", &ip4_table_index))
13829         ;
13830       else if (unformat (i, "ip6-table %d", &ip6_table_index))
13831         ;
13832       else if (unformat (i, "l2-table %d", &l2_table_index))
13833         ;
13834       else
13835         {
13836           clib_warning ("parse error '%U'", format_unformat_error, i);
13837           return -99;
13838         }
13839     }
13840
13841   if (sw_if_index_set == 0)
13842     {
13843       errmsg ("missing interface name or sw_if_index");
13844       return -99;
13845     }
13846
13847   M (INPUT_ACL_SET_INTERFACE, mp);
13848
13849   mp->sw_if_index = ntohl (sw_if_index);
13850   mp->ip4_table_index = ntohl (ip4_table_index);
13851   mp->ip6_table_index = ntohl (ip6_table_index);
13852   mp->l2_table_index = ntohl (l2_table_index);
13853   mp->is_add = is_add;
13854
13855   S (mp);
13856   W (ret);
13857   return ret;
13858 }
13859
13860 static int
13861 api_output_acl_set_interface (vat_main_t * vam)
13862 {
13863   unformat_input_t *i = vam->input;
13864   vl_api_output_acl_set_interface_t *mp;
13865   u32 sw_if_index;
13866   int sw_if_index_set;
13867   u32 ip4_table_index = ~0;
13868   u32 ip6_table_index = ~0;
13869   u32 l2_table_index = ~0;
13870   u8 is_add = 1;
13871   int ret;
13872
13873   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13874     {
13875       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13876         sw_if_index_set = 1;
13877       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13878         sw_if_index_set = 1;
13879       else if (unformat (i, "del"))
13880         is_add = 0;
13881       else if (unformat (i, "ip4-table %d", &ip4_table_index))
13882         ;
13883       else if (unformat (i, "ip6-table %d", &ip6_table_index))
13884         ;
13885       else if (unformat (i, "l2-table %d", &l2_table_index))
13886         ;
13887       else
13888         {
13889           clib_warning ("parse error '%U'", format_unformat_error, i);
13890           return -99;
13891         }
13892     }
13893
13894   if (sw_if_index_set == 0)
13895     {
13896       errmsg ("missing interface name or sw_if_index");
13897       return -99;
13898     }
13899
13900   M (OUTPUT_ACL_SET_INTERFACE, mp);
13901
13902   mp->sw_if_index = ntohl (sw_if_index);
13903   mp->ip4_table_index = ntohl (ip4_table_index);
13904   mp->ip6_table_index = ntohl (ip6_table_index);
13905   mp->l2_table_index = ntohl (l2_table_index);
13906   mp->is_add = is_add;
13907
13908   S (mp);
13909   W (ret);
13910   return ret;
13911 }
13912
13913 static int
13914 api_ip_address_dump (vat_main_t * vam)
13915 {
13916   unformat_input_t *i = vam->input;
13917   vl_api_ip_address_dump_t *mp;
13918   vl_api_control_ping_t *mp_ping;
13919   u32 sw_if_index = ~0;
13920   u8 sw_if_index_set = 0;
13921   u8 ipv4_set = 0;
13922   u8 ipv6_set = 0;
13923   int ret;
13924
13925   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13926     {
13927       if (unformat (i, "sw_if_index %d", &sw_if_index))
13928         sw_if_index_set = 1;
13929       else
13930         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13931         sw_if_index_set = 1;
13932       else if (unformat (i, "ipv4"))
13933         ipv4_set = 1;
13934       else if (unformat (i, "ipv6"))
13935         ipv6_set = 1;
13936       else
13937         break;
13938     }
13939
13940   if (ipv4_set && ipv6_set)
13941     {
13942       errmsg ("ipv4 and ipv6 flags cannot be both set");
13943       return -99;
13944     }
13945
13946   if ((!ipv4_set) && (!ipv6_set))
13947     {
13948       errmsg ("no ipv4 nor ipv6 flag set");
13949       return -99;
13950     }
13951
13952   if (sw_if_index_set == 0)
13953     {
13954       errmsg ("missing interface name or sw_if_index");
13955       return -99;
13956     }
13957
13958   vam->current_sw_if_index = sw_if_index;
13959   vam->is_ipv6 = ipv6_set;
13960
13961   M (IP_ADDRESS_DUMP, mp);
13962   mp->sw_if_index = ntohl (sw_if_index);
13963   mp->is_ipv6 = ipv6_set;
13964   S (mp);
13965
13966   /* Use a control ping for synchronization */
13967   MPING (CONTROL_PING, mp_ping);
13968   S (mp_ping);
13969
13970   W (ret);
13971   return ret;
13972 }
13973
13974 static int
13975 api_ip_dump (vat_main_t * vam)
13976 {
13977   vl_api_ip_dump_t *mp;
13978   vl_api_control_ping_t *mp_ping;
13979   unformat_input_t *in = vam->input;
13980   int ipv4_set = 0;
13981   int ipv6_set = 0;
13982   int is_ipv6;
13983   int i;
13984   int ret;
13985
13986   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
13987     {
13988       if (unformat (in, "ipv4"))
13989         ipv4_set = 1;
13990       else if (unformat (in, "ipv6"))
13991         ipv6_set = 1;
13992       else
13993         break;
13994     }
13995
13996   if (ipv4_set && ipv6_set)
13997     {
13998       errmsg ("ipv4 and ipv6 flags cannot be both set");
13999       return -99;
14000     }
14001
14002   if ((!ipv4_set) && (!ipv6_set))
14003     {
14004       errmsg ("no ipv4 nor ipv6 flag set");
14005       return -99;
14006     }
14007
14008   is_ipv6 = ipv6_set;
14009   vam->is_ipv6 = is_ipv6;
14010
14011   /* free old data */
14012   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
14013     {
14014       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
14015     }
14016   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
14017
14018   M (IP_DUMP, mp);
14019   mp->is_ipv6 = ipv6_set;
14020   S (mp);
14021
14022   /* Use a control ping for synchronization */
14023   MPING (CONTROL_PING, mp_ping);
14024   S (mp_ping);
14025
14026   W (ret);
14027   return ret;
14028 }
14029
14030 static int
14031 api_ipsec_spd_add_del (vat_main_t * vam)
14032 {
14033   unformat_input_t *i = vam->input;
14034   vl_api_ipsec_spd_add_del_t *mp;
14035   u32 spd_id = ~0;
14036   u8 is_add = 1;
14037   int ret;
14038
14039   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14040     {
14041       if (unformat (i, "spd_id %d", &spd_id))
14042         ;
14043       else if (unformat (i, "del"))
14044         is_add = 0;
14045       else
14046         {
14047           clib_warning ("parse error '%U'", format_unformat_error, i);
14048           return -99;
14049         }
14050     }
14051   if (spd_id == ~0)
14052     {
14053       errmsg ("spd_id must be set");
14054       return -99;
14055     }
14056
14057   M (IPSEC_SPD_ADD_DEL, mp);
14058
14059   mp->spd_id = ntohl (spd_id);
14060   mp->is_add = is_add;
14061
14062   S (mp);
14063   W (ret);
14064   return ret;
14065 }
14066
14067 static int
14068 api_ipsec_interface_add_del_spd (vat_main_t * vam)
14069 {
14070   unformat_input_t *i = vam->input;
14071   vl_api_ipsec_interface_add_del_spd_t *mp;
14072   u32 sw_if_index;
14073   u8 sw_if_index_set = 0;
14074   u32 spd_id = (u32) ~ 0;
14075   u8 is_add = 1;
14076   int ret;
14077
14078   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14079     {
14080       if (unformat (i, "del"))
14081         is_add = 0;
14082       else if (unformat (i, "spd_id %d", &spd_id))
14083         ;
14084       else
14085         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14086         sw_if_index_set = 1;
14087       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14088         sw_if_index_set = 1;
14089       else
14090         {
14091           clib_warning ("parse error '%U'", format_unformat_error, i);
14092           return -99;
14093         }
14094
14095     }
14096
14097   if (spd_id == (u32) ~ 0)
14098     {
14099       errmsg ("spd_id must be set");
14100       return -99;
14101     }
14102
14103   if (sw_if_index_set == 0)
14104     {
14105       errmsg ("missing interface name or sw_if_index");
14106       return -99;
14107     }
14108
14109   M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
14110
14111   mp->spd_id = ntohl (spd_id);
14112   mp->sw_if_index = ntohl (sw_if_index);
14113   mp->is_add = is_add;
14114
14115   S (mp);
14116   W (ret);
14117   return ret;
14118 }
14119
14120 static int
14121 api_ipsec_spd_entry_add_del (vat_main_t * vam)
14122 {
14123   unformat_input_t *i = vam->input;
14124   vl_api_ipsec_spd_entry_add_del_t *mp;
14125   u8 is_add = 1, is_outbound = 0;
14126   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
14127   i32 priority = 0;
14128   u32 rport_start = 0, rport_stop = (u32) ~ 0;
14129   u32 lport_start = 0, lport_stop = (u32) ~ 0;
14130   vl_api_address_t laddr_start = { }, laddr_stop =
14131   {
14132   }, raddr_start =
14133   {
14134   }, raddr_stop =
14135   {
14136   };
14137   int ret;
14138
14139   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14140     {
14141       if (unformat (i, "del"))
14142         is_add = 0;
14143       if (unformat (i, "outbound"))
14144         is_outbound = 1;
14145       if (unformat (i, "inbound"))
14146         is_outbound = 0;
14147       else if (unformat (i, "spd_id %d", &spd_id))
14148         ;
14149       else if (unformat (i, "sa_id %d", &sa_id))
14150         ;
14151       else if (unformat (i, "priority %d", &priority))
14152         ;
14153       else if (unformat (i, "protocol %d", &protocol))
14154         ;
14155       else if (unformat (i, "lport_start %d", &lport_start))
14156         ;
14157       else if (unformat (i, "lport_stop %d", &lport_stop))
14158         ;
14159       else if (unformat (i, "rport_start %d", &rport_start))
14160         ;
14161       else if (unformat (i, "rport_stop %d", &rport_stop))
14162         ;
14163       else if (unformat (i, "laddr_start %U",
14164                          unformat_vl_api_address, &laddr_start))
14165         ;
14166       else if (unformat (i, "laddr_stop %U", unformat_vl_api_address,
14167                          &laddr_stop))
14168         ;
14169       else if (unformat (i, "raddr_start %U", unformat_vl_api_address,
14170                          &raddr_start))
14171         ;
14172       else if (unformat (i, "raddr_stop %U", unformat_vl_api_address,
14173                          &raddr_stop))
14174         ;
14175       else
14176         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
14177         {
14178           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
14179             {
14180               clib_warning ("unsupported action: 'resolve'");
14181               return -99;
14182             }
14183         }
14184       else
14185         {
14186           clib_warning ("parse error '%U'", format_unformat_error, i);
14187           return -99;
14188         }
14189
14190     }
14191
14192   M (IPSEC_SPD_ENTRY_ADD_DEL, mp);
14193
14194   mp->is_add = is_add;
14195
14196   mp->entry.spd_id = ntohl (spd_id);
14197   mp->entry.priority = ntohl (priority);
14198   mp->entry.is_outbound = is_outbound;
14199
14200   clib_memcpy (&mp->entry.remote_address_start, &raddr_start,
14201                sizeof (vl_api_address_t));
14202   clib_memcpy (&mp->entry.remote_address_stop, &raddr_stop,
14203                sizeof (vl_api_address_t));
14204   clib_memcpy (&mp->entry.local_address_start, &laddr_start,
14205                sizeof (vl_api_address_t));
14206   clib_memcpy (&mp->entry.local_address_stop, &laddr_stop,
14207                sizeof (vl_api_address_t));
14208
14209   mp->entry.protocol = (u8) protocol;
14210   mp->entry.local_port_start = ntohs ((u16) lport_start);
14211   mp->entry.local_port_stop = ntohs ((u16) lport_stop);
14212   mp->entry.remote_port_start = ntohs ((u16) rport_start);
14213   mp->entry.remote_port_stop = ntohs ((u16) rport_stop);
14214   mp->entry.policy = (u8) policy;
14215   mp->entry.sa_id = ntohl (sa_id);
14216
14217   S (mp);
14218   W (ret);
14219   return ret;
14220 }
14221
14222 static int
14223 api_ipsec_sad_entry_add_del (vat_main_t * vam)
14224 {
14225   unformat_input_t *i = vam->input;
14226   vl_api_ipsec_sad_entry_add_del_t *mp;
14227   u32 sad_id = 0, spi = 0;
14228   u8 *ck = 0, *ik = 0;
14229   u8 is_add = 1;
14230
14231   vl_api_ipsec_crypto_alg_t crypto_alg = IPSEC_API_CRYPTO_ALG_NONE;
14232   vl_api_ipsec_integ_alg_t integ_alg = IPSEC_API_INTEG_ALG_NONE;
14233   vl_api_ipsec_sad_flags_t flags = IPSEC_API_SAD_FLAG_NONE;
14234   vl_api_ipsec_proto_t protocol = IPSEC_API_PROTO_AH;
14235   vl_api_address_t tun_src, tun_dst;
14236   int ret;
14237
14238   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14239     {
14240       if (unformat (i, "del"))
14241         is_add = 0;
14242       else if (unformat (i, "sad_id %d", &sad_id))
14243         ;
14244       else if (unformat (i, "spi %d", &spi))
14245         ;
14246       else if (unformat (i, "esp"))
14247         protocol = IPSEC_API_PROTO_ESP;
14248       else
14249         if (unformat (i, "tunnel_src %U", unformat_vl_api_address, &tun_src))
14250         {
14251           flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL;
14252           if (ADDRESS_IP6 == tun_src.af)
14253             flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL_V6;
14254         }
14255       else
14256         if (unformat (i, "tunnel_dst %U", unformat_vl_api_address, &tun_dst))
14257         {
14258           flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL;
14259           if (ADDRESS_IP6 == tun_src.af)
14260             flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL_V6;
14261         }
14262       else
14263         if (unformat (i, "crypto_alg %U",
14264                       unformat_ipsec_api_crypto_alg, &crypto_alg))
14265         ;
14266       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
14267         ;
14268       else if (unformat (i, "integ_alg %U",
14269                          unformat_ipsec_api_integ_alg, &integ_alg))
14270         ;
14271       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
14272         ;
14273       else
14274         {
14275           clib_warning ("parse error '%U'", format_unformat_error, i);
14276           return -99;
14277         }
14278
14279     }
14280
14281   M (IPSEC_SAD_ENTRY_ADD_DEL, mp);
14282
14283   mp->is_add = is_add;
14284   mp->entry.sad_id = ntohl (sad_id);
14285   mp->entry.protocol = protocol;
14286   mp->entry.spi = ntohl (spi);
14287   mp->entry.flags = flags;
14288
14289   mp->entry.crypto_algorithm = crypto_alg;
14290   mp->entry.integrity_algorithm = integ_alg;
14291   mp->entry.crypto_key.length = vec_len (ck);
14292   mp->entry.integrity_key.length = vec_len (ik);
14293
14294   if (mp->entry.crypto_key.length > sizeof (mp->entry.crypto_key.data))
14295     mp->entry.crypto_key.length = sizeof (mp->entry.crypto_key.data);
14296
14297   if (mp->entry.integrity_key.length > sizeof (mp->entry.integrity_key.data))
14298     mp->entry.integrity_key.length = sizeof (mp->entry.integrity_key.data);
14299
14300   if (ck)
14301     clib_memcpy (mp->entry.crypto_key.data, ck, mp->entry.crypto_key.length);
14302   if (ik)
14303     clib_memcpy (mp->entry.integrity_key.data, ik,
14304                  mp->entry.integrity_key.length);
14305
14306   if (flags & IPSEC_API_SAD_FLAG_IS_TUNNEL)
14307     {
14308       clib_memcpy (&mp->entry.tunnel_src, &tun_src,
14309                    sizeof (mp->entry.tunnel_src));
14310       clib_memcpy (&mp->entry.tunnel_dst, &tun_dst,
14311                    sizeof (mp->entry.tunnel_dst));
14312     }
14313
14314   S (mp);
14315   W (ret);
14316   return ret;
14317 }
14318
14319 static int
14320 api_ipsec_tunnel_if_add_del (vat_main_t * vam)
14321 {
14322   unformat_input_t *i = vam->input;
14323   vl_api_ipsec_tunnel_if_add_del_t *mp;
14324   u32 local_spi = 0, remote_spi = 0;
14325   u32 crypto_alg = 0, integ_alg = 0;
14326   u8 *lck = NULL, *rck = NULL;
14327   u8 *lik = NULL, *rik = NULL;
14328   vl_api_address_t local_ip = { 0 };
14329   vl_api_address_t remote_ip = { 0 };
14330   f64 before = 0;
14331   u8 is_add = 1;
14332   u8 esn = 0;
14333   u8 anti_replay = 0;
14334   u8 renumber = 0;
14335   u32 instance = ~0;
14336   u32 count = 1, jj;
14337   int ret = -1;
14338
14339   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14340     {
14341       if (unformat (i, "del"))
14342         is_add = 0;
14343       else if (unformat (i, "esn"))
14344         esn = 1;
14345       else if (unformat (i, "anti-replay"))
14346         anti_replay = 1;
14347       else if (unformat (i, "count %d", &count))
14348         ;
14349       else if (unformat (i, "local_spi %d", &local_spi))
14350         ;
14351       else if (unformat (i, "remote_spi %d", &remote_spi))
14352         ;
14353       else
14354         if (unformat (i, "local_ip %U", unformat_vl_api_address, &local_ip))
14355         ;
14356       else
14357         if (unformat (i, "remote_ip %U", unformat_vl_api_address, &remote_ip))
14358         ;
14359       else if (unformat (i, "local_crypto_key %U", unformat_hex_string, &lck))
14360         ;
14361       else
14362         if (unformat (i, "remote_crypto_key %U", unformat_hex_string, &rck))
14363         ;
14364       else if (unformat (i, "local_integ_key %U", unformat_hex_string, &lik))
14365         ;
14366       else if (unformat (i, "remote_integ_key %U", unformat_hex_string, &rik))
14367         ;
14368       else
14369         if (unformat
14370             (i, "crypto_alg %U", unformat_ipsec_api_crypto_alg, &crypto_alg))
14371         {
14372           if (crypto_alg >= IPSEC_CRYPTO_N_ALG)
14373             {
14374               errmsg ("unsupported crypto-alg: '%U'\n",
14375                       format_ipsec_crypto_alg, crypto_alg);
14376               return -99;
14377             }
14378         }
14379       else
14380         if (unformat
14381             (i, "integ_alg %U", unformat_ipsec_api_integ_alg, &integ_alg))
14382         {
14383           if (integ_alg >= IPSEC_INTEG_N_ALG)
14384             {
14385               errmsg ("unsupported integ-alg: '%U'\n",
14386                       format_ipsec_integ_alg, integ_alg);
14387               return -99;
14388             }
14389         }
14390       else if (unformat (i, "instance %u", &instance))
14391         renumber = 1;
14392       else
14393         {
14394           errmsg ("parse error '%U'\n", format_unformat_error, i);
14395           return -99;
14396         }
14397     }
14398
14399   if (count > 1)
14400     {
14401       /* Turn on async mode */
14402       vam->async_mode = 1;
14403       vam->async_errors = 0;
14404       before = vat_time_now (vam);
14405     }
14406
14407   for (jj = 0; jj < count; jj++)
14408     {
14409       M (IPSEC_TUNNEL_IF_ADD_DEL, mp);
14410
14411       mp->is_add = is_add;
14412       mp->esn = esn;
14413       mp->anti_replay = anti_replay;
14414
14415       if (jj > 0)
14416         increment_address (&remote_ip);
14417
14418       clib_memcpy (&mp->local_ip, &local_ip, sizeof (local_ip));
14419       clib_memcpy (&mp->remote_ip, &remote_ip, sizeof (remote_ip));
14420
14421       mp->local_spi = htonl (local_spi + jj);
14422       mp->remote_spi = htonl (remote_spi + jj);
14423       mp->crypto_alg = (u8) crypto_alg;
14424
14425       mp->local_crypto_key_len = 0;
14426       if (lck)
14427         {
14428           mp->local_crypto_key_len = vec_len (lck);
14429           if (mp->local_crypto_key_len > sizeof (mp->local_crypto_key))
14430             mp->local_crypto_key_len = sizeof (mp->local_crypto_key);
14431           clib_memcpy (mp->local_crypto_key, lck, mp->local_crypto_key_len);
14432         }
14433
14434       mp->remote_crypto_key_len = 0;
14435       if (rck)
14436         {
14437           mp->remote_crypto_key_len = vec_len (rck);
14438           if (mp->remote_crypto_key_len > sizeof (mp->remote_crypto_key))
14439             mp->remote_crypto_key_len = sizeof (mp->remote_crypto_key);
14440           clib_memcpy (mp->remote_crypto_key, rck, mp->remote_crypto_key_len);
14441         }
14442
14443       mp->integ_alg = (u8) integ_alg;
14444
14445       mp->local_integ_key_len = 0;
14446       if (lik)
14447         {
14448           mp->local_integ_key_len = vec_len (lik);
14449           if (mp->local_integ_key_len > sizeof (mp->local_integ_key))
14450             mp->local_integ_key_len = sizeof (mp->local_integ_key);
14451           clib_memcpy (mp->local_integ_key, lik, mp->local_integ_key_len);
14452         }
14453
14454       mp->remote_integ_key_len = 0;
14455       if (rik)
14456         {
14457           mp->remote_integ_key_len = vec_len (rik);
14458           if (mp->remote_integ_key_len > sizeof (mp->remote_integ_key))
14459             mp->remote_integ_key_len = sizeof (mp->remote_integ_key);
14460           clib_memcpy (mp->remote_integ_key, rik, mp->remote_integ_key_len);
14461         }
14462
14463       if (renumber)
14464         {
14465           mp->renumber = renumber;
14466           mp->show_instance = ntohl (instance);
14467         }
14468       S (mp);
14469     }
14470
14471   /* When testing multiple add/del ops, use a control-ping to sync */
14472   if (count > 1)
14473     {
14474       vl_api_control_ping_t *mp_ping;
14475       f64 after;
14476       f64 timeout;
14477
14478       /* Shut off async mode */
14479       vam->async_mode = 0;
14480
14481       MPING (CONTROL_PING, mp_ping);
14482       S (mp_ping);
14483
14484       timeout = vat_time_now (vam) + 1.0;
14485       while (vat_time_now (vam) < timeout)
14486         if (vam->result_ready == 1)
14487           goto out;
14488       vam->retval = -99;
14489
14490     out:
14491       if (vam->retval == -99)
14492         errmsg ("timeout");
14493
14494       if (vam->async_errors > 0)
14495         {
14496           errmsg ("%d asynchronous errors", vam->async_errors);
14497           vam->retval = -98;
14498         }
14499       vam->async_errors = 0;
14500       after = vat_time_now (vam);
14501
14502       /* slim chance, but we might have eaten SIGTERM on the first iteration */
14503       if (jj > 0)
14504         count = jj;
14505
14506       print (vam->ofp, "%d tunnels in %.6f secs, %.2f tunnels/sec",
14507              count, after - before, count / (after - before));
14508     }
14509   else
14510     {
14511       /* Wait for a reply... */
14512       W (ret);
14513       return ret;
14514     }
14515
14516   return ret;
14517 }
14518
14519 static void
14520 vl_api_ipsec_sa_details_t_handler (vl_api_ipsec_sa_details_t * mp)
14521 {
14522   vat_main_t *vam = &vat_main;
14523
14524   print (vam->ofp, "sa_id %u sw_if_index %u spi %u proto %u crypto_alg %u "
14525          "crypto_key %U integ_alg %u integ_key %U flags %x "
14526          "tunnel_src_addr %U tunnel_dst_addr %U "
14527          "salt %u seq_outbound %lu last_seq_inbound %lu "
14528          "replay_window %lu\n",
14529          ntohl (mp->entry.sad_id),
14530          ntohl (mp->sw_if_index),
14531          ntohl (mp->entry.spi),
14532          ntohl (mp->entry.protocol),
14533          ntohl (mp->entry.crypto_algorithm),
14534          format_hex_bytes, mp->entry.crypto_key.data,
14535          mp->entry.crypto_key.length, ntohl (mp->entry.integrity_algorithm),
14536          format_hex_bytes, mp->entry.integrity_key.data,
14537          mp->entry.integrity_key.length, ntohl (mp->entry.flags),
14538          format_vl_api_address, &mp->entry.tunnel_src, format_vl_api_address,
14539          &mp->entry.tunnel_dst, ntohl (mp->salt),
14540          clib_net_to_host_u64 (mp->seq_outbound),
14541          clib_net_to_host_u64 (mp->last_seq_inbound),
14542          clib_net_to_host_u64 (mp->replay_window));
14543 }
14544
14545 #define vl_api_ipsec_sa_details_t_endian vl_noop_handler
14546 #define vl_api_ipsec_sa_details_t_print vl_noop_handler
14547
14548 static void vl_api_ipsec_sa_details_t_handler_json
14549   (vl_api_ipsec_sa_details_t * mp)
14550 {
14551   vat_main_t *vam = &vat_main;
14552   vat_json_node_t *node = NULL;
14553   vl_api_ipsec_sad_flags_t flags;
14554
14555   if (VAT_JSON_ARRAY != vam->json_tree.type)
14556     {
14557       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14558       vat_json_init_array (&vam->json_tree);
14559     }
14560   node = vat_json_array_add (&vam->json_tree);
14561
14562   vat_json_init_object (node);
14563   vat_json_object_add_uint (node, "sa_id", ntohl (mp->entry.sad_id));
14564   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
14565   vat_json_object_add_uint (node, "spi", ntohl (mp->entry.spi));
14566   vat_json_object_add_uint (node, "proto", ntohl (mp->entry.protocol));
14567   vat_json_object_add_uint (node, "crypto_alg",
14568                             ntohl (mp->entry.crypto_algorithm));
14569   vat_json_object_add_uint (node, "integ_alg",
14570                             ntohl (mp->entry.integrity_algorithm));
14571   flags = ntohl (mp->entry.flags);
14572   vat_json_object_add_uint (node, "use_esn",
14573                             ! !(flags & IPSEC_API_SAD_FLAG_USE_ESN));
14574   vat_json_object_add_uint (node, "use_anti_replay",
14575                             ! !(flags & IPSEC_API_SAD_FLAG_USE_ANTI_REPLAY));
14576   vat_json_object_add_uint (node, "is_tunnel",
14577                             ! !(flags & IPSEC_API_SAD_FLAG_IS_TUNNEL));
14578   vat_json_object_add_uint (node, "is_tunnel_ip6",
14579                             ! !(flags & IPSEC_API_SAD_FLAG_IS_TUNNEL_V6));
14580   vat_json_object_add_uint (node, "udp_encap",
14581                             ! !(flags & IPSEC_API_SAD_FLAG_UDP_ENCAP));
14582   vat_json_object_add_bytes (node, "crypto_key", mp->entry.crypto_key.data,
14583                              mp->entry.crypto_key.length);
14584   vat_json_object_add_bytes (node, "integ_key", mp->entry.integrity_key.data,
14585                              mp->entry.integrity_key.length);
14586   vat_json_object_add_address (node, "src", &mp->entry.tunnel_src);
14587   vat_json_object_add_address (node, "dst", &mp->entry.tunnel_dst);
14588   vat_json_object_add_uint (node, "replay_window",
14589                             clib_net_to_host_u64 (mp->replay_window));
14590 }
14591
14592 static int
14593 api_ipsec_sa_dump (vat_main_t * vam)
14594 {
14595   unformat_input_t *i = vam->input;
14596   vl_api_ipsec_sa_dump_t *mp;
14597   vl_api_control_ping_t *mp_ping;
14598   u32 sa_id = ~0;
14599   int ret;
14600
14601   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14602     {
14603       if (unformat (i, "sa_id %d", &sa_id))
14604         ;
14605       else
14606         {
14607           clib_warning ("parse error '%U'", format_unformat_error, i);
14608           return -99;
14609         }
14610     }
14611
14612   M (IPSEC_SA_DUMP, mp);
14613
14614   mp->sa_id = ntohl (sa_id);
14615
14616   S (mp);
14617
14618   /* Use a control ping for synchronization */
14619   M (CONTROL_PING, mp_ping);
14620   S (mp_ping);
14621
14622   W (ret);
14623   return ret;
14624 }
14625
14626 static int
14627 api_ipsec_tunnel_if_set_sa (vat_main_t * vam)
14628 {
14629   unformat_input_t *i = vam->input;
14630   vl_api_ipsec_tunnel_if_set_sa_t *mp;
14631   u32 sw_if_index = ~0;
14632   u32 sa_id = ~0;
14633   u8 is_outbound = (u8) ~ 0;
14634   int ret;
14635
14636   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14637     {
14638       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14639         ;
14640       else if (unformat (i, "sa_id %d", &sa_id))
14641         ;
14642       else if (unformat (i, "outbound"))
14643         is_outbound = 1;
14644       else if (unformat (i, "inbound"))
14645         is_outbound = 0;
14646       else
14647         {
14648           clib_warning ("parse error '%U'", format_unformat_error, i);
14649           return -99;
14650         }
14651     }
14652
14653   if (sw_if_index == ~0)
14654     {
14655       errmsg ("interface must be specified");
14656       return -99;
14657     }
14658
14659   if (sa_id == ~0)
14660     {
14661       errmsg ("SA ID must be specified");
14662       return -99;
14663     }
14664
14665   M (IPSEC_TUNNEL_IF_SET_SA, mp);
14666
14667   mp->sw_if_index = htonl (sw_if_index);
14668   mp->sa_id = htonl (sa_id);
14669   mp->is_outbound = is_outbound;
14670
14671   S (mp);
14672   W (ret);
14673
14674   return ret;
14675 }
14676
14677 static int
14678 api_get_first_msg_id (vat_main_t * vam)
14679 {
14680   vl_api_get_first_msg_id_t *mp;
14681   unformat_input_t *i = vam->input;
14682   u8 *name;
14683   u8 name_set = 0;
14684   int ret;
14685
14686   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14687     {
14688       if (unformat (i, "client %s", &name))
14689         name_set = 1;
14690       else
14691         break;
14692     }
14693
14694   if (name_set == 0)
14695     {
14696       errmsg ("missing client name");
14697       return -99;
14698     }
14699   vec_add1 (name, 0);
14700
14701   if (vec_len (name) > 63)
14702     {
14703       errmsg ("client name too long");
14704       return -99;
14705     }
14706
14707   M (GET_FIRST_MSG_ID, mp);
14708   clib_memcpy (mp->name, name, vec_len (name));
14709   S (mp);
14710   W (ret);
14711   return ret;
14712 }
14713
14714 static int
14715 api_cop_interface_enable_disable (vat_main_t * vam)
14716 {
14717   unformat_input_t *line_input = vam->input;
14718   vl_api_cop_interface_enable_disable_t *mp;
14719   u32 sw_if_index = ~0;
14720   u8 enable_disable = 1;
14721   int ret;
14722
14723   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14724     {
14725       if (unformat (line_input, "disable"))
14726         enable_disable = 0;
14727       if (unformat (line_input, "enable"))
14728         enable_disable = 1;
14729       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
14730                          vam, &sw_if_index))
14731         ;
14732       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
14733         ;
14734       else
14735         break;
14736     }
14737
14738   if (sw_if_index == ~0)
14739     {
14740       errmsg ("missing interface name or sw_if_index");
14741       return -99;
14742     }
14743
14744   /* Construct the API message */
14745   M (COP_INTERFACE_ENABLE_DISABLE, mp);
14746   mp->sw_if_index = ntohl (sw_if_index);
14747   mp->enable_disable = enable_disable;
14748
14749   /* send it... */
14750   S (mp);
14751   /* Wait for the reply */
14752   W (ret);
14753   return ret;
14754 }
14755
14756 static int
14757 api_cop_whitelist_enable_disable (vat_main_t * vam)
14758 {
14759   unformat_input_t *line_input = vam->input;
14760   vl_api_cop_whitelist_enable_disable_t *mp;
14761   u32 sw_if_index = ~0;
14762   u8 ip4 = 0, ip6 = 0, default_cop = 0;
14763   u32 fib_id = 0;
14764   int ret;
14765
14766   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14767     {
14768       if (unformat (line_input, "ip4"))
14769         ip4 = 1;
14770       else if (unformat (line_input, "ip6"))
14771         ip6 = 1;
14772       else if (unformat (line_input, "default"))
14773         default_cop = 1;
14774       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
14775                          vam, &sw_if_index))
14776         ;
14777       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
14778         ;
14779       else if (unformat (line_input, "fib-id %d", &fib_id))
14780         ;
14781       else
14782         break;
14783     }
14784
14785   if (sw_if_index == ~0)
14786     {
14787       errmsg ("missing interface name or sw_if_index");
14788       return -99;
14789     }
14790
14791   /* Construct the API message */
14792   M (COP_WHITELIST_ENABLE_DISABLE, mp);
14793   mp->sw_if_index = ntohl (sw_if_index);
14794   mp->fib_id = ntohl (fib_id);
14795   mp->ip4 = ip4;
14796   mp->ip6 = ip6;
14797   mp->default_cop = default_cop;
14798
14799   /* send it... */
14800   S (mp);
14801   /* Wait for the reply */
14802   W (ret);
14803   return ret;
14804 }
14805
14806 static int
14807 api_get_node_graph (vat_main_t * vam)
14808 {
14809   vl_api_get_node_graph_t *mp;
14810   int ret;
14811
14812   M (GET_NODE_GRAPH, mp);
14813
14814   /* send it... */
14815   S (mp);
14816   /* Wait for the reply */
14817   W (ret);
14818   return ret;
14819 }
14820
14821 /* *INDENT-OFF* */
14822 /** Used for parsing LISP eids */
14823 typedef CLIB_PACKED(struct{
14824   u8 addr[16];   /**< eid address */
14825   u32 len;       /**< prefix length if IP */
14826   u8 type;      /**< type of eid */
14827 }) lisp_eid_vat_t;
14828 /* *INDENT-ON* */
14829
14830 static uword
14831 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
14832 {
14833   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
14834
14835   clib_memset (a, 0, sizeof (a[0]));
14836
14837   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
14838     {
14839       a->type = 0;              /* ipv4 type */
14840     }
14841   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
14842     {
14843       a->type = 1;              /* ipv6 type */
14844     }
14845   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
14846     {
14847       a->type = 2;              /* mac type */
14848     }
14849   else if (unformat (input, "%U", unformat_nsh_address, a->addr))
14850     {
14851       a->type = 3;              /* NSH type */
14852       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) a->addr;
14853       nsh->spi = clib_host_to_net_u32 (nsh->spi);
14854     }
14855   else
14856     {
14857       return 0;
14858     }
14859
14860   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
14861     {
14862       return 0;
14863     }
14864
14865   return 1;
14866 }
14867
14868 static int
14869 lisp_eid_size_vat (u8 type)
14870 {
14871   switch (type)
14872     {
14873     case 0:
14874       return 4;
14875     case 1:
14876       return 16;
14877     case 2:
14878       return 6;
14879     case 3:
14880       return 5;
14881     }
14882   return 0;
14883 }
14884
14885 static void
14886 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
14887 {
14888   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
14889 }
14890
14891 static int
14892 api_one_add_del_locator_set (vat_main_t * vam)
14893 {
14894   unformat_input_t *input = vam->input;
14895   vl_api_one_add_del_locator_set_t *mp;
14896   u8 is_add = 1;
14897   u8 *locator_set_name = NULL;
14898   u8 locator_set_name_set = 0;
14899   vl_api_local_locator_t locator, *locators = 0;
14900   u32 sw_if_index, priority, weight;
14901   u32 data_len = 0;
14902
14903   int ret;
14904   /* Parse args required to build the message */
14905   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14906     {
14907       if (unformat (input, "del"))
14908         {
14909           is_add = 0;
14910         }
14911       else if (unformat (input, "locator-set %s", &locator_set_name))
14912         {
14913           locator_set_name_set = 1;
14914         }
14915       else if (unformat (input, "sw_if_index %u p %u w %u",
14916                          &sw_if_index, &priority, &weight))
14917         {
14918           locator.sw_if_index = htonl (sw_if_index);
14919           locator.priority = priority;
14920           locator.weight = weight;
14921           vec_add1 (locators, locator);
14922         }
14923       else
14924         if (unformat
14925             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
14926              &sw_if_index, &priority, &weight))
14927         {
14928           locator.sw_if_index = htonl (sw_if_index);
14929           locator.priority = priority;
14930           locator.weight = weight;
14931           vec_add1 (locators, locator);
14932         }
14933       else
14934         break;
14935     }
14936
14937   if (locator_set_name_set == 0)
14938     {
14939       errmsg ("missing locator-set name");
14940       vec_free (locators);
14941       return -99;
14942     }
14943
14944   if (vec_len (locator_set_name) > 64)
14945     {
14946       errmsg ("locator-set name too long");
14947       vec_free (locator_set_name);
14948       vec_free (locators);
14949       return -99;
14950     }
14951   vec_add1 (locator_set_name, 0);
14952
14953   data_len = sizeof (vl_api_local_locator_t) * vec_len (locators);
14954
14955   /* Construct the API message */
14956   M2 (ONE_ADD_DEL_LOCATOR_SET, mp, data_len);
14957
14958   mp->is_add = is_add;
14959   clib_memcpy (mp->locator_set_name, locator_set_name,
14960                vec_len (locator_set_name));
14961   vec_free (locator_set_name);
14962
14963   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
14964   if (locators)
14965     clib_memcpy (mp->locators, locators, data_len);
14966   vec_free (locators);
14967
14968   /* send it... */
14969   S (mp);
14970
14971   /* Wait for a reply... */
14972   W (ret);
14973   return ret;
14974 }
14975
14976 #define api_lisp_add_del_locator_set api_one_add_del_locator_set
14977
14978 static int
14979 api_one_add_del_locator (vat_main_t * vam)
14980 {
14981   unformat_input_t *input = vam->input;
14982   vl_api_one_add_del_locator_t *mp;
14983   u32 tmp_if_index = ~0;
14984   u32 sw_if_index = ~0;
14985   u8 sw_if_index_set = 0;
14986   u8 sw_if_index_if_name_set = 0;
14987   u32 priority = ~0;
14988   u8 priority_set = 0;
14989   u32 weight = ~0;
14990   u8 weight_set = 0;
14991   u8 is_add = 1;
14992   u8 *locator_set_name = NULL;
14993   u8 locator_set_name_set = 0;
14994   int ret;
14995
14996   /* Parse args required to build the message */
14997   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14998     {
14999       if (unformat (input, "del"))
15000         {
15001           is_add = 0;
15002         }
15003       else if (unformat (input, "locator-set %s", &locator_set_name))
15004         {
15005           locator_set_name_set = 1;
15006         }
15007       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
15008                          &tmp_if_index))
15009         {
15010           sw_if_index_if_name_set = 1;
15011           sw_if_index = tmp_if_index;
15012         }
15013       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
15014         {
15015           sw_if_index_set = 1;
15016           sw_if_index = tmp_if_index;
15017         }
15018       else if (unformat (input, "p %d", &priority))
15019         {
15020           priority_set = 1;
15021         }
15022       else if (unformat (input, "w %d", &weight))
15023         {
15024           weight_set = 1;
15025         }
15026       else
15027         break;
15028     }
15029
15030   if (locator_set_name_set == 0)
15031     {
15032       errmsg ("missing locator-set name");
15033       return -99;
15034     }
15035
15036   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
15037     {
15038       errmsg ("missing sw_if_index");
15039       vec_free (locator_set_name);
15040       return -99;
15041     }
15042
15043   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
15044     {
15045       errmsg ("cannot use both params interface name and sw_if_index");
15046       vec_free (locator_set_name);
15047       return -99;
15048     }
15049
15050   if (priority_set == 0)
15051     {
15052       errmsg ("missing locator-set priority");
15053       vec_free (locator_set_name);
15054       return -99;
15055     }
15056
15057   if (weight_set == 0)
15058     {
15059       errmsg ("missing locator-set weight");
15060       vec_free (locator_set_name);
15061       return -99;
15062     }
15063
15064   if (vec_len (locator_set_name) > 64)
15065     {
15066       errmsg ("locator-set name too long");
15067       vec_free (locator_set_name);
15068       return -99;
15069     }
15070   vec_add1 (locator_set_name, 0);
15071
15072   /* Construct the API message */
15073   M (ONE_ADD_DEL_LOCATOR, mp);
15074
15075   mp->is_add = is_add;
15076   mp->sw_if_index = ntohl (sw_if_index);
15077   mp->priority = priority;
15078   mp->weight = weight;
15079   clib_memcpy (mp->locator_set_name, locator_set_name,
15080                vec_len (locator_set_name));
15081   vec_free (locator_set_name);
15082
15083   /* send it... */
15084   S (mp);
15085
15086   /* Wait for a reply... */
15087   W (ret);
15088   return ret;
15089 }
15090
15091 #define api_lisp_add_del_locator api_one_add_del_locator
15092
15093 uword
15094 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
15095 {
15096   u32 *key_id = va_arg (*args, u32 *);
15097   u8 *s = 0;
15098
15099   if (unformat (input, "%s", &s))
15100     {
15101       if (!strcmp ((char *) s, "sha1"))
15102         key_id[0] = HMAC_SHA_1_96;
15103       else if (!strcmp ((char *) s, "sha256"))
15104         key_id[0] = HMAC_SHA_256_128;
15105       else
15106         {
15107           clib_warning ("invalid key_id: '%s'", s);
15108           key_id[0] = HMAC_NO_KEY;
15109         }
15110     }
15111   else
15112     return 0;
15113
15114   vec_free (s);
15115   return 1;
15116 }
15117
15118 static int
15119 api_one_add_del_local_eid (vat_main_t * vam)
15120 {
15121   unformat_input_t *input = vam->input;
15122   vl_api_one_add_del_local_eid_t *mp;
15123   u8 is_add = 1;
15124   u8 eid_set = 0;
15125   lisp_eid_vat_t _eid, *eid = &_eid;
15126   u8 *locator_set_name = 0;
15127   u8 locator_set_name_set = 0;
15128   u32 vni = 0;
15129   u16 key_id = 0;
15130   u8 *key = 0;
15131   int ret;
15132
15133   /* Parse args required to build the message */
15134   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15135     {
15136       if (unformat (input, "del"))
15137         {
15138           is_add = 0;
15139         }
15140       else if (unformat (input, "vni %d", &vni))
15141         {
15142           ;
15143         }
15144       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
15145         {
15146           eid_set = 1;
15147         }
15148       else if (unformat (input, "locator-set %s", &locator_set_name))
15149         {
15150           locator_set_name_set = 1;
15151         }
15152       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
15153         ;
15154       else if (unformat (input, "secret-key %_%v%_", &key))
15155         ;
15156       else
15157         break;
15158     }
15159
15160   if (locator_set_name_set == 0)
15161     {
15162       errmsg ("missing locator-set name");
15163       return -99;
15164     }
15165
15166   if (0 == eid_set)
15167     {
15168       errmsg ("EID address not set!");
15169       vec_free (locator_set_name);
15170       return -99;
15171     }
15172
15173   if (key && (0 == key_id))
15174     {
15175       errmsg ("invalid key_id!");
15176       return -99;
15177     }
15178
15179   if (vec_len (key) > 64)
15180     {
15181       errmsg ("key too long");
15182       vec_free (key);
15183       return -99;
15184     }
15185
15186   if (vec_len (locator_set_name) > 64)
15187     {
15188       errmsg ("locator-set name too long");
15189       vec_free (locator_set_name);
15190       return -99;
15191     }
15192   vec_add1 (locator_set_name, 0);
15193
15194   /* Construct the API message */
15195   M (ONE_ADD_DEL_LOCAL_EID, mp);
15196
15197   mp->is_add = is_add;
15198   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
15199   mp->eid_type = eid->type;
15200   mp->prefix_len = eid->len;
15201   mp->vni = clib_host_to_net_u32 (vni);
15202   mp->key_id = clib_host_to_net_u16 (key_id);
15203   clib_memcpy (mp->locator_set_name, locator_set_name,
15204                vec_len (locator_set_name));
15205   clib_memcpy (mp->key, key, vec_len (key));
15206
15207   vec_free (locator_set_name);
15208   vec_free (key);
15209
15210   /* send it... */
15211   S (mp);
15212
15213   /* Wait for a reply... */
15214   W (ret);
15215   return ret;
15216 }
15217
15218 #define api_lisp_add_del_local_eid api_one_add_del_local_eid
15219
15220 static int
15221 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
15222 {
15223   u32 dp_table = 0, vni = 0;;
15224   unformat_input_t *input = vam->input;
15225   vl_api_gpe_add_del_fwd_entry_t *mp;
15226   u8 is_add = 1;
15227   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
15228   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
15229   u8 rmt_eid_set = 0, lcl_eid_set = 0;
15230   u32 action = ~0, w;
15231   ip4_address_t rmt_rloc4, lcl_rloc4;
15232   ip6_address_t rmt_rloc6, lcl_rloc6;
15233   vl_api_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
15234   int ret;
15235
15236   clib_memset (&rloc, 0, sizeof (rloc));
15237
15238   /* Parse args required to build the message */
15239   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15240     {
15241       if (unformat (input, "del"))
15242         is_add = 0;
15243       else if (unformat (input, "add"))
15244         is_add = 1;
15245       else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
15246         {
15247           rmt_eid_set = 1;
15248         }
15249       else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
15250         {
15251           lcl_eid_set = 1;
15252         }
15253       else if (unformat (input, "vrf %d", &dp_table))
15254         ;
15255       else if (unformat (input, "bd %d", &dp_table))
15256         ;
15257       else if (unformat (input, "vni %d", &vni))
15258         ;
15259       else if (unformat (input, "w %d", &w))
15260         {
15261           if (!curr_rloc)
15262             {
15263               errmsg ("No RLOC configured for setting priority/weight!");
15264               return -99;
15265             }
15266           curr_rloc->weight = w;
15267         }
15268       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
15269                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
15270         {
15271           rloc.is_ip4 = 1;
15272
15273           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
15274           rloc.weight = 0;
15275           vec_add1 (lcl_locs, rloc);
15276
15277           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
15278           vec_add1 (rmt_locs, rloc);
15279           /* weight saved in rmt loc */
15280           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
15281         }
15282       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
15283                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
15284         {
15285           rloc.is_ip4 = 0;
15286           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
15287           rloc.weight = 0;
15288           vec_add1 (lcl_locs, rloc);
15289
15290           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
15291           vec_add1 (rmt_locs, rloc);
15292           /* weight saved in rmt loc */
15293           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
15294         }
15295       else if (unformat (input, "action %d", &action))
15296         {
15297           ;
15298         }
15299       else
15300         {
15301           clib_warning ("parse error '%U'", format_unformat_error, input);
15302           return -99;
15303         }
15304     }
15305
15306   if (!rmt_eid_set)
15307     {
15308       errmsg ("remote eid addresses not set");
15309       return -99;
15310     }
15311
15312   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
15313     {
15314       errmsg ("eid types don't match");
15315       return -99;
15316     }
15317
15318   if (0 == rmt_locs && (u32) ~ 0 == action)
15319     {
15320       errmsg ("action not set for negative mapping");
15321       return -99;
15322     }
15323
15324   /* Construct the API message */
15325   M2 (GPE_ADD_DEL_FWD_ENTRY, mp,
15326       sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs) * 2);
15327
15328   mp->is_add = is_add;
15329   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
15330   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
15331   mp->eid_type = rmt_eid->type;
15332   mp->dp_table = clib_host_to_net_u32 (dp_table);
15333   mp->vni = clib_host_to_net_u32 (vni);
15334   mp->rmt_len = rmt_eid->len;
15335   mp->lcl_len = lcl_eid->len;
15336   mp->action = action;
15337
15338   if (0 != rmt_locs && 0 != lcl_locs)
15339     {
15340       mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
15341       clib_memcpy (mp->locs, lcl_locs,
15342                    (sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs)));
15343
15344       u32 offset = sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs);
15345       clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
15346                    (sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs)));
15347     }
15348   vec_free (lcl_locs);
15349   vec_free (rmt_locs);
15350
15351   /* send it... */
15352   S (mp);
15353
15354   /* Wait for a reply... */
15355   W (ret);
15356   return ret;
15357 }
15358
15359 static int
15360 api_one_add_del_map_server (vat_main_t * vam)
15361 {
15362   unformat_input_t *input = vam->input;
15363   vl_api_one_add_del_map_server_t *mp;
15364   u8 is_add = 1;
15365   u8 ipv4_set = 0;
15366   u8 ipv6_set = 0;
15367   ip4_address_t ipv4;
15368   ip6_address_t ipv6;
15369   int ret;
15370
15371   /* Parse args required to build the message */
15372   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15373     {
15374       if (unformat (input, "del"))
15375         {
15376           is_add = 0;
15377         }
15378       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
15379         {
15380           ipv4_set = 1;
15381         }
15382       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
15383         {
15384           ipv6_set = 1;
15385         }
15386       else
15387         break;
15388     }
15389
15390   if (ipv4_set && ipv6_set)
15391     {
15392       errmsg ("both eid v4 and v6 addresses set");
15393       return -99;
15394     }
15395
15396   if (!ipv4_set && !ipv6_set)
15397     {
15398       errmsg ("eid addresses not set");
15399       return -99;
15400     }
15401
15402   /* Construct the API message */
15403   M (ONE_ADD_DEL_MAP_SERVER, mp);
15404
15405   mp->is_add = is_add;
15406   if (ipv6_set)
15407     {
15408       mp->is_ipv6 = 1;
15409       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
15410     }
15411   else
15412     {
15413       mp->is_ipv6 = 0;
15414       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
15415     }
15416
15417   /* send it... */
15418   S (mp);
15419
15420   /* Wait for a reply... */
15421   W (ret);
15422   return ret;
15423 }
15424
15425 #define api_lisp_add_del_map_server api_one_add_del_map_server
15426
15427 static int
15428 api_one_add_del_map_resolver (vat_main_t * vam)
15429 {
15430   unformat_input_t *input = vam->input;
15431   vl_api_one_add_del_map_resolver_t *mp;
15432   u8 is_add = 1;
15433   u8 ipv4_set = 0;
15434   u8 ipv6_set = 0;
15435   ip4_address_t ipv4;
15436   ip6_address_t ipv6;
15437   int ret;
15438
15439   /* Parse args required to build the message */
15440   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15441     {
15442       if (unformat (input, "del"))
15443         {
15444           is_add = 0;
15445         }
15446       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
15447         {
15448           ipv4_set = 1;
15449         }
15450       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
15451         {
15452           ipv6_set = 1;
15453         }
15454       else
15455         break;
15456     }
15457
15458   if (ipv4_set && ipv6_set)
15459     {
15460       errmsg ("both eid v4 and v6 addresses set");
15461       return -99;
15462     }
15463
15464   if (!ipv4_set && !ipv6_set)
15465     {
15466       errmsg ("eid addresses not set");
15467       return -99;
15468     }
15469
15470   /* Construct the API message */
15471   M (ONE_ADD_DEL_MAP_RESOLVER, mp);
15472
15473   mp->is_add = is_add;
15474   if (ipv6_set)
15475     {
15476       mp->is_ipv6 = 1;
15477       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
15478     }
15479   else
15480     {
15481       mp->is_ipv6 = 0;
15482       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
15483     }
15484
15485   /* send it... */
15486   S (mp);
15487
15488   /* Wait for a reply... */
15489   W (ret);
15490   return ret;
15491 }
15492
15493 #define api_lisp_add_del_map_resolver api_one_add_del_map_resolver
15494
15495 static int
15496 api_lisp_gpe_enable_disable (vat_main_t * vam)
15497 {
15498   unformat_input_t *input = vam->input;
15499   vl_api_gpe_enable_disable_t *mp;
15500   u8 is_set = 0;
15501   u8 is_en = 1;
15502   int ret;
15503
15504   /* Parse args required to build the message */
15505   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15506     {
15507       if (unformat (input, "enable"))
15508         {
15509           is_set = 1;
15510           is_en = 1;
15511         }
15512       else if (unformat (input, "disable"))
15513         {
15514           is_set = 1;
15515           is_en = 0;
15516         }
15517       else
15518         break;
15519     }
15520
15521   if (is_set == 0)
15522     {
15523       errmsg ("Value not set");
15524       return -99;
15525     }
15526
15527   /* Construct the API message */
15528   M (GPE_ENABLE_DISABLE, mp);
15529
15530   mp->is_en = is_en;
15531
15532   /* send it... */
15533   S (mp);
15534
15535   /* Wait for a reply... */
15536   W (ret);
15537   return ret;
15538 }
15539
15540 static int
15541 api_one_rloc_probe_enable_disable (vat_main_t * vam)
15542 {
15543   unformat_input_t *input = vam->input;
15544   vl_api_one_rloc_probe_enable_disable_t *mp;
15545   u8 is_set = 0;
15546   u8 is_en = 0;
15547   int ret;
15548
15549   /* Parse args required to build the message */
15550   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15551     {
15552       if (unformat (input, "enable"))
15553         {
15554           is_set = 1;
15555           is_en = 1;
15556         }
15557       else if (unformat (input, "disable"))
15558         is_set = 1;
15559       else
15560         break;
15561     }
15562
15563   if (!is_set)
15564     {
15565       errmsg ("Value not set");
15566       return -99;
15567     }
15568
15569   /* Construct the API message */
15570   M (ONE_RLOC_PROBE_ENABLE_DISABLE, mp);
15571
15572   mp->is_enabled = is_en;
15573
15574   /* send it... */
15575   S (mp);
15576
15577   /* Wait for a reply... */
15578   W (ret);
15579   return ret;
15580 }
15581
15582 #define api_lisp_rloc_probe_enable_disable api_one_rloc_probe_enable_disable
15583
15584 static int
15585 api_one_map_register_enable_disable (vat_main_t * vam)
15586 {
15587   unformat_input_t *input = vam->input;
15588   vl_api_one_map_register_enable_disable_t *mp;
15589   u8 is_set = 0;
15590   u8 is_en = 0;
15591   int ret;
15592
15593   /* Parse args required to build the message */
15594   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15595     {
15596       if (unformat (input, "enable"))
15597         {
15598           is_set = 1;
15599           is_en = 1;
15600         }
15601       else if (unformat (input, "disable"))
15602         is_set = 1;
15603       else
15604         break;
15605     }
15606
15607   if (!is_set)
15608     {
15609       errmsg ("Value not set");
15610       return -99;
15611     }
15612
15613   /* Construct the API message */
15614   M (ONE_MAP_REGISTER_ENABLE_DISABLE, mp);
15615
15616   mp->is_enabled = is_en;
15617
15618   /* send it... */
15619   S (mp);
15620
15621   /* Wait for a reply... */
15622   W (ret);
15623   return ret;
15624 }
15625
15626 #define api_lisp_map_register_enable_disable api_one_map_register_enable_disable
15627
15628 static int
15629 api_one_enable_disable (vat_main_t * vam)
15630 {
15631   unformat_input_t *input = vam->input;
15632   vl_api_one_enable_disable_t *mp;
15633   u8 is_set = 0;
15634   u8 is_en = 0;
15635   int ret;
15636
15637   /* Parse args required to build the message */
15638   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15639     {
15640       if (unformat (input, "enable"))
15641         {
15642           is_set = 1;
15643           is_en = 1;
15644         }
15645       else if (unformat (input, "disable"))
15646         {
15647           is_set = 1;
15648         }
15649       else
15650         break;
15651     }
15652
15653   if (!is_set)
15654     {
15655       errmsg ("Value not set");
15656       return -99;
15657     }
15658
15659   /* Construct the API message */
15660   M (ONE_ENABLE_DISABLE, mp);
15661
15662   mp->is_en = is_en;
15663
15664   /* send it... */
15665   S (mp);
15666
15667   /* Wait for a reply... */
15668   W (ret);
15669   return ret;
15670 }
15671
15672 #define api_lisp_enable_disable api_one_enable_disable
15673
15674 static int
15675 api_one_enable_disable_xtr_mode (vat_main_t * vam)
15676 {
15677   unformat_input_t *input = vam->input;
15678   vl_api_one_enable_disable_xtr_mode_t *mp;
15679   u8 is_set = 0;
15680   u8 is_en = 0;
15681   int ret;
15682
15683   /* Parse args required to build the message */
15684   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15685     {
15686       if (unformat (input, "enable"))
15687         {
15688           is_set = 1;
15689           is_en = 1;
15690         }
15691       else if (unformat (input, "disable"))
15692         {
15693           is_set = 1;
15694         }
15695       else
15696         break;
15697     }
15698
15699   if (!is_set)
15700     {
15701       errmsg ("Value not set");
15702       return -99;
15703     }
15704
15705   /* Construct the API message */
15706   M (ONE_ENABLE_DISABLE_XTR_MODE, mp);
15707
15708   mp->is_en = is_en;
15709
15710   /* send it... */
15711   S (mp);
15712
15713   /* Wait for a reply... */
15714   W (ret);
15715   return ret;
15716 }
15717
15718 static int
15719 api_one_show_xtr_mode (vat_main_t * vam)
15720 {
15721   vl_api_one_show_xtr_mode_t *mp;
15722   int ret;
15723
15724   /* Construct the API message */
15725   M (ONE_SHOW_XTR_MODE, mp);
15726
15727   /* send it... */
15728   S (mp);
15729
15730   /* Wait for a reply... */
15731   W (ret);
15732   return ret;
15733 }
15734
15735 static int
15736 api_one_enable_disable_pitr_mode (vat_main_t * vam)
15737 {
15738   unformat_input_t *input = vam->input;
15739   vl_api_one_enable_disable_pitr_mode_t *mp;
15740   u8 is_set = 0;
15741   u8 is_en = 0;
15742   int ret;
15743
15744   /* Parse args required to build the message */
15745   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15746     {
15747       if (unformat (input, "enable"))
15748         {
15749           is_set = 1;
15750           is_en = 1;
15751         }
15752       else if (unformat (input, "disable"))
15753         {
15754           is_set = 1;
15755         }
15756       else
15757         break;
15758     }
15759
15760   if (!is_set)
15761     {
15762       errmsg ("Value not set");
15763       return -99;
15764     }
15765
15766   /* Construct the API message */
15767   M (ONE_ENABLE_DISABLE_PITR_MODE, mp);
15768
15769   mp->is_en = is_en;
15770
15771   /* send it... */
15772   S (mp);
15773
15774   /* Wait for a reply... */
15775   W (ret);
15776   return ret;
15777 }
15778
15779 static int
15780 api_one_show_pitr_mode (vat_main_t * vam)
15781 {
15782   vl_api_one_show_pitr_mode_t *mp;
15783   int ret;
15784
15785   /* Construct the API message */
15786   M (ONE_SHOW_PITR_MODE, mp);
15787
15788   /* send it... */
15789   S (mp);
15790
15791   /* Wait for a reply... */
15792   W (ret);
15793   return ret;
15794 }
15795
15796 static int
15797 api_one_enable_disable_petr_mode (vat_main_t * vam)
15798 {
15799   unformat_input_t *input = vam->input;
15800   vl_api_one_enable_disable_petr_mode_t *mp;
15801   u8 is_set = 0;
15802   u8 is_en = 0;
15803   int ret;
15804
15805   /* Parse args required to build the message */
15806   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15807     {
15808       if (unformat (input, "enable"))
15809         {
15810           is_set = 1;
15811           is_en = 1;
15812         }
15813       else if (unformat (input, "disable"))
15814         {
15815           is_set = 1;
15816         }
15817       else
15818         break;
15819     }
15820
15821   if (!is_set)
15822     {
15823       errmsg ("Value not set");
15824       return -99;
15825     }
15826
15827   /* Construct the API message */
15828   M (ONE_ENABLE_DISABLE_PETR_MODE, mp);
15829
15830   mp->is_en = is_en;
15831
15832   /* send it... */
15833   S (mp);
15834
15835   /* Wait for a reply... */
15836   W (ret);
15837   return ret;
15838 }
15839
15840 static int
15841 api_one_show_petr_mode (vat_main_t * vam)
15842 {
15843   vl_api_one_show_petr_mode_t *mp;
15844   int ret;
15845
15846   /* Construct the API message */
15847   M (ONE_SHOW_PETR_MODE, mp);
15848
15849   /* send it... */
15850   S (mp);
15851
15852   /* Wait for a reply... */
15853   W (ret);
15854   return ret;
15855 }
15856
15857 static int
15858 api_show_one_map_register_state (vat_main_t * vam)
15859 {
15860   vl_api_show_one_map_register_state_t *mp;
15861   int ret;
15862
15863   M (SHOW_ONE_MAP_REGISTER_STATE, mp);
15864
15865   /* send */
15866   S (mp);
15867
15868   /* wait for reply */
15869   W (ret);
15870   return ret;
15871 }
15872
15873 #define api_show_lisp_map_register_state api_show_one_map_register_state
15874
15875 static int
15876 api_show_one_rloc_probe_state (vat_main_t * vam)
15877 {
15878   vl_api_show_one_rloc_probe_state_t *mp;
15879   int ret;
15880
15881   M (SHOW_ONE_RLOC_PROBE_STATE, mp);
15882
15883   /* send */
15884   S (mp);
15885
15886   /* wait for reply */
15887   W (ret);
15888   return ret;
15889 }
15890
15891 #define api_show_lisp_rloc_probe_state api_show_one_rloc_probe_state
15892
15893 static int
15894 api_one_add_del_ndp_entry (vat_main_t * vam)
15895 {
15896   vl_api_one_add_del_ndp_entry_t *mp;
15897   unformat_input_t *input = vam->input;
15898   u8 is_add = 1;
15899   u8 mac_set = 0;
15900   u8 bd_set = 0;
15901   u8 ip_set = 0;
15902   u8 mac[6] = { 0, };
15903   u8 ip6[16] = { 0, };
15904   u32 bd = ~0;
15905   int ret;
15906
15907   /* Parse args required to build the message */
15908   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15909     {
15910       if (unformat (input, "del"))
15911         is_add = 0;
15912       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
15913         mac_set = 1;
15914       else if (unformat (input, "ip %U", unformat_ip6_address, ip6))
15915         ip_set = 1;
15916       else if (unformat (input, "bd %d", &bd))
15917         bd_set = 1;
15918       else
15919         {
15920           errmsg ("parse error '%U'", format_unformat_error, input);
15921           return -99;
15922         }
15923     }
15924
15925   if (!bd_set || !ip_set || (!mac_set && is_add))
15926     {
15927       errmsg ("Missing BD, IP or MAC!");
15928       return -99;
15929     }
15930
15931   M (ONE_ADD_DEL_NDP_ENTRY, mp);
15932   mp->is_add = is_add;
15933   clib_memcpy (mp->mac, mac, 6);
15934   mp->bd = clib_host_to_net_u32 (bd);
15935   clib_memcpy (mp->ip6, ip6, sizeof (mp->ip6));
15936
15937   /* send */
15938   S (mp);
15939
15940   /* wait for reply */
15941   W (ret);
15942   return ret;
15943 }
15944
15945 static int
15946 api_one_add_del_l2_arp_entry (vat_main_t * vam)
15947 {
15948   vl_api_one_add_del_l2_arp_entry_t *mp;
15949   unformat_input_t *input = vam->input;
15950   u8 is_add = 1;
15951   u8 mac_set = 0;
15952   u8 bd_set = 0;
15953   u8 ip_set = 0;
15954   u8 mac[6] = { 0, };
15955   u32 ip4 = 0, bd = ~0;
15956   int ret;
15957
15958   /* Parse args required to build the message */
15959   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15960     {
15961       if (unformat (input, "del"))
15962         is_add = 0;
15963       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
15964         mac_set = 1;
15965       else if (unformat (input, "ip %U", unformat_ip4_address, &ip4))
15966         ip_set = 1;
15967       else if (unformat (input, "bd %d", &bd))
15968         bd_set = 1;
15969       else
15970         {
15971           errmsg ("parse error '%U'", format_unformat_error, input);
15972           return -99;
15973         }
15974     }
15975
15976   if (!bd_set || !ip_set || (!mac_set && is_add))
15977     {
15978       errmsg ("Missing BD, IP or MAC!");
15979       return -99;
15980     }
15981
15982   M (ONE_ADD_DEL_L2_ARP_ENTRY, mp);
15983   mp->is_add = is_add;
15984   clib_memcpy (mp->mac, mac, 6);
15985   mp->bd = clib_host_to_net_u32 (bd);
15986   mp->ip4 = ip4;
15987
15988   /* send */
15989   S (mp);
15990
15991   /* wait for reply */
15992   W (ret);
15993   return ret;
15994 }
15995
15996 static int
15997 api_one_ndp_bd_get (vat_main_t * vam)
15998 {
15999   vl_api_one_ndp_bd_get_t *mp;
16000   int ret;
16001
16002   M (ONE_NDP_BD_GET, mp);
16003
16004   /* send */
16005   S (mp);
16006
16007   /* wait for reply */
16008   W (ret);
16009   return ret;
16010 }
16011
16012 static int
16013 api_one_ndp_entries_get (vat_main_t * vam)
16014 {
16015   vl_api_one_ndp_entries_get_t *mp;
16016   unformat_input_t *input = vam->input;
16017   u8 bd_set = 0;
16018   u32 bd = ~0;
16019   int ret;
16020
16021   /* Parse args required to build the message */
16022   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16023     {
16024       if (unformat (input, "bd %d", &bd))
16025         bd_set = 1;
16026       else
16027         {
16028           errmsg ("parse error '%U'", format_unformat_error, input);
16029           return -99;
16030         }
16031     }
16032
16033   if (!bd_set)
16034     {
16035       errmsg ("Expected bridge domain!");
16036       return -99;
16037     }
16038
16039   M (ONE_NDP_ENTRIES_GET, mp);
16040   mp->bd = clib_host_to_net_u32 (bd);
16041
16042   /* send */
16043   S (mp);
16044
16045   /* wait for reply */
16046   W (ret);
16047   return ret;
16048 }
16049
16050 static int
16051 api_one_l2_arp_bd_get (vat_main_t * vam)
16052 {
16053   vl_api_one_l2_arp_bd_get_t *mp;
16054   int ret;
16055
16056   M (ONE_L2_ARP_BD_GET, mp);
16057
16058   /* send */
16059   S (mp);
16060
16061   /* wait for reply */
16062   W (ret);
16063   return ret;
16064 }
16065
16066 static int
16067 api_one_l2_arp_entries_get (vat_main_t * vam)
16068 {
16069   vl_api_one_l2_arp_entries_get_t *mp;
16070   unformat_input_t *input = vam->input;
16071   u8 bd_set = 0;
16072   u32 bd = ~0;
16073   int ret;
16074
16075   /* Parse args required to build the message */
16076   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16077     {
16078       if (unformat (input, "bd %d", &bd))
16079         bd_set = 1;
16080       else
16081         {
16082           errmsg ("parse error '%U'", format_unformat_error, input);
16083           return -99;
16084         }
16085     }
16086
16087   if (!bd_set)
16088     {
16089       errmsg ("Expected bridge domain!");
16090       return -99;
16091     }
16092
16093   M (ONE_L2_ARP_ENTRIES_GET, mp);
16094   mp->bd = clib_host_to_net_u32 (bd);
16095
16096   /* send */
16097   S (mp);
16098
16099   /* wait for reply */
16100   W (ret);
16101   return ret;
16102 }
16103
16104 static int
16105 api_one_stats_enable_disable (vat_main_t * vam)
16106 {
16107   vl_api_one_stats_enable_disable_t *mp;
16108   unformat_input_t *input = vam->input;
16109   u8 is_set = 0;
16110   u8 is_en = 0;
16111   int ret;
16112
16113   /* Parse args required to build the message */
16114   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16115     {
16116       if (unformat (input, "enable"))
16117         {
16118           is_set = 1;
16119           is_en = 1;
16120         }
16121       else if (unformat (input, "disable"))
16122         {
16123           is_set = 1;
16124         }
16125       else
16126         break;
16127     }
16128
16129   if (!is_set)
16130     {
16131       errmsg ("Value not set");
16132       return -99;
16133     }
16134
16135   M (ONE_STATS_ENABLE_DISABLE, mp);
16136   mp->is_en = is_en;
16137
16138   /* send */
16139   S (mp);
16140
16141   /* wait for reply */
16142   W (ret);
16143   return ret;
16144 }
16145
16146 static int
16147 api_show_one_stats_enable_disable (vat_main_t * vam)
16148 {
16149   vl_api_show_one_stats_enable_disable_t *mp;
16150   int ret;
16151
16152   M (SHOW_ONE_STATS_ENABLE_DISABLE, mp);
16153
16154   /* send */
16155   S (mp);
16156
16157   /* wait for reply */
16158   W (ret);
16159   return ret;
16160 }
16161
16162 static int
16163 api_show_one_map_request_mode (vat_main_t * vam)
16164 {
16165   vl_api_show_one_map_request_mode_t *mp;
16166   int ret;
16167
16168   M (SHOW_ONE_MAP_REQUEST_MODE, mp);
16169
16170   /* send */
16171   S (mp);
16172
16173   /* wait for reply */
16174   W (ret);
16175   return ret;
16176 }
16177
16178 #define api_show_lisp_map_request_mode api_show_one_map_request_mode
16179
16180 static int
16181 api_one_map_request_mode (vat_main_t * vam)
16182 {
16183   unformat_input_t *input = vam->input;
16184   vl_api_one_map_request_mode_t *mp;
16185   u8 mode = 0;
16186   int ret;
16187
16188   /* Parse args required to build the message */
16189   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16190     {
16191       if (unformat (input, "dst-only"))
16192         mode = 0;
16193       else if (unformat (input, "src-dst"))
16194         mode = 1;
16195       else
16196         {
16197           errmsg ("parse error '%U'", format_unformat_error, input);
16198           return -99;
16199         }
16200     }
16201
16202   M (ONE_MAP_REQUEST_MODE, mp);
16203
16204   mp->mode = mode;
16205
16206   /* send */
16207   S (mp);
16208
16209   /* wait for reply */
16210   W (ret);
16211   return ret;
16212 }
16213
16214 #define api_lisp_map_request_mode api_one_map_request_mode
16215
16216 /**
16217  * Enable/disable ONE proxy ITR.
16218  *
16219  * @param vam vpp API test context
16220  * @return return code
16221  */
16222 static int
16223 api_one_pitr_set_locator_set (vat_main_t * vam)
16224 {
16225   u8 ls_name_set = 0;
16226   unformat_input_t *input = vam->input;
16227   vl_api_one_pitr_set_locator_set_t *mp;
16228   u8 is_add = 1;
16229   u8 *ls_name = 0;
16230   int ret;
16231
16232   /* Parse args required to build the message */
16233   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16234     {
16235       if (unformat (input, "del"))
16236         is_add = 0;
16237       else if (unformat (input, "locator-set %s", &ls_name))
16238         ls_name_set = 1;
16239       else
16240         {
16241           errmsg ("parse error '%U'", format_unformat_error, input);
16242           return -99;
16243         }
16244     }
16245
16246   if (!ls_name_set)
16247     {
16248       errmsg ("locator-set name not set!");
16249       return -99;
16250     }
16251
16252   M (ONE_PITR_SET_LOCATOR_SET, mp);
16253
16254   mp->is_add = is_add;
16255   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
16256   vec_free (ls_name);
16257
16258   /* send */
16259   S (mp);
16260
16261   /* wait for reply */
16262   W (ret);
16263   return ret;
16264 }
16265
16266 #define api_lisp_pitr_set_locator_set api_one_pitr_set_locator_set
16267
16268 static int
16269 api_one_nsh_set_locator_set (vat_main_t * vam)
16270 {
16271   u8 ls_name_set = 0;
16272   unformat_input_t *input = vam->input;
16273   vl_api_one_nsh_set_locator_set_t *mp;
16274   u8 is_add = 1;
16275   u8 *ls_name = 0;
16276   int ret;
16277
16278   /* Parse args required to build the message */
16279   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16280     {
16281       if (unformat (input, "del"))
16282         is_add = 0;
16283       else if (unformat (input, "ls %s", &ls_name))
16284         ls_name_set = 1;
16285       else
16286         {
16287           errmsg ("parse error '%U'", format_unformat_error, input);
16288           return -99;
16289         }
16290     }
16291
16292   if (!ls_name_set && is_add)
16293     {
16294       errmsg ("locator-set name not set!");
16295       return -99;
16296     }
16297
16298   M (ONE_NSH_SET_LOCATOR_SET, mp);
16299
16300   mp->is_add = is_add;
16301   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
16302   vec_free (ls_name);
16303
16304   /* send */
16305   S (mp);
16306
16307   /* wait for reply */
16308   W (ret);
16309   return ret;
16310 }
16311
16312 static int
16313 api_show_one_pitr (vat_main_t * vam)
16314 {
16315   vl_api_show_one_pitr_t *mp;
16316   int ret;
16317
16318   if (!vam->json_output)
16319     {
16320       print (vam->ofp, "%=20s", "lisp status:");
16321     }
16322
16323   M (SHOW_ONE_PITR, mp);
16324   /* send it... */
16325   S (mp);
16326
16327   /* Wait for a reply... */
16328   W (ret);
16329   return ret;
16330 }
16331
16332 #define api_show_lisp_pitr api_show_one_pitr
16333
16334 static int
16335 api_one_use_petr (vat_main_t * vam)
16336 {
16337   unformat_input_t *input = vam->input;
16338   vl_api_one_use_petr_t *mp;
16339   u8 is_add = 0;
16340   ip_address_t ip;
16341   int ret;
16342
16343   clib_memset (&ip, 0, sizeof (ip));
16344
16345   /* Parse args required to build the message */
16346   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16347     {
16348       if (unformat (input, "disable"))
16349         is_add = 0;
16350       else
16351         if (unformat (input, "%U", unformat_ip4_address, &ip_addr_v4 (&ip)))
16352         {
16353           is_add = 1;
16354           ip_addr_version (&ip) = AF_IP4;
16355         }
16356       else
16357         if (unformat (input, "%U", unformat_ip6_address, &ip_addr_v6 (&ip)))
16358         {
16359           is_add = 1;
16360           ip_addr_version (&ip) = AF_IP6;
16361         }
16362       else
16363         {
16364           errmsg ("parse error '%U'", format_unformat_error, input);
16365           return -99;
16366         }
16367     }
16368
16369   M (ONE_USE_PETR, mp);
16370
16371   mp->is_add = is_add;
16372   if (is_add)
16373     {
16374       mp->is_ip4 = ip_addr_version (&ip) == AF_IP4 ? 1 : 0;
16375       if (mp->is_ip4)
16376         clib_memcpy (mp->address, &ip, 4);
16377       else
16378         clib_memcpy (mp->address, &ip, 16);
16379     }
16380
16381   /* send */
16382   S (mp);
16383
16384   /* wait for reply */
16385   W (ret);
16386   return ret;
16387 }
16388
16389 #define api_lisp_use_petr api_one_use_petr
16390
16391 static int
16392 api_show_one_nsh_mapping (vat_main_t * vam)
16393 {
16394   vl_api_show_one_use_petr_t *mp;
16395   int ret;
16396
16397   if (!vam->json_output)
16398     {
16399       print (vam->ofp, "%=20s", "local ONE NSH mapping:");
16400     }
16401
16402   M (SHOW_ONE_NSH_MAPPING, mp);
16403   /* send it... */
16404   S (mp);
16405
16406   /* Wait for a reply... */
16407   W (ret);
16408   return ret;
16409 }
16410
16411 static int
16412 api_show_one_use_petr (vat_main_t * vam)
16413 {
16414   vl_api_show_one_use_petr_t *mp;
16415   int ret;
16416
16417   if (!vam->json_output)
16418     {
16419       print (vam->ofp, "%=20s", "Proxy-ETR status:");
16420     }
16421
16422   M (SHOW_ONE_USE_PETR, mp);
16423   /* send it... */
16424   S (mp);
16425
16426   /* Wait for a reply... */
16427   W (ret);
16428   return ret;
16429 }
16430
16431 #define api_show_lisp_use_petr api_show_one_use_petr
16432
16433 /**
16434  * Add/delete mapping between vni and vrf
16435  */
16436 static int
16437 api_one_eid_table_add_del_map (vat_main_t * vam)
16438 {
16439   unformat_input_t *input = vam->input;
16440   vl_api_one_eid_table_add_del_map_t *mp;
16441   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
16442   u32 vni, vrf, bd_index;
16443   int ret;
16444
16445   /* Parse args required to build the message */
16446   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16447     {
16448       if (unformat (input, "del"))
16449         is_add = 0;
16450       else if (unformat (input, "vrf %d", &vrf))
16451         vrf_set = 1;
16452       else if (unformat (input, "bd_index %d", &bd_index))
16453         bd_index_set = 1;
16454       else if (unformat (input, "vni %d", &vni))
16455         vni_set = 1;
16456       else
16457         break;
16458     }
16459
16460   if (!vni_set || (!vrf_set && !bd_index_set))
16461     {
16462       errmsg ("missing arguments!");
16463       return -99;
16464     }
16465
16466   if (vrf_set && bd_index_set)
16467     {
16468       errmsg ("error: both vrf and bd entered!");
16469       return -99;
16470     }
16471
16472   M (ONE_EID_TABLE_ADD_DEL_MAP, mp);
16473
16474   mp->is_add = is_add;
16475   mp->vni = htonl (vni);
16476   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
16477   mp->is_l2 = bd_index_set;
16478
16479   /* send */
16480   S (mp);
16481
16482   /* wait for reply */
16483   W (ret);
16484   return ret;
16485 }
16486
16487 #define api_lisp_eid_table_add_del_map api_one_eid_table_add_del_map
16488
16489 uword
16490 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
16491 {
16492   u32 *action = va_arg (*args, u32 *);
16493   u8 *s = 0;
16494
16495   if (unformat (input, "%s", &s))
16496     {
16497       if (!strcmp ((char *) s, "no-action"))
16498         action[0] = 0;
16499       else if (!strcmp ((char *) s, "natively-forward"))
16500         action[0] = 1;
16501       else if (!strcmp ((char *) s, "send-map-request"))
16502         action[0] = 2;
16503       else if (!strcmp ((char *) s, "drop"))
16504         action[0] = 3;
16505       else
16506         {
16507           clib_warning ("invalid action: '%s'", s);
16508           action[0] = 3;
16509         }
16510     }
16511   else
16512     return 0;
16513
16514   vec_free (s);
16515   return 1;
16516 }
16517
16518 /**
16519  * Add/del remote mapping to/from ONE control plane
16520  *
16521  * @param vam vpp API test context
16522  * @return return code
16523  */
16524 static int
16525 api_one_add_del_remote_mapping (vat_main_t * vam)
16526 {
16527   unformat_input_t *input = vam->input;
16528   vl_api_one_add_del_remote_mapping_t *mp;
16529   u32 vni = 0;
16530   lisp_eid_vat_t _eid, *eid = &_eid;
16531   lisp_eid_vat_t _seid, *seid = &_seid;
16532   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
16533   u32 action = ~0, p, w, data_len;
16534   ip4_address_t rloc4;
16535   ip6_address_t rloc6;
16536   vl_api_remote_locator_t *rlocs = 0, rloc, *curr_rloc = 0;
16537   int ret;
16538
16539   clib_memset (&rloc, 0, sizeof (rloc));
16540
16541   /* Parse args required to build the message */
16542   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16543     {
16544       if (unformat (input, "del-all"))
16545         {
16546           del_all = 1;
16547         }
16548       else if (unformat (input, "del"))
16549         {
16550           is_add = 0;
16551         }
16552       else if (unformat (input, "add"))
16553         {
16554           is_add = 1;
16555         }
16556       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
16557         {
16558           eid_set = 1;
16559         }
16560       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
16561         {
16562           seid_set = 1;
16563         }
16564       else if (unformat (input, "vni %d", &vni))
16565         {
16566           ;
16567         }
16568       else if (unformat (input, "p %d w %d", &p, &w))
16569         {
16570           if (!curr_rloc)
16571             {
16572               errmsg ("No RLOC configured for setting priority/weight!");
16573               return -99;
16574             }
16575           curr_rloc->priority = p;
16576           curr_rloc->weight = w;
16577         }
16578       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
16579         {
16580           rloc.is_ip4 = 1;
16581           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
16582           vec_add1 (rlocs, rloc);
16583           curr_rloc = &rlocs[vec_len (rlocs) - 1];
16584         }
16585       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
16586         {
16587           rloc.is_ip4 = 0;
16588           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
16589           vec_add1 (rlocs, rloc);
16590           curr_rloc = &rlocs[vec_len (rlocs) - 1];
16591         }
16592       else if (unformat (input, "action %U",
16593                          unformat_negative_mapping_action, &action))
16594         {
16595           ;
16596         }
16597       else
16598         {
16599           clib_warning ("parse error '%U'", format_unformat_error, input);
16600           return -99;
16601         }
16602     }
16603
16604   if (0 == eid_set)
16605     {
16606       errmsg ("missing params!");
16607       return -99;
16608     }
16609
16610   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
16611     {
16612       errmsg ("no action set for negative map-reply!");
16613       return -99;
16614     }
16615
16616   data_len = vec_len (rlocs) * sizeof (vl_api_remote_locator_t);
16617
16618   M2 (ONE_ADD_DEL_REMOTE_MAPPING, mp, data_len);
16619   mp->is_add = is_add;
16620   mp->vni = htonl (vni);
16621   mp->action = (u8) action;
16622   mp->is_src_dst = seid_set;
16623   mp->eid_len = eid->len;
16624   mp->seid_len = seid->len;
16625   mp->del_all = del_all;
16626   mp->eid_type = eid->type;
16627   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
16628   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
16629
16630   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
16631   clib_memcpy (mp->rlocs, rlocs, data_len);
16632   vec_free (rlocs);
16633
16634   /* send it... */
16635   S (mp);
16636
16637   /* Wait for a reply... */
16638   W (ret);
16639   return ret;
16640 }
16641
16642 #define api_lisp_add_del_remote_mapping api_one_add_del_remote_mapping
16643
16644 /**
16645  * Add/del ONE adjacency. Saves mapping in ONE control plane and updates
16646  * forwarding entries in data-plane accordingly.
16647  *
16648  * @param vam vpp API test context
16649  * @return return code
16650  */
16651 static int
16652 api_one_add_del_adjacency (vat_main_t * vam)
16653 {
16654   unformat_input_t *input = vam->input;
16655   vl_api_one_add_del_adjacency_t *mp;
16656   u32 vni = 0;
16657   ip4_address_t leid4, reid4;
16658   ip6_address_t leid6, reid6;
16659   u8 reid_mac[6] = { 0 };
16660   u8 leid_mac[6] = { 0 };
16661   u8 reid_type, leid_type;
16662   u32 leid_len = 0, reid_len = 0, len;
16663   u8 is_add = 1;
16664   int ret;
16665
16666   leid_type = reid_type = (u8) ~ 0;
16667
16668   /* Parse args required to build the message */
16669   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16670     {
16671       if (unformat (input, "del"))
16672         {
16673           is_add = 0;
16674         }
16675       else if (unformat (input, "add"))
16676         {
16677           is_add = 1;
16678         }
16679       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
16680                          &reid4, &len))
16681         {
16682           reid_type = 0;        /* ipv4 */
16683           reid_len = len;
16684         }
16685       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
16686                          &reid6, &len))
16687         {
16688           reid_type = 1;        /* ipv6 */
16689           reid_len = len;
16690         }
16691       else if (unformat (input, "reid %U", unformat_ethernet_address,
16692                          reid_mac))
16693         {
16694           reid_type = 2;        /* mac */
16695         }
16696       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
16697                          &leid4, &len))
16698         {
16699           leid_type = 0;        /* ipv4 */
16700           leid_len = len;
16701         }
16702       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
16703                          &leid6, &len))
16704         {
16705           leid_type = 1;        /* ipv6 */
16706           leid_len = len;
16707         }
16708       else if (unformat (input, "leid %U", unformat_ethernet_address,
16709                          leid_mac))
16710         {
16711           leid_type = 2;        /* mac */
16712         }
16713       else if (unformat (input, "vni %d", &vni))
16714         {
16715           ;
16716         }
16717       else
16718         {
16719           errmsg ("parse error '%U'", format_unformat_error, input);
16720           return -99;
16721         }
16722     }
16723
16724   if ((u8) ~ 0 == reid_type)
16725     {
16726       errmsg ("missing params!");
16727       return -99;
16728     }
16729
16730   if (leid_type != reid_type)
16731     {
16732       errmsg ("remote and local EIDs are of different types!");
16733       return -99;
16734     }
16735
16736   M (ONE_ADD_DEL_ADJACENCY, mp);
16737   mp->is_add = is_add;
16738   mp->vni = htonl (vni);
16739   mp->leid_len = leid_len;
16740   mp->reid_len = reid_len;
16741   mp->eid_type = reid_type;
16742
16743   switch (mp->eid_type)
16744     {
16745     case 0:
16746       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
16747       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
16748       break;
16749     case 1:
16750       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
16751       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
16752       break;
16753     case 2:
16754       clib_memcpy (mp->leid, leid_mac, 6);
16755       clib_memcpy (mp->reid, reid_mac, 6);
16756       break;
16757     default:
16758       errmsg ("unknown EID type %d!", mp->eid_type);
16759       return 0;
16760     }
16761
16762   /* send it... */
16763   S (mp);
16764
16765   /* Wait for a reply... */
16766   W (ret);
16767   return ret;
16768 }
16769
16770 #define api_lisp_add_del_adjacency api_one_add_del_adjacency
16771
16772 uword
16773 unformat_gpe_encap_mode (unformat_input_t * input, va_list * args)
16774 {
16775   u32 *mode = va_arg (*args, u32 *);
16776
16777   if (unformat (input, "lisp"))
16778     *mode = 0;
16779   else if (unformat (input, "vxlan"))
16780     *mode = 1;
16781   else
16782     return 0;
16783
16784   return 1;
16785 }
16786
16787 static int
16788 api_gpe_get_encap_mode (vat_main_t * vam)
16789 {
16790   vl_api_gpe_get_encap_mode_t *mp;
16791   int ret;
16792
16793   /* Construct the API message */
16794   M (GPE_GET_ENCAP_MODE, mp);
16795
16796   /* send it... */
16797   S (mp);
16798
16799   /* Wait for a reply... */
16800   W (ret);
16801   return ret;
16802 }
16803
16804 static int
16805 api_gpe_set_encap_mode (vat_main_t * vam)
16806 {
16807   unformat_input_t *input = vam->input;
16808   vl_api_gpe_set_encap_mode_t *mp;
16809   int ret;
16810   u32 mode = 0;
16811
16812   /* Parse args required to build the message */
16813   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16814     {
16815       if (unformat (input, "%U", unformat_gpe_encap_mode, &mode))
16816         ;
16817       else
16818         break;
16819     }
16820
16821   /* Construct the API message */
16822   M (GPE_SET_ENCAP_MODE, mp);
16823
16824   mp->mode = mode;
16825
16826   /* send it... */
16827   S (mp);
16828
16829   /* Wait for a reply... */
16830   W (ret);
16831   return ret;
16832 }
16833
16834 static int
16835 api_lisp_gpe_add_del_iface (vat_main_t * vam)
16836 {
16837   unformat_input_t *input = vam->input;
16838   vl_api_gpe_add_del_iface_t *mp;
16839   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
16840   u32 dp_table = 0, vni = 0;
16841   int ret;
16842
16843   /* Parse args required to build the message */
16844   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16845     {
16846       if (unformat (input, "up"))
16847         {
16848           action_set = 1;
16849           is_add = 1;
16850         }
16851       else if (unformat (input, "down"))
16852         {
16853           action_set = 1;
16854           is_add = 0;
16855         }
16856       else if (unformat (input, "table_id %d", &dp_table))
16857         {
16858           dp_table_set = 1;
16859         }
16860       else if (unformat (input, "bd_id %d", &dp_table))
16861         {
16862           dp_table_set = 1;
16863           is_l2 = 1;
16864         }
16865       else if (unformat (input, "vni %d", &vni))
16866         {
16867           vni_set = 1;
16868         }
16869       else
16870         break;
16871     }
16872
16873   if (action_set == 0)
16874     {
16875       errmsg ("Action not set");
16876       return -99;
16877     }
16878   if (dp_table_set == 0 || vni_set == 0)
16879     {
16880       errmsg ("vni and dp_table must be set");
16881       return -99;
16882     }
16883
16884   /* Construct the API message */
16885   M (GPE_ADD_DEL_IFACE, mp);
16886
16887   mp->is_add = is_add;
16888   mp->dp_table = clib_host_to_net_u32 (dp_table);
16889   mp->is_l2 = is_l2;
16890   mp->vni = clib_host_to_net_u32 (vni);
16891
16892   /* send it... */
16893   S (mp);
16894
16895   /* Wait for a reply... */
16896   W (ret);
16897   return ret;
16898 }
16899
16900 static int
16901 api_one_map_register_fallback_threshold (vat_main_t * vam)
16902 {
16903   unformat_input_t *input = vam->input;
16904   vl_api_one_map_register_fallback_threshold_t *mp;
16905   u32 value = 0;
16906   u8 is_set = 0;
16907   int ret;
16908
16909   /* Parse args required to build the message */
16910   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16911     {
16912       if (unformat (input, "%u", &value))
16913         is_set = 1;
16914       else
16915         {
16916           clib_warning ("parse error '%U'", format_unformat_error, input);
16917           return -99;
16918         }
16919     }
16920
16921   if (!is_set)
16922     {
16923       errmsg ("fallback threshold value is missing!");
16924       return -99;
16925     }
16926
16927   M (ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
16928   mp->value = clib_host_to_net_u32 (value);
16929
16930   /* send it... */
16931   S (mp);
16932
16933   /* Wait for a reply... */
16934   W (ret);
16935   return ret;
16936 }
16937
16938 static int
16939 api_show_one_map_register_fallback_threshold (vat_main_t * vam)
16940 {
16941   vl_api_show_one_map_register_fallback_threshold_t *mp;
16942   int ret;
16943
16944   M (SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
16945
16946   /* send it... */
16947   S (mp);
16948
16949   /* Wait for a reply... */
16950   W (ret);
16951   return ret;
16952 }
16953
16954 uword
16955 unformat_lisp_transport_protocol (unformat_input_t * input, va_list * args)
16956 {
16957   u32 *proto = va_arg (*args, u32 *);
16958
16959   if (unformat (input, "udp"))
16960     *proto = 1;
16961   else if (unformat (input, "api"))
16962     *proto = 2;
16963   else
16964     return 0;
16965
16966   return 1;
16967 }
16968
16969 static int
16970 api_one_set_transport_protocol (vat_main_t * vam)
16971 {
16972   unformat_input_t *input = vam->input;
16973   vl_api_one_set_transport_protocol_t *mp;
16974   u8 is_set = 0;
16975   u32 protocol = 0;
16976   int ret;
16977
16978   /* Parse args required to build the message */
16979   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16980     {
16981       if (unformat (input, "%U", unformat_lisp_transport_protocol, &protocol))
16982         is_set = 1;
16983       else
16984         {
16985           clib_warning ("parse error '%U'", format_unformat_error, input);
16986           return -99;
16987         }
16988     }
16989
16990   if (!is_set)
16991     {
16992       errmsg ("Transport protocol missing!");
16993       return -99;
16994     }
16995
16996   M (ONE_SET_TRANSPORT_PROTOCOL, mp);
16997   mp->protocol = (u8) protocol;
16998
16999   /* send it... */
17000   S (mp);
17001
17002   /* Wait for a reply... */
17003   W (ret);
17004   return ret;
17005 }
17006
17007 static int
17008 api_one_get_transport_protocol (vat_main_t * vam)
17009 {
17010   vl_api_one_get_transport_protocol_t *mp;
17011   int ret;
17012
17013   M (ONE_GET_TRANSPORT_PROTOCOL, mp);
17014
17015   /* send it... */
17016   S (mp);
17017
17018   /* Wait for a reply... */
17019   W (ret);
17020   return ret;
17021 }
17022
17023 static int
17024 api_one_map_register_set_ttl (vat_main_t * vam)
17025 {
17026   unformat_input_t *input = vam->input;
17027   vl_api_one_map_register_set_ttl_t *mp;
17028   u32 ttl = 0;
17029   u8 is_set = 0;
17030   int ret;
17031
17032   /* Parse args required to build the message */
17033   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17034     {
17035       if (unformat (input, "%u", &ttl))
17036         is_set = 1;
17037       else
17038         {
17039           clib_warning ("parse error '%U'", format_unformat_error, input);
17040           return -99;
17041         }
17042     }
17043
17044   if (!is_set)
17045     {
17046       errmsg ("TTL value missing!");
17047       return -99;
17048     }
17049
17050   M (ONE_MAP_REGISTER_SET_TTL, mp);
17051   mp->ttl = clib_host_to_net_u32 (ttl);
17052
17053   /* send it... */
17054   S (mp);
17055
17056   /* Wait for a reply... */
17057   W (ret);
17058   return ret;
17059 }
17060
17061 static int
17062 api_show_one_map_register_ttl (vat_main_t * vam)
17063 {
17064   vl_api_show_one_map_register_ttl_t *mp;
17065   int ret;
17066
17067   M (SHOW_ONE_MAP_REGISTER_TTL, mp);
17068
17069   /* send it... */
17070   S (mp);
17071
17072   /* Wait for a reply... */
17073   W (ret);
17074   return ret;
17075 }
17076
17077 /**
17078  * Add/del map request itr rlocs from ONE control plane and updates
17079  *
17080  * @param vam vpp API test context
17081  * @return return code
17082  */
17083 static int
17084 api_one_add_del_map_request_itr_rlocs (vat_main_t * vam)
17085 {
17086   unformat_input_t *input = vam->input;
17087   vl_api_one_add_del_map_request_itr_rlocs_t *mp;
17088   u8 *locator_set_name = 0;
17089   u8 locator_set_name_set = 0;
17090   u8 is_add = 1;
17091   int ret;
17092
17093   /* Parse args required to build the message */
17094   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17095     {
17096       if (unformat (input, "del"))
17097         {
17098           is_add = 0;
17099         }
17100       else if (unformat (input, "%_%v%_", &locator_set_name))
17101         {
17102           locator_set_name_set = 1;
17103         }
17104       else
17105         {
17106           clib_warning ("parse error '%U'", format_unformat_error, input);
17107           return -99;
17108         }
17109     }
17110
17111   if (is_add && !locator_set_name_set)
17112     {
17113       errmsg ("itr-rloc is not set!");
17114       return -99;
17115     }
17116
17117   if (is_add && vec_len (locator_set_name) > 64)
17118     {
17119       errmsg ("itr-rloc locator-set name too long");
17120       vec_free (locator_set_name);
17121       return -99;
17122     }
17123
17124   M (ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS, mp);
17125   mp->is_add = is_add;
17126   if (is_add)
17127     {
17128       clib_memcpy (mp->locator_set_name, locator_set_name,
17129                    vec_len (locator_set_name));
17130     }
17131   else
17132     {
17133       clib_memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
17134     }
17135   vec_free (locator_set_name);
17136
17137   /* send it... */
17138   S (mp);
17139
17140   /* Wait for a reply... */
17141   W (ret);
17142   return ret;
17143 }
17144
17145 #define api_lisp_add_del_map_request_itr_rlocs api_one_add_del_map_request_itr_rlocs
17146
17147 static int
17148 api_one_locator_dump (vat_main_t * vam)
17149 {
17150   unformat_input_t *input = vam->input;
17151   vl_api_one_locator_dump_t *mp;
17152   vl_api_control_ping_t *mp_ping;
17153   u8 is_index_set = 0, is_name_set = 0;
17154   u8 *ls_name = 0;
17155   u32 ls_index = ~0;
17156   int ret;
17157
17158   /* Parse args required to build the message */
17159   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17160     {
17161       if (unformat (input, "ls_name %_%v%_", &ls_name))
17162         {
17163           is_name_set = 1;
17164         }
17165       else if (unformat (input, "ls_index %d", &ls_index))
17166         {
17167           is_index_set = 1;
17168         }
17169       else
17170         {
17171           errmsg ("parse error '%U'", format_unformat_error, input);
17172           return -99;
17173         }
17174     }
17175
17176   if (!is_index_set && !is_name_set)
17177     {
17178       errmsg ("error: expected one of index or name!");
17179       return -99;
17180     }
17181
17182   if (is_index_set && is_name_set)
17183     {
17184       errmsg ("error: only one param expected!");
17185       return -99;
17186     }
17187
17188   if (vec_len (ls_name) > 62)
17189     {
17190       errmsg ("error: locator set name too long!");
17191       return -99;
17192     }
17193
17194   if (!vam->json_output)
17195     {
17196       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
17197     }
17198
17199   M (ONE_LOCATOR_DUMP, mp);
17200   mp->is_index_set = is_index_set;
17201
17202   if (is_index_set)
17203     mp->ls_index = clib_host_to_net_u32 (ls_index);
17204   else
17205     {
17206       vec_add1 (ls_name, 0);
17207       strncpy ((char *) mp->ls_name, (char *) ls_name,
17208                sizeof (mp->ls_name) - 1);
17209     }
17210
17211   /* send it... */
17212   S (mp);
17213
17214   /* Use a control ping for synchronization */
17215   MPING (CONTROL_PING, mp_ping);
17216   S (mp_ping);
17217
17218   /* Wait for a reply... */
17219   W (ret);
17220   return ret;
17221 }
17222
17223 #define api_lisp_locator_dump api_one_locator_dump
17224
17225 static int
17226 api_one_locator_set_dump (vat_main_t * vam)
17227 {
17228   vl_api_one_locator_set_dump_t *mp;
17229   vl_api_control_ping_t *mp_ping;
17230   unformat_input_t *input = vam->input;
17231   u8 filter = 0;
17232   int ret;
17233
17234   /* Parse args required to build the message */
17235   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17236     {
17237       if (unformat (input, "local"))
17238         {
17239           filter = 1;
17240         }
17241       else if (unformat (input, "remote"))
17242         {
17243           filter = 2;
17244         }
17245       else
17246         {
17247           errmsg ("parse error '%U'", format_unformat_error, input);
17248           return -99;
17249         }
17250     }
17251
17252   if (!vam->json_output)
17253     {
17254       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
17255     }
17256
17257   M (ONE_LOCATOR_SET_DUMP, mp);
17258
17259   mp->filter = filter;
17260
17261   /* send it... */
17262   S (mp);
17263
17264   /* Use a control ping for synchronization */
17265   MPING (CONTROL_PING, mp_ping);
17266   S (mp_ping);
17267
17268   /* Wait for a reply... */
17269   W (ret);
17270   return ret;
17271 }
17272
17273 #define api_lisp_locator_set_dump api_one_locator_set_dump
17274
17275 static int
17276 api_one_eid_table_map_dump (vat_main_t * vam)
17277 {
17278   u8 is_l2 = 0;
17279   u8 mode_set = 0;
17280   unformat_input_t *input = vam->input;
17281   vl_api_one_eid_table_map_dump_t *mp;
17282   vl_api_control_ping_t *mp_ping;
17283   int ret;
17284
17285   /* Parse args required to build the message */
17286   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17287     {
17288       if (unformat (input, "l2"))
17289         {
17290           is_l2 = 1;
17291           mode_set = 1;
17292         }
17293       else if (unformat (input, "l3"))
17294         {
17295           is_l2 = 0;
17296           mode_set = 1;
17297         }
17298       else
17299         {
17300           errmsg ("parse error '%U'", format_unformat_error, input);
17301           return -99;
17302         }
17303     }
17304
17305   if (!mode_set)
17306     {
17307       errmsg ("expected one of 'l2' or 'l3' parameter!");
17308       return -99;
17309     }
17310
17311   if (!vam->json_output)
17312     {
17313       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
17314     }
17315
17316   M (ONE_EID_TABLE_MAP_DUMP, mp);
17317   mp->is_l2 = is_l2;
17318
17319   /* send it... */
17320   S (mp);
17321
17322   /* Use a control ping for synchronization */
17323   MPING (CONTROL_PING, mp_ping);
17324   S (mp_ping);
17325
17326   /* Wait for a reply... */
17327   W (ret);
17328   return ret;
17329 }
17330
17331 #define api_lisp_eid_table_map_dump api_one_eid_table_map_dump
17332
17333 static int
17334 api_one_eid_table_vni_dump (vat_main_t * vam)
17335 {
17336   vl_api_one_eid_table_vni_dump_t *mp;
17337   vl_api_control_ping_t *mp_ping;
17338   int ret;
17339
17340   if (!vam->json_output)
17341     {
17342       print (vam->ofp, "VNI");
17343     }
17344
17345   M (ONE_EID_TABLE_VNI_DUMP, mp);
17346
17347   /* send it... */
17348   S (mp);
17349
17350   /* Use a control ping for synchronization */
17351   MPING (CONTROL_PING, mp_ping);
17352   S (mp_ping);
17353
17354   /* Wait for a reply... */
17355   W (ret);
17356   return ret;
17357 }
17358
17359 #define api_lisp_eid_table_vni_dump api_one_eid_table_vni_dump
17360
17361 static int
17362 api_one_eid_table_dump (vat_main_t * vam)
17363 {
17364   unformat_input_t *i = vam->input;
17365   vl_api_one_eid_table_dump_t *mp;
17366   vl_api_control_ping_t *mp_ping;
17367   struct in_addr ip4;
17368   struct in6_addr ip6;
17369   u8 mac[6];
17370   u8 eid_type = ~0, eid_set = 0;
17371   u32 prefix_length = ~0, t, vni = 0;
17372   u8 filter = 0;
17373   int ret;
17374   lisp_nsh_api_t nsh;
17375
17376   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17377     {
17378       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
17379         {
17380           eid_set = 1;
17381           eid_type = 0;
17382           prefix_length = t;
17383         }
17384       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
17385         {
17386           eid_set = 1;
17387           eid_type = 1;
17388           prefix_length = t;
17389         }
17390       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
17391         {
17392           eid_set = 1;
17393           eid_type = 2;
17394         }
17395       else if (unformat (i, "eid %U", unformat_nsh_address, &nsh))
17396         {
17397           eid_set = 1;
17398           eid_type = 3;
17399         }
17400       else if (unformat (i, "vni %d", &t))
17401         {
17402           vni = t;
17403         }
17404       else if (unformat (i, "local"))
17405         {
17406           filter = 1;
17407         }
17408       else if (unformat (i, "remote"))
17409         {
17410           filter = 2;
17411         }
17412       else
17413         {
17414           errmsg ("parse error '%U'", format_unformat_error, i);
17415           return -99;
17416         }
17417     }
17418
17419   if (!vam->json_output)
17420     {
17421       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
17422              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
17423     }
17424
17425   M (ONE_EID_TABLE_DUMP, mp);
17426
17427   mp->filter = filter;
17428   if (eid_set)
17429     {
17430       mp->eid_set = 1;
17431       mp->vni = htonl (vni);
17432       mp->eid_type = eid_type;
17433       switch (eid_type)
17434         {
17435         case 0:
17436           mp->prefix_length = prefix_length;
17437           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
17438           break;
17439         case 1:
17440           mp->prefix_length = prefix_length;
17441           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
17442           break;
17443         case 2:
17444           clib_memcpy (mp->eid, mac, sizeof (mac));
17445           break;
17446         case 3:
17447           clib_memcpy (mp->eid, &nsh, sizeof (nsh));
17448           break;
17449         default:
17450           errmsg ("unknown EID type %d!", eid_type);
17451           return -99;
17452         }
17453     }
17454
17455   /* send it... */
17456   S (mp);
17457
17458   /* Use a control ping for synchronization */
17459   MPING (CONTROL_PING, mp_ping);
17460   S (mp_ping);
17461
17462   /* Wait for a reply... */
17463   W (ret);
17464   return ret;
17465 }
17466
17467 #define api_lisp_eid_table_dump api_one_eid_table_dump
17468
17469 static int
17470 api_lisp_gpe_fwd_entries_get (vat_main_t * vam)
17471 {
17472   unformat_input_t *i = vam->input;
17473   vl_api_gpe_fwd_entries_get_t *mp;
17474   u8 vni_set = 0;
17475   u32 vni = ~0;
17476   int ret;
17477
17478   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17479     {
17480       if (unformat (i, "vni %d", &vni))
17481         {
17482           vni_set = 1;
17483         }
17484       else
17485         {
17486           errmsg ("parse error '%U'", format_unformat_error, i);
17487           return -99;
17488         }
17489     }
17490
17491   if (!vni_set)
17492     {
17493       errmsg ("vni not set!");
17494       return -99;
17495     }
17496
17497   if (!vam->json_output)
17498     {
17499       print (vam->ofp, "%10s %10s %s %40s", "fwd_index", "dp_table",
17500              "leid", "reid");
17501     }
17502
17503   M (GPE_FWD_ENTRIES_GET, mp);
17504   mp->vni = clib_host_to_net_u32 (vni);
17505
17506   /* send it... */
17507   S (mp);
17508
17509   /* Wait for a reply... */
17510   W (ret);
17511   return ret;
17512 }
17513
17514 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_endian vl_noop_handler
17515 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_print vl_noop_handler
17516 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_endian vl_noop_handler
17517 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_print vl_noop_handler
17518 #define vl_api_gpe_fwd_entries_get_reply_t_endian vl_noop_handler
17519 #define vl_api_gpe_fwd_entries_get_reply_t_print vl_noop_handler
17520 #define vl_api_gpe_fwd_entry_path_details_t_endian vl_noop_handler
17521 #define vl_api_gpe_fwd_entry_path_details_t_print vl_noop_handler
17522
17523 static int
17524 api_one_adjacencies_get (vat_main_t * vam)
17525 {
17526   unformat_input_t *i = vam->input;
17527   vl_api_one_adjacencies_get_t *mp;
17528   u8 vni_set = 0;
17529   u32 vni = ~0;
17530   int ret;
17531
17532   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17533     {
17534       if (unformat (i, "vni %d", &vni))
17535         {
17536           vni_set = 1;
17537         }
17538       else
17539         {
17540           errmsg ("parse error '%U'", format_unformat_error, i);
17541           return -99;
17542         }
17543     }
17544
17545   if (!vni_set)
17546     {
17547       errmsg ("vni not set!");
17548       return -99;
17549     }
17550
17551   if (!vam->json_output)
17552     {
17553       print (vam->ofp, "%s %40s", "leid", "reid");
17554     }
17555
17556   M (ONE_ADJACENCIES_GET, mp);
17557   mp->vni = clib_host_to_net_u32 (vni);
17558
17559   /* send it... */
17560   S (mp);
17561
17562   /* Wait for a reply... */
17563   W (ret);
17564   return ret;
17565 }
17566
17567 #define api_lisp_adjacencies_get api_one_adjacencies_get
17568
17569 static int
17570 api_gpe_native_fwd_rpaths_get (vat_main_t * vam)
17571 {
17572   unformat_input_t *i = vam->input;
17573   vl_api_gpe_native_fwd_rpaths_get_t *mp;
17574   int ret;
17575   u8 ip_family_set = 0, is_ip4 = 1;
17576
17577   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17578     {
17579       if (unformat (i, "ip4"))
17580         {
17581           ip_family_set = 1;
17582           is_ip4 = 1;
17583         }
17584       else if (unformat (i, "ip6"))
17585         {
17586           ip_family_set = 1;
17587           is_ip4 = 0;
17588         }
17589       else
17590         {
17591           errmsg ("parse error '%U'", format_unformat_error, i);
17592           return -99;
17593         }
17594     }
17595
17596   if (!ip_family_set)
17597     {
17598       errmsg ("ip family not set!");
17599       return -99;
17600     }
17601
17602   M (GPE_NATIVE_FWD_RPATHS_GET, mp);
17603   mp->is_ip4 = is_ip4;
17604
17605   /* send it... */
17606   S (mp);
17607
17608   /* Wait for a reply... */
17609   W (ret);
17610   return ret;
17611 }
17612
17613 static int
17614 api_gpe_fwd_entry_vnis_get (vat_main_t * vam)
17615 {
17616   vl_api_gpe_fwd_entry_vnis_get_t *mp;
17617   int ret;
17618
17619   if (!vam->json_output)
17620     {
17621       print (vam->ofp, "VNIs");
17622     }
17623
17624   M (GPE_FWD_ENTRY_VNIS_GET, mp);
17625
17626   /* send it... */
17627   S (mp);
17628
17629   /* Wait for a reply... */
17630   W (ret);
17631   return ret;
17632 }
17633
17634 static int
17635 api_gpe_add_del_native_fwd_rpath (vat_main_t * vam)
17636 {
17637   unformat_input_t *i = vam->input;
17638   vl_api_gpe_add_del_native_fwd_rpath_t *mp;
17639   int ret = 0;
17640   u8 is_add = 1, ip_set = 0, is_ip4 = 1;
17641   struct in_addr ip4;
17642   struct in6_addr ip6;
17643   u32 table_id = 0, nh_sw_if_index = ~0;
17644
17645   clib_memset (&ip4, 0, sizeof (ip4));
17646   clib_memset (&ip6, 0, sizeof (ip6));
17647
17648   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17649     {
17650       if (unformat (i, "del"))
17651         is_add = 0;
17652       else if (unformat (i, "via %U %U", unformat_ip4_address, &ip4,
17653                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
17654         {
17655           ip_set = 1;
17656           is_ip4 = 1;
17657         }
17658       else if (unformat (i, "via %U %U", unformat_ip6_address, &ip6,
17659                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
17660         {
17661           ip_set = 1;
17662           is_ip4 = 0;
17663         }
17664       else if (unformat (i, "via %U", unformat_ip4_address, &ip4))
17665         {
17666           ip_set = 1;
17667           is_ip4 = 1;
17668           nh_sw_if_index = ~0;
17669         }
17670       else if (unformat (i, "via %U", unformat_ip6_address, &ip6))
17671         {
17672           ip_set = 1;
17673           is_ip4 = 0;
17674           nh_sw_if_index = ~0;
17675         }
17676       else if (unformat (i, "table %d", &table_id))
17677         ;
17678       else
17679         {
17680           errmsg ("parse error '%U'", format_unformat_error, i);
17681           return -99;
17682         }
17683     }
17684
17685   if (!ip_set)
17686     {
17687       errmsg ("nh addr not set!");
17688       return -99;
17689     }
17690
17691   M (GPE_ADD_DEL_NATIVE_FWD_RPATH, mp);
17692   mp->is_add = is_add;
17693   mp->table_id = clib_host_to_net_u32 (table_id);
17694   mp->nh_sw_if_index = clib_host_to_net_u32 (nh_sw_if_index);
17695   mp->is_ip4 = is_ip4;
17696   if (is_ip4)
17697     clib_memcpy (mp->nh_addr, &ip4, sizeof (ip4));
17698   else
17699     clib_memcpy (mp->nh_addr, &ip6, sizeof (ip6));
17700
17701   /* send it... */
17702   S (mp);
17703
17704   /* Wait for a reply... */
17705   W (ret);
17706   return ret;
17707 }
17708
17709 static int
17710 api_one_map_server_dump (vat_main_t * vam)
17711 {
17712   vl_api_one_map_server_dump_t *mp;
17713   vl_api_control_ping_t *mp_ping;
17714   int ret;
17715
17716   if (!vam->json_output)
17717     {
17718       print (vam->ofp, "%=20s", "Map server");
17719     }
17720
17721   M (ONE_MAP_SERVER_DUMP, mp);
17722   /* send it... */
17723   S (mp);
17724
17725   /* Use a control ping for synchronization */
17726   MPING (CONTROL_PING, mp_ping);
17727   S (mp_ping);
17728
17729   /* Wait for a reply... */
17730   W (ret);
17731   return ret;
17732 }
17733
17734 #define api_lisp_map_server_dump api_one_map_server_dump
17735
17736 static int
17737 api_one_map_resolver_dump (vat_main_t * vam)
17738 {
17739   vl_api_one_map_resolver_dump_t *mp;
17740   vl_api_control_ping_t *mp_ping;
17741   int ret;
17742
17743   if (!vam->json_output)
17744     {
17745       print (vam->ofp, "%=20s", "Map resolver");
17746     }
17747
17748   M (ONE_MAP_RESOLVER_DUMP, mp);
17749   /* send it... */
17750   S (mp);
17751
17752   /* Use a control ping for synchronization */
17753   MPING (CONTROL_PING, mp_ping);
17754   S (mp_ping);
17755
17756   /* Wait for a reply... */
17757   W (ret);
17758   return ret;
17759 }
17760
17761 #define api_lisp_map_resolver_dump api_one_map_resolver_dump
17762
17763 static int
17764 api_one_stats_flush (vat_main_t * vam)
17765 {
17766   vl_api_one_stats_flush_t *mp;
17767   int ret = 0;
17768
17769   M (ONE_STATS_FLUSH, mp);
17770   S (mp);
17771   W (ret);
17772   return ret;
17773 }
17774
17775 static int
17776 api_one_stats_dump (vat_main_t * vam)
17777 {
17778   vl_api_one_stats_dump_t *mp;
17779   vl_api_control_ping_t *mp_ping;
17780   int ret;
17781
17782   M (ONE_STATS_DUMP, mp);
17783   /* send it... */
17784   S (mp);
17785
17786   /* Use a control ping for synchronization */
17787   MPING (CONTROL_PING, mp_ping);
17788   S (mp_ping);
17789
17790   /* Wait for a reply... */
17791   W (ret);
17792   return ret;
17793 }
17794
17795 static int
17796 api_show_one_status (vat_main_t * vam)
17797 {
17798   vl_api_show_one_status_t *mp;
17799   int ret;
17800
17801   if (!vam->json_output)
17802     {
17803       print (vam->ofp, "%-20s%-16s", "ONE status", "locator-set");
17804     }
17805
17806   M (SHOW_ONE_STATUS, mp);
17807   /* send it... */
17808   S (mp);
17809   /* Wait for a reply... */
17810   W (ret);
17811   return ret;
17812 }
17813
17814 #define api_show_lisp_status api_show_one_status
17815
17816 static int
17817 api_lisp_gpe_fwd_entry_path_dump (vat_main_t * vam)
17818 {
17819   vl_api_gpe_fwd_entry_path_dump_t *mp;
17820   vl_api_control_ping_t *mp_ping;
17821   unformat_input_t *i = vam->input;
17822   u32 fwd_entry_index = ~0;
17823   int ret;
17824
17825   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17826     {
17827       if (unformat (i, "index %d", &fwd_entry_index))
17828         ;
17829       else
17830         break;
17831     }
17832
17833   if (~0 == fwd_entry_index)
17834     {
17835       errmsg ("no index specified!");
17836       return -99;
17837     }
17838
17839   if (!vam->json_output)
17840     {
17841       print (vam->ofp, "first line");
17842     }
17843
17844   M (GPE_FWD_ENTRY_PATH_DUMP, mp);
17845
17846   /* send it... */
17847   S (mp);
17848   /* Use a control ping for synchronization */
17849   MPING (CONTROL_PING, mp_ping);
17850   S (mp_ping);
17851
17852   /* Wait for a reply... */
17853   W (ret);
17854   return ret;
17855 }
17856
17857 static int
17858 api_one_get_map_request_itr_rlocs (vat_main_t * vam)
17859 {
17860   vl_api_one_get_map_request_itr_rlocs_t *mp;
17861   int ret;
17862
17863   if (!vam->json_output)
17864     {
17865       print (vam->ofp, "%=20s", "itr-rlocs:");
17866     }
17867
17868   M (ONE_GET_MAP_REQUEST_ITR_RLOCS, mp);
17869   /* send it... */
17870   S (mp);
17871   /* Wait for a reply... */
17872   W (ret);
17873   return ret;
17874 }
17875
17876 #define api_lisp_get_map_request_itr_rlocs api_one_get_map_request_itr_rlocs
17877
17878 static int
17879 api_af_packet_create (vat_main_t * vam)
17880 {
17881   unformat_input_t *i = vam->input;
17882   vl_api_af_packet_create_t *mp;
17883   u8 *host_if_name = 0;
17884   u8 hw_addr[6];
17885   u8 random_hw_addr = 1;
17886   int ret;
17887
17888   clib_memset (hw_addr, 0, sizeof (hw_addr));
17889
17890   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17891     {
17892       if (unformat (i, "name %s", &host_if_name))
17893         vec_add1 (host_if_name, 0);
17894       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
17895         random_hw_addr = 0;
17896       else
17897         break;
17898     }
17899
17900   if (!vec_len (host_if_name))
17901     {
17902       errmsg ("host-interface name must be specified");
17903       return -99;
17904     }
17905
17906   if (vec_len (host_if_name) > 64)
17907     {
17908       errmsg ("host-interface name too long");
17909       return -99;
17910     }
17911
17912   M (AF_PACKET_CREATE, mp);
17913
17914   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
17915   clib_memcpy (mp->hw_addr, hw_addr, 6);
17916   mp->use_random_hw_addr = random_hw_addr;
17917   vec_free (host_if_name);
17918
17919   S (mp);
17920
17921   /* *INDENT-OFF* */
17922   W2 (ret,
17923       ({
17924         if (ret == 0)
17925           fprintf (vam->ofp ? vam->ofp : stderr,
17926                    " new sw_if_index = %d\n", vam->sw_if_index);
17927       }));
17928   /* *INDENT-ON* */
17929   return ret;
17930 }
17931
17932 static int
17933 api_af_packet_delete (vat_main_t * vam)
17934 {
17935   unformat_input_t *i = vam->input;
17936   vl_api_af_packet_delete_t *mp;
17937   u8 *host_if_name = 0;
17938   int ret;
17939
17940   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17941     {
17942       if (unformat (i, "name %s", &host_if_name))
17943         vec_add1 (host_if_name, 0);
17944       else
17945         break;
17946     }
17947
17948   if (!vec_len (host_if_name))
17949     {
17950       errmsg ("host-interface name must be specified");
17951       return -99;
17952     }
17953
17954   if (vec_len (host_if_name) > 64)
17955     {
17956       errmsg ("host-interface name too long");
17957       return -99;
17958     }
17959
17960   M (AF_PACKET_DELETE, mp);
17961
17962   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
17963   vec_free (host_if_name);
17964
17965   S (mp);
17966   W (ret);
17967   return ret;
17968 }
17969
17970 static void vl_api_af_packet_details_t_handler
17971   (vl_api_af_packet_details_t * mp)
17972 {
17973   vat_main_t *vam = &vat_main;
17974
17975   print (vam->ofp, "%-16s %d",
17976          mp->host_if_name, clib_net_to_host_u32 (mp->sw_if_index));
17977 }
17978
17979 static void vl_api_af_packet_details_t_handler_json
17980   (vl_api_af_packet_details_t * mp)
17981 {
17982   vat_main_t *vam = &vat_main;
17983   vat_json_node_t *node = NULL;
17984
17985   if (VAT_JSON_ARRAY != vam->json_tree.type)
17986     {
17987       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17988       vat_json_init_array (&vam->json_tree);
17989     }
17990   node = vat_json_array_add (&vam->json_tree);
17991
17992   vat_json_init_object (node);
17993   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
17994   vat_json_object_add_string_copy (node, "dev_name", mp->host_if_name);
17995 }
17996
17997 static int
17998 api_af_packet_dump (vat_main_t * vam)
17999 {
18000   vl_api_af_packet_dump_t *mp;
18001   vl_api_control_ping_t *mp_ping;
18002   int ret;
18003
18004   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
18005   /* Get list of tap interfaces */
18006   M (AF_PACKET_DUMP, mp);
18007   S (mp);
18008
18009   /* Use a control ping for synchronization */
18010   MPING (CONTROL_PING, mp_ping);
18011   S (mp_ping);
18012
18013   W (ret);
18014   return ret;
18015 }
18016
18017 static int
18018 api_policer_add_del (vat_main_t * vam)
18019 {
18020   unformat_input_t *i = vam->input;
18021   vl_api_policer_add_del_t *mp;
18022   u8 is_add = 1;
18023   u8 *name = 0;
18024   u32 cir = 0;
18025   u32 eir = 0;
18026   u64 cb = 0;
18027   u64 eb = 0;
18028   u8 rate_type = 0;
18029   u8 round_type = 0;
18030   u8 type = 0;
18031   u8 color_aware = 0;
18032   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
18033   int ret;
18034
18035   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
18036   conform_action.dscp = 0;
18037   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
18038   exceed_action.dscp = 0;
18039   violate_action.action_type = SSE2_QOS_ACTION_DROP;
18040   violate_action.dscp = 0;
18041
18042   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18043     {
18044       if (unformat (i, "del"))
18045         is_add = 0;
18046       else if (unformat (i, "name %s", &name))
18047         vec_add1 (name, 0);
18048       else if (unformat (i, "cir %u", &cir))
18049         ;
18050       else if (unformat (i, "eir %u", &eir))
18051         ;
18052       else if (unformat (i, "cb %u", &cb))
18053         ;
18054       else if (unformat (i, "eb %u", &eb))
18055         ;
18056       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
18057                          &rate_type))
18058         ;
18059       else if (unformat (i, "round_type %U", unformat_policer_round_type,
18060                          &round_type))
18061         ;
18062       else if (unformat (i, "type %U", unformat_policer_type, &type))
18063         ;
18064       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
18065                          &conform_action))
18066         ;
18067       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
18068                          &exceed_action))
18069         ;
18070       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
18071                          &violate_action))
18072         ;
18073       else if (unformat (i, "color-aware"))
18074         color_aware = 1;
18075       else
18076         break;
18077     }
18078
18079   if (!vec_len (name))
18080     {
18081       errmsg ("policer name must be specified");
18082       return -99;
18083     }
18084
18085   if (vec_len (name) > 64)
18086     {
18087       errmsg ("policer name too long");
18088       return -99;
18089     }
18090
18091   M (POLICER_ADD_DEL, mp);
18092
18093   clib_memcpy (mp->name, name, vec_len (name));
18094   vec_free (name);
18095   mp->is_add = is_add;
18096   mp->cir = ntohl (cir);
18097   mp->eir = ntohl (eir);
18098   mp->cb = clib_net_to_host_u64 (cb);
18099   mp->eb = clib_net_to_host_u64 (eb);
18100   mp->rate_type = rate_type;
18101   mp->round_type = round_type;
18102   mp->type = type;
18103   mp->conform_action_type = conform_action.action_type;
18104   mp->conform_dscp = conform_action.dscp;
18105   mp->exceed_action_type = exceed_action.action_type;
18106   mp->exceed_dscp = exceed_action.dscp;
18107   mp->violate_action_type = violate_action.action_type;
18108   mp->violate_dscp = violate_action.dscp;
18109   mp->color_aware = color_aware;
18110
18111   S (mp);
18112   W (ret);
18113   return ret;
18114 }
18115
18116 static int
18117 api_policer_dump (vat_main_t * vam)
18118 {
18119   unformat_input_t *i = vam->input;
18120   vl_api_policer_dump_t *mp;
18121   vl_api_control_ping_t *mp_ping;
18122   u8 *match_name = 0;
18123   u8 match_name_valid = 0;
18124   int ret;
18125
18126   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18127     {
18128       if (unformat (i, "name %s", &match_name))
18129         {
18130           vec_add1 (match_name, 0);
18131           match_name_valid = 1;
18132         }
18133       else
18134         break;
18135     }
18136
18137   M (POLICER_DUMP, mp);
18138   mp->match_name_valid = match_name_valid;
18139   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
18140   vec_free (match_name);
18141   /* send it... */
18142   S (mp);
18143
18144   /* Use a control ping for synchronization */
18145   MPING (CONTROL_PING, mp_ping);
18146   S (mp_ping);
18147
18148   /* Wait for a reply... */
18149   W (ret);
18150   return ret;
18151 }
18152
18153 static int
18154 api_policer_classify_set_interface (vat_main_t * vam)
18155 {
18156   unformat_input_t *i = vam->input;
18157   vl_api_policer_classify_set_interface_t *mp;
18158   u32 sw_if_index;
18159   int sw_if_index_set;
18160   u32 ip4_table_index = ~0;
18161   u32 ip6_table_index = ~0;
18162   u32 l2_table_index = ~0;
18163   u8 is_add = 1;
18164   int ret;
18165
18166   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18167     {
18168       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18169         sw_if_index_set = 1;
18170       else if (unformat (i, "sw_if_index %d", &sw_if_index))
18171         sw_if_index_set = 1;
18172       else if (unformat (i, "del"))
18173         is_add = 0;
18174       else if (unformat (i, "ip4-table %d", &ip4_table_index))
18175         ;
18176       else if (unformat (i, "ip6-table %d", &ip6_table_index))
18177         ;
18178       else if (unformat (i, "l2-table %d", &l2_table_index))
18179         ;
18180       else
18181         {
18182           clib_warning ("parse error '%U'", format_unformat_error, i);
18183           return -99;
18184         }
18185     }
18186
18187   if (sw_if_index_set == 0)
18188     {
18189       errmsg ("missing interface name or sw_if_index");
18190       return -99;
18191     }
18192
18193   M (POLICER_CLASSIFY_SET_INTERFACE, mp);
18194
18195   mp->sw_if_index = ntohl (sw_if_index);
18196   mp->ip4_table_index = ntohl (ip4_table_index);
18197   mp->ip6_table_index = ntohl (ip6_table_index);
18198   mp->l2_table_index = ntohl (l2_table_index);
18199   mp->is_add = is_add;
18200
18201   S (mp);
18202   W (ret);
18203   return ret;
18204 }
18205
18206 static int
18207 api_policer_classify_dump (vat_main_t * vam)
18208 {
18209   unformat_input_t *i = vam->input;
18210   vl_api_policer_classify_dump_t *mp;
18211   vl_api_control_ping_t *mp_ping;
18212   u8 type = POLICER_CLASSIFY_N_TABLES;
18213   int ret;
18214
18215   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
18216     ;
18217   else
18218     {
18219       errmsg ("classify table type must be specified");
18220       return -99;
18221     }
18222
18223   if (!vam->json_output)
18224     {
18225       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
18226     }
18227
18228   M (POLICER_CLASSIFY_DUMP, mp);
18229   mp->type = type;
18230   /* send it... */
18231   S (mp);
18232
18233   /* Use a control ping for synchronization */
18234   MPING (CONTROL_PING, mp_ping);
18235   S (mp_ping);
18236
18237   /* Wait for a reply... */
18238   W (ret);
18239   return ret;
18240 }
18241
18242 static int
18243 api_netmap_create (vat_main_t * vam)
18244 {
18245   unformat_input_t *i = vam->input;
18246   vl_api_netmap_create_t *mp;
18247   u8 *if_name = 0;
18248   u8 hw_addr[6];
18249   u8 random_hw_addr = 1;
18250   u8 is_pipe = 0;
18251   u8 is_master = 0;
18252   int ret;
18253
18254   clib_memset (hw_addr, 0, sizeof (hw_addr));
18255
18256   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18257     {
18258       if (unformat (i, "name %s", &if_name))
18259         vec_add1 (if_name, 0);
18260       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
18261         random_hw_addr = 0;
18262       else if (unformat (i, "pipe"))
18263         is_pipe = 1;
18264       else if (unformat (i, "master"))
18265         is_master = 1;
18266       else if (unformat (i, "slave"))
18267         is_master = 0;
18268       else
18269         break;
18270     }
18271
18272   if (!vec_len (if_name))
18273     {
18274       errmsg ("interface name must be specified");
18275       return -99;
18276     }
18277
18278   if (vec_len (if_name) > 64)
18279     {
18280       errmsg ("interface name too long");
18281       return -99;
18282     }
18283
18284   M (NETMAP_CREATE, mp);
18285
18286   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
18287   clib_memcpy (mp->hw_addr, hw_addr, 6);
18288   mp->use_random_hw_addr = random_hw_addr;
18289   mp->is_pipe = is_pipe;
18290   mp->is_master = is_master;
18291   vec_free (if_name);
18292
18293   S (mp);
18294   W (ret);
18295   return ret;
18296 }
18297
18298 static int
18299 api_netmap_delete (vat_main_t * vam)
18300 {
18301   unformat_input_t *i = vam->input;
18302   vl_api_netmap_delete_t *mp;
18303   u8 *if_name = 0;
18304   int ret;
18305
18306   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18307     {
18308       if (unformat (i, "name %s", &if_name))
18309         vec_add1 (if_name, 0);
18310       else
18311         break;
18312     }
18313
18314   if (!vec_len (if_name))
18315     {
18316       errmsg ("interface name must be specified");
18317       return -99;
18318     }
18319
18320   if (vec_len (if_name) > 64)
18321     {
18322       errmsg ("interface name too long");
18323       return -99;
18324     }
18325
18326   M (NETMAP_DELETE, mp);
18327
18328   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
18329   vec_free (if_name);
18330
18331   S (mp);
18332   W (ret);
18333   return ret;
18334 }
18335
18336 static u8 *
18337 format_fib_api_path_nh_proto (u8 * s, va_list * args)
18338 {
18339   vl_api_fib_path_nh_proto_t proto =
18340     va_arg (*args, vl_api_fib_path_nh_proto_t);
18341
18342   switch (proto)
18343     {
18344     case FIB_API_PATH_NH_PROTO_IP4:
18345       s = format (s, "ip4");
18346       break;
18347     case FIB_API_PATH_NH_PROTO_IP6:
18348       s = format (s, "ip6");
18349       break;
18350     case FIB_API_PATH_NH_PROTO_MPLS:
18351       s = format (s, "mpls");
18352       break;
18353     case FIB_API_PATH_NH_PROTO_BIER:
18354       s = format (s, "bier");
18355       break;
18356     case FIB_API_PATH_NH_PROTO_ETHERNET:
18357       s = format (s, "ethernet");
18358       break;
18359     }
18360
18361   return (s);
18362 }
18363
18364 static u8 *
18365 format_vl_api_ip_address_union (u8 * s, va_list * args)
18366 {
18367   vl_api_address_family_t af = va_arg (*args, vl_api_address_family_t);
18368   const vl_api_address_union_t *u = va_arg (*args, vl_api_address_union_t *);
18369
18370   switch (af)
18371     {
18372     case ADDRESS_IP4:
18373       s = format (s, "%U", format_ip4_address, u->ip4);
18374       break;
18375     case ADDRESS_IP6:
18376       s = format (s, "%U", format_ip6_address, u->ip6);
18377       break;
18378     }
18379   return (s);
18380 }
18381
18382 static u8 *
18383 format_vl_api_fib_path_type (u8 * s, va_list * args)
18384 {
18385   vl_api_fib_path_type_t t = va_arg (*args, vl_api_fib_path_type_t);
18386
18387   switch (t)
18388     {
18389     case FIB_API_PATH_TYPE_NORMAL:
18390       s = format (s, "normal");
18391       break;
18392     case FIB_API_PATH_TYPE_LOCAL:
18393       s = format (s, "local");
18394       break;
18395     case FIB_API_PATH_TYPE_DROP:
18396       s = format (s, "drop");
18397       break;
18398     case FIB_API_PATH_TYPE_UDP_ENCAP:
18399       s = format (s, "udp-encap");
18400       break;
18401     case FIB_API_PATH_TYPE_BIER_IMP:
18402       s = format (s, "bier-imp");
18403       break;
18404     case FIB_API_PATH_TYPE_ICMP_UNREACH:
18405       s = format (s, "unreach");
18406       break;
18407     case FIB_API_PATH_TYPE_ICMP_PROHIBIT:
18408       s = format (s, "prohibit");
18409       break;
18410     case FIB_API_PATH_TYPE_SOURCE_LOOKUP:
18411       s = format (s, "src-lookup");
18412       break;
18413     case FIB_API_PATH_TYPE_DVR:
18414       s = format (s, "dvr");
18415       break;
18416     case FIB_API_PATH_TYPE_INTERFACE_RX:
18417       s = format (s, "interface-rx");
18418       break;
18419     case FIB_API_PATH_TYPE_CLASSIFY:
18420       s = format (s, "classify");
18421       break;
18422     }
18423
18424   return (s);
18425 }
18426
18427 static void
18428 vl_api_fib_path_print (vat_main_t * vam, vl_api_fib_path_t * fp)
18429 {
18430   print (vam->ofp,
18431          "  weight %d, sw_if_index %d, type %U, afi %U, next_hop %U",
18432          ntohl (fp->weight), ntohl (fp->sw_if_index),
18433          format_vl_api_fib_path_type, fp->type,
18434          format_fib_api_path_nh_proto, fp->proto,
18435          format_vl_api_ip_address_union, &fp->nh.address);
18436 }
18437
18438 static void
18439 vl_api_mpls_fib_path_json_print (vat_json_node_t * node,
18440                                  vl_api_fib_path_t * fp)
18441 {
18442   struct in_addr ip4;
18443   struct in6_addr ip6;
18444
18445   vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
18446   vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
18447   vat_json_object_add_uint (node, "type", fp->type);
18448   vat_json_object_add_uint (node, "next_hop_proto", fp->proto);
18449   if (fp->proto == FIB_API_PATH_NH_PROTO_IP4)
18450     {
18451       clib_memcpy (&ip4, &fp->nh.address.ip4, sizeof (ip4));
18452       vat_json_object_add_ip4 (node, "next_hop", ip4);
18453     }
18454   else if (fp->proto == FIB_API_PATH_NH_PROTO_IP4)
18455     {
18456       clib_memcpy (&ip6, &fp->nh.address.ip6, sizeof (ip6));
18457       vat_json_object_add_ip6 (node, "next_hop", ip6);
18458     }
18459 }
18460
18461 static void
18462 vl_api_mpls_tunnel_details_t_handler (vl_api_mpls_tunnel_details_t * mp)
18463 {
18464   vat_main_t *vam = &vat_main;
18465   int count = ntohl (mp->mt_tunnel.mt_n_paths);
18466   vl_api_fib_path_t *fp;
18467   i32 i;
18468
18469   print (vam->ofp, "sw_if_index %d via:",
18470          ntohl (mp->mt_tunnel.mt_sw_if_index));
18471   fp = mp->mt_tunnel.mt_paths;
18472   for (i = 0; i < count; i++)
18473     {
18474       vl_api_fib_path_print (vam, fp);
18475       fp++;
18476     }
18477
18478   print (vam->ofp, "");
18479 }
18480
18481 #define vl_api_mpls_tunnel_details_t_endian vl_noop_handler
18482 #define vl_api_mpls_tunnel_details_t_print vl_noop_handler
18483
18484 static void
18485 vl_api_mpls_tunnel_details_t_handler_json (vl_api_mpls_tunnel_details_t * mp)
18486 {
18487   vat_main_t *vam = &vat_main;
18488   vat_json_node_t *node = NULL;
18489   int count = ntohl (mp->mt_tunnel.mt_n_paths);
18490   vl_api_fib_path_t *fp;
18491   i32 i;
18492
18493   if (VAT_JSON_ARRAY != vam->json_tree.type)
18494     {
18495       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18496       vat_json_init_array (&vam->json_tree);
18497     }
18498   node = vat_json_array_add (&vam->json_tree);
18499
18500   vat_json_init_object (node);
18501   vat_json_object_add_uint (node, "sw_if_index",
18502                             ntohl (mp->mt_tunnel.mt_sw_if_index));
18503
18504   vat_json_object_add_uint (node, "l2_only", mp->mt_tunnel.mt_l2_only);
18505
18506   fp = mp->mt_tunnel.mt_paths;
18507   for (i = 0; i < count; i++)
18508     {
18509       vl_api_mpls_fib_path_json_print (node, fp);
18510       fp++;
18511     }
18512 }
18513
18514 static int
18515 api_mpls_tunnel_dump (vat_main_t * vam)
18516 {
18517   vl_api_mpls_tunnel_dump_t *mp;
18518   vl_api_control_ping_t *mp_ping;
18519   int ret;
18520
18521   M (MPLS_TUNNEL_DUMP, mp);
18522
18523   S (mp);
18524
18525   /* Use a control ping for synchronization */
18526   MPING (CONTROL_PING, mp_ping);
18527   S (mp_ping);
18528
18529   W (ret);
18530   return ret;
18531 }
18532
18533 #define vl_api_mpls_table_details_t_endian vl_noop_handler
18534 #define vl_api_mpls_table_details_t_print vl_noop_handler
18535
18536
18537 static void
18538 vl_api_mpls_table_details_t_handler (vl_api_mpls_table_details_t * mp)
18539 {
18540   vat_main_t *vam = &vat_main;
18541
18542   print (vam->ofp, "table-id %d,", ntohl (mp->mt_table.mt_table_id));
18543 }
18544
18545 static void vl_api_mpls_table_details_t_handler_json
18546   (vl_api_mpls_table_details_t * mp)
18547 {
18548   vat_main_t *vam = &vat_main;
18549   vat_json_node_t *node = NULL;
18550
18551   if (VAT_JSON_ARRAY != vam->json_tree.type)
18552     {
18553       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18554       vat_json_init_array (&vam->json_tree);
18555     }
18556   node = vat_json_array_add (&vam->json_tree);
18557
18558   vat_json_init_object (node);
18559   vat_json_object_add_uint (node, "table", ntohl (mp->mt_table.mt_table_id));
18560 }
18561
18562 static int
18563 api_mpls_table_dump (vat_main_t * vam)
18564 {
18565   vl_api_mpls_table_dump_t *mp;
18566   vl_api_control_ping_t *mp_ping;
18567   int ret;
18568
18569   M (MPLS_TABLE_DUMP, mp);
18570   S (mp);
18571
18572   /* Use a control ping for synchronization */
18573   MPING (CONTROL_PING, mp_ping);
18574   S (mp_ping);
18575
18576   W (ret);
18577   return ret;
18578 }
18579
18580 #define vl_api_mpls_route_details_t_endian vl_noop_handler
18581 #define vl_api_mpls_route_details_t_print vl_noop_handler
18582
18583 static void
18584 vl_api_mpls_route_details_t_handler (vl_api_mpls_route_details_t * mp)
18585 {
18586   vat_main_t *vam = &vat_main;
18587   int count = (int) clib_net_to_host_u32 (mp->mr_route.mr_n_paths);
18588   vl_api_fib_path_t *fp;
18589   int i;
18590
18591   print (vam->ofp,
18592          "table-id %d, label %u, ess_bit %u",
18593          ntohl (mp->mr_route.mr_table_id),
18594          ntohl (mp->mr_route.mr_label), mp->mr_route.mr_eos);
18595   fp = mp->mr_route.mr_paths;
18596   for (i = 0; i < count; i++)
18597     {
18598       vl_api_fib_path_print (vam, fp);
18599       fp++;
18600     }
18601 }
18602
18603 static void vl_api_mpls_route_details_t_handler_json
18604   (vl_api_mpls_route_details_t * mp)
18605 {
18606   vat_main_t *vam = &vat_main;
18607   int count = (int) clib_host_to_net_u32 (mp->mr_route.mr_n_paths);
18608   vat_json_node_t *node = NULL;
18609   vl_api_fib_path_t *fp;
18610   int i;
18611
18612   if (VAT_JSON_ARRAY != vam->json_tree.type)
18613     {
18614       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18615       vat_json_init_array (&vam->json_tree);
18616     }
18617   node = vat_json_array_add (&vam->json_tree);
18618
18619   vat_json_init_object (node);
18620   vat_json_object_add_uint (node, "table", ntohl (mp->mr_route.mr_table_id));
18621   vat_json_object_add_uint (node, "s_bit", mp->mr_route.mr_eos);
18622   vat_json_object_add_uint (node, "label", ntohl (mp->mr_route.mr_label));
18623   vat_json_object_add_uint (node, "path_count", count);
18624   fp = mp->mr_route.mr_paths;
18625   for (i = 0; i < count; i++)
18626     {
18627       vl_api_mpls_fib_path_json_print (node, fp);
18628       fp++;
18629     }
18630 }
18631
18632 static int
18633 api_mpls_route_dump (vat_main_t * vam)
18634 {
18635   unformat_input_t *input = vam->input;
18636   vl_api_mpls_route_dump_t *mp;
18637   vl_api_control_ping_t *mp_ping;
18638   u32 table_id;
18639   int ret;
18640
18641   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18642     {
18643       if (unformat (input, "table_id %d", &table_id))
18644         ;
18645       else
18646         break;
18647     }
18648   if (table_id == ~0)
18649     {
18650       errmsg ("missing table id");
18651       return -99;
18652     }
18653
18654   M (MPLS_ROUTE_DUMP, mp);
18655
18656   mp->table.mt_table_id = ntohl (table_id);
18657   S (mp);
18658
18659   /* Use a control ping for synchronization */
18660   MPING (CONTROL_PING, mp_ping);
18661   S (mp_ping);
18662
18663   W (ret);
18664   return ret;
18665 }
18666
18667 #define vl_api_ip_table_details_t_endian vl_noop_handler
18668 #define vl_api_ip_table_details_t_print vl_noop_handler
18669
18670 static void
18671 vl_api_ip_table_details_t_handler (vl_api_ip_table_details_t * mp)
18672 {
18673   vat_main_t *vam = &vat_main;
18674
18675   print (vam->ofp,
18676          "%s; table-id %d, prefix %U/%d",
18677          mp->table.name, ntohl (mp->table.table_id));
18678 }
18679
18680
18681 static void vl_api_ip_table_details_t_handler_json
18682   (vl_api_ip_table_details_t * mp)
18683 {
18684   vat_main_t *vam = &vat_main;
18685   vat_json_node_t *node = NULL;
18686
18687   if (VAT_JSON_ARRAY != vam->json_tree.type)
18688     {
18689       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18690       vat_json_init_array (&vam->json_tree);
18691     }
18692   node = vat_json_array_add (&vam->json_tree);
18693
18694   vat_json_init_object (node);
18695   vat_json_object_add_uint (node, "table", ntohl (mp->table.table_id));
18696 }
18697
18698 static int
18699 api_ip_table_dump (vat_main_t * vam)
18700 {
18701   vl_api_ip_table_dump_t *mp;
18702   vl_api_control_ping_t *mp_ping;
18703   int ret;
18704
18705   M (IP_TABLE_DUMP, mp);
18706   S (mp);
18707
18708   /* Use a control ping for synchronization */
18709   MPING (CONTROL_PING, mp_ping);
18710   S (mp_ping);
18711
18712   W (ret);
18713   return ret;
18714 }
18715
18716 static int
18717 api_ip_mtable_dump (vat_main_t * vam)
18718 {
18719   vl_api_ip_mtable_dump_t *mp;
18720   vl_api_control_ping_t *mp_ping;
18721   int ret;
18722
18723   M (IP_MTABLE_DUMP, mp);
18724   S (mp);
18725
18726   /* Use a control ping for synchronization */
18727   MPING (CONTROL_PING, mp_ping);
18728   S (mp_ping);
18729
18730   W (ret);
18731   return ret;
18732 }
18733
18734 static int
18735 api_ip_mroute_dump (vat_main_t * vam)
18736 {
18737   unformat_input_t *input = vam->input;
18738   vl_api_control_ping_t *mp_ping;
18739   vl_api_ip_mroute_dump_t *mp;
18740   int ret, is_ip6;
18741   u32 table_id;
18742
18743   is_ip6 = 0;
18744   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18745     {
18746       if (unformat (input, "table_id %d", &table_id))
18747         ;
18748       else if (unformat (input, "ip6"))
18749         is_ip6 = 1;
18750       else if (unformat (input, "ip4"))
18751         is_ip6 = 0;
18752       else
18753         break;
18754     }
18755   if (table_id == ~0)
18756     {
18757       errmsg ("missing table id");
18758       return -99;
18759     }
18760
18761   M (IP_MROUTE_DUMP, mp);
18762   mp->table.table_id = table_id;
18763   mp->table.is_ip6 = is_ip6;
18764   S (mp);
18765
18766   /* Use a control ping for synchronization */
18767   MPING (CONTROL_PING, mp_ping);
18768   S (mp_ping);
18769
18770   W (ret);
18771   return ret;
18772 }
18773
18774 static void vl_api_ip_neighbor_details_t_handler
18775   (vl_api_ip_neighbor_details_t * mp)
18776 {
18777   vat_main_t *vam = &vat_main;
18778
18779   print (vam->ofp, "%c %U %U",
18780          (ntohl (mp->neighbor.flags) & IP_NEIGHBOR_FLAG_STATIC) ? 'S' : 'D',
18781          format_vl_api_mac_address, &mp->neighbor.mac_address,
18782          format_vl_api_address, &mp->neighbor.ip_address);
18783 }
18784
18785 static void vl_api_ip_neighbor_details_t_handler_json
18786   (vl_api_ip_neighbor_details_t * mp)
18787 {
18788
18789   vat_main_t *vam = &vat_main;
18790   vat_json_node_t *node;
18791
18792   if (VAT_JSON_ARRAY != vam->json_tree.type)
18793     {
18794       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18795       vat_json_init_array (&vam->json_tree);
18796     }
18797   node = vat_json_array_add (&vam->json_tree);
18798
18799   vat_json_init_object (node);
18800   vat_json_object_add_string_copy
18801     (node, "flag",
18802      ((ntohl (mp->neighbor.flags) & IP_NEIGHBOR_FLAG_STATIC) ?
18803       (u8 *) "static" : (u8 *) "dynamic"));
18804
18805   vat_json_object_add_string_copy (node, "link_layer",
18806                                    format (0, "%U", format_vl_api_mac_address,
18807                                            &mp->neighbor.mac_address));
18808   vat_json_object_add_address (node, "ip", &mp->neighbor.ip_address);
18809 }
18810
18811 static int
18812 api_ip_neighbor_dump (vat_main_t * vam)
18813 {
18814   unformat_input_t *i = vam->input;
18815   vl_api_ip_neighbor_dump_t *mp;
18816   vl_api_control_ping_t *mp_ping;
18817   u8 is_ipv6 = 0;
18818   u32 sw_if_index = ~0;
18819   int ret;
18820
18821   /* Parse args required to build the message */
18822   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18823     {
18824       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18825         ;
18826       else if (unformat (i, "sw_if_index %d", &sw_if_index))
18827         ;
18828       else if (unformat (i, "ip6"))
18829         is_ipv6 = 1;
18830       else
18831         break;
18832     }
18833
18834   if (sw_if_index == ~0)
18835     {
18836       errmsg ("missing interface name or sw_if_index");
18837       return -99;
18838     }
18839
18840   M (IP_NEIGHBOR_DUMP, mp);
18841   mp->is_ipv6 = (u8) is_ipv6;
18842   mp->sw_if_index = ntohl (sw_if_index);
18843   S (mp);
18844
18845   /* Use a control ping for synchronization */
18846   MPING (CONTROL_PING, mp_ping);
18847   S (mp_ping);
18848
18849   W (ret);
18850   return ret;
18851 }
18852
18853 #define vl_api_ip_route_details_t_endian vl_noop_handler
18854 #define vl_api_ip_route_details_t_print vl_noop_handler
18855
18856 static void
18857 vl_api_ip_route_details_t_handler (vl_api_ip_route_details_t * mp)
18858 {
18859   vat_main_t *vam = &vat_main;
18860   u8 count = mp->route.n_paths;
18861   vl_api_fib_path_t *fp;
18862   int i;
18863
18864   print (vam->ofp,
18865          "table-id %d, prefix %U/%d",
18866          ntohl (mp->route.table_id),
18867          format_ip46_address, mp->route.prefix.address, mp->route.prefix.len);
18868   for (i = 0; i < count; i++)
18869     {
18870       fp = &mp->route.paths[i];
18871
18872       vl_api_fib_path_print (vam, fp);
18873       fp++;
18874     }
18875 }
18876
18877 static void vl_api_ip_route_details_t_handler_json
18878   (vl_api_ip_route_details_t * mp)
18879 {
18880   vat_main_t *vam = &vat_main;
18881   u8 count = mp->route.n_paths;
18882   vat_json_node_t *node = NULL;
18883   struct in_addr ip4;
18884   struct in6_addr ip6;
18885   vl_api_fib_path_t *fp;
18886   int i;
18887
18888   if (VAT_JSON_ARRAY != vam->json_tree.type)
18889     {
18890       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18891       vat_json_init_array (&vam->json_tree);
18892     }
18893   node = vat_json_array_add (&vam->json_tree);
18894
18895   vat_json_init_object (node);
18896   vat_json_object_add_uint (node, "table", ntohl (mp->route.table_id));
18897   if (ADDRESS_IP6 == mp->route.prefix.address.af)
18898     {
18899       clib_memcpy (&ip6, &mp->route.prefix.address.un.ip6, sizeof (ip6));
18900       vat_json_object_add_ip6 (node, "prefix", ip6);
18901     }
18902   else
18903     {
18904       clib_memcpy (&ip4, &mp->route.prefix.address.un.ip4, sizeof (ip4));
18905       vat_json_object_add_ip4 (node, "prefix", ip4);
18906     }
18907   vat_json_object_add_uint (node, "mask_length", mp->route.prefix.len);
18908   vat_json_object_add_uint (node, "path_count", count);
18909   for (i = 0; i < count; i++)
18910     {
18911       fp = &mp->route.paths[i];
18912       vl_api_mpls_fib_path_json_print (node, fp);
18913     }
18914 }
18915
18916 static int
18917 api_ip_route_dump (vat_main_t * vam)
18918 {
18919   unformat_input_t *input = vam->input;
18920   vl_api_ip_route_dump_t *mp;
18921   vl_api_control_ping_t *mp_ping;
18922   u32 table_id;
18923   u8 is_ip6;
18924   int ret;
18925
18926   is_ip6 = 0;
18927   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18928     {
18929       if (unformat (input, "table_id %d", &table_id))
18930         ;
18931       else if (unformat (input, "ip6"))
18932         is_ip6 = 1;
18933       else if (unformat (input, "ip4"))
18934         is_ip6 = 0;
18935       else
18936         break;
18937     }
18938   if (table_id == ~0)
18939     {
18940       errmsg ("missing table id");
18941       return -99;
18942     }
18943
18944   M (IP_ROUTE_DUMP, mp);
18945
18946   mp->table.table_id = table_id;
18947   mp->table.is_ip6 = is_ip6;
18948
18949   S (mp);
18950
18951   /* Use a control ping for synchronization */
18952   MPING (CONTROL_PING, mp_ping);
18953   S (mp_ping);
18954
18955   W (ret);
18956   return ret;
18957 }
18958
18959 int
18960 api_classify_table_ids (vat_main_t * vam)
18961 {
18962   vl_api_classify_table_ids_t *mp;
18963   int ret;
18964
18965   /* Construct the API message */
18966   M (CLASSIFY_TABLE_IDS, mp);
18967   mp->context = 0;
18968
18969   S (mp);
18970   W (ret);
18971   return ret;
18972 }
18973
18974 int
18975 api_classify_table_by_interface (vat_main_t * vam)
18976 {
18977   unformat_input_t *input = vam->input;
18978   vl_api_classify_table_by_interface_t *mp;
18979
18980   u32 sw_if_index = ~0;
18981   int ret;
18982   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18983     {
18984       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18985         ;
18986       else if (unformat (input, "sw_if_index %d", &sw_if_index))
18987         ;
18988       else
18989         break;
18990     }
18991   if (sw_if_index == ~0)
18992     {
18993       errmsg ("missing interface name or sw_if_index");
18994       return -99;
18995     }
18996
18997   /* Construct the API message */
18998   M (CLASSIFY_TABLE_BY_INTERFACE, mp);
18999   mp->context = 0;
19000   mp->sw_if_index = ntohl (sw_if_index);
19001
19002   S (mp);
19003   W (ret);
19004   return ret;
19005 }
19006
19007 int
19008 api_classify_table_info (vat_main_t * vam)
19009 {
19010   unformat_input_t *input = vam->input;
19011   vl_api_classify_table_info_t *mp;
19012
19013   u32 table_id = ~0;
19014   int ret;
19015   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19016     {
19017       if (unformat (input, "table_id %d", &table_id))
19018         ;
19019       else
19020         break;
19021     }
19022   if (table_id == ~0)
19023     {
19024       errmsg ("missing table id");
19025       return -99;
19026     }
19027
19028   /* Construct the API message */
19029   M (CLASSIFY_TABLE_INFO, mp);
19030   mp->context = 0;
19031   mp->table_id = ntohl (table_id);
19032
19033   S (mp);
19034   W (ret);
19035   return ret;
19036 }
19037
19038 int
19039 api_classify_session_dump (vat_main_t * vam)
19040 {
19041   unformat_input_t *input = vam->input;
19042   vl_api_classify_session_dump_t *mp;
19043   vl_api_control_ping_t *mp_ping;
19044
19045   u32 table_id = ~0;
19046   int ret;
19047   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19048     {
19049       if (unformat (input, "table_id %d", &table_id))
19050         ;
19051       else
19052         break;
19053     }
19054   if (table_id == ~0)
19055     {
19056       errmsg ("missing table id");
19057       return -99;
19058     }
19059
19060   /* Construct the API message */
19061   M (CLASSIFY_SESSION_DUMP, mp);
19062   mp->context = 0;
19063   mp->table_id = ntohl (table_id);
19064   S (mp);
19065
19066   /* Use a control ping for synchronization */
19067   MPING (CONTROL_PING, mp_ping);
19068   S (mp_ping);
19069
19070   W (ret);
19071   return ret;
19072 }
19073
19074 static void
19075 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
19076 {
19077   vat_main_t *vam = &vat_main;
19078
19079   print (vam->ofp, "collector_address %U, collector_port %d, "
19080          "src_address %U, vrf_id %d, path_mtu %u, "
19081          "template_interval %u, udp_checksum %d",
19082          format_ip4_address, mp->collector_address,
19083          ntohs (mp->collector_port),
19084          format_ip4_address, mp->src_address,
19085          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
19086          ntohl (mp->template_interval), mp->udp_checksum);
19087
19088   vam->retval = 0;
19089   vam->result_ready = 1;
19090 }
19091
19092 static void
19093   vl_api_ipfix_exporter_details_t_handler_json
19094   (vl_api_ipfix_exporter_details_t * mp)
19095 {
19096   vat_main_t *vam = &vat_main;
19097   vat_json_node_t node;
19098   struct in_addr collector_address;
19099   struct in_addr src_address;
19100
19101   vat_json_init_object (&node);
19102   clib_memcpy (&collector_address, &mp->collector_address,
19103                sizeof (collector_address));
19104   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
19105   vat_json_object_add_uint (&node, "collector_port",
19106                             ntohs (mp->collector_port));
19107   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
19108   vat_json_object_add_ip4 (&node, "src_address", src_address);
19109   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
19110   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
19111   vat_json_object_add_uint (&node, "template_interval",
19112                             ntohl (mp->template_interval));
19113   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
19114
19115   vat_json_print (vam->ofp, &node);
19116   vat_json_free (&node);
19117   vam->retval = 0;
19118   vam->result_ready = 1;
19119 }
19120
19121 int
19122 api_ipfix_exporter_dump (vat_main_t * vam)
19123 {
19124   vl_api_ipfix_exporter_dump_t *mp;
19125   int ret;
19126
19127   /* Construct the API message */
19128   M (IPFIX_EXPORTER_DUMP, mp);
19129   mp->context = 0;
19130
19131   S (mp);
19132   W (ret);
19133   return ret;
19134 }
19135
19136 static int
19137 api_ipfix_classify_stream_dump (vat_main_t * vam)
19138 {
19139   vl_api_ipfix_classify_stream_dump_t *mp;
19140   int ret;
19141
19142   /* Construct the API message */
19143   M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
19144   mp->context = 0;
19145
19146   S (mp);
19147   W (ret);
19148   return ret;
19149   /* NOTREACHED */
19150   return 0;
19151 }
19152
19153 static void
19154   vl_api_ipfix_classify_stream_details_t_handler
19155   (vl_api_ipfix_classify_stream_details_t * mp)
19156 {
19157   vat_main_t *vam = &vat_main;
19158   print (vam->ofp, "domain_id %d, src_port %d",
19159          ntohl (mp->domain_id), ntohs (mp->src_port));
19160   vam->retval = 0;
19161   vam->result_ready = 1;
19162 }
19163
19164 static void
19165   vl_api_ipfix_classify_stream_details_t_handler_json
19166   (vl_api_ipfix_classify_stream_details_t * mp)
19167 {
19168   vat_main_t *vam = &vat_main;
19169   vat_json_node_t node;
19170
19171   vat_json_init_object (&node);
19172   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
19173   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
19174
19175   vat_json_print (vam->ofp, &node);
19176   vat_json_free (&node);
19177   vam->retval = 0;
19178   vam->result_ready = 1;
19179 }
19180
19181 static int
19182 api_ipfix_classify_table_dump (vat_main_t * vam)
19183 {
19184   vl_api_ipfix_classify_table_dump_t *mp;
19185   vl_api_control_ping_t *mp_ping;
19186   int ret;
19187
19188   if (!vam->json_output)
19189     {
19190       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
19191              "transport_protocol");
19192     }
19193
19194   /* Construct the API message */
19195   M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
19196
19197   /* send it... */
19198   S (mp);
19199
19200   /* Use a control ping for synchronization */
19201   MPING (CONTROL_PING, mp_ping);
19202   S (mp_ping);
19203
19204   W (ret);
19205   return ret;
19206 }
19207
19208 static void
19209   vl_api_ipfix_classify_table_details_t_handler
19210   (vl_api_ipfix_classify_table_details_t * mp)
19211 {
19212   vat_main_t *vam = &vat_main;
19213   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
19214          mp->transport_protocol);
19215 }
19216
19217 static void
19218   vl_api_ipfix_classify_table_details_t_handler_json
19219   (vl_api_ipfix_classify_table_details_t * mp)
19220 {
19221   vat_json_node_t *node = NULL;
19222   vat_main_t *vam = &vat_main;
19223
19224   if (VAT_JSON_ARRAY != vam->json_tree.type)
19225     {
19226       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19227       vat_json_init_array (&vam->json_tree);
19228     }
19229
19230   node = vat_json_array_add (&vam->json_tree);
19231   vat_json_init_object (node);
19232
19233   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
19234   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
19235   vat_json_object_add_uint (node, "transport_protocol",
19236                             mp->transport_protocol);
19237 }
19238
19239 static int
19240 api_sw_interface_span_enable_disable (vat_main_t * vam)
19241 {
19242   unformat_input_t *i = vam->input;
19243   vl_api_sw_interface_span_enable_disable_t *mp;
19244   u32 src_sw_if_index = ~0;
19245   u32 dst_sw_if_index = ~0;
19246   u8 state = 3;
19247   int ret;
19248   u8 is_l2 = 0;
19249
19250   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19251     {
19252       if (unformat
19253           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
19254         ;
19255       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
19256         ;
19257       else
19258         if (unformat
19259             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
19260         ;
19261       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
19262         ;
19263       else if (unformat (i, "disable"))
19264         state = 0;
19265       else if (unformat (i, "rx"))
19266         state = 1;
19267       else if (unformat (i, "tx"))
19268         state = 2;
19269       else if (unformat (i, "both"))
19270         state = 3;
19271       else if (unformat (i, "l2"))
19272         is_l2 = 1;
19273       else
19274         break;
19275     }
19276
19277   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
19278
19279   mp->sw_if_index_from = htonl (src_sw_if_index);
19280   mp->sw_if_index_to = htonl (dst_sw_if_index);
19281   mp->state = state;
19282   mp->is_l2 = is_l2;
19283
19284   S (mp);
19285   W (ret);
19286   return ret;
19287 }
19288
19289 static void
19290 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
19291                                             * mp)
19292 {
19293   vat_main_t *vam = &vat_main;
19294   u8 *sw_if_from_name = 0;
19295   u8 *sw_if_to_name = 0;
19296   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
19297   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
19298   char *states[] = { "none", "rx", "tx", "both" };
19299   hash_pair_t *p;
19300
19301   /* *INDENT-OFF* */
19302   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
19303   ({
19304     if ((u32) p->value[0] == sw_if_index_from)
19305       {
19306         sw_if_from_name = (u8 *)(p->key);
19307         if (sw_if_to_name)
19308           break;
19309       }
19310     if ((u32) p->value[0] == sw_if_index_to)
19311       {
19312         sw_if_to_name = (u8 *)(p->key);
19313         if (sw_if_from_name)
19314           break;
19315       }
19316   }));
19317   /* *INDENT-ON* */
19318   print (vam->ofp, "%20s => %20s (%s) %s",
19319          sw_if_from_name, sw_if_to_name, states[mp->state],
19320          mp->is_l2 ? "l2" : "device");
19321 }
19322
19323 static void
19324   vl_api_sw_interface_span_details_t_handler_json
19325   (vl_api_sw_interface_span_details_t * mp)
19326 {
19327   vat_main_t *vam = &vat_main;
19328   vat_json_node_t *node = NULL;
19329   u8 *sw_if_from_name = 0;
19330   u8 *sw_if_to_name = 0;
19331   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
19332   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
19333   hash_pair_t *p;
19334
19335   /* *INDENT-OFF* */
19336   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
19337   ({
19338     if ((u32) p->value[0] == sw_if_index_from)
19339       {
19340         sw_if_from_name = (u8 *)(p->key);
19341         if (sw_if_to_name)
19342           break;
19343       }
19344     if ((u32) p->value[0] == sw_if_index_to)
19345       {
19346         sw_if_to_name = (u8 *)(p->key);
19347         if (sw_if_from_name)
19348           break;
19349       }
19350   }));
19351   /* *INDENT-ON* */
19352
19353   if (VAT_JSON_ARRAY != vam->json_tree.type)
19354     {
19355       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19356       vat_json_init_array (&vam->json_tree);
19357     }
19358   node = vat_json_array_add (&vam->json_tree);
19359
19360   vat_json_init_object (node);
19361   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
19362   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
19363   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
19364   if (0 != sw_if_to_name)
19365     {
19366       vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
19367     }
19368   vat_json_object_add_uint (node, "state", mp->state);
19369   vat_json_object_add_uint (node, "is-l2", mp->is_l2);
19370 }
19371
19372 static int
19373 api_sw_interface_span_dump (vat_main_t * vam)
19374 {
19375   unformat_input_t *input = vam->input;
19376   vl_api_sw_interface_span_dump_t *mp;
19377   vl_api_control_ping_t *mp_ping;
19378   u8 is_l2 = 0;
19379   int ret;
19380
19381   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19382     {
19383       if (unformat (input, "l2"))
19384         is_l2 = 1;
19385       else
19386         break;
19387     }
19388
19389   M (SW_INTERFACE_SPAN_DUMP, mp);
19390   mp->is_l2 = is_l2;
19391   S (mp);
19392
19393   /* Use a control ping for synchronization */
19394   MPING (CONTROL_PING, mp_ping);
19395   S (mp_ping);
19396
19397   W (ret);
19398   return ret;
19399 }
19400
19401 int
19402 api_pg_create_interface (vat_main_t * vam)
19403 {
19404   unformat_input_t *input = vam->input;
19405   vl_api_pg_create_interface_t *mp;
19406
19407   u32 if_id = ~0, gso_size = 0;
19408   u8 gso_enabled = 0;
19409   int ret;
19410   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19411     {
19412       if (unformat (input, "if_id %d", &if_id))
19413         ;
19414       else if (unformat (input, "gso-enabled"))
19415         {
19416           gso_enabled = 1;
19417           if (unformat (input, "gso-size %u", &gso_size))
19418             ;
19419           else
19420             {
19421               errmsg ("missing gso-size");
19422               return -99;
19423             }
19424         }
19425       else
19426         break;
19427     }
19428   if (if_id == ~0)
19429     {
19430       errmsg ("missing pg interface index");
19431       return -99;
19432     }
19433
19434   /* Construct the API message */
19435   M (PG_CREATE_INTERFACE, mp);
19436   mp->context = 0;
19437   mp->interface_id = ntohl (if_id);
19438   mp->gso_enabled = gso_enabled;
19439
19440   S (mp);
19441   W (ret);
19442   return ret;
19443 }
19444
19445 int
19446 api_pg_capture (vat_main_t * vam)
19447 {
19448   unformat_input_t *input = vam->input;
19449   vl_api_pg_capture_t *mp;
19450
19451   u32 if_id = ~0;
19452   u8 enable = 1;
19453   u32 count = 1;
19454   u8 pcap_file_set = 0;
19455   u8 *pcap_file = 0;
19456   int ret;
19457   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19458     {
19459       if (unformat (input, "if_id %d", &if_id))
19460         ;
19461       else if (unformat (input, "pcap %s", &pcap_file))
19462         pcap_file_set = 1;
19463       else if (unformat (input, "count %d", &count))
19464         ;
19465       else if (unformat (input, "disable"))
19466         enable = 0;
19467       else
19468         break;
19469     }
19470   if (if_id == ~0)
19471     {
19472       errmsg ("missing pg interface index");
19473       return -99;
19474     }
19475   if (pcap_file_set > 0)
19476     {
19477       if (vec_len (pcap_file) > 255)
19478         {
19479           errmsg ("pcap file name is too long");
19480           return -99;
19481         }
19482     }
19483
19484   u32 name_len = vec_len (pcap_file);
19485   /* Construct the API message */
19486   M (PG_CAPTURE, mp);
19487   mp->context = 0;
19488   mp->interface_id = ntohl (if_id);
19489   mp->is_enabled = enable;
19490   mp->count = ntohl (count);
19491   mp->pcap_name_length = ntohl (name_len);
19492   if (pcap_file_set != 0)
19493     {
19494       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
19495     }
19496   vec_free (pcap_file);
19497
19498   S (mp);
19499   W (ret);
19500   return ret;
19501 }
19502
19503 int
19504 api_pg_enable_disable (vat_main_t * vam)
19505 {
19506   unformat_input_t *input = vam->input;
19507   vl_api_pg_enable_disable_t *mp;
19508
19509   u8 enable = 1;
19510   u8 stream_name_set = 0;
19511   u8 *stream_name = 0;
19512   int ret;
19513   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19514     {
19515       if (unformat (input, "stream %s", &stream_name))
19516         stream_name_set = 1;
19517       else if (unformat (input, "disable"))
19518         enable = 0;
19519       else
19520         break;
19521     }
19522
19523   if (stream_name_set > 0)
19524     {
19525       if (vec_len (stream_name) > 255)
19526         {
19527           errmsg ("stream name too long");
19528           return -99;
19529         }
19530     }
19531
19532   u32 name_len = vec_len (stream_name);
19533   /* Construct the API message */
19534   M (PG_ENABLE_DISABLE, mp);
19535   mp->context = 0;
19536   mp->is_enabled = enable;
19537   if (stream_name_set != 0)
19538     {
19539       mp->stream_name_length = ntohl (name_len);
19540       clib_memcpy (mp->stream_name, stream_name, name_len);
19541     }
19542   vec_free (stream_name);
19543
19544   S (mp);
19545   W (ret);
19546   return ret;
19547 }
19548
19549 int
19550 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
19551 {
19552   unformat_input_t *input = vam->input;
19553   vl_api_ip_source_and_port_range_check_add_del_t *mp;
19554
19555   u16 *low_ports = 0;
19556   u16 *high_ports = 0;
19557   u16 this_low;
19558   u16 this_hi;
19559   vl_api_prefix_t prefix;
19560   u32 tmp, tmp2;
19561   u8 prefix_set = 0;
19562   u32 vrf_id = ~0;
19563   u8 is_add = 1;
19564   int ret;
19565
19566   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19567     {
19568       if (unformat (input, "%U", unformat_vl_api_prefix, &prefix))
19569         prefix_set = 1;
19570       else if (unformat (input, "vrf %d", &vrf_id))
19571         ;
19572       else if (unformat (input, "del"))
19573         is_add = 0;
19574       else if (unformat (input, "port %d", &tmp))
19575         {
19576           if (tmp == 0 || tmp > 65535)
19577             {
19578               errmsg ("port %d out of range", tmp);
19579               return -99;
19580             }
19581           this_low = tmp;
19582           this_hi = this_low + 1;
19583           vec_add1 (low_ports, this_low);
19584           vec_add1 (high_ports, this_hi);
19585         }
19586       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
19587         {
19588           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
19589             {
19590               errmsg ("incorrect range parameters");
19591               return -99;
19592             }
19593           this_low = tmp;
19594           /* Note: in debug CLI +1 is added to high before
19595              passing to real fn that does "the work"
19596              (ip_source_and_port_range_check_add_del).
19597              This fn is a wrapper around the binary API fn a
19598              control plane will call, which expects this increment
19599              to have occurred. Hence letting the binary API control
19600              plane fn do the increment for consistency between VAT
19601              and other control planes.
19602            */
19603           this_hi = tmp2;
19604           vec_add1 (low_ports, this_low);
19605           vec_add1 (high_ports, this_hi);
19606         }
19607       else
19608         break;
19609     }
19610
19611   if (prefix_set == 0)
19612     {
19613       errmsg ("<address>/<mask> not specified");
19614       return -99;
19615     }
19616
19617   if (vrf_id == ~0)
19618     {
19619       errmsg ("VRF ID required, not specified");
19620       return -99;
19621     }
19622
19623   if (vrf_id == 0)
19624     {
19625       errmsg
19626         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
19627       return -99;
19628     }
19629
19630   if (vec_len (low_ports) == 0)
19631     {
19632       errmsg ("At least one port or port range required");
19633       return -99;
19634     }
19635
19636   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
19637
19638   mp->is_add = is_add;
19639
19640   clib_memcpy (&mp->prefix, &prefix, sizeof (prefix));
19641
19642   mp->number_of_ranges = vec_len (low_ports);
19643
19644   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
19645   vec_free (low_ports);
19646
19647   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
19648   vec_free (high_ports);
19649
19650   mp->vrf_id = ntohl (vrf_id);
19651
19652   S (mp);
19653   W (ret);
19654   return ret;
19655 }
19656
19657 int
19658 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
19659 {
19660   unformat_input_t *input = vam->input;
19661   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
19662   u32 sw_if_index = ~0;
19663   int vrf_set = 0;
19664   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
19665   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
19666   u8 is_add = 1;
19667   int ret;
19668
19669   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19670     {
19671       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19672         ;
19673       else if (unformat (input, "sw_if_index %d", &sw_if_index))
19674         ;
19675       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
19676         vrf_set = 1;
19677       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
19678         vrf_set = 1;
19679       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
19680         vrf_set = 1;
19681       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
19682         vrf_set = 1;
19683       else if (unformat (input, "del"))
19684         is_add = 0;
19685       else
19686         break;
19687     }
19688
19689   if (sw_if_index == ~0)
19690     {
19691       errmsg ("Interface required but not specified");
19692       return -99;
19693     }
19694
19695   if (vrf_set == 0)
19696     {
19697       errmsg ("VRF ID required but not specified");
19698       return -99;
19699     }
19700
19701   if (tcp_out_vrf_id == 0
19702       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
19703     {
19704       errmsg
19705         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
19706       return -99;
19707     }
19708
19709   /* Construct the API message */
19710   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
19711
19712   mp->sw_if_index = ntohl (sw_if_index);
19713   mp->is_add = is_add;
19714   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
19715   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
19716   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
19717   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
19718
19719   /* send it... */
19720   S (mp);
19721
19722   /* Wait for a reply... */
19723   W (ret);
19724   return ret;
19725 }
19726
19727 static int
19728 api_set_punt (vat_main_t * vam)
19729 {
19730   unformat_input_t *i = vam->input;
19731   vl_api_address_family_t af;
19732   vl_api_set_punt_t *mp;
19733   u32 protocol = ~0;
19734   u32 port = ~0;
19735   int is_add = 1;
19736   int ret;
19737
19738   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19739     {
19740       if (unformat (i, "%U", unformat_vl_api_address_family, &af))
19741         ;
19742       else if (unformat (i, "protocol %d", &protocol))
19743         ;
19744       else if (unformat (i, "port %d", &port))
19745         ;
19746       else if (unformat (i, "del"))
19747         is_add = 0;
19748       else
19749         {
19750           clib_warning ("parse error '%U'", format_unformat_error, i);
19751           return -99;
19752         }
19753     }
19754
19755   M (SET_PUNT, mp);
19756
19757   mp->is_add = (u8) is_add;
19758   mp->punt.type = PUNT_API_TYPE_L4;
19759   mp->punt.punt.l4.af = af;
19760   mp->punt.punt.l4.protocol = (u8) protocol;
19761   mp->punt.punt.l4.port = htons ((u16) port);
19762
19763   S (mp);
19764   W (ret);
19765   return ret;
19766 }
19767
19768 static int
19769 api_delete_subif (vat_main_t * vam)
19770 {
19771   unformat_input_t *i = vam->input;
19772   vl_api_delete_subif_t *mp;
19773   u32 sw_if_index = ~0;
19774   int ret;
19775
19776   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19777     {
19778       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19779         ;
19780       if (unformat (i, "sw_if_index %d", &sw_if_index))
19781         ;
19782       else
19783         break;
19784     }
19785
19786   if (sw_if_index == ~0)
19787     {
19788       errmsg ("missing sw_if_index");
19789       return -99;
19790     }
19791
19792   /* Construct the API message */
19793   M (DELETE_SUBIF, mp);
19794   mp->sw_if_index = ntohl (sw_if_index);
19795
19796   S (mp);
19797   W (ret);
19798   return ret;
19799 }
19800
19801 #define foreach_pbb_vtr_op      \
19802 _("disable",  L2_VTR_DISABLED)  \
19803 _("pop",  L2_VTR_POP_2)         \
19804 _("push",  L2_VTR_PUSH_2)
19805
19806 static int
19807 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
19808 {
19809   unformat_input_t *i = vam->input;
19810   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
19811   u32 sw_if_index = ~0, vtr_op = ~0;
19812   u16 outer_tag = ~0;
19813   u8 dmac[6], smac[6];
19814   u8 dmac_set = 0, smac_set = 0;
19815   u16 vlanid = 0;
19816   u32 sid = ~0;
19817   u32 tmp;
19818   int ret;
19819
19820   /* Shut up coverity */
19821   clib_memset (dmac, 0, sizeof (dmac));
19822   clib_memset (smac, 0, sizeof (smac));
19823
19824   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19825     {
19826       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19827         ;
19828       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19829         ;
19830       else if (unformat (i, "vtr_op %d", &vtr_op))
19831         ;
19832 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
19833       foreach_pbb_vtr_op
19834 #undef _
19835         else if (unformat (i, "translate_pbb_stag"))
19836         {
19837           if (unformat (i, "%d", &tmp))
19838             {
19839               vtr_op = L2_VTR_TRANSLATE_2_1;
19840               outer_tag = tmp;
19841             }
19842           else
19843             {
19844               errmsg
19845                 ("translate_pbb_stag operation requires outer tag definition");
19846               return -99;
19847             }
19848         }
19849       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
19850         dmac_set++;
19851       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
19852         smac_set++;
19853       else if (unformat (i, "sid %d", &sid))
19854         ;
19855       else if (unformat (i, "vlanid %d", &tmp))
19856         vlanid = tmp;
19857       else
19858         {
19859           clib_warning ("parse error '%U'", format_unformat_error, i);
19860           return -99;
19861         }
19862     }
19863
19864   if ((sw_if_index == ~0) || (vtr_op == ~0))
19865     {
19866       errmsg ("missing sw_if_index or vtr operation");
19867       return -99;
19868     }
19869   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
19870       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
19871     {
19872       errmsg
19873         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
19874       return -99;
19875     }
19876
19877   M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
19878   mp->sw_if_index = ntohl (sw_if_index);
19879   mp->vtr_op = ntohl (vtr_op);
19880   mp->outer_tag = ntohs (outer_tag);
19881   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
19882   clib_memcpy (mp->b_smac, smac, sizeof (smac));
19883   mp->b_vlanid = ntohs (vlanid);
19884   mp->i_sid = ntohl (sid);
19885
19886   S (mp);
19887   W (ret);
19888   return ret;
19889 }
19890
19891 static int
19892 api_flow_classify_set_interface (vat_main_t * vam)
19893 {
19894   unformat_input_t *i = vam->input;
19895   vl_api_flow_classify_set_interface_t *mp;
19896   u32 sw_if_index;
19897   int sw_if_index_set;
19898   u32 ip4_table_index = ~0;
19899   u32 ip6_table_index = ~0;
19900   u8 is_add = 1;
19901   int ret;
19902
19903   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19904     {
19905       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19906         sw_if_index_set = 1;
19907       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19908         sw_if_index_set = 1;
19909       else if (unformat (i, "del"))
19910         is_add = 0;
19911       else if (unformat (i, "ip4-table %d", &ip4_table_index))
19912         ;
19913       else if (unformat (i, "ip6-table %d", &ip6_table_index))
19914         ;
19915       else
19916         {
19917           clib_warning ("parse error '%U'", format_unformat_error, i);
19918           return -99;
19919         }
19920     }
19921
19922   if (sw_if_index_set == 0)
19923     {
19924       errmsg ("missing interface name or sw_if_index");
19925       return -99;
19926     }
19927
19928   M (FLOW_CLASSIFY_SET_INTERFACE, mp);
19929
19930   mp->sw_if_index = ntohl (sw_if_index);
19931   mp->ip4_table_index = ntohl (ip4_table_index);
19932   mp->ip6_table_index = ntohl (ip6_table_index);
19933   mp->is_add = is_add;
19934
19935   S (mp);
19936   W (ret);
19937   return ret;
19938 }
19939
19940 static int
19941 api_flow_classify_dump (vat_main_t * vam)
19942 {
19943   unformat_input_t *i = vam->input;
19944   vl_api_flow_classify_dump_t *mp;
19945   vl_api_control_ping_t *mp_ping;
19946   u8 type = FLOW_CLASSIFY_N_TABLES;
19947   int ret;
19948
19949   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
19950     ;
19951   else
19952     {
19953       errmsg ("classify table type must be specified");
19954       return -99;
19955     }
19956
19957   if (!vam->json_output)
19958     {
19959       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
19960     }
19961
19962   M (FLOW_CLASSIFY_DUMP, mp);
19963   mp->type = type;
19964   /* send it... */
19965   S (mp);
19966
19967   /* Use a control ping for synchronization */
19968   MPING (CONTROL_PING, mp_ping);
19969   S (mp_ping);
19970
19971   /* Wait for a reply... */
19972   W (ret);
19973   return ret;
19974 }
19975
19976 static int
19977 api_feature_enable_disable (vat_main_t * vam)
19978 {
19979   unformat_input_t *i = vam->input;
19980   vl_api_feature_enable_disable_t *mp;
19981   u8 *arc_name = 0;
19982   u8 *feature_name = 0;
19983   u32 sw_if_index = ~0;
19984   u8 enable = 1;
19985   int ret;
19986
19987   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19988     {
19989       if (unformat (i, "arc_name %s", &arc_name))
19990         ;
19991       else if (unformat (i, "feature_name %s", &feature_name))
19992         ;
19993       else
19994         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19995         ;
19996       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19997         ;
19998       else if (unformat (i, "disable"))
19999         enable = 0;
20000       else
20001         break;
20002     }
20003
20004   if (arc_name == 0)
20005     {
20006       errmsg ("missing arc name");
20007       return -99;
20008     }
20009   if (vec_len (arc_name) > 63)
20010     {
20011       errmsg ("arc name too long");
20012     }
20013
20014   if (feature_name == 0)
20015     {
20016       errmsg ("missing feature name");
20017       return -99;
20018     }
20019   if (vec_len (feature_name) > 63)
20020     {
20021       errmsg ("feature name too long");
20022     }
20023
20024   if (sw_if_index == ~0)
20025     {
20026       errmsg ("missing interface name or sw_if_index");
20027       return -99;
20028     }
20029
20030   /* Construct the API message */
20031   M (FEATURE_ENABLE_DISABLE, mp);
20032   mp->sw_if_index = ntohl (sw_if_index);
20033   mp->enable = enable;
20034   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
20035   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
20036   vec_free (arc_name);
20037   vec_free (feature_name);
20038
20039   S (mp);
20040   W (ret);
20041   return ret;
20042 }
20043
20044 static int
20045 api_feature_gso_enable_disable (vat_main_t * vam)
20046 {
20047   unformat_input_t *i = vam->input;
20048   vl_api_feature_gso_enable_disable_t *mp;
20049   u32 sw_if_index = ~0;
20050   u8 enable = 1;
20051   int ret;
20052
20053   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20054     {
20055       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20056         ;
20057       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20058         ;
20059       else if (unformat (i, "enable"))
20060         enable = 1;
20061       else if (unformat (i, "disable"))
20062         enable = 0;
20063       else
20064         break;
20065     }
20066
20067   if (sw_if_index == ~0)
20068     {
20069       errmsg ("missing interface name or sw_if_index");
20070       return -99;
20071     }
20072
20073   /* Construct the API message */
20074   M (FEATURE_GSO_ENABLE_DISABLE, mp);
20075   mp->sw_if_index = ntohl (sw_if_index);
20076   mp->enable_disable = enable;
20077
20078   S (mp);
20079   W (ret);
20080   return ret;
20081 }
20082
20083 static int
20084 api_sw_interface_tag_add_del (vat_main_t * vam)
20085 {
20086   unformat_input_t *i = vam->input;
20087   vl_api_sw_interface_tag_add_del_t *mp;
20088   u32 sw_if_index = ~0;
20089   u8 *tag = 0;
20090   u8 enable = 1;
20091   int ret;
20092
20093   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20094     {
20095       if (unformat (i, "tag %s", &tag))
20096         ;
20097       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20098         ;
20099       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20100         ;
20101       else if (unformat (i, "del"))
20102         enable = 0;
20103       else
20104         break;
20105     }
20106
20107   if (sw_if_index == ~0)
20108     {
20109       errmsg ("missing interface name or sw_if_index");
20110       return -99;
20111     }
20112
20113   if (enable && (tag == 0))
20114     {
20115       errmsg ("no tag specified");
20116       return -99;
20117     }
20118
20119   /* Construct the API message */
20120   M (SW_INTERFACE_TAG_ADD_DEL, mp);
20121   mp->sw_if_index = ntohl (sw_if_index);
20122   mp->is_add = enable;
20123   if (enable)
20124     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
20125   vec_free (tag);
20126
20127   S (mp);
20128   W (ret);
20129   return ret;
20130 }
20131
20132 static int
20133 api_sw_interface_add_del_mac_address (vat_main_t * vam)
20134 {
20135   unformat_input_t *i = vam->input;
20136   vl_api_mac_address_t mac = { 0 };
20137   vl_api_sw_interface_add_del_mac_address_t *mp;
20138   u32 sw_if_index = ~0;
20139   u8 is_add = 1;
20140   u8 mac_set = 0;
20141   int ret;
20142
20143   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20144     {
20145       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20146         ;
20147       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20148         ;
20149       else if (unformat (i, "%U", unformat_vl_api_mac_address, &mac))
20150         mac_set++;
20151       else if (unformat (i, "del"))
20152         is_add = 0;
20153       else
20154         break;
20155     }
20156
20157   if (sw_if_index == ~0)
20158     {
20159       errmsg ("missing interface name or sw_if_index");
20160       return -99;
20161     }
20162
20163   if (!mac_set)
20164     {
20165       errmsg ("missing MAC address");
20166       return -99;
20167     }
20168
20169   /* Construct the API message */
20170   M (SW_INTERFACE_ADD_DEL_MAC_ADDRESS, mp);
20171   mp->sw_if_index = ntohl (sw_if_index);
20172   mp->is_add = is_add;
20173   clib_memcpy (&mp->addr, &mac, sizeof (mac));
20174
20175   S (mp);
20176   W (ret);
20177   return ret;
20178 }
20179
20180 static void vl_api_l2_xconnect_details_t_handler
20181   (vl_api_l2_xconnect_details_t * mp)
20182 {
20183   vat_main_t *vam = &vat_main;
20184
20185   print (vam->ofp, "%15d%15d",
20186          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
20187 }
20188
20189 static void vl_api_l2_xconnect_details_t_handler_json
20190   (vl_api_l2_xconnect_details_t * mp)
20191 {
20192   vat_main_t *vam = &vat_main;
20193   vat_json_node_t *node = NULL;
20194
20195   if (VAT_JSON_ARRAY != vam->json_tree.type)
20196     {
20197       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20198       vat_json_init_array (&vam->json_tree);
20199     }
20200   node = vat_json_array_add (&vam->json_tree);
20201
20202   vat_json_init_object (node);
20203   vat_json_object_add_uint (node, "rx_sw_if_index",
20204                             ntohl (mp->rx_sw_if_index));
20205   vat_json_object_add_uint (node, "tx_sw_if_index",
20206                             ntohl (mp->tx_sw_if_index));
20207 }
20208
20209 static int
20210 api_l2_xconnect_dump (vat_main_t * vam)
20211 {
20212   vl_api_l2_xconnect_dump_t *mp;
20213   vl_api_control_ping_t *mp_ping;
20214   int ret;
20215
20216   if (!vam->json_output)
20217     {
20218       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
20219     }
20220
20221   M (L2_XCONNECT_DUMP, mp);
20222
20223   S (mp);
20224
20225   /* Use a control ping for synchronization */
20226   MPING (CONTROL_PING, mp_ping);
20227   S (mp_ping);
20228
20229   W (ret);
20230   return ret;
20231 }
20232
20233 static int
20234 api_hw_interface_set_mtu (vat_main_t * vam)
20235 {
20236   unformat_input_t *i = vam->input;
20237   vl_api_hw_interface_set_mtu_t *mp;
20238   u32 sw_if_index = ~0;
20239   u32 mtu = 0;
20240   int ret;
20241
20242   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20243     {
20244       if (unformat (i, "mtu %d", &mtu))
20245         ;
20246       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20247         ;
20248       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20249         ;
20250       else
20251         break;
20252     }
20253
20254   if (sw_if_index == ~0)
20255     {
20256       errmsg ("missing interface name or sw_if_index");
20257       return -99;
20258     }
20259
20260   if (mtu == 0)
20261     {
20262       errmsg ("no mtu specified");
20263       return -99;
20264     }
20265
20266   /* Construct the API message */
20267   M (HW_INTERFACE_SET_MTU, mp);
20268   mp->sw_if_index = ntohl (sw_if_index);
20269   mp->mtu = ntohs ((u16) mtu);
20270
20271   S (mp);
20272   W (ret);
20273   return ret;
20274 }
20275
20276 static int
20277 api_p2p_ethernet_add (vat_main_t * vam)
20278 {
20279   unformat_input_t *i = vam->input;
20280   vl_api_p2p_ethernet_add_t *mp;
20281   u32 parent_if_index = ~0;
20282   u32 sub_id = ~0;
20283   u8 remote_mac[6];
20284   u8 mac_set = 0;
20285   int ret;
20286
20287   clib_memset (remote_mac, 0, sizeof (remote_mac));
20288   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20289     {
20290       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
20291         ;
20292       else if (unformat (i, "sw_if_index %d", &parent_if_index))
20293         ;
20294       else
20295         if (unformat
20296             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
20297         mac_set++;
20298       else if (unformat (i, "sub_id %d", &sub_id))
20299         ;
20300       else
20301         {
20302           clib_warning ("parse error '%U'", format_unformat_error, i);
20303           return -99;
20304         }
20305     }
20306
20307   if (parent_if_index == ~0)
20308     {
20309       errmsg ("missing interface name or sw_if_index");
20310       return -99;
20311     }
20312   if (mac_set == 0)
20313     {
20314       errmsg ("missing remote mac address");
20315       return -99;
20316     }
20317   if (sub_id == ~0)
20318     {
20319       errmsg ("missing sub-interface id");
20320       return -99;
20321     }
20322
20323   M (P2P_ETHERNET_ADD, mp);
20324   mp->parent_if_index = ntohl (parent_if_index);
20325   mp->subif_id = ntohl (sub_id);
20326   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
20327
20328   S (mp);
20329   W (ret);
20330   return ret;
20331 }
20332
20333 static int
20334 api_p2p_ethernet_del (vat_main_t * vam)
20335 {
20336   unformat_input_t *i = vam->input;
20337   vl_api_p2p_ethernet_del_t *mp;
20338   u32 parent_if_index = ~0;
20339   u8 remote_mac[6];
20340   u8 mac_set = 0;
20341   int ret;
20342
20343   clib_memset (remote_mac, 0, sizeof (remote_mac));
20344   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20345     {
20346       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
20347         ;
20348       else if (unformat (i, "sw_if_index %d", &parent_if_index))
20349         ;
20350       else
20351         if (unformat
20352             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
20353         mac_set++;
20354       else
20355         {
20356           clib_warning ("parse error '%U'", format_unformat_error, i);
20357           return -99;
20358         }
20359     }
20360
20361   if (parent_if_index == ~0)
20362     {
20363       errmsg ("missing interface name or sw_if_index");
20364       return -99;
20365     }
20366   if (mac_set == 0)
20367     {
20368       errmsg ("missing remote mac address");
20369       return -99;
20370     }
20371
20372   M (P2P_ETHERNET_DEL, mp);
20373   mp->parent_if_index = ntohl (parent_if_index);
20374   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
20375
20376   S (mp);
20377   W (ret);
20378   return ret;
20379 }
20380
20381 static int
20382 api_lldp_config (vat_main_t * vam)
20383 {
20384   unformat_input_t *i = vam->input;
20385   vl_api_lldp_config_t *mp;
20386   int tx_hold = 0;
20387   int tx_interval = 0;
20388   u8 *sys_name = NULL;
20389   int ret;
20390
20391   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20392     {
20393       if (unformat (i, "system-name %s", &sys_name))
20394         ;
20395       else if (unformat (i, "tx-hold %d", &tx_hold))
20396         ;
20397       else if (unformat (i, "tx-interval %d", &tx_interval))
20398         ;
20399       else
20400         {
20401           clib_warning ("parse error '%U'", format_unformat_error, i);
20402           return -99;
20403         }
20404     }
20405
20406   vec_add1 (sys_name, 0);
20407
20408   M (LLDP_CONFIG, mp);
20409   mp->tx_hold = htonl (tx_hold);
20410   mp->tx_interval = htonl (tx_interval);
20411   clib_memcpy (mp->system_name, sys_name, vec_len (sys_name));
20412   vec_free (sys_name);
20413
20414   S (mp);
20415   W (ret);
20416   return ret;
20417 }
20418
20419 static int
20420 api_sw_interface_set_lldp (vat_main_t * vam)
20421 {
20422   unformat_input_t *i = vam->input;
20423   vl_api_sw_interface_set_lldp_t *mp;
20424   u32 sw_if_index = ~0;
20425   u32 enable = 1;
20426   u8 *port_desc = NULL, *mgmt_oid = NULL;
20427   ip4_address_t ip4_addr;
20428   ip6_address_t ip6_addr;
20429   int ret;
20430
20431   clib_memset (&ip4_addr, 0, sizeof (ip4_addr));
20432   clib_memset (&ip6_addr, 0, sizeof (ip6_addr));
20433
20434   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20435     {
20436       if (unformat (i, "disable"))
20437         enable = 0;
20438       else
20439         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20440         ;
20441       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20442         ;
20443       else if (unformat (i, "port-desc %s", &port_desc))
20444         ;
20445       else if (unformat (i, "mgmt-ip4 %U", unformat_ip4_address, &ip4_addr))
20446         ;
20447       else if (unformat (i, "mgmt-ip6 %U", unformat_ip6_address, &ip6_addr))
20448         ;
20449       else if (unformat (i, "mgmt-oid %s", &mgmt_oid))
20450         ;
20451       else
20452         break;
20453     }
20454
20455   if (sw_if_index == ~0)
20456     {
20457       errmsg ("missing interface name or sw_if_index");
20458       return -99;
20459     }
20460
20461   /* Construct the API message */
20462   vec_add1 (port_desc, 0);
20463   vec_add1 (mgmt_oid, 0);
20464   M (SW_INTERFACE_SET_LLDP, mp);
20465   mp->sw_if_index = ntohl (sw_if_index);
20466   mp->enable = enable;
20467   clib_memcpy (mp->port_desc, port_desc, vec_len (port_desc));
20468   clib_memcpy (mp->mgmt_oid, mgmt_oid, vec_len (mgmt_oid));
20469   clib_memcpy (mp->mgmt_ip4, &ip4_addr, sizeof (ip4_addr));
20470   clib_memcpy (mp->mgmt_ip6, &ip6_addr, sizeof (ip6_addr));
20471   vec_free (port_desc);
20472   vec_free (mgmt_oid);
20473
20474   S (mp);
20475   W (ret);
20476   return ret;
20477 }
20478
20479 static int
20480 api_tcp_configure_src_addresses (vat_main_t * vam)
20481 {
20482   vl_api_tcp_configure_src_addresses_t *mp;
20483   unformat_input_t *i = vam->input;
20484   ip4_address_t v4first, v4last;
20485   ip6_address_t v6first, v6last;
20486   u8 range_set = 0;
20487   u32 vrf_id = 0;
20488   int ret;
20489
20490   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20491     {
20492       if (unformat (i, "%U - %U",
20493                     unformat_ip4_address, &v4first,
20494                     unformat_ip4_address, &v4last))
20495         {
20496           if (range_set)
20497             {
20498               errmsg ("one range per message (range already set)");
20499               return -99;
20500             }
20501           range_set = 1;
20502         }
20503       else if (unformat (i, "%U - %U",
20504                          unformat_ip6_address, &v6first,
20505                          unformat_ip6_address, &v6last))
20506         {
20507           if (range_set)
20508             {
20509               errmsg ("one range per message (range already set)");
20510               return -99;
20511             }
20512           range_set = 2;
20513         }
20514       else if (unformat (i, "vrf %d", &vrf_id))
20515         ;
20516       else
20517         break;
20518     }
20519
20520   if (range_set == 0)
20521     {
20522       errmsg ("address range not set");
20523       return -99;
20524     }
20525
20526   M (TCP_CONFIGURE_SRC_ADDRESSES, mp);
20527   mp->vrf_id = ntohl (vrf_id);
20528   /* ipv6? */
20529   if (range_set == 2)
20530     {
20531       mp->is_ipv6 = 1;
20532       clib_memcpy (mp->first_address, &v6first, sizeof (v6first));
20533       clib_memcpy (mp->last_address, &v6last, sizeof (v6last));
20534     }
20535   else
20536     {
20537       mp->is_ipv6 = 0;
20538       clib_memcpy (mp->first_address, &v4first, sizeof (v4first));
20539       clib_memcpy (mp->last_address, &v4last, sizeof (v4last));
20540     }
20541   S (mp);
20542   W (ret);
20543   return ret;
20544 }
20545
20546 static void vl_api_app_namespace_add_del_reply_t_handler
20547   (vl_api_app_namespace_add_del_reply_t * mp)
20548 {
20549   vat_main_t *vam = &vat_main;
20550   i32 retval = ntohl (mp->retval);
20551   if (vam->async_mode)
20552     {
20553       vam->async_errors += (retval < 0);
20554     }
20555   else
20556     {
20557       vam->retval = retval;
20558       if (retval == 0)
20559         errmsg ("app ns index %d\n", ntohl (mp->appns_index));
20560       vam->result_ready = 1;
20561     }
20562 }
20563
20564 static void vl_api_app_namespace_add_del_reply_t_handler_json
20565   (vl_api_app_namespace_add_del_reply_t * mp)
20566 {
20567   vat_main_t *vam = &vat_main;
20568   vat_json_node_t node;
20569
20570   vat_json_init_object (&node);
20571   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
20572   vat_json_object_add_uint (&node, "appns_index", ntohl (mp->appns_index));
20573
20574   vat_json_print (vam->ofp, &node);
20575   vat_json_free (&node);
20576
20577   vam->retval = ntohl (mp->retval);
20578   vam->result_ready = 1;
20579 }
20580
20581 static int
20582 api_app_namespace_add_del (vat_main_t * vam)
20583 {
20584   vl_api_app_namespace_add_del_t *mp;
20585   unformat_input_t *i = vam->input;
20586   u8 *ns_id = 0, secret_set = 0, sw_if_index_set = 0;
20587   u32 sw_if_index, ip4_fib_id, ip6_fib_id;
20588   u64 secret;
20589   int ret;
20590
20591   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20592     {
20593       if (unformat (i, "id %_%v%_", &ns_id))
20594         ;
20595       else if (unformat (i, "secret %lu", &secret))
20596         secret_set = 1;
20597       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20598         sw_if_index_set = 1;
20599       else if (unformat (i, "ip4_fib_id %d", &ip4_fib_id))
20600         ;
20601       else if (unformat (i, "ip6_fib_id %d", &ip6_fib_id))
20602         ;
20603       else
20604         break;
20605     }
20606   if (!ns_id || !secret_set || !sw_if_index_set)
20607     {
20608       errmsg ("namespace id, secret and sw_if_index must be set");
20609       return -99;
20610     }
20611   if (vec_len (ns_id) > 64)
20612     {
20613       errmsg ("namespace id too long");
20614       return -99;
20615     }
20616   M (APP_NAMESPACE_ADD_DEL, mp);
20617
20618   clib_memcpy (mp->namespace_id, ns_id, vec_len (ns_id));
20619   mp->namespace_id_len = vec_len (ns_id);
20620   mp->secret = clib_host_to_net_u64 (secret);
20621   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
20622   mp->ip4_fib_id = clib_host_to_net_u32 (ip4_fib_id);
20623   mp->ip6_fib_id = clib_host_to_net_u32 (ip6_fib_id);
20624   vec_free (ns_id);
20625   S (mp);
20626   W (ret);
20627   return ret;
20628 }
20629
20630 static int
20631 api_sock_init_shm (vat_main_t * vam)
20632 {
20633 #if VPP_API_TEST_BUILTIN == 0
20634   unformat_input_t *i = vam->input;
20635   vl_api_shm_elem_config_t *config = 0;
20636   u64 size = 64 << 20;
20637   int rv;
20638
20639   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20640     {
20641       if (unformat (i, "size %U", unformat_memory_size, &size))
20642         ;
20643       else
20644         break;
20645     }
20646
20647   /*
20648    * Canned custom ring allocator config.
20649    * Should probably parse all of this
20650    */
20651   vec_validate (config, 6);
20652   config[0].type = VL_API_VLIB_RING;
20653   config[0].size = 256;
20654   config[0].count = 32;
20655
20656   config[1].type = VL_API_VLIB_RING;
20657   config[1].size = 1024;
20658   config[1].count = 16;
20659
20660   config[2].type = VL_API_VLIB_RING;
20661   config[2].size = 4096;
20662   config[2].count = 2;
20663
20664   config[3].type = VL_API_CLIENT_RING;
20665   config[3].size = 256;
20666   config[3].count = 32;
20667
20668   config[4].type = VL_API_CLIENT_RING;
20669   config[4].size = 1024;
20670   config[4].count = 16;
20671
20672   config[5].type = VL_API_CLIENT_RING;
20673   config[5].size = 4096;
20674   config[5].count = 2;
20675
20676   config[6].type = VL_API_QUEUE;
20677   config[6].count = 128;
20678   config[6].size = sizeof (uword);
20679
20680   rv = vl_socket_client_init_shm (config, 1 /* want_pthread */ );
20681   if (!rv)
20682     vam->client_index_invalid = 1;
20683   return rv;
20684 #else
20685   return -99;
20686 #endif
20687 }
20688
20689 static void
20690 vl_api_session_rules_details_t_handler (vl_api_session_rules_details_t * mp)
20691 {
20692   vat_main_t *vam = &vat_main;
20693
20694   if (mp->is_ip4)
20695     {
20696       print (vam->ofp,
20697              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
20698              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
20699              mp->scope, format_ip4_address, &mp->lcl_ip, mp->lcl_plen,
20700              clib_net_to_host_u16 (mp->lcl_port), format_ip4_address,
20701              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
20702              clib_net_to_host_u32 (mp->action_index), mp->tag);
20703     }
20704   else
20705     {
20706       print (vam->ofp,
20707              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
20708              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
20709              mp->scope, format_ip6_address, &mp->lcl_ip, mp->lcl_plen,
20710              clib_net_to_host_u16 (mp->lcl_port), format_ip6_address,
20711              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
20712              clib_net_to_host_u32 (mp->action_index), mp->tag);
20713     }
20714 }
20715
20716 static void
20717 vl_api_session_rules_details_t_handler_json (vl_api_session_rules_details_t *
20718                                              mp)
20719 {
20720   vat_main_t *vam = &vat_main;
20721   vat_json_node_t *node = NULL;
20722   struct in6_addr ip6;
20723   struct in_addr ip4;
20724
20725   if (VAT_JSON_ARRAY != vam->json_tree.type)
20726     {
20727       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20728       vat_json_init_array (&vam->json_tree);
20729     }
20730   node = vat_json_array_add (&vam->json_tree);
20731   vat_json_init_object (node);
20732
20733   vat_json_object_add_uint (node, "is_ip4", mp->is_ip4 ? 1 : 0);
20734   vat_json_object_add_uint (node, "appns_index",
20735                             clib_net_to_host_u32 (mp->appns_index));
20736   vat_json_object_add_uint (node, "transport_proto", mp->transport_proto);
20737   vat_json_object_add_uint (node, "scope", mp->scope);
20738   vat_json_object_add_uint (node, "action_index",
20739                             clib_net_to_host_u32 (mp->action_index));
20740   vat_json_object_add_uint (node, "lcl_port",
20741                             clib_net_to_host_u16 (mp->lcl_port));
20742   vat_json_object_add_uint (node, "rmt_port",
20743                             clib_net_to_host_u16 (mp->rmt_port));
20744   vat_json_object_add_uint (node, "lcl_plen", mp->lcl_plen);
20745   vat_json_object_add_uint (node, "rmt_plen", mp->rmt_plen);
20746   vat_json_object_add_string_copy (node, "tag", mp->tag);
20747   if (mp->is_ip4)
20748     {
20749       clib_memcpy (&ip4, mp->lcl_ip, sizeof (ip4));
20750       vat_json_object_add_ip4 (node, "lcl_ip", ip4);
20751       clib_memcpy (&ip4, mp->rmt_ip, sizeof (ip4));
20752       vat_json_object_add_ip4 (node, "rmt_ip", ip4);
20753     }
20754   else
20755     {
20756       clib_memcpy (&ip6, mp->lcl_ip, sizeof (ip6));
20757       vat_json_object_add_ip6 (node, "lcl_ip", ip6);
20758       clib_memcpy (&ip6, mp->rmt_ip, sizeof (ip6));
20759       vat_json_object_add_ip6 (node, "rmt_ip", ip6);
20760     }
20761 }
20762
20763 static int
20764 api_session_rule_add_del (vat_main_t * vam)
20765 {
20766   vl_api_session_rule_add_del_t *mp;
20767   unformat_input_t *i = vam->input;
20768   u32 proto = ~0, lcl_port, rmt_port, action = 0, lcl_plen, rmt_plen;
20769   u32 appns_index = 0, scope = 0;
20770   ip4_address_t lcl_ip4, rmt_ip4;
20771   ip6_address_t lcl_ip6, rmt_ip6;
20772   u8 is_ip4 = 1, conn_set = 0;
20773   u8 is_add = 1, *tag = 0;
20774   int ret;
20775
20776   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20777     {
20778       if (unformat (i, "del"))
20779         is_add = 0;
20780       else if (unformat (i, "add"))
20781         ;
20782       else if (unformat (i, "proto tcp"))
20783         proto = 0;
20784       else if (unformat (i, "proto udp"))
20785         proto = 1;
20786       else if (unformat (i, "appns %d", &appns_index))
20787         ;
20788       else if (unformat (i, "scope %d", &scope))
20789         ;
20790       else if (unformat (i, "tag %_%v%_", &tag))
20791         ;
20792       else
20793         if (unformat
20794             (i, "%U/%d %d %U/%d %d", unformat_ip4_address, &lcl_ip4,
20795              &lcl_plen, &lcl_port, unformat_ip4_address, &rmt_ip4, &rmt_plen,
20796              &rmt_port))
20797         {
20798           is_ip4 = 1;
20799           conn_set = 1;
20800         }
20801       else
20802         if (unformat
20803             (i, "%U/%d %d %U/%d %d", unformat_ip6_address, &lcl_ip6,
20804              &lcl_plen, &lcl_port, unformat_ip6_address, &rmt_ip6, &rmt_plen,
20805              &rmt_port))
20806         {
20807           is_ip4 = 0;
20808           conn_set = 1;
20809         }
20810       else if (unformat (i, "action %d", &action))
20811         ;
20812       else
20813         break;
20814     }
20815   if (proto == ~0 || !conn_set || action == ~0)
20816     {
20817       errmsg ("transport proto, connection and action must be set");
20818       return -99;
20819     }
20820
20821   if (scope > 3)
20822     {
20823       errmsg ("scope should be 0-3");
20824       return -99;
20825     }
20826
20827   M (SESSION_RULE_ADD_DEL, mp);
20828
20829   mp->is_ip4 = is_ip4;
20830   mp->transport_proto = proto;
20831   mp->lcl_port = clib_host_to_net_u16 ((u16) lcl_port);
20832   mp->rmt_port = clib_host_to_net_u16 ((u16) rmt_port);
20833   mp->lcl_plen = lcl_plen;
20834   mp->rmt_plen = rmt_plen;
20835   mp->action_index = clib_host_to_net_u32 (action);
20836   mp->appns_index = clib_host_to_net_u32 (appns_index);
20837   mp->scope = scope;
20838   mp->is_add = is_add;
20839   if (is_ip4)
20840     {
20841       clib_memcpy (mp->lcl_ip, &lcl_ip4, sizeof (lcl_ip4));
20842       clib_memcpy (mp->rmt_ip, &rmt_ip4, sizeof (rmt_ip4));
20843     }
20844   else
20845     {
20846       clib_memcpy (mp->lcl_ip, &lcl_ip6, sizeof (lcl_ip6));
20847       clib_memcpy (mp->rmt_ip, &rmt_ip6, sizeof (rmt_ip6));
20848     }
20849   if (tag)
20850     {
20851       clib_memcpy (mp->tag, tag, vec_len (tag));
20852       vec_free (tag);
20853     }
20854
20855   S (mp);
20856   W (ret);
20857   return ret;
20858 }
20859
20860 static int
20861 api_session_rules_dump (vat_main_t * vam)
20862 {
20863   vl_api_session_rules_dump_t *mp;
20864   vl_api_control_ping_t *mp_ping;
20865   int ret;
20866
20867   if (!vam->json_output)
20868     {
20869       print (vam->ofp, "%=20s", "Session Rules");
20870     }
20871
20872   M (SESSION_RULES_DUMP, mp);
20873   /* send it... */
20874   S (mp);
20875
20876   /* Use a control ping for synchronization */
20877   MPING (CONTROL_PING, mp_ping);
20878   S (mp_ping);
20879
20880   /* Wait for a reply... */
20881   W (ret);
20882   return ret;
20883 }
20884
20885 static int
20886 api_ip_container_proxy_add_del (vat_main_t * vam)
20887 {
20888   vl_api_ip_container_proxy_add_del_t *mp;
20889   unformat_input_t *i = vam->input;
20890   u32 sw_if_index = ~0;
20891   vl_api_prefix_t pfx = { };
20892   u8 is_add = 1;
20893   int ret;
20894
20895   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20896     {
20897       if (unformat (i, "del"))
20898         is_add = 0;
20899       else if (unformat (i, "add"))
20900         ;
20901       if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
20902         ;
20903       else if (unformat (i, "sw_if_index %u", &sw_if_index))
20904         ;
20905       else
20906         break;
20907     }
20908   if (sw_if_index == ~0 || pfx.len == 0)
20909     {
20910       errmsg ("address and sw_if_index must be set");
20911       return -99;
20912     }
20913
20914   M (IP_CONTAINER_PROXY_ADD_DEL, mp);
20915
20916   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
20917   mp->is_add = is_add;
20918   clib_memcpy (&mp->pfx, &pfx, sizeof (pfx));
20919
20920   S (mp);
20921   W (ret);
20922   return ret;
20923 }
20924
20925 static int
20926 api_qos_record_enable_disable (vat_main_t * vam)
20927 {
20928   unformat_input_t *i = vam->input;
20929   vl_api_qos_record_enable_disable_t *mp;
20930   u32 sw_if_index, qs = 0xff;
20931   u8 sw_if_index_set = 0;
20932   u8 enable = 1;
20933   int ret;
20934
20935   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20936     {
20937       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20938         sw_if_index_set = 1;
20939       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20940         sw_if_index_set = 1;
20941       else if (unformat (i, "%U", unformat_qos_source, &qs))
20942         ;
20943       else if (unformat (i, "disable"))
20944         enable = 0;
20945       else
20946         {
20947           clib_warning ("parse error '%U'", format_unformat_error, i);
20948           return -99;
20949         }
20950     }
20951
20952   if (sw_if_index_set == 0)
20953     {
20954       errmsg ("missing interface name or sw_if_index");
20955       return -99;
20956     }
20957   if (qs == 0xff)
20958     {
20959       errmsg ("input location must be specified");
20960       return -99;
20961     }
20962
20963   M (QOS_RECORD_ENABLE_DISABLE, mp);
20964
20965   mp->record.sw_if_index = ntohl (sw_if_index);
20966   mp->record.input_source = qs;
20967   mp->enable = enable;
20968
20969   S (mp);
20970   W (ret);
20971   return ret;
20972 }
20973
20974
20975 static int
20976 q_or_quit (vat_main_t * vam)
20977 {
20978 #if VPP_API_TEST_BUILTIN == 0
20979   longjmp (vam->jump_buf, 1);
20980 #endif
20981   return 0;                     /* not so much */
20982 }
20983
20984 static int
20985 q (vat_main_t * vam)
20986 {
20987   return q_or_quit (vam);
20988 }
20989
20990 static int
20991 quit (vat_main_t * vam)
20992 {
20993   return q_or_quit (vam);
20994 }
20995
20996 static int
20997 comment (vat_main_t * vam)
20998 {
20999   return 0;
21000 }
21001
21002 static int
21003 elog_save (vat_main_t * vam)
21004 {
21005 #if VPP_API_TEST_BUILTIN == 0
21006   elog_main_t *em = &vam->elog_main;
21007   unformat_input_t *i = vam->input;
21008   char *file, *chroot_file;
21009   clib_error_t *error;
21010
21011   if (!unformat (i, "%s", &file))
21012     {
21013       errmsg ("expected file name, got `%U'", format_unformat_error, i);
21014       return 0;
21015     }
21016
21017   /* It's fairly hard to get "../oopsie" through unformat; just in case */
21018   if (strstr (file, "..") || index (file, '/'))
21019     {
21020       errmsg ("illegal characters in filename '%s'", file);
21021       return 0;
21022     }
21023
21024   chroot_file = (char *) format (0, "/tmp/%s%c", file, 0);
21025
21026   vec_free (file);
21027
21028   errmsg ("Saving %wd of %wd events to %s",
21029           elog_n_events_in_buffer (em),
21030           elog_buffer_capacity (em), chroot_file);
21031
21032   error = elog_write_file (em, chroot_file, 1 /* flush ring */ );
21033   vec_free (chroot_file);
21034
21035   if (error)
21036     clib_error_report (error);
21037 #else
21038   errmsg ("Use the vpp event loger...");
21039 #endif
21040
21041   return 0;
21042 }
21043
21044 static int
21045 elog_setup (vat_main_t * vam)
21046 {
21047 #if VPP_API_TEST_BUILTIN == 0
21048   elog_main_t *em = &vam->elog_main;
21049   unformat_input_t *i = vam->input;
21050   u32 nevents = 128 << 10;
21051
21052   (void) unformat (i, "nevents %d", &nevents);
21053
21054   elog_init (em, nevents);
21055   vl_api_set_elog_main (em);
21056   vl_api_set_elog_trace_api_messages (1);
21057   errmsg ("Event logger initialized with %u events", nevents);
21058 #else
21059   errmsg ("Use the vpp event loger...");
21060 #endif
21061   return 0;
21062 }
21063
21064 static int
21065 elog_enable (vat_main_t * vam)
21066 {
21067 #if VPP_API_TEST_BUILTIN == 0
21068   elog_main_t *em = &vam->elog_main;
21069
21070   elog_enable_disable (em, 1 /* enable */ );
21071   vl_api_set_elog_trace_api_messages (1);
21072   errmsg ("Event logger enabled...");
21073 #else
21074   errmsg ("Use the vpp event loger...");
21075 #endif
21076   return 0;
21077 }
21078
21079 static int
21080 elog_disable (vat_main_t * vam)
21081 {
21082 #if VPP_API_TEST_BUILTIN == 0
21083   elog_main_t *em = &vam->elog_main;
21084
21085   elog_enable_disable (em, 0 /* enable */ );
21086   vl_api_set_elog_trace_api_messages (1);
21087   errmsg ("Event logger disabled...");
21088 #else
21089   errmsg ("Use the vpp event loger...");
21090 #endif
21091   return 0;
21092 }
21093
21094 static int
21095 statseg (vat_main_t * vam)
21096 {
21097   ssvm_private_t *ssvmp = &vam->stat_segment;
21098   ssvm_shared_header_t *shared_header = ssvmp->sh;
21099   vlib_counter_t **counters;
21100   u64 thread0_index1_packets;
21101   u64 thread0_index1_bytes;
21102   f64 vector_rate, input_rate;
21103   uword *p;
21104
21105   uword *counter_vector_by_name;
21106   if (vam->stat_segment_lockp == 0)
21107     {
21108       errmsg ("Stat segment not mapped...");
21109       return -99;
21110     }
21111
21112   /* look up "/if/rx for sw_if_index 1 as a test */
21113
21114   clib_spinlock_lock (vam->stat_segment_lockp);
21115
21116   counter_vector_by_name = (uword *) shared_header->opaque[1];
21117
21118   p = hash_get_mem (counter_vector_by_name, "/if/rx");
21119   if (p == 0)
21120     {
21121       clib_spinlock_unlock (vam->stat_segment_lockp);
21122       errmsg ("/if/tx not found?");
21123       return -99;
21124     }
21125
21126   /* Fish per-thread vector of combined counters from shared memory */
21127   counters = (vlib_counter_t **) p[0];
21128
21129   if (vec_len (counters[0]) < 2)
21130     {
21131       clib_spinlock_unlock (vam->stat_segment_lockp);
21132       errmsg ("/if/tx vector length %d", vec_len (counters[0]));
21133       return -99;
21134     }
21135
21136   /* Read thread 0 sw_if_index 1 counter */
21137   thread0_index1_packets = counters[0][1].packets;
21138   thread0_index1_bytes = counters[0][1].bytes;
21139
21140   p = hash_get_mem (counter_vector_by_name, "vector_rate");
21141   if (p == 0)
21142     {
21143       clib_spinlock_unlock (vam->stat_segment_lockp);
21144       errmsg ("vector_rate not found?");
21145       return -99;
21146     }
21147
21148   vector_rate = *(f64 *) (p[0]);
21149   p = hash_get_mem (counter_vector_by_name, "input_rate");
21150   if (p == 0)
21151     {
21152       clib_spinlock_unlock (vam->stat_segment_lockp);
21153       errmsg ("input_rate not found?");
21154       return -99;
21155     }
21156   input_rate = *(f64 *) (p[0]);
21157
21158   clib_spinlock_unlock (vam->stat_segment_lockp);
21159
21160   print (vam->ofp, "vector_rate %.2f input_rate %.2f",
21161          vector_rate, input_rate);
21162   print (vam->ofp, "thread 0 sw_if_index 1 rx pkts %lld, bytes %lld",
21163          thread0_index1_packets, thread0_index1_bytes);
21164
21165   return 0;
21166 }
21167
21168 static int
21169 cmd_cmp (void *a1, void *a2)
21170 {
21171   u8 **c1 = a1;
21172   u8 **c2 = a2;
21173
21174   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
21175 }
21176
21177 static int
21178 help (vat_main_t * vam)
21179 {
21180   u8 **cmds = 0;
21181   u8 *name = 0;
21182   hash_pair_t *p;
21183   unformat_input_t *i = vam->input;
21184   int j;
21185
21186   if (unformat (i, "%s", &name))
21187     {
21188       uword *hs;
21189
21190       vec_add1 (name, 0);
21191
21192       hs = hash_get_mem (vam->help_by_name, name);
21193       if (hs)
21194         print (vam->ofp, "usage: %s %s", name, hs[0]);
21195       else
21196         print (vam->ofp, "No such msg / command '%s'", name);
21197       vec_free (name);
21198       return 0;
21199     }
21200
21201   print (vam->ofp, "Help is available for the following:");
21202
21203     /* *INDENT-OFF* */
21204     hash_foreach_pair (p, vam->function_by_name,
21205     ({
21206       vec_add1 (cmds, (u8 *)(p->key));
21207     }));
21208     /* *INDENT-ON* */
21209
21210   vec_sort_with_function (cmds, cmd_cmp);
21211
21212   for (j = 0; j < vec_len (cmds); j++)
21213     print (vam->ofp, "%s", cmds[j]);
21214
21215   vec_free (cmds);
21216   return 0;
21217 }
21218
21219 static int
21220 set (vat_main_t * vam)
21221 {
21222   u8 *name = 0, *value = 0;
21223   unformat_input_t *i = vam->input;
21224
21225   if (unformat (i, "%s", &name))
21226     {
21227       /* The input buffer is a vector, not a string. */
21228       value = vec_dup (i->buffer);
21229       vec_delete (value, i->index, 0);
21230       /* Almost certainly has a trailing newline */
21231       if (value[vec_len (value) - 1] == '\n')
21232         value[vec_len (value) - 1] = 0;
21233       /* Make sure it's a proper string, one way or the other */
21234       vec_add1 (value, 0);
21235       (void) clib_macro_set_value (&vam->macro_main,
21236                                    (char *) name, (char *) value);
21237     }
21238   else
21239     errmsg ("usage: set <name> <value>");
21240
21241   vec_free (name);
21242   vec_free (value);
21243   return 0;
21244 }
21245
21246 static int
21247 unset (vat_main_t * vam)
21248 {
21249   u8 *name = 0;
21250
21251   if (unformat (vam->input, "%s", &name))
21252     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
21253       errmsg ("unset: %s wasn't set", name);
21254   vec_free (name);
21255   return 0;
21256 }
21257
21258 typedef struct
21259 {
21260   u8 *name;
21261   u8 *value;
21262 } macro_sort_t;
21263
21264
21265 static int
21266 macro_sort_cmp (void *a1, void *a2)
21267 {
21268   macro_sort_t *s1 = a1;
21269   macro_sort_t *s2 = a2;
21270
21271   return strcmp ((char *) (s1->name), (char *) (s2->name));
21272 }
21273
21274 static int
21275 dump_macro_table (vat_main_t * vam)
21276 {
21277   macro_sort_t *sort_me = 0, *sm;
21278   int i;
21279   hash_pair_t *p;
21280
21281     /* *INDENT-OFF* */
21282     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
21283     ({
21284       vec_add2 (sort_me, sm, 1);
21285       sm->name = (u8 *)(p->key);
21286       sm->value = (u8 *) (p->value[0]);
21287     }));
21288     /* *INDENT-ON* */
21289
21290   vec_sort_with_function (sort_me, macro_sort_cmp);
21291
21292   if (vec_len (sort_me))
21293     print (vam->ofp, "%-15s%s", "Name", "Value");
21294   else
21295     print (vam->ofp, "The macro table is empty...");
21296
21297   for (i = 0; i < vec_len (sort_me); i++)
21298     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
21299   return 0;
21300 }
21301
21302 static int
21303 dump_node_table (vat_main_t * vam)
21304 {
21305   int i, j;
21306   vlib_node_t *node, *next_node;
21307
21308   if (vec_len (vam->graph_nodes) == 0)
21309     {
21310       print (vam->ofp, "Node table empty, issue get_node_graph...");
21311       return 0;
21312     }
21313
21314   for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
21315     {
21316       node = vam->graph_nodes[0][i];
21317       print (vam->ofp, "[%d] %s", i, node->name);
21318       for (j = 0; j < vec_len (node->next_nodes); j++)
21319         {
21320           if (node->next_nodes[j] != ~0)
21321             {
21322               next_node = vam->graph_nodes[0][node->next_nodes[j]];
21323               print (vam->ofp, "  [%d] %s", j, next_node->name);
21324             }
21325         }
21326     }
21327   return 0;
21328 }
21329
21330 static int
21331 value_sort_cmp (void *a1, void *a2)
21332 {
21333   name_sort_t *n1 = a1;
21334   name_sort_t *n2 = a2;
21335
21336   if (n1->value < n2->value)
21337     return -1;
21338   if (n1->value > n2->value)
21339     return 1;
21340   return 0;
21341 }
21342
21343
21344 static int
21345 dump_msg_api_table (vat_main_t * vam)
21346 {
21347   api_main_t *am = vlibapi_get_main ();
21348   name_sort_t *nses = 0, *ns;
21349   hash_pair_t *hp;
21350   int i;
21351
21352   /* *INDENT-OFF* */
21353   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
21354   ({
21355     vec_add2 (nses, ns, 1);
21356     ns->name = (u8 *)(hp->key);
21357     ns->value = (u32) hp->value[0];
21358   }));
21359   /* *INDENT-ON* */
21360
21361   vec_sort_with_function (nses, value_sort_cmp);
21362
21363   for (i = 0; i < vec_len (nses); i++)
21364     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
21365   vec_free (nses);
21366   return 0;
21367 }
21368
21369 static int
21370 get_msg_id (vat_main_t * vam)
21371 {
21372   u8 *name_and_crc;
21373   u32 message_index;
21374
21375   if (unformat (vam->input, "%s", &name_and_crc))
21376     {
21377       message_index = vl_msg_api_get_msg_index (name_and_crc);
21378       if (message_index == ~0)
21379         {
21380           print (vam->ofp, " '%s' not found", name_and_crc);
21381           return 0;
21382         }
21383       print (vam->ofp, " '%s' has message index %d",
21384              name_and_crc, message_index);
21385       return 0;
21386     }
21387   errmsg ("name_and_crc required...");
21388   return 0;
21389 }
21390
21391 static int
21392 search_node_table (vat_main_t * vam)
21393 {
21394   unformat_input_t *line_input = vam->input;
21395   u8 *node_to_find;
21396   int j;
21397   vlib_node_t *node, *next_node;
21398   uword *p;
21399
21400   if (vam->graph_node_index_by_name == 0)
21401     {
21402       print (vam->ofp, "Node table empty, issue get_node_graph...");
21403       return 0;
21404     }
21405
21406   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
21407     {
21408       if (unformat (line_input, "%s", &node_to_find))
21409         {
21410           vec_add1 (node_to_find, 0);
21411           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
21412           if (p == 0)
21413             {
21414               print (vam->ofp, "%s not found...", node_to_find);
21415               goto out;
21416             }
21417           node = vam->graph_nodes[0][p[0]];
21418           print (vam->ofp, "[%d] %s", p[0], node->name);
21419           for (j = 0; j < vec_len (node->next_nodes); j++)
21420             {
21421               if (node->next_nodes[j] != ~0)
21422                 {
21423                   next_node = vam->graph_nodes[0][node->next_nodes[j]];
21424                   print (vam->ofp, "  [%d] %s", j, next_node->name);
21425                 }
21426             }
21427         }
21428
21429       else
21430         {
21431           clib_warning ("parse error '%U'", format_unformat_error,
21432                         line_input);
21433           return -99;
21434         }
21435
21436     out:
21437       vec_free (node_to_find);
21438
21439     }
21440
21441   return 0;
21442 }
21443
21444
21445 static int
21446 script (vat_main_t * vam)
21447 {
21448 #if (VPP_API_TEST_BUILTIN==0)
21449   u8 *s = 0;
21450   char *save_current_file;
21451   unformat_input_t save_input;
21452   jmp_buf save_jump_buf;
21453   u32 save_line_number;
21454
21455   FILE *new_fp, *save_ifp;
21456
21457   if (unformat (vam->input, "%s", &s))
21458     {
21459       new_fp = fopen ((char *) s, "r");
21460       if (new_fp == 0)
21461         {
21462           errmsg ("Couldn't open script file %s", s);
21463           vec_free (s);
21464           return -99;
21465         }
21466     }
21467   else
21468     {
21469       errmsg ("Missing script name");
21470       return -99;
21471     }
21472
21473   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
21474   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
21475   save_ifp = vam->ifp;
21476   save_line_number = vam->input_line_number;
21477   save_current_file = (char *) vam->current_file;
21478
21479   vam->input_line_number = 0;
21480   vam->ifp = new_fp;
21481   vam->current_file = s;
21482   do_one_file (vam);
21483
21484   clib_memcpy (&vam->input, &save_input, sizeof (save_input));
21485   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
21486   vam->ifp = save_ifp;
21487   vam->input_line_number = save_line_number;
21488   vam->current_file = (u8 *) save_current_file;
21489   vec_free (s);
21490
21491   return 0;
21492 #else
21493   clib_warning ("use the exec command...");
21494   return -99;
21495 #endif
21496 }
21497
21498 static int
21499 echo (vat_main_t * vam)
21500 {
21501   print (vam->ofp, "%v", vam->input->buffer);
21502   return 0;
21503 }
21504
21505 /* List of API message constructors, CLI names map to api_xxx */
21506 #define foreach_vpe_api_msg                                             \
21507 _(create_loopback,"[mac <mac-addr>] [instance <instance>]")             \
21508 _(sw_interface_dump,"")                                                 \
21509 _(sw_interface_set_flags,                                               \
21510   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
21511 _(sw_interface_add_del_address,                                         \
21512   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
21513 _(sw_interface_set_rx_mode,                                             \
21514   "<intfc> | sw_if_index <id> [queue <id>] <polling | interrupt | adaptive>") \
21515 _(sw_interface_set_rx_placement,                                        \
21516   "<intfc> | sw_if_index <id> [queue <id>] [worker <id> | main]")       \
21517 _(sw_interface_rx_placement_dump,                                       \
21518   "[<intfc> | sw_if_index <id>]")                                         \
21519 _(sw_interface_set_table,                                               \
21520   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
21521 _(sw_interface_set_mpls_enable,                                         \
21522   "<intfc> | sw_if_index [disable | dis]")                              \
21523 _(sw_interface_set_vpath,                                               \
21524   "<intfc> | sw_if_index <id> enable | disable")                        \
21525 _(sw_interface_set_vxlan_bypass,                                        \
21526   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
21527 _(sw_interface_set_geneve_bypass,                                       \
21528   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
21529 _(sw_interface_set_l2_xconnect,                                         \
21530   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
21531   "enable | disable")                                                   \
21532 _(sw_interface_set_l2_bridge,                                           \
21533   "{<intfc> | sw_if_index <id>} bd_id <bridge-domain-id>\n"             \
21534   "[shg <split-horizon-group>] [bvi]\n"                                 \
21535   "enable | disable")                                                   \
21536 _(bridge_domain_set_mac_age, "bd_id <bridge-domain-id> mac-age 0-255")  \
21537 _(bridge_domain_add_del,                                                \
21538   "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") \
21539 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
21540 _(l2fib_add_del,                                                        \
21541   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
21542 _(l2fib_flush_bd, "bd_id <bridge-domain-id>")                           \
21543 _(l2fib_flush_int, "<intfc> | sw_if_index <id>")                        \
21544 _(l2_flags,                                                             \
21545   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
21546 _(bridge_flags,                                                         \
21547   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
21548 _(tap_create_v2,                                                        \
21549   "id <num> [hw-addr <mac-addr>] [host-ns <name>] [rx-ring-size <num> [tx-ring-size <num>] [host-mtu-size <mtu>] [gso | no-gso]") \
21550 _(tap_delete_v2,                                                        \
21551   "<vpp-if-name> | sw_if_index <id>")                                   \
21552 _(sw_interface_tap_v2_dump, "")                                         \
21553 _(virtio_pci_create,                                                    \
21554   "pci-addr <pci-address> [use_random_mac | hw-addr <mac-addr>] [features <hex-value>] [gso-enabled]") \
21555 _(virtio_pci_delete,                                                    \
21556   "<vpp-if-name> | sw_if_index <id>")                                   \
21557 _(sw_interface_virtio_pci_dump, "")                                     \
21558 _(bond_create,                                                          \
21559   "[hw-addr <mac-addr>] {round-robin | active-backup | "                \
21560   "broadcast | {lacp | xor} [load-balance { l2 | l23 | l34 }]} "        \
21561   "[id <if-id>]")                                                       \
21562 _(bond_delete,                                                          \
21563   "<vpp-if-name> | sw_if_index <id>")                                   \
21564 _(bond_enslave,                                                         \
21565   "sw_if_index <n> bond <sw_if_index> [is_passive] [is_long_timeout]")  \
21566 _(bond_detach_slave,                                                    \
21567   "sw_if_index <n>")                                                    \
21568  _(sw_interface_set_bond_weight, "<intfc> | sw_if_index <nn> weight <value>") \
21569 _(sw_interface_bond_dump, "")                                           \
21570 _(sw_interface_slave_dump,                                              \
21571   "<vpp-if-name> | sw_if_index <id>")                                   \
21572 _(ip_table_add_del,                                                     \
21573   "table <n> [ipv6] [add | del]\n")                                     \
21574 _(ip_route_add_del,                                                     \
21575   "<addr>/<mask> via <<addr>|<intfc>|sw_if_index <id>|via-label <n>>\n" \
21576   "[table-id <n>] [<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"\
21577   "[weight <n>] [drop] [local] [classify <n>]  [out-label <n>]\n"       \
21578   "[multipath] [count <n>] [del]")                                      \
21579 _(ip_mroute_add_del,                                                    \
21580   "<src> <grp>/<mask> [table-id <n>]\n"                                 \
21581   "[<intfc> | sw_if_index <id>] [local] [del]")                         \
21582 _(mpls_table_add_del,                                                   \
21583   "table <n> [add | del]\n")                                            \
21584 _(mpls_route_add_del,                                                   \
21585   "<label> <eos> via <addr | next-hop-table <n> | via-label <n> |\n"    \
21586   "lookup-ip4-table <n> | lookup-in-ip6-table <n> |\n"                  \
21587   "l2-input-on <intfc> | l2-input-on sw_if_index <id>>\n"               \
21588   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>] [weight <n>]\n"  \
21589   "[drop] [local] [classify <n>] [out-label <n>] [multipath]\n"         \
21590   "[count <n>] [del]")                                                  \
21591 _(mpls_ip_bind_unbind,                                                  \
21592   "<label> <addr/len>")                                                 \
21593 _(mpls_tunnel_add_del,                                                  \
21594   "[add | del <intfc | sw_if_index <id>>] via <addr | via-label <n>>\n" \
21595   "[<intfc> | sw_if_index <id> | next-hop-table <id>]\n"                \
21596   "[l2-only]  [out-label <n>]")                                         \
21597 _(sr_mpls_policy_add,                                                   \
21598   "bsid <id> [weight <n>] [spray] next <sid> [next <sid>]")             \
21599 _(sr_mpls_policy_del,                                                   \
21600   "bsid <id>")                                                          \
21601 _(bier_table_add_del,                                                   \
21602   "<label> <sub-domain> <set> <bsl> [del]")                             \
21603 _(bier_route_add_del,                                                   \
21604   "<bit-position> <sub-domain> <set> <bsl> via <addr> [table-id <n>]\n" \
21605   "[<intfc> | sw_if_index <id>]"                                        \
21606   "[weight <n>] [del] [multipath]")                                     \
21607 _(proxy_arp_add_del,                                                    \
21608   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
21609 _(proxy_arp_intfc_enable_disable,                                       \
21610   "<intfc> | sw_if_index <id> enable | disable")                        \
21611 _(sw_interface_set_unnumbered,                                          \
21612   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
21613 _(ip_neighbor_add_del,                                                  \
21614   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
21615   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
21616 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
21617 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
21618   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
21619   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
21620   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
21621 _(ip_table_replace_begin, "table <n> [ipv6]")                           \
21622 _(ip_table_flush, "table <n> [ipv6]")                                   \
21623 _(ip_table_replace_end, "table <n> [ipv6]")                             \
21624 _(set_ip_flow_hash,                                                     \
21625   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
21626 _(sw_interface_ip6_enable_disable,                                      \
21627   "<intfc> | sw_if_index <id> enable | disable")                        \
21628 _(ip6nd_proxy_add_del,                                                  \
21629   "<intfc> | sw_if_index <id> <ip6-address>")                           \
21630 _(ip6nd_proxy_dump, "")                                                 \
21631 _(sw_interface_ip6nd_ra_prefix,                                         \
21632   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
21633   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
21634   "[nolink] [isno]")                                                    \
21635 _(sw_interface_ip6nd_ra_config,                                         \
21636   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
21637   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
21638   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
21639 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
21640 _(l2_patch_add_del,                                                     \
21641   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
21642   "enable | disable")                                                   \
21643 _(sr_localsid_add_del,                                                  \
21644   "(del) address <addr> next_hop <addr> behavior <beh>\n"               \
21645   "fib-table <num> (end.psp) sw_if_index <num>")                        \
21646 _(classify_add_del_table,                                               \
21647   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
21648   " [del] [del-chain] mask <mask-value>\n"                              \
21649   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
21650   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
21651 _(classify_add_del_session,                                             \
21652   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
21653   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
21654   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
21655   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
21656 _(classify_set_interface_ip_table,                                      \
21657   "<intfc> | sw_if_index <nn> table <nn>")                              \
21658 _(classify_set_interface_l2_tables,                                     \
21659   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
21660   "  [other-table <nn>]")                                               \
21661 _(get_node_index, "node <node-name")                                    \
21662 _(add_node_next, "node <node-name> next <next-node-name>")              \
21663 _(l2tpv3_create_tunnel,                                                 \
21664   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
21665   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
21666   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
21667 _(l2tpv3_set_tunnel_cookies,                                            \
21668   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
21669   "[new_remote_cookie <nn>]\n")                                         \
21670 _(l2tpv3_interface_enable_disable,                                      \
21671   "<intfc> | sw_if_index <nn> enable | disable")                        \
21672 _(l2tpv3_set_lookup_key,                                                \
21673   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
21674 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
21675 _(vxlan_offload_rx,                                                     \
21676   "hw { <interface name> | hw_if_index <nn>} "                          \
21677   "rx { <vxlan tunnel name> | sw_if_index <nn> } [del]")                \
21678 _(vxlan_add_del_tunnel,                                                 \
21679   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
21680   "{ <intfc> | mcast_sw_if_index <nn> } [instance <id>]}\n"             \
21681   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
21682 _(geneve_add_del_tunnel,                                                \
21683   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
21684   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
21685   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
21686 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
21687 _(geneve_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                   \
21688 _(gre_tunnel_add_del,                                                   \
21689   "src <ip-addr> dst <ip-addr> [outer-fib-id <nn>] [instance <n>]\n"    \
21690   "[teb | erspan <session-id>] [del]")                                  \
21691 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
21692 _(l2_fib_clear_table, "")                                               \
21693 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
21694 _(l2_interface_vlan_tag_rewrite,                                        \
21695   "<intfc> | sw_if_index <nn> \n"                                       \
21696   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
21697   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
21698 _(create_vhost_user_if,                                                 \
21699         "socket <filename> [server] [renumber <dev_instance>] "         \
21700         "[disable_mrg_rxbuf] [disable_indirect_desc] [gso] "            \
21701         "[mac <mac_address>]")                                          \
21702 _(modify_vhost_user_if,                                                 \
21703         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
21704         "[server] [renumber <dev_instance>] [gso]")                     \
21705 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
21706 _(sw_interface_vhost_user_dump, "")                                     \
21707 _(show_version, "")                                                     \
21708 _(show_threads, "")                                                     \
21709 _(vxlan_gpe_add_del_tunnel,                                             \
21710   "local <addr> remote <addr>  | group <mcast-ip-addr>\n"               \
21711   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
21712   "vni <nn> [encap-vrf-id <nn>] [decap-vrf-id <nn>]\n"                  \
21713   "[next-ip4][next-ip6][next-ethernet] [next-nsh] [del]\n")             \
21714 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
21715 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
21716 _(interface_name_renumber,                                              \
21717   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
21718 _(input_acl_set_interface,                                              \
21719   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
21720   "  [l2-table <nn>] [del]")                                            \
21721 _(ip_probe_neighbor, "(<intc> | sw_if_index <nn>) address <ip4|ip6-addr>") \
21722 _(ip_scan_neighbor_enable_disable, "[ip4|ip6|both|disable] [interval <n-min>]\n" \
21723   "  [max-time <n-usec>] [max-update <n>] [delay <n-msec>] [stale <n-min>]") \
21724 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
21725 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
21726 _(want_l2_macs_events, "[disable] [learn-limit <n>] [scan-delay <n>] [max-entries <n>]") \
21727 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
21728 _(ip_dump, "ipv4 | ipv6")                                               \
21729 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
21730 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
21731   "  spid_id <n> ")                                                     \
21732 _(ipsec_sad_entry_add_del, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
21733   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
21734   "  integ_alg <alg> integ_key <hex>")                                  \
21735 _(ipsec_spd_entry_add_del, "spd_id <n> priority <n> action <action>\n"  \
21736   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
21737   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
21738   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
21739 _(ipsec_tunnel_if_add_del, "local_spi <n> remote_spi <n>\n"             \
21740   "  crypto_alg <alg> local_crypto_key <hex> remote_crypto_key <hex>\n" \
21741   "  integ_alg <alg> local_integ_key <hex> remote_integ_key <hex>\n"    \
21742   "  local_ip <addr> remote_ip <addr> [esn] [anti_replay] [del]\n"      \
21743   "  [instance <n>]")     \
21744 _(ipsec_sa_dump, "[sa_id <n>]")                                         \
21745 _(ipsec_tunnel_if_set_sa, "<intfc> sa_id <n> <inbound|outbound>\n")     \
21746 _(delete_loopback,"sw_if_index <nn>")                                   \
21747 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
21748 _(bd_ip_mac_flush, "bd_id <bridge-domain-id>")                          \
21749 _(bd_ip_mac_dump, "[bd_id] <bridge-domain-id>")                         \
21750 _(want_interface_events,  "enable|disable")                             \
21751 _(get_first_msg_id, "client <name>")                                    \
21752 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
21753 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
21754   "fib-id <nn> [ip4][ip6][default]")                                    \
21755 _(get_node_graph, " ")                                                  \
21756 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
21757 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
21758 _(ioam_disable, "")                                                     \
21759 _(one_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
21760                             " sw_if_index <sw_if_index> p <priority> "  \
21761                             "w <weight>] [del]")                        \
21762 _(one_add_del_locator, "locator-set <locator_name> "                    \
21763                         "iface <intf> | sw_if_index <sw_if_index> "     \
21764                         "p <priority> w <weight> [del]")                \
21765 _(one_add_del_local_eid,"vni <vni> eid "                                \
21766                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
21767                          "locator-set <locator_name> [del]"             \
21768                          "[key-id sha1|sha256 secret-key <secret-key>]")\
21769 _(one_add_del_map_resolver, "<ip4|6-addr> [del]")                       \
21770 _(one_add_del_map_server, "<ip4|6-addr> [del]")                         \
21771 _(one_enable_disable, "enable|disable")                                 \
21772 _(one_map_register_enable_disable, "enable|disable")                    \
21773 _(one_map_register_fallback_threshold, "<value>")                       \
21774 _(one_rloc_probe_enable_disable, "enable|disable")                      \
21775 _(one_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "       \
21776                                "[seid <seid>] "                         \
21777                                "rloc <locator> p <prio> "               \
21778                                "w <weight> [rloc <loc> ... ] "          \
21779                                "action <action> [del-all]")             \
21780 _(one_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "    \
21781                           "<local-eid>")                                \
21782 _(one_pitr_set_locator_set, "locator-set <loc-set-name> | del")         \
21783 _(one_use_petr, "ip-address> | disable")                                \
21784 _(one_map_request_mode, "src-dst|dst-only")                             \
21785 _(one_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")            \
21786 _(one_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")               \
21787 _(one_locator_set_dump, "[local | remote]")                             \
21788 _(one_locator_dump, "ls_index <index> | ls_name <name>")                \
21789 _(one_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "       \
21790                        "[local] | [remote]")                            \
21791 _(one_add_del_ndp_entry, "[del] mac <mac> bd <bd> ip6 <ip6>")           \
21792 _(one_ndp_bd_get, "")                                                   \
21793 _(one_ndp_entries_get, "bd <bridge-domain>")                            \
21794 _(one_add_del_l2_arp_entry, "[del] mac <mac> bd <bd> ip4 <ip4>")        \
21795 _(one_l2_arp_bd_get, "")                                                \
21796 _(one_l2_arp_entries_get, "bd <bridge-domain>")                         \
21797 _(one_stats_enable_disable, "enable|disable")                           \
21798 _(show_one_stats_enable_disable, "")                                    \
21799 _(one_eid_table_vni_dump, "")                                           \
21800 _(one_eid_table_map_dump, "l2|l3")                                      \
21801 _(one_map_resolver_dump, "")                                            \
21802 _(one_map_server_dump, "")                                              \
21803 _(one_adjacencies_get, "vni <vni>")                                     \
21804 _(one_nsh_set_locator_set, "[del] ls <locator-set-name>")               \
21805 _(show_one_rloc_probe_state, "")                                        \
21806 _(show_one_map_register_state, "")                                      \
21807 _(show_one_status, "")                                                  \
21808 _(one_stats_dump, "")                                                   \
21809 _(one_stats_flush, "")                                                  \
21810 _(one_get_map_request_itr_rlocs, "")                                    \
21811 _(one_map_register_set_ttl, "<ttl>")                                    \
21812 _(one_set_transport_protocol, "udp|api")                                \
21813 _(one_get_transport_protocol, "")                                       \
21814 _(one_enable_disable_xtr_mode, "enable|disable")                        \
21815 _(one_show_xtr_mode, "")                                                \
21816 _(one_enable_disable_pitr_mode, "enable|disable")                       \
21817 _(one_show_pitr_mode, "")                                               \
21818 _(one_enable_disable_petr_mode, "enable|disable")                       \
21819 _(one_show_petr_mode, "")                                               \
21820 _(show_one_nsh_mapping, "")                                             \
21821 _(show_one_pitr, "")                                                    \
21822 _(show_one_use_petr, "")                                                \
21823 _(show_one_map_request_mode, "")                                        \
21824 _(show_one_map_register_ttl, "")                                        \
21825 _(show_one_map_register_fallback_threshold, "")                         \
21826 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
21827                             " sw_if_index <sw_if_index> p <priority> "  \
21828                             "w <weight>] [del]")                        \
21829 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
21830                         "iface <intf> | sw_if_index <sw_if_index> "     \
21831                         "p <priority> w <weight> [del]")                \
21832 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
21833                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
21834                          "locator-set <locator_name> [del]"             \
21835                          "[key-id sha1|sha256 secret-key <secret-key>]") \
21836 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
21837 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
21838 _(lisp_enable_disable, "enable|disable")                                \
21839 _(lisp_map_register_enable_disable, "enable|disable")                   \
21840 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
21841 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
21842                                "[seid <seid>] "                         \
21843                                "rloc <locator> p <prio> "               \
21844                                "w <weight> [rloc <loc> ... ] "          \
21845                                "action <action> [del-all]")             \
21846 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
21847                           "<local-eid>")                                \
21848 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
21849 _(lisp_use_petr, "<ip-address> | disable")                              \
21850 _(lisp_map_request_mode, "src-dst|dst-only")                            \
21851 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
21852 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
21853 _(lisp_locator_set_dump, "[local | remote]")                            \
21854 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
21855 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
21856                        "[local] | [remote]")                            \
21857 _(lisp_eid_table_vni_dump, "")                                          \
21858 _(lisp_eid_table_map_dump, "l2|l3")                                     \
21859 _(lisp_map_resolver_dump, "")                                           \
21860 _(lisp_map_server_dump, "")                                             \
21861 _(lisp_adjacencies_get, "vni <vni>")                                    \
21862 _(gpe_fwd_entry_vnis_get, "")                                           \
21863 _(gpe_native_fwd_rpaths_get, "ip4 | ip6")                               \
21864 _(gpe_add_del_native_fwd_rpath, "[del] via <nh-ip-addr> [iface] "       \
21865                                 "[table <table-id>]")                   \
21866 _(lisp_gpe_fwd_entries_get, "vni <vni>")                                \
21867 _(lisp_gpe_fwd_entry_path_dump, "index <fwd_entry_index>")              \
21868 _(gpe_set_encap_mode, "lisp|vxlan")                                     \
21869 _(gpe_get_encap_mode, "")                                               \
21870 _(lisp_gpe_add_del_iface, "up|down")                                    \
21871 _(lisp_gpe_enable_disable, "enable|disable")                            \
21872 _(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>"       \
21873   "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
21874 _(show_lisp_rloc_probe_state, "")                                       \
21875 _(show_lisp_map_register_state, "")                                     \
21876 _(show_lisp_status, "")                                                 \
21877 _(lisp_get_map_request_itr_rlocs, "")                                   \
21878 _(show_lisp_pitr, "")                                                   \
21879 _(show_lisp_use_petr, "")                                               \
21880 _(show_lisp_map_request_mode, "")                                       \
21881 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
21882 _(af_packet_delete, "name <host interface name>")                       \
21883 _(af_packet_dump, "")                                                   \
21884 _(policer_add_del, "name <policer name> <params> [del]")                \
21885 _(policer_dump, "[name <policer name>]")                                \
21886 _(policer_classify_set_interface,                                       \
21887   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
21888   "  [l2-table <nn>] [del]")                                            \
21889 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
21890 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
21891     "[master|slave]")                                                   \
21892 _(netmap_delete, "name <interface name>")                               \
21893 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
21894 _(mpls_table_dump, "")                                                  \
21895 _(mpls_route_dump, "table-id <ID>")                                     \
21896 _(classify_table_ids, "")                                               \
21897 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
21898 _(classify_table_info, "table_id <nn>")                                 \
21899 _(classify_session_dump, "table_id <nn>")                               \
21900 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
21901     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
21902     "[template_interval <nn>] [udp_checksum]")                          \
21903 _(ipfix_exporter_dump, "")                                              \
21904 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
21905 _(ipfix_classify_stream_dump, "")                                       \
21906 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
21907 _(ipfix_classify_table_dump, "")                                        \
21908 _(sw_interface_span_enable_disable, "[l2] [src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
21909 _(sw_interface_span_dump, "[l2]")                                           \
21910 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
21911 _(pg_create_interface, "if_id <nn> [gso-enabled gso-size <size>]")      \
21912 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
21913 _(pg_enable_disable, "[stream <id>] disable")                           \
21914 _(ip_source_and_port_range_check_add_del,                               \
21915   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
21916 _(ip_source_and_port_range_check_interface_add_del,                     \
21917   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
21918   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
21919 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
21920 _(l2_interface_pbb_tag_rewrite,                                         \
21921   "<intfc> | sw_if_index <nn> \n"                                       \
21922   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
21923   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
21924 _(set_punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
21925 _(flow_classify_set_interface,                                          \
21926   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
21927 _(flow_classify_dump, "type [ip4|ip6]")                                 \
21928 _(ip_table_dump, "")                                                    \
21929 _(ip_route_dump, "table-id [ip4|ip6]")                                  \
21930 _(ip_mtable_dump, "")                                                   \
21931 _(ip_mroute_dump, "table-id [ip4|ip6]")                                 \
21932 _(feature_enable_disable, "arc_name <arc_name> "                        \
21933   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
21934 _(feature_gso_enable_disable, "<intfc> | sw_if_index <nn> "             \
21935   "[enable | disable] ")                                                \
21936 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
21937 "[disable]")                                                            \
21938 _(sw_interface_add_del_mac_address, "<intfc> | sw_if_index <nn> "       \
21939   "mac <mac-address> [del]")                                            \
21940 _(l2_xconnect_dump, "")                                                 \
21941 _(hw_interface_set_mtu, "<intfc> | hw_if_index <nn> mtu <nn>")        \
21942 _(ip_neighbor_dump, "[ip6] <intfc> | sw_if_index <nn>")                 \
21943 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")          \
21944 _(p2p_ethernet_add, "<intfc> | sw_if_index <nn> remote_mac <mac-address> sub_id <id>") \
21945 _(p2p_ethernet_del, "<intfc> | sw_if_index <nn> remote_mac <mac-address>") \
21946 _(lldp_config, "system-name <name> tx-hold <nn> tx-interval <nn>") \
21947 _(sw_interface_set_lldp, "<intfc> | sw_if_index <nn> [port-desc <description>]\n" \
21948   " [mgmt-ip4 <ip4>] [mgmt-ip6 <ip6>] [mgmt-oid <object id>] [disable]") \
21949 _(tcp_configure_src_addresses, "<ip4|6>first-<ip4|6>last [vrf <id>]")   \
21950 _(sock_init_shm, "size <nnn>")                                          \
21951 _(app_namespace_add_del, "[add] id <ns-id> secret <nn> sw_if_index <nn>")\
21952 _(session_rule_add_del, "[add|del] proto <tcp/udp> <lcl-ip>/<plen> "    \
21953   "<lcl-port> <rmt-ip>/<plen> <rmt-port> action <nn>")                  \
21954 _(session_rules_dump, "")                                               \
21955 _(ip_container_proxy_add_del, "[add|del] <address> <sw_if_index>")      \
21956 _(output_acl_set_interface,                                             \
21957   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
21958   "  [l2-table <nn>] [del]")                                            \
21959 _(qos_record_enable_disable, "<record-source> <intfc> | sw_if_index <id> [disable]")
21960
21961 /* List of command functions, CLI names map directly to functions */
21962 #define foreach_cli_function                                    \
21963 _(comment, "usage: comment <ignore-rest-of-line>")              \
21964 _(dump_interface_table, "usage: dump_interface_table")          \
21965 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
21966 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
21967 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
21968 _(dump_macro_table, "usage: dump_macro_table ")                 \
21969 _(dump_node_table, "usage: dump_node_table")                    \
21970 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
21971 _(elog_setup, "usage: elog_setup [nevents, default 128K]")      \
21972 _(elog_disable, "usage: elog_disable")                          \
21973 _(elog_enable, "usage: elog_enable")                            \
21974 _(elog_save, "usage: elog_save <filename>")                     \
21975 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
21976 _(echo, "usage: echo <message>")                                \
21977 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
21978 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
21979 _(help, "usage: help")                                          \
21980 _(q, "usage: quit")                                             \
21981 _(quit, "usage: quit")                                          \
21982 _(search_node_table, "usage: search_node_table <name>...")      \
21983 _(set, "usage: set <variable-name> <value>")                    \
21984 _(script, "usage: script <file-name>")                          \
21985 _(statseg, "usage: statseg")                                    \
21986 _(unset, "usage: unset <variable-name>")
21987
21988 #define _(N,n)                                  \
21989     static void vl_api_##n##_t_handler_uni      \
21990     (vl_api_##n##_t * mp)                       \
21991     {                                           \
21992         vat_main_t * vam = &vat_main;           \
21993         if (vam->json_output) {                 \
21994             vl_api_##n##_t_handler_json(mp);    \
21995         } else {                                \
21996             vl_api_##n##_t_handler(mp);         \
21997         }                                       \
21998     }
21999 foreach_vpe_api_reply_msg;
22000 #if VPP_API_TEST_BUILTIN == 0
22001 foreach_standalone_reply_msg;
22002 #endif
22003 #undef _
22004
22005 void
22006 vat_api_hookup (vat_main_t * vam)
22007 {
22008 #define _(N,n)                                                  \
22009     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
22010                            vl_api_##n##_t_handler_uni,          \
22011                            vl_noop_handler,                     \
22012                            vl_api_##n##_t_endian,               \
22013                            vl_api_##n##_t_print,                \
22014                            sizeof(vl_api_##n##_t), 1);
22015   foreach_vpe_api_reply_msg;
22016 #if VPP_API_TEST_BUILTIN == 0
22017   foreach_standalone_reply_msg;
22018 #endif
22019 #undef _
22020
22021 #if (VPP_API_TEST_BUILTIN==0)
22022   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
22023
22024   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
22025
22026   vam->function_by_name = hash_create_string (0, sizeof (uword));
22027
22028   vam->help_by_name = hash_create_string (0, sizeof (uword));
22029 #endif
22030
22031   /* API messages we can send */
22032 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
22033   foreach_vpe_api_msg;
22034 #undef _
22035
22036   /* Help strings */
22037 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
22038   foreach_vpe_api_msg;
22039 #undef _
22040
22041   /* CLI functions */
22042 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
22043   foreach_cli_function;
22044 #undef _
22045
22046   /* Help strings */
22047 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
22048   foreach_cli_function;
22049 #undef _
22050 }
22051
22052 #if VPP_API_TEST_BUILTIN
22053 static clib_error_t *
22054 vat_api_hookup_shim (vlib_main_t * vm)
22055 {
22056   vat_api_hookup (&vat_main);
22057   return 0;
22058 }
22059
22060 VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
22061 #endif
22062
22063 /*
22064  * fd.io coding-style-patch-verification: ON
22065  *
22066  * Local Variables:
22067  * eval: (c-set-style "gnu")
22068  * End:
22069  */