fib: Table Replace
[vpp.git] / src / vat / api_format.c
1 /*
2  *------------------------------------------------------------------
3  * api_format.c
4  *
5  * Copyright (c) 2014-2016 Cisco and/or its affiliates.
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at:
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *------------------------------------------------------------------
18  */
19
20 #include <vat/vat.h>
21 #include <vlib/pci/pci.h>
22 #include <vpp/api/types.h>
23 #include <vppinfra/socket.h>
24 #include <vlibapi/api.h>
25 #include <vlibmemory/api.h>
26 #include <vnet/ip/ip.h>
27 #include <vnet/ip/ip_neighbor.h>
28 #include <vnet/ip/ip_types_api.h>
29 #include <vnet/l2/l2_input.h>
30 #include <vnet/l2tp/l2tp.h>
31 #include <vnet/vxlan/vxlan.h>
32 #include <vnet/geneve/geneve.h>
33 #include <vnet/gre/gre.h>
34 #include <vnet/vxlan-gpe/vxlan_gpe.h>
35 #include <vnet/lisp-gpe/lisp_gpe.h>
36
37 #include <vpp/api/vpe_msg_enum.h>
38 #include <vnet/l2/l2_classify.h>
39 #include <vnet/l2/l2_vtr.h>
40 #include <vnet/classify/in_out_acl.h>
41 #include <vnet/classify/policer_classify.h>
42 #include <vnet/classify/flow_classify.h>
43 #include <vnet/mpls/mpls.h>
44 #include <vnet/ipsec/ipsec.h>
45 #include <inttypes.h>
46 #include <vnet/cop/cop.h>
47 #include <vnet/ip/ip6_hop_by_hop.h>
48 #include <vnet/ip/ip_source_and_port_range_check.h>
49 #include <vnet/policer/xlate.h>
50 #include <vnet/span/span.h>
51 #include <vnet/policer/policer.h>
52 #include <vnet/policer/police.h>
53 #include <vnet/mfib/mfib_types.h>
54 #include <vnet/bonding/node.h>
55 #include <vnet/qos/qos_types.h>
56 #include <vnet/ethernet/ethernet_types_api.h>
57 #include <vnet/ip/ip_types_api.h>
58 #include "vat/json_format.h"
59 #include <vnet/ip/ip_types_api.h>
60 #include <vnet/ethernet/ethernet_types_api.h>
61
62 #include <inttypes.h>
63 #include <sys/stat.h>
64
65 #define vl_typedefs             /* define message structures */
66 #include <vpp/api/vpe_all_api_h.h>
67 #undef vl_typedefs
68
69 /* declare message handlers for each api */
70
71 #define vl_endianfun            /* define message structures */
72 #include <vpp/api/vpe_all_api_h.h>
73 #undef vl_endianfun
74
75 /* instantiate all the print functions we know about */
76 #if VPP_API_TEST_BUILTIN == 0
77 #define vl_print(handle, ...)
78 #else
79 #define vl_print(handle, ...) vlib_cli_output (handle, __VA_ARGS__)
80 #endif
81 #define vl_printfun
82 #include <vpp/api/vpe_all_api_h.h>
83 #undef vl_printfun
84
85 #define __plugin_msg_base 0
86 #include <vlibapi/vat_helper_macros.h>
87
88 #include <vnet/format_fns.h>
89
90 void vl_api_set_elog_main (elog_main_t * m);
91 int vl_api_set_elog_trace_api_messages (int enable);
92
93 #if VPP_API_TEST_BUILTIN == 0
94 #include <netdb.h>
95
96 u32
97 vl (void *p)
98 {
99   return vec_len (p);
100 }
101
102 int
103 vat_socket_connect (vat_main_t * vam)
104 {
105   int rv;
106   vam->socket_client_main = &socket_client_main;
107   if ((rv = vl_socket_client_connect ((char *) vam->socket_name,
108                                       "vpp_api_test",
109                                       0 /* default socket rx, tx buffer */ )))
110     return rv;
111   /* vpp expects the client index in network order */
112   vam->my_client_index = htonl (socket_client_main.client_index);
113   return 0;
114 }
115 #else /* vpp built-in case, we don't do sockets... */
116 int
117 vat_socket_connect (vat_main_t * vam)
118 {
119   return 0;
120 }
121
122 int
123 vl_socket_client_read (int wait)
124 {
125   return -1;
126 };
127
128 int
129 vl_socket_client_write ()
130 {
131   return -1;
132 };
133
134 void *
135 vl_socket_client_msg_alloc (int nbytes)
136 {
137   return 0;
138 }
139 #endif
140
141
142 f64
143 vat_time_now (vat_main_t * vam)
144 {
145 #if VPP_API_TEST_BUILTIN
146   return vlib_time_now (vam->vlib_main);
147 #else
148   return clib_time_now (&vam->clib_time);
149 #endif
150 }
151
152 void
153 errmsg (char *fmt, ...)
154 {
155   vat_main_t *vam = &vat_main;
156   va_list va;
157   u8 *s;
158
159   va_start (va, fmt);
160   s = va_format (0, fmt, &va);
161   va_end (va);
162
163   vec_add1 (s, 0);
164
165 #if VPP_API_TEST_BUILTIN
166   vlib_cli_output (vam->vlib_main, (char *) s);
167 #else
168   {
169     if (vam->ifp != stdin)
170       fformat (vam->ofp, "%s(%d): \n", vam->current_file,
171                vam->input_line_number);
172     else
173       fformat (vam->ofp, "%s\n", (char *) s);
174     fflush (vam->ofp);
175   }
176 #endif
177
178   vec_free (s);
179 }
180
181 #if VPP_API_TEST_BUILTIN == 0
182 static uword
183 api_unformat_sw_if_index (unformat_input_t * input, va_list * args)
184 {
185   vat_main_t *vam = va_arg (*args, vat_main_t *);
186   u32 *result = va_arg (*args, u32 *);
187   u8 *if_name;
188   uword *p;
189
190   if (!unformat (input, "%s", &if_name))
191     return 0;
192
193   p = hash_get_mem (vam->sw_if_index_by_interface_name, if_name);
194   if (p == 0)
195     return 0;
196   *result = p[0];
197   return 1;
198 }
199
200 static uword
201 api_unformat_hw_if_index (unformat_input_t * input, va_list * args)
202 {
203   return 0;
204 }
205
206 /* Parse an IP4 address %d.%d.%d.%d. */
207 uword
208 unformat_ip4_address (unformat_input_t * input, va_list * args)
209 {
210   u8 *result = va_arg (*args, u8 *);
211   unsigned a[4];
212
213   if (!unformat (input, "%d.%d.%d.%d", &a[0], &a[1], &a[2], &a[3]))
214     return 0;
215
216   if (a[0] >= 256 || a[1] >= 256 || a[2] >= 256 || a[3] >= 256)
217     return 0;
218
219   result[0] = a[0];
220   result[1] = a[1];
221   result[2] = a[2];
222   result[3] = a[3];
223
224   return 1;
225 }
226
227 uword
228 unformat_ethernet_address (unformat_input_t * input, va_list * args)
229 {
230   u8 *result = va_arg (*args, u8 *);
231   u32 i, a[6];
232
233   if (!unformat (input, "%_%x:%x:%x:%x:%x:%x%_",
234                  &a[0], &a[1], &a[2], &a[3], &a[4], &a[5]))
235     return 0;
236
237   /* Check range. */
238   for (i = 0; i < 6; i++)
239     if (a[i] >= (1 << 8))
240       return 0;
241
242   for (i = 0; i < 6; i++)
243     result[i] = a[i];
244
245   return 1;
246 }
247
248 /* Returns ethernet type as an int in host byte order. */
249 uword
250 unformat_ethernet_type_host_byte_order (unformat_input_t * input,
251                                         va_list * args)
252 {
253   u16 *result = va_arg (*args, u16 *);
254   int type;
255
256   /* Numeric type. */
257   if (unformat (input, "0x%x", &type) || unformat (input, "%d", &type))
258     {
259       if (type >= (1 << 16))
260         return 0;
261       *result = type;
262       return 1;
263     }
264   return 0;
265 }
266
267 /* Parse an IP6 address. */
268 uword
269 unformat_ip6_address (unformat_input_t * input, va_list * args)
270 {
271   ip6_address_t *result = va_arg (*args, ip6_address_t *);
272   u16 hex_quads[8];
273   uword hex_quad, n_hex_quads, hex_digit, n_hex_digits;
274   uword c, n_colon, double_colon_index;
275
276   n_hex_quads = hex_quad = n_hex_digits = n_colon = 0;
277   double_colon_index = ARRAY_LEN (hex_quads);
278   while ((c = unformat_get_input (input)) != UNFORMAT_END_OF_INPUT)
279     {
280       hex_digit = 16;
281       if (c >= '0' && c <= '9')
282         hex_digit = c - '0';
283       else if (c >= 'a' && c <= 'f')
284         hex_digit = c + 10 - 'a';
285       else if (c >= 'A' && c <= 'F')
286         hex_digit = c + 10 - 'A';
287       else if (c == ':' && n_colon < 2)
288         n_colon++;
289       else
290         {
291           unformat_put_input (input);
292           break;
293         }
294
295       /* Too many hex quads. */
296       if (n_hex_quads >= ARRAY_LEN (hex_quads))
297         return 0;
298
299       if (hex_digit < 16)
300         {
301           hex_quad = (hex_quad << 4) | hex_digit;
302
303           /* Hex quad must fit in 16 bits. */
304           if (n_hex_digits >= 4)
305             return 0;
306
307           n_colon = 0;
308           n_hex_digits++;
309         }
310
311       /* Save position of :: */
312       if (n_colon == 2)
313         {
314           /* More than one :: ? */
315           if (double_colon_index < ARRAY_LEN (hex_quads))
316             return 0;
317           double_colon_index = n_hex_quads;
318         }
319
320       if (n_colon > 0 && n_hex_digits > 0)
321         {
322           hex_quads[n_hex_quads++] = hex_quad;
323           hex_quad = 0;
324           n_hex_digits = 0;
325         }
326     }
327
328   if (n_hex_digits > 0)
329     hex_quads[n_hex_quads++] = hex_quad;
330
331   {
332     word i;
333
334     /* Expand :: to appropriate number of zero hex quads. */
335     if (double_colon_index < ARRAY_LEN (hex_quads))
336       {
337         word n_zero = ARRAY_LEN (hex_quads) - n_hex_quads;
338
339         for (i = n_hex_quads - 1; i >= (signed) double_colon_index; i--)
340           hex_quads[n_zero + i] = hex_quads[i];
341
342         for (i = 0; i < n_zero; i++)
343           hex_quads[double_colon_index + i] = 0;
344
345         n_hex_quads = ARRAY_LEN (hex_quads);
346       }
347
348     /* Too few hex quads given. */
349     if (n_hex_quads < ARRAY_LEN (hex_quads))
350       return 0;
351
352     for (i = 0; i < ARRAY_LEN (hex_quads); i++)
353       result->as_u16[i] = clib_host_to_net_u16 (hex_quads[i]);
354
355     return 1;
356   }
357 }
358
359 uword
360 unformat_ipsec_policy_action (unformat_input_t * input, va_list * args)
361 {
362   u32 *r = va_arg (*args, u32 *);
363
364   if (0);
365 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_POLICY_ACTION_##f;
366   foreach_ipsec_policy_action
367 #undef _
368     else
369     return 0;
370   return 1;
371 }
372
373 u8 *
374 format_ipsec_crypto_alg (u8 * s, va_list * args)
375 {
376   u32 i = va_arg (*args, u32);
377   u8 *t = 0;
378
379   switch (i)
380     {
381 #define _(v,f,str) case IPSEC_CRYPTO_ALG_##f: t = (u8 *) str; break;
382       foreach_ipsec_crypto_alg
383 #undef _
384     default:
385       return format (s, "unknown");
386     }
387   return format (s, "%s", t);
388 }
389
390 u8 *
391 format_ipsec_integ_alg (u8 * s, va_list * args)
392 {
393   u32 i = va_arg (*args, u32);
394   u8 *t = 0;
395
396   switch (i)
397     {
398 #define _(v,f,str) case IPSEC_INTEG_ALG_##f: t = (u8 *) str; break;
399       foreach_ipsec_integ_alg
400 #undef _
401     default:
402       return format (s, "unknown");
403     }
404   return format (s, "%s", t);
405 }
406
407 #else /* VPP_API_TEST_BUILTIN == 1 */
408 static uword
409 api_unformat_sw_if_index (unformat_input_t * input, va_list * args)
410 {
411   vat_main_t *vam __clib_unused = va_arg (*args, vat_main_t *);
412   vnet_main_t *vnm = vnet_get_main ();
413   u32 *result = va_arg (*args, u32 *);
414
415   return unformat (input, "%U", unformat_vnet_sw_interface, vnm, result);
416 }
417
418 static uword
419 api_unformat_hw_if_index (unformat_input_t * input, va_list * args)
420 {
421   vat_main_t *vam __clib_unused = va_arg (*args, vat_main_t *);
422   vnet_main_t *vnm = vnet_get_main ();
423   u32 *result = va_arg (*args, u32 *);
424
425   return unformat (input, "%U", unformat_vnet_hw_interface, vnm, result);
426 }
427
428 #endif /* VPP_API_TEST_BUILTIN */
429
430 uword
431 unformat_ipsec_api_crypto_alg (unformat_input_t * input, va_list * args)
432 {
433   u32 *r = va_arg (*args, u32 *);
434
435   if (0);
436 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_API_CRYPTO_ALG_##f;
437   foreach_ipsec_crypto_alg
438 #undef _
439     else
440     return 0;
441   return 1;
442 }
443
444 uword
445 unformat_ipsec_api_integ_alg (unformat_input_t * input, va_list * args)
446 {
447   u32 *r = va_arg (*args, u32 *);
448
449   if (0);
450 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_API_INTEG_ALG_##f;
451   foreach_ipsec_integ_alg
452 #undef _
453     else
454     return 0;
455   return 1;
456 }
457
458 static uword
459 unformat_policer_rate_type (unformat_input_t * input, va_list * args)
460 {
461   u8 *r = va_arg (*args, u8 *);
462
463   if (unformat (input, "kbps"))
464     *r = SSE2_QOS_RATE_KBPS;
465   else if (unformat (input, "pps"))
466     *r = SSE2_QOS_RATE_PPS;
467   else
468     return 0;
469   return 1;
470 }
471
472 static uword
473 unformat_policer_round_type (unformat_input_t * input, va_list * args)
474 {
475   u8 *r = va_arg (*args, u8 *);
476
477   if (unformat (input, "closest"))
478     *r = SSE2_QOS_ROUND_TO_CLOSEST;
479   else if (unformat (input, "up"))
480     *r = SSE2_QOS_ROUND_TO_UP;
481   else if (unformat (input, "down"))
482     *r = SSE2_QOS_ROUND_TO_DOWN;
483   else
484     return 0;
485   return 1;
486 }
487
488 static uword
489 unformat_policer_type (unformat_input_t * input, va_list * args)
490 {
491   u8 *r = va_arg (*args, u8 *);
492
493   if (unformat (input, "1r2c"))
494     *r = SSE2_QOS_POLICER_TYPE_1R2C;
495   else if (unformat (input, "1r3c"))
496     *r = SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697;
497   else if (unformat (input, "2r3c-2698"))
498     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698;
499   else if (unformat (input, "2r3c-4115"))
500     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115;
501   else if (unformat (input, "2r3c-mef5cf1"))
502     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1;
503   else
504     return 0;
505   return 1;
506 }
507
508 static uword
509 unformat_dscp (unformat_input_t * input, va_list * va)
510 {
511   u8 *r = va_arg (*va, u8 *);
512
513   if (0);
514 #define _(v,f,str) else if (unformat (input, str)) *r = VNET_DSCP_##f;
515   foreach_vnet_dscp
516 #undef _
517     else
518     return 0;
519   return 1;
520 }
521
522 static uword
523 unformat_policer_action_type (unformat_input_t * input, va_list * va)
524 {
525   sse2_qos_pol_action_params_st *a
526     = va_arg (*va, sse2_qos_pol_action_params_st *);
527
528   if (unformat (input, "drop"))
529     a->action_type = SSE2_QOS_ACTION_DROP;
530   else if (unformat (input, "transmit"))
531     a->action_type = SSE2_QOS_ACTION_TRANSMIT;
532   else if (unformat (input, "mark-and-transmit %U", unformat_dscp, &a->dscp))
533     a->action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
534   else
535     return 0;
536   return 1;
537 }
538
539 static uword
540 unformat_policer_classify_table_type (unformat_input_t * input, va_list * va)
541 {
542   u32 *r = va_arg (*va, u32 *);
543   u32 tid;
544
545   if (unformat (input, "ip4"))
546     tid = POLICER_CLASSIFY_TABLE_IP4;
547   else if (unformat (input, "ip6"))
548     tid = POLICER_CLASSIFY_TABLE_IP6;
549   else if (unformat (input, "l2"))
550     tid = POLICER_CLASSIFY_TABLE_L2;
551   else
552     return 0;
553
554   *r = tid;
555   return 1;
556 }
557
558 static uword
559 unformat_flow_classify_table_type (unformat_input_t * input, va_list * va)
560 {
561   u32 *r = va_arg (*va, u32 *);
562   u32 tid;
563
564   if (unformat (input, "ip4"))
565     tid = FLOW_CLASSIFY_TABLE_IP4;
566   else if (unformat (input, "ip6"))
567     tid = FLOW_CLASSIFY_TABLE_IP6;
568   else
569     return 0;
570
571   *r = tid;
572   return 1;
573 }
574
575 #if (VPP_API_TEST_BUILTIN==0)
576
577 static const char *mfib_flag_names[] = MFIB_ENTRY_NAMES_SHORT;
578 static const char *mfib_flag_long_names[] = MFIB_ENTRY_NAMES_LONG;
579 static const char *mfib_itf_flag_long_names[] = MFIB_ITF_NAMES_LONG;
580 static const char *mfib_itf_flag_names[] = MFIB_ITF_NAMES_SHORT;
581
582 uword
583 unformat_mfib_itf_flags (unformat_input_t * input, va_list * args)
584 {
585   mfib_itf_flags_t old, *iflags = va_arg (*args, mfib_itf_flags_t *);
586   mfib_itf_attribute_t attr;
587
588   old = *iflags;
589   FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
590   {
591     if (unformat (input, mfib_itf_flag_long_names[attr]))
592       *iflags |= (1 << attr);
593   }
594   FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
595   {
596     if (unformat (input, mfib_itf_flag_names[attr]))
597       *iflags |= (1 << attr);
598   }
599
600   return (old == *iflags ? 0 : 1);
601 }
602
603 uword
604 unformat_mfib_entry_flags (unformat_input_t * input, va_list * args)
605 {
606   mfib_entry_flags_t old, *eflags = va_arg (*args, mfib_entry_flags_t *);
607   mfib_entry_attribute_t attr;
608
609   old = *eflags;
610   FOR_EACH_MFIB_ATTRIBUTE (attr)
611   {
612     if (unformat (input, mfib_flag_long_names[attr]))
613       *eflags |= (1 << attr);
614   }
615   FOR_EACH_MFIB_ATTRIBUTE (attr)
616   {
617     if (unformat (input, mfib_flag_names[attr]))
618       *eflags |= (1 << attr);
619   }
620
621   return (old == *eflags ? 0 : 1);
622 }
623
624 u8 *
625 format_ip4_address (u8 * s, va_list * args)
626 {
627   u8 *a = va_arg (*args, u8 *);
628   return format (s, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]);
629 }
630
631 u8 *
632 format_ip6_address (u8 * s, va_list * args)
633 {
634   ip6_address_t *a = va_arg (*args, ip6_address_t *);
635   u32 i, i_max_n_zero, max_n_zeros, i_first_zero, n_zeros, last_double_colon;
636
637   i_max_n_zero = ARRAY_LEN (a->as_u16);
638   max_n_zeros = 0;
639   i_first_zero = i_max_n_zero;
640   n_zeros = 0;
641   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
642     {
643       u32 is_zero = a->as_u16[i] == 0;
644       if (is_zero && i_first_zero >= ARRAY_LEN (a->as_u16))
645         {
646           i_first_zero = i;
647           n_zeros = 0;
648         }
649       n_zeros += is_zero;
650       if ((!is_zero && n_zeros > max_n_zeros)
651           || (i + 1 >= ARRAY_LEN (a->as_u16) && n_zeros > max_n_zeros))
652         {
653           i_max_n_zero = i_first_zero;
654           max_n_zeros = n_zeros;
655           i_first_zero = ARRAY_LEN (a->as_u16);
656           n_zeros = 0;
657         }
658     }
659
660   last_double_colon = 0;
661   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
662     {
663       if (i == i_max_n_zero && max_n_zeros > 1)
664         {
665           s = format (s, "::");
666           i += max_n_zeros - 1;
667           last_double_colon = 1;
668         }
669       else
670         {
671           s = format (s, "%s%x",
672                       (last_double_colon || i == 0) ? "" : ":",
673                       clib_net_to_host_u16 (a->as_u16[i]));
674           last_double_colon = 0;
675         }
676     }
677
678   return s;
679 }
680
681 /* Format an IP46 address. */
682 u8 *
683 format_ip46_address (u8 * s, va_list * args)
684 {
685   ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
686   ip46_type_t type = va_arg (*args, ip46_type_t);
687   int is_ip4 = 1;
688
689   switch (type)
690     {
691     case IP46_TYPE_ANY:
692       is_ip4 = ip46_address_is_ip4 (ip46);
693       break;
694     case IP46_TYPE_IP4:
695       is_ip4 = 1;
696       break;
697     case IP46_TYPE_IP6:
698       is_ip4 = 0;
699       break;
700     }
701
702   return is_ip4 ?
703     format (s, "%U", format_ip4_address, &ip46->ip4) :
704     format (s, "%U", format_ip6_address, &ip46->ip6);
705 }
706
707 u8 *
708 format_ethernet_address (u8 * s, va_list * args)
709 {
710   u8 *a = va_arg (*args, u8 *);
711
712   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
713                  a[0], a[1], a[2], a[3], a[4], a[5]);
714 }
715 #endif
716
717 static void
718 increment_v4_address (vl_api_ip4_address_t * i)
719 {
720   ip4_address_t *a = (ip4_address_t *) i;
721   u32 v;
722
723   v = ntohl (a->as_u32) + 1;
724   a->as_u32 = ntohl (v);
725 }
726
727 static void
728 increment_v6_address (vl_api_ip6_address_t * i)
729 {
730   ip6_address_t *a = (ip6_address_t *) i;
731   u64 v0, v1;
732
733   v0 = clib_net_to_host_u64 (a->as_u64[0]);
734   v1 = clib_net_to_host_u64 (a->as_u64[1]);
735
736   v1 += 1;
737   if (v1 == 0)
738     v0 += 1;
739   a->as_u64[0] = clib_net_to_host_u64 (v0);
740   a->as_u64[1] = clib_net_to_host_u64 (v1);
741 }
742
743 static void
744 increment_address (vl_api_address_t * a)
745 {
746   if (clib_net_to_host_u32 (a->af) == ADDRESS_IP4)
747     increment_v4_address (&a->un.ip4);
748   else if (clib_net_to_host_u32 (a->af) == ADDRESS_IP6)
749     increment_v6_address (&a->un.ip6);
750 }
751
752 static void
753 set_ip4_address (vl_api_address_t * a, u32 v)
754 {
755   if (a->af == ADDRESS_IP4)
756     {
757       ip4_address_t *i = (ip4_address_t *) & a->un.ip4;
758       i->as_u32 = v;
759     }
760 }
761
762 static void
763 increment_mac_address (u8 * mac)
764 {
765   u64 tmp = *((u64 *) mac);
766   tmp = clib_net_to_host_u64 (tmp);
767   tmp += 1 << 16;               /* skip unused (least significant) octets */
768   tmp = clib_host_to_net_u64 (tmp);
769
770   clib_memcpy (mac, &tmp, 6);
771 }
772
773 static void
774 vat_json_object_add_address (vat_json_node_t * node,
775                              const char *str, const vl_api_address_t * addr)
776 {
777   if (ADDRESS_IP6 == addr->af)
778     {
779       struct in6_addr ip6;
780
781       clib_memcpy (&ip6, &addr->un.ip6, sizeof (ip6));
782       vat_json_object_add_ip6 (node, str, ip6);
783     }
784   else
785     {
786       struct in_addr ip4;
787
788       clib_memcpy (&ip4, &addr->un.ip4, sizeof (ip4));
789       vat_json_object_add_ip4 (node, str, ip4);
790     }
791 }
792
793 static void
794 vat_json_object_add_prefix (vat_json_node_t * node,
795                             const vl_api_prefix_t * prefix)
796 {
797   vat_json_object_add_uint (node, "len", prefix->len);
798   vat_json_object_add_address (node, "address", &prefix->address);
799 }
800
801 static void vl_api_create_loopback_reply_t_handler
802   (vl_api_create_loopback_reply_t * mp)
803 {
804   vat_main_t *vam = &vat_main;
805   i32 retval = ntohl (mp->retval);
806
807   vam->retval = retval;
808   vam->regenerate_interface_table = 1;
809   vam->sw_if_index = ntohl (mp->sw_if_index);
810   vam->result_ready = 1;
811 }
812
813 static void vl_api_create_loopback_reply_t_handler_json
814   (vl_api_create_loopback_reply_t * mp)
815 {
816   vat_main_t *vam = &vat_main;
817   vat_json_node_t node;
818
819   vat_json_init_object (&node);
820   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
821   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
822
823   vat_json_print (vam->ofp, &node);
824   vat_json_free (&node);
825   vam->retval = ntohl (mp->retval);
826   vam->result_ready = 1;
827 }
828
829 static void vl_api_create_loopback_instance_reply_t_handler
830   (vl_api_create_loopback_instance_reply_t * mp)
831 {
832   vat_main_t *vam = &vat_main;
833   i32 retval = ntohl (mp->retval);
834
835   vam->retval = retval;
836   vam->regenerate_interface_table = 1;
837   vam->sw_if_index = ntohl (mp->sw_if_index);
838   vam->result_ready = 1;
839 }
840
841 static void vl_api_create_loopback_instance_reply_t_handler_json
842   (vl_api_create_loopback_instance_reply_t * mp)
843 {
844   vat_main_t *vam = &vat_main;
845   vat_json_node_t node;
846
847   vat_json_init_object (&node);
848   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
849   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
850
851   vat_json_print (vam->ofp, &node);
852   vat_json_free (&node);
853   vam->retval = ntohl (mp->retval);
854   vam->result_ready = 1;
855 }
856
857 static void vl_api_af_packet_create_reply_t_handler
858   (vl_api_af_packet_create_reply_t * mp)
859 {
860   vat_main_t *vam = &vat_main;
861   i32 retval = ntohl (mp->retval);
862
863   vam->retval = retval;
864   vam->regenerate_interface_table = 1;
865   vam->sw_if_index = ntohl (mp->sw_if_index);
866   vam->result_ready = 1;
867 }
868
869 static void vl_api_af_packet_create_reply_t_handler_json
870   (vl_api_af_packet_create_reply_t * mp)
871 {
872   vat_main_t *vam = &vat_main;
873   vat_json_node_t node;
874
875   vat_json_init_object (&node);
876   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
877   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
878
879   vat_json_print (vam->ofp, &node);
880   vat_json_free (&node);
881
882   vam->retval = ntohl (mp->retval);
883   vam->result_ready = 1;
884 }
885
886 static void vl_api_create_vlan_subif_reply_t_handler
887   (vl_api_create_vlan_subif_reply_t * mp)
888 {
889   vat_main_t *vam = &vat_main;
890   i32 retval = ntohl (mp->retval);
891
892   vam->retval = retval;
893   vam->regenerate_interface_table = 1;
894   vam->sw_if_index = ntohl (mp->sw_if_index);
895   vam->result_ready = 1;
896 }
897
898 static void vl_api_create_vlan_subif_reply_t_handler_json
899   (vl_api_create_vlan_subif_reply_t * mp)
900 {
901   vat_main_t *vam = &vat_main;
902   vat_json_node_t node;
903
904   vat_json_init_object (&node);
905   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
906   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
907
908   vat_json_print (vam->ofp, &node);
909   vat_json_free (&node);
910
911   vam->retval = ntohl (mp->retval);
912   vam->result_ready = 1;
913 }
914
915 static void vl_api_create_subif_reply_t_handler
916   (vl_api_create_subif_reply_t * mp)
917 {
918   vat_main_t *vam = &vat_main;
919   i32 retval = ntohl (mp->retval);
920
921   vam->retval = retval;
922   vam->regenerate_interface_table = 1;
923   vam->sw_if_index = ntohl (mp->sw_if_index);
924   vam->result_ready = 1;
925 }
926
927 static void vl_api_create_subif_reply_t_handler_json
928   (vl_api_create_subif_reply_t * mp)
929 {
930   vat_main_t *vam = &vat_main;
931   vat_json_node_t node;
932
933   vat_json_init_object (&node);
934   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
935   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
936
937   vat_json_print (vam->ofp, &node);
938   vat_json_free (&node);
939
940   vam->retval = ntohl (mp->retval);
941   vam->result_ready = 1;
942 }
943
944 static void vl_api_interface_name_renumber_reply_t_handler
945   (vl_api_interface_name_renumber_reply_t * mp)
946 {
947   vat_main_t *vam = &vat_main;
948   i32 retval = ntohl (mp->retval);
949
950   vam->retval = retval;
951   vam->regenerate_interface_table = 1;
952   vam->result_ready = 1;
953 }
954
955 static void vl_api_interface_name_renumber_reply_t_handler_json
956   (vl_api_interface_name_renumber_reply_t * mp)
957 {
958   vat_main_t *vam = &vat_main;
959   vat_json_node_t node;
960
961   vat_json_init_object (&node);
962   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
963
964   vat_json_print (vam->ofp, &node);
965   vat_json_free (&node);
966
967   vam->retval = ntohl (mp->retval);
968   vam->result_ready = 1;
969 }
970
971 /*
972  * Special-case: build the interface table, maintain
973  * the next loopback sw_if_index vbl.
974  */
975 static void vl_api_sw_interface_details_t_handler
976   (vl_api_sw_interface_details_t * mp)
977 {
978   vat_main_t *vam = &vat_main;
979   u8 *s = format (0, "%s%c", mp->interface_name, 0);
980
981   hash_set_mem (vam->sw_if_index_by_interface_name, s,
982                 ntohl (mp->sw_if_index));
983
984   /* In sub interface case, fill the sub interface table entry */
985   if (mp->sw_if_index != mp->sup_sw_if_index)
986     {
987       sw_interface_subif_t *sub = NULL;
988
989       vec_add2 (vam->sw_if_subif_table, sub, 1);
990
991       vec_validate (sub->interface_name, strlen ((char *) s) + 1);
992       strncpy ((char *) sub->interface_name, (char *) s,
993                vec_len (sub->interface_name));
994       sub->sw_if_index = ntohl (mp->sw_if_index);
995       sub->sub_id = ntohl (mp->sub_id);
996
997       sub->raw_flags = ntohl (mp->sub_if_flags & SUB_IF_API_FLAG_MASK_VNET);
998
999       sub->sub_number_of_tags = mp->sub_number_of_tags;
1000       sub->sub_outer_vlan_id = ntohs (mp->sub_outer_vlan_id);
1001       sub->sub_inner_vlan_id = ntohs (mp->sub_inner_vlan_id);
1002
1003       /* vlan tag rewrite */
1004       sub->vtr_op = ntohl (mp->vtr_op);
1005       sub->vtr_push_dot1q = ntohl (mp->vtr_push_dot1q);
1006       sub->vtr_tag1 = ntohl (mp->vtr_tag1);
1007       sub->vtr_tag2 = ntohl (mp->vtr_tag2);
1008     }
1009 }
1010
1011 static void vl_api_sw_interface_details_t_handler_json
1012   (vl_api_sw_interface_details_t * mp)
1013 {
1014   vat_main_t *vam = &vat_main;
1015   vat_json_node_t *node = NULL;
1016
1017   if (VAT_JSON_ARRAY != vam->json_tree.type)
1018     {
1019       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1020       vat_json_init_array (&vam->json_tree);
1021     }
1022   node = vat_json_array_add (&vam->json_tree);
1023
1024   vat_json_init_object (node);
1025   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
1026   vat_json_object_add_uint (node, "sup_sw_if_index",
1027                             ntohl (mp->sup_sw_if_index));
1028   vat_json_object_add_bytes (node, "l2_address", mp->l2_address,
1029                              sizeof (mp->l2_address));
1030   vat_json_object_add_string_copy (node, "interface_name",
1031                                    mp->interface_name);
1032   vat_json_object_add_string_copy (node, "interface_dev_type",
1033                                    mp->interface_dev_type);
1034   vat_json_object_add_uint (node, "flags", mp->flags);
1035   vat_json_object_add_uint (node, "link_duplex", mp->link_duplex);
1036   vat_json_object_add_uint (node, "link_speed", mp->link_speed);
1037   vat_json_object_add_uint (node, "mtu", ntohs (mp->link_mtu));
1038   vat_json_object_add_uint (node, "sub_id", ntohl (mp->sub_id));
1039   vat_json_object_add_uint (node, "sub_number_of_tags",
1040                             mp->sub_number_of_tags);
1041   vat_json_object_add_uint (node, "sub_outer_vlan_id",
1042                             ntohs (mp->sub_outer_vlan_id));
1043   vat_json_object_add_uint (node, "sub_inner_vlan_id",
1044                             ntohs (mp->sub_inner_vlan_id));
1045   vat_json_object_add_uint (node, "sub_if_flags", ntohl (mp->sub_if_flags));
1046   vat_json_object_add_uint (node, "vtr_op", ntohl (mp->vtr_op));
1047   vat_json_object_add_uint (node, "vtr_push_dot1q",
1048                             ntohl (mp->vtr_push_dot1q));
1049   vat_json_object_add_uint (node, "vtr_tag1", ntohl (mp->vtr_tag1));
1050   vat_json_object_add_uint (node, "vtr_tag2", ntohl (mp->vtr_tag2));
1051   if (ntohl (mp->sub_if_flags) & SUB_IF_API_FLAG_DOT1AH)
1052     {
1053       vat_json_object_add_string_copy (node, "pbb_vtr_dmac",
1054                                        format (0, "%U",
1055                                                format_ethernet_address,
1056                                                &mp->b_dmac));
1057       vat_json_object_add_string_copy (node, "pbb_vtr_smac",
1058                                        format (0, "%U",
1059                                                format_ethernet_address,
1060                                                &mp->b_smac));
1061       vat_json_object_add_uint (node, "pbb_vtr_b_vlanid", mp->b_vlanid);
1062       vat_json_object_add_uint (node, "pbb_vtr_i_sid", mp->i_sid);
1063     }
1064 }
1065
1066 #if VPP_API_TEST_BUILTIN == 0
1067 static void vl_api_sw_interface_event_t_handler
1068   (vl_api_sw_interface_event_t * mp)
1069 {
1070   vat_main_t *vam = &vat_main;
1071   if (vam->interface_event_display)
1072     errmsg ("interface flags: sw_if_index %d %s %s",
1073             ntohl (mp->sw_if_index),
1074             ((ntohl (mp->flags)) & IF_STATUS_API_FLAG_ADMIN_UP) ?
1075             "admin-up" : "admin-down",
1076             ((ntohl (mp->flags)) & IF_STATUS_API_FLAG_LINK_UP) ?
1077             "link-up" : "link-down");
1078 }
1079 #endif
1080
1081 __clib_unused static void
1082 vl_api_sw_interface_event_t_handler_json (vl_api_sw_interface_event_t * mp)
1083 {
1084   /* JSON output not supported */
1085 }
1086
1087 static void
1088 vl_api_cli_reply_t_handler (vl_api_cli_reply_t * mp)
1089 {
1090   vat_main_t *vam = &vat_main;
1091   i32 retval = ntohl (mp->retval);
1092
1093   vam->retval = retval;
1094   vam->shmem_result = uword_to_pointer (mp->reply_in_shmem, u8 *);
1095   vam->result_ready = 1;
1096 }
1097
1098 static void
1099 vl_api_cli_reply_t_handler_json (vl_api_cli_reply_t * mp)
1100 {
1101   vat_main_t *vam = &vat_main;
1102   vat_json_node_t node;
1103   api_main_t *am = &api_main;
1104   void *oldheap;
1105   u8 *reply;
1106
1107   vat_json_init_object (&node);
1108   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1109   vat_json_object_add_uint (&node, "reply_in_shmem",
1110                             ntohl (mp->reply_in_shmem));
1111   /* Toss the shared-memory original... */
1112   pthread_mutex_lock (&am->vlib_rp->mutex);
1113   oldheap = svm_push_data_heap (am->vlib_rp);
1114
1115   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
1116   vec_free (reply);
1117
1118   svm_pop_heap (oldheap);
1119   pthread_mutex_unlock (&am->vlib_rp->mutex);
1120
1121   vat_json_print (vam->ofp, &node);
1122   vat_json_free (&node);
1123
1124   vam->retval = ntohl (mp->retval);
1125   vam->result_ready = 1;
1126 }
1127
1128 static void
1129 vl_api_cli_inband_reply_t_handler (vl_api_cli_inband_reply_t * mp)
1130 {
1131   vat_main_t *vam = &vat_main;
1132   i32 retval = ntohl (mp->retval);
1133   u32 length = vl_api_string_len (&mp->reply);
1134
1135   vec_reset_length (vam->cmd_reply);
1136
1137   vam->retval = retval;
1138   if (retval == 0)
1139     {
1140       vec_validate (vam->cmd_reply, length);
1141       clib_memcpy ((char *) (vam->cmd_reply),
1142                    vl_api_from_api_string (&mp->reply), length);
1143       vam->cmd_reply[length] = 0;
1144     }
1145   vam->result_ready = 1;
1146 }
1147
1148 static void
1149 vl_api_cli_inband_reply_t_handler_json (vl_api_cli_inband_reply_t * mp)
1150 {
1151   vat_main_t *vam = &vat_main;
1152   vat_json_node_t node;
1153
1154   vec_reset_length (vam->cmd_reply);
1155
1156   vat_json_init_object (&node);
1157   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1158   vat_json_object_add_string_copy (&node, "reply",
1159                                    vl_api_from_api_string (&mp->reply));
1160
1161   vat_json_print (vam->ofp, &node);
1162   vat_json_free (&node);
1163
1164   vam->retval = ntohl (mp->retval);
1165   vam->result_ready = 1;
1166 }
1167
1168 static void vl_api_classify_add_del_table_reply_t_handler
1169   (vl_api_classify_add_del_table_reply_t * mp)
1170 {
1171   vat_main_t *vam = &vat_main;
1172   i32 retval = ntohl (mp->retval);
1173   if (vam->async_mode)
1174     {
1175       vam->async_errors += (retval < 0);
1176     }
1177   else
1178     {
1179       vam->retval = retval;
1180       if (retval == 0 &&
1181           ((mp->new_table_index != 0xFFFFFFFF) ||
1182            (mp->skip_n_vectors != 0xFFFFFFFF) ||
1183            (mp->match_n_vectors != 0xFFFFFFFF)))
1184         /*
1185          * Note: this is just barely thread-safe, depends on
1186          * the main thread spinning waiting for an answer...
1187          */
1188         errmsg ("new index %d, skip_n_vectors %d, match_n_vectors %d",
1189                 ntohl (mp->new_table_index),
1190                 ntohl (mp->skip_n_vectors), ntohl (mp->match_n_vectors));
1191       vam->result_ready = 1;
1192     }
1193 }
1194
1195 static void vl_api_classify_add_del_table_reply_t_handler_json
1196   (vl_api_classify_add_del_table_reply_t * mp)
1197 {
1198   vat_main_t *vam = &vat_main;
1199   vat_json_node_t node;
1200
1201   vat_json_init_object (&node);
1202   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1203   vat_json_object_add_uint (&node, "new_table_index",
1204                             ntohl (mp->new_table_index));
1205   vat_json_object_add_uint (&node, "skip_n_vectors",
1206                             ntohl (mp->skip_n_vectors));
1207   vat_json_object_add_uint (&node, "match_n_vectors",
1208                             ntohl (mp->match_n_vectors));
1209
1210   vat_json_print (vam->ofp, &node);
1211   vat_json_free (&node);
1212
1213   vam->retval = ntohl (mp->retval);
1214   vam->result_ready = 1;
1215 }
1216
1217 static void vl_api_get_node_index_reply_t_handler
1218   (vl_api_get_node_index_reply_t * mp)
1219 {
1220   vat_main_t *vam = &vat_main;
1221   i32 retval = ntohl (mp->retval);
1222   if (vam->async_mode)
1223     {
1224       vam->async_errors += (retval < 0);
1225     }
1226   else
1227     {
1228       vam->retval = retval;
1229       if (retval == 0)
1230         errmsg ("node index %d", ntohl (mp->node_index));
1231       vam->result_ready = 1;
1232     }
1233 }
1234
1235 static void vl_api_get_node_index_reply_t_handler_json
1236   (vl_api_get_node_index_reply_t * mp)
1237 {
1238   vat_main_t *vam = &vat_main;
1239   vat_json_node_t node;
1240
1241   vat_json_init_object (&node);
1242   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1243   vat_json_object_add_uint (&node, "node_index", ntohl (mp->node_index));
1244
1245   vat_json_print (vam->ofp, &node);
1246   vat_json_free (&node);
1247
1248   vam->retval = ntohl (mp->retval);
1249   vam->result_ready = 1;
1250 }
1251
1252 static void vl_api_get_next_index_reply_t_handler
1253   (vl_api_get_next_index_reply_t * mp)
1254 {
1255   vat_main_t *vam = &vat_main;
1256   i32 retval = ntohl (mp->retval);
1257   if (vam->async_mode)
1258     {
1259       vam->async_errors += (retval < 0);
1260     }
1261   else
1262     {
1263       vam->retval = retval;
1264       if (retval == 0)
1265         errmsg ("next node index %d", ntohl (mp->next_index));
1266       vam->result_ready = 1;
1267     }
1268 }
1269
1270 static void vl_api_get_next_index_reply_t_handler_json
1271   (vl_api_get_next_index_reply_t * mp)
1272 {
1273   vat_main_t *vam = &vat_main;
1274   vat_json_node_t node;
1275
1276   vat_json_init_object (&node);
1277   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1278   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1279
1280   vat_json_print (vam->ofp, &node);
1281   vat_json_free (&node);
1282
1283   vam->retval = ntohl (mp->retval);
1284   vam->result_ready = 1;
1285 }
1286
1287 static void vl_api_add_node_next_reply_t_handler
1288   (vl_api_add_node_next_reply_t * mp)
1289 {
1290   vat_main_t *vam = &vat_main;
1291   i32 retval = ntohl (mp->retval);
1292   if (vam->async_mode)
1293     {
1294       vam->async_errors += (retval < 0);
1295     }
1296   else
1297     {
1298       vam->retval = retval;
1299       if (retval == 0)
1300         errmsg ("next index %d", ntohl (mp->next_index));
1301       vam->result_ready = 1;
1302     }
1303 }
1304
1305 static void vl_api_add_node_next_reply_t_handler_json
1306   (vl_api_add_node_next_reply_t * mp)
1307 {
1308   vat_main_t *vam = &vat_main;
1309   vat_json_node_t node;
1310
1311   vat_json_init_object (&node);
1312   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1313   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1314
1315   vat_json_print (vam->ofp, &node);
1316   vat_json_free (&node);
1317
1318   vam->retval = ntohl (mp->retval);
1319   vam->result_ready = 1;
1320 }
1321
1322 static void vl_api_show_version_reply_t_handler
1323   (vl_api_show_version_reply_t * mp)
1324 {
1325   vat_main_t *vam = &vat_main;
1326   i32 retval = ntohl (mp->retval);
1327
1328   if (retval >= 0)
1329     {
1330       errmsg ("        program: %s", mp->program);
1331       errmsg ("        version: %s", mp->version);
1332       errmsg ("     build date: %s", mp->build_date);
1333       errmsg ("build directory: %s", mp->build_directory);
1334     }
1335   vam->retval = retval;
1336   vam->result_ready = 1;
1337 }
1338
1339 static void vl_api_show_version_reply_t_handler_json
1340   (vl_api_show_version_reply_t * mp)
1341 {
1342   vat_main_t *vam = &vat_main;
1343   vat_json_node_t node;
1344
1345   vat_json_init_object (&node);
1346   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1347   vat_json_object_add_string_copy (&node, "program", mp->program);
1348   vat_json_object_add_string_copy (&node, "version", mp->version);
1349   vat_json_object_add_string_copy (&node, "build_date", mp->build_date);
1350   vat_json_object_add_string_copy (&node, "build_directory",
1351                                    mp->build_directory);
1352
1353   vat_json_print (vam->ofp, &node);
1354   vat_json_free (&node);
1355
1356   vam->retval = ntohl (mp->retval);
1357   vam->result_ready = 1;
1358 }
1359
1360 static void vl_api_show_threads_reply_t_handler
1361   (vl_api_show_threads_reply_t * mp)
1362 {
1363   vat_main_t *vam = &vat_main;
1364   i32 retval = ntohl (mp->retval);
1365   int i, count = 0;
1366
1367   if (retval >= 0)
1368     count = ntohl (mp->count);
1369
1370   for (i = 0; i < count; i++)
1371     print (vam->ofp,
1372            "\n%-2d %-11s %-11s %-5d %-6d %-4d %-6d",
1373            ntohl (mp->thread_data[i].id), mp->thread_data[i].name,
1374            mp->thread_data[i].type, ntohl (mp->thread_data[i].pid),
1375            ntohl (mp->thread_data[i].cpu_id), ntohl (mp->thread_data[i].core),
1376            ntohl (mp->thread_data[i].cpu_socket));
1377
1378   vam->retval = retval;
1379   vam->result_ready = 1;
1380 }
1381
1382 static void vl_api_show_threads_reply_t_handler_json
1383   (vl_api_show_threads_reply_t * mp)
1384 {
1385   vat_main_t *vam = &vat_main;
1386   vat_json_node_t node;
1387   vl_api_thread_data_t *td;
1388   i32 retval = ntohl (mp->retval);
1389   int i, count = 0;
1390
1391   if (retval >= 0)
1392     count = ntohl (mp->count);
1393
1394   vat_json_init_object (&node);
1395   vat_json_object_add_int (&node, "retval", retval);
1396   vat_json_object_add_uint (&node, "count", count);
1397
1398   for (i = 0; i < count; i++)
1399     {
1400       td = &mp->thread_data[i];
1401       vat_json_object_add_uint (&node, "id", ntohl (td->id));
1402       vat_json_object_add_string_copy (&node, "name", td->name);
1403       vat_json_object_add_string_copy (&node, "type", td->type);
1404       vat_json_object_add_uint (&node, "pid", ntohl (td->pid));
1405       vat_json_object_add_int (&node, "cpu_id", ntohl (td->cpu_id));
1406       vat_json_object_add_int (&node, "core", ntohl (td->id));
1407       vat_json_object_add_int (&node, "cpu_socket", ntohl (td->cpu_socket));
1408     }
1409
1410   vat_json_print (vam->ofp, &node);
1411   vat_json_free (&node);
1412
1413   vam->retval = retval;
1414   vam->result_ready = 1;
1415 }
1416
1417 static int
1418 api_show_threads (vat_main_t * vam)
1419 {
1420   vl_api_show_threads_t *mp;
1421   int ret;
1422
1423   print (vam->ofp,
1424          "\n%-2s %-11s %-11s %-5s %-6s %-4s %-6s",
1425          "ID", "Name", "Type", "LWP", "cpu_id", "Core", "Socket");
1426
1427   M (SHOW_THREADS, mp);
1428
1429   S (mp);
1430   W (ret);
1431   return ret;
1432 }
1433
1434 static void
1435 vl_api_ip4_arp_event_t_handler (vl_api_ip4_arp_event_t * mp)
1436 {
1437   u32 sw_if_index = ntohl (mp->sw_if_index);
1438   errmsg ("arp %s event: pid %d address %U new mac %U sw_if_index %d\n",
1439           mp->mac_ip ? "mac/ip binding" : "address resolution",
1440           ntohl (mp->pid), format_ip4_address, mp->ip,
1441           format_vl_api_mac_address, &mp->mac, sw_if_index);
1442 }
1443
1444 static void
1445 vl_api_ip4_arp_event_t_handler_json (vl_api_ip4_arp_event_t * mp)
1446 {
1447   /* JSON output not supported */
1448 }
1449
1450 static void
1451 vl_api_ip6_nd_event_t_handler (vl_api_ip6_nd_event_t * mp)
1452 {
1453   u32 sw_if_index = ntohl (mp->sw_if_index);
1454   errmsg ("ip6 nd %s event: pid %d address %U new mac %U sw_if_index %d\n",
1455           mp->mac_ip ? "mac/ip binding" : "address resolution",
1456           ntohl (mp->pid), format_vl_api_ip6_address, mp->ip,
1457           format_vl_api_mac_address, mp->mac, sw_if_index);
1458 }
1459
1460 static void
1461 vl_api_ip6_nd_event_t_handler_json (vl_api_ip6_nd_event_t * mp)
1462 {
1463   /* JSON output not supported */
1464 }
1465
1466 static void
1467 vl_api_l2_macs_event_t_handler (vl_api_l2_macs_event_t * mp)
1468 {
1469   u32 n_macs = ntohl (mp->n_macs);
1470   errmsg ("L2MAC event received with pid %d cl-idx %d for %d macs: \n",
1471           ntohl (mp->pid), mp->client_index, n_macs);
1472   int i;
1473   for (i = 0; i < n_macs; i++)
1474     {
1475       vl_api_mac_entry_t *mac = &mp->mac[i];
1476       errmsg (" [%d] sw_if_index %d  mac_addr %U  action %d \n",
1477               i + 1, ntohl (mac->sw_if_index),
1478               format_ethernet_address, mac->mac_addr, mac->action);
1479       if (i == 1000)
1480         break;
1481     }
1482 }
1483
1484 static void
1485 vl_api_l2_macs_event_t_handler_json (vl_api_l2_macs_event_t * mp)
1486 {
1487   /* JSON output not supported */
1488 }
1489
1490 #define vl_api_bridge_domain_details_t_endian vl_noop_handler
1491 #define vl_api_bridge_domain_details_t_print vl_noop_handler
1492
1493 /*
1494  * Special-case: build the bridge domain table, maintain
1495  * the next bd id vbl.
1496  */
1497 static void vl_api_bridge_domain_details_t_handler
1498   (vl_api_bridge_domain_details_t * mp)
1499 {
1500   vat_main_t *vam = &vat_main;
1501   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1502   int i;
1503
1504   print (vam->ofp, "\n%-3s %-3s %-3s %-3s %-3s %-6s %-3s",
1505          " ID", "LRN", "FWD", "FLD", "BVI", "UU-FWD", "#IF");
1506
1507   print (vam->ofp, "%3d %3d %3d %3d %3d %6d %3d",
1508          ntohl (mp->bd_id), mp->learn, mp->forward,
1509          mp->flood, ntohl (mp->bvi_sw_if_index),
1510          ntohl (mp->uu_fwd_sw_if_index), n_sw_ifs);
1511
1512   if (n_sw_ifs)
1513     {
1514       vl_api_bridge_domain_sw_if_t *sw_ifs;
1515       print (vam->ofp, "\n\n%s %s  %s", "sw_if_index", "SHG",
1516              "Interface Name");
1517
1518       sw_ifs = mp->sw_if_details;
1519       for (i = 0; i < n_sw_ifs; i++)
1520         {
1521           u8 *sw_if_name = 0;
1522           u32 sw_if_index;
1523           hash_pair_t *p;
1524
1525           sw_if_index = ntohl (sw_ifs->sw_if_index);
1526
1527           /* *INDENT-OFF* */
1528           hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
1529                              ({
1530                                if ((u32) p->value[0] == sw_if_index)
1531                                  {
1532                                    sw_if_name = (u8 *)(p->key);
1533                                    break;
1534                                  }
1535                              }));
1536           /* *INDENT-ON* */
1537           print (vam->ofp, "%7d     %3d  %s", sw_if_index,
1538                  sw_ifs->shg, sw_if_name ? (char *) sw_if_name :
1539                  "sw_if_index not found!");
1540
1541           sw_ifs++;
1542         }
1543     }
1544 }
1545
1546 static void vl_api_bridge_domain_details_t_handler_json
1547   (vl_api_bridge_domain_details_t * mp)
1548 {
1549   vat_main_t *vam = &vat_main;
1550   vat_json_node_t *node, *array = NULL;
1551   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1552
1553   if (VAT_JSON_ARRAY != vam->json_tree.type)
1554     {
1555       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1556       vat_json_init_array (&vam->json_tree);
1557     }
1558   node = vat_json_array_add (&vam->json_tree);
1559
1560   vat_json_init_object (node);
1561   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1562   vat_json_object_add_uint (node, "flood", mp->flood);
1563   vat_json_object_add_uint (node, "forward", mp->forward);
1564   vat_json_object_add_uint (node, "learn", mp->learn);
1565   vat_json_object_add_uint (node, "bvi_sw_if_index",
1566                             ntohl (mp->bvi_sw_if_index));
1567   vat_json_object_add_uint (node, "n_sw_ifs", n_sw_ifs);
1568   array = vat_json_object_add (node, "sw_if");
1569   vat_json_init_array (array);
1570
1571
1572
1573   if (n_sw_ifs)
1574     {
1575       vl_api_bridge_domain_sw_if_t *sw_ifs;
1576       int i;
1577
1578       sw_ifs = mp->sw_if_details;
1579       for (i = 0; i < n_sw_ifs; i++)
1580         {
1581           node = vat_json_array_add (array);
1582           vat_json_init_object (node);
1583           vat_json_object_add_uint (node, "sw_if_index",
1584                                     ntohl (sw_ifs->sw_if_index));
1585           vat_json_object_add_uint (node, "shg", sw_ifs->shg);
1586           sw_ifs++;
1587         }
1588     }
1589 }
1590
1591 static void vl_api_control_ping_reply_t_handler
1592   (vl_api_control_ping_reply_t * mp)
1593 {
1594   vat_main_t *vam = &vat_main;
1595   i32 retval = ntohl (mp->retval);
1596   if (vam->async_mode)
1597     {
1598       vam->async_errors += (retval < 0);
1599     }
1600   else
1601     {
1602       vam->retval = retval;
1603       vam->result_ready = 1;
1604     }
1605   if (vam->socket_client_main)
1606     vam->socket_client_main->control_pings_outstanding--;
1607 }
1608
1609 static void vl_api_control_ping_reply_t_handler_json
1610   (vl_api_control_ping_reply_t * mp)
1611 {
1612   vat_main_t *vam = &vat_main;
1613   i32 retval = ntohl (mp->retval);
1614
1615   if (VAT_JSON_NONE != vam->json_tree.type)
1616     {
1617       vat_json_print (vam->ofp, &vam->json_tree);
1618       vat_json_free (&vam->json_tree);
1619       vam->json_tree.type = VAT_JSON_NONE;
1620     }
1621   else
1622     {
1623       /* just print [] */
1624       vat_json_init_array (&vam->json_tree);
1625       vat_json_print (vam->ofp, &vam->json_tree);
1626       vam->json_tree.type = VAT_JSON_NONE;
1627     }
1628
1629   vam->retval = retval;
1630   vam->result_ready = 1;
1631 }
1632
1633 static void
1634   vl_api_bridge_domain_set_mac_age_reply_t_handler
1635   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1636 {
1637   vat_main_t *vam = &vat_main;
1638   i32 retval = ntohl (mp->retval);
1639   if (vam->async_mode)
1640     {
1641       vam->async_errors += (retval < 0);
1642     }
1643   else
1644     {
1645       vam->retval = retval;
1646       vam->result_ready = 1;
1647     }
1648 }
1649
1650 static void vl_api_bridge_domain_set_mac_age_reply_t_handler_json
1651   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1652 {
1653   vat_main_t *vam = &vat_main;
1654   vat_json_node_t node;
1655
1656   vat_json_init_object (&node);
1657   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1658
1659   vat_json_print (vam->ofp, &node);
1660   vat_json_free (&node);
1661
1662   vam->retval = ntohl (mp->retval);
1663   vam->result_ready = 1;
1664 }
1665
1666 static void
1667 vl_api_l2_flags_reply_t_handler (vl_api_l2_flags_reply_t * mp)
1668 {
1669   vat_main_t *vam = &vat_main;
1670   i32 retval = ntohl (mp->retval);
1671   if (vam->async_mode)
1672     {
1673       vam->async_errors += (retval < 0);
1674     }
1675   else
1676     {
1677       vam->retval = retval;
1678       vam->result_ready = 1;
1679     }
1680 }
1681
1682 static void vl_api_l2_flags_reply_t_handler_json
1683   (vl_api_l2_flags_reply_t * mp)
1684 {
1685   vat_main_t *vam = &vat_main;
1686   vat_json_node_t node;
1687
1688   vat_json_init_object (&node);
1689   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1690   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1691                             ntohl (mp->resulting_feature_bitmap));
1692
1693   vat_json_print (vam->ofp, &node);
1694   vat_json_free (&node);
1695
1696   vam->retval = ntohl (mp->retval);
1697   vam->result_ready = 1;
1698 }
1699
1700 static void vl_api_bridge_flags_reply_t_handler
1701   (vl_api_bridge_flags_reply_t * mp)
1702 {
1703   vat_main_t *vam = &vat_main;
1704   i32 retval = ntohl (mp->retval);
1705   if (vam->async_mode)
1706     {
1707       vam->async_errors += (retval < 0);
1708     }
1709   else
1710     {
1711       vam->retval = retval;
1712       vam->result_ready = 1;
1713     }
1714 }
1715
1716 static void vl_api_bridge_flags_reply_t_handler_json
1717   (vl_api_bridge_flags_reply_t * mp)
1718 {
1719   vat_main_t *vam = &vat_main;
1720   vat_json_node_t node;
1721
1722   vat_json_init_object (&node);
1723   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1724   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1725                             ntohl (mp->resulting_feature_bitmap));
1726
1727   vat_json_print (vam->ofp, &node);
1728   vat_json_free (&node);
1729
1730   vam->retval = ntohl (mp->retval);
1731   vam->result_ready = 1;
1732 }
1733
1734 static void
1735 vl_api_tap_create_v2_reply_t_handler (vl_api_tap_create_v2_reply_t * mp)
1736 {
1737   vat_main_t *vam = &vat_main;
1738   i32 retval = ntohl (mp->retval);
1739   if (vam->async_mode)
1740     {
1741       vam->async_errors += (retval < 0);
1742     }
1743   else
1744     {
1745       vam->retval = retval;
1746       vam->sw_if_index = ntohl (mp->sw_if_index);
1747       vam->result_ready = 1;
1748     }
1749
1750 }
1751
1752 static void vl_api_tap_create_v2_reply_t_handler_json
1753   (vl_api_tap_create_v2_reply_t * mp)
1754 {
1755   vat_main_t *vam = &vat_main;
1756   vat_json_node_t node;
1757
1758   vat_json_init_object (&node);
1759   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1760   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1761
1762   vat_json_print (vam->ofp, &node);
1763   vat_json_free (&node);
1764
1765   vam->retval = ntohl (mp->retval);
1766   vam->result_ready = 1;
1767
1768 }
1769
1770 static void
1771 vl_api_tap_delete_v2_reply_t_handler (vl_api_tap_delete_v2_reply_t * mp)
1772 {
1773   vat_main_t *vam = &vat_main;
1774   i32 retval = ntohl (mp->retval);
1775   if (vam->async_mode)
1776     {
1777       vam->async_errors += (retval < 0);
1778     }
1779   else
1780     {
1781       vam->retval = retval;
1782       vam->result_ready = 1;
1783     }
1784 }
1785
1786 static void vl_api_tap_delete_v2_reply_t_handler_json
1787   (vl_api_tap_delete_v2_reply_t * mp)
1788 {
1789   vat_main_t *vam = &vat_main;
1790   vat_json_node_t node;
1791
1792   vat_json_init_object (&node);
1793   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1794
1795   vat_json_print (vam->ofp, &node);
1796   vat_json_free (&node);
1797
1798   vam->retval = ntohl (mp->retval);
1799   vam->result_ready = 1;
1800 }
1801
1802 static void
1803 vl_api_virtio_pci_create_reply_t_handler (vl_api_virtio_pci_create_reply_t *
1804                                           mp)
1805 {
1806   vat_main_t *vam = &vat_main;
1807   i32 retval = ntohl (mp->retval);
1808   if (vam->async_mode)
1809     {
1810       vam->async_errors += (retval < 0);
1811     }
1812   else
1813     {
1814       vam->retval = retval;
1815       vam->sw_if_index = ntohl (mp->sw_if_index);
1816       vam->result_ready = 1;
1817     }
1818 }
1819
1820 static void vl_api_virtio_pci_create_reply_t_handler_json
1821   (vl_api_virtio_pci_create_reply_t * mp)
1822 {
1823   vat_main_t *vam = &vat_main;
1824   vat_json_node_t node;
1825
1826   vat_json_init_object (&node);
1827   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1828   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1829
1830   vat_json_print (vam->ofp, &node);
1831   vat_json_free (&node);
1832
1833   vam->retval = ntohl (mp->retval);
1834   vam->result_ready = 1;
1835
1836 }
1837
1838 static void
1839 vl_api_virtio_pci_delete_reply_t_handler (vl_api_virtio_pci_delete_reply_t *
1840                                           mp)
1841 {
1842   vat_main_t *vam = &vat_main;
1843   i32 retval = ntohl (mp->retval);
1844   if (vam->async_mode)
1845     {
1846       vam->async_errors += (retval < 0);
1847     }
1848   else
1849     {
1850       vam->retval = retval;
1851       vam->result_ready = 1;
1852     }
1853 }
1854
1855 static void vl_api_virtio_pci_delete_reply_t_handler_json
1856   (vl_api_virtio_pci_delete_reply_t * mp)
1857 {
1858   vat_main_t *vam = &vat_main;
1859   vat_json_node_t node;
1860
1861   vat_json_init_object (&node);
1862   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1863
1864   vat_json_print (vam->ofp, &node);
1865   vat_json_free (&node);
1866
1867   vam->retval = ntohl (mp->retval);
1868   vam->result_ready = 1;
1869 }
1870
1871 static void
1872 vl_api_bond_create_reply_t_handler (vl_api_bond_create_reply_t * mp)
1873 {
1874   vat_main_t *vam = &vat_main;
1875   i32 retval = ntohl (mp->retval);
1876
1877   if (vam->async_mode)
1878     {
1879       vam->async_errors += (retval < 0);
1880     }
1881   else
1882     {
1883       vam->retval = retval;
1884       vam->sw_if_index = ntohl (mp->sw_if_index);
1885       vam->result_ready = 1;
1886     }
1887 }
1888
1889 static void vl_api_bond_create_reply_t_handler_json
1890   (vl_api_bond_create_reply_t * mp)
1891 {
1892   vat_main_t *vam = &vat_main;
1893   vat_json_node_t node;
1894
1895   vat_json_init_object (&node);
1896   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1897   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1898
1899   vat_json_print (vam->ofp, &node);
1900   vat_json_free (&node);
1901
1902   vam->retval = ntohl (mp->retval);
1903   vam->result_ready = 1;
1904 }
1905
1906 static void
1907 vl_api_bond_delete_reply_t_handler (vl_api_bond_delete_reply_t * mp)
1908 {
1909   vat_main_t *vam = &vat_main;
1910   i32 retval = ntohl (mp->retval);
1911
1912   if (vam->async_mode)
1913     {
1914       vam->async_errors += (retval < 0);
1915     }
1916   else
1917     {
1918       vam->retval = retval;
1919       vam->result_ready = 1;
1920     }
1921 }
1922
1923 static void vl_api_bond_delete_reply_t_handler_json
1924   (vl_api_bond_delete_reply_t * mp)
1925 {
1926   vat_main_t *vam = &vat_main;
1927   vat_json_node_t node;
1928
1929   vat_json_init_object (&node);
1930   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1931
1932   vat_json_print (vam->ofp, &node);
1933   vat_json_free (&node);
1934
1935   vam->retval = ntohl (mp->retval);
1936   vam->result_ready = 1;
1937 }
1938
1939 static void
1940 vl_api_bond_enslave_reply_t_handler (vl_api_bond_enslave_reply_t * mp)
1941 {
1942   vat_main_t *vam = &vat_main;
1943   i32 retval = ntohl (mp->retval);
1944
1945   if (vam->async_mode)
1946     {
1947       vam->async_errors += (retval < 0);
1948     }
1949   else
1950     {
1951       vam->retval = retval;
1952       vam->result_ready = 1;
1953     }
1954 }
1955
1956 static void vl_api_bond_enslave_reply_t_handler_json
1957   (vl_api_bond_enslave_reply_t * mp)
1958 {
1959   vat_main_t *vam = &vat_main;
1960   vat_json_node_t node;
1961
1962   vat_json_init_object (&node);
1963   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1964
1965   vat_json_print (vam->ofp, &node);
1966   vat_json_free (&node);
1967
1968   vam->retval = ntohl (mp->retval);
1969   vam->result_ready = 1;
1970 }
1971
1972 static void
1973 vl_api_bond_detach_slave_reply_t_handler (vl_api_bond_detach_slave_reply_t *
1974                                           mp)
1975 {
1976   vat_main_t *vam = &vat_main;
1977   i32 retval = ntohl (mp->retval);
1978
1979   if (vam->async_mode)
1980     {
1981       vam->async_errors += (retval < 0);
1982     }
1983   else
1984     {
1985       vam->retval = retval;
1986       vam->result_ready = 1;
1987     }
1988 }
1989
1990 static void vl_api_bond_detach_slave_reply_t_handler_json
1991   (vl_api_bond_detach_slave_reply_t * mp)
1992 {
1993   vat_main_t *vam = &vat_main;
1994   vat_json_node_t node;
1995
1996   vat_json_init_object (&node);
1997   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1998
1999   vat_json_print (vam->ofp, &node);
2000   vat_json_free (&node);
2001
2002   vam->retval = ntohl (mp->retval);
2003   vam->result_ready = 1;
2004 }
2005
2006 static int
2007 api_sw_interface_set_bond_weight (vat_main_t * vam)
2008 {
2009   unformat_input_t *i = vam->input;
2010   vl_api_sw_interface_set_bond_weight_t *mp;
2011   u32 sw_if_index = ~0;
2012   u32 weight = 0;
2013   u8 weight_enter = 0;
2014   int ret;
2015
2016   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2017     {
2018       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
2019         ;
2020       else if (unformat (i, "sw_if_index %d", &sw_if_index))
2021         ;
2022       else if (unformat (i, "weight %u", &weight))
2023         weight_enter = 1;
2024       else
2025         break;
2026     }
2027
2028   if (sw_if_index == ~0)
2029     {
2030       errmsg ("missing interface name or sw_if_index");
2031       return -99;
2032     }
2033   if (weight_enter == 0)
2034     {
2035       errmsg ("missing valid weight");
2036       return -99;
2037     }
2038
2039   /* Construct the API message */
2040   M (SW_INTERFACE_SET_BOND_WEIGHT, mp);
2041   mp->sw_if_index = ntohl (sw_if_index);
2042   mp->weight = ntohl (weight);
2043
2044   S (mp);
2045   W (ret);
2046   return ret;
2047 }
2048
2049 static void vl_api_sw_interface_bond_details_t_handler
2050   (vl_api_sw_interface_bond_details_t * mp)
2051 {
2052   vat_main_t *vam = &vat_main;
2053
2054   print (vam->ofp,
2055          "%-16s %-12d %-12U %-13U %-14u %-14u",
2056          mp->interface_name, ntohl (mp->sw_if_index),
2057          format_bond_mode, ntohl (mp->mode), format_bond_load_balance,
2058          ntohl (mp->lb), ntohl (mp->active_slaves), ntohl (mp->slaves));
2059 }
2060
2061 static void vl_api_sw_interface_bond_details_t_handler_json
2062   (vl_api_sw_interface_bond_details_t * mp)
2063 {
2064   vat_main_t *vam = &vat_main;
2065   vat_json_node_t *node = NULL;
2066
2067   if (VAT_JSON_ARRAY != vam->json_tree.type)
2068     {
2069       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2070       vat_json_init_array (&vam->json_tree);
2071     }
2072   node = vat_json_array_add (&vam->json_tree);
2073
2074   vat_json_init_object (node);
2075   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
2076   vat_json_object_add_string_copy (node, "interface_name",
2077                                    mp->interface_name);
2078   vat_json_object_add_uint (node, "mode", ntohl (mp->mode));
2079   vat_json_object_add_uint (node, "load_balance", ntohl (mp->lb));
2080   vat_json_object_add_uint (node, "active_slaves", ntohl (mp->active_slaves));
2081   vat_json_object_add_uint (node, "slaves", ntohl (mp->slaves));
2082 }
2083
2084 static int
2085 api_sw_interface_bond_dump (vat_main_t * vam)
2086 {
2087   vl_api_sw_interface_bond_dump_t *mp;
2088   vl_api_control_ping_t *mp_ping;
2089   int ret;
2090
2091   print (vam->ofp,
2092          "\n%-16s %-12s %-12s %-13s %-14s %-14s",
2093          "interface name", "sw_if_index", "mode", "load balance",
2094          "active slaves", "slaves");
2095
2096   /* Get list of bond interfaces */
2097   M (SW_INTERFACE_BOND_DUMP, mp);
2098   S (mp);
2099
2100   /* Use a control ping for synchronization */
2101   MPING (CONTROL_PING, mp_ping);
2102   S (mp_ping);
2103
2104   W (ret);
2105   return ret;
2106 }
2107
2108 static void vl_api_sw_interface_slave_details_t_handler
2109   (vl_api_sw_interface_slave_details_t * mp)
2110 {
2111   vat_main_t *vam = &vat_main;
2112
2113   print (vam->ofp,
2114          "%-25s %-12d %-7d %-12d %-10d %-10d", mp->interface_name,
2115          ntohl (mp->sw_if_index), mp->is_passive, mp->is_long_timeout,
2116          ntohl (mp->weight), mp->is_local_numa);
2117 }
2118
2119 static void vl_api_sw_interface_slave_details_t_handler_json
2120   (vl_api_sw_interface_slave_details_t * mp)
2121 {
2122   vat_main_t *vam = &vat_main;
2123   vat_json_node_t *node = NULL;
2124
2125   if (VAT_JSON_ARRAY != vam->json_tree.type)
2126     {
2127       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2128       vat_json_init_array (&vam->json_tree);
2129     }
2130   node = vat_json_array_add (&vam->json_tree);
2131
2132   vat_json_init_object (node);
2133   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
2134   vat_json_object_add_string_copy (node, "interface_name",
2135                                    mp->interface_name);
2136   vat_json_object_add_uint (node, "passive", mp->is_passive);
2137   vat_json_object_add_uint (node, "long_timeout", mp->is_long_timeout);
2138   vat_json_object_add_uint (node, "weight", ntohl (mp->weight));
2139   vat_json_object_add_uint (node, "is_local_numa", mp->is_local_numa);
2140 }
2141
2142 static int
2143 api_sw_interface_slave_dump (vat_main_t * vam)
2144 {
2145   unformat_input_t *i = vam->input;
2146   vl_api_sw_interface_slave_dump_t *mp;
2147   vl_api_control_ping_t *mp_ping;
2148   u32 sw_if_index = ~0;
2149   u8 sw_if_index_set = 0;
2150   int ret;
2151
2152   /* Parse args required to build the message */
2153   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2154     {
2155       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
2156         sw_if_index_set = 1;
2157       else if (unformat (i, "sw_if_index %d", &sw_if_index))
2158         sw_if_index_set = 1;
2159       else
2160         break;
2161     }
2162
2163   if (sw_if_index_set == 0)
2164     {
2165       errmsg ("missing vpp interface name. ");
2166       return -99;
2167     }
2168
2169   print (vam->ofp,
2170          "\n%-25s %-12s %-7s %-12s %-10s %-10s",
2171          "slave interface name", "sw_if_index", "passive", "long_timeout",
2172          "weight", "local numa");
2173
2174   /* Get list of bond interfaces */
2175   M (SW_INTERFACE_SLAVE_DUMP, mp);
2176   mp->sw_if_index = ntohl (sw_if_index);
2177   S (mp);
2178
2179   /* Use a control ping for synchronization */
2180   MPING (CONTROL_PING, mp_ping);
2181   S (mp_ping);
2182
2183   W (ret);
2184   return ret;
2185 }
2186
2187 static void vl_api_mpls_tunnel_add_del_reply_t_handler
2188   (vl_api_mpls_tunnel_add_del_reply_t * mp)
2189 {
2190   vat_main_t *vam = &vat_main;
2191   i32 retval = ntohl (mp->retval);
2192   if (vam->async_mode)
2193     {
2194       vam->async_errors += (retval < 0);
2195     }
2196   else
2197     {
2198       vam->retval = retval;
2199       vam->sw_if_index = ntohl (mp->sw_if_index);
2200       vam->result_ready = 1;
2201     }
2202   vam->regenerate_interface_table = 1;
2203 }
2204
2205 static void vl_api_mpls_tunnel_add_del_reply_t_handler_json
2206   (vl_api_mpls_tunnel_add_del_reply_t * mp)
2207 {
2208   vat_main_t *vam = &vat_main;
2209   vat_json_node_t node;
2210
2211   vat_json_init_object (&node);
2212   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2213   vat_json_object_add_uint (&node, "tunnel_sw_if_index",
2214                             ntohl (mp->sw_if_index));
2215
2216   vat_json_print (vam->ofp, &node);
2217   vat_json_free (&node);
2218
2219   vam->retval = ntohl (mp->retval);
2220   vam->result_ready = 1;
2221 }
2222
2223 static void vl_api_l2tpv3_create_tunnel_reply_t_handler
2224   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
2225 {
2226   vat_main_t *vam = &vat_main;
2227   i32 retval = ntohl (mp->retval);
2228   if (vam->async_mode)
2229     {
2230       vam->async_errors += (retval < 0);
2231     }
2232   else
2233     {
2234       vam->retval = retval;
2235       vam->sw_if_index = ntohl (mp->sw_if_index);
2236       vam->result_ready = 1;
2237     }
2238 }
2239
2240 static void vl_api_l2tpv3_create_tunnel_reply_t_handler_json
2241   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
2242 {
2243   vat_main_t *vam = &vat_main;
2244   vat_json_node_t node;
2245
2246   vat_json_init_object (&node);
2247   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2248   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2249
2250   vat_json_print (vam->ofp, &node);
2251   vat_json_free (&node);
2252
2253   vam->retval = ntohl (mp->retval);
2254   vam->result_ready = 1;
2255 }
2256
2257 static void vl_api_gpe_add_del_fwd_entry_reply_t_handler
2258   (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
2259 {
2260   vat_main_t *vam = &vat_main;
2261   i32 retval = ntohl (mp->retval);
2262   if (vam->async_mode)
2263     {
2264       vam->async_errors += (retval < 0);
2265     }
2266   else
2267     {
2268       vam->retval = retval;
2269       vam->result_ready = 1;
2270     }
2271 }
2272
2273 static void vl_api_gpe_add_del_fwd_entry_reply_t_handler_json
2274   (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
2275 {
2276   vat_main_t *vam = &vat_main;
2277   vat_json_node_t node;
2278
2279   vat_json_init_object (&node);
2280   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2281   vat_json_object_add_uint (&node, "fwd_entry_index",
2282                             clib_net_to_host_u32 (mp->fwd_entry_index));
2283
2284   vat_json_print (vam->ofp, &node);
2285   vat_json_free (&node);
2286
2287   vam->retval = ntohl (mp->retval);
2288   vam->result_ready = 1;
2289 }
2290
2291 u8 *
2292 format_lisp_transport_protocol (u8 * s, va_list * args)
2293 {
2294   u32 proto = va_arg (*args, u32);
2295
2296   switch (proto)
2297     {
2298     case 1:
2299       return format (s, "udp");
2300     case 2:
2301       return format (s, "api");
2302     default:
2303       return 0;
2304     }
2305   return 0;
2306 }
2307
2308 static void vl_api_one_get_transport_protocol_reply_t_handler
2309   (vl_api_one_get_transport_protocol_reply_t * mp)
2310 {
2311   vat_main_t *vam = &vat_main;
2312   i32 retval = ntohl (mp->retval);
2313   if (vam->async_mode)
2314     {
2315       vam->async_errors += (retval < 0);
2316     }
2317   else
2318     {
2319       u32 proto = mp->protocol;
2320       print (vam->ofp, "Transport protocol: %U",
2321              format_lisp_transport_protocol, proto);
2322       vam->retval = retval;
2323       vam->result_ready = 1;
2324     }
2325 }
2326
2327 static void vl_api_one_get_transport_protocol_reply_t_handler_json
2328   (vl_api_one_get_transport_protocol_reply_t * mp)
2329 {
2330   vat_main_t *vam = &vat_main;
2331   vat_json_node_t node;
2332   u8 *s;
2333
2334   s = format (0, "%U", format_lisp_transport_protocol, mp->protocol);
2335   vec_add1 (s, 0);
2336
2337   vat_json_init_object (&node);
2338   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2339   vat_json_object_add_string_copy (&node, "transport-protocol", s);
2340
2341   vec_free (s);
2342   vat_json_print (vam->ofp, &node);
2343   vat_json_free (&node);
2344
2345   vam->retval = ntohl (mp->retval);
2346   vam->result_ready = 1;
2347 }
2348
2349 static void vl_api_one_add_del_locator_set_reply_t_handler
2350   (vl_api_one_add_del_locator_set_reply_t * mp)
2351 {
2352   vat_main_t *vam = &vat_main;
2353   i32 retval = ntohl (mp->retval);
2354   if (vam->async_mode)
2355     {
2356       vam->async_errors += (retval < 0);
2357     }
2358   else
2359     {
2360       vam->retval = retval;
2361       vam->result_ready = 1;
2362     }
2363 }
2364
2365 static void vl_api_one_add_del_locator_set_reply_t_handler_json
2366   (vl_api_one_add_del_locator_set_reply_t * mp)
2367 {
2368   vat_main_t *vam = &vat_main;
2369   vat_json_node_t node;
2370
2371   vat_json_init_object (&node);
2372   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2373   vat_json_object_add_uint (&node, "locator_set_index", ntohl (mp->ls_index));
2374
2375   vat_json_print (vam->ofp, &node);
2376   vat_json_free (&node);
2377
2378   vam->retval = ntohl (mp->retval);
2379   vam->result_ready = 1;
2380 }
2381
2382 static void vl_api_vxlan_add_del_tunnel_reply_t_handler
2383   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
2384 {
2385   vat_main_t *vam = &vat_main;
2386   i32 retval = ntohl (mp->retval);
2387   if (vam->async_mode)
2388     {
2389       vam->async_errors += (retval < 0);
2390     }
2391   else
2392     {
2393       vam->retval = retval;
2394       vam->sw_if_index = ntohl (mp->sw_if_index);
2395       vam->result_ready = 1;
2396     }
2397   vam->regenerate_interface_table = 1;
2398 }
2399
2400 static void vl_api_vxlan_add_del_tunnel_reply_t_handler_json
2401   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
2402 {
2403   vat_main_t *vam = &vat_main;
2404   vat_json_node_t node;
2405
2406   vat_json_init_object (&node);
2407   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2408   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2409
2410   vat_json_print (vam->ofp, &node);
2411   vat_json_free (&node);
2412
2413   vam->retval = ntohl (mp->retval);
2414   vam->result_ready = 1;
2415 }
2416
2417 static void vl_api_vxlan_offload_rx_reply_t_handler
2418   (vl_api_vxlan_offload_rx_reply_t * mp)
2419 {
2420   vat_main_t *vam = &vat_main;
2421   i32 retval = ntohl (mp->retval);
2422   if (vam->async_mode)
2423     {
2424       vam->async_errors += (retval < 0);
2425     }
2426   else
2427     {
2428       vam->retval = retval;
2429       vam->result_ready = 1;
2430     }
2431 }
2432
2433 static void vl_api_vxlan_offload_rx_reply_t_handler_json
2434   (vl_api_vxlan_offload_rx_reply_t * mp)
2435 {
2436   vat_main_t *vam = &vat_main;
2437   vat_json_node_t node;
2438
2439   vat_json_init_object (&node);
2440   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2441
2442   vat_json_print (vam->ofp, &node);
2443   vat_json_free (&node);
2444
2445   vam->retval = ntohl (mp->retval);
2446   vam->result_ready = 1;
2447 }
2448
2449 static void vl_api_geneve_add_del_tunnel_reply_t_handler
2450   (vl_api_geneve_add_del_tunnel_reply_t * mp)
2451 {
2452   vat_main_t *vam = &vat_main;
2453   i32 retval = ntohl (mp->retval);
2454   if (vam->async_mode)
2455     {
2456       vam->async_errors += (retval < 0);
2457     }
2458   else
2459     {
2460       vam->retval = retval;
2461       vam->sw_if_index = ntohl (mp->sw_if_index);
2462       vam->result_ready = 1;
2463     }
2464 }
2465
2466 static void vl_api_geneve_add_del_tunnel_reply_t_handler_json
2467   (vl_api_geneve_add_del_tunnel_reply_t * mp)
2468 {
2469   vat_main_t *vam = &vat_main;
2470   vat_json_node_t node;
2471
2472   vat_json_init_object (&node);
2473   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2474   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2475
2476   vat_json_print (vam->ofp, &node);
2477   vat_json_free (&node);
2478
2479   vam->retval = ntohl (mp->retval);
2480   vam->result_ready = 1;
2481 }
2482
2483 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler
2484   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
2485 {
2486   vat_main_t *vam = &vat_main;
2487   i32 retval = ntohl (mp->retval);
2488   if (vam->async_mode)
2489     {
2490       vam->async_errors += (retval < 0);
2491     }
2492   else
2493     {
2494       vam->retval = retval;
2495       vam->sw_if_index = ntohl (mp->sw_if_index);
2496       vam->result_ready = 1;
2497     }
2498   vam->regenerate_interface_table = 1;
2499 }
2500
2501 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler_json
2502   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
2503 {
2504   vat_main_t *vam = &vat_main;
2505   vat_json_node_t node;
2506
2507   vat_json_init_object (&node);
2508   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2509   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2510
2511   vat_json_print (vam->ofp, &node);
2512   vat_json_free (&node);
2513
2514   vam->retval = ntohl (mp->retval);
2515   vam->result_ready = 1;
2516 }
2517
2518 static void vl_api_gre_tunnel_add_del_reply_t_handler
2519   (vl_api_gre_tunnel_add_del_reply_t * mp)
2520 {
2521   vat_main_t *vam = &vat_main;
2522   i32 retval = ntohl (mp->retval);
2523   if (vam->async_mode)
2524     {
2525       vam->async_errors += (retval < 0);
2526     }
2527   else
2528     {
2529       vam->retval = retval;
2530       vam->sw_if_index = ntohl (mp->sw_if_index);
2531       vam->result_ready = 1;
2532     }
2533 }
2534
2535 static void vl_api_gre_tunnel_add_del_reply_t_handler_json
2536   (vl_api_gre_tunnel_add_del_reply_t * mp)
2537 {
2538   vat_main_t *vam = &vat_main;
2539   vat_json_node_t node;
2540
2541   vat_json_init_object (&node);
2542   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2543   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2544
2545   vat_json_print (vam->ofp, &node);
2546   vat_json_free (&node);
2547
2548   vam->retval = ntohl (mp->retval);
2549   vam->result_ready = 1;
2550 }
2551
2552 static void vl_api_create_vhost_user_if_reply_t_handler
2553   (vl_api_create_vhost_user_if_reply_t * mp)
2554 {
2555   vat_main_t *vam = &vat_main;
2556   i32 retval = ntohl (mp->retval);
2557   if (vam->async_mode)
2558     {
2559       vam->async_errors += (retval < 0);
2560     }
2561   else
2562     {
2563       vam->retval = retval;
2564       vam->sw_if_index = ntohl (mp->sw_if_index);
2565       vam->result_ready = 1;
2566     }
2567   vam->regenerate_interface_table = 1;
2568 }
2569
2570 static void vl_api_create_vhost_user_if_reply_t_handler_json
2571   (vl_api_create_vhost_user_if_reply_t * mp)
2572 {
2573   vat_main_t *vam = &vat_main;
2574   vat_json_node_t node;
2575
2576   vat_json_init_object (&node);
2577   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2578   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2579
2580   vat_json_print (vam->ofp, &node);
2581   vat_json_free (&node);
2582
2583   vam->retval = ntohl (mp->retval);
2584   vam->result_ready = 1;
2585 }
2586
2587 static void vl_api_ip_address_details_t_handler
2588   (vl_api_ip_address_details_t * mp)
2589 {
2590   vat_main_t *vam = &vat_main;
2591   static ip_address_details_t empty_ip_address_details = { {0} };
2592   ip_address_details_t *address = NULL;
2593   ip_details_t *current_ip_details = NULL;
2594   ip_details_t *details = NULL;
2595
2596   details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
2597
2598   if (!details || vam->current_sw_if_index >= vec_len (details)
2599       || !details[vam->current_sw_if_index].present)
2600     {
2601       errmsg ("ip address details arrived but not stored");
2602       errmsg ("ip_dump should be called first");
2603       return;
2604     }
2605
2606   current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
2607
2608 #define addresses (current_ip_details->addr)
2609
2610   vec_validate_init_empty (addresses, vec_len (addresses),
2611                            empty_ip_address_details);
2612
2613   address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
2614
2615   clib_memcpy (&address->ip, &mp->prefix.address.un, sizeof (address->ip));
2616   address->prefix_length = mp->prefix.len;
2617 #undef addresses
2618 }
2619
2620 static void vl_api_ip_address_details_t_handler_json
2621   (vl_api_ip_address_details_t * mp)
2622 {
2623   vat_main_t *vam = &vat_main;
2624   vat_json_node_t *node = NULL;
2625
2626   if (VAT_JSON_ARRAY != vam->json_tree.type)
2627     {
2628       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2629       vat_json_init_array (&vam->json_tree);
2630     }
2631   node = vat_json_array_add (&vam->json_tree);
2632
2633   vat_json_init_object (node);
2634   vat_json_object_add_prefix (node, &mp->prefix);
2635 }
2636
2637 static void
2638 vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
2639 {
2640   vat_main_t *vam = &vat_main;
2641   static ip_details_t empty_ip_details = { 0 };
2642   ip_details_t *ip = NULL;
2643   u32 sw_if_index = ~0;
2644
2645   sw_if_index = ntohl (mp->sw_if_index);
2646
2647   vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2648                            sw_if_index, empty_ip_details);
2649
2650   ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2651                          sw_if_index);
2652
2653   ip->present = 1;
2654 }
2655
2656 static void
2657 vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
2658 {
2659   vat_main_t *vam = &vat_main;
2660
2661   if (VAT_JSON_ARRAY != vam->json_tree.type)
2662     {
2663       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2664       vat_json_init_array (&vam->json_tree);
2665     }
2666   vat_json_array_add_uint (&vam->json_tree,
2667                            clib_net_to_host_u32 (mp->sw_if_index));
2668 }
2669
2670 static void vl_api_get_first_msg_id_reply_t_handler
2671   (vl_api_get_first_msg_id_reply_t * mp)
2672 {
2673   vat_main_t *vam = &vat_main;
2674   i32 retval = ntohl (mp->retval);
2675
2676   if (vam->async_mode)
2677     {
2678       vam->async_errors += (retval < 0);
2679     }
2680   else
2681     {
2682       vam->retval = retval;
2683       vam->result_ready = 1;
2684     }
2685   if (retval >= 0)
2686     {
2687       errmsg ("first message id %d", ntohs (mp->first_msg_id));
2688     }
2689 }
2690
2691 static void vl_api_get_first_msg_id_reply_t_handler_json
2692   (vl_api_get_first_msg_id_reply_t * mp)
2693 {
2694   vat_main_t *vam = &vat_main;
2695   vat_json_node_t node;
2696
2697   vat_json_init_object (&node);
2698   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2699   vat_json_object_add_uint (&node, "first_msg_id",
2700                             (uint) ntohs (mp->first_msg_id));
2701
2702   vat_json_print (vam->ofp, &node);
2703   vat_json_free (&node);
2704
2705   vam->retval = ntohl (mp->retval);
2706   vam->result_ready = 1;
2707 }
2708
2709 static void vl_api_get_node_graph_reply_t_handler
2710   (vl_api_get_node_graph_reply_t * mp)
2711 {
2712   vat_main_t *vam = &vat_main;
2713   api_main_t *am = &api_main;
2714   i32 retval = ntohl (mp->retval);
2715   u8 *pvt_copy, *reply;
2716   void *oldheap;
2717   vlib_node_t *node;
2718   int i;
2719
2720   if (vam->async_mode)
2721     {
2722       vam->async_errors += (retval < 0);
2723     }
2724   else
2725     {
2726       vam->retval = retval;
2727       vam->result_ready = 1;
2728     }
2729
2730   /* "Should never happen..." */
2731   if (retval != 0)
2732     return;
2733
2734   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2735   pvt_copy = vec_dup (reply);
2736
2737   /* Toss the shared-memory original... */
2738   pthread_mutex_lock (&am->vlib_rp->mutex);
2739   oldheap = svm_push_data_heap (am->vlib_rp);
2740
2741   vec_free (reply);
2742
2743   svm_pop_heap (oldheap);
2744   pthread_mutex_unlock (&am->vlib_rp->mutex);
2745
2746   if (vam->graph_nodes)
2747     {
2748       hash_free (vam->graph_node_index_by_name);
2749
2750       for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
2751         {
2752           node = vam->graph_nodes[0][i];
2753           vec_free (node->name);
2754           vec_free (node->next_nodes);
2755           vec_free (node);
2756         }
2757       vec_free (vam->graph_nodes[0]);
2758       vec_free (vam->graph_nodes);
2759     }
2760
2761   vam->graph_node_index_by_name = hash_create_string (0, sizeof (uword));
2762   vam->graph_nodes = vlib_node_unserialize (pvt_copy);
2763   vec_free (pvt_copy);
2764
2765   for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
2766     {
2767       node = vam->graph_nodes[0][i];
2768       hash_set_mem (vam->graph_node_index_by_name, node->name, i);
2769     }
2770 }
2771
2772 static void vl_api_get_node_graph_reply_t_handler_json
2773   (vl_api_get_node_graph_reply_t * mp)
2774 {
2775   vat_main_t *vam = &vat_main;
2776   api_main_t *am = &api_main;
2777   void *oldheap;
2778   vat_json_node_t node;
2779   u8 *reply;
2780
2781   /* $$$$ make this real? */
2782   vat_json_init_object (&node);
2783   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2784   vat_json_object_add_uint (&node, "reply_in_shmem", mp->reply_in_shmem);
2785
2786   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2787
2788   /* Toss the shared-memory original... */
2789   pthread_mutex_lock (&am->vlib_rp->mutex);
2790   oldheap = svm_push_data_heap (am->vlib_rp);
2791
2792   vec_free (reply);
2793
2794   svm_pop_heap (oldheap);
2795   pthread_mutex_unlock (&am->vlib_rp->mutex);
2796
2797   vat_json_print (vam->ofp, &node);
2798   vat_json_free (&node);
2799
2800   vam->retval = ntohl (mp->retval);
2801   vam->result_ready = 1;
2802 }
2803
2804 static void
2805 vl_api_one_locator_details_t_handler (vl_api_one_locator_details_t * mp)
2806 {
2807   vat_main_t *vam = &vat_main;
2808   u8 *s = 0;
2809
2810   if (mp->local)
2811     {
2812       s = format (s, "%=16d%=16d%=16d",
2813                   ntohl (mp->sw_if_index), mp->priority, mp->weight);
2814     }
2815   else
2816     {
2817       s = format (s, "%=16U%=16d%=16d",
2818                   mp->is_ipv6 ? format_ip6_address :
2819                   format_ip4_address,
2820                   mp->ip_address, mp->priority, mp->weight);
2821     }
2822
2823   print (vam->ofp, "%v", s);
2824   vec_free (s);
2825 }
2826
2827 static void
2828 vl_api_one_locator_details_t_handler_json (vl_api_one_locator_details_t * mp)
2829 {
2830   vat_main_t *vam = &vat_main;
2831   vat_json_node_t *node = NULL;
2832   struct in6_addr ip6;
2833   struct in_addr ip4;
2834
2835   if (VAT_JSON_ARRAY != vam->json_tree.type)
2836     {
2837       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2838       vat_json_init_array (&vam->json_tree);
2839     }
2840   node = vat_json_array_add (&vam->json_tree);
2841   vat_json_init_object (node);
2842
2843   vat_json_object_add_uint (node, "local", mp->local ? 1 : 0);
2844   vat_json_object_add_uint (node, "priority", mp->priority);
2845   vat_json_object_add_uint (node, "weight", mp->weight);
2846
2847   if (mp->local)
2848     vat_json_object_add_uint (node, "sw_if_index",
2849                               clib_net_to_host_u32 (mp->sw_if_index));
2850   else
2851     {
2852       if (mp->is_ipv6)
2853         {
2854           clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2855           vat_json_object_add_ip6 (node, "address", ip6);
2856         }
2857       else
2858         {
2859           clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2860           vat_json_object_add_ip4 (node, "address", ip4);
2861         }
2862     }
2863 }
2864
2865 static void
2866 vl_api_one_locator_set_details_t_handler (vl_api_one_locator_set_details_t *
2867                                           mp)
2868 {
2869   vat_main_t *vam = &vat_main;
2870   u8 *ls_name = 0;
2871
2872   ls_name = format (0, "%s", mp->ls_name);
2873
2874   print (vam->ofp, "%=10d%=15v", clib_net_to_host_u32 (mp->ls_index),
2875          ls_name);
2876   vec_free (ls_name);
2877 }
2878
2879 static void
2880   vl_api_one_locator_set_details_t_handler_json
2881   (vl_api_one_locator_set_details_t * mp)
2882 {
2883   vat_main_t *vam = &vat_main;
2884   vat_json_node_t *node = 0;
2885   u8 *ls_name = 0;
2886
2887   ls_name = format (0, "%s", mp->ls_name);
2888   vec_add1 (ls_name, 0);
2889
2890   if (VAT_JSON_ARRAY != vam->json_tree.type)
2891     {
2892       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2893       vat_json_init_array (&vam->json_tree);
2894     }
2895   node = vat_json_array_add (&vam->json_tree);
2896
2897   vat_json_init_object (node);
2898   vat_json_object_add_string_copy (node, "ls_name", ls_name);
2899   vat_json_object_add_uint (node, "ls_index",
2900                             clib_net_to_host_u32 (mp->ls_index));
2901   vec_free (ls_name);
2902 }
2903
2904 typedef struct
2905 {
2906   u32 spi;
2907   u8 si;
2908 } __attribute__ ((__packed__)) lisp_nsh_api_t;
2909
2910 uword
2911 unformat_nsh_address (unformat_input_t * input, va_list * args)
2912 {
2913   lisp_nsh_api_t *nsh = va_arg (*args, lisp_nsh_api_t *);
2914   return unformat (input, "SPI:%d SI:%d", &nsh->spi, &nsh->si);
2915 }
2916
2917 u8 *
2918 format_nsh_address_vat (u8 * s, va_list * args)
2919 {
2920   nsh_t *a = va_arg (*args, nsh_t *);
2921   return format (s, "SPI:%d SI:%d", clib_net_to_host_u32 (a->spi), a->si);
2922 }
2923
2924 static u8 *
2925 format_lisp_flat_eid (u8 * s, va_list * args)
2926 {
2927   u32 type = va_arg (*args, u32);
2928   u8 *eid = va_arg (*args, u8 *);
2929   u32 eid_len = va_arg (*args, u32);
2930
2931   switch (type)
2932     {
2933     case 0:
2934       return format (s, "%U/%d", format_ip4_address, eid, eid_len);
2935     case 1:
2936       return format (s, "%U/%d", format_ip6_address, eid, eid_len);
2937     case 2:
2938       return format (s, "%U", format_ethernet_address, eid);
2939     case 3:
2940       return format (s, "%U", format_nsh_address_vat, eid);
2941     }
2942   return 0;
2943 }
2944
2945 static u8 *
2946 format_lisp_eid_vat (u8 * s, va_list * args)
2947 {
2948   u32 type = va_arg (*args, u32);
2949   u8 *eid = va_arg (*args, u8 *);
2950   u32 eid_len = va_arg (*args, u32);
2951   u8 *seid = va_arg (*args, u8 *);
2952   u32 seid_len = va_arg (*args, u32);
2953   u32 is_src_dst = va_arg (*args, u32);
2954
2955   if (is_src_dst)
2956     s = format (s, "%U|", format_lisp_flat_eid, type, seid, seid_len);
2957
2958   s = format (s, "%U", format_lisp_flat_eid, type, eid, eid_len);
2959
2960   return s;
2961 }
2962
2963 static void
2964 vl_api_one_eid_table_details_t_handler (vl_api_one_eid_table_details_t * mp)
2965 {
2966   vat_main_t *vam = &vat_main;
2967   u8 *s = 0, *eid = 0;
2968
2969   if (~0 == mp->locator_set_index)
2970     s = format (0, "action: %d", mp->action);
2971   else
2972     s = format (0, "%d", clib_net_to_host_u32 (mp->locator_set_index));
2973
2974   eid = format (0, "%U", format_lisp_eid_vat,
2975                 mp->eid_type,
2976                 mp->eid,
2977                 mp->eid_prefix_len,
2978                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
2979   vec_add1 (eid, 0);
2980
2981   print (vam->ofp, "[%d] %-35s%-20s%-30s%-20d%-20d%-10d%-20s",
2982          clib_net_to_host_u32 (mp->vni),
2983          eid,
2984          mp->is_local ? "local" : "remote",
2985          s, clib_net_to_host_u32 (mp->ttl), mp->authoritative,
2986          clib_net_to_host_u16 (mp->key_id), mp->key);
2987
2988   vec_free (s);
2989   vec_free (eid);
2990 }
2991
2992 static void
2993 vl_api_one_eid_table_details_t_handler_json (vl_api_one_eid_table_details_t
2994                                              * mp)
2995 {
2996   vat_main_t *vam = &vat_main;
2997   vat_json_node_t *node = 0;
2998   u8 *eid = 0;
2999
3000   if (VAT_JSON_ARRAY != vam->json_tree.type)
3001     {
3002       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3003       vat_json_init_array (&vam->json_tree);
3004     }
3005   node = vat_json_array_add (&vam->json_tree);
3006
3007   vat_json_init_object (node);
3008   if (~0 == mp->locator_set_index)
3009     vat_json_object_add_uint (node, "action", mp->action);
3010   else
3011     vat_json_object_add_uint (node, "locator_set_index",
3012                               clib_net_to_host_u32 (mp->locator_set_index));
3013
3014   vat_json_object_add_uint (node, "is_local", mp->is_local ? 1 : 0);
3015   if (mp->eid_type == 3)
3016     {
3017       vat_json_node_t *nsh_json = vat_json_object_add (node, "eid");
3018       vat_json_init_object (nsh_json);
3019       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) mp->eid;
3020       vat_json_object_add_uint (nsh_json, "spi",
3021                                 clib_net_to_host_u32 (nsh->spi));
3022       vat_json_object_add_uint (nsh_json, "si", nsh->si);
3023     }
3024   else
3025     {
3026       eid = format (0, "%U", format_lisp_eid_vat,
3027                     mp->eid_type,
3028                     mp->eid,
3029                     mp->eid_prefix_len,
3030                     mp->seid, mp->seid_prefix_len, mp->is_src_dst);
3031       vec_add1 (eid, 0);
3032       vat_json_object_add_string_copy (node, "eid", eid);
3033       vec_free (eid);
3034     }
3035   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3036   vat_json_object_add_uint (node, "ttl", clib_net_to_host_u32 (mp->ttl));
3037   vat_json_object_add_uint (node, "authoritative", (mp->authoritative));
3038
3039   if (mp->key_id)
3040     {
3041       vat_json_object_add_uint (node, "key_id",
3042                                 clib_net_to_host_u16 (mp->key_id));
3043       vat_json_object_add_string_copy (node, "key", mp->key);
3044     }
3045 }
3046
3047 static void
3048 vl_api_one_stats_details_t_handler (vl_api_one_stats_details_t * mp)
3049 {
3050   vat_main_t *vam = &vat_main;
3051   u8 *seid = 0, *deid = 0;
3052   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3053
3054   deid = format (0, "%U", format_lisp_eid_vat,
3055                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
3056
3057   seid = format (0, "%U", format_lisp_eid_vat,
3058                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
3059
3060   vec_add1 (deid, 0);
3061   vec_add1 (seid, 0);
3062
3063   if (mp->is_ip4)
3064     format_ip_address_fcn = format_ip4_address;
3065   else
3066     format_ip_address_fcn = format_ip6_address;
3067
3068
3069   print (vam->ofp, "([%d] %s %s) (%U %U) %u %u",
3070          clib_net_to_host_u32 (mp->vni),
3071          seid, deid,
3072          format_ip_address_fcn, mp->lloc,
3073          format_ip_address_fcn, mp->rloc,
3074          clib_net_to_host_u32 (mp->pkt_count),
3075          clib_net_to_host_u32 (mp->bytes));
3076
3077   vec_free (deid);
3078   vec_free (seid);
3079 }
3080
3081 static void
3082 vl_api_one_stats_details_t_handler_json (vl_api_one_stats_details_t * mp)
3083 {
3084   struct in6_addr ip6;
3085   struct in_addr ip4;
3086   vat_main_t *vam = &vat_main;
3087   vat_json_node_t *node = 0;
3088   u8 *deid = 0, *seid = 0;
3089
3090   if (VAT_JSON_ARRAY != vam->json_tree.type)
3091     {
3092       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3093       vat_json_init_array (&vam->json_tree);
3094     }
3095   node = vat_json_array_add (&vam->json_tree);
3096
3097   vat_json_init_object (node);
3098   deid = format (0, "%U", format_lisp_eid_vat,
3099                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
3100
3101   seid = format (0, "%U", format_lisp_eid_vat,
3102                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
3103
3104   vec_add1 (deid, 0);
3105   vec_add1 (seid, 0);
3106
3107   vat_json_object_add_string_copy (node, "seid", seid);
3108   vat_json_object_add_string_copy (node, "deid", deid);
3109   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3110
3111   if (mp->is_ip4)
3112     {
3113       clib_memcpy (&ip4, mp->lloc, sizeof (ip4));
3114       vat_json_object_add_ip4 (node, "lloc", ip4);
3115       clib_memcpy (&ip4, mp->rloc, sizeof (ip4));
3116       vat_json_object_add_ip4 (node, "rloc", ip4);
3117     }
3118   else
3119     {
3120       clib_memcpy (&ip6, mp->lloc, sizeof (ip6));
3121       vat_json_object_add_ip6 (node, "lloc", ip6);
3122       clib_memcpy (&ip6, mp->rloc, sizeof (ip6));
3123       vat_json_object_add_ip6 (node, "rloc", ip6);
3124     }
3125   vat_json_object_add_uint (node, "pkt_count",
3126                             clib_net_to_host_u32 (mp->pkt_count));
3127   vat_json_object_add_uint (node, "bytes", clib_net_to_host_u32 (mp->bytes));
3128
3129   vec_free (deid);
3130   vec_free (seid);
3131 }
3132
3133 static void
3134   vl_api_one_eid_table_map_details_t_handler
3135   (vl_api_one_eid_table_map_details_t * mp)
3136 {
3137   vat_main_t *vam = &vat_main;
3138
3139   u8 *line = format (0, "%=10d%=10d",
3140                      clib_net_to_host_u32 (mp->vni),
3141                      clib_net_to_host_u32 (mp->dp_table));
3142   print (vam->ofp, "%v", line);
3143   vec_free (line);
3144 }
3145
3146 static void
3147   vl_api_one_eid_table_map_details_t_handler_json
3148   (vl_api_one_eid_table_map_details_t * mp)
3149 {
3150   vat_main_t *vam = &vat_main;
3151   vat_json_node_t *node = NULL;
3152
3153   if (VAT_JSON_ARRAY != vam->json_tree.type)
3154     {
3155       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3156       vat_json_init_array (&vam->json_tree);
3157     }
3158   node = vat_json_array_add (&vam->json_tree);
3159   vat_json_init_object (node);
3160   vat_json_object_add_uint (node, "dp_table",
3161                             clib_net_to_host_u32 (mp->dp_table));
3162   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3163 }
3164
3165 static void
3166   vl_api_one_eid_table_vni_details_t_handler
3167   (vl_api_one_eid_table_vni_details_t * mp)
3168 {
3169   vat_main_t *vam = &vat_main;
3170
3171   u8 *line = format (0, "%d", clib_net_to_host_u32 (mp->vni));
3172   print (vam->ofp, "%v", line);
3173   vec_free (line);
3174 }
3175
3176 static void
3177   vl_api_one_eid_table_vni_details_t_handler_json
3178   (vl_api_one_eid_table_vni_details_t * mp)
3179 {
3180   vat_main_t *vam = &vat_main;
3181   vat_json_node_t *node = NULL;
3182
3183   if (VAT_JSON_ARRAY != vam->json_tree.type)
3184     {
3185       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3186       vat_json_init_array (&vam->json_tree);
3187     }
3188   node = vat_json_array_add (&vam->json_tree);
3189   vat_json_init_object (node);
3190   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3191 }
3192
3193 static void
3194   vl_api_show_one_map_register_fallback_threshold_reply_t_handler
3195   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
3196 {
3197   vat_main_t *vam = &vat_main;
3198   int retval = clib_net_to_host_u32 (mp->retval);
3199
3200   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
3201   print (vam->ofp, "fallback threshold value: %d", mp->value);
3202
3203   vam->retval = retval;
3204   vam->result_ready = 1;
3205 }
3206
3207 static void
3208   vl_api_show_one_map_register_fallback_threshold_reply_t_handler_json
3209   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
3210 {
3211   vat_main_t *vam = &vat_main;
3212   vat_json_node_t _node, *node = &_node;
3213   int retval = clib_net_to_host_u32 (mp->retval);
3214
3215   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
3216   vat_json_init_object (node);
3217   vat_json_object_add_uint (node, "value", mp->value);
3218
3219   vat_json_print (vam->ofp, node);
3220   vat_json_free (node);
3221
3222   vam->retval = retval;
3223   vam->result_ready = 1;
3224 }
3225
3226 static void
3227   vl_api_show_one_map_register_state_reply_t_handler
3228   (vl_api_show_one_map_register_state_reply_t * mp)
3229 {
3230   vat_main_t *vam = &vat_main;
3231   int retval = clib_net_to_host_u32 (mp->retval);
3232
3233   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
3234
3235   vam->retval = retval;
3236   vam->result_ready = 1;
3237 }
3238
3239 static void
3240   vl_api_show_one_map_register_state_reply_t_handler_json
3241   (vl_api_show_one_map_register_state_reply_t * mp)
3242 {
3243   vat_main_t *vam = &vat_main;
3244   vat_json_node_t _node, *node = &_node;
3245   int retval = clib_net_to_host_u32 (mp->retval);
3246
3247   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
3248
3249   vat_json_init_object (node);
3250   vat_json_object_add_string_copy (node, "state", s);
3251
3252   vat_json_print (vam->ofp, node);
3253   vat_json_free (node);
3254
3255   vam->retval = retval;
3256   vam->result_ready = 1;
3257   vec_free (s);
3258 }
3259
3260 static void
3261   vl_api_show_one_rloc_probe_state_reply_t_handler
3262   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3263 {
3264   vat_main_t *vam = &vat_main;
3265   int retval = clib_net_to_host_u32 (mp->retval);
3266
3267   if (retval)
3268     goto end;
3269
3270   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
3271 end:
3272   vam->retval = retval;
3273   vam->result_ready = 1;
3274 }
3275
3276 static void
3277   vl_api_show_one_rloc_probe_state_reply_t_handler_json
3278   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3279 {
3280   vat_main_t *vam = &vat_main;
3281   vat_json_node_t _node, *node = &_node;
3282   int retval = clib_net_to_host_u32 (mp->retval);
3283
3284   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
3285   vat_json_init_object (node);
3286   vat_json_object_add_string_copy (node, "state", s);
3287
3288   vat_json_print (vam->ofp, node);
3289   vat_json_free (node);
3290
3291   vam->retval = retval;
3292   vam->result_ready = 1;
3293   vec_free (s);
3294 }
3295
3296 static void
3297   vl_api_show_one_stats_enable_disable_reply_t_handler
3298   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3299 {
3300   vat_main_t *vam = &vat_main;
3301   int retval = clib_net_to_host_u32 (mp->retval);
3302
3303   if (retval)
3304     goto end;
3305
3306   print (vam->ofp, "%s", mp->is_en ? "enabled" : "disabled");
3307 end:
3308   vam->retval = retval;
3309   vam->result_ready = 1;
3310 }
3311
3312 static void
3313   vl_api_show_one_stats_enable_disable_reply_t_handler_json
3314   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3315 {
3316   vat_main_t *vam = &vat_main;
3317   vat_json_node_t _node, *node = &_node;
3318   int retval = clib_net_to_host_u32 (mp->retval);
3319
3320   u8 *s = format (0, "%s", mp->is_en ? "enabled" : "disabled");
3321   vat_json_init_object (node);
3322   vat_json_object_add_string_copy (node, "state", s);
3323
3324   vat_json_print (vam->ofp, node);
3325   vat_json_free (node);
3326
3327   vam->retval = retval;
3328   vam->result_ready = 1;
3329   vec_free (s);
3330 }
3331
3332 static void
3333 api_gpe_fwd_entry_net_to_host (vl_api_gpe_fwd_entry_t * e)
3334 {
3335   e->dp_table = clib_net_to_host_u32 (e->dp_table);
3336   e->fwd_entry_index = clib_net_to_host_u32 (e->fwd_entry_index);
3337   e->vni = clib_net_to_host_u32 (e->vni);
3338 }
3339
3340 static void
3341   gpe_fwd_entries_get_reply_t_net_to_host
3342   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3343 {
3344   u32 i;
3345
3346   mp->count = clib_net_to_host_u32 (mp->count);
3347   for (i = 0; i < mp->count; i++)
3348     {
3349       api_gpe_fwd_entry_net_to_host (&mp->entries[i]);
3350     }
3351 }
3352
3353 static u8 *
3354 format_gpe_encap_mode (u8 * s, va_list * args)
3355 {
3356   u32 mode = va_arg (*args, u32);
3357
3358   switch (mode)
3359     {
3360     case 0:
3361       return format (s, "lisp");
3362     case 1:
3363       return format (s, "vxlan");
3364     }
3365   return 0;
3366 }
3367
3368 static void
3369   vl_api_gpe_get_encap_mode_reply_t_handler
3370   (vl_api_gpe_get_encap_mode_reply_t * mp)
3371 {
3372   vat_main_t *vam = &vat_main;
3373
3374   print (vam->ofp, "gpe mode: %U", format_gpe_encap_mode, mp->encap_mode);
3375   vam->retval = ntohl (mp->retval);
3376   vam->result_ready = 1;
3377 }
3378
3379 static void
3380   vl_api_gpe_get_encap_mode_reply_t_handler_json
3381   (vl_api_gpe_get_encap_mode_reply_t * mp)
3382 {
3383   vat_main_t *vam = &vat_main;
3384   vat_json_node_t node;
3385
3386   u8 *encap_mode = format (0, "%U", format_gpe_encap_mode, mp->encap_mode);
3387   vec_add1 (encap_mode, 0);
3388
3389   vat_json_init_object (&node);
3390   vat_json_object_add_string_copy (&node, "gpe_mode", encap_mode);
3391
3392   vec_free (encap_mode);
3393   vat_json_print (vam->ofp, &node);
3394   vat_json_free (&node);
3395
3396   vam->retval = ntohl (mp->retval);
3397   vam->result_ready = 1;
3398 }
3399
3400 static void
3401   vl_api_gpe_fwd_entry_path_details_t_handler
3402   (vl_api_gpe_fwd_entry_path_details_t * mp)
3403 {
3404   vat_main_t *vam = &vat_main;
3405   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3406
3407   if (mp->lcl_loc.is_ip4)
3408     format_ip_address_fcn = format_ip4_address;
3409   else
3410     format_ip_address_fcn = format_ip6_address;
3411
3412   print (vam->ofp, "w:%d %30U %30U", mp->rmt_loc.weight,
3413          format_ip_address_fcn, &mp->lcl_loc,
3414          format_ip_address_fcn, &mp->rmt_loc);
3415 }
3416
3417 static void
3418 lisp_fill_locator_node (vat_json_node_t * n, vl_api_gpe_locator_t * loc)
3419 {
3420   struct in6_addr ip6;
3421   struct in_addr ip4;
3422
3423   if (loc->is_ip4)
3424     {
3425       clib_memcpy (&ip4, loc->addr, sizeof (ip4));
3426       vat_json_object_add_ip4 (n, "address", ip4);
3427     }
3428   else
3429     {
3430       clib_memcpy (&ip6, loc->addr, sizeof (ip6));
3431       vat_json_object_add_ip6 (n, "address", ip6);
3432     }
3433   vat_json_object_add_uint (n, "weight", loc->weight);
3434 }
3435
3436 static void
3437   vl_api_gpe_fwd_entry_path_details_t_handler_json
3438   (vl_api_gpe_fwd_entry_path_details_t * mp)
3439 {
3440   vat_main_t *vam = &vat_main;
3441   vat_json_node_t *node = NULL;
3442   vat_json_node_t *loc_node;
3443
3444   if (VAT_JSON_ARRAY != vam->json_tree.type)
3445     {
3446       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3447       vat_json_init_array (&vam->json_tree);
3448     }
3449   node = vat_json_array_add (&vam->json_tree);
3450   vat_json_init_object (node);
3451
3452   loc_node = vat_json_object_add (node, "local_locator");
3453   vat_json_init_object (loc_node);
3454   lisp_fill_locator_node (loc_node, &mp->lcl_loc);
3455
3456   loc_node = vat_json_object_add (node, "remote_locator");
3457   vat_json_init_object (loc_node);
3458   lisp_fill_locator_node (loc_node, &mp->rmt_loc);
3459 }
3460
3461 static void
3462   vl_api_gpe_fwd_entries_get_reply_t_handler
3463   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3464 {
3465   vat_main_t *vam = &vat_main;
3466   u32 i;
3467   int retval = clib_net_to_host_u32 (mp->retval);
3468   vl_api_gpe_fwd_entry_t *e;
3469
3470   if (retval)
3471     goto end;
3472
3473   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3474
3475   for (i = 0; i < mp->count; i++)
3476     {
3477       e = &mp->entries[i];
3478       print (vam->ofp, "%10d %10d %U %40U", e->fwd_entry_index, e->dp_table,
3479              format_lisp_flat_eid, e->eid_type, e->leid, e->leid_prefix_len,
3480              format_lisp_flat_eid, e->eid_type, e->reid, e->reid_prefix_len);
3481     }
3482
3483 end:
3484   vam->retval = retval;
3485   vam->result_ready = 1;
3486 }
3487
3488 static void
3489   vl_api_gpe_fwd_entries_get_reply_t_handler_json
3490   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3491 {
3492   u8 *s = 0;
3493   vat_main_t *vam = &vat_main;
3494   vat_json_node_t *e = 0, root;
3495   u32 i;
3496   int retval = clib_net_to_host_u32 (mp->retval);
3497   vl_api_gpe_fwd_entry_t *fwd;
3498
3499   if (retval)
3500     goto end;
3501
3502   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3503   vat_json_init_array (&root);
3504
3505   for (i = 0; i < mp->count; i++)
3506     {
3507       e = vat_json_array_add (&root);
3508       fwd = &mp->entries[i];
3509
3510       vat_json_init_object (e);
3511       vat_json_object_add_int (e, "fwd_entry_index", fwd->fwd_entry_index);
3512       vat_json_object_add_int (e, "dp_table", fwd->dp_table);
3513       vat_json_object_add_int (e, "vni", fwd->vni);
3514       vat_json_object_add_int (e, "action", fwd->action);
3515
3516       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->leid,
3517                   fwd->leid_prefix_len);
3518       vec_add1 (s, 0);
3519       vat_json_object_add_string_copy (e, "leid", s);
3520       vec_free (s);
3521
3522       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->reid,
3523                   fwd->reid_prefix_len);
3524       vec_add1 (s, 0);
3525       vat_json_object_add_string_copy (e, "reid", s);
3526       vec_free (s);
3527     }
3528
3529   vat_json_print (vam->ofp, &root);
3530   vat_json_free (&root);
3531
3532 end:
3533   vam->retval = retval;
3534   vam->result_ready = 1;
3535 }
3536
3537 static void
3538   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler
3539   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3540 {
3541   vat_main_t *vam = &vat_main;
3542   u32 i, n;
3543   int retval = clib_net_to_host_u32 (mp->retval);
3544   vl_api_gpe_native_fwd_rpath_t *r;
3545
3546   if (retval)
3547     goto end;
3548
3549   n = clib_net_to_host_u32 (mp->count);
3550
3551   for (i = 0; i < n; i++)
3552     {
3553       r = &mp->entries[i];
3554       print (vam->ofp, "fib_index: %d sw_if_index %d nh %U",
3555              clib_net_to_host_u32 (r->fib_index),
3556              clib_net_to_host_u32 (r->nh_sw_if_index),
3557              r->is_ip4 ? format_ip4_address : format_ip6_address, r->nh_addr);
3558     }
3559
3560 end:
3561   vam->retval = retval;
3562   vam->result_ready = 1;
3563 }
3564
3565 static void
3566   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler_json
3567   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3568 {
3569   vat_main_t *vam = &vat_main;
3570   vat_json_node_t root, *e;
3571   u32 i, n;
3572   int retval = clib_net_to_host_u32 (mp->retval);
3573   vl_api_gpe_native_fwd_rpath_t *r;
3574   u8 *s;
3575
3576   if (retval)
3577     goto end;
3578
3579   n = clib_net_to_host_u32 (mp->count);
3580   vat_json_init_array (&root);
3581
3582   for (i = 0; i < n; i++)
3583     {
3584       e = vat_json_array_add (&root);
3585       vat_json_init_object (e);
3586       r = &mp->entries[i];
3587       s =
3588         format (0, "%U", r->is_ip4 ? format_ip4_address : format_ip6_address,
3589                 r->nh_addr);
3590       vec_add1 (s, 0);
3591       vat_json_object_add_string_copy (e, "ip4", s);
3592       vec_free (s);
3593
3594       vat_json_object_add_uint (e, "fib_index",
3595                                 clib_net_to_host_u32 (r->fib_index));
3596       vat_json_object_add_uint (e, "nh_sw_if_index",
3597                                 clib_net_to_host_u32 (r->nh_sw_if_index));
3598     }
3599
3600   vat_json_print (vam->ofp, &root);
3601   vat_json_free (&root);
3602
3603 end:
3604   vam->retval = retval;
3605   vam->result_ready = 1;
3606 }
3607
3608 static void
3609   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler
3610   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3611 {
3612   vat_main_t *vam = &vat_main;
3613   u32 i, n;
3614   int retval = clib_net_to_host_u32 (mp->retval);
3615
3616   if (retval)
3617     goto end;
3618
3619   n = clib_net_to_host_u32 (mp->count);
3620
3621   for (i = 0; i < n; i++)
3622     print (vam->ofp, "%d", clib_net_to_host_u32 (mp->vnis[i]));
3623
3624 end:
3625   vam->retval = retval;
3626   vam->result_ready = 1;
3627 }
3628
3629 static void
3630   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler_json
3631   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3632 {
3633   vat_main_t *vam = &vat_main;
3634   vat_json_node_t root;
3635   u32 i, n;
3636   int retval = clib_net_to_host_u32 (mp->retval);
3637
3638   if (retval)
3639     goto end;
3640
3641   n = clib_net_to_host_u32 (mp->count);
3642   vat_json_init_array (&root);
3643
3644   for (i = 0; i < n; i++)
3645     vat_json_array_add_uint (&root, clib_net_to_host_u32 (mp->vnis[i]));
3646
3647   vat_json_print (vam->ofp, &root);
3648   vat_json_free (&root);
3649
3650 end:
3651   vam->retval = retval;
3652   vam->result_ready = 1;
3653 }
3654
3655 static void
3656   vl_api_one_ndp_entries_get_reply_t_handler
3657   (vl_api_one_ndp_entries_get_reply_t * mp)
3658 {
3659   vat_main_t *vam = &vat_main;
3660   u32 i, n;
3661   int retval = clib_net_to_host_u32 (mp->retval);
3662
3663   if (retval)
3664     goto end;
3665
3666   n = clib_net_to_host_u32 (mp->count);
3667
3668   for (i = 0; i < n; i++)
3669     print (vam->ofp, "%U -> %U", format_ip6_address, &mp->entries[i].ip6,
3670            format_ethernet_address, mp->entries[i].mac);
3671
3672 end:
3673   vam->retval = retval;
3674   vam->result_ready = 1;
3675 }
3676
3677 static void
3678   vl_api_one_ndp_entries_get_reply_t_handler_json
3679   (vl_api_one_ndp_entries_get_reply_t * mp)
3680 {
3681   u8 *s = 0;
3682   vat_main_t *vam = &vat_main;
3683   vat_json_node_t *e = 0, root;
3684   u32 i, n;
3685   int retval = clib_net_to_host_u32 (mp->retval);
3686   vl_api_one_ndp_entry_t *arp_entry;
3687
3688   if (retval)
3689     goto end;
3690
3691   n = clib_net_to_host_u32 (mp->count);
3692   vat_json_init_array (&root);
3693
3694   for (i = 0; i < n; i++)
3695     {
3696       e = vat_json_array_add (&root);
3697       arp_entry = &mp->entries[i];
3698
3699       vat_json_init_object (e);
3700       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
3701       vec_add1 (s, 0);
3702
3703       vat_json_object_add_string_copy (e, "mac", s);
3704       vec_free (s);
3705
3706       s = format (0, "%U", format_ip6_address, &arp_entry->ip6);
3707       vec_add1 (s, 0);
3708       vat_json_object_add_string_copy (e, "ip6", s);
3709       vec_free (s);
3710     }
3711
3712   vat_json_print (vam->ofp, &root);
3713   vat_json_free (&root);
3714
3715 end:
3716   vam->retval = retval;
3717   vam->result_ready = 1;
3718 }
3719
3720 static void
3721   vl_api_one_l2_arp_entries_get_reply_t_handler
3722   (vl_api_one_l2_arp_entries_get_reply_t * mp)
3723 {
3724   vat_main_t *vam = &vat_main;
3725   u32 i, n;
3726   int retval = clib_net_to_host_u32 (mp->retval);
3727
3728   if (retval)
3729     goto end;
3730
3731   n = clib_net_to_host_u32 (mp->count);
3732
3733   for (i = 0; i < n; i++)
3734     print (vam->ofp, "%U -> %U", format_ip4_address, &mp->entries[i].ip4,
3735            format_ethernet_address, mp->entries[i].mac);
3736
3737 end:
3738   vam->retval = retval;
3739   vam->result_ready = 1;
3740 }
3741
3742 static void
3743   vl_api_one_l2_arp_entries_get_reply_t_handler_json
3744   (vl_api_one_l2_arp_entries_get_reply_t * mp)
3745 {
3746   u8 *s = 0;
3747   vat_main_t *vam = &vat_main;
3748   vat_json_node_t *e = 0, root;
3749   u32 i, n;
3750   int retval = clib_net_to_host_u32 (mp->retval);
3751   vl_api_one_l2_arp_entry_t *arp_entry;
3752
3753   if (retval)
3754     goto end;
3755
3756   n = clib_net_to_host_u32 (mp->count);
3757   vat_json_init_array (&root);
3758
3759   for (i = 0; i < n; i++)
3760     {
3761       e = vat_json_array_add (&root);
3762       arp_entry = &mp->entries[i];
3763
3764       vat_json_init_object (e);
3765       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
3766       vec_add1 (s, 0);
3767
3768       vat_json_object_add_string_copy (e, "mac", s);
3769       vec_free (s);
3770
3771       s = format (0, "%U", format_ip4_address, &arp_entry->ip4);
3772       vec_add1 (s, 0);
3773       vat_json_object_add_string_copy (e, "ip4", s);
3774       vec_free (s);
3775     }
3776
3777   vat_json_print (vam->ofp, &root);
3778   vat_json_free (&root);
3779
3780 end:
3781   vam->retval = retval;
3782   vam->result_ready = 1;
3783 }
3784
3785 static void
3786 vl_api_one_ndp_bd_get_reply_t_handler (vl_api_one_ndp_bd_get_reply_t * mp)
3787 {
3788   vat_main_t *vam = &vat_main;
3789   u32 i, n;
3790   int retval = clib_net_to_host_u32 (mp->retval);
3791
3792   if (retval)
3793     goto end;
3794
3795   n = clib_net_to_host_u32 (mp->count);
3796
3797   for (i = 0; i < n; i++)
3798     {
3799       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
3800     }
3801
3802 end:
3803   vam->retval = retval;
3804   vam->result_ready = 1;
3805 }
3806
3807 static void
3808   vl_api_one_ndp_bd_get_reply_t_handler_json
3809   (vl_api_one_ndp_bd_get_reply_t * mp)
3810 {
3811   vat_main_t *vam = &vat_main;
3812   vat_json_node_t root;
3813   u32 i, n;
3814   int retval = clib_net_to_host_u32 (mp->retval);
3815
3816   if (retval)
3817     goto end;
3818
3819   n = clib_net_to_host_u32 (mp->count);
3820   vat_json_init_array (&root);
3821
3822   for (i = 0; i < n; i++)
3823     {
3824       vat_json_array_add_uint (&root,
3825                                clib_net_to_host_u32 (mp->bridge_domains[i]));
3826     }
3827
3828   vat_json_print (vam->ofp, &root);
3829   vat_json_free (&root);
3830
3831 end:
3832   vam->retval = retval;
3833   vam->result_ready = 1;
3834 }
3835
3836 static void
3837   vl_api_one_l2_arp_bd_get_reply_t_handler
3838   (vl_api_one_l2_arp_bd_get_reply_t * mp)
3839 {
3840   vat_main_t *vam = &vat_main;
3841   u32 i, n;
3842   int retval = clib_net_to_host_u32 (mp->retval);
3843
3844   if (retval)
3845     goto end;
3846
3847   n = clib_net_to_host_u32 (mp->count);
3848
3849   for (i = 0; i < n; i++)
3850     {
3851       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
3852     }
3853
3854 end:
3855   vam->retval = retval;
3856   vam->result_ready = 1;
3857 }
3858
3859 static void
3860   vl_api_one_l2_arp_bd_get_reply_t_handler_json
3861   (vl_api_one_l2_arp_bd_get_reply_t * mp)
3862 {
3863   vat_main_t *vam = &vat_main;
3864   vat_json_node_t root;
3865   u32 i, n;
3866   int retval = clib_net_to_host_u32 (mp->retval);
3867
3868   if (retval)
3869     goto end;
3870
3871   n = clib_net_to_host_u32 (mp->count);
3872   vat_json_init_array (&root);
3873
3874   for (i = 0; i < n; i++)
3875     {
3876       vat_json_array_add_uint (&root,
3877                                clib_net_to_host_u32 (mp->bridge_domains[i]));
3878     }
3879
3880   vat_json_print (vam->ofp, &root);
3881   vat_json_free (&root);
3882
3883 end:
3884   vam->retval = retval;
3885   vam->result_ready = 1;
3886 }
3887
3888 static void
3889   vl_api_one_adjacencies_get_reply_t_handler
3890   (vl_api_one_adjacencies_get_reply_t * mp)
3891 {
3892   vat_main_t *vam = &vat_main;
3893   u32 i, n;
3894   int retval = clib_net_to_host_u32 (mp->retval);
3895   vl_api_one_adjacency_t *a;
3896
3897   if (retval)
3898     goto end;
3899
3900   n = clib_net_to_host_u32 (mp->count);
3901
3902   for (i = 0; i < n; i++)
3903     {
3904       a = &mp->adjacencies[i];
3905       print (vam->ofp, "%U %40U",
3906              format_lisp_flat_eid, a->eid_type, a->leid, a->leid_prefix_len,
3907              format_lisp_flat_eid, a->eid_type, a->reid, a->reid_prefix_len);
3908     }
3909
3910 end:
3911   vam->retval = retval;
3912   vam->result_ready = 1;
3913 }
3914
3915 static void
3916   vl_api_one_adjacencies_get_reply_t_handler_json
3917   (vl_api_one_adjacencies_get_reply_t * mp)
3918 {
3919   u8 *s = 0;
3920   vat_main_t *vam = &vat_main;
3921   vat_json_node_t *e = 0, root;
3922   u32 i, n;
3923   int retval = clib_net_to_host_u32 (mp->retval);
3924   vl_api_one_adjacency_t *a;
3925
3926   if (retval)
3927     goto end;
3928
3929   n = clib_net_to_host_u32 (mp->count);
3930   vat_json_init_array (&root);
3931
3932   for (i = 0; i < n; i++)
3933     {
3934       e = vat_json_array_add (&root);
3935       a = &mp->adjacencies[i];
3936
3937       vat_json_init_object (e);
3938       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->leid,
3939                   a->leid_prefix_len);
3940       vec_add1 (s, 0);
3941       vat_json_object_add_string_copy (e, "leid", s);
3942       vec_free (s);
3943
3944       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->reid,
3945                   a->reid_prefix_len);
3946       vec_add1 (s, 0);
3947       vat_json_object_add_string_copy (e, "reid", s);
3948       vec_free (s);
3949     }
3950
3951   vat_json_print (vam->ofp, &root);
3952   vat_json_free (&root);
3953
3954 end:
3955   vam->retval = retval;
3956   vam->result_ready = 1;
3957 }
3958
3959 static void
3960 vl_api_one_map_server_details_t_handler (vl_api_one_map_server_details_t * mp)
3961 {
3962   vat_main_t *vam = &vat_main;
3963
3964   print (vam->ofp, "%=20U",
3965          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
3966          mp->ip_address);
3967 }
3968
3969 static void
3970   vl_api_one_map_server_details_t_handler_json
3971   (vl_api_one_map_server_details_t * mp)
3972 {
3973   vat_main_t *vam = &vat_main;
3974   vat_json_node_t *node = NULL;
3975   struct in6_addr ip6;
3976   struct in_addr ip4;
3977
3978   if (VAT_JSON_ARRAY != vam->json_tree.type)
3979     {
3980       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3981       vat_json_init_array (&vam->json_tree);
3982     }
3983   node = vat_json_array_add (&vam->json_tree);
3984
3985   vat_json_init_object (node);
3986   if (mp->is_ipv6)
3987     {
3988       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
3989       vat_json_object_add_ip6 (node, "map-server", ip6);
3990     }
3991   else
3992     {
3993       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
3994       vat_json_object_add_ip4 (node, "map-server", ip4);
3995     }
3996 }
3997
3998 static void
3999 vl_api_one_map_resolver_details_t_handler (vl_api_one_map_resolver_details_t
4000                                            * mp)
4001 {
4002   vat_main_t *vam = &vat_main;
4003
4004   print (vam->ofp, "%=20U",
4005          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
4006          mp->ip_address);
4007 }
4008
4009 static void
4010   vl_api_one_map_resolver_details_t_handler_json
4011   (vl_api_one_map_resolver_details_t * mp)
4012 {
4013   vat_main_t *vam = &vat_main;
4014   vat_json_node_t *node = NULL;
4015   struct in6_addr ip6;
4016   struct in_addr ip4;
4017
4018   if (VAT_JSON_ARRAY != vam->json_tree.type)
4019     {
4020       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4021       vat_json_init_array (&vam->json_tree);
4022     }
4023   node = vat_json_array_add (&vam->json_tree);
4024
4025   vat_json_init_object (node);
4026   if (mp->is_ipv6)
4027     {
4028       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
4029       vat_json_object_add_ip6 (node, "map resolver", ip6);
4030     }
4031   else
4032     {
4033       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
4034       vat_json_object_add_ip4 (node, "map resolver", ip4);
4035     }
4036 }
4037
4038 static void
4039 vl_api_show_one_status_reply_t_handler (vl_api_show_one_status_reply_t * mp)
4040 {
4041   vat_main_t *vam = &vat_main;
4042   i32 retval = ntohl (mp->retval);
4043
4044   if (0 <= retval)
4045     {
4046       print (vam->ofp, "feature: %s\ngpe: %s",
4047              mp->feature_status ? "enabled" : "disabled",
4048              mp->gpe_status ? "enabled" : "disabled");
4049     }
4050
4051   vam->retval = retval;
4052   vam->result_ready = 1;
4053 }
4054
4055 static void
4056   vl_api_show_one_status_reply_t_handler_json
4057   (vl_api_show_one_status_reply_t * mp)
4058 {
4059   vat_main_t *vam = &vat_main;
4060   vat_json_node_t node;
4061   u8 *gpe_status = NULL;
4062   u8 *feature_status = NULL;
4063
4064   gpe_status = format (0, "%s", mp->gpe_status ? "enabled" : "disabled");
4065   feature_status = format (0, "%s",
4066                            mp->feature_status ? "enabled" : "disabled");
4067   vec_add1 (gpe_status, 0);
4068   vec_add1 (feature_status, 0);
4069
4070   vat_json_init_object (&node);
4071   vat_json_object_add_string_copy (&node, "gpe_status", gpe_status);
4072   vat_json_object_add_string_copy (&node, "feature_status", feature_status);
4073
4074   vec_free (gpe_status);
4075   vec_free (feature_status);
4076
4077   vat_json_print (vam->ofp, &node);
4078   vat_json_free (&node);
4079
4080   vam->retval = ntohl (mp->retval);
4081   vam->result_ready = 1;
4082 }
4083
4084 static void
4085   vl_api_one_get_map_request_itr_rlocs_reply_t_handler
4086   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
4087 {
4088   vat_main_t *vam = &vat_main;
4089   i32 retval = ntohl (mp->retval);
4090
4091   if (retval >= 0)
4092     {
4093       print (vam->ofp, "%=20s", mp->locator_set_name);
4094     }
4095
4096   vam->retval = retval;
4097   vam->result_ready = 1;
4098 }
4099
4100 static void
4101   vl_api_one_get_map_request_itr_rlocs_reply_t_handler_json
4102   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
4103 {
4104   vat_main_t *vam = &vat_main;
4105   vat_json_node_t *node = NULL;
4106
4107   if (VAT_JSON_ARRAY != vam->json_tree.type)
4108     {
4109       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4110       vat_json_init_array (&vam->json_tree);
4111     }
4112   node = vat_json_array_add (&vam->json_tree);
4113
4114   vat_json_init_object (node);
4115   vat_json_object_add_string_copy (node, "itr-rlocs", mp->locator_set_name);
4116
4117   vat_json_print (vam->ofp, node);
4118   vat_json_free (node);
4119
4120   vam->retval = ntohl (mp->retval);
4121   vam->result_ready = 1;
4122 }
4123
4124 static u8 *
4125 format_lisp_map_request_mode (u8 * s, va_list * args)
4126 {
4127   u32 mode = va_arg (*args, u32);
4128
4129   switch (mode)
4130     {
4131     case 0:
4132       return format (0, "dst-only");
4133     case 1:
4134       return format (0, "src-dst");
4135     }
4136   return 0;
4137 }
4138
4139 static void
4140   vl_api_show_one_map_request_mode_reply_t_handler
4141   (vl_api_show_one_map_request_mode_reply_t * mp)
4142 {
4143   vat_main_t *vam = &vat_main;
4144   i32 retval = ntohl (mp->retval);
4145
4146   if (0 <= retval)
4147     {
4148       u32 mode = mp->mode;
4149       print (vam->ofp, "map_request_mode: %U",
4150              format_lisp_map_request_mode, mode);
4151     }
4152
4153   vam->retval = retval;
4154   vam->result_ready = 1;
4155 }
4156
4157 static void
4158   vl_api_show_one_map_request_mode_reply_t_handler_json
4159   (vl_api_show_one_map_request_mode_reply_t * mp)
4160 {
4161   vat_main_t *vam = &vat_main;
4162   vat_json_node_t node;
4163   u8 *s = 0;
4164   u32 mode;
4165
4166   mode = mp->mode;
4167   s = format (0, "%U", format_lisp_map_request_mode, mode);
4168   vec_add1 (s, 0);
4169
4170   vat_json_init_object (&node);
4171   vat_json_object_add_string_copy (&node, "map_request_mode", s);
4172   vat_json_print (vam->ofp, &node);
4173   vat_json_free (&node);
4174
4175   vec_free (s);
4176   vam->retval = ntohl (mp->retval);
4177   vam->result_ready = 1;
4178 }
4179
4180 static void
4181   vl_api_one_show_xtr_mode_reply_t_handler
4182   (vl_api_one_show_xtr_mode_reply_t * mp)
4183 {
4184   vat_main_t *vam = &vat_main;
4185   i32 retval = ntohl (mp->retval);
4186
4187   if (0 <= retval)
4188     {
4189       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4190     }
4191
4192   vam->retval = retval;
4193   vam->result_ready = 1;
4194 }
4195
4196 static void
4197   vl_api_one_show_xtr_mode_reply_t_handler_json
4198   (vl_api_one_show_xtr_mode_reply_t * mp)
4199 {
4200   vat_main_t *vam = &vat_main;
4201   vat_json_node_t node;
4202   u8 *status = 0;
4203
4204   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4205   vec_add1 (status, 0);
4206
4207   vat_json_init_object (&node);
4208   vat_json_object_add_string_copy (&node, "status", status);
4209
4210   vec_free (status);
4211
4212   vat_json_print (vam->ofp, &node);
4213   vat_json_free (&node);
4214
4215   vam->retval = ntohl (mp->retval);
4216   vam->result_ready = 1;
4217 }
4218
4219 static void
4220   vl_api_one_show_pitr_mode_reply_t_handler
4221   (vl_api_one_show_pitr_mode_reply_t * mp)
4222 {
4223   vat_main_t *vam = &vat_main;
4224   i32 retval = ntohl (mp->retval);
4225
4226   if (0 <= retval)
4227     {
4228       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4229     }
4230
4231   vam->retval = retval;
4232   vam->result_ready = 1;
4233 }
4234
4235 static void
4236   vl_api_one_show_pitr_mode_reply_t_handler_json
4237   (vl_api_one_show_pitr_mode_reply_t * mp)
4238 {
4239   vat_main_t *vam = &vat_main;
4240   vat_json_node_t node;
4241   u8 *status = 0;
4242
4243   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4244   vec_add1 (status, 0);
4245
4246   vat_json_init_object (&node);
4247   vat_json_object_add_string_copy (&node, "status", status);
4248
4249   vec_free (status);
4250
4251   vat_json_print (vam->ofp, &node);
4252   vat_json_free (&node);
4253
4254   vam->retval = ntohl (mp->retval);
4255   vam->result_ready = 1;
4256 }
4257
4258 static void
4259   vl_api_one_show_petr_mode_reply_t_handler
4260   (vl_api_one_show_petr_mode_reply_t * mp)
4261 {
4262   vat_main_t *vam = &vat_main;
4263   i32 retval = ntohl (mp->retval);
4264
4265   if (0 <= retval)
4266     {
4267       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4268     }
4269
4270   vam->retval = retval;
4271   vam->result_ready = 1;
4272 }
4273
4274 static void
4275   vl_api_one_show_petr_mode_reply_t_handler_json
4276   (vl_api_one_show_petr_mode_reply_t * mp)
4277 {
4278   vat_main_t *vam = &vat_main;
4279   vat_json_node_t node;
4280   u8 *status = 0;
4281
4282   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4283   vec_add1 (status, 0);
4284
4285   vat_json_init_object (&node);
4286   vat_json_object_add_string_copy (&node, "status", status);
4287
4288   vec_free (status);
4289
4290   vat_json_print (vam->ofp, &node);
4291   vat_json_free (&node);
4292
4293   vam->retval = ntohl (mp->retval);
4294   vam->result_ready = 1;
4295 }
4296
4297 static void
4298   vl_api_show_one_use_petr_reply_t_handler
4299   (vl_api_show_one_use_petr_reply_t * mp)
4300 {
4301   vat_main_t *vam = &vat_main;
4302   i32 retval = ntohl (mp->retval);
4303
4304   if (0 <= retval)
4305     {
4306       print (vam->ofp, "%s\n", mp->status ? "enabled" : "disabled");
4307       if (mp->status)
4308         {
4309           print (vam->ofp, "Proxy-ETR address; %U",
4310                  mp->is_ip4 ? format_ip4_address : format_ip6_address,
4311                  mp->address);
4312         }
4313     }
4314
4315   vam->retval = retval;
4316   vam->result_ready = 1;
4317 }
4318
4319 static void
4320   vl_api_show_one_use_petr_reply_t_handler_json
4321   (vl_api_show_one_use_petr_reply_t * mp)
4322 {
4323   vat_main_t *vam = &vat_main;
4324   vat_json_node_t node;
4325   u8 *status = 0;
4326   struct in_addr ip4;
4327   struct in6_addr ip6;
4328
4329   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4330   vec_add1 (status, 0);
4331
4332   vat_json_init_object (&node);
4333   vat_json_object_add_string_copy (&node, "status", status);
4334   if (mp->status)
4335     {
4336       if (mp->is_ip4)
4337         {
4338           clib_memcpy (&ip6, mp->address, sizeof (ip6));
4339           vat_json_object_add_ip6 (&node, "address", ip6);
4340         }
4341       else
4342         {
4343           clib_memcpy (&ip4, mp->address, sizeof (ip4));
4344           vat_json_object_add_ip4 (&node, "address", ip4);
4345         }
4346     }
4347
4348   vec_free (status);
4349
4350   vat_json_print (vam->ofp, &node);
4351   vat_json_free (&node);
4352
4353   vam->retval = ntohl (mp->retval);
4354   vam->result_ready = 1;
4355 }
4356
4357 static void
4358   vl_api_show_one_nsh_mapping_reply_t_handler
4359   (vl_api_show_one_nsh_mapping_reply_t * mp)
4360 {
4361   vat_main_t *vam = &vat_main;
4362   i32 retval = ntohl (mp->retval);
4363
4364   if (0 <= retval)
4365     {
4366       print (vam->ofp, "%-20s%-16s",
4367              mp->is_set ? "set" : "not-set",
4368              mp->is_set ? (char *) mp->locator_set_name : "");
4369     }
4370
4371   vam->retval = retval;
4372   vam->result_ready = 1;
4373 }
4374
4375 static void
4376   vl_api_show_one_nsh_mapping_reply_t_handler_json
4377   (vl_api_show_one_nsh_mapping_reply_t * mp)
4378 {
4379   vat_main_t *vam = &vat_main;
4380   vat_json_node_t node;
4381   u8 *status = 0;
4382
4383   status = format (0, "%s", mp->is_set ? "yes" : "no");
4384   vec_add1 (status, 0);
4385
4386   vat_json_init_object (&node);
4387   vat_json_object_add_string_copy (&node, "is_set", status);
4388   if (mp->is_set)
4389     {
4390       vat_json_object_add_string_copy (&node, "locator_set",
4391                                        mp->locator_set_name);
4392     }
4393
4394   vec_free (status);
4395
4396   vat_json_print (vam->ofp, &node);
4397   vat_json_free (&node);
4398
4399   vam->retval = ntohl (mp->retval);
4400   vam->result_ready = 1;
4401 }
4402
4403 static void
4404   vl_api_show_one_map_register_ttl_reply_t_handler
4405   (vl_api_show_one_map_register_ttl_reply_t * mp)
4406 {
4407   vat_main_t *vam = &vat_main;
4408   i32 retval = ntohl (mp->retval);
4409
4410   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4411
4412   if (0 <= retval)
4413     {
4414       print (vam->ofp, "ttl: %u", mp->ttl);
4415     }
4416
4417   vam->retval = retval;
4418   vam->result_ready = 1;
4419 }
4420
4421 static void
4422   vl_api_show_one_map_register_ttl_reply_t_handler_json
4423   (vl_api_show_one_map_register_ttl_reply_t * mp)
4424 {
4425   vat_main_t *vam = &vat_main;
4426   vat_json_node_t node;
4427
4428   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4429   vat_json_init_object (&node);
4430   vat_json_object_add_uint (&node, "ttl", mp->ttl);
4431
4432   vat_json_print (vam->ofp, &node);
4433   vat_json_free (&node);
4434
4435   vam->retval = ntohl (mp->retval);
4436   vam->result_ready = 1;
4437 }
4438
4439 static void
4440 vl_api_show_one_pitr_reply_t_handler (vl_api_show_one_pitr_reply_t * mp)
4441 {
4442   vat_main_t *vam = &vat_main;
4443   i32 retval = ntohl (mp->retval);
4444
4445   if (0 <= retval)
4446     {
4447       print (vam->ofp, "%-20s%-16s",
4448              mp->status ? "enabled" : "disabled",
4449              mp->status ? (char *) mp->locator_set_name : "");
4450     }
4451
4452   vam->retval = retval;
4453   vam->result_ready = 1;
4454 }
4455
4456 static void
4457 vl_api_show_one_pitr_reply_t_handler_json (vl_api_show_one_pitr_reply_t * mp)
4458 {
4459   vat_main_t *vam = &vat_main;
4460   vat_json_node_t node;
4461   u8 *status = 0;
4462
4463   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4464   vec_add1 (status, 0);
4465
4466   vat_json_init_object (&node);
4467   vat_json_object_add_string_copy (&node, "status", status);
4468   if (mp->status)
4469     {
4470       vat_json_object_add_string_copy (&node, "locator_set",
4471                                        mp->locator_set_name);
4472     }
4473
4474   vec_free (status);
4475
4476   vat_json_print (vam->ofp, &node);
4477   vat_json_free (&node);
4478
4479   vam->retval = ntohl (mp->retval);
4480   vam->result_ready = 1;
4481 }
4482
4483 static u8 *
4484 format_policer_type (u8 * s, va_list * va)
4485 {
4486   u32 i = va_arg (*va, u32);
4487
4488   if (i == SSE2_QOS_POLICER_TYPE_1R2C)
4489     s = format (s, "1r2c");
4490   else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
4491     s = format (s, "1r3c");
4492   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
4493     s = format (s, "2r3c-2698");
4494   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
4495     s = format (s, "2r3c-4115");
4496   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
4497     s = format (s, "2r3c-mef5cf1");
4498   else
4499     s = format (s, "ILLEGAL");
4500   return s;
4501 }
4502
4503 static u8 *
4504 format_policer_rate_type (u8 * s, va_list * va)
4505 {
4506   u32 i = va_arg (*va, u32);
4507
4508   if (i == SSE2_QOS_RATE_KBPS)
4509     s = format (s, "kbps");
4510   else if (i == SSE2_QOS_RATE_PPS)
4511     s = format (s, "pps");
4512   else
4513     s = format (s, "ILLEGAL");
4514   return s;
4515 }
4516
4517 static u8 *
4518 format_policer_round_type (u8 * s, va_list * va)
4519 {
4520   u32 i = va_arg (*va, u32);
4521
4522   if (i == SSE2_QOS_ROUND_TO_CLOSEST)
4523     s = format (s, "closest");
4524   else if (i == SSE2_QOS_ROUND_TO_UP)
4525     s = format (s, "up");
4526   else if (i == SSE2_QOS_ROUND_TO_DOWN)
4527     s = format (s, "down");
4528   else
4529     s = format (s, "ILLEGAL");
4530   return s;
4531 }
4532
4533 static u8 *
4534 format_policer_action_type (u8 * s, va_list * va)
4535 {
4536   u32 i = va_arg (*va, u32);
4537
4538   if (i == SSE2_QOS_ACTION_DROP)
4539     s = format (s, "drop");
4540   else if (i == SSE2_QOS_ACTION_TRANSMIT)
4541     s = format (s, "transmit");
4542   else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4543     s = format (s, "mark-and-transmit");
4544   else
4545     s = format (s, "ILLEGAL");
4546   return s;
4547 }
4548
4549 static u8 *
4550 format_dscp (u8 * s, va_list * va)
4551 {
4552   u32 i = va_arg (*va, u32);
4553   char *t = 0;
4554
4555   switch (i)
4556     {
4557 #define _(v,f,str) case VNET_DSCP_##f: t = str; break;
4558       foreach_vnet_dscp
4559 #undef _
4560     default:
4561       return format (s, "ILLEGAL");
4562     }
4563   s = format (s, "%s", t);
4564   return s;
4565 }
4566
4567 static void
4568 vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
4569 {
4570   vat_main_t *vam = &vat_main;
4571   u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
4572
4573   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4574     conform_dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
4575   else
4576     conform_dscp_str = format (0, "");
4577
4578   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4579     exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
4580   else
4581     exceed_dscp_str = format (0, "");
4582
4583   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4584     violate_dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
4585   else
4586     violate_dscp_str = format (0, "");
4587
4588   print (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
4589          "rate type %U, round type %U, %s rate, %s color-aware, "
4590          "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
4591          "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
4592          "conform action %U%s, exceed action %U%s, violate action %U%s",
4593          mp->name,
4594          format_policer_type, mp->type,
4595          ntohl (mp->cir),
4596          ntohl (mp->eir),
4597          clib_net_to_host_u64 (mp->cb),
4598          clib_net_to_host_u64 (mp->eb),
4599          format_policer_rate_type, mp->rate_type,
4600          format_policer_round_type, mp->round_type,
4601          mp->single_rate ? "single" : "dual",
4602          mp->color_aware ? "is" : "not",
4603          ntohl (mp->cir_tokens_per_period),
4604          ntohl (mp->pir_tokens_per_period),
4605          ntohl (mp->scale),
4606          ntohl (mp->current_limit),
4607          ntohl (mp->current_bucket),
4608          ntohl (mp->extended_limit),
4609          ntohl (mp->extended_bucket),
4610          clib_net_to_host_u64 (mp->last_update_time),
4611          format_policer_action_type, mp->conform_action_type,
4612          conform_dscp_str,
4613          format_policer_action_type, mp->exceed_action_type,
4614          exceed_dscp_str,
4615          format_policer_action_type, mp->violate_action_type,
4616          violate_dscp_str);
4617
4618   vec_free (conform_dscp_str);
4619   vec_free (exceed_dscp_str);
4620   vec_free (violate_dscp_str);
4621 }
4622
4623 static void vl_api_policer_details_t_handler_json
4624   (vl_api_policer_details_t * mp)
4625 {
4626   vat_main_t *vam = &vat_main;
4627   vat_json_node_t *node;
4628   u8 *rate_type_str, *round_type_str, *type_str;
4629   u8 *conform_action_str, *exceed_action_str, *violate_action_str;
4630
4631   rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
4632   round_type_str =
4633     format (0, "%U", format_policer_round_type, mp->round_type);
4634   type_str = format (0, "%U", format_policer_type, mp->type);
4635   conform_action_str = format (0, "%U", format_policer_action_type,
4636                                mp->conform_action_type);
4637   exceed_action_str = format (0, "%U", format_policer_action_type,
4638                               mp->exceed_action_type);
4639   violate_action_str = format (0, "%U", format_policer_action_type,
4640                                mp->violate_action_type);
4641
4642   if (VAT_JSON_ARRAY != vam->json_tree.type)
4643     {
4644       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4645       vat_json_init_array (&vam->json_tree);
4646     }
4647   node = vat_json_array_add (&vam->json_tree);
4648
4649   vat_json_init_object (node);
4650   vat_json_object_add_string_copy (node, "name", mp->name);
4651   vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
4652   vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
4653   vat_json_object_add_uint (node, "cb", clib_net_to_host_u64 (mp->cb));
4654   vat_json_object_add_uint (node, "eb", clib_net_to_host_u64 (mp->eb));
4655   vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
4656   vat_json_object_add_string_copy (node, "round_type", round_type_str);
4657   vat_json_object_add_string_copy (node, "type", type_str);
4658   vat_json_object_add_uint (node, "single_rate", mp->single_rate);
4659   vat_json_object_add_uint (node, "color_aware", mp->color_aware);
4660   vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
4661   vat_json_object_add_uint (node, "cir_tokens_per_period",
4662                             ntohl (mp->cir_tokens_per_period));
4663   vat_json_object_add_uint (node, "eir_tokens_per_period",
4664                             ntohl (mp->pir_tokens_per_period));
4665   vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
4666   vat_json_object_add_uint (node, "current_bucket",
4667                             ntohl (mp->current_bucket));
4668   vat_json_object_add_uint (node, "extended_limit",
4669                             ntohl (mp->extended_limit));
4670   vat_json_object_add_uint (node, "extended_bucket",
4671                             ntohl (mp->extended_bucket));
4672   vat_json_object_add_uint (node, "last_update_time",
4673                             ntohl (mp->last_update_time));
4674   vat_json_object_add_string_copy (node, "conform_action",
4675                                    conform_action_str);
4676   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4677     {
4678       u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
4679       vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
4680       vec_free (dscp_str);
4681     }
4682   vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
4683   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4684     {
4685       u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
4686       vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
4687       vec_free (dscp_str);
4688     }
4689   vat_json_object_add_string_copy (node, "violate_action",
4690                                    violate_action_str);
4691   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4692     {
4693       u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
4694       vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
4695       vec_free (dscp_str);
4696     }
4697
4698   vec_free (rate_type_str);
4699   vec_free (round_type_str);
4700   vec_free (type_str);
4701   vec_free (conform_action_str);
4702   vec_free (exceed_action_str);
4703   vec_free (violate_action_str);
4704 }
4705
4706 static void
4707 vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
4708                                            mp)
4709 {
4710   vat_main_t *vam = &vat_main;
4711   int i, count = ntohl (mp->count);
4712
4713   if (count > 0)
4714     print (vam->ofp, "classify table ids (%d) : ", count);
4715   for (i = 0; i < count; i++)
4716     {
4717       print (vam->ofp, "%d", ntohl (mp->ids[i]));
4718       print (vam->ofp, (i < count - 1) ? "," : "");
4719     }
4720   vam->retval = ntohl (mp->retval);
4721   vam->result_ready = 1;
4722 }
4723
4724 static void
4725   vl_api_classify_table_ids_reply_t_handler_json
4726   (vl_api_classify_table_ids_reply_t * mp)
4727 {
4728   vat_main_t *vam = &vat_main;
4729   int i, count = ntohl (mp->count);
4730
4731   if (count > 0)
4732     {
4733       vat_json_node_t node;
4734
4735       vat_json_init_object (&node);
4736       for (i = 0; i < count; i++)
4737         {
4738           vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
4739         }
4740       vat_json_print (vam->ofp, &node);
4741       vat_json_free (&node);
4742     }
4743   vam->retval = ntohl (mp->retval);
4744   vam->result_ready = 1;
4745 }
4746
4747 static void
4748   vl_api_classify_table_by_interface_reply_t_handler
4749   (vl_api_classify_table_by_interface_reply_t * mp)
4750 {
4751   vat_main_t *vam = &vat_main;
4752   u32 table_id;
4753
4754   table_id = ntohl (mp->l2_table_id);
4755   if (table_id != ~0)
4756     print (vam->ofp, "l2 table id : %d", table_id);
4757   else
4758     print (vam->ofp, "l2 table id : No input ACL tables configured");
4759   table_id = ntohl (mp->ip4_table_id);
4760   if (table_id != ~0)
4761     print (vam->ofp, "ip4 table id : %d", table_id);
4762   else
4763     print (vam->ofp, "ip4 table id : No input ACL tables configured");
4764   table_id = ntohl (mp->ip6_table_id);
4765   if (table_id != ~0)
4766     print (vam->ofp, "ip6 table id : %d", table_id);
4767   else
4768     print (vam->ofp, "ip6 table id : No input ACL tables configured");
4769   vam->retval = ntohl (mp->retval);
4770   vam->result_ready = 1;
4771 }
4772
4773 static void
4774   vl_api_classify_table_by_interface_reply_t_handler_json
4775   (vl_api_classify_table_by_interface_reply_t * mp)
4776 {
4777   vat_main_t *vam = &vat_main;
4778   vat_json_node_t node;
4779
4780   vat_json_init_object (&node);
4781
4782   vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
4783   vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
4784   vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
4785
4786   vat_json_print (vam->ofp, &node);
4787   vat_json_free (&node);
4788
4789   vam->retval = ntohl (mp->retval);
4790   vam->result_ready = 1;
4791 }
4792
4793 static void vl_api_policer_add_del_reply_t_handler
4794   (vl_api_policer_add_del_reply_t * mp)
4795 {
4796   vat_main_t *vam = &vat_main;
4797   i32 retval = ntohl (mp->retval);
4798   if (vam->async_mode)
4799     {
4800       vam->async_errors += (retval < 0);
4801     }
4802   else
4803     {
4804       vam->retval = retval;
4805       vam->result_ready = 1;
4806       if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
4807         /*
4808          * Note: this is just barely thread-safe, depends on
4809          * the main thread spinning waiting for an answer...
4810          */
4811         errmsg ("policer index %d", ntohl (mp->policer_index));
4812     }
4813 }
4814
4815 static void vl_api_policer_add_del_reply_t_handler_json
4816   (vl_api_policer_add_del_reply_t * mp)
4817 {
4818   vat_main_t *vam = &vat_main;
4819   vat_json_node_t node;
4820
4821   vat_json_init_object (&node);
4822   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
4823   vat_json_object_add_uint (&node, "policer_index",
4824                             ntohl (mp->policer_index));
4825
4826   vat_json_print (vam->ofp, &node);
4827   vat_json_free (&node);
4828
4829   vam->retval = ntohl (mp->retval);
4830   vam->result_ready = 1;
4831 }
4832
4833 /* Format hex dump. */
4834 u8 *
4835 format_hex_bytes (u8 * s, va_list * va)
4836 {
4837   u8 *bytes = va_arg (*va, u8 *);
4838   int n_bytes = va_arg (*va, int);
4839   uword i;
4840
4841   /* Print short or long form depending on byte count. */
4842   uword short_form = n_bytes <= 32;
4843   u32 indent = format_get_indent (s);
4844
4845   if (n_bytes == 0)
4846     return s;
4847
4848   for (i = 0; i < n_bytes; i++)
4849     {
4850       if (!short_form && (i % 32) == 0)
4851         s = format (s, "%08x: ", i);
4852       s = format (s, "%02x", bytes[i]);
4853       if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
4854         s = format (s, "\n%U", format_white_space, indent);
4855     }
4856
4857   return s;
4858 }
4859
4860 static void
4861 vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
4862                                             * mp)
4863 {
4864   vat_main_t *vam = &vat_main;
4865   i32 retval = ntohl (mp->retval);
4866   if (retval == 0)
4867     {
4868       print (vam->ofp, "classify table info :");
4869       print (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d",
4870              ntohl (mp->active_sessions), ntohl (mp->next_table_index),
4871              ntohl (mp->miss_next_index));
4872       print (vam->ofp, "nbuckets: %d skip: %d match: %d",
4873              ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
4874              ntohl (mp->match_n_vectors));
4875       print (vam->ofp, "mask: %U", format_hex_bytes, mp->mask,
4876              ntohl (mp->mask_length));
4877     }
4878   vam->retval = retval;
4879   vam->result_ready = 1;
4880 }
4881
4882 static void
4883   vl_api_classify_table_info_reply_t_handler_json
4884   (vl_api_classify_table_info_reply_t * mp)
4885 {
4886   vat_main_t *vam = &vat_main;
4887   vat_json_node_t node;
4888
4889   i32 retval = ntohl (mp->retval);
4890   if (retval == 0)
4891     {
4892       vat_json_init_object (&node);
4893
4894       vat_json_object_add_int (&node, "sessions",
4895                                ntohl (mp->active_sessions));
4896       vat_json_object_add_int (&node, "nexttbl",
4897                                ntohl (mp->next_table_index));
4898       vat_json_object_add_int (&node, "nextnode",
4899                                ntohl (mp->miss_next_index));
4900       vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
4901       vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
4902       vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
4903       u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
4904                       ntohl (mp->mask_length), 0);
4905       vat_json_object_add_string_copy (&node, "mask", s);
4906
4907       vat_json_print (vam->ofp, &node);
4908       vat_json_free (&node);
4909     }
4910   vam->retval = ntohl (mp->retval);
4911   vam->result_ready = 1;
4912 }
4913
4914 static void
4915 vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
4916                                            mp)
4917 {
4918   vat_main_t *vam = &vat_main;
4919
4920   print (vam->ofp, "next_index: %d advance: %d opaque: %d ",
4921          ntohl (mp->hit_next_index), ntohl (mp->advance),
4922          ntohl (mp->opaque_index));
4923   print (vam->ofp, "mask: %U", format_hex_bytes, mp->match,
4924          ntohl (mp->match_length));
4925 }
4926
4927 static void
4928   vl_api_classify_session_details_t_handler_json
4929   (vl_api_classify_session_details_t * mp)
4930 {
4931   vat_main_t *vam = &vat_main;
4932   vat_json_node_t *node = NULL;
4933
4934   if (VAT_JSON_ARRAY != vam->json_tree.type)
4935     {
4936       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4937       vat_json_init_array (&vam->json_tree);
4938     }
4939   node = vat_json_array_add (&vam->json_tree);
4940
4941   vat_json_init_object (node);
4942   vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
4943   vat_json_object_add_int (node, "advance", ntohl (mp->advance));
4944   vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
4945   u8 *s =
4946     format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
4947             0);
4948   vat_json_object_add_string_copy (node, "match", s);
4949 }
4950
4951 static void vl_api_pg_create_interface_reply_t_handler
4952   (vl_api_pg_create_interface_reply_t * mp)
4953 {
4954   vat_main_t *vam = &vat_main;
4955
4956   vam->retval = ntohl (mp->retval);
4957   vam->result_ready = 1;
4958 }
4959
4960 static void vl_api_pg_create_interface_reply_t_handler_json
4961   (vl_api_pg_create_interface_reply_t * mp)
4962 {
4963   vat_main_t *vam = &vat_main;
4964   vat_json_node_t node;
4965
4966   i32 retval = ntohl (mp->retval);
4967   if (retval == 0)
4968     {
4969       vat_json_init_object (&node);
4970
4971       vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
4972
4973       vat_json_print (vam->ofp, &node);
4974       vat_json_free (&node);
4975     }
4976   vam->retval = ntohl (mp->retval);
4977   vam->result_ready = 1;
4978 }
4979
4980 static void vl_api_policer_classify_details_t_handler
4981   (vl_api_policer_classify_details_t * mp)
4982 {
4983   vat_main_t *vam = &vat_main;
4984
4985   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
4986          ntohl (mp->table_index));
4987 }
4988
4989 static void vl_api_policer_classify_details_t_handler_json
4990   (vl_api_policer_classify_details_t * mp)
4991 {
4992   vat_main_t *vam = &vat_main;
4993   vat_json_node_t *node;
4994
4995   if (VAT_JSON_ARRAY != vam->json_tree.type)
4996     {
4997       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4998       vat_json_init_array (&vam->json_tree);
4999     }
5000   node = vat_json_array_add (&vam->json_tree);
5001
5002   vat_json_init_object (node);
5003   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
5004   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
5005 }
5006
5007 static void vl_api_flow_classify_details_t_handler
5008   (vl_api_flow_classify_details_t * mp)
5009 {
5010   vat_main_t *vam = &vat_main;
5011
5012   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
5013          ntohl (mp->table_index));
5014 }
5015
5016 static void vl_api_flow_classify_details_t_handler_json
5017   (vl_api_flow_classify_details_t * mp)
5018 {
5019   vat_main_t *vam = &vat_main;
5020   vat_json_node_t *node;
5021
5022   if (VAT_JSON_ARRAY != vam->json_tree.type)
5023     {
5024       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
5025       vat_json_init_array (&vam->json_tree);
5026     }
5027   node = vat_json_array_add (&vam->json_tree);
5028
5029   vat_json_init_object (node);
5030   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
5031   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
5032 }
5033
5034 #define vl_api_one_adjacencies_get_reply_t_endian vl_noop_handler
5035 #define vl_api_one_adjacencies_get_reply_t_print vl_noop_handler
5036 #define vl_api_one_l2_arp_bd_get_reply_t_print vl_noop_handler
5037 #define vl_api_one_l2_arp_entries_get_reply_t_endian vl_noop_handler
5038 #define vl_api_one_l2_arp_entries_get_reply_t_print vl_noop_handler
5039 #define vl_api_one_l2_arp_bd_get_reply_t_endian vl_noop_handler
5040 #define vl_api_one_ndp_bd_get_reply_t_endian vl_noop_handler
5041 #define vl_api_one_ndp_bd_get_reply_t_print vl_noop_handler
5042 #define vl_api_one_ndp_entries_get_reply_t_print vl_noop_handler
5043 #define vl_api_one_ndp_entries_get_reply_t_endian vl_noop_handler
5044
5045 /*
5046  * Generate boilerplate reply handlers, which
5047  * dig the return value out of the xxx_reply_t API message,
5048  * stick it into vam->retval, and set vam->result_ready
5049  *
5050  * Could also do this by pointing N message decode slots at
5051  * a single function, but that could break in subtle ways.
5052  */
5053
5054 #define foreach_standard_reply_retval_handler           \
5055 _(sw_interface_set_flags_reply)                         \
5056 _(sw_interface_add_del_address_reply)                   \
5057 _(sw_interface_set_rx_mode_reply)                       \
5058 _(sw_interface_set_rx_placement_reply)                  \
5059 _(sw_interface_set_table_reply)                         \
5060 _(sw_interface_set_mpls_enable_reply)                   \
5061 _(sw_interface_set_vpath_reply)                         \
5062 _(sw_interface_set_vxlan_bypass_reply)                  \
5063 _(sw_interface_set_geneve_bypass_reply)                 \
5064 _(sw_interface_set_vxlan_gpe_bypass_reply)              \
5065 _(sw_interface_set_l2_bridge_reply)                     \
5066 _(sw_interface_set_bond_weight_reply)                   \
5067 _(bridge_domain_add_del_reply)                          \
5068 _(sw_interface_set_l2_xconnect_reply)                   \
5069 _(l2fib_add_del_reply)                                  \
5070 _(l2fib_flush_int_reply)                                \
5071 _(l2fib_flush_bd_reply)                                 \
5072 _(ip_route_add_del_reply)                               \
5073 _(ip_table_add_del_reply)                               \
5074 _(ip_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_addr_set = host_ip4_prefix_len != 0;
7478   mp->host_ip6_addr_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_addr, &host_ip4_addr, 4);
7497   if (host_ip6_prefix_len)
7498     clib_memcpy (mp->host_ip6_addr, &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 = format (0, "%U/%d", format_ip4_address, mp->host_ip4_addr,
11863                     mp->host_ip4_prefix_len);
11864   u8 *ip6 = format (0, "%U/%d", format_ip6_address, mp->host_ip6_addr,
11865                     mp->host_ip6_prefix_len);
11866
11867   print (vam->ofp,
11868          "\n%-16s %-12d %-5d %-12d %-12d %-14U %-30s %-20s %-20s %-30s 0x%-08x",
11869          mp->dev_name, ntohl (mp->sw_if_index), ntohl (mp->id),
11870          ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
11871          format_ethernet_address, mp->host_mac_addr, mp->host_namespace,
11872          mp->host_bridge, ip4, ip6, ntohl (mp->tap_flags));
11873
11874   vec_free (ip4);
11875   vec_free (ip6);
11876 }
11877
11878 static void vl_api_sw_interface_tap_v2_details_t_handler_json
11879   (vl_api_sw_interface_tap_v2_details_t * mp)
11880 {
11881   vat_main_t *vam = &vat_main;
11882   vat_json_node_t *node = NULL;
11883
11884   if (VAT_JSON_ARRAY != vam->json_tree.type)
11885     {
11886       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11887       vat_json_init_array (&vam->json_tree);
11888     }
11889   node = vat_json_array_add (&vam->json_tree);
11890
11891   vat_json_init_object (node);
11892   vat_json_object_add_uint (node, "id", ntohl (mp->id));
11893   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11894   vat_json_object_add_uint (node, "tap_flags", ntohl (mp->tap_flags));
11895   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
11896   vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
11897   vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
11898   vat_json_object_add_string_copy (node, "host_mac_addr",
11899                                    format (0, "%U", format_ethernet_address,
11900                                            &mp->host_mac_addr));
11901   vat_json_object_add_string_copy (node, "host_namespace",
11902                                    mp->host_namespace);
11903   vat_json_object_add_string_copy (node, "host_bridge", mp->host_bridge);
11904   vat_json_object_add_string_copy (node, "host_ip4_addr",
11905                                    format (0, "%U/%d", format_ip4_address,
11906                                            mp->host_ip4_addr,
11907                                            mp->host_ip4_prefix_len));
11908   vat_json_object_add_string_copy (node, "host_ip6_addr",
11909                                    format (0, "%U/%d", format_ip6_address,
11910                                            mp->host_ip6_addr,
11911                                            mp->host_ip6_prefix_len));
11912
11913 }
11914
11915 static int
11916 api_sw_interface_tap_v2_dump (vat_main_t * vam)
11917 {
11918   vl_api_sw_interface_tap_v2_dump_t *mp;
11919   vl_api_control_ping_t *mp_ping;
11920   int ret;
11921
11922   print (vam->ofp,
11923          "\n%-16s %-12s %-5s %-12s %-12s %-14s %-30s %-20s %-20s %-30s",
11924          "dev_name", "sw_if_index", "id", "rx_ring_sz", "tx_ring_sz",
11925          "host_mac_addr", "host_namespace", "host_bridge", "host_ip4_addr",
11926          "host_ip6_addr");
11927
11928   /* Get list of tap interfaces */
11929   M (SW_INTERFACE_TAP_V2_DUMP, mp);
11930   S (mp);
11931
11932   /* Use a control ping for synchronization */
11933   MPING (CONTROL_PING, mp_ping);
11934   S (mp_ping);
11935
11936   W (ret);
11937   return ret;
11938 }
11939
11940 static void vl_api_sw_interface_virtio_pci_details_t_handler
11941   (vl_api_sw_interface_virtio_pci_details_t * mp)
11942 {
11943   vat_main_t *vam = &vat_main;
11944
11945   typedef union
11946   {
11947     struct
11948     {
11949       u16 domain;
11950       u8 bus;
11951       u8 slot:5;
11952       u8 function:3;
11953     };
11954     u32 as_u32;
11955   } pci_addr_t;
11956   pci_addr_t addr;
11957   addr.as_u32 = ntohl (mp->pci_addr);
11958   u8 *pci_addr = format (0, "%04x:%02x:%02x.%x", addr.domain, addr.bus,
11959                          addr.slot, addr.function);
11960
11961   print (vam->ofp,
11962          "\n%-12s %-12d %-12d %-12d %-17U 0x%-08llx",
11963          pci_addr, ntohl (mp->sw_if_index),
11964          ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
11965          format_ethernet_address, mp->mac_addr,
11966          clib_net_to_host_u64 (mp->features));
11967   vec_free (pci_addr);
11968 }
11969
11970 static void vl_api_sw_interface_virtio_pci_details_t_handler_json
11971   (vl_api_sw_interface_virtio_pci_details_t * mp)
11972 {
11973   vat_main_t *vam = &vat_main;
11974   vat_json_node_t *node = NULL;
11975
11976   if (VAT_JSON_ARRAY != vam->json_tree.type)
11977     {
11978       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11979       vat_json_init_array (&vam->json_tree);
11980     }
11981   node = vat_json_array_add (&vam->json_tree);
11982
11983   vat_json_init_object (node);
11984   vat_json_object_add_uint (node, "pci-addr", ntohl (mp->pci_addr));
11985   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11986   vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
11987   vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
11988   vat_json_object_add_uint (node, "features",
11989                             clib_net_to_host_u64 (mp->features));
11990   vat_json_object_add_string_copy (node, "mac_addr",
11991                                    format (0, "%U", format_ethernet_address,
11992                                            &mp->mac_addr));
11993 }
11994
11995 static int
11996 api_sw_interface_virtio_pci_dump (vat_main_t * vam)
11997 {
11998   vl_api_sw_interface_virtio_pci_dump_t *mp;
11999   vl_api_control_ping_t *mp_ping;
12000   int ret;
12001
12002   print (vam->ofp,
12003          "\n%-12s %-12s %-12s %-12s %-17s %-08s",
12004          "pci_addr", "sw_if_index", "rx_ring_sz", "tx_ring_sz",
12005          "mac_addr", "features");
12006
12007   /* Get list of tap interfaces */
12008   M (SW_INTERFACE_VIRTIO_PCI_DUMP, mp);
12009   S (mp);
12010
12011   /* Use a control ping for synchronization */
12012   MPING (CONTROL_PING, mp_ping);
12013   S (mp_ping);
12014
12015   W (ret);
12016   return ret;
12017 }
12018
12019 static int
12020 api_vxlan_offload_rx (vat_main_t * vam)
12021 {
12022   unformat_input_t *line_input = vam->input;
12023   vl_api_vxlan_offload_rx_t *mp;
12024   u32 hw_if_index = ~0, rx_if_index = ~0;
12025   u8 is_add = 1;
12026   int ret;
12027
12028   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12029     {
12030       if (unformat (line_input, "del"))
12031         is_add = 0;
12032       else if (unformat (line_input, "hw %U", api_unformat_hw_if_index, vam,
12033                          &hw_if_index))
12034         ;
12035       else if (unformat (line_input, "hw hw_if_index %u", &hw_if_index))
12036         ;
12037       else if (unformat (line_input, "rx %U", api_unformat_sw_if_index, vam,
12038                          &rx_if_index))
12039         ;
12040       else if (unformat (line_input, "rx sw_if_index %u", &rx_if_index))
12041         ;
12042       else
12043         {
12044           errmsg ("parse error '%U'", format_unformat_error, line_input);
12045           return -99;
12046         }
12047     }
12048
12049   if (hw_if_index == ~0)
12050     {
12051       errmsg ("no hw interface");
12052       return -99;
12053     }
12054
12055   if (rx_if_index == ~0)
12056     {
12057       errmsg ("no rx tunnel");
12058       return -99;
12059     }
12060
12061   M (VXLAN_OFFLOAD_RX, mp);
12062
12063   mp->hw_if_index = ntohl (hw_if_index);
12064   mp->sw_if_index = ntohl (rx_if_index);
12065   mp->enable = is_add;
12066
12067   S (mp);
12068   W (ret);
12069   return ret;
12070 }
12071
12072 static uword unformat_vxlan_decap_next
12073   (unformat_input_t * input, va_list * args)
12074 {
12075   u32 *result = va_arg (*args, u32 *);
12076   u32 tmp;
12077
12078   if (unformat (input, "l2"))
12079     *result = VXLAN_INPUT_NEXT_L2_INPUT;
12080   else if (unformat (input, "%d", &tmp))
12081     *result = tmp;
12082   else
12083     return 0;
12084   return 1;
12085 }
12086
12087 static int
12088 api_vxlan_add_del_tunnel (vat_main_t * vam)
12089 {
12090   unformat_input_t *line_input = vam->input;
12091   vl_api_vxlan_add_del_tunnel_t *mp;
12092   ip46_address_t src, dst;
12093   u8 is_add = 1;
12094   u8 ipv4_set = 0, ipv6_set = 0;
12095   u8 src_set = 0;
12096   u8 dst_set = 0;
12097   u8 grp_set = 0;
12098   u32 instance = ~0;
12099   u32 mcast_sw_if_index = ~0;
12100   u32 encap_vrf_id = 0;
12101   u32 decap_next_index = ~0;
12102   u32 vni = 0;
12103   int ret;
12104
12105   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
12106   clib_memset (&src, 0, sizeof src);
12107   clib_memset (&dst, 0, sizeof dst);
12108
12109   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12110     {
12111       if (unformat (line_input, "del"))
12112         is_add = 0;
12113       else if (unformat (line_input, "instance %d", &instance))
12114         ;
12115       else
12116         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
12117         {
12118           ipv4_set = 1;
12119           src_set = 1;
12120         }
12121       else
12122         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
12123         {
12124           ipv4_set = 1;
12125           dst_set = 1;
12126         }
12127       else
12128         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
12129         {
12130           ipv6_set = 1;
12131           src_set = 1;
12132         }
12133       else
12134         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
12135         {
12136           ipv6_set = 1;
12137           dst_set = 1;
12138         }
12139       else if (unformat (line_input, "group %U %U",
12140                          unformat_ip4_address, &dst.ip4,
12141                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12142         {
12143           grp_set = dst_set = 1;
12144           ipv4_set = 1;
12145         }
12146       else if (unformat (line_input, "group %U",
12147                          unformat_ip4_address, &dst.ip4))
12148         {
12149           grp_set = dst_set = 1;
12150           ipv4_set = 1;
12151         }
12152       else if (unformat (line_input, "group %U %U",
12153                          unformat_ip6_address, &dst.ip6,
12154                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12155         {
12156           grp_set = dst_set = 1;
12157           ipv6_set = 1;
12158         }
12159       else if (unformat (line_input, "group %U",
12160                          unformat_ip6_address, &dst.ip6))
12161         {
12162           grp_set = dst_set = 1;
12163           ipv6_set = 1;
12164         }
12165       else
12166         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
12167         ;
12168       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
12169         ;
12170       else if (unformat (line_input, "decap-next %U",
12171                          unformat_vxlan_decap_next, &decap_next_index))
12172         ;
12173       else if (unformat (line_input, "vni %d", &vni))
12174         ;
12175       else
12176         {
12177           errmsg ("parse error '%U'", format_unformat_error, line_input);
12178           return -99;
12179         }
12180     }
12181
12182   if (src_set == 0)
12183     {
12184       errmsg ("tunnel src address not specified");
12185       return -99;
12186     }
12187   if (dst_set == 0)
12188     {
12189       errmsg ("tunnel dst address not specified");
12190       return -99;
12191     }
12192
12193   if (grp_set && !ip46_address_is_multicast (&dst))
12194     {
12195       errmsg ("tunnel group address not multicast");
12196       return -99;
12197     }
12198   if (grp_set && mcast_sw_if_index == ~0)
12199     {
12200       errmsg ("tunnel nonexistent multicast device");
12201       return -99;
12202     }
12203   if (grp_set == 0 && ip46_address_is_multicast (&dst))
12204     {
12205       errmsg ("tunnel dst address must be unicast");
12206       return -99;
12207     }
12208
12209
12210   if (ipv4_set && ipv6_set)
12211     {
12212       errmsg ("both IPv4 and IPv6 addresses specified");
12213       return -99;
12214     }
12215
12216   if ((vni == 0) || (vni >> 24))
12217     {
12218       errmsg ("vni not specified or out of range");
12219       return -99;
12220     }
12221
12222   M (VXLAN_ADD_DEL_TUNNEL, mp);
12223
12224   if (ipv6_set)
12225     {
12226       clib_memcpy (mp->src_address, &src.ip6, sizeof (src.ip6));
12227       clib_memcpy (mp->dst_address, &dst.ip6, sizeof (dst.ip6));
12228     }
12229   else
12230     {
12231       clib_memcpy (mp->src_address, &src.ip4, sizeof (src.ip4));
12232       clib_memcpy (mp->dst_address, &dst.ip4, sizeof (dst.ip4));
12233     }
12234
12235   mp->instance = htonl (instance);
12236   mp->encap_vrf_id = ntohl (encap_vrf_id);
12237   mp->decap_next_index = ntohl (decap_next_index);
12238   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
12239   mp->vni = ntohl (vni);
12240   mp->is_add = is_add;
12241   mp->is_ipv6 = ipv6_set;
12242
12243   S (mp);
12244   W (ret);
12245   return ret;
12246 }
12247
12248 static void vl_api_vxlan_tunnel_details_t_handler
12249   (vl_api_vxlan_tunnel_details_t * mp)
12250 {
12251   vat_main_t *vam = &vat_main;
12252   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
12253   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
12254
12255   print (vam->ofp, "%11d%11d%24U%24U%14d%18d%13d%19d",
12256          ntohl (mp->sw_if_index),
12257          ntohl (mp->instance),
12258          format_ip46_address, &src, IP46_TYPE_ANY,
12259          format_ip46_address, &dst, IP46_TYPE_ANY,
12260          ntohl (mp->encap_vrf_id),
12261          ntohl (mp->decap_next_index), ntohl (mp->vni),
12262          ntohl (mp->mcast_sw_if_index));
12263 }
12264
12265 static void vl_api_vxlan_tunnel_details_t_handler_json
12266   (vl_api_vxlan_tunnel_details_t * mp)
12267 {
12268   vat_main_t *vam = &vat_main;
12269   vat_json_node_t *node = NULL;
12270
12271   if (VAT_JSON_ARRAY != vam->json_tree.type)
12272     {
12273       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12274       vat_json_init_array (&vam->json_tree);
12275     }
12276   node = vat_json_array_add (&vam->json_tree);
12277
12278   vat_json_init_object (node);
12279   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12280
12281   vat_json_object_add_uint (node, "instance", ntohl (mp->instance));
12282
12283   if (mp->is_ipv6)
12284     {
12285       struct in6_addr ip6;
12286
12287       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
12288       vat_json_object_add_ip6 (node, "src_address", ip6);
12289       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
12290       vat_json_object_add_ip6 (node, "dst_address", ip6);
12291     }
12292   else
12293     {
12294       struct in_addr ip4;
12295
12296       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
12297       vat_json_object_add_ip4 (node, "src_address", ip4);
12298       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
12299       vat_json_object_add_ip4 (node, "dst_address", ip4);
12300     }
12301   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
12302   vat_json_object_add_uint (node, "decap_next_index",
12303                             ntohl (mp->decap_next_index));
12304   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
12305   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
12306   vat_json_object_add_uint (node, "mcast_sw_if_index",
12307                             ntohl (mp->mcast_sw_if_index));
12308 }
12309
12310 static int
12311 api_vxlan_tunnel_dump (vat_main_t * vam)
12312 {
12313   unformat_input_t *i = vam->input;
12314   vl_api_vxlan_tunnel_dump_t *mp;
12315   vl_api_control_ping_t *mp_ping;
12316   u32 sw_if_index;
12317   u8 sw_if_index_set = 0;
12318   int ret;
12319
12320   /* Parse args required to build the message */
12321   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12322     {
12323       if (unformat (i, "sw_if_index %d", &sw_if_index))
12324         sw_if_index_set = 1;
12325       else
12326         break;
12327     }
12328
12329   if (sw_if_index_set == 0)
12330     {
12331       sw_if_index = ~0;
12332     }
12333
12334   if (!vam->json_output)
12335     {
12336       print (vam->ofp, "%11s%11s%24s%24s%14s%18s%13s%19s",
12337              "sw_if_index", "instance", "src_address", "dst_address",
12338              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
12339     }
12340
12341   /* Get list of vxlan-tunnel interfaces */
12342   M (VXLAN_TUNNEL_DUMP, mp);
12343
12344   mp->sw_if_index = htonl (sw_if_index);
12345
12346   S (mp);
12347
12348   /* Use a control ping for synchronization */
12349   MPING (CONTROL_PING, mp_ping);
12350   S (mp_ping);
12351
12352   W (ret);
12353   return ret;
12354 }
12355
12356 static uword unformat_geneve_decap_next
12357   (unformat_input_t * input, va_list * args)
12358 {
12359   u32 *result = va_arg (*args, u32 *);
12360   u32 tmp;
12361
12362   if (unformat (input, "l2"))
12363     *result = GENEVE_INPUT_NEXT_L2_INPUT;
12364   else if (unformat (input, "%d", &tmp))
12365     *result = tmp;
12366   else
12367     return 0;
12368   return 1;
12369 }
12370
12371 static int
12372 api_geneve_add_del_tunnel (vat_main_t * vam)
12373 {
12374   unformat_input_t *line_input = vam->input;
12375   vl_api_geneve_add_del_tunnel_t *mp;
12376   ip46_address_t src, dst;
12377   u8 is_add = 1;
12378   u8 ipv4_set = 0, ipv6_set = 0;
12379   u8 src_set = 0;
12380   u8 dst_set = 0;
12381   u8 grp_set = 0;
12382   u32 mcast_sw_if_index = ~0;
12383   u32 encap_vrf_id = 0;
12384   u32 decap_next_index = ~0;
12385   u32 vni = 0;
12386   int ret;
12387
12388   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
12389   clib_memset (&src, 0, sizeof src);
12390   clib_memset (&dst, 0, sizeof dst);
12391
12392   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12393     {
12394       if (unformat (line_input, "del"))
12395         is_add = 0;
12396       else
12397         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
12398         {
12399           ipv4_set = 1;
12400           src_set = 1;
12401         }
12402       else
12403         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
12404         {
12405           ipv4_set = 1;
12406           dst_set = 1;
12407         }
12408       else
12409         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
12410         {
12411           ipv6_set = 1;
12412           src_set = 1;
12413         }
12414       else
12415         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
12416         {
12417           ipv6_set = 1;
12418           dst_set = 1;
12419         }
12420       else if (unformat (line_input, "group %U %U",
12421                          unformat_ip4_address, &dst.ip4,
12422                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12423         {
12424           grp_set = dst_set = 1;
12425           ipv4_set = 1;
12426         }
12427       else if (unformat (line_input, "group %U",
12428                          unformat_ip4_address, &dst.ip4))
12429         {
12430           grp_set = dst_set = 1;
12431           ipv4_set = 1;
12432         }
12433       else if (unformat (line_input, "group %U %U",
12434                          unformat_ip6_address, &dst.ip6,
12435                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12436         {
12437           grp_set = dst_set = 1;
12438           ipv6_set = 1;
12439         }
12440       else if (unformat (line_input, "group %U",
12441                          unformat_ip6_address, &dst.ip6))
12442         {
12443           grp_set = dst_set = 1;
12444           ipv6_set = 1;
12445         }
12446       else
12447         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
12448         ;
12449       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
12450         ;
12451       else if (unformat (line_input, "decap-next %U",
12452                          unformat_geneve_decap_next, &decap_next_index))
12453         ;
12454       else if (unformat (line_input, "vni %d", &vni))
12455         ;
12456       else
12457         {
12458           errmsg ("parse error '%U'", format_unformat_error, line_input);
12459           return -99;
12460         }
12461     }
12462
12463   if (src_set == 0)
12464     {
12465       errmsg ("tunnel src address not specified");
12466       return -99;
12467     }
12468   if (dst_set == 0)
12469     {
12470       errmsg ("tunnel dst address not specified");
12471       return -99;
12472     }
12473
12474   if (grp_set && !ip46_address_is_multicast (&dst))
12475     {
12476       errmsg ("tunnel group address not multicast");
12477       return -99;
12478     }
12479   if (grp_set && mcast_sw_if_index == ~0)
12480     {
12481       errmsg ("tunnel nonexistent multicast device");
12482       return -99;
12483     }
12484   if (grp_set == 0 && ip46_address_is_multicast (&dst))
12485     {
12486       errmsg ("tunnel dst address must be unicast");
12487       return -99;
12488     }
12489
12490
12491   if (ipv4_set && ipv6_set)
12492     {
12493       errmsg ("both IPv4 and IPv6 addresses specified");
12494       return -99;
12495     }
12496
12497   if ((vni == 0) || (vni >> 24))
12498     {
12499       errmsg ("vni not specified or out of range");
12500       return -99;
12501     }
12502
12503   M (GENEVE_ADD_DEL_TUNNEL, mp);
12504
12505   if (ipv6_set)
12506     {
12507       clib_memcpy (&mp->local_address.un.ip6, &src.ip6, sizeof (src.ip6));
12508       clib_memcpy (&mp->remote_address.un.ip6, &dst.ip6, sizeof (dst.ip6));
12509     }
12510   else
12511     {
12512       clib_memcpy (&mp->local_address.un.ip4, &src.ip4, sizeof (src.ip4));
12513       clib_memcpy (&mp->remote_address.un.ip4, &dst.ip4, sizeof (dst.ip4));
12514     }
12515   mp->encap_vrf_id = ntohl (encap_vrf_id);
12516   mp->decap_next_index = ntohl (decap_next_index);
12517   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
12518   mp->vni = ntohl (vni);
12519   mp->is_add = is_add;
12520
12521   S (mp);
12522   W (ret);
12523   return ret;
12524 }
12525
12526 static void vl_api_geneve_tunnel_details_t_handler
12527   (vl_api_geneve_tunnel_details_t * mp)
12528 {
12529   vat_main_t *vam = &vat_main;
12530   ip46_address_t src = {.as_u64[0] = 0,.as_u64[1] = 0 };
12531   ip46_address_t dst = {.as_u64[0] = 0,.as_u64[1] = 0 };
12532
12533   if (mp->src_address.af == ADDRESS_IP6)
12534     {
12535       clib_memcpy (&src.ip6, &mp->src_address.un.ip6, sizeof (ip6_address_t));
12536       clib_memcpy (&dst.ip6, &mp->dst_address.un.ip6, sizeof (ip6_address_t));
12537     }
12538   else
12539     {
12540       clib_memcpy (&src.ip4, &mp->src_address.un.ip4, sizeof (ip4_address_t));
12541       clib_memcpy (&dst.ip4, &mp->dst_address.un.ip4, sizeof (ip4_address_t));
12542     }
12543
12544   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
12545          ntohl (mp->sw_if_index),
12546          format_ip46_address, &src, IP46_TYPE_ANY,
12547          format_ip46_address, &dst, IP46_TYPE_ANY,
12548          ntohl (mp->encap_vrf_id),
12549          ntohl (mp->decap_next_index), ntohl (mp->vni),
12550          ntohl (mp->mcast_sw_if_index));
12551 }
12552
12553 static void vl_api_geneve_tunnel_details_t_handler_json
12554   (vl_api_geneve_tunnel_details_t * mp)
12555 {
12556   vat_main_t *vam = &vat_main;
12557   vat_json_node_t *node = NULL;
12558   bool is_ipv6;
12559
12560   if (VAT_JSON_ARRAY != vam->json_tree.type)
12561     {
12562       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12563       vat_json_init_array (&vam->json_tree);
12564     }
12565   node = vat_json_array_add (&vam->json_tree);
12566
12567   vat_json_init_object (node);
12568   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12569   is_ipv6 = mp->src_address.af == ADDRESS_IP6;
12570   if (is_ipv6)
12571     {
12572       struct in6_addr ip6;
12573
12574       clib_memcpy (&ip6, &mp->src_address.un.ip6, sizeof (ip6));
12575       vat_json_object_add_ip6 (node, "src_address", ip6);
12576       clib_memcpy (&ip6, &mp->dst_address.un.ip6, sizeof (ip6));
12577       vat_json_object_add_ip6 (node, "dst_address", ip6);
12578     }
12579   else
12580     {
12581       struct in_addr ip4;
12582
12583       clib_memcpy (&ip4, &mp->src_address.un.ip4, sizeof (ip4));
12584       vat_json_object_add_ip4 (node, "src_address", ip4);
12585       clib_memcpy (&ip4, &mp->dst_address.un.ip4, sizeof (ip4));
12586       vat_json_object_add_ip4 (node, "dst_address", ip4);
12587     }
12588   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
12589   vat_json_object_add_uint (node, "decap_next_index",
12590                             ntohl (mp->decap_next_index));
12591   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
12592   vat_json_object_add_uint (node, "mcast_sw_if_index",
12593                             ntohl (mp->mcast_sw_if_index));
12594 }
12595
12596 static int
12597 api_geneve_tunnel_dump (vat_main_t * vam)
12598 {
12599   unformat_input_t *i = vam->input;
12600   vl_api_geneve_tunnel_dump_t *mp;
12601   vl_api_control_ping_t *mp_ping;
12602   u32 sw_if_index;
12603   u8 sw_if_index_set = 0;
12604   int ret;
12605
12606   /* Parse args required to build the message */
12607   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12608     {
12609       if (unformat (i, "sw_if_index %d", &sw_if_index))
12610         sw_if_index_set = 1;
12611       else
12612         break;
12613     }
12614
12615   if (sw_if_index_set == 0)
12616     {
12617       sw_if_index = ~0;
12618     }
12619
12620   if (!vam->json_output)
12621     {
12622       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
12623              "sw_if_index", "local_address", "remote_address",
12624              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
12625     }
12626
12627   /* Get list of geneve-tunnel interfaces */
12628   M (GENEVE_TUNNEL_DUMP, mp);
12629
12630   mp->sw_if_index = htonl (sw_if_index);
12631
12632   S (mp);
12633
12634   /* Use a control ping for synchronization */
12635   M (CONTROL_PING, mp_ping);
12636   S (mp_ping);
12637
12638   W (ret);
12639   return ret;
12640 }
12641
12642 static int
12643 api_gre_tunnel_add_del (vat_main_t * vam)
12644 {
12645   unformat_input_t *line_input = vam->input;
12646   vl_api_address_t src = { }, dst =
12647   {
12648   };
12649   vl_api_gre_tunnel_add_del_t *mp;
12650   vl_api_gre_tunnel_type_t t_type;
12651   u8 is_add = 1;
12652   u8 src_set = 0;
12653   u8 dst_set = 0;
12654   u32 outer_fib_id = 0;
12655   u32 session_id = 0;
12656   u32 instance = ~0;
12657   int ret;
12658
12659   t_type = GRE_API_TUNNEL_TYPE_L3;
12660
12661   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12662     {
12663       if (unformat (line_input, "del"))
12664         is_add = 0;
12665       else if (unformat (line_input, "instance %d", &instance))
12666         ;
12667       else if (unformat (line_input, "src %U", unformat_vl_api_address, &src))
12668         {
12669           src_set = 1;
12670         }
12671       else if (unformat (line_input, "dst %U", unformat_vl_api_address, &dst))
12672         {
12673           dst_set = 1;
12674         }
12675       else if (unformat (line_input, "outer-fib-id %d", &outer_fib_id))
12676         ;
12677       else if (unformat (line_input, "teb"))
12678         t_type = GRE_API_TUNNEL_TYPE_TEB;
12679       else if (unformat (line_input, "erspan %d", &session_id))
12680         t_type = GRE_API_TUNNEL_TYPE_ERSPAN;
12681       else
12682         {
12683           errmsg ("parse error '%U'", format_unformat_error, line_input);
12684           return -99;
12685         }
12686     }
12687
12688   if (src_set == 0)
12689     {
12690       errmsg ("tunnel src address not specified");
12691       return -99;
12692     }
12693   if (dst_set == 0)
12694     {
12695       errmsg ("tunnel dst address not specified");
12696       return -99;
12697     }
12698
12699   M (GRE_TUNNEL_ADD_DEL, mp);
12700
12701   clib_memcpy (&mp->tunnel.src, &src, sizeof (mp->tunnel.src));
12702   clib_memcpy (&mp->tunnel.dst, &dst, sizeof (mp->tunnel.dst));
12703
12704   mp->tunnel.instance = htonl (instance);
12705   mp->tunnel.outer_fib_id = htonl (outer_fib_id);
12706   mp->is_add = is_add;
12707   mp->tunnel.session_id = htons ((u16) session_id);
12708   mp->tunnel.type = htonl (t_type);
12709
12710   S (mp);
12711   W (ret);
12712   return ret;
12713 }
12714
12715 static void vl_api_gre_tunnel_details_t_handler
12716   (vl_api_gre_tunnel_details_t * mp)
12717 {
12718   vat_main_t *vam = &vat_main;
12719
12720   print (vam->ofp, "%11d%11d%24U%24U%13d%14d%12d",
12721          ntohl (mp->tunnel.sw_if_index),
12722          ntohl (mp->tunnel.instance),
12723          format_vl_api_address, &mp->tunnel.src,
12724          format_vl_api_address, &mp->tunnel.dst,
12725          mp->tunnel.type, ntohl (mp->tunnel.outer_fib_id),
12726          ntohl (mp->tunnel.session_id));
12727 }
12728
12729 static void vl_api_gre_tunnel_details_t_handler_json
12730   (vl_api_gre_tunnel_details_t * mp)
12731 {
12732   vat_main_t *vam = &vat_main;
12733   vat_json_node_t *node = NULL;
12734
12735   if (VAT_JSON_ARRAY != vam->json_tree.type)
12736     {
12737       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12738       vat_json_init_array (&vam->json_tree);
12739     }
12740   node = vat_json_array_add (&vam->json_tree);
12741
12742   vat_json_init_object (node);
12743   vat_json_object_add_uint (node, "sw_if_index",
12744                             ntohl (mp->tunnel.sw_if_index));
12745   vat_json_object_add_uint (node, "instance", ntohl (mp->tunnel.instance));
12746
12747   vat_json_object_add_address (node, "src", &mp->tunnel.src);
12748   vat_json_object_add_address (node, "dst", &mp->tunnel.dst);
12749   vat_json_object_add_uint (node, "tunnel_type", mp->tunnel.type);
12750   vat_json_object_add_uint (node, "outer_fib_id",
12751                             ntohl (mp->tunnel.outer_fib_id));
12752   vat_json_object_add_uint (node, "session_id", mp->tunnel.session_id);
12753 }
12754
12755 static int
12756 api_gre_tunnel_dump (vat_main_t * vam)
12757 {
12758   unformat_input_t *i = vam->input;
12759   vl_api_gre_tunnel_dump_t *mp;
12760   vl_api_control_ping_t *mp_ping;
12761   u32 sw_if_index;
12762   u8 sw_if_index_set = 0;
12763   int ret;
12764
12765   /* Parse args required to build the message */
12766   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12767     {
12768       if (unformat (i, "sw_if_index %d", &sw_if_index))
12769         sw_if_index_set = 1;
12770       else
12771         break;
12772     }
12773
12774   if (sw_if_index_set == 0)
12775     {
12776       sw_if_index = ~0;
12777     }
12778
12779   if (!vam->json_output)
12780     {
12781       print (vam->ofp, "%11s%11s%24s%24s%13s%14s%12s",
12782              "sw_if_index", "instance", "src_address", "dst_address",
12783              "tunnel_type", "outer_fib_id", "session_id");
12784     }
12785
12786   /* Get list of gre-tunnel interfaces */
12787   M (GRE_TUNNEL_DUMP, mp);
12788
12789   mp->sw_if_index = htonl (sw_if_index);
12790
12791   S (mp);
12792
12793   /* Use a control ping for synchronization */
12794   MPING (CONTROL_PING, mp_ping);
12795   S (mp_ping);
12796
12797   W (ret);
12798   return ret;
12799 }
12800
12801 static int
12802 api_l2_fib_clear_table (vat_main_t * vam)
12803 {
12804 //  unformat_input_t * i = vam->input;
12805   vl_api_l2_fib_clear_table_t *mp;
12806   int ret;
12807
12808   M (L2_FIB_CLEAR_TABLE, mp);
12809
12810   S (mp);
12811   W (ret);
12812   return ret;
12813 }
12814
12815 static int
12816 api_l2_interface_efp_filter (vat_main_t * vam)
12817 {
12818   unformat_input_t *i = vam->input;
12819   vl_api_l2_interface_efp_filter_t *mp;
12820   u32 sw_if_index;
12821   u8 enable = 1;
12822   u8 sw_if_index_set = 0;
12823   int ret;
12824
12825   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12826     {
12827       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12828         sw_if_index_set = 1;
12829       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12830         sw_if_index_set = 1;
12831       else if (unformat (i, "enable"))
12832         enable = 1;
12833       else if (unformat (i, "disable"))
12834         enable = 0;
12835       else
12836         {
12837           clib_warning ("parse error '%U'", format_unformat_error, i);
12838           return -99;
12839         }
12840     }
12841
12842   if (sw_if_index_set == 0)
12843     {
12844       errmsg ("missing sw_if_index");
12845       return -99;
12846     }
12847
12848   M (L2_INTERFACE_EFP_FILTER, mp);
12849
12850   mp->sw_if_index = ntohl (sw_if_index);
12851   mp->enable_disable = enable;
12852
12853   S (mp);
12854   W (ret);
12855   return ret;
12856 }
12857
12858 #define foreach_vtr_op                          \
12859 _("disable",  L2_VTR_DISABLED)                  \
12860 _("push-1",  L2_VTR_PUSH_1)                     \
12861 _("push-2",  L2_VTR_PUSH_2)                     \
12862 _("pop-1",  L2_VTR_POP_1)                       \
12863 _("pop-2",  L2_VTR_POP_2)                       \
12864 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
12865 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
12866 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
12867 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
12868
12869 static int
12870 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
12871 {
12872   unformat_input_t *i = vam->input;
12873   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
12874   u32 sw_if_index;
12875   u8 sw_if_index_set = 0;
12876   u8 vtr_op_set = 0;
12877   u32 vtr_op = 0;
12878   u32 push_dot1q = 1;
12879   u32 tag1 = ~0;
12880   u32 tag2 = ~0;
12881   int ret;
12882
12883   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12884     {
12885       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12886         sw_if_index_set = 1;
12887       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12888         sw_if_index_set = 1;
12889       else if (unformat (i, "vtr_op %d", &vtr_op))
12890         vtr_op_set = 1;
12891 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
12892       foreach_vtr_op
12893 #undef _
12894         else if (unformat (i, "push_dot1q %d", &push_dot1q))
12895         ;
12896       else if (unformat (i, "tag1 %d", &tag1))
12897         ;
12898       else if (unformat (i, "tag2 %d", &tag2))
12899         ;
12900       else
12901         {
12902           clib_warning ("parse error '%U'", format_unformat_error, i);
12903           return -99;
12904         }
12905     }
12906
12907   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
12908     {
12909       errmsg ("missing vtr operation or sw_if_index");
12910       return -99;
12911     }
12912
12913   M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
12914   mp->sw_if_index = ntohl (sw_if_index);
12915   mp->vtr_op = ntohl (vtr_op);
12916   mp->push_dot1q = ntohl (push_dot1q);
12917   mp->tag1 = ntohl (tag1);
12918   mp->tag2 = ntohl (tag2);
12919
12920   S (mp);
12921   W (ret);
12922   return ret;
12923 }
12924
12925 static int
12926 api_create_vhost_user_if (vat_main_t * vam)
12927 {
12928   unformat_input_t *i = vam->input;
12929   vl_api_create_vhost_user_if_t *mp;
12930   u8 *file_name;
12931   u8 is_server = 0;
12932   u8 file_name_set = 0;
12933   u32 custom_dev_instance = ~0;
12934   u8 hwaddr[6];
12935   u8 use_custom_mac = 0;
12936   u8 disable_mrg_rxbuf = 0;
12937   u8 disable_indirect_desc = 0;
12938   u8 *tag = 0;
12939   u8 enable_gso = 0;
12940   int ret;
12941
12942   /* Shut up coverity */
12943   clib_memset (hwaddr, 0, sizeof (hwaddr));
12944
12945   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12946     {
12947       if (unformat (i, "socket %s", &file_name))
12948         {
12949           file_name_set = 1;
12950         }
12951       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
12952         ;
12953       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
12954         use_custom_mac = 1;
12955       else if (unformat (i, "server"))
12956         is_server = 1;
12957       else if (unformat (i, "disable_mrg_rxbuf"))
12958         disable_mrg_rxbuf = 1;
12959       else if (unformat (i, "disable_indirect_desc"))
12960         disable_indirect_desc = 1;
12961       else if (unformat (i, "gso"))
12962         enable_gso = 1;
12963       else if (unformat (i, "tag %s", &tag))
12964         ;
12965       else
12966         break;
12967     }
12968
12969   if (file_name_set == 0)
12970     {
12971       errmsg ("missing socket file name");
12972       return -99;
12973     }
12974
12975   if (vec_len (file_name) > 255)
12976     {
12977       errmsg ("socket file name too long");
12978       return -99;
12979     }
12980   vec_add1 (file_name, 0);
12981
12982   M (CREATE_VHOST_USER_IF, mp);
12983
12984   mp->is_server = is_server;
12985   mp->disable_mrg_rxbuf = disable_mrg_rxbuf;
12986   mp->disable_indirect_desc = disable_indirect_desc;
12987   mp->enable_gso = enable_gso;
12988   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
12989   vec_free (file_name);
12990   if (custom_dev_instance != ~0)
12991     {
12992       mp->renumber = 1;
12993       mp->custom_dev_instance = ntohl (custom_dev_instance);
12994     }
12995
12996   mp->use_custom_mac = use_custom_mac;
12997   clib_memcpy (mp->mac_address, hwaddr, 6);
12998   if (tag)
12999     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
13000   vec_free (tag);
13001
13002   S (mp);
13003   W (ret);
13004   return ret;
13005 }
13006
13007 static int
13008 api_modify_vhost_user_if (vat_main_t * vam)
13009 {
13010   unformat_input_t *i = vam->input;
13011   vl_api_modify_vhost_user_if_t *mp;
13012   u8 *file_name;
13013   u8 is_server = 0;
13014   u8 file_name_set = 0;
13015   u32 custom_dev_instance = ~0;
13016   u8 sw_if_index_set = 0;
13017   u32 sw_if_index = (u32) ~ 0;
13018   u8 enable_gso = 0;
13019   int ret;
13020
13021   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13022     {
13023       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13024         sw_if_index_set = 1;
13025       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13026         sw_if_index_set = 1;
13027       else if (unformat (i, "socket %s", &file_name))
13028         {
13029           file_name_set = 1;
13030         }
13031       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
13032         ;
13033       else if (unformat (i, "server"))
13034         is_server = 1;
13035       else if (unformat (i, "gso"))
13036         enable_gso = 1;
13037       else
13038         break;
13039     }
13040
13041   if (sw_if_index_set == 0)
13042     {
13043       errmsg ("missing sw_if_index or interface name");
13044       return -99;
13045     }
13046
13047   if (file_name_set == 0)
13048     {
13049       errmsg ("missing socket file name");
13050       return -99;
13051     }
13052
13053   if (vec_len (file_name) > 255)
13054     {
13055       errmsg ("socket file name too long");
13056       return -99;
13057     }
13058   vec_add1 (file_name, 0);
13059
13060   M (MODIFY_VHOST_USER_IF, mp);
13061
13062   mp->sw_if_index = ntohl (sw_if_index);
13063   mp->is_server = is_server;
13064   mp->enable_gso = enable_gso;
13065   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
13066   vec_free (file_name);
13067   if (custom_dev_instance != ~0)
13068     {
13069       mp->renumber = 1;
13070       mp->custom_dev_instance = ntohl (custom_dev_instance);
13071     }
13072
13073   S (mp);
13074   W (ret);
13075   return ret;
13076 }
13077
13078 static int
13079 api_delete_vhost_user_if (vat_main_t * vam)
13080 {
13081   unformat_input_t *i = vam->input;
13082   vl_api_delete_vhost_user_if_t *mp;
13083   u32 sw_if_index = ~0;
13084   u8 sw_if_index_set = 0;
13085   int ret;
13086
13087   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13088     {
13089       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13090         sw_if_index_set = 1;
13091       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13092         sw_if_index_set = 1;
13093       else
13094         break;
13095     }
13096
13097   if (sw_if_index_set == 0)
13098     {
13099       errmsg ("missing sw_if_index or interface name");
13100       return -99;
13101     }
13102
13103
13104   M (DELETE_VHOST_USER_IF, mp);
13105
13106   mp->sw_if_index = ntohl (sw_if_index);
13107
13108   S (mp);
13109   W (ret);
13110   return ret;
13111 }
13112
13113 static void vl_api_sw_interface_vhost_user_details_t_handler
13114   (vl_api_sw_interface_vhost_user_details_t * mp)
13115 {
13116   vat_main_t *vam = &vat_main;
13117
13118   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s",
13119          (char *) mp->interface_name,
13120          ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
13121          clib_net_to_host_u64 (mp->features), mp->is_server,
13122          ntohl (mp->num_regions), (char *) mp->sock_filename);
13123   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
13124 }
13125
13126 static void vl_api_sw_interface_vhost_user_details_t_handler_json
13127   (vl_api_sw_interface_vhost_user_details_t * mp)
13128 {
13129   vat_main_t *vam = &vat_main;
13130   vat_json_node_t *node = NULL;
13131
13132   if (VAT_JSON_ARRAY != vam->json_tree.type)
13133     {
13134       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13135       vat_json_init_array (&vam->json_tree);
13136     }
13137   node = vat_json_array_add (&vam->json_tree);
13138
13139   vat_json_init_object (node);
13140   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13141   vat_json_object_add_string_copy (node, "interface_name",
13142                                    mp->interface_name);
13143   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
13144                             ntohl (mp->virtio_net_hdr_sz));
13145   vat_json_object_add_uint (node, "features",
13146                             clib_net_to_host_u64 (mp->features));
13147   vat_json_object_add_uint (node, "is_server", mp->is_server);
13148   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
13149   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
13150   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
13151 }
13152
13153 static int
13154 api_sw_interface_vhost_user_dump (vat_main_t * vam)
13155 {
13156   vl_api_sw_interface_vhost_user_dump_t *mp;
13157   vl_api_control_ping_t *mp_ping;
13158   int ret;
13159   print (vam->ofp,
13160          "Interface name            idx hdr_sz features server regions filename");
13161
13162   /* Get list of vhost-user interfaces */
13163   M (SW_INTERFACE_VHOST_USER_DUMP, mp);
13164   S (mp);
13165
13166   /* Use a control ping for synchronization */
13167   MPING (CONTROL_PING, mp_ping);
13168   S (mp_ping);
13169
13170   W (ret);
13171   return ret;
13172 }
13173
13174 static int
13175 api_show_version (vat_main_t * vam)
13176 {
13177   vl_api_show_version_t *mp;
13178   int ret;
13179
13180   M (SHOW_VERSION, mp);
13181
13182   S (mp);
13183   W (ret);
13184   return ret;
13185 }
13186
13187
13188 static int
13189 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
13190 {
13191   unformat_input_t *line_input = vam->input;
13192   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
13193   ip4_address_t local4, remote4;
13194   ip6_address_t local6, remote6;
13195   u8 is_add = 1;
13196   u8 ipv4_set = 0, ipv6_set = 0;
13197   u8 local_set = 0;
13198   u8 remote_set = 0;
13199   u8 grp_set = 0;
13200   u32 mcast_sw_if_index = ~0;
13201   u32 encap_vrf_id = 0;
13202   u32 decap_vrf_id = 0;
13203   u8 protocol = ~0;
13204   u32 vni;
13205   u8 vni_set = 0;
13206   int ret;
13207
13208   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
13209   clib_memset (&local4, 0, sizeof local4);
13210   clib_memset (&remote4, 0, sizeof remote4);
13211   clib_memset (&local6, 0, sizeof local6);
13212   clib_memset (&remote6, 0, sizeof remote6);
13213
13214   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13215     {
13216       if (unformat (line_input, "del"))
13217         is_add = 0;
13218       else if (unformat (line_input, "local %U",
13219                          unformat_ip4_address, &local4))
13220         {
13221           local_set = 1;
13222           ipv4_set = 1;
13223         }
13224       else if (unformat (line_input, "remote %U",
13225                          unformat_ip4_address, &remote4))
13226         {
13227           remote_set = 1;
13228           ipv4_set = 1;
13229         }
13230       else if (unformat (line_input, "local %U",
13231                          unformat_ip6_address, &local6))
13232         {
13233           local_set = 1;
13234           ipv6_set = 1;
13235         }
13236       else if (unformat (line_input, "remote %U",
13237                          unformat_ip6_address, &remote6))
13238         {
13239           remote_set = 1;
13240           ipv6_set = 1;
13241         }
13242       else if (unformat (line_input, "group %U %U",
13243                          unformat_ip4_address, &remote4,
13244                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13245         {
13246           grp_set = remote_set = 1;
13247           ipv4_set = 1;
13248         }
13249       else if (unformat (line_input, "group %U",
13250                          unformat_ip4_address, &remote4))
13251         {
13252           grp_set = remote_set = 1;
13253           ipv4_set = 1;
13254         }
13255       else if (unformat (line_input, "group %U %U",
13256                          unformat_ip6_address, &remote6,
13257                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
13258         {
13259           grp_set = remote_set = 1;
13260           ipv6_set = 1;
13261         }
13262       else if (unformat (line_input, "group %U",
13263                          unformat_ip6_address, &remote6))
13264         {
13265           grp_set = remote_set = 1;
13266           ipv6_set = 1;
13267         }
13268       else
13269         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
13270         ;
13271       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
13272         ;
13273       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
13274         ;
13275       else if (unformat (line_input, "vni %d", &vni))
13276         vni_set = 1;
13277       else if (unformat (line_input, "next-ip4"))
13278         protocol = 1;
13279       else if (unformat (line_input, "next-ip6"))
13280         protocol = 2;
13281       else if (unformat (line_input, "next-ethernet"))
13282         protocol = 3;
13283       else if (unformat (line_input, "next-nsh"))
13284         protocol = 4;
13285       else
13286         {
13287           errmsg ("parse error '%U'", format_unformat_error, line_input);
13288           return -99;
13289         }
13290     }
13291
13292   if (local_set == 0)
13293     {
13294       errmsg ("tunnel local address not specified");
13295       return -99;
13296     }
13297   if (remote_set == 0)
13298     {
13299       errmsg ("tunnel remote address not specified");
13300       return -99;
13301     }
13302   if (grp_set && mcast_sw_if_index == ~0)
13303     {
13304       errmsg ("tunnel nonexistent multicast device");
13305       return -99;
13306     }
13307   if (ipv4_set && ipv6_set)
13308     {
13309       errmsg ("both IPv4 and IPv6 addresses specified");
13310       return -99;
13311     }
13312
13313   if (vni_set == 0)
13314     {
13315       errmsg ("vni not specified");
13316       return -99;
13317     }
13318
13319   M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
13320
13321
13322   if (ipv6_set)
13323     {
13324       clib_memcpy (&mp->local, &local6, sizeof (local6));
13325       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
13326     }
13327   else
13328     {
13329       clib_memcpy (&mp->local, &local4, sizeof (local4));
13330       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
13331     }
13332
13333   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
13334   mp->encap_vrf_id = ntohl (encap_vrf_id);
13335   mp->decap_vrf_id = ntohl (decap_vrf_id);
13336   mp->protocol = protocol;
13337   mp->vni = ntohl (vni);
13338   mp->is_add = is_add;
13339   mp->is_ipv6 = ipv6_set;
13340
13341   S (mp);
13342   W (ret);
13343   return ret;
13344 }
13345
13346 static void vl_api_vxlan_gpe_tunnel_details_t_handler
13347   (vl_api_vxlan_gpe_tunnel_details_t * mp)
13348 {
13349   vat_main_t *vam = &vat_main;
13350   ip46_address_t local = to_ip46 (mp->is_ipv6, mp->local);
13351   ip46_address_t remote = to_ip46 (mp->is_ipv6, mp->remote);
13352
13353   print (vam->ofp, "%11d%24U%24U%13d%12d%19d%14d%14d",
13354          ntohl (mp->sw_if_index),
13355          format_ip46_address, &local, IP46_TYPE_ANY,
13356          format_ip46_address, &remote, IP46_TYPE_ANY,
13357          ntohl (mp->vni), mp->protocol,
13358          ntohl (mp->mcast_sw_if_index),
13359          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
13360 }
13361
13362
13363 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
13364   (vl_api_vxlan_gpe_tunnel_details_t * mp)
13365 {
13366   vat_main_t *vam = &vat_main;
13367   vat_json_node_t *node = NULL;
13368   struct in_addr ip4;
13369   struct in6_addr ip6;
13370
13371   if (VAT_JSON_ARRAY != vam->json_tree.type)
13372     {
13373       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13374       vat_json_init_array (&vam->json_tree);
13375     }
13376   node = vat_json_array_add (&vam->json_tree);
13377
13378   vat_json_init_object (node);
13379   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13380   if (mp->is_ipv6)
13381     {
13382       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
13383       vat_json_object_add_ip6 (node, "local", ip6);
13384       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
13385       vat_json_object_add_ip6 (node, "remote", ip6);
13386     }
13387   else
13388     {
13389       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
13390       vat_json_object_add_ip4 (node, "local", ip4);
13391       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
13392       vat_json_object_add_ip4 (node, "remote", ip4);
13393     }
13394   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
13395   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
13396   vat_json_object_add_uint (node, "mcast_sw_if_index",
13397                             ntohl (mp->mcast_sw_if_index));
13398   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
13399   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
13400   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
13401 }
13402
13403 static int
13404 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
13405 {
13406   unformat_input_t *i = vam->input;
13407   vl_api_vxlan_gpe_tunnel_dump_t *mp;
13408   vl_api_control_ping_t *mp_ping;
13409   u32 sw_if_index;
13410   u8 sw_if_index_set = 0;
13411   int ret;
13412
13413   /* Parse args required to build the message */
13414   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13415     {
13416       if (unformat (i, "sw_if_index %d", &sw_if_index))
13417         sw_if_index_set = 1;
13418       else
13419         break;
13420     }
13421
13422   if (sw_if_index_set == 0)
13423     {
13424       sw_if_index = ~0;
13425     }
13426
13427   if (!vam->json_output)
13428     {
13429       print (vam->ofp, "%11s%24s%24s%13s%15s%19s%14s%14s",
13430              "sw_if_index", "local", "remote", "vni",
13431              "protocol", "mcast_sw_if_index", "encap_vrf_id", "decap_vrf_id");
13432     }
13433
13434   /* Get list of vxlan-tunnel interfaces */
13435   M (VXLAN_GPE_TUNNEL_DUMP, mp);
13436
13437   mp->sw_if_index = htonl (sw_if_index);
13438
13439   S (mp);
13440
13441   /* Use a control ping for synchronization */
13442   MPING (CONTROL_PING, mp_ping);
13443   S (mp_ping);
13444
13445   W (ret);
13446   return ret;
13447 }
13448
13449 static void vl_api_l2_fib_table_details_t_handler
13450   (vl_api_l2_fib_table_details_t * mp)
13451 {
13452   vat_main_t *vam = &vat_main;
13453
13454   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
13455          "       %d       %d     %d",
13456          ntohl (mp->bd_id), format_ethernet_address, mp->mac,
13457          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
13458          mp->bvi_mac);
13459 }
13460
13461 static void vl_api_l2_fib_table_details_t_handler_json
13462   (vl_api_l2_fib_table_details_t * mp)
13463 {
13464   vat_main_t *vam = &vat_main;
13465   vat_json_node_t *node = NULL;
13466
13467   if (VAT_JSON_ARRAY != vam->json_tree.type)
13468     {
13469       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13470       vat_json_init_array (&vam->json_tree);
13471     }
13472   node = vat_json_array_add (&vam->json_tree);
13473
13474   vat_json_init_object (node);
13475   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
13476   vat_json_object_add_bytes (node, "mac", mp->mac, 6);
13477   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13478   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
13479   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
13480   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
13481 }
13482
13483 static int
13484 api_l2_fib_table_dump (vat_main_t * vam)
13485 {
13486   unformat_input_t *i = vam->input;
13487   vl_api_l2_fib_table_dump_t *mp;
13488   vl_api_control_ping_t *mp_ping;
13489   u32 bd_id;
13490   u8 bd_id_set = 0;
13491   int ret;
13492
13493   /* Parse args required to build the message */
13494   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13495     {
13496       if (unformat (i, "bd_id %d", &bd_id))
13497         bd_id_set = 1;
13498       else
13499         break;
13500     }
13501
13502   if (bd_id_set == 0)
13503     {
13504       errmsg ("missing bridge domain");
13505       return -99;
13506     }
13507
13508   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
13509
13510   /* Get list of l2 fib entries */
13511   M (L2_FIB_TABLE_DUMP, mp);
13512
13513   mp->bd_id = ntohl (bd_id);
13514   S (mp);
13515
13516   /* Use a control ping for synchronization */
13517   MPING (CONTROL_PING, mp_ping);
13518   S (mp_ping);
13519
13520   W (ret);
13521   return ret;
13522 }
13523
13524
13525 static int
13526 api_interface_name_renumber (vat_main_t * vam)
13527 {
13528   unformat_input_t *line_input = vam->input;
13529   vl_api_interface_name_renumber_t *mp;
13530   u32 sw_if_index = ~0;
13531   u32 new_show_dev_instance = ~0;
13532   int ret;
13533
13534   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13535     {
13536       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
13537                     &sw_if_index))
13538         ;
13539       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
13540         ;
13541       else if (unformat (line_input, "new_show_dev_instance %d",
13542                          &new_show_dev_instance))
13543         ;
13544       else
13545         break;
13546     }
13547
13548   if (sw_if_index == ~0)
13549     {
13550       errmsg ("missing interface name or sw_if_index");
13551       return -99;
13552     }
13553
13554   if (new_show_dev_instance == ~0)
13555     {
13556       errmsg ("missing new_show_dev_instance");
13557       return -99;
13558     }
13559
13560   M (INTERFACE_NAME_RENUMBER, mp);
13561
13562   mp->sw_if_index = ntohl (sw_if_index);
13563   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
13564
13565   S (mp);
13566   W (ret);
13567   return ret;
13568 }
13569
13570 static int
13571 api_ip_probe_neighbor (vat_main_t * vam)
13572 {
13573   unformat_input_t *i = vam->input;
13574   vl_api_ip_probe_neighbor_t *mp;
13575   vl_api_address_t dst_adr = { };
13576   u8 int_set = 0;
13577   u8 adr_set = 0;
13578   u32 sw_if_index;
13579   int ret;
13580
13581   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13582     {
13583       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13584         int_set = 1;
13585       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13586         int_set = 1;
13587       else if (unformat (i, "address %U", unformat_vl_api_address, &dst_adr))
13588         adr_set = 1;
13589       else
13590         break;
13591     }
13592
13593   if (int_set == 0)
13594     {
13595       errmsg ("missing interface");
13596       return -99;
13597     }
13598
13599   if (adr_set == 0)
13600     {
13601       errmsg ("missing addresses");
13602       return -99;
13603     }
13604
13605   M (IP_PROBE_NEIGHBOR, mp);
13606
13607   mp->sw_if_index = ntohl (sw_if_index);
13608   clib_memcpy (&mp->dst, &dst_adr, sizeof (dst_adr));
13609
13610   S (mp);
13611   W (ret);
13612   return ret;
13613 }
13614
13615 static int
13616 api_ip_scan_neighbor_enable_disable (vat_main_t * vam)
13617 {
13618   unformat_input_t *i = vam->input;
13619   vl_api_ip_scan_neighbor_enable_disable_t *mp;
13620   u8 mode = IP_SCAN_V46_NEIGHBORS;
13621   u32 interval = 0, time = 0, update = 0, delay = 0, stale = 0;
13622   int ret;
13623
13624   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13625     {
13626       if (unformat (i, "ip4"))
13627         mode = IP_SCAN_V4_NEIGHBORS;
13628       else if (unformat (i, "ip6"))
13629         mode = IP_SCAN_V6_NEIGHBORS;
13630       if (unformat (i, "both"))
13631         mode = IP_SCAN_V46_NEIGHBORS;
13632       else if (unformat (i, "disable"))
13633         mode = IP_SCAN_DISABLED;
13634       else if (unformat (i, "interval %d", &interval))
13635         ;
13636       else if (unformat (i, "max-time %d", &time))
13637         ;
13638       else if (unformat (i, "max-update %d", &update))
13639         ;
13640       else if (unformat (i, "delay %d", &delay))
13641         ;
13642       else if (unformat (i, "stale %d", &stale))
13643         ;
13644       else
13645         break;
13646     }
13647
13648   if (interval > 255)
13649     {
13650       errmsg ("interval cannot exceed 255 minutes.");
13651       return -99;
13652     }
13653   if (time > 255)
13654     {
13655       errmsg ("max-time cannot exceed 255 usec.");
13656       return -99;
13657     }
13658   if (update > 255)
13659     {
13660       errmsg ("max-update cannot exceed 255.");
13661       return -99;
13662     }
13663   if (delay > 255)
13664     {
13665       errmsg ("delay cannot exceed 255 msec.");
13666       return -99;
13667     }
13668   if (stale > 255)
13669     {
13670       errmsg ("stale cannot exceed 255 minutes.");
13671       return -99;
13672     }
13673
13674   M (IP_SCAN_NEIGHBOR_ENABLE_DISABLE, mp);
13675   mp->mode = mode;
13676   mp->scan_interval = interval;
13677   mp->max_proc_time = time;
13678   mp->max_update = update;
13679   mp->scan_int_delay = delay;
13680   mp->stale_threshold = stale;
13681
13682   S (mp);
13683   W (ret);
13684   return ret;
13685 }
13686
13687 static int
13688 api_want_ip4_arp_events (vat_main_t * vam)
13689 {
13690   unformat_input_t *line_input = vam->input;
13691   vl_api_want_ip4_arp_events_t *mp;
13692   ip4_address_t address;
13693   int address_set = 0;
13694   u32 enable_disable = 1;
13695   int ret;
13696
13697   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13698     {
13699       if (unformat (line_input, "address %U", unformat_ip4_address, &address))
13700         address_set = 1;
13701       else if (unformat (line_input, "del"))
13702         enable_disable = 0;
13703       else
13704         break;
13705     }
13706
13707   if (address_set == 0)
13708     {
13709       errmsg ("missing addresses");
13710       return -99;
13711     }
13712
13713   M (WANT_IP4_ARP_EVENTS, mp);
13714   mp->enable_disable = enable_disable;
13715   mp->pid = htonl (getpid ());
13716   clib_memcpy (mp->ip, &address, sizeof (address));
13717
13718   S (mp);
13719   W (ret);
13720   return ret;
13721 }
13722
13723 static int
13724 api_want_ip6_nd_events (vat_main_t * vam)
13725 {
13726   unformat_input_t *line_input = vam->input;
13727   vl_api_want_ip6_nd_events_t *mp;
13728   vl_api_ip6_address_t address;
13729   int address_set = 0;
13730   u32 enable_disable = 1;
13731   int ret;
13732
13733   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13734     {
13735       if (unformat
13736           (line_input, "address %U", unformat_vl_api_ip6_address, &address))
13737         address_set = 1;
13738       else if (unformat (line_input, "del"))
13739         enable_disable = 0;
13740       else
13741         break;
13742     }
13743
13744   if (address_set == 0)
13745     {
13746       errmsg ("missing addresses");
13747       return -99;
13748     }
13749
13750   M (WANT_IP6_ND_EVENTS, mp);
13751   mp->enable_disable = enable_disable;
13752   mp->pid = htonl (getpid ());
13753   clib_memcpy (&mp->ip, &address, sizeof (address));
13754
13755   S (mp);
13756   W (ret);
13757   return ret;
13758 }
13759
13760 static int
13761 api_want_l2_macs_events (vat_main_t * vam)
13762 {
13763   unformat_input_t *line_input = vam->input;
13764   vl_api_want_l2_macs_events_t *mp;
13765   u8 enable_disable = 1;
13766   u32 scan_delay = 0;
13767   u32 max_macs_in_event = 0;
13768   u32 learn_limit = 0;
13769   int ret;
13770
13771   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13772     {
13773       if (unformat (line_input, "learn-limit %d", &learn_limit))
13774         ;
13775       else if (unformat (line_input, "scan-delay %d", &scan_delay))
13776         ;
13777       else if (unformat (line_input, "max-entries %d", &max_macs_in_event))
13778         ;
13779       else if (unformat (line_input, "disable"))
13780         enable_disable = 0;
13781       else
13782         break;
13783     }
13784
13785   M (WANT_L2_MACS_EVENTS, mp);
13786   mp->enable_disable = enable_disable;
13787   mp->pid = htonl (getpid ());
13788   mp->learn_limit = htonl (learn_limit);
13789   mp->scan_delay = (u8) scan_delay;
13790   mp->max_macs_in_event = (u8) (max_macs_in_event / 10);
13791   S (mp);
13792   W (ret);
13793   return ret;
13794 }
13795
13796 static int
13797 api_input_acl_set_interface (vat_main_t * vam)
13798 {
13799   unformat_input_t *i = vam->input;
13800   vl_api_input_acl_set_interface_t *mp;
13801   u32 sw_if_index;
13802   int sw_if_index_set;
13803   u32 ip4_table_index = ~0;
13804   u32 ip6_table_index = ~0;
13805   u32 l2_table_index = ~0;
13806   u8 is_add = 1;
13807   int ret;
13808
13809   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13810     {
13811       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13812         sw_if_index_set = 1;
13813       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13814         sw_if_index_set = 1;
13815       else if (unformat (i, "del"))
13816         is_add = 0;
13817       else if (unformat (i, "ip4-table %d", &ip4_table_index))
13818         ;
13819       else if (unformat (i, "ip6-table %d", &ip6_table_index))
13820         ;
13821       else if (unformat (i, "l2-table %d", &l2_table_index))
13822         ;
13823       else
13824         {
13825           clib_warning ("parse error '%U'", format_unformat_error, i);
13826           return -99;
13827         }
13828     }
13829
13830   if (sw_if_index_set == 0)
13831     {
13832       errmsg ("missing interface name or sw_if_index");
13833       return -99;
13834     }
13835
13836   M (INPUT_ACL_SET_INTERFACE, mp);
13837
13838   mp->sw_if_index = ntohl (sw_if_index);
13839   mp->ip4_table_index = ntohl (ip4_table_index);
13840   mp->ip6_table_index = ntohl (ip6_table_index);
13841   mp->l2_table_index = ntohl (l2_table_index);
13842   mp->is_add = is_add;
13843
13844   S (mp);
13845   W (ret);
13846   return ret;
13847 }
13848
13849 static int
13850 api_output_acl_set_interface (vat_main_t * vam)
13851 {
13852   unformat_input_t *i = vam->input;
13853   vl_api_output_acl_set_interface_t *mp;
13854   u32 sw_if_index;
13855   int sw_if_index_set;
13856   u32 ip4_table_index = ~0;
13857   u32 ip6_table_index = ~0;
13858   u32 l2_table_index = ~0;
13859   u8 is_add = 1;
13860   int ret;
13861
13862   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13863     {
13864       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13865         sw_if_index_set = 1;
13866       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13867         sw_if_index_set = 1;
13868       else if (unformat (i, "del"))
13869         is_add = 0;
13870       else if (unformat (i, "ip4-table %d", &ip4_table_index))
13871         ;
13872       else if (unformat (i, "ip6-table %d", &ip6_table_index))
13873         ;
13874       else if (unformat (i, "l2-table %d", &l2_table_index))
13875         ;
13876       else
13877         {
13878           clib_warning ("parse error '%U'", format_unformat_error, i);
13879           return -99;
13880         }
13881     }
13882
13883   if (sw_if_index_set == 0)
13884     {
13885       errmsg ("missing interface name or sw_if_index");
13886       return -99;
13887     }
13888
13889   M (OUTPUT_ACL_SET_INTERFACE, mp);
13890
13891   mp->sw_if_index = ntohl (sw_if_index);
13892   mp->ip4_table_index = ntohl (ip4_table_index);
13893   mp->ip6_table_index = ntohl (ip6_table_index);
13894   mp->l2_table_index = ntohl (l2_table_index);
13895   mp->is_add = is_add;
13896
13897   S (mp);
13898   W (ret);
13899   return ret;
13900 }
13901
13902 static int
13903 api_ip_address_dump (vat_main_t * vam)
13904 {
13905   unformat_input_t *i = vam->input;
13906   vl_api_ip_address_dump_t *mp;
13907   vl_api_control_ping_t *mp_ping;
13908   u32 sw_if_index = ~0;
13909   u8 sw_if_index_set = 0;
13910   u8 ipv4_set = 0;
13911   u8 ipv6_set = 0;
13912   int ret;
13913
13914   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13915     {
13916       if (unformat (i, "sw_if_index %d", &sw_if_index))
13917         sw_if_index_set = 1;
13918       else
13919         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13920         sw_if_index_set = 1;
13921       else if (unformat (i, "ipv4"))
13922         ipv4_set = 1;
13923       else if (unformat (i, "ipv6"))
13924         ipv6_set = 1;
13925       else
13926         break;
13927     }
13928
13929   if (ipv4_set && ipv6_set)
13930     {
13931       errmsg ("ipv4 and ipv6 flags cannot be both set");
13932       return -99;
13933     }
13934
13935   if ((!ipv4_set) && (!ipv6_set))
13936     {
13937       errmsg ("no ipv4 nor ipv6 flag set");
13938       return -99;
13939     }
13940
13941   if (sw_if_index_set == 0)
13942     {
13943       errmsg ("missing interface name or sw_if_index");
13944       return -99;
13945     }
13946
13947   vam->current_sw_if_index = sw_if_index;
13948   vam->is_ipv6 = ipv6_set;
13949
13950   M (IP_ADDRESS_DUMP, mp);
13951   mp->sw_if_index = ntohl (sw_if_index);
13952   mp->is_ipv6 = ipv6_set;
13953   S (mp);
13954
13955   /* Use a control ping for synchronization */
13956   MPING (CONTROL_PING, mp_ping);
13957   S (mp_ping);
13958
13959   W (ret);
13960   return ret;
13961 }
13962
13963 static int
13964 api_ip_dump (vat_main_t * vam)
13965 {
13966   vl_api_ip_dump_t *mp;
13967   vl_api_control_ping_t *mp_ping;
13968   unformat_input_t *in = vam->input;
13969   int ipv4_set = 0;
13970   int ipv6_set = 0;
13971   int is_ipv6;
13972   int i;
13973   int ret;
13974
13975   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
13976     {
13977       if (unformat (in, "ipv4"))
13978         ipv4_set = 1;
13979       else if (unformat (in, "ipv6"))
13980         ipv6_set = 1;
13981       else
13982         break;
13983     }
13984
13985   if (ipv4_set && ipv6_set)
13986     {
13987       errmsg ("ipv4 and ipv6 flags cannot be both set");
13988       return -99;
13989     }
13990
13991   if ((!ipv4_set) && (!ipv6_set))
13992     {
13993       errmsg ("no ipv4 nor ipv6 flag set");
13994       return -99;
13995     }
13996
13997   is_ipv6 = ipv6_set;
13998   vam->is_ipv6 = is_ipv6;
13999
14000   /* free old data */
14001   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
14002     {
14003       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
14004     }
14005   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
14006
14007   M (IP_DUMP, mp);
14008   mp->is_ipv6 = ipv6_set;
14009   S (mp);
14010
14011   /* Use a control ping for synchronization */
14012   MPING (CONTROL_PING, mp_ping);
14013   S (mp_ping);
14014
14015   W (ret);
14016   return ret;
14017 }
14018
14019 static int
14020 api_ipsec_spd_add_del (vat_main_t * vam)
14021 {
14022   unformat_input_t *i = vam->input;
14023   vl_api_ipsec_spd_add_del_t *mp;
14024   u32 spd_id = ~0;
14025   u8 is_add = 1;
14026   int ret;
14027
14028   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14029     {
14030       if (unformat (i, "spd_id %d", &spd_id))
14031         ;
14032       else if (unformat (i, "del"))
14033         is_add = 0;
14034       else
14035         {
14036           clib_warning ("parse error '%U'", format_unformat_error, i);
14037           return -99;
14038         }
14039     }
14040   if (spd_id == ~0)
14041     {
14042       errmsg ("spd_id must be set");
14043       return -99;
14044     }
14045
14046   M (IPSEC_SPD_ADD_DEL, mp);
14047
14048   mp->spd_id = ntohl (spd_id);
14049   mp->is_add = is_add;
14050
14051   S (mp);
14052   W (ret);
14053   return ret;
14054 }
14055
14056 static int
14057 api_ipsec_interface_add_del_spd (vat_main_t * vam)
14058 {
14059   unformat_input_t *i = vam->input;
14060   vl_api_ipsec_interface_add_del_spd_t *mp;
14061   u32 sw_if_index;
14062   u8 sw_if_index_set = 0;
14063   u32 spd_id = (u32) ~ 0;
14064   u8 is_add = 1;
14065   int ret;
14066
14067   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14068     {
14069       if (unformat (i, "del"))
14070         is_add = 0;
14071       else if (unformat (i, "spd_id %d", &spd_id))
14072         ;
14073       else
14074         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14075         sw_if_index_set = 1;
14076       else if (unformat (i, "sw_if_index %d", &sw_if_index))
14077         sw_if_index_set = 1;
14078       else
14079         {
14080           clib_warning ("parse error '%U'", format_unformat_error, i);
14081           return -99;
14082         }
14083
14084     }
14085
14086   if (spd_id == (u32) ~ 0)
14087     {
14088       errmsg ("spd_id must be set");
14089       return -99;
14090     }
14091
14092   if (sw_if_index_set == 0)
14093     {
14094       errmsg ("missing interface name or sw_if_index");
14095       return -99;
14096     }
14097
14098   M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
14099
14100   mp->spd_id = ntohl (spd_id);
14101   mp->sw_if_index = ntohl (sw_if_index);
14102   mp->is_add = is_add;
14103
14104   S (mp);
14105   W (ret);
14106   return ret;
14107 }
14108
14109 static int
14110 api_ipsec_spd_entry_add_del (vat_main_t * vam)
14111 {
14112   unformat_input_t *i = vam->input;
14113   vl_api_ipsec_spd_entry_add_del_t *mp;
14114   u8 is_add = 1, is_outbound = 0;
14115   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
14116   i32 priority = 0;
14117   u32 rport_start = 0, rport_stop = (u32) ~ 0;
14118   u32 lport_start = 0, lport_stop = (u32) ~ 0;
14119   vl_api_address_t laddr_start = { }, laddr_stop =
14120   {
14121   }, raddr_start =
14122   {
14123   }, raddr_stop =
14124   {
14125   };
14126   int ret;
14127
14128   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14129     {
14130       if (unformat (i, "del"))
14131         is_add = 0;
14132       if (unformat (i, "outbound"))
14133         is_outbound = 1;
14134       if (unformat (i, "inbound"))
14135         is_outbound = 0;
14136       else if (unformat (i, "spd_id %d", &spd_id))
14137         ;
14138       else if (unformat (i, "sa_id %d", &sa_id))
14139         ;
14140       else if (unformat (i, "priority %d", &priority))
14141         ;
14142       else if (unformat (i, "protocol %d", &protocol))
14143         ;
14144       else if (unformat (i, "lport_start %d", &lport_start))
14145         ;
14146       else if (unformat (i, "lport_stop %d", &lport_stop))
14147         ;
14148       else if (unformat (i, "rport_start %d", &rport_start))
14149         ;
14150       else if (unformat (i, "rport_stop %d", &rport_stop))
14151         ;
14152       else if (unformat (i, "laddr_start %U",
14153                          unformat_vl_api_address, &laddr_start))
14154         ;
14155       else if (unformat (i, "laddr_stop %U", unformat_vl_api_address,
14156                          &laddr_stop))
14157         ;
14158       else if (unformat (i, "raddr_start %U", unformat_vl_api_address,
14159                          &raddr_start))
14160         ;
14161       else if (unformat (i, "raddr_stop %U", unformat_vl_api_address,
14162                          &raddr_stop))
14163         ;
14164       else
14165         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
14166         {
14167           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
14168             {
14169               clib_warning ("unsupported action: 'resolve'");
14170               return -99;
14171             }
14172         }
14173       else
14174         {
14175           clib_warning ("parse error '%U'", format_unformat_error, i);
14176           return -99;
14177         }
14178
14179     }
14180
14181   M (IPSEC_SPD_ENTRY_ADD_DEL, mp);
14182
14183   mp->is_add = is_add;
14184
14185   mp->entry.spd_id = ntohl (spd_id);
14186   mp->entry.priority = ntohl (priority);
14187   mp->entry.is_outbound = is_outbound;
14188
14189   clib_memcpy (&mp->entry.remote_address_start, &raddr_start,
14190                sizeof (vl_api_address_t));
14191   clib_memcpy (&mp->entry.remote_address_stop, &raddr_stop,
14192                sizeof (vl_api_address_t));
14193   clib_memcpy (&mp->entry.local_address_start, &laddr_start,
14194                sizeof (vl_api_address_t));
14195   clib_memcpy (&mp->entry.local_address_stop, &laddr_stop,
14196                sizeof (vl_api_address_t));
14197
14198   mp->entry.protocol = (u8) protocol;
14199   mp->entry.local_port_start = ntohs ((u16) lport_start);
14200   mp->entry.local_port_stop = ntohs ((u16) lport_stop);
14201   mp->entry.remote_port_start = ntohs ((u16) rport_start);
14202   mp->entry.remote_port_stop = ntohs ((u16) rport_stop);
14203   mp->entry.policy = (u8) policy;
14204   mp->entry.sa_id = ntohl (sa_id);
14205
14206   S (mp);
14207   W (ret);
14208   return ret;
14209 }
14210
14211 static int
14212 api_ipsec_sad_entry_add_del (vat_main_t * vam)
14213 {
14214   unformat_input_t *i = vam->input;
14215   vl_api_ipsec_sad_entry_add_del_t *mp;
14216   u32 sad_id = 0, spi = 0;
14217   u8 *ck = 0, *ik = 0;
14218   u8 is_add = 1;
14219
14220   vl_api_ipsec_crypto_alg_t crypto_alg = IPSEC_API_CRYPTO_ALG_NONE;
14221   vl_api_ipsec_integ_alg_t integ_alg = IPSEC_API_INTEG_ALG_NONE;
14222   vl_api_ipsec_sad_flags_t flags = IPSEC_API_SAD_FLAG_NONE;
14223   vl_api_ipsec_proto_t protocol = IPSEC_API_PROTO_AH;
14224   vl_api_address_t tun_src, tun_dst;
14225   int ret;
14226
14227   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14228     {
14229       if (unformat (i, "del"))
14230         is_add = 0;
14231       else if (unformat (i, "sad_id %d", &sad_id))
14232         ;
14233       else if (unformat (i, "spi %d", &spi))
14234         ;
14235       else if (unformat (i, "esp"))
14236         protocol = IPSEC_API_PROTO_ESP;
14237       else
14238         if (unformat (i, "tunnel_src %U", unformat_vl_api_address, &tun_src))
14239         {
14240           flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL;
14241           if (ADDRESS_IP6 == tun_src.af)
14242             flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL_V6;
14243         }
14244       else
14245         if (unformat (i, "tunnel_dst %U", unformat_vl_api_address, &tun_dst))
14246         {
14247           flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL;
14248           if (ADDRESS_IP6 == tun_src.af)
14249             flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL_V6;
14250         }
14251       else
14252         if (unformat (i, "crypto_alg %U",
14253                       unformat_ipsec_api_crypto_alg, &crypto_alg))
14254         ;
14255       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
14256         ;
14257       else if (unformat (i, "integ_alg %U",
14258                          unformat_ipsec_api_integ_alg, &integ_alg))
14259         ;
14260       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
14261         ;
14262       else
14263         {
14264           clib_warning ("parse error '%U'", format_unformat_error, i);
14265           return -99;
14266         }
14267
14268     }
14269
14270   M (IPSEC_SAD_ENTRY_ADD_DEL, mp);
14271
14272   mp->is_add = is_add;
14273   mp->entry.sad_id = ntohl (sad_id);
14274   mp->entry.protocol = protocol;
14275   mp->entry.spi = ntohl (spi);
14276   mp->entry.flags = flags;
14277
14278   mp->entry.crypto_algorithm = crypto_alg;
14279   mp->entry.integrity_algorithm = integ_alg;
14280   mp->entry.crypto_key.length = vec_len (ck);
14281   mp->entry.integrity_key.length = vec_len (ik);
14282
14283   if (mp->entry.crypto_key.length > sizeof (mp->entry.crypto_key.data))
14284     mp->entry.crypto_key.length = sizeof (mp->entry.crypto_key.data);
14285
14286   if (mp->entry.integrity_key.length > sizeof (mp->entry.integrity_key.data))
14287     mp->entry.integrity_key.length = sizeof (mp->entry.integrity_key.data);
14288
14289   if (ck)
14290     clib_memcpy (mp->entry.crypto_key.data, ck, mp->entry.crypto_key.length);
14291   if (ik)
14292     clib_memcpy (mp->entry.integrity_key.data, ik,
14293                  mp->entry.integrity_key.length);
14294
14295   if (flags & IPSEC_API_SAD_FLAG_IS_TUNNEL)
14296     {
14297       clib_memcpy (&mp->entry.tunnel_src, &tun_src,
14298                    sizeof (mp->entry.tunnel_src));
14299       clib_memcpy (&mp->entry.tunnel_dst, &tun_dst,
14300                    sizeof (mp->entry.tunnel_dst));
14301     }
14302
14303   S (mp);
14304   W (ret);
14305   return ret;
14306 }
14307
14308 static int
14309 api_ipsec_tunnel_if_add_del (vat_main_t * vam)
14310 {
14311   unformat_input_t *i = vam->input;
14312   vl_api_ipsec_tunnel_if_add_del_t *mp;
14313   u32 local_spi = 0, remote_spi = 0;
14314   u32 crypto_alg = 0, integ_alg = 0;
14315   u8 *lck = NULL, *rck = NULL;
14316   u8 *lik = NULL, *rik = NULL;
14317   vl_api_address_t local_ip = { 0 };
14318   vl_api_address_t remote_ip = { 0 };
14319   f64 before = 0;
14320   u8 is_add = 1;
14321   u8 esn = 0;
14322   u8 anti_replay = 0;
14323   u8 renumber = 0;
14324   u32 instance = ~0;
14325   u32 count = 1, jj;
14326   int ret = -1;
14327
14328   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14329     {
14330       if (unformat (i, "del"))
14331         is_add = 0;
14332       else if (unformat (i, "esn"))
14333         esn = 1;
14334       else if (unformat (i, "anti-replay"))
14335         anti_replay = 1;
14336       else if (unformat (i, "count %d", &count))
14337         ;
14338       else if (unformat (i, "local_spi %d", &local_spi))
14339         ;
14340       else if (unformat (i, "remote_spi %d", &remote_spi))
14341         ;
14342       else
14343         if (unformat (i, "local_ip %U", unformat_vl_api_address, &local_ip))
14344         ;
14345       else
14346         if (unformat (i, "remote_ip %U", unformat_vl_api_address, &remote_ip))
14347         ;
14348       else if (unformat (i, "local_crypto_key %U", unformat_hex_string, &lck))
14349         ;
14350       else
14351         if (unformat (i, "remote_crypto_key %U", unformat_hex_string, &rck))
14352         ;
14353       else if (unformat (i, "local_integ_key %U", unformat_hex_string, &lik))
14354         ;
14355       else if (unformat (i, "remote_integ_key %U", unformat_hex_string, &rik))
14356         ;
14357       else
14358         if (unformat
14359             (i, "crypto_alg %U", unformat_ipsec_api_crypto_alg, &crypto_alg))
14360         {
14361           if (crypto_alg >= IPSEC_CRYPTO_N_ALG)
14362             {
14363               errmsg ("unsupported crypto-alg: '%U'\n",
14364                       format_ipsec_crypto_alg, crypto_alg);
14365               return -99;
14366             }
14367         }
14368       else
14369         if (unformat
14370             (i, "integ_alg %U", unformat_ipsec_api_integ_alg, &integ_alg))
14371         {
14372           if (integ_alg >= IPSEC_INTEG_N_ALG)
14373             {
14374               errmsg ("unsupported integ-alg: '%U'\n",
14375                       format_ipsec_integ_alg, integ_alg);
14376               return -99;
14377             }
14378         }
14379       else if (unformat (i, "instance %u", &instance))
14380         renumber = 1;
14381       else
14382         {
14383           errmsg ("parse error '%U'\n", format_unformat_error, i);
14384           return -99;
14385         }
14386     }
14387
14388   if (count > 1)
14389     {
14390       /* Turn on async mode */
14391       vam->async_mode = 1;
14392       vam->async_errors = 0;
14393       before = vat_time_now (vam);
14394     }
14395
14396   for (jj = 0; jj < count; jj++)
14397     {
14398       M (IPSEC_TUNNEL_IF_ADD_DEL, mp);
14399
14400       mp->is_add = is_add;
14401       mp->esn = esn;
14402       mp->anti_replay = anti_replay;
14403
14404       if (jj > 0)
14405         increment_address (&remote_ip);
14406
14407       clib_memcpy (&mp->local_ip, &local_ip, sizeof (local_ip));
14408       clib_memcpy (&mp->remote_ip, &remote_ip, sizeof (remote_ip));
14409
14410       mp->local_spi = htonl (local_spi + jj);
14411       mp->remote_spi = htonl (remote_spi + jj);
14412       mp->crypto_alg = (u8) crypto_alg;
14413
14414       mp->local_crypto_key_len = 0;
14415       if (lck)
14416         {
14417           mp->local_crypto_key_len = vec_len (lck);
14418           if (mp->local_crypto_key_len > sizeof (mp->local_crypto_key))
14419             mp->local_crypto_key_len = sizeof (mp->local_crypto_key);
14420           clib_memcpy (mp->local_crypto_key, lck, mp->local_crypto_key_len);
14421         }
14422
14423       mp->remote_crypto_key_len = 0;
14424       if (rck)
14425         {
14426           mp->remote_crypto_key_len = vec_len (rck);
14427           if (mp->remote_crypto_key_len > sizeof (mp->remote_crypto_key))
14428             mp->remote_crypto_key_len = sizeof (mp->remote_crypto_key);
14429           clib_memcpy (mp->remote_crypto_key, rck, mp->remote_crypto_key_len);
14430         }
14431
14432       mp->integ_alg = (u8) integ_alg;
14433
14434       mp->local_integ_key_len = 0;
14435       if (lik)
14436         {
14437           mp->local_integ_key_len = vec_len (lik);
14438           if (mp->local_integ_key_len > sizeof (mp->local_integ_key))
14439             mp->local_integ_key_len = sizeof (mp->local_integ_key);
14440           clib_memcpy (mp->local_integ_key, lik, mp->local_integ_key_len);
14441         }
14442
14443       mp->remote_integ_key_len = 0;
14444       if (rik)
14445         {
14446           mp->remote_integ_key_len = vec_len (rik);
14447           if (mp->remote_integ_key_len > sizeof (mp->remote_integ_key))
14448             mp->remote_integ_key_len = sizeof (mp->remote_integ_key);
14449           clib_memcpy (mp->remote_integ_key, rik, mp->remote_integ_key_len);
14450         }
14451
14452       if (renumber)
14453         {
14454           mp->renumber = renumber;
14455           mp->show_instance = ntohl (instance);
14456         }
14457       S (mp);
14458     }
14459
14460   /* When testing multiple add/del ops, use a control-ping to sync */
14461   if (count > 1)
14462     {
14463       vl_api_control_ping_t *mp_ping;
14464       f64 after;
14465       f64 timeout;
14466
14467       /* Shut off async mode */
14468       vam->async_mode = 0;
14469
14470       MPING (CONTROL_PING, mp_ping);
14471       S (mp_ping);
14472
14473       timeout = vat_time_now (vam) + 1.0;
14474       while (vat_time_now (vam) < timeout)
14475         if (vam->result_ready == 1)
14476           goto out;
14477       vam->retval = -99;
14478
14479     out:
14480       if (vam->retval == -99)
14481         errmsg ("timeout");
14482
14483       if (vam->async_errors > 0)
14484         {
14485           errmsg ("%d asynchronous errors", vam->async_errors);
14486           vam->retval = -98;
14487         }
14488       vam->async_errors = 0;
14489       after = vat_time_now (vam);
14490
14491       /* slim chance, but we might have eaten SIGTERM on the first iteration */
14492       if (jj > 0)
14493         count = jj;
14494
14495       print (vam->ofp, "%d tunnels in %.6f secs, %.2f tunnels/sec",
14496              count, after - before, count / (after - before));
14497     }
14498   else
14499     {
14500       /* Wait for a reply... */
14501       W (ret);
14502       return ret;
14503     }
14504
14505   return ret;
14506 }
14507
14508 static void
14509 vl_api_ipsec_sa_details_t_handler (vl_api_ipsec_sa_details_t * mp)
14510 {
14511   vat_main_t *vam = &vat_main;
14512
14513   print (vam->ofp, "sa_id %u sw_if_index %u spi %u proto %u crypto_alg %u "
14514          "crypto_key %U integ_alg %u integ_key %U flags %x "
14515          "tunnel_src_addr %U tunnel_dst_addr %U "
14516          "salt %u seq_outbound %lu last_seq_inbound %lu "
14517          "replay_window %lu\n",
14518          ntohl (mp->entry.sad_id),
14519          ntohl (mp->sw_if_index),
14520          ntohl (mp->entry.spi),
14521          ntohl (mp->entry.protocol),
14522          ntohl (mp->entry.crypto_algorithm),
14523          format_hex_bytes, mp->entry.crypto_key.data,
14524          mp->entry.crypto_key.length, ntohl (mp->entry.integrity_algorithm),
14525          format_hex_bytes, mp->entry.integrity_key.data,
14526          mp->entry.integrity_key.length, ntohl (mp->entry.flags),
14527          format_vl_api_address, &mp->entry.tunnel_src, format_vl_api_address,
14528          &mp->entry.tunnel_dst, ntohl (mp->salt),
14529          clib_net_to_host_u64 (mp->seq_outbound),
14530          clib_net_to_host_u64 (mp->last_seq_inbound),
14531          clib_net_to_host_u64 (mp->replay_window));
14532 }
14533
14534 #define vl_api_ipsec_sa_details_t_endian vl_noop_handler
14535 #define vl_api_ipsec_sa_details_t_print vl_noop_handler
14536
14537 static void vl_api_ipsec_sa_details_t_handler_json
14538   (vl_api_ipsec_sa_details_t * mp)
14539 {
14540   vat_main_t *vam = &vat_main;
14541   vat_json_node_t *node = NULL;
14542   vl_api_ipsec_sad_flags_t flags;
14543
14544   if (VAT_JSON_ARRAY != vam->json_tree.type)
14545     {
14546       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
14547       vat_json_init_array (&vam->json_tree);
14548     }
14549   node = vat_json_array_add (&vam->json_tree);
14550
14551   vat_json_init_object (node);
14552   vat_json_object_add_uint (node, "sa_id", ntohl (mp->entry.sad_id));
14553   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
14554   vat_json_object_add_uint (node, "spi", ntohl (mp->entry.spi));
14555   vat_json_object_add_uint (node, "proto", ntohl (mp->entry.protocol));
14556   vat_json_object_add_uint (node, "crypto_alg",
14557                             ntohl (mp->entry.crypto_algorithm));
14558   vat_json_object_add_uint (node, "integ_alg",
14559                             ntohl (mp->entry.integrity_algorithm));
14560   flags = ntohl (mp->entry.flags);
14561   vat_json_object_add_uint (node, "use_esn",
14562                             ! !(flags & IPSEC_API_SAD_FLAG_USE_ESN));
14563   vat_json_object_add_uint (node, "use_anti_replay",
14564                             ! !(flags & IPSEC_API_SAD_FLAG_USE_ANTI_REPLAY));
14565   vat_json_object_add_uint (node, "is_tunnel",
14566                             ! !(flags & IPSEC_API_SAD_FLAG_IS_TUNNEL));
14567   vat_json_object_add_uint (node, "is_tunnel_ip6",
14568                             ! !(flags & IPSEC_API_SAD_FLAG_IS_TUNNEL_V6));
14569   vat_json_object_add_uint (node, "udp_encap",
14570                             ! !(flags & IPSEC_API_SAD_FLAG_UDP_ENCAP));
14571   vat_json_object_add_bytes (node, "crypto_key", mp->entry.crypto_key.data,
14572                              mp->entry.crypto_key.length);
14573   vat_json_object_add_bytes (node, "integ_key", mp->entry.integrity_key.data,
14574                              mp->entry.integrity_key.length);
14575   vat_json_object_add_address (node, "src", &mp->entry.tunnel_src);
14576   vat_json_object_add_address (node, "dst", &mp->entry.tunnel_dst);
14577   vat_json_object_add_uint (node, "replay_window",
14578                             clib_net_to_host_u64 (mp->replay_window));
14579 }
14580
14581 static int
14582 api_ipsec_sa_dump (vat_main_t * vam)
14583 {
14584   unformat_input_t *i = vam->input;
14585   vl_api_ipsec_sa_dump_t *mp;
14586   vl_api_control_ping_t *mp_ping;
14587   u32 sa_id = ~0;
14588   int ret;
14589
14590   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14591     {
14592       if (unformat (i, "sa_id %d", &sa_id))
14593         ;
14594       else
14595         {
14596           clib_warning ("parse error '%U'", format_unformat_error, i);
14597           return -99;
14598         }
14599     }
14600
14601   M (IPSEC_SA_DUMP, mp);
14602
14603   mp->sa_id = ntohl (sa_id);
14604
14605   S (mp);
14606
14607   /* Use a control ping for synchronization */
14608   M (CONTROL_PING, mp_ping);
14609   S (mp_ping);
14610
14611   W (ret);
14612   return ret;
14613 }
14614
14615 static int
14616 api_ipsec_tunnel_if_set_sa (vat_main_t * vam)
14617 {
14618   unformat_input_t *i = vam->input;
14619   vl_api_ipsec_tunnel_if_set_sa_t *mp;
14620   u32 sw_if_index = ~0;
14621   u32 sa_id = ~0;
14622   u8 is_outbound = (u8) ~ 0;
14623   int ret;
14624
14625   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14626     {
14627       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
14628         ;
14629       else if (unformat (i, "sa_id %d", &sa_id))
14630         ;
14631       else if (unformat (i, "outbound"))
14632         is_outbound = 1;
14633       else if (unformat (i, "inbound"))
14634         is_outbound = 0;
14635       else
14636         {
14637           clib_warning ("parse error '%U'", format_unformat_error, i);
14638           return -99;
14639         }
14640     }
14641
14642   if (sw_if_index == ~0)
14643     {
14644       errmsg ("interface must be specified");
14645       return -99;
14646     }
14647
14648   if (sa_id == ~0)
14649     {
14650       errmsg ("SA ID must be specified");
14651       return -99;
14652     }
14653
14654   M (IPSEC_TUNNEL_IF_SET_SA, mp);
14655
14656   mp->sw_if_index = htonl (sw_if_index);
14657   mp->sa_id = htonl (sa_id);
14658   mp->is_outbound = is_outbound;
14659
14660   S (mp);
14661   W (ret);
14662
14663   return ret;
14664 }
14665
14666 static int
14667 api_get_first_msg_id (vat_main_t * vam)
14668 {
14669   vl_api_get_first_msg_id_t *mp;
14670   unformat_input_t *i = vam->input;
14671   u8 *name;
14672   u8 name_set = 0;
14673   int ret;
14674
14675   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
14676     {
14677       if (unformat (i, "client %s", &name))
14678         name_set = 1;
14679       else
14680         break;
14681     }
14682
14683   if (name_set == 0)
14684     {
14685       errmsg ("missing client name");
14686       return -99;
14687     }
14688   vec_add1 (name, 0);
14689
14690   if (vec_len (name) > 63)
14691     {
14692       errmsg ("client name too long");
14693       return -99;
14694     }
14695
14696   M (GET_FIRST_MSG_ID, mp);
14697   clib_memcpy (mp->name, name, vec_len (name));
14698   S (mp);
14699   W (ret);
14700   return ret;
14701 }
14702
14703 static int
14704 api_cop_interface_enable_disable (vat_main_t * vam)
14705 {
14706   unformat_input_t *line_input = vam->input;
14707   vl_api_cop_interface_enable_disable_t *mp;
14708   u32 sw_if_index = ~0;
14709   u8 enable_disable = 1;
14710   int ret;
14711
14712   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14713     {
14714       if (unformat (line_input, "disable"))
14715         enable_disable = 0;
14716       if (unformat (line_input, "enable"))
14717         enable_disable = 1;
14718       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
14719                          vam, &sw_if_index))
14720         ;
14721       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
14722         ;
14723       else
14724         break;
14725     }
14726
14727   if (sw_if_index == ~0)
14728     {
14729       errmsg ("missing interface name or sw_if_index");
14730       return -99;
14731     }
14732
14733   /* Construct the API message */
14734   M (COP_INTERFACE_ENABLE_DISABLE, mp);
14735   mp->sw_if_index = ntohl (sw_if_index);
14736   mp->enable_disable = enable_disable;
14737
14738   /* send it... */
14739   S (mp);
14740   /* Wait for the reply */
14741   W (ret);
14742   return ret;
14743 }
14744
14745 static int
14746 api_cop_whitelist_enable_disable (vat_main_t * vam)
14747 {
14748   unformat_input_t *line_input = vam->input;
14749   vl_api_cop_whitelist_enable_disable_t *mp;
14750   u32 sw_if_index = ~0;
14751   u8 ip4 = 0, ip6 = 0, default_cop = 0;
14752   u32 fib_id = 0;
14753   int ret;
14754
14755   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14756     {
14757       if (unformat (line_input, "ip4"))
14758         ip4 = 1;
14759       else if (unformat (line_input, "ip6"))
14760         ip6 = 1;
14761       else if (unformat (line_input, "default"))
14762         default_cop = 1;
14763       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
14764                          vam, &sw_if_index))
14765         ;
14766       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
14767         ;
14768       else if (unformat (line_input, "fib-id %d", &fib_id))
14769         ;
14770       else
14771         break;
14772     }
14773
14774   if (sw_if_index == ~0)
14775     {
14776       errmsg ("missing interface name or sw_if_index");
14777       return -99;
14778     }
14779
14780   /* Construct the API message */
14781   M (COP_WHITELIST_ENABLE_DISABLE, mp);
14782   mp->sw_if_index = ntohl (sw_if_index);
14783   mp->fib_id = ntohl (fib_id);
14784   mp->ip4 = ip4;
14785   mp->ip6 = ip6;
14786   mp->default_cop = default_cop;
14787
14788   /* send it... */
14789   S (mp);
14790   /* Wait for the reply */
14791   W (ret);
14792   return ret;
14793 }
14794
14795 static int
14796 api_get_node_graph (vat_main_t * vam)
14797 {
14798   vl_api_get_node_graph_t *mp;
14799   int ret;
14800
14801   M (GET_NODE_GRAPH, mp);
14802
14803   /* send it... */
14804   S (mp);
14805   /* Wait for the reply */
14806   W (ret);
14807   return ret;
14808 }
14809
14810 /* *INDENT-OFF* */
14811 /** Used for parsing LISP eids */
14812 typedef CLIB_PACKED(struct{
14813   u8 addr[16];   /**< eid address */
14814   u32 len;       /**< prefix length if IP */
14815   u8 type;      /**< type of eid */
14816 }) lisp_eid_vat_t;
14817 /* *INDENT-ON* */
14818
14819 static uword
14820 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
14821 {
14822   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
14823
14824   clib_memset (a, 0, sizeof (a[0]));
14825
14826   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
14827     {
14828       a->type = 0;              /* ipv4 type */
14829     }
14830   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
14831     {
14832       a->type = 1;              /* ipv6 type */
14833     }
14834   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
14835     {
14836       a->type = 2;              /* mac type */
14837     }
14838   else if (unformat (input, "%U", unformat_nsh_address, a->addr))
14839     {
14840       a->type = 3;              /* NSH type */
14841       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) a->addr;
14842       nsh->spi = clib_host_to_net_u32 (nsh->spi);
14843     }
14844   else
14845     {
14846       return 0;
14847     }
14848
14849   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
14850     {
14851       return 0;
14852     }
14853
14854   return 1;
14855 }
14856
14857 static int
14858 lisp_eid_size_vat (u8 type)
14859 {
14860   switch (type)
14861     {
14862     case 0:
14863       return 4;
14864     case 1:
14865       return 16;
14866     case 2:
14867       return 6;
14868     case 3:
14869       return 5;
14870     }
14871   return 0;
14872 }
14873
14874 static void
14875 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
14876 {
14877   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
14878 }
14879
14880 static int
14881 api_one_add_del_locator_set (vat_main_t * vam)
14882 {
14883   unformat_input_t *input = vam->input;
14884   vl_api_one_add_del_locator_set_t *mp;
14885   u8 is_add = 1;
14886   u8 *locator_set_name = NULL;
14887   u8 locator_set_name_set = 0;
14888   vl_api_local_locator_t locator, *locators = 0;
14889   u32 sw_if_index, priority, weight;
14890   u32 data_len = 0;
14891
14892   int ret;
14893   /* Parse args required to build the message */
14894   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14895     {
14896       if (unformat (input, "del"))
14897         {
14898           is_add = 0;
14899         }
14900       else if (unformat (input, "locator-set %s", &locator_set_name))
14901         {
14902           locator_set_name_set = 1;
14903         }
14904       else if (unformat (input, "sw_if_index %u p %u w %u",
14905                          &sw_if_index, &priority, &weight))
14906         {
14907           locator.sw_if_index = htonl (sw_if_index);
14908           locator.priority = priority;
14909           locator.weight = weight;
14910           vec_add1 (locators, locator);
14911         }
14912       else
14913         if (unformat
14914             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
14915              &sw_if_index, &priority, &weight))
14916         {
14917           locator.sw_if_index = htonl (sw_if_index);
14918           locator.priority = priority;
14919           locator.weight = weight;
14920           vec_add1 (locators, locator);
14921         }
14922       else
14923         break;
14924     }
14925
14926   if (locator_set_name_set == 0)
14927     {
14928       errmsg ("missing locator-set name");
14929       vec_free (locators);
14930       return -99;
14931     }
14932
14933   if (vec_len (locator_set_name) > 64)
14934     {
14935       errmsg ("locator-set name too long");
14936       vec_free (locator_set_name);
14937       vec_free (locators);
14938       return -99;
14939     }
14940   vec_add1 (locator_set_name, 0);
14941
14942   data_len = sizeof (vl_api_local_locator_t) * vec_len (locators);
14943
14944   /* Construct the API message */
14945   M2 (ONE_ADD_DEL_LOCATOR_SET, mp, data_len);
14946
14947   mp->is_add = is_add;
14948   clib_memcpy (mp->locator_set_name, locator_set_name,
14949                vec_len (locator_set_name));
14950   vec_free (locator_set_name);
14951
14952   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
14953   if (locators)
14954     clib_memcpy (mp->locators, locators, data_len);
14955   vec_free (locators);
14956
14957   /* send it... */
14958   S (mp);
14959
14960   /* Wait for a reply... */
14961   W (ret);
14962   return ret;
14963 }
14964
14965 #define api_lisp_add_del_locator_set api_one_add_del_locator_set
14966
14967 static int
14968 api_one_add_del_locator (vat_main_t * vam)
14969 {
14970   unformat_input_t *input = vam->input;
14971   vl_api_one_add_del_locator_t *mp;
14972   u32 tmp_if_index = ~0;
14973   u32 sw_if_index = ~0;
14974   u8 sw_if_index_set = 0;
14975   u8 sw_if_index_if_name_set = 0;
14976   u32 priority = ~0;
14977   u8 priority_set = 0;
14978   u32 weight = ~0;
14979   u8 weight_set = 0;
14980   u8 is_add = 1;
14981   u8 *locator_set_name = NULL;
14982   u8 locator_set_name_set = 0;
14983   int ret;
14984
14985   /* Parse args required to build the message */
14986   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14987     {
14988       if (unformat (input, "del"))
14989         {
14990           is_add = 0;
14991         }
14992       else if (unformat (input, "locator-set %s", &locator_set_name))
14993         {
14994           locator_set_name_set = 1;
14995         }
14996       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
14997                          &tmp_if_index))
14998         {
14999           sw_if_index_if_name_set = 1;
15000           sw_if_index = tmp_if_index;
15001         }
15002       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
15003         {
15004           sw_if_index_set = 1;
15005           sw_if_index = tmp_if_index;
15006         }
15007       else if (unformat (input, "p %d", &priority))
15008         {
15009           priority_set = 1;
15010         }
15011       else if (unformat (input, "w %d", &weight))
15012         {
15013           weight_set = 1;
15014         }
15015       else
15016         break;
15017     }
15018
15019   if (locator_set_name_set == 0)
15020     {
15021       errmsg ("missing locator-set name");
15022       return -99;
15023     }
15024
15025   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
15026     {
15027       errmsg ("missing sw_if_index");
15028       vec_free (locator_set_name);
15029       return -99;
15030     }
15031
15032   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
15033     {
15034       errmsg ("cannot use both params interface name and sw_if_index");
15035       vec_free (locator_set_name);
15036       return -99;
15037     }
15038
15039   if (priority_set == 0)
15040     {
15041       errmsg ("missing locator-set priority");
15042       vec_free (locator_set_name);
15043       return -99;
15044     }
15045
15046   if (weight_set == 0)
15047     {
15048       errmsg ("missing locator-set weight");
15049       vec_free (locator_set_name);
15050       return -99;
15051     }
15052
15053   if (vec_len (locator_set_name) > 64)
15054     {
15055       errmsg ("locator-set name too long");
15056       vec_free (locator_set_name);
15057       return -99;
15058     }
15059   vec_add1 (locator_set_name, 0);
15060
15061   /* Construct the API message */
15062   M (ONE_ADD_DEL_LOCATOR, mp);
15063
15064   mp->is_add = is_add;
15065   mp->sw_if_index = ntohl (sw_if_index);
15066   mp->priority = priority;
15067   mp->weight = weight;
15068   clib_memcpy (mp->locator_set_name, locator_set_name,
15069                vec_len (locator_set_name));
15070   vec_free (locator_set_name);
15071
15072   /* send it... */
15073   S (mp);
15074
15075   /* Wait for a reply... */
15076   W (ret);
15077   return ret;
15078 }
15079
15080 #define api_lisp_add_del_locator api_one_add_del_locator
15081
15082 uword
15083 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
15084 {
15085   u32 *key_id = va_arg (*args, u32 *);
15086   u8 *s = 0;
15087
15088   if (unformat (input, "%s", &s))
15089     {
15090       if (!strcmp ((char *) s, "sha1"))
15091         key_id[0] = HMAC_SHA_1_96;
15092       else if (!strcmp ((char *) s, "sha256"))
15093         key_id[0] = HMAC_SHA_256_128;
15094       else
15095         {
15096           clib_warning ("invalid key_id: '%s'", s);
15097           key_id[0] = HMAC_NO_KEY;
15098         }
15099     }
15100   else
15101     return 0;
15102
15103   vec_free (s);
15104   return 1;
15105 }
15106
15107 static int
15108 api_one_add_del_local_eid (vat_main_t * vam)
15109 {
15110   unformat_input_t *input = vam->input;
15111   vl_api_one_add_del_local_eid_t *mp;
15112   u8 is_add = 1;
15113   u8 eid_set = 0;
15114   lisp_eid_vat_t _eid, *eid = &_eid;
15115   u8 *locator_set_name = 0;
15116   u8 locator_set_name_set = 0;
15117   u32 vni = 0;
15118   u16 key_id = 0;
15119   u8 *key = 0;
15120   int ret;
15121
15122   /* Parse args required to build the message */
15123   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15124     {
15125       if (unformat (input, "del"))
15126         {
15127           is_add = 0;
15128         }
15129       else if (unformat (input, "vni %d", &vni))
15130         {
15131           ;
15132         }
15133       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
15134         {
15135           eid_set = 1;
15136         }
15137       else if (unformat (input, "locator-set %s", &locator_set_name))
15138         {
15139           locator_set_name_set = 1;
15140         }
15141       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
15142         ;
15143       else if (unformat (input, "secret-key %_%v%_", &key))
15144         ;
15145       else
15146         break;
15147     }
15148
15149   if (locator_set_name_set == 0)
15150     {
15151       errmsg ("missing locator-set name");
15152       return -99;
15153     }
15154
15155   if (0 == eid_set)
15156     {
15157       errmsg ("EID address not set!");
15158       vec_free (locator_set_name);
15159       return -99;
15160     }
15161
15162   if (key && (0 == key_id))
15163     {
15164       errmsg ("invalid key_id!");
15165       return -99;
15166     }
15167
15168   if (vec_len (key) > 64)
15169     {
15170       errmsg ("key too long");
15171       vec_free (key);
15172       return -99;
15173     }
15174
15175   if (vec_len (locator_set_name) > 64)
15176     {
15177       errmsg ("locator-set name too long");
15178       vec_free (locator_set_name);
15179       return -99;
15180     }
15181   vec_add1 (locator_set_name, 0);
15182
15183   /* Construct the API message */
15184   M (ONE_ADD_DEL_LOCAL_EID, mp);
15185
15186   mp->is_add = is_add;
15187   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
15188   mp->eid_type = eid->type;
15189   mp->prefix_len = eid->len;
15190   mp->vni = clib_host_to_net_u32 (vni);
15191   mp->key_id = clib_host_to_net_u16 (key_id);
15192   clib_memcpy (mp->locator_set_name, locator_set_name,
15193                vec_len (locator_set_name));
15194   clib_memcpy (mp->key, key, vec_len (key));
15195
15196   vec_free (locator_set_name);
15197   vec_free (key);
15198
15199   /* send it... */
15200   S (mp);
15201
15202   /* Wait for a reply... */
15203   W (ret);
15204   return ret;
15205 }
15206
15207 #define api_lisp_add_del_local_eid api_one_add_del_local_eid
15208
15209 static int
15210 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
15211 {
15212   u32 dp_table = 0, vni = 0;;
15213   unformat_input_t *input = vam->input;
15214   vl_api_gpe_add_del_fwd_entry_t *mp;
15215   u8 is_add = 1;
15216   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
15217   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
15218   u8 rmt_eid_set = 0, lcl_eid_set = 0;
15219   u32 action = ~0, w;
15220   ip4_address_t rmt_rloc4, lcl_rloc4;
15221   ip6_address_t rmt_rloc6, lcl_rloc6;
15222   vl_api_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
15223   int ret;
15224
15225   clib_memset (&rloc, 0, sizeof (rloc));
15226
15227   /* Parse args required to build the message */
15228   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15229     {
15230       if (unformat (input, "del"))
15231         is_add = 0;
15232       else if (unformat (input, "add"))
15233         is_add = 1;
15234       else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
15235         {
15236           rmt_eid_set = 1;
15237         }
15238       else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
15239         {
15240           lcl_eid_set = 1;
15241         }
15242       else if (unformat (input, "vrf %d", &dp_table))
15243         ;
15244       else if (unformat (input, "bd %d", &dp_table))
15245         ;
15246       else if (unformat (input, "vni %d", &vni))
15247         ;
15248       else if (unformat (input, "w %d", &w))
15249         {
15250           if (!curr_rloc)
15251             {
15252               errmsg ("No RLOC configured for setting priority/weight!");
15253               return -99;
15254             }
15255           curr_rloc->weight = w;
15256         }
15257       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
15258                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
15259         {
15260           rloc.is_ip4 = 1;
15261
15262           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
15263           rloc.weight = 0;
15264           vec_add1 (lcl_locs, rloc);
15265
15266           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
15267           vec_add1 (rmt_locs, rloc);
15268           /* weight saved in rmt loc */
15269           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
15270         }
15271       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
15272                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
15273         {
15274           rloc.is_ip4 = 0;
15275           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
15276           rloc.weight = 0;
15277           vec_add1 (lcl_locs, rloc);
15278
15279           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
15280           vec_add1 (rmt_locs, rloc);
15281           /* weight saved in rmt loc */
15282           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
15283         }
15284       else if (unformat (input, "action %d", &action))
15285         {
15286           ;
15287         }
15288       else
15289         {
15290           clib_warning ("parse error '%U'", format_unformat_error, input);
15291           return -99;
15292         }
15293     }
15294
15295   if (!rmt_eid_set)
15296     {
15297       errmsg ("remote eid addresses not set");
15298       return -99;
15299     }
15300
15301   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
15302     {
15303       errmsg ("eid types don't match");
15304       return -99;
15305     }
15306
15307   if (0 == rmt_locs && (u32) ~ 0 == action)
15308     {
15309       errmsg ("action not set for negative mapping");
15310       return -99;
15311     }
15312
15313   /* Construct the API message */
15314   M2 (GPE_ADD_DEL_FWD_ENTRY, mp,
15315       sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs) * 2);
15316
15317   mp->is_add = is_add;
15318   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
15319   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
15320   mp->eid_type = rmt_eid->type;
15321   mp->dp_table = clib_host_to_net_u32 (dp_table);
15322   mp->vni = clib_host_to_net_u32 (vni);
15323   mp->rmt_len = rmt_eid->len;
15324   mp->lcl_len = lcl_eid->len;
15325   mp->action = action;
15326
15327   if (0 != rmt_locs && 0 != lcl_locs)
15328     {
15329       mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
15330       clib_memcpy (mp->locs, lcl_locs,
15331                    (sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs)));
15332
15333       u32 offset = sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs);
15334       clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
15335                    (sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs)));
15336     }
15337   vec_free (lcl_locs);
15338   vec_free (rmt_locs);
15339
15340   /* send it... */
15341   S (mp);
15342
15343   /* Wait for a reply... */
15344   W (ret);
15345   return ret;
15346 }
15347
15348 static int
15349 api_one_add_del_map_server (vat_main_t * vam)
15350 {
15351   unformat_input_t *input = vam->input;
15352   vl_api_one_add_del_map_server_t *mp;
15353   u8 is_add = 1;
15354   u8 ipv4_set = 0;
15355   u8 ipv6_set = 0;
15356   ip4_address_t ipv4;
15357   ip6_address_t ipv6;
15358   int ret;
15359
15360   /* Parse args required to build the message */
15361   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15362     {
15363       if (unformat (input, "del"))
15364         {
15365           is_add = 0;
15366         }
15367       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
15368         {
15369           ipv4_set = 1;
15370         }
15371       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
15372         {
15373           ipv6_set = 1;
15374         }
15375       else
15376         break;
15377     }
15378
15379   if (ipv4_set && ipv6_set)
15380     {
15381       errmsg ("both eid v4 and v6 addresses set");
15382       return -99;
15383     }
15384
15385   if (!ipv4_set && !ipv6_set)
15386     {
15387       errmsg ("eid addresses not set");
15388       return -99;
15389     }
15390
15391   /* Construct the API message */
15392   M (ONE_ADD_DEL_MAP_SERVER, mp);
15393
15394   mp->is_add = is_add;
15395   if (ipv6_set)
15396     {
15397       mp->is_ipv6 = 1;
15398       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
15399     }
15400   else
15401     {
15402       mp->is_ipv6 = 0;
15403       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
15404     }
15405
15406   /* send it... */
15407   S (mp);
15408
15409   /* Wait for a reply... */
15410   W (ret);
15411   return ret;
15412 }
15413
15414 #define api_lisp_add_del_map_server api_one_add_del_map_server
15415
15416 static int
15417 api_one_add_del_map_resolver (vat_main_t * vam)
15418 {
15419   unformat_input_t *input = vam->input;
15420   vl_api_one_add_del_map_resolver_t *mp;
15421   u8 is_add = 1;
15422   u8 ipv4_set = 0;
15423   u8 ipv6_set = 0;
15424   ip4_address_t ipv4;
15425   ip6_address_t ipv6;
15426   int ret;
15427
15428   /* Parse args required to build the message */
15429   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15430     {
15431       if (unformat (input, "del"))
15432         {
15433           is_add = 0;
15434         }
15435       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
15436         {
15437           ipv4_set = 1;
15438         }
15439       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
15440         {
15441           ipv6_set = 1;
15442         }
15443       else
15444         break;
15445     }
15446
15447   if (ipv4_set && ipv6_set)
15448     {
15449       errmsg ("both eid v4 and v6 addresses set");
15450       return -99;
15451     }
15452
15453   if (!ipv4_set && !ipv6_set)
15454     {
15455       errmsg ("eid addresses not set");
15456       return -99;
15457     }
15458
15459   /* Construct the API message */
15460   M (ONE_ADD_DEL_MAP_RESOLVER, mp);
15461
15462   mp->is_add = is_add;
15463   if (ipv6_set)
15464     {
15465       mp->is_ipv6 = 1;
15466       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
15467     }
15468   else
15469     {
15470       mp->is_ipv6 = 0;
15471       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
15472     }
15473
15474   /* send it... */
15475   S (mp);
15476
15477   /* Wait for a reply... */
15478   W (ret);
15479   return ret;
15480 }
15481
15482 #define api_lisp_add_del_map_resolver api_one_add_del_map_resolver
15483
15484 static int
15485 api_lisp_gpe_enable_disable (vat_main_t * vam)
15486 {
15487   unformat_input_t *input = vam->input;
15488   vl_api_gpe_enable_disable_t *mp;
15489   u8 is_set = 0;
15490   u8 is_en = 1;
15491   int ret;
15492
15493   /* Parse args required to build the message */
15494   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15495     {
15496       if (unformat (input, "enable"))
15497         {
15498           is_set = 1;
15499           is_en = 1;
15500         }
15501       else if (unformat (input, "disable"))
15502         {
15503           is_set = 1;
15504           is_en = 0;
15505         }
15506       else
15507         break;
15508     }
15509
15510   if (is_set == 0)
15511     {
15512       errmsg ("Value not set");
15513       return -99;
15514     }
15515
15516   /* Construct the API message */
15517   M (GPE_ENABLE_DISABLE, mp);
15518
15519   mp->is_en = is_en;
15520
15521   /* send it... */
15522   S (mp);
15523
15524   /* Wait for a reply... */
15525   W (ret);
15526   return ret;
15527 }
15528
15529 static int
15530 api_one_rloc_probe_enable_disable (vat_main_t * vam)
15531 {
15532   unformat_input_t *input = vam->input;
15533   vl_api_one_rloc_probe_enable_disable_t *mp;
15534   u8 is_set = 0;
15535   u8 is_en = 0;
15536   int ret;
15537
15538   /* Parse args required to build the message */
15539   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15540     {
15541       if (unformat (input, "enable"))
15542         {
15543           is_set = 1;
15544           is_en = 1;
15545         }
15546       else if (unformat (input, "disable"))
15547         is_set = 1;
15548       else
15549         break;
15550     }
15551
15552   if (!is_set)
15553     {
15554       errmsg ("Value not set");
15555       return -99;
15556     }
15557
15558   /* Construct the API message */
15559   M (ONE_RLOC_PROBE_ENABLE_DISABLE, mp);
15560
15561   mp->is_enabled = is_en;
15562
15563   /* send it... */
15564   S (mp);
15565
15566   /* Wait for a reply... */
15567   W (ret);
15568   return ret;
15569 }
15570
15571 #define api_lisp_rloc_probe_enable_disable api_one_rloc_probe_enable_disable
15572
15573 static int
15574 api_one_map_register_enable_disable (vat_main_t * vam)
15575 {
15576   unformat_input_t *input = vam->input;
15577   vl_api_one_map_register_enable_disable_t *mp;
15578   u8 is_set = 0;
15579   u8 is_en = 0;
15580   int ret;
15581
15582   /* Parse args required to build the message */
15583   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15584     {
15585       if (unformat (input, "enable"))
15586         {
15587           is_set = 1;
15588           is_en = 1;
15589         }
15590       else if (unformat (input, "disable"))
15591         is_set = 1;
15592       else
15593         break;
15594     }
15595
15596   if (!is_set)
15597     {
15598       errmsg ("Value not set");
15599       return -99;
15600     }
15601
15602   /* Construct the API message */
15603   M (ONE_MAP_REGISTER_ENABLE_DISABLE, mp);
15604
15605   mp->is_enabled = is_en;
15606
15607   /* send it... */
15608   S (mp);
15609
15610   /* Wait for a reply... */
15611   W (ret);
15612   return ret;
15613 }
15614
15615 #define api_lisp_map_register_enable_disable api_one_map_register_enable_disable
15616
15617 static int
15618 api_one_enable_disable (vat_main_t * vam)
15619 {
15620   unformat_input_t *input = vam->input;
15621   vl_api_one_enable_disable_t *mp;
15622   u8 is_set = 0;
15623   u8 is_en = 0;
15624   int ret;
15625
15626   /* Parse args required to build the message */
15627   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15628     {
15629       if (unformat (input, "enable"))
15630         {
15631           is_set = 1;
15632           is_en = 1;
15633         }
15634       else if (unformat (input, "disable"))
15635         {
15636           is_set = 1;
15637         }
15638       else
15639         break;
15640     }
15641
15642   if (!is_set)
15643     {
15644       errmsg ("Value not set");
15645       return -99;
15646     }
15647
15648   /* Construct the API message */
15649   M (ONE_ENABLE_DISABLE, mp);
15650
15651   mp->is_en = is_en;
15652
15653   /* send it... */
15654   S (mp);
15655
15656   /* Wait for a reply... */
15657   W (ret);
15658   return ret;
15659 }
15660
15661 #define api_lisp_enable_disable api_one_enable_disable
15662
15663 static int
15664 api_one_enable_disable_xtr_mode (vat_main_t * vam)
15665 {
15666   unformat_input_t *input = vam->input;
15667   vl_api_one_enable_disable_xtr_mode_t *mp;
15668   u8 is_set = 0;
15669   u8 is_en = 0;
15670   int ret;
15671
15672   /* Parse args required to build the message */
15673   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15674     {
15675       if (unformat (input, "enable"))
15676         {
15677           is_set = 1;
15678           is_en = 1;
15679         }
15680       else if (unformat (input, "disable"))
15681         {
15682           is_set = 1;
15683         }
15684       else
15685         break;
15686     }
15687
15688   if (!is_set)
15689     {
15690       errmsg ("Value not set");
15691       return -99;
15692     }
15693
15694   /* Construct the API message */
15695   M (ONE_ENABLE_DISABLE_XTR_MODE, mp);
15696
15697   mp->is_en = is_en;
15698
15699   /* send it... */
15700   S (mp);
15701
15702   /* Wait for a reply... */
15703   W (ret);
15704   return ret;
15705 }
15706
15707 static int
15708 api_one_show_xtr_mode (vat_main_t * vam)
15709 {
15710   vl_api_one_show_xtr_mode_t *mp;
15711   int ret;
15712
15713   /* Construct the API message */
15714   M (ONE_SHOW_XTR_MODE, mp);
15715
15716   /* send it... */
15717   S (mp);
15718
15719   /* Wait for a reply... */
15720   W (ret);
15721   return ret;
15722 }
15723
15724 static int
15725 api_one_enable_disable_pitr_mode (vat_main_t * vam)
15726 {
15727   unformat_input_t *input = vam->input;
15728   vl_api_one_enable_disable_pitr_mode_t *mp;
15729   u8 is_set = 0;
15730   u8 is_en = 0;
15731   int ret;
15732
15733   /* Parse args required to build the message */
15734   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15735     {
15736       if (unformat (input, "enable"))
15737         {
15738           is_set = 1;
15739           is_en = 1;
15740         }
15741       else if (unformat (input, "disable"))
15742         {
15743           is_set = 1;
15744         }
15745       else
15746         break;
15747     }
15748
15749   if (!is_set)
15750     {
15751       errmsg ("Value not set");
15752       return -99;
15753     }
15754
15755   /* Construct the API message */
15756   M (ONE_ENABLE_DISABLE_PITR_MODE, mp);
15757
15758   mp->is_en = is_en;
15759
15760   /* send it... */
15761   S (mp);
15762
15763   /* Wait for a reply... */
15764   W (ret);
15765   return ret;
15766 }
15767
15768 static int
15769 api_one_show_pitr_mode (vat_main_t * vam)
15770 {
15771   vl_api_one_show_pitr_mode_t *mp;
15772   int ret;
15773
15774   /* Construct the API message */
15775   M (ONE_SHOW_PITR_MODE, mp);
15776
15777   /* send it... */
15778   S (mp);
15779
15780   /* Wait for a reply... */
15781   W (ret);
15782   return ret;
15783 }
15784
15785 static int
15786 api_one_enable_disable_petr_mode (vat_main_t * vam)
15787 {
15788   unformat_input_t *input = vam->input;
15789   vl_api_one_enable_disable_petr_mode_t *mp;
15790   u8 is_set = 0;
15791   u8 is_en = 0;
15792   int ret;
15793
15794   /* Parse args required to build the message */
15795   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15796     {
15797       if (unformat (input, "enable"))
15798         {
15799           is_set = 1;
15800           is_en = 1;
15801         }
15802       else if (unformat (input, "disable"))
15803         {
15804           is_set = 1;
15805         }
15806       else
15807         break;
15808     }
15809
15810   if (!is_set)
15811     {
15812       errmsg ("Value not set");
15813       return -99;
15814     }
15815
15816   /* Construct the API message */
15817   M (ONE_ENABLE_DISABLE_PETR_MODE, mp);
15818
15819   mp->is_en = is_en;
15820
15821   /* send it... */
15822   S (mp);
15823
15824   /* Wait for a reply... */
15825   W (ret);
15826   return ret;
15827 }
15828
15829 static int
15830 api_one_show_petr_mode (vat_main_t * vam)
15831 {
15832   vl_api_one_show_petr_mode_t *mp;
15833   int ret;
15834
15835   /* Construct the API message */
15836   M (ONE_SHOW_PETR_MODE, mp);
15837
15838   /* send it... */
15839   S (mp);
15840
15841   /* Wait for a reply... */
15842   W (ret);
15843   return ret;
15844 }
15845
15846 static int
15847 api_show_one_map_register_state (vat_main_t * vam)
15848 {
15849   vl_api_show_one_map_register_state_t *mp;
15850   int ret;
15851
15852   M (SHOW_ONE_MAP_REGISTER_STATE, mp);
15853
15854   /* send */
15855   S (mp);
15856
15857   /* wait for reply */
15858   W (ret);
15859   return ret;
15860 }
15861
15862 #define api_show_lisp_map_register_state api_show_one_map_register_state
15863
15864 static int
15865 api_show_one_rloc_probe_state (vat_main_t * vam)
15866 {
15867   vl_api_show_one_rloc_probe_state_t *mp;
15868   int ret;
15869
15870   M (SHOW_ONE_RLOC_PROBE_STATE, mp);
15871
15872   /* send */
15873   S (mp);
15874
15875   /* wait for reply */
15876   W (ret);
15877   return ret;
15878 }
15879
15880 #define api_show_lisp_rloc_probe_state api_show_one_rloc_probe_state
15881
15882 static int
15883 api_one_add_del_ndp_entry (vat_main_t * vam)
15884 {
15885   vl_api_one_add_del_ndp_entry_t *mp;
15886   unformat_input_t *input = vam->input;
15887   u8 is_add = 1;
15888   u8 mac_set = 0;
15889   u8 bd_set = 0;
15890   u8 ip_set = 0;
15891   u8 mac[6] = { 0, };
15892   u8 ip6[16] = { 0, };
15893   u32 bd = ~0;
15894   int ret;
15895
15896   /* Parse args required to build the message */
15897   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15898     {
15899       if (unformat (input, "del"))
15900         is_add = 0;
15901       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
15902         mac_set = 1;
15903       else if (unformat (input, "ip %U", unformat_ip6_address, ip6))
15904         ip_set = 1;
15905       else if (unformat (input, "bd %d", &bd))
15906         bd_set = 1;
15907       else
15908         {
15909           errmsg ("parse error '%U'", format_unformat_error, input);
15910           return -99;
15911         }
15912     }
15913
15914   if (!bd_set || !ip_set || (!mac_set && is_add))
15915     {
15916       errmsg ("Missing BD, IP or MAC!");
15917       return -99;
15918     }
15919
15920   M (ONE_ADD_DEL_NDP_ENTRY, mp);
15921   mp->is_add = is_add;
15922   clib_memcpy (mp->mac, mac, 6);
15923   mp->bd = clib_host_to_net_u32 (bd);
15924   clib_memcpy (mp->ip6, ip6, sizeof (mp->ip6));
15925
15926   /* send */
15927   S (mp);
15928
15929   /* wait for reply */
15930   W (ret);
15931   return ret;
15932 }
15933
15934 static int
15935 api_one_add_del_l2_arp_entry (vat_main_t * vam)
15936 {
15937   vl_api_one_add_del_l2_arp_entry_t *mp;
15938   unformat_input_t *input = vam->input;
15939   u8 is_add = 1;
15940   u8 mac_set = 0;
15941   u8 bd_set = 0;
15942   u8 ip_set = 0;
15943   u8 mac[6] = { 0, };
15944   u32 ip4 = 0, bd = ~0;
15945   int ret;
15946
15947   /* Parse args required to build the message */
15948   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15949     {
15950       if (unformat (input, "del"))
15951         is_add = 0;
15952       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
15953         mac_set = 1;
15954       else if (unformat (input, "ip %U", unformat_ip4_address, &ip4))
15955         ip_set = 1;
15956       else if (unformat (input, "bd %d", &bd))
15957         bd_set = 1;
15958       else
15959         {
15960           errmsg ("parse error '%U'", format_unformat_error, input);
15961           return -99;
15962         }
15963     }
15964
15965   if (!bd_set || !ip_set || (!mac_set && is_add))
15966     {
15967       errmsg ("Missing BD, IP or MAC!");
15968       return -99;
15969     }
15970
15971   M (ONE_ADD_DEL_L2_ARP_ENTRY, mp);
15972   mp->is_add = is_add;
15973   clib_memcpy (mp->mac, mac, 6);
15974   mp->bd = clib_host_to_net_u32 (bd);
15975   mp->ip4 = ip4;
15976
15977   /* send */
15978   S (mp);
15979
15980   /* wait for reply */
15981   W (ret);
15982   return ret;
15983 }
15984
15985 static int
15986 api_one_ndp_bd_get (vat_main_t * vam)
15987 {
15988   vl_api_one_ndp_bd_get_t *mp;
15989   int ret;
15990
15991   M (ONE_NDP_BD_GET, mp);
15992
15993   /* send */
15994   S (mp);
15995
15996   /* wait for reply */
15997   W (ret);
15998   return ret;
15999 }
16000
16001 static int
16002 api_one_ndp_entries_get (vat_main_t * vam)
16003 {
16004   vl_api_one_ndp_entries_get_t *mp;
16005   unformat_input_t *input = vam->input;
16006   u8 bd_set = 0;
16007   u32 bd = ~0;
16008   int ret;
16009
16010   /* Parse args required to build the message */
16011   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16012     {
16013       if (unformat (input, "bd %d", &bd))
16014         bd_set = 1;
16015       else
16016         {
16017           errmsg ("parse error '%U'", format_unformat_error, input);
16018           return -99;
16019         }
16020     }
16021
16022   if (!bd_set)
16023     {
16024       errmsg ("Expected bridge domain!");
16025       return -99;
16026     }
16027
16028   M (ONE_NDP_ENTRIES_GET, mp);
16029   mp->bd = clib_host_to_net_u32 (bd);
16030
16031   /* send */
16032   S (mp);
16033
16034   /* wait for reply */
16035   W (ret);
16036   return ret;
16037 }
16038
16039 static int
16040 api_one_l2_arp_bd_get (vat_main_t * vam)
16041 {
16042   vl_api_one_l2_arp_bd_get_t *mp;
16043   int ret;
16044
16045   M (ONE_L2_ARP_BD_GET, mp);
16046
16047   /* send */
16048   S (mp);
16049
16050   /* wait for reply */
16051   W (ret);
16052   return ret;
16053 }
16054
16055 static int
16056 api_one_l2_arp_entries_get (vat_main_t * vam)
16057 {
16058   vl_api_one_l2_arp_entries_get_t *mp;
16059   unformat_input_t *input = vam->input;
16060   u8 bd_set = 0;
16061   u32 bd = ~0;
16062   int ret;
16063
16064   /* Parse args required to build the message */
16065   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16066     {
16067       if (unformat (input, "bd %d", &bd))
16068         bd_set = 1;
16069       else
16070         {
16071           errmsg ("parse error '%U'", format_unformat_error, input);
16072           return -99;
16073         }
16074     }
16075
16076   if (!bd_set)
16077     {
16078       errmsg ("Expected bridge domain!");
16079       return -99;
16080     }
16081
16082   M (ONE_L2_ARP_ENTRIES_GET, mp);
16083   mp->bd = clib_host_to_net_u32 (bd);
16084
16085   /* send */
16086   S (mp);
16087
16088   /* wait for reply */
16089   W (ret);
16090   return ret;
16091 }
16092
16093 static int
16094 api_one_stats_enable_disable (vat_main_t * vam)
16095 {
16096   vl_api_one_stats_enable_disable_t *mp;
16097   unformat_input_t *input = vam->input;
16098   u8 is_set = 0;
16099   u8 is_en = 0;
16100   int ret;
16101
16102   /* Parse args required to build the message */
16103   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16104     {
16105       if (unformat (input, "enable"))
16106         {
16107           is_set = 1;
16108           is_en = 1;
16109         }
16110       else if (unformat (input, "disable"))
16111         {
16112           is_set = 1;
16113         }
16114       else
16115         break;
16116     }
16117
16118   if (!is_set)
16119     {
16120       errmsg ("Value not set");
16121       return -99;
16122     }
16123
16124   M (ONE_STATS_ENABLE_DISABLE, mp);
16125   mp->is_en = is_en;
16126
16127   /* send */
16128   S (mp);
16129
16130   /* wait for reply */
16131   W (ret);
16132   return ret;
16133 }
16134
16135 static int
16136 api_show_one_stats_enable_disable (vat_main_t * vam)
16137 {
16138   vl_api_show_one_stats_enable_disable_t *mp;
16139   int ret;
16140
16141   M (SHOW_ONE_STATS_ENABLE_DISABLE, mp);
16142
16143   /* send */
16144   S (mp);
16145
16146   /* wait for reply */
16147   W (ret);
16148   return ret;
16149 }
16150
16151 static int
16152 api_show_one_map_request_mode (vat_main_t * vam)
16153 {
16154   vl_api_show_one_map_request_mode_t *mp;
16155   int ret;
16156
16157   M (SHOW_ONE_MAP_REQUEST_MODE, mp);
16158
16159   /* send */
16160   S (mp);
16161
16162   /* wait for reply */
16163   W (ret);
16164   return ret;
16165 }
16166
16167 #define api_show_lisp_map_request_mode api_show_one_map_request_mode
16168
16169 static int
16170 api_one_map_request_mode (vat_main_t * vam)
16171 {
16172   unformat_input_t *input = vam->input;
16173   vl_api_one_map_request_mode_t *mp;
16174   u8 mode = 0;
16175   int ret;
16176
16177   /* Parse args required to build the message */
16178   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16179     {
16180       if (unformat (input, "dst-only"))
16181         mode = 0;
16182       else if (unformat (input, "src-dst"))
16183         mode = 1;
16184       else
16185         {
16186           errmsg ("parse error '%U'", format_unformat_error, input);
16187           return -99;
16188         }
16189     }
16190
16191   M (ONE_MAP_REQUEST_MODE, mp);
16192
16193   mp->mode = mode;
16194
16195   /* send */
16196   S (mp);
16197
16198   /* wait for reply */
16199   W (ret);
16200   return ret;
16201 }
16202
16203 #define api_lisp_map_request_mode api_one_map_request_mode
16204
16205 /**
16206  * Enable/disable ONE proxy ITR.
16207  *
16208  * @param vam vpp API test context
16209  * @return return code
16210  */
16211 static int
16212 api_one_pitr_set_locator_set (vat_main_t * vam)
16213 {
16214   u8 ls_name_set = 0;
16215   unformat_input_t *input = vam->input;
16216   vl_api_one_pitr_set_locator_set_t *mp;
16217   u8 is_add = 1;
16218   u8 *ls_name = 0;
16219   int ret;
16220
16221   /* Parse args required to build the message */
16222   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16223     {
16224       if (unformat (input, "del"))
16225         is_add = 0;
16226       else if (unformat (input, "locator-set %s", &ls_name))
16227         ls_name_set = 1;
16228       else
16229         {
16230           errmsg ("parse error '%U'", format_unformat_error, input);
16231           return -99;
16232         }
16233     }
16234
16235   if (!ls_name_set)
16236     {
16237       errmsg ("locator-set name not set!");
16238       return -99;
16239     }
16240
16241   M (ONE_PITR_SET_LOCATOR_SET, mp);
16242
16243   mp->is_add = is_add;
16244   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
16245   vec_free (ls_name);
16246
16247   /* send */
16248   S (mp);
16249
16250   /* wait for reply */
16251   W (ret);
16252   return ret;
16253 }
16254
16255 #define api_lisp_pitr_set_locator_set api_one_pitr_set_locator_set
16256
16257 static int
16258 api_one_nsh_set_locator_set (vat_main_t * vam)
16259 {
16260   u8 ls_name_set = 0;
16261   unformat_input_t *input = vam->input;
16262   vl_api_one_nsh_set_locator_set_t *mp;
16263   u8 is_add = 1;
16264   u8 *ls_name = 0;
16265   int ret;
16266
16267   /* Parse args required to build the message */
16268   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16269     {
16270       if (unformat (input, "del"))
16271         is_add = 0;
16272       else if (unformat (input, "ls %s", &ls_name))
16273         ls_name_set = 1;
16274       else
16275         {
16276           errmsg ("parse error '%U'", format_unformat_error, input);
16277           return -99;
16278         }
16279     }
16280
16281   if (!ls_name_set && is_add)
16282     {
16283       errmsg ("locator-set name not set!");
16284       return -99;
16285     }
16286
16287   M (ONE_NSH_SET_LOCATOR_SET, mp);
16288
16289   mp->is_add = is_add;
16290   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
16291   vec_free (ls_name);
16292
16293   /* send */
16294   S (mp);
16295
16296   /* wait for reply */
16297   W (ret);
16298   return ret;
16299 }
16300
16301 static int
16302 api_show_one_pitr (vat_main_t * vam)
16303 {
16304   vl_api_show_one_pitr_t *mp;
16305   int ret;
16306
16307   if (!vam->json_output)
16308     {
16309       print (vam->ofp, "%=20s", "lisp status:");
16310     }
16311
16312   M (SHOW_ONE_PITR, mp);
16313   /* send it... */
16314   S (mp);
16315
16316   /* Wait for a reply... */
16317   W (ret);
16318   return ret;
16319 }
16320
16321 #define api_show_lisp_pitr api_show_one_pitr
16322
16323 static int
16324 api_one_use_petr (vat_main_t * vam)
16325 {
16326   unformat_input_t *input = vam->input;
16327   vl_api_one_use_petr_t *mp;
16328   u8 is_add = 0;
16329   ip_address_t ip;
16330   int ret;
16331
16332   clib_memset (&ip, 0, sizeof (ip));
16333
16334   /* Parse args required to build the message */
16335   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16336     {
16337       if (unformat (input, "disable"))
16338         is_add = 0;
16339       else
16340         if (unformat (input, "%U", unformat_ip4_address, &ip_addr_v4 (&ip)))
16341         {
16342           is_add = 1;
16343           ip_addr_version (&ip) = AF_IP4;
16344         }
16345       else
16346         if (unformat (input, "%U", unformat_ip6_address, &ip_addr_v6 (&ip)))
16347         {
16348           is_add = 1;
16349           ip_addr_version (&ip) = AF_IP6;
16350         }
16351       else
16352         {
16353           errmsg ("parse error '%U'", format_unformat_error, input);
16354           return -99;
16355         }
16356     }
16357
16358   M (ONE_USE_PETR, mp);
16359
16360   mp->is_add = is_add;
16361   if (is_add)
16362     {
16363       mp->is_ip4 = ip_addr_version (&ip) == AF_IP4 ? 1 : 0;
16364       if (mp->is_ip4)
16365         clib_memcpy (mp->address, &ip, 4);
16366       else
16367         clib_memcpy (mp->address, &ip, 16);
16368     }
16369
16370   /* send */
16371   S (mp);
16372
16373   /* wait for reply */
16374   W (ret);
16375   return ret;
16376 }
16377
16378 #define api_lisp_use_petr api_one_use_petr
16379
16380 static int
16381 api_show_one_nsh_mapping (vat_main_t * vam)
16382 {
16383   vl_api_show_one_use_petr_t *mp;
16384   int ret;
16385
16386   if (!vam->json_output)
16387     {
16388       print (vam->ofp, "%=20s", "local ONE NSH mapping:");
16389     }
16390
16391   M (SHOW_ONE_NSH_MAPPING, mp);
16392   /* send it... */
16393   S (mp);
16394
16395   /* Wait for a reply... */
16396   W (ret);
16397   return ret;
16398 }
16399
16400 static int
16401 api_show_one_use_petr (vat_main_t * vam)
16402 {
16403   vl_api_show_one_use_petr_t *mp;
16404   int ret;
16405
16406   if (!vam->json_output)
16407     {
16408       print (vam->ofp, "%=20s", "Proxy-ETR status:");
16409     }
16410
16411   M (SHOW_ONE_USE_PETR, mp);
16412   /* send it... */
16413   S (mp);
16414
16415   /* Wait for a reply... */
16416   W (ret);
16417   return ret;
16418 }
16419
16420 #define api_show_lisp_use_petr api_show_one_use_petr
16421
16422 /**
16423  * Add/delete mapping between vni and vrf
16424  */
16425 static int
16426 api_one_eid_table_add_del_map (vat_main_t * vam)
16427 {
16428   unformat_input_t *input = vam->input;
16429   vl_api_one_eid_table_add_del_map_t *mp;
16430   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
16431   u32 vni, vrf, bd_index;
16432   int ret;
16433
16434   /* Parse args required to build the message */
16435   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16436     {
16437       if (unformat (input, "del"))
16438         is_add = 0;
16439       else if (unformat (input, "vrf %d", &vrf))
16440         vrf_set = 1;
16441       else if (unformat (input, "bd_index %d", &bd_index))
16442         bd_index_set = 1;
16443       else if (unformat (input, "vni %d", &vni))
16444         vni_set = 1;
16445       else
16446         break;
16447     }
16448
16449   if (!vni_set || (!vrf_set && !bd_index_set))
16450     {
16451       errmsg ("missing arguments!");
16452       return -99;
16453     }
16454
16455   if (vrf_set && bd_index_set)
16456     {
16457       errmsg ("error: both vrf and bd entered!");
16458       return -99;
16459     }
16460
16461   M (ONE_EID_TABLE_ADD_DEL_MAP, mp);
16462
16463   mp->is_add = is_add;
16464   mp->vni = htonl (vni);
16465   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
16466   mp->is_l2 = bd_index_set;
16467
16468   /* send */
16469   S (mp);
16470
16471   /* wait for reply */
16472   W (ret);
16473   return ret;
16474 }
16475
16476 #define api_lisp_eid_table_add_del_map api_one_eid_table_add_del_map
16477
16478 uword
16479 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
16480 {
16481   u32 *action = va_arg (*args, u32 *);
16482   u8 *s = 0;
16483
16484   if (unformat (input, "%s", &s))
16485     {
16486       if (!strcmp ((char *) s, "no-action"))
16487         action[0] = 0;
16488       else if (!strcmp ((char *) s, "natively-forward"))
16489         action[0] = 1;
16490       else if (!strcmp ((char *) s, "send-map-request"))
16491         action[0] = 2;
16492       else if (!strcmp ((char *) s, "drop"))
16493         action[0] = 3;
16494       else
16495         {
16496           clib_warning ("invalid action: '%s'", s);
16497           action[0] = 3;
16498         }
16499     }
16500   else
16501     return 0;
16502
16503   vec_free (s);
16504   return 1;
16505 }
16506
16507 /**
16508  * Add/del remote mapping to/from ONE control plane
16509  *
16510  * @param vam vpp API test context
16511  * @return return code
16512  */
16513 static int
16514 api_one_add_del_remote_mapping (vat_main_t * vam)
16515 {
16516   unformat_input_t *input = vam->input;
16517   vl_api_one_add_del_remote_mapping_t *mp;
16518   u32 vni = 0;
16519   lisp_eid_vat_t _eid, *eid = &_eid;
16520   lisp_eid_vat_t _seid, *seid = &_seid;
16521   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
16522   u32 action = ~0, p, w, data_len;
16523   ip4_address_t rloc4;
16524   ip6_address_t rloc6;
16525   vl_api_remote_locator_t *rlocs = 0, rloc, *curr_rloc = 0;
16526   int ret;
16527
16528   clib_memset (&rloc, 0, sizeof (rloc));
16529
16530   /* Parse args required to build the message */
16531   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16532     {
16533       if (unformat (input, "del-all"))
16534         {
16535           del_all = 1;
16536         }
16537       else if (unformat (input, "del"))
16538         {
16539           is_add = 0;
16540         }
16541       else if (unformat (input, "add"))
16542         {
16543           is_add = 1;
16544         }
16545       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
16546         {
16547           eid_set = 1;
16548         }
16549       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
16550         {
16551           seid_set = 1;
16552         }
16553       else if (unformat (input, "vni %d", &vni))
16554         {
16555           ;
16556         }
16557       else if (unformat (input, "p %d w %d", &p, &w))
16558         {
16559           if (!curr_rloc)
16560             {
16561               errmsg ("No RLOC configured for setting priority/weight!");
16562               return -99;
16563             }
16564           curr_rloc->priority = p;
16565           curr_rloc->weight = w;
16566         }
16567       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
16568         {
16569           rloc.is_ip4 = 1;
16570           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
16571           vec_add1 (rlocs, rloc);
16572           curr_rloc = &rlocs[vec_len (rlocs) - 1];
16573         }
16574       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
16575         {
16576           rloc.is_ip4 = 0;
16577           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
16578           vec_add1 (rlocs, rloc);
16579           curr_rloc = &rlocs[vec_len (rlocs) - 1];
16580         }
16581       else if (unformat (input, "action %U",
16582                          unformat_negative_mapping_action, &action))
16583         {
16584           ;
16585         }
16586       else
16587         {
16588           clib_warning ("parse error '%U'", format_unformat_error, input);
16589           return -99;
16590         }
16591     }
16592
16593   if (0 == eid_set)
16594     {
16595       errmsg ("missing params!");
16596       return -99;
16597     }
16598
16599   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
16600     {
16601       errmsg ("no action set for negative map-reply!");
16602       return -99;
16603     }
16604
16605   data_len = vec_len (rlocs) * sizeof (vl_api_remote_locator_t);
16606
16607   M2 (ONE_ADD_DEL_REMOTE_MAPPING, mp, data_len);
16608   mp->is_add = is_add;
16609   mp->vni = htonl (vni);
16610   mp->action = (u8) action;
16611   mp->is_src_dst = seid_set;
16612   mp->eid_len = eid->len;
16613   mp->seid_len = seid->len;
16614   mp->del_all = del_all;
16615   mp->eid_type = eid->type;
16616   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
16617   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
16618
16619   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
16620   clib_memcpy (mp->rlocs, rlocs, data_len);
16621   vec_free (rlocs);
16622
16623   /* send it... */
16624   S (mp);
16625
16626   /* Wait for a reply... */
16627   W (ret);
16628   return ret;
16629 }
16630
16631 #define api_lisp_add_del_remote_mapping api_one_add_del_remote_mapping
16632
16633 /**
16634  * Add/del ONE adjacency. Saves mapping in ONE control plane and updates
16635  * forwarding entries in data-plane accordingly.
16636  *
16637  * @param vam vpp API test context
16638  * @return return code
16639  */
16640 static int
16641 api_one_add_del_adjacency (vat_main_t * vam)
16642 {
16643   unformat_input_t *input = vam->input;
16644   vl_api_one_add_del_adjacency_t *mp;
16645   u32 vni = 0;
16646   ip4_address_t leid4, reid4;
16647   ip6_address_t leid6, reid6;
16648   u8 reid_mac[6] = { 0 };
16649   u8 leid_mac[6] = { 0 };
16650   u8 reid_type, leid_type;
16651   u32 leid_len = 0, reid_len = 0, len;
16652   u8 is_add = 1;
16653   int ret;
16654
16655   leid_type = reid_type = (u8) ~ 0;
16656
16657   /* Parse args required to build the message */
16658   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16659     {
16660       if (unformat (input, "del"))
16661         {
16662           is_add = 0;
16663         }
16664       else if (unformat (input, "add"))
16665         {
16666           is_add = 1;
16667         }
16668       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
16669                          &reid4, &len))
16670         {
16671           reid_type = 0;        /* ipv4 */
16672           reid_len = len;
16673         }
16674       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
16675                          &reid6, &len))
16676         {
16677           reid_type = 1;        /* ipv6 */
16678           reid_len = len;
16679         }
16680       else if (unformat (input, "reid %U", unformat_ethernet_address,
16681                          reid_mac))
16682         {
16683           reid_type = 2;        /* mac */
16684         }
16685       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
16686                          &leid4, &len))
16687         {
16688           leid_type = 0;        /* ipv4 */
16689           leid_len = len;
16690         }
16691       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
16692                          &leid6, &len))
16693         {
16694           leid_type = 1;        /* ipv6 */
16695           leid_len = len;
16696         }
16697       else if (unformat (input, "leid %U", unformat_ethernet_address,
16698                          leid_mac))
16699         {
16700           leid_type = 2;        /* mac */
16701         }
16702       else if (unformat (input, "vni %d", &vni))
16703         {
16704           ;
16705         }
16706       else
16707         {
16708           errmsg ("parse error '%U'", format_unformat_error, input);
16709           return -99;
16710         }
16711     }
16712
16713   if ((u8) ~ 0 == reid_type)
16714     {
16715       errmsg ("missing params!");
16716       return -99;
16717     }
16718
16719   if (leid_type != reid_type)
16720     {
16721       errmsg ("remote and local EIDs are of different types!");
16722       return -99;
16723     }
16724
16725   M (ONE_ADD_DEL_ADJACENCY, mp);
16726   mp->is_add = is_add;
16727   mp->vni = htonl (vni);
16728   mp->leid_len = leid_len;
16729   mp->reid_len = reid_len;
16730   mp->eid_type = reid_type;
16731
16732   switch (mp->eid_type)
16733     {
16734     case 0:
16735       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
16736       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
16737       break;
16738     case 1:
16739       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
16740       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
16741       break;
16742     case 2:
16743       clib_memcpy (mp->leid, leid_mac, 6);
16744       clib_memcpy (mp->reid, reid_mac, 6);
16745       break;
16746     default:
16747       errmsg ("unknown EID type %d!", mp->eid_type);
16748       return 0;
16749     }
16750
16751   /* send it... */
16752   S (mp);
16753
16754   /* Wait for a reply... */
16755   W (ret);
16756   return ret;
16757 }
16758
16759 #define api_lisp_add_del_adjacency api_one_add_del_adjacency
16760
16761 uword
16762 unformat_gpe_encap_mode (unformat_input_t * input, va_list * args)
16763 {
16764   u32 *mode = va_arg (*args, u32 *);
16765
16766   if (unformat (input, "lisp"))
16767     *mode = 0;
16768   else if (unformat (input, "vxlan"))
16769     *mode = 1;
16770   else
16771     return 0;
16772
16773   return 1;
16774 }
16775
16776 static int
16777 api_gpe_get_encap_mode (vat_main_t * vam)
16778 {
16779   vl_api_gpe_get_encap_mode_t *mp;
16780   int ret;
16781
16782   /* Construct the API message */
16783   M (GPE_GET_ENCAP_MODE, mp);
16784
16785   /* send it... */
16786   S (mp);
16787
16788   /* Wait for a reply... */
16789   W (ret);
16790   return ret;
16791 }
16792
16793 static int
16794 api_gpe_set_encap_mode (vat_main_t * vam)
16795 {
16796   unformat_input_t *input = vam->input;
16797   vl_api_gpe_set_encap_mode_t *mp;
16798   int ret;
16799   u32 mode = 0;
16800
16801   /* Parse args required to build the message */
16802   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16803     {
16804       if (unformat (input, "%U", unformat_gpe_encap_mode, &mode))
16805         ;
16806       else
16807         break;
16808     }
16809
16810   /* Construct the API message */
16811   M (GPE_SET_ENCAP_MODE, mp);
16812
16813   mp->mode = mode;
16814
16815   /* send it... */
16816   S (mp);
16817
16818   /* Wait for a reply... */
16819   W (ret);
16820   return ret;
16821 }
16822
16823 static int
16824 api_lisp_gpe_add_del_iface (vat_main_t * vam)
16825 {
16826   unformat_input_t *input = vam->input;
16827   vl_api_gpe_add_del_iface_t *mp;
16828   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
16829   u32 dp_table = 0, vni = 0;
16830   int ret;
16831
16832   /* Parse args required to build the message */
16833   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16834     {
16835       if (unformat (input, "up"))
16836         {
16837           action_set = 1;
16838           is_add = 1;
16839         }
16840       else if (unformat (input, "down"))
16841         {
16842           action_set = 1;
16843           is_add = 0;
16844         }
16845       else if (unformat (input, "table_id %d", &dp_table))
16846         {
16847           dp_table_set = 1;
16848         }
16849       else if (unformat (input, "bd_id %d", &dp_table))
16850         {
16851           dp_table_set = 1;
16852           is_l2 = 1;
16853         }
16854       else if (unformat (input, "vni %d", &vni))
16855         {
16856           vni_set = 1;
16857         }
16858       else
16859         break;
16860     }
16861
16862   if (action_set == 0)
16863     {
16864       errmsg ("Action not set");
16865       return -99;
16866     }
16867   if (dp_table_set == 0 || vni_set == 0)
16868     {
16869       errmsg ("vni and dp_table must be set");
16870       return -99;
16871     }
16872
16873   /* Construct the API message */
16874   M (GPE_ADD_DEL_IFACE, mp);
16875
16876   mp->is_add = is_add;
16877   mp->dp_table = clib_host_to_net_u32 (dp_table);
16878   mp->is_l2 = is_l2;
16879   mp->vni = clib_host_to_net_u32 (vni);
16880
16881   /* send it... */
16882   S (mp);
16883
16884   /* Wait for a reply... */
16885   W (ret);
16886   return ret;
16887 }
16888
16889 static int
16890 api_one_map_register_fallback_threshold (vat_main_t * vam)
16891 {
16892   unformat_input_t *input = vam->input;
16893   vl_api_one_map_register_fallback_threshold_t *mp;
16894   u32 value = 0;
16895   u8 is_set = 0;
16896   int ret;
16897
16898   /* Parse args required to build the message */
16899   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16900     {
16901       if (unformat (input, "%u", &value))
16902         is_set = 1;
16903       else
16904         {
16905           clib_warning ("parse error '%U'", format_unformat_error, input);
16906           return -99;
16907         }
16908     }
16909
16910   if (!is_set)
16911     {
16912       errmsg ("fallback threshold value is missing!");
16913       return -99;
16914     }
16915
16916   M (ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
16917   mp->value = clib_host_to_net_u32 (value);
16918
16919   /* send it... */
16920   S (mp);
16921
16922   /* Wait for a reply... */
16923   W (ret);
16924   return ret;
16925 }
16926
16927 static int
16928 api_show_one_map_register_fallback_threshold (vat_main_t * vam)
16929 {
16930   vl_api_show_one_map_register_fallback_threshold_t *mp;
16931   int ret;
16932
16933   M (SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
16934
16935   /* send it... */
16936   S (mp);
16937
16938   /* Wait for a reply... */
16939   W (ret);
16940   return ret;
16941 }
16942
16943 uword
16944 unformat_lisp_transport_protocol (unformat_input_t * input, va_list * args)
16945 {
16946   u32 *proto = va_arg (*args, u32 *);
16947
16948   if (unformat (input, "udp"))
16949     *proto = 1;
16950   else if (unformat (input, "api"))
16951     *proto = 2;
16952   else
16953     return 0;
16954
16955   return 1;
16956 }
16957
16958 static int
16959 api_one_set_transport_protocol (vat_main_t * vam)
16960 {
16961   unformat_input_t *input = vam->input;
16962   vl_api_one_set_transport_protocol_t *mp;
16963   u8 is_set = 0;
16964   u32 protocol = 0;
16965   int ret;
16966
16967   /* Parse args required to build the message */
16968   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16969     {
16970       if (unformat (input, "%U", unformat_lisp_transport_protocol, &protocol))
16971         is_set = 1;
16972       else
16973         {
16974           clib_warning ("parse error '%U'", format_unformat_error, input);
16975           return -99;
16976         }
16977     }
16978
16979   if (!is_set)
16980     {
16981       errmsg ("Transport protocol missing!");
16982       return -99;
16983     }
16984
16985   M (ONE_SET_TRANSPORT_PROTOCOL, mp);
16986   mp->protocol = (u8) protocol;
16987
16988   /* send it... */
16989   S (mp);
16990
16991   /* Wait for a reply... */
16992   W (ret);
16993   return ret;
16994 }
16995
16996 static int
16997 api_one_get_transport_protocol (vat_main_t * vam)
16998 {
16999   vl_api_one_get_transport_protocol_t *mp;
17000   int ret;
17001
17002   M (ONE_GET_TRANSPORT_PROTOCOL, mp);
17003
17004   /* send it... */
17005   S (mp);
17006
17007   /* Wait for a reply... */
17008   W (ret);
17009   return ret;
17010 }
17011
17012 static int
17013 api_one_map_register_set_ttl (vat_main_t * vam)
17014 {
17015   unformat_input_t *input = vam->input;
17016   vl_api_one_map_register_set_ttl_t *mp;
17017   u32 ttl = 0;
17018   u8 is_set = 0;
17019   int ret;
17020
17021   /* Parse args required to build the message */
17022   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17023     {
17024       if (unformat (input, "%u", &ttl))
17025         is_set = 1;
17026       else
17027         {
17028           clib_warning ("parse error '%U'", format_unformat_error, input);
17029           return -99;
17030         }
17031     }
17032
17033   if (!is_set)
17034     {
17035       errmsg ("TTL value missing!");
17036       return -99;
17037     }
17038
17039   M (ONE_MAP_REGISTER_SET_TTL, mp);
17040   mp->ttl = clib_host_to_net_u32 (ttl);
17041
17042   /* send it... */
17043   S (mp);
17044
17045   /* Wait for a reply... */
17046   W (ret);
17047   return ret;
17048 }
17049
17050 static int
17051 api_show_one_map_register_ttl (vat_main_t * vam)
17052 {
17053   vl_api_show_one_map_register_ttl_t *mp;
17054   int ret;
17055
17056   M (SHOW_ONE_MAP_REGISTER_TTL, mp);
17057
17058   /* send it... */
17059   S (mp);
17060
17061   /* Wait for a reply... */
17062   W (ret);
17063   return ret;
17064 }
17065
17066 /**
17067  * Add/del map request itr rlocs from ONE control plane and updates
17068  *
17069  * @param vam vpp API test context
17070  * @return return code
17071  */
17072 static int
17073 api_one_add_del_map_request_itr_rlocs (vat_main_t * vam)
17074 {
17075   unformat_input_t *input = vam->input;
17076   vl_api_one_add_del_map_request_itr_rlocs_t *mp;
17077   u8 *locator_set_name = 0;
17078   u8 locator_set_name_set = 0;
17079   u8 is_add = 1;
17080   int ret;
17081
17082   /* Parse args required to build the message */
17083   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17084     {
17085       if (unformat (input, "del"))
17086         {
17087           is_add = 0;
17088         }
17089       else if (unformat (input, "%_%v%_", &locator_set_name))
17090         {
17091           locator_set_name_set = 1;
17092         }
17093       else
17094         {
17095           clib_warning ("parse error '%U'", format_unformat_error, input);
17096           return -99;
17097         }
17098     }
17099
17100   if (is_add && !locator_set_name_set)
17101     {
17102       errmsg ("itr-rloc is not set!");
17103       return -99;
17104     }
17105
17106   if (is_add && vec_len (locator_set_name) > 64)
17107     {
17108       errmsg ("itr-rloc locator-set name too long");
17109       vec_free (locator_set_name);
17110       return -99;
17111     }
17112
17113   M (ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS, mp);
17114   mp->is_add = is_add;
17115   if (is_add)
17116     {
17117       clib_memcpy (mp->locator_set_name, locator_set_name,
17118                    vec_len (locator_set_name));
17119     }
17120   else
17121     {
17122       clib_memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
17123     }
17124   vec_free (locator_set_name);
17125
17126   /* send it... */
17127   S (mp);
17128
17129   /* Wait for a reply... */
17130   W (ret);
17131   return ret;
17132 }
17133
17134 #define api_lisp_add_del_map_request_itr_rlocs api_one_add_del_map_request_itr_rlocs
17135
17136 static int
17137 api_one_locator_dump (vat_main_t * vam)
17138 {
17139   unformat_input_t *input = vam->input;
17140   vl_api_one_locator_dump_t *mp;
17141   vl_api_control_ping_t *mp_ping;
17142   u8 is_index_set = 0, is_name_set = 0;
17143   u8 *ls_name = 0;
17144   u32 ls_index = ~0;
17145   int ret;
17146
17147   /* Parse args required to build the message */
17148   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17149     {
17150       if (unformat (input, "ls_name %_%v%_", &ls_name))
17151         {
17152           is_name_set = 1;
17153         }
17154       else if (unformat (input, "ls_index %d", &ls_index))
17155         {
17156           is_index_set = 1;
17157         }
17158       else
17159         {
17160           errmsg ("parse error '%U'", format_unformat_error, input);
17161           return -99;
17162         }
17163     }
17164
17165   if (!is_index_set && !is_name_set)
17166     {
17167       errmsg ("error: expected one of index or name!");
17168       return -99;
17169     }
17170
17171   if (is_index_set && is_name_set)
17172     {
17173       errmsg ("error: only one param expected!");
17174       return -99;
17175     }
17176
17177   if (vec_len (ls_name) > 62)
17178     {
17179       errmsg ("error: locator set name too long!");
17180       return -99;
17181     }
17182
17183   if (!vam->json_output)
17184     {
17185       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
17186     }
17187
17188   M (ONE_LOCATOR_DUMP, mp);
17189   mp->is_index_set = is_index_set;
17190
17191   if (is_index_set)
17192     mp->ls_index = clib_host_to_net_u32 (ls_index);
17193   else
17194     {
17195       vec_add1 (ls_name, 0);
17196       strncpy ((char *) mp->ls_name, (char *) ls_name,
17197                sizeof (mp->ls_name) - 1);
17198     }
17199
17200   /* send it... */
17201   S (mp);
17202
17203   /* Use a control ping for synchronization */
17204   MPING (CONTROL_PING, mp_ping);
17205   S (mp_ping);
17206
17207   /* Wait for a reply... */
17208   W (ret);
17209   return ret;
17210 }
17211
17212 #define api_lisp_locator_dump api_one_locator_dump
17213
17214 static int
17215 api_one_locator_set_dump (vat_main_t * vam)
17216 {
17217   vl_api_one_locator_set_dump_t *mp;
17218   vl_api_control_ping_t *mp_ping;
17219   unformat_input_t *input = vam->input;
17220   u8 filter = 0;
17221   int ret;
17222
17223   /* Parse args required to build the message */
17224   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17225     {
17226       if (unformat (input, "local"))
17227         {
17228           filter = 1;
17229         }
17230       else if (unformat (input, "remote"))
17231         {
17232           filter = 2;
17233         }
17234       else
17235         {
17236           errmsg ("parse error '%U'", format_unformat_error, input);
17237           return -99;
17238         }
17239     }
17240
17241   if (!vam->json_output)
17242     {
17243       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
17244     }
17245
17246   M (ONE_LOCATOR_SET_DUMP, mp);
17247
17248   mp->filter = filter;
17249
17250   /* send it... */
17251   S (mp);
17252
17253   /* Use a control ping for synchronization */
17254   MPING (CONTROL_PING, mp_ping);
17255   S (mp_ping);
17256
17257   /* Wait for a reply... */
17258   W (ret);
17259   return ret;
17260 }
17261
17262 #define api_lisp_locator_set_dump api_one_locator_set_dump
17263
17264 static int
17265 api_one_eid_table_map_dump (vat_main_t * vam)
17266 {
17267   u8 is_l2 = 0;
17268   u8 mode_set = 0;
17269   unformat_input_t *input = vam->input;
17270   vl_api_one_eid_table_map_dump_t *mp;
17271   vl_api_control_ping_t *mp_ping;
17272   int ret;
17273
17274   /* Parse args required to build the message */
17275   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17276     {
17277       if (unformat (input, "l2"))
17278         {
17279           is_l2 = 1;
17280           mode_set = 1;
17281         }
17282       else if (unformat (input, "l3"))
17283         {
17284           is_l2 = 0;
17285           mode_set = 1;
17286         }
17287       else
17288         {
17289           errmsg ("parse error '%U'", format_unformat_error, input);
17290           return -99;
17291         }
17292     }
17293
17294   if (!mode_set)
17295     {
17296       errmsg ("expected one of 'l2' or 'l3' parameter!");
17297       return -99;
17298     }
17299
17300   if (!vam->json_output)
17301     {
17302       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
17303     }
17304
17305   M (ONE_EID_TABLE_MAP_DUMP, mp);
17306   mp->is_l2 = is_l2;
17307
17308   /* send it... */
17309   S (mp);
17310
17311   /* Use a control ping for synchronization */
17312   MPING (CONTROL_PING, mp_ping);
17313   S (mp_ping);
17314
17315   /* Wait for a reply... */
17316   W (ret);
17317   return ret;
17318 }
17319
17320 #define api_lisp_eid_table_map_dump api_one_eid_table_map_dump
17321
17322 static int
17323 api_one_eid_table_vni_dump (vat_main_t * vam)
17324 {
17325   vl_api_one_eid_table_vni_dump_t *mp;
17326   vl_api_control_ping_t *mp_ping;
17327   int ret;
17328
17329   if (!vam->json_output)
17330     {
17331       print (vam->ofp, "VNI");
17332     }
17333
17334   M (ONE_EID_TABLE_VNI_DUMP, mp);
17335
17336   /* send it... */
17337   S (mp);
17338
17339   /* Use a control ping for synchronization */
17340   MPING (CONTROL_PING, mp_ping);
17341   S (mp_ping);
17342
17343   /* Wait for a reply... */
17344   W (ret);
17345   return ret;
17346 }
17347
17348 #define api_lisp_eid_table_vni_dump api_one_eid_table_vni_dump
17349
17350 static int
17351 api_one_eid_table_dump (vat_main_t * vam)
17352 {
17353   unformat_input_t *i = vam->input;
17354   vl_api_one_eid_table_dump_t *mp;
17355   vl_api_control_ping_t *mp_ping;
17356   struct in_addr ip4;
17357   struct in6_addr ip6;
17358   u8 mac[6];
17359   u8 eid_type = ~0, eid_set = 0;
17360   u32 prefix_length = ~0, t, vni = 0;
17361   u8 filter = 0;
17362   int ret;
17363   lisp_nsh_api_t nsh;
17364
17365   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17366     {
17367       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
17368         {
17369           eid_set = 1;
17370           eid_type = 0;
17371           prefix_length = t;
17372         }
17373       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
17374         {
17375           eid_set = 1;
17376           eid_type = 1;
17377           prefix_length = t;
17378         }
17379       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
17380         {
17381           eid_set = 1;
17382           eid_type = 2;
17383         }
17384       else if (unformat (i, "eid %U", unformat_nsh_address, &nsh))
17385         {
17386           eid_set = 1;
17387           eid_type = 3;
17388         }
17389       else if (unformat (i, "vni %d", &t))
17390         {
17391           vni = t;
17392         }
17393       else if (unformat (i, "local"))
17394         {
17395           filter = 1;
17396         }
17397       else if (unformat (i, "remote"))
17398         {
17399           filter = 2;
17400         }
17401       else
17402         {
17403           errmsg ("parse error '%U'", format_unformat_error, i);
17404           return -99;
17405         }
17406     }
17407
17408   if (!vam->json_output)
17409     {
17410       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
17411              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
17412     }
17413
17414   M (ONE_EID_TABLE_DUMP, mp);
17415
17416   mp->filter = filter;
17417   if (eid_set)
17418     {
17419       mp->eid_set = 1;
17420       mp->vni = htonl (vni);
17421       mp->eid_type = eid_type;
17422       switch (eid_type)
17423         {
17424         case 0:
17425           mp->prefix_length = prefix_length;
17426           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
17427           break;
17428         case 1:
17429           mp->prefix_length = prefix_length;
17430           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
17431           break;
17432         case 2:
17433           clib_memcpy (mp->eid, mac, sizeof (mac));
17434           break;
17435         case 3:
17436           clib_memcpy (mp->eid, &nsh, sizeof (nsh));
17437           break;
17438         default:
17439           errmsg ("unknown EID type %d!", eid_type);
17440           return -99;
17441         }
17442     }
17443
17444   /* send it... */
17445   S (mp);
17446
17447   /* Use a control ping for synchronization */
17448   MPING (CONTROL_PING, mp_ping);
17449   S (mp_ping);
17450
17451   /* Wait for a reply... */
17452   W (ret);
17453   return ret;
17454 }
17455
17456 #define api_lisp_eid_table_dump api_one_eid_table_dump
17457
17458 static int
17459 api_lisp_gpe_fwd_entries_get (vat_main_t * vam)
17460 {
17461   unformat_input_t *i = vam->input;
17462   vl_api_gpe_fwd_entries_get_t *mp;
17463   u8 vni_set = 0;
17464   u32 vni = ~0;
17465   int ret;
17466
17467   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17468     {
17469       if (unformat (i, "vni %d", &vni))
17470         {
17471           vni_set = 1;
17472         }
17473       else
17474         {
17475           errmsg ("parse error '%U'", format_unformat_error, i);
17476           return -99;
17477         }
17478     }
17479
17480   if (!vni_set)
17481     {
17482       errmsg ("vni not set!");
17483       return -99;
17484     }
17485
17486   if (!vam->json_output)
17487     {
17488       print (vam->ofp, "%10s %10s %s %40s", "fwd_index", "dp_table",
17489              "leid", "reid");
17490     }
17491
17492   M (GPE_FWD_ENTRIES_GET, mp);
17493   mp->vni = clib_host_to_net_u32 (vni);
17494
17495   /* send it... */
17496   S (mp);
17497
17498   /* Wait for a reply... */
17499   W (ret);
17500   return ret;
17501 }
17502
17503 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_endian vl_noop_handler
17504 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_print vl_noop_handler
17505 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_endian vl_noop_handler
17506 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_print vl_noop_handler
17507 #define vl_api_gpe_fwd_entries_get_reply_t_endian vl_noop_handler
17508 #define vl_api_gpe_fwd_entries_get_reply_t_print vl_noop_handler
17509 #define vl_api_gpe_fwd_entry_path_details_t_endian vl_noop_handler
17510 #define vl_api_gpe_fwd_entry_path_details_t_print vl_noop_handler
17511
17512 static int
17513 api_one_adjacencies_get (vat_main_t * vam)
17514 {
17515   unformat_input_t *i = vam->input;
17516   vl_api_one_adjacencies_get_t *mp;
17517   u8 vni_set = 0;
17518   u32 vni = ~0;
17519   int ret;
17520
17521   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17522     {
17523       if (unformat (i, "vni %d", &vni))
17524         {
17525           vni_set = 1;
17526         }
17527       else
17528         {
17529           errmsg ("parse error '%U'", format_unformat_error, i);
17530           return -99;
17531         }
17532     }
17533
17534   if (!vni_set)
17535     {
17536       errmsg ("vni not set!");
17537       return -99;
17538     }
17539
17540   if (!vam->json_output)
17541     {
17542       print (vam->ofp, "%s %40s", "leid", "reid");
17543     }
17544
17545   M (ONE_ADJACENCIES_GET, mp);
17546   mp->vni = clib_host_to_net_u32 (vni);
17547
17548   /* send it... */
17549   S (mp);
17550
17551   /* Wait for a reply... */
17552   W (ret);
17553   return ret;
17554 }
17555
17556 #define api_lisp_adjacencies_get api_one_adjacencies_get
17557
17558 static int
17559 api_gpe_native_fwd_rpaths_get (vat_main_t * vam)
17560 {
17561   unformat_input_t *i = vam->input;
17562   vl_api_gpe_native_fwd_rpaths_get_t *mp;
17563   int ret;
17564   u8 ip_family_set = 0, is_ip4 = 1;
17565
17566   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17567     {
17568       if (unformat (i, "ip4"))
17569         {
17570           ip_family_set = 1;
17571           is_ip4 = 1;
17572         }
17573       else if (unformat (i, "ip6"))
17574         {
17575           ip_family_set = 1;
17576           is_ip4 = 0;
17577         }
17578       else
17579         {
17580           errmsg ("parse error '%U'", format_unformat_error, i);
17581           return -99;
17582         }
17583     }
17584
17585   if (!ip_family_set)
17586     {
17587       errmsg ("ip family not set!");
17588       return -99;
17589     }
17590
17591   M (GPE_NATIVE_FWD_RPATHS_GET, mp);
17592   mp->is_ip4 = is_ip4;
17593
17594   /* send it... */
17595   S (mp);
17596
17597   /* Wait for a reply... */
17598   W (ret);
17599   return ret;
17600 }
17601
17602 static int
17603 api_gpe_fwd_entry_vnis_get (vat_main_t * vam)
17604 {
17605   vl_api_gpe_fwd_entry_vnis_get_t *mp;
17606   int ret;
17607
17608   if (!vam->json_output)
17609     {
17610       print (vam->ofp, "VNIs");
17611     }
17612
17613   M (GPE_FWD_ENTRY_VNIS_GET, mp);
17614
17615   /* send it... */
17616   S (mp);
17617
17618   /* Wait for a reply... */
17619   W (ret);
17620   return ret;
17621 }
17622
17623 static int
17624 api_gpe_add_del_native_fwd_rpath (vat_main_t * vam)
17625 {
17626   unformat_input_t *i = vam->input;
17627   vl_api_gpe_add_del_native_fwd_rpath_t *mp;
17628   int ret = 0;
17629   u8 is_add = 1, ip_set = 0, is_ip4 = 1;
17630   struct in_addr ip4;
17631   struct in6_addr ip6;
17632   u32 table_id = 0, nh_sw_if_index = ~0;
17633
17634   clib_memset (&ip4, 0, sizeof (ip4));
17635   clib_memset (&ip6, 0, sizeof (ip6));
17636
17637   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17638     {
17639       if (unformat (i, "del"))
17640         is_add = 0;
17641       else if (unformat (i, "via %U %U", unformat_ip4_address, &ip4,
17642                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
17643         {
17644           ip_set = 1;
17645           is_ip4 = 1;
17646         }
17647       else if (unformat (i, "via %U %U", unformat_ip6_address, &ip6,
17648                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
17649         {
17650           ip_set = 1;
17651           is_ip4 = 0;
17652         }
17653       else if (unformat (i, "via %U", unformat_ip4_address, &ip4))
17654         {
17655           ip_set = 1;
17656           is_ip4 = 1;
17657           nh_sw_if_index = ~0;
17658         }
17659       else if (unformat (i, "via %U", unformat_ip6_address, &ip6))
17660         {
17661           ip_set = 1;
17662           is_ip4 = 0;
17663           nh_sw_if_index = ~0;
17664         }
17665       else if (unformat (i, "table %d", &table_id))
17666         ;
17667       else
17668         {
17669           errmsg ("parse error '%U'", format_unformat_error, i);
17670           return -99;
17671         }
17672     }
17673
17674   if (!ip_set)
17675     {
17676       errmsg ("nh addr not set!");
17677       return -99;
17678     }
17679
17680   M (GPE_ADD_DEL_NATIVE_FWD_RPATH, mp);
17681   mp->is_add = is_add;
17682   mp->table_id = clib_host_to_net_u32 (table_id);
17683   mp->nh_sw_if_index = clib_host_to_net_u32 (nh_sw_if_index);
17684   mp->is_ip4 = is_ip4;
17685   if (is_ip4)
17686     clib_memcpy (mp->nh_addr, &ip4, sizeof (ip4));
17687   else
17688     clib_memcpy (mp->nh_addr, &ip6, sizeof (ip6));
17689
17690   /* send it... */
17691   S (mp);
17692
17693   /* Wait for a reply... */
17694   W (ret);
17695   return ret;
17696 }
17697
17698 static int
17699 api_one_map_server_dump (vat_main_t * vam)
17700 {
17701   vl_api_one_map_server_dump_t *mp;
17702   vl_api_control_ping_t *mp_ping;
17703   int ret;
17704
17705   if (!vam->json_output)
17706     {
17707       print (vam->ofp, "%=20s", "Map server");
17708     }
17709
17710   M (ONE_MAP_SERVER_DUMP, mp);
17711   /* send it... */
17712   S (mp);
17713
17714   /* Use a control ping for synchronization */
17715   MPING (CONTROL_PING, mp_ping);
17716   S (mp_ping);
17717
17718   /* Wait for a reply... */
17719   W (ret);
17720   return ret;
17721 }
17722
17723 #define api_lisp_map_server_dump api_one_map_server_dump
17724
17725 static int
17726 api_one_map_resolver_dump (vat_main_t * vam)
17727 {
17728   vl_api_one_map_resolver_dump_t *mp;
17729   vl_api_control_ping_t *mp_ping;
17730   int ret;
17731
17732   if (!vam->json_output)
17733     {
17734       print (vam->ofp, "%=20s", "Map resolver");
17735     }
17736
17737   M (ONE_MAP_RESOLVER_DUMP, mp);
17738   /* send it... */
17739   S (mp);
17740
17741   /* Use a control ping for synchronization */
17742   MPING (CONTROL_PING, mp_ping);
17743   S (mp_ping);
17744
17745   /* Wait for a reply... */
17746   W (ret);
17747   return ret;
17748 }
17749
17750 #define api_lisp_map_resolver_dump api_one_map_resolver_dump
17751
17752 static int
17753 api_one_stats_flush (vat_main_t * vam)
17754 {
17755   vl_api_one_stats_flush_t *mp;
17756   int ret = 0;
17757
17758   M (ONE_STATS_FLUSH, mp);
17759   S (mp);
17760   W (ret);
17761   return ret;
17762 }
17763
17764 static int
17765 api_one_stats_dump (vat_main_t * vam)
17766 {
17767   vl_api_one_stats_dump_t *mp;
17768   vl_api_control_ping_t *mp_ping;
17769   int ret;
17770
17771   M (ONE_STATS_DUMP, mp);
17772   /* send it... */
17773   S (mp);
17774
17775   /* Use a control ping for synchronization */
17776   MPING (CONTROL_PING, mp_ping);
17777   S (mp_ping);
17778
17779   /* Wait for a reply... */
17780   W (ret);
17781   return ret;
17782 }
17783
17784 static int
17785 api_show_one_status (vat_main_t * vam)
17786 {
17787   vl_api_show_one_status_t *mp;
17788   int ret;
17789
17790   if (!vam->json_output)
17791     {
17792       print (vam->ofp, "%-20s%-16s", "ONE status", "locator-set");
17793     }
17794
17795   M (SHOW_ONE_STATUS, mp);
17796   /* send it... */
17797   S (mp);
17798   /* Wait for a reply... */
17799   W (ret);
17800   return ret;
17801 }
17802
17803 #define api_show_lisp_status api_show_one_status
17804
17805 static int
17806 api_lisp_gpe_fwd_entry_path_dump (vat_main_t * vam)
17807 {
17808   vl_api_gpe_fwd_entry_path_dump_t *mp;
17809   vl_api_control_ping_t *mp_ping;
17810   unformat_input_t *i = vam->input;
17811   u32 fwd_entry_index = ~0;
17812   int ret;
17813
17814   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17815     {
17816       if (unformat (i, "index %d", &fwd_entry_index))
17817         ;
17818       else
17819         break;
17820     }
17821
17822   if (~0 == fwd_entry_index)
17823     {
17824       errmsg ("no index specified!");
17825       return -99;
17826     }
17827
17828   if (!vam->json_output)
17829     {
17830       print (vam->ofp, "first line");
17831     }
17832
17833   M (GPE_FWD_ENTRY_PATH_DUMP, mp);
17834
17835   /* send it... */
17836   S (mp);
17837   /* Use a control ping for synchronization */
17838   MPING (CONTROL_PING, mp_ping);
17839   S (mp_ping);
17840
17841   /* Wait for a reply... */
17842   W (ret);
17843   return ret;
17844 }
17845
17846 static int
17847 api_one_get_map_request_itr_rlocs (vat_main_t * vam)
17848 {
17849   vl_api_one_get_map_request_itr_rlocs_t *mp;
17850   int ret;
17851
17852   if (!vam->json_output)
17853     {
17854       print (vam->ofp, "%=20s", "itr-rlocs:");
17855     }
17856
17857   M (ONE_GET_MAP_REQUEST_ITR_RLOCS, mp);
17858   /* send it... */
17859   S (mp);
17860   /* Wait for a reply... */
17861   W (ret);
17862   return ret;
17863 }
17864
17865 #define api_lisp_get_map_request_itr_rlocs api_one_get_map_request_itr_rlocs
17866
17867 static int
17868 api_af_packet_create (vat_main_t * vam)
17869 {
17870   unformat_input_t *i = vam->input;
17871   vl_api_af_packet_create_t *mp;
17872   u8 *host_if_name = 0;
17873   u8 hw_addr[6];
17874   u8 random_hw_addr = 1;
17875   int ret;
17876
17877   clib_memset (hw_addr, 0, sizeof (hw_addr));
17878
17879   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17880     {
17881       if (unformat (i, "name %s", &host_if_name))
17882         vec_add1 (host_if_name, 0);
17883       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
17884         random_hw_addr = 0;
17885       else
17886         break;
17887     }
17888
17889   if (!vec_len (host_if_name))
17890     {
17891       errmsg ("host-interface name must be specified");
17892       return -99;
17893     }
17894
17895   if (vec_len (host_if_name) > 64)
17896     {
17897       errmsg ("host-interface name too long");
17898       return -99;
17899     }
17900
17901   M (AF_PACKET_CREATE, mp);
17902
17903   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
17904   clib_memcpy (mp->hw_addr, hw_addr, 6);
17905   mp->use_random_hw_addr = random_hw_addr;
17906   vec_free (host_if_name);
17907
17908   S (mp);
17909
17910   /* *INDENT-OFF* */
17911   W2 (ret,
17912       ({
17913         if (ret == 0)
17914           fprintf (vam->ofp ? vam->ofp : stderr,
17915                    " new sw_if_index = %d\n", vam->sw_if_index);
17916       }));
17917   /* *INDENT-ON* */
17918   return ret;
17919 }
17920
17921 static int
17922 api_af_packet_delete (vat_main_t * vam)
17923 {
17924   unformat_input_t *i = vam->input;
17925   vl_api_af_packet_delete_t *mp;
17926   u8 *host_if_name = 0;
17927   int ret;
17928
17929   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17930     {
17931       if (unformat (i, "name %s", &host_if_name))
17932         vec_add1 (host_if_name, 0);
17933       else
17934         break;
17935     }
17936
17937   if (!vec_len (host_if_name))
17938     {
17939       errmsg ("host-interface name must be specified");
17940       return -99;
17941     }
17942
17943   if (vec_len (host_if_name) > 64)
17944     {
17945       errmsg ("host-interface name too long");
17946       return -99;
17947     }
17948
17949   M (AF_PACKET_DELETE, mp);
17950
17951   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
17952   vec_free (host_if_name);
17953
17954   S (mp);
17955   W (ret);
17956   return ret;
17957 }
17958
17959 static void vl_api_af_packet_details_t_handler
17960   (vl_api_af_packet_details_t * mp)
17961 {
17962   vat_main_t *vam = &vat_main;
17963
17964   print (vam->ofp, "%-16s %d",
17965          mp->host_if_name, clib_net_to_host_u32 (mp->sw_if_index));
17966 }
17967
17968 static void vl_api_af_packet_details_t_handler_json
17969   (vl_api_af_packet_details_t * mp)
17970 {
17971   vat_main_t *vam = &vat_main;
17972   vat_json_node_t *node = NULL;
17973
17974   if (VAT_JSON_ARRAY != vam->json_tree.type)
17975     {
17976       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17977       vat_json_init_array (&vam->json_tree);
17978     }
17979   node = vat_json_array_add (&vam->json_tree);
17980
17981   vat_json_init_object (node);
17982   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
17983   vat_json_object_add_string_copy (node, "dev_name", mp->host_if_name);
17984 }
17985
17986 static int
17987 api_af_packet_dump (vat_main_t * vam)
17988 {
17989   vl_api_af_packet_dump_t *mp;
17990   vl_api_control_ping_t *mp_ping;
17991   int ret;
17992
17993   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
17994   /* Get list of tap interfaces */
17995   M (AF_PACKET_DUMP, mp);
17996   S (mp);
17997
17998   /* Use a control ping for synchronization */
17999   MPING (CONTROL_PING, mp_ping);
18000   S (mp_ping);
18001
18002   W (ret);
18003   return ret;
18004 }
18005
18006 static int
18007 api_policer_add_del (vat_main_t * vam)
18008 {
18009   unformat_input_t *i = vam->input;
18010   vl_api_policer_add_del_t *mp;
18011   u8 is_add = 1;
18012   u8 *name = 0;
18013   u32 cir = 0;
18014   u32 eir = 0;
18015   u64 cb = 0;
18016   u64 eb = 0;
18017   u8 rate_type = 0;
18018   u8 round_type = 0;
18019   u8 type = 0;
18020   u8 color_aware = 0;
18021   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
18022   int ret;
18023
18024   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
18025   conform_action.dscp = 0;
18026   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
18027   exceed_action.dscp = 0;
18028   violate_action.action_type = SSE2_QOS_ACTION_DROP;
18029   violate_action.dscp = 0;
18030
18031   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18032     {
18033       if (unformat (i, "del"))
18034         is_add = 0;
18035       else if (unformat (i, "name %s", &name))
18036         vec_add1 (name, 0);
18037       else if (unformat (i, "cir %u", &cir))
18038         ;
18039       else if (unformat (i, "eir %u", &eir))
18040         ;
18041       else if (unformat (i, "cb %u", &cb))
18042         ;
18043       else if (unformat (i, "eb %u", &eb))
18044         ;
18045       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
18046                          &rate_type))
18047         ;
18048       else if (unformat (i, "round_type %U", unformat_policer_round_type,
18049                          &round_type))
18050         ;
18051       else if (unformat (i, "type %U", unformat_policer_type, &type))
18052         ;
18053       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
18054                          &conform_action))
18055         ;
18056       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
18057                          &exceed_action))
18058         ;
18059       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
18060                          &violate_action))
18061         ;
18062       else if (unformat (i, "color-aware"))
18063         color_aware = 1;
18064       else
18065         break;
18066     }
18067
18068   if (!vec_len (name))
18069     {
18070       errmsg ("policer name must be specified");
18071       return -99;
18072     }
18073
18074   if (vec_len (name) > 64)
18075     {
18076       errmsg ("policer name too long");
18077       return -99;
18078     }
18079
18080   M (POLICER_ADD_DEL, mp);
18081
18082   clib_memcpy (mp->name, name, vec_len (name));
18083   vec_free (name);
18084   mp->is_add = is_add;
18085   mp->cir = ntohl (cir);
18086   mp->eir = ntohl (eir);
18087   mp->cb = clib_net_to_host_u64 (cb);
18088   mp->eb = clib_net_to_host_u64 (eb);
18089   mp->rate_type = rate_type;
18090   mp->round_type = round_type;
18091   mp->type = type;
18092   mp->conform_action_type = conform_action.action_type;
18093   mp->conform_dscp = conform_action.dscp;
18094   mp->exceed_action_type = exceed_action.action_type;
18095   mp->exceed_dscp = exceed_action.dscp;
18096   mp->violate_action_type = violate_action.action_type;
18097   mp->violate_dscp = violate_action.dscp;
18098   mp->color_aware = color_aware;
18099
18100   S (mp);
18101   W (ret);
18102   return ret;
18103 }
18104
18105 static int
18106 api_policer_dump (vat_main_t * vam)
18107 {
18108   unformat_input_t *i = vam->input;
18109   vl_api_policer_dump_t *mp;
18110   vl_api_control_ping_t *mp_ping;
18111   u8 *match_name = 0;
18112   u8 match_name_valid = 0;
18113   int ret;
18114
18115   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18116     {
18117       if (unformat (i, "name %s", &match_name))
18118         {
18119           vec_add1 (match_name, 0);
18120           match_name_valid = 1;
18121         }
18122       else
18123         break;
18124     }
18125
18126   M (POLICER_DUMP, mp);
18127   mp->match_name_valid = match_name_valid;
18128   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
18129   vec_free (match_name);
18130   /* send it... */
18131   S (mp);
18132
18133   /* Use a control ping for synchronization */
18134   MPING (CONTROL_PING, mp_ping);
18135   S (mp_ping);
18136
18137   /* Wait for a reply... */
18138   W (ret);
18139   return ret;
18140 }
18141
18142 static int
18143 api_policer_classify_set_interface (vat_main_t * vam)
18144 {
18145   unformat_input_t *i = vam->input;
18146   vl_api_policer_classify_set_interface_t *mp;
18147   u32 sw_if_index;
18148   int sw_if_index_set;
18149   u32 ip4_table_index = ~0;
18150   u32 ip6_table_index = ~0;
18151   u32 l2_table_index = ~0;
18152   u8 is_add = 1;
18153   int ret;
18154
18155   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18156     {
18157       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18158         sw_if_index_set = 1;
18159       else if (unformat (i, "sw_if_index %d", &sw_if_index))
18160         sw_if_index_set = 1;
18161       else if (unformat (i, "del"))
18162         is_add = 0;
18163       else if (unformat (i, "ip4-table %d", &ip4_table_index))
18164         ;
18165       else if (unformat (i, "ip6-table %d", &ip6_table_index))
18166         ;
18167       else if (unformat (i, "l2-table %d", &l2_table_index))
18168         ;
18169       else
18170         {
18171           clib_warning ("parse error '%U'", format_unformat_error, i);
18172           return -99;
18173         }
18174     }
18175
18176   if (sw_if_index_set == 0)
18177     {
18178       errmsg ("missing interface name or sw_if_index");
18179       return -99;
18180     }
18181
18182   M (POLICER_CLASSIFY_SET_INTERFACE, mp);
18183
18184   mp->sw_if_index = ntohl (sw_if_index);
18185   mp->ip4_table_index = ntohl (ip4_table_index);
18186   mp->ip6_table_index = ntohl (ip6_table_index);
18187   mp->l2_table_index = ntohl (l2_table_index);
18188   mp->is_add = is_add;
18189
18190   S (mp);
18191   W (ret);
18192   return ret;
18193 }
18194
18195 static int
18196 api_policer_classify_dump (vat_main_t * vam)
18197 {
18198   unformat_input_t *i = vam->input;
18199   vl_api_policer_classify_dump_t *mp;
18200   vl_api_control_ping_t *mp_ping;
18201   u8 type = POLICER_CLASSIFY_N_TABLES;
18202   int ret;
18203
18204   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
18205     ;
18206   else
18207     {
18208       errmsg ("classify table type must be specified");
18209       return -99;
18210     }
18211
18212   if (!vam->json_output)
18213     {
18214       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
18215     }
18216
18217   M (POLICER_CLASSIFY_DUMP, mp);
18218   mp->type = type;
18219   /* send it... */
18220   S (mp);
18221
18222   /* Use a control ping for synchronization */
18223   MPING (CONTROL_PING, mp_ping);
18224   S (mp_ping);
18225
18226   /* Wait for a reply... */
18227   W (ret);
18228   return ret;
18229 }
18230
18231 static int
18232 api_netmap_create (vat_main_t * vam)
18233 {
18234   unformat_input_t *i = vam->input;
18235   vl_api_netmap_create_t *mp;
18236   u8 *if_name = 0;
18237   u8 hw_addr[6];
18238   u8 random_hw_addr = 1;
18239   u8 is_pipe = 0;
18240   u8 is_master = 0;
18241   int ret;
18242
18243   clib_memset (hw_addr, 0, sizeof (hw_addr));
18244
18245   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18246     {
18247       if (unformat (i, "name %s", &if_name))
18248         vec_add1 (if_name, 0);
18249       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
18250         random_hw_addr = 0;
18251       else if (unformat (i, "pipe"))
18252         is_pipe = 1;
18253       else if (unformat (i, "master"))
18254         is_master = 1;
18255       else if (unformat (i, "slave"))
18256         is_master = 0;
18257       else
18258         break;
18259     }
18260
18261   if (!vec_len (if_name))
18262     {
18263       errmsg ("interface name must be specified");
18264       return -99;
18265     }
18266
18267   if (vec_len (if_name) > 64)
18268     {
18269       errmsg ("interface name too long");
18270       return -99;
18271     }
18272
18273   M (NETMAP_CREATE, mp);
18274
18275   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
18276   clib_memcpy (mp->hw_addr, hw_addr, 6);
18277   mp->use_random_hw_addr = random_hw_addr;
18278   mp->is_pipe = is_pipe;
18279   mp->is_master = is_master;
18280   vec_free (if_name);
18281
18282   S (mp);
18283   W (ret);
18284   return ret;
18285 }
18286
18287 static int
18288 api_netmap_delete (vat_main_t * vam)
18289 {
18290   unformat_input_t *i = vam->input;
18291   vl_api_netmap_delete_t *mp;
18292   u8 *if_name = 0;
18293   int ret;
18294
18295   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18296     {
18297       if (unformat (i, "name %s", &if_name))
18298         vec_add1 (if_name, 0);
18299       else
18300         break;
18301     }
18302
18303   if (!vec_len (if_name))
18304     {
18305       errmsg ("interface name must be specified");
18306       return -99;
18307     }
18308
18309   if (vec_len (if_name) > 64)
18310     {
18311       errmsg ("interface name too long");
18312       return -99;
18313     }
18314
18315   M (NETMAP_DELETE, mp);
18316
18317   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
18318   vec_free (if_name);
18319
18320   S (mp);
18321   W (ret);
18322   return ret;
18323 }
18324
18325 static u8 *
18326 format_fib_api_path_nh_proto (u8 * s, va_list * args)
18327 {
18328   vl_api_fib_path_nh_proto_t proto =
18329     va_arg (*args, vl_api_fib_path_nh_proto_t);
18330
18331   switch (proto)
18332     {
18333     case FIB_API_PATH_NH_PROTO_IP4:
18334       s = format (s, "ip4");
18335       break;
18336     case FIB_API_PATH_NH_PROTO_IP6:
18337       s = format (s, "ip6");
18338       break;
18339     case FIB_API_PATH_NH_PROTO_MPLS:
18340       s = format (s, "mpls");
18341       break;
18342     case FIB_API_PATH_NH_PROTO_BIER:
18343       s = format (s, "bier");
18344       break;
18345     case FIB_API_PATH_NH_PROTO_ETHERNET:
18346       s = format (s, "ethernet");
18347       break;
18348     }
18349
18350   return (s);
18351 }
18352
18353 static u8 *
18354 format_vl_api_ip_address_union (u8 * s, va_list * args)
18355 {
18356   vl_api_address_family_t af = va_arg (*args, vl_api_address_family_t);
18357   const vl_api_address_union_t *u = va_arg (*args, vl_api_address_union_t *);
18358
18359   switch (af)
18360     {
18361     case ADDRESS_IP4:
18362       s = format (s, "%U", format_ip4_address, u->ip4);
18363       break;
18364     case ADDRESS_IP6:
18365       s = format (s, "%U", format_ip6_address, u->ip6);
18366       break;
18367     }
18368   return (s);
18369 }
18370
18371 static u8 *
18372 format_vl_api_fib_path_type (u8 * s, va_list * args)
18373 {
18374   vl_api_fib_path_type_t t = va_arg (*args, vl_api_fib_path_type_t);
18375
18376   switch (t)
18377     {
18378     case FIB_API_PATH_TYPE_NORMAL:
18379       s = format (s, "normal");
18380       break;
18381     case FIB_API_PATH_TYPE_LOCAL:
18382       s = format (s, "local");
18383       break;
18384     case FIB_API_PATH_TYPE_DROP:
18385       s = format (s, "drop");
18386       break;
18387     case FIB_API_PATH_TYPE_UDP_ENCAP:
18388       s = format (s, "udp-encap");
18389       break;
18390     case FIB_API_PATH_TYPE_BIER_IMP:
18391       s = format (s, "bier-imp");
18392       break;
18393     case FIB_API_PATH_TYPE_ICMP_UNREACH:
18394       s = format (s, "unreach");
18395       break;
18396     case FIB_API_PATH_TYPE_ICMP_PROHIBIT:
18397       s = format (s, "prohibit");
18398       break;
18399     case FIB_API_PATH_TYPE_SOURCE_LOOKUP:
18400       s = format (s, "src-lookup");
18401       break;
18402     case FIB_API_PATH_TYPE_DVR:
18403       s = format (s, "dvr");
18404       break;
18405     case FIB_API_PATH_TYPE_INTERFACE_RX:
18406       s = format (s, "interface-rx");
18407       break;
18408     case FIB_API_PATH_TYPE_CLASSIFY:
18409       s = format (s, "classify");
18410       break;
18411     }
18412
18413   return (s);
18414 }
18415
18416 static void
18417 vl_api_fib_path_print (vat_main_t * vam, vl_api_fib_path_t * fp)
18418 {
18419   print (vam->ofp,
18420          "  weight %d, sw_if_index %d, type %U, afi %U, next_hop %U",
18421          ntohl (fp->weight), ntohl (fp->sw_if_index),
18422          format_vl_api_fib_path_type, fp->type,
18423          format_fib_api_path_nh_proto, fp->proto,
18424          format_vl_api_ip_address_union, &fp->nh.address);
18425 }
18426
18427 static void
18428 vl_api_mpls_fib_path_json_print (vat_json_node_t * node,
18429                                  vl_api_fib_path_t * fp)
18430 {
18431   struct in_addr ip4;
18432   struct in6_addr ip6;
18433
18434   vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
18435   vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
18436   vat_json_object_add_uint (node, "type", fp->type);
18437   vat_json_object_add_uint (node, "next_hop_proto", fp->proto);
18438   if (fp->proto == FIB_API_PATH_NH_PROTO_IP4)
18439     {
18440       clib_memcpy (&ip4, &fp->nh.address.ip4, sizeof (ip4));
18441       vat_json_object_add_ip4 (node, "next_hop", ip4);
18442     }
18443   else if (fp->proto == FIB_API_PATH_NH_PROTO_IP4)
18444     {
18445       clib_memcpy (&ip6, &fp->nh.address.ip6, sizeof (ip6));
18446       vat_json_object_add_ip6 (node, "next_hop", ip6);
18447     }
18448 }
18449
18450 static void
18451 vl_api_mpls_tunnel_details_t_handler (vl_api_mpls_tunnel_details_t * mp)
18452 {
18453   vat_main_t *vam = &vat_main;
18454   int count = ntohl (mp->mt_tunnel.mt_n_paths);
18455   vl_api_fib_path_t *fp;
18456   i32 i;
18457
18458   print (vam->ofp, "sw_if_index %d via:",
18459          ntohl (mp->mt_tunnel.mt_sw_if_index));
18460   fp = mp->mt_tunnel.mt_paths;
18461   for (i = 0; i < count; i++)
18462     {
18463       vl_api_fib_path_print (vam, fp);
18464       fp++;
18465     }
18466
18467   print (vam->ofp, "");
18468 }
18469
18470 #define vl_api_mpls_tunnel_details_t_endian vl_noop_handler
18471 #define vl_api_mpls_tunnel_details_t_print vl_noop_handler
18472
18473 static void
18474 vl_api_mpls_tunnel_details_t_handler_json (vl_api_mpls_tunnel_details_t * mp)
18475 {
18476   vat_main_t *vam = &vat_main;
18477   vat_json_node_t *node = NULL;
18478   int count = ntohl (mp->mt_tunnel.mt_n_paths);
18479   vl_api_fib_path_t *fp;
18480   i32 i;
18481
18482   if (VAT_JSON_ARRAY != vam->json_tree.type)
18483     {
18484       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18485       vat_json_init_array (&vam->json_tree);
18486     }
18487   node = vat_json_array_add (&vam->json_tree);
18488
18489   vat_json_init_object (node);
18490   vat_json_object_add_uint (node, "sw_if_index",
18491                             ntohl (mp->mt_tunnel.mt_sw_if_index));
18492
18493   vat_json_object_add_uint (node, "l2_only", mp->mt_tunnel.mt_l2_only);
18494
18495   fp = mp->mt_tunnel.mt_paths;
18496   for (i = 0; i < count; i++)
18497     {
18498       vl_api_mpls_fib_path_json_print (node, fp);
18499       fp++;
18500     }
18501 }
18502
18503 static int
18504 api_mpls_tunnel_dump (vat_main_t * vam)
18505 {
18506   vl_api_mpls_tunnel_dump_t *mp;
18507   vl_api_control_ping_t *mp_ping;
18508   int ret;
18509
18510   M (MPLS_TUNNEL_DUMP, mp);
18511
18512   S (mp);
18513
18514   /* Use a control ping for synchronization */
18515   MPING (CONTROL_PING, mp_ping);
18516   S (mp_ping);
18517
18518   W (ret);
18519   return ret;
18520 }
18521
18522 #define vl_api_mpls_table_details_t_endian vl_noop_handler
18523 #define vl_api_mpls_table_details_t_print vl_noop_handler
18524
18525
18526 static void
18527 vl_api_mpls_table_details_t_handler (vl_api_mpls_table_details_t * mp)
18528 {
18529   vat_main_t *vam = &vat_main;
18530
18531   print (vam->ofp, "table-id %d,", ntohl (mp->mt_table.mt_table_id));
18532 }
18533
18534 static void vl_api_mpls_table_details_t_handler_json
18535   (vl_api_mpls_table_details_t * mp)
18536 {
18537   vat_main_t *vam = &vat_main;
18538   vat_json_node_t *node = NULL;
18539
18540   if (VAT_JSON_ARRAY != vam->json_tree.type)
18541     {
18542       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18543       vat_json_init_array (&vam->json_tree);
18544     }
18545   node = vat_json_array_add (&vam->json_tree);
18546
18547   vat_json_init_object (node);
18548   vat_json_object_add_uint (node, "table", ntohl (mp->mt_table.mt_table_id));
18549 }
18550
18551 static int
18552 api_mpls_table_dump (vat_main_t * vam)
18553 {
18554   vl_api_mpls_table_dump_t *mp;
18555   vl_api_control_ping_t *mp_ping;
18556   int ret;
18557
18558   M (MPLS_TABLE_DUMP, mp);
18559   S (mp);
18560
18561   /* Use a control ping for synchronization */
18562   MPING (CONTROL_PING, mp_ping);
18563   S (mp_ping);
18564
18565   W (ret);
18566   return ret;
18567 }
18568
18569 #define vl_api_mpls_route_details_t_endian vl_noop_handler
18570 #define vl_api_mpls_route_details_t_print vl_noop_handler
18571
18572 static void
18573 vl_api_mpls_route_details_t_handler (vl_api_mpls_route_details_t * mp)
18574 {
18575   vat_main_t *vam = &vat_main;
18576   int count = (int) clib_net_to_host_u32 (mp->mr_route.mr_n_paths);
18577   vl_api_fib_path_t *fp;
18578   int i;
18579
18580   print (vam->ofp,
18581          "table-id %d, label %u, ess_bit %u",
18582          ntohl (mp->mr_route.mr_table_id),
18583          ntohl (mp->mr_route.mr_label), mp->mr_route.mr_eos);
18584   fp = mp->mr_route.mr_paths;
18585   for (i = 0; i < count; i++)
18586     {
18587       vl_api_fib_path_print (vam, fp);
18588       fp++;
18589     }
18590 }
18591
18592 static void vl_api_mpls_route_details_t_handler_json
18593   (vl_api_mpls_route_details_t * mp)
18594 {
18595   vat_main_t *vam = &vat_main;
18596   int count = (int) clib_host_to_net_u32 (mp->mr_route.mr_n_paths);
18597   vat_json_node_t *node = NULL;
18598   vl_api_fib_path_t *fp;
18599   int i;
18600
18601   if (VAT_JSON_ARRAY != vam->json_tree.type)
18602     {
18603       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18604       vat_json_init_array (&vam->json_tree);
18605     }
18606   node = vat_json_array_add (&vam->json_tree);
18607
18608   vat_json_init_object (node);
18609   vat_json_object_add_uint (node, "table", ntohl (mp->mr_route.mr_table_id));
18610   vat_json_object_add_uint (node, "s_bit", mp->mr_route.mr_eos);
18611   vat_json_object_add_uint (node, "label", ntohl (mp->mr_route.mr_label));
18612   vat_json_object_add_uint (node, "path_count", count);
18613   fp = mp->mr_route.mr_paths;
18614   for (i = 0; i < count; i++)
18615     {
18616       vl_api_mpls_fib_path_json_print (node, fp);
18617       fp++;
18618     }
18619 }
18620
18621 static int
18622 api_mpls_route_dump (vat_main_t * vam)
18623 {
18624   unformat_input_t *input = vam->input;
18625   vl_api_mpls_route_dump_t *mp;
18626   vl_api_control_ping_t *mp_ping;
18627   u32 table_id;
18628   int ret;
18629
18630   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18631     {
18632       if (unformat (input, "table_id %d", &table_id))
18633         ;
18634       else
18635         break;
18636     }
18637   if (table_id == ~0)
18638     {
18639       errmsg ("missing table id");
18640       return -99;
18641     }
18642
18643   M (MPLS_ROUTE_DUMP, mp);
18644
18645   mp->table.mt_table_id = ntohl (table_id);
18646   S (mp);
18647
18648   /* Use a control ping for synchronization */
18649   MPING (CONTROL_PING, mp_ping);
18650   S (mp_ping);
18651
18652   W (ret);
18653   return ret;
18654 }
18655
18656 #define vl_api_ip_table_details_t_endian vl_noop_handler
18657 #define vl_api_ip_table_details_t_print vl_noop_handler
18658
18659 static void
18660 vl_api_ip_table_details_t_handler (vl_api_ip_table_details_t * mp)
18661 {
18662   vat_main_t *vam = &vat_main;
18663
18664   print (vam->ofp,
18665          "%s; table-id %d, prefix %U/%d",
18666          mp->table.name, ntohl (mp->table.table_id));
18667 }
18668
18669
18670 static void vl_api_ip_table_details_t_handler_json
18671   (vl_api_ip_table_details_t * mp)
18672 {
18673   vat_main_t *vam = &vat_main;
18674   vat_json_node_t *node = NULL;
18675
18676   if (VAT_JSON_ARRAY != vam->json_tree.type)
18677     {
18678       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18679       vat_json_init_array (&vam->json_tree);
18680     }
18681   node = vat_json_array_add (&vam->json_tree);
18682
18683   vat_json_init_object (node);
18684   vat_json_object_add_uint (node, "table", ntohl (mp->table.table_id));
18685 }
18686
18687 static int
18688 api_ip_table_dump (vat_main_t * vam)
18689 {
18690   vl_api_ip_table_dump_t *mp;
18691   vl_api_control_ping_t *mp_ping;
18692   int ret;
18693
18694   M (IP_TABLE_DUMP, mp);
18695   S (mp);
18696
18697   /* Use a control ping for synchronization */
18698   MPING (CONTROL_PING, mp_ping);
18699   S (mp_ping);
18700
18701   W (ret);
18702   return ret;
18703 }
18704
18705 static int
18706 api_ip_mtable_dump (vat_main_t * vam)
18707 {
18708   vl_api_ip_mtable_dump_t *mp;
18709   vl_api_control_ping_t *mp_ping;
18710   int ret;
18711
18712   M (IP_MTABLE_DUMP, mp);
18713   S (mp);
18714
18715   /* Use a control ping for synchronization */
18716   MPING (CONTROL_PING, mp_ping);
18717   S (mp_ping);
18718
18719   W (ret);
18720   return ret;
18721 }
18722
18723 static int
18724 api_ip_mroute_dump (vat_main_t * vam)
18725 {
18726   unformat_input_t *input = vam->input;
18727   vl_api_control_ping_t *mp_ping;
18728   vl_api_ip_mroute_dump_t *mp;
18729   int ret, is_ip6;
18730   u32 table_id;
18731
18732   is_ip6 = 0;
18733   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18734     {
18735       if (unformat (input, "table_id %d", &table_id))
18736         ;
18737       else if (unformat (input, "ip6"))
18738         is_ip6 = 1;
18739       else if (unformat (input, "ip4"))
18740         is_ip6 = 0;
18741       else
18742         break;
18743     }
18744   if (table_id == ~0)
18745     {
18746       errmsg ("missing table id");
18747       return -99;
18748     }
18749
18750   M (IP_MROUTE_DUMP, mp);
18751   mp->table.table_id = table_id;
18752   mp->table.is_ip6 = is_ip6;
18753   S (mp);
18754
18755   /* Use a control ping for synchronization */
18756   MPING (CONTROL_PING, mp_ping);
18757   S (mp_ping);
18758
18759   W (ret);
18760   return ret;
18761 }
18762
18763 static void vl_api_ip_neighbor_details_t_handler
18764   (vl_api_ip_neighbor_details_t * mp)
18765 {
18766   vat_main_t *vam = &vat_main;
18767
18768   print (vam->ofp, "%c %U %U",
18769          (ntohl (mp->neighbor.flags) & IP_NEIGHBOR_FLAG_STATIC) ? 'S' : 'D',
18770          format_vl_api_mac_address, &mp->neighbor.mac_address,
18771          format_vl_api_address, &mp->neighbor.ip_address);
18772 }
18773
18774 static void vl_api_ip_neighbor_details_t_handler_json
18775   (vl_api_ip_neighbor_details_t * mp)
18776 {
18777
18778   vat_main_t *vam = &vat_main;
18779   vat_json_node_t *node;
18780
18781   if (VAT_JSON_ARRAY != vam->json_tree.type)
18782     {
18783       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18784       vat_json_init_array (&vam->json_tree);
18785     }
18786   node = vat_json_array_add (&vam->json_tree);
18787
18788   vat_json_init_object (node);
18789   vat_json_object_add_string_copy
18790     (node, "flag",
18791      ((ntohl (mp->neighbor.flags) & IP_NEIGHBOR_FLAG_STATIC) ?
18792       (u8 *) "static" : (u8 *) "dynamic"));
18793
18794   vat_json_object_add_string_copy (node, "link_layer",
18795                                    format (0, "%U", format_vl_api_mac_address,
18796                                            &mp->neighbor.mac_address));
18797   vat_json_object_add_address (node, "ip", &mp->neighbor.ip_address);
18798 }
18799
18800 static int
18801 api_ip_neighbor_dump (vat_main_t * vam)
18802 {
18803   unformat_input_t *i = vam->input;
18804   vl_api_ip_neighbor_dump_t *mp;
18805   vl_api_control_ping_t *mp_ping;
18806   u8 is_ipv6 = 0;
18807   u32 sw_if_index = ~0;
18808   int ret;
18809
18810   /* Parse args required to build the message */
18811   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18812     {
18813       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18814         ;
18815       else if (unformat (i, "sw_if_index %d", &sw_if_index))
18816         ;
18817       else if (unformat (i, "ip6"))
18818         is_ipv6 = 1;
18819       else
18820         break;
18821     }
18822
18823   if (sw_if_index == ~0)
18824     {
18825       errmsg ("missing interface name or sw_if_index");
18826       return -99;
18827     }
18828
18829   M (IP_NEIGHBOR_DUMP, mp);
18830   mp->is_ipv6 = (u8) is_ipv6;
18831   mp->sw_if_index = ntohl (sw_if_index);
18832   S (mp);
18833
18834   /* Use a control ping for synchronization */
18835   MPING (CONTROL_PING, mp_ping);
18836   S (mp_ping);
18837
18838   W (ret);
18839   return ret;
18840 }
18841
18842 #define vl_api_ip_route_details_t_endian vl_noop_handler
18843 #define vl_api_ip_route_details_t_print vl_noop_handler
18844
18845 static void
18846 vl_api_ip_route_details_t_handler (vl_api_ip_route_details_t * mp)
18847 {
18848   vat_main_t *vam = &vat_main;
18849   u8 count = mp->route.n_paths;
18850   vl_api_fib_path_t *fp;
18851   int i;
18852
18853   print (vam->ofp,
18854          "table-id %d, prefix %U/%d",
18855          ntohl (mp->route.table_id),
18856          format_ip46_address, mp->route.prefix.address, mp->route.prefix.len);
18857   for (i = 0; i < count; i++)
18858     {
18859       fp = &mp->route.paths[i];
18860
18861       vl_api_fib_path_print (vam, fp);
18862       fp++;
18863     }
18864 }
18865
18866 static void vl_api_ip_route_details_t_handler_json
18867   (vl_api_ip_route_details_t * mp)
18868 {
18869   vat_main_t *vam = &vat_main;
18870   u8 count = mp->route.n_paths;
18871   vat_json_node_t *node = NULL;
18872   struct in_addr ip4;
18873   struct in6_addr ip6;
18874   vl_api_fib_path_t *fp;
18875   int i;
18876
18877   if (VAT_JSON_ARRAY != vam->json_tree.type)
18878     {
18879       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18880       vat_json_init_array (&vam->json_tree);
18881     }
18882   node = vat_json_array_add (&vam->json_tree);
18883
18884   vat_json_init_object (node);
18885   vat_json_object_add_uint (node, "table", ntohl (mp->route.table_id));
18886   if (ADDRESS_IP6 == mp->route.prefix.address.af)
18887     {
18888       clib_memcpy (&ip6, &mp->route.prefix.address.un.ip6, sizeof (ip6));
18889       vat_json_object_add_ip6 (node, "prefix", ip6);
18890     }
18891   else
18892     {
18893       clib_memcpy (&ip4, &mp->route.prefix.address.un.ip4, sizeof (ip4));
18894       vat_json_object_add_ip4 (node, "prefix", ip4);
18895     }
18896   vat_json_object_add_uint (node, "mask_length", mp->route.prefix.len);
18897   vat_json_object_add_uint (node, "path_count", count);
18898   for (i = 0; i < count; i++)
18899     {
18900       fp = &mp->route.paths[i];
18901       vl_api_mpls_fib_path_json_print (node, fp);
18902     }
18903 }
18904
18905 static int
18906 api_ip_route_dump (vat_main_t * vam)
18907 {
18908   unformat_input_t *input = vam->input;
18909   vl_api_ip_route_dump_t *mp;
18910   vl_api_control_ping_t *mp_ping;
18911   u32 table_id;
18912   u8 is_ip6;
18913   int ret;
18914
18915   is_ip6 = 0;
18916   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18917     {
18918       if (unformat (input, "table_id %d", &table_id))
18919         ;
18920       else if (unformat (input, "ip6"))
18921         is_ip6 = 1;
18922       else if (unformat (input, "ip4"))
18923         is_ip6 = 0;
18924       else
18925         break;
18926     }
18927   if (table_id == ~0)
18928     {
18929       errmsg ("missing table id");
18930       return -99;
18931     }
18932
18933   M (IP_ROUTE_DUMP, mp);
18934
18935   mp->table.table_id = table_id;
18936   mp->table.is_ip6 = is_ip6;
18937
18938   S (mp);
18939
18940   /* Use a control ping for synchronization */
18941   MPING (CONTROL_PING, mp_ping);
18942   S (mp_ping);
18943
18944   W (ret);
18945   return ret;
18946 }
18947
18948 int
18949 api_classify_table_ids (vat_main_t * vam)
18950 {
18951   vl_api_classify_table_ids_t *mp;
18952   int ret;
18953
18954   /* Construct the API message */
18955   M (CLASSIFY_TABLE_IDS, mp);
18956   mp->context = 0;
18957
18958   S (mp);
18959   W (ret);
18960   return ret;
18961 }
18962
18963 int
18964 api_classify_table_by_interface (vat_main_t * vam)
18965 {
18966   unformat_input_t *input = vam->input;
18967   vl_api_classify_table_by_interface_t *mp;
18968
18969   u32 sw_if_index = ~0;
18970   int ret;
18971   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18972     {
18973       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18974         ;
18975       else if (unformat (input, "sw_if_index %d", &sw_if_index))
18976         ;
18977       else
18978         break;
18979     }
18980   if (sw_if_index == ~0)
18981     {
18982       errmsg ("missing interface name or sw_if_index");
18983       return -99;
18984     }
18985
18986   /* Construct the API message */
18987   M (CLASSIFY_TABLE_BY_INTERFACE, mp);
18988   mp->context = 0;
18989   mp->sw_if_index = ntohl (sw_if_index);
18990
18991   S (mp);
18992   W (ret);
18993   return ret;
18994 }
18995
18996 int
18997 api_classify_table_info (vat_main_t * vam)
18998 {
18999   unformat_input_t *input = vam->input;
19000   vl_api_classify_table_info_t *mp;
19001
19002   u32 table_id = ~0;
19003   int ret;
19004   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19005     {
19006       if (unformat (input, "table_id %d", &table_id))
19007         ;
19008       else
19009         break;
19010     }
19011   if (table_id == ~0)
19012     {
19013       errmsg ("missing table id");
19014       return -99;
19015     }
19016
19017   /* Construct the API message */
19018   M (CLASSIFY_TABLE_INFO, mp);
19019   mp->context = 0;
19020   mp->table_id = ntohl (table_id);
19021
19022   S (mp);
19023   W (ret);
19024   return ret;
19025 }
19026
19027 int
19028 api_classify_session_dump (vat_main_t * vam)
19029 {
19030   unformat_input_t *input = vam->input;
19031   vl_api_classify_session_dump_t *mp;
19032   vl_api_control_ping_t *mp_ping;
19033
19034   u32 table_id = ~0;
19035   int ret;
19036   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19037     {
19038       if (unformat (input, "table_id %d", &table_id))
19039         ;
19040       else
19041         break;
19042     }
19043   if (table_id == ~0)
19044     {
19045       errmsg ("missing table id");
19046       return -99;
19047     }
19048
19049   /* Construct the API message */
19050   M (CLASSIFY_SESSION_DUMP, mp);
19051   mp->context = 0;
19052   mp->table_id = ntohl (table_id);
19053   S (mp);
19054
19055   /* Use a control ping for synchronization */
19056   MPING (CONTROL_PING, mp_ping);
19057   S (mp_ping);
19058
19059   W (ret);
19060   return ret;
19061 }
19062
19063 static void
19064 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
19065 {
19066   vat_main_t *vam = &vat_main;
19067
19068   print (vam->ofp, "collector_address %U, collector_port %d, "
19069          "src_address %U, vrf_id %d, path_mtu %u, "
19070          "template_interval %u, udp_checksum %d",
19071          format_ip4_address, mp->collector_address,
19072          ntohs (mp->collector_port),
19073          format_ip4_address, mp->src_address,
19074          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
19075          ntohl (mp->template_interval), mp->udp_checksum);
19076
19077   vam->retval = 0;
19078   vam->result_ready = 1;
19079 }
19080
19081 static void
19082   vl_api_ipfix_exporter_details_t_handler_json
19083   (vl_api_ipfix_exporter_details_t * mp)
19084 {
19085   vat_main_t *vam = &vat_main;
19086   vat_json_node_t node;
19087   struct in_addr collector_address;
19088   struct in_addr src_address;
19089
19090   vat_json_init_object (&node);
19091   clib_memcpy (&collector_address, &mp->collector_address,
19092                sizeof (collector_address));
19093   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
19094   vat_json_object_add_uint (&node, "collector_port",
19095                             ntohs (mp->collector_port));
19096   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
19097   vat_json_object_add_ip4 (&node, "src_address", src_address);
19098   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
19099   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
19100   vat_json_object_add_uint (&node, "template_interval",
19101                             ntohl (mp->template_interval));
19102   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
19103
19104   vat_json_print (vam->ofp, &node);
19105   vat_json_free (&node);
19106   vam->retval = 0;
19107   vam->result_ready = 1;
19108 }
19109
19110 int
19111 api_ipfix_exporter_dump (vat_main_t * vam)
19112 {
19113   vl_api_ipfix_exporter_dump_t *mp;
19114   int ret;
19115
19116   /* Construct the API message */
19117   M (IPFIX_EXPORTER_DUMP, mp);
19118   mp->context = 0;
19119
19120   S (mp);
19121   W (ret);
19122   return ret;
19123 }
19124
19125 static int
19126 api_ipfix_classify_stream_dump (vat_main_t * vam)
19127 {
19128   vl_api_ipfix_classify_stream_dump_t *mp;
19129   int ret;
19130
19131   /* Construct the API message */
19132   M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
19133   mp->context = 0;
19134
19135   S (mp);
19136   W (ret);
19137   return ret;
19138   /* NOTREACHED */
19139   return 0;
19140 }
19141
19142 static void
19143   vl_api_ipfix_classify_stream_details_t_handler
19144   (vl_api_ipfix_classify_stream_details_t * mp)
19145 {
19146   vat_main_t *vam = &vat_main;
19147   print (vam->ofp, "domain_id %d, src_port %d",
19148          ntohl (mp->domain_id), ntohs (mp->src_port));
19149   vam->retval = 0;
19150   vam->result_ready = 1;
19151 }
19152
19153 static void
19154   vl_api_ipfix_classify_stream_details_t_handler_json
19155   (vl_api_ipfix_classify_stream_details_t * mp)
19156 {
19157   vat_main_t *vam = &vat_main;
19158   vat_json_node_t node;
19159
19160   vat_json_init_object (&node);
19161   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
19162   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
19163
19164   vat_json_print (vam->ofp, &node);
19165   vat_json_free (&node);
19166   vam->retval = 0;
19167   vam->result_ready = 1;
19168 }
19169
19170 static int
19171 api_ipfix_classify_table_dump (vat_main_t * vam)
19172 {
19173   vl_api_ipfix_classify_table_dump_t *mp;
19174   vl_api_control_ping_t *mp_ping;
19175   int ret;
19176
19177   if (!vam->json_output)
19178     {
19179       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
19180              "transport_protocol");
19181     }
19182
19183   /* Construct the API message */
19184   M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
19185
19186   /* send it... */
19187   S (mp);
19188
19189   /* Use a control ping for synchronization */
19190   MPING (CONTROL_PING, mp_ping);
19191   S (mp_ping);
19192
19193   W (ret);
19194   return ret;
19195 }
19196
19197 static void
19198   vl_api_ipfix_classify_table_details_t_handler
19199   (vl_api_ipfix_classify_table_details_t * mp)
19200 {
19201   vat_main_t *vam = &vat_main;
19202   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
19203          mp->transport_protocol);
19204 }
19205
19206 static void
19207   vl_api_ipfix_classify_table_details_t_handler_json
19208   (vl_api_ipfix_classify_table_details_t * mp)
19209 {
19210   vat_json_node_t *node = NULL;
19211   vat_main_t *vam = &vat_main;
19212
19213   if (VAT_JSON_ARRAY != vam->json_tree.type)
19214     {
19215       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19216       vat_json_init_array (&vam->json_tree);
19217     }
19218
19219   node = vat_json_array_add (&vam->json_tree);
19220   vat_json_init_object (node);
19221
19222   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
19223   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
19224   vat_json_object_add_uint (node, "transport_protocol",
19225                             mp->transport_protocol);
19226 }
19227
19228 static int
19229 api_sw_interface_span_enable_disable (vat_main_t * vam)
19230 {
19231   unformat_input_t *i = vam->input;
19232   vl_api_sw_interface_span_enable_disable_t *mp;
19233   u32 src_sw_if_index = ~0;
19234   u32 dst_sw_if_index = ~0;
19235   u8 state = 3;
19236   int ret;
19237   u8 is_l2 = 0;
19238
19239   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19240     {
19241       if (unformat
19242           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
19243         ;
19244       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
19245         ;
19246       else
19247         if (unformat
19248             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
19249         ;
19250       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
19251         ;
19252       else if (unformat (i, "disable"))
19253         state = 0;
19254       else if (unformat (i, "rx"))
19255         state = 1;
19256       else if (unformat (i, "tx"))
19257         state = 2;
19258       else if (unformat (i, "both"))
19259         state = 3;
19260       else if (unformat (i, "l2"))
19261         is_l2 = 1;
19262       else
19263         break;
19264     }
19265
19266   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
19267
19268   mp->sw_if_index_from = htonl (src_sw_if_index);
19269   mp->sw_if_index_to = htonl (dst_sw_if_index);
19270   mp->state = state;
19271   mp->is_l2 = is_l2;
19272
19273   S (mp);
19274   W (ret);
19275   return ret;
19276 }
19277
19278 static void
19279 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
19280                                             * mp)
19281 {
19282   vat_main_t *vam = &vat_main;
19283   u8 *sw_if_from_name = 0;
19284   u8 *sw_if_to_name = 0;
19285   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
19286   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
19287   char *states[] = { "none", "rx", "tx", "both" };
19288   hash_pair_t *p;
19289
19290   /* *INDENT-OFF* */
19291   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
19292   ({
19293     if ((u32) p->value[0] == sw_if_index_from)
19294       {
19295         sw_if_from_name = (u8 *)(p->key);
19296         if (sw_if_to_name)
19297           break;
19298       }
19299     if ((u32) p->value[0] == sw_if_index_to)
19300       {
19301         sw_if_to_name = (u8 *)(p->key);
19302         if (sw_if_from_name)
19303           break;
19304       }
19305   }));
19306   /* *INDENT-ON* */
19307   print (vam->ofp, "%20s => %20s (%s) %s",
19308          sw_if_from_name, sw_if_to_name, states[mp->state],
19309          mp->is_l2 ? "l2" : "device");
19310 }
19311
19312 static void
19313   vl_api_sw_interface_span_details_t_handler_json
19314   (vl_api_sw_interface_span_details_t * mp)
19315 {
19316   vat_main_t *vam = &vat_main;
19317   vat_json_node_t *node = NULL;
19318   u8 *sw_if_from_name = 0;
19319   u8 *sw_if_to_name = 0;
19320   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
19321   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
19322   hash_pair_t *p;
19323
19324   /* *INDENT-OFF* */
19325   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
19326   ({
19327     if ((u32) p->value[0] == sw_if_index_from)
19328       {
19329         sw_if_from_name = (u8 *)(p->key);
19330         if (sw_if_to_name)
19331           break;
19332       }
19333     if ((u32) p->value[0] == sw_if_index_to)
19334       {
19335         sw_if_to_name = (u8 *)(p->key);
19336         if (sw_if_from_name)
19337           break;
19338       }
19339   }));
19340   /* *INDENT-ON* */
19341
19342   if (VAT_JSON_ARRAY != vam->json_tree.type)
19343     {
19344       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19345       vat_json_init_array (&vam->json_tree);
19346     }
19347   node = vat_json_array_add (&vam->json_tree);
19348
19349   vat_json_init_object (node);
19350   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
19351   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
19352   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
19353   if (0 != sw_if_to_name)
19354     {
19355       vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
19356     }
19357   vat_json_object_add_uint (node, "state", mp->state);
19358   vat_json_object_add_uint (node, "is-l2", mp->is_l2);
19359 }
19360
19361 static int
19362 api_sw_interface_span_dump (vat_main_t * vam)
19363 {
19364   unformat_input_t *input = vam->input;
19365   vl_api_sw_interface_span_dump_t *mp;
19366   vl_api_control_ping_t *mp_ping;
19367   u8 is_l2 = 0;
19368   int ret;
19369
19370   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19371     {
19372       if (unformat (input, "l2"))
19373         is_l2 = 1;
19374       else
19375         break;
19376     }
19377
19378   M (SW_INTERFACE_SPAN_DUMP, mp);
19379   mp->is_l2 = is_l2;
19380   S (mp);
19381
19382   /* Use a control ping for synchronization */
19383   MPING (CONTROL_PING, mp_ping);
19384   S (mp_ping);
19385
19386   W (ret);
19387   return ret;
19388 }
19389
19390 int
19391 api_pg_create_interface (vat_main_t * vam)
19392 {
19393   unformat_input_t *input = vam->input;
19394   vl_api_pg_create_interface_t *mp;
19395
19396   u32 if_id = ~0, gso_size = 0;
19397   u8 gso_enabled = 0;
19398   int ret;
19399   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19400     {
19401       if (unformat (input, "if_id %d", &if_id))
19402         ;
19403       else if (unformat (input, "gso-enabled"))
19404         {
19405           gso_enabled = 1;
19406           if (unformat (input, "gso-size %u", &gso_size))
19407             ;
19408           else
19409             {
19410               errmsg ("missing gso-size");
19411               return -99;
19412             }
19413         }
19414       else
19415         break;
19416     }
19417   if (if_id == ~0)
19418     {
19419       errmsg ("missing pg interface index");
19420       return -99;
19421     }
19422
19423   /* Construct the API message */
19424   M (PG_CREATE_INTERFACE, mp);
19425   mp->context = 0;
19426   mp->interface_id = ntohl (if_id);
19427   mp->gso_enabled = gso_enabled;
19428
19429   S (mp);
19430   W (ret);
19431   return ret;
19432 }
19433
19434 int
19435 api_pg_capture (vat_main_t * vam)
19436 {
19437   unformat_input_t *input = vam->input;
19438   vl_api_pg_capture_t *mp;
19439
19440   u32 if_id = ~0;
19441   u8 enable = 1;
19442   u32 count = 1;
19443   u8 pcap_file_set = 0;
19444   u8 *pcap_file = 0;
19445   int ret;
19446   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19447     {
19448       if (unformat (input, "if_id %d", &if_id))
19449         ;
19450       else if (unformat (input, "pcap %s", &pcap_file))
19451         pcap_file_set = 1;
19452       else if (unformat (input, "count %d", &count))
19453         ;
19454       else if (unformat (input, "disable"))
19455         enable = 0;
19456       else
19457         break;
19458     }
19459   if (if_id == ~0)
19460     {
19461       errmsg ("missing pg interface index");
19462       return -99;
19463     }
19464   if (pcap_file_set > 0)
19465     {
19466       if (vec_len (pcap_file) > 255)
19467         {
19468           errmsg ("pcap file name is too long");
19469           return -99;
19470         }
19471     }
19472
19473   u32 name_len = vec_len (pcap_file);
19474   /* Construct the API message */
19475   M (PG_CAPTURE, mp);
19476   mp->context = 0;
19477   mp->interface_id = ntohl (if_id);
19478   mp->is_enabled = enable;
19479   mp->count = ntohl (count);
19480   mp->pcap_name_length = ntohl (name_len);
19481   if (pcap_file_set != 0)
19482     {
19483       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
19484     }
19485   vec_free (pcap_file);
19486
19487   S (mp);
19488   W (ret);
19489   return ret;
19490 }
19491
19492 int
19493 api_pg_enable_disable (vat_main_t * vam)
19494 {
19495   unformat_input_t *input = vam->input;
19496   vl_api_pg_enable_disable_t *mp;
19497
19498   u8 enable = 1;
19499   u8 stream_name_set = 0;
19500   u8 *stream_name = 0;
19501   int ret;
19502   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19503     {
19504       if (unformat (input, "stream %s", &stream_name))
19505         stream_name_set = 1;
19506       else if (unformat (input, "disable"))
19507         enable = 0;
19508       else
19509         break;
19510     }
19511
19512   if (stream_name_set > 0)
19513     {
19514       if (vec_len (stream_name) > 255)
19515         {
19516           errmsg ("stream name too long");
19517           return -99;
19518         }
19519     }
19520
19521   u32 name_len = vec_len (stream_name);
19522   /* Construct the API message */
19523   M (PG_ENABLE_DISABLE, mp);
19524   mp->context = 0;
19525   mp->is_enabled = enable;
19526   if (stream_name_set != 0)
19527     {
19528       mp->stream_name_length = ntohl (name_len);
19529       clib_memcpy (mp->stream_name, stream_name, name_len);
19530     }
19531   vec_free (stream_name);
19532
19533   S (mp);
19534   W (ret);
19535   return ret;
19536 }
19537
19538 int
19539 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
19540 {
19541   unformat_input_t *input = vam->input;
19542   vl_api_ip_source_and_port_range_check_add_del_t *mp;
19543
19544   u16 *low_ports = 0;
19545   u16 *high_ports = 0;
19546   u16 this_low;
19547   u16 this_hi;
19548   vl_api_prefix_t prefix;
19549   u32 tmp, tmp2;
19550   u8 prefix_set = 0;
19551   u32 vrf_id = ~0;
19552   u8 is_add = 1;
19553   int ret;
19554
19555   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19556     {
19557       if (unformat (input, "%U", unformat_vl_api_prefix, &prefix))
19558         prefix_set = 1;
19559       else if (unformat (input, "vrf %d", &vrf_id))
19560         ;
19561       else if (unformat (input, "del"))
19562         is_add = 0;
19563       else if (unformat (input, "port %d", &tmp))
19564         {
19565           if (tmp == 0 || tmp > 65535)
19566             {
19567               errmsg ("port %d out of range", tmp);
19568               return -99;
19569             }
19570           this_low = tmp;
19571           this_hi = this_low + 1;
19572           vec_add1 (low_ports, this_low);
19573           vec_add1 (high_ports, this_hi);
19574         }
19575       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
19576         {
19577           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
19578             {
19579               errmsg ("incorrect range parameters");
19580               return -99;
19581             }
19582           this_low = tmp;
19583           /* Note: in debug CLI +1 is added to high before
19584              passing to real fn that does "the work"
19585              (ip_source_and_port_range_check_add_del).
19586              This fn is a wrapper around the binary API fn a
19587              control plane will call, which expects this increment
19588              to have occurred. Hence letting the binary API control
19589              plane fn do the increment for consistency between VAT
19590              and other control planes.
19591            */
19592           this_hi = tmp2;
19593           vec_add1 (low_ports, this_low);
19594           vec_add1 (high_ports, this_hi);
19595         }
19596       else
19597         break;
19598     }
19599
19600   if (prefix_set == 0)
19601     {
19602       errmsg ("<address>/<mask> not specified");
19603       return -99;
19604     }
19605
19606   if (vrf_id == ~0)
19607     {
19608       errmsg ("VRF ID required, not specified");
19609       return -99;
19610     }
19611
19612   if (vrf_id == 0)
19613     {
19614       errmsg
19615         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
19616       return -99;
19617     }
19618
19619   if (vec_len (low_ports) == 0)
19620     {
19621       errmsg ("At least one port or port range required");
19622       return -99;
19623     }
19624
19625   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
19626
19627   mp->is_add = is_add;
19628
19629   clib_memcpy (&mp->prefix, &prefix, sizeof (prefix));
19630
19631   mp->number_of_ranges = vec_len (low_ports);
19632
19633   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
19634   vec_free (low_ports);
19635
19636   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
19637   vec_free (high_ports);
19638
19639   mp->vrf_id = ntohl (vrf_id);
19640
19641   S (mp);
19642   W (ret);
19643   return ret;
19644 }
19645
19646 int
19647 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
19648 {
19649   unformat_input_t *input = vam->input;
19650   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
19651   u32 sw_if_index = ~0;
19652   int vrf_set = 0;
19653   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
19654   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
19655   u8 is_add = 1;
19656   int ret;
19657
19658   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
19659     {
19660       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19661         ;
19662       else if (unformat (input, "sw_if_index %d", &sw_if_index))
19663         ;
19664       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
19665         vrf_set = 1;
19666       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
19667         vrf_set = 1;
19668       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
19669         vrf_set = 1;
19670       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
19671         vrf_set = 1;
19672       else if (unformat (input, "del"))
19673         is_add = 0;
19674       else
19675         break;
19676     }
19677
19678   if (sw_if_index == ~0)
19679     {
19680       errmsg ("Interface required but not specified");
19681       return -99;
19682     }
19683
19684   if (vrf_set == 0)
19685     {
19686       errmsg ("VRF ID required but not specified");
19687       return -99;
19688     }
19689
19690   if (tcp_out_vrf_id == 0
19691       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
19692     {
19693       errmsg
19694         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
19695       return -99;
19696     }
19697
19698   /* Construct the API message */
19699   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
19700
19701   mp->sw_if_index = ntohl (sw_if_index);
19702   mp->is_add = is_add;
19703   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
19704   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
19705   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
19706   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
19707
19708   /* send it... */
19709   S (mp);
19710
19711   /* Wait for a reply... */
19712   W (ret);
19713   return ret;
19714 }
19715
19716 static int
19717 api_set_punt (vat_main_t * vam)
19718 {
19719   unformat_input_t *i = vam->input;
19720   vl_api_address_family_t af;
19721   vl_api_set_punt_t *mp;
19722   u32 protocol = ~0;
19723   u32 port = ~0;
19724   int is_add = 1;
19725   int ret;
19726
19727   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19728     {
19729       if (unformat (i, "%U", unformat_vl_api_address_family, &af))
19730         ;
19731       else if (unformat (i, "protocol %d", &protocol))
19732         ;
19733       else if (unformat (i, "port %d", &port))
19734         ;
19735       else if (unformat (i, "del"))
19736         is_add = 0;
19737       else
19738         {
19739           clib_warning ("parse error '%U'", format_unformat_error, i);
19740           return -99;
19741         }
19742     }
19743
19744   M (SET_PUNT, mp);
19745
19746   mp->is_add = (u8) is_add;
19747   mp->punt.type = PUNT_API_TYPE_L4;
19748   mp->punt.punt.l4.af = af;
19749   mp->punt.punt.l4.protocol = (u8) protocol;
19750   mp->punt.punt.l4.port = htons ((u16) port);
19751
19752   S (mp);
19753   W (ret);
19754   return ret;
19755 }
19756
19757 static int
19758 api_delete_subif (vat_main_t * vam)
19759 {
19760   unformat_input_t *i = vam->input;
19761   vl_api_delete_subif_t *mp;
19762   u32 sw_if_index = ~0;
19763   int ret;
19764
19765   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19766     {
19767       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19768         ;
19769       if (unformat (i, "sw_if_index %d", &sw_if_index))
19770         ;
19771       else
19772         break;
19773     }
19774
19775   if (sw_if_index == ~0)
19776     {
19777       errmsg ("missing sw_if_index");
19778       return -99;
19779     }
19780
19781   /* Construct the API message */
19782   M (DELETE_SUBIF, mp);
19783   mp->sw_if_index = ntohl (sw_if_index);
19784
19785   S (mp);
19786   W (ret);
19787   return ret;
19788 }
19789
19790 #define foreach_pbb_vtr_op      \
19791 _("disable",  L2_VTR_DISABLED)  \
19792 _("pop",  L2_VTR_POP_2)         \
19793 _("push",  L2_VTR_PUSH_2)
19794
19795 static int
19796 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
19797 {
19798   unformat_input_t *i = vam->input;
19799   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
19800   u32 sw_if_index = ~0, vtr_op = ~0;
19801   u16 outer_tag = ~0;
19802   u8 dmac[6], smac[6];
19803   u8 dmac_set = 0, smac_set = 0;
19804   u16 vlanid = 0;
19805   u32 sid = ~0;
19806   u32 tmp;
19807   int ret;
19808
19809   /* Shut up coverity */
19810   clib_memset (dmac, 0, sizeof (dmac));
19811   clib_memset (smac, 0, sizeof (smac));
19812
19813   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19814     {
19815       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19816         ;
19817       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19818         ;
19819       else if (unformat (i, "vtr_op %d", &vtr_op))
19820         ;
19821 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
19822       foreach_pbb_vtr_op
19823 #undef _
19824         else if (unformat (i, "translate_pbb_stag"))
19825         {
19826           if (unformat (i, "%d", &tmp))
19827             {
19828               vtr_op = L2_VTR_TRANSLATE_2_1;
19829               outer_tag = tmp;
19830             }
19831           else
19832             {
19833               errmsg
19834                 ("translate_pbb_stag operation requires outer tag definition");
19835               return -99;
19836             }
19837         }
19838       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
19839         dmac_set++;
19840       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
19841         smac_set++;
19842       else if (unformat (i, "sid %d", &sid))
19843         ;
19844       else if (unformat (i, "vlanid %d", &tmp))
19845         vlanid = tmp;
19846       else
19847         {
19848           clib_warning ("parse error '%U'", format_unformat_error, i);
19849           return -99;
19850         }
19851     }
19852
19853   if ((sw_if_index == ~0) || (vtr_op == ~0))
19854     {
19855       errmsg ("missing sw_if_index or vtr operation");
19856       return -99;
19857     }
19858   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
19859       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
19860     {
19861       errmsg
19862         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
19863       return -99;
19864     }
19865
19866   M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
19867   mp->sw_if_index = ntohl (sw_if_index);
19868   mp->vtr_op = ntohl (vtr_op);
19869   mp->outer_tag = ntohs (outer_tag);
19870   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
19871   clib_memcpy (mp->b_smac, smac, sizeof (smac));
19872   mp->b_vlanid = ntohs (vlanid);
19873   mp->i_sid = ntohl (sid);
19874
19875   S (mp);
19876   W (ret);
19877   return ret;
19878 }
19879
19880 static int
19881 api_flow_classify_set_interface (vat_main_t * vam)
19882 {
19883   unformat_input_t *i = vam->input;
19884   vl_api_flow_classify_set_interface_t *mp;
19885   u32 sw_if_index;
19886   int sw_if_index_set;
19887   u32 ip4_table_index = ~0;
19888   u32 ip6_table_index = ~0;
19889   u8 is_add = 1;
19890   int ret;
19891
19892   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19893     {
19894       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19895         sw_if_index_set = 1;
19896       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19897         sw_if_index_set = 1;
19898       else if (unformat (i, "del"))
19899         is_add = 0;
19900       else if (unformat (i, "ip4-table %d", &ip4_table_index))
19901         ;
19902       else if (unformat (i, "ip6-table %d", &ip6_table_index))
19903         ;
19904       else
19905         {
19906           clib_warning ("parse error '%U'", format_unformat_error, i);
19907           return -99;
19908         }
19909     }
19910
19911   if (sw_if_index_set == 0)
19912     {
19913       errmsg ("missing interface name or sw_if_index");
19914       return -99;
19915     }
19916
19917   M (FLOW_CLASSIFY_SET_INTERFACE, mp);
19918
19919   mp->sw_if_index = ntohl (sw_if_index);
19920   mp->ip4_table_index = ntohl (ip4_table_index);
19921   mp->ip6_table_index = ntohl (ip6_table_index);
19922   mp->is_add = is_add;
19923
19924   S (mp);
19925   W (ret);
19926   return ret;
19927 }
19928
19929 static int
19930 api_flow_classify_dump (vat_main_t * vam)
19931 {
19932   unformat_input_t *i = vam->input;
19933   vl_api_flow_classify_dump_t *mp;
19934   vl_api_control_ping_t *mp_ping;
19935   u8 type = FLOW_CLASSIFY_N_TABLES;
19936   int ret;
19937
19938   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
19939     ;
19940   else
19941     {
19942       errmsg ("classify table type must be specified");
19943       return -99;
19944     }
19945
19946   if (!vam->json_output)
19947     {
19948       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
19949     }
19950
19951   M (FLOW_CLASSIFY_DUMP, mp);
19952   mp->type = type;
19953   /* send it... */
19954   S (mp);
19955
19956   /* Use a control ping for synchronization */
19957   MPING (CONTROL_PING, mp_ping);
19958   S (mp_ping);
19959
19960   /* Wait for a reply... */
19961   W (ret);
19962   return ret;
19963 }
19964
19965 static int
19966 api_feature_enable_disable (vat_main_t * vam)
19967 {
19968   unformat_input_t *i = vam->input;
19969   vl_api_feature_enable_disable_t *mp;
19970   u8 *arc_name = 0;
19971   u8 *feature_name = 0;
19972   u32 sw_if_index = ~0;
19973   u8 enable = 1;
19974   int ret;
19975
19976   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19977     {
19978       if (unformat (i, "arc_name %s", &arc_name))
19979         ;
19980       else if (unformat (i, "feature_name %s", &feature_name))
19981         ;
19982       else
19983         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19984         ;
19985       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19986         ;
19987       else if (unformat (i, "disable"))
19988         enable = 0;
19989       else
19990         break;
19991     }
19992
19993   if (arc_name == 0)
19994     {
19995       errmsg ("missing arc name");
19996       return -99;
19997     }
19998   if (vec_len (arc_name) > 63)
19999     {
20000       errmsg ("arc name too long");
20001     }
20002
20003   if (feature_name == 0)
20004     {
20005       errmsg ("missing feature name");
20006       return -99;
20007     }
20008   if (vec_len (feature_name) > 63)
20009     {
20010       errmsg ("feature name too long");
20011     }
20012
20013   if (sw_if_index == ~0)
20014     {
20015       errmsg ("missing interface name or sw_if_index");
20016       return -99;
20017     }
20018
20019   /* Construct the API message */
20020   M (FEATURE_ENABLE_DISABLE, mp);
20021   mp->sw_if_index = ntohl (sw_if_index);
20022   mp->enable = enable;
20023   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
20024   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
20025   vec_free (arc_name);
20026   vec_free (feature_name);
20027
20028   S (mp);
20029   W (ret);
20030   return ret;
20031 }
20032
20033 static int
20034 api_feature_gso_enable_disable (vat_main_t * vam)
20035 {
20036   unformat_input_t *i = vam->input;
20037   vl_api_feature_gso_enable_disable_t *mp;
20038   u32 sw_if_index = ~0;
20039   u8 enable = 1;
20040   int ret;
20041
20042   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20043     {
20044       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20045         ;
20046       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20047         ;
20048       else if (unformat (i, "enable"))
20049         enable = 1;
20050       else if (unformat (i, "disable"))
20051         enable = 0;
20052       else
20053         break;
20054     }
20055
20056   if (sw_if_index == ~0)
20057     {
20058       errmsg ("missing interface name or sw_if_index");
20059       return -99;
20060     }
20061
20062   /* Construct the API message */
20063   M (FEATURE_GSO_ENABLE_DISABLE, mp);
20064   mp->sw_if_index = ntohl (sw_if_index);
20065   mp->enable_disable = enable;
20066
20067   S (mp);
20068   W (ret);
20069   return ret;
20070 }
20071
20072 static int
20073 api_sw_interface_tag_add_del (vat_main_t * vam)
20074 {
20075   unformat_input_t *i = vam->input;
20076   vl_api_sw_interface_tag_add_del_t *mp;
20077   u32 sw_if_index = ~0;
20078   u8 *tag = 0;
20079   u8 enable = 1;
20080   int ret;
20081
20082   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20083     {
20084       if (unformat (i, "tag %s", &tag))
20085         ;
20086       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20087         ;
20088       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20089         ;
20090       else if (unformat (i, "del"))
20091         enable = 0;
20092       else
20093         break;
20094     }
20095
20096   if (sw_if_index == ~0)
20097     {
20098       errmsg ("missing interface name or sw_if_index");
20099       return -99;
20100     }
20101
20102   if (enable && (tag == 0))
20103     {
20104       errmsg ("no tag specified");
20105       return -99;
20106     }
20107
20108   /* Construct the API message */
20109   M (SW_INTERFACE_TAG_ADD_DEL, mp);
20110   mp->sw_if_index = ntohl (sw_if_index);
20111   mp->is_add = enable;
20112   if (enable)
20113     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
20114   vec_free (tag);
20115
20116   S (mp);
20117   W (ret);
20118   return ret;
20119 }
20120
20121 static int
20122 api_sw_interface_add_del_mac_address (vat_main_t * vam)
20123 {
20124   unformat_input_t *i = vam->input;
20125   vl_api_mac_address_t mac = { 0 };
20126   vl_api_sw_interface_add_del_mac_address_t *mp;
20127   u32 sw_if_index = ~0;
20128   u8 is_add = 1;
20129   u8 mac_set = 0;
20130   int ret;
20131
20132   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20133     {
20134       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20135         ;
20136       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20137         ;
20138       else if (unformat (i, "%U", unformat_vl_api_mac_address, &mac))
20139         mac_set++;
20140       else if (unformat (i, "del"))
20141         is_add = 0;
20142       else
20143         break;
20144     }
20145
20146   if (sw_if_index == ~0)
20147     {
20148       errmsg ("missing interface name or sw_if_index");
20149       return -99;
20150     }
20151
20152   if (!mac_set)
20153     {
20154       errmsg ("missing MAC address");
20155       return -99;
20156     }
20157
20158   /* Construct the API message */
20159   M (SW_INTERFACE_ADD_DEL_MAC_ADDRESS, mp);
20160   mp->sw_if_index = ntohl (sw_if_index);
20161   mp->is_add = is_add;
20162   clib_memcpy (&mp->addr, &mac, sizeof (mac));
20163
20164   S (mp);
20165   W (ret);
20166   return ret;
20167 }
20168
20169 static void vl_api_l2_xconnect_details_t_handler
20170   (vl_api_l2_xconnect_details_t * mp)
20171 {
20172   vat_main_t *vam = &vat_main;
20173
20174   print (vam->ofp, "%15d%15d",
20175          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
20176 }
20177
20178 static void vl_api_l2_xconnect_details_t_handler_json
20179   (vl_api_l2_xconnect_details_t * mp)
20180 {
20181   vat_main_t *vam = &vat_main;
20182   vat_json_node_t *node = NULL;
20183
20184   if (VAT_JSON_ARRAY != vam->json_tree.type)
20185     {
20186       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20187       vat_json_init_array (&vam->json_tree);
20188     }
20189   node = vat_json_array_add (&vam->json_tree);
20190
20191   vat_json_init_object (node);
20192   vat_json_object_add_uint (node, "rx_sw_if_index",
20193                             ntohl (mp->rx_sw_if_index));
20194   vat_json_object_add_uint (node, "tx_sw_if_index",
20195                             ntohl (mp->tx_sw_if_index));
20196 }
20197
20198 static int
20199 api_l2_xconnect_dump (vat_main_t * vam)
20200 {
20201   vl_api_l2_xconnect_dump_t *mp;
20202   vl_api_control_ping_t *mp_ping;
20203   int ret;
20204
20205   if (!vam->json_output)
20206     {
20207       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
20208     }
20209
20210   M (L2_XCONNECT_DUMP, mp);
20211
20212   S (mp);
20213
20214   /* Use a control ping for synchronization */
20215   MPING (CONTROL_PING, mp_ping);
20216   S (mp_ping);
20217
20218   W (ret);
20219   return ret;
20220 }
20221
20222 static int
20223 api_hw_interface_set_mtu (vat_main_t * vam)
20224 {
20225   unformat_input_t *i = vam->input;
20226   vl_api_hw_interface_set_mtu_t *mp;
20227   u32 sw_if_index = ~0;
20228   u32 mtu = 0;
20229   int ret;
20230
20231   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20232     {
20233       if (unformat (i, "mtu %d", &mtu))
20234         ;
20235       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20236         ;
20237       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20238         ;
20239       else
20240         break;
20241     }
20242
20243   if (sw_if_index == ~0)
20244     {
20245       errmsg ("missing interface name or sw_if_index");
20246       return -99;
20247     }
20248
20249   if (mtu == 0)
20250     {
20251       errmsg ("no mtu specified");
20252       return -99;
20253     }
20254
20255   /* Construct the API message */
20256   M (HW_INTERFACE_SET_MTU, mp);
20257   mp->sw_if_index = ntohl (sw_if_index);
20258   mp->mtu = ntohs ((u16) mtu);
20259
20260   S (mp);
20261   W (ret);
20262   return ret;
20263 }
20264
20265 static int
20266 api_p2p_ethernet_add (vat_main_t * vam)
20267 {
20268   unformat_input_t *i = vam->input;
20269   vl_api_p2p_ethernet_add_t *mp;
20270   u32 parent_if_index = ~0;
20271   u32 sub_id = ~0;
20272   u8 remote_mac[6];
20273   u8 mac_set = 0;
20274   int ret;
20275
20276   clib_memset (remote_mac, 0, sizeof (remote_mac));
20277   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20278     {
20279       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
20280         ;
20281       else if (unformat (i, "sw_if_index %d", &parent_if_index))
20282         ;
20283       else
20284         if (unformat
20285             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
20286         mac_set++;
20287       else if (unformat (i, "sub_id %d", &sub_id))
20288         ;
20289       else
20290         {
20291           clib_warning ("parse error '%U'", format_unformat_error, i);
20292           return -99;
20293         }
20294     }
20295
20296   if (parent_if_index == ~0)
20297     {
20298       errmsg ("missing interface name or sw_if_index");
20299       return -99;
20300     }
20301   if (mac_set == 0)
20302     {
20303       errmsg ("missing remote mac address");
20304       return -99;
20305     }
20306   if (sub_id == ~0)
20307     {
20308       errmsg ("missing sub-interface id");
20309       return -99;
20310     }
20311
20312   M (P2P_ETHERNET_ADD, mp);
20313   mp->parent_if_index = ntohl (parent_if_index);
20314   mp->subif_id = ntohl (sub_id);
20315   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
20316
20317   S (mp);
20318   W (ret);
20319   return ret;
20320 }
20321
20322 static int
20323 api_p2p_ethernet_del (vat_main_t * vam)
20324 {
20325   unformat_input_t *i = vam->input;
20326   vl_api_p2p_ethernet_del_t *mp;
20327   u32 parent_if_index = ~0;
20328   u8 remote_mac[6];
20329   u8 mac_set = 0;
20330   int ret;
20331
20332   clib_memset (remote_mac, 0, sizeof (remote_mac));
20333   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20334     {
20335       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
20336         ;
20337       else if (unformat (i, "sw_if_index %d", &parent_if_index))
20338         ;
20339       else
20340         if (unformat
20341             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
20342         mac_set++;
20343       else
20344         {
20345           clib_warning ("parse error '%U'", format_unformat_error, i);
20346           return -99;
20347         }
20348     }
20349
20350   if (parent_if_index == ~0)
20351     {
20352       errmsg ("missing interface name or sw_if_index");
20353       return -99;
20354     }
20355   if (mac_set == 0)
20356     {
20357       errmsg ("missing remote mac address");
20358       return -99;
20359     }
20360
20361   M (P2P_ETHERNET_DEL, mp);
20362   mp->parent_if_index = ntohl (parent_if_index);
20363   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
20364
20365   S (mp);
20366   W (ret);
20367   return ret;
20368 }
20369
20370 static int
20371 api_lldp_config (vat_main_t * vam)
20372 {
20373   unformat_input_t *i = vam->input;
20374   vl_api_lldp_config_t *mp;
20375   int tx_hold = 0;
20376   int tx_interval = 0;
20377   u8 *sys_name = NULL;
20378   int ret;
20379
20380   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20381     {
20382       if (unformat (i, "system-name %s", &sys_name))
20383         ;
20384       else if (unformat (i, "tx-hold %d", &tx_hold))
20385         ;
20386       else if (unformat (i, "tx-interval %d", &tx_interval))
20387         ;
20388       else
20389         {
20390           clib_warning ("parse error '%U'", format_unformat_error, i);
20391           return -99;
20392         }
20393     }
20394
20395   vec_add1 (sys_name, 0);
20396
20397   M (LLDP_CONFIG, mp);
20398   mp->tx_hold = htonl (tx_hold);
20399   mp->tx_interval = htonl (tx_interval);
20400   clib_memcpy (mp->system_name, sys_name, vec_len (sys_name));
20401   vec_free (sys_name);
20402
20403   S (mp);
20404   W (ret);
20405   return ret;
20406 }
20407
20408 static int
20409 api_sw_interface_set_lldp (vat_main_t * vam)
20410 {
20411   unformat_input_t *i = vam->input;
20412   vl_api_sw_interface_set_lldp_t *mp;
20413   u32 sw_if_index = ~0;
20414   u32 enable = 1;
20415   u8 *port_desc = NULL, *mgmt_oid = NULL;
20416   ip4_address_t ip4_addr;
20417   ip6_address_t ip6_addr;
20418   int ret;
20419
20420   clib_memset (&ip4_addr, 0, sizeof (ip4_addr));
20421   clib_memset (&ip6_addr, 0, sizeof (ip6_addr));
20422
20423   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20424     {
20425       if (unformat (i, "disable"))
20426         enable = 0;
20427       else
20428         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20429         ;
20430       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20431         ;
20432       else if (unformat (i, "port-desc %s", &port_desc))
20433         ;
20434       else if (unformat (i, "mgmt-ip4 %U", unformat_ip4_address, &ip4_addr))
20435         ;
20436       else if (unformat (i, "mgmt-ip6 %U", unformat_ip6_address, &ip6_addr))
20437         ;
20438       else if (unformat (i, "mgmt-oid %s", &mgmt_oid))
20439         ;
20440       else
20441         break;
20442     }
20443
20444   if (sw_if_index == ~0)
20445     {
20446       errmsg ("missing interface name or sw_if_index");
20447       return -99;
20448     }
20449
20450   /* Construct the API message */
20451   vec_add1 (port_desc, 0);
20452   vec_add1 (mgmt_oid, 0);
20453   M (SW_INTERFACE_SET_LLDP, mp);
20454   mp->sw_if_index = ntohl (sw_if_index);
20455   mp->enable = enable;
20456   clib_memcpy (mp->port_desc, port_desc, vec_len (port_desc));
20457   clib_memcpy (mp->mgmt_oid, mgmt_oid, vec_len (mgmt_oid));
20458   clib_memcpy (mp->mgmt_ip4, &ip4_addr, sizeof (ip4_addr));
20459   clib_memcpy (mp->mgmt_ip6, &ip6_addr, sizeof (ip6_addr));
20460   vec_free (port_desc);
20461   vec_free (mgmt_oid);
20462
20463   S (mp);
20464   W (ret);
20465   return ret;
20466 }
20467
20468 static int
20469 api_tcp_configure_src_addresses (vat_main_t * vam)
20470 {
20471   vl_api_tcp_configure_src_addresses_t *mp;
20472   unformat_input_t *i = vam->input;
20473   ip4_address_t v4first, v4last;
20474   ip6_address_t v6first, v6last;
20475   u8 range_set = 0;
20476   u32 vrf_id = 0;
20477   int ret;
20478
20479   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20480     {
20481       if (unformat (i, "%U - %U",
20482                     unformat_ip4_address, &v4first,
20483                     unformat_ip4_address, &v4last))
20484         {
20485           if (range_set)
20486             {
20487               errmsg ("one range per message (range already set)");
20488               return -99;
20489             }
20490           range_set = 1;
20491         }
20492       else if (unformat (i, "%U - %U",
20493                          unformat_ip6_address, &v6first,
20494                          unformat_ip6_address, &v6last))
20495         {
20496           if (range_set)
20497             {
20498               errmsg ("one range per message (range already set)");
20499               return -99;
20500             }
20501           range_set = 2;
20502         }
20503       else if (unformat (i, "vrf %d", &vrf_id))
20504         ;
20505       else
20506         break;
20507     }
20508
20509   if (range_set == 0)
20510     {
20511       errmsg ("address range not set");
20512       return -99;
20513     }
20514
20515   M (TCP_CONFIGURE_SRC_ADDRESSES, mp);
20516   mp->vrf_id = ntohl (vrf_id);
20517   /* ipv6? */
20518   if (range_set == 2)
20519     {
20520       mp->is_ipv6 = 1;
20521       clib_memcpy (mp->first_address, &v6first, sizeof (v6first));
20522       clib_memcpy (mp->last_address, &v6last, sizeof (v6last));
20523     }
20524   else
20525     {
20526       mp->is_ipv6 = 0;
20527       clib_memcpy (mp->first_address, &v4first, sizeof (v4first));
20528       clib_memcpy (mp->last_address, &v4last, sizeof (v4last));
20529     }
20530   S (mp);
20531   W (ret);
20532   return ret;
20533 }
20534
20535 static void vl_api_app_namespace_add_del_reply_t_handler
20536   (vl_api_app_namespace_add_del_reply_t * mp)
20537 {
20538   vat_main_t *vam = &vat_main;
20539   i32 retval = ntohl (mp->retval);
20540   if (vam->async_mode)
20541     {
20542       vam->async_errors += (retval < 0);
20543     }
20544   else
20545     {
20546       vam->retval = retval;
20547       if (retval == 0)
20548         errmsg ("app ns index %d\n", ntohl (mp->appns_index));
20549       vam->result_ready = 1;
20550     }
20551 }
20552
20553 static void vl_api_app_namespace_add_del_reply_t_handler_json
20554   (vl_api_app_namespace_add_del_reply_t * mp)
20555 {
20556   vat_main_t *vam = &vat_main;
20557   vat_json_node_t node;
20558
20559   vat_json_init_object (&node);
20560   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
20561   vat_json_object_add_uint (&node, "appns_index", ntohl (mp->appns_index));
20562
20563   vat_json_print (vam->ofp, &node);
20564   vat_json_free (&node);
20565
20566   vam->retval = ntohl (mp->retval);
20567   vam->result_ready = 1;
20568 }
20569
20570 static int
20571 api_app_namespace_add_del (vat_main_t * vam)
20572 {
20573   vl_api_app_namespace_add_del_t *mp;
20574   unformat_input_t *i = vam->input;
20575   u8 *ns_id = 0, secret_set = 0, sw_if_index_set = 0;
20576   u32 sw_if_index, ip4_fib_id, ip6_fib_id;
20577   u64 secret;
20578   int ret;
20579
20580   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20581     {
20582       if (unformat (i, "id %_%v%_", &ns_id))
20583         ;
20584       else if (unformat (i, "secret %lu", &secret))
20585         secret_set = 1;
20586       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20587         sw_if_index_set = 1;
20588       else if (unformat (i, "ip4_fib_id %d", &ip4_fib_id))
20589         ;
20590       else if (unformat (i, "ip6_fib_id %d", &ip6_fib_id))
20591         ;
20592       else
20593         break;
20594     }
20595   if (!ns_id || !secret_set || !sw_if_index_set)
20596     {
20597       errmsg ("namespace id, secret and sw_if_index must be set");
20598       return -99;
20599     }
20600   if (vec_len (ns_id) > 64)
20601     {
20602       errmsg ("namespace id too long");
20603       return -99;
20604     }
20605   M (APP_NAMESPACE_ADD_DEL, mp);
20606
20607   clib_memcpy (mp->namespace_id, ns_id, vec_len (ns_id));
20608   mp->namespace_id_len = vec_len (ns_id);
20609   mp->secret = clib_host_to_net_u64 (secret);
20610   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
20611   mp->ip4_fib_id = clib_host_to_net_u32 (ip4_fib_id);
20612   mp->ip6_fib_id = clib_host_to_net_u32 (ip6_fib_id);
20613   vec_free (ns_id);
20614   S (mp);
20615   W (ret);
20616   return ret;
20617 }
20618
20619 static int
20620 api_sock_init_shm (vat_main_t * vam)
20621 {
20622 #if VPP_API_TEST_BUILTIN == 0
20623   unformat_input_t *i = vam->input;
20624   vl_api_shm_elem_config_t *config = 0;
20625   u64 size = 64 << 20;
20626   int rv;
20627
20628   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20629     {
20630       if (unformat (i, "size %U", unformat_memory_size, &size))
20631         ;
20632       else
20633         break;
20634     }
20635
20636   /*
20637    * Canned custom ring allocator config.
20638    * Should probably parse all of this
20639    */
20640   vec_validate (config, 6);
20641   config[0].type = VL_API_VLIB_RING;
20642   config[0].size = 256;
20643   config[0].count = 32;
20644
20645   config[1].type = VL_API_VLIB_RING;
20646   config[1].size = 1024;
20647   config[1].count = 16;
20648
20649   config[2].type = VL_API_VLIB_RING;
20650   config[2].size = 4096;
20651   config[2].count = 2;
20652
20653   config[3].type = VL_API_CLIENT_RING;
20654   config[3].size = 256;
20655   config[3].count = 32;
20656
20657   config[4].type = VL_API_CLIENT_RING;
20658   config[4].size = 1024;
20659   config[4].count = 16;
20660
20661   config[5].type = VL_API_CLIENT_RING;
20662   config[5].size = 4096;
20663   config[5].count = 2;
20664
20665   config[6].type = VL_API_QUEUE;
20666   config[6].count = 128;
20667   config[6].size = sizeof (uword);
20668
20669   rv = vl_socket_client_init_shm (config, 1 /* want_pthread */ );
20670   if (!rv)
20671     vam->client_index_invalid = 1;
20672   return rv;
20673 #else
20674   return -99;
20675 #endif
20676 }
20677
20678 static void
20679 vl_api_session_rules_details_t_handler (vl_api_session_rules_details_t * mp)
20680 {
20681   vat_main_t *vam = &vat_main;
20682
20683   if (mp->is_ip4)
20684     {
20685       print (vam->ofp,
20686              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
20687              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
20688              mp->scope, format_ip4_address, &mp->lcl_ip, mp->lcl_plen,
20689              clib_net_to_host_u16 (mp->lcl_port), format_ip4_address,
20690              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
20691              clib_net_to_host_u32 (mp->action_index), mp->tag);
20692     }
20693   else
20694     {
20695       print (vam->ofp,
20696              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
20697              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
20698              mp->scope, format_ip6_address, &mp->lcl_ip, mp->lcl_plen,
20699              clib_net_to_host_u16 (mp->lcl_port), format_ip6_address,
20700              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
20701              clib_net_to_host_u32 (mp->action_index), mp->tag);
20702     }
20703 }
20704
20705 static void
20706 vl_api_session_rules_details_t_handler_json (vl_api_session_rules_details_t *
20707                                              mp)
20708 {
20709   vat_main_t *vam = &vat_main;
20710   vat_json_node_t *node = NULL;
20711   struct in6_addr ip6;
20712   struct in_addr ip4;
20713
20714   if (VAT_JSON_ARRAY != vam->json_tree.type)
20715     {
20716       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
20717       vat_json_init_array (&vam->json_tree);
20718     }
20719   node = vat_json_array_add (&vam->json_tree);
20720   vat_json_init_object (node);
20721
20722   vat_json_object_add_uint (node, "is_ip4", mp->is_ip4 ? 1 : 0);
20723   vat_json_object_add_uint (node, "appns_index",
20724                             clib_net_to_host_u32 (mp->appns_index));
20725   vat_json_object_add_uint (node, "transport_proto", mp->transport_proto);
20726   vat_json_object_add_uint (node, "scope", mp->scope);
20727   vat_json_object_add_uint (node, "action_index",
20728                             clib_net_to_host_u32 (mp->action_index));
20729   vat_json_object_add_uint (node, "lcl_port",
20730                             clib_net_to_host_u16 (mp->lcl_port));
20731   vat_json_object_add_uint (node, "rmt_port",
20732                             clib_net_to_host_u16 (mp->rmt_port));
20733   vat_json_object_add_uint (node, "lcl_plen", mp->lcl_plen);
20734   vat_json_object_add_uint (node, "rmt_plen", mp->rmt_plen);
20735   vat_json_object_add_string_copy (node, "tag", mp->tag);
20736   if (mp->is_ip4)
20737     {
20738       clib_memcpy (&ip4, mp->lcl_ip, sizeof (ip4));
20739       vat_json_object_add_ip4 (node, "lcl_ip", ip4);
20740       clib_memcpy (&ip4, mp->rmt_ip, sizeof (ip4));
20741       vat_json_object_add_ip4 (node, "rmt_ip", ip4);
20742     }
20743   else
20744     {
20745       clib_memcpy (&ip6, mp->lcl_ip, sizeof (ip6));
20746       vat_json_object_add_ip6 (node, "lcl_ip", ip6);
20747       clib_memcpy (&ip6, mp->rmt_ip, sizeof (ip6));
20748       vat_json_object_add_ip6 (node, "rmt_ip", ip6);
20749     }
20750 }
20751
20752 static int
20753 api_session_rule_add_del (vat_main_t * vam)
20754 {
20755   vl_api_session_rule_add_del_t *mp;
20756   unformat_input_t *i = vam->input;
20757   u32 proto = ~0, lcl_port, rmt_port, action = 0, lcl_plen, rmt_plen;
20758   u32 appns_index = 0, scope = 0;
20759   ip4_address_t lcl_ip4, rmt_ip4;
20760   ip6_address_t lcl_ip6, rmt_ip6;
20761   u8 is_ip4 = 1, conn_set = 0;
20762   u8 is_add = 1, *tag = 0;
20763   int ret;
20764
20765   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20766     {
20767       if (unformat (i, "del"))
20768         is_add = 0;
20769       else if (unformat (i, "add"))
20770         ;
20771       else if (unformat (i, "proto tcp"))
20772         proto = 0;
20773       else if (unformat (i, "proto udp"))
20774         proto = 1;
20775       else if (unformat (i, "appns %d", &appns_index))
20776         ;
20777       else if (unformat (i, "scope %d", &scope))
20778         ;
20779       else if (unformat (i, "tag %_%v%_", &tag))
20780         ;
20781       else
20782         if (unformat
20783             (i, "%U/%d %d %U/%d %d", unformat_ip4_address, &lcl_ip4,
20784              &lcl_plen, &lcl_port, unformat_ip4_address, &rmt_ip4, &rmt_plen,
20785              &rmt_port))
20786         {
20787           is_ip4 = 1;
20788           conn_set = 1;
20789         }
20790       else
20791         if (unformat
20792             (i, "%U/%d %d %U/%d %d", unformat_ip6_address, &lcl_ip6,
20793              &lcl_plen, &lcl_port, unformat_ip6_address, &rmt_ip6, &rmt_plen,
20794              &rmt_port))
20795         {
20796           is_ip4 = 0;
20797           conn_set = 1;
20798         }
20799       else if (unformat (i, "action %d", &action))
20800         ;
20801       else
20802         break;
20803     }
20804   if (proto == ~0 || !conn_set || action == ~0)
20805     {
20806       errmsg ("transport proto, connection and action must be set");
20807       return -99;
20808     }
20809
20810   if (scope > 3)
20811     {
20812       errmsg ("scope should be 0-3");
20813       return -99;
20814     }
20815
20816   M (SESSION_RULE_ADD_DEL, mp);
20817
20818   mp->is_ip4 = is_ip4;
20819   mp->transport_proto = proto;
20820   mp->lcl_port = clib_host_to_net_u16 ((u16) lcl_port);
20821   mp->rmt_port = clib_host_to_net_u16 ((u16) rmt_port);
20822   mp->lcl_plen = lcl_plen;
20823   mp->rmt_plen = rmt_plen;
20824   mp->action_index = clib_host_to_net_u32 (action);
20825   mp->appns_index = clib_host_to_net_u32 (appns_index);
20826   mp->scope = scope;
20827   mp->is_add = is_add;
20828   if (is_ip4)
20829     {
20830       clib_memcpy (mp->lcl_ip, &lcl_ip4, sizeof (lcl_ip4));
20831       clib_memcpy (mp->rmt_ip, &rmt_ip4, sizeof (rmt_ip4));
20832     }
20833   else
20834     {
20835       clib_memcpy (mp->lcl_ip, &lcl_ip6, sizeof (lcl_ip6));
20836       clib_memcpy (mp->rmt_ip, &rmt_ip6, sizeof (rmt_ip6));
20837     }
20838   if (tag)
20839     {
20840       clib_memcpy (mp->tag, tag, vec_len (tag));
20841       vec_free (tag);
20842     }
20843
20844   S (mp);
20845   W (ret);
20846   return ret;
20847 }
20848
20849 static int
20850 api_session_rules_dump (vat_main_t * vam)
20851 {
20852   vl_api_session_rules_dump_t *mp;
20853   vl_api_control_ping_t *mp_ping;
20854   int ret;
20855
20856   if (!vam->json_output)
20857     {
20858       print (vam->ofp, "%=20s", "Session Rules");
20859     }
20860
20861   M (SESSION_RULES_DUMP, mp);
20862   /* send it... */
20863   S (mp);
20864
20865   /* Use a control ping for synchronization */
20866   MPING (CONTROL_PING, mp_ping);
20867   S (mp_ping);
20868
20869   /* Wait for a reply... */
20870   W (ret);
20871   return ret;
20872 }
20873
20874 static int
20875 api_ip_container_proxy_add_del (vat_main_t * vam)
20876 {
20877   vl_api_ip_container_proxy_add_del_t *mp;
20878   unformat_input_t *i = vam->input;
20879   u32 sw_if_index = ~0;
20880   vl_api_prefix_t pfx = { };
20881   u8 is_add = 1;
20882   int ret;
20883
20884   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20885     {
20886       if (unformat (i, "del"))
20887         is_add = 0;
20888       else if (unformat (i, "add"))
20889         ;
20890       if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
20891         ;
20892       else if (unformat (i, "sw_if_index %u", &sw_if_index))
20893         ;
20894       else
20895         break;
20896     }
20897   if (sw_if_index == ~0 || pfx.len == 0)
20898     {
20899       errmsg ("address and sw_if_index must be set");
20900       return -99;
20901     }
20902
20903   M (IP_CONTAINER_PROXY_ADD_DEL, mp);
20904
20905   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
20906   mp->is_add = is_add;
20907   clib_memcpy (&mp->pfx, &pfx, sizeof (pfx));
20908
20909   S (mp);
20910   W (ret);
20911   return ret;
20912 }
20913
20914 static int
20915 api_qos_record_enable_disable (vat_main_t * vam)
20916 {
20917   unformat_input_t *i = vam->input;
20918   vl_api_qos_record_enable_disable_t *mp;
20919   u32 sw_if_index, qs = 0xff;
20920   u8 sw_if_index_set = 0;
20921   u8 enable = 1;
20922   int ret;
20923
20924   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20925     {
20926       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20927         sw_if_index_set = 1;
20928       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20929         sw_if_index_set = 1;
20930       else if (unformat (i, "%U", unformat_qos_source, &qs))
20931         ;
20932       else if (unformat (i, "disable"))
20933         enable = 0;
20934       else
20935         {
20936           clib_warning ("parse error '%U'", format_unformat_error, i);
20937           return -99;
20938         }
20939     }
20940
20941   if (sw_if_index_set == 0)
20942     {
20943       errmsg ("missing interface name or sw_if_index");
20944       return -99;
20945     }
20946   if (qs == 0xff)
20947     {
20948       errmsg ("input location must be specified");
20949       return -99;
20950     }
20951
20952   M (QOS_RECORD_ENABLE_DISABLE, mp);
20953
20954   mp->record.sw_if_index = ntohl (sw_if_index);
20955   mp->record.input_source = qs;
20956   mp->enable = enable;
20957
20958   S (mp);
20959   W (ret);
20960   return ret;
20961 }
20962
20963
20964 static int
20965 q_or_quit (vat_main_t * vam)
20966 {
20967 #if VPP_API_TEST_BUILTIN == 0
20968   longjmp (vam->jump_buf, 1);
20969 #endif
20970   return 0;                     /* not so much */
20971 }
20972
20973 static int
20974 q (vat_main_t * vam)
20975 {
20976   return q_or_quit (vam);
20977 }
20978
20979 static int
20980 quit (vat_main_t * vam)
20981 {
20982   return q_or_quit (vam);
20983 }
20984
20985 static int
20986 comment (vat_main_t * vam)
20987 {
20988   return 0;
20989 }
20990
20991 static int
20992 elog_save (vat_main_t * vam)
20993 {
20994 #if VPP_API_TEST_BUILTIN == 0
20995   elog_main_t *em = &vam->elog_main;
20996   unformat_input_t *i = vam->input;
20997   char *file, *chroot_file;
20998   clib_error_t *error;
20999
21000   if (!unformat (i, "%s", &file))
21001     {
21002       errmsg ("expected file name, got `%U'", format_unformat_error, i);
21003       return 0;
21004     }
21005
21006   /* It's fairly hard to get "../oopsie" through unformat; just in case */
21007   if (strstr (file, "..") || index (file, '/'))
21008     {
21009       errmsg ("illegal characters in filename '%s'", file);
21010       return 0;
21011     }
21012
21013   chroot_file = (char *) format (0, "/tmp/%s%c", file, 0);
21014
21015   vec_free (file);
21016
21017   errmsg ("Saving %wd of %wd events to %s",
21018           elog_n_events_in_buffer (em),
21019           elog_buffer_capacity (em), chroot_file);
21020
21021   error = elog_write_file (em, chroot_file, 1 /* flush ring */ );
21022   vec_free (chroot_file);
21023
21024   if (error)
21025     clib_error_report (error);
21026 #else
21027   errmsg ("Use the vpp event loger...");
21028 #endif
21029
21030   return 0;
21031 }
21032
21033 static int
21034 elog_setup (vat_main_t * vam)
21035 {
21036 #if VPP_API_TEST_BUILTIN == 0
21037   elog_main_t *em = &vam->elog_main;
21038   unformat_input_t *i = vam->input;
21039   u32 nevents = 128 << 10;
21040
21041   (void) unformat (i, "nevents %d", &nevents);
21042
21043   elog_init (em, nevents);
21044   vl_api_set_elog_main (em);
21045   vl_api_set_elog_trace_api_messages (1);
21046   errmsg ("Event logger initialized with %u events", nevents);
21047 #else
21048   errmsg ("Use the vpp event loger...");
21049 #endif
21050   return 0;
21051 }
21052
21053 static int
21054 elog_enable (vat_main_t * vam)
21055 {
21056 #if VPP_API_TEST_BUILTIN == 0
21057   elog_main_t *em = &vam->elog_main;
21058
21059   elog_enable_disable (em, 1 /* enable */ );
21060   vl_api_set_elog_trace_api_messages (1);
21061   errmsg ("Event logger enabled...");
21062 #else
21063   errmsg ("Use the vpp event loger...");
21064 #endif
21065   return 0;
21066 }
21067
21068 static int
21069 elog_disable (vat_main_t * vam)
21070 {
21071 #if VPP_API_TEST_BUILTIN == 0
21072   elog_main_t *em = &vam->elog_main;
21073
21074   elog_enable_disable (em, 0 /* enable */ );
21075   vl_api_set_elog_trace_api_messages (1);
21076   errmsg ("Event logger disabled...");
21077 #else
21078   errmsg ("Use the vpp event loger...");
21079 #endif
21080   return 0;
21081 }
21082
21083 static int
21084 statseg (vat_main_t * vam)
21085 {
21086   ssvm_private_t *ssvmp = &vam->stat_segment;
21087   ssvm_shared_header_t *shared_header = ssvmp->sh;
21088   vlib_counter_t **counters;
21089   u64 thread0_index1_packets;
21090   u64 thread0_index1_bytes;
21091   f64 vector_rate, input_rate;
21092   uword *p;
21093
21094   uword *counter_vector_by_name;
21095   if (vam->stat_segment_lockp == 0)
21096     {
21097       errmsg ("Stat segment not mapped...");
21098       return -99;
21099     }
21100
21101   /* look up "/if/rx for sw_if_index 1 as a test */
21102
21103   clib_spinlock_lock (vam->stat_segment_lockp);
21104
21105   counter_vector_by_name = (uword *) shared_header->opaque[1];
21106
21107   p = hash_get_mem (counter_vector_by_name, "/if/rx");
21108   if (p == 0)
21109     {
21110       clib_spinlock_unlock (vam->stat_segment_lockp);
21111       errmsg ("/if/tx not found?");
21112       return -99;
21113     }
21114
21115   /* Fish per-thread vector of combined counters from shared memory */
21116   counters = (vlib_counter_t **) p[0];
21117
21118   if (vec_len (counters[0]) < 2)
21119     {
21120       clib_spinlock_unlock (vam->stat_segment_lockp);
21121       errmsg ("/if/tx vector length %d", vec_len (counters[0]));
21122       return -99;
21123     }
21124
21125   /* Read thread 0 sw_if_index 1 counter */
21126   thread0_index1_packets = counters[0][1].packets;
21127   thread0_index1_bytes = counters[0][1].bytes;
21128
21129   p = hash_get_mem (counter_vector_by_name, "vector_rate");
21130   if (p == 0)
21131     {
21132       clib_spinlock_unlock (vam->stat_segment_lockp);
21133       errmsg ("vector_rate not found?");
21134       return -99;
21135     }
21136
21137   vector_rate = *(f64 *) (p[0]);
21138   p = hash_get_mem (counter_vector_by_name, "input_rate");
21139   if (p == 0)
21140     {
21141       clib_spinlock_unlock (vam->stat_segment_lockp);
21142       errmsg ("input_rate not found?");
21143       return -99;
21144     }
21145   input_rate = *(f64 *) (p[0]);
21146
21147   clib_spinlock_unlock (vam->stat_segment_lockp);
21148
21149   print (vam->ofp, "vector_rate %.2f input_rate %.2f",
21150          vector_rate, input_rate);
21151   print (vam->ofp, "thread 0 sw_if_index 1 rx pkts %lld, bytes %lld",
21152          thread0_index1_packets, thread0_index1_bytes);
21153
21154   return 0;
21155 }
21156
21157 static int
21158 cmd_cmp (void *a1, void *a2)
21159 {
21160   u8 **c1 = a1;
21161   u8 **c2 = a2;
21162
21163   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
21164 }
21165
21166 static int
21167 help (vat_main_t * vam)
21168 {
21169   u8 **cmds = 0;
21170   u8 *name = 0;
21171   hash_pair_t *p;
21172   unformat_input_t *i = vam->input;
21173   int j;
21174
21175   if (unformat (i, "%s", &name))
21176     {
21177       uword *hs;
21178
21179       vec_add1 (name, 0);
21180
21181       hs = hash_get_mem (vam->help_by_name, name);
21182       if (hs)
21183         print (vam->ofp, "usage: %s %s", name, hs[0]);
21184       else
21185         print (vam->ofp, "No such msg / command '%s'", name);
21186       vec_free (name);
21187       return 0;
21188     }
21189
21190   print (vam->ofp, "Help is available for the following:");
21191
21192     /* *INDENT-OFF* */
21193     hash_foreach_pair (p, vam->function_by_name,
21194     ({
21195       vec_add1 (cmds, (u8 *)(p->key));
21196     }));
21197     /* *INDENT-ON* */
21198
21199   vec_sort_with_function (cmds, cmd_cmp);
21200
21201   for (j = 0; j < vec_len (cmds); j++)
21202     print (vam->ofp, "%s", cmds[j]);
21203
21204   vec_free (cmds);
21205   return 0;
21206 }
21207
21208 static int
21209 set (vat_main_t * vam)
21210 {
21211   u8 *name = 0, *value = 0;
21212   unformat_input_t *i = vam->input;
21213
21214   if (unformat (i, "%s", &name))
21215     {
21216       /* The input buffer is a vector, not a string. */
21217       value = vec_dup (i->buffer);
21218       vec_delete (value, i->index, 0);
21219       /* Almost certainly has a trailing newline */
21220       if (value[vec_len (value) - 1] == '\n')
21221         value[vec_len (value) - 1] = 0;
21222       /* Make sure it's a proper string, one way or the other */
21223       vec_add1 (value, 0);
21224       (void) clib_macro_set_value (&vam->macro_main,
21225                                    (char *) name, (char *) value);
21226     }
21227   else
21228     errmsg ("usage: set <name> <value>");
21229
21230   vec_free (name);
21231   vec_free (value);
21232   return 0;
21233 }
21234
21235 static int
21236 unset (vat_main_t * vam)
21237 {
21238   u8 *name = 0;
21239
21240   if (unformat (vam->input, "%s", &name))
21241     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
21242       errmsg ("unset: %s wasn't set", name);
21243   vec_free (name);
21244   return 0;
21245 }
21246
21247 typedef struct
21248 {
21249   u8 *name;
21250   u8 *value;
21251 } macro_sort_t;
21252
21253
21254 static int
21255 macro_sort_cmp (void *a1, void *a2)
21256 {
21257   macro_sort_t *s1 = a1;
21258   macro_sort_t *s2 = a2;
21259
21260   return strcmp ((char *) (s1->name), (char *) (s2->name));
21261 }
21262
21263 static int
21264 dump_macro_table (vat_main_t * vam)
21265 {
21266   macro_sort_t *sort_me = 0, *sm;
21267   int i;
21268   hash_pair_t *p;
21269
21270     /* *INDENT-OFF* */
21271     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
21272     ({
21273       vec_add2 (sort_me, sm, 1);
21274       sm->name = (u8 *)(p->key);
21275       sm->value = (u8 *) (p->value[0]);
21276     }));
21277     /* *INDENT-ON* */
21278
21279   vec_sort_with_function (sort_me, macro_sort_cmp);
21280
21281   if (vec_len (sort_me))
21282     print (vam->ofp, "%-15s%s", "Name", "Value");
21283   else
21284     print (vam->ofp, "The macro table is empty...");
21285
21286   for (i = 0; i < vec_len (sort_me); i++)
21287     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
21288   return 0;
21289 }
21290
21291 static int
21292 dump_node_table (vat_main_t * vam)
21293 {
21294   int i, j;
21295   vlib_node_t *node, *next_node;
21296
21297   if (vec_len (vam->graph_nodes) == 0)
21298     {
21299       print (vam->ofp, "Node table empty, issue get_node_graph...");
21300       return 0;
21301     }
21302
21303   for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
21304     {
21305       node = vam->graph_nodes[0][i];
21306       print (vam->ofp, "[%d] %s", i, node->name);
21307       for (j = 0; j < vec_len (node->next_nodes); j++)
21308         {
21309           if (node->next_nodes[j] != ~0)
21310             {
21311               next_node = vam->graph_nodes[0][node->next_nodes[j]];
21312               print (vam->ofp, "  [%d] %s", j, next_node->name);
21313             }
21314         }
21315     }
21316   return 0;
21317 }
21318
21319 static int
21320 value_sort_cmp (void *a1, void *a2)
21321 {
21322   name_sort_t *n1 = a1;
21323   name_sort_t *n2 = a2;
21324
21325   if (n1->value < n2->value)
21326     return -1;
21327   if (n1->value > n2->value)
21328     return 1;
21329   return 0;
21330 }
21331
21332
21333 static int
21334 dump_msg_api_table (vat_main_t * vam)
21335 {
21336   api_main_t *am = &api_main;
21337   name_sort_t *nses = 0, *ns;
21338   hash_pair_t *hp;
21339   int i;
21340
21341   /* *INDENT-OFF* */
21342   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
21343   ({
21344     vec_add2 (nses, ns, 1);
21345     ns->name = (u8 *)(hp->key);
21346     ns->value = (u32) hp->value[0];
21347   }));
21348   /* *INDENT-ON* */
21349
21350   vec_sort_with_function (nses, value_sort_cmp);
21351
21352   for (i = 0; i < vec_len (nses); i++)
21353     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
21354   vec_free (nses);
21355   return 0;
21356 }
21357
21358 static int
21359 get_msg_id (vat_main_t * vam)
21360 {
21361   u8 *name_and_crc;
21362   u32 message_index;
21363
21364   if (unformat (vam->input, "%s", &name_and_crc))
21365     {
21366       message_index = vl_msg_api_get_msg_index (name_and_crc);
21367       if (message_index == ~0)
21368         {
21369           print (vam->ofp, " '%s' not found", name_and_crc);
21370           return 0;
21371         }
21372       print (vam->ofp, " '%s' has message index %d",
21373              name_and_crc, message_index);
21374       return 0;
21375     }
21376   errmsg ("name_and_crc required...");
21377   return 0;
21378 }
21379
21380 static int
21381 search_node_table (vat_main_t * vam)
21382 {
21383   unformat_input_t *line_input = vam->input;
21384   u8 *node_to_find;
21385   int j;
21386   vlib_node_t *node, *next_node;
21387   uword *p;
21388
21389   if (vam->graph_node_index_by_name == 0)
21390     {
21391       print (vam->ofp, "Node table empty, issue get_node_graph...");
21392       return 0;
21393     }
21394
21395   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
21396     {
21397       if (unformat (line_input, "%s", &node_to_find))
21398         {
21399           vec_add1 (node_to_find, 0);
21400           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
21401           if (p == 0)
21402             {
21403               print (vam->ofp, "%s not found...", node_to_find);
21404               goto out;
21405             }
21406           node = vam->graph_nodes[0][p[0]];
21407           print (vam->ofp, "[%d] %s", p[0], node->name);
21408           for (j = 0; j < vec_len (node->next_nodes); j++)
21409             {
21410               if (node->next_nodes[j] != ~0)
21411                 {
21412                   next_node = vam->graph_nodes[0][node->next_nodes[j]];
21413                   print (vam->ofp, "  [%d] %s", j, next_node->name);
21414                 }
21415             }
21416         }
21417
21418       else
21419         {
21420           clib_warning ("parse error '%U'", format_unformat_error,
21421                         line_input);
21422           return -99;
21423         }
21424
21425     out:
21426       vec_free (node_to_find);
21427
21428     }
21429
21430   return 0;
21431 }
21432
21433
21434 static int
21435 script (vat_main_t * vam)
21436 {
21437 #if (VPP_API_TEST_BUILTIN==0)
21438   u8 *s = 0;
21439   char *save_current_file;
21440   unformat_input_t save_input;
21441   jmp_buf save_jump_buf;
21442   u32 save_line_number;
21443
21444   FILE *new_fp, *save_ifp;
21445
21446   if (unformat (vam->input, "%s", &s))
21447     {
21448       new_fp = fopen ((char *) s, "r");
21449       if (new_fp == 0)
21450         {
21451           errmsg ("Couldn't open script file %s", s);
21452           vec_free (s);
21453           return -99;
21454         }
21455     }
21456   else
21457     {
21458       errmsg ("Missing script name");
21459       return -99;
21460     }
21461
21462   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
21463   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
21464   save_ifp = vam->ifp;
21465   save_line_number = vam->input_line_number;
21466   save_current_file = (char *) vam->current_file;
21467
21468   vam->input_line_number = 0;
21469   vam->ifp = new_fp;
21470   vam->current_file = s;
21471   do_one_file (vam);
21472
21473   clib_memcpy (&vam->input, &save_input, sizeof (save_input));
21474   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
21475   vam->ifp = save_ifp;
21476   vam->input_line_number = save_line_number;
21477   vam->current_file = (u8 *) save_current_file;
21478   vec_free (s);
21479
21480   return 0;
21481 #else
21482   clib_warning ("use the exec command...");
21483   return -99;
21484 #endif
21485 }
21486
21487 static int
21488 echo (vat_main_t * vam)
21489 {
21490   print (vam->ofp, "%v", vam->input->buffer);
21491   return 0;
21492 }
21493
21494 /* List of API message constructors, CLI names map to api_xxx */
21495 #define foreach_vpe_api_msg                                             \
21496 _(create_loopback,"[mac <mac-addr>] [instance <instance>]")             \
21497 _(sw_interface_dump,"")                                                 \
21498 _(sw_interface_set_flags,                                               \
21499   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
21500 _(sw_interface_add_del_address,                                         \
21501   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
21502 _(sw_interface_set_rx_mode,                                             \
21503   "<intfc> | sw_if_index <id> [queue <id>] <polling | interrupt | adaptive>") \
21504 _(sw_interface_set_rx_placement,                                        \
21505   "<intfc> | sw_if_index <id> [queue <id>] [worker <id> | main]")       \
21506 _(sw_interface_rx_placement_dump,                                       \
21507   "[<intfc> | sw_if_index <id>]")                                         \
21508 _(sw_interface_set_table,                                               \
21509   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
21510 _(sw_interface_set_mpls_enable,                                         \
21511   "<intfc> | sw_if_index [disable | dis]")                              \
21512 _(sw_interface_set_vpath,                                               \
21513   "<intfc> | sw_if_index <id> enable | disable")                        \
21514 _(sw_interface_set_vxlan_bypass,                                        \
21515   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
21516 _(sw_interface_set_geneve_bypass,                                       \
21517   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
21518 _(sw_interface_set_l2_xconnect,                                         \
21519   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
21520   "enable | disable")                                                   \
21521 _(sw_interface_set_l2_bridge,                                           \
21522   "{<intfc> | sw_if_index <id>} bd_id <bridge-domain-id>\n"             \
21523   "[shg <split-horizon-group>] [bvi]\n"                                 \
21524   "enable | disable")                                                   \
21525 _(bridge_domain_set_mac_age, "bd_id <bridge-domain-id> mac-age 0-255")  \
21526 _(bridge_domain_add_del,                                                \
21527   "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") \
21528 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
21529 _(l2fib_add_del,                                                        \
21530   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
21531 _(l2fib_flush_bd, "bd_id <bridge-domain-id>")                           \
21532 _(l2fib_flush_int, "<intfc> | sw_if_index <id>")                        \
21533 _(l2_flags,                                                             \
21534   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
21535 _(bridge_flags,                                                         \
21536   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
21537 _(tap_create_v2,                                                        \
21538   "id <num> [hw-addr <mac-addr>] [host-ns <name>] [rx-ring-size <num> [tx-ring-size <num>] [host-mtu-size <mtu>] [gso | no-gso]") \
21539 _(tap_delete_v2,                                                        \
21540   "<vpp-if-name> | sw_if_index <id>")                                   \
21541 _(sw_interface_tap_v2_dump, "")                                         \
21542 _(virtio_pci_create,                                                    \
21543   "pci-addr <pci-address> [use_random_mac | hw-addr <mac-addr>] [features <hex-value>] [gso-enabled]") \
21544 _(virtio_pci_delete,                                                    \
21545   "<vpp-if-name> | sw_if_index <id>")                                   \
21546 _(sw_interface_virtio_pci_dump, "")                                     \
21547 _(bond_create,                                                          \
21548   "[hw-addr <mac-addr>] {round-robin | active-backup | "                \
21549   "broadcast | {lacp | xor} [load-balance { l2 | l23 | l34 }]} "        \
21550   "[id <if-id>]")                                                       \
21551 _(bond_delete,                                                          \
21552   "<vpp-if-name> | sw_if_index <id>")                                   \
21553 _(bond_enslave,                                                         \
21554   "sw_if_index <n> bond <sw_if_index> [is_passive] [is_long_timeout]")  \
21555 _(bond_detach_slave,                                                    \
21556   "sw_if_index <n>")                                                    \
21557  _(sw_interface_set_bond_weight, "<intfc> | sw_if_index <nn> weight <value>") \
21558 _(sw_interface_bond_dump, "")                                           \
21559 _(sw_interface_slave_dump,                                              \
21560   "<vpp-if-name> | sw_if_index <id>")                                   \
21561 _(ip_table_add_del,                                                     \
21562   "table <n> [ipv6] [add | del]\n")                                     \
21563 _(ip_route_add_del,                                                     \
21564   "<addr>/<mask> via <<addr>|<intfc>|sw_if_index <id>|via-label <n>>\n" \
21565   "[table-id <n>] [<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"\
21566   "[weight <n>] [drop] [local] [classify <n>]  [out-label <n>]\n"       \
21567   "[multipath] [count <n>] [del]")                                      \
21568 _(ip_mroute_add_del,                                                    \
21569   "<src> <grp>/<mask> [table-id <n>]\n"                                 \
21570   "[<intfc> | sw_if_index <id>] [local] [del]")                         \
21571 _(mpls_table_add_del,                                                   \
21572   "table <n> [add | del]\n")                                            \
21573 _(mpls_route_add_del,                                                   \
21574   "<label> <eos> via <addr | next-hop-table <n> | via-label <n> |\n"    \
21575   "lookup-ip4-table <n> | lookup-in-ip6-table <n> |\n"                  \
21576   "l2-input-on <intfc> | l2-input-on sw_if_index <id>>\n"               \
21577   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>] [weight <n>]\n"  \
21578   "[drop] [local] [classify <n>] [out-label <n>] [multipath]\n"         \
21579   "[count <n>] [del]")                                                  \
21580 _(mpls_ip_bind_unbind,                                                  \
21581   "<label> <addr/len>")                                                 \
21582 _(mpls_tunnel_add_del,                                                  \
21583   "[add | del <intfc | sw_if_index <id>>] via <addr | via-label <n>>\n" \
21584   "[<intfc> | sw_if_index <id> | next-hop-table <id>]\n"                \
21585   "[l2-only]  [out-label <n>]")                                         \
21586 _(sr_mpls_policy_add,                                                   \
21587   "bsid <id> [weight <n>] [spray] next <sid> [next <sid>]")             \
21588 _(sr_mpls_policy_del,                                                   \
21589   "bsid <id>")                                                          \
21590 _(bier_table_add_del,                                                   \
21591   "<label> <sub-domain> <set> <bsl> [del]")                             \
21592 _(bier_route_add_del,                                                   \
21593   "<bit-position> <sub-domain> <set> <bsl> via <addr> [table-id <n>]\n" \
21594   "[<intfc> | sw_if_index <id>]"                                        \
21595   "[weight <n>] [del] [multipath]")                                     \
21596 _(proxy_arp_add_del,                                                    \
21597   "<lo-ip4-addr> - <hi-ip4-addr> [vrf <n>] [del]")                      \
21598 _(proxy_arp_intfc_enable_disable,                                       \
21599   "<intfc> | sw_if_index <id> enable | disable")                        \
21600 _(sw_interface_set_unnumbered,                                          \
21601   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
21602 _(ip_neighbor_add_del,                                                  \
21603   "(<intfc> | sw_if_index <id>) dst <ip46-address> "                    \
21604   "[mac <mac-addr>] [vrf <vrf-id>] [is_static] [del]")                  \
21605 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
21606 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
21607   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
21608   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
21609   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
21610 _(ip_table_replace_begin, "table <n> [ipv6]")                           \
21611 _(ip_table_flush, "table <n> [ipv6]")                                   \
21612 _(ip_table_replace_end, "table <n> [ipv6]")                             \
21613 _(set_ip_flow_hash,                                                     \
21614   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
21615 _(sw_interface_ip6_enable_disable,                                      \
21616   "<intfc> | sw_if_index <id> enable | disable")                        \
21617 _(ip6nd_proxy_add_del,                                                  \
21618   "<intfc> | sw_if_index <id> <ip6-address>")                           \
21619 _(ip6nd_proxy_dump, "")                                                 \
21620 _(sw_interface_ip6nd_ra_prefix,                                         \
21621   "<intfc> | sw_if_index <id> <ip6-address>/<mask-width>\n"             \
21622   "val_life <n> pref_life <n> [def] [noadv] [offl] [noauto]\n"          \
21623   "[nolink] [isno]")                                                    \
21624 _(sw_interface_ip6nd_ra_config,                                         \
21625   "<intfc> | sw_if_index <id> [maxint <n>] [minint <n>]\n"              \
21626   "[life <n>] [count <n>] [interval <n>] [suppress]\n"                  \
21627   "[managed] [other] [ll] [send] [cease] [isno] [def]")                 \
21628 _(set_arp_neighbor_limit, "arp_nbr_limit <n> [ipv6]")                   \
21629 _(l2_patch_add_del,                                                     \
21630   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
21631   "enable | disable")                                                   \
21632 _(sr_localsid_add_del,                                                  \
21633   "(del) address <addr> next_hop <addr> behavior <beh>\n"               \
21634   "fib-table <num> (end.psp) sw_if_index <num>")                        \
21635 _(classify_add_del_table,                                               \
21636   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
21637   " [del] [del-chain] mask <mask-value>\n"                              \
21638   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
21639   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
21640 _(classify_add_del_session,                                             \
21641   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
21642   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
21643   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
21644   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
21645 _(classify_set_interface_ip_table,                                      \
21646   "<intfc> | sw_if_index <nn> table <nn>")                              \
21647 _(classify_set_interface_l2_tables,                                     \
21648   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
21649   "  [other-table <nn>]")                                               \
21650 _(get_node_index, "node <node-name")                                    \
21651 _(add_node_next, "node <node-name> next <next-node-name>")              \
21652 _(l2tpv3_create_tunnel,                                                 \
21653   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
21654   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
21655   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
21656 _(l2tpv3_set_tunnel_cookies,                                            \
21657   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
21658   "[new_remote_cookie <nn>]\n")                                         \
21659 _(l2tpv3_interface_enable_disable,                                      \
21660   "<intfc> | sw_if_index <nn> enable | disable")                        \
21661 _(l2tpv3_set_lookup_key,                                                \
21662   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
21663 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
21664 _(vxlan_offload_rx,                                                     \
21665   "hw { <interface name> | hw_if_index <nn>} "                          \
21666   "rx { <vxlan tunnel name> | sw_if_index <nn> } [del]")                \
21667 _(vxlan_add_del_tunnel,                                                 \
21668   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
21669   "{ <intfc> | mcast_sw_if_index <nn> } [instance <id>]}\n"             \
21670   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
21671 _(geneve_add_del_tunnel,                                                \
21672   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
21673   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
21674   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
21675 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
21676 _(geneve_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                   \
21677 _(gre_tunnel_add_del,                                                   \
21678   "src <ip-addr> dst <ip-addr> [outer-fib-id <nn>] [instance <n>]\n"    \
21679   "[teb | erspan <session-id>] [del]")                                  \
21680 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
21681 _(l2_fib_clear_table, "")                                               \
21682 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
21683 _(l2_interface_vlan_tag_rewrite,                                        \
21684   "<intfc> | sw_if_index <nn> \n"                                       \
21685   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
21686   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
21687 _(create_vhost_user_if,                                                 \
21688         "socket <filename> [server] [renumber <dev_instance>] "         \
21689         "[disable_mrg_rxbuf] [disable_indirect_desc] [gso] "            \
21690         "[mac <mac_address>]")                                          \
21691 _(modify_vhost_user_if,                                                 \
21692         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
21693         "[server] [renumber <dev_instance>] [gso]")                     \
21694 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
21695 _(sw_interface_vhost_user_dump, "")                                     \
21696 _(show_version, "")                                                     \
21697 _(show_threads, "")                                                     \
21698 _(vxlan_gpe_add_del_tunnel,                                             \
21699   "local <addr> remote <addr>  | group <mcast-ip-addr>\n"               \
21700   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
21701   "vni <nn> [encap-vrf-id <nn>] [decap-vrf-id <nn>]\n"                  \
21702   "[next-ip4][next-ip6][next-ethernet] [next-nsh] [del]\n")             \
21703 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
21704 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
21705 _(interface_name_renumber,                                              \
21706   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
21707 _(input_acl_set_interface,                                              \
21708   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
21709   "  [l2-table <nn>] [del]")                                            \
21710 _(ip_probe_neighbor, "(<intc> | sw_if_index <nn>) address <ip4|ip6-addr>") \
21711 _(ip_scan_neighbor_enable_disable, "[ip4|ip6|both|disable] [interval <n-min>]\n" \
21712   "  [max-time <n-usec>] [max-update <n>] [delay <n-msec>] [stale <n-min>]") \
21713 _(want_ip4_arp_events, "address <ip4-address> [del]")                   \
21714 _(want_ip6_nd_events, "address <ip6-address> [del]")                    \
21715 _(want_l2_macs_events, "[disable] [learn-limit <n>] [scan-delay <n>] [max-entries <n>]") \
21716 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
21717 _(ip_dump, "ipv4 | ipv6")                                               \
21718 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
21719 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
21720   "  spid_id <n> ")                                                     \
21721 _(ipsec_sad_entry_add_del, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
21722   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
21723   "  integ_alg <alg> integ_key <hex>")                                  \
21724 _(ipsec_spd_entry_add_del, "spd_id <n> priority <n> action <action>\n"  \
21725   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
21726   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
21727   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
21728 _(ipsec_tunnel_if_add_del, "local_spi <n> remote_spi <n>\n"             \
21729   "  crypto_alg <alg> local_crypto_key <hex> remote_crypto_key <hex>\n" \
21730   "  integ_alg <alg> local_integ_key <hex> remote_integ_key <hex>\n"    \
21731   "  local_ip <addr> remote_ip <addr> [esn] [anti_replay] [del]\n"      \
21732   "  [instance <n>]")     \
21733 _(ipsec_sa_dump, "[sa_id <n>]")                                         \
21734 _(ipsec_tunnel_if_set_sa, "<intfc> sa_id <n> <inbound|outbound>\n")     \
21735 _(delete_loopback,"sw_if_index <nn>")                                   \
21736 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
21737 _(bd_ip_mac_flush, "bd_id <bridge-domain-id>")                          \
21738 _(bd_ip_mac_dump, "[bd_id] <bridge-domain-id>")                         \
21739 _(want_interface_events,  "enable|disable")                             \
21740 _(get_first_msg_id, "client <name>")                                    \
21741 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
21742 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
21743   "fib-id <nn> [ip4][ip6][default]")                                    \
21744 _(get_node_graph, " ")                                                  \
21745 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
21746 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
21747 _(ioam_disable, "")                                                     \
21748 _(one_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
21749                             " sw_if_index <sw_if_index> p <priority> "  \
21750                             "w <weight>] [del]")                        \
21751 _(one_add_del_locator, "locator-set <locator_name> "                    \
21752                         "iface <intf> | sw_if_index <sw_if_index> "     \
21753                         "p <priority> w <weight> [del]")                \
21754 _(one_add_del_local_eid,"vni <vni> eid "                                \
21755                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
21756                          "locator-set <locator_name> [del]"             \
21757                          "[key-id sha1|sha256 secret-key <secret-key>]")\
21758 _(one_add_del_map_resolver, "<ip4|6-addr> [del]")                       \
21759 _(one_add_del_map_server, "<ip4|6-addr> [del]")                         \
21760 _(one_enable_disable, "enable|disable")                                 \
21761 _(one_map_register_enable_disable, "enable|disable")                    \
21762 _(one_map_register_fallback_threshold, "<value>")                       \
21763 _(one_rloc_probe_enable_disable, "enable|disable")                      \
21764 _(one_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "       \
21765                                "[seid <seid>] "                         \
21766                                "rloc <locator> p <prio> "               \
21767                                "w <weight> [rloc <loc> ... ] "          \
21768                                "action <action> [del-all]")             \
21769 _(one_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "    \
21770                           "<local-eid>")                                \
21771 _(one_pitr_set_locator_set, "locator-set <loc-set-name> | del")         \
21772 _(one_use_petr, "ip-address> | disable")                                \
21773 _(one_map_request_mode, "src-dst|dst-only")                             \
21774 _(one_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")            \
21775 _(one_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")               \
21776 _(one_locator_set_dump, "[local | remote]")                             \
21777 _(one_locator_dump, "ls_index <index> | ls_name <name>")                \
21778 _(one_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "       \
21779                        "[local] | [remote]")                            \
21780 _(one_add_del_ndp_entry, "[del] mac <mac> bd <bd> ip6 <ip6>")           \
21781 _(one_ndp_bd_get, "")                                                   \
21782 _(one_ndp_entries_get, "bd <bridge-domain>")                            \
21783 _(one_add_del_l2_arp_entry, "[del] mac <mac> bd <bd> ip4 <ip4>")        \
21784 _(one_l2_arp_bd_get, "")                                                \
21785 _(one_l2_arp_entries_get, "bd <bridge-domain>")                         \
21786 _(one_stats_enable_disable, "enable|disable")                           \
21787 _(show_one_stats_enable_disable, "")                                    \
21788 _(one_eid_table_vni_dump, "")                                           \
21789 _(one_eid_table_map_dump, "l2|l3")                                      \
21790 _(one_map_resolver_dump, "")                                            \
21791 _(one_map_server_dump, "")                                              \
21792 _(one_adjacencies_get, "vni <vni>")                                     \
21793 _(one_nsh_set_locator_set, "[del] ls <locator-set-name>")               \
21794 _(show_one_rloc_probe_state, "")                                        \
21795 _(show_one_map_register_state, "")                                      \
21796 _(show_one_status, "")                                                  \
21797 _(one_stats_dump, "")                                                   \
21798 _(one_stats_flush, "")                                                  \
21799 _(one_get_map_request_itr_rlocs, "")                                    \
21800 _(one_map_register_set_ttl, "<ttl>")                                    \
21801 _(one_set_transport_protocol, "udp|api")                                \
21802 _(one_get_transport_protocol, "")                                       \
21803 _(one_enable_disable_xtr_mode, "enable|disable")                        \
21804 _(one_show_xtr_mode, "")                                                \
21805 _(one_enable_disable_pitr_mode, "enable|disable")                       \
21806 _(one_show_pitr_mode, "")                                               \
21807 _(one_enable_disable_petr_mode, "enable|disable")                       \
21808 _(one_show_petr_mode, "")                                               \
21809 _(show_one_nsh_mapping, "")                                             \
21810 _(show_one_pitr, "")                                                    \
21811 _(show_one_use_petr, "")                                                \
21812 _(show_one_map_request_mode, "")                                        \
21813 _(show_one_map_register_ttl, "")                                        \
21814 _(show_one_map_register_fallback_threshold, "")                         \
21815 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
21816                             " sw_if_index <sw_if_index> p <priority> "  \
21817                             "w <weight>] [del]")                        \
21818 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
21819                         "iface <intf> | sw_if_index <sw_if_index> "     \
21820                         "p <priority> w <weight> [del]")                \
21821 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
21822                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
21823                          "locator-set <locator_name> [del]"             \
21824                          "[key-id sha1|sha256 secret-key <secret-key>]") \
21825 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
21826 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
21827 _(lisp_enable_disable, "enable|disable")                                \
21828 _(lisp_map_register_enable_disable, "enable|disable")                   \
21829 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
21830 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
21831                                "[seid <seid>] "                         \
21832                                "rloc <locator> p <prio> "               \
21833                                "w <weight> [rloc <loc> ... ] "          \
21834                                "action <action> [del-all]")             \
21835 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
21836                           "<local-eid>")                                \
21837 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
21838 _(lisp_use_petr, "<ip-address> | disable")                              \
21839 _(lisp_map_request_mode, "src-dst|dst-only")                            \
21840 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
21841 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
21842 _(lisp_locator_set_dump, "[local | remote]")                            \
21843 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
21844 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
21845                        "[local] | [remote]")                            \
21846 _(lisp_eid_table_vni_dump, "")                                          \
21847 _(lisp_eid_table_map_dump, "l2|l3")                                     \
21848 _(lisp_map_resolver_dump, "")                                           \
21849 _(lisp_map_server_dump, "")                                             \
21850 _(lisp_adjacencies_get, "vni <vni>")                                    \
21851 _(gpe_fwd_entry_vnis_get, "")                                           \
21852 _(gpe_native_fwd_rpaths_get, "ip4 | ip6")                               \
21853 _(gpe_add_del_native_fwd_rpath, "[del] via <nh-ip-addr> [iface] "       \
21854                                 "[table <table-id>]")                   \
21855 _(lisp_gpe_fwd_entries_get, "vni <vni>")                                \
21856 _(lisp_gpe_fwd_entry_path_dump, "index <fwd_entry_index>")              \
21857 _(gpe_set_encap_mode, "lisp|vxlan")                                     \
21858 _(gpe_get_encap_mode, "")                                               \
21859 _(lisp_gpe_add_del_iface, "up|down")                                    \
21860 _(lisp_gpe_enable_disable, "enable|disable")                            \
21861 _(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>"       \
21862   "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
21863 _(show_lisp_rloc_probe_state, "")                                       \
21864 _(show_lisp_map_register_state, "")                                     \
21865 _(show_lisp_status, "")                                                 \
21866 _(lisp_get_map_request_itr_rlocs, "")                                   \
21867 _(show_lisp_pitr, "")                                                   \
21868 _(show_lisp_use_petr, "")                                               \
21869 _(show_lisp_map_request_mode, "")                                       \
21870 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
21871 _(af_packet_delete, "name <host interface name>")                       \
21872 _(af_packet_dump, "")                                                   \
21873 _(policer_add_del, "name <policer name> <params> [del]")                \
21874 _(policer_dump, "[name <policer name>]")                                \
21875 _(policer_classify_set_interface,                                       \
21876   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
21877   "  [l2-table <nn>] [del]")                                            \
21878 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
21879 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
21880     "[master|slave]")                                                   \
21881 _(netmap_delete, "name <interface name>")                               \
21882 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
21883 _(mpls_table_dump, "")                                                  \
21884 _(mpls_route_dump, "table-id <ID>")                                     \
21885 _(classify_table_ids, "")                                               \
21886 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
21887 _(classify_table_info, "table_id <nn>")                                 \
21888 _(classify_session_dump, "table_id <nn>")                               \
21889 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
21890     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
21891     "[template_interval <nn>] [udp_checksum]")                          \
21892 _(ipfix_exporter_dump, "")                                              \
21893 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
21894 _(ipfix_classify_stream_dump, "")                                       \
21895 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
21896 _(ipfix_classify_table_dump, "")                                        \
21897 _(sw_interface_span_enable_disable, "[l2] [src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
21898 _(sw_interface_span_dump, "[l2]")                                           \
21899 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
21900 _(pg_create_interface, "if_id <nn> [gso-enabled gso-size <size>]")      \
21901 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
21902 _(pg_enable_disable, "[stream <id>] disable")                           \
21903 _(ip_source_and_port_range_check_add_del,                               \
21904   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
21905 _(ip_source_and_port_range_check_interface_add_del,                     \
21906   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
21907   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
21908 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
21909 _(l2_interface_pbb_tag_rewrite,                                         \
21910   "<intfc> | sw_if_index <nn> \n"                                       \
21911   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
21912   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
21913 _(set_punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
21914 _(flow_classify_set_interface,                                          \
21915   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
21916 _(flow_classify_dump, "type [ip4|ip6]")                                 \
21917 _(ip_table_dump, "")                                                    \
21918 _(ip_route_dump, "table-id [ip4|ip6]")                                  \
21919 _(ip_mtable_dump, "")                                                   \
21920 _(ip_mroute_dump, "table-id [ip4|ip6]")                                 \
21921 _(feature_enable_disable, "arc_name <arc_name> "                        \
21922   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
21923 _(feature_gso_enable_disable, "<intfc> | sw_if_index <nn> "             \
21924   "[enable | disable] ")                                                \
21925 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
21926 "[disable]")                                                            \
21927 _(sw_interface_add_del_mac_address, "<intfc> | sw_if_index <nn> "       \
21928   "mac <mac-address> [del]")                                            \
21929 _(l2_xconnect_dump, "")                                                 \
21930 _(hw_interface_set_mtu, "<intfc> | hw_if_index <nn> mtu <nn>")        \
21931 _(ip_neighbor_dump, "[ip6] <intfc> | sw_if_index <nn>")                 \
21932 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")          \
21933 _(p2p_ethernet_add, "<intfc> | sw_if_index <nn> remote_mac <mac-address> sub_id <id>") \
21934 _(p2p_ethernet_del, "<intfc> | sw_if_index <nn> remote_mac <mac-address>") \
21935 _(lldp_config, "system-name <name> tx-hold <nn> tx-interval <nn>") \
21936 _(sw_interface_set_lldp, "<intfc> | sw_if_index <nn> [port-desc <description>]\n" \
21937   " [mgmt-ip4 <ip4>] [mgmt-ip6 <ip6>] [mgmt-oid <object id>] [disable]") \
21938 _(tcp_configure_src_addresses, "<ip4|6>first-<ip4|6>last [vrf <id>]")   \
21939 _(sock_init_shm, "size <nnn>")                                          \
21940 _(app_namespace_add_del, "[add] id <ns-id> secret <nn> sw_if_index <nn>")\
21941 _(session_rule_add_del, "[add|del] proto <tcp/udp> <lcl-ip>/<plen> "    \
21942   "<lcl-port> <rmt-ip>/<plen> <rmt-port> action <nn>")                  \
21943 _(session_rules_dump, "")                                               \
21944 _(ip_container_proxy_add_del, "[add|del] <address> <sw_if_index>")      \
21945 _(output_acl_set_interface,                                             \
21946   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
21947   "  [l2-table <nn>] [del]")                                            \
21948 _(qos_record_enable_disable, "<record-source> <intfc> | sw_if_index <id> [disable]")
21949
21950 /* List of command functions, CLI names map directly to functions */
21951 #define foreach_cli_function                                    \
21952 _(comment, "usage: comment <ignore-rest-of-line>")              \
21953 _(dump_interface_table, "usage: dump_interface_table")          \
21954 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
21955 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
21956 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
21957 _(dump_macro_table, "usage: dump_macro_table ")                 \
21958 _(dump_node_table, "usage: dump_node_table")                    \
21959 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
21960 _(elog_setup, "usage: elog_setup [nevents, default 128K]")      \
21961 _(elog_disable, "usage: elog_disable")                          \
21962 _(elog_enable, "usage: elog_enable")                            \
21963 _(elog_save, "usage: elog_save <filename>")                     \
21964 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
21965 _(echo, "usage: echo <message>")                                \
21966 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
21967 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
21968 _(help, "usage: help")                                          \
21969 _(q, "usage: quit")                                             \
21970 _(quit, "usage: quit")                                          \
21971 _(search_node_table, "usage: search_node_table <name>...")      \
21972 _(set, "usage: set <variable-name> <value>")                    \
21973 _(script, "usage: script <file-name>")                          \
21974 _(statseg, "usage: statseg")                                    \
21975 _(unset, "usage: unset <variable-name>")
21976
21977 #define _(N,n)                                  \
21978     static void vl_api_##n##_t_handler_uni      \
21979     (vl_api_##n##_t * mp)                       \
21980     {                                           \
21981         vat_main_t * vam = &vat_main;           \
21982         if (vam->json_output) {                 \
21983             vl_api_##n##_t_handler_json(mp);    \
21984         } else {                                \
21985             vl_api_##n##_t_handler(mp);         \
21986         }                                       \
21987     }
21988 foreach_vpe_api_reply_msg;
21989 #if VPP_API_TEST_BUILTIN == 0
21990 foreach_standalone_reply_msg;
21991 #endif
21992 #undef _
21993
21994 void
21995 vat_api_hookup (vat_main_t * vam)
21996 {
21997 #define _(N,n)                                                  \
21998     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
21999                            vl_api_##n##_t_handler_uni,          \
22000                            vl_noop_handler,                     \
22001                            vl_api_##n##_t_endian,               \
22002                            vl_api_##n##_t_print,                \
22003                            sizeof(vl_api_##n##_t), 1);
22004   foreach_vpe_api_reply_msg;
22005 #if VPP_API_TEST_BUILTIN == 0
22006   foreach_standalone_reply_msg;
22007 #endif
22008 #undef _
22009
22010 #if (VPP_API_TEST_BUILTIN==0)
22011   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
22012
22013   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
22014
22015   vam->function_by_name = hash_create_string (0, sizeof (uword));
22016
22017   vam->help_by_name = hash_create_string (0, sizeof (uword));
22018 #endif
22019
22020   /* API messages we can send */
22021 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
22022   foreach_vpe_api_msg;
22023 #undef _
22024
22025   /* Help strings */
22026 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
22027   foreach_vpe_api_msg;
22028 #undef _
22029
22030   /* CLI functions */
22031 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
22032   foreach_cli_function;
22033 #undef _
22034
22035   /* Help strings */
22036 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
22037   foreach_cli_function;
22038 #undef _
22039 }
22040
22041 #if VPP_API_TEST_BUILTIN
22042 static clib_error_t *
22043 vat_api_hookup_shim (vlib_main_t * vm)
22044 {
22045   vat_api_hookup (&vat_main);
22046   return 0;
22047 }
22048
22049 VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
22050 #endif
22051
22052 /*
22053  * fd.io coding-style-patch-verification: ON
22054  *
22055  * Local Variables:
22056  * eval: (c-set-style "gnu")
22057  * End:
22058  */