tap: split gso and checksum offload functionality
[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-neighbor/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   void *oldheap;
1104   u8 *reply;
1105
1106   vat_json_init_object (&node);
1107   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1108   vat_json_object_add_uint (&node, "reply_in_shmem",
1109                             ntohl (mp->reply_in_shmem));
1110   /* Toss the shared-memory original... */
1111   oldheap = vl_msg_push_heap ();
1112
1113   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
1114   vec_free (reply);
1115
1116   vl_msg_pop_heap (oldheap);
1117
1118   vat_json_print (vam->ofp, &node);
1119   vat_json_free (&node);
1120
1121   vam->retval = ntohl (mp->retval);
1122   vam->result_ready = 1;
1123 }
1124
1125 static void
1126 vl_api_cli_inband_reply_t_handler (vl_api_cli_inband_reply_t * mp)
1127 {
1128   vat_main_t *vam = &vat_main;
1129   i32 retval = ntohl (mp->retval);
1130   u32 length = vl_api_string_len (&mp->reply);
1131
1132   vec_reset_length (vam->cmd_reply);
1133
1134   vam->retval = retval;
1135   if (retval == 0)
1136     {
1137       vec_validate (vam->cmd_reply, length);
1138       clib_memcpy ((char *) (vam->cmd_reply),
1139                    vl_api_from_api_string (&mp->reply), length);
1140       vam->cmd_reply[length] = 0;
1141     }
1142   vam->result_ready = 1;
1143 }
1144
1145 static void
1146 vl_api_cli_inband_reply_t_handler_json (vl_api_cli_inband_reply_t * mp)
1147 {
1148   vat_main_t *vam = &vat_main;
1149   vat_json_node_t node;
1150
1151   vec_reset_length (vam->cmd_reply);
1152
1153   vat_json_init_object (&node);
1154   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1155   vat_json_object_add_string_copy (&node, "reply",
1156                                    vl_api_from_api_string (&mp->reply));
1157
1158   vat_json_print (vam->ofp, &node);
1159   vat_json_free (&node);
1160
1161   vam->retval = ntohl (mp->retval);
1162   vam->result_ready = 1;
1163 }
1164
1165 static void vl_api_classify_add_del_table_reply_t_handler
1166   (vl_api_classify_add_del_table_reply_t * mp)
1167 {
1168   vat_main_t *vam = &vat_main;
1169   i32 retval = ntohl (mp->retval);
1170   if (vam->async_mode)
1171     {
1172       vam->async_errors += (retval < 0);
1173     }
1174   else
1175     {
1176       vam->retval = retval;
1177       if (retval == 0 &&
1178           ((mp->new_table_index != 0xFFFFFFFF) ||
1179            (mp->skip_n_vectors != 0xFFFFFFFF) ||
1180            (mp->match_n_vectors != 0xFFFFFFFF)))
1181         /*
1182          * Note: this is just barely thread-safe, depends on
1183          * the main thread spinning waiting for an answer...
1184          */
1185         errmsg ("new index %d, skip_n_vectors %d, match_n_vectors %d",
1186                 ntohl (mp->new_table_index),
1187                 ntohl (mp->skip_n_vectors), ntohl (mp->match_n_vectors));
1188       vam->result_ready = 1;
1189     }
1190 }
1191
1192 static void vl_api_classify_add_del_table_reply_t_handler_json
1193   (vl_api_classify_add_del_table_reply_t * mp)
1194 {
1195   vat_main_t *vam = &vat_main;
1196   vat_json_node_t node;
1197
1198   vat_json_init_object (&node);
1199   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1200   vat_json_object_add_uint (&node, "new_table_index",
1201                             ntohl (mp->new_table_index));
1202   vat_json_object_add_uint (&node, "skip_n_vectors",
1203                             ntohl (mp->skip_n_vectors));
1204   vat_json_object_add_uint (&node, "match_n_vectors",
1205                             ntohl (mp->match_n_vectors));
1206
1207   vat_json_print (vam->ofp, &node);
1208   vat_json_free (&node);
1209
1210   vam->retval = ntohl (mp->retval);
1211   vam->result_ready = 1;
1212 }
1213
1214 static void vl_api_get_node_index_reply_t_handler
1215   (vl_api_get_node_index_reply_t * mp)
1216 {
1217   vat_main_t *vam = &vat_main;
1218   i32 retval = ntohl (mp->retval);
1219   if (vam->async_mode)
1220     {
1221       vam->async_errors += (retval < 0);
1222     }
1223   else
1224     {
1225       vam->retval = retval;
1226       if (retval == 0)
1227         errmsg ("node index %d", ntohl (mp->node_index));
1228       vam->result_ready = 1;
1229     }
1230 }
1231
1232 static void vl_api_get_node_index_reply_t_handler_json
1233   (vl_api_get_node_index_reply_t * mp)
1234 {
1235   vat_main_t *vam = &vat_main;
1236   vat_json_node_t node;
1237
1238   vat_json_init_object (&node);
1239   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1240   vat_json_object_add_uint (&node, "node_index", ntohl (mp->node_index));
1241
1242   vat_json_print (vam->ofp, &node);
1243   vat_json_free (&node);
1244
1245   vam->retval = ntohl (mp->retval);
1246   vam->result_ready = 1;
1247 }
1248
1249 static void vl_api_get_next_index_reply_t_handler
1250   (vl_api_get_next_index_reply_t * mp)
1251 {
1252   vat_main_t *vam = &vat_main;
1253   i32 retval = ntohl (mp->retval);
1254   if (vam->async_mode)
1255     {
1256       vam->async_errors += (retval < 0);
1257     }
1258   else
1259     {
1260       vam->retval = retval;
1261       if (retval == 0)
1262         errmsg ("next node index %d", ntohl (mp->next_index));
1263       vam->result_ready = 1;
1264     }
1265 }
1266
1267 static void vl_api_get_next_index_reply_t_handler_json
1268   (vl_api_get_next_index_reply_t * mp)
1269 {
1270   vat_main_t *vam = &vat_main;
1271   vat_json_node_t node;
1272
1273   vat_json_init_object (&node);
1274   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1275   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1276
1277   vat_json_print (vam->ofp, &node);
1278   vat_json_free (&node);
1279
1280   vam->retval = ntohl (mp->retval);
1281   vam->result_ready = 1;
1282 }
1283
1284 static void vl_api_add_node_next_reply_t_handler
1285   (vl_api_add_node_next_reply_t * mp)
1286 {
1287   vat_main_t *vam = &vat_main;
1288   i32 retval = ntohl (mp->retval);
1289   if (vam->async_mode)
1290     {
1291       vam->async_errors += (retval < 0);
1292     }
1293   else
1294     {
1295       vam->retval = retval;
1296       if (retval == 0)
1297         errmsg ("next index %d", ntohl (mp->next_index));
1298       vam->result_ready = 1;
1299     }
1300 }
1301
1302 static void vl_api_add_node_next_reply_t_handler_json
1303   (vl_api_add_node_next_reply_t * mp)
1304 {
1305   vat_main_t *vam = &vat_main;
1306   vat_json_node_t node;
1307
1308   vat_json_init_object (&node);
1309   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1310   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1311
1312   vat_json_print (vam->ofp, &node);
1313   vat_json_free (&node);
1314
1315   vam->retval = ntohl (mp->retval);
1316   vam->result_ready = 1;
1317 }
1318
1319 static void vl_api_show_version_reply_t_handler
1320   (vl_api_show_version_reply_t * mp)
1321 {
1322   vat_main_t *vam = &vat_main;
1323   i32 retval = ntohl (mp->retval);
1324
1325   if (retval >= 0)
1326     {
1327       errmsg ("        program: %s", mp->program);
1328       errmsg ("        version: %s", mp->version);
1329       errmsg ("     build date: %s", mp->build_date);
1330       errmsg ("build directory: %s", mp->build_directory);
1331     }
1332   vam->retval = retval;
1333   vam->result_ready = 1;
1334 }
1335
1336 static void vl_api_show_version_reply_t_handler_json
1337   (vl_api_show_version_reply_t * mp)
1338 {
1339   vat_main_t *vam = &vat_main;
1340   vat_json_node_t node;
1341
1342   vat_json_init_object (&node);
1343   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1344   vat_json_object_add_string_copy (&node, "program", mp->program);
1345   vat_json_object_add_string_copy (&node, "version", mp->version);
1346   vat_json_object_add_string_copy (&node, "build_date", mp->build_date);
1347   vat_json_object_add_string_copy (&node, "build_directory",
1348                                    mp->build_directory);
1349
1350   vat_json_print (vam->ofp, &node);
1351   vat_json_free (&node);
1352
1353   vam->retval = ntohl (mp->retval);
1354   vam->result_ready = 1;
1355 }
1356
1357 static void vl_api_show_threads_reply_t_handler
1358   (vl_api_show_threads_reply_t * mp)
1359 {
1360   vat_main_t *vam = &vat_main;
1361   i32 retval = ntohl (mp->retval);
1362   int i, count = 0;
1363
1364   if (retval >= 0)
1365     count = ntohl (mp->count);
1366
1367   for (i = 0; i < count; i++)
1368     print (vam->ofp,
1369            "\n%-2d %-11s %-11s %-5d %-6d %-4d %-6d",
1370            ntohl (mp->thread_data[i].id), mp->thread_data[i].name,
1371            mp->thread_data[i].type, ntohl (mp->thread_data[i].pid),
1372            ntohl (mp->thread_data[i].cpu_id), ntohl (mp->thread_data[i].core),
1373            ntohl (mp->thread_data[i].cpu_socket));
1374
1375   vam->retval = retval;
1376   vam->result_ready = 1;
1377 }
1378
1379 static void vl_api_show_threads_reply_t_handler_json
1380   (vl_api_show_threads_reply_t * mp)
1381 {
1382   vat_main_t *vam = &vat_main;
1383   vat_json_node_t node;
1384   vl_api_thread_data_t *td;
1385   i32 retval = ntohl (mp->retval);
1386   int i, count = 0;
1387
1388   if (retval >= 0)
1389     count = ntohl (mp->count);
1390
1391   vat_json_init_object (&node);
1392   vat_json_object_add_int (&node, "retval", retval);
1393   vat_json_object_add_uint (&node, "count", count);
1394
1395   for (i = 0; i < count; i++)
1396     {
1397       td = &mp->thread_data[i];
1398       vat_json_object_add_uint (&node, "id", ntohl (td->id));
1399       vat_json_object_add_string_copy (&node, "name", td->name);
1400       vat_json_object_add_string_copy (&node, "type", td->type);
1401       vat_json_object_add_uint (&node, "pid", ntohl (td->pid));
1402       vat_json_object_add_int (&node, "cpu_id", ntohl (td->cpu_id));
1403       vat_json_object_add_int (&node, "core", ntohl (td->id));
1404       vat_json_object_add_int (&node, "cpu_socket", ntohl (td->cpu_socket));
1405     }
1406
1407   vat_json_print (vam->ofp, &node);
1408   vat_json_free (&node);
1409
1410   vam->retval = retval;
1411   vam->result_ready = 1;
1412 }
1413
1414 static int
1415 api_show_threads (vat_main_t * vam)
1416 {
1417   vl_api_show_threads_t *mp;
1418   int ret;
1419
1420   print (vam->ofp,
1421          "\n%-2s %-11s %-11s %-5s %-6s %-4s %-6s",
1422          "ID", "Name", "Type", "LWP", "cpu_id", "Core", "Socket");
1423
1424   M (SHOW_THREADS, mp);
1425
1426   S (mp);
1427   W (ret);
1428   return ret;
1429 }
1430
1431 static void
1432 vl_api_l2_macs_event_t_handler (vl_api_l2_macs_event_t * mp)
1433 {
1434   u32 n_macs = ntohl (mp->n_macs);
1435   errmsg ("L2MAC event received with pid %d cl-idx %d for %d macs: \n",
1436           ntohl (mp->pid), mp->client_index, n_macs);
1437   int i;
1438   for (i = 0; i < n_macs; i++)
1439     {
1440       vl_api_mac_entry_t *mac = &mp->mac[i];
1441       errmsg (" [%d] sw_if_index %d  mac_addr %U  action %d \n",
1442               i + 1, ntohl (mac->sw_if_index),
1443               format_ethernet_address, mac->mac_addr, mac->action);
1444       if (i == 1000)
1445         break;
1446     }
1447 }
1448
1449 static void
1450 vl_api_l2_macs_event_t_handler_json (vl_api_l2_macs_event_t * mp)
1451 {
1452   /* JSON output not supported */
1453 }
1454
1455 #define vl_api_bridge_domain_details_t_endian vl_noop_handler
1456 #define vl_api_bridge_domain_details_t_print vl_noop_handler
1457
1458 /*
1459  * Special-case: build the bridge domain table, maintain
1460  * the next bd id vbl.
1461  */
1462 static void vl_api_bridge_domain_details_t_handler
1463   (vl_api_bridge_domain_details_t * mp)
1464 {
1465   vat_main_t *vam = &vat_main;
1466   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1467   int i;
1468
1469   print (vam->ofp, "\n%-3s %-3s %-3s %-3s %-3s %-6s %-3s",
1470          " ID", "LRN", "FWD", "FLD", "BVI", "UU-FWD", "#IF");
1471
1472   print (vam->ofp, "%3d %3d %3d %3d %3d %6d %3d",
1473          ntohl (mp->bd_id), mp->learn, mp->forward,
1474          mp->flood, ntohl (mp->bvi_sw_if_index),
1475          ntohl (mp->uu_fwd_sw_if_index), n_sw_ifs);
1476
1477   if (n_sw_ifs)
1478     {
1479       vl_api_bridge_domain_sw_if_t *sw_ifs;
1480       print (vam->ofp, "\n\n%s %s  %s", "sw_if_index", "SHG",
1481              "Interface Name");
1482
1483       sw_ifs = mp->sw_if_details;
1484       for (i = 0; i < n_sw_ifs; i++)
1485         {
1486           u8 *sw_if_name = 0;
1487           u32 sw_if_index;
1488           hash_pair_t *p;
1489
1490           sw_if_index = ntohl (sw_ifs->sw_if_index);
1491
1492           /* *INDENT-OFF* */
1493           hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
1494                              ({
1495                                if ((u32) p->value[0] == sw_if_index)
1496                                  {
1497                                    sw_if_name = (u8 *)(p->key);
1498                                    break;
1499                                  }
1500                              }));
1501           /* *INDENT-ON* */
1502           print (vam->ofp, "%7d     %3d  %s", sw_if_index,
1503                  sw_ifs->shg, sw_if_name ? (char *) sw_if_name :
1504                  "sw_if_index not found!");
1505
1506           sw_ifs++;
1507         }
1508     }
1509 }
1510
1511 static void vl_api_bridge_domain_details_t_handler_json
1512   (vl_api_bridge_domain_details_t * mp)
1513 {
1514   vat_main_t *vam = &vat_main;
1515   vat_json_node_t *node, *array = NULL;
1516   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1517
1518   if (VAT_JSON_ARRAY != vam->json_tree.type)
1519     {
1520       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1521       vat_json_init_array (&vam->json_tree);
1522     }
1523   node = vat_json_array_add (&vam->json_tree);
1524
1525   vat_json_init_object (node);
1526   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1527   vat_json_object_add_uint (node, "flood", mp->flood);
1528   vat_json_object_add_uint (node, "forward", mp->forward);
1529   vat_json_object_add_uint (node, "learn", mp->learn);
1530   vat_json_object_add_uint (node, "bvi_sw_if_index",
1531                             ntohl (mp->bvi_sw_if_index));
1532   vat_json_object_add_uint (node, "n_sw_ifs", n_sw_ifs);
1533   array = vat_json_object_add (node, "sw_if");
1534   vat_json_init_array (array);
1535
1536
1537
1538   if (n_sw_ifs)
1539     {
1540       vl_api_bridge_domain_sw_if_t *sw_ifs;
1541       int i;
1542
1543       sw_ifs = mp->sw_if_details;
1544       for (i = 0; i < n_sw_ifs; i++)
1545         {
1546           node = vat_json_array_add (array);
1547           vat_json_init_object (node);
1548           vat_json_object_add_uint (node, "sw_if_index",
1549                                     ntohl (sw_ifs->sw_if_index));
1550           vat_json_object_add_uint (node, "shg", sw_ifs->shg);
1551           sw_ifs++;
1552         }
1553     }
1554 }
1555
1556 static void vl_api_control_ping_reply_t_handler
1557   (vl_api_control_ping_reply_t * mp)
1558 {
1559   vat_main_t *vam = &vat_main;
1560   i32 retval = ntohl (mp->retval);
1561   if (vam->async_mode)
1562     {
1563       vam->async_errors += (retval < 0);
1564     }
1565   else
1566     {
1567       vam->retval = retval;
1568       vam->result_ready = 1;
1569     }
1570   if (vam->socket_client_main)
1571     vam->socket_client_main->control_pings_outstanding--;
1572 }
1573
1574 static void vl_api_control_ping_reply_t_handler_json
1575   (vl_api_control_ping_reply_t * mp)
1576 {
1577   vat_main_t *vam = &vat_main;
1578   i32 retval = ntohl (mp->retval);
1579
1580   if (VAT_JSON_NONE != vam->json_tree.type)
1581     {
1582       vat_json_print (vam->ofp, &vam->json_tree);
1583       vat_json_free (&vam->json_tree);
1584       vam->json_tree.type = VAT_JSON_NONE;
1585     }
1586   else
1587     {
1588       /* just print [] */
1589       vat_json_init_array (&vam->json_tree);
1590       vat_json_print (vam->ofp, &vam->json_tree);
1591       vam->json_tree.type = VAT_JSON_NONE;
1592     }
1593
1594   vam->retval = retval;
1595   vam->result_ready = 1;
1596 }
1597
1598 static void
1599   vl_api_bridge_domain_set_mac_age_reply_t_handler
1600   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1601 {
1602   vat_main_t *vam = &vat_main;
1603   i32 retval = ntohl (mp->retval);
1604   if (vam->async_mode)
1605     {
1606       vam->async_errors += (retval < 0);
1607     }
1608   else
1609     {
1610       vam->retval = retval;
1611       vam->result_ready = 1;
1612     }
1613 }
1614
1615 static void vl_api_bridge_domain_set_mac_age_reply_t_handler_json
1616   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1617 {
1618   vat_main_t *vam = &vat_main;
1619   vat_json_node_t node;
1620
1621   vat_json_init_object (&node);
1622   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1623
1624   vat_json_print (vam->ofp, &node);
1625   vat_json_free (&node);
1626
1627   vam->retval = ntohl (mp->retval);
1628   vam->result_ready = 1;
1629 }
1630
1631 static void
1632 vl_api_l2_flags_reply_t_handler (vl_api_l2_flags_reply_t * mp)
1633 {
1634   vat_main_t *vam = &vat_main;
1635   i32 retval = ntohl (mp->retval);
1636   if (vam->async_mode)
1637     {
1638       vam->async_errors += (retval < 0);
1639     }
1640   else
1641     {
1642       vam->retval = retval;
1643       vam->result_ready = 1;
1644     }
1645 }
1646
1647 static void vl_api_l2_flags_reply_t_handler_json
1648   (vl_api_l2_flags_reply_t * mp)
1649 {
1650   vat_main_t *vam = &vat_main;
1651   vat_json_node_t node;
1652
1653   vat_json_init_object (&node);
1654   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1655   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1656                             ntohl (mp->resulting_feature_bitmap));
1657
1658   vat_json_print (vam->ofp, &node);
1659   vat_json_free (&node);
1660
1661   vam->retval = ntohl (mp->retval);
1662   vam->result_ready = 1;
1663 }
1664
1665 static void vl_api_bridge_flags_reply_t_handler
1666   (vl_api_bridge_flags_reply_t * mp)
1667 {
1668   vat_main_t *vam = &vat_main;
1669   i32 retval = ntohl (mp->retval);
1670   if (vam->async_mode)
1671     {
1672       vam->async_errors += (retval < 0);
1673     }
1674   else
1675     {
1676       vam->retval = retval;
1677       vam->result_ready = 1;
1678     }
1679 }
1680
1681 static void vl_api_bridge_flags_reply_t_handler_json
1682   (vl_api_bridge_flags_reply_t * mp)
1683 {
1684   vat_main_t *vam = &vat_main;
1685   vat_json_node_t node;
1686
1687   vat_json_init_object (&node);
1688   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1689   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1690                             ntohl (mp->resulting_feature_bitmap));
1691
1692   vat_json_print (vam->ofp, &node);
1693   vat_json_free (&node);
1694
1695   vam->retval = ntohl (mp->retval);
1696   vam->result_ready = 1;
1697 }
1698
1699 static void
1700 vl_api_tap_create_v2_reply_t_handler (vl_api_tap_create_v2_reply_t * mp)
1701 {
1702   vat_main_t *vam = &vat_main;
1703   i32 retval = ntohl (mp->retval);
1704   if (vam->async_mode)
1705     {
1706       vam->async_errors += (retval < 0);
1707     }
1708   else
1709     {
1710       vam->retval = retval;
1711       vam->sw_if_index = ntohl (mp->sw_if_index);
1712       vam->result_ready = 1;
1713     }
1714
1715 }
1716
1717 static void vl_api_tap_create_v2_reply_t_handler_json
1718   (vl_api_tap_create_v2_reply_t * mp)
1719 {
1720   vat_main_t *vam = &vat_main;
1721   vat_json_node_t node;
1722
1723   vat_json_init_object (&node);
1724   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1725   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
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
1735 static void
1736 vl_api_tap_delete_v2_reply_t_handler (vl_api_tap_delete_v2_reply_t * mp)
1737 {
1738   vat_main_t *vam = &vat_main;
1739   i32 retval = ntohl (mp->retval);
1740   if (vam->async_mode)
1741     {
1742       vam->async_errors += (retval < 0);
1743     }
1744   else
1745     {
1746       vam->retval = retval;
1747       vam->result_ready = 1;
1748     }
1749 }
1750
1751 static void vl_api_tap_delete_v2_reply_t_handler_json
1752   (vl_api_tap_delete_v2_reply_t * mp)
1753 {
1754   vat_main_t *vam = &vat_main;
1755   vat_json_node_t node;
1756
1757   vat_json_init_object (&node);
1758   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1759
1760   vat_json_print (vam->ofp, &node);
1761   vat_json_free (&node);
1762
1763   vam->retval = ntohl (mp->retval);
1764   vam->result_ready = 1;
1765 }
1766
1767 static void
1768 vl_api_virtio_pci_create_reply_t_handler (vl_api_virtio_pci_create_reply_t *
1769                                           mp)
1770 {
1771   vat_main_t *vam = &vat_main;
1772   i32 retval = ntohl (mp->retval);
1773   if (vam->async_mode)
1774     {
1775       vam->async_errors += (retval < 0);
1776     }
1777   else
1778     {
1779       vam->retval = retval;
1780       vam->sw_if_index = ntohl (mp->sw_if_index);
1781       vam->result_ready = 1;
1782     }
1783 }
1784
1785 static void vl_api_virtio_pci_create_reply_t_handler_json
1786   (vl_api_virtio_pci_create_reply_t * mp)
1787 {
1788   vat_main_t *vam = &vat_main;
1789   vat_json_node_t node;
1790
1791   vat_json_init_object (&node);
1792   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1793   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
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
1803 static void
1804 vl_api_virtio_pci_delete_reply_t_handler (vl_api_virtio_pci_delete_reply_t *
1805                                           mp)
1806 {
1807   vat_main_t *vam = &vat_main;
1808   i32 retval = ntohl (mp->retval);
1809   if (vam->async_mode)
1810     {
1811       vam->async_errors += (retval < 0);
1812     }
1813   else
1814     {
1815       vam->retval = retval;
1816       vam->result_ready = 1;
1817     }
1818 }
1819
1820 static void vl_api_virtio_pci_delete_reply_t_handler_json
1821   (vl_api_virtio_pci_delete_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
1829   vat_json_print (vam->ofp, &node);
1830   vat_json_free (&node);
1831
1832   vam->retval = ntohl (mp->retval);
1833   vam->result_ready = 1;
1834 }
1835
1836 static void
1837 vl_api_bond_create_reply_t_handler (vl_api_bond_create_reply_t * mp)
1838 {
1839   vat_main_t *vam = &vat_main;
1840   i32 retval = ntohl (mp->retval);
1841
1842   if (vam->async_mode)
1843     {
1844       vam->async_errors += (retval < 0);
1845     }
1846   else
1847     {
1848       vam->retval = retval;
1849       vam->sw_if_index = ntohl (mp->sw_if_index);
1850       vam->result_ready = 1;
1851     }
1852 }
1853
1854 static void vl_api_bond_create_reply_t_handler_json
1855   (vl_api_bond_create_reply_t * mp)
1856 {
1857   vat_main_t *vam = &vat_main;
1858   vat_json_node_t node;
1859
1860   vat_json_init_object (&node);
1861   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1862   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
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_delete_reply_t_handler (vl_api_bond_delete_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->result_ready = 1;
1885     }
1886 }
1887
1888 static void vl_api_bond_delete_reply_t_handler_json
1889   (vl_api_bond_delete_reply_t * mp)
1890 {
1891   vat_main_t *vam = &vat_main;
1892   vat_json_node_t node;
1893
1894   vat_json_init_object (&node);
1895   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1896
1897   vat_json_print (vam->ofp, &node);
1898   vat_json_free (&node);
1899
1900   vam->retval = ntohl (mp->retval);
1901   vam->result_ready = 1;
1902 }
1903
1904 static void
1905 vl_api_bond_enslave_reply_t_handler (vl_api_bond_enslave_reply_t * mp)
1906 {
1907   vat_main_t *vam = &vat_main;
1908   i32 retval = ntohl (mp->retval);
1909
1910   if (vam->async_mode)
1911     {
1912       vam->async_errors += (retval < 0);
1913     }
1914   else
1915     {
1916       vam->retval = retval;
1917       vam->result_ready = 1;
1918     }
1919 }
1920
1921 static void vl_api_bond_enslave_reply_t_handler_json
1922   (vl_api_bond_enslave_reply_t * mp)
1923 {
1924   vat_main_t *vam = &vat_main;
1925   vat_json_node_t node;
1926
1927   vat_json_init_object (&node);
1928   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1929
1930   vat_json_print (vam->ofp, &node);
1931   vat_json_free (&node);
1932
1933   vam->retval = ntohl (mp->retval);
1934   vam->result_ready = 1;
1935 }
1936
1937 static void
1938 vl_api_bond_detach_slave_reply_t_handler (vl_api_bond_detach_slave_reply_t *
1939                                           mp)
1940 {
1941   vat_main_t *vam = &vat_main;
1942   i32 retval = ntohl (mp->retval);
1943
1944   if (vam->async_mode)
1945     {
1946       vam->async_errors += (retval < 0);
1947     }
1948   else
1949     {
1950       vam->retval = retval;
1951       vam->result_ready = 1;
1952     }
1953 }
1954
1955 static void vl_api_bond_detach_slave_reply_t_handler_json
1956   (vl_api_bond_detach_slave_reply_t * mp)
1957 {
1958   vat_main_t *vam = &vat_main;
1959   vat_json_node_t node;
1960
1961   vat_json_init_object (&node);
1962   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1963
1964   vat_json_print (vam->ofp, &node);
1965   vat_json_free (&node);
1966
1967   vam->retval = ntohl (mp->retval);
1968   vam->result_ready = 1;
1969 }
1970
1971 static int
1972 api_sw_interface_set_bond_weight (vat_main_t * vam)
1973 {
1974   unformat_input_t *i = vam->input;
1975   vl_api_sw_interface_set_bond_weight_t *mp;
1976   u32 sw_if_index = ~0;
1977   u32 weight = 0;
1978   u8 weight_enter = 0;
1979   int ret;
1980
1981   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
1982     {
1983       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
1984         ;
1985       else if (unformat (i, "sw_if_index %d", &sw_if_index))
1986         ;
1987       else if (unformat (i, "weight %u", &weight))
1988         weight_enter = 1;
1989       else
1990         break;
1991     }
1992
1993   if (sw_if_index == ~0)
1994     {
1995       errmsg ("missing interface name or sw_if_index");
1996       return -99;
1997     }
1998   if (weight_enter == 0)
1999     {
2000       errmsg ("missing valid weight");
2001       return -99;
2002     }
2003
2004   /* Construct the API message */
2005   M (SW_INTERFACE_SET_BOND_WEIGHT, mp);
2006   mp->sw_if_index = ntohl (sw_if_index);
2007   mp->weight = ntohl (weight);
2008
2009   S (mp);
2010   W (ret);
2011   return ret;
2012 }
2013
2014 static void vl_api_sw_interface_bond_details_t_handler
2015   (vl_api_sw_interface_bond_details_t * mp)
2016 {
2017   vat_main_t *vam = &vat_main;
2018
2019   print (vam->ofp,
2020          "%-16s %-12d %-12U %-13U %-14u %-14u",
2021          mp->interface_name, ntohl (mp->sw_if_index),
2022          format_bond_mode, ntohl (mp->mode), format_bond_load_balance,
2023          ntohl (mp->lb), ntohl (mp->active_slaves), ntohl (mp->slaves));
2024 }
2025
2026 static void vl_api_sw_interface_bond_details_t_handler_json
2027   (vl_api_sw_interface_bond_details_t * mp)
2028 {
2029   vat_main_t *vam = &vat_main;
2030   vat_json_node_t *node = NULL;
2031
2032   if (VAT_JSON_ARRAY != vam->json_tree.type)
2033     {
2034       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2035       vat_json_init_array (&vam->json_tree);
2036     }
2037   node = vat_json_array_add (&vam->json_tree);
2038
2039   vat_json_init_object (node);
2040   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
2041   vat_json_object_add_string_copy (node, "interface_name",
2042                                    mp->interface_name);
2043   vat_json_object_add_uint (node, "mode", ntohl (mp->mode));
2044   vat_json_object_add_uint (node, "load_balance", ntohl (mp->lb));
2045   vat_json_object_add_uint (node, "active_slaves", ntohl (mp->active_slaves));
2046   vat_json_object_add_uint (node, "slaves", ntohl (mp->slaves));
2047 }
2048
2049 static int
2050 api_sw_interface_bond_dump (vat_main_t * vam)
2051 {
2052   vl_api_sw_interface_bond_dump_t *mp;
2053   vl_api_control_ping_t *mp_ping;
2054   int ret;
2055
2056   print (vam->ofp,
2057          "\n%-16s %-12s %-12s %-13s %-14s %-14s",
2058          "interface name", "sw_if_index", "mode", "load balance",
2059          "active slaves", "slaves");
2060
2061   /* Get list of bond interfaces */
2062   M (SW_INTERFACE_BOND_DUMP, mp);
2063   S (mp);
2064
2065   /* Use a control ping for synchronization */
2066   MPING (CONTROL_PING, mp_ping);
2067   S (mp_ping);
2068
2069   W (ret);
2070   return ret;
2071 }
2072
2073 static void vl_api_sw_interface_slave_details_t_handler
2074   (vl_api_sw_interface_slave_details_t * mp)
2075 {
2076   vat_main_t *vam = &vat_main;
2077
2078   print (vam->ofp,
2079          "%-25s %-12d %-7d %-12d %-10d %-10d", mp->interface_name,
2080          ntohl (mp->sw_if_index), mp->is_passive, mp->is_long_timeout,
2081          ntohl (mp->weight), mp->is_local_numa);
2082 }
2083
2084 static void vl_api_sw_interface_slave_details_t_handler_json
2085   (vl_api_sw_interface_slave_details_t * mp)
2086 {
2087   vat_main_t *vam = &vat_main;
2088   vat_json_node_t *node = NULL;
2089
2090   if (VAT_JSON_ARRAY != vam->json_tree.type)
2091     {
2092       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2093       vat_json_init_array (&vam->json_tree);
2094     }
2095   node = vat_json_array_add (&vam->json_tree);
2096
2097   vat_json_init_object (node);
2098   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
2099   vat_json_object_add_string_copy (node, "interface_name",
2100                                    mp->interface_name);
2101   vat_json_object_add_uint (node, "passive", mp->is_passive);
2102   vat_json_object_add_uint (node, "long_timeout", mp->is_long_timeout);
2103   vat_json_object_add_uint (node, "weight", ntohl (mp->weight));
2104   vat_json_object_add_uint (node, "is_local_numa", mp->is_local_numa);
2105 }
2106
2107 static int
2108 api_sw_interface_slave_dump (vat_main_t * vam)
2109 {
2110   unformat_input_t *i = vam->input;
2111   vl_api_sw_interface_slave_dump_t *mp;
2112   vl_api_control_ping_t *mp_ping;
2113   u32 sw_if_index = ~0;
2114   u8 sw_if_index_set = 0;
2115   int ret;
2116
2117   /* Parse args required to build the message */
2118   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2119     {
2120       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
2121         sw_if_index_set = 1;
2122       else if (unformat (i, "sw_if_index %d", &sw_if_index))
2123         sw_if_index_set = 1;
2124       else
2125         break;
2126     }
2127
2128   if (sw_if_index_set == 0)
2129     {
2130       errmsg ("missing vpp interface name. ");
2131       return -99;
2132     }
2133
2134   print (vam->ofp,
2135          "\n%-25s %-12s %-7s %-12s %-10s %-10s",
2136          "slave interface name", "sw_if_index", "passive", "long_timeout",
2137          "weight", "local numa");
2138
2139   /* Get list of bond interfaces */
2140   M (SW_INTERFACE_SLAVE_DUMP, mp);
2141   mp->sw_if_index = ntohl (sw_if_index);
2142   S (mp);
2143
2144   /* Use a control ping for synchronization */
2145   MPING (CONTROL_PING, mp_ping);
2146   S (mp_ping);
2147
2148   W (ret);
2149   return ret;
2150 }
2151
2152 static void vl_api_mpls_tunnel_add_del_reply_t_handler
2153   (vl_api_mpls_tunnel_add_del_reply_t * mp)
2154 {
2155   vat_main_t *vam = &vat_main;
2156   i32 retval = ntohl (mp->retval);
2157   if (vam->async_mode)
2158     {
2159       vam->async_errors += (retval < 0);
2160     }
2161   else
2162     {
2163       vam->retval = retval;
2164       vam->sw_if_index = ntohl (mp->sw_if_index);
2165       vam->result_ready = 1;
2166     }
2167   vam->regenerate_interface_table = 1;
2168 }
2169
2170 static void vl_api_mpls_tunnel_add_del_reply_t_handler_json
2171   (vl_api_mpls_tunnel_add_del_reply_t * mp)
2172 {
2173   vat_main_t *vam = &vat_main;
2174   vat_json_node_t node;
2175
2176   vat_json_init_object (&node);
2177   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2178   vat_json_object_add_uint (&node, "tunnel_sw_if_index",
2179                             ntohl (mp->sw_if_index));
2180
2181   vat_json_print (vam->ofp, &node);
2182   vat_json_free (&node);
2183
2184   vam->retval = ntohl (mp->retval);
2185   vam->result_ready = 1;
2186 }
2187
2188 static void vl_api_l2tpv3_create_tunnel_reply_t_handler
2189   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
2190 {
2191   vat_main_t *vam = &vat_main;
2192   i32 retval = ntohl (mp->retval);
2193   if (vam->async_mode)
2194     {
2195       vam->async_errors += (retval < 0);
2196     }
2197   else
2198     {
2199       vam->retval = retval;
2200       vam->sw_if_index = ntohl (mp->sw_if_index);
2201       vam->result_ready = 1;
2202     }
2203 }
2204
2205 static void vl_api_l2tpv3_create_tunnel_reply_t_handler_json
2206   (vl_api_l2tpv3_create_tunnel_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, "sw_if_index", ntohl (mp->sw_if_index));
2214
2215   vat_json_print (vam->ofp, &node);
2216   vat_json_free (&node);
2217
2218   vam->retval = ntohl (mp->retval);
2219   vam->result_ready = 1;
2220 }
2221
2222 static void vl_api_gpe_add_del_fwd_entry_reply_t_handler
2223   (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
2224 {
2225   vat_main_t *vam = &vat_main;
2226   i32 retval = ntohl (mp->retval);
2227   if (vam->async_mode)
2228     {
2229       vam->async_errors += (retval < 0);
2230     }
2231   else
2232     {
2233       vam->retval = retval;
2234       vam->result_ready = 1;
2235     }
2236 }
2237
2238 static void vl_api_gpe_add_del_fwd_entry_reply_t_handler_json
2239   (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
2240 {
2241   vat_main_t *vam = &vat_main;
2242   vat_json_node_t node;
2243
2244   vat_json_init_object (&node);
2245   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2246   vat_json_object_add_uint (&node, "fwd_entry_index",
2247                             clib_net_to_host_u32 (mp->fwd_entry_index));
2248
2249   vat_json_print (vam->ofp, &node);
2250   vat_json_free (&node);
2251
2252   vam->retval = ntohl (mp->retval);
2253   vam->result_ready = 1;
2254 }
2255
2256 u8 *
2257 format_lisp_transport_protocol (u8 * s, va_list * args)
2258 {
2259   u32 proto = va_arg (*args, u32);
2260
2261   switch (proto)
2262     {
2263     case 1:
2264       return format (s, "udp");
2265     case 2:
2266       return format (s, "api");
2267     default:
2268       return 0;
2269     }
2270   return 0;
2271 }
2272
2273 static void vl_api_one_get_transport_protocol_reply_t_handler
2274   (vl_api_one_get_transport_protocol_reply_t * mp)
2275 {
2276   vat_main_t *vam = &vat_main;
2277   i32 retval = ntohl (mp->retval);
2278   if (vam->async_mode)
2279     {
2280       vam->async_errors += (retval < 0);
2281     }
2282   else
2283     {
2284       u32 proto = mp->protocol;
2285       print (vam->ofp, "Transport protocol: %U",
2286              format_lisp_transport_protocol, proto);
2287       vam->retval = retval;
2288       vam->result_ready = 1;
2289     }
2290 }
2291
2292 static void vl_api_one_get_transport_protocol_reply_t_handler_json
2293   (vl_api_one_get_transport_protocol_reply_t * mp)
2294 {
2295   vat_main_t *vam = &vat_main;
2296   vat_json_node_t node;
2297   u8 *s;
2298
2299   s = format (0, "%U", format_lisp_transport_protocol, mp->protocol);
2300   vec_add1 (s, 0);
2301
2302   vat_json_init_object (&node);
2303   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2304   vat_json_object_add_string_copy (&node, "transport-protocol", s);
2305
2306   vec_free (s);
2307   vat_json_print (vam->ofp, &node);
2308   vat_json_free (&node);
2309
2310   vam->retval = ntohl (mp->retval);
2311   vam->result_ready = 1;
2312 }
2313
2314 static void vl_api_one_add_del_locator_set_reply_t_handler
2315   (vl_api_one_add_del_locator_set_reply_t * mp)
2316 {
2317   vat_main_t *vam = &vat_main;
2318   i32 retval = ntohl (mp->retval);
2319   if (vam->async_mode)
2320     {
2321       vam->async_errors += (retval < 0);
2322     }
2323   else
2324     {
2325       vam->retval = retval;
2326       vam->result_ready = 1;
2327     }
2328 }
2329
2330 static void vl_api_one_add_del_locator_set_reply_t_handler_json
2331   (vl_api_one_add_del_locator_set_reply_t * mp)
2332 {
2333   vat_main_t *vam = &vat_main;
2334   vat_json_node_t node;
2335
2336   vat_json_init_object (&node);
2337   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2338   vat_json_object_add_uint (&node, "locator_set_index", ntohl (mp->ls_index));
2339
2340   vat_json_print (vam->ofp, &node);
2341   vat_json_free (&node);
2342
2343   vam->retval = ntohl (mp->retval);
2344   vam->result_ready = 1;
2345 }
2346
2347 static void vl_api_vxlan_add_del_tunnel_reply_t_handler
2348   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
2349 {
2350   vat_main_t *vam = &vat_main;
2351   i32 retval = ntohl (mp->retval);
2352   if (vam->async_mode)
2353     {
2354       vam->async_errors += (retval < 0);
2355     }
2356   else
2357     {
2358       vam->retval = retval;
2359       vam->sw_if_index = ntohl (mp->sw_if_index);
2360       vam->result_ready = 1;
2361     }
2362   vam->regenerate_interface_table = 1;
2363 }
2364
2365 static void vl_api_vxlan_add_del_tunnel_reply_t_handler_json
2366   (vl_api_vxlan_add_del_tunnel_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, "sw_if_index", ntohl (mp->sw_if_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_offload_rx_reply_t_handler
2383   (vl_api_vxlan_offload_rx_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->result_ready = 1;
2395     }
2396 }
2397
2398 static void vl_api_vxlan_offload_rx_reply_t_handler_json
2399   (vl_api_vxlan_offload_rx_reply_t * mp)
2400 {
2401   vat_main_t *vam = &vat_main;
2402   vat_json_node_t node;
2403
2404   vat_json_init_object (&node);
2405   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2406
2407   vat_json_print (vam->ofp, &node);
2408   vat_json_free (&node);
2409
2410   vam->retval = ntohl (mp->retval);
2411   vam->result_ready = 1;
2412 }
2413
2414 static void vl_api_geneve_add_del_tunnel_reply_t_handler
2415   (vl_api_geneve_add_del_tunnel_reply_t * mp)
2416 {
2417   vat_main_t *vam = &vat_main;
2418   i32 retval = ntohl (mp->retval);
2419   if (vam->async_mode)
2420     {
2421       vam->async_errors += (retval < 0);
2422     }
2423   else
2424     {
2425       vam->retval = retval;
2426       vam->sw_if_index = ntohl (mp->sw_if_index);
2427       vam->result_ready = 1;
2428     }
2429 }
2430
2431 static void vl_api_geneve_add_del_tunnel_reply_t_handler_json
2432   (vl_api_geneve_add_del_tunnel_reply_t * mp)
2433 {
2434   vat_main_t *vam = &vat_main;
2435   vat_json_node_t node;
2436
2437   vat_json_init_object (&node);
2438   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2439   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2440
2441   vat_json_print (vam->ofp, &node);
2442   vat_json_free (&node);
2443
2444   vam->retval = ntohl (mp->retval);
2445   vam->result_ready = 1;
2446 }
2447
2448 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler
2449   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
2450 {
2451   vat_main_t *vam = &vat_main;
2452   i32 retval = ntohl (mp->retval);
2453   if (vam->async_mode)
2454     {
2455       vam->async_errors += (retval < 0);
2456     }
2457   else
2458     {
2459       vam->retval = retval;
2460       vam->sw_if_index = ntohl (mp->sw_if_index);
2461       vam->result_ready = 1;
2462     }
2463   vam->regenerate_interface_table = 1;
2464 }
2465
2466 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler_json
2467   (vl_api_vxlan_gpe_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_gre_tunnel_add_del_reply_t_handler
2484   (vl_api_gre_tunnel_add_del_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 }
2499
2500 static void vl_api_gre_tunnel_add_del_reply_t_handler_json
2501   (vl_api_gre_tunnel_add_del_reply_t * mp)
2502 {
2503   vat_main_t *vam = &vat_main;
2504   vat_json_node_t node;
2505
2506   vat_json_init_object (&node);
2507   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2508   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2509
2510   vat_json_print (vam->ofp, &node);
2511   vat_json_free (&node);
2512
2513   vam->retval = ntohl (mp->retval);
2514   vam->result_ready = 1;
2515 }
2516
2517 static void vl_api_create_vhost_user_if_reply_t_handler
2518   (vl_api_create_vhost_user_if_reply_t * mp)
2519 {
2520   vat_main_t *vam = &vat_main;
2521   i32 retval = ntohl (mp->retval);
2522   if (vam->async_mode)
2523     {
2524       vam->async_errors += (retval < 0);
2525     }
2526   else
2527     {
2528       vam->retval = retval;
2529       vam->sw_if_index = ntohl (mp->sw_if_index);
2530       vam->result_ready = 1;
2531     }
2532   vam->regenerate_interface_table = 1;
2533 }
2534
2535 static void vl_api_create_vhost_user_if_reply_t_handler_json
2536   (vl_api_create_vhost_user_if_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_ip_address_details_t_handler
2553   (vl_api_ip_address_details_t * mp)
2554 {
2555   vat_main_t *vam = &vat_main;
2556   static ip_address_details_t empty_ip_address_details = { {0} };
2557   ip_address_details_t *address = NULL;
2558   ip_details_t *current_ip_details = NULL;
2559   ip_details_t *details = NULL;
2560
2561   details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
2562
2563   if (!details || vam->current_sw_if_index >= vec_len (details)
2564       || !details[vam->current_sw_if_index].present)
2565     {
2566       errmsg ("ip address details arrived but not stored");
2567       errmsg ("ip_dump should be called first");
2568       return;
2569     }
2570
2571   current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
2572
2573 #define addresses (current_ip_details->addr)
2574
2575   vec_validate_init_empty (addresses, vec_len (addresses),
2576                            empty_ip_address_details);
2577
2578   address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
2579
2580   clib_memcpy (&address->ip, &mp->prefix.address.un, sizeof (address->ip));
2581   address->prefix_length = mp->prefix.len;
2582 #undef addresses
2583 }
2584
2585 static void vl_api_ip_address_details_t_handler_json
2586   (vl_api_ip_address_details_t * mp)
2587 {
2588   vat_main_t *vam = &vat_main;
2589   vat_json_node_t *node = NULL;
2590
2591   if (VAT_JSON_ARRAY != vam->json_tree.type)
2592     {
2593       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2594       vat_json_init_array (&vam->json_tree);
2595     }
2596   node = vat_json_array_add (&vam->json_tree);
2597
2598   vat_json_init_object (node);
2599   vat_json_object_add_prefix (node, &mp->prefix);
2600 }
2601
2602 static void
2603 vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
2604 {
2605   vat_main_t *vam = &vat_main;
2606   static ip_details_t empty_ip_details = { 0 };
2607   ip_details_t *ip = NULL;
2608   u32 sw_if_index = ~0;
2609
2610   sw_if_index = ntohl (mp->sw_if_index);
2611
2612   vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2613                            sw_if_index, empty_ip_details);
2614
2615   ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2616                          sw_if_index);
2617
2618   ip->present = 1;
2619 }
2620
2621 static void
2622 vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
2623 {
2624   vat_main_t *vam = &vat_main;
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   vat_json_array_add_uint (&vam->json_tree,
2632                            clib_net_to_host_u32 (mp->sw_if_index));
2633 }
2634
2635 static void vl_api_get_first_msg_id_reply_t_handler
2636   (vl_api_get_first_msg_id_reply_t * mp)
2637 {
2638   vat_main_t *vam = &vat_main;
2639   i32 retval = ntohl (mp->retval);
2640
2641   if (vam->async_mode)
2642     {
2643       vam->async_errors += (retval < 0);
2644     }
2645   else
2646     {
2647       vam->retval = retval;
2648       vam->result_ready = 1;
2649     }
2650   if (retval >= 0)
2651     {
2652       errmsg ("first message id %d", ntohs (mp->first_msg_id));
2653     }
2654 }
2655
2656 static void vl_api_get_first_msg_id_reply_t_handler_json
2657   (vl_api_get_first_msg_id_reply_t * mp)
2658 {
2659   vat_main_t *vam = &vat_main;
2660   vat_json_node_t node;
2661
2662   vat_json_init_object (&node);
2663   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2664   vat_json_object_add_uint (&node, "first_msg_id",
2665                             (uint) ntohs (mp->first_msg_id));
2666
2667   vat_json_print (vam->ofp, &node);
2668   vat_json_free (&node);
2669
2670   vam->retval = ntohl (mp->retval);
2671   vam->result_ready = 1;
2672 }
2673
2674 static void vl_api_get_node_graph_reply_t_handler
2675   (vl_api_get_node_graph_reply_t * mp)
2676 {
2677   vat_main_t *vam = &vat_main;
2678   i32 retval = ntohl (mp->retval);
2679   u8 *pvt_copy, *reply;
2680   void *oldheap;
2681   vlib_node_t *node;
2682   int i;
2683
2684   if (vam->async_mode)
2685     {
2686       vam->async_errors += (retval < 0);
2687     }
2688   else
2689     {
2690       vam->retval = retval;
2691       vam->result_ready = 1;
2692     }
2693
2694   /* "Should never happen..." */
2695   if (retval != 0)
2696     return;
2697
2698   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2699   pvt_copy = vec_dup (reply);
2700
2701   /* Toss the shared-memory original... */
2702   oldheap = vl_msg_push_heap ();
2703
2704   vec_free (reply);
2705
2706   vl_msg_pop_heap (oldheap);
2707
2708   if (vam->graph_nodes)
2709     {
2710       hash_free (vam->graph_node_index_by_name);
2711
2712       for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
2713         {
2714           node = vam->graph_nodes[0][i];
2715           vec_free (node->name);
2716           vec_free (node->next_nodes);
2717           vec_free (node);
2718         }
2719       vec_free (vam->graph_nodes[0]);
2720       vec_free (vam->graph_nodes);
2721     }
2722
2723   vam->graph_node_index_by_name = hash_create_string (0, sizeof (uword));
2724   vam->graph_nodes = vlib_node_unserialize (pvt_copy);
2725   vec_free (pvt_copy);
2726
2727   for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
2728     {
2729       node = vam->graph_nodes[0][i];
2730       hash_set_mem (vam->graph_node_index_by_name, node->name, i);
2731     }
2732 }
2733
2734 static void vl_api_get_node_graph_reply_t_handler_json
2735   (vl_api_get_node_graph_reply_t * mp)
2736 {
2737   vat_main_t *vam = &vat_main;
2738   void *oldheap;
2739   vat_json_node_t node;
2740   u8 *reply;
2741
2742   /* $$$$ make this real? */
2743   vat_json_init_object (&node);
2744   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2745   vat_json_object_add_uint (&node, "reply_in_shmem", mp->reply_in_shmem);
2746
2747   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2748
2749   /* Toss the shared-memory original... */
2750   oldheap = vl_msg_push_heap ();
2751
2752   vec_free (reply);
2753
2754   vl_msg_pop_heap (oldheap);
2755
2756   vat_json_print (vam->ofp, &node);
2757   vat_json_free (&node);
2758
2759   vam->retval = ntohl (mp->retval);
2760   vam->result_ready = 1;
2761 }
2762
2763 static void
2764 vl_api_one_locator_details_t_handler (vl_api_one_locator_details_t * mp)
2765 {
2766   vat_main_t *vam = &vat_main;
2767   u8 *s = 0;
2768
2769   if (mp->local)
2770     {
2771       s = format (s, "%=16d%=16d%=16d",
2772                   ntohl (mp->sw_if_index), mp->priority, mp->weight);
2773     }
2774   else
2775     {
2776       s = format (s, "%=16U%=16d%=16d",
2777                   mp->is_ipv6 ? format_ip6_address :
2778                   format_ip4_address,
2779                   mp->ip_address, mp->priority, mp->weight);
2780     }
2781
2782   print (vam->ofp, "%v", s);
2783   vec_free (s);
2784 }
2785
2786 static void
2787 vl_api_one_locator_details_t_handler_json (vl_api_one_locator_details_t * mp)
2788 {
2789   vat_main_t *vam = &vat_main;
2790   vat_json_node_t *node = NULL;
2791   struct in6_addr ip6;
2792   struct in_addr ip4;
2793
2794   if (VAT_JSON_ARRAY != vam->json_tree.type)
2795     {
2796       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2797       vat_json_init_array (&vam->json_tree);
2798     }
2799   node = vat_json_array_add (&vam->json_tree);
2800   vat_json_init_object (node);
2801
2802   vat_json_object_add_uint (node, "local", mp->local ? 1 : 0);
2803   vat_json_object_add_uint (node, "priority", mp->priority);
2804   vat_json_object_add_uint (node, "weight", mp->weight);
2805
2806   if (mp->local)
2807     vat_json_object_add_uint (node, "sw_if_index",
2808                               clib_net_to_host_u32 (mp->sw_if_index));
2809   else
2810     {
2811       if (mp->is_ipv6)
2812         {
2813           clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2814           vat_json_object_add_ip6 (node, "address", ip6);
2815         }
2816       else
2817         {
2818           clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2819           vat_json_object_add_ip4 (node, "address", ip4);
2820         }
2821     }
2822 }
2823
2824 static void
2825 vl_api_one_locator_set_details_t_handler (vl_api_one_locator_set_details_t *
2826                                           mp)
2827 {
2828   vat_main_t *vam = &vat_main;
2829   u8 *ls_name = 0;
2830
2831   ls_name = format (0, "%s", mp->ls_name);
2832
2833   print (vam->ofp, "%=10d%=15v", clib_net_to_host_u32 (mp->ls_index),
2834          ls_name);
2835   vec_free (ls_name);
2836 }
2837
2838 static void
2839   vl_api_one_locator_set_details_t_handler_json
2840   (vl_api_one_locator_set_details_t * mp)
2841 {
2842   vat_main_t *vam = &vat_main;
2843   vat_json_node_t *node = 0;
2844   u8 *ls_name = 0;
2845
2846   ls_name = format (0, "%s", mp->ls_name);
2847   vec_add1 (ls_name, 0);
2848
2849   if (VAT_JSON_ARRAY != vam->json_tree.type)
2850     {
2851       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2852       vat_json_init_array (&vam->json_tree);
2853     }
2854   node = vat_json_array_add (&vam->json_tree);
2855
2856   vat_json_init_object (node);
2857   vat_json_object_add_string_copy (node, "ls_name", ls_name);
2858   vat_json_object_add_uint (node, "ls_index",
2859                             clib_net_to_host_u32 (mp->ls_index));
2860   vec_free (ls_name);
2861 }
2862
2863 typedef struct
2864 {
2865   u32 spi;
2866   u8 si;
2867 } __attribute__ ((__packed__)) lisp_nsh_api_t;
2868
2869 uword
2870 unformat_nsh_address (unformat_input_t * input, va_list * args)
2871 {
2872   lisp_nsh_api_t *nsh = va_arg (*args, lisp_nsh_api_t *);
2873   return unformat (input, "SPI:%d SI:%d", &nsh->spi, &nsh->si);
2874 }
2875
2876 u8 *
2877 format_nsh_address_vat (u8 * s, va_list * args)
2878 {
2879   nsh_t *a = va_arg (*args, nsh_t *);
2880   return format (s, "SPI:%d SI:%d", clib_net_to_host_u32 (a->spi), a->si);
2881 }
2882
2883 static u8 *
2884 format_lisp_flat_eid (u8 * s, va_list * args)
2885 {
2886   u32 type = va_arg (*args, u32);
2887   u8 *eid = va_arg (*args, u8 *);
2888   u32 eid_len = va_arg (*args, u32);
2889
2890   switch (type)
2891     {
2892     case 0:
2893       return format (s, "%U/%d", format_ip4_address, eid, eid_len);
2894     case 1:
2895       return format (s, "%U/%d", format_ip6_address, eid, eid_len);
2896     case 2:
2897       return format (s, "%U", format_ethernet_address, eid);
2898     case 3:
2899       return format (s, "%U", format_nsh_address_vat, eid);
2900     }
2901   return 0;
2902 }
2903
2904 static u8 *
2905 format_lisp_eid_vat (u8 * s, va_list * args)
2906 {
2907   u32 type = va_arg (*args, u32);
2908   u8 *eid = va_arg (*args, u8 *);
2909   u32 eid_len = va_arg (*args, u32);
2910   u8 *seid = va_arg (*args, u8 *);
2911   u32 seid_len = va_arg (*args, u32);
2912   u32 is_src_dst = va_arg (*args, u32);
2913
2914   if (is_src_dst)
2915     s = format (s, "%U|", format_lisp_flat_eid, type, seid, seid_len);
2916
2917   s = format (s, "%U", format_lisp_flat_eid, type, eid, eid_len);
2918
2919   return s;
2920 }
2921
2922 static void
2923 vl_api_one_eid_table_details_t_handler (vl_api_one_eid_table_details_t * mp)
2924 {
2925   vat_main_t *vam = &vat_main;
2926   u8 *s = 0, *eid = 0;
2927
2928   if (~0 == mp->locator_set_index)
2929     s = format (0, "action: %d", mp->action);
2930   else
2931     s = format (0, "%d", clib_net_to_host_u32 (mp->locator_set_index));
2932
2933   eid = format (0, "%U", format_lisp_eid_vat,
2934                 mp->eid_type,
2935                 mp->eid,
2936                 mp->eid_prefix_len,
2937                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
2938   vec_add1 (eid, 0);
2939
2940   print (vam->ofp, "[%d] %-35s%-20s%-30s%-20d%-20d%-10d%-20s",
2941          clib_net_to_host_u32 (mp->vni),
2942          eid,
2943          mp->is_local ? "local" : "remote",
2944          s, clib_net_to_host_u32 (mp->ttl), mp->authoritative,
2945          clib_net_to_host_u16 (mp->key_id), mp->key);
2946
2947   vec_free (s);
2948   vec_free (eid);
2949 }
2950
2951 static void
2952 vl_api_one_eid_table_details_t_handler_json (vl_api_one_eid_table_details_t
2953                                              * mp)
2954 {
2955   vat_main_t *vam = &vat_main;
2956   vat_json_node_t *node = 0;
2957   u8 *eid = 0;
2958
2959   if (VAT_JSON_ARRAY != vam->json_tree.type)
2960     {
2961       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2962       vat_json_init_array (&vam->json_tree);
2963     }
2964   node = vat_json_array_add (&vam->json_tree);
2965
2966   vat_json_init_object (node);
2967   if (~0 == mp->locator_set_index)
2968     vat_json_object_add_uint (node, "action", mp->action);
2969   else
2970     vat_json_object_add_uint (node, "locator_set_index",
2971                               clib_net_to_host_u32 (mp->locator_set_index));
2972
2973   vat_json_object_add_uint (node, "is_local", mp->is_local ? 1 : 0);
2974   if (mp->eid_type == 3)
2975     {
2976       vat_json_node_t *nsh_json = vat_json_object_add (node, "eid");
2977       vat_json_init_object (nsh_json);
2978       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) mp->eid;
2979       vat_json_object_add_uint (nsh_json, "spi",
2980                                 clib_net_to_host_u32 (nsh->spi));
2981       vat_json_object_add_uint (nsh_json, "si", nsh->si);
2982     }
2983   else
2984     {
2985       eid = format (0, "%U", format_lisp_eid_vat,
2986                     mp->eid_type,
2987                     mp->eid,
2988                     mp->eid_prefix_len,
2989                     mp->seid, mp->seid_prefix_len, mp->is_src_dst);
2990       vec_add1 (eid, 0);
2991       vat_json_object_add_string_copy (node, "eid", eid);
2992       vec_free (eid);
2993     }
2994   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2995   vat_json_object_add_uint (node, "ttl", clib_net_to_host_u32 (mp->ttl));
2996   vat_json_object_add_uint (node, "authoritative", (mp->authoritative));
2997
2998   if (mp->key_id)
2999     {
3000       vat_json_object_add_uint (node, "key_id",
3001                                 clib_net_to_host_u16 (mp->key_id));
3002       vat_json_object_add_string_copy (node, "key", mp->key);
3003     }
3004 }
3005
3006 static void
3007 vl_api_one_stats_details_t_handler (vl_api_one_stats_details_t * mp)
3008 {
3009   vat_main_t *vam = &vat_main;
3010   u8 *seid = 0, *deid = 0;
3011   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3012
3013   deid = format (0, "%U", format_lisp_eid_vat,
3014                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
3015
3016   seid = format (0, "%U", format_lisp_eid_vat,
3017                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
3018
3019   vec_add1 (deid, 0);
3020   vec_add1 (seid, 0);
3021
3022   if (mp->is_ip4)
3023     format_ip_address_fcn = format_ip4_address;
3024   else
3025     format_ip_address_fcn = format_ip6_address;
3026
3027
3028   print (vam->ofp, "([%d] %s %s) (%U %U) %u %u",
3029          clib_net_to_host_u32 (mp->vni),
3030          seid, deid,
3031          format_ip_address_fcn, mp->lloc,
3032          format_ip_address_fcn, mp->rloc,
3033          clib_net_to_host_u32 (mp->pkt_count),
3034          clib_net_to_host_u32 (mp->bytes));
3035
3036   vec_free (deid);
3037   vec_free (seid);
3038 }
3039
3040 static void
3041 vl_api_one_stats_details_t_handler_json (vl_api_one_stats_details_t * mp)
3042 {
3043   struct in6_addr ip6;
3044   struct in_addr ip4;
3045   vat_main_t *vam = &vat_main;
3046   vat_json_node_t *node = 0;
3047   u8 *deid = 0, *seid = 0;
3048
3049   if (VAT_JSON_ARRAY != vam->json_tree.type)
3050     {
3051       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3052       vat_json_init_array (&vam->json_tree);
3053     }
3054   node = vat_json_array_add (&vam->json_tree);
3055
3056   vat_json_init_object (node);
3057   deid = format (0, "%U", format_lisp_eid_vat,
3058                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
3059
3060   seid = format (0, "%U", format_lisp_eid_vat,
3061                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
3062
3063   vec_add1 (deid, 0);
3064   vec_add1 (seid, 0);
3065
3066   vat_json_object_add_string_copy (node, "seid", seid);
3067   vat_json_object_add_string_copy (node, "deid", deid);
3068   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3069
3070   if (mp->is_ip4)
3071     {
3072       clib_memcpy (&ip4, mp->lloc, sizeof (ip4));
3073       vat_json_object_add_ip4 (node, "lloc", ip4);
3074       clib_memcpy (&ip4, mp->rloc, sizeof (ip4));
3075       vat_json_object_add_ip4 (node, "rloc", ip4);
3076     }
3077   else
3078     {
3079       clib_memcpy (&ip6, mp->lloc, sizeof (ip6));
3080       vat_json_object_add_ip6 (node, "lloc", ip6);
3081       clib_memcpy (&ip6, mp->rloc, sizeof (ip6));
3082       vat_json_object_add_ip6 (node, "rloc", ip6);
3083     }
3084   vat_json_object_add_uint (node, "pkt_count",
3085                             clib_net_to_host_u32 (mp->pkt_count));
3086   vat_json_object_add_uint (node, "bytes", clib_net_to_host_u32 (mp->bytes));
3087
3088   vec_free (deid);
3089   vec_free (seid);
3090 }
3091
3092 static void
3093   vl_api_one_eid_table_map_details_t_handler
3094   (vl_api_one_eid_table_map_details_t * mp)
3095 {
3096   vat_main_t *vam = &vat_main;
3097
3098   u8 *line = format (0, "%=10d%=10d",
3099                      clib_net_to_host_u32 (mp->vni),
3100                      clib_net_to_host_u32 (mp->dp_table));
3101   print (vam->ofp, "%v", line);
3102   vec_free (line);
3103 }
3104
3105 static void
3106   vl_api_one_eid_table_map_details_t_handler_json
3107   (vl_api_one_eid_table_map_details_t * mp)
3108 {
3109   vat_main_t *vam = &vat_main;
3110   vat_json_node_t *node = NULL;
3111
3112   if (VAT_JSON_ARRAY != vam->json_tree.type)
3113     {
3114       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3115       vat_json_init_array (&vam->json_tree);
3116     }
3117   node = vat_json_array_add (&vam->json_tree);
3118   vat_json_init_object (node);
3119   vat_json_object_add_uint (node, "dp_table",
3120                             clib_net_to_host_u32 (mp->dp_table));
3121   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3122 }
3123
3124 static void
3125   vl_api_one_eid_table_vni_details_t_handler
3126   (vl_api_one_eid_table_vni_details_t * mp)
3127 {
3128   vat_main_t *vam = &vat_main;
3129
3130   u8 *line = format (0, "%d", clib_net_to_host_u32 (mp->vni));
3131   print (vam->ofp, "%v", line);
3132   vec_free (line);
3133 }
3134
3135 static void
3136   vl_api_one_eid_table_vni_details_t_handler_json
3137   (vl_api_one_eid_table_vni_details_t * mp)
3138 {
3139   vat_main_t *vam = &vat_main;
3140   vat_json_node_t *node = NULL;
3141
3142   if (VAT_JSON_ARRAY != vam->json_tree.type)
3143     {
3144       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3145       vat_json_init_array (&vam->json_tree);
3146     }
3147   node = vat_json_array_add (&vam->json_tree);
3148   vat_json_init_object (node);
3149   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3150 }
3151
3152 static void
3153   vl_api_show_one_map_register_fallback_threshold_reply_t_handler
3154   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
3155 {
3156   vat_main_t *vam = &vat_main;
3157   int retval = clib_net_to_host_u32 (mp->retval);
3158
3159   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
3160   print (vam->ofp, "fallback threshold value: %d", mp->value);
3161
3162   vam->retval = retval;
3163   vam->result_ready = 1;
3164 }
3165
3166 static void
3167   vl_api_show_one_map_register_fallback_threshold_reply_t_handler_json
3168   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
3169 {
3170   vat_main_t *vam = &vat_main;
3171   vat_json_node_t _node, *node = &_node;
3172   int retval = clib_net_to_host_u32 (mp->retval);
3173
3174   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
3175   vat_json_init_object (node);
3176   vat_json_object_add_uint (node, "value", mp->value);
3177
3178   vat_json_print (vam->ofp, node);
3179   vat_json_free (node);
3180
3181   vam->retval = retval;
3182   vam->result_ready = 1;
3183 }
3184
3185 static void
3186   vl_api_show_one_map_register_state_reply_t_handler
3187   (vl_api_show_one_map_register_state_reply_t * mp)
3188 {
3189   vat_main_t *vam = &vat_main;
3190   int retval = clib_net_to_host_u32 (mp->retval);
3191
3192   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
3193
3194   vam->retval = retval;
3195   vam->result_ready = 1;
3196 }
3197
3198 static void
3199   vl_api_show_one_map_register_state_reply_t_handler_json
3200   (vl_api_show_one_map_register_state_reply_t * mp)
3201 {
3202   vat_main_t *vam = &vat_main;
3203   vat_json_node_t _node, *node = &_node;
3204   int retval = clib_net_to_host_u32 (mp->retval);
3205
3206   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
3207
3208   vat_json_init_object (node);
3209   vat_json_object_add_string_copy (node, "state", s);
3210
3211   vat_json_print (vam->ofp, node);
3212   vat_json_free (node);
3213
3214   vam->retval = retval;
3215   vam->result_ready = 1;
3216   vec_free (s);
3217 }
3218
3219 static void
3220   vl_api_show_one_rloc_probe_state_reply_t_handler
3221   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3222 {
3223   vat_main_t *vam = &vat_main;
3224   int retval = clib_net_to_host_u32 (mp->retval);
3225
3226   if (retval)
3227     goto end;
3228
3229   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
3230 end:
3231   vam->retval = retval;
3232   vam->result_ready = 1;
3233 }
3234
3235 static void
3236   vl_api_show_one_rloc_probe_state_reply_t_handler_json
3237   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3238 {
3239   vat_main_t *vam = &vat_main;
3240   vat_json_node_t _node, *node = &_node;
3241   int retval = clib_net_to_host_u32 (mp->retval);
3242
3243   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
3244   vat_json_init_object (node);
3245   vat_json_object_add_string_copy (node, "state", s);
3246
3247   vat_json_print (vam->ofp, node);
3248   vat_json_free (node);
3249
3250   vam->retval = retval;
3251   vam->result_ready = 1;
3252   vec_free (s);
3253 }
3254
3255 static void
3256   vl_api_show_one_stats_enable_disable_reply_t_handler
3257   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3258 {
3259   vat_main_t *vam = &vat_main;
3260   int retval = clib_net_to_host_u32 (mp->retval);
3261
3262   if (retval)
3263     goto end;
3264
3265   print (vam->ofp, "%s", mp->is_en ? "enabled" : "disabled");
3266 end:
3267   vam->retval = retval;
3268   vam->result_ready = 1;
3269 }
3270
3271 static void
3272   vl_api_show_one_stats_enable_disable_reply_t_handler_json
3273   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3274 {
3275   vat_main_t *vam = &vat_main;
3276   vat_json_node_t _node, *node = &_node;
3277   int retval = clib_net_to_host_u32 (mp->retval);
3278
3279   u8 *s = format (0, "%s", mp->is_en ? "enabled" : "disabled");
3280   vat_json_init_object (node);
3281   vat_json_object_add_string_copy (node, "state", s);
3282
3283   vat_json_print (vam->ofp, node);
3284   vat_json_free (node);
3285
3286   vam->retval = retval;
3287   vam->result_ready = 1;
3288   vec_free (s);
3289 }
3290
3291 static void
3292 api_gpe_fwd_entry_net_to_host (vl_api_gpe_fwd_entry_t * e)
3293 {
3294   e->dp_table = clib_net_to_host_u32 (e->dp_table);
3295   e->fwd_entry_index = clib_net_to_host_u32 (e->fwd_entry_index);
3296   e->vni = clib_net_to_host_u32 (e->vni);
3297 }
3298
3299 static void
3300   gpe_fwd_entries_get_reply_t_net_to_host
3301   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3302 {
3303   u32 i;
3304
3305   mp->count = clib_net_to_host_u32 (mp->count);
3306   for (i = 0; i < mp->count; i++)
3307     {
3308       api_gpe_fwd_entry_net_to_host (&mp->entries[i]);
3309     }
3310 }
3311
3312 static u8 *
3313 format_gpe_encap_mode (u8 * s, va_list * args)
3314 {
3315   u32 mode = va_arg (*args, u32);
3316
3317   switch (mode)
3318     {
3319     case 0:
3320       return format (s, "lisp");
3321     case 1:
3322       return format (s, "vxlan");
3323     }
3324   return 0;
3325 }
3326
3327 static void
3328   vl_api_gpe_get_encap_mode_reply_t_handler
3329   (vl_api_gpe_get_encap_mode_reply_t * mp)
3330 {
3331   vat_main_t *vam = &vat_main;
3332
3333   print (vam->ofp, "gpe mode: %U", format_gpe_encap_mode, mp->encap_mode);
3334   vam->retval = ntohl (mp->retval);
3335   vam->result_ready = 1;
3336 }
3337
3338 static void
3339   vl_api_gpe_get_encap_mode_reply_t_handler_json
3340   (vl_api_gpe_get_encap_mode_reply_t * mp)
3341 {
3342   vat_main_t *vam = &vat_main;
3343   vat_json_node_t node;
3344
3345   u8 *encap_mode = format (0, "%U", format_gpe_encap_mode, mp->encap_mode);
3346   vec_add1 (encap_mode, 0);
3347
3348   vat_json_init_object (&node);
3349   vat_json_object_add_string_copy (&node, "gpe_mode", encap_mode);
3350
3351   vec_free (encap_mode);
3352   vat_json_print (vam->ofp, &node);
3353   vat_json_free (&node);
3354
3355   vam->retval = ntohl (mp->retval);
3356   vam->result_ready = 1;
3357 }
3358
3359 static void
3360   vl_api_gpe_fwd_entry_path_details_t_handler
3361   (vl_api_gpe_fwd_entry_path_details_t * mp)
3362 {
3363   vat_main_t *vam = &vat_main;
3364   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3365
3366   if (mp->lcl_loc.is_ip4)
3367     format_ip_address_fcn = format_ip4_address;
3368   else
3369     format_ip_address_fcn = format_ip6_address;
3370
3371   print (vam->ofp, "w:%d %30U %30U", mp->rmt_loc.weight,
3372          format_ip_address_fcn, &mp->lcl_loc,
3373          format_ip_address_fcn, &mp->rmt_loc);
3374 }
3375
3376 static void
3377 lisp_fill_locator_node (vat_json_node_t * n, vl_api_gpe_locator_t * loc)
3378 {
3379   struct in6_addr ip6;
3380   struct in_addr ip4;
3381
3382   if (loc->is_ip4)
3383     {
3384       clib_memcpy (&ip4, loc->addr, sizeof (ip4));
3385       vat_json_object_add_ip4 (n, "address", ip4);
3386     }
3387   else
3388     {
3389       clib_memcpy (&ip6, loc->addr, sizeof (ip6));
3390       vat_json_object_add_ip6 (n, "address", ip6);
3391     }
3392   vat_json_object_add_uint (n, "weight", loc->weight);
3393 }
3394
3395 static void
3396   vl_api_gpe_fwd_entry_path_details_t_handler_json
3397   (vl_api_gpe_fwd_entry_path_details_t * mp)
3398 {
3399   vat_main_t *vam = &vat_main;
3400   vat_json_node_t *node = NULL;
3401   vat_json_node_t *loc_node;
3402
3403   if (VAT_JSON_ARRAY != vam->json_tree.type)
3404     {
3405       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3406       vat_json_init_array (&vam->json_tree);
3407     }
3408   node = vat_json_array_add (&vam->json_tree);
3409   vat_json_init_object (node);
3410
3411   loc_node = vat_json_object_add (node, "local_locator");
3412   vat_json_init_object (loc_node);
3413   lisp_fill_locator_node (loc_node, &mp->lcl_loc);
3414
3415   loc_node = vat_json_object_add (node, "remote_locator");
3416   vat_json_init_object (loc_node);
3417   lisp_fill_locator_node (loc_node, &mp->rmt_loc);
3418 }
3419
3420 static void
3421   vl_api_gpe_fwd_entries_get_reply_t_handler
3422   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3423 {
3424   vat_main_t *vam = &vat_main;
3425   u32 i;
3426   int retval = clib_net_to_host_u32 (mp->retval);
3427   vl_api_gpe_fwd_entry_t *e;
3428
3429   if (retval)
3430     goto end;
3431
3432   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3433
3434   for (i = 0; i < mp->count; i++)
3435     {
3436       e = &mp->entries[i];
3437       print (vam->ofp, "%10d %10d %U %40U", e->fwd_entry_index, e->dp_table,
3438              format_lisp_flat_eid, e->eid_type, e->leid, e->leid_prefix_len,
3439              format_lisp_flat_eid, e->eid_type, e->reid, e->reid_prefix_len);
3440     }
3441
3442 end:
3443   vam->retval = retval;
3444   vam->result_ready = 1;
3445 }
3446
3447 static void
3448   vl_api_gpe_fwd_entries_get_reply_t_handler_json
3449   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3450 {
3451   u8 *s = 0;
3452   vat_main_t *vam = &vat_main;
3453   vat_json_node_t *e = 0, root;
3454   u32 i;
3455   int retval = clib_net_to_host_u32 (mp->retval);
3456   vl_api_gpe_fwd_entry_t *fwd;
3457
3458   if (retval)
3459     goto end;
3460
3461   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3462   vat_json_init_array (&root);
3463
3464   for (i = 0; i < mp->count; i++)
3465     {
3466       e = vat_json_array_add (&root);
3467       fwd = &mp->entries[i];
3468
3469       vat_json_init_object (e);
3470       vat_json_object_add_int (e, "fwd_entry_index", fwd->fwd_entry_index);
3471       vat_json_object_add_int (e, "dp_table", fwd->dp_table);
3472       vat_json_object_add_int (e, "vni", fwd->vni);
3473       vat_json_object_add_int (e, "action", fwd->action);
3474
3475       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->leid,
3476                   fwd->leid_prefix_len);
3477       vec_add1 (s, 0);
3478       vat_json_object_add_string_copy (e, "leid", s);
3479       vec_free (s);
3480
3481       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->reid,
3482                   fwd->reid_prefix_len);
3483       vec_add1 (s, 0);
3484       vat_json_object_add_string_copy (e, "reid", s);
3485       vec_free (s);
3486     }
3487
3488   vat_json_print (vam->ofp, &root);
3489   vat_json_free (&root);
3490
3491 end:
3492   vam->retval = retval;
3493   vam->result_ready = 1;
3494 }
3495
3496 static void
3497   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler
3498   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3499 {
3500   vat_main_t *vam = &vat_main;
3501   u32 i, n;
3502   int retval = clib_net_to_host_u32 (mp->retval);
3503   vl_api_gpe_native_fwd_rpath_t *r;
3504
3505   if (retval)
3506     goto end;
3507
3508   n = clib_net_to_host_u32 (mp->count);
3509
3510   for (i = 0; i < n; i++)
3511     {
3512       r = &mp->entries[i];
3513       print (vam->ofp, "fib_index: %d sw_if_index %d nh %U",
3514              clib_net_to_host_u32 (r->fib_index),
3515              clib_net_to_host_u32 (r->nh_sw_if_index),
3516              r->is_ip4 ? format_ip4_address : format_ip6_address, r->nh_addr);
3517     }
3518
3519 end:
3520   vam->retval = retval;
3521   vam->result_ready = 1;
3522 }
3523
3524 static void
3525   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler_json
3526   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3527 {
3528   vat_main_t *vam = &vat_main;
3529   vat_json_node_t root, *e;
3530   u32 i, n;
3531   int retval = clib_net_to_host_u32 (mp->retval);
3532   vl_api_gpe_native_fwd_rpath_t *r;
3533   u8 *s;
3534
3535   if (retval)
3536     goto end;
3537
3538   n = clib_net_to_host_u32 (mp->count);
3539   vat_json_init_array (&root);
3540
3541   for (i = 0; i < n; i++)
3542     {
3543       e = vat_json_array_add (&root);
3544       vat_json_init_object (e);
3545       r = &mp->entries[i];
3546       s =
3547         format (0, "%U", r->is_ip4 ? format_ip4_address : format_ip6_address,
3548                 r->nh_addr);
3549       vec_add1 (s, 0);
3550       vat_json_object_add_string_copy (e, "ip4", s);
3551       vec_free (s);
3552
3553       vat_json_object_add_uint (e, "fib_index",
3554                                 clib_net_to_host_u32 (r->fib_index));
3555       vat_json_object_add_uint (e, "nh_sw_if_index",
3556                                 clib_net_to_host_u32 (r->nh_sw_if_index));
3557     }
3558
3559   vat_json_print (vam->ofp, &root);
3560   vat_json_free (&root);
3561
3562 end:
3563   vam->retval = retval;
3564   vam->result_ready = 1;
3565 }
3566
3567 static void
3568   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler
3569   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3570 {
3571   vat_main_t *vam = &vat_main;
3572   u32 i, n;
3573   int retval = clib_net_to_host_u32 (mp->retval);
3574
3575   if (retval)
3576     goto end;
3577
3578   n = clib_net_to_host_u32 (mp->count);
3579
3580   for (i = 0; i < n; i++)
3581     print (vam->ofp, "%d", clib_net_to_host_u32 (mp->vnis[i]));
3582
3583 end:
3584   vam->retval = retval;
3585   vam->result_ready = 1;
3586 }
3587
3588 static void
3589   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler_json
3590   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3591 {
3592   vat_main_t *vam = &vat_main;
3593   vat_json_node_t root;
3594   u32 i, n;
3595   int retval = clib_net_to_host_u32 (mp->retval);
3596
3597   if (retval)
3598     goto end;
3599
3600   n = clib_net_to_host_u32 (mp->count);
3601   vat_json_init_array (&root);
3602
3603   for (i = 0; i < n; i++)
3604     vat_json_array_add_uint (&root, clib_net_to_host_u32 (mp->vnis[i]));
3605
3606   vat_json_print (vam->ofp, &root);
3607   vat_json_free (&root);
3608
3609 end:
3610   vam->retval = retval;
3611   vam->result_ready = 1;
3612 }
3613
3614 static void
3615   vl_api_one_ndp_entries_get_reply_t_handler
3616   (vl_api_one_ndp_entries_get_reply_t * mp)
3617 {
3618   vat_main_t *vam = &vat_main;
3619   u32 i, n;
3620   int retval = clib_net_to_host_u32 (mp->retval);
3621
3622   if (retval)
3623     goto end;
3624
3625   n = clib_net_to_host_u32 (mp->count);
3626
3627   for (i = 0; i < n; i++)
3628     print (vam->ofp, "%U -> %U", format_ip6_address, &mp->entries[i].ip6,
3629            format_ethernet_address, mp->entries[i].mac);
3630
3631 end:
3632   vam->retval = retval;
3633   vam->result_ready = 1;
3634 }
3635
3636 static void
3637   vl_api_one_ndp_entries_get_reply_t_handler_json
3638   (vl_api_one_ndp_entries_get_reply_t * mp)
3639 {
3640   u8 *s = 0;
3641   vat_main_t *vam = &vat_main;
3642   vat_json_node_t *e = 0, root;
3643   u32 i, n;
3644   int retval = clib_net_to_host_u32 (mp->retval);
3645   vl_api_one_ndp_entry_t *arp_entry;
3646
3647   if (retval)
3648     goto end;
3649
3650   n = clib_net_to_host_u32 (mp->count);
3651   vat_json_init_array (&root);
3652
3653   for (i = 0; i < n; i++)
3654     {
3655       e = vat_json_array_add (&root);
3656       arp_entry = &mp->entries[i];
3657
3658       vat_json_init_object (e);
3659       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
3660       vec_add1 (s, 0);
3661
3662       vat_json_object_add_string_copy (e, "mac", s);
3663       vec_free (s);
3664
3665       s = format (0, "%U", format_ip6_address, &arp_entry->ip6);
3666       vec_add1 (s, 0);
3667       vat_json_object_add_string_copy (e, "ip6", s);
3668       vec_free (s);
3669     }
3670
3671   vat_json_print (vam->ofp, &root);
3672   vat_json_free (&root);
3673
3674 end:
3675   vam->retval = retval;
3676   vam->result_ready = 1;
3677 }
3678
3679 static void
3680   vl_api_one_l2_arp_entries_get_reply_t_handler
3681   (vl_api_one_l2_arp_entries_get_reply_t * mp)
3682 {
3683   vat_main_t *vam = &vat_main;
3684   u32 i, n;
3685   int retval = clib_net_to_host_u32 (mp->retval);
3686
3687   if (retval)
3688     goto end;
3689
3690   n = clib_net_to_host_u32 (mp->count);
3691
3692   for (i = 0; i < n; i++)
3693     print (vam->ofp, "%U -> %U", format_ip4_address, &mp->entries[i].ip4,
3694            format_ethernet_address, mp->entries[i].mac);
3695
3696 end:
3697   vam->retval = retval;
3698   vam->result_ready = 1;
3699 }
3700
3701 static void
3702   vl_api_one_l2_arp_entries_get_reply_t_handler_json
3703   (vl_api_one_l2_arp_entries_get_reply_t * mp)
3704 {
3705   u8 *s = 0;
3706   vat_main_t *vam = &vat_main;
3707   vat_json_node_t *e = 0, root;
3708   u32 i, n;
3709   int retval = clib_net_to_host_u32 (mp->retval);
3710   vl_api_one_l2_arp_entry_t *arp_entry;
3711
3712   if (retval)
3713     goto end;
3714
3715   n = clib_net_to_host_u32 (mp->count);
3716   vat_json_init_array (&root);
3717
3718   for (i = 0; i < n; i++)
3719     {
3720       e = vat_json_array_add (&root);
3721       arp_entry = &mp->entries[i];
3722
3723       vat_json_init_object (e);
3724       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
3725       vec_add1 (s, 0);
3726
3727       vat_json_object_add_string_copy (e, "mac", s);
3728       vec_free (s);
3729
3730       s = format (0, "%U", format_ip4_address, &arp_entry->ip4);
3731       vec_add1 (s, 0);
3732       vat_json_object_add_string_copy (e, "ip4", s);
3733       vec_free (s);
3734     }
3735
3736   vat_json_print (vam->ofp, &root);
3737   vat_json_free (&root);
3738
3739 end:
3740   vam->retval = retval;
3741   vam->result_ready = 1;
3742 }
3743
3744 static void
3745 vl_api_one_ndp_bd_get_reply_t_handler (vl_api_one_ndp_bd_get_reply_t * mp)
3746 {
3747   vat_main_t *vam = &vat_main;
3748   u32 i, n;
3749   int retval = clib_net_to_host_u32 (mp->retval);
3750
3751   if (retval)
3752     goto end;
3753
3754   n = clib_net_to_host_u32 (mp->count);
3755
3756   for (i = 0; i < n; i++)
3757     {
3758       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
3759     }
3760
3761 end:
3762   vam->retval = retval;
3763   vam->result_ready = 1;
3764 }
3765
3766 static void
3767   vl_api_one_ndp_bd_get_reply_t_handler_json
3768   (vl_api_one_ndp_bd_get_reply_t * mp)
3769 {
3770   vat_main_t *vam = &vat_main;
3771   vat_json_node_t root;
3772   u32 i, n;
3773   int retval = clib_net_to_host_u32 (mp->retval);
3774
3775   if (retval)
3776     goto end;
3777
3778   n = clib_net_to_host_u32 (mp->count);
3779   vat_json_init_array (&root);
3780
3781   for (i = 0; i < n; i++)
3782     {
3783       vat_json_array_add_uint (&root,
3784                                clib_net_to_host_u32 (mp->bridge_domains[i]));
3785     }
3786
3787   vat_json_print (vam->ofp, &root);
3788   vat_json_free (&root);
3789
3790 end:
3791   vam->retval = retval;
3792   vam->result_ready = 1;
3793 }
3794
3795 static void
3796   vl_api_one_l2_arp_bd_get_reply_t_handler
3797   (vl_api_one_l2_arp_bd_get_reply_t * mp)
3798 {
3799   vat_main_t *vam = &vat_main;
3800   u32 i, n;
3801   int retval = clib_net_to_host_u32 (mp->retval);
3802
3803   if (retval)
3804     goto end;
3805
3806   n = clib_net_to_host_u32 (mp->count);
3807
3808   for (i = 0; i < n; i++)
3809     {
3810       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
3811     }
3812
3813 end:
3814   vam->retval = retval;
3815   vam->result_ready = 1;
3816 }
3817
3818 static void
3819   vl_api_one_l2_arp_bd_get_reply_t_handler_json
3820   (vl_api_one_l2_arp_bd_get_reply_t * mp)
3821 {
3822   vat_main_t *vam = &vat_main;
3823   vat_json_node_t root;
3824   u32 i, n;
3825   int retval = clib_net_to_host_u32 (mp->retval);
3826
3827   if (retval)
3828     goto end;
3829
3830   n = clib_net_to_host_u32 (mp->count);
3831   vat_json_init_array (&root);
3832
3833   for (i = 0; i < n; i++)
3834     {
3835       vat_json_array_add_uint (&root,
3836                                clib_net_to_host_u32 (mp->bridge_domains[i]));
3837     }
3838
3839   vat_json_print (vam->ofp, &root);
3840   vat_json_free (&root);
3841
3842 end:
3843   vam->retval = retval;
3844   vam->result_ready = 1;
3845 }
3846
3847 static void
3848   vl_api_one_adjacencies_get_reply_t_handler
3849   (vl_api_one_adjacencies_get_reply_t * mp)
3850 {
3851   vat_main_t *vam = &vat_main;
3852   u32 i, n;
3853   int retval = clib_net_to_host_u32 (mp->retval);
3854   vl_api_one_adjacency_t *a;
3855
3856   if (retval)
3857     goto end;
3858
3859   n = clib_net_to_host_u32 (mp->count);
3860
3861   for (i = 0; i < n; i++)
3862     {
3863       a = &mp->adjacencies[i];
3864       print (vam->ofp, "%U %40U",
3865              format_lisp_flat_eid, a->eid_type, a->leid, a->leid_prefix_len,
3866              format_lisp_flat_eid, a->eid_type, a->reid, a->reid_prefix_len);
3867     }
3868
3869 end:
3870   vam->retval = retval;
3871   vam->result_ready = 1;
3872 }
3873
3874 static void
3875   vl_api_one_adjacencies_get_reply_t_handler_json
3876   (vl_api_one_adjacencies_get_reply_t * mp)
3877 {
3878   u8 *s = 0;
3879   vat_main_t *vam = &vat_main;
3880   vat_json_node_t *e = 0, root;
3881   u32 i, n;
3882   int retval = clib_net_to_host_u32 (mp->retval);
3883   vl_api_one_adjacency_t *a;
3884
3885   if (retval)
3886     goto end;
3887
3888   n = clib_net_to_host_u32 (mp->count);
3889   vat_json_init_array (&root);
3890
3891   for (i = 0; i < n; i++)
3892     {
3893       e = vat_json_array_add (&root);
3894       a = &mp->adjacencies[i];
3895
3896       vat_json_init_object (e);
3897       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->leid,
3898                   a->leid_prefix_len);
3899       vec_add1 (s, 0);
3900       vat_json_object_add_string_copy (e, "leid", s);
3901       vec_free (s);
3902
3903       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->reid,
3904                   a->reid_prefix_len);
3905       vec_add1 (s, 0);
3906       vat_json_object_add_string_copy (e, "reid", s);
3907       vec_free (s);
3908     }
3909
3910   vat_json_print (vam->ofp, &root);
3911   vat_json_free (&root);
3912
3913 end:
3914   vam->retval = retval;
3915   vam->result_ready = 1;
3916 }
3917
3918 static void
3919 vl_api_one_map_server_details_t_handler (vl_api_one_map_server_details_t * mp)
3920 {
3921   vat_main_t *vam = &vat_main;
3922
3923   print (vam->ofp, "%=20U",
3924          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
3925          mp->ip_address);
3926 }
3927
3928 static void
3929   vl_api_one_map_server_details_t_handler_json
3930   (vl_api_one_map_server_details_t * mp)
3931 {
3932   vat_main_t *vam = &vat_main;
3933   vat_json_node_t *node = NULL;
3934   struct in6_addr ip6;
3935   struct in_addr ip4;
3936
3937   if (VAT_JSON_ARRAY != vam->json_tree.type)
3938     {
3939       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3940       vat_json_init_array (&vam->json_tree);
3941     }
3942   node = vat_json_array_add (&vam->json_tree);
3943
3944   vat_json_init_object (node);
3945   if (mp->is_ipv6)
3946     {
3947       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
3948       vat_json_object_add_ip6 (node, "map-server", ip6);
3949     }
3950   else
3951     {
3952       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
3953       vat_json_object_add_ip4 (node, "map-server", ip4);
3954     }
3955 }
3956
3957 static void
3958 vl_api_one_map_resolver_details_t_handler (vl_api_one_map_resolver_details_t
3959                                            * mp)
3960 {
3961   vat_main_t *vam = &vat_main;
3962
3963   print (vam->ofp, "%=20U",
3964          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
3965          mp->ip_address);
3966 }
3967
3968 static void
3969   vl_api_one_map_resolver_details_t_handler_json
3970   (vl_api_one_map_resolver_details_t * mp)
3971 {
3972   vat_main_t *vam = &vat_main;
3973   vat_json_node_t *node = NULL;
3974   struct in6_addr ip6;
3975   struct in_addr ip4;
3976
3977   if (VAT_JSON_ARRAY != vam->json_tree.type)
3978     {
3979       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3980       vat_json_init_array (&vam->json_tree);
3981     }
3982   node = vat_json_array_add (&vam->json_tree);
3983
3984   vat_json_init_object (node);
3985   if (mp->is_ipv6)
3986     {
3987       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
3988       vat_json_object_add_ip6 (node, "map resolver", ip6);
3989     }
3990   else
3991     {
3992       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
3993       vat_json_object_add_ip4 (node, "map resolver", ip4);
3994     }
3995 }
3996
3997 static void
3998 vl_api_show_one_status_reply_t_handler (vl_api_show_one_status_reply_t * mp)
3999 {
4000   vat_main_t *vam = &vat_main;
4001   i32 retval = ntohl (mp->retval);
4002
4003   if (0 <= retval)
4004     {
4005       print (vam->ofp, "feature: %s\ngpe: %s",
4006              mp->feature_status ? "enabled" : "disabled",
4007              mp->gpe_status ? "enabled" : "disabled");
4008     }
4009
4010   vam->retval = retval;
4011   vam->result_ready = 1;
4012 }
4013
4014 static void
4015   vl_api_show_one_status_reply_t_handler_json
4016   (vl_api_show_one_status_reply_t * mp)
4017 {
4018   vat_main_t *vam = &vat_main;
4019   vat_json_node_t node;
4020   u8 *gpe_status = NULL;
4021   u8 *feature_status = NULL;
4022
4023   gpe_status = format (0, "%s", mp->gpe_status ? "enabled" : "disabled");
4024   feature_status = format (0, "%s",
4025                            mp->feature_status ? "enabled" : "disabled");
4026   vec_add1 (gpe_status, 0);
4027   vec_add1 (feature_status, 0);
4028
4029   vat_json_init_object (&node);
4030   vat_json_object_add_string_copy (&node, "gpe_status", gpe_status);
4031   vat_json_object_add_string_copy (&node, "feature_status", feature_status);
4032
4033   vec_free (gpe_status);
4034   vec_free (feature_status);
4035
4036   vat_json_print (vam->ofp, &node);
4037   vat_json_free (&node);
4038
4039   vam->retval = ntohl (mp->retval);
4040   vam->result_ready = 1;
4041 }
4042
4043 static void
4044   vl_api_one_get_map_request_itr_rlocs_reply_t_handler
4045   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
4046 {
4047   vat_main_t *vam = &vat_main;
4048   i32 retval = ntohl (mp->retval);
4049
4050   if (retval >= 0)
4051     {
4052       print (vam->ofp, "%=20s", mp->locator_set_name);
4053     }
4054
4055   vam->retval = retval;
4056   vam->result_ready = 1;
4057 }
4058
4059 static void
4060   vl_api_one_get_map_request_itr_rlocs_reply_t_handler_json
4061   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
4062 {
4063   vat_main_t *vam = &vat_main;
4064   vat_json_node_t *node = NULL;
4065
4066   if (VAT_JSON_ARRAY != vam->json_tree.type)
4067     {
4068       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4069       vat_json_init_array (&vam->json_tree);
4070     }
4071   node = vat_json_array_add (&vam->json_tree);
4072
4073   vat_json_init_object (node);
4074   vat_json_object_add_string_copy (node, "itr-rlocs", mp->locator_set_name);
4075
4076   vat_json_print (vam->ofp, node);
4077   vat_json_free (node);
4078
4079   vam->retval = ntohl (mp->retval);
4080   vam->result_ready = 1;
4081 }
4082
4083 static u8 *
4084 format_lisp_map_request_mode (u8 * s, va_list * args)
4085 {
4086   u32 mode = va_arg (*args, u32);
4087
4088   switch (mode)
4089     {
4090     case 0:
4091       return format (0, "dst-only");
4092     case 1:
4093       return format (0, "src-dst");
4094     }
4095   return 0;
4096 }
4097
4098 static void
4099   vl_api_show_one_map_request_mode_reply_t_handler
4100   (vl_api_show_one_map_request_mode_reply_t * mp)
4101 {
4102   vat_main_t *vam = &vat_main;
4103   i32 retval = ntohl (mp->retval);
4104
4105   if (0 <= retval)
4106     {
4107       u32 mode = mp->mode;
4108       print (vam->ofp, "map_request_mode: %U",
4109              format_lisp_map_request_mode, mode);
4110     }
4111
4112   vam->retval = retval;
4113   vam->result_ready = 1;
4114 }
4115
4116 static void
4117   vl_api_show_one_map_request_mode_reply_t_handler_json
4118   (vl_api_show_one_map_request_mode_reply_t * mp)
4119 {
4120   vat_main_t *vam = &vat_main;
4121   vat_json_node_t node;
4122   u8 *s = 0;
4123   u32 mode;
4124
4125   mode = mp->mode;
4126   s = format (0, "%U", format_lisp_map_request_mode, mode);
4127   vec_add1 (s, 0);
4128
4129   vat_json_init_object (&node);
4130   vat_json_object_add_string_copy (&node, "map_request_mode", s);
4131   vat_json_print (vam->ofp, &node);
4132   vat_json_free (&node);
4133
4134   vec_free (s);
4135   vam->retval = ntohl (mp->retval);
4136   vam->result_ready = 1;
4137 }
4138
4139 static void
4140   vl_api_one_show_xtr_mode_reply_t_handler
4141   (vl_api_one_show_xtr_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       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4149     }
4150
4151   vam->retval = retval;
4152   vam->result_ready = 1;
4153 }
4154
4155 static void
4156   vl_api_one_show_xtr_mode_reply_t_handler_json
4157   (vl_api_one_show_xtr_mode_reply_t * mp)
4158 {
4159   vat_main_t *vam = &vat_main;
4160   vat_json_node_t node;
4161   u8 *status = 0;
4162
4163   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4164   vec_add1 (status, 0);
4165
4166   vat_json_init_object (&node);
4167   vat_json_object_add_string_copy (&node, "status", status);
4168
4169   vec_free (status);
4170
4171   vat_json_print (vam->ofp, &node);
4172   vat_json_free (&node);
4173
4174   vam->retval = ntohl (mp->retval);
4175   vam->result_ready = 1;
4176 }
4177
4178 static void
4179   vl_api_one_show_pitr_mode_reply_t_handler
4180   (vl_api_one_show_pitr_mode_reply_t * mp)
4181 {
4182   vat_main_t *vam = &vat_main;
4183   i32 retval = ntohl (mp->retval);
4184
4185   if (0 <= retval)
4186     {
4187       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4188     }
4189
4190   vam->retval = retval;
4191   vam->result_ready = 1;
4192 }
4193
4194 static void
4195   vl_api_one_show_pitr_mode_reply_t_handler_json
4196   (vl_api_one_show_pitr_mode_reply_t * mp)
4197 {
4198   vat_main_t *vam = &vat_main;
4199   vat_json_node_t node;
4200   u8 *status = 0;
4201
4202   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4203   vec_add1 (status, 0);
4204
4205   vat_json_init_object (&node);
4206   vat_json_object_add_string_copy (&node, "status", status);
4207
4208   vec_free (status);
4209
4210   vat_json_print (vam->ofp, &node);
4211   vat_json_free (&node);
4212
4213   vam->retval = ntohl (mp->retval);
4214   vam->result_ready = 1;
4215 }
4216
4217 static void
4218   vl_api_one_show_petr_mode_reply_t_handler
4219   (vl_api_one_show_petr_mode_reply_t * mp)
4220 {
4221   vat_main_t *vam = &vat_main;
4222   i32 retval = ntohl (mp->retval);
4223
4224   if (0 <= retval)
4225     {
4226       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4227     }
4228
4229   vam->retval = retval;
4230   vam->result_ready = 1;
4231 }
4232
4233 static void
4234   vl_api_one_show_petr_mode_reply_t_handler_json
4235   (vl_api_one_show_petr_mode_reply_t * mp)
4236 {
4237   vat_main_t *vam = &vat_main;
4238   vat_json_node_t node;
4239   u8 *status = 0;
4240
4241   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4242   vec_add1 (status, 0);
4243
4244   vat_json_init_object (&node);
4245   vat_json_object_add_string_copy (&node, "status", status);
4246
4247   vec_free (status);
4248
4249   vat_json_print (vam->ofp, &node);
4250   vat_json_free (&node);
4251
4252   vam->retval = ntohl (mp->retval);
4253   vam->result_ready = 1;
4254 }
4255
4256 static void
4257   vl_api_show_one_use_petr_reply_t_handler
4258   (vl_api_show_one_use_petr_reply_t * mp)
4259 {
4260   vat_main_t *vam = &vat_main;
4261   i32 retval = ntohl (mp->retval);
4262
4263   if (0 <= retval)
4264     {
4265       print (vam->ofp, "%s\n", mp->status ? "enabled" : "disabled");
4266       if (mp->status)
4267         {
4268           print (vam->ofp, "Proxy-ETR address; %U",
4269                  mp->is_ip4 ? format_ip4_address : format_ip6_address,
4270                  mp->address);
4271         }
4272     }
4273
4274   vam->retval = retval;
4275   vam->result_ready = 1;
4276 }
4277
4278 static void
4279   vl_api_show_one_use_petr_reply_t_handler_json
4280   (vl_api_show_one_use_petr_reply_t * mp)
4281 {
4282   vat_main_t *vam = &vat_main;
4283   vat_json_node_t node;
4284   u8 *status = 0;
4285   struct in_addr ip4;
4286   struct in6_addr ip6;
4287
4288   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4289   vec_add1 (status, 0);
4290
4291   vat_json_init_object (&node);
4292   vat_json_object_add_string_copy (&node, "status", status);
4293   if (mp->status)
4294     {
4295       if (mp->is_ip4)
4296         {
4297           clib_memcpy (&ip6, mp->address, sizeof (ip6));
4298           vat_json_object_add_ip6 (&node, "address", ip6);
4299         }
4300       else
4301         {
4302           clib_memcpy (&ip4, mp->address, sizeof (ip4));
4303           vat_json_object_add_ip4 (&node, "address", ip4);
4304         }
4305     }
4306
4307   vec_free (status);
4308
4309   vat_json_print (vam->ofp, &node);
4310   vat_json_free (&node);
4311
4312   vam->retval = ntohl (mp->retval);
4313   vam->result_ready = 1;
4314 }
4315
4316 static void
4317   vl_api_show_one_nsh_mapping_reply_t_handler
4318   (vl_api_show_one_nsh_mapping_reply_t * mp)
4319 {
4320   vat_main_t *vam = &vat_main;
4321   i32 retval = ntohl (mp->retval);
4322
4323   if (0 <= retval)
4324     {
4325       print (vam->ofp, "%-20s%-16s",
4326              mp->is_set ? "set" : "not-set",
4327              mp->is_set ? (char *) mp->locator_set_name : "");
4328     }
4329
4330   vam->retval = retval;
4331   vam->result_ready = 1;
4332 }
4333
4334 static void
4335   vl_api_show_one_nsh_mapping_reply_t_handler_json
4336   (vl_api_show_one_nsh_mapping_reply_t * mp)
4337 {
4338   vat_main_t *vam = &vat_main;
4339   vat_json_node_t node;
4340   u8 *status = 0;
4341
4342   status = format (0, "%s", mp->is_set ? "yes" : "no");
4343   vec_add1 (status, 0);
4344
4345   vat_json_init_object (&node);
4346   vat_json_object_add_string_copy (&node, "is_set", status);
4347   if (mp->is_set)
4348     {
4349       vat_json_object_add_string_copy (&node, "locator_set",
4350                                        mp->locator_set_name);
4351     }
4352
4353   vec_free (status);
4354
4355   vat_json_print (vam->ofp, &node);
4356   vat_json_free (&node);
4357
4358   vam->retval = ntohl (mp->retval);
4359   vam->result_ready = 1;
4360 }
4361
4362 static void
4363   vl_api_show_one_map_register_ttl_reply_t_handler
4364   (vl_api_show_one_map_register_ttl_reply_t * mp)
4365 {
4366   vat_main_t *vam = &vat_main;
4367   i32 retval = ntohl (mp->retval);
4368
4369   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4370
4371   if (0 <= retval)
4372     {
4373       print (vam->ofp, "ttl: %u", mp->ttl);
4374     }
4375
4376   vam->retval = retval;
4377   vam->result_ready = 1;
4378 }
4379
4380 static void
4381   vl_api_show_one_map_register_ttl_reply_t_handler_json
4382   (vl_api_show_one_map_register_ttl_reply_t * mp)
4383 {
4384   vat_main_t *vam = &vat_main;
4385   vat_json_node_t node;
4386
4387   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4388   vat_json_init_object (&node);
4389   vat_json_object_add_uint (&node, "ttl", mp->ttl);
4390
4391   vat_json_print (vam->ofp, &node);
4392   vat_json_free (&node);
4393
4394   vam->retval = ntohl (mp->retval);
4395   vam->result_ready = 1;
4396 }
4397
4398 static void
4399 vl_api_show_one_pitr_reply_t_handler (vl_api_show_one_pitr_reply_t * mp)
4400 {
4401   vat_main_t *vam = &vat_main;
4402   i32 retval = ntohl (mp->retval);
4403
4404   if (0 <= retval)
4405     {
4406       print (vam->ofp, "%-20s%-16s",
4407              mp->status ? "enabled" : "disabled",
4408              mp->status ? (char *) mp->locator_set_name : "");
4409     }
4410
4411   vam->retval = retval;
4412   vam->result_ready = 1;
4413 }
4414
4415 static void
4416 vl_api_show_one_pitr_reply_t_handler_json (vl_api_show_one_pitr_reply_t * mp)
4417 {
4418   vat_main_t *vam = &vat_main;
4419   vat_json_node_t node;
4420   u8 *status = 0;
4421
4422   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4423   vec_add1 (status, 0);
4424
4425   vat_json_init_object (&node);
4426   vat_json_object_add_string_copy (&node, "status", status);
4427   if (mp->status)
4428     {
4429       vat_json_object_add_string_copy (&node, "locator_set",
4430                                        mp->locator_set_name);
4431     }
4432
4433   vec_free (status);
4434
4435   vat_json_print (vam->ofp, &node);
4436   vat_json_free (&node);
4437
4438   vam->retval = ntohl (mp->retval);
4439   vam->result_ready = 1;
4440 }
4441
4442 static u8 *
4443 format_policer_type (u8 * s, va_list * va)
4444 {
4445   u32 i = va_arg (*va, u32);
4446
4447   if (i == SSE2_QOS_POLICER_TYPE_1R2C)
4448     s = format (s, "1r2c");
4449   else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
4450     s = format (s, "1r3c");
4451   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
4452     s = format (s, "2r3c-2698");
4453   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
4454     s = format (s, "2r3c-4115");
4455   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
4456     s = format (s, "2r3c-mef5cf1");
4457   else
4458     s = format (s, "ILLEGAL");
4459   return s;
4460 }
4461
4462 static u8 *
4463 format_policer_rate_type (u8 * s, va_list * va)
4464 {
4465   u32 i = va_arg (*va, u32);
4466
4467   if (i == SSE2_QOS_RATE_KBPS)
4468     s = format (s, "kbps");
4469   else if (i == SSE2_QOS_RATE_PPS)
4470     s = format (s, "pps");
4471   else
4472     s = format (s, "ILLEGAL");
4473   return s;
4474 }
4475
4476 static u8 *
4477 format_policer_round_type (u8 * s, va_list * va)
4478 {
4479   u32 i = va_arg (*va, u32);
4480
4481   if (i == SSE2_QOS_ROUND_TO_CLOSEST)
4482     s = format (s, "closest");
4483   else if (i == SSE2_QOS_ROUND_TO_UP)
4484     s = format (s, "up");
4485   else if (i == SSE2_QOS_ROUND_TO_DOWN)
4486     s = format (s, "down");
4487   else
4488     s = format (s, "ILLEGAL");
4489   return s;
4490 }
4491
4492 static u8 *
4493 format_policer_action_type (u8 * s, va_list * va)
4494 {
4495   u32 i = va_arg (*va, u32);
4496
4497   if (i == SSE2_QOS_ACTION_DROP)
4498     s = format (s, "drop");
4499   else if (i == SSE2_QOS_ACTION_TRANSMIT)
4500     s = format (s, "transmit");
4501   else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4502     s = format (s, "mark-and-transmit");
4503   else
4504     s = format (s, "ILLEGAL");
4505   return s;
4506 }
4507
4508 static u8 *
4509 format_dscp (u8 * s, va_list * va)
4510 {
4511   u32 i = va_arg (*va, u32);
4512   char *t = 0;
4513
4514   switch (i)
4515     {
4516 #define _(v,f,str) case VNET_DSCP_##f: t = str; break;
4517       foreach_vnet_dscp
4518 #undef _
4519     default:
4520       return format (s, "ILLEGAL");
4521     }
4522   s = format (s, "%s", t);
4523   return s;
4524 }
4525
4526 static void
4527 vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
4528 {
4529   vat_main_t *vam = &vat_main;
4530   u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
4531
4532   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4533     conform_dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
4534   else
4535     conform_dscp_str = format (0, "");
4536
4537   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4538     exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
4539   else
4540     exceed_dscp_str = format (0, "");
4541
4542   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4543     violate_dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
4544   else
4545     violate_dscp_str = format (0, "");
4546
4547   print (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
4548          "rate type %U, round type %U, %s rate, %s color-aware, "
4549          "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
4550          "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
4551          "conform action %U%s, exceed action %U%s, violate action %U%s",
4552          mp->name,
4553          format_policer_type, mp->type,
4554          ntohl (mp->cir),
4555          ntohl (mp->eir),
4556          clib_net_to_host_u64 (mp->cb),
4557          clib_net_to_host_u64 (mp->eb),
4558          format_policer_rate_type, mp->rate_type,
4559          format_policer_round_type, mp->round_type,
4560          mp->single_rate ? "single" : "dual",
4561          mp->color_aware ? "is" : "not",
4562          ntohl (mp->cir_tokens_per_period),
4563          ntohl (mp->pir_tokens_per_period),
4564          ntohl (mp->scale),
4565          ntohl (mp->current_limit),
4566          ntohl (mp->current_bucket),
4567          ntohl (mp->extended_limit),
4568          ntohl (mp->extended_bucket),
4569          clib_net_to_host_u64 (mp->last_update_time),
4570          format_policer_action_type, mp->conform_action_type,
4571          conform_dscp_str,
4572          format_policer_action_type, mp->exceed_action_type,
4573          exceed_dscp_str,
4574          format_policer_action_type, mp->violate_action_type,
4575          violate_dscp_str);
4576
4577   vec_free (conform_dscp_str);
4578   vec_free (exceed_dscp_str);
4579   vec_free (violate_dscp_str);
4580 }
4581
4582 static void vl_api_policer_details_t_handler_json
4583   (vl_api_policer_details_t * mp)
4584 {
4585   vat_main_t *vam = &vat_main;
4586   vat_json_node_t *node;
4587   u8 *rate_type_str, *round_type_str, *type_str;
4588   u8 *conform_action_str, *exceed_action_str, *violate_action_str;
4589
4590   rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
4591   round_type_str =
4592     format (0, "%U", format_policer_round_type, mp->round_type);
4593   type_str = format (0, "%U", format_policer_type, mp->type);
4594   conform_action_str = format (0, "%U", format_policer_action_type,
4595                                mp->conform_action_type);
4596   exceed_action_str = format (0, "%U", format_policer_action_type,
4597                               mp->exceed_action_type);
4598   violate_action_str = format (0, "%U", format_policer_action_type,
4599                                mp->violate_action_type);
4600
4601   if (VAT_JSON_ARRAY != vam->json_tree.type)
4602     {
4603       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4604       vat_json_init_array (&vam->json_tree);
4605     }
4606   node = vat_json_array_add (&vam->json_tree);
4607
4608   vat_json_init_object (node);
4609   vat_json_object_add_string_copy (node, "name", mp->name);
4610   vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
4611   vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
4612   vat_json_object_add_uint (node, "cb", clib_net_to_host_u64 (mp->cb));
4613   vat_json_object_add_uint (node, "eb", clib_net_to_host_u64 (mp->eb));
4614   vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
4615   vat_json_object_add_string_copy (node, "round_type", round_type_str);
4616   vat_json_object_add_string_copy (node, "type", type_str);
4617   vat_json_object_add_uint (node, "single_rate", mp->single_rate);
4618   vat_json_object_add_uint (node, "color_aware", mp->color_aware);
4619   vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
4620   vat_json_object_add_uint (node, "cir_tokens_per_period",
4621                             ntohl (mp->cir_tokens_per_period));
4622   vat_json_object_add_uint (node, "eir_tokens_per_period",
4623                             ntohl (mp->pir_tokens_per_period));
4624   vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
4625   vat_json_object_add_uint (node, "current_bucket",
4626                             ntohl (mp->current_bucket));
4627   vat_json_object_add_uint (node, "extended_limit",
4628                             ntohl (mp->extended_limit));
4629   vat_json_object_add_uint (node, "extended_bucket",
4630                             ntohl (mp->extended_bucket));
4631   vat_json_object_add_uint (node, "last_update_time",
4632                             ntohl (mp->last_update_time));
4633   vat_json_object_add_string_copy (node, "conform_action",
4634                                    conform_action_str);
4635   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4636     {
4637       u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
4638       vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
4639       vec_free (dscp_str);
4640     }
4641   vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
4642   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4643     {
4644       u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
4645       vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
4646       vec_free (dscp_str);
4647     }
4648   vat_json_object_add_string_copy (node, "violate_action",
4649                                    violate_action_str);
4650   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4651     {
4652       u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
4653       vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
4654       vec_free (dscp_str);
4655     }
4656
4657   vec_free (rate_type_str);
4658   vec_free (round_type_str);
4659   vec_free (type_str);
4660   vec_free (conform_action_str);
4661   vec_free (exceed_action_str);
4662   vec_free (violate_action_str);
4663 }
4664
4665 static void
4666 vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
4667                                            mp)
4668 {
4669   vat_main_t *vam = &vat_main;
4670   int i, count = ntohl (mp->count);
4671
4672   if (count > 0)
4673     print (vam->ofp, "classify table ids (%d) : ", count);
4674   for (i = 0; i < count; i++)
4675     {
4676       print (vam->ofp, "%d", ntohl (mp->ids[i]));
4677       print (vam->ofp, (i < count - 1) ? "," : "");
4678     }
4679   vam->retval = ntohl (mp->retval);
4680   vam->result_ready = 1;
4681 }
4682
4683 static void
4684   vl_api_classify_table_ids_reply_t_handler_json
4685   (vl_api_classify_table_ids_reply_t * mp)
4686 {
4687   vat_main_t *vam = &vat_main;
4688   int i, count = ntohl (mp->count);
4689
4690   if (count > 0)
4691     {
4692       vat_json_node_t node;
4693
4694       vat_json_init_object (&node);
4695       for (i = 0; i < count; i++)
4696         {
4697           vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
4698         }
4699       vat_json_print (vam->ofp, &node);
4700       vat_json_free (&node);
4701     }
4702   vam->retval = ntohl (mp->retval);
4703   vam->result_ready = 1;
4704 }
4705
4706 static void
4707   vl_api_classify_table_by_interface_reply_t_handler
4708   (vl_api_classify_table_by_interface_reply_t * mp)
4709 {
4710   vat_main_t *vam = &vat_main;
4711   u32 table_id;
4712
4713   table_id = ntohl (mp->l2_table_id);
4714   if (table_id != ~0)
4715     print (vam->ofp, "l2 table id : %d", table_id);
4716   else
4717     print (vam->ofp, "l2 table id : No input ACL tables configured");
4718   table_id = ntohl (mp->ip4_table_id);
4719   if (table_id != ~0)
4720     print (vam->ofp, "ip4 table id : %d", table_id);
4721   else
4722     print (vam->ofp, "ip4 table id : No input ACL tables configured");
4723   table_id = ntohl (mp->ip6_table_id);
4724   if (table_id != ~0)
4725     print (vam->ofp, "ip6 table id : %d", table_id);
4726   else
4727     print (vam->ofp, "ip6 table id : No input ACL tables configured");
4728   vam->retval = ntohl (mp->retval);
4729   vam->result_ready = 1;
4730 }
4731
4732 static void
4733   vl_api_classify_table_by_interface_reply_t_handler_json
4734   (vl_api_classify_table_by_interface_reply_t * mp)
4735 {
4736   vat_main_t *vam = &vat_main;
4737   vat_json_node_t node;
4738
4739   vat_json_init_object (&node);
4740
4741   vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
4742   vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
4743   vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
4744
4745   vat_json_print (vam->ofp, &node);
4746   vat_json_free (&node);
4747
4748   vam->retval = ntohl (mp->retval);
4749   vam->result_ready = 1;
4750 }
4751
4752 static void vl_api_policer_add_del_reply_t_handler
4753   (vl_api_policer_add_del_reply_t * mp)
4754 {
4755   vat_main_t *vam = &vat_main;
4756   i32 retval = ntohl (mp->retval);
4757   if (vam->async_mode)
4758     {
4759       vam->async_errors += (retval < 0);
4760     }
4761   else
4762     {
4763       vam->retval = retval;
4764       vam->result_ready = 1;
4765       if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
4766         /*
4767          * Note: this is just barely thread-safe, depends on
4768          * the main thread spinning waiting for an answer...
4769          */
4770         errmsg ("policer index %d", ntohl (mp->policer_index));
4771     }
4772 }
4773
4774 static void vl_api_policer_add_del_reply_t_handler_json
4775   (vl_api_policer_add_del_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   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
4782   vat_json_object_add_uint (&node, "policer_index",
4783                             ntohl (mp->policer_index));
4784
4785   vat_json_print (vam->ofp, &node);
4786   vat_json_free (&node);
4787
4788   vam->retval = ntohl (mp->retval);
4789   vam->result_ready = 1;
4790 }
4791
4792 /* Format hex dump. */
4793 u8 *
4794 format_hex_bytes (u8 * s, va_list * va)
4795 {
4796   u8 *bytes = va_arg (*va, u8 *);
4797   int n_bytes = va_arg (*va, int);
4798   uword i;
4799
4800   /* Print short or long form depending on byte count. */
4801   uword short_form = n_bytes <= 32;
4802   u32 indent = format_get_indent (s);
4803
4804   if (n_bytes == 0)
4805     return s;
4806
4807   for (i = 0; i < n_bytes; i++)
4808     {
4809       if (!short_form && (i % 32) == 0)
4810         s = format (s, "%08x: ", i);
4811       s = format (s, "%02x", bytes[i]);
4812       if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
4813         s = format (s, "\n%U", format_white_space, indent);
4814     }
4815
4816   return s;
4817 }
4818
4819 static void
4820 vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
4821                                             * mp)
4822 {
4823   vat_main_t *vam = &vat_main;
4824   i32 retval = ntohl (mp->retval);
4825   if (retval == 0)
4826     {
4827       print (vam->ofp, "classify table info :");
4828       print (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d",
4829              ntohl (mp->active_sessions), ntohl (mp->next_table_index),
4830              ntohl (mp->miss_next_index));
4831       print (vam->ofp, "nbuckets: %d skip: %d match: %d",
4832              ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
4833              ntohl (mp->match_n_vectors));
4834       print (vam->ofp, "mask: %U", format_hex_bytes, mp->mask,
4835              ntohl (mp->mask_length));
4836     }
4837   vam->retval = retval;
4838   vam->result_ready = 1;
4839 }
4840
4841 static void
4842   vl_api_classify_table_info_reply_t_handler_json
4843   (vl_api_classify_table_info_reply_t * mp)
4844 {
4845   vat_main_t *vam = &vat_main;
4846   vat_json_node_t node;
4847
4848   i32 retval = ntohl (mp->retval);
4849   if (retval == 0)
4850     {
4851       vat_json_init_object (&node);
4852
4853       vat_json_object_add_int (&node, "sessions",
4854                                ntohl (mp->active_sessions));
4855       vat_json_object_add_int (&node, "nexttbl",
4856                                ntohl (mp->next_table_index));
4857       vat_json_object_add_int (&node, "nextnode",
4858                                ntohl (mp->miss_next_index));
4859       vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
4860       vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
4861       vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
4862       u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
4863                       ntohl (mp->mask_length), 0);
4864       vat_json_object_add_string_copy (&node, "mask", s);
4865
4866       vat_json_print (vam->ofp, &node);
4867       vat_json_free (&node);
4868     }
4869   vam->retval = ntohl (mp->retval);
4870   vam->result_ready = 1;
4871 }
4872
4873 static void
4874 vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
4875                                            mp)
4876 {
4877   vat_main_t *vam = &vat_main;
4878
4879   print (vam->ofp, "next_index: %d advance: %d opaque: %d ",
4880          ntohl (mp->hit_next_index), ntohl (mp->advance),
4881          ntohl (mp->opaque_index));
4882   print (vam->ofp, "mask: %U", format_hex_bytes, mp->match,
4883          ntohl (mp->match_length));
4884 }
4885
4886 static void
4887   vl_api_classify_session_details_t_handler_json
4888   (vl_api_classify_session_details_t * mp)
4889 {
4890   vat_main_t *vam = &vat_main;
4891   vat_json_node_t *node = NULL;
4892
4893   if (VAT_JSON_ARRAY != vam->json_tree.type)
4894     {
4895       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4896       vat_json_init_array (&vam->json_tree);
4897     }
4898   node = vat_json_array_add (&vam->json_tree);
4899
4900   vat_json_init_object (node);
4901   vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
4902   vat_json_object_add_int (node, "advance", ntohl (mp->advance));
4903   vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
4904   u8 *s =
4905     format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
4906             0);
4907   vat_json_object_add_string_copy (node, "match", s);
4908 }
4909
4910 static void vl_api_pg_create_interface_reply_t_handler
4911   (vl_api_pg_create_interface_reply_t * mp)
4912 {
4913   vat_main_t *vam = &vat_main;
4914
4915   vam->retval = ntohl (mp->retval);
4916   vam->result_ready = 1;
4917 }
4918
4919 static void vl_api_pg_create_interface_reply_t_handler_json
4920   (vl_api_pg_create_interface_reply_t * mp)
4921 {
4922   vat_main_t *vam = &vat_main;
4923   vat_json_node_t node;
4924
4925   i32 retval = ntohl (mp->retval);
4926   if (retval == 0)
4927     {
4928       vat_json_init_object (&node);
4929
4930       vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
4931
4932       vat_json_print (vam->ofp, &node);
4933       vat_json_free (&node);
4934     }
4935   vam->retval = ntohl (mp->retval);
4936   vam->result_ready = 1;
4937 }
4938
4939 static void vl_api_policer_classify_details_t_handler
4940   (vl_api_policer_classify_details_t * mp)
4941 {
4942   vat_main_t *vam = &vat_main;
4943
4944   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
4945          ntohl (mp->table_index));
4946 }
4947
4948 static void vl_api_policer_classify_details_t_handler_json
4949   (vl_api_policer_classify_details_t * mp)
4950 {
4951   vat_main_t *vam = &vat_main;
4952   vat_json_node_t *node;
4953
4954   if (VAT_JSON_ARRAY != vam->json_tree.type)
4955     {
4956       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4957       vat_json_init_array (&vam->json_tree);
4958     }
4959   node = vat_json_array_add (&vam->json_tree);
4960
4961   vat_json_init_object (node);
4962   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
4963   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
4964 }
4965
4966 static void vl_api_flow_classify_details_t_handler
4967   (vl_api_flow_classify_details_t * mp)
4968 {
4969   vat_main_t *vam = &vat_main;
4970
4971   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
4972          ntohl (mp->table_index));
4973 }
4974
4975 static void vl_api_flow_classify_details_t_handler_json
4976   (vl_api_flow_classify_details_t * mp)
4977 {
4978   vat_main_t *vam = &vat_main;
4979   vat_json_node_t *node;
4980
4981   if (VAT_JSON_ARRAY != vam->json_tree.type)
4982     {
4983       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4984       vat_json_init_array (&vam->json_tree);
4985     }
4986   node = vat_json_array_add (&vam->json_tree);
4987
4988   vat_json_init_object (node);
4989   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
4990   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
4991 }
4992
4993 #define vl_api_one_adjacencies_get_reply_t_endian vl_noop_handler
4994 #define vl_api_one_adjacencies_get_reply_t_print vl_noop_handler
4995 #define vl_api_one_l2_arp_bd_get_reply_t_print vl_noop_handler
4996 #define vl_api_one_l2_arp_entries_get_reply_t_endian vl_noop_handler
4997 #define vl_api_one_l2_arp_entries_get_reply_t_print vl_noop_handler
4998 #define vl_api_one_l2_arp_bd_get_reply_t_endian vl_noop_handler
4999 #define vl_api_one_ndp_bd_get_reply_t_endian vl_noop_handler
5000 #define vl_api_one_ndp_bd_get_reply_t_print vl_noop_handler
5001 #define vl_api_one_ndp_entries_get_reply_t_print vl_noop_handler
5002 #define vl_api_one_ndp_entries_get_reply_t_endian vl_noop_handler
5003
5004 /*
5005  * Generate boilerplate reply handlers, which
5006  * dig the return value out of the xxx_reply_t API message,
5007  * stick it into vam->retval, and set vam->result_ready
5008  *
5009  * Could also do this by pointing N message decode slots at
5010  * a single function, but that could break in subtle ways.
5011  */
5012
5013 #define foreach_standard_reply_retval_handler           \
5014 _(sw_interface_set_flags_reply)                         \
5015 _(sw_interface_add_del_address_reply)                   \
5016 _(sw_interface_set_rx_mode_reply)                       \
5017 _(sw_interface_set_rx_placement_reply)                  \
5018 _(sw_interface_set_table_reply)                         \
5019 _(sw_interface_set_mpls_enable_reply)                   \
5020 _(sw_interface_set_vpath_reply)                         \
5021 _(sw_interface_set_vxlan_bypass_reply)                  \
5022 _(sw_interface_set_geneve_bypass_reply)                 \
5023 _(sw_interface_set_vxlan_gpe_bypass_reply)              \
5024 _(sw_interface_set_l2_bridge_reply)                     \
5025 _(sw_interface_set_bond_weight_reply)                   \
5026 _(bridge_domain_add_del_reply)                          \
5027 _(sw_interface_set_l2_xconnect_reply)                   \
5028 _(l2fib_add_del_reply)                                  \
5029 _(l2fib_flush_int_reply)                                \
5030 _(l2fib_flush_bd_reply)                                 \
5031 _(ip_route_add_del_reply)                               \
5032 _(ip_table_add_del_reply)                               \
5033 _(ip_table_replace_begin_reply)                         \
5034 _(ip_table_flush_reply)                                 \
5035 _(ip_table_replace_end_reply)                           \
5036 _(ip_mroute_add_del_reply)                              \
5037 _(mpls_route_add_del_reply)                             \
5038 _(mpls_table_add_del_reply)                             \
5039 _(mpls_ip_bind_unbind_reply)                            \
5040 _(bier_route_add_del_reply)                             \
5041 _(bier_table_add_del_reply)                             \
5042 _(sw_interface_set_unnumbered_reply)                    \
5043 _(set_ip_flow_hash_reply)                               \
5044 _(sw_interface_ip6_enable_disable_reply)                \
5045 _(l2_patch_add_del_reply)                               \
5046 _(sr_mpls_policy_add_reply)                             \
5047 _(sr_mpls_policy_mod_reply)                             \
5048 _(sr_mpls_policy_del_reply)                             \
5049 _(sr_policy_add_reply)                                  \
5050 _(sr_policy_mod_reply)                                  \
5051 _(sr_policy_del_reply)                                  \
5052 _(sr_localsid_add_del_reply)                            \
5053 _(sr_steering_add_del_reply)                            \
5054 _(classify_add_del_session_reply)                       \
5055 _(classify_set_interface_ip_table_reply)                \
5056 _(classify_set_interface_l2_tables_reply)               \
5057 _(l2tpv3_set_tunnel_cookies_reply)                      \
5058 _(l2tpv3_interface_enable_disable_reply)                \
5059 _(l2tpv3_set_lookup_key_reply)                          \
5060 _(l2_fib_clear_table_reply)                             \
5061 _(l2_interface_efp_filter_reply)                        \
5062 _(l2_interface_vlan_tag_rewrite_reply)                  \
5063 _(modify_vhost_user_if_reply)                           \
5064 _(delete_vhost_user_if_reply)                           \
5065 _(want_l2_macs_events_reply)                            \
5066 _(input_acl_set_interface_reply)                        \
5067 _(ipsec_spd_add_del_reply)                              \
5068 _(ipsec_interface_add_del_spd_reply)                    \
5069 _(ipsec_spd_entry_add_del_reply)                        \
5070 _(ipsec_sad_entry_add_del_reply)                        \
5071 _(ipsec_tunnel_if_add_del_reply)                        \
5072 _(ipsec_tunnel_if_set_sa_reply)                         \
5073 _(delete_loopback_reply)                                \
5074 _(bd_ip_mac_add_del_reply)                              \
5075 _(bd_ip_mac_flush_reply)                                \
5076 _(want_interface_events_reply)                          \
5077 _(cop_interface_enable_disable_reply)                   \
5078 _(cop_whitelist_enable_disable_reply)                   \
5079 _(sw_interface_clear_stats_reply)                       \
5080 _(ioam_enable_reply)                                    \
5081 _(ioam_disable_reply)                                   \
5082 _(one_add_del_locator_reply)                            \
5083 _(one_add_del_local_eid_reply)                          \
5084 _(one_add_del_remote_mapping_reply)                     \
5085 _(one_add_del_adjacency_reply)                          \
5086 _(one_add_del_map_resolver_reply)                       \
5087 _(one_add_del_map_server_reply)                         \
5088 _(one_enable_disable_reply)                             \
5089 _(one_rloc_probe_enable_disable_reply)                  \
5090 _(one_map_register_enable_disable_reply)                \
5091 _(one_map_register_set_ttl_reply)                       \
5092 _(one_set_transport_protocol_reply)                     \
5093 _(one_map_register_fallback_threshold_reply)            \
5094 _(one_pitr_set_locator_set_reply)                       \
5095 _(one_map_request_mode_reply)                           \
5096 _(one_add_del_map_request_itr_rlocs_reply)              \
5097 _(one_eid_table_add_del_map_reply)                      \
5098 _(one_use_petr_reply)                                   \
5099 _(one_stats_enable_disable_reply)                       \
5100 _(one_add_del_l2_arp_entry_reply)                       \
5101 _(one_add_del_ndp_entry_reply)                          \
5102 _(one_stats_flush_reply)                                \
5103 _(one_enable_disable_xtr_mode_reply)                    \
5104 _(one_enable_disable_pitr_mode_reply)                   \
5105 _(one_enable_disable_petr_mode_reply)                   \
5106 _(gpe_enable_disable_reply)                             \
5107 _(gpe_set_encap_mode_reply)                             \
5108 _(gpe_add_del_iface_reply)                              \
5109 _(gpe_add_del_native_fwd_rpath_reply)                   \
5110 _(af_packet_delete_reply)                               \
5111 _(policer_classify_set_interface_reply)                 \
5112 _(netmap_create_reply)                                  \
5113 _(netmap_delete_reply)                                  \
5114 _(set_ipfix_exporter_reply)                             \
5115 _(set_ipfix_classify_stream_reply)                      \
5116 _(ipfix_classify_table_add_del_reply)                   \
5117 _(flow_classify_set_interface_reply)                    \
5118 _(sw_interface_span_enable_disable_reply)               \
5119 _(pg_capture_reply)                                     \
5120 _(pg_enable_disable_reply)                              \
5121 _(ip_source_and_port_range_check_add_del_reply)         \
5122 _(ip_source_and_port_range_check_interface_add_del_reply)\
5123 _(delete_subif_reply)                                   \
5124 _(l2_interface_pbb_tag_rewrite_reply)                   \
5125 _(set_punt_reply)                                       \
5126 _(feature_enable_disable_reply)                         \
5127 _(feature_gso_enable_disable_reply)                     \
5128 _(sw_interface_tag_add_del_reply)                       \
5129 _(sw_interface_add_del_mac_address_reply)               \
5130 _(hw_interface_set_mtu_reply)                           \
5131 _(p2p_ethernet_add_reply)                               \
5132 _(p2p_ethernet_del_reply)                               \
5133 _(lldp_config_reply)                                    \
5134 _(sw_interface_set_lldp_reply)                          \
5135 _(tcp_configure_src_addresses_reply)                    \
5136 _(session_rule_add_del_reply)                           \
5137 _(ip_container_proxy_add_del_reply)                     \
5138 _(output_acl_set_interface_reply)                       \
5139 _(qos_record_enable_disable_reply)
5140
5141 #define _(n)                                    \
5142     static void vl_api_##n##_t_handler          \
5143     (vl_api_##n##_t * mp)                       \
5144     {                                           \
5145         vat_main_t * vam = &vat_main;           \
5146         i32 retval = ntohl(mp->retval);         \
5147         if (vam->async_mode) {                  \
5148             vam->async_errors += (retval < 0);  \
5149         } else {                                \
5150             vam->retval = retval;               \
5151             vam->result_ready = 1;              \
5152         }                                       \
5153     }
5154 foreach_standard_reply_retval_handler;
5155 #undef _
5156
5157 #define _(n)                                    \
5158     static void vl_api_##n##_t_handler_json     \
5159     (vl_api_##n##_t * mp)                       \
5160     {                                           \
5161         vat_main_t * vam = &vat_main;           \
5162         vat_json_node_t node;                   \
5163         vat_json_init_object(&node);            \
5164         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
5165         vat_json_print(vam->ofp, &node);        \
5166         vam->retval = ntohl(mp->retval);        \
5167         vam->result_ready = 1;                  \
5168     }
5169 foreach_standard_reply_retval_handler;
5170 #undef _
5171
5172 /*
5173  * Table of message reply handlers, must include boilerplate handlers
5174  * we just generated
5175  */
5176
5177 #define foreach_vpe_api_reply_msg                                       \
5178 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
5179 _(CREATE_LOOPBACK_INSTANCE_REPLY, create_loopback_instance_reply)       \
5180 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
5181 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
5182 _(CONTROL_PING_REPLY, control_ping_reply)                               \
5183 _(CLI_REPLY, cli_reply)                                                 \
5184 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
5185 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
5186   sw_interface_add_del_address_reply)                                   \
5187 _(SW_INTERFACE_SET_RX_MODE_REPLY, sw_interface_set_rx_mode_reply)       \
5188 _(SW_INTERFACE_SET_RX_PLACEMENT_REPLY, sw_interface_set_rx_placement_reply)     \
5189 _(SW_INTERFACE_RX_PLACEMENT_DETAILS, sw_interface_rx_placement_details) \
5190 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
5191 _(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
5192 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
5193 _(SW_INTERFACE_SET_VXLAN_BYPASS_REPLY, sw_interface_set_vxlan_bypass_reply) \
5194 _(SW_INTERFACE_SET_GENEVE_BYPASS_REPLY, sw_interface_set_geneve_bypass_reply) \
5195 _(SW_INTERFACE_SET_VXLAN_GPE_BYPASS_REPLY, sw_interface_set_vxlan_gpe_bypass_reply) \
5196 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
5197   sw_interface_set_l2_xconnect_reply)                                   \
5198 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
5199   sw_interface_set_l2_bridge_reply)                                     \
5200 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
5201 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
5202 _(BRIDGE_DOMAIN_SET_MAC_AGE_REPLY, bridge_domain_set_mac_age_reply)     \
5203 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
5204 _(L2FIB_FLUSH_INT_REPLY, l2fib_flush_int_reply)                         \
5205 _(L2FIB_FLUSH_BD_REPLY, l2fib_flush_bd_reply)                           \
5206 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
5207 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
5208 _(TAP_CREATE_V2_REPLY, tap_create_v2_reply)                             \
5209 _(TAP_DELETE_V2_REPLY, tap_delete_v2_reply)                             \
5210 _(SW_INTERFACE_TAP_V2_DETAILS, sw_interface_tap_v2_details)             \
5211 _(VIRTIO_PCI_CREATE_REPLY, virtio_pci_create_reply)                     \
5212 _(VIRTIO_PCI_DELETE_REPLY, virtio_pci_delete_reply)                     \
5213 _(SW_INTERFACE_VIRTIO_PCI_DETAILS, sw_interface_virtio_pci_details)     \
5214 _(BOND_CREATE_REPLY, bond_create_reply)                                 \
5215 _(BOND_DELETE_REPLY, bond_delete_reply)                                 \
5216 _(BOND_ENSLAVE_REPLY, bond_enslave_reply)                               \
5217 _(BOND_DETACH_SLAVE_REPLY, bond_detach_slave_reply)                     \
5218 _(SW_INTERFACE_SET_BOND_WEIGHT_REPLY, sw_interface_set_bond_weight_reply) \
5219 _(SW_INTERFACE_BOND_DETAILS, sw_interface_bond_details)                 \
5220 _(SW_INTERFACE_SLAVE_DETAILS, sw_interface_slave_details)               \
5221 _(IP_ROUTE_ADD_DEL_REPLY, ip_route_add_del_reply)                       \
5222 _(IP_TABLE_ADD_DEL_REPLY, ip_table_add_del_reply)                       \
5223 _(IP_TABLE_REPLACE_BEGIN_REPLY, ip_table_replace_begin_reply)           \
5224 _(IP_TABLE_FLUSH_REPLY, ip_table_flush_reply)                           \
5225 _(IP_TABLE_REPLACE_END_REPLY, ip_table_replace_end_reply)               \
5226 _(IP_MROUTE_ADD_DEL_REPLY, ip_mroute_add_del_reply)                     \
5227 _(MPLS_TABLE_ADD_DEL_REPLY, mpls_table_add_del_reply)                   \
5228 _(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply)                   \
5229 _(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply)                 \
5230 _(BIER_ROUTE_ADD_DEL_REPLY, bier_route_add_del_reply)                   \
5231 _(BIER_TABLE_ADD_DEL_REPLY, bier_table_add_del_reply)                   \
5232 _(MPLS_TUNNEL_ADD_DEL_REPLY, mpls_tunnel_add_del_reply)                 \
5233 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
5234   sw_interface_set_unnumbered_reply)                                    \
5235 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
5236 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
5237 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
5238 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
5239   sw_interface_ip6_enable_disable_reply)                                \
5240 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
5241 _(SR_MPLS_POLICY_ADD_REPLY, sr_mpls_policy_add_reply)                   \
5242 _(SR_MPLS_POLICY_MOD_REPLY, sr_mpls_policy_mod_reply)                   \
5243 _(SR_MPLS_POLICY_DEL_REPLY, sr_mpls_policy_del_reply)                   \
5244 _(SR_POLICY_ADD_REPLY, sr_policy_add_reply)                             \
5245 _(SR_POLICY_MOD_REPLY, sr_policy_mod_reply)                             \
5246 _(SR_POLICY_DEL_REPLY, sr_policy_del_reply)                             \
5247 _(SR_LOCALSID_ADD_DEL_REPLY, sr_localsid_add_del_reply)                 \
5248 _(SR_STEERING_ADD_DEL_REPLY, sr_steering_add_del_reply)                 \
5249 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
5250 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
5251 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
5252 classify_set_interface_ip_table_reply)                                  \
5253 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
5254   classify_set_interface_l2_tables_reply)                               \
5255 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
5256 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
5257 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
5258 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
5259 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
5260   l2tpv3_interface_enable_disable_reply)                                \
5261 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
5262 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
5263 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
5264 _(VXLAN_OFFLOAD_RX_REPLY, vxlan_offload_rx_reply)               \
5265 _(GENEVE_ADD_DEL_TUNNEL_REPLY, geneve_add_del_tunnel_reply)             \
5266 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
5267 _(GENEVE_TUNNEL_DETAILS, geneve_tunnel_details)                         \
5268 _(GRE_TUNNEL_ADD_DEL_REPLY, gre_tunnel_add_del_reply)                   \
5269 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
5270 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
5271 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
5272 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
5273 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
5274 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
5275 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
5276 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
5277 _(SHOW_VERSION_REPLY, show_version_reply)                               \
5278 _(SHOW_THREADS_REPLY, show_threads_reply)                               \
5279 _(L2_FIB_TABLE_DETAILS, l2_fib_table_details)                           \
5280 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)       \
5281 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
5282 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
5283 _(WANT_L2_MACS_EVENTS_REPLY, want_l2_macs_events_reply)                 \
5284 _(L2_MACS_EVENT, l2_macs_event)                                         \
5285 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
5286 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
5287 _(IP_DETAILS, ip_details)                                               \
5288 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
5289 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
5290 _(IPSEC_SPD_ENTRY_ADD_DEL_REPLY, ipsec_spd_entry_add_del_reply)         \
5291 _(IPSEC_SAD_ENTRY_ADD_DEL_REPLY, ipsec_sad_entry_add_del_reply)         \
5292 _(IPSEC_SA_DETAILS, ipsec_sa_details)                                   \
5293 _(IPSEC_TUNNEL_IF_ADD_DEL_REPLY, ipsec_tunnel_if_add_del_reply)         \
5294 _(IPSEC_TUNNEL_IF_SET_SA_REPLY, ipsec_tunnel_if_set_sa_reply)           \
5295 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
5296 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
5297 _(BD_IP_MAC_FLUSH_REPLY, bd_ip_mac_flush_reply)                         \
5298 _(BD_IP_MAC_DETAILS, bd_ip_mac_details)                                 \
5299 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
5300 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
5301 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
5302 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
5303 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
5304 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
5305 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
5306 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
5307 _(ONE_ADD_DEL_LOCATOR_SET_REPLY, one_add_del_locator_set_reply)         \
5308 _(ONE_ADD_DEL_LOCATOR_REPLY, one_add_del_locator_reply)                 \
5309 _(ONE_ADD_DEL_LOCAL_EID_REPLY, one_add_del_local_eid_reply)             \
5310 _(ONE_ADD_DEL_REMOTE_MAPPING_REPLY, one_add_del_remote_mapping_reply)   \
5311 _(ONE_ADD_DEL_ADJACENCY_REPLY, one_add_del_adjacency_reply)             \
5312 _(ONE_ADD_DEL_MAP_RESOLVER_REPLY, one_add_del_map_resolver_reply)       \
5313 _(ONE_ADD_DEL_MAP_SERVER_REPLY, one_add_del_map_server_reply)           \
5314 _(ONE_ENABLE_DISABLE_REPLY, one_enable_disable_reply)                   \
5315 _(ONE_MAP_REGISTER_ENABLE_DISABLE_REPLY,                                \
5316   one_map_register_enable_disable_reply)                                \
5317 _(ONE_MAP_REGISTER_SET_TTL_REPLY, one_map_register_set_ttl_reply)       \
5318 _(ONE_SET_TRANSPORT_PROTOCOL_REPLY, one_set_transport_protocol_reply)   \
5319 _(ONE_GET_TRANSPORT_PROTOCOL_REPLY, one_get_transport_protocol_reply)   \
5320 _(ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                            \
5321   one_map_register_fallback_threshold_reply)                            \
5322 _(ONE_RLOC_PROBE_ENABLE_DISABLE_REPLY,                                  \
5323   one_rloc_probe_enable_disable_reply)                                  \
5324 _(ONE_PITR_SET_LOCATOR_SET_REPLY, one_pitr_set_locator_set_reply)       \
5325 _(ONE_USE_PETR_REPLY, one_use_petr_reply)                               \
5326 _(ONE_MAP_REQUEST_MODE_REPLY, one_map_request_mode_reply)               \
5327 _(ONE_EID_TABLE_ADD_DEL_MAP_REPLY, one_eid_table_add_del_map_reply)     \
5328 _(ONE_LOCATOR_SET_DETAILS, one_locator_set_details)                     \
5329 _(ONE_LOCATOR_DETAILS, one_locator_details)                             \
5330 _(ONE_EID_TABLE_DETAILS, one_eid_table_details)                         \
5331 _(ONE_EID_TABLE_MAP_DETAILS, one_eid_table_map_details)                 \
5332 _(ONE_EID_TABLE_VNI_DETAILS, one_eid_table_vni_details)                 \
5333 _(ONE_MAP_RESOLVER_DETAILS, one_map_resolver_details)                   \
5334 _(ONE_MAP_SERVER_DETAILS, one_map_server_details)                       \
5335 _(ONE_ADJACENCIES_GET_REPLY, one_adjacencies_get_reply)                 \
5336 _(ONE_STATS_DETAILS, one_stats_details)                                 \
5337 _(ONE_STATS_FLUSH_REPLY, one_stats_flush_reply)                         \
5338 _(ONE_STATS_ENABLE_DISABLE_REPLY, one_stats_enable_disable_reply)       \
5339 _(SHOW_ONE_STATS_ENABLE_DISABLE_REPLY,                                  \
5340   show_one_stats_enable_disable_reply)                                  \
5341 _(ONE_ADD_DEL_NDP_ENTRY_REPLY, one_add_del_ndp_entry_reply)             \
5342 _(ONE_NDP_BD_GET_REPLY, one_ndp_bd_get_reply)                           \
5343 _(ONE_NDP_ENTRIES_GET_REPLY, one_ndp_entries_get_reply)                 \
5344 _(ONE_ADD_DEL_L2_ARP_ENTRY_REPLY, one_add_del_l2_arp_entry_reply)       \
5345 _(ONE_L2_ARP_BD_GET_REPLY, one_l2_arp_bd_get_reply)                     \
5346 _(ONE_L2_ARP_ENTRIES_GET_REPLY, one_l2_arp_entries_get_reply)           \
5347 _(ONE_ENABLE_DISABLE_XTR_MODE_REPLY, one_enable_disable_xtr_mode_reply) \
5348 _(ONE_ENABLE_DISABLE_PITR_MODE_REPLY,                                   \
5349   one_enable_disable_pitr_mode_reply)                                   \
5350 _(ONE_ENABLE_DISABLE_PETR_MODE_REPLY,                                   \
5351   one_enable_disable_petr_mode_reply)                                   \
5352 _(ONE_SHOW_XTR_MODE_REPLY, one_show_xtr_mode_reply)                     \
5353 _(ONE_SHOW_PITR_MODE_REPLY, one_show_pitr_mode_reply)                   \
5354 _(ONE_SHOW_PETR_MODE_REPLY, one_show_petr_mode_reply)                   \
5355 _(GPE_SET_ENCAP_MODE_REPLY, gpe_set_encap_mode_reply)                   \
5356 _(GPE_GET_ENCAP_MODE_REPLY, gpe_get_encap_mode_reply)                   \
5357 _(GPE_ADD_DEL_IFACE_REPLY, gpe_add_del_iface_reply)                     \
5358 _(GPE_ENABLE_DISABLE_REPLY, gpe_enable_disable_reply)                   \
5359 _(GPE_ADD_DEL_FWD_ENTRY_REPLY, gpe_add_del_fwd_entry_reply)             \
5360 _(GPE_FWD_ENTRY_VNIS_GET_REPLY, gpe_fwd_entry_vnis_get_reply)           \
5361 _(GPE_FWD_ENTRIES_GET_REPLY, gpe_fwd_entries_get_reply)                 \
5362 _(GPE_NATIVE_FWD_RPATHS_GET_REPLY, gpe_native_fwd_rpaths_get_reply)     \
5363 _(GPE_ADD_DEL_NATIVE_FWD_RPATH_REPLY,                                   \
5364   gpe_add_del_native_fwd_rpath_reply)                                   \
5365 _(GPE_FWD_ENTRY_PATH_DETAILS,                                           \
5366   gpe_fwd_entry_path_details)                                           \
5367 _(SHOW_ONE_STATUS_REPLY, show_one_status_reply)                         \
5368 _(ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                              \
5369   one_add_del_map_request_itr_rlocs_reply)                              \
5370 _(ONE_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                  \
5371   one_get_map_request_itr_rlocs_reply)                                  \
5372 _(SHOW_ONE_NSH_MAPPING_REPLY, show_one_nsh_mapping_reply)               \
5373 _(SHOW_ONE_PITR_REPLY, show_one_pitr_reply)                             \
5374 _(SHOW_ONE_USE_PETR_REPLY, show_one_use_petr_reply)                     \
5375 _(SHOW_ONE_MAP_REQUEST_MODE_REPLY, show_one_map_request_mode_reply)     \
5376 _(SHOW_ONE_RLOC_PROBE_STATE_REPLY, show_one_rloc_probe_state_reply)     \
5377 _(SHOW_ONE_MAP_REGISTER_STATE_REPLY,                                    \
5378   show_one_map_register_state_reply)                                    \
5379 _(SHOW_ONE_MAP_REGISTER_TTL_REPLY, show_one_map_register_ttl_reply)     \
5380 _(SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                       \
5381   show_one_map_register_fallback_threshold_reply)                       \
5382 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
5383 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
5384 _(AF_PACKET_DETAILS, af_packet_details)                                 \
5385 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
5386 _(POLICER_DETAILS, policer_details)                                     \
5387 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
5388 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
5389 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
5390 _(NETMAP_DELETE_REPLY, netmap_delete_reply)                             \
5391 _(MPLS_TUNNEL_DETAILS, mpls_tunnel_details)                             \
5392 _(MPLS_TABLE_DETAILS, mpls_table_details)                               \
5393 _(MPLS_ROUTE_DETAILS, mpls_route_details)                               \
5394 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
5395 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
5396 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
5397 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
5398 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
5399 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
5400 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
5401 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
5402 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
5403 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
5404 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
5405 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
5406 _(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
5407 _(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details)                 \
5408 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
5409 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
5410 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
5411 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
5412 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
5413  ip_source_and_port_range_check_add_del_reply)                          \
5414 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
5415  ip_source_and_port_range_check_interface_add_del_reply)                \
5416 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
5417 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
5418 _(SET_PUNT_REPLY, set_punt_reply)                                       \
5419 _(IP_TABLE_DETAILS, ip_table_details)                                   \
5420 _(IP_ROUTE_DETAILS, ip_route_details)                                   \
5421 _(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply)           \
5422 _(FEATURE_GSO_ENABLE_DISABLE_REPLY, feature_gso_enable_disable_reply)   \
5423 _(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply)       \
5424 _(SW_INTERFACE_ADD_DEL_MAC_ADDRESS_REPLY, sw_interface_add_del_mac_address_reply) \
5425 _(L2_XCONNECT_DETAILS, l2_xconnect_details)                             \
5426 _(HW_INTERFACE_SET_MTU_REPLY, hw_interface_set_mtu_reply)               \
5427 _(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply)           \
5428 _(P2P_ETHERNET_ADD_REPLY, p2p_ethernet_add_reply)                       \
5429 _(P2P_ETHERNET_DEL_REPLY, p2p_ethernet_del_reply)                       \
5430 _(LLDP_CONFIG_REPLY, lldp_config_reply)                                 \
5431 _(SW_INTERFACE_SET_LLDP_REPLY, sw_interface_set_lldp_reply)             \
5432 _(TCP_CONFIGURE_SRC_ADDRESSES_REPLY, tcp_configure_src_addresses_reply) \
5433 _(APP_NAMESPACE_ADD_DEL_REPLY, app_namespace_add_del_reply)             \
5434 _(SESSION_RULE_ADD_DEL_REPLY, session_rule_add_del_reply)               \
5435 _(SESSION_RULES_DETAILS, session_rules_details)                         \
5436 _(IP_CONTAINER_PROXY_ADD_DEL_REPLY, ip_container_proxy_add_del_reply)   \
5437 _(OUTPUT_ACL_SET_INTERFACE_REPLY, output_acl_set_interface_reply)       \
5438 _(QOS_RECORD_ENABLE_DISABLE_REPLY, qos_record_enable_disable_reply)
5439
5440 #define foreach_standalone_reply_msg                                    \
5441 _(SW_INTERFACE_EVENT, sw_interface_event)
5442
5443 typedef struct
5444 {
5445   u8 *name;
5446   u32 value;
5447 } name_sort_t;
5448
5449 #define STR_VTR_OP_CASE(op)     \
5450     case L2_VTR_ ## op:         \
5451         return "" # op;
5452
5453 static const char *
5454 str_vtr_op (u32 vtr_op)
5455 {
5456   switch (vtr_op)
5457     {
5458       STR_VTR_OP_CASE (DISABLED);
5459       STR_VTR_OP_CASE (PUSH_1);
5460       STR_VTR_OP_CASE (PUSH_2);
5461       STR_VTR_OP_CASE (POP_1);
5462       STR_VTR_OP_CASE (POP_2);
5463       STR_VTR_OP_CASE (TRANSLATE_1_1);
5464       STR_VTR_OP_CASE (TRANSLATE_1_2);
5465       STR_VTR_OP_CASE (TRANSLATE_2_1);
5466       STR_VTR_OP_CASE (TRANSLATE_2_2);
5467     }
5468
5469   return "UNKNOWN";
5470 }
5471
5472 static int
5473 dump_sub_interface_table (vat_main_t * vam)
5474 {
5475   const sw_interface_subif_t *sub = NULL;
5476
5477   if (vam->json_output)
5478     {
5479       clib_warning
5480         ("JSON output supported only for VPE API calls and dump_stats_table");
5481       return -99;
5482     }
5483
5484   print (vam->ofp,
5485          "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
5486          "Interface", "sw_if_index",
5487          "sub id", "dot1ad", "tags", "outer id",
5488          "inner id", "exact", "default", "outer any", "inner any");
5489
5490   vec_foreach (sub, vam->sw_if_subif_table)
5491   {
5492     print (vam->ofp,
5493            "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
5494            sub->interface_name,
5495            sub->sw_if_index,
5496            sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
5497            sub->sub_number_of_tags, sub->sub_outer_vlan_id,
5498            sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
5499            sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
5500     if (sub->vtr_op != L2_VTR_DISABLED)
5501       {
5502         print (vam->ofp,
5503                "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
5504                "tag1: %d tag2: %d ]",
5505                str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
5506                sub->vtr_tag1, sub->vtr_tag2);
5507       }
5508   }
5509
5510   return 0;
5511 }
5512
5513 static int
5514 name_sort_cmp (void *a1, void *a2)
5515 {
5516   name_sort_t *n1 = a1;
5517   name_sort_t *n2 = a2;
5518
5519   return strcmp ((char *) n1->name, (char *) n2->name);
5520 }
5521
5522 static int
5523 dump_interface_table (vat_main_t * vam)
5524 {
5525   hash_pair_t *p;
5526   name_sort_t *nses = 0, *ns;
5527
5528   if (vam->json_output)
5529     {
5530       clib_warning
5531         ("JSON output supported only for VPE API calls and dump_stats_table");
5532       return -99;
5533     }
5534
5535   /* *INDENT-OFF* */
5536   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5537   ({
5538     vec_add2 (nses, ns, 1);
5539     ns->name = (u8 *)(p->key);
5540     ns->value = (u32) p->value[0];
5541   }));
5542   /* *INDENT-ON* */
5543
5544   vec_sort_with_function (nses, name_sort_cmp);
5545
5546   print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
5547   vec_foreach (ns, nses)
5548   {
5549     print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
5550   }
5551   vec_free (nses);
5552   return 0;
5553 }
5554
5555 static int
5556 dump_ip_table (vat_main_t * vam, int is_ipv6)
5557 {
5558   const ip_details_t *det = NULL;
5559   const ip_address_details_t *address = NULL;
5560   u32 i = ~0;
5561
5562   print (vam->ofp, "%-12s", "sw_if_index");
5563
5564   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
5565   {
5566     i++;
5567     if (!det->present)
5568       {
5569         continue;
5570       }
5571     print (vam->ofp, "%-12d", i);
5572     print (vam->ofp, "            %-30s%-13s", "Address", "Prefix length");
5573     if (!det->addr)
5574       {
5575         continue;
5576       }
5577     vec_foreach (address, det->addr)
5578     {
5579       print (vam->ofp,
5580              "            %-30U%-13d",
5581              is_ipv6 ? format_ip6_address : format_ip4_address,
5582              address->ip, address->prefix_length);
5583     }
5584   }
5585
5586   return 0;
5587 }
5588
5589 static int
5590 dump_ipv4_table (vat_main_t * vam)
5591 {
5592   if (vam->json_output)
5593     {
5594       clib_warning
5595         ("JSON output supported only for VPE API calls and dump_stats_table");
5596       return -99;
5597     }
5598
5599   return dump_ip_table (vam, 0);
5600 }
5601
5602 static int
5603 dump_ipv6_table (vat_main_t * vam)
5604 {
5605   if (vam->json_output)
5606     {
5607       clib_warning
5608         ("JSON output supported only for VPE API calls and dump_stats_table");
5609       return -99;
5610     }
5611
5612   return dump_ip_table (vam, 1);
5613 }
5614
5615 /*
5616  * Pass CLI buffers directly in the CLI_INBAND API message,
5617  * instead of an additional shared memory area.
5618  */
5619 static int
5620 exec_inband (vat_main_t * vam)
5621 {
5622   vl_api_cli_inband_t *mp;
5623   unformat_input_t *i = vam->input;
5624   int ret;
5625
5626   if (vec_len (i->buffer) == 0)
5627     return -1;
5628
5629   if (vam->exec_mode == 0 && unformat (i, "mode"))
5630     {
5631       vam->exec_mode = 1;
5632       return 0;
5633     }
5634   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
5635     {
5636       vam->exec_mode = 0;
5637       return 0;
5638     }
5639
5640   /*
5641    * In order for the CLI command to work, it
5642    * must be a vector ending in \n, not a C-string ending
5643    * in \n\0.
5644    */
5645   u32 len = vec_len (vam->input->buffer);
5646   M2 (CLI_INBAND, mp, len);
5647   vl_api_to_api_string (len - 1, (const char *) vam->input->buffer, &mp->cmd);
5648
5649   S (mp);
5650   W (ret);
5651   /* json responses may or may not include a useful reply... */
5652   if (vec_len (vam->cmd_reply))
5653     print (vam->ofp, "%v", (char *) (vam->cmd_reply));
5654   return ret;
5655 }
5656
5657 int
5658 exec (vat_main_t * vam)
5659 {
5660   return exec_inband (vam);
5661 }
5662
5663 static int
5664 api_create_loopback (vat_main_t * vam)
5665 {
5666   unformat_input_t *i = vam->input;
5667   vl_api_create_loopback_t *mp;
5668   vl_api_create_loopback_instance_t *mp_lbi;
5669   u8 mac_address[6];
5670   u8 mac_set = 0;
5671   u8 is_specified = 0;
5672   u32 user_instance = 0;
5673   int ret;
5674
5675   clib_memset (mac_address, 0, sizeof (mac_address));
5676
5677   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5678     {
5679       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5680         mac_set = 1;
5681       if (unformat (i, "instance %d", &user_instance))
5682         is_specified = 1;
5683       else
5684         break;
5685     }
5686
5687   if (is_specified)
5688     {
5689       M (CREATE_LOOPBACK_INSTANCE, mp_lbi);
5690       mp_lbi->is_specified = is_specified;
5691       if (is_specified)
5692         mp_lbi->user_instance = htonl (user_instance);
5693       if (mac_set)
5694         clib_memcpy (mp_lbi->mac_address, mac_address, sizeof (mac_address));
5695       S (mp_lbi);
5696     }
5697   else
5698     {
5699       /* Construct the API message */
5700       M (CREATE_LOOPBACK, mp);
5701       if (mac_set)
5702         clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
5703       S (mp);
5704     }
5705
5706   W (ret);
5707   return ret;
5708 }
5709
5710 static int
5711 api_delete_loopback (vat_main_t * vam)
5712 {
5713   unformat_input_t *i = vam->input;
5714   vl_api_delete_loopback_t *mp;
5715   u32 sw_if_index = ~0;
5716   int ret;
5717
5718   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5719     {
5720       if (unformat (i, "sw_if_index %d", &sw_if_index))
5721         ;
5722       else
5723         break;
5724     }
5725
5726   if (sw_if_index == ~0)
5727     {
5728       errmsg ("missing sw_if_index");
5729       return -99;
5730     }
5731
5732   /* Construct the API message */
5733   M (DELETE_LOOPBACK, mp);
5734   mp->sw_if_index = ntohl (sw_if_index);
5735
5736   S (mp);
5737   W (ret);
5738   return ret;
5739 }
5740
5741 static int
5742 api_want_interface_events (vat_main_t * vam)
5743 {
5744   unformat_input_t *i = vam->input;
5745   vl_api_want_interface_events_t *mp;
5746   int enable = -1;
5747   int ret;
5748
5749   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5750     {
5751       if (unformat (i, "enable"))
5752         enable = 1;
5753       else if (unformat (i, "disable"))
5754         enable = 0;
5755       else
5756         break;
5757     }
5758
5759   if (enable == -1)
5760     {
5761       errmsg ("missing enable|disable");
5762       return -99;
5763     }
5764
5765   M (WANT_INTERFACE_EVENTS, mp);
5766   mp->enable_disable = enable;
5767
5768   vam->interface_event_display = enable;
5769
5770   S (mp);
5771   W (ret);
5772   return ret;
5773 }
5774
5775
5776 /* Note: non-static, called once to set up the initial intfc table */
5777 int
5778 api_sw_interface_dump (vat_main_t * vam)
5779 {
5780   vl_api_sw_interface_dump_t *mp;
5781   vl_api_control_ping_t *mp_ping;
5782   hash_pair_t *p;
5783   name_sort_t *nses = 0, *ns;
5784   sw_interface_subif_t *sub = NULL;
5785   int ret;
5786
5787   /* Toss the old name table */
5788   /* *INDENT-OFF* */
5789   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5790   ({
5791     vec_add2 (nses, ns, 1);
5792     ns->name = (u8 *)(p->key);
5793     ns->value = (u32) p->value[0];
5794   }));
5795   /* *INDENT-ON* */
5796
5797   hash_free (vam->sw_if_index_by_interface_name);
5798
5799   vec_foreach (ns, nses) vec_free (ns->name);
5800
5801   vec_free (nses);
5802
5803   vec_foreach (sub, vam->sw_if_subif_table)
5804   {
5805     vec_free (sub->interface_name);
5806   }
5807   vec_free (vam->sw_if_subif_table);
5808
5809   /* recreate the interface name hash table */
5810   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
5811
5812   /*
5813    * Ask for all interface names. Otherwise, the epic catalog of
5814    * name filters becomes ridiculously long, and vat ends up needing
5815    * to be taught about new interface types.
5816    */
5817   M (SW_INTERFACE_DUMP, mp);
5818   S (mp);
5819
5820   /* Use a control ping for synchronization */
5821   MPING (CONTROL_PING, mp_ping);
5822   S (mp_ping);
5823
5824   W (ret);
5825   return ret;
5826 }
5827
5828 static int
5829 api_sw_interface_set_flags (vat_main_t * vam)
5830 {
5831   unformat_input_t *i = vam->input;
5832   vl_api_sw_interface_set_flags_t *mp;
5833   u32 sw_if_index;
5834   u8 sw_if_index_set = 0;
5835   u8 admin_up = 0;
5836   int ret;
5837
5838   /* Parse args required to build the message */
5839   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5840     {
5841       if (unformat (i, "admin-up"))
5842         admin_up = 1;
5843       else if (unformat (i, "admin-down"))
5844         admin_up = 0;
5845       else
5846         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5847         sw_if_index_set = 1;
5848       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5849         sw_if_index_set = 1;
5850       else
5851         break;
5852     }
5853
5854   if (sw_if_index_set == 0)
5855     {
5856       errmsg ("missing interface name or sw_if_index");
5857       return -99;
5858     }
5859
5860   /* Construct the API message */
5861   M (SW_INTERFACE_SET_FLAGS, mp);
5862   mp->sw_if_index = ntohl (sw_if_index);
5863   mp->flags = ntohl ((admin_up) ? IF_STATUS_API_FLAG_ADMIN_UP : 0);
5864
5865   /* send it... */
5866   S (mp);
5867
5868   /* Wait for a reply, return the good/bad news... */
5869   W (ret);
5870   return ret;
5871 }
5872
5873 static int
5874 api_sw_interface_set_rx_mode (vat_main_t * vam)
5875 {
5876   unformat_input_t *i = vam->input;
5877   vl_api_sw_interface_set_rx_mode_t *mp;
5878   u32 sw_if_index;
5879   u8 sw_if_index_set = 0;
5880   int ret;
5881   u8 queue_id_valid = 0;
5882   u32 queue_id;
5883   vnet_hw_interface_rx_mode mode = VNET_HW_INTERFACE_RX_MODE_UNKNOWN;
5884
5885   /* Parse args required to build the message */
5886   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5887     {
5888       if (unformat (i, "queue %d", &queue_id))
5889         queue_id_valid = 1;
5890       else if (unformat (i, "polling"))
5891         mode = VNET_HW_INTERFACE_RX_MODE_POLLING;
5892       else if (unformat (i, "interrupt"))
5893         mode = VNET_HW_INTERFACE_RX_MODE_INTERRUPT;
5894       else if (unformat (i, "adaptive"))
5895         mode = VNET_HW_INTERFACE_RX_MODE_ADAPTIVE;
5896       else
5897         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5898         sw_if_index_set = 1;
5899       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5900         sw_if_index_set = 1;
5901       else
5902         break;
5903     }
5904
5905   if (sw_if_index_set == 0)
5906     {
5907       errmsg ("missing interface name or sw_if_index");
5908       return -99;
5909     }
5910   if (mode == VNET_HW_INTERFACE_RX_MODE_UNKNOWN)
5911     {
5912       errmsg ("missing rx-mode");
5913       return -99;
5914     }
5915
5916   /* Construct the API message */
5917   M (SW_INTERFACE_SET_RX_MODE, mp);
5918   mp->sw_if_index = ntohl (sw_if_index);
5919   mp->mode = (vl_api_rx_mode_t) mode;
5920   mp->queue_id_valid = queue_id_valid;
5921   mp->queue_id = queue_id_valid ? ntohl (queue_id) : ~0;
5922
5923   /* send it... */
5924   S (mp);
5925
5926   /* Wait for a reply, return the good/bad news... */
5927   W (ret);
5928   return ret;
5929 }
5930
5931 static int
5932 api_sw_interface_set_rx_placement (vat_main_t * vam)
5933 {
5934   unformat_input_t *i = vam->input;
5935   vl_api_sw_interface_set_rx_placement_t *mp;
5936   u32 sw_if_index;
5937   u8 sw_if_index_set = 0;
5938   int ret;
5939   u8 is_main = 0;
5940   u32 queue_id, thread_index;
5941
5942   /* Parse args required to build the message */
5943   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5944     {
5945       if (unformat (i, "queue %d", &queue_id))
5946         ;
5947       else if (unformat (i, "main"))
5948         is_main = 1;
5949       else if (unformat (i, "worker %d", &thread_index))
5950         ;
5951       else
5952         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5953         sw_if_index_set = 1;
5954       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5955         sw_if_index_set = 1;
5956       else
5957         break;
5958     }
5959
5960   if (sw_if_index_set == 0)
5961     {
5962       errmsg ("missing interface name or sw_if_index");
5963       return -99;
5964     }
5965
5966   if (is_main)
5967     thread_index = 0;
5968   /* Construct the API message */
5969   M (SW_INTERFACE_SET_RX_PLACEMENT, mp);
5970   mp->sw_if_index = ntohl (sw_if_index);
5971   mp->worker_id = ntohl (thread_index);
5972   mp->queue_id = ntohl (queue_id);
5973   mp->is_main = is_main;
5974
5975   /* send it... */
5976   S (mp);
5977   /* Wait for a reply, return the good/bad news... */
5978   W (ret);
5979   return ret;
5980 }
5981
5982 static void vl_api_sw_interface_rx_placement_details_t_handler
5983   (vl_api_sw_interface_rx_placement_details_t * mp)
5984 {
5985   vat_main_t *vam = &vat_main;
5986   u32 worker_id = ntohl (mp->worker_id);
5987
5988   print (vam->ofp,
5989          "\n%-11d %-11s %-6d %-5d %-9s",
5990          ntohl (mp->sw_if_index), (worker_id == 0) ? "main" : "worker",
5991          worker_id, ntohl (mp->queue_id),
5992          (mp->mode ==
5993           1) ? "polling" : ((mp->mode == 2) ? "interrupt" : "adaptive"));
5994 }
5995
5996 static void vl_api_sw_interface_rx_placement_details_t_handler_json
5997   (vl_api_sw_interface_rx_placement_details_t * mp)
5998 {
5999   vat_main_t *vam = &vat_main;
6000   vat_json_node_t *node = NULL;
6001
6002   if (VAT_JSON_ARRAY != vam->json_tree.type)
6003     {
6004       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
6005       vat_json_init_array (&vam->json_tree);
6006     }
6007   node = vat_json_array_add (&vam->json_tree);
6008
6009   vat_json_init_object (node);
6010   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
6011   vat_json_object_add_uint (node, "worker_id", ntohl (mp->worker_id));
6012   vat_json_object_add_uint (node, "queue_id", ntohl (mp->queue_id));
6013   vat_json_object_add_uint (node, "mode", mp->mode);
6014 }
6015
6016 static int
6017 api_sw_interface_rx_placement_dump (vat_main_t * vam)
6018 {
6019   unformat_input_t *i = vam->input;
6020   vl_api_sw_interface_rx_placement_dump_t *mp;
6021   vl_api_control_ping_t *mp_ping;
6022   int ret;
6023   u32 sw_if_index;
6024   u8 sw_if_index_set = 0;
6025
6026   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6027     {
6028       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6029         sw_if_index_set++;
6030       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6031         sw_if_index_set++;
6032       else
6033         break;
6034     }
6035
6036   print (vam->ofp,
6037          "\n%-11s %-11s %-6s %-5s %-4s",
6038          "sw_if_index", "main/worker", "thread", "queue", "mode");
6039
6040   /* Dump Interface rx placement */
6041   M (SW_INTERFACE_RX_PLACEMENT_DUMP, mp);
6042
6043   if (sw_if_index_set)
6044     mp->sw_if_index = htonl (sw_if_index);
6045   else
6046     mp->sw_if_index = ~0;
6047
6048   S (mp);
6049
6050   /* Use a control ping for synchronization */
6051   MPING (CONTROL_PING, mp_ping);
6052   S (mp_ping);
6053
6054   W (ret);
6055   return ret;
6056 }
6057
6058 static int
6059 api_sw_interface_clear_stats (vat_main_t * vam)
6060 {
6061   unformat_input_t *i = vam->input;
6062   vl_api_sw_interface_clear_stats_t *mp;
6063   u32 sw_if_index;
6064   u8 sw_if_index_set = 0;
6065   int ret;
6066
6067   /* Parse args required to build the message */
6068   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6069     {
6070       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6071         sw_if_index_set = 1;
6072       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6073         sw_if_index_set = 1;
6074       else
6075         break;
6076     }
6077
6078   /* Construct the API message */
6079   M (SW_INTERFACE_CLEAR_STATS, mp);
6080
6081   if (sw_if_index_set == 1)
6082     mp->sw_if_index = ntohl (sw_if_index);
6083   else
6084     mp->sw_if_index = ~0;
6085
6086   /* send it... */
6087   S (mp);
6088
6089   /* Wait for a reply, return the good/bad news... */
6090   W (ret);
6091   return ret;
6092 }
6093
6094 static int
6095 api_sw_interface_add_del_address (vat_main_t * vam)
6096 {
6097   unformat_input_t *i = vam->input;
6098   vl_api_sw_interface_add_del_address_t *mp;
6099   u32 sw_if_index;
6100   u8 sw_if_index_set = 0;
6101   u8 is_add = 1, del_all = 0;
6102   u32 address_length = 0;
6103   u8 v4_address_set = 0;
6104   u8 v6_address_set = 0;
6105   ip4_address_t v4address;
6106   ip6_address_t v6address;
6107   int ret;
6108
6109   /* Parse args required to build the message */
6110   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6111     {
6112       if (unformat (i, "del-all"))
6113         del_all = 1;
6114       else if (unformat (i, "del"))
6115         is_add = 0;
6116       else
6117         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6118         sw_if_index_set = 1;
6119       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6120         sw_if_index_set = 1;
6121       else if (unformat (i, "%U/%d",
6122                          unformat_ip4_address, &v4address, &address_length))
6123         v4_address_set = 1;
6124       else if (unformat (i, "%U/%d",
6125                          unformat_ip6_address, &v6address, &address_length))
6126         v6_address_set = 1;
6127       else
6128         break;
6129     }
6130
6131   if (sw_if_index_set == 0)
6132     {
6133       errmsg ("missing interface name or sw_if_index");
6134       return -99;
6135     }
6136   if (v4_address_set && v6_address_set)
6137     {
6138       errmsg ("both v4 and v6 addresses set");
6139       return -99;
6140     }
6141   if (!v4_address_set && !v6_address_set && !del_all)
6142     {
6143       errmsg ("no addresses set");
6144       return -99;
6145     }
6146
6147   /* Construct the API message */
6148   M (SW_INTERFACE_ADD_DEL_ADDRESS, mp);
6149
6150   mp->sw_if_index = ntohl (sw_if_index);
6151   mp->is_add = is_add;
6152   mp->del_all = del_all;
6153   if (v6_address_set)
6154     {
6155       mp->prefix.address.af = ADDRESS_IP6;
6156       clib_memcpy (mp->prefix.address.un.ip6, &v6address, sizeof (v6address));
6157     }
6158   else
6159     {
6160       mp->prefix.address.af = ADDRESS_IP4;
6161       clib_memcpy (mp->prefix.address.un.ip4, &v4address, sizeof (v4address));
6162     }
6163   mp->prefix.len = address_length;
6164
6165   /* send it... */
6166   S (mp);
6167
6168   /* Wait for a reply, return good/bad news  */
6169   W (ret);
6170   return ret;
6171 }
6172
6173 static int
6174 api_sw_interface_set_mpls_enable (vat_main_t * vam)
6175 {
6176   unformat_input_t *i = vam->input;
6177   vl_api_sw_interface_set_mpls_enable_t *mp;
6178   u32 sw_if_index;
6179   u8 sw_if_index_set = 0;
6180   u8 enable = 1;
6181   int ret;
6182
6183   /* Parse args required to build the message */
6184   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6185     {
6186       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6187         sw_if_index_set = 1;
6188       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6189         sw_if_index_set = 1;
6190       else if (unformat (i, "disable"))
6191         enable = 0;
6192       else if (unformat (i, "dis"))
6193         enable = 0;
6194       else
6195         break;
6196     }
6197
6198   if (sw_if_index_set == 0)
6199     {
6200       errmsg ("missing interface name or sw_if_index");
6201       return -99;
6202     }
6203
6204   /* Construct the API message */
6205   M (SW_INTERFACE_SET_MPLS_ENABLE, mp);
6206
6207   mp->sw_if_index = ntohl (sw_if_index);
6208   mp->enable = enable;
6209
6210   /* send it... */
6211   S (mp);
6212
6213   /* Wait for a reply... */
6214   W (ret);
6215   return ret;
6216 }
6217
6218 static int
6219 api_sw_interface_set_table (vat_main_t * vam)
6220 {
6221   unformat_input_t *i = vam->input;
6222   vl_api_sw_interface_set_table_t *mp;
6223   u32 sw_if_index, vrf_id = 0;
6224   u8 sw_if_index_set = 0;
6225   u8 is_ipv6 = 0;
6226   int ret;
6227
6228   /* Parse args required to build the message */
6229   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6230     {
6231       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6232         sw_if_index_set = 1;
6233       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6234         sw_if_index_set = 1;
6235       else if (unformat (i, "vrf %d", &vrf_id))
6236         ;
6237       else if (unformat (i, "ipv6"))
6238         is_ipv6 = 1;
6239       else
6240         break;
6241     }
6242
6243   if (sw_if_index_set == 0)
6244     {
6245       errmsg ("missing interface name or sw_if_index");
6246       return -99;
6247     }
6248
6249   /* Construct the API message */
6250   M (SW_INTERFACE_SET_TABLE, mp);
6251
6252   mp->sw_if_index = ntohl (sw_if_index);
6253   mp->is_ipv6 = is_ipv6;
6254   mp->vrf_id = ntohl (vrf_id);
6255
6256   /* send it... */
6257   S (mp);
6258
6259   /* Wait for a reply... */
6260   W (ret);
6261   return ret;
6262 }
6263
6264 static void vl_api_sw_interface_get_table_reply_t_handler
6265   (vl_api_sw_interface_get_table_reply_t * mp)
6266 {
6267   vat_main_t *vam = &vat_main;
6268
6269   print (vam->ofp, "%d", ntohl (mp->vrf_id));
6270
6271   vam->retval = ntohl (mp->retval);
6272   vam->result_ready = 1;
6273
6274 }
6275
6276 static void vl_api_sw_interface_get_table_reply_t_handler_json
6277   (vl_api_sw_interface_get_table_reply_t * mp)
6278 {
6279   vat_main_t *vam = &vat_main;
6280   vat_json_node_t node;
6281
6282   vat_json_init_object (&node);
6283   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
6284   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
6285
6286   vat_json_print (vam->ofp, &node);
6287   vat_json_free (&node);
6288
6289   vam->retval = ntohl (mp->retval);
6290   vam->result_ready = 1;
6291 }
6292
6293 static int
6294 api_sw_interface_get_table (vat_main_t * vam)
6295 {
6296   unformat_input_t *i = vam->input;
6297   vl_api_sw_interface_get_table_t *mp;
6298   u32 sw_if_index;
6299   u8 sw_if_index_set = 0;
6300   u8 is_ipv6 = 0;
6301   int ret;
6302
6303   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6304     {
6305       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6306         sw_if_index_set = 1;
6307       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6308         sw_if_index_set = 1;
6309       else if (unformat (i, "ipv6"))
6310         is_ipv6 = 1;
6311       else
6312         break;
6313     }
6314
6315   if (sw_if_index_set == 0)
6316     {
6317       errmsg ("missing interface name or sw_if_index");
6318       return -99;
6319     }
6320
6321   M (SW_INTERFACE_GET_TABLE, mp);
6322   mp->sw_if_index = htonl (sw_if_index);
6323   mp->is_ipv6 = is_ipv6;
6324
6325   S (mp);
6326   W (ret);
6327   return ret;
6328 }
6329
6330 static int
6331 api_sw_interface_set_vpath (vat_main_t * vam)
6332 {
6333   unformat_input_t *i = vam->input;
6334   vl_api_sw_interface_set_vpath_t *mp;
6335   u32 sw_if_index = 0;
6336   u8 sw_if_index_set = 0;
6337   u8 is_enable = 0;
6338   int ret;
6339
6340   /* Parse args required to build the message */
6341   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6342     {
6343       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6344         sw_if_index_set = 1;
6345       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6346         sw_if_index_set = 1;
6347       else if (unformat (i, "enable"))
6348         is_enable = 1;
6349       else if (unformat (i, "disable"))
6350         is_enable = 0;
6351       else
6352         break;
6353     }
6354
6355   if (sw_if_index_set == 0)
6356     {
6357       errmsg ("missing interface name or sw_if_index");
6358       return -99;
6359     }
6360
6361   /* Construct the API message */
6362   M (SW_INTERFACE_SET_VPATH, mp);
6363
6364   mp->sw_if_index = ntohl (sw_if_index);
6365   mp->enable = is_enable;
6366
6367   /* send it... */
6368   S (mp);
6369
6370   /* Wait for a reply... */
6371   W (ret);
6372   return ret;
6373 }
6374
6375 static int
6376 api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
6377 {
6378   unformat_input_t *i = vam->input;
6379   vl_api_sw_interface_set_vxlan_bypass_t *mp;
6380   u32 sw_if_index = 0;
6381   u8 sw_if_index_set = 0;
6382   u8 is_enable = 1;
6383   u8 is_ipv6 = 0;
6384   int ret;
6385
6386   /* Parse args required to build the message */
6387   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6388     {
6389       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6390         sw_if_index_set = 1;
6391       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6392         sw_if_index_set = 1;
6393       else if (unformat (i, "enable"))
6394         is_enable = 1;
6395       else if (unformat (i, "disable"))
6396         is_enable = 0;
6397       else if (unformat (i, "ip4"))
6398         is_ipv6 = 0;
6399       else if (unformat (i, "ip6"))
6400         is_ipv6 = 1;
6401       else
6402         break;
6403     }
6404
6405   if (sw_if_index_set == 0)
6406     {
6407       errmsg ("missing interface name or sw_if_index");
6408       return -99;
6409     }
6410
6411   /* Construct the API message */
6412   M (SW_INTERFACE_SET_VXLAN_BYPASS, mp);
6413
6414   mp->sw_if_index = ntohl (sw_if_index);
6415   mp->enable = is_enable;
6416   mp->is_ipv6 = is_ipv6;
6417
6418   /* send it... */
6419   S (mp);
6420
6421   /* Wait for a reply... */
6422   W (ret);
6423   return ret;
6424 }
6425
6426 static int
6427 api_sw_interface_set_geneve_bypass (vat_main_t * vam)
6428 {
6429   unformat_input_t *i = vam->input;
6430   vl_api_sw_interface_set_geneve_bypass_t *mp;
6431   u32 sw_if_index = 0;
6432   u8 sw_if_index_set = 0;
6433   u8 is_enable = 1;
6434   u8 is_ipv6 = 0;
6435   int ret;
6436
6437   /* Parse args required to build the message */
6438   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6439     {
6440       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6441         sw_if_index_set = 1;
6442       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6443         sw_if_index_set = 1;
6444       else if (unformat (i, "enable"))
6445         is_enable = 1;
6446       else if (unformat (i, "disable"))
6447         is_enable = 0;
6448       else if (unformat (i, "ip4"))
6449         is_ipv6 = 0;
6450       else if (unformat (i, "ip6"))
6451         is_ipv6 = 1;
6452       else
6453         break;
6454     }
6455
6456   if (sw_if_index_set == 0)
6457     {
6458       errmsg ("missing interface name or sw_if_index");
6459       return -99;
6460     }
6461
6462   /* Construct the API message */
6463   M (SW_INTERFACE_SET_GENEVE_BYPASS, mp);
6464
6465   mp->sw_if_index = ntohl (sw_if_index);
6466   mp->enable = is_enable;
6467   mp->is_ipv6 = is_ipv6;
6468
6469   /* send it... */
6470   S (mp);
6471
6472   /* Wait for a reply... */
6473   W (ret);
6474   return ret;
6475 }
6476
6477 static int
6478 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
6479 {
6480   unformat_input_t *i = vam->input;
6481   vl_api_sw_interface_set_l2_xconnect_t *mp;
6482   u32 rx_sw_if_index;
6483   u8 rx_sw_if_index_set = 0;
6484   u32 tx_sw_if_index;
6485   u8 tx_sw_if_index_set = 0;
6486   u8 enable = 1;
6487   int ret;
6488
6489   /* Parse args required to build the message */
6490   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6491     {
6492       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
6493         rx_sw_if_index_set = 1;
6494       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
6495         tx_sw_if_index_set = 1;
6496       else if (unformat (i, "rx"))
6497         {
6498           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6499             {
6500               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6501                             &rx_sw_if_index))
6502                 rx_sw_if_index_set = 1;
6503             }
6504           else
6505             break;
6506         }
6507       else if (unformat (i, "tx"))
6508         {
6509           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6510             {
6511               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6512                             &tx_sw_if_index))
6513                 tx_sw_if_index_set = 1;
6514             }
6515           else
6516             break;
6517         }
6518       else if (unformat (i, "enable"))
6519         enable = 1;
6520       else if (unformat (i, "disable"))
6521         enable = 0;
6522       else
6523         break;
6524     }
6525
6526   if (rx_sw_if_index_set == 0)
6527     {
6528       errmsg ("missing rx interface name or rx_sw_if_index");
6529       return -99;
6530     }
6531
6532   if (enable && (tx_sw_if_index_set == 0))
6533     {
6534       errmsg ("missing tx interface name or tx_sw_if_index");
6535       return -99;
6536     }
6537
6538   M (SW_INTERFACE_SET_L2_XCONNECT, mp);
6539
6540   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6541   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
6542   mp->enable = enable;
6543
6544   S (mp);
6545   W (ret);
6546   return ret;
6547 }
6548
6549 static int
6550 api_sw_interface_set_l2_bridge (vat_main_t * vam)
6551 {
6552   unformat_input_t *i = vam->input;
6553   vl_api_sw_interface_set_l2_bridge_t *mp;
6554   vl_api_l2_port_type_t port_type;
6555   u32 rx_sw_if_index;
6556   u8 rx_sw_if_index_set = 0;
6557   u32 bd_id;
6558   u8 bd_id_set = 0;
6559   u32 shg = 0;
6560   u8 enable = 1;
6561   int ret;
6562
6563   port_type = L2_API_PORT_TYPE_NORMAL;
6564
6565   /* Parse args required to build the message */
6566   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6567     {
6568       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
6569         rx_sw_if_index_set = 1;
6570       else if (unformat (i, "bd_id %d", &bd_id))
6571         bd_id_set = 1;
6572       else
6573         if (unformat
6574             (i, "%U", api_unformat_sw_if_index, vam, &rx_sw_if_index))
6575         rx_sw_if_index_set = 1;
6576       else if (unformat (i, "shg %d", &shg))
6577         ;
6578       else if (unformat (i, "bvi"))
6579         port_type = L2_API_PORT_TYPE_BVI;
6580       else if (unformat (i, "uu-fwd"))
6581         port_type = L2_API_PORT_TYPE_UU_FWD;
6582       else if (unformat (i, "enable"))
6583         enable = 1;
6584       else if (unformat (i, "disable"))
6585         enable = 0;
6586       else
6587         break;
6588     }
6589
6590   if (rx_sw_if_index_set == 0)
6591     {
6592       errmsg ("missing rx interface name or sw_if_index");
6593       return -99;
6594     }
6595
6596   if (enable && (bd_id_set == 0))
6597     {
6598       errmsg ("missing bridge domain");
6599       return -99;
6600     }
6601
6602   M (SW_INTERFACE_SET_L2_BRIDGE, mp);
6603
6604   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6605   mp->bd_id = ntohl (bd_id);
6606   mp->shg = (u8) shg;
6607   mp->port_type = ntohl (port_type);
6608   mp->enable = enable;
6609
6610   S (mp);
6611   W (ret);
6612   return ret;
6613 }
6614
6615 static int
6616 api_bridge_domain_dump (vat_main_t * vam)
6617 {
6618   unformat_input_t *i = vam->input;
6619   vl_api_bridge_domain_dump_t *mp;
6620   vl_api_control_ping_t *mp_ping;
6621   u32 bd_id = ~0;
6622   int ret;
6623
6624   /* Parse args required to build the message */
6625   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6626     {
6627       if (unformat (i, "bd_id %d", &bd_id))
6628         ;
6629       else
6630         break;
6631     }
6632
6633   M (BRIDGE_DOMAIN_DUMP, mp);
6634   mp->bd_id = ntohl (bd_id);
6635   S (mp);
6636
6637   /* Use a control ping for synchronization */
6638   MPING (CONTROL_PING, mp_ping);
6639   S (mp_ping);
6640
6641   W (ret);
6642   return ret;
6643 }
6644
6645 static int
6646 api_bridge_domain_add_del (vat_main_t * vam)
6647 {
6648   unformat_input_t *i = vam->input;
6649   vl_api_bridge_domain_add_del_t *mp;
6650   u32 bd_id = ~0;
6651   u8 is_add = 1;
6652   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
6653   u8 *bd_tag = NULL;
6654   u32 mac_age = 0;
6655   int ret;
6656
6657   /* Parse args required to build the message */
6658   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6659     {
6660       if (unformat (i, "bd_id %d", &bd_id))
6661         ;
6662       else if (unformat (i, "flood %d", &flood))
6663         ;
6664       else if (unformat (i, "uu-flood %d", &uu_flood))
6665         ;
6666       else if (unformat (i, "forward %d", &forward))
6667         ;
6668       else if (unformat (i, "learn %d", &learn))
6669         ;
6670       else if (unformat (i, "arp-term %d", &arp_term))
6671         ;
6672       else if (unformat (i, "mac-age %d", &mac_age))
6673         ;
6674       else if (unformat (i, "bd-tag %s", &bd_tag))
6675         ;
6676       else if (unformat (i, "del"))
6677         {
6678           is_add = 0;
6679           flood = uu_flood = forward = learn = 0;
6680         }
6681       else
6682         break;
6683     }
6684
6685   if (bd_id == ~0)
6686     {
6687       errmsg ("missing bridge domain");
6688       ret = -99;
6689       goto done;
6690     }
6691
6692   if (mac_age > 255)
6693     {
6694       errmsg ("mac age must be less than 256 ");
6695       ret = -99;
6696       goto done;
6697     }
6698
6699   if ((bd_tag) && (vec_len (bd_tag) > 63))
6700     {
6701       errmsg ("bd-tag cannot be longer than 63");
6702       ret = -99;
6703       goto done;
6704     }
6705
6706   M (BRIDGE_DOMAIN_ADD_DEL, mp);
6707
6708   mp->bd_id = ntohl (bd_id);
6709   mp->flood = flood;
6710   mp->uu_flood = uu_flood;
6711   mp->forward = forward;
6712   mp->learn = learn;
6713   mp->arp_term = arp_term;
6714   mp->is_add = is_add;
6715   mp->mac_age = (u8) mac_age;
6716   if (bd_tag)
6717     {
6718       clib_memcpy (mp->bd_tag, bd_tag, vec_len (bd_tag));
6719       mp->bd_tag[vec_len (bd_tag)] = 0;
6720     }
6721   S (mp);
6722   W (ret);
6723
6724 done:
6725   vec_free (bd_tag);
6726   return ret;
6727 }
6728
6729 static int
6730 api_l2fib_flush_bd (vat_main_t * vam)
6731 {
6732   unformat_input_t *i = vam->input;
6733   vl_api_l2fib_flush_bd_t *mp;
6734   u32 bd_id = ~0;
6735   int ret;
6736
6737   /* Parse args required to build the message */
6738   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6739     {
6740       if (unformat (i, "bd_id %d", &bd_id));
6741       else
6742         break;
6743     }
6744
6745   if (bd_id == ~0)
6746     {
6747       errmsg ("missing bridge domain");
6748       return -99;
6749     }
6750
6751   M (L2FIB_FLUSH_BD, mp);
6752
6753   mp->bd_id = htonl (bd_id);
6754
6755   S (mp);
6756   W (ret);
6757   return ret;
6758 }
6759
6760 static int
6761 api_l2fib_flush_int (vat_main_t * vam)
6762 {
6763   unformat_input_t *i = vam->input;
6764   vl_api_l2fib_flush_int_t *mp;
6765   u32 sw_if_index = ~0;
6766   int ret;
6767
6768   /* Parse args required to build the message */
6769   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6770     {
6771       if (unformat (i, "sw_if_index %d", &sw_if_index));
6772       else
6773         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index));
6774       else
6775         break;
6776     }
6777
6778   if (sw_if_index == ~0)
6779     {
6780       errmsg ("missing interface name or sw_if_index");
6781       return -99;
6782     }
6783
6784   M (L2FIB_FLUSH_INT, mp);
6785
6786   mp->sw_if_index = ntohl (sw_if_index);
6787
6788   S (mp);
6789   W (ret);
6790   return ret;
6791 }
6792
6793 static int
6794 api_l2fib_add_del (vat_main_t * vam)
6795 {
6796   unformat_input_t *i = vam->input;
6797   vl_api_l2fib_add_del_t *mp;
6798   f64 timeout;
6799   u8 mac[6] = { 0 };
6800   u8 mac_set = 0;
6801   u32 bd_id;
6802   u8 bd_id_set = 0;
6803   u32 sw_if_index = 0;
6804   u8 sw_if_index_set = 0;
6805   u8 is_add = 1;
6806   u8 static_mac = 0;
6807   u8 filter_mac = 0;
6808   u8 bvi_mac = 0;
6809   int count = 1;
6810   f64 before = 0;
6811   int j;
6812
6813   /* Parse args required to build the message */
6814   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6815     {
6816       if (unformat (i, "mac %U", unformat_ethernet_address, mac))
6817         mac_set = 1;
6818       else if (unformat (i, "bd_id %d", &bd_id))
6819         bd_id_set = 1;
6820       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6821         sw_if_index_set = 1;
6822       else if (unformat (i, "sw_if"))
6823         {
6824           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6825             {
6826               if (unformat
6827                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6828                 sw_if_index_set = 1;
6829             }
6830           else
6831             break;
6832         }
6833       else if (unformat (i, "static"))
6834         static_mac = 1;
6835       else if (unformat (i, "filter"))
6836         {
6837           filter_mac = 1;
6838           static_mac = 1;
6839         }
6840       else if (unformat (i, "bvi"))
6841         {
6842           bvi_mac = 1;
6843           static_mac = 1;
6844         }
6845       else if (unformat (i, "del"))
6846         is_add = 0;
6847       else if (unformat (i, "count %d", &count))
6848         ;
6849       else
6850         break;
6851     }
6852
6853   if (mac_set == 0)
6854     {
6855       errmsg ("missing mac address");
6856       return -99;
6857     }
6858
6859   if (bd_id_set == 0)
6860     {
6861       errmsg ("missing bridge domain");
6862       return -99;
6863     }
6864
6865   if (is_add && sw_if_index_set == 0 && filter_mac == 0)
6866     {
6867       errmsg ("missing interface name or sw_if_index");
6868       return -99;
6869     }
6870
6871   if (count > 1)
6872     {
6873       /* Turn on async mode */
6874       vam->async_mode = 1;
6875       vam->async_errors = 0;
6876       before = vat_time_now (vam);
6877     }
6878
6879   for (j = 0; j < count; j++)
6880     {
6881       M (L2FIB_ADD_DEL, mp);
6882
6883       clib_memcpy (mp->mac, mac, 6);
6884       mp->bd_id = ntohl (bd_id);
6885       mp->is_add = is_add;
6886       mp->sw_if_index = ntohl (sw_if_index);
6887
6888       if (is_add)
6889         {
6890           mp->static_mac = static_mac;
6891           mp->filter_mac = filter_mac;
6892           mp->bvi_mac = bvi_mac;
6893         }
6894       increment_mac_address (mac);
6895       /* send it... */
6896       S (mp);
6897     }
6898
6899   if (count > 1)
6900     {
6901       vl_api_control_ping_t *mp_ping;
6902       f64 after;
6903
6904       /* Shut off async mode */
6905       vam->async_mode = 0;
6906
6907       MPING (CONTROL_PING, mp_ping);
6908       S (mp_ping);
6909
6910       timeout = vat_time_now (vam) + 1.0;
6911       while (vat_time_now (vam) < timeout)
6912         if (vam->result_ready == 1)
6913           goto out;
6914       vam->retval = -99;
6915
6916     out:
6917       if (vam->retval == -99)
6918         errmsg ("timeout");
6919
6920       if (vam->async_errors > 0)
6921         {
6922           errmsg ("%d asynchronous errors", vam->async_errors);
6923           vam->retval = -98;
6924         }
6925       vam->async_errors = 0;
6926       after = vat_time_now (vam);
6927
6928       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
6929              count, after - before, count / (after - before));
6930     }
6931   else
6932     {
6933       int ret;
6934
6935       /* Wait for a reply... */
6936       W (ret);
6937       return ret;
6938     }
6939   /* Return the good/bad news */
6940   return (vam->retval);
6941 }
6942
6943 static int
6944 api_bridge_domain_set_mac_age (vat_main_t * vam)
6945 {
6946   unformat_input_t *i = vam->input;
6947   vl_api_bridge_domain_set_mac_age_t *mp;
6948   u32 bd_id = ~0;
6949   u32 mac_age = 0;
6950   int ret;
6951
6952   /* Parse args required to build the message */
6953   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6954     {
6955       if (unformat (i, "bd_id %d", &bd_id));
6956       else if (unformat (i, "mac-age %d", &mac_age));
6957       else
6958         break;
6959     }
6960
6961   if (bd_id == ~0)
6962     {
6963       errmsg ("missing bridge domain");
6964       return -99;
6965     }
6966
6967   if (mac_age > 255)
6968     {
6969       errmsg ("mac age must be less than 256 ");
6970       return -99;
6971     }
6972
6973   M (BRIDGE_DOMAIN_SET_MAC_AGE, mp);
6974
6975   mp->bd_id = htonl (bd_id);
6976   mp->mac_age = (u8) mac_age;
6977
6978   S (mp);
6979   W (ret);
6980   return ret;
6981 }
6982
6983 static int
6984 api_l2_flags (vat_main_t * vam)
6985 {
6986   unformat_input_t *i = vam->input;
6987   vl_api_l2_flags_t *mp;
6988   u32 sw_if_index;
6989   u32 flags = 0;
6990   u8 sw_if_index_set = 0;
6991   u8 is_set = 0;
6992   int ret;
6993
6994   /* Parse args required to build the message */
6995   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6996     {
6997       if (unformat (i, "sw_if_index %d", &sw_if_index))
6998         sw_if_index_set = 1;
6999       else if (unformat (i, "sw_if"))
7000         {
7001           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7002             {
7003               if (unformat
7004                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7005                 sw_if_index_set = 1;
7006             }
7007           else
7008             break;
7009         }
7010       else if (unformat (i, "learn"))
7011         flags |= L2_LEARN;
7012       else if (unformat (i, "forward"))
7013         flags |= L2_FWD;
7014       else if (unformat (i, "flood"))
7015         flags |= L2_FLOOD;
7016       else if (unformat (i, "uu-flood"))
7017         flags |= L2_UU_FLOOD;
7018       else if (unformat (i, "arp-term"))
7019         flags |= L2_ARP_TERM;
7020       else if (unformat (i, "off"))
7021         is_set = 0;
7022       else if (unformat (i, "disable"))
7023         is_set = 0;
7024       else
7025         break;
7026     }
7027
7028   if (sw_if_index_set == 0)
7029     {
7030       errmsg ("missing interface name or sw_if_index");
7031       return -99;
7032     }
7033
7034   M (L2_FLAGS, mp);
7035
7036   mp->sw_if_index = ntohl (sw_if_index);
7037   mp->feature_bitmap = ntohl (flags);
7038   mp->is_set = is_set;
7039
7040   S (mp);
7041   W (ret);
7042   return ret;
7043 }
7044
7045 static int
7046 api_bridge_flags (vat_main_t * vam)
7047 {
7048   unformat_input_t *i = vam->input;
7049   vl_api_bridge_flags_t *mp;
7050   u32 bd_id;
7051   u8 bd_id_set = 0;
7052   u8 is_set = 1;
7053   bd_flags_t flags = 0;
7054   int ret;
7055
7056   /* Parse args required to build the message */
7057   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7058     {
7059       if (unformat (i, "bd_id %d", &bd_id))
7060         bd_id_set = 1;
7061       else if (unformat (i, "learn"))
7062         flags |= BRIDGE_API_FLAG_LEARN;
7063       else if (unformat (i, "forward"))
7064         flags |= BRIDGE_API_FLAG_FWD;
7065       else if (unformat (i, "flood"))
7066         flags |= BRIDGE_API_FLAG_FLOOD;
7067       else if (unformat (i, "uu-flood"))
7068         flags |= BRIDGE_API_FLAG_UU_FLOOD;
7069       else if (unformat (i, "arp-term"))
7070         flags |= BRIDGE_API_FLAG_ARP_TERM;
7071       else if (unformat (i, "off"))
7072         is_set = 0;
7073       else if (unformat (i, "disable"))
7074         is_set = 0;
7075       else
7076         break;
7077     }
7078
7079   if (bd_id_set == 0)
7080     {
7081       errmsg ("missing bridge domain");
7082       return -99;
7083     }
7084
7085   M (BRIDGE_FLAGS, mp);
7086
7087   mp->bd_id = ntohl (bd_id);
7088   mp->flags = ntohl (flags);
7089   mp->is_set = is_set;
7090
7091   S (mp);
7092   W (ret);
7093   return ret;
7094 }
7095
7096 static int
7097 api_bd_ip_mac_add_del (vat_main_t * vam)
7098 {
7099   vl_api_address_t ip = VL_API_ZERO_ADDRESS;
7100   vl_api_mac_address_t mac = { 0 };
7101   unformat_input_t *i = vam->input;
7102   vl_api_bd_ip_mac_add_del_t *mp;
7103   u32 bd_id;
7104   u8 is_add = 1;
7105   u8 bd_id_set = 0;
7106   u8 ip_set = 0;
7107   u8 mac_set = 0;
7108   int ret;
7109
7110
7111   /* Parse args required to build the message */
7112   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7113     {
7114       if (unformat (i, "bd_id %d", &bd_id))
7115         {
7116           bd_id_set++;
7117         }
7118       else if (unformat (i, "%U", unformat_vl_api_address, &ip))
7119         {
7120           ip_set++;
7121         }
7122       else if (unformat (i, "%U", unformat_vl_api_mac_address, &mac))
7123         {
7124           mac_set++;
7125         }
7126       else if (unformat (i, "del"))
7127         is_add = 0;
7128       else
7129         break;
7130     }
7131
7132   if (bd_id_set == 0)
7133     {
7134       errmsg ("missing bridge domain");
7135       return -99;
7136     }
7137   else if (ip_set == 0)
7138     {
7139       errmsg ("missing IP address");
7140       return -99;
7141     }
7142   else if (mac_set == 0)
7143     {
7144       errmsg ("missing MAC address");
7145       return -99;
7146     }
7147
7148   M (BD_IP_MAC_ADD_DEL, mp);
7149
7150   mp->entry.bd_id = ntohl (bd_id);
7151   mp->is_add = is_add;
7152
7153   clib_memcpy (&mp->entry.ip, &ip, sizeof (ip));
7154   clib_memcpy (&mp->entry.mac, &mac, sizeof (mac));
7155
7156   S (mp);
7157   W (ret);
7158   return ret;
7159 }
7160
7161 static int
7162 api_bd_ip_mac_flush (vat_main_t * vam)
7163 {
7164   unformat_input_t *i = vam->input;
7165   vl_api_bd_ip_mac_flush_t *mp;
7166   u32 bd_id;
7167   u8 bd_id_set = 0;
7168   int ret;
7169
7170   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7171     {
7172       if (unformat (i, "bd_id %d", &bd_id))
7173         {
7174           bd_id_set++;
7175         }
7176       else
7177         break;
7178     }
7179
7180   if (bd_id_set == 0)
7181     {
7182       errmsg ("missing bridge domain");
7183       return -99;
7184     }
7185
7186   M (BD_IP_MAC_FLUSH, mp);
7187
7188   mp->bd_id = ntohl (bd_id);
7189
7190   S (mp);
7191   W (ret);
7192   return ret;
7193 }
7194
7195 static void vl_api_bd_ip_mac_details_t_handler
7196   (vl_api_bd_ip_mac_details_t * mp)
7197 {
7198   vat_main_t *vam = &vat_main;
7199
7200   print (vam->ofp,
7201          "\n%-5d %U %U",
7202          ntohl (mp->entry.bd_id),
7203          format_vl_api_mac_address, mp->entry.mac,
7204          format_vl_api_address, &mp->entry.ip);
7205 }
7206
7207 static void vl_api_bd_ip_mac_details_t_handler_json
7208   (vl_api_bd_ip_mac_details_t * mp)
7209 {
7210   vat_main_t *vam = &vat_main;
7211   vat_json_node_t *node = NULL;
7212
7213   if (VAT_JSON_ARRAY != vam->json_tree.type)
7214     {
7215       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
7216       vat_json_init_array (&vam->json_tree);
7217     }
7218   node = vat_json_array_add (&vam->json_tree);
7219
7220   vat_json_init_object (node);
7221   vat_json_object_add_uint (node, "bd_id", ntohl (mp->entry.bd_id));
7222   vat_json_object_add_string_copy (node, "mac_address",
7223                                    format (0, "%U", format_vl_api_mac_address,
7224                                            &mp->entry.mac));
7225   u8 *ip = 0;
7226
7227   ip = format (0, "%U", format_vl_api_address, &mp->entry.ip);
7228   vat_json_object_add_string_copy (node, "ip_address", ip);
7229   vec_free (ip);
7230 }
7231
7232 static int
7233 api_bd_ip_mac_dump (vat_main_t * vam)
7234 {
7235   unformat_input_t *i = vam->input;
7236   vl_api_bd_ip_mac_dump_t *mp;
7237   vl_api_control_ping_t *mp_ping;
7238   int ret;
7239   u32 bd_id;
7240   u8 bd_id_set = 0;
7241
7242   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7243     {
7244       if (unformat (i, "bd_id %d", &bd_id))
7245         {
7246           bd_id_set++;
7247         }
7248       else
7249         break;
7250     }
7251
7252   print (vam->ofp,
7253          "\n%-5s %-7s %-20s %-30s",
7254          "bd_id", "is_ipv6", "mac_address", "ip_address");
7255
7256   /* Dump Bridge Domain Ip to Mac entries */
7257   M (BD_IP_MAC_DUMP, mp);
7258
7259   if (bd_id_set)
7260     mp->bd_id = htonl (bd_id);
7261   else
7262     mp->bd_id = ~0;
7263
7264   S (mp);
7265
7266   /* Use a control ping for synchronization */
7267   MPING (CONTROL_PING, mp_ping);
7268   S (mp_ping);
7269
7270   W (ret);
7271   return ret;
7272 }
7273
7274 static int
7275 api_tap_create_v2 (vat_main_t * vam)
7276 {
7277   unformat_input_t *i = vam->input;
7278   vl_api_tap_create_v2_t *mp;
7279 #define TAP_FLAG_GSO (1 << 0)
7280   u8 mac_address[6];
7281   u8 random_mac = 1;
7282   u32 id = ~0;
7283   u8 *host_if_name = 0;
7284   u8 *host_ns = 0;
7285   u8 host_mac_addr[6];
7286   u8 host_mac_addr_set = 0;
7287   u8 *host_bridge = 0;
7288   ip4_address_t host_ip4_addr;
7289   ip4_address_t host_ip4_gw;
7290   u8 host_ip4_gw_set = 0;
7291   u32 host_ip4_prefix_len = 0;
7292   ip6_address_t host_ip6_addr;
7293   ip6_address_t host_ip6_gw;
7294   u8 host_ip6_gw_set = 0;
7295   u32 host_ip6_prefix_len = 0;
7296   u8 host_mtu_set = 0;
7297   u32 host_mtu_size = 0;
7298   u32 tap_flags = 0;
7299   int ret;
7300   u32 rx_ring_sz = 0, tx_ring_sz = 0;
7301
7302   clib_memset (mac_address, 0, sizeof (mac_address));
7303
7304   /* Parse args required to build the message */
7305   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7306     {
7307       if (unformat (i, "hw-addr %U", unformat_ethernet_address, mac_address))
7308         {
7309           random_mac = 0;
7310         }
7311       else if (unformat (i, "id %u", &id))
7312         ;
7313       else if (unformat (i, "host-if-name %s", &host_if_name))
7314         ;
7315       else if (unformat (i, "host-ns %s", &host_ns))
7316         ;
7317       else if (unformat (i, "host-mac-addr %U", unformat_ethernet_address,
7318                          host_mac_addr))
7319         host_mac_addr_set = 1;
7320       else if (unformat (i, "host-bridge %s", &host_bridge))
7321         ;
7322       else if (unformat (i, "host-ip4-addr %U/%d", unformat_ip4_address,
7323                          &host_ip4_addr, &host_ip4_prefix_len))
7324         ;
7325       else if (unformat (i, "host-ip6-addr %U/%d", unformat_ip6_address,
7326                          &host_ip6_addr, &host_ip6_prefix_len))
7327         ;
7328       else if (unformat (i, "host-ip4-gw %U", unformat_ip4_address,
7329                          &host_ip4_gw))
7330         host_ip4_gw_set = 1;
7331       else if (unformat (i, "host-ip6-gw %U", unformat_ip6_address,
7332                          &host_ip6_gw))
7333         host_ip6_gw_set = 1;
7334       else if (unformat (i, "rx-ring-size %d", &rx_ring_sz))
7335         ;
7336       else if (unformat (i, "tx-ring-size %d", &tx_ring_sz))
7337         ;
7338       else if (unformat (i, "host-mtu-size %d", &host_mtu_size))
7339         host_mtu_set = 1;
7340       else if (unformat (i, "no-gso"))
7341         tap_flags &= ~TAP_FLAG_GSO;
7342       else if (unformat (i, "gso"))
7343         tap_flags |= TAP_FLAG_GSO;
7344       else if (unformat (i, "csum-offload"))
7345         tap_flags |= TAP_FLAG_CSUM_OFFLOAD;
7346       else
7347         break;
7348     }
7349
7350   if (vec_len (host_if_name) > 63)
7351     {
7352       errmsg ("tap name too long. ");
7353       return -99;
7354     }
7355   if (vec_len (host_ns) > 63)
7356     {
7357       errmsg ("host name space too long. ");
7358       return -99;
7359     }
7360   if (vec_len (host_bridge) > 63)
7361     {
7362       errmsg ("host bridge name too long. ");
7363       return -99;
7364     }
7365   if (host_ip4_prefix_len > 32)
7366     {
7367       errmsg ("host ip4 prefix length not valid. ");
7368       return -99;
7369     }
7370   if (host_ip6_prefix_len > 128)
7371     {
7372       errmsg ("host ip6 prefix length not valid. ");
7373       return -99;
7374     }
7375   if (!is_pow2 (rx_ring_sz))
7376     {
7377       errmsg ("rx ring size must be power of 2. ");
7378       return -99;
7379     }
7380   if (rx_ring_sz > 32768)
7381     {
7382       errmsg ("rx ring size must be 32768 or lower. ");
7383       return -99;
7384     }
7385   if (!is_pow2 (tx_ring_sz))
7386     {
7387       errmsg ("tx ring size must be power of 2. ");
7388       return -99;
7389     }
7390   if (tx_ring_sz > 32768)
7391     {
7392       errmsg ("tx ring size must be 32768 or lower. ");
7393       return -99;
7394     }
7395   if (host_mtu_set && (host_mtu_size < 64 || host_mtu_size > 65355))
7396     {
7397       errmsg ("host MTU size must be in between 64 and 65355. ");
7398       return -99;
7399     }
7400
7401   /* Construct the API message */
7402   M (TAP_CREATE_V2, mp);
7403
7404   mp->use_random_mac = random_mac;
7405
7406   mp->id = ntohl (id);
7407   mp->host_namespace_set = host_ns != 0;
7408   mp->host_bridge_set = host_bridge != 0;
7409   mp->host_ip4_prefix_set = host_ip4_prefix_len != 0;
7410   mp->host_ip6_prefix_set = host_ip6_prefix_len != 0;
7411   mp->rx_ring_sz = ntohs (rx_ring_sz);
7412   mp->tx_ring_sz = ntohs (tx_ring_sz);
7413   mp->host_mtu_set = host_mtu_set;
7414   mp->host_mtu_size = ntohl (host_mtu_size);
7415   mp->tap_flags = ntohl (tap_flags);
7416
7417   if (random_mac == 0)
7418     clib_memcpy (mp->mac_address, mac_address, 6);
7419   if (host_mac_addr_set)
7420     clib_memcpy (mp->host_mac_addr, host_mac_addr, 6);
7421   if (host_if_name)
7422     clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
7423   if (host_ns)
7424     clib_memcpy (mp->host_namespace, host_ns, vec_len (host_ns));
7425   if (host_bridge)
7426     clib_memcpy (mp->host_bridge, host_bridge, vec_len (host_bridge));
7427   if (host_ip4_prefix_len)
7428     clib_memcpy (mp->host_ip4_prefix.address, &host_ip4_addr, 4);
7429   if (host_ip6_prefix_len)
7430     clib_memcpy (mp->host_ip6_prefix.address, &host_ip6_addr, 16);
7431   if (host_ip4_gw_set)
7432     clib_memcpy (mp->host_ip4_gw, &host_ip4_gw, 4);
7433   if (host_ip6_gw_set)
7434     clib_memcpy (mp->host_ip6_gw, &host_ip6_gw, 16);
7435
7436   vec_free (host_ns);
7437   vec_free (host_if_name);
7438   vec_free (host_bridge);
7439
7440   /* send it... */
7441   S (mp);
7442
7443   /* Wait for a reply... */
7444   W (ret);
7445   return ret;
7446 }
7447
7448 static int
7449 api_tap_delete_v2 (vat_main_t * vam)
7450 {
7451   unformat_input_t *i = vam->input;
7452   vl_api_tap_delete_v2_t *mp;
7453   u32 sw_if_index = ~0;
7454   u8 sw_if_index_set = 0;
7455   int ret;
7456
7457   /* Parse args required to build the message */
7458   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7459     {
7460       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7461         sw_if_index_set = 1;
7462       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7463         sw_if_index_set = 1;
7464       else
7465         break;
7466     }
7467
7468   if (sw_if_index_set == 0)
7469     {
7470       errmsg ("missing vpp interface name. ");
7471       return -99;
7472     }
7473
7474   /* Construct the API message */
7475   M (TAP_DELETE_V2, mp);
7476
7477   mp->sw_if_index = ntohl (sw_if_index);
7478
7479   /* send it... */
7480   S (mp);
7481
7482   /* Wait for a reply... */
7483   W (ret);
7484   return ret;
7485 }
7486
7487 uword
7488 unformat_vlib_pci_addr (unformat_input_t * input, va_list * args)
7489 {
7490   vlib_pci_addr_t *addr = va_arg (*args, vlib_pci_addr_t *);
7491   u32 x[4];
7492
7493   if (!unformat (input, "%x:%x:%x.%x", &x[0], &x[1], &x[2], &x[3]))
7494     return 0;
7495
7496   addr->domain = x[0];
7497   addr->bus = x[1];
7498   addr->slot = x[2];
7499   addr->function = x[3];
7500
7501   return 1;
7502 }
7503
7504 static int
7505 api_virtio_pci_create (vat_main_t * vam)
7506 {
7507   unformat_input_t *i = vam->input;
7508   vl_api_virtio_pci_create_t *mp;
7509   u8 mac_address[6];
7510   u8 random_mac = 1;
7511   u8 gso_enabled = 0;
7512   u8 checksum_offload_enabled = 0;
7513   u32 pci_addr = 0;
7514   u64 features = (u64) ~ (0ULL);
7515   int ret;
7516
7517   clib_memset (mac_address, 0, sizeof (mac_address));
7518
7519   /* Parse args required to build the message */
7520   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7521     {
7522       if (unformat (i, "hw-addr %U", unformat_ethernet_address, mac_address))
7523         {
7524           random_mac = 0;
7525         }
7526       else if (unformat (i, "pci-addr %U", unformat_vlib_pci_addr, &pci_addr))
7527         ;
7528       else if (unformat (i, "features 0x%llx", &features))
7529         ;
7530       else if (unformat (i, "gso-enabled"))
7531         gso_enabled = 1;
7532       else if (unformat (i, "csum-offload-enabled"))
7533         checksum_offload_enabled = 1;
7534       else
7535         break;
7536     }
7537
7538   if (pci_addr == 0)
7539     {
7540       errmsg ("pci address must be non zero. ");
7541       return -99;
7542     }
7543
7544   /* Construct the API message */
7545   M (VIRTIO_PCI_CREATE, mp);
7546
7547   mp->use_random_mac = random_mac;
7548
7549   mp->pci_addr.domain = htons (((vlib_pci_addr_t) pci_addr).domain);
7550   mp->pci_addr.bus = ((vlib_pci_addr_t) pci_addr).bus;
7551   mp->pci_addr.slot = ((vlib_pci_addr_t) pci_addr).slot;
7552   mp->pci_addr.function = ((vlib_pci_addr_t) pci_addr).function;
7553
7554   mp->features = clib_host_to_net_u64 (features);
7555   mp->gso_enabled = gso_enabled;
7556   mp->checksum_offload_enabled = checksum_offload_enabled;
7557
7558   if (random_mac == 0)
7559     clib_memcpy (mp->mac_address, mac_address, 6);
7560
7561   /* send it... */
7562   S (mp);
7563
7564   /* Wait for a reply... */
7565   W (ret);
7566   return ret;
7567 }
7568
7569 static int
7570 api_virtio_pci_delete (vat_main_t * vam)
7571 {
7572   unformat_input_t *i = vam->input;
7573   vl_api_virtio_pci_delete_t *mp;
7574   u32 sw_if_index = ~0;
7575   u8 sw_if_index_set = 0;
7576   int ret;
7577
7578   /* Parse args required to build the message */
7579   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7580     {
7581       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7582         sw_if_index_set = 1;
7583       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7584         sw_if_index_set = 1;
7585       else
7586         break;
7587     }
7588
7589   if (sw_if_index_set == 0)
7590     {
7591       errmsg ("missing vpp interface name. ");
7592       return -99;
7593     }
7594
7595   /* Construct the API message */
7596   M (VIRTIO_PCI_DELETE, mp);
7597
7598   mp->sw_if_index = htonl (sw_if_index);
7599
7600   /* send it... */
7601   S (mp);
7602
7603   /* Wait for a reply... */
7604   W (ret);
7605   return ret;
7606 }
7607
7608 static int
7609 api_bond_create (vat_main_t * vam)
7610 {
7611   unformat_input_t *i = vam->input;
7612   vl_api_bond_create_t *mp;
7613   u8 mac_address[6];
7614   u8 custom_mac = 0;
7615   int ret;
7616   u8 mode;
7617   u8 lb;
7618   u8 mode_is_set = 0;
7619   u32 id = ~0;
7620   u8 numa_only = 0;
7621
7622   clib_memset (mac_address, 0, sizeof (mac_address));
7623   lb = BOND_LB_L2;
7624
7625   /* Parse args required to build the message */
7626   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7627     {
7628       if (unformat (i, "mode %U", unformat_bond_mode, &mode))
7629         mode_is_set = 1;
7630       else if (((mode == BOND_MODE_LACP) || (mode == BOND_MODE_XOR))
7631                && unformat (i, "lb %U", unformat_bond_load_balance, &lb))
7632         ;
7633       else if (unformat (i, "hw-addr %U", unformat_ethernet_address,
7634                          mac_address))
7635         custom_mac = 1;
7636       else if (unformat (i, "numa-only"))
7637         numa_only = 1;
7638       else if (unformat (i, "id %u", &id))
7639         ;
7640       else
7641         break;
7642     }
7643
7644   if (mode_is_set == 0)
7645     {
7646       errmsg ("Missing bond mode. ");
7647       return -99;
7648     }
7649
7650   /* Construct the API message */
7651   M (BOND_CREATE, mp);
7652
7653   mp->use_custom_mac = custom_mac;
7654
7655   mp->mode = htonl (mode);
7656   mp->lb = htonl (lb);
7657   mp->id = htonl (id);
7658   mp->numa_only = numa_only;
7659
7660   if (custom_mac)
7661     clib_memcpy (mp->mac_address, mac_address, 6);
7662
7663   /* send it... */
7664   S (mp);
7665
7666   /* Wait for a reply... */
7667   W (ret);
7668   return ret;
7669 }
7670
7671 static int
7672 api_bond_delete (vat_main_t * vam)
7673 {
7674   unformat_input_t *i = vam->input;
7675   vl_api_bond_delete_t *mp;
7676   u32 sw_if_index = ~0;
7677   u8 sw_if_index_set = 0;
7678   int ret;
7679
7680   /* Parse args required to build the message */
7681   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7682     {
7683       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7684         sw_if_index_set = 1;
7685       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7686         sw_if_index_set = 1;
7687       else
7688         break;
7689     }
7690
7691   if (sw_if_index_set == 0)
7692     {
7693       errmsg ("missing vpp interface name. ");
7694       return -99;
7695     }
7696
7697   /* Construct the API message */
7698   M (BOND_DELETE, mp);
7699
7700   mp->sw_if_index = ntohl (sw_if_index);
7701
7702   /* send it... */
7703   S (mp);
7704
7705   /* Wait for a reply... */
7706   W (ret);
7707   return ret;
7708 }
7709
7710 static int
7711 api_bond_enslave (vat_main_t * vam)
7712 {
7713   unformat_input_t *i = vam->input;
7714   vl_api_bond_enslave_t *mp;
7715   u32 bond_sw_if_index;
7716   int ret;
7717   u8 is_passive;
7718   u8 is_long_timeout;
7719   u32 bond_sw_if_index_is_set = 0;
7720   u32 sw_if_index;
7721   u8 sw_if_index_is_set = 0;
7722
7723   /* Parse args required to build the message */
7724   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7725     {
7726       if (unformat (i, "sw_if_index %d", &sw_if_index))
7727         sw_if_index_is_set = 1;
7728       else if (unformat (i, "bond %u", &bond_sw_if_index))
7729         bond_sw_if_index_is_set = 1;
7730       else if (unformat (i, "passive %d", &is_passive))
7731         ;
7732       else if (unformat (i, "long-timeout %d", &is_long_timeout))
7733         ;
7734       else
7735         break;
7736     }
7737
7738   if (bond_sw_if_index_is_set == 0)
7739     {
7740       errmsg ("Missing bond sw_if_index. ");
7741       return -99;
7742     }
7743   if (sw_if_index_is_set == 0)
7744     {
7745       errmsg ("Missing slave sw_if_index. ");
7746       return -99;
7747     }
7748
7749   /* Construct the API message */
7750   M (BOND_ENSLAVE, mp);
7751
7752   mp->bond_sw_if_index = ntohl (bond_sw_if_index);
7753   mp->sw_if_index = ntohl (sw_if_index);
7754   mp->is_long_timeout = is_long_timeout;
7755   mp->is_passive = is_passive;
7756
7757   /* send it... */
7758   S (mp);
7759
7760   /* Wait for a reply... */
7761   W (ret);
7762   return ret;
7763 }
7764
7765 static int
7766 api_bond_detach_slave (vat_main_t * vam)
7767 {
7768   unformat_input_t *i = vam->input;
7769   vl_api_bond_detach_slave_t *mp;
7770   u32 sw_if_index = ~0;
7771   u8 sw_if_index_set = 0;
7772   int ret;
7773
7774   /* Parse args required to build the message */
7775   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7776     {
7777       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7778         sw_if_index_set = 1;
7779       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7780         sw_if_index_set = 1;
7781       else
7782         break;
7783     }
7784
7785   if (sw_if_index_set == 0)
7786     {
7787       errmsg ("missing vpp interface name. ");
7788       return -99;
7789     }
7790
7791   /* Construct the API message */
7792   M (BOND_DETACH_SLAVE, mp);
7793
7794   mp->sw_if_index = ntohl (sw_if_index);
7795
7796   /* send it... */
7797   S (mp);
7798
7799   /* Wait for a reply... */
7800   W (ret);
7801   return ret;
7802 }
7803
7804 static int
7805 api_ip_table_add_del (vat_main_t * vam)
7806 {
7807   unformat_input_t *i = vam->input;
7808   vl_api_ip_table_add_del_t *mp;
7809   u32 table_id = ~0;
7810   u8 is_ipv6 = 0;
7811   u8 is_add = 1;
7812   int ret = 0;
7813
7814   /* Parse args required to build the message */
7815   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7816     {
7817       if (unformat (i, "ipv6"))
7818         is_ipv6 = 1;
7819       else if (unformat (i, "del"))
7820         is_add = 0;
7821       else if (unformat (i, "add"))
7822         is_add = 1;
7823       else if (unformat (i, "table %d", &table_id))
7824         ;
7825       else
7826         {
7827           clib_warning ("parse error '%U'", format_unformat_error, i);
7828           return -99;
7829         }
7830     }
7831
7832   if (~0 == table_id)
7833     {
7834       errmsg ("missing table-ID");
7835       return -99;
7836     }
7837
7838   /* Construct the API message */
7839   M (IP_TABLE_ADD_DEL, mp);
7840
7841   mp->table.table_id = ntohl (table_id);
7842   mp->table.is_ip6 = is_ipv6;
7843   mp->is_add = is_add;
7844
7845   /* send it... */
7846   S (mp);
7847
7848   /* Wait for a reply... */
7849   W (ret);
7850
7851   return ret;
7852 }
7853
7854 uword
7855 unformat_fib_path (unformat_input_t * input, va_list * args)
7856 {
7857   vat_main_t *vam = va_arg (*args, vat_main_t *);
7858   vl_api_fib_path_t *path = va_arg (*args, vl_api_fib_path_t *);
7859   u32 weight, preference;
7860   mpls_label_t out_label;
7861
7862   clib_memset (path, 0, sizeof (*path));
7863   path->weight = 1;
7864   path->sw_if_index = ~0;
7865   path->rpf_id = ~0;
7866   path->n_labels = 0;
7867
7868   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7869     {
7870       if (unformat (input, "%U %U",
7871                     unformat_vl_api_ip4_address,
7872                     &path->nh.address.ip4,
7873                     api_unformat_sw_if_index, vam, &path->sw_if_index))
7874         {
7875           path->proto = FIB_API_PATH_NH_PROTO_IP4;
7876         }
7877       else if (unformat (input, "%U %U",
7878                          unformat_vl_api_ip6_address,
7879                          &path->nh.address.ip6,
7880                          api_unformat_sw_if_index, vam, &path->sw_if_index))
7881         {
7882           path->proto = FIB_API_PATH_NH_PROTO_IP6;
7883         }
7884       else if (unformat (input, "weight %u", &weight))
7885         {
7886           path->weight = weight;
7887         }
7888       else if (unformat (input, "preference %u", &preference))
7889         {
7890           path->preference = preference;
7891         }
7892       else if (unformat (input, "%U next-hop-table %d",
7893                          unformat_vl_api_ip4_address,
7894                          &path->nh.address.ip4, &path->table_id))
7895         {
7896           path->proto = FIB_API_PATH_NH_PROTO_IP4;
7897         }
7898       else if (unformat (input, "%U next-hop-table %d",
7899                          unformat_vl_api_ip6_address,
7900                          &path->nh.address.ip6, &path->table_id))
7901         {
7902           path->proto = FIB_API_PATH_NH_PROTO_IP6;
7903         }
7904       else if (unformat (input, "%U",
7905                          unformat_vl_api_ip4_address, &path->nh.address.ip4))
7906         {
7907           /*
7908            * the recursive next-hops are by default in the default table
7909            */
7910           path->table_id = 0;
7911           path->sw_if_index = ~0;
7912           path->proto = FIB_API_PATH_NH_PROTO_IP4;
7913         }
7914       else if (unformat (input, "%U",
7915                          unformat_vl_api_ip6_address, &path->nh.address.ip6))
7916         {
7917           /*
7918            * the recursive next-hops are by default in the default table
7919            */
7920           path->table_id = 0;
7921           path->sw_if_index = ~0;
7922           path->proto = FIB_API_PATH_NH_PROTO_IP6;
7923         }
7924       else if (unformat (input, "resolve-via-host"))
7925         {
7926           path->flags |= FIB_API_PATH_FLAG_RESOLVE_VIA_HOST;
7927         }
7928       else if (unformat (input, "resolve-via-attached"))
7929         {
7930           path->flags |= FIB_API_PATH_FLAG_RESOLVE_VIA_ATTACHED;
7931         }
7932       else if (unformat (input, "ip4-lookup-in-table %d", &path->table_id))
7933         {
7934           path->type = FIB_API_PATH_TYPE_LOCAL;
7935           path->sw_if_index = ~0;
7936           path->proto = FIB_API_PATH_NH_PROTO_IP4;
7937         }
7938       else if (unformat (input, "ip6-lookup-in-table %d", &path->table_id))
7939         {
7940           path->type = FIB_API_PATH_TYPE_LOCAL;
7941           path->sw_if_index = ~0;
7942           path->proto = FIB_API_PATH_NH_PROTO_IP6;
7943         }
7944       else if (unformat (input, "sw_if_index %d", &path->sw_if_index))
7945         ;
7946       else if (unformat (input, "via-label %d", &path->nh.via_label))
7947         {
7948           path->proto = FIB_API_PATH_NH_PROTO_MPLS;
7949           path->sw_if_index = ~0;
7950         }
7951       else if (unformat (input, "l2-input-on %d", &path->sw_if_index))
7952         {
7953           path->proto = FIB_API_PATH_NH_PROTO_ETHERNET;
7954           path->type = FIB_API_PATH_TYPE_INTERFACE_RX;
7955         }
7956       else if (unformat (input, "local"))
7957         {
7958           path->type = FIB_API_PATH_TYPE_LOCAL;
7959         }
7960       else if (unformat (input, "out-labels"))
7961         {
7962           while (unformat (input, "%d", &out_label))
7963             {
7964               path->label_stack[path->n_labels].label = out_label;
7965               path->label_stack[path->n_labels].is_uniform = 0;
7966               path->label_stack[path->n_labels].ttl = 64;
7967               path->n_labels++;
7968             }
7969         }
7970       else if (unformat (input, "via"))
7971         {
7972           /* new path, back up and return */
7973           unformat_put_input (input);
7974           unformat_put_input (input);
7975           unformat_put_input (input);
7976           unformat_put_input (input);
7977           break;
7978         }
7979       else
7980         {
7981           return (0);
7982         }
7983     }
7984
7985   path->proto = ntohl (path->proto);
7986   path->type = ntohl (path->type);
7987   path->flags = ntohl (path->flags);
7988   path->table_id = ntohl (path->table_id);
7989   path->sw_if_index = ntohl (path->sw_if_index);
7990
7991   return (1);
7992 }
7993
7994 static int
7995 api_ip_route_add_del (vat_main_t * vam)
7996 {
7997   unformat_input_t *i = vam->input;
7998   vl_api_ip_route_add_del_t *mp;
7999   u32 vrf_id = 0;
8000   u8 is_add = 1;
8001   u8 is_multipath = 0;
8002   u8 prefix_set = 0;
8003   u8 path_count = 0;
8004   vl_api_prefix_t pfx = { };
8005   vl_api_fib_path_t paths[8];
8006   int count = 1;
8007   int j;
8008   f64 before = 0;
8009   u32 random_add_del = 0;
8010   u32 *random_vector = 0;
8011   u32 random_seed = 0xdeaddabe;
8012
8013   /* Parse args required to build the message */
8014   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8015     {
8016       if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
8017         prefix_set = 1;
8018       else if (unformat (i, "del"))
8019         is_add = 0;
8020       else if (unformat (i, "add"))
8021         is_add = 1;
8022       else if (unformat (i, "vrf %d", &vrf_id))
8023         ;
8024       else if (unformat (i, "count %d", &count))
8025         ;
8026       else if (unformat (i, "random"))
8027         random_add_del = 1;
8028       else if (unformat (i, "multipath"))
8029         is_multipath = 1;
8030       else if (unformat (i, "seed %d", &random_seed))
8031         ;
8032       else
8033         if (unformat
8034             (i, "via %U", unformat_fib_path, vam, &paths[path_count]))
8035         {
8036           path_count++;
8037           if (8 == path_count)
8038             {
8039               errmsg ("max 8 paths");
8040               return -99;
8041             }
8042         }
8043       else
8044         {
8045           clib_warning ("parse error '%U'", format_unformat_error, i);
8046           return -99;
8047         }
8048     }
8049
8050   if (!path_count)
8051     {
8052       errmsg ("specify a path; via ...");
8053       return -99;
8054     }
8055   if (prefix_set == 0)
8056     {
8057       errmsg ("missing prefix");
8058       return -99;
8059     }
8060
8061   /* Generate a pile of unique, random routes */
8062   if (random_add_del)
8063     {
8064       ip4_address_t *i = (ip4_address_t *) & paths[0].nh.address.ip4;
8065       u32 this_random_address;
8066       uword *random_hash;
8067
8068       random_hash = hash_create (count, sizeof (uword));
8069
8070       hash_set (random_hash, i->as_u32, 1);
8071       for (j = 0; j <= count; j++)
8072         {
8073           do
8074             {
8075               this_random_address = random_u32 (&random_seed);
8076               this_random_address =
8077                 clib_host_to_net_u32 (this_random_address);
8078             }
8079           while (hash_get (random_hash, this_random_address));
8080           vec_add1 (random_vector, this_random_address);
8081           hash_set (random_hash, this_random_address, 1);
8082         }
8083       hash_free (random_hash);
8084       set_ip4_address (&pfx.address, random_vector[0]);
8085     }
8086
8087   if (count > 1)
8088     {
8089       /* Turn on async mode */
8090       vam->async_mode = 1;
8091       vam->async_errors = 0;
8092       before = vat_time_now (vam);
8093     }
8094
8095   for (j = 0; j < count; j++)
8096     {
8097       /* Construct the API message */
8098       M2 (IP_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t) * path_count);
8099
8100       mp->is_add = is_add;
8101       mp->is_multipath = is_multipath;
8102
8103       clib_memcpy (&mp->route.prefix, &pfx, sizeof (pfx));
8104       mp->route.table_id = ntohl (vrf_id);
8105       mp->route.n_paths = path_count;
8106
8107       clib_memcpy (&mp->route.paths, &paths, sizeof (paths[0]) * path_count);
8108
8109       if (random_add_del)
8110         set_ip4_address (&pfx.address, random_vector[j + 1]);
8111       else
8112         increment_address (&pfx.address);
8113       /* send it... */
8114       S (mp);
8115       /* If we receive SIGTERM, stop now... */
8116       if (vam->do_exit)
8117         break;
8118     }
8119
8120   /* When testing multiple add/del ops, use a control-ping to sync */
8121   if (count > 1)
8122     {
8123       vl_api_control_ping_t *mp_ping;
8124       f64 after;
8125       f64 timeout;
8126
8127       /* Shut off async mode */
8128       vam->async_mode = 0;
8129
8130       MPING (CONTROL_PING, mp_ping);
8131       S (mp_ping);
8132
8133       timeout = vat_time_now (vam) + 1.0;
8134       while (vat_time_now (vam) < timeout)
8135         if (vam->result_ready == 1)
8136           goto out;
8137       vam->retval = -99;
8138
8139     out:
8140       if (vam->retval == -99)
8141         errmsg ("timeout");
8142
8143       if (vam->async_errors > 0)
8144         {
8145           errmsg ("%d asynchronous errors", vam->async_errors);
8146           vam->retval = -98;
8147         }
8148       vam->async_errors = 0;
8149       after = vat_time_now (vam);
8150
8151       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8152       if (j > 0)
8153         count = j;
8154
8155       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8156              count, after - before, count / (after - before));
8157     }
8158   else
8159     {
8160       int ret;
8161
8162       /* Wait for a reply... */
8163       W (ret);
8164       return ret;
8165     }
8166
8167   /* Return the good/bad news */
8168   return (vam->retval);
8169 }
8170
8171 static int
8172 api_ip_mroute_add_del (vat_main_t * vam)
8173 {
8174   unformat_input_t *i = vam->input;
8175   u8 path_set = 0, prefix_set = 0, is_add = 1;
8176   vl_api_ip_mroute_add_del_t *mp;
8177   mfib_entry_flags_t eflags = 0;
8178   vl_api_mfib_path_t path;
8179   vl_api_mprefix_t pfx = { };
8180   u32 vrf_id = 0;
8181   int ret;
8182
8183   /* Parse args required to build the message */
8184   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8185     {
8186       if (unformat (i, "%U", unformat_vl_api_mprefix, &pfx))
8187         {
8188           prefix_set = 1;
8189           pfx.grp_address_length = htons (pfx.grp_address_length);
8190         }
8191       else if (unformat (i, "del"))
8192         is_add = 0;
8193       else if (unformat (i, "add"))
8194         is_add = 1;
8195       else if (unformat (i, "vrf %d", &vrf_id))
8196         ;
8197       else if (unformat (i, "%U", unformat_mfib_itf_flags, &path.itf_flags))
8198         path.itf_flags = htonl (path.itf_flags);
8199       else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
8200         ;
8201       else if (unformat (i, "via %U", unformat_fib_path, vam, &path.path))
8202         path_set = 1;
8203       else
8204         {
8205           clib_warning ("parse error '%U'", format_unformat_error, i);
8206           return -99;
8207         }
8208     }
8209
8210   if (prefix_set == 0)
8211     {
8212       errmsg ("missing addresses\n");
8213       return -99;
8214     }
8215   if (path_set == 0)
8216     {
8217       errmsg ("missing path\n");
8218       return -99;
8219     }
8220
8221   /* Construct the API message */
8222   M (IP_MROUTE_ADD_DEL, mp);
8223
8224   mp->is_add = is_add;
8225   mp->is_multipath = 1;
8226
8227   clib_memcpy (&mp->route.prefix, &pfx, sizeof (pfx));
8228   mp->route.table_id = htonl (vrf_id);
8229   mp->route.n_paths = 1;
8230   mp->route.entry_flags = htonl (eflags);
8231
8232   clib_memcpy (&mp->route.paths, &path, sizeof (path));
8233
8234   /* send it... */
8235   S (mp);
8236   /* Wait for a reply... */
8237   W (ret);
8238   return ret;
8239 }
8240
8241 static int
8242 api_mpls_table_add_del (vat_main_t * vam)
8243 {
8244   unformat_input_t *i = vam->input;
8245   vl_api_mpls_table_add_del_t *mp;
8246   u32 table_id = ~0;
8247   u8 is_add = 1;
8248   int ret = 0;
8249
8250   /* Parse args required to build the message */
8251   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8252     {
8253       if (unformat (i, "table %d", &table_id))
8254         ;
8255       else if (unformat (i, "del"))
8256         is_add = 0;
8257       else if (unformat (i, "add"))
8258         is_add = 1;
8259       else
8260         {
8261           clib_warning ("parse error '%U'", format_unformat_error, i);
8262           return -99;
8263         }
8264     }
8265
8266   if (~0 == table_id)
8267     {
8268       errmsg ("missing table-ID");
8269       return -99;
8270     }
8271
8272   /* Construct the API message */
8273   M (MPLS_TABLE_ADD_DEL, mp);
8274
8275   mp->mt_table.mt_table_id = ntohl (table_id);
8276   mp->mt_is_add = is_add;
8277
8278   /* send it... */
8279   S (mp);
8280
8281   /* Wait for a reply... */
8282   W (ret);
8283
8284   return ret;
8285 }
8286
8287 static int
8288 api_mpls_route_add_del (vat_main_t * vam)
8289 {
8290   u8 is_add = 1, path_count = 0, is_multipath = 0, is_eos = 0;
8291   mpls_label_t local_label = MPLS_LABEL_INVALID;
8292   unformat_input_t *i = vam->input;
8293   vl_api_mpls_route_add_del_t *mp;
8294   vl_api_fib_path_t paths[8];
8295   int count = 1, j;
8296   f64 before = 0;
8297
8298   /* Parse args required to build the message */
8299   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8300     {
8301       if (unformat (i, "%d", &local_label))
8302         ;
8303       else if (unformat (i, "eos"))
8304         is_eos = 1;
8305       else if (unformat (i, "non-eos"))
8306         is_eos = 0;
8307       else if (unformat (i, "del"))
8308         is_add = 0;
8309       else if (unformat (i, "add"))
8310         is_add = 1;
8311       else if (unformat (i, "multipath"))
8312         is_multipath = 1;
8313       else if (unformat (i, "count %d", &count))
8314         ;
8315       else
8316         if (unformat
8317             (i, "via %U", unformat_fib_path, vam, &paths[path_count]))
8318         {
8319           path_count++;
8320           if (8 == path_count)
8321             {
8322               errmsg ("max 8 paths");
8323               return -99;
8324             }
8325         }
8326       else
8327         {
8328           clib_warning ("parse error '%U'", format_unformat_error, i);
8329           return -99;
8330         }
8331     }
8332
8333   if (!path_count)
8334     {
8335       errmsg ("specify a path; via ...");
8336       return -99;
8337     }
8338
8339   if (MPLS_LABEL_INVALID == local_label)
8340     {
8341       errmsg ("missing label");
8342       return -99;
8343     }
8344
8345   if (count > 1)
8346     {
8347       /* Turn on async mode */
8348       vam->async_mode = 1;
8349       vam->async_errors = 0;
8350       before = vat_time_now (vam);
8351     }
8352
8353   for (j = 0; j < count; j++)
8354     {
8355       /* Construct the API message */
8356       M2 (MPLS_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t) * path_count);
8357
8358       mp->mr_is_add = is_add;
8359       mp->mr_is_multipath = is_multipath;
8360
8361       mp->mr_route.mr_label = local_label;
8362       mp->mr_route.mr_eos = is_eos;
8363       mp->mr_route.mr_table_id = 0;
8364       mp->mr_route.mr_n_paths = path_count;
8365
8366       clib_memcpy (&mp->mr_route.mr_paths, paths,
8367                    sizeof (paths[0]) * path_count);
8368
8369       local_label++;
8370
8371       /* send it... */
8372       S (mp);
8373       /* If we receive SIGTERM, stop now... */
8374       if (vam->do_exit)
8375         break;
8376     }
8377
8378   /* When testing multiple add/del ops, use a control-ping to sync */
8379   if (count > 1)
8380     {
8381       vl_api_control_ping_t *mp_ping;
8382       f64 after;
8383       f64 timeout;
8384
8385       /* Shut off async mode */
8386       vam->async_mode = 0;
8387
8388       MPING (CONTROL_PING, mp_ping);
8389       S (mp_ping);
8390
8391       timeout = vat_time_now (vam) + 1.0;
8392       while (vat_time_now (vam) < timeout)
8393         if (vam->result_ready == 1)
8394           goto out;
8395       vam->retval = -99;
8396
8397     out:
8398       if (vam->retval == -99)
8399         errmsg ("timeout");
8400
8401       if (vam->async_errors > 0)
8402         {
8403           errmsg ("%d asynchronous errors", vam->async_errors);
8404           vam->retval = -98;
8405         }
8406       vam->async_errors = 0;
8407       after = vat_time_now (vam);
8408
8409       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8410       if (j > 0)
8411         count = j;
8412
8413       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8414              count, after - before, count / (after - before));
8415     }
8416   else
8417     {
8418       int ret;
8419
8420       /* Wait for a reply... */
8421       W (ret);
8422       return ret;
8423     }
8424
8425   /* Return the good/bad news */
8426   return (vam->retval);
8427   return (0);
8428 }
8429
8430 static int
8431 api_mpls_ip_bind_unbind (vat_main_t * vam)
8432 {
8433   unformat_input_t *i = vam->input;
8434   vl_api_mpls_ip_bind_unbind_t *mp;
8435   u32 ip_table_id = 0;
8436   u8 is_bind = 1;
8437   vl_api_prefix_t pfx;
8438   u8 prefix_set = 0;
8439   mpls_label_t local_label = MPLS_LABEL_INVALID;
8440   int ret;
8441
8442   /* Parse args required to build the message */
8443   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8444     {
8445       if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
8446         prefix_set = 1;
8447       else if (unformat (i, "%d", &local_label))
8448         ;
8449       else if (unformat (i, "table-id %d", &ip_table_id))
8450         ;
8451       else if (unformat (i, "unbind"))
8452         is_bind = 0;
8453       else if (unformat (i, "bind"))
8454         is_bind = 1;
8455       else
8456         {
8457           clib_warning ("parse error '%U'", format_unformat_error, i);
8458           return -99;
8459         }
8460     }
8461
8462   if (!prefix_set)
8463     {
8464       errmsg ("IP prefix not set");
8465       return -99;
8466     }
8467
8468   if (MPLS_LABEL_INVALID == local_label)
8469     {
8470       errmsg ("missing label");
8471       return -99;
8472     }
8473
8474   /* Construct the API message */
8475   M (MPLS_IP_BIND_UNBIND, mp);
8476
8477   mp->mb_is_bind = is_bind;
8478   mp->mb_ip_table_id = ntohl (ip_table_id);
8479   mp->mb_mpls_table_id = 0;
8480   mp->mb_label = ntohl (local_label);
8481   clib_memcpy (&mp->mb_prefix, &pfx, sizeof (pfx));
8482
8483   /* send it... */
8484   S (mp);
8485
8486   /* Wait for a reply... */
8487   W (ret);
8488   return ret;
8489   return (0);
8490 }
8491
8492 static int
8493 api_sr_mpls_policy_add (vat_main_t * vam)
8494 {
8495   unformat_input_t *i = vam->input;
8496   vl_api_sr_mpls_policy_add_t *mp;
8497   u32 bsid = 0;
8498   u32 weight = 1;
8499   u8 type = 0;
8500   u8 n_segments = 0;
8501   u32 sid;
8502   u32 *segments = NULL;
8503   int ret;
8504
8505   /* Parse args required to build the message */
8506   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8507     {
8508       if (unformat (i, "bsid %d", &bsid))
8509         ;
8510       else if (unformat (i, "weight %d", &weight))
8511         ;
8512       else if (unformat (i, "spray"))
8513         type = 1;
8514       else if (unformat (i, "next %d", &sid))
8515         {
8516           n_segments += 1;
8517           vec_add1 (segments, htonl (sid));
8518         }
8519       else
8520         {
8521           clib_warning ("parse error '%U'", format_unformat_error, i);
8522           return -99;
8523         }
8524     }
8525
8526   if (bsid == 0)
8527     {
8528       errmsg ("bsid not set");
8529       return -99;
8530     }
8531
8532   if (n_segments == 0)
8533     {
8534       errmsg ("no sid in segment stack");
8535       return -99;
8536     }
8537
8538   /* Construct the API message */
8539   M2 (SR_MPLS_POLICY_ADD, mp, sizeof (u32) * n_segments);
8540
8541   mp->bsid = htonl (bsid);
8542   mp->weight = htonl (weight);
8543   mp->type = type;
8544   mp->n_segments = n_segments;
8545   memcpy (mp->segments, segments, sizeof (u32) * n_segments);
8546   vec_free (segments);
8547
8548   /* send it... */
8549   S (mp);
8550
8551   /* Wait for a reply... */
8552   W (ret);
8553   return ret;
8554 }
8555
8556 static int
8557 api_sr_mpls_policy_del (vat_main_t * vam)
8558 {
8559   unformat_input_t *i = vam->input;
8560   vl_api_sr_mpls_policy_del_t *mp;
8561   u32 bsid = 0;
8562   int ret;
8563
8564   /* Parse args required to build the message */
8565   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8566     {
8567       if (unformat (i, "bsid %d", &bsid))
8568         ;
8569       else
8570         {
8571           clib_warning ("parse error '%U'", format_unformat_error, i);
8572           return -99;
8573         }
8574     }
8575
8576   if (bsid == 0)
8577     {
8578       errmsg ("bsid not set");
8579       return -99;
8580     }
8581
8582   /* Construct the API message */
8583   M (SR_MPLS_POLICY_DEL, mp);
8584
8585   mp->bsid = htonl (bsid);
8586
8587   /* send it... */
8588   S (mp);
8589
8590   /* Wait for a reply... */
8591   W (ret);
8592   return ret;
8593 }
8594
8595 static int
8596 api_bier_table_add_del (vat_main_t * vam)
8597 {
8598   unformat_input_t *i = vam->input;
8599   vl_api_bier_table_add_del_t *mp;
8600   u8 is_add = 1;
8601   u32 set = 0, sub_domain = 0, hdr_len = 3;
8602   mpls_label_t local_label = MPLS_LABEL_INVALID;
8603   int ret;
8604
8605   /* Parse args required to build the message */
8606   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8607     {
8608       if (unformat (i, "sub-domain %d", &sub_domain))
8609         ;
8610       else if (unformat (i, "set %d", &set))
8611         ;
8612       else if (unformat (i, "label %d", &local_label))
8613         ;
8614       else if (unformat (i, "hdr-len %d", &hdr_len))
8615         ;
8616       else if (unformat (i, "add"))
8617         is_add = 1;
8618       else if (unformat (i, "del"))
8619         is_add = 0;
8620       else
8621         {
8622           clib_warning ("parse error '%U'", format_unformat_error, i);
8623           return -99;
8624         }
8625     }
8626
8627   if (MPLS_LABEL_INVALID == local_label)
8628     {
8629       errmsg ("missing label\n");
8630       return -99;
8631     }
8632
8633   /* Construct the API message */
8634   M (BIER_TABLE_ADD_DEL, mp);
8635
8636   mp->bt_is_add = is_add;
8637   mp->bt_label = ntohl (local_label);
8638   mp->bt_tbl_id.bt_set = set;
8639   mp->bt_tbl_id.bt_sub_domain = sub_domain;
8640   mp->bt_tbl_id.bt_hdr_len_id = hdr_len;
8641
8642   /* send it... */
8643   S (mp);
8644
8645   /* Wait for a reply... */
8646   W (ret);
8647
8648   return (ret);
8649 }
8650
8651 static int
8652 api_bier_route_add_del (vat_main_t * vam)
8653 {
8654   unformat_input_t *i = vam->input;
8655   vl_api_bier_route_add_del_t *mp;
8656   u8 is_add = 1;
8657   u32 set = 0, sub_domain = 0, hdr_len = 3, bp = 0;
8658   ip4_address_t v4_next_hop_address;
8659   ip6_address_t v6_next_hop_address;
8660   u8 next_hop_set = 0;
8661   u8 next_hop_proto_is_ip4 = 1;
8662   mpls_label_t next_hop_out_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, "%U", unformat_ip4_address, &v4_next_hop_address))
8669         {
8670           next_hop_proto_is_ip4 = 1;
8671           next_hop_set = 1;
8672         }
8673       else if (unformat (i, "%U", unformat_ip6_address, &v6_next_hop_address))
8674         {
8675           next_hop_proto_is_ip4 = 0;
8676           next_hop_set = 1;
8677         }
8678       if (unformat (i, "sub-domain %d", &sub_domain))
8679         ;
8680       else if (unformat (i, "set %d", &set))
8681         ;
8682       else if (unformat (i, "hdr-len %d", &hdr_len))
8683         ;
8684       else if (unformat (i, "bp %d", &bp))
8685         ;
8686       else if (unformat (i, "add"))
8687         is_add = 1;
8688       else if (unformat (i, "del"))
8689         is_add = 0;
8690       else if (unformat (i, "out-label %d", &next_hop_out_label))
8691         ;
8692       else
8693         {
8694           clib_warning ("parse error '%U'", format_unformat_error, i);
8695           return -99;
8696         }
8697     }
8698
8699   if (!next_hop_set || (MPLS_LABEL_INVALID == next_hop_out_label))
8700     {
8701       errmsg ("next hop / label set\n");
8702       return -99;
8703     }
8704   if (0 == bp)
8705     {
8706       errmsg ("bit=position not set\n");
8707       return -99;
8708     }
8709
8710   /* Construct the API message */
8711   M2 (BIER_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t));
8712
8713   mp->br_is_add = is_add;
8714   mp->br_route.br_tbl_id.bt_set = set;
8715   mp->br_route.br_tbl_id.bt_sub_domain = sub_domain;
8716   mp->br_route.br_tbl_id.bt_hdr_len_id = hdr_len;
8717   mp->br_route.br_bp = ntohs (bp);
8718   mp->br_route.br_n_paths = 1;
8719   mp->br_route.br_paths[0].n_labels = 1;
8720   mp->br_route.br_paths[0].label_stack[0].label = ntohl (next_hop_out_label);
8721   mp->br_route.br_paths[0].proto = (next_hop_proto_is_ip4 ?
8722                                     FIB_API_PATH_NH_PROTO_IP4 :
8723                                     FIB_API_PATH_NH_PROTO_IP6);
8724
8725   if (next_hop_proto_is_ip4)
8726     {
8727       clib_memcpy (&mp->br_route.br_paths[0].nh.address.ip4,
8728                    &v4_next_hop_address, sizeof (v4_next_hop_address));
8729     }
8730   else
8731     {
8732       clib_memcpy (&mp->br_route.br_paths[0].nh.address.ip6,
8733                    &v6_next_hop_address, sizeof (v6_next_hop_address));
8734     }
8735
8736   /* send it... */
8737   S (mp);
8738
8739   /* Wait for a reply... */
8740   W (ret);
8741
8742   return (ret);
8743 }
8744
8745 static int
8746 api_mpls_tunnel_add_del (vat_main_t * vam)
8747 {
8748   unformat_input_t *i = vam->input;
8749   vl_api_mpls_tunnel_add_del_t *mp;
8750
8751   vl_api_fib_path_t paths[8];
8752   u32 sw_if_index = ~0;
8753   u8 path_count = 0;
8754   u8 l2_only = 0;
8755   u8 is_add = 1;
8756   int ret;
8757
8758   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8759     {
8760       if (unformat (i, "add"))
8761         is_add = 1;
8762       else
8763         if (unformat
8764             (i, "del %U", api_unformat_sw_if_index, vam, &sw_if_index))
8765         is_add = 0;
8766       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
8767         is_add = 0;
8768       else if (unformat (i, "l2-only"))
8769         l2_only = 1;
8770       else
8771         if (unformat
8772             (i, "via %U", unformat_fib_path, vam, &paths[path_count]))
8773         {
8774           path_count++;
8775           if (8 == path_count)
8776             {
8777               errmsg ("max 8 paths");
8778               return -99;
8779             }
8780         }
8781       else
8782         {
8783           clib_warning ("parse error '%U'", format_unformat_error, i);
8784           return -99;
8785         }
8786     }
8787
8788   M2 (MPLS_TUNNEL_ADD_DEL, mp, sizeof (vl_api_fib_path_t) * path_count);
8789
8790   mp->mt_is_add = is_add;
8791   mp->mt_tunnel.mt_sw_if_index = ntohl (sw_if_index);
8792   mp->mt_tunnel.mt_l2_only = l2_only;
8793   mp->mt_tunnel.mt_is_multicast = 0;
8794   mp->mt_tunnel.mt_n_paths = path_count;
8795
8796   clib_memcpy (&mp->mt_tunnel.mt_paths, &paths,
8797                sizeof (paths[0]) * path_count);
8798
8799   S (mp);
8800   W (ret);
8801   return ret;
8802 }
8803
8804 static int
8805 api_sw_interface_set_unnumbered (vat_main_t * vam)
8806 {
8807   unformat_input_t *i = vam->input;
8808   vl_api_sw_interface_set_unnumbered_t *mp;
8809   u32 sw_if_index;
8810   u32 unnum_sw_index = ~0;
8811   u8 is_add = 1;
8812   u8 sw_if_index_set = 0;
8813   int ret;
8814
8815   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8816     {
8817       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8818         sw_if_index_set = 1;
8819       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8820         sw_if_index_set = 1;
8821       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
8822         ;
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 (sw_if_index_set == 0)
8833     {
8834       errmsg ("missing interface name or sw_if_index");
8835       return -99;
8836     }
8837
8838   M (SW_INTERFACE_SET_UNNUMBERED, mp);
8839
8840   mp->sw_if_index = ntohl (sw_if_index);
8841   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
8842   mp->is_add = is_add;
8843
8844   S (mp);
8845   W (ret);
8846   return ret;
8847 }
8848
8849
8850 static int
8851 api_create_vlan_subif (vat_main_t * vam)
8852 {
8853   unformat_input_t *i = vam->input;
8854   vl_api_create_vlan_subif_t *mp;
8855   u32 sw_if_index;
8856   u8 sw_if_index_set = 0;
8857   u32 vlan_id;
8858   u8 vlan_id_set = 0;
8859   int ret;
8860
8861   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8862     {
8863       if (unformat (i, "sw_if_index %d", &sw_if_index))
8864         sw_if_index_set = 1;
8865       else
8866         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8867         sw_if_index_set = 1;
8868       else if (unformat (i, "vlan %d", &vlan_id))
8869         vlan_id_set = 1;
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   if (vlan_id_set == 0)
8884     {
8885       errmsg ("missing vlan_id");
8886       return -99;
8887     }
8888   M (CREATE_VLAN_SUBIF, mp);
8889
8890   mp->sw_if_index = ntohl (sw_if_index);
8891   mp->vlan_id = ntohl (vlan_id);
8892
8893   S (mp);
8894   W (ret);
8895   return ret;
8896 }
8897
8898 #define foreach_create_subif_bit                \
8899 _(no_tags)                                      \
8900 _(one_tag)                                      \
8901 _(two_tags)                                     \
8902 _(dot1ad)                                       \
8903 _(exact_match)                                  \
8904 _(default_sub)                                  \
8905 _(outer_vlan_id_any)                            \
8906 _(inner_vlan_id_any)
8907
8908 #define foreach_create_subif_flag               \
8909 _(0, "no_tags")                                 \
8910 _(1, "one_tag")                                 \
8911 _(2, "two_tags")                                \
8912 _(3, "dot1ad")                                  \
8913 _(4, "exact_match")                             \
8914 _(5, "default_sub")                             \
8915 _(6, "outer_vlan_id_any")                       \
8916 _(7, "inner_vlan_id_any")
8917
8918 static int
8919 api_create_subif (vat_main_t * vam)
8920 {
8921   unformat_input_t *i = vam->input;
8922   vl_api_create_subif_t *mp;
8923   u32 sw_if_index;
8924   u8 sw_if_index_set = 0;
8925   u32 sub_id;
8926   u8 sub_id_set = 0;
8927   u32 __attribute__ ((unused)) no_tags = 0;
8928   u32 __attribute__ ((unused)) one_tag = 0;
8929   u32 __attribute__ ((unused)) two_tags = 0;
8930   u32 __attribute__ ((unused)) dot1ad = 0;
8931   u32 __attribute__ ((unused)) exact_match = 0;
8932   u32 __attribute__ ((unused)) default_sub = 0;
8933   u32 __attribute__ ((unused)) outer_vlan_id_any = 0;
8934   u32 __attribute__ ((unused)) inner_vlan_id_any = 0;
8935   u32 tmp;
8936   u16 outer_vlan_id = 0;
8937   u16 inner_vlan_id = 0;
8938   int ret;
8939
8940   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8941     {
8942       if (unformat (i, "sw_if_index %d", &sw_if_index))
8943         sw_if_index_set = 1;
8944       else
8945         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8946         sw_if_index_set = 1;
8947       else if (unformat (i, "sub_id %d", &sub_id))
8948         sub_id_set = 1;
8949       else if (unformat (i, "outer_vlan_id %d", &tmp))
8950         outer_vlan_id = tmp;
8951       else if (unformat (i, "inner_vlan_id %d", &tmp))
8952         inner_vlan_id = tmp;
8953
8954 #define _(a) else if (unformat (i, #a)) a = 1 ;
8955       foreach_create_subif_bit
8956 #undef _
8957         else
8958         {
8959           clib_warning ("parse error '%U'", format_unformat_error, i);
8960           return -99;
8961         }
8962     }
8963
8964   if (sw_if_index_set == 0)
8965     {
8966       errmsg ("missing interface name or sw_if_index");
8967       return -99;
8968     }
8969
8970   if (sub_id_set == 0)
8971     {
8972       errmsg ("missing sub_id");
8973       return -99;
8974     }
8975   M (CREATE_SUBIF, mp);
8976
8977   mp->sw_if_index = ntohl (sw_if_index);
8978   mp->sub_id = ntohl (sub_id);
8979
8980 #define _(a,b) mp->sub_if_flags |= (1 << a);
8981   foreach_create_subif_flag;
8982 #undef _
8983
8984   mp->outer_vlan_id = ntohs (outer_vlan_id);
8985   mp->inner_vlan_id = ntohs (inner_vlan_id);
8986
8987   S (mp);
8988   W (ret);
8989   return ret;
8990 }
8991
8992 static int
8993 api_ip_table_replace_begin (vat_main_t * vam)
8994 {
8995   unformat_input_t *i = vam->input;
8996   vl_api_ip_table_replace_begin_t *mp;
8997   u32 table_id = 0;
8998   u8 is_ipv6 = 0;
8999
9000   int ret;
9001   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9002     {
9003       if (unformat (i, "table %d", &table_id))
9004         ;
9005       else if (unformat (i, "ipv6"))
9006         is_ipv6 = 1;
9007       else
9008         {
9009           clib_warning ("parse error '%U'", format_unformat_error, i);
9010           return -99;
9011         }
9012     }
9013
9014   M (IP_TABLE_REPLACE_BEGIN, mp);
9015
9016   mp->table.table_id = ntohl (table_id);
9017   mp->table.is_ip6 = is_ipv6;
9018
9019   S (mp);
9020   W (ret);
9021   return ret;
9022 }
9023
9024 static int
9025 api_ip_table_flush (vat_main_t * vam)
9026 {
9027   unformat_input_t *i = vam->input;
9028   vl_api_ip_table_flush_t *mp;
9029   u32 table_id = 0;
9030   u8 is_ipv6 = 0;
9031
9032   int ret;
9033   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9034     {
9035       if (unformat (i, "table %d", &table_id))
9036         ;
9037       else if (unformat (i, "ipv6"))
9038         is_ipv6 = 1;
9039       else
9040         {
9041           clib_warning ("parse error '%U'", format_unformat_error, i);
9042           return -99;
9043         }
9044     }
9045
9046   M (IP_TABLE_FLUSH, mp);
9047
9048   mp->table.table_id = ntohl (table_id);
9049   mp->table.is_ip6 = is_ipv6;
9050
9051   S (mp);
9052   W (ret);
9053   return ret;
9054 }
9055
9056 static int
9057 api_ip_table_replace_end (vat_main_t * vam)
9058 {
9059   unformat_input_t *i = vam->input;
9060   vl_api_ip_table_replace_end_t *mp;
9061   u32 table_id = 0;
9062   u8 is_ipv6 = 0;
9063
9064   int ret;
9065   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9066     {
9067       if (unformat (i, "table %d", &table_id))
9068         ;
9069       else if (unformat (i, "ipv6"))
9070         is_ipv6 = 1;
9071       else
9072         {
9073           clib_warning ("parse error '%U'", format_unformat_error, i);
9074           return -99;
9075         }
9076     }
9077
9078   M (IP_TABLE_REPLACE_END, mp);
9079
9080   mp->table.table_id = ntohl (table_id);
9081   mp->table.is_ip6 = is_ipv6;
9082
9083   S (mp);
9084   W (ret);
9085   return ret;
9086 }
9087
9088 static int
9089 api_set_ip_flow_hash (vat_main_t * vam)
9090 {
9091   unformat_input_t *i = vam->input;
9092   vl_api_set_ip_flow_hash_t *mp;
9093   u32 vrf_id = 0;
9094   u8 is_ipv6 = 0;
9095   u8 vrf_id_set = 0;
9096   u8 src = 0;
9097   u8 dst = 0;
9098   u8 sport = 0;
9099   u8 dport = 0;
9100   u8 proto = 0;
9101   u8 reverse = 0;
9102   int ret;
9103
9104   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9105     {
9106       if (unformat (i, "vrf %d", &vrf_id))
9107         vrf_id_set = 1;
9108       else if (unformat (i, "ipv6"))
9109         is_ipv6 = 1;
9110       else if (unformat (i, "src"))
9111         src = 1;
9112       else if (unformat (i, "dst"))
9113         dst = 1;
9114       else if (unformat (i, "sport"))
9115         sport = 1;
9116       else if (unformat (i, "dport"))
9117         dport = 1;
9118       else if (unformat (i, "proto"))
9119         proto = 1;
9120       else if (unformat (i, "reverse"))
9121         reverse = 1;
9122
9123       else
9124         {
9125           clib_warning ("parse error '%U'", format_unformat_error, i);
9126           return -99;
9127         }
9128     }
9129
9130   if (vrf_id_set == 0)
9131     {
9132       errmsg ("missing vrf id");
9133       return -99;
9134     }
9135
9136   M (SET_IP_FLOW_HASH, mp);
9137   mp->src = src;
9138   mp->dst = dst;
9139   mp->sport = sport;
9140   mp->dport = dport;
9141   mp->proto = proto;
9142   mp->reverse = reverse;
9143   mp->vrf_id = ntohl (vrf_id);
9144   mp->is_ipv6 = is_ipv6;
9145
9146   S (mp);
9147   W (ret);
9148   return ret;
9149 }
9150
9151 static int
9152 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
9153 {
9154   unformat_input_t *i = vam->input;
9155   vl_api_sw_interface_ip6_enable_disable_t *mp;
9156   u32 sw_if_index;
9157   u8 sw_if_index_set = 0;
9158   u8 enable = 0;
9159   int ret;
9160
9161   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9162     {
9163       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9164         sw_if_index_set = 1;
9165       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9166         sw_if_index_set = 1;
9167       else if (unformat (i, "enable"))
9168         enable = 1;
9169       else if (unformat (i, "disable"))
9170         enable = 0;
9171       else
9172         {
9173           clib_warning ("parse error '%U'", format_unformat_error, i);
9174           return -99;
9175         }
9176     }
9177
9178   if (sw_if_index_set == 0)
9179     {
9180       errmsg ("missing interface name or sw_if_index");
9181       return -99;
9182     }
9183
9184   M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
9185
9186   mp->sw_if_index = ntohl (sw_if_index);
9187   mp->enable = enable;
9188
9189   S (mp);
9190   W (ret);
9191   return ret;
9192 }
9193
9194
9195 static int
9196 api_l2_patch_add_del (vat_main_t * vam)
9197 {
9198   unformat_input_t *i = vam->input;
9199   vl_api_l2_patch_add_del_t *mp;
9200   u32 rx_sw_if_index;
9201   u8 rx_sw_if_index_set = 0;
9202   u32 tx_sw_if_index;
9203   u8 tx_sw_if_index_set = 0;
9204   u8 is_add = 1;
9205   int ret;
9206
9207   /* Parse args required to build the message */
9208   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9209     {
9210       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
9211         rx_sw_if_index_set = 1;
9212       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
9213         tx_sw_if_index_set = 1;
9214       else if (unformat (i, "rx"))
9215         {
9216           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9217             {
9218               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
9219                             &rx_sw_if_index))
9220                 rx_sw_if_index_set = 1;
9221             }
9222           else
9223             break;
9224         }
9225       else if (unformat (i, "tx"))
9226         {
9227           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9228             {
9229               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
9230                             &tx_sw_if_index))
9231                 tx_sw_if_index_set = 1;
9232             }
9233           else
9234             break;
9235         }
9236       else if (unformat (i, "del"))
9237         is_add = 0;
9238       else
9239         break;
9240     }
9241
9242   if (rx_sw_if_index_set == 0)
9243     {
9244       errmsg ("missing rx interface name or rx_sw_if_index");
9245       return -99;
9246     }
9247
9248   if (tx_sw_if_index_set == 0)
9249     {
9250       errmsg ("missing tx interface name or tx_sw_if_index");
9251       return -99;
9252     }
9253
9254   M (L2_PATCH_ADD_DEL, mp);
9255
9256   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
9257   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
9258   mp->is_add = is_add;
9259
9260   S (mp);
9261   W (ret);
9262   return ret;
9263 }
9264
9265 u8 is_del;
9266 u8 localsid_addr[16];
9267 u8 end_psp;
9268 u8 behavior;
9269 u32 sw_if_index;
9270 u32 vlan_index;
9271 u32 fib_table;
9272 u8 nh_addr[16];
9273
9274 static int
9275 api_sr_localsid_add_del (vat_main_t * vam)
9276 {
9277   unformat_input_t *i = vam->input;
9278   vl_api_sr_localsid_add_del_t *mp;
9279
9280   u8 is_del;
9281   ip6_address_t localsid;
9282   u8 end_psp = 0;
9283   u8 behavior = ~0;
9284   u32 sw_if_index;
9285   u32 fib_table = ~(u32) 0;
9286   ip6_address_t nh_addr6;
9287   ip4_address_t nh_addr4;
9288   clib_memset (&nh_addr6, 0, sizeof (ip6_address_t));
9289   clib_memset (&nh_addr4, 0, sizeof (ip4_address_t));
9290
9291   bool nexthop_set = 0;
9292
9293   int ret;
9294
9295   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9296     {
9297       if (unformat (i, "del"))
9298         is_del = 1;
9299       else if (unformat (i, "address %U", unformat_ip6_address, &localsid));
9300       else if (unformat (i, "next-hop %U", unformat_ip4_address, &nh_addr4))
9301         nexthop_set = 1;
9302       else if (unformat (i, "next-hop %U", unformat_ip6_address, &nh_addr6))
9303         nexthop_set = 1;
9304       else if (unformat (i, "behavior %u", &behavior));
9305       else if (unformat (i, "sw_if_index %u", &sw_if_index));
9306       else if (unformat (i, "fib-table %u", &fib_table));
9307       else if (unformat (i, "end.psp %u", &behavior));
9308       else
9309         break;
9310     }
9311
9312   M (SR_LOCALSID_ADD_DEL, mp);
9313
9314   clib_memcpy (mp->localsid.addr, &localsid, sizeof (mp->localsid));
9315
9316   if (nexthop_set)
9317     {
9318       clib_memcpy (mp->nh_addr6, &nh_addr6, sizeof (mp->nh_addr6));
9319       clib_memcpy (mp->nh_addr4, &nh_addr4, sizeof (mp->nh_addr4));
9320     }
9321   mp->behavior = behavior;
9322   mp->sw_if_index = ntohl (sw_if_index);
9323   mp->fib_table = ntohl (fib_table);
9324   mp->end_psp = end_psp;
9325   mp->is_del = is_del;
9326
9327   S (mp);
9328   W (ret);
9329   return ret;
9330 }
9331
9332 static int
9333 api_ioam_enable (vat_main_t * vam)
9334 {
9335   unformat_input_t *input = vam->input;
9336   vl_api_ioam_enable_t *mp;
9337   u32 id = 0;
9338   int has_trace_option = 0;
9339   int has_pot_option = 0;
9340   int has_seqno_option = 0;
9341   int has_analyse_option = 0;
9342   int ret;
9343
9344   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9345     {
9346       if (unformat (input, "trace"))
9347         has_trace_option = 1;
9348       else if (unformat (input, "pot"))
9349         has_pot_option = 1;
9350       else if (unformat (input, "seqno"))
9351         has_seqno_option = 1;
9352       else if (unformat (input, "analyse"))
9353         has_analyse_option = 1;
9354       else
9355         break;
9356     }
9357   M (IOAM_ENABLE, mp);
9358   mp->id = htons (id);
9359   mp->seqno = has_seqno_option;
9360   mp->analyse = has_analyse_option;
9361   mp->pot_enable = has_pot_option;
9362   mp->trace_enable = has_trace_option;
9363
9364   S (mp);
9365   W (ret);
9366   return ret;
9367 }
9368
9369
9370 static int
9371 api_ioam_disable (vat_main_t * vam)
9372 {
9373   vl_api_ioam_disable_t *mp;
9374   int ret;
9375
9376   M (IOAM_DISABLE, mp);
9377   S (mp);
9378   W (ret);
9379   return ret;
9380 }
9381
9382 #define foreach_tcp_proto_field                 \
9383 _(src_port)                                     \
9384 _(dst_port)
9385
9386 #define foreach_udp_proto_field                 \
9387 _(src_port)                                     \
9388 _(dst_port)
9389
9390 #define foreach_ip4_proto_field                 \
9391 _(src_address)                                  \
9392 _(dst_address)                                  \
9393 _(tos)                                          \
9394 _(length)                                       \
9395 _(fragment_id)                                  \
9396 _(ttl)                                          \
9397 _(protocol)                                     \
9398 _(checksum)
9399
9400 typedef struct
9401 {
9402   u16 src_port, dst_port;
9403 } tcpudp_header_t;
9404
9405 #if VPP_API_TEST_BUILTIN == 0
9406 uword
9407 unformat_tcp_mask (unformat_input_t * input, va_list * args)
9408 {
9409   u8 **maskp = va_arg (*args, u8 **);
9410   u8 *mask = 0;
9411   u8 found_something = 0;
9412   tcp_header_t *tcp;
9413
9414 #define _(a) u8 a=0;
9415   foreach_tcp_proto_field;
9416 #undef _
9417
9418   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9419     {
9420       if (0);
9421 #define _(a) else if (unformat (input, #a)) a=1;
9422       foreach_tcp_proto_field
9423 #undef _
9424         else
9425         break;
9426     }
9427
9428 #define _(a) found_something += a;
9429   foreach_tcp_proto_field;
9430 #undef _
9431
9432   if (found_something == 0)
9433     return 0;
9434
9435   vec_validate (mask, sizeof (*tcp) - 1);
9436
9437   tcp = (tcp_header_t *) mask;
9438
9439 #define _(a) if (a) clib_memset (&tcp->a, 0xff, sizeof (tcp->a));
9440   foreach_tcp_proto_field;
9441 #undef _
9442
9443   *maskp = mask;
9444   return 1;
9445 }
9446
9447 uword
9448 unformat_udp_mask (unformat_input_t * input, va_list * args)
9449 {
9450   u8 **maskp = va_arg (*args, u8 **);
9451   u8 *mask = 0;
9452   u8 found_something = 0;
9453   udp_header_t *udp;
9454
9455 #define _(a) u8 a=0;
9456   foreach_udp_proto_field;
9457 #undef _
9458
9459   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9460     {
9461       if (0);
9462 #define _(a) else if (unformat (input, #a)) a=1;
9463       foreach_udp_proto_field
9464 #undef _
9465         else
9466         break;
9467     }
9468
9469 #define _(a) found_something += a;
9470   foreach_udp_proto_field;
9471 #undef _
9472
9473   if (found_something == 0)
9474     return 0;
9475
9476   vec_validate (mask, sizeof (*udp) - 1);
9477
9478   udp = (udp_header_t *) mask;
9479
9480 #define _(a) if (a) clib_memset (&udp->a, 0xff, sizeof (udp->a));
9481   foreach_udp_proto_field;
9482 #undef _
9483
9484   *maskp = mask;
9485   return 1;
9486 }
9487
9488 uword
9489 unformat_l4_mask (unformat_input_t * input, va_list * args)
9490 {
9491   u8 **maskp = va_arg (*args, u8 **);
9492   u16 src_port = 0, dst_port = 0;
9493   tcpudp_header_t *tcpudp;
9494
9495   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9496     {
9497       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
9498         return 1;
9499       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
9500         return 1;
9501       else if (unformat (input, "src_port"))
9502         src_port = 0xFFFF;
9503       else if (unformat (input, "dst_port"))
9504         dst_port = 0xFFFF;
9505       else
9506         return 0;
9507     }
9508
9509   if (!src_port && !dst_port)
9510     return 0;
9511
9512   u8 *mask = 0;
9513   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
9514
9515   tcpudp = (tcpudp_header_t *) mask;
9516   tcpudp->src_port = src_port;
9517   tcpudp->dst_port = dst_port;
9518
9519   *maskp = mask;
9520
9521   return 1;
9522 }
9523
9524 uword
9525 unformat_ip4_mask (unformat_input_t * input, va_list * args)
9526 {
9527   u8 **maskp = va_arg (*args, u8 **);
9528   u8 *mask = 0;
9529   u8 found_something = 0;
9530   ip4_header_t *ip;
9531
9532 #define _(a) u8 a=0;
9533   foreach_ip4_proto_field;
9534 #undef _
9535   u8 version = 0;
9536   u8 hdr_length = 0;
9537
9538
9539   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9540     {
9541       if (unformat (input, "version"))
9542         version = 1;
9543       else if (unformat (input, "hdr_length"))
9544         hdr_length = 1;
9545       else if (unformat (input, "src"))
9546         src_address = 1;
9547       else if (unformat (input, "dst"))
9548         dst_address = 1;
9549       else if (unformat (input, "proto"))
9550         protocol = 1;
9551
9552 #define _(a) else if (unformat (input, #a)) a=1;
9553       foreach_ip4_proto_field
9554 #undef _
9555         else
9556         break;
9557     }
9558
9559 #define _(a) found_something += a;
9560   foreach_ip4_proto_field;
9561 #undef _
9562
9563   if (found_something == 0)
9564     return 0;
9565
9566   vec_validate (mask, sizeof (*ip) - 1);
9567
9568   ip = (ip4_header_t *) mask;
9569
9570 #define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
9571   foreach_ip4_proto_field;
9572 #undef _
9573
9574   ip->ip_version_and_header_length = 0;
9575
9576   if (version)
9577     ip->ip_version_and_header_length |= 0xF0;
9578
9579   if (hdr_length)
9580     ip->ip_version_and_header_length |= 0x0F;
9581
9582   *maskp = mask;
9583   return 1;
9584 }
9585
9586 #define foreach_ip6_proto_field                 \
9587 _(src_address)                                  \
9588 _(dst_address)                                  \
9589 _(payload_length)                               \
9590 _(hop_limit)                                    \
9591 _(protocol)
9592
9593 uword
9594 unformat_ip6_mask (unformat_input_t * input, va_list * args)
9595 {
9596   u8 **maskp = va_arg (*args, u8 **);
9597   u8 *mask = 0;
9598   u8 found_something = 0;
9599   ip6_header_t *ip;
9600   u32 ip_version_traffic_class_and_flow_label;
9601
9602 #define _(a) u8 a=0;
9603   foreach_ip6_proto_field;
9604 #undef _
9605   u8 version = 0;
9606   u8 traffic_class = 0;
9607   u8 flow_label = 0;
9608
9609   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9610     {
9611       if (unformat (input, "version"))
9612         version = 1;
9613       else if (unformat (input, "traffic-class"))
9614         traffic_class = 1;
9615       else if (unformat (input, "flow-label"))
9616         flow_label = 1;
9617       else if (unformat (input, "src"))
9618         src_address = 1;
9619       else if (unformat (input, "dst"))
9620         dst_address = 1;
9621       else if (unformat (input, "proto"))
9622         protocol = 1;
9623
9624 #define _(a) else if (unformat (input, #a)) a=1;
9625       foreach_ip6_proto_field
9626 #undef _
9627         else
9628         break;
9629     }
9630
9631 #define _(a) found_something += a;
9632   foreach_ip6_proto_field;
9633 #undef _
9634
9635   if (found_something == 0)
9636     return 0;
9637
9638   vec_validate (mask, sizeof (*ip) - 1);
9639
9640   ip = (ip6_header_t *) mask;
9641
9642 #define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
9643   foreach_ip6_proto_field;
9644 #undef _
9645
9646   ip_version_traffic_class_and_flow_label = 0;
9647
9648   if (version)
9649     ip_version_traffic_class_and_flow_label |= 0xF0000000;
9650
9651   if (traffic_class)
9652     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
9653
9654   if (flow_label)
9655     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
9656
9657   ip->ip_version_traffic_class_and_flow_label =
9658     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
9659
9660   *maskp = mask;
9661   return 1;
9662 }
9663
9664 uword
9665 unformat_l3_mask (unformat_input_t * input, va_list * args)
9666 {
9667   u8 **maskp = va_arg (*args, u8 **);
9668
9669   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9670     {
9671       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
9672         return 1;
9673       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
9674         return 1;
9675       else
9676         break;
9677     }
9678   return 0;
9679 }
9680
9681 uword
9682 unformat_l2_mask (unformat_input_t * input, va_list * args)
9683 {
9684   u8 **maskp = va_arg (*args, u8 **);
9685   u8 *mask = 0;
9686   u8 src = 0;
9687   u8 dst = 0;
9688   u8 proto = 0;
9689   u8 tag1 = 0;
9690   u8 tag2 = 0;
9691   u8 ignore_tag1 = 0;
9692   u8 ignore_tag2 = 0;
9693   u8 cos1 = 0;
9694   u8 cos2 = 0;
9695   u8 dot1q = 0;
9696   u8 dot1ad = 0;
9697   int len = 14;
9698
9699   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9700     {
9701       if (unformat (input, "src"))
9702         src = 1;
9703       else if (unformat (input, "dst"))
9704         dst = 1;
9705       else if (unformat (input, "proto"))
9706         proto = 1;
9707       else if (unformat (input, "tag1"))
9708         tag1 = 1;
9709       else if (unformat (input, "tag2"))
9710         tag2 = 1;
9711       else if (unformat (input, "ignore-tag1"))
9712         ignore_tag1 = 1;
9713       else if (unformat (input, "ignore-tag2"))
9714         ignore_tag2 = 1;
9715       else if (unformat (input, "cos1"))
9716         cos1 = 1;
9717       else if (unformat (input, "cos2"))
9718         cos2 = 1;
9719       else if (unformat (input, "dot1q"))
9720         dot1q = 1;
9721       else if (unformat (input, "dot1ad"))
9722         dot1ad = 1;
9723       else
9724         break;
9725     }
9726   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
9727        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
9728     return 0;
9729
9730   if (tag1 || ignore_tag1 || cos1 || dot1q)
9731     len = 18;
9732   if (tag2 || ignore_tag2 || cos2 || dot1ad)
9733     len = 22;
9734
9735   vec_validate (mask, len - 1);
9736
9737   if (dst)
9738     clib_memset (mask, 0xff, 6);
9739
9740   if (src)
9741     clib_memset (mask + 6, 0xff, 6);
9742
9743   if (tag2 || dot1ad)
9744     {
9745       /* inner vlan tag */
9746       if (tag2)
9747         {
9748           mask[19] = 0xff;
9749           mask[18] = 0x0f;
9750         }
9751       if (cos2)
9752         mask[18] |= 0xe0;
9753       if (proto)
9754         mask[21] = mask[20] = 0xff;
9755       if (tag1)
9756         {
9757           mask[15] = 0xff;
9758           mask[14] = 0x0f;
9759         }
9760       if (cos1)
9761         mask[14] |= 0xe0;
9762       *maskp = mask;
9763       return 1;
9764     }
9765   if (tag1 | dot1q)
9766     {
9767       if (tag1)
9768         {
9769           mask[15] = 0xff;
9770           mask[14] = 0x0f;
9771         }
9772       if (cos1)
9773         mask[14] |= 0xe0;
9774       if (proto)
9775         mask[16] = mask[17] = 0xff;
9776
9777       *maskp = mask;
9778       return 1;
9779     }
9780   if (cos2)
9781     mask[18] |= 0xe0;
9782   if (cos1)
9783     mask[14] |= 0xe0;
9784   if (proto)
9785     mask[12] = mask[13] = 0xff;
9786
9787   *maskp = mask;
9788   return 1;
9789 }
9790
9791 uword
9792 unformat_classify_mask (unformat_input_t * input, va_list * args)
9793 {
9794   u8 **maskp = va_arg (*args, u8 **);
9795   u32 *skipp = va_arg (*args, u32 *);
9796   u32 *matchp = va_arg (*args, u32 *);
9797   u32 match;
9798   u8 *mask = 0;
9799   u8 *l2 = 0;
9800   u8 *l3 = 0;
9801   u8 *l4 = 0;
9802   int i;
9803
9804   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9805     {
9806       if (unformat (input, "hex %U", unformat_hex_string, &mask))
9807         ;
9808       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
9809         ;
9810       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
9811         ;
9812       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
9813         ;
9814       else
9815         break;
9816     }
9817
9818   if (l4 && !l3)
9819     {
9820       vec_free (mask);
9821       vec_free (l2);
9822       vec_free (l4);
9823       return 0;
9824     }
9825
9826   if (mask || l2 || l3 || l4)
9827     {
9828       if (l2 || l3 || l4)
9829         {
9830           /* "With a free Ethernet header in every package" */
9831           if (l2 == 0)
9832             vec_validate (l2, 13);
9833           mask = l2;
9834           if (vec_len (l3))
9835             {
9836               vec_append (mask, l3);
9837               vec_free (l3);
9838             }
9839           if (vec_len (l4))
9840             {
9841               vec_append (mask, l4);
9842               vec_free (l4);
9843             }
9844         }
9845
9846       /* Scan forward looking for the first significant mask octet */
9847       for (i = 0; i < vec_len (mask); i++)
9848         if (mask[i])
9849           break;
9850
9851       /* compute (skip, match) params */
9852       *skipp = i / sizeof (u32x4);
9853       vec_delete (mask, *skipp * sizeof (u32x4), 0);
9854
9855       /* Pad mask to an even multiple of the vector size */
9856       while (vec_len (mask) % sizeof (u32x4))
9857         vec_add1 (mask, 0);
9858
9859       match = vec_len (mask) / sizeof (u32x4);
9860
9861       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
9862         {
9863           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
9864           if (*tmp || *(tmp + 1))
9865             break;
9866           match--;
9867         }
9868       if (match == 0)
9869         clib_warning ("BUG: match 0");
9870
9871       _vec_len (mask) = match * sizeof (u32x4);
9872
9873       *matchp = match;
9874       *maskp = mask;
9875
9876       return 1;
9877     }
9878
9879   return 0;
9880 }
9881 #endif /* VPP_API_TEST_BUILTIN */
9882
9883 #define foreach_l2_next                         \
9884 _(drop, DROP)                                   \
9885 _(ethernet, ETHERNET_INPUT)                     \
9886 _(ip4, IP4_INPUT)                               \
9887 _(ip6, IP6_INPUT)
9888
9889 uword
9890 unformat_l2_next_index (unformat_input_t * input, va_list * args)
9891 {
9892   u32 *miss_next_indexp = va_arg (*args, u32 *);
9893   u32 next_index = 0;
9894   u32 tmp;
9895
9896 #define _(n,N) \
9897   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
9898   foreach_l2_next;
9899 #undef _
9900
9901   if (unformat (input, "%d", &tmp))
9902     {
9903       next_index = tmp;
9904       goto out;
9905     }
9906
9907   return 0;
9908
9909 out:
9910   *miss_next_indexp = next_index;
9911   return 1;
9912 }
9913
9914 #define foreach_ip_next                         \
9915 _(drop, DROP)                                   \
9916 _(local, LOCAL)                                 \
9917 _(rewrite, REWRITE)
9918
9919 uword
9920 api_unformat_ip_next_index (unformat_input_t * input, va_list * args)
9921 {
9922   u32 *miss_next_indexp = va_arg (*args, u32 *);
9923   u32 next_index = 0;
9924   u32 tmp;
9925
9926 #define _(n,N) \
9927   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
9928   foreach_ip_next;
9929 #undef _
9930
9931   if (unformat (input, "%d", &tmp))
9932     {
9933       next_index = tmp;
9934       goto out;
9935     }
9936
9937   return 0;
9938
9939 out:
9940   *miss_next_indexp = next_index;
9941   return 1;
9942 }
9943
9944 #define foreach_acl_next                        \
9945 _(deny, DENY)
9946
9947 uword
9948 api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
9949 {
9950   u32 *miss_next_indexp = va_arg (*args, u32 *);
9951   u32 next_index = 0;
9952   u32 tmp;
9953
9954 #define _(n,N) \
9955   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
9956   foreach_acl_next;
9957 #undef _
9958
9959   if (unformat (input, "permit"))
9960     {
9961       next_index = ~0;
9962       goto out;
9963     }
9964   else if (unformat (input, "%d", &tmp))
9965     {
9966       next_index = tmp;
9967       goto out;
9968     }
9969
9970   return 0;
9971
9972 out:
9973   *miss_next_indexp = next_index;
9974   return 1;
9975 }
9976
9977 uword
9978 unformat_policer_precolor (unformat_input_t * input, va_list * args)
9979 {
9980   u32 *r = va_arg (*args, u32 *);
9981
9982   if (unformat (input, "conform-color"))
9983     *r = POLICE_CONFORM;
9984   else if (unformat (input, "exceed-color"))
9985     *r = POLICE_EXCEED;
9986   else
9987     return 0;
9988
9989   return 1;
9990 }
9991
9992 static int
9993 api_classify_add_del_table (vat_main_t * vam)
9994 {
9995   unformat_input_t *i = vam->input;
9996   vl_api_classify_add_del_table_t *mp;
9997
9998   u32 nbuckets = 2;
9999   u32 skip = ~0;
10000   u32 match = ~0;
10001   int is_add = 1;
10002   int del_chain = 0;
10003   u32 table_index = ~0;
10004   u32 next_table_index = ~0;
10005   u32 miss_next_index = ~0;
10006   u32 memory_size = 32 << 20;
10007   u8 *mask = 0;
10008   u32 current_data_flag = 0;
10009   int current_data_offset = 0;
10010   int ret;
10011
10012   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10013     {
10014       if (unformat (i, "del"))
10015         is_add = 0;
10016       else if (unformat (i, "del-chain"))
10017         {
10018           is_add = 0;
10019           del_chain = 1;
10020         }
10021       else if (unformat (i, "buckets %d", &nbuckets))
10022         ;
10023       else if (unformat (i, "memory_size %d", &memory_size))
10024         ;
10025       else if (unformat (i, "skip %d", &skip))
10026         ;
10027       else if (unformat (i, "match %d", &match))
10028         ;
10029       else if (unformat (i, "table %d", &table_index))
10030         ;
10031       else if (unformat (i, "mask %U", unformat_classify_mask,
10032                          &mask, &skip, &match))
10033         ;
10034       else if (unformat (i, "next-table %d", &next_table_index))
10035         ;
10036       else if (unformat (i, "miss-next %U", api_unformat_ip_next_index,
10037                          &miss_next_index))
10038         ;
10039       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
10040                          &miss_next_index))
10041         ;
10042       else if (unformat (i, "acl-miss-next %U", api_unformat_acl_next_index,
10043                          &miss_next_index))
10044         ;
10045       else if (unformat (i, "current-data-flag %d", &current_data_flag))
10046         ;
10047       else if (unformat (i, "current-data-offset %d", &current_data_offset))
10048         ;
10049       else
10050         break;
10051     }
10052
10053   if (is_add && mask == 0)
10054     {
10055       errmsg ("Mask required");
10056       return -99;
10057     }
10058
10059   if (is_add && skip == ~0)
10060     {
10061       errmsg ("skip count required");
10062       return -99;
10063     }
10064
10065   if (is_add && match == ~0)
10066     {
10067       errmsg ("match count required");
10068       return -99;
10069     }
10070
10071   if (!is_add && table_index == ~0)
10072     {
10073       errmsg ("table index required for delete");
10074       return -99;
10075     }
10076
10077   M2 (CLASSIFY_ADD_DEL_TABLE, mp, vec_len (mask));
10078
10079   mp->is_add = is_add;
10080   mp->del_chain = del_chain;
10081   mp->table_index = ntohl (table_index);
10082   mp->nbuckets = ntohl (nbuckets);
10083   mp->memory_size = ntohl (memory_size);
10084   mp->skip_n_vectors = ntohl (skip);
10085   mp->match_n_vectors = ntohl (match);
10086   mp->next_table_index = ntohl (next_table_index);
10087   mp->miss_next_index = ntohl (miss_next_index);
10088   mp->current_data_flag = ntohl (current_data_flag);
10089   mp->current_data_offset = ntohl (current_data_offset);
10090   mp->mask_len = ntohl (vec_len (mask));
10091   clib_memcpy (mp->mask, mask, vec_len (mask));
10092
10093   vec_free (mask);
10094
10095   S (mp);
10096   W (ret);
10097   return ret;
10098 }
10099
10100 #if VPP_API_TEST_BUILTIN == 0
10101 uword
10102 unformat_l4_match (unformat_input_t * input, va_list * args)
10103 {
10104   u8 **matchp = va_arg (*args, u8 **);
10105
10106   u8 *proto_header = 0;
10107   int src_port = 0;
10108   int dst_port = 0;
10109
10110   tcpudp_header_t h;
10111
10112   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10113     {
10114       if (unformat (input, "src_port %d", &src_port))
10115         ;
10116       else if (unformat (input, "dst_port %d", &dst_port))
10117         ;
10118       else
10119         return 0;
10120     }
10121
10122   h.src_port = clib_host_to_net_u16 (src_port);
10123   h.dst_port = clib_host_to_net_u16 (dst_port);
10124   vec_validate (proto_header, sizeof (h) - 1);
10125   memcpy (proto_header, &h, sizeof (h));
10126
10127   *matchp = proto_header;
10128
10129   return 1;
10130 }
10131
10132 uword
10133 unformat_ip4_match (unformat_input_t * input, va_list * args)
10134 {
10135   u8 **matchp = va_arg (*args, u8 **);
10136   u8 *match = 0;
10137   ip4_header_t *ip;
10138   int version = 0;
10139   u32 version_val;
10140   int hdr_length = 0;
10141   u32 hdr_length_val;
10142   int src = 0, dst = 0;
10143   ip4_address_t src_val, dst_val;
10144   int proto = 0;
10145   u32 proto_val;
10146   int tos = 0;
10147   u32 tos_val;
10148   int length = 0;
10149   u32 length_val;
10150   int fragment_id = 0;
10151   u32 fragment_id_val;
10152   int ttl = 0;
10153   int ttl_val;
10154   int checksum = 0;
10155   u32 checksum_val;
10156
10157   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10158     {
10159       if (unformat (input, "version %d", &version_val))
10160         version = 1;
10161       else if (unformat (input, "hdr_length %d", &hdr_length_val))
10162         hdr_length = 1;
10163       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
10164         src = 1;
10165       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
10166         dst = 1;
10167       else if (unformat (input, "proto %d", &proto_val))
10168         proto = 1;
10169       else if (unformat (input, "tos %d", &tos_val))
10170         tos = 1;
10171       else if (unformat (input, "length %d", &length_val))
10172         length = 1;
10173       else if (unformat (input, "fragment_id %d", &fragment_id_val))
10174         fragment_id = 1;
10175       else if (unformat (input, "ttl %d", &ttl_val))
10176         ttl = 1;
10177       else if (unformat (input, "checksum %d", &checksum_val))
10178         checksum = 1;
10179       else
10180         break;
10181     }
10182
10183   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
10184       + ttl + checksum == 0)
10185     return 0;
10186
10187   /*
10188    * Aligned because we use the real comparison functions
10189    */
10190   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
10191
10192   ip = (ip4_header_t *) match;
10193
10194   /* These are realistically matched in practice */
10195   if (src)
10196     ip->src_address.as_u32 = src_val.as_u32;
10197
10198   if (dst)
10199     ip->dst_address.as_u32 = dst_val.as_u32;
10200
10201   if (proto)
10202     ip->protocol = proto_val;
10203
10204
10205   /* These are not, but they're included for completeness */
10206   if (version)
10207     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
10208
10209   if (hdr_length)
10210     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
10211
10212   if (tos)
10213     ip->tos = tos_val;
10214
10215   if (length)
10216     ip->length = clib_host_to_net_u16 (length_val);
10217
10218   if (ttl)
10219     ip->ttl = ttl_val;
10220
10221   if (checksum)
10222     ip->checksum = clib_host_to_net_u16 (checksum_val);
10223
10224   *matchp = match;
10225   return 1;
10226 }
10227
10228 uword
10229 unformat_ip6_match (unformat_input_t * input, va_list * args)
10230 {
10231   u8 **matchp = va_arg (*args, u8 **);
10232   u8 *match = 0;
10233   ip6_header_t *ip;
10234   int version = 0;
10235   u32 version_val;
10236   u8 traffic_class = 0;
10237   u32 traffic_class_val = 0;
10238   u8 flow_label = 0;
10239   u8 flow_label_val;
10240   int src = 0, dst = 0;
10241   ip6_address_t src_val, dst_val;
10242   int proto = 0;
10243   u32 proto_val;
10244   int payload_length = 0;
10245   u32 payload_length_val;
10246   int hop_limit = 0;
10247   int hop_limit_val;
10248   u32 ip_version_traffic_class_and_flow_label;
10249
10250   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10251     {
10252       if (unformat (input, "version %d", &version_val))
10253         version = 1;
10254       else if (unformat (input, "traffic_class %d", &traffic_class_val))
10255         traffic_class = 1;
10256       else if (unformat (input, "flow_label %d", &flow_label_val))
10257         flow_label = 1;
10258       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
10259         src = 1;
10260       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
10261         dst = 1;
10262       else if (unformat (input, "proto %d", &proto_val))
10263         proto = 1;
10264       else if (unformat (input, "payload_length %d", &payload_length_val))
10265         payload_length = 1;
10266       else if (unformat (input, "hop_limit %d", &hop_limit_val))
10267         hop_limit = 1;
10268       else
10269         break;
10270     }
10271
10272   if (version + traffic_class + flow_label + src + dst + proto +
10273       payload_length + hop_limit == 0)
10274     return 0;
10275
10276   /*
10277    * Aligned because we use the real comparison functions
10278    */
10279   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
10280
10281   ip = (ip6_header_t *) match;
10282
10283   if (src)
10284     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
10285
10286   if (dst)
10287     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
10288
10289   if (proto)
10290     ip->protocol = proto_val;
10291
10292   ip_version_traffic_class_and_flow_label = 0;
10293
10294   if (version)
10295     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
10296
10297   if (traffic_class)
10298     ip_version_traffic_class_and_flow_label |=
10299       (traffic_class_val & 0xFF) << 20;
10300
10301   if (flow_label)
10302     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
10303
10304   ip->ip_version_traffic_class_and_flow_label =
10305     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
10306
10307   if (payload_length)
10308     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
10309
10310   if (hop_limit)
10311     ip->hop_limit = hop_limit_val;
10312
10313   *matchp = match;
10314   return 1;
10315 }
10316
10317 uword
10318 unformat_l3_match (unformat_input_t * input, va_list * args)
10319 {
10320   u8 **matchp = va_arg (*args, u8 **);
10321
10322   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10323     {
10324       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
10325         return 1;
10326       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
10327         return 1;
10328       else
10329         break;
10330     }
10331   return 0;
10332 }
10333
10334 uword
10335 unformat_vlan_tag (unformat_input_t * input, va_list * args)
10336 {
10337   u8 *tagp = va_arg (*args, u8 *);
10338   u32 tag;
10339
10340   if (unformat (input, "%d", &tag))
10341     {
10342       tagp[0] = (tag >> 8) & 0x0F;
10343       tagp[1] = tag & 0xFF;
10344       return 1;
10345     }
10346
10347   return 0;
10348 }
10349
10350 uword
10351 unformat_l2_match (unformat_input_t * input, va_list * args)
10352 {
10353   u8 **matchp = va_arg (*args, u8 **);
10354   u8 *match = 0;
10355   u8 src = 0;
10356   u8 src_val[6];
10357   u8 dst = 0;
10358   u8 dst_val[6];
10359   u8 proto = 0;
10360   u16 proto_val;
10361   u8 tag1 = 0;
10362   u8 tag1_val[2];
10363   u8 tag2 = 0;
10364   u8 tag2_val[2];
10365   int len = 14;
10366   u8 ignore_tag1 = 0;
10367   u8 ignore_tag2 = 0;
10368   u8 cos1 = 0;
10369   u8 cos2 = 0;
10370   u32 cos1_val = 0;
10371   u32 cos2_val = 0;
10372
10373   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10374     {
10375       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
10376         src = 1;
10377       else
10378         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
10379         dst = 1;
10380       else if (unformat (input, "proto %U",
10381                          unformat_ethernet_type_host_byte_order, &proto_val))
10382         proto = 1;
10383       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
10384         tag1 = 1;
10385       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
10386         tag2 = 1;
10387       else if (unformat (input, "ignore-tag1"))
10388         ignore_tag1 = 1;
10389       else if (unformat (input, "ignore-tag2"))
10390         ignore_tag2 = 1;
10391       else if (unformat (input, "cos1 %d", &cos1_val))
10392         cos1 = 1;
10393       else if (unformat (input, "cos2 %d", &cos2_val))
10394         cos2 = 1;
10395       else
10396         break;
10397     }
10398   if ((src + dst + proto + tag1 + tag2 +
10399        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
10400     return 0;
10401
10402   if (tag1 || ignore_tag1 || cos1)
10403     len = 18;
10404   if (tag2 || ignore_tag2 || cos2)
10405     len = 22;
10406
10407   vec_validate_aligned (match, len - 1, sizeof (u32x4));
10408
10409   if (dst)
10410     clib_memcpy (match, dst_val, 6);
10411
10412   if (src)
10413     clib_memcpy (match + 6, src_val, 6);
10414
10415   if (tag2)
10416     {
10417       /* inner vlan tag */
10418       match[19] = tag2_val[1];
10419       match[18] = tag2_val[0];
10420       if (cos2)
10421         match[18] |= (cos2_val & 0x7) << 5;
10422       if (proto)
10423         {
10424           match[21] = proto_val & 0xff;
10425           match[20] = proto_val >> 8;
10426         }
10427       if (tag1)
10428         {
10429           match[15] = tag1_val[1];
10430           match[14] = tag1_val[0];
10431         }
10432       if (cos1)
10433         match[14] |= (cos1_val & 0x7) << 5;
10434       *matchp = match;
10435       return 1;
10436     }
10437   if (tag1)
10438     {
10439       match[15] = tag1_val[1];
10440       match[14] = tag1_val[0];
10441       if (proto)
10442         {
10443           match[17] = proto_val & 0xff;
10444           match[16] = proto_val >> 8;
10445         }
10446       if (cos1)
10447         match[14] |= (cos1_val & 0x7) << 5;
10448
10449       *matchp = match;
10450       return 1;
10451     }
10452   if (cos2)
10453     match[18] |= (cos2_val & 0x7) << 5;
10454   if (cos1)
10455     match[14] |= (cos1_val & 0x7) << 5;
10456   if (proto)
10457     {
10458       match[13] = proto_val & 0xff;
10459       match[12] = proto_val >> 8;
10460     }
10461
10462   *matchp = match;
10463   return 1;
10464 }
10465
10466 uword
10467 unformat_qos_source (unformat_input_t * input, va_list * args)
10468 {
10469   int *qs = va_arg (*args, int *);
10470
10471   if (unformat (input, "ip"))
10472     *qs = QOS_SOURCE_IP;
10473   else if (unformat (input, "mpls"))
10474     *qs = QOS_SOURCE_MPLS;
10475   else if (unformat (input, "ext"))
10476     *qs = QOS_SOURCE_EXT;
10477   else if (unformat (input, "vlan"))
10478     *qs = QOS_SOURCE_VLAN;
10479   else
10480     return 0;
10481
10482   return 1;
10483 }
10484 #endif
10485
10486 uword
10487 api_unformat_classify_match (unformat_input_t * input, va_list * args)
10488 {
10489   u8 **matchp = va_arg (*args, u8 **);
10490   u32 skip_n_vectors = va_arg (*args, u32);
10491   u32 match_n_vectors = va_arg (*args, u32);
10492
10493   u8 *match = 0;
10494   u8 *l2 = 0;
10495   u8 *l3 = 0;
10496   u8 *l4 = 0;
10497
10498   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10499     {
10500       if (unformat (input, "hex %U", unformat_hex_string, &match))
10501         ;
10502       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
10503         ;
10504       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
10505         ;
10506       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
10507         ;
10508       else
10509         break;
10510     }
10511
10512   if (l4 && !l3)
10513     {
10514       vec_free (match);
10515       vec_free (l2);
10516       vec_free (l4);
10517       return 0;
10518     }
10519
10520   if (match || l2 || l3 || l4)
10521     {
10522       if (l2 || l3 || l4)
10523         {
10524           /* "Win a free Ethernet header in every packet" */
10525           if (l2 == 0)
10526             vec_validate_aligned (l2, 13, sizeof (u32x4));
10527           match = l2;
10528           if (vec_len (l3))
10529             {
10530               vec_append_aligned (match, l3, sizeof (u32x4));
10531               vec_free (l3);
10532             }
10533           if (vec_len (l4))
10534             {
10535               vec_append_aligned (match, l4, sizeof (u32x4));
10536               vec_free (l4);
10537             }
10538         }
10539
10540       /* Make sure the vector is big enough even if key is all 0's */
10541       vec_validate_aligned
10542         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
10543          sizeof (u32x4));
10544
10545       /* Set size, include skipped vectors */
10546       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
10547
10548       *matchp = match;
10549
10550       return 1;
10551     }
10552
10553   return 0;
10554 }
10555
10556 static int
10557 api_classify_add_del_session (vat_main_t * vam)
10558 {
10559   unformat_input_t *i = vam->input;
10560   vl_api_classify_add_del_session_t *mp;
10561   int is_add = 1;
10562   u32 table_index = ~0;
10563   u32 hit_next_index = ~0;
10564   u32 opaque_index = ~0;
10565   u8 *match = 0;
10566   i32 advance = 0;
10567   u32 skip_n_vectors = 0;
10568   u32 match_n_vectors = 0;
10569   u32 action = 0;
10570   u32 metadata = 0;
10571   int ret;
10572
10573   /*
10574    * Warning: you have to supply skip_n and match_n
10575    * because the API client cant simply look at the classify
10576    * table object.
10577    */
10578
10579   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10580     {
10581       if (unformat (i, "del"))
10582         is_add = 0;
10583       else if (unformat (i, "hit-next %U", api_unformat_ip_next_index,
10584                          &hit_next_index))
10585         ;
10586       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
10587                          &hit_next_index))
10588         ;
10589       else if (unformat (i, "acl-hit-next %U", api_unformat_acl_next_index,
10590                          &hit_next_index))
10591         ;
10592       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
10593         ;
10594       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
10595         ;
10596       else if (unformat (i, "opaque-index %d", &opaque_index))
10597         ;
10598       else if (unformat (i, "skip_n %d", &skip_n_vectors))
10599         ;
10600       else if (unformat (i, "match_n %d", &match_n_vectors))
10601         ;
10602       else if (unformat (i, "match %U", api_unformat_classify_match,
10603                          &match, skip_n_vectors, match_n_vectors))
10604         ;
10605       else if (unformat (i, "advance %d", &advance))
10606         ;
10607       else if (unformat (i, "table-index %d", &table_index))
10608         ;
10609       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
10610         action = 1;
10611       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
10612         action = 2;
10613       else if (unformat (i, "action %d", &action))
10614         ;
10615       else if (unformat (i, "metadata %d", &metadata))
10616         ;
10617       else
10618         break;
10619     }
10620
10621   if (table_index == ~0)
10622     {
10623       errmsg ("Table index required");
10624       return -99;
10625     }
10626
10627   if (is_add && match == 0)
10628     {
10629       errmsg ("Match value required");
10630       return -99;
10631     }
10632
10633   M2 (CLASSIFY_ADD_DEL_SESSION, mp, vec_len (match));
10634
10635   mp->is_add = is_add;
10636   mp->table_index = ntohl (table_index);
10637   mp->hit_next_index = ntohl (hit_next_index);
10638   mp->opaque_index = ntohl (opaque_index);
10639   mp->advance = ntohl (advance);
10640   mp->action = action;
10641   mp->metadata = ntohl (metadata);
10642   mp->match_len = ntohl (vec_len (match));
10643   clib_memcpy (mp->match, match, vec_len (match));
10644   vec_free (match);
10645
10646   S (mp);
10647   W (ret);
10648   return ret;
10649 }
10650
10651 static int
10652 api_classify_set_interface_ip_table (vat_main_t * vam)
10653 {
10654   unformat_input_t *i = vam->input;
10655   vl_api_classify_set_interface_ip_table_t *mp;
10656   u32 sw_if_index;
10657   int sw_if_index_set;
10658   u32 table_index = ~0;
10659   u8 is_ipv6 = 0;
10660   int ret;
10661
10662   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10663     {
10664       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10665         sw_if_index_set = 1;
10666       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10667         sw_if_index_set = 1;
10668       else if (unformat (i, "table %d", &table_index))
10669         ;
10670       else
10671         {
10672           clib_warning ("parse error '%U'", format_unformat_error, i);
10673           return -99;
10674         }
10675     }
10676
10677   if (sw_if_index_set == 0)
10678     {
10679       errmsg ("missing interface name or sw_if_index");
10680       return -99;
10681     }
10682
10683
10684   M (CLASSIFY_SET_INTERFACE_IP_TABLE, mp);
10685
10686   mp->sw_if_index = ntohl (sw_if_index);
10687   mp->table_index = ntohl (table_index);
10688   mp->is_ipv6 = is_ipv6;
10689
10690   S (mp);
10691   W (ret);
10692   return ret;
10693 }
10694
10695 static int
10696 api_classify_set_interface_l2_tables (vat_main_t * vam)
10697 {
10698   unformat_input_t *i = vam->input;
10699   vl_api_classify_set_interface_l2_tables_t *mp;
10700   u32 sw_if_index;
10701   int sw_if_index_set;
10702   u32 ip4_table_index = ~0;
10703   u32 ip6_table_index = ~0;
10704   u32 other_table_index = ~0;
10705   u32 is_input = 1;
10706   int ret;
10707
10708   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10709     {
10710       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10711         sw_if_index_set = 1;
10712       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10713         sw_if_index_set = 1;
10714       else if (unformat (i, "ip4-table %d", &ip4_table_index))
10715         ;
10716       else if (unformat (i, "ip6-table %d", &ip6_table_index))
10717         ;
10718       else if (unformat (i, "other-table %d", &other_table_index))
10719         ;
10720       else if (unformat (i, "is-input %d", &is_input))
10721         ;
10722       else
10723         {
10724           clib_warning ("parse error '%U'", format_unformat_error, i);
10725           return -99;
10726         }
10727     }
10728
10729   if (sw_if_index_set == 0)
10730     {
10731       errmsg ("missing interface name or sw_if_index");
10732       return -99;
10733     }
10734
10735
10736   M (CLASSIFY_SET_INTERFACE_L2_TABLES, mp);
10737
10738   mp->sw_if_index = ntohl (sw_if_index);
10739   mp->ip4_table_index = ntohl (ip4_table_index);
10740   mp->ip6_table_index = ntohl (ip6_table_index);
10741   mp->other_table_index = ntohl (other_table_index);
10742   mp->is_input = (u8) is_input;
10743
10744   S (mp);
10745   W (ret);
10746   return ret;
10747 }
10748
10749 static int
10750 api_set_ipfix_exporter (vat_main_t * vam)
10751 {
10752   unformat_input_t *i = vam->input;
10753   vl_api_set_ipfix_exporter_t *mp;
10754   ip4_address_t collector_address;
10755   u8 collector_address_set = 0;
10756   u32 collector_port = ~0;
10757   ip4_address_t src_address;
10758   u8 src_address_set = 0;
10759   u32 vrf_id = ~0;
10760   u32 path_mtu = ~0;
10761   u32 template_interval = ~0;
10762   u8 udp_checksum = 0;
10763   int ret;
10764
10765   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10766     {
10767       if (unformat (i, "collector_address %U", unformat_ip4_address,
10768                     &collector_address))
10769         collector_address_set = 1;
10770       else if (unformat (i, "collector_port %d", &collector_port))
10771         ;
10772       else if (unformat (i, "src_address %U", unformat_ip4_address,
10773                          &src_address))
10774         src_address_set = 1;
10775       else if (unformat (i, "vrf_id %d", &vrf_id))
10776         ;
10777       else if (unformat (i, "path_mtu %d", &path_mtu))
10778         ;
10779       else if (unformat (i, "template_interval %d", &template_interval))
10780         ;
10781       else if (unformat (i, "udp_checksum"))
10782         udp_checksum = 1;
10783       else
10784         break;
10785     }
10786
10787   if (collector_address_set == 0)
10788     {
10789       errmsg ("collector_address required");
10790       return -99;
10791     }
10792
10793   if (src_address_set == 0)
10794     {
10795       errmsg ("src_address required");
10796       return -99;
10797     }
10798
10799   M (SET_IPFIX_EXPORTER, mp);
10800
10801   memcpy (mp->collector_address.un.ip4, collector_address.data,
10802           sizeof (collector_address.data));
10803   mp->collector_port = htons ((u16) collector_port);
10804   memcpy (mp->src_address.un.ip4, src_address.data,
10805           sizeof (src_address.data));
10806   mp->vrf_id = htonl (vrf_id);
10807   mp->path_mtu = htonl (path_mtu);
10808   mp->template_interval = htonl (template_interval);
10809   mp->udp_checksum = udp_checksum;
10810
10811   S (mp);
10812   W (ret);
10813   return ret;
10814 }
10815
10816 static int
10817 api_set_ipfix_classify_stream (vat_main_t * vam)
10818 {
10819   unformat_input_t *i = vam->input;
10820   vl_api_set_ipfix_classify_stream_t *mp;
10821   u32 domain_id = 0;
10822   u32 src_port = UDP_DST_PORT_ipfix;
10823   int ret;
10824
10825   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10826     {
10827       if (unformat (i, "domain %d", &domain_id))
10828         ;
10829       else if (unformat (i, "src_port %d", &src_port))
10830         ;
10831       else
10832         {
10833           errmsg ("unknown input `%U'", format_unformat_error, i);
10834           return -99;
10835         }
10836     }
10837
10838   M (SET_IPFIX_CLASSIFY_STREAM, mp);
10839
10840   mp->domain_id = htonl (domain_id);
10841   mp->src_port = htons ((u16) src_port);
10842
10843   S (mp);
10844   W (ret);
10845   return ret;
10846 }
10847
10848 static int
10849 api_ipfix_classify_table_add_del (vat_main_t * vam)
10850 {
10851   unformat_input_t *i = vam->input;
10852   vl_api_ipfix_classify_table_add_del_t *mp;
10853   int is_add = -1;
10854   u32 classify_table_index = ~0;
10855   u8 ip_version = 0;
10856   u8 transport_protocol = 255;
10857   int ret;
10858
10859   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10860     {
10861       if (unformat (i, "add"))
10862         is_add = 1;
10863       else if (unformat (i, "del"))
10864         is_add = 0;
10865       else if (unformat (i, "table %d", &classify_table_index))
10866         ;
10867       else if (unformat (i, "ip4"))
10868         ip_version = 4;
10869       else if (unformat (i, "ip6"))
10870         ip_version = 6;
10871       else if (unformat (i, "tcp"))
10872         transport_protocol = 6;
10873       else if (unformat (i, "udp"))
10874         transport_protocol = 17;
10875       else
10876         {
10877           errmsg ("unknown input `%U'", format_unformat_error, i);
10878           return -99;
10879         }
10880     }
10881
10882   if (is_add == -1)
10883     {
10884       errmsg ("expecting: add|del");
10885       return -99;
10886     }
10887   if (classify_table_index == ~0)
10888     {
10889       errmsg ("classifier table not specified");
10890       return -99;
10891     }
10892   if (ip_version == 0)
10893     {
10894       errmsg ("IP version not specified");
10895       return -99;
10896     }
10897
10898   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, mp);
10899
10900   mp->is_add = is_add;
10901   mp->table_id = htonl (classify_table_index);
10902   mp->ip_version = ip_version;
10903   mp->transport_protocol = transport_protocol;
10904
10905   S (mp);
10906   W (ret);
10907   return ret;
10908 }
10909
10910 static int
10911 api_get_node_index (vat_main_t * vam)
10912 {
10913   unformat_input_t *i = vam->input;
10914   vl_api_get_node_index_t *mp;
10915   u8 *name = 0;
10916   int ret;
10917
10918   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10919     {
10920       if (unformat (i, "node %s", &name))
10921         ;
10922       else
10923         break;
10924     }
10925   if (name == 0)
10926     {
10927       errmsg ("node name required");
10928       return -99;
10929     }
10930   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
10931     {
10932       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
10933       return -99;
10934     }
10935
10936   M (GET_NODE_INDEX, mp);
10937   clib_memcpy (mp->node_name, name, vec_len (name));
10938   vec_free (name);
10939
10940   S (mp);
10941   W (ret);
10942   return ret;
10943 }
10944
10945 static int
10946 api_get_next_index (vat_main_t * vam)
10947 {
10948   unformat_input_t *i = vam->input;
10949   vl_api_get_next_index_t *mp;
10950   u8 *node_name = 0, *next_node_name = 0;
10951   int ret;
10952
10953   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10954     {
10955       if (unformat (i, "node-name %s", &node_name))
10956         ;
10957       else if (unformat (i, "next-node-name %s", &next_node_name))
10958         break;
10959     }
10960
10961   if (node_name == 0)
10962     {
10963       errmsg ("node name required");
10964       return -99;
10965     }
10966   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
10967     {
10968       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
10969       return -99;
10970     }
10971
10972   if (next_node_name == 0)
10973     {
10974       errmsg ("next node name required");
10975       return -99;
10976     }
10977   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
10978     {
10979       errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
10980       return -99;
10981     }
10982
10983   M (GET_NEXT_INDEX, mp);
10984   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
10985   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
10986   vec_free (node_name);
10987   vec_free (next_node_name);
10988
10989   S (mp);
10990   W (ret);
10991   return ret;
10992 }
10993
10994 static int
10995 api_add_node_next (vat_main_t * vam)
10996 {
10997   unformat_input_t *i = vam->input;
10998   vl_api_add_node_next_t *mp;
10999   u8 *name = 0;
11000   u8 *next = 0;
11001   int ret;
11002
11003   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11004     {
11005       if (unformat (i, "node %s", &name))
11006         ;
11007       else if (unformat (i, "next %s", &next))
11008         ;
11009       else
11010         break;
11011     }
11012   if (name == 0)
11013     {
11014       errmsg ("node name required");
11015       return -99;
11016     }
11017   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
11018     {
11019       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11020       return -99;
11021     }
11022   if (next == 0)
11023     {
11024       errmsg ("next node required");
11025       return -99;
11026     }
11027   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
11028     {
11029       errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
11030       return -99;
11031     }
11032
11033   M (ADD_NODE_NEXT, mp);
11034   clib_memcpy (mp->node_name, name, vec_len (name));
11035   clib_memcpy (mp->next_name, next, vec_len (next));
11036   vec_free (name);
11037   vec_free (next);
11038
11039   S (mp);
11040   W (ret);
11041   return ret;
11042 }
11043
11044 static int
11045 api_l2tpv3_create_tunnel (vat_main_t * vam)
11046 {
11047   unformat_input_t *i = vam->input;
11048   ip6_address_t client_address, our_address;
11049   int client_address_set = 0;
11050   int our_address_set = 0;
11051   u32 local_session_id = 0;
11052   u32 remote_session_id = 0;
11053   u64 local_cookie = 0;
11054   u64 remote_cookie = 0;
11055   u8 l2_sublayer_present = 0;
11056   vl_api_l2tpv3_create_tunnel_t *mp;
11057   int ret;
11058
11059   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11060     {
11061       if (unformat (i, "client_address %U", unformat_ip6_address,
11062                     &client_address))
11063         client_address_set = 1;
11064       else if (unformat (i, "our_address %U", unformat_ip6_address,
11065                          &our_address))
11066         our_address_set = 1;
11067       else if (unformat (i, "local_session_id %d", &local_session_id))
11068         ;
11069       else if (unformat (i, "remote_session_id %d", &remote_session_id))
11070         ;
11071       else if (unformat (i, "local_cookie %lld", &local_cookie))
11072         ;
11073       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
11074         ;
11075       else if (unformat (i, "l2-sublayer-present"))
11076         l2_sublayer_present = 1;
11077       else
11078         break;
11079     }
11080
11081   if (client_address_set == 0)
11082     {
11083       errmsg ("client_address required");
11084       return -99;
11085     }
11086
11087   if (our_address_set == 0)
11088     {
11089       errmsg ("our_address required");
11090       return -99;
11091     }
11092
11093   M (L2TPV3_CREATE_TUNNEL, mp);
11094
11095   clib_memcpy (mp->client_address.un.ip6, client_address.as_u8,
11096                sizeof (ip6_address_t));
11097
11098   clib_memcpy (mp->our_address.un.ip6, our_address.as_u8,
11099                sizeof (ip6_address_t));
11100
11101   mp->local_session_id = ntohl (local_session_id);
11102   mp->remote_session_id = ntohl (remote_session_id);
11103   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
11104   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
11105   mp->l2_sublayer_present = l2_sublayer_present;
11106
11107   S (mp);
11108   W (ret);
11109   return ret;
11110 }
11111
11112 static int
11113 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
11114 {
11115   unformat_input_t *i = vam->input;
11116   u32 sw_if_index;
11117   u8 sw_if_index_set = 0;
11118   u64 new_local_cookie = 0;
11119   u64 new_remote_cookie = 0;
11120   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
11121   int ret;
11122
11123   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11124     {
11125       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11126         sw_if_index_set = 1;
11127       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11128         sw_if_index_set = 1;
11129       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
11130         ;
11131       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
11132         ;
11133       else
11134         break;
11135     }
11136
11137   if (sw_if_index_set == 0)
11138     {
11139       errmsg ("missing interface name or sw_if_index");
11140       return -99;
11141     }
11142
11143   M (L2TPV3_SET_TUNNEL_COOKIES, mp);
11144
11145   mp->sw_if_index = ntohl (sw_if_index);
11146   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
11147   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
11148
11149   S (mp);
11150   W (ret);
11151   return ret;
11152 }
11153
11154 static int
11155 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
11156 {
11157   unformat_input_t *i = vam->input;
11158   vl_api_l2tpv3_interface_enable_disable_t *mp;
11159   u32 sw_if_index;
11160   u8 sw_if_index_set = 0;
11161   u8 enable_disable = 1;
11162   int ret;
11163
11164   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11165     {
11166       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11167         sw_if_index_set = 1;
11168       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11169         sw_if_index_set = 1;
11170       else if (unformat (i, "enable"))
11171         enable_disable = 1;
11172       else if (unformat (i, "disable"))
11173         enable_disable = 0;
11174       else
11175         break;
11176     }
11177
11178   if (sw_if_index_set == 0)
11179     {
11180       errmsg ("missing interface name or sw_if_index");
11181       return -99;
11182     }
11183
11184   M (L2TPV3_INTERFACE_ENABLE_DISABLE, mp);
11185
11186   mp->sw_if_index = ntohl (sw_if_index);
11187   mp->enable_disable = enable_disable;
11188
11189   S (mp);
11190   W (ret);
11191   return ret;
11192 }
11193
11194 static int
11195 api_l2tpv3_set_lookup_key (vat_main_t * vam)
11196 {
11197   unformat_input_t *i = vam->input;
11198   vl_api_l2tpv3_set_lookup_key_t *mp;
11199   u8 key = ~0;
11200   int ret;
11201
11202   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11203     {
11204       if (unformat (i, "lookup_v6_src"))
11205         key = L2T_LOOKUP_SRC_ADDRESS;
11206       else if (unformat (i, "lookup_v6_dst"))
11207         key = L2T_LOOKUP_DST_ADDRESS;
11208       else if (unformat (i, "lookup_session_id"))
11209         key = L2T_LOOKUP_SESSION_ID;
11210       else
11211         break;
11212     }
11213
11214   if (key == (u8) ~ 0)
11215     {
11216       errmsg ("l2tp session lookup key unset");
11217       return -99;
11218     }
11219
11220   M (L2TPV3_SET_LOOKUP_KEY, mp);
11221
11222   mp->key = key;
11223
11224   S (mp);
11225   W (ret);
11226   return ret;
11227 }
11228
11229 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
11230   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
11231 {
11232   vat_main_t *vam = &vat_main;
11233
11234   print (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)",
11235          format_ip6_address, mp->our_address,
11236          format_ip6_address, mp->client_address,
11237          clib_net_to_host_u32 (mp->sw_if_index));
11238
11239   print (vam->ofp,
11240          "   local cookies %016llx %016llx remote cookie %016llx",
11241          clib_net_to_host_u64 (mp->local_cookie[0]),
11242          clib_net_to_host_u64 (mp->local_cookie[1]),
11243          clib_net_to_host_u64 (mp->remote_cookie));
11244
11245   print (vam->ofp, "   local session-id %d remote session-id %d",
11246          clib_net_to_host_u32 (mp->local_session_id),
11247          clib_net_to_host_u32 (mp->remote_session_id));
11248
11249   print (vam->ofp, "   l2 specific sublayer %s\n",
11250          mp->l2_sublayer_present ? "preset" : "absent");
11251
11252 }
11253
11254 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
11255   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
11256 {
11257   vat_main_t *vam = &vat_main;
11258   vat_json_node_t *node = NULL;
11259   struct in6_addr addr;
11260
11261   if (VAT_JSON_ARRAY != vam->json_tree.type)
11262     {
11263       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11264       vat_json_init_array (&vam->json_tree);
11265     }
11266   node = vat_json_array_add (&vam->json_tree);
11267
11268   vat_json_init_object (node);
11269
11270   clib_memcpy (&addr, mp->our_address.un.ip6, sizeof (addr));
11271   vat_json_object_add_ip6 (node, "our_address", addr);
11272   clib_memcpy (&addr, mp->client_address.un.ip6, sizeof (addr));
11273   vat_json_object_add_ip6 (node, "client_address", addr);
11274
11275   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
11276   vat_json_init_array (lc);
11277   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
11278   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
11279   vat_json_object_add_uint (node, "remote_cookie",
11280                             clib_net_to_host_u64 (mp->remote_cookie));
11281
11282   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
11283   vat_json_object_add_uint (node, "local_session_id",
11284                             clib_net_to_host_u32 (mp->local_session_id));
11285   vat_json_object_add_uint (node, "remote_session_id",
11286                             clib_net_to_host_u32 (mp->remote_session_id));
11287   vat_json_object_add_string_copy (node, "l2_sublayer",
11288                                    mp->l2_sublayer_present ? (u8 *) "present"
11289                                    : (u8 *) "absent");
11290 }
11291
11292 static int
11293 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
11294 {
11295   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
11296   vl_api_control_ping_t *mp_ping;
11297   int ret;
11298
11299   /* Get list of l2tpv3-tunnel interfaces */
11300   M (SW_IF_L2TPV3_TUNNEL_DUMP, mp);
11301   S (mp);
11302
11303   /* Use a control ping for synchronization */
11304   MPING (CONTROL_PING, mp_ping);
11305   S (mp_ping);
11306
11307   W (ret);
11308   return ret;
11309 }
11310
11311
11312 static void vl_api_sw_interface_tap_v2_details_t_handler
11313   (vl_api_sw_interface_tap_v2_details_t * mp)
11314 {
11315   vat_main_t *vam = &vat_main;
11316
11317   u8 *ip4 =
11318     format (0, "%U/%d", format_ip4_address, mp->host_ip4_prefix.address,
11319             mp->host_ip4_prefix.len);
11320   u8 *ip6 =
11321     format (0, "%U/%d", format_ip6_address, mp->host_ip6_prefix.address,
11322             mp->host_ip6_prefix.len);
11323
11324   print (vam->ofp,
11325          "\n%-16s %-12d %-5d %-12d %-12d %-14U %-30s %-20s %-20s %-30s 0x%-08x",
11326          mp->dev_name, ntohl (mp->sw_if_index), ntohl (mp->id),
11327          ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
11328          format_ethernet_address, mp->host_mac_addr, mp->host_namespace,
11329          mp->host_bridge, ip4, ip6, ntohl (mp->tap_flags));
11330
11331   vec_free (ip4);
11332   vec_free (ip6);
11333 }
11334
11335 static void vl_api_sw_interface_tap_v2_details_t_handler_json
11336   (vl_api_sw_interface_tap_v2_details_t * mp)
11337 {
11338   vat_main_t *vam = &vat_main;
11339   vat_json_node_t *node = NULL;
11340
11341   if (VAT_JSON_ARRAY != vam->json_tree.type)
11342     {
11343       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11344       vat_json_init_array (&vam->json_tree);
11345     }
11346   node = vat_json_array_add (&vam->json_tree);
11347
11348   vat_json_init_object (node);
11349   vat_json_object_add_uint (node, "id", ntohl (mp->id));
11350   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11351   vat_json_object_add_uint (node, "tap_flags", ntohl (mp->tap_flags));
11352   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
11353   vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
11354   vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
11355   vat_json_object_add_string_copy (node, "host_mac_addr",
11356                                    format (0, "%U", format_ethernet_address,
11357                                            &mp->host_mac_addr));
11358   vat_json_object_add_string_copy (node, "host_namespace",
11359                                    mp->host_namespace);
11360   vat_json_object_add_string_copy (node, "host_bridge", mp->host_bridge);
11361   vat_json_object_add_string_copy (node, "host_ip4_addr",
11362                                    format (0, "%U/%d", format_ip4_address,
11363                                            mp->host_ip4_prefix.address,
11364                                            mp->host_ip4_prefix.len));
11365   vat_json_object_add_string_copy (node, "host_ip6_prefix",
11366                                    format (0, "%U/%d", format_ip6_address,
11367                                            mp->host_ip6_prefix.address,
11368                                            mp->host_ip6_prefix.len));
11369
11370 }
11371
11372 static int
11373 api_sw_interface_tap_v2_dump (vat_main_t * vam)
11374 {
11375   vl_api_sw_interface_tap_v2_dump_t *mp;
11376   vl_api_control_ping_t *mp_ping;
11377   int ret;
11378
11379   print (vam->ofp,
11380          "\n%-16s %-12s %-5s %-12s %-12s %-14s %-30s %-20s %-20s %-30s",
11381          "dev_name", "sw_if_index", "id", "rx_ring_sz", "tx_ring_sz",
11382          "host_mac_addr", "host_namespace", "host_bridge", "host_ip4_addr",
11383          "host_ip6_addr");
11384
11385   /* Get list of tap interfaces */
11386   M (SW_INTERFACE_TAP_V2_DUMP, mp);
11387   S (mp);
11388
11389   /* Use a control ping for synchronization */
11390   MPING (CONTROL_PING, mp_ping);
11391   S (mp_ping);
11392
11393   W (ret);
11394   return ret;
11395 }
11396
11397 static void vl_api_sw_interface_virtio_pci_details_t_handler
11398   (vl_api_sw_interface_virtio_pci_details_t * mp)
11399 {
11400   vat_main_t *vam = &vat_main;
11401
11402   typedef union
11403   {
11404     struct
11405     {
11406       u16 domain;
11407       u8 bus;
11408       u8 slot:5;
11409       u8 function:3;
11410     };
11411     u32 as_u32;
11412   } pci_addr_t;
11413   pci_addr_t addr;
11414
11415   addr.domain = ntohs (mp->pci_addr.domain);
11416   addr.bus = mp->pci_addr.bus;
11417   addr.slot = mp->pci_addr.slot;
11418   addr.function = mp->pci_addr.function;
11419
11420   u8 *pci_addr = format (0, "%04x:%02x:%02x.%x", addr.domain, addr.bus,
11421                          addr.slot, addr.function);
11422
11423   print (vam->ofp,
11424          "\n%-12s %-12d %-12d %-12d %-17U 0x%-08llx",
11425          pci_addr, ntohl (mp->sw_if_index),
11426          ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
11427          format_ethernet_address, mp->mac_addr,
11428          clib_net_to_host_u64 (mp->features));
11429   vec_free (pci_addr);
11430 }
11431
11432 static void vl_api_sw_interface_virtio_pci_details_t_handler_json
11433   (vl_api_sw_interface_virtio_pci_details_t * mp)
11434 {
11435   vat_main_t *vam = &vat_main;
11436   vat_json_node_t *node = NULL;
11437   vlib_pci_addr_t pci_addr;
11438
11439   if (VAT_JSON_ARRAY != vam->json_tree.type)
11440     {
11441       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11442       vat_json_init_array (&vam->json_tree);
11443     }
11444   node = vat_json_array_add (&vam->json_tree);
11445
11446   pci_addr.domain = ntohs (mp->pci_addr.domain);
11447   pci_addr.bus = mp->pci_addr.bus;
11448   pci_addr.slot = mp->pci_addr.slot;
11449   pci_addr.function = mp->pci_addr.function;
11450
11451   vat_json_init_object (node);
11452   vat_json_object_add_uint (node, "pci-addr", pci_addr.as_u32);
11453   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11454   vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
11455   vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
11456   vat_json_object_add_uint (node, "features",
11457                             clib_net_to_host_u64 (mp->features));
11458   vat_json_object_add_string_copy (node, "mac_addr",
11459                                    format (0, "%U", format_ethernet_address,
11460                                            &mp->mac_addr));
11461 }
11462
11463 static int
11464 api_sw_interface_virtio_pci_dump (vat_main_t * vam)
11465 {
11466   vl_api_sw_interface_virtio_pci_dump_t *mp;
11467   vl_api_control_ping_t *mp_ping;
11468   int ret;
11469
11470   print (vam->ofp,
11471          "\n%-12s %-12s %-12s %-12s %-17s %-08s",
11472          "pci_addr", "sw_if_index", "rx_ring_sz", "tx_ring_sz",
11473          "mac_addr", "features");
11474
11475   /* Get list of tap interfaces */
11476   M (SW_INTERFACE_VIRTIO_PCI_DUMP, mp);
11477   S (mp);
11478
11479   /* Use a control ping for synchronization */
11480   MPING (CONTROL_PING, mp_ping);
11481   S (mp_ping);
11482
11483   W (ret);
11484   return ret;
11485 }
11486
11487 static int
11488 api_vxlan_offload_rx (vat_main_t * vam)
11489 {
11490   unformat_input_t *line_input = vam->input;
11491   vl_api_vxlan_offload_rx_t *mp;
11492   u32 hw_if_index = ~0, rx_if_index = ~0;
11493   u8 is_add = 1;
11494   int ret;
11495
11496   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11497     {
11498       if (unformat (line_input, "del"))
11499         is_add = 0;
11500       else if (unformat (line_input, "hw %U", api_unformat_hw_if_index, vam,
11501                          &hw_if_index))
11502         ;
11503       else if (unformat (line_input, "hw hw_if_index %u", &hw_if_index))
11504         ;
11505       else if (unformat (line_input, "rx %U", api_unformat_sw_if_index, vam,
11506                          &rx_if_index))
11507         ;
11508       else if (unformat (line_input, "rx sw_if_index %u", &rx_if_index))
11509         ;
11510       else
11511         {
11512           errmsg ("parse error '%U'", format_unformat_error, line_input);
11513           return -99;
11514         }
11515     }
11516
11517   if (hw_if_index == ~0)
11518     {
11519       errmsg ("no hw interface");
11520       return -99;
11521     }
11522
11523   if (rx_if_index == ~0)
11524     {
11525       errmsg ("no rx tunnel");
11526       return -99;
11527     }
11528
11529   M (VXLAN_OFFLOAD_RX, mp);
11530
11531   mp->hw_if_index = ntohl (hw_if_index);
11532   mp->sw_if_index = ntohl (rx_if_index);
11533   mp->enable = is_add;
11534
11535   S (mp);
11536   W (ret);
11537   return ret;
11538 }
11539
11540 static uword unformat_vxlan_decap_next
11541   (unformat_input_t * input, va_list * args)
11542 {
11543   u32 *result = va_arg (*args, u32 *);
11544   u32 tmp;
11545
11546   if (unformat (input, "l2"))
11547     *result = VXLAN_INPUT_NEXT_L2_INPUT;
11548   else if (unformat (input, "%d", &tmp))
11549     *result = tmp;
11550   else
11551     return 0;
11552   return 1;
11553 }
11554
11555 static int
11556 api_vxlan_add_del_tunnel (vat_main_t * vam)
11557 {
11558   unformat_input_t *line_input = vam->input;
11559   vl_api_vxlan_add_del_tunnel_t *mp;
11560   ip46_address_t src, dst;
11561   u8 is_add = 1;
11562   u8 ipv4_set = 0, ipv6_set = 0;
11563   u8 src_set = 0;
11564   u8 dst_set = 0;
11565   u8 grp_set = 0;
11566   u32 instance = ~0;
11567   u32 mcast_sw_if_index = ~0;
11568   u32 encap_vrf_id = 0;
11569   u32 decap_next_index = ~0;
11570   u32 vni = 0;
11571   int ret;
11572
11573   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
11574   clib_memset (&src, 0, sizeof src);
11575   clib_memset (&dst, 0, sizeof dst);
11576
11577   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11578     {
11579       if (unformat (line_input, "del"))
11580         is_add = 0;
11581       else if (unformat (line_input, "instance %d", &instance))
11582         ;
11583       else
11584         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
11585         {
11586           ipv4_set = 1;
11587           src_set = 1;
11588         }
11589       else
11590         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
11591         {
11592           ipv4_set = 1;
11593           dst_set = 1;
11594         }
11595       else
11596         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
11597         {
11598           ipv6_set = 1;
11599           src_set = 1;
11600         }
11601       else
11602         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
11603         {
11604           ipv6_set = 1;
11605           dst_set = 1;
11606         }
11607       else if (unformat (line_input, "group %U %U",
11608                          unformat_ip4_address, &dst.ip4,
11609                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
11610         {
11611           grp_set = dst_set = 1;
11612           ipv4_set = 1;
11613         }
11614       else if (unformat (line_input, "group %U",
11615                          unformat_ip4_address, &dst.ip4))
11616         {
11617           grp_set = dst_set = 1;
11618           ipv4_set = 1;
11619         }
11620       else if (unformat (line_input, "group %U %U",
11621                          unformat_ip6_address, &dst.ip6,
11622                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
11623         {
11624           grp_set = dst_set = 1;
11625           ipv6_set = 1;
11626         }
11627       else if (unformat (line_input, "group %U",
11628                          unformat_ip6_address, &dst.ip6))
11629         {
11630           grp_set = dst_set = 1;
11631           ipv6_set = 1;
11632         }
11633       else
11634         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
11635         ;
11636       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
11637         ;
11638       else if (unformat (line_input, "decap-next %U",
11639                          unformat_vxlan_decap_next, &decap_next_index))
11640         ;
11641       else if (unformat (line_input, "vni %d", &vni))
11642         ;
11643       else
11644         {
11645           errmsg ("parse error '%U'", format_unformat_error, line_input);
11646           return -99;
11647         }
11648     }
11649
11650   if (src_set == 0)
11651     {
11652       errmsg ("tunnel src address not specified");
11653       return -99;
11654     }
11655   if (dst_set == 0)
11656     {
11657       errmsg ("tunnel dst address not specified");
11658       return -99;
11659     }
11660
11661   if (grp_set && !ip46_address_is_multicast (&dst))
11662     {
11663       errmsg ("tunnel group address not multicast");
11664       return -99;
11665     }
11666   if (grp_set && mcast_sw_if_index == ~0)
11667     {
11668       errmsg ("tunnel nonexistent multicast device");
11669       return -99;
11670     }
11671   if (grp_set == 0 && ip46_address_is_multicast (&dst))
11672     {
11673       errmsg ("tunnel dst address must be unicast");
11674       return -99;
11675     }
11676
11677
11678   if (ipv4_set && ipv6_set)
11679     {
11680       errmsg ("both IPv4 and IPv6 addresses specified");
11681       return -99;
11682     }
11683
11684   if ((vni == 0) || (vni >> 24))
11685     {
11686       errmsg ("vni not specified or out of range");
11687       return -99;
11688     }
11689
11690   M (VXLAN_ADD_DEL_TUNNEL, mp);
11691
11692   if (ipv6_set)
11693     {
11694       clib_memcpy (mp->src_address, &src.ip6, sizeof (src.ip6));
11695       clib_memcpy (mp->dst_address, &dst.ip6, sizeof (dst.ip6));
11696     }
11697   else
11698     {
11699       clib_memcpy (mp->src_address, &src.ip4, sizeof (src.ip4));
11700       clib_memcpy (mp->dst_address, &dst.ip4, sizeof (dst.ip4));
11701     }
11702
11703   mp->instance = htonl (instance);
11704   mp->encap_vrf_id = ntohl (encap_vrf_id);
11705   mp->decap_next_index = ntohl (decap_next_index);
11706   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
11707   mp->vni = ntohl (vni);
11708   mp->is_add = is_add;
11709   mp->is_ipv6 = ipv6_set;
11710
11711   S (mp);
11712   W (ret);
11713   return ret;
11714 }
11715
11716 static void vl_api_vxlan_tunnel_details_t_handler
11717   (vl_api_vxlan_tunnel_details_t * mp)
11718 {
11719   vat_main_t *vam = &vat_main;
11720   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
11721   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
11722
11723   print (vam->ofp, "%11d%11d%24U%24U%14d%18d%13d%19d",
11724          ntohl (mp->sw_if_index),
11725          ntohl (mp->instance),
11726          format_ip46_address, &src, IP46_TYPE_ANY,
11727          format_ip46_address, &dst, IP46_TYPE_ANY,
11728          ntohl (mp->encap_vrf_id),
11729          ntohl (mp->decap_next_index), ntohl (mp->vni),
11730          ntohl (mp->mcast_sw_if_index));
11731 }
11732
11733 static void vl_api_vxlan_tunnel_details_t_handler_json
11734   (vl_api_vxlan_tunnel_details_t * mp)
11735 {
11736   vat_main_t *vam = &vat_main;
11737   vat_json_node_t *node = NULL;
11738
11739   if (VAT_JSON_ARRAY != vam->json_tree.type)
11740     {
11741       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11742       vat_json_init_array (&vam->json_tree);
11743     }
11744   node = vat_json_array_add (&vam->json_tree);
11745
11746   vat_json_init_object (node);
11747   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11748
11749   vat_json_object_add_uint (node, "instance", ntohl (mp->instance));
11750
11751   if (mp->is_ipv6)
11752     {
11753       struct in6_addr ip6;
11754
11755       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
11756       vat_json_object_add_ip6 (node, "src_address", ip6);
11757       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
11758       vat_json_object_add_ip6 (node, "dst_address", ip6);
11759     }
11760   else
11761     {
11762       struct in_addr ip4;
11763
11764       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
11765       vat_json_object_add_ip4 (node, "src_address", ip4);
11766       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
11767       vat_json_object_add_ip4 (node, "dst_address", ip4);
11768     }
11769   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
11770   vat_json_object_add_uint (node, "decap_next_index",
11771                             ntohl (mp->decap_next_index));
11772   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
11773   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
11774   vat_json_object_add_uint (node, "mcast_sw_if_index",
11775                             ntohl (mp->mcast_sw_if_index));
11776 }
11777
11778 static int
11779 api_vxlan_tunnel_dump (vat_main_t * vam)
11780 {
11781   unformat_input_t *i = vam->input;
11782   vl_api_vxlan_tunnel_dump_t *mp;
11783   vl_api_control_ping_t *mp_ping;
11784   u32 sw_if_index;
11785   u8 sw_if_index_set = 0;
11786   int ret;
11787
11788   /* Parse args required to build the message */
11789   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11790     {
11791       if (unformat (i, "sw_if_index %d", &sw_if_index))
11792         sw_if_index_set = 1;
11793       else
11794         break;
11795     }
11796
11797   if (sw_if_index_set == 0)
11798     {
11799       sw_if_index = ~0;
11800     }
11801
11802   if (!vam->json_output)
11803     {
11804       print (vam->ofp, "%11s%11s%24s%24s%14s%18s%13s%19s",
11805              "sw_if_index", "instance", "src_address", "dst_address",
11806              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
11807     }
11808
11809   /* Get list of vxlan-tunnel interfaces */
11810   M (VXLAN_TUNNEL_DUMP, mp);
11811
11812   mp->sw_if_index = htonl (sw_if_index);
11813
11814   S (mp);
11815
11816   /* Use a control ping for synchronization */
11817   MPING (CONTROL_PING, mp_ping);
11818   S (mp_ping);
11819
11820   W (ret);
11821   return ret;
11822 }
11823
11824 static uword unformat_geneve_decap_next
11825   (unformat_input_t * input, va_list * args)
11826 {
11827   u32 *result = va_arg (*args, u32 *);
11828   u32 tmp;
11829
11830   if (unformat (input, "l2"))
11831     *result = GENEVE_INPUT_NEXT_L2_INPUT;
11832   else if (unformat (input, "%d", &tmp))
11833     *result = tmp;
11834   else
11835     return 0;
11836   return 1;
11837 }
11838
11839 static int
11840 api_geneve_add_del_tunnel (vat_main_t * vam)
11841 {
11842   unformat_input_t *line_input = vam->input;
11843   vl_api_geneve_add_del_tunnel_t *mp;
11844   ip46_address_t src, dst;
11845   u8 is_add = 1;
11846   u8 ipv4_set = 0, ipv6_set = 0;
11847   u8 src_set = 0;
11848   u8 dst_set = 0;
11849   u8 grp_set = 0;
11850   u32 mcast_sw_if_index = ~0;
11851   u32 encap_vrf_id = 0;
11852   u32 decap_next_index = ~0;
11853   u32 vni = 0;
11854   int ret;
11855
11856   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
11857   clib_memset (&src, 0, sizeof src);
11858   clib_memset (&dst, 0, sizeof dst);
11859
11860   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11861     {
11862       if (unformat (line_input, "del"))
11863         is_add = 0;
11864       else
11865         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
11866         {
11867           ipv4_set = 1;
11868           src_set = 1;
11869         }
11870       else
11871         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
11872         {
11873           ipv4_set = 1;
11874           dst_set = 1;
11875         }
11876       else
11877         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
11878         {
11879           ipv6_set = 1;
11880           src_set = 1;
11881         }
11882       else
11883         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
11884         {
11885           ipv6_set = 1;
11886           dst_set = 1;
11887         }
11888       else if (unformat (line_input, "group %U %U",
11889                          unformat_ip4_address, &dst.ip4,
11890                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
11891         {
11892           grp_set = dst_set = 1;
11893           ipv4_set = 1;
11894         }
11895       else if (unformat (line_input, "group %U",
11896                          unformat_ip4_address, &dst.ip4))
11897         {
11898           grp_set = dst_set = 1;
11899           ipv4_set = 1;
11900         }
11901       else if (unformat (line_input, "group %U %U",
11902                          unformat_ip6_address, &dst.ip6,
11903                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
11904         {
11905           grp_set = dst_set = 1;
11906           ipv6_set = 1;
11907         }
11908       else if (unformat (line_input, "group %U",
11909                          unformat_ip6_address, &dst.ip6))
11910         {
11911           grp_set = dst_set = 1;
11912           ipv6_set = 1;
11913         }
11914       else
11915         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
11916         ;
11917       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
11918         ;
11919       else if (unformat (line_input, "decap-next %U",
11920                          unformat_geneve_decap_next, &decap_next_index))
11921         ;
11922       else if (unformat (line_input, "vni %d", &vni))
11923         ;
11924       else
11925         {
11926           errmsg ("parse error '%U'", format_unformat_error, line_input);
11927           return -99;
11928         }
11929     }
11930
11931   if (src_set == 0)
11932     {
11933       errmsg ("tunnel src address not specified");
11934       return -99;
11935     }
11936   if (dst_set == 0)
11937     {
11938       errmsg ("tunnel dst address not specified");
11939       return -99;
11940     }
11941
11942   if (grp_set && !ip46_address_is_multicast (&dst))
11943     {
11944       errmsg ("tunnel group address not multicast");
11945       return -99;
11946     }
11947   if (grp_set && mcast_sw_if_index == ~0)
11948     {
11949       errmsg ("tunnel nonexistent multicast device");
11950       return -99;
11951     }
11952   if (grp_set == 0 && ip46_address_is_multicast (&dst))
11953     {
11954       errmsg ("tunnel dst address must be unicast");
11955       return -99;
11956     }
11957
11958
11959   if (ipv4_set && ipv6_set)
11960     {
11961       errmsg ("both IPv4 and IPv6 addresses specified");
11962       return -99;
11963     }
11964
11965   if ((vni == 0) || (vni >> 24))
11966     {
11967       errmsg ("vni not specified or out of range");
11968       return -99;
11969     }
11970
11971   M (GENEVE_ADD_DEL_TUNNEL, mp);
11972
11973   if (ipv6_set)
11974     {
11975       clib_memcpy (&mp->local_address.un.ip6, &src.ip6, sizeof (src.ip6));
11976       clib_memcpy (&mp->remote_address.un.ip6, &dst.ip6, sizeof (dst.ip6));
11977     }
11978   else
11979     {
11980       clib_memcpy (&mp->local_address.un.ip4, &src.ip4, sizeof (src.ip4));
11981       clib_memcpy (&mp->remote_address.un.ip4, &dst.ip4, sizeof (dst.ip4));
11982     }
11983   mp->encap_vrf_id = ntohl (encap_vrf_id);
11984   mp->decap_next_index = ntohl (decap_next_index);
11985   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
11986   mp->vni = ntohl (vni);
11987   mp->is_add = is_add;
11988
11989   S (mp);
11990   W (ret);
11991   return ret;
11992 }
11993
11994 static void vl_api_geneve_tunnel_details_t_handler
11995   (vl_api_geneve_tunnel_details_t * mp)
11996 {
11997   vat_main_t *vam = &vat_main;
11998   ip46_address_t src = {.as_u64[0] = 0,.as_u64[1] = 0 };
11999   ip46_address_t dst = {.as_u64[0] = 0,.as_u64[1] = 0 };
12000
12001   if (mp->src_address.af == ADDRESS_IP6)
12002     {
12003       clib_memcpy (&src.ip6, &mp->src_address.un.ip6, sizeof (ip6_address_t));
12004       clib_memcpy (&dst.ip6, &mp->dst_address.un.ip6, sizeof (ip6_address_t));
12005     }
12006   else
12007     {
12008       clib_memcpy (&src.ip4, &mp->src_address.un.ip4, sizeof (ip4_address_t));
12009       clib_memcpy (&dst.ip4, &mp->dst_address.un.ip4, sizeof (ip4_address_t));
12010     }
12011
12012   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
12013          ntohl (mp->sw_if_index),
12014          format_ip46_address, &src, IP46_TYPE_ANY,
12015          format_ip46_address, &dst, IP46_TYPE_ANY,
12016          ntohl (mp->encap_vrf_id),
12017          ntohl (mp->decap_next_index), ntohl (mp->vni),
12018          ntohl (mp->mcast_sw_if_index));
12019 }
12020
12021 static void vl_api_geneve_tunnel_details_t_handler_json
12022   (vl_api_geneve_tunnel_details_t * mp)
12023 {
12024   vat_main_t *vam = &vat_main;
12025   vat_json_node_t *node = NULL;
12026   bool is_ipv6;
12027
12028   if (VAT_JSON_ARRAY != vam->json_tree.type)
12029     {
12030       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12031       vat_json_init_array (&vam->json_tree);
12032     }
12033   node = vat_json_array_add (&vam->json_tree);
12034
12035   vat_json_init_object (node);
12036   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12037   is_ipv6 = mp->src_address.af == ADDRESS_IP6;
12038   if (is_ipv6)
12039     {
12040       struct in6_addr ip6;
12041
12042       clib_memcpy (&ip6, &mp->src_address.un.ip6, sizeof (ip6));
12043       vat_json_object_add_ip6 (node, "src_address", ip6);
12044       clib_memcpy (&ip6, &mp->dst_address.un.ip6, sizeof (ip6));
12045       vat_json_object_add_ip6 (node, "dst_address", ip6);
12046     }
12047   else
12048     {
12049       struct in_addr ip4;
12050
12051       clib_memcpy (&ip4, &mp->src_address.un.ip4, sizeof (ip4));
12052       vat_json_object_add_ip4 (node, "src_address", ip4);
12053       clib_memcpy (&ip4, &mp->dst_address.un.ip4, sizeof (ip4));
12054       vat_json_object_add_ip4 (node, "dst_address", ip4);
12055     }
12056   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
12057   vat_json_object_add_uint (node, "decap_next_index",
12058                             ntohl (mp->decap_next_index));
12059   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
12060   vat_json_object_add_uint (node, "mcast_sw_if_index",
12061                             ntohl (mp->mcast_sw_if_index));
12062 }
12063
12064 static int
12065 api_geneve_tunnel_dump (vat_main_t * vam)
12066 {
12067   unformat_input_t *i = vam->input;
12068   vl_api_geneve_tunnel_dump_t *mp;
12069   vl_api_control_ping_t *mp_ping;
12070   u32 sw_if_index;
12071   u8 sw_if_index_set = 0;
12072   int ret;
12073
12074   /* Parse args required to build the message */
12075   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12076     {
12077       if (unformat (i, "sw_if_index %d", &sw_if_index))
12078         sw_if_index_set = 1;
12079       else
12080         break;
12081     }
12082
12083   if (sw_if_index_set == 0)
12084     {
12085       sw_if_index = ~0;
12086     }
12087
12088   if (!vam->json_output)
12089     {
12090       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
12091              "sw_if_index", "local_address", "remote_address",
12092              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
12093     }
12094
12095   /* Get list of geneve-tunnel interfaces */
12096   M (GENEVE_TUNNEL_DUMP, mp);
12097
12098   mp->sw_if_index = htonl (sw_if_index);
12099
12100   S (mp);
12101
12102   /* Use a control ping for synchronization */
12103   M (CONTROL_PING, mp_ping);
12104   S (mp_ping);
12105
12106   W (ret);
12107   return ret;
12108 }
12109
12110 static int
12111 api_gre_tunnel_add_del (vat_main_t * vam)
12112 {
12113   unformat_input_t *line_input = vam->input;
12114   vl_api_address_t src = { }, dst =
12115   {
12116   };
12117   vl_api_gre_tunnel_add_del_t *mp;
12118   vl_api_gre_tunnel_type_t t_type;
12119   u8 is_add = 1;
12120   u8 src_set = 0;
12121   u8 dst_set = 0;
12122   u32 outer_table_id = 0;
12123   u32 session_id = 0;
12124   u32 instance = ~0;
12125   int ret;
12126
12127   t_type = GRE_API_TUNNEL_TYPE_L3;
12128
12129   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12130     {
12131       if (unformat (line_input, "del"))
12132         is_add = 0;
12133       else if (unformat (line_input, "instance %d", &instance))
12134         ;
12135       else if (unformat (line_input, "src %U", unformat_vl_api_address, &src))
12136         {
12137           src_set = 1;
12138         }
12139       else if (unformat (line_input, "dst %U", unformat_vl_api_address, &dst))
12140         {
12141           dst_set = 1;
12142         }
12143       else if (unformat (line_input, "outer-table-id %d", &outer_table_id))
12144         ;
12145       else if (unformat (line_input, "teb"))
12146         t_type = GRE_API_TUNNEL_TYPE_TEB;
12147       else if (unformat (line_input, "erspan %d", &session_id))
12148         t_type = GRE_API_TUNNEL_TYPE_ERSPAN;
12149       else
12150         {
12151           errmsg ("parse error '%U'", format_unformat_error, line_input);
12152           return -99;
12153         }
12154     }
12155
12156   if (src_set == 0)
12157     {
12158       errmsg ("tunnel src address not specified");
12159       return -99;
12160     }
12161   if (dst_set == 0)
12162     {
12163       errmsg ("tunnel dst address not specified");
12164       return -99;
12165     }
12166
12167   M (GRE_TUNNEL_ADD_DEL, mp);
12168
12169   clib_memcpy (&mp->tunnel.src, &src, sizeof (mp->tunnel.src));
12170   clib_memcpy (&mp->tunnel.dst, &dst, sizeof (mp->tunnel.dst));
12171
12172   mp->tunnel.instance = htonl (instance);
12173   mp->tunnel.outer_table_id = htonl (outer_table_id);
12174   mp->is_add = is_add;
12175   mp->tunnel.session_id = htons ((u16) session_id);
12176   mp->tunnel.type = htonl (t_type);
12177
12178   S (mp);
12179   W (ret);
12180   return ret;
12181 }
12182
12183 static void vl_api_gre_tunnel_details_t_handler
12184   (vl_api_gre_tunnel_details_t * mp)
12185 {
12186   vat_main_t *vam = &vat_main;
12187
12188   print (vam->ofp, "%11d%11d%24U%24U%13d%14d%12d",
12189          ntohl (mp->tunnel.sw_if_index),
12190          ntohl (mp->tunnel.instance),
12191          format_vl_api_address, &mp->tunnel.src,
12192          format_vl_api_address, &mp->tunnel.dst,
12193          mp->tunnel.type, ntohl (mp->tunnel.outer_table_id),
12194          ntohl (mp->tunnel.session_id));
12195 }
12196
12197 static void vl_api_gre_tunnel_details_t_handler_json
12198   (vl_api_gre_tunnel_details_t * mp)
12199 {
12200   vat_main_t *vam = &vat_main;
12201   vat_json_node_t *node = NULL;
12202
12203   if (VAT_JSON_ARRAY != vam->json_tree.type)
12204     {
12205       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12206       vat_json_init_array (&vam->json_tree);
12207     }
12208   node = vat_json_array_add (&vam->json_tree);
12209
12210   vat_json_init_object (node);
12211   vat_json_object_add_uint (node, "sw_if_index",
12212                             ntohl (mp->tunnel.sw_if_index));
12213   vat_json_object_add_uint (node, "instance", ntohl (mp->tunnel.instance));
12214
12215   vat_json_object_add_address (node, "src", &mp->tunnel.src);
12216   vat_json_object_add_address (node, "dst", &mp->tunnel.dst);
12217   vat_json_object_add_uint (node, "tunnel_type", mp->tunnel.type);
12218   vat_json_object_add_uint (node, "outer_table_id",
12219                             ntohl (mp->tunnel.outer_table_id));
12220   vat_json_object_add_uint (node, "session_id", mp->tunnel.session_id);
12221 }
12222
12223 static int
12224 api_gre_tunnel_dump (vat_main_t * vam)
12225 {
12226   unformat_input_t *i = vam->input;
12227   vl_api_gre_tunnel_dump_t *mp;
12228   vl_api_control_ping_t *mp_ping;
12229   u32 sw_if_index;
12230   u8 sw_if_index_set = 0;
12231   int ret;
12232
12233   /* Parse args required to build the message */
12234   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12235     {
12236       if (unformat (i, "sw_if_index %d", &sw_if_index))
12237         sw_if_index_set = 1;
12238       else
12239         break;
12240     }
12241
12242   if (sw_if_index_set == 0)
12243     {
12244       sw_if_index = ~0;
12245     }
12246
12247   if (!vam->json_output)
12248     {
12249       print (vam->ofp, "%11s%11s%24s%24s%13s%14s%12s",
12250              "sw_if_index", "instance", "src_address", "dst_address",
12251              "tunnel_type", "outer_fib_id", "session_id");
12252     }
12253
12254   /* Get list of gre-tunnel interfaces */
12255   M (GRE_TUNNEL_DUMP, mp);
12256
12257   mp->sw_if_index = htonl (sw_if_index);
12258
12259   S (mp);
12260
12261   /* Use a control ping for synchronization */
12262   MPING (CONTROL_PING, mp_ping);
12263   S (mp_ping);
12264
12265   W (ret);
12266   return ret;
12267 }
12268
12269 static int
12270 api_l2_fib_clear_table (vat_main_t * vam)
12271 {
12272 //  unformat_input_t * i = vam->input;
12273   vl_api_l2_fib_clear_table_t *mp;
12274   int ret;
12275
12276   M (L2_FIB_CLEAR_TABLE, mp);
12277
12278   S (mp);
12279   W (ret);
12280   return ret;
12281 }
12282
12283 static int
12284 api_l2_interface_efp_filter (vat_main_t * vam)
12285 {
12286   unformat_input_t *i = vam->input;
12287   vl_api_l2_interface_efp_filter_t *mp;
12288   u32 sw_if_index;
12289   u8 enable = 1;
12290   u8 sw_if_index_set = 0;
12291   int ret;
12292
12293   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12294     {
12295       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12296         sw_if_index_set = 1;
12297       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12298         sw_if_index_set = 1;
12299       else if (unformat (i, "enable"))
12300         enable = 1;
12301       else if (unformat (i, "disable"))
12302         enable = 0;
12303       else
12304         {
12305           clib_warning ("parse error '%U'", format_unformat_error, i);
12306           return -99;
12307         }
12308     }
12309
12310   if (sw_if_index_set == 0)
12311     {
12312       errmsg ("missing sw_if_index");
12313       return -99;
12314     }
12315
12316   M (L2_INTERFACE_EFP_FILTER, mp);
12317
12318   mp->sw_if_index = ntohl (sw_if_index);
12319   mp->enable_disable = enable;
12320
12321   S (mp);
12322   W (ret);
12323   return ret;
12324 }
12325
12326 #define foreach_vtr_op                          \
12327 _("disable",  L2_VTR_DISABLED)                  \
12328 _("push-1",  L2_VTR_PUSH_1)                     \
12329 _("push-2",  L2_VTR_PUSH_2)                     \
12330 _("pop-1",  L2_VTR_POP_1)                       \
12331 _("pop-2",  L2_VTR_POP_2)                       \
12332 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
12333 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
12334 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
12335 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
12336
12337 static int
12338 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
12339 {
12340   unformat_input_t *i = vam->input;
12341   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
12342   u32 sw_if_index;
12343   u8 sw_if_index_set = 0;
12344   u8 vtr_op_set = 0;
12345   u32 vtr_op = 0;
12346   u32 push_dot1q = 1;
12347   u32 tag1 = ~0;
12348   u32 tag2 = ~0;
12349   int ret;
12350
12351   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12352     {
12353       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12354         sw_if_index_set = 1;
12355       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12356         sw_if_index_set = 1;
12357       else if (unformat (i, "vtr_op %d", &vtr_op))
12358         vtr_op_set = 1;
12359 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
12360       foreach_vtr_op
12361 #undef _
12362         else if (unformat (i, "push_dot1q %d", &push_dot1q))
12363         ;
12364       else if (unformat (i, "tag1 %d", &tag1))
12365         ;
12366       else if (unformat (i, "tag2 %d", &tag2))
12367         ;
12368       else
12369         {
12370           clib_warning ("parse error '%U'", format_unformat_error, i);
12371           return -99;
12372         }
12373     }
12374
12375   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
12376     {
12377       errmsg ("missing vtr operation or sw_if_index");
12378       return -99;
12379     }
12380
12381   M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
12382   mp->sw_if_index = ntohl (sw_if_index);
12383   mp->vtr_op = ntohl (vtr_op);
12384   mp->push_dot1q = ntohl (push_dot1q);
12385   mp->tag1 = ntohl (tag1);
12386   mp->tag2 = ntohl (tag2);
12387
12388   S (mp);
12389   W (ret);
12390   return ret;
12391 }
12392
12393 static int
12394 api_create_vhost_user_if (vat_main_t * vam)
12395 {
12396   unformat_input_t *i = vam->input;
12397   vl_api_create_vhost_user_if_t *mp;
12398   u8 *file_name;
12399   u8 is_server = 0;
12400   u8 file_name_set = 0;
12401   u32 custom_dev_instance = ~0;
12402   u8 hwaddr[6];
12403   u8 use_custom_mac = 0;
12404   u8 disable_mrg_rxbuf = 0;
12405   u8 disable_indirect_desc = 0;
12406   u8 *tag = 0;
12407   u8 enable_gso = 0;
12408   int ret;
12409
12410   /* Shut up coverity */
12411   clib_memset (hwaddr, 0, sizeof (hwaddr));
12412
12413   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12414     {
12415       if (unformat (i, "socket %s", &file_name))
12416         {
12417           file_name_set = 1;
12418         }
12419       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
12420         ;
12421       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
12422         use_custom_mac = 1;
12423       else if (unformat (i, "server"))
12424         is_server = 1;
12425       else if (unformat (i, "disable_mrg_rxbuf"))
12426         disable_mrg_rxbuf = 1;
12427       else if (unformat (i, "disable_indirect_desc"))
12428         disable_indirect_desc = 1;
12429       else if (unformat (i, "gso"))
12430         enable_gso = 1;
12431       else if (unformat (i, "tag %s", &tag))
12432         ;
12433       else
12434         break;
12435     }
12436
12437   if (file_name_set == 0)
12438     {
12439       errmsg ("missing socket file name");
12440       return -99;
12441     }
12442
12443   if (vec_len (file_name) > 255)
12444     {
12445       errmsg ("socket file name too long");
12446       return -99;
12447     }
12448   vec_add1 (file_name, 0);
12449
12450   M (CREATE_VHOST_USER_IF, mp);
12451
12452   mp->is_server = is_server;
12453   mp->disable_mrg_rxbuf = disable_mrg_rxbuf;
12454   mp->disable_indirect_desc = disable_indirect_desc;
12455   mp->enable_gso = enable_gso;
12456   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
12457   vec_free (file_name);
12458   if (custom_dev_instance != ~0)
12459     {
12460       mp->renumber = 1;
12461       mp->custom_dev_instance = ntohl (custom_dev_instance);
12462     }
12463
12464   mp->use_custom_mac = use_custom_mac;
12465   clib_memcpy (mp->mac_address, hwaddr, 6);
12466   if (tag)
12467     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
12468   vec_free (tag);
12469
12470   S (mp);
12471   W (ret);
12472   return ret;
12473 }
12474
12475 static int
12476 api_modify_vhost_user_if (vat_main_t * vam)
12477 {
12478   unformat_input_t *i = vam->input;
12479   vl_api_modify_vhost_user_if_t *mp;
12480   u8 *file_name;
12481   u8 is_server = 0;
12482   u8 file_name_set = 0;
12483   u32 custom_dev_instance = ~0;
12484   u8 sw_if_index_set = 0;
12485   u32 sw_if_index = (u32) ~ 0;
12486   u8 enable_gso = 0;
12487   int ret;
12488
12489   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12490     {
12491       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12492         sw_if_index_set = 1;
12493       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12494         sw_if_index_set = 1;
12495       else if (unformat (i, "socket %s", &file_name))
12496         {
12497           file_name_set = 1;
12498         }
12499       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
12500         ;
12501       else if (unformat (i, "server"))
12502         is_server = 1;
12503       else if (unformat (i, "gso"))
12504         enable_gso = 1;
12505       else
12506         break;
12507     }
12508
12509   if (sw_if_index_set == 0)
12510     {
12511       errmsg ("missing sw_if_index or interface name");
12512       return -99;
12513     }
12514
12515   if (file_name_set == 0)
12516     {
12517       errmsg ("missing socket file name");
12518       return -99;
12519     }
12520
12521   if (vec_len (file_name) > 255)
12522     {
12523       errmsg ("socket file name too long");
12524       return -99;
12525     }
12526   vec_add1 (file_name, 0);
12527
12528   M (MODIFY_VHOST_USER_IF, mp);
12529
12530   mp->sw_if_index = ntohl (sw_if_index);
12531   mp->is_server = is_server;
12532   mp->enable_gso = enable_gso;
12533   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
12534   vec_free (file_name);
12535   if (custom_dev_instance != ~0)
12536     {
12537       mp->renumber = 1;
12538       mp->custom_dev_instance = ntohl (custom_dev_instance);
12539     }
12540
12541   S (mp);
12542   W (ret);
12543   return ret;
12544 }
12545
12546 static int
12547 api_delete_vhost_user_if (vat_main_t * vam)
12548 {
12549   unformat_input_t *i = vam->input;
12550   vl_api_delete_vhost_user_if_t *mp;
12551   u32 sw_if_index = ~0;
12552   u8 sw_if_index_set = 0;
12553   int ret;
12554
12555   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12556     {
12557       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12558         sw_if_index_set = 1;
12559       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12560         sw_if_index_set = 1;
12561       else
12562         break;
12563     }
12564
12565   if (sw_if_index_set == 0)
12566     {
12567       errmsg ("missing sw_if_index or interface name");
12568       return -99;
12569     }
12570
12571
12572   M (DELETE_VHOST_USER_IF, mp);
12573
12574   mp->sw_if_index = ntohl (sw_if_index);
12575
12576   S (mp);
12577   W (ret);
12578   return ret;
12579 }
12580
12581 static void vl_api_sw_interface_vhost_user_details_t_handler
12582   (vl_api_sw_interface_vhost_user_details_t * mp)
12583 {
12584   vat_main_t *vam = &vat_main;
12585   u64 features;
12586
12587   features =
12588     clib_net_to_host_u32 (mp->features_first_32) | ((u64)
12589                                                     clib_net_to_host_u32
12590                                                     (mp->features_last_32) <<
12591                                                     32);
12592
12593   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s",
12594          (char *) mp->interface_name,
12595          ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
12596          features, mp->is_server,
12597          ntohl (mp->num_regions), (char *) mp->sock_filename);
12598   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
12599 }
12600
12601 static void vl_api_sw_interface_vhost_user_details_t_handler_json
12602   (vl_api_sw_interface_vhost_user_details_t * mp)
12603 {
12604   vat_main_t *vam = &vat_main;
12605   vat_json_node_t *node = NULL;
12606
12607   if (VAT_JSON_ARRAY != vam->json_tree.type)
12608     {
12609       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12610       vat_json_init_array (&vam->json_tree);
12611     }
12612   node = vat_json_array_add (&vam->json_tree);
12613
12614   vat_json_init_object (node);
12615   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12616   vat_json_object_add_string_copy (node, "interface_name",
12617                                    mp->interface_name);
12618   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
12619                             ntohl (mp->virtio_net_hdr_sz));
12620   vat_json_object_add_uint (node, "features_first_32",
12621                             clib_net_to_host_u32 (mp->features_first_32));
12622   vat_json_object_add_uint (node, "features_last_32",
12623                             clib_net_to_host_u32 (mp->features_last_32));
12624   vat_json_object_add_uint (node, "is_server", mp->is_server);
12625   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
12626   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
12627   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
12628 }
12629
12630 static int
12631 api_sw_interface_vhost_user_dump (vat_main_t * vam)
12632 {
12633   vl_api_sw_interface_vhost_user_dump_t *mp;
12634   vl_api_control_ping_t *mp_ping;
12635   int ret;
12636   print (vam->ofp,
12637          "Interface name            idx hdr_sz features server regions filename");
12638
12639   /* Get list of vhost-user interfaces */
12640   M (SW_INTERFACE_VHOST_USER_DUMP, mp);
12641   S (mp);
12642
12643   /* Use a control ping for synchronization */
12644   MPING (CONTROL_PING, mp_ping);
12645   S (mp_ping);
12646
12647   W (ret);
12648   return ret;
12649 }
12650
12651 static int
12652 api_show_version (vat_main_t * vam)
12653 {
12654   vl_api_show_version_t *mp;
12655   int ret;
12656
12657   M (SHOW_VERSION, mp);
12658
12659   S (mp);
12660   W (ret);
12661   return ret;
12662 }
12663
12664
12665 static int
12666 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
12667 {
12668   unformat_input_t *line_input = vam->input;
12669   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
12670   ip4_address_t local4, remote4;
12671   ip6_address_t local6, remote6;
12672   u8 is_add = 1;
12673   u8 ipv4_set = 0, ipv6_set = 0;
12674   u8 local_set = 0;
12675   u8 remote_set = 0;
12676   u8 grp_set = 0;
12677   u32 mcast_sw_if_index = ~0;
12678   u32 encap_vrf_id = 0;
12679   u32 decap_vrf_id = 0;
12680   u8 protocol = ~0;
12681   u32 vni;
12682   u8 vni_set = 0;
12683   int ret;
12684
12685   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
12686   clib_memset (&local4, 0, sizeof local4);
12687   clib_memset (&remote4, 0, sizeof remote4);
12688   clib_memset (&local6, 0, sizeof local6);
12689   clib_memset (&remote6, 0, sizeof remote6);
12690
12691   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12692     {
12693       if (unformat (line_input, "del"))
12694         is_add = 0;
12695       else if (unformat (line_input, "local %U",
12696                          unformat_ip4_address, &local4))
12697         {
12698           local_set = 1;
12699           ipv4_set = 1;
12700         }
12701       else if (unformat (line_input, "remote %U",
12702                          unformat_ip4_address, &remote4))
12703         {
12704           remote_set = 1;
12705           ipv4_set = 1;
12706         }
12707       else if (unformat (line_input, "local %U",
12708                          unformat_ip6_address, &local6))
12709         {
12710           local_set = 1;
12711           ipv6_set = 1;
12712         }
12713       else if (unformat (line_input, "remote %U",
12714                          unformat_ip6_address, &remote6))
12715         {
12716           remote_set = 1;
12717           ipv6_set = 1;
12718         }
12719       else if (unformat (line_input, "group %U %U",
12720                          unformat_ip4_address, &remote4,
12721                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12722         {
12723           grp_set = remote_set = 1;
12724           ipv4_set = 1;
12725         }
12726       else if (unformat (line_input, "group %U",
12727                          unformat_ip4_address, &remote4))
12728         {
12729           grp_set = remote_set = 1;
12730           ipv4_set = 1;
12731         }
12732       else if (unformat (line_input, "group %U %U",
12733                          unformat_ip6_address, &remote6,
12734                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12735         {
12736           grp_set = remote_set = 1;
12737           ipv6_set = 1;
12738         }
12739       else if (unformat (line_input, "group %U",
12740                          unformat_ip6_address, &remote6))
12741         {
12742           grp_set = remote_set = 1;
12743           ipv6_set = 1;
12744         }
12745       else
12746         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
12747         ;
12748       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
12749         ;
12750       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
12751         ;
12752       else if (unformat (line_input, "vni %d", &vni))
12753         vni_set = 1;
12754       else if (unformat (line_input, "next-ip4"))
12755         protocol = 1;
12756       else if (unformat (line_input, "next-ip6"))
12757         protocol = 2;
12758       else if (unformat (line_input, "next-ethernet"))
12759         protocol = 3;
12760       else if (unformat (line_input, "next-nsh"))
12761         protocol = 4;
12762       else
12763         {
12764           errmsg ("parse error '%U'", format_unformat_error, line_input);
12765           return -99;
12766         }
12767     }
12768
12769   if (local_set == 0)
12770     {
12771       errmsg ("tunnel local address not specified");
12772       return -99;
12773     }
12774   if (remote_set == 0)
12775     {
12776       errmsg ("tunnel remote address not specified");
12777       return -99;
12778     }
12779   if (grp_set && mcast_sw_if_index == ~0)
12780     {
12781       errmsg ("tunnel nonexistent multicast device");
12782       return -99;
12783     }
12784   if (ipv4_set && ipv6_set)
12785     {
12786       errmsg ("both IPv4 and IPv6 addresses specified");
12787       return -99;
12788     }
12789
12790   if (vni_set == 0)
12791     {
12792       errmsg ("vni not specified");
12793       return -99;
12794     }
12795
12796   M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
12797
12798
12799   if (ipv6_set)
12800     {
12801       clib_memcpy (&mp->local, &local6, sizeof (local6));
12802       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
12803     }
12804   else
12805     {
12806       clib_memcpy (&mp->local, &local4, sizeof (local4));
12807       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
12808     }
12809
12810   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
12811   mp->encap_vrf_id = ntohl (encap_vrf_id);
12812   mp->decap_vrf_id = ntohl (decap_vrf_id);
12813   mp->protocol = protocol;
12814   mp->vni = ntohl (vni);
12815   mp->is_add = is_add;
12816   mp->is_ipv6 = ipv6_set;
12817
12818   S (mp);
12819   W (ret);
12820   return ret;
12821 }
12822
12823 static void vl_api_vxlan_gpe_tunnel_details_t_handler
12824   (vl_api_vxlan_gpe_tunnel_details_t * mp)
12825 {
12826   vat_main_t *vam = &vat_main;
12827   ip46_address_t local = to_ip46 (mp->is_ipv6, mp->local);
12828   ip46_address_t remote = to_ip46 (mp->is_ipv6, mp->remote);
12829
12830   print (vam->ofp, "%11d%24U%24U%13d%12d%19d%14d%14d",
12831          ntohl (mp->sw_if_index),
12832          format_ip46_address, &local, IP46_TYPE_ANY,
12833          format_ip46_address, &remote, IP46_TYPE_ANY,
12834          ntohl (mp->vni), mp->protocol,
12835          ntohl (mp->mcast_sw_if_index),
12836          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
12837 }
12838
12839
12840 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
12841   (vl_api_vxlan_gpe_tunnel_details_t * mp)
12842 {
12843   vat_main_t *vam = &vat_main;
12844   vat_json_node_t *node = NULL;
12845   struct in_addr ip4;
12846   struct in6_addr ip6;
12847
12848   if (VAT_JSON_ARRAY != vam->json_tree.type)
12849     {
12850       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12851       vat_json_init_array (&vam->json_tree);
12852     }
12853   node = vat_json_array_add (&vam->json_tree);
12854
12855   vat_json_init_object (node);
12856   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12857   if (mp->is_ipv6)
12858     {
12859       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
12860       vat_json_object_add_ip6 (node, "local", ip6);
12861       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
12862       vat_json_object_add_ip6 (node, "remote", ip6);
12863     }
12864   else
12865     {
12866       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
12867       vat_json_object_add_ip4 (node, "local", ip4);
12868       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
12869       vat_json_object_add_ip4 (node, "remote", ip4);
12870     }
12871   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
12872   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
12873   vat_json_object_add_uint (node, "mcast_sw_if_index",
12874                             ntohl (mp->mcast_sw_if_index));
12875   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
12876   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
12877   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
12878 }
12879
12880 static int
12881 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
12882 {
12883   unformat_input_t *i = vam->input;
12884   vl_api_vxlan_gpe_tunnel_dump_t *mp;
12885   vl_api_control_ping_t *mp_ping;
12886   u32 sw_if_index;
12887   u8 sw_if_index_set = 0;
12888   int ret;
12889
12890   /* Parse args required to build the message */
12891   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12892     {
12893       if (unformat (i, "sw_if_index %d", &sw_if_index))
12894         sw_if_index_set = 1;
12895       else
12896         break;
12897     }
12898
12899   if (sw_if_index_set == 0)
12900     {
12901       sw_if_index = ~0;
12902     }
12903
12904   if (!vam->json_output)
12905     {
12906       print (vam->ofp, "%11s%24s%24s%13s%15s%19s%14s%14s",
12907              "sw_if_index", "local", "remote", "vni",
12908              "protocol", "mcast_sw_if_index", "encap_vrf_id", "decap_vrf_id");
12909     }
12910
12911   /* Get list of vxlan-tunnel interfaces */
12912   M (VXLAN_GPE_TUNNEL_DUMP, mp);
12913
12914   mp->sw_if_index = htonl (sw_if_index);
12915
12916   S (mp);
12917
12918   /* Use a control ping for synchronization */
12919   MPING (CONTROL_PING, mp_ping);
12920   S (mp_ping);
12921
12922   W (ret);
12923   return ret;
12924 }
12925
12926 static void vl_api_l2_fib_table_details_t_handler
12927   (vl_api_l2_fib_table_details_t * mp)
12928 {
12929   vat_main_t *vam = &vat_main;
12930
12931   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
12932          "       %d       %d     %d",
12933          ntohl (mp->bd_id), format_ethernet_address, mp->mac,
12934          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
12935          mp->bvi_mac);
12936 }
12937
12938 static void vl_api_l2_fib_table_details_t_handler_json
12939   (vl_api_l2_fib_table_details_t * mp)
12940 {
12941   vat_main_t *vam = &vat_main;
12942   vat_json_node_t *node = NULL;
12943
12944   if (VAT_JSON_ARRAY != vam->json_tree.type)
12945     {
12946       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12947       vat_json_init_array (&vam->json_tree);
12948     }
12949   node = vat_json_array_add (&vam->json_tree);
12950
12951   vat_json_init_object (node);
12952   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
12953   vat_json_object_add_bytes (node, "mac", mp->mac, 6);
12954   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12955   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
12956   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
12957   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
12958 }
12959
12960 static int
12961 api_l2_fib_table_dump (vat_main_t * vam)
12962 {
12963   unformat_input_t *i = vam->input;
12964   vl_api_l2_fib_table_dump_t *mp;
12965   vl_api_control_ping_t *mp_ping;
12966   u32 bd_id;
12967   u8 bd_id_set = 0;
12968   int ret;
12969
12970   /* Parse args required to build the message */
12971   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12972     {
12973       if (unformat (i, "bd_id %d", &bd_id))
12974         bd_id_set = 1;
12975       else
12976         break;
12977     }
12978
12979   if (bd_id_set == 0)
12980     {
12981       errmsg ("missing bridge domain");
12982       return -99;
12983     }
12984
12985   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
12986
12987   /* Get list of l2 fib entries */
12988   M (L2_FIB_TABLE_DUMP, mp);
12989
12990   mp->bd_id = ntohl (bd_id);
12991   S (mp);
12992
12993   /* Use a control ping for synchronization */
12994   MPING (CONTROL_PING, mp_ping);
12995   S (mp_ping);
12996
12997   W (ret);
12998   return ret;
12999 }
13000
13001
13002 static int
13003 api_interface_name_renumber (vat_main_t * vam)
13004 {
13005   unformat_input_t *line_input = vam->input;
13006   vl_api_interface_name_renumber_t *mp;
13007   u32 sw_if_index = ~0;
13008   u32 new_show_dev_instance = ~0;
13009   int ret;
13010
13011   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13012     {
13013       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
13014                     &sw_if_index))
13015         ;
13016       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
13017         ;
13018       else if (unformat (line_input, "new_show_dev_instance %d",
13019                          &new_show_dev_instance))
13020         ;
13021       else
13022         break;
13023     }
13024
13025   if (sw_if_index == ~0)
13026     {
13027       errmsg ("missing interface name or sw_if_index");
13028       return -99;
13029     }
13030
13031   if (new_show_dev_instance == ~0)
13032     {
13033       errmsg ("missing new_show_dev_instance");
13034       return -99;
13035     }
13036
13037   M (INTERFACE_NAME_RENUMBER, mp);
13038
13039   mp->sw_if_index = ntohl (sw_if_index);
13040   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
13041
13042   S (mp);
13043   W (ret);
13044   return ret;
13045 }
13046
13047 static int
13048 api_want_l2_macs_events (vat_main_t * vam)
13049 {
13050   unformat_input_t *line_input = vam->input;
13051   vl_api_want_l2_macs_events_t *mp;
13052   u8 enable_disable = 1;
13053   u32 scan_delay = 0;
13054   u32 max_macs_in_event = 0;
13055   u32 learn_limit = 0;
13056   int ret;
13057
13058   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13059     {
13060       if (unformat (line_input, "learn-limit %d", &learn_limit))
13061         ;
13062       else if (unformat (line_input, "scan-delay %d", &scan_delay))
13063         ;
13064       else if (unformat (line_input, "max-entries %d", &max_macs_in_event))
13065         ;
13066       else if (unformat (line_input, "disable"))
13067         enable_disable = 0;
13068       else
13069         break;
13070     }
13071
13072   M (WANT_L2_MACS_EVENTS, mp);
13073   mp->enable_disable = enable_disable;
13074   mp->pid = htonl (getpid ());
13075   mp->learn_limit = htonl (learn_limit);
13076   mp->scan_delay = (u8) scan_delay;
13077   mp->max_macs_in_event = (u8) (max_macs_in_event / 10);
13078   S (mp);
13079   W (ret);
13080   return ret;
13081 }
13082
13083 static int
13084 api_input_acl_set_interface (vat_main_t * vam)
13085 {
13086   unformat_input_t *i = vam->input;
13087   vl_api_input_acl_set_interface_t *mp;
13088   u32 sw_if_index;
13089   int sw_if_index_set;
13090   u32 ip4_table_index = ~0;
13091   u32 ip6_table_index = ~0;
13092   u32 l2_table_index = ~0;
13093   u8 is_add = 1;
13094   int ret;
13095
13096   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13097     {
13098       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13099         sw_if_index_set = 1;
13100       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13101         sw_if_index_set = 1;
13102       else if (unformat (i, "del"))
13103         is_add = 0;
13104       else if (unformat (i, "ip4-table %d", &ip4_table_index))
13105         ;
13106       else if (unformat (i, "ip6-table %d", &ip6_table_index))
13107         ;
13108       else if (unformat (i, "l2-table %d", &l2_table_index))
13109         ;
13110       else
13111         {
13112           clib_warning ("parse error '%U'", format_unformat_error, i);
13113           return -99;
13114         }
13115     }
13116
13117   if (sw_if_index_set == 0)
13118     {
13119       errmsg ("missing interface name or sw_if_index");
13120       return -99;
13121     }
13122
13123   M (INPUT_ACL_SET_INTERFACE, mp);
13124
13125   mp->sw_if_index = ntohl (sw_if_index);
13126   mp->ip4_table_index = ntohl (ip4_table_index);
13127   mp->ip6_table_index = ntohl (ip6_table_index);
13128   mp->l2_table_index = ntohl (l2_table_index);
13129   mp->is_add = is_add;
13130
13131   S (mp);
13132   W (ret);
13133   return ret;
13134 }
13135
13136 static int
13137 api_output_acl_set_interface (vat_main_t * vam)
13138 {
13139   unformat_input_t *i = vam->input;
13140   vl_api_output_acl_set_interface_t *mp;
13141   u32 sw_if_index;
13142   int sw_if_index_set;
13143   u32 ip4_table_index = ~0;
13144   u32 ip6_table_index = ~0;
13145   u32 l2_table_index = ~0;
13146   u8 is_add = 1;
13147   int ret;
13148
13149   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13150     {
13151       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13152         sw_if_index_set = 1;
13153       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13154         sw_if_index_set = 1;
13155       else if (unformat (i, "del"))
13156         is_add = 0;
13157       else if (unformat (i, "ip4-table %d", &ip4_table_index))
13158         ;
13159       else if (unformat (i, "ip6-table %d", &ip6_table_index))
13160         ;
13161       else if (unformat (i, "l2-table %d", &l2_table_index))
13162         ;
13163       else
13164         {
13165           clib_warning ("parse error '%U'", format_unformat_error, i);
13166           return -99;
13167         }
13168     }
13169
13170   if (sw_if_index_set == 0)
13171     {
13172       errmsg ("missing interface name or sw_if_index");
13173       return -99;
13174     }
13175
13176   M (OUTPUT_ACL_SET_INTERFACE, mp);
13177
13178   mp->sw_if_index = ntohl (sw_if_index);
13179   mp->ip4_table_index = ntohl (ip4_table_index);
13180   mp->ip6_table_index = ntohl (ip6_table_index);
13181   mp->l2_table_index = ntohl (l2_table_index);
13182   mp->is_add = is_add;
13183
13184   S (mp);
13185   W (ret);
13186   return ret;
13187 }
13188
13189 static int
13190 api_ip_address_dump (vat_main_t * vam)
13191 {
13192   unformat_input_t *i = vam->input;
13193   vl_api_ip_address_dump_t *mp;
13194   vl_api_control_ping_t *mp_ping;
13195   u32 sw_if_index = ~0;
13196   u8 sw_if_index_set = 0;
13197   u8 ipv4_set = 0;
13198   u8 ipv6_set = 0;
13199   int ret;
13200
13201   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13202     {
13203       if (unformat (i, "sw_if_index %d", &sw_if_index))
13204         sw_if_index_set = 1;
13205       else
13206         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13207         sw_if_index_set = 1;
13208       else if (unformat (i, "ipv4"))
13209         ipv4_set = 1;
13210       else if (unformat (i, "ipv6"))
13211         ipv6_set = 1;
13212       else
13213         break;
13214     }
13215
13216   if (ipv4_set && ipv6_set)
13217     {
13218       errmsg ("ipv4 and ipv6 flags cannot be both set");
13219       return -99;
13220     }
13221
13222   if ((!ipv4_set) && (!ipv6_set))
13223     {
13224       errmsg ("no ipv4 nor ipv6 flag set");
13225       return -99;
13226     }
13227
13228   if (sw_if_index_set == 0)
13229     {
13230       errmsg ("missing interface name or sw_if_index");
13231       return -99;
13232     }
13233
13234   vam->current_sw_if_index = sw_if_index;
13235   vam->is_ipv6 = ipv6_set;
13236
13237   M (IP_ADDRESS_DUMP, mp);
13238   mp->sw_if_index = ntohl (sw_if_index);
13239   mp->is_ipv6 = ipv6_set;
13240   S (mp);
13241
13242   /* Use a control ping for synchronization */
13243   MPING (CONTROL_PING, mp_ping);
13244   S (mp_ping);
13245
13246   W (ret);
13247   return ret;
13248 }
13249
13250 static int
13251 api_ip_dump (vat_main_t * vam)
13252 {
13253   vl_api_ip_dump_t *mp;
13254   vl_api_control_ping_t *mp_ping;
13255   unformat_input_t *in = vam->input;
13256   int ipv4_set = 0;
13257   int ipv6_set = 0;
13258   int is_ipv6;
13259   int i;
13260   int ret;
13261
13262   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
13263     {
13264       if (unformat (in, "ipv4"))
13265         ipv4_set = 1;
13266       else if (unformat (in, "ipv6"))
13267         ipv6_set = 1;
13268       else
13269         break;
13270     }
13271
13272   if (ipv4_set && ipv6_set)
13273     {
13274       errmsg ("ipv4 and ipv6 flags cannot be both set");
13275       return -99;
13276     }
13277
13278   if ((!ipv4_set) && (!ipv6_set))
13279     {
13280       errmsg ("no ipv4 nor ipv6 flag set");
13281       return -99;
13282     }
13283
13284   is_ipv6 = ipv6_set;
13285   vam->is_ipv6 = is_ipv6;
13286
13287   /* free old data */
13288   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
13289     {
13290       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
13291     }
13292   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
13293
13294   M (IP_DUMP, mp);
13295   mp->is_ipv6 = ipv6_set;
13296   S (mp);
13297
13298   /* Use a control ping for synchronization */
13299   MPING (CONTROL_PING, mp_ping);
13300   S (mp_ping);
13301
13302   W (ret);
13303   return ret;
13304 }
13305
13306 static int
13307 api_ipsec_spd_add_del (vat_main_t * vam)
13308 {
13309   unformat_input_t *i = vam->input;
13310   vl_api_ipsec_spd_add_del_t *mp;
13311   u32 spd_id = ~0;
13312   u8 is_add = 1;
13313   int ret;
13314
13315   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13316     {
13317       if (unformat (i, "spd_id %d", &spd_id))
13318         ;
13319       else if (unformat (i, "del"))
13320         is_add = 0;
13321       else
13322         {
13323           clib_warning ("parse error '%U'", format_unformat_error, i);
13324           return -99;
13325         }
13326     }
13327   if (spd_id == ~0)
13328     {
13329       errmsg ("spd_id must be set");
13330       return -99;
13331     }
13332
13333   M (IPSEC_SPD_ADD_DEL, mp);
13334
13335   mp->spd_id = ntohl (spd_id);
13336   mp->is_add = is_add;
13337
13338   S (mp);
13339   W (ret);
13340   return ret;
13341 }
13342
13343 static int
13344 api_ipsec_interface_add_del_spd (vat_main_t * vam)
13345 {
13346   unformat_input_t *i = vam->input;
13347   vl_api_ipsec_interface_add_del_spd_t *mp;
13348   u32 sw_if_index;
13349   u8 sw_if_index_set = 0;
13350   u32 spd_id = (u32) ~ 0;
13351   u8 is_add = 1;
13352   int ret;
13353
13354   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13355     {
13356       if (unformat (i, "del"))
13357         is_add = 0;
13358       else if (unformat (i, "spd_id %d", &spd_id))
13359         ;
13360       else
13361         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13362         sw_if_index_set = 1;
13363       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13364         sw_if_index_set = 1;
13365       else
13366         {
13367           clib_warning ("parse error '%U'", format_unformat_error, i);
13368           return -99;
13369         }
13370
13371     }
13372
13373   if (spd_id == (u32) ~ 0)
13374     {
13375       errmsg ("spd_id must be set");
13376       return -99;
13377     }
13378
13379   if (sw_if_index_set == 0)
13380     {
13381       errmsg ("missing interface name or sw_if_index");
13382       return -99;
13383     }
13384
13385   M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
13386
13387   mp->spd_id = ntohl (spd_id);
13388   mp->sw_if_index = ntohl (sw_if_index);
13389   mp->is_add = is_add;
13390
13391   S (mp);
13392   W (ret);
13393   return ret;
13394 }
13395
13396 static int
13397 api_ipsec_spd_entry_add_del (vat_main_t * vam)
13398 {
13399   unformat_input_t *i = vam->input;
13400   vl_api_ipsec_spd_entry_add_del_t *mp;
13401   u8 is_add = 1, is_outbound = 0;
13402   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
13403   i32 priority = 0;
13404   u32 rport_start = 0, rport_stop = (u32) ~ 0;
13405   u32 lport_start = 0, lport_stop = (u32) ~ 0;
13406   vl_api_address_t laddr_start = { }, laddr_stop =
13407   {
13408   }, raddr_start =
13409   {
13410   }, raddr_stop =
13411   {
13412   };
13413   int ret;
13414
13415   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13416     {
13417       if (unformat (i, "del"))
13418         is_add = 0;
13419       if (unformat (i, "outbound"))
13420         is_outbound = 1;
13421       if (unformat (i, "inbound"))
13422         is_outbound = 0;
13423       else if (unformat (i, "spd_id %d", &spd_id))
13424         ;
13425       else if (unformat (i, "sa_id %d", &sa_id))
13426         ;
13427       else if (unformat (i, "priority %d", &priority))
13428         ;
13429       else if (unformat (i, "protocol %d", &protocol))
13430         ;
13431       else if (unformat (i, "lport_start %d", &lport_start))
13432         ;
13433       else if (unformat (i, "lport_stop %d", &lport_stop))
13434         ;
13435       else if (unformat (i, "rport_start %d", &rport_start))
13436         ;
13437       else if (unformat (i, "rport_stop %d", &rport_stop))
13438         ;
13439       else if (unformat (i, "laddr_start %U",
13440                          unformat_vl_api_address, &laddr_start))
13441         ;
13442       else if (unformat (i, "laddr_stop %U", unformat_vl_api_address,
13443                          &laddr_stop))
13444         ;
13445       else if (unformat (i, "raddr_start %U", unformat_vl_api_address,
13446                          &raddr_start))
13447         ;
13448       else if (unformat (i, "raddr_stop %U", unformat_vl_api_address,
13449                          &raddr_stop))
13450         ;
13451       else
13452         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
13453         {
13454           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
13455             {
13456               clib_warning ("unsupported action: 'resolve'");
13457               return -99;
13458             }
13459         }
13460       else
13461         {
13462           clib_warning ("parse error '%U'", format_unformat_error, i);
13463           return -99;
13464         }
13465
13466     }
13467
13468   M (IPSEC_SPD_ENTRY_ADD_DEL, mp);
13469
13470   mp->is_add = is_add;
13471
13472   mp->entry.spd_id = ntohl (spd_id);
13473   mp->entry.priority = ntohl (priority);
13474   mp->entry.is_outbound = is_outbound;
13475
13476   clib_memcpy (&mp->entry.remote_address_start, &raddr_start,
13477                sizeof (vl_api_address_t));
13478   clib_memcpy (&mp->entry.remote_address_stop, &raddr_stop,
13479                sizeof (vl_api_address_t));
13480   clib_memcpy (&mp->entry.local_address_start, &laddr_start,
13481                sizeof (vl_api_address_t));
13482   clib_memcpy (&mp->entry.local_address_stop, &laddr_stop,
13483                sizeof (vl_api_address_t));
13484
13485   mp->entry.protocol = (u8) protocol;
13486   mp->entry.local_port_start = ntohs ((u16) lport_start);
13487   mp->entry.local_port_stop = ntohs ((u16) lport_stop);
13488   mp->entry.remote_port_start = ntohs ((u16) rport_start);
13489   mp->entry.remote_port_stop = ntohs ((u16) rport_stop);
13490   mp->entry.policy = (u8) policy;
13491   mp->entry.sa_id = ntohl (sa_id);
13492
13493   S (mp);
13494   W (ret);
13495   return ret;
13496 }
13497
13498 static int
13499 api_ipsec_sad_entry_add_del (vat_main_t * vam)
13500 {
13501   unformat_input_t *i = vam->input;
13502   vl_api_ipsec_sad_entry_add_del_t *mp;
13503   u32 sad_id = 0, spi = 0;
13504   u8 *ck = 0, *ik = 0;
13505   u8 is_add = 1;
13506
13507   vl_api_ipsec_crypto_alg_t crypto_alg = IPSEC_API_CRYPTO_ALG_NONE;
13508   vl_api_ipsec_integ_alg_t integ_alg = IPSEC_API_INTEG_ALG_NONE;
13509   vl_api_ipsec_sad_flags_t flags = IPSEC_API_SAD_FLAG_NONE;
13510   vl_api_ipsec_proto_t protocol = IPSEC_API_PROTO_AH;
13511   vl_api_address_t tun_src, tun_dst;
13512   int ret;
13513
13514   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13515     {
13516       if (unformat (i, "del"))
13517         is_add = 0;
13518       else if (unformat (i, "sad_id %d", &sad_id))
13519         ;
13520       else if (unformat (i, "spi %d", &spi))
13521         ;
13522       else if (unformat (i, "esp"))
13523         protocol = IPSEC_API_PROTO_ESP;
13524       else
13525         if (unformat (i, "tunnel_src %U", unformat_vl_api_address, &tun_src))
13526         {
13527           flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL;
13528           if (ADDRESS_IP6 == tun_src.af)
13529             flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL_V6;
13530         }
13531       else
13532         if (unformat (i, "tunnel_dst %U", unformat_vl_api_address, &tun_dst))
13533         {
13534           flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL;
13535           if (ADDRESS_IP6 == tun_src.af)
13536             flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL_V6;
13537         }
13538       else
13539         if (unformat (i, "crypto_alg %U",
13540                       unformat_ipsec_api_crypto_alg, &crypto_alg))
13541         ;
13542       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
13543         ;
13544       else if (unformat (i, "integ_alg %U",
13545                          unformat_ipsec_api_integ_alg, &integ_alg))
13546         ;
13547       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
13548         ;
13549       else
13550         {
13551           clib_warning ("parse error '%U'", format_unformat_error, i);
13552           return -99;
13553         }
13554
13555     }
13556
13557   M (IPSEC_SAD_ENTRY_ADD_DEL, mp);
13558
13559   mp->is_add = is_add;
13560   mp->entry.sad_id = ntohl (sad_id);
13561   mp->entry.protocol = protocol;
13562   mp->entry.spi = ntohl (spi);
13563   mp->entry.flags = flags;
13564
13565   mp->entry.crypto_algorithm = crypto_alg;
13566   mp->entry.integrity_algorithm = integ_alg;
13567   mp->entry.crypto_key.length = vec_len (ck);
13568   mp->entry.integrity_key.length = vec_len (ik);
13569
13570   if (mp->entry.crypto_key.length > sizeof (mp->entry.crypto_key.data))
13571     mp->entry.crypto_key.length = sizeof (mp->entry.crypto_key.data);
13572
13573   if (mp->entry.integrity_key.length > sizeof (mp->entry.integrity_key.data))
13574     mp->entry.integrity_key.length = sizeof (mp->entry.integrity_key.data);
13575
13576   if (ck)
13577     clib_memcpy (mp->entry.crypto_key.data, ck, mp->entry.crypto_key.length);
13578   if (ik)
13579     clib_memcpy (mp->entry.integrity_key.data, ik,
13580                  mp->entry.integrity_key.length);
13581
13582   if (flags & IPSEC_API_SAD_FLAG_IS_TUNNEL)
13583     {
13584       clib_memcpy (&mp->entry.tunnel_src, &tun_src,
13585                    sizeof (mp->entry.tunnel_src));
13586       clib_memcpy (&mp->entry.tunnel_dst, &tun_dst,
13587                    sizeof (mp->entry.tunnel_dst));
13588     }
13589
13590   S (mp);
13591   W (ret);
13592   return ret;
13593 }
13594
13595 static int
13596 api_ipsec_tunnel_if_add_del (vat_main_t * vam)
13597 {
13598   unformat_input_t *i = vam->input;
13599   vl_api_ipsec_tunnel_if_add_del_t *mp;
13600   u32 local_spi = 0, remote_spi = 0;
13601   u32 crypto_alg = 0, integ_alg = 0;
13602   u8 *lck = NULL, *rck = NULL;
13603   u8 *lik = NULL, *rik = NULL;
13604   vl_api_address_t local_ip = { 0 };
13605   vl_api_address_t remote_ip = { 0 };
13606   f64 before = 0;
13607   u8 is_add = 1;
13608   u8 esn = 0;
13609   u8 anti_replay = 0;
13610   u8 renumber = 0;
13611   u32 instance = ~0;
13612   u32 count = 1, jj;
13613   int ret = -1;
13614
13615   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13616     {
13617       if (unformat (i, "del"))
13618         is_add = 0;
13619       else if (unformat (i, "esn"))
13620         esn = 1;
13621       else if (unformat (i, "anti-replay"))
13622         anti_replay = 1;
13623       else if (unformat (i, "count %d", &count))
13624         ;
13625       else if (unformat (i, "local_spi %d", &local_spi))
13626         ;
13627       else if (unformat (i, "remote_spi %d", &remote_spi))
13628         ;
13629       else
13630         if (unformat (i, "local_ip %U", unformat_vl_api_address, &local_ip))
13631         ;
13632       else
13633         if (unformat (i, "remote_ip %U", unformat_vl_api_address, &remote_ip))
13634         ;
13635       else if (unformat (i, "local_crypto_key %U", unformat_hex_string, &lck))
13636         ;
13637       else
13638         if (unformat (i, "remote_crypto_key %U", unformat_hex_string, &rck))
13639         ;
13640       else if (unformat (i, "local_integ_key %U", unformat_hex_string, &lik))
13641         ;
13642       else if (unformat (i, "remote_integ_key %U", unformat_hex_string, &rik))
13643         ;
13644       else
13645         if (unformat
13646             (i, "crypto_alg %U", unformat_ipsec_api_crypto_alg, &crypto_alg))
13647         {
13648           if (crypto_alg >= IPSEC_CRYPTO_N_ALG)
13649             {
13650               errmsg ("unsupported crypto-alg: '%U'\n",
13651                       format_ipsec_crypto_alg, crypto_alg);
13652               return -99;
13653             }
13654         }
13655       else
13656         if (unformat
13657             (i, "integ_alg %U", unformat_ipsec_api_integ_alg, &integ_alg))
13658         {
13659           if (integ_alg >= IPSEC_INTEG_N_ALG)
13660             {
13661               errmsg ("unsupported integ-alg: '%U'\n",
13662                       format_ipsec_integ_alg, integ_alg);
13663               return -99;
13664             }
13665         }
13666       else if (unformat (i, "instance %u", &instance))
13667         renumber = 1;
13668       else
13669         {
13670           errmsg ("parse error '%U'\n", format_unformat_error, i);
13671           return -99;
13672         }
13673     }
13674
13675   if (count > 1)
13676     {
13677       /* Turn on async mode */
13678       vam->async_mode = 1;
13679       vam->async_errors = 0;
13680       before = vat_time_now (vam);
13681     }
13682
13683   for (jj = 0; jj < count; jj++)
13684     {
13685       M (IPSEC_TUNNEL_IF_ADD_DEL, mp);
13686
13687       mp->is_add = is_add;
13688       mp->esn = esn;
13689       mp->anti_replay = anti_replay;
13690
13691       if (jj > 0)
13692         increment_address (&remote_ip);
13693
13694       clib_memcpy (&mp->local_ip, &local_ip, sizeof (local_ip));
13695       clib_memcpy (&mp->remote_ip, &remote_ip, sizeof (remote_ip));
13696
13697       mp->local_spi = htonl (local_spi + jj);
13698       mp->remote_spi = htonl (remote_spi + jj);
13699       mp->crypto_alg = (u8) crypto_alg;
13700
13701       mp->local_crypto_key_len = 0;
13702       if (lck)
13703         {
13704           mp->local_crypto_key_len = vec_len (lck);
13705           if (mp->local_crypto_key_len > sizeof (mp->local_crypto_key))
13706             mp->local_crypto_key_len = sizeof (mp->local_crypto_key);
13707           clib_memcpy (mp->local_crypto_key, lck, mp->local_crypto_key_len);
13708         }
13709
13710       mp->remote_crypto_key_len = 0;
13711       if (rck)
13712         {
13713           mp->remote_crypto_key_len = vec_len (rck);
13714           if (mp->remote_crypto_key_len > sizeof (mp->remote_crypto_key))
13715             mp->remote_crypto_key_len = sizeof (mp->remote_crypto_key);
13716           clib_memcpy (mp->remote_crypto_key, rck, mp->remote_crypto_key_len);
13717         }
13718
13719       mp->integ_alg = (u8) integ_alg;
13720
13721       mp->local_integ_key_len = 0;
13722       if (lik)
13723         {
13724           mp->local_integ_key_len = vec_len (lik);
13725           if (mp->local_integ_key_len > sizeof (mp->local_integ_key))
13726             mp->local_integ_key_len = sizeof (mp->local_integ_key);
13727           clib_memcpy (mp->local_integ_key, lik, mp->local_integ_key_len);
13728         }
13729
13730       mp->remote_integ_key_len = 0;
13731       if (rik)
13732         {
13733           mp->remote_integ_key_len = vec_len (rik);
13734           if (mp->remote_integ_key_len > sizeof (mp->remote_integ_key))
13735             mp->remote_integ_key_len = sizeof (mp->remote_integ_key);
13736           clib_memcpy (mp->remote_integ_key, rik, mp->remote_integ_key_len);
13737         }
13738
13739       if (renumber)
13740         {
13741           mp->renumber = renumber;
13742           mp->show_instance = ntohl (instance);
13743         }
13744       S (mp);
13745     }
13746
13747   /* When testing multiple add/del ops, use a control-ping to sync */
13748   if (count > 1)
13749     {
13750       vl_api_control_ping_t *mp_ping;
13751       f64 after;
13752       f64 timeout;
13753
13754       /* Shut off async mode */
13755       vam->async_mode = 0;
13756
13757       MPING (CONTROL_PING, mp_ping);
13758       S (mp_ping);
13759
13760       timeout = vat_time_now (vam) + 1.0;
13761       while (vat_time_now (vam) < timeout)
13762         if (vam->result_ready == 1)
13763           goto out;
13764       vam->retval = -99;
13765
13766     out:
13767       if (vam->retval == -99)
13768         errmsg ("timeout");
13769
13770       if (vam->async_errors > 0)
13771         {
13772           errmsg ("%d asynchronous errors", vam->async_errors);
13773           vam->retval = -98;
13774         }
13775       vam->async_errors = 0;
13776       after = vat_time_now (vam);
13777
13778       /* slim chance, but we might have eaten SIGTERM on the first iteration */
13779       if (jj > 0)
13780         count = jj;
13781
13782       print (vam->ofp, "%d tunnels in %.6f secs, %.2f tunnels/sec",
13783              count, after - before, count / (after - before));
13784     }
13785   else
13786     {
13787       /* Wait for a reply... */
13788       W (ret);
13789       return ret;
13790     }
13791
13792   return ret;
13793 }
13794
13795 static void
13796 vl_api_ipsec_sa_details_t_handler (vl_api_ipsec_sa_details_t * mp)
13797 {
13798   vat_main_t *vam = &vat_main;
13799
13800   print (vam->ofp, "sa_id %u sw_if_index %u spi %u proto %u crypto_alg %u "
13801          "crypto_key %U integ_alg %u integ_key %U flags %x "
13802          "tunnel_src_addr %U tunnel_dst_addr %U "
13803          "salt %u seq_outbound %lu last_seq_inbound %lu "
13804          "replay_window %lu\n",
13805          ntohl (mp->entry.sad_id),
13806          ntohl (mp->sw_if_index),
13807          ntohl (mp->entry.spi),
13808          ntohl (mp->entry.protocol),
13809          ntohl (mp->entry.crypto_algorithm),
13810          format_hex_bytes, mp->entry.crypto_key.data,
13811          mp->entry.crypto_key.length, ntohl (mp->entry.integrity_algorithm),
13812          format_hex_bytes, mp->entry.integrity_key.data,
13813          mp->entry.integrity_key.length, ntohl (mp->entry.flags),
13814          format_vl_api_address, &mp->entry.tunnel_src, format_vl_api_address,
13815          &mp->entry.tunnel_dst, ntohl (mp->salt),
13816          clib_net_to_host_u64 (mp->seq_outbound),
13817          clib_net_to_host_u64 (mp->last_seq_inbound),
13818          clib_net_to_host_u64 (mp->replay_window));
13819 }
13820
13821 #define vl_api_ipsec_sa_details_t_endian vl_noop_handler
13822 #define vl_api_ipsec_sa_details_t_print vl_noop_handler
13823
13824 static void vl_api_ipsec_sa_details_t_handler_json
13825   (vl_api_ipsec_sa_details_t * mp)
13826 {
13827   vat_main_t *vam = &vat_main;
13828   vat_json_node_t *node = NULL;
13829   vl_api_ipsec_sad_flags_t flags;
13830
13831   if (VAT_JSON_ARRAY != vam->json_tree.type)
13832     {
13833       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13834       vat_json_init_array (&vam->json_tree);
13835     }
13836   node = vat_json_array_add (&vam->json_tree);
13837
13838   vat_json_init_object (node);
13839   vat_json_object_add_uint (node, "sa_id", ntohl (mp->entry.sad_id));
13840   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13841   vat_json_object_add_uint (node, "spi", ntohl (mp->entry.spi));
13842   vat_json_object_add_uint (node, "proto", ntohl (mp->entry.protocol));
13843   vat_json_object_add_uint (node, "crypto_alg",
13844                             ntohl (mp->entry.crypto_algorithm));
13845   vat_json_object_add_uint (node, "integ_alg",
13846                             ntohl (mp->entry.integrity_algorithm));
13847   flags = ntohl (mp->entry.flags);
13848   vat_json_object_add_uint (node, "use_esn",
13849                             ! !(flags & IPSEC_API_SAD_FLAG_USE_ESN));
13850   vat_json_object_add_uint (node, "use_anti_replay",
13851                             ! !(flags & IPSEC_API_SAD_FLAG_USE_ANTI_REPLAY));
13852   vat_json_object_add_uint (node, "is_tunnel",
13853                             ! !(flags & IPSEC_API_SAD_FLAG_IS_TUNNEL));
13854   vat_json_object_add_uint (node, "is_tunnel_ip6",
13855                             ! !(flags & IPSEC_API_SAD_FLAG_IS_TUNNEL_V6));
13856   vat_json_object_add_uint (node, "udp_encap",
13857                             ! !(flags & IPSEC_API_SAD_FLAG_UDP_ENCAP));
13858   vat_json_object_add_bytes (node, "crypto_key", mp->entry.crypto_key.data,
13859                              mp->entry.crypto_key.length);
13860   vat_json_object_add_bytes (node, "integ_key", mp->entry.integrity_key.data,
13861                              mp->entry.integrity_key.length);
13862   vat_json_object_add_address (node, "src", &mp->entry.tunnel_src);
13863   vat_json_object_add_address (node, "dst", &mp->entry.tunnel_dst);
13864   vat_json_object_add_uint (node, "replay_window",
13865                             clib_net_to_host_u64 (mp->replay_window));
13866 }
13867
13868 static int
13869 api_ipsec_sa_dump (vat_main_t * vam)
13870 {
13871   unformat_input_t *i = vam->input;
13872   vl_api_ipsec_sa_dump_t *mp;
13873   vl_api_control_ping_t *mp_ping;
13874   u32 sa_id = ~0;
13875   int ret;
13876
13877   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13878     {
13879       if (unformat (i, "sa_id %d", &sa_id))
13880         ;
13881       else
13882         {
13883           clib_warning ("parse error '%U'", format_unformat_error, i);
13884           return -99;
13885         }
13886     }
13887
13888   M (IPSEC_SA_DUMP, mp);
13889
13890   mp->sa_id = ntohl (sa_id);
13891
13892   S (mp);
13893
13894   /* Use a control ping for synchronization */
13895   M (CONTROL_PING, mp_ping);
13896   S (mp_ping);
13897
13898   W (ret);
13899   return ret;
13900 }
13901
13902 static int
13903 api_ipsec_tunnel_if_set_sa (vat_main_t * vam)
13904 {
13905   unformat_input_t *i = vam->input;
13906   vl_api_ipsec_tunnel_if_set_sa_t *mp;
13907   u32 sw_if_index = ~0;
13908   u32 sa_id = ~0;
13909   u8 is_outbound = (u8) ~ 0;
13910   int ret;
13911
13912   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13913     {
13914       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13915         ;
13916       else if (unformat (i, "sa_id %d", &sa_id))
13917         ;
13918       else if (unformat (i, "outbound"))
13919         is_outbound = 1;
13920       else if (unformat (i, "inbound"))
13921         is_outbound = 0;
13922       else
13923         {
13924           clib_warning ("parse error '%U'", format_unformat_error, i);
13925           return -99;
13926         }
13927     }
13928
13929   if (sw_if_index == ~0)
13930     {
13931       errmsg ("interface must be specified");
13932       return -99;
13933     }
13934
13935   if (sa_id == ~0)
13936     {
13937       errmsg ("SA ID must be specified");
13938       return -99;
13939     }
13940
13941   M (IPSEC_TUNNEL_IF_SET_SA, mp);
13942
13943   mp->sw_if_index = htonl (sw_if_index);
13944   mp->sa_id = htonl (sa_id);
13945   mp->is_outbound = is_outbound;
13946
13947   S (mp);
13948   W (ret);
13949
13950   return ret;
13951 }
13952
13953 static int
13954 api_get_first_msg_id (vat_main_t * vam)
13955 {
13956   vl_api_get_first_msg_id_t *mp;
13957   unformat_input_t *i = vam->input;
13958   u8 *name;
13959   u8 name_set = 0;
13960   int ret;
13961
13962   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13963     {
13964       if (unformat (i, "client %s", &name))
13965         name_set = 1;
13966       else
13967         break;
13968     }
13969
13970   if (name_set == 0)
13971     {
13972       errmsg ("missing client name");
13973       return -99;
13974     }
13975   vec_add1 (name, 0);
13976
13977   if (vec_len (name) > 63)
13978     {
13979       errmsg ("client name too long");
13980       return -99;
13981     }
13982
13983   M (GET_FIRST_MSG_ID, mp);
13984   clib_memcpy (mp->name, name, vec_len (name));
13985   S (mp);
13986   W (ret);
13987   return ret;
13988 }
13989
13990 static int
13991 api_cop_interface_enable_disable (vat_main_t * vam)
13992 {
13993   unformat_input_t *line_input = vam->input;
13994   vl_api_cop_interface_enable_disable_t *mp;
13995   u32 sw_if_index = ~0;
13996   u8 enable_disable = 1;
13997   int ret;
13998
13999   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14000     {
14001       if (unformat (line_input, "disable"))
14002         enable_disable = 0;
14003       if (unformat (line_input, "enable"))
14004         enable_disable = 1;
14005       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
14006                          vam, &sw_if_index))
14007         ;
14008       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
14009         ;
14010       else
14011         break;
14012     }
14013
14014   if (sw_if_index == ~0)
14015     {
14016       errmsg ("missing interface name or sw_if_index");
14017       return -99;
14018     }
14019
14020   /* Construct the API message */
14021   M (COP_INTERFACE_ENABLE_DISABLE, mp);
14022   mp->sw_if_index = ntohl (sw_if_index);
14023   mp->enable_disable = enable_disable;
14024
14025   /* send it... */
14026   S (mp);
14027   /* Wait for the reply */
14028   W (ret);
14029   return ret;
14030 }
14031
14032 static int
14033 api_cop_whitelist_enable_disable (vat_main_t * vam)
14034 {
14035   unformat_input_t *line_input = vam->input;
14036   vl_api_cop_whitelist_enable_disable_t *mp;
14037   u32 sw_if_index = ~0;
14038   u8 ip4 = 0, ip6 = 0, default_cop = 0;
14039   u32 fib_id = 0;
14040   int ret;
14041
14042   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14043     {
14044       if (unformat (line_input, "ip4"))
14045         ip4 = 1;
14046       else if (unformat (line_input, "ip6"))
14047         ip6 = 1;
14048       else if (unformat (line_input, "default"))
14049         default_cop = 1;
14050       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
14051                          vam, &sw_if_index))
14052         ;
14053       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
14054         ;
14055       else if (unformat (line_input, "fib-id %d", &fib_id))
14056         ;
14057       else
14058         break;
14059     }
14060
14061   if (sw_if_index == ~0)
14062     {
14063       errmsg ("missing interface name or sw_if_index");
14064       return -99;
14065     }
14066
14067   /* Construct the API message */
14068   M (COP_WHITELIST_ENABLE_DISABLE, mp);
14069   mp->sw_if_index = ntohl (sw_if_index);
14070   mp->fib_id = ntohl (fib_id);
14071   mp->ip4 = ip4;
14072   mp->ip6 = ip6;
14073   mp->default_cop = default_cop;
14074
14075   /* send it... */
14076   S (mp);
14077   /* Wait for the reply */
14078   W (ret);
14079   return ret;
14080 }
14081
14082 static int
14083 api_get_node_graph (vat_main_t * vam)
14084 {
14085   vl_api_get_node_graph_t *mp;
14086   int ret;
14087
14088   M (GET_NODE_GRAPH, mp);
14089
14090   /* send it... */
14091   S (mp);
14092   /* Wait for the reply */
14093   W (ret);
14094   return ret;
14095 }
14096
14097 /* *INDENT-OFF* */
14098 /** Used for parsing LISP eids */
14099 typedef CLIB_PACKED(struct{
14100   u8 addr[16];   /**< eid address */
14101   u32 len;       /**< prefix length if IP */
14102   u8 type;      /**< type of eid */
14103 }) lisp_eid_vat_t;
14104 /* *INDENT-ON* */
14105
14106 static uword
14107 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
14108 {
14109   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
14110
14111   clib_memset (a, 0, sizeof (a[0]));
14112
14113   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
14114     {
14115       a->type = 0;              /* ipv4 type */
14116     }
14117   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
14118     {
14119       a->type = 1;              /* ipv6 type */
14120     }
14121   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
14122     {
14123       a->type = 2;              /* mac type */
14124     }
14125   else if (unformat (input, "%U", unformat_nsh_address, a->addr))
14126     {
14127       a->type = 3;              /* NSH type */
14128       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) a->addr;
14129       nsh->spi = clib_host_to_net_u32 (nsh->spi);
14130     }
14131   else
14132     {
14133       return 0;
14134     }
14135
14136   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
14137     {
14138       return 0;
14139     }
14140
14141   return 1;
14142 }
14143
14144 static int
14145 lisp_eid_size_vat (u8 type)
14146 {
14147   switch (type)
14148     {
14149     case 0:
14150       return 4;
14151     case 1:
14152       return 16;
14153     case 2:
14154       return 6;
14155     case 3:
14156       return 5;
14157     }
14158   return 0;
14159 }
14160
14161 static void
14162 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
14163 {
14164   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
14165 }
14166
14167 static int
14168 api_one_add_del_locator_set (vat_main_t * vam)
14169 {
14170   unformat_input_t *input = vam->input;
14171   vl_api_one_add_del_locator_set_t *mp;
14172   u8 is_add = 1;
14173   u8 *locator_set_name = NULL;
14174   u8 locator_set_name_set = 0;
14175   vl_api_local_locator_t locator, *locators = 0;
14176   u32 sw_if_index, priority, weight;
14177   u32 data_len = 0;
14178
14179   int ret;
14180   /* Parse args required to build the message */
14181   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14182     {
14183       if (unformat (input, "del"))
14184         {
14185           is_add = 0;
14186         }
14187       else if (unformat (input, "locator-set %s", &locator_set_name))
14188         {
14189           locator_set_name_set = 1;
14190         }
14191       else if (unformat (input, "sw_if_index %u p %u w %u",
14192                          &sw_if_index, &priority, &weight))
14193         {
14194           locator.sw_if_index = htonl (sw_if_index);
14195           locator.priority = priority;
14196           locator.weight = weight;
14197           vec_add1 (locators, locator);
14198         }
14199       else
14200         if (unformat
14201             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
14202              &sw_if_index, &priority, &weight))
14203         {
14204           locator.sw_if_index = htonl (sw_if_index);
14205           locator.priority = priority;
14206           locator.weight = weight;
14207           vec_add1 (locators, locator);
14208         }
14209       else
14210         break;
14211     }
14212
14213   if (locator_set_name_set == 0)
14214     {
14215       errmsg ("missing locator-set name");
14216       vec_free (locators);
14217       return -99;
14218     }
14219
14220   if (vec_len (locator_set_name) > 64)
14221     {
14222       errmsg ("locator-set name too long");
14223       vec_free (locator_set_name);
14224       vec_free (locators);
14225       return -99;
14226     }
14227   vec_add1 (locator_set_name, 0);
14228
14229   data_len = sizeof (vl_api_local_locator_t) * vec_len (locators);
14230
14231   /* Construct the API message */
14232   M2 (ONE_ADD_DEL_LOCATOR_SET, mp, data_len);
14233
14234   mp->is_add = is_add;
14235   clib_memcpy (mp->locator_set_name, locator_set_name,
14236                vec_len (locator_set_name));
14237   vec_free (locator_set_name);
14238
14239   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
14240   if (locators)
14241     clib_memcpy (mp->locators, locators, data_len);
14242   vec_free (locators);
14243
14244   /* send it... */
14245   S (mp);
14246
14247   /* Wait for a reply... */
14248   W (ret);
14249   return ret;
14250 }
14251
14252 #define api_lisp_add_del_locator_set api_one_add_del_locator_set
14253
14254 static int
14255 api_one_add_del_locator (vat_main_t * vam)
14256 {
14257   unformat_input_t *input = vam->input;
14258   vl_api_one_add_del_locator_t *mp;
14259   u32 tmp_if_index = ~0;
14260   u32 sw_if_index = ~0;
14261   u8 sw_if_index_set = 0;
14262   u8 sw_if_index_if_name_set = 0;
14263   u32 priority = ~0;
14264   u8 priority_set = 0;
14265   u32 weight = ~0;
14266   u8 weight_set = 0;
14267   u8 is_add = 1;
14268   u8 *locator_set_name = NULL;
14269   u8 locator_set_name_set = 0;
14270   int ret;
14271
14272   /* Parse args required to build the message */
14273   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14274     {
14275       if (unformat (input, "del"))
14276         {
14277           is_add = 0;
14278         }
14279       else if (unformat (input, "locator-set %s", &locator_set_name))
14280         {
14281           locator_set_name_set = 1;
14282         }
14283       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
14284                          &tmp_if_index))
14285         {
14286           sw_if_index_if_name_set = 1;
14287           sw_if_index = tmp_if_index;
14288         }
14289       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
14290         {
14291           sw_if_index_set = 1;
14292           sw_if_index = tmp_if_index;
14293         }
14294       else if (unformat (input, "p %d", &priority))
14295         {
14296           priority_set = 1;
14297         }
14298       else if (unformat (input, "w %d", &weight))
14299         {
14300           weight_set = 1;
14301         }
14302       else
14303         break;
14304     }
14305
14306   if (locator_set_name_set == 0)
14307     {
14308       errmsg ("missing locator-set name");
14309       return -99;
14310     }
14311
14312   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
14313     {
14314       errmsg ("missing sw_if_index");
14315       vec_free (locator_set_name);
14316       return -99;
14317     }
14318
14319   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
14320     {
14321       errmsg ("cannot use both params interface name and sw_if_index");
14322       vec_free (locator_set_name);
14323       return -99;
14324     }
14325
14326   if (priority_set == 0)
14327     {
14328       errmsg ("missing locator-set priority");
14329       vec_free (locator_set_name);
14330       return -99;
14331     }
14332
14333   if (weight_set == 0)
14334     {
14335       errmsg ("missing locator-set weight");
14336       vec_free (locator_set_name);
14337       return -99;
14338     }
14339
14340   if (vec_len (locator_set_name) > 64)
14341     {
14342       errmsg ("locator-set name too long");
14343       vec_free (locator_set_name);
14344       return -99;
14345     }
14346   vec_add1 (locator_set_name, 0);
14347
14348   /* Construct the API message */
14349   M (ONE_ADD_DEL_LOCATOR, mp);
14350
14351   mp->is_add = is_add;
14352   mp->sw_if_index = ntohl (sw_if_index);
14353   mp->priority = priority;
14354   mp->weight = weight;
14355   clib_memcpy (mp->locator_set_name, locator_set_name,
14356                vec_len (locator_set_name));
14357   vec_free (locator_set_name);
14358
14359   /* send it... */
14360   S (mp);
14361
14362   /* Wait for a reply... */
14363   W (ret);
14364   return ret;
14365 }
14366
14367 #define api_lisp_add_del_locator api_one_add_del_locator
14368
14369 uword
14370 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
14371 {
14372   u32 *key_id = va_arg (*args, u32 *);
14373   u8 *s = 0;
14374
14375   if (unformat (input, "%s", &s))
14376     {
14377       if (!strcmp ((char *) s, "sha1"))
14378         key_id[0] = HMAC_SHA_1_96;
14379       else if (!strcmp ((char *) s, "sha256"))
14380         key_id[0] = HMAC_SHA_256_128;
14381       else
14382         {
14383           clib_warning ("invalid key_id: '%s'", s);
14384           key_id[0] = HMAC_NO_KEY;
14385         }
14386     }
14387   else
14388     return 0;
14389
14390   vec_free (s);
14391   return 1;
14392 }
14393
14394 static int
14395 api_one_add_del_local_eid (vat_main_t * vam)
14396 {
14397   unformat_input_t *input = vam->input;
14398   vl_api_one_add_del_local_eid_t *mp;
14399   u8 is_add = 1;
14400   u8 eid_set = 0;
14401   lisp_eid_vat_t _eid, *eid = &_eid;
14402   u8 *locator_set_name = 0;
14403   u8 locator_set_name_set = 0;
14404   u32 vni = 0;
14405   u16 key_id = 0;
14406   u8 *key = 0;
14407   int ret;
14408
14409   /* Parse args required to build the message */
14410   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14411     {
14412       if (unformat (input, "del"))
14413         {
14414           is_add = 0;
14415         }
14416       else if (unformat (input, "vni %d", &vni))
14417         {
14418           ;
14419         }
14420       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
14421         {
14422           eid_set = 1;
14423         }
14424       else if (unformat (input, "locator-set %s", &locator_set_name))
14425         {
14426           locator_set_name_set = 1;
14427         }
14428       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
14429         ;
14430       else if (unformat (input, "secret-key %_%v%_", &key))
14431         ;
14432       else
14433         break;
14434     }
14435
14436   if (locator_set_name_set == 0)
14437     {
14438       errmsg ("missing locator-set name");
14439       return -99;
14440     }
14441
14442   if (0 == eid_set)
14443     {
14444       errmsg ("EID address not set!");
14445       vec_free (locator_set_name);
14446       return -99;
14447     }
14448
14449   if (key && (0 == key_id))
14450     {
14451       errmsg ("invalid key_id!");
14452       return -99;
14453     }
14454
14455   if (vec_len (key) > 64)
14456     {
14457       errmsg ("key too long");
14458       vec_free (key);
14459       return -99;
14460     }
14461
14462   if (vec_len (locator_set_name) > 64)
14463     {
14464       errmsg ("locator-set name too long");
14465       vec_free (locator_set_name);
14466       return -99;
14467     }
14468   vec_add1 (locator_set_name, 0);
14469
14470   /* Construct the API message */
14471   M (ONE_ADD_DEL_LOCAL_EID, mp);
14472
14473   mp->is_add = is_add;
14474   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
14475   mp->eid_type = eid->type;
14476   mp->prefix_len = eid->len;
14477   mp->vni = clib_host_to_net_u32 (vni);
14478   mp->key_id = clib_host_to_net_u16 (key_id);
14479   clib_memcpy (mp->locator_set_name, locator_set_name,
14480                vec_len (locator_set_name));
14481   clib_memcpy (mp->key, key, vec_len (key));
14482
14483   vec_free (locator_set_name);
14484   vec_free (key);
14485
14486   /* send it... */
14487   S (mp);
14488
14489   /* Wait for a reply... */
14490   W (ret);
14491   return ret;
14492 }
14493
14494 #define api_lisp_add_del_local_eid api_one_add_del_local_eid
14495
14496 static int
14497 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
14498 {
14499   u32 dp_table = 0, vni = 0;;
14500   unformat_input_t *input = vam->input;
14501   vl_api_gpe_add_del_fwd_entry_t *mp;
14502   u8 is_add = 1;
14503   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
14504   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
14505   u8 rmt_eid_set = 0, lcl_eid_set = 0;
14506   u32 action = ~0, w;
14507   ip4_address_t rmt_rloc4, lcl_rloc4;
14508   ip6_address_t rmt_rloc6, lcl_rloc6;
14509   vl_api_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
14510   int ret;
14511
14512   clib_memset (&rloc, 0, sizeof (rloc));
14513
14514   /* Parse args required to build the message */
14515   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14516     {
14517       if (unformat (input, "del"))
14518         is_add = 0;
14519       else if (unformat (input, "add"))
14520         is_add = 1;
14521       else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
14522         {
14523           rmt_eid_set = 1;
14524         }
14525       else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
14526         {
14527           lcl_eid_set = 1;
14528         }
14529       else if (unformat (input, "vrf %d", &dp_table))
14530         ;
14531       else if (unformat (input, "bd %d", &dp_table))
14532         ;
14533       else if (unformat (input, "vni %d", &vni))
14534         ;
14535       else if (unformat (input, "w %d", &w))
14536         {
14537           if (!curr_rloc)
14538             {
14539               errmsg ("No RLOC configured for setting priority/weight!");
14540               return -99;
14541             }
14542           curr_rloc->weight = w;
14543         }
14544       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
14545                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
14546         {
14547           rloc.is_ip4 = 1;
14548
14549           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
14550           rloc.weight = 0;
14551           vec_add1 (lcl_locs, rloc);
14552
14553           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
14554           vec_add1 (rmt_locs, rloc);
14555           /* weight saved in rmt loc */
14556           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
14557         }
14558       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
14559                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
14560         {
14561           rloc.is_ip4 = 0;
14562           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
14563           rloc.weight = 0;
14564           vec_add1 (lcl_locs, rloc);
14565
14566           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
14567           vec_add1 (rmt_locs, rloc);
14568           /* weight saved in rmt loc */
14569           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
14570         }
14571       else if (unformat (input, "action %d", &action))
14572         {
14573           ;
14574         }
14575       else
14576         {
14577           clib_warning ("parse error '%U'", format_unformat_error, input);
14578           return -99;
14579         }
14580     }
14581
14582   if (!rmt_eid_set)
14583     {
14584       errmsg ("remote eid addresses not set");
14585       return -99;
14586     }
14587
14588   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
14589     {
14590       errmsg ("eid types don't match");
14591       return -99;
14592     }
14593
14594   if (0 == rmt_locs && (u32) ~ 0 == action)
14595     {
14596       errmsg ("action not set for negative mapping");
14597       return -99;
14598     }
14599
14600   /* Construct the API message */
14601   M2 (GPE_ADD_DEL_FWD_ENTRY, mp,
14602       sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs) * 2);
14603
14604   mp->is_add = is_add;
14605   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
14606   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
14607   mp->eid_type = rmt_eid->type;
14608   mp->dp_table = clib_host_to_net_u32 (dp_table);
14609   mp->vni = clib_host_to_net_u32 (vni);
14610   mp->rmt_len = rmt_eid->len;
14611   mp->lcl_len = lcl_eid->len;
14612   mp->action = action;
14613
14614   if (0 != rmt_locs && 0 != lcl_locs)
14615     {
14616       mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
14617       clib_memcpy (mp->locs, lcl_locs,
14618                    (sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs)));
14619
14620       u32 offset = sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs);
14621       clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
14622                    (sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs)));
14623     }
14624   vec_free (lcl_locs);
14625   vec_free (rmt_locs);
14626
14627   /* send it... */
14628   S (mp);
14629
14630   /* Wait for a reply... */
14631   W (ret);
14632   return ret;
14633 }
14634
14635 static int
14636 api_one_add_del_map_server (vat_main_t * vam)
14637 {
14638   unformat_input_t *input = vam->input;
14639   vl_api_one_add_del_map_server_t *mp;
14640   u8 is_add = 1;
14641   u8 ipv4_set = 0;
14642   u8 ipv6_set = 0;
14643   ip4_address_t ipv4;
14644   ip6_address_t ipv6;
14645   int ret;
14646
14647   /* Parse args required to build the message */
14648   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14649     {
14650       if (unformat (input, "del"))
14651         {
14652           is_add = 0;
14653         }
14654       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
14655         {
14656           ipv4_set = 1;
14657         }
14658       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
14659         {
14660           ipv6_set = 1;
14661         }
14662       else
14663         break;
14664     }
14665
14666   if (ipv4_set && ipv6_set)
14667     {
14668       errmsg ("both eid v4 and v6 addresses set");
14669       return -99;
14670     }
14671
14672   if (!ipv4_set && !ipv6_set)
14673     {
14674       errmsg ("eid addresses not set");
14675       return -99;
14676     }
14677
14678   /* Construct the API message */
14679   M (ONE_ADD_DEL_MAP_SERVER, mp);
14680
14681   mp->is_add = is_add;
14682   if (ipv6_set)
14683     {
14684       mp->is_ipv6 = 1;
14685       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
14686     }
14687   else
14688     {
14689       mp->is_ipv6 = 0;
14690       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
14691     }
14692
14693   /* send it... */
14694   S (mp);
14695
14696   /* Wait for a reply... */
14697   W (ret);
14698   return ret;
14699 }
14700
14701 #define api_lisp_add_del_map_server api_one_add_del_map_server
14702
14703 static int
14704 api_one_add_del_map_resolver (vat_main_t * vam)
14705 {
14706   unformat_input_t *input = vam->input;
14707   vl_api_one_add_del_map_resolver_t *mp;
14708   u8 is_add = 1;
14709   u8 ipv4_set = 0;
14710   u8 ipv6_set = 0;
14711   ip4_address_t ipv4;
14712   ip6_address_t ipv6;
14713   int ret;
14714
14715   /* Parse args required to build the message */
14716   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14717     {
14718       if (unformat (input, "del"))
14719         {
14720           is_add = 0;
14721         }
14722       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
14723         {
14724           ipv4_set = 1;
14725         }
14726       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
14727         {
14728           ipv6_set = 1;
14729         }
14730       else
14731         break;
14732     }
14733
14734   if (ipv4_set && ipv6_set)
14735     {
14736       errmsg ("both eid v4 and v6 addresses set");
14737       return -99;
14738     }
14739
14740   if (!ipv4_set && !ipv6_set)
14741     {
14742       errmsg ("eid addresses not set");
14743       return -99;
14744     }
14745
14746   /* Construct the API message */
14747   M (ONE_ADD_DEL_MAP_RESOLVER, mp);
14748
14749   mp->is_add = is_add;
14750   if (ipv6_set)
14751     {
14752       mp->is_ipv6 = 1;
14753       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
14754     }
14755   else
14756     {
14757       mp->is_ipv6 = 0;
14758       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
14759     }
14760
14761   /* send it... */
14762   S (mp);
14763
14764   /* Wait for a reply... */
14765   W (ret);
14766   return ret;
14767 }
14768
14769 #define api_lisp_add_del_map_resolver api_one_add_del_map_resolver
14770
14771 static int
14772 api_lisp_gpe_enable_disable (vat_main_t * vam)
14773 {
14774   unformat_input_t *input = vam->input;
14775   vl_api_gpe_enable_disable_t *mp;
14776   u8 is_set = 0;
14777   u8 is_en = 1;
14778   int ret;
14779
14780   /* Parse args required to build the message */
14781   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14782     {
14783       if (unformat (input, "enable"))
14784         {
14785           is_set = 1;
14786           is_en = 1;
14787         }
14788       else if (unformat (input, "disable"))
14789         {
14790           is_set = 1;
14791           is_en = 0;
14792         }
14793       else
14794         break;
14795     }
14796
14797   if (is_set == 0)
14798     {
14799       errmsg ("Value not set");
14800       return -99;
14801     }
14802
14803   /* Construct the API message */
14804   M (GPE_ENABLE_DISABLE, mp);
14805
14806   mp->is_en = is_en;
14807
14808   /* send it... */
14809   S (mp);
14810
14811   /* Wait for a reply... */
14812   W (ret);
14813   return ret;
14814 }
14815
14816 static int
14817 api_one_rloc_probe_enable_disable (vat_main_t * vam)
14818 {
14819   unformat_input_t *input = vam->input;
14820   vl_api_one_rloc_probe_enable_disable_t *mp;
14821   u8 is_set = 0;
14822   u8 is_en = 0;
14823   int ret;
14824
14825   /* Parse args required to build the message */
14826   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14827     {
14828       if (unformat (input, "enable"))
14829         {
14830           is_set = 1;
14831           is_en = 1;
14832         }
14833       else if (unformat (input, "disable"))
14834         is_set = 1;
14835       else
14836         break;
14837     }
14838
14839   if (!is_set)
14840     {
14841       errmsg ("Value not set");
14842       return -99;
14843     }
14844
14845   /* Construct the API message */
14846   M (ONE_RLOC_PROBE_ENABLE_DISABLE, mp);
14847
14848   mp->is_enabled = is_en;
14849
14850   /* send it... */
14851   S (mp);
14852
14853   /* Wait for a reply... */
14854   W (ret);
14855   return ret;
14856 }
14857
14858 #define api_lisp_rloc_probe_enable_disable api_one_rloc_probe_enable_disable
14859
14860 static int
14861 api_one_map_register_enable_disable (vat_main_t * vam)
14862 {
14863   unformat_input_t *input = vam->input;
14864   vl_api_one_map_register_enable_disable_t *mp;
14865   u8 is_set = 0;
14866   u8 is_en = 0;
14867   int ret;
14868
14869   /* Parse args required to build the message */
14870   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14871     {
14872       if (unformat (input, "enable"))
14873         {
14874           is_set = 1;
14875           is_en = 1;
14876         }
14877       else if (unformat (input, "disable"))
14878         is_set = 1;
14879       else
14880         break;
14881     }
14882
14883   if (!is_set)
14884     {
14885       errmsg ("Value not set");
14886       return -99;
14887     }
14888
14889   /* Construct the API message */
14890   M (ONE_MAP_REGISTER_ENABLE_DISABLE, mp);
14891
14892   mp->is_enabled = is_en;
14893
14894   /* send it... */
14895   S (mp);
14896
14897   /* Wait for a reply... */
14898   W (ret);
14899   return ret;
14900 }
14901
14902 #define api_lisp_map_register_enable_disable api_one_map_register_enable_disable
14903
14904 static int
14905 api_one_enable_disable (vat_main_t * vam)
14906 {
14907   unformat_input_t *input = vam->input;
14908   vl_api_one_enable_disable_t *mp;
14909   u8 is_set = 0;
14910   u8 is_en = 0;
14911   int ret;
14912
14913   /* Parse args required to build the message */
14914   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14915     {
14916       if (unformat (input, "enable"))
14917         {
14918           is_set = 1;
14919           is_en = 1;
14920         }
14921       else if (unformat (input, "disable"))
14922         {
14923           is_set = 1;
14924         }
14925       else
14926         break;
14927     }
14928
14929   if (!is_set)
14930     {
14931       errmsg ("Value not set");
14932       return -99;
14933     }
14934
14935   /* Construct the API message */
14936   M (ONE_ENABLE_DISABLE, mp);
14937
14938   mp->is_en = is_en;
14939
14940   /* send it... */
14941   S (mp);
14942
14943   /* Wait for a reply... */
14944   W (ret);
14945   return ret;
14946 }
14947
14948 #define api_lisp_enable_disable api_one_enable_disable
14949
14950 static int
14951 api_one_enable_disable_xtr_mode (vat_main_t * vam)
14952 {
14953   unformat_input_t *input = vam->input;
14954   vl_api_one_enable_disable_xtr_mode_t *mp;
14955   u8 is_set = 0;
14956   u8 is_en = 0;
14957   int ret;
14958
14959   /* Parse args required to build the message */
14960   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14961     {
14962       if (unformat (input, "enable"))
14963         {
14964           is_set = 1;
14965           is_en = 1;
14966         }
14967       else if (unformat (input, "disable"))
14968         {
14969           is_set = 1;
14970         }
14971       else
14972         break;
14973     }
14974
14975   if (!is_set)
14976     {
14977       errmsg ("Value not set");
14978       return -99;
14979     }
14980
14981   /* Construct the API message */
14982   M (ONE_ENABLE_DISABLE_XTR_MODE, mp);
14983
14984   mp->is_en = is_en;
14985
14986   /* send it... */
14987   S (mp);
14988
14989   /* Wait for a reply... */
14990   W (ret);
14991   return ret;
14992 }
14993
14994 static int
14995 api_one_show_xtr_mode (vat_main_t * vam)
14996 {
14997   vl_api_one_show_xtr_mode_t *mp;
14998   int ret;
14999
15000   /* Construct the API message */
15001   M (ONE_SHOW_XTR_MODE, mp);
15002
15003   /* send it... */
15004   S (mp);
15005
15006   /* Wait for a reply... */
15007   W (ret);
15008   return ret;
15009 }
15010
15011 static int
15012 api_one_enable_disable_pitr_mode (vat_main_t * vam)
15013 {
15014   unformat_input_t *input = vam->input;
15015   vl_api_one_enable_disable_pitr_mode_t *mp;
15016   u8 is_set = 0;
15017   u8 is_en = 0;
15018   int ret;
15019
15020   /* Parse args required to build the message */
15021   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15022     {
15023       if (unformat (input, "enable"))
15024         {
15025           is_set = 1;
15026           is_en = 1;
15027         }
15028       else if (unformat (input, "disable"))
15029         {
15030           is_set = 1;
15031         }
15032       else
15033         break;
15034     }
15035
15036   if (!is_set)
15037     {
15038       errmsg ("Value not set");
15039       return -99;
15040     }
15041
15042   /* Construct the API message */
15043   M (ONE_ENABLE_DISABLE_PITR_MODE, mp);
15044
15045   mp->is_en = is_en;
15046
15047   /* send it... */
15048   S (mp);
15049
15050   /* Wait for a reply... */
15051   W (ret);
15052   return ret;
15053 }
15054
15055 static int
15056 api_one_show_pitr_mode (vat_main_t * vam)
15057 {
15058   vl_api_one_show_pitr_mode_t *mp;
15059   int ret;
15060
15061   /* Construct the API message */
15062   M (ONE_SHOW_PITR_MODE, mp);
15063
15064   /* send it... */
15065   S (mp);
15066
15067   /* Wait for a reply... */
15068   W (ret);
15069   return ret;
15070 }
15071
15072 static int
15073 api_one_enable_disable_petr_mode (vat_main_t * vam)
15074 {
15075   unformat_input_t *input = vam->input;
15076   vl_api_one_enable_disable_petr_mode_t *mp;
15077   u8 is_set = 0;
15078   u8 is_en = 0;
15079   int ret;
15080
15081   /* Parse args required to build the message */
15082   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15083     {
15084       if (unformat (input, "enable"))
15085         {
15086           is_set = 1;
15087           is_en = 1;
15088         }
15089       else if (unformat (input, "disable"))
15090         {
15091           is_set = 1;
15092         }
15093       else
15094         break;
15095     }
15096
15097   if (!is_set)
15098     {
15099       errmsg ("Value not set");
15100       return -99;
15101     }
15102
15103   /* Construct the API message */
15104   M (ONE_ENABLE_DISABLE_PETR_MODE, mp);
15105
15106   mp->is_en = is_en;
15107
15108   /* send it... */
15109   S (mp);
15110
15111   /* Wait for a reply... */
15112   W (ret);
15113   return ret;
15114 }
15115
15116 static int
15117 api_one_show_petr_mode (vat_main_t * vam)
15118 {
15119   vl_api_one_show_petr_mode_t *mp;
15120   int ret;
15121
15122   /* Construct the API message */
15123   M (ONE_SHOW_PETR_MODE, mp);
15124
15125   /* send it... */
15126   S (mp);
15127
15128   /* Wait for a reply... */
15129   W (ret);
15130   return ret;
15131 }
15132
15133 static int
15134 api_show_one_map_register_state (vat_main_t * vam)
15135 {
15136   vl_api_show_one_map_register_state_t *mp;
15137   int ret;
15138
15139   M (SHOW_ONE_MAP_REGISTER_STATE, mp);
15140
15141   /* send */
15142   S (mp);
15143
15144   /* wait for reply */
15145   W (ret);
15146   return ret;
15147 }
15148
15149 #define api_show_lisp_map_register_state api_show_one_map_register_state
15150
15151 static int
15152 api_show_one_rloc_probe_state (vat_main_t * vam)
15153 {
15154   vl_api_show_one_rloc_probe_state_t *mp;
15155   int ret;
15156
15157   M (SHOW_ONE_RLOC_PROBE_STATE, mp);
15158
15159   /* send */
15160   S (mp);
15161
15162   /* wait for reply */
15163   W (ret);
15164   return ret;
15165 }
15166
15167 #define api_show_lisp_rloc_probe_state api_show_one_rloc_probe_state
15168
15169 static int
15170 api_one_add_del_ndp_entry (vat_main_t * vam)
15171 {
15172   vl_api_one_add_del_ndp_entry_t *mp;
15173   unformat_input_t *input = vam->input;
15174   u8 is_add = 1;
15175   u8 mac_set = 0;
15176   u8 bd_set = 0;
15177   u8 ip_set = 0;
15178   u8 mac[6] = { 0, };
15179   u8 ip6[16] = { 0, };
15180   u32 bd = ~0;
15181   int ret;
15182
15183   /* Parse args required to build the message */
15184   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15185     {
15186       if (unformat (input, "del"))
15187         is_add = 0;
15188       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
15189         mac_set = 1;
15190       else if (unformat (input, "ip %U", unformat_ip6_address, ip6))
15191         ip_set = 1;
15192       else if (unformat (input, "bd %d", &bd))
15193         bd_set = 1;
15194       else
15195         {
15196           errmsg ("parse error '%U'", format_unformat_error, input);
15197           return -99;
15198         }
15199     }
15200
15201   if (!bd_set || !ip_set || (!mac_set && is_add))
15202     {
15203       errmsg ("Missing BD, IP or MAC!");
15204       return -99;
15205     }
15206
15207   M (ONE_ADD_DEL_NDP_ENTRY, mp);
15208   mp->is_add = is_add;
15209   clib_memcpy (mp->mac, mac, 6);
15210   mp->bd = clib_host_to_net_u32 (bd);
15211   clib_memcpy (mp->ip6, ip6, sizeof (mp->ip6));
15212
15213   /* send */
15214   S (mp);
15215
15216   /* wait for reply */
15217   W (ret);
15218   return ret;
15219 }
15220
15221 static int
15222 api_one_add_del_l2_arp_entry (vat_main_t * vam)
15223 {
15224   vl_api_one_add_del_l2_arp_entry_t *mp;
15225   unformat_input_t *input = vam->input;
15226   u8 is_add = 1;
15227   u8 mac_set = 0;
15228   u8 bd_set = 0;
15229   u8 ip_set = 0;
15230   u8 mac[6] = { 0, };
15231   u32 ip4 = 0, bd = ~0;
15232   int ret;
15233
15234   /* Parse args required to build the message */
15235   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15236     {
15237       if (unformat (input, "del"))
15238         is_add = 0;
15239       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
15240         mac_set = 1;
15241       else if (unformat (input, "ip %U", unformat_ip4_address, &ip4))
15242         ip_set = 1;
15243       else if (unformat (input, "bd %d", &bd))
15244         bd_set = 1;
15245       else
15246         {
15247           errmsg ("parse error '%U'", format_unformat_error, input);
15248           return -99;
15249         }
15250     }
15251
15252   if (!bd_set || !ip_set || (!mac_set && is_add))
15253     {
15254       errmsg ("Missing BD, IP or MAC!");
15255       return -99;
15256     }
15257
15258   M (ONE_ADD_DEL_L2_ARP_ENTRY, mp);
15259   mp->is_add = is_add;
15260   clib_memcpy (mp->mac, mac, 6);
15261   mp->bd = clib_host_to_net_u32 (bd);
15262   mp->ip4 = ip4;
15263
15264   /* send */
15265   S (mp);
15266
15267   /* wait for reply */
15268   W (ret);
15269   return ret;
15270 }
15271
15272 static int
15273 api_one_ndp_bd_get (vat_main_t * vam)
15274 {
15275   vl_api_one_ndp_bd_get_t *mp;
15276   int ret;
15277
15278   M (ONE_NDP_BD_GET, mp);
15279
15280   /* send */
15281   S (mp);
15282
15283   /* wait for reply */
15284   W (ret);
15285   return ret;
15286 }
15287
15288 static int
15289 api_one_ndp_entries_get (vat_main_t * vam)
15290 {
15291   vl_api_one_ndp_entries_get_t *mp;
15292   unformat_input_t *input = vam->input;
15293   u8 bd_set = 0;
15294   u32 bd = ~0;
15295   int ret;
15296
15297   /* Parse args required to build the message */
15298   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15299     {
15300       if (unformat (input, "bd %d", &bd))
15301         bd_set = 1;
15302       else
15303         {
15304           errmsg ("parse error '%U'", format_unformat_error, input);
15305           return -99;
15306         }
15307     }
15308
15309   if (!bd_set)
15310     {
15311       errmsg ("Expected bridge domain!");
15312       return -99;
15313     }
15314
15315   M (ONE_NDP_ENTRIES_GET, mp);
15316   mp->bd = clib_host_to_net_u32 (bd);
15317
15318   /* send */
15319   S (mp);
15320
15321   /* wait for reply */
15322   W (ret);
15323   return ret;
15324 }
15325
15326 static int
15327 api_one_l2_arp_bd_get (vat_main_t * vam)
15328 {
15329   vl_api_one_l2_arp_bd_get_t *mp;
15330   int ret;
15331
15332   M (ONE_L2_ARP_BD_GET, mp);
15333
15334   /* send */
15335   S (mp);
15336
15337   /* wait for reply */
15338   W (ret);
15339   return ret;
15340 }
15341
15342 static int
15343 api_one_l2_arp_entries_get (vat_main_t * vam)
15344 {
15345   vl_api_one_l2_arp_entries_get_t *mp;
15346   unformat_input_t *input = vam->input;
15347   u8 bd_set = 0;
15348   u32 bd = ~0;
15349   int ret;
15350
15351   /* Parse args required to build the message */
15352   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15353     {
15354       if (unformat (input, "bd %d", &bd))
15355         bd_set = 1;
15356       else
15357         {
15358           errmsg ("parse error '%U'", format_unformat_error, input);
15359           return -99;
15360         }
15361     }
15362
15363   if (!bd_set)
15364     {
15365       errmsg ("Expected bridge domain!");
15366       return -99;
15367     }
15368
15369   M (ONE_L2_ARP_ENTRIES_GET, mp);
15370   mp->bd = clib_host_to_net_u32 (bd);
15371
15372   /* send */
15373   S (mp);
15374
15375   /* wait for reply */
15376   W (ret);
15377   return ret;
15378 }
15379
15380 static int
15381 api_one_stats_enable_disable (vat_main_t * vam)
15382 {
15383   vl_api_one_stats_enable_disable_t *mp;
15384   unformat_input_t *input = vam->input;
15385   u8 is_set = 0;
15386   u8 is_en = 0;
15387   int ret;
15388
15389   /* Parse args required to build the message */
15390   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15391     {
15392       if (unformat (input, "enable"))
15393         {
15394           is_set = 1;
15395           is_en = 1;
15396         }
15397       else if (unformat (input, "disable"))
15398         {
15399           is_set = 1;
15400         }
15401       else
15402         break;
15403     }
15404
15405   if (!is_set)
15406     {
15407       errmsg ("Value not set");
15408       return -99;
15409     }
15410
15411   M (ONE_STATS_ENABLE_DISABLE, mp);
15412   mp->is_en = is_en;
15413
15414   /* send */
15415   S (mp);
15416
15417   /* wait for reply */
15418   W (ret);
15419   return ret;
15420 }
15421
15422 static int
15423 api_show_one_stats_enable_disable (vat_main_t * vam)
15424 {
15425   vl_api_show_one_stats_enable_disable_t *mp;
15426   int ret;
15427
15428   M (SHOW_ONE_STATS_ENABLE_DISABLE, mp);
15429
15430   /* send */
15431   S (mp);
15432
15433   /* wait for reply */
15434   W (ret);
15435   return ret;
15436 }
15437
15438 static int
15439 api_show_one_map_request_mode (vat_main_t * vam)
15440 {
15441   vl_api_show_one_map_request_mode_t *mp;
15442   int ret;
15443
15444   M (SHOW_ONE_MAP_REQUEST_MODE, mp);
15445
15446   /* send */
15447   S (mp);
15448
15449   /* wait for reply */
15450   W (ret);
15451   return ret;
15452 }
15453
15454 #define api_show_lisp_map_request_mode api_show_one_map_request_mode
15455
15456 static int
15457 api_one_map_request_mode (vat_main_t * vam)
15458 {
15459   unformat_input_t *input = vam->input;
15460   vl_api_one_map_request_mode_t *mp;
15461   u8 mode = 0;
15462   int ret;
15463
15464   /* Parse args required to build the message */
15465   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15466     {
15467       if (unformat (input, "dst-only"))
15468         mode = 0;
15469       else if (unformat (input, "src-dst"))
15470         mode = 1;
15471       else
15472         {
15473           errmsg ("parse error '%U'", format_unformat_error, input);
15474           return -99;
15475         }
15476     }
15477
15478   M (ONE_MAP_REQUEST_MODE, mp);
15479
15480   mp->mode = mode;
15481
15482   /* send */
15483   S (mp);
15484
15485   /* wait for reply */
15486   W (ret);
15487   return ret;
15488 }
15489
15490 #define api_lisp_map_request_mode api_one_map_request_mode
15491
15492 /**
15493  * Enable/disable ONE proxy ITR.
15494  *
15495  * @param vam vpp API test context
15496  * @return return code
15497  */
15498 static int
15499 api_one_pitr_set_locator_set (vat_main_t * vam)
15500 {
15501   u8 ls_name_set = 0;
15502   unformat_input_t *input = vam->input;
15503   vl_api_one_pitr_set_locator_set_t *mp;
15504   u8 is_add = 1;
15505   u8 *ls_name = 0;
15506   int ret;
15507
15508   /* Parse args required to build the message */
15509   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15510     {
15511       if (unformat (input, "del"))
15512         is_add = 0;
15513       else if (unformat (input, "locator-set %s", &ls_name))
15514         ls_name_set = 1;
15515       else
15516         {
15517           errmsg ("parse error '%U'", format_unformat_error, input);
15518           return -99;
15519         }
15520     }
15521
15522   if (!ls_name_set)
15523     {
15524       errmsg ("locator-set name not set!");
15525       return -99;
15526     }
15527
15528   M (ONE_PITR_SET_LOCATOR_SET, mp);
15529
15530   mp->is_add = is_add;
15531   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
15532   vec_free (ls_name);
15533
15534   /* send */
15535   S (mp);
15536
15537   /* wait for reply */
15538   W (ret);
15539   return ret;
15540 }
15541
15542 #define api_lisp_pitr_set_locator_set api_one_pitr_set_locator_set
15543
15544 static int
15545 api_one_nsh_set_locator_set (vat_main_t * vam)
15546 {
15547   u8 ls_name_set = 0;
15548   unformat_input_t *input = vam->input;
15549   vl_api_one_nsh_set_locator_set_t *mp;
15550   u8 is_add = 1;
15551   u8 *ls_name = 0;
15552   int ret;
15553
15554   /* Parse args required to build the message */
15555   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15556     {
15557       if (unformat (input, "del"))
15558         is_add = 0;
15559       else if (unformat (input, "ls %s", &ls_name))
15560         ls_name_set = 1;
15561       else
15562         {
15563           errmsg ("parse error '%U'", format_unformat_error, input);
15564           return -99;
15565         }
15566     }
15567
15568   if (!ls_name_set && is_add)
15569     {
15570       errmsg ("locator-set name not set!");
15571       return -99;
15572     }
15573
15574   M (ONE_NSH_SET_LOCATOR_SET, mp);
15575
15576   mp->is_add = is_add;
15577   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
15578   vec_free (ls_name);
15579
15580   /* send */
15581   S (mp);
15582
15583   /* wait for reply */
15584   W (ret);
15585   return ret;
15586 }
15587
15588 static int
15589 api_show_one_pitr (vat_main_t * vam)
15590 {
15591   vl_api_show_one_pitr_t *mp;
15592   int ret;
15593
15594   if (!vam->json_output)
15595     {
15596       print (vam->ofp, "%=20s", "lisp status:");
15597     }
15598
15599   M (SHOW_ONE_PITR, mp);
15600   /* send it... */
15601   S (mp);
15602
15603   /* Wait for a reply... */
15604   W (ret);
15605   return ret;
15606 }
15607
15608 #define api_show_lisp_pitr api_show_one_pitr
15609
15610 static int
15611 api_one_use_petr (vat_main_t * vam)
15612 {
15613   unformat_input_t *input = vam->input;
15614   vl_api_one_use_petr_t *mp;
15615   u8 is_add = 0;
15616   ip_address_t ip;
15617   int ret;
15618
15619   clib_memset (&ip, 0, sizeof (ip));
15620
15621   /* Parse args required to build the message */
15622   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15623     {
15624       if (unformat (input, "disable"))
15625         is_add = 0;
15626       else
15627         if (unformat (input, "%U", unformat_ip4_address, &ip_addr_v4 (&ip)))
15628         {
15629           is_add = 1;
15630           ip_addr_version (&ip) = AF_IP4;
15631         }
15632       else
15633         if (unformat (input, "%U", unformat_ip6_address, &ip_addr_v6 (&ip)))
15634         {
15635           is_add = 1;
15636           ip_addr_version (&ip) = AF_IP6;
15637         }
15638       else
15639         {
15640           errmsg ("parse error '%U'", format_unformat_error, input);
15641           return -99;
15642         }
15643     }
15644
15645   M (ONE_USE_PETR, mp);
15646
15647   mp->is_add = is_add;
15648   if (is_add)
15649     {
15650       mp->is_ip4 = ip_addr_version (&ip) == AF_IP4 ? 1 : 0;
15651       if (mp->is_ip4)
15652         clib_memcpy (mp->address, &ip, 4);
15653       else
15654         clib_memcpy (mp->address, &ip, 16);
15655     }
15656
15657   /* send */
15658   S (mp);
15659
15660   /* wait for reply */
15661   W (ret);
15662   return ret;
15663 }
15664
15665 #define api_lisp_use_petr api_one_use_petr
15666
15667 static int
15668 api_show_one_nsh_mapping (vat_main_t * vam)
15669 {
15670   vl_api_show_one_use_petr_t *mp;
15671   int ret;
15672
15673   if (!vam->json_output)
15674     {
15675       print (vam->ofp, "%=20s", "local ONE NSH mapping:");
15676     }
15677
15678   M (SHOW_ONE_NSH_MAPPING, mp);
15679   /* send it... */
15680   S (mp);
15681
15682   /* Wait for a reply... */
15683   W (ret);
15684   return ret;
15685 }
15686
15687 static int
15688 api_show_one_use_petr (vat_main_t * vam)
15689 {
15690   vl_api_show_one_use_petr_t *mp;
15691   int ret;
15692
15693   if (!vam->json_output)
15694     {
15695       print (vam->ofp, "%=20s", "Proxy-ETR status:");
15696     }
15697
15698   M (SHOW_ONE_USE_PETR, mp);
15699   /* send it... */
15700   S (mp);
15701
15702   /* Wait for a reply... */
15703   W (ret);
15704   return ret;
15705 }
15706
15707 #define api_show_lisp_use_petr api_show_one_use_petr
15708
15709 /**
15710  * Add/delete mapping between vni and vrf
15711  */
15712 static int
15713 api_one_eid_table_add_del_map (vat_main_t * vam)
15714 {
15715   unformat_input_t *input = vam->input;
15716   vl_api_one_eid_table_add_del_map_t *mp;
15717   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
15718   u32 vni, vrf, bd_index;
15719   int ret;
15720
15721   /* Parse args required to build the message */
15722   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15723     {
15724       if (unformat (input, "del"))
15725         is_add = 0;
15726       else if (unformat (input, "vrf %d", &vrf))
15727         vrf_set = 1;
15728       else if (unformat (input, "bd_index %d", &bd_index))
15729         bd_index_set = 1;
15730       else if (unformat (input, "vni %d", &vni))
15731         vni_set = 1;
15732       else
15733         break;
15734     }
15735
15736   if (!vni_set || (!vrf_set && !bd_index_set))
15737     {
15738       errmsg ("missing arguments!");
15739       return -99;
15740     }
15741
15742   if (vrf_set && bd_index_set)
15743     {
15744       errmsg ("error: both vrf and bd entered!");
15745       return -99;
15746     }
15747
15748   M (ONE_EID_TABLE_ADD_DEL_MAP, mp);
15749
15750   mp->is_add = is_add;
15751   mp->vni = htonl (vni);
15752   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
15753   mp->is_l2 = bd_index_set;
15754
15755   /* send */
15756   S (mp);
15757
15758   /* wait for reply */
15759   W (ret);
15760   return ret;
15761 }
15762
15763 #define api_lisp_eid_table_add_del_map api_one_eid_table_add_del_map
15764
15765 uword
15766 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
15767 {
15768   u32 *action = va_arg (*args, u32 *);
15769   u8 *s = 0;
15770
15771   if (unformat (input, "%s", &s))
15772     {
15773       if (!strcmp ((char *) s, "no-action"))
15774         action[0] = 0;
15775       else if (!strcmp ((char *) s, "natively-forward"))
15776         action[0] = 1;
15777       else if (!strcmp ((char *) s, "send-map-request"))
15778         action[0] = 2;
15779       else if (!strcmp ((char *) s, "drop"))
15780         action[0] = 3;
15781       else
15782         {
15783           clib_warning ("invalid action: '%s'", s);
15784           action[0] = 3;
15785         }
15786     }
15787   else
15788     return 0;
15789
15790   vec_free (s);
15791   return 1;
15792 }
15793
15794 /**
15795  * Add/del remote mapping to/from ONE control plane
15796  *
15797  * @param vam vpp API test context
15798  * @return return code
15799  */
15800 static int
15801 api_one_add_del_remote_mapping (vat_main_t * vam)
15802 {
15803   unformat_input_t *input = vam->input;
15804   vl_api_one_add_del_remote_mapping_t *mp;
15805   u32 vni = 0;
15806   lisp_eid_vat_t _eid, *eid = &_eid;
15807   lisp_eid_vat_t _seid, *seid = &_seid;
15808   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
15809   u32 action = ~0, p, w, data_len;
15810   ip4_address_t rloc4;
15811   ip6_address_t rloc6;
15812   vl_api_remote_locator_t *rlocs = 0, rloc, *curr_rloc = 0;
15813   int ret;
15814
15815   clib_memset (&rloc, 0, sizeof (rloc));
15816
15817   /* Parse args required to build the message */
15818   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15819     {
15820       if (unformat (input, "del-all"))
15821         {
15822           del_all = 1;
15823         }
15824       else if (unformat (input, "del"))
15825         {
15826           is_add = 0;
15827         }
15828       else if (unformat (input, "add"))
15829         {
15830           is_add = 1;
15831         }
15832       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
15833         {
15834           eid_set = 1;
15835         }
15836       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
15837         {
15838           seid_set = 1;
15839         }
15840       else if (unformat (input, "vni %d", &vni))
15841         {
15842           ;
15843         }
15844       else if (unformat (input, "p %d w %d", &p, &w))
15845         {
15846           if (!curr_rloc)
15847             {
15848               errmsg ("No RLOC configured for setting priority/weight!");
15849               return -99;
15850             }
15851           curr_rloc->priority = p;
15852           curr_rloc->weight = w;
15853         }
15854       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
15855         {
15856           rloc.is_ip4 = 1;
15857           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
15858           vec_add1 (rlocs, rloc);
15859           curr_rloc = &rlocs[vec_len (rlocs) - 1];
15860         }
15861       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
15862         {
15863           rloc.is_ip4 = 0;
15864           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
15865           vec_add1 (rlocs, rloc);
15866           curr_rloc = &rlocs[vec_len (rlocs) - 1];
15867         }
15868       else if (unformat (input, "action %U",
15869                          unformat_negative_mapping_action, &action))
15870         {
15871           ;
15872         }
15873       else
15874         {
15875           clib_warning ("parse error '%U'", format_unformat_error, input);
15876           return -99;
15877         }
15878     }
15879
15880   if (0 == eid_set)
15881     {
15882       errmsg ("missing params!");
15883       return -99;
15884     }
15885
15886   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
15887     {
15888       errmsg ("no action set for negative map-reply!");
15889       return -99;
15890     }
15891
15892   data_len = vec_len (rlocs) * sizeof (vl_api_remote_locator_t);
15893
15894   M2 (ONE_ADD_DEL_REMOTE_MAPPING, mp, data_len);
15895   mp->is_add = is_add;
15896   mp->vni = htonl (vni);
15897   mp->action = (u8) action;
15898   mp->is_src_dst = seid_set;
15899   mp->eid_len = eid->len;
15900   mp->seid_len = seid->len;
15901   mp->del_all = del_all;
15902   mp->eid_type = eid->type;
15903   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
15904   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
15905
15906   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
15907   clib_memcpy (mp->rlocs, rlocs, data_len);
15908   vec_free (rlocs);
15909
15910   /* send it... */
15911   S (mp);
15912
15913   /* Wait for a reply... */
15914   W (ret);
15915   return ret;
15916 }
15917
15918 #define api_lisp_add_del_remote_mapping api_one_add_del_remote_mapping
15919
15920 /**
15921  * Add/del ONE adjacency. Saves mapping in ONE control plane and updates
15922  * forwarding entries in data-plane accordingly.
15923  *
15924  * @param vam vpp API test context
15925  * @return return code
15926  */
15927 static int
15928 api_one_add_del_adjacency (vat_main_t * vam)
15929 {
15930   unformat_input_t *input = vam->input;
15931   vl_api_one_add_del_adjacency_t *mp;
15932   u32 vni = 0;
15933   ip4_address_t leid4, reid4;
15934   ip6_address_t leid6, reid6;
15935   u8 reid_mac[6] = { 0 };
15936   u8 leid_mac[6] = { 0 };
15937   u8 reid_type, leid_type;
15938   u32 leid_len = 0, reid_len = 0, len;
15939   u8 is_add = 1;
15940   int ret;
15941
15942   leid_type = reid_type = (u8) ~ 0;
15943
15944   /* Parse args required to build the message */
15945   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15946     {
15947       if (unformat (input, "del"))
15948         {
15949           is_add = 0;
15950         }
15951       else if (unformat (input, "add"))
15952         {
15953           is_add = 1;
15954         }
15955       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
15956                          &reid4, &len))
15957         {
15958           reid_type = 0;        /* ipv4 */
15959           reid_len = len;
15960         }
15961       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
15962                          &reid6, &len))
15963         {
15964           reid_type = 1;        /* ipv6 */
15965           reid_len = len;
15966         }
15967       else if (unformat (input, "reid %U", unformat_ethernet_address,
15968                          reid_mac))
15969         {
15970           reid_type = 2;        /* mac */
15971         }
15972       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
15973                          &leid4, &len))
15974         {
15975           leid_type = 0;        /* ipv4 */
15976           leid_len = len;
15977         }
15978       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
15979                          &leid6, &len))
15980         {
15981           leid_type = 1;        /* ipv6 */
15982           leid_len = len;
15983         }
15984       else if (unformat (input, "leid %U", unformat_ethernet_address,
15985                          leid_mac))
15986         {
15987           leid_type = 2;        /* mac */
15988         }
15989       else if (unformat (input, "vni %d", &vni))
15990         {
15991           ;
15992         }
15993       else
15994         {
15995           errmsg ("parse error '%U'", format_unformat_error, input);
15996           return -99;
15997         }
15998     }
15999
16000   if ((u8) ~ 0 == reid_type)
16001     {
16002       errmsg ("missing params!");
16003       return -99;
16004     }
16005
16006   if (leid_type != reid_type)
16007     {
16008       errmsg ("remote and local EIDs are of different types!");
16009       return -99;
16010     }
16011
16012   M (ONE_ADD_DEL_ADJACENCY, mp);
16013   mp->is_add = is_add;
16014   mp->vni = htonl (vni);
16015   mp->leid_len = leid_len;
16016   mp->reid_len = reid_len;
16017   mp->eid_type = reid_type;
16018
16019   switch (mp->eid_type)
16020     {
16021     case 0:
16022       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
16023       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
16024       break;
16025     case 1:
16026       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
16027       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
16028       break;
16029     case 2:
16030       clib_memcpy (mp->leid, leid_mac, 6);
16031       clib_memcpy (mp->reid, reid_mac, 6);
16032       break;
16033     default:
16034       errmsg ("unknown EID type %d!", mp->eid_type);
16035       return 0;
16036     }
16037
16038   /* send it... */
16039   S (mp);
16040
16041   /* Wait for a reply... */
16042   W (ret);
16043   return ret;
16044 }
16045
16046 #define api_lisp_add_del_adjacency api_one_add_del_adjacency
16047
16048 uword
16049 unformat_gpe_encap_mode (unformat_input_t * input, va_list * args)
16050 {
16051   u32 *mode = va_arg (*args, u32 *);
16052
16053   if (unformat (input, "lisp"))
16054     *mode = 0;
16055   else if (unformat (input, "vxlan"))
16056     *mode = 1;
16057   else
16058     return 0;
16059
16060   return 1;
16061 }
16062
16063 static int
16064 api_gpe_get_encap_mode (vat_main_t * vam)
16065 {
16066   vl_api_gpe_get_encap_mode_t *mp;
16067   int ret;
16068
16069   /* Construct the API message */
16070   M (GPE_GET_ENCAP_MODE, mp);
16071
16072   /* send it... */
16073   S (mp);
16074
16075   /* Wait for a reply... */
16076   W (ret);
16077   return ret;
16078 }
16079
16080 static int
16081 api_gpe_set_encap_mode (vat_main_t * vam)
16082 {
16083   unformat_input_t *input = vam->input;
16084   vl_api_gpe_set_encap_mode_t *mp;
16085   int ret;
16086   u32 mode = 0;
16087
16088   /* Parse args required to build the message */
16089   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16090     {
16091       if (unformat (input, "%U", unformat_gpe_encap_mode, &mode))
16092         ;
16093       else
16094         break;
16095     }
16096
16097   /* Construct the API message */
16098   M (GPE_SET_ENCAP_MODE, mp);
16099
16100   mp->mode = mode;
16101
16102   /* send it... */
16103   S (mp);
16104
16105   /* Wait for a reply... */
16106   W (ret);
16107   return ret;
16108 }
16109
16110 static int
16111 api_lisp_gpe_add_del_iface (vat_main_t * vam)
16112 {
16113   unformat_input_t *input = vam->input;
16114   vl_api_gpe_add_del_iface_t *mp;
16115   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
16116   u32 dp_table = 0, vni = 0;
16117   int ret;
16118
16119   /* Parse args required to build the message */
16120   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16121     {
16122       if (unformat (input, "up"))
16123         {
16124           action_set = 1;
16125           is_add = 1;
16126         }
16127       else if (unformat (input, "down"))
16128         {
16129           action_set = 1;
16130           is_add = 0;
16131         }
16132       else if (unformat (input, "table_id %d", &dp_table))
16133         {
16134           dp_table_set = 1;
16135         }
16136       else if (unformat (input, "bd_id %d", &dp_table))
16137         {
16138           dp_table_set = 1;
16139           is_l2 = 1;
16140         }
16141       else if (unformat (input, "vni %d", &vni))
16142         {
16143           vni_set = 1;
16144         }
16145       else
16146         break;
16147     }
16148
16149   if (action_set == 0)
16150     {
16151       errmsg ("Action not set");
16152       return -99;
16153     }
16154   if (dp_table_set == 0 || vni_set == 0)
16155     {
16156       errmsg ("vni and dp_table must be set");
16157       return -99;
16158     }
16159
16160   /* Construct the API message */
16161   M (GPE_ADD_DEL_IFACE, mp);
16162
16163   mp->is_add = is_add;
16164   mp->dp_table = clib_host_to_net_u32 (dp_table);
16165   mp->is_l2 = is_l2;
16166   mp->vni = clib_host_to_net_u32 (vni);
16167
16168   /* send it... */
16169   S (mp);
16170
16171   /* Wait for a reply... */
16172   W (ret);
16173   return ret;
16174 }
16175
16176 static int
16177 api_one_map_register_fallback_threshold (vat_main_t * vam)
16178 {
16179   unformat_input_t *input = vam->input;
16180   vl_api_one_map_register_fallback_threshold_t *mp;
16181   u32 value = 0;
16182   u8 is_set = 0;
16183   int ret;
16184
16185   /* Parse args required to build the message */
16186   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16187     {
16188       if (unformat (input, "%u", &value))
16189         is_set = 1;
16190       else
16191         {
16192           clib_warning ("parse error '%U'", format_unformat_error, input);
16193           return -99;
16194         }
16195     }
16196
16197   if (!is_set)
16198     {
16199       errmsg ("fallback threshold value is missing!");
16200       return -99;
16201     }
16202
16203   M (ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
16204   mp->value = clib_host_to_net_u32 (value);
16205
16206   /* send it... */
16207   S (mp);
16208
16209   /* Wait for a reply... */
16210   W (ret);
16211   return ret;
16212 }
16213
16214 static int
16215 api_show_one_map_register_fallback_threshold (vat_main_t * vam)
16216 {
16217   vl_api_show_one_map_register_fallback_threshold_t *mp;
16218   int ret;
16219
16220   M (SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
16221
16222   /* send it... */
16223   S (mp);
16224
16225   /* Wait for a reply... */
16226   W (ret);
16227   return ret;
16228 }
16229
16230 uword
16231 unformat_lisp_transport_protocol (unformat_input_t * input, va_list * args)
16232 {
16233   u32 *proto = va_arg (*args, u32 *);
16234
16235   if (unformat (input, "udp"))
16236     *proto = 1;
16237   else if (unformat (input, "api"))
16238     *proto = 2;
16239   else
16240     return 0;
16241
16242   return 1;
16243 }
16244
16245 static int
16246 api_one_set_transport_protocol (vat_main_t * vam)
16247 {
16248   unformat_input_t *input = vam->input;
16249   vl_api_one_set_transport_protocol_t *mp;
16250   u8 is_set = 0;
16251   u32 protocol = 0;
16252   int ret;
16253
16254   /* Parse args required to build the message */
16255   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16256     {
16257       if (unformat (input, "%U", unformat_lisp_transport_protocol, &protocol))
16258         is_set = 1;
16259       else
16260         {
16261           clib_warning ("parse error '%U'", format_unformat_error, input);
16262           return -99;
16263         }
16264     }
16265
16266   if (!is_set)
16267     {
16268       errmsg ("Transport protocol missing!");
16269       return -99;
16270     }
16271
16272   M (ONE_SET_TRANSPORT_PROTOCOL, mp);
16273   mp->protocol = (u8) protocol;
16274
16275   /* send it... */
16276   S (mp);
16277
16278   /* Wait for a reply... */
16279   W (ret);
16280   return ret;
16281 }
16282
16283 static int
16284 api_one_get_transport_protocol (vat_main_t * vam)
16285 {
16286   vl_api_one_get_transport_protocol_t *mp;
16287   int ret;
16288
16289   M (ONE_GET_TRANSPORT_PROTOCOL, mp);
16290
16291   /* send it... */
16292   S (mp);
16293
16294   /* Wait for a reply... */
16295   W (ret);
16296   return ret;
16297 }
16298
16299 static int
16300 api_one_map_register_set_ttl (vat_main_t * vam)
16301 {
16302   unformat_input_t *input = vam->input;
16303   vl_api_one_map_register_set_ttl_t *mp;
16304   u32 ttl = 0;
16305   u8 is_set = 0;
16306   int ret;
16307
16308   /* Parse args required to build the message */
16309   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16310     {
16311       if (unformat (input, "%u", &ttl))
16312         is_set = 1;
16313       else
16314         {
16315           clib_warning ("parse error '%U'", format_unformat_error, input);
16316           return -99;
16317         }
16318     }
16319
16320   if (!is_set)
16321     {
16322       errmsg ("TTL value missing!");
16323       return -99;
16324     }
16325
16326   M (ONE_MAP_REGISTER_SET_TTL, mp);
16327   mp->ttl = clib_host_to_net_u32 (ttl);
16328
16329   /* send it... */
16330   S (mp);
16331
16332   /* Wait for a reply... */
16333   W (ret);
16334   return ret;
16335 }
16336
16337 static int
16338 api_show_one_map_register_ttl (vat_main_t * vam)
16339 {
16340   vl_api_show_one_map_register_ttl_t *mp;
16341   int ret;
16342
16343   M (SHOW_ONE_MAP_REGISTER_TTL, mp);
16344
16345   /* send it... */
16346   S (mp);
16347
16348   /* Wait for a reply... */
16349   W (ret);
16350   return ret;
16351 }
16352
16353 /**
16354  * Add/del map request itr rlocs from ONE control plane and updates
16355  *
16356  * @param vam vpp API test context
16357  * @return return code
16358  */
16359 static int
16360 api_one_add_del_map_request_itr_rlocs (vat_main_t * vam)
16361 {
16362   unformat_input_t *input = vam->input;
16363   vl_api_one_add_del_map_request_itr_rlocs_t *mp;
16364   u8 *locator_set_name = 0;
16365   u8 locator_set_name_set = 0;
16366   u8 is_add = 1;
16367   int ret;
16368
16369   /* Parse args required to build the message */
16370   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16371     {
16372       if (unformat (input, "del"))
16373         {
16374           is_add = 0;
16375         }
16376       else if (unformat (input, "%_%v%_", &locator_set_name))
16377         {
16378           locator_set_name_set = 1;
16379         }
16380       else
16381         {
16382           clib_warning ("parse error '%U'", format_unformat_error, input);
16383           return -99;
16384         }
16385     }
16386
16387   if (is_add && !locator_set_name_set)
16388     {
16389       errmsg ("itr-rloc is not set!");
16390       return -99;
16391     }
16392
16393   if (is_add && vec_len (locator_set_name) > 64)
16394     {
16395       errmsg ("itr-rloc locator-set name too long");
16396       vec_free (locator_set_name);
16397       return -99;
16398     }
16399
16400   M (ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS, mp);
16401   mp->is_add = is_add;
16402   if (is_add)
16403     {
16404       clib_memcpy (mp->locator_set_name, locator_set_name,
16405                    vec_len (locator_set_name));
16406     }
16407   else
16408     {
16409       clib_memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
16410     }
16411   vec_free (locator_set_name);
16412
16413   /* send it... */
16414   S (mp);
16415
16416   /* Wait for a reply... */
16417   W (ret);
16418   return ret;
16419 }
16420
16421 #define api_lisp_add_del_map_request_itr_rlocs api_one_add_del_map_request_itr_rlocs
16422
16423 static int
16424 api_one_locator_dump (vat_main_t * vam)
16425 {
16426   unformat_input_t *input = vam->input;
16427   vl_api_one_locator_dump_t *mp;
16428   vl_api_control_ping_t *mp_ping;
16429   u8 is_index_set = 0, is_name_set = 0;
16430   u8 *ls_name = 0;
16431   u32 ls_index = ~0;
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, "ls_name %_%v%_", &ls_name))
16438         {
16439           is_name_set = 1;
16440         }
16441       else if (unformat (input, "ls_index %d", &ls_index))
16442         {
16443           is_index_set = 1;
16444         }
16445       else
16446         {
16447           errmsg ("parse error '%U'", format_unformat_error, input);
16448           return -99;
16449         }
16450     }
16451
16452   if (!is_index_set && !is_name_set)
16453     {
16454       errmsg ("error: expected one of index or name!");
16455       return -99;
16456     }
16457
16458   if (is_index_set && is_name_set)
16459     {
16460       errmsg ("error: only one param expected!");
16461       return -99;
16462     }
16463
16464   if (vec_len (ls_name) > 62)
16465     {
16466       errmsg ("error: locator set name too long!");
16467       return -99;
16468     }
16469
16470   if (!vam->json_output)
16471     {
16472       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
16473     }
16474
16475   M (ONE_LOCATOR_DUMP, mp);
16476   mp->is_index_set = is_index_set;
16477
16478   if (is_index_set)
16479     mp->ls_index = clib_host_to_net_u32 (ls_index);
16480   else
16481     {
16482       vec_add1 (ls_name, 0);
16483       strncpy ((char *) mp->ls_name, (char *) ls_name,
16484                sizeof (mp->ls_name) - 1);
16485     }
16486
16487   /* send it... */
16488   S (mp);
16489
16490   /* Use a control ping for synchronization */
16491   MPING (CONTROL_PING, mp_ping);
16492   S (mp_ping);
16493
16494   /* Wait for a reply... */
16495   W (ret);
16496   return ret;
16497 }
16498
16499 #define api_lisp_locator_dump api_one_locator_dump
16500
16501 static int
16502 api_one_locator_set_dump (vat_main_t * vam)
16503 {
16504   vl_api_one_locator_set_dump_t *mp;
16505   vl_api_control_ping_t *mp_ping;
16506   unformat_input_t *input = vam->input;
16507   u8 filter = 0;
16508   int ret;
16509
16510   /* Parse args required to build the message */
16511   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16512     {
16513       if (unformat (input, "local"))
16514         {
16515           filter = 1;
16516         }
16517       else if (unformat (input, "remote"))
16518         {
16519           filter = 2;
16520         }
16521       else
16522         {
16523           errmsg ("parse error '%U'", format_unformat_error, input);
16524           return -99;
16525         }
16526     }
16527
16528   if (!vam->json_output)
16529     {
16530       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
16531     }
16532
16533   M (ONE_LOCATOR_SET_DUMP, mp);
16534
16535   mp->filter = filter;
16536
16537   /* send it... */
16538   S (mp);
16539
16540   /* Use a control ping for synchronization */
16541   MPING (CONTROL_PING, mp_ping);
16542   S (mp_ping);
16543
16544   /* Wait for a reply... */
16545   W (ret);
16546   return ret;
16547 }
16548
16549 #define api_lisp_locator_set_dump api_one_locator_set_dump
16550
16551 static int
16552 api_one_eid_table_map_dump (vat_main_t * vam)
16553 {
16554   u8 is_l2 = 0;
16555   u8 mode_set = 0;
16556   unformat_input_t *input = vam->input;
16557   vl_api_one_eid_table_map_dump_t *mp;
16558   vl_api_control_ping_t *mp_ping;
16559   int ret;
16560
16561   /* Parse args required to build the message */
16562   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16563     {
16564       if (unformat (input, "l2"))
16565         {
16566           is_l2 = 1;
16567           mode_set = 1;
16568         }
16569       else if (unformat (input, "l3"))
16570         {
16571           is_l2 = 0;
16572           mode_set = 1;
16573         }
16574       else
16575         {
16576           errmsg ("parse error '%U'", format_unformat_error, input);
16577           return -99;
16578         }
16579     }
16580
16581   if (!mode_set)
16582     {
16583       errmsg ("expected one of 'l2' or 'l3' parameter!");
16584       return -99;
16585     }
16586
16587   if (!vam->json_output)
16588     {
16589       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
16590     }
16591
16592   M (ONE_EID_TABLE_MAP_DUMP, mp);
16593   mp->is_l2 = is_l2;
16594
16595   /* send it... */
16596   S (mp);
16597
16598   /* Use a control ping for synchronization */
16599   MPING (CONTROL_PING, mp_ping);
16600   S (mp_ping);
16601
16602   /* Wait for a reply... */
16603   W (ret);
16604   return ret;
16605 }
16606
16607 #define api_lisp_eid_table_map_dump api_one_eid_table_map_dump
16608
16609 static int
16610 api_one_eid_table_vni_dump (vat_main_t * vam)
16611 {
16612   vl_api_one_eid_table_vni_dump_t *mp;
16613   vl_api_control_ping_t *mp_ping;
16614   int ret;
16615
16616   if (!vam->json_output)
16617     {
16618       print (vam->ofp, "VNI");
16619     }
16620
16621   M (ONE_EID_TABLE_VNI_DUMP, mp);
16622
16623   /* send it... */
16624   S (mp);
16625
16626   /* Use a control ping for synchronization */
16627   MPING (CONTROL_PING, mp_ping);
16628   S (mp_ping);
16629
16630   /* Wait for a reply... */
16631   W (ret);
16632   return ret;
16633 }
16634
16635 #define api_lisp_eid_table_vni_dump api_one_eid_table_vni_dump
16636
16637 static int
16638 api_one_eid_table_dump (vat_main_t * vam)
16639 {
16640   unformat_input_t *i = vam->input;
16641   vl_api_one_eid_table_dump_t *mp;
16642   vl_api_control_ping_t *mp_ping;
16643   struct in_addr ip4;
16644   struct in6_addr ip6;
16645   u8 mac[6];
16646   u8 eid_type = ~0, eid_set = 0;
16647   u32 prefix_length = ~0, t, vni = 0;
16648   u8 filter = 0;
16649   int ret;
16650   lisp_nsh_api_t nsh;
16651
16652   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16653     {
16654       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
16655         {
16656           eid_set = 1;
16657           eid_type = 0;
16658           prefix_length = t;
16659         }
16660       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
16661         {
16662           eid_set = 1;
16663           eid_type = 1;
16664           prefix_length = t;
16665         }
16666       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
16667         {
16668           eid_set = 1;
16669           eid_type = 2;
16670         }
16671       else if (unformat (i, "eid %U", unformat_nsh_address, &nsh))
16672         {
16673           eid_set = 1;
16674           eid_type = 3;
16675         }
16676       else if (unformat (i, "vni %d", &t))
16677         {
16678           vni = t;
16679         }
16680       else if (unformat (i, "local"))
16681         {
16682           filter = 1;
16683         }
16684       else if (unformat (i, "remote"))
16685         {
16686           filter = 2;
16687         }
16688       else
16689         {
16690           errmsg ("parse error '%U'", format_unformat_error, i);
16691           return -99;
16692         }
16693     }
16694
16695   if (!vam->json_output)
16696     {
16697       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
16698              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
16699     }
16700
16701   M (ONE_EID_TABLE_DUMP, mp);
16702
16703   mp->filter = filter;
16704   if (eid_set)
16705     {
16706       mp->eid_set = 1;
16707       mp->vni = htonl (vni);
16708       mp->eid_type = eid_type;
16709       switch (eid_type)
16710         {
16711         case 0:
16712           mp->prefix_length = prefix_length;
16713           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
16714           break;
16715         case 1:
16716           mp->prefix_length = prefix_length;
16717           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
16718           break;
16719         case 2:
16720           clib_memcpy (mp->eid, mac, sizeof (mac));
16721           break;
16722         case 3:
16723           clib_memcpy (mp->eid, &nsh, sizeof (nsh));
16724           break;
16725         default:
16726           errmsg ("unknown EID type %d!", eid_type);
16727           return -99;
16728         }
16729     }
16730
16731   /* send it... */
16732   S (mp);
16733
16734   /* Use a control ping for synchronization */
16735   MPING (CONTROL_PING, mp_ping);
16736   S (mp_ping);
16737
16738   /* Wait for a reply... */
16739   W (ret);
16740   return ret;
16741 }
16742
16743 #define api_lisp_eid_table_dump api_one_eid_table_dump
16744
16745 static int
16746 api_lisp_gpe_fwd_entries_get (vat_main_t * vam)
16747 {
16748   unformat_input_t *i = vam->input;
16749   vl_api_gpe_fwd_entries_get_t *mp;
16750   u8 vni_set = 0;
16751   u32 vni = ~0;
16752   int ret;
16753
16754   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16755     {
16756       if (unformat (i, "vni %d", &vni))
16757         {
16758           vni_set = 1;
16759         }
16760       else
16761         {
16762           errmsg ("parse error '%U'", format_unformat_error, i);
16763           return -99;
16764         }
16765     }
16766
16767   if (!vni_set)
16768     {
16769       errmsg ("vni not set!");
16770       return -99;
16771     }
16772
16773   if (!vam->json_output)
16774     {
16775       print (vam->ofp, "%10s %10s %s %40s", "fwd_index", "dp_table",
16776              "leid", "reid");
16777     }
16778
16779   M (GPE_FWD_ENTRIES_GET, mp);
16780   mp->vni = clib_host_to_net_u32 (vni);
16781
16782   /* send it... */
16783   S (mp);
16784
16785   /* Wait for a reply... */
16786   W (ret);
16787   return ret;
16788 }
16789
16790 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_endian vl_noop_handler
16791 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_print vl_noop_handler
16792 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_endian vl_noop_handler
16793 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_print vl_noop_handler
16794 #define vl_api_gpe_fwd_entries_get_reply_t_endian vl_noop_handler
16795 #define vl_api_gpe_fwd_entries_get_reply_t_print vl_noop_handler
16796 #define vl_api_gpe_fwd_entry_path_details_t_endian vl_noop_handler
16797 #define vl_api_gpe_fwd_entry_path_details_t_print vl_noop_handler
16798
16799 static int
16800 api_one_adjacencies_get (vat_main_t * vam)
16801 {
16802   unformat_input_t *i = vam->input;
16803   vl_api_one_adjacencies_get_t *mp;
16804   u8 vni_set = 0;
16805   u32 vni = ~0;
16806   int ret;
16807
16808   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16809     {
16810       if (unformat (i, "vni %d", &vni))
16811         {
16812           vni_set = 1;
16813         }
16814       else
16815         {
16816           errmsg ("parse error '%U'", format_unformat_error, i);
16817           return -99;
16818         }
16819     }
16820
16821   if (!vni_set)
16822     {
16823       errmsg ("vni not set!");
16824       return -99;
16825     }
16826
16827   if (!vam->json_output)
16828     {
16829       print (vam->ofp, "%s %40s", "leid", "reid");
16830     }
16831
16832   M (ONE_ADJACENCIES_GET, mp);
16833   mp->vni = clib_host_to_net_u32 (vni);
16834
16835   /* send it... */
16836   S (mp);
16837
16838   /* Wait for a reply... */
16839   W (ret);
16840   return ret;
16841 }
16842
16843 #define api_lisp_adjacencies_get api_one_adjacencies_get
16844
16845 static int
16846 api_gpe_native_fwd_rpaths_get (vat_main_t * vam)
16847 {
16848   unformat_input_t *i = vam->input;
16849   vl_api_gpe_native_fwd_rpaths_get_t *mp;
16850   int ret;
16851   u8 ip_family_set = 0, is_ip4 = 1;
16852
16853   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16854     {
16855       if (unformat (i, "ip4"))
16856         {
16857           ip_family_set = 1;
16858           is_ip4 = 1;
16859         }
16860       else if (unformat (i, "ip6"))
16861         {
16862           ip_family_set = 1;
16863           is_ip4 = 0;
16864         }
16865       else
16866         {
16867           errmsg ("parse error '%U'", format_unformat_error, i);
16868           return -99;
16869         }
16870     }
16871
16872   if (!ip_family_set)
16873     {
16874       errmsg ("ip family not set!");
16875       return -99;
16876     }
16877
16878   M (GPE_NATIVE_FWD_RPATHS_GET, mp);
16879   mp->is_ip4 = is_ip4;
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_gpe_fwd_entry_vnis_get (vat_main_t * vam)
16891 {
16892   vl_api_gpe_fwd_entry_vnis_get_t *mp;
16893   int ret;
16894
16895   if (!vam->json_output)
16896     {
16897       print (vam->ofp, "VNIs");
16898     }
16899
16900   M (GPE_FWD_ENTRY_VNIS_GET, mp);
16901
16902   /* send it... */
16903   S (mp);
16904
16905   /* Wait for a reply... */
16906   W (ret);
16907   return ret;
16908 }
16909
16910 static int
16911 api_gpe_add_del_native_fwd_rpath (vat_main_t * vam)
16912 {
16913   unformat_input_t *i = vam->input;
16914   vl_api_gpe_add_del_native_fwd_rpath_t *mp;
16915   int ret = 0;
16916   u8 is_add = 1, ip_set = 0, is_ip4 = 1;
16917   struct in_addr ip4;
16918   struct in6_addr ip6;
16919   u32 table_id = 0, nh_sw_if_index = ~0;
16920
16921   clib_memset (&ip4, 0, sizeof (ip4));
16922   clib_memset (&ip6, 0, sizeof (ip6));
16923
16924   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16925     {
16926       if (unformat (i, "del"))
16927         is_add = 0;
16928       else if (unformat (i, "via %U %U", unformat_ip4_address, &ip4,
16929                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
16930         {
16931           ip_set = 1;
16932           is_ip4 = 1;
16933         }
16934       else if (unformat (i, "via %U %U", unformat_ip6_address, &ip6,
16935                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
16936         {
16937           ip_set = 1;
16938           is_ip4 = 0;
16939         }
16940       else if (unformat (i, "via %U", unformat_ip4_address, &ip4))
16941         {
16942           ip_set = 1;
16943           is_ip4 = 1;
16944           nh_sw_if_index = ~0;
16945         }
16946       else if (unformat (i, "via %U", unformat_ip6_address, &ip6))
16947         {
16948           ip_set = 1;
16949           is_ip4 = 0;
16950           nh_sw_if_index = ~0;
16951         }
16952       else if (unformat (i, "table %d", &table_id))
16953         ;
16954       else
16955         {
16956           errmsg ("parse error '%U'", format_unformat_error, i);
16957           return -99;
16958         }
16959     }
16960
16961   if (!ip_set)
16962     {
16963       errmsg ("nh addr not set!");
16964       return -99;
16965     }
16966
16967   M (GPE_ADD_DEL_NATIVE_FWD_RPATH, mp);
16968   mp->is_add = is_add;
16969   mp->table_id = clib_host_to_net_u32 (table_id);
16970   mp->nh_sw_if_index = clib_host_to_net_u32 (nh_sw_if_index);
16971   mp->is_ip4 = is_ip4;
16972   if (is_ip4)
16973     clib_memcpy (mp->nh_addr, &ip4, sizeof (ip4));
16974   else
16975     clib_memcpy (mp->nh_addr, &ip6, sizeof (ip6));
16976
16977   /* send it... */
16978   S (mp);
16979
16980   /* Wait for a reply... */
16981   W (ret);
16982   return ret;
16983 }
16984
16985 static int
16986 api_one_map_server_dump (vat_main_t * vam)
16987 {
16988   vl_api_one_map_server_dump_t *mp;
16989   vl_api_control_ping_t *mp_ping;
16990   int ret;
16991
16992   if (!vam->json_output)
16993     {
16994       print (vam->ofp, "%=20s", "Map server");
16995     }
16996
16997   M (ONE_MAP_SERVER_DUMP, mp);
16998   /* send it... */
16999   S (mp);
17000
17001   /* Use a control ping for synchronization */
17002   MPING (CONTROL_PING, mp_ping);
17003   S (mp_ping);
17004
17005   /* Wait for a reply... */
17006   W (ret);
17007   return ret;
17008 }
17009
17010 #define api_lisp_map_server_dump api_one_map_server_dump
17011
17012 static int
17013 api_one_map_resolver_dump (vat_main_t * vam)
17014 {
17015   vl_api_one_map_resolver_dump_t *mp;
17016   vl_api_control_ping_t *mp_ping;
17017   int ret;
17018
17019   if (!vam->json_output)
17020     {
17021       print (vam->ofp, "%=20s", "Map resolver");
17022     }
17023
17024   M (ONE_MAP_RESOLVER_DUMP, mp);
17025   /* send it... */
17026   S (mp);
17027
17028   /* Use a control ping for synchronization */
17029   MPING (CONTROL_PING, mp_ping);
17030   S (mp_ping);
17031
17032   /* Wait for a reply... */
17033   W (ret);
17034   return ret;
17035 }
17036
17037 #define api_lisp_map_resolver_dump api_one_map_resolver_dump
17038
17039 static int
17040 api_one_stats_flush (vat_main_t * vam)
17041 {
17042   vl_api_one_stats_flush_t *mp;
17043   int ret = 0;
17044
17045   M (ONE_STATS_FLUSH, mp);
17046   S (mp);
17047   W (ret);
17048   return ret;
17049 }
17050
17051 static int
17052 api_one_stats_dump (vat_main_t * vam)
17053 {
17054   vl_api_one_stats_dump_t *mp;
17055   vl_api_control_ping_t *mp_ping;
17056   int ret;
17057
17058   M (ONE_STATS_DUMP, mp);
17059   /* send it... */
17060   S (mp);
17061
17062   /* Use a control ping for synchronization */
17063   MPING (CONTROL_PING, mp_ping);
17064   S (mp_ping);
17065
17066   /* Wait for a reply... */
17067   W (ret);
17068   return ret;
17069 }
17070
17071 static int
17072 api_show_one_status (vat_main_t * vam)
17073 {
17074   vl_api_show_one_status_t *mp;
17075   int ret;
17076
17077   if (!vam->json_output)
17078     {
17079       print (vam->ofp, "%-20s%-16s", "ONE status", "locator-set");
17080     }
17081
17082   M (SHOW_ONE_STATUS, mp);
17083   /* send it... */
17084   S (mp);
17085   /* Wait for a reply... */
17086   W (ret);
17087   return ret;
17088 }
17089
17090 #define api_show_lisp_status api_show_one_status
17091
17092 static int
17093 api_lisp_gpe_fwd_entry_path_dump (vat_main_t * vam)
17094 {
17095   vl_api_gpe_fwd_entry_path_dump_t *mp;
17096   vl_api_control_ping_t *mp_ping;
17097   unformat_input_t *i = vam->input;
17098   u32 fwd_entry_index = ~0;
17099   int ret;
17100
17101   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17102     {
17103       if (unformat (i, "index %d", &fwd_entry_index))
17104         ;
17105       else
17106         break;
17107     }
17108
17109   if (~0 == fwd_entry_index)
17110     {
17111       errmsg ("no index specified!");
17112       return -99;
17113     }
17114
17115   if (!vam->json_output)
17116     {
17117       print (vam->ofp, "first line");
17118     }
17119
17120   M (GPE_FWD_ENTRY_PATH_DUMP, mp);
17121
17122   /* send it... */
17123   S (mp);
17124   /* Use a control ping for synchronization */
17125   MPING (CONTROL_PING, mp_ping);
17126   S (mp_ping);
17127
17128   /* Wait for a reply... */
17129   W (ret);
17130   return ret;
17131 }
17132
17133 static int
17134 api_one_get_map_request_itr_rlocs (vat_main_t * vam)
17135 {
17136   vl_api_one_get_map_request_itr_rlocs_t *mp;
17137   int ret;
17138
17139   if (!vam->json_output)
17140     {
17141       print (vam->ofp, "%=20s", "itr-rlocs:");
17142     }
17143
17144   M (ONE_GET_MAP_REQUEST_ITR_RLOCS, mp);
17145   /* send it... */
17146   S (mp);
17147   /* Wait for a reply... */
17148   W (ret);
17149   return ret;
17150 }
17151
17152 #define api_lisp_get_map_request_itr_rlocs api_one_get_map_request_itr_rlocs
17153
17154 static int
17155 api_af_packet_create (vat_main_t * vam)
17156 {
17157   unformat_input_t *i = vam->input;
17158   vl_api_af_packet_create_t *mp;
17159   u8 *host_if_name = 0;
17160   u8 hw_addr[6];
17161   u8 random_hw_addr = 1;
17162   int ret;
17163
17164   clib_memset (hw_addr, 0, sizeof (hw_addr));
17165
17166   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17167     {
17168       if (unformat (i, "name %s", &host_if_name))
17169         vec_add1 (host_if_name, 0);
17170       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
17171         random_hw_addr = 0;
17172       else
17173         break;
17174     }
17175
17176   if (!vec_len (host_if_name))
17177     {
17178       errmsg ("host-interface name must be specified");
17179       return -99;
17180     }
17181
17182   if (vec_len (host_if_name) > 64)
17183     {
17184       errmsg ("host-interface name too long");
17185       return -99;
17186     }
17187
17188   M (AF_PACKET_CREATE, mp);
17189
17190   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
17191   clib_memcpy (mp->hw_addr, hw_addr, 6);
17192   mp->use_random_hw_addr = random_hw_addr;
17193   vec_free (host_if_name);
17194
17195   S (mp);
17196
17197   /* *INDENT-OFF* */
17198   W2 (ret,
17199       ({
17200         if (ret == 0)
17201           fprintf (vam->ofp ? vam->ofp : stderr,
17202                    " new sw_if_index = %d\n", vam->sw_if_index);
17203       }));
17204   /* *INDENT-ON* */
17205   return ret;
17206 }
17207
17208 static int
17209 api_af_packet_delete (vat_main_t * vam)
17210 {
17211   unformat_input_t *i = vam->input;
17212   vl_api_af_packet_delete_t *mp;
17213   u8 *host_if_name = 0;
17214   int ret;
17215
17216   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17217     {
17218       if (unformat (i, "name %s", &host_if_name))
17219         vec_add1 (host_if_name, 0);
17220       else
17221         break;
17222     }
17223
17224   if (!vec_len (host_if_name))
17225     {
17226       errmsg ("host-interface name must be specified");
17227       return -99;
17228     }
17229
17230   if (vec_len (host_if_name) > 64)
17231     {
17232       errmsg ("host-interface name too long");
17233       return -99;
17234     }
17235
17236   M (AF_PACKET_DELETE, mp);
17237
17238   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
17239   vec_free (host_if_name);
17240
17241   S (mp);
17242   W (ret);
17243   return ret;
17244 }
17245
17246 static void vl_api_af_packet_details_t_handler
17247   (vl_api_af_packet_details_t * mp)
17248 {
17249   vat_main_t *vam = &vat_main;
17250
17251   print (vam->ofp, "%-16s %d",
17252          mp->host_if_name, clib_net_to_host_u32 (mp->sw_if_index));
17253 }
17254
17255 static void vl_api_af_packet_details_t_handler_json
17256   (vl_api_af_packet_details_t * mp)
17257 {
17258   vat_main_t *vam = &vat_main;
17259   vat_json_node_t *node = NULL;
17260
17261   if (VAT_JSON_ARRAY != vam->json_tree.type)
17262     {
17263       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17264       vat_json_init_array (&vam->json_tree);
17265     }
17266   node = vat_json_array_add (&vam->json_tree);
17267
17268   vat_json_init_object (node);
17269   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
17270   vat_json_object_add_string_copy (node, "dev_name", mp->host_if_name);
17271 }
17272
17273 static int
17274 api_af_packet_dump (vat_main_t * vam)
17275 {
17276   vl_api_af_packet_dump_t *mp;
17277   vl_api_control_ping_t *mp_ping;
17278   int ret;
17279
17280   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
17281   /* Get list of tap interfaces */
17282   M (AF_PACKET_DUMP, mp);
17283   S (mp);
17284
17285   /* Use a control ping for synchronization */
17286   MPING (CONTROL_PING, mp_ping);
17287   S (mp_ping);
17288
17289   W (ret);
17290   return ret;
17291 }
17292
17293 static int
17294 api_policer_add_del (vat_main_t * vam)
17295 {
17296   unformat_input_t *i = vam->input;
17297   vl_api_policer_add_del_t *mp;
17298   u8 is_add = 1;
17299   u8 *name = 0;
17300   u32 cir = 0;
17301   u32 eir = 0;
17302   u64 cb = 0;
17303   u64 eb = 0;
17304   u8 rate_type = 0;
17305   u8 round_type = 0;
17306   u8 type = 0;
17307   u8 color_aware = 0;
17308   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
17309   int ret;
17310
17311   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
17312   conform_action.dscp = 0;
17313   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
17314   exceed_action.dscp = 0;
17315   violate_action.action_type = SSE2_QOS_ACTION_DROP;
17316   violate_action.dscp = 0;
17317
17318   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17319     {
17320       if (unformat (i, "del"))
17321         is_add = 0;
17322       else if (unformat (i, "name %s", &name))
17323         vec_add1 (name, 0);
17324       else if (unformat (i, "cir %u", &cir))
17325         ;
17326       else if (unformat (i, "eir %u", &eir))
17327         ;
17328       else if (unformat (i, "cb %u", &cb))
17329         ;
17330       else if (unformat (i, "eb %u", &eb))
17331         ;
17332       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
17333                          &rate_type))
17334         ;
17335       else if (unformat (i, "round_type %U", unformat_policer_round_type,
17336                          &round_type))
17337         ;
17338       else if (unformat (i, "type %U", unformat_policer_type, &type))
17339         ;
17340       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
17341                          &conform_action))
17342         ;
17343       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
17344                          &exceed_action))
17345         ;
17346       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
17347                          &violate_action))
17348         ;
17349       else if (unformat (i, "color-aware"))
17350         color_aware = 1;
17351       else
17352         break;
17353     }
17354
17355   if (!vec_len (name))
17356     {
17357       errmsg ("policer name must be specified");
17358       return -99;
17359     }
17360
17361   if (vec_len (name) > 64)
17362     {
17363       errmsg ("policer name too long");
17364       return -99;
17365     }
17366
17367   M (POLICER_ADD_DEL, mp);
17368
17369   clib_memcpy (mp->name, name, vec_len (name));
17370   vec_free (name);
17371   mp->is_add = is_add;
17372   mp->cir = ntohl (cir);
17373   mp->eir = ntohl (eir);
17374   mp->cb = clib_net_to_host_u64 (cb);
17375   mp->eb = clib_net_to_host_u64 (eb);
17376   mp->rate_type = rate_type;
17377   mp->round_type = round_type;
17378   mp->type = type;
17379   mp->conform_action_type = conform_action.action_type;
17380   mp->conform_dscp = conform_action.dscp;
17381   mp->exceed_action_type = exceed_action.action_type;
17382   mp->exceed_dscp = exceed_action.dscp;
17383   mp->violate_action_type = violate_action.action_type;
17384   mp->violate_dscp = violate_action.dscp;
17385   mp->color_aware = color_aware;
17386
17387   S (mp);
17388   W (ret);
17389   return ret;
17390 }
17391
17392 static int
17393 api_policer_dump (vat_main_t * vam)
17394 {
17395   unformat_input_t *i = vam->input;
17396   vl_api_policer_dump_t *mp;
17397   vl_api_control_ping_t *mp_ping;
17398   u8 *match_name = 0;
17399   u8 match_name_valid = 0;
17400   int ret;
17401
17402   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17403     {
17404       if (unformat (i, "name %s", &match_name))
17405         {
17406           vec_add1 (match_name, 0);
17407           match_name_valid = 1;
17408         }
17409       else
17410         break;
17411     }
17412
17413   M (POLICER_DUMP, mp);
17414   mp->match_name_valid = match_name_valid;
17415   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
17416   vec_free (match_name);
17417   /* send it... */
17418   S (mp);
17419
17420   /* Use a control ping for synchronization */
17421   MPING (CONTROL_PING, mp_ping);
17422   S (mp_ping);
17423
17424   /* Wait for a reply... */
17425   W (ret);
17426   return ret;
17427 }
17428
17429 static int
17430 api_policer_classify_set_interface (vat_main_t * vam)
17431 {
17432   unformat_input_t *i = vam->input;
17433   vl_api_policer_classify_set_interface_t *mp;
17434   u32 sw_if_index;
17435   int sw_if_index_set;
17436   u32 ip4_table_index = ~0;
17437   u32 ip6_table_index = ~0;
17438   u32 l2_table_index = ~0;
17439   u8 is_add = 1;
17440   int ret;
17441
17442   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17443     {
17444       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17445         sw_if_index_set = 1;
17446       else if (unformat (i, "sw_if_index %d", &sw_if_index))
17447         sw_if_index_set = 1;
17448       else if (unformat (i, "del"))
17449         is_add = 0;
17450       else if (unformat (i, "ip4-table %d", &ip4_table_index))
17451         ;
17452       else if (unformat (i, "ip6-table %d", &ip6_table_index))
17453         ;
17454       else if (unformat (i, "l2-table %d", &l2_table_index))
17455         ;
17456       else
17457         {
17458           clib_warning ("parse error '%U'", format_unformat_error, i);
17459           return -99;
17460         }
17461     }
17462
17463   if (sw_if_index_set == 0)
17464     {
17465       errmsg ("missing interface name or sw_if_index");
17466       return -99;
17467     }
17468
17469   M (POLICER_CLASSIFY_SET_INTERFACE, mp);
17470
17471   mp->sw_if_index = ntohl (sw_if_index);
17472   mp->ip4_table_index = ntohl (ip4_table_index);
17473   mp->ip6_table_index = ntohl (ip6_table_index);
17474   mp->l2_table_index = ntohl (l2_table_index);
17475   mp->is_add = is_add;
17476
17477   S (mp);
17478   W (ret);
17479   return ret;
17480 }
17481
17482 static int
17483 api_policer_classify_dump (vat_main_t * vam)
17484 {
17485   unformat_input_t *i = vam->input;
17486   vl_api_policer_classify_dump_t *mp;
17487   vl_api_control_ping_t *mp_ping;
17488   u8 type = POLICER_CLASSIFY_N_TABLES;
17489   int ret;
17490
17491   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
17492     ;
17493   else
17494     {
17495       errmsg ("classify table type must be specified");
17496       return -99;
17497     }
17498
17499   if (!vam->json_output)
17500     {
17501       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
17502     }
17503
17504   M (POLICER_CLASSIFY_DUMP, mp);
17505   mp->type = type;
17506   /* send it... */
17507   S (mp);
17508
17509   /* Use a control ping for synchronization */
17510   MPING (CONTROL_PING, mp_ping);
17511   S (mp_ping);
17512
17513   /* Wait for a reply... */
17514   W (ret);
17515   return ret;
17516 }
17517
17518 static int
17519 api_netmap_create (vat_main_t * vam)
17520 {
17521   unformat_input_t *i = vam->input;
17522   vl_api_netmap_create_t *mp;
17523   u8 *if_name = 0;
17524   u8 hw_addr[6];
17525   u8 random_hw_addr = 1;
17526   u8 is_pipe = 0;
17527   u8 is_master = 0;
17528   int ret;
17529
17530   clib_memset (hw_addr, 0, sizeof (hw_addr));
17531
17532   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17533     {
17534       if (unformat (i, "name %s", &if_name))
17535         vec_add1 (if_name, 0);
17536       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
17537         random_hw_addr = 0;
17538       else if (unformat (i, "pipe"))
17539         is_pipe = 1;
17540       else if (unformat (i, "master"))
17541         is_master = 1;
17542       else if (unformat (i, "slave"))
17543         is_master = 0;
17544       else
17545         break;
17546     }
17547
17548   if (!vec_len (if_name))
17549     {
17550       errmsg ("interface name must be specified");
17551       return -99;
17552     }
17553
17554   if (vec_len (if_name) > 64)
17555     {
17556       errmsg ("interface name too long");
17557       return -99;
17558     }
17559
17560   M (NETMAP_CREATE, mp);
17561
17562   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
17563   clib_memcpy (mp->hw_addr, hw_addr, 6);
17564   mp->use_random_hw_addr = random_hw_addr;
17565   mp->is_pipe = is_pipe;
17566   mp->is_master = is_master;
17567   vec_free (if_name);
17568
17569   S (mp);
17570   W (ret);
17571   return ret;
17572 }
17573
17574 static int
17575 api_netmap_delete (vat_main_t * vam)
17576 {
17577   unformat_input_t *i = vam->input;
17578   vl_api_netmap_delete_t *mp;
17579   u8 *if_name = 0;
17580   int ret;
17581
17582   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17583     {
17584       if (unformat (i, "name %s", &if_name))
17585         vec_add1 (if_name, 0);
17586       else
17587         break;
17588     }
17589
17590   if (!vec_len (if_name))
17591     {
17592       errmsg ("interface name must be specified");
17593       return -99;
17594     }
17595
17596   if (vec_len (if_name) > 64)
17597     {
17598       errmsg ("interface name too long");
17599       return -99;
17600     }
17601
17602   M (NETMAP_DELETE, mp);
17603
17604   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
17605   vec_free (if_name);
17606
17607   S (mp);
17608   W (ret);
17609   return ret;
17610 }
17611
17612 static u8 *
17613 format_fib_api_path_nh_proto (u8 * s, va_list * args)
17614 {
17615   vl_api_fib_path_nh_proto_t proto =
17616     va_arg (*args, vl_api_fib_path_nh_proto_t);
17617
17618   switch (proto)
17619     {
17620     case FIB_API_PATH_NH_PROTO_IP4:
17621       s = format (s, "ip4");
17622       break;
17623     case FIB_API_PATH_NH_PROTO_IP6:
17624       s = format (s, "ip6");
17625       break;
17626     case FIB_API_PATH_NH_PROTO_MPLS:
17627       s = format (s, "mpls");
17628       break;
17629     case FIB_API_PATH_NH_PROTO_BIER:
17630       s = format (s, "bier");
17631       break;
17632     case FIB_API_PATH_NH_PROTO_ETHERNET:
17633       s = format (s, "ethernet");
17634       break;
17635     }
17636
17637   return (s);
17638 }
17639
17640 static u8 *
17641 format_vl_api_ip_address_union (u8 * s, va_list * args)
17642 {
17643   vl_api_address_family_t af = va_arg (*args, vl_api_address_family_t);
17644   const vl_api_address_union_t *u = va_arg (*args, vl_api_address_union_t *);
17645
17646   switch (af)
17647     {
17648     case ADDRESS_IP4:
17649       s = format (s, "%U", format_ip4_address, u->ip4);
17650       break;
17651     case ADDRESS_IP6:
17652       s = format (s, "%U", format_ip6_address, u->ip6);
17653       break;
17654     }
17655   return (s);
17656 }
17657
17658 static u8 *
17659 format_vl_api_fib_path_type (u8 * s, va_list * args)
17660 {
17661   vl_api_fib_path_type_t t = va_arg (*args, vl_api_fib_path_type_t);
17662
17663   switch (t)
17664     {
17665     case FIB_API_PATH_TYPE_NORMAL:
17666       s = format (s, "normal");
17667       break;
17668     case FIB_API_PATH_TYPE_LOCAL:
17669       s = format (s, "local");
17670       break;
17671     case FIB_API_PATH_TYPE_DROP:
17672       s = format (s, "drop");
17673       break;
17674     case FIB_API_PATH_TYPE_UDP_ENCAP:
17675       s = format (s, "udp-encap");
17676       break;
17677     case FIB_API_PATH_TYPE_BIER_IMP:
17678       s = format (s, "bier-imp");
17679       break;
17680     case FIB_API_PATH_TYPE_ICMP_UNREACH:
17681       s = format (s, "unreach");
17682       break;
17683     case FIB_API_PATH_TYPE_ICMP_PROHIBIT:
17684       s = format (s, "prohibit");
17685       break;
17686     case FIB_API_PATH_TYPE_SOURCE_LOOKUP:
17687       s = format (s, "src-lookup");
17688       break;
17689     case FIB_API_PATH_TYPE_DVR:
17690       s = format (s, "dvr");
17691       break;
17692     case FIB_API_PATH_TYPE_INTERFACE_RX:
17693       s = format (s, "interface-rx");
17694       break;
17695     case FIB_API_PATH_TYPE_CLASSIFY:
17696       s = format (s, "classify");
17697       break;
17698     }
17699
17700   return (s);
17701 }
17702
17703 static void
17704 vl_api_fib_path_print (vat_main_t * vam, vl_api_fib_path_t * fp)
17705 {
17706   print (vam->ofp,
17707          "  weight %d, sw_if_index %d, type %U, afi %U, next_hop %U",
17708          ntohl (fp->weight), ntohl (fp->sw_if_index),
17709          format_vl_api_fib_path_type, fp->type,
17710          format_fib_api_path_nh_proto, fp->proto,
17711          format_vl_api_ip_address_union, &fp->nh.address);
17712 }
17713
17714 static void
17715 vl_api_mpls_fib_path_json_print (vat_json_node_t * node,
17716                                  vl_api_fib_path_t * fp)
17717 {
17718   struct in_addr ip4;
17719   struct in6_addr ip6;
17720
17721   vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
17722   vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
17723   vat_json_object_add_uint (node, "type", fp->type);
17724   vat_json_object_add_uint (node, "next_hop_proto", fp->proto);
17725   if (fp->proto == FIB_API_PATH_NH_PROTO_IP4)
17726     {
17727       clib_memcpy (&ip4, &fp->nh.address.ip4, sizeof (ip4));
17728       vat_json_object_add_ip4 (node, "next_hop", ip4);
17729     }
17730   else if (fp->proto == FIB_API_PATH_NH_PROTO_IP4)
17731     {
17732       clib_memcpy (&ip6, &fp->nh.address.ip6, sizeof (ip6));
17733       vat_json_object_add_ip6 (node, "next_hop", ip6);
17734     }
17735 }
17736
17737 static void
17738 vl_api_mpls_tunnel_details_t_handler (vl_api_mpls_tunnel_details_t * mp)
17739 {
17740   vat_main_t *vam = &vat_main;
17741   int count = ntohl (mp->mt_tunnel.mt_n_paths);
17742   vl_api_fib_path_t *fp;
17743   i32 i;
17744
17745   print (vam->ofp, "sw_if_index %d via:",
17746          ntohl (mp->mt_tunnel.mt_sw_if_index));
17747   fp = mp->mt_tunnel.mt_paths;
17748   for (i = 0; i < count; i++)
17749     {
17750       vl_api_fib_path_print (vam, fp);
17751       fp++;
17752     }
17753
17754   print (vam->ofp, "");
17755 }
17756
17757 #define vl_api_mpls_tunnel_details_t_endian vl_noop_handler
17758 #define vl_api_mpls_tunnel_details_t_print vl_noop_handler
17759
17760 static void
17761 vl_api_mpls_tunnel_details_t_handler_json (vl_api_mpls_tunnel_details_t * mp)
17762 {
17763   vat_main_t *vam = &vat_main;
17764   vat_json_node_t *node = NULL;
17765   int count = ntohl (mp->mt_tunnel.mt_n_paths);
17766   vl_api_fib_path_t *fp;
17767   i32 i;
17768
17769   if (VAT_JSON_ARRAY != vam->json_tree.type)
17770     {
17771       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17772       vat_json_init_array (&vam->json_tree);
17773     }
17774   node = vat_json_array_add (&vam->json_tree);
17775
17776   vat_json_init_object (node);
17777   vat_json_object_add_uint (node, "sw_if_index",
17778                             ntohl (mp->mt_tunnel.mt_sw_if_index));
17779
17780   vat_json_object_add_uint (node, "l2_only", mp->mt_tunnel.mt_l2_only);
17781
17782   fp = mp->mt_tunnel.mt_paths;
17783   for (i = 0; i < count; i++)
17784     {
17785       vl_api_mpls_fib_path_json_print (node, fp);
17786       fp++;
17787     }
17788 }
17789
17790 static int
17791 api_mpls_tunnel_dump (vat_main_t * vam)
17792 {
17793   vl_api_mpls_tunnel_dump_t *mp;
17794   vl_api_control_ping_t *mp_ping;
17795   int ret;
17796
17797   M (MPLS_TUNNEL_DUMP, mp);
17798
17799   S (mp);
17800
17801   /* Use a control ping for synchronization */
17802   MPING (CONTROL_PING, mp_ping);
17803   S (mp_ping);
17804
17805   W (ret);
17806   return ret;
17807 }
17808
17809 #define vl_api_mpls_table_details_t_endian vl_noop_handler
17810 #define vl_api_mpls_table_details_t_print vl_noop_handler
17811
17812
17813 static void
17814 vl_api_mpls_table_details_t_handler (vl_api_mpls_table_details_t * mp)
17815 {
17816   vat_main_t *vam = &vat_main;
17817
17818   print (vam->ofp, "table-id %d,", ntohl (mp->mt_table.mt_table_id));
17819 }
17820
17821 static void vl_api_mpls_table_details_t_handler_json
17822   (vl_api_mpls_table_details_t * mp)
17823 {
17824   vat_main_t *vam = &vat_main;
17825   vat_json_node_t *node = NULL;
17826
17827   if (VAT_JSON_ARRAY != vam->json_tree.type)
17828     {
17829       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17830       vat_json_init_array (&vam->json_tree);
17831     }
17832   node = vat_json_array_add (&vam->json_tree);
17833
17834   vat_json_init_object (node);
17835   vat_json_object_add_uint (node, "table", ntohl (mp->mt_table.mt_table_id));
17836 }
17837
17838 static int
17839 api_mpls_table_dump (vat_main_t * vam)
17840 {
17841   vl_api_mpls_table_dump_t *mp;
17842   vl_api_control_ping_t *mp_ping;
17843   int ret;
17844
17845   M (MPLS_TABLE_DUMP, mp);
17846   S (mp);
17847
17848   /* Use a control ping for synchronization */
17849   MPING (CONTROL_PING, mp_ping);
17850   S (mp_ping);
17851
17852   W (ret);
17853   return ret;
17854 }
17855
17856 #define vl_api_mpls_route_details_t_endian vl_noop_handler
17857 #define vl_api_mpls_route_details_t_print vl_noop_handler
17858
17859 static void
17860 vl_api_mpls_route_details_t_handler (vl_api_mpls_route_details_t * mp)
17861 {
17862   vat_main_t *vam = &vat_main;
17863   int count = (int) clib_net_to_host_u32 (mp->mr_route.mr_n_paths);
17864   vl_api_fib_path_t *fp;
17865   int i;
17866
17867   print (vam->ofp,
17868          "table-id %d, label %u, ess_bit %u",
17869          ntohl (mp->mr_route.mr_table_id),
17870          ntohl (mp->mr_route.mr_label), mp->mr_route.mr_eos);
17871   fp = mp->mr_route.mr_paths;
17872   for (i = 0; i < count; i++)
17873     {
17874       vl_api_fib_path_print (vam, fp);
17875       fp++;
17876     }
17877 }
17878
17879 static void vl_api_mpls_route_details_t_handler_json
17880   (vl_api_mpls_route_details_t * mp)
17881 {
17882   vat_main_t *vam = &vat_main;
17883   int count = (int) clib_host_to_net_u32 (mp->mr_route.mr_n_paths);
17884   vat_json_node_t *node = NULL;
17885   vl_api_fib_path_t *fp;
17886   int i;
17887
17888   if (VAT_JSON_ARRAY != vam->json_tree.type)
17889     {
17890       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17891       vat_json_init_array (&vam->json_tree);
17892     }
17893   node = vat_json_array_add (&vam->json_tree);
17894
17895   vat_json_init_object (node);
17896   vat_json_object_add_uint (node, "table", ntohl (mp->mr_route.mr_table_id));
17897   vat_json_object_add_uint (node, "s_bit", mp->mr_route.mr_eos);
17898   vat_json_object_add_uint (node, "label", ntohl (mp->mr_route.mr_label));
17899   vat_json_object_add_uint (node, "path_count", count);
17900   fp = mp->mr_route.mr_paths;
17901   for (i = 0; i < count; i++)
17902     {
17903       vl_api_mpls_fib_path_json_print (node, fp);
17904       fp++;
17905     }
17906 }
17907
17908 static int
17909 api_mpls_route_dump (vat_main_t * vam)
17910 {
17911   unformat_input_t *input = vam->input;
17912   vl_api_mpls_route_dump_t *mp;
17913   vl_api_control_ping_t *mp_ping;
17914   u32 table_id;
17915   int ret;
17916
17917   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17918     {
17919       if (unformat (input, "table_id %d", &table_id))
17920         ;
17921       else
17922         break;
17923     }
17924   if (table_id == ~0)
17925     {
17926       errmsg ("missing table id");
17927       return -99;
17928     }
17929
17930   M (MPLS_ROUTE_DUMP, mp);
17931
17932   mp->table.mt_table_id = ntohl (table_id);
17933   S (mp);
17934
17935   /* Use a control ping for synchronization */
17936   MPING (CONTROL_PING, mp_ping);
17937   S (mp_ping);
17938
17939   W (ret);
17940   return ret;
17941 }
17942
17943 #define vl_api_ip_table_details_t_endian vl_noop_handler
17944 #define vl_api_ip_table_details_t_print vl_noop_handler
17945
17946 static void
17947 vl_api_ip_table_details_t_handler (vl_api_ip_table_details_t * mp)
17948 {
17949   vat_main_t *vam = &vat_main;
17950
17951   print (vam->ofp,
17952          "%s; table-id %d, prefix %U/%d",
17953          mp->table.name, ntohl (mp->table.table_id));
17954 }
17955
17956
17957 static void vl_api_ip_table_details_t_handler_json
17958   (vl_api_ip_table_details_t * mp)
17959 {
17960   vat_main_t *vam = &vat_main;
17961   vat_json_node_t *node = NULL;
17962
17963   if (VAT_JSON_ARRAY != vam->json_tree.type)
17964     {
17965       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17966       vat_json_init_array (&vam->json_tree);
17967     }
17968   node = vat_json_array_add (&vam->json_tree);
17969
17970   vat_json_init_object (node);
17971   vat_json_object_add_uint (node, "table", ntohl (mp->table.table_id));
17972 }
17973
17974 static int
17975 api_ip_table_dump (vat_main_t * vam)
17976 {
17977   vl_api_ip_table_dump_t *mp;
17978   vl_api_control_ping_t *mp_ping;
17979   int ret;
17980
17981   M (IP_TABLE_DUMP, mp);
17982   S (mp);
17983
17984   /* Use a control ping for synchronization */
17985   MPING (CONTROL_PING, mp_ping);
17986   S (mp_ping);
17987
17988   W (ret);
17989   return ret;
17990 }
17991
17992 static int
17993 api_ip_mtable_dump (vat_main_t * vam)
17994 {
17995   vl_api_ip_mtable_dump_t *mp;
17996   vl_api_control_ping_t *mp_ping;
17997   int ret;
17998
17999   M (IP_MTABLE_DUMP, mp);
18000   S (mp);
18001
18002   /* Use a control ping for synchronization */
18003   MPING (CONTROL_PING, mp_ping);
18004   S (mp_ping);
18005
18006   W (ret);
18007   return ret;
18008 }
18009
18010 static int
18011 api_ip_mroute_dump (vat_main_t * vam)
18012 {
18013   unformat_input_t *input = vam->input;
18014   vl_api_control_ping_t *mp_ping;
18015   vl_api_ip_mroute_dump_t *mp;
18016   int ret, is_ip6;
18017   u32 table_id;
18018
18019   is_ip6 = 0;
18020   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18021     {
18022       if (unformat (input, "table_id %d", &table_id))
18023         ;
18024       else if (unformat (input, "ip6"))
18025         is_ip6 = 1;
18026       else if (unformat (input, "ip4"))
18027         is_ip6 = 0;
18028       else
18029         break;
18030     }
18031   if (table_id == ~0)
18032     {
18033       errmsg ("missing table id");
18034       return -99;
18035     }
18036
18037   M (IP_MROUTE_DUMP, mp);
18038   mp->table.table_id = table_id;
18039   mp->table.is_ip6 = is_ip6;
18040   S (mp);
18041
18042   /* Use a control ping for synchronization */
18043   MPING (CONTROL_PING, mp_ping);
18044   S (mp_ping);
18045
18046   W (ret);
18047   return ret;
18048 }
18049
18050 #define vl_api_ip_route_details_t_endian vl_noop_handler
18051 #define vl_api_ip_route_details_t_print vl_noop_handler
18052
18053 static void
18054 vl_api_ip_route_details_t_handler (vl_api_ip_route_details_t * mp)
18055 {
18056   vat_main_t *vam = &vat_main;
18057   u8 count = mp->route.n_paths;
18058   vl_api_fib_path_t *fp;
18059   int i;
18060
18061   print (vam->ofp,
18062          "table-id %d, prefix %U/%d",
18063          ntohl (mp->route.table_id),
18064          format_ip46_address, mp->route.prefix.address, mp->route.prefix.len);
18065   for (i = 0; i < count; i++)
18066     {
18067       fp = &mp->route.paths[i];
18068
18069       vl_api_fib_path_print (vam, fp);
18070       fp++;
18071     }
18072 }
18073
18074 static void vl_api_ip_route_details_t_handler_json
18075   (vl_api_ip_route_details_t * mp)
18076 {
18077   vat_main_t *vam = &vat_main;
18078   u8 count = mp->route.n_paths;
18079   vat_json_node_t *node = NULL;
18080   struct in_addr ip4;
18081   struct in6_addr ip6;
18082   vl_api_fib_path_t *fp;
18083   int i;
18084
18085   if (VAT_JSON_ARRAY != vam->json_tree.type)
18086     {
18087       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18088       vat_json_init_array (&vam->json_tree);
18089     }
18090   node = vat_json_array_add (&vam->json_tree);
18091
18092   vat_json_init_object (node);
18093   vat_json_object_add_uint (node, "table", ntohl (mp->route.table_id));
18094   if (ADDRESS_IP6 == mp->route.prefix.address.af)
18095     {
18096       clib_memcpy (&ip6, &mp->route.prefix.address.un.ip6, sizeof (ip6));
18097       vat_json_object_add_ip6 (node, "prefix", ip6);
18098     }
18099   else
18100     {
18101       clib_memcpy (&ip4, &mp->route.prefix.address.un.ip4, sizeof (ip4));
18102       vat_json_object_add_ip4 (node, "prefix", ip4);
18103     }
18104   vat_json_object_add_uint (node, "mask_length", mp->route.prefix.len);
18105   vat_json_object_add_uint (node, "path_count", count);
18106   for (i = 0; i < count; i++)
18107     {
18108       fp = &mp->route.paths[i];
18109       vl_api_mpls_fib_path_json_print (node, fp);
18110     }
18111 }
18112
18113 static int
18114 api_ip_route_dump (vat_main_t * vam)
18115 {
18116   unformat_input_t *input = vam->input;
18117   vl_api_ip_route_dump_t *mp;
18118   vl_api_control_ping_t *mp_ping;
18119   u32 table_id;
18120   u8 is_ip6;
18121   int ret;
18122
18123   is_ip6 = 0;
18124   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18125     {
18126       if (unformat (input, "table_id %d", &table_id))
18127         ;
18128       else if (unformat (input, "ip6"))
18129         is_ip6 = 1;
18130       else if (unformat (input, "ip4"))
18131         is_ip6 = 0;
18132       else
18133         break;
18134     }
18135   if (table_id == ~0)
18136     {
18137       errmsg ("missing table id");
18138       return -99;
18139     }
18140
18141   M (IP_ROUTE_DUMP, mp);
18142
18143   mp->table.table_id = table_id;
18144   mp->table.is_ip6 = is_ip6;
18145
18146   S (mp);
18147
18148   /* Use a control ping for synchronization */
18149   MPING (CONTROL_PING, mp_ping);
18150   S (mp_ping);
18151
18152   W (ret);
18153   return ret;
18154 }
18155
18156 int
18157 api_classify_table_ids (vat_main_t * vam)
18158 {
18159   vl_api_classify_table_ids_t *mp;
18160   int ret;
18161
18162   /* Construct the API message */
18163   M (CLASSIFY_TABLE_IDS, mp);
18164   mp->context = 0;
18165
18166   S (mp);
18167   W (ret);
18168   return ret;
18169 }
18170
18171 int
18172 api_classify_table_by_interface (vat_main_t * vam)
18173 {
18174   unformat_input_t *input = vam->input;
18175   vl_api_classify_table_by_interface_t *mp;
18176
18177   u32 sw_if_index = ~0;
18178   int ret;
18179   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18180     {
18181       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18182         ;
18183       else if (unformat (input, "sw_if_index %d", &sw_if_index))
18184         ;
18185       else
18186         break;
18187     }
18188   if (sw_if_index == ~0)
18189     {
18190       errmsg ("missing interface name or sw_if_index");
18191       return -99;
18192     }
18193
18194   /* Construct the API message */
18195   M (CLASSIFY_TABLE_BY_INTERFACE, mp);
18196   mp->context = 0;
18197   mp->sw_if_index = ntohl (sw_if_index);
18198
18199   S (mp);
18200   W (ret);
18201   return ret;
18202 }
18203
18204 int
18205 api_classify_table_info (vat_main_t * vam)
18206 {
18207   unformat_input_t *input = vam->input;
18208   vl_api_classify_table_info_t *mp;
18209
18210   u32 table_id = ~0;
18211   int ret;
18212   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18213     {
18214       if (unformat (input, "table_id %d", &table_id))
18215         ;
18216       else
18217         break;
18218     }
18219   if (table_id == ~0)
18220     {
18221       errmsg ("missing table id");
18222       return -99;
18223     }
18224
18225   /* Construct the API message */
18226   M (CLASSIFY_TABLE_INFO, mp);
18227   mp->context = 0;
18228   mp->table_id = ntohl (table_id);
18229
18230   S (mp);
18231   W (ret);
18232   return ret;
18233 }
18234
18235 int
18236 api_classify_session_dump (vat_main_t * vam)
18237 {
18238   unformat_input_t *input = vam->input;
18239   vl_api_classify_session_dump_t *mp;
18240   vl_api_control_ping_t *mp_ping;
18241
18242   u32 table_id = ~0;
18243   int ret;
18244   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18245     {
18246       if (unformat (input, "table_id %d", &table_id))
18247         ;
18248       else
18249         break;
18250     }
18251   if (table_id == ~0)
18252     {
18253       errmsg ("missing table id");
18254       return -99;
18255     }
18256
18257   /* Construct the API message */
18258   M (CLASSIFY_SESSION_DUMP, mp);
18259   mp->context = 0;
18260   mp->table_id = ntohl (table_id);
18261   S (mp);
18262
18263   /* Use a control ping for synchronization */
18264   MPING (CONTROL_PING, mp_ping);
18265   S (mp_ping);
18266
18267   W (ret);
18268   return ret;
18269 }
18270
18271 static void
18272 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
18273 {
18274   vat_main_t *vam = &vat_main;
18275
18276   print (vam->ofp, "collector_address %U, collector_port %d, "
18277          "src_address %U, vrf_id %d, path_mtu %u, "
18278          "template_interval %u, udp_checksum %d",
18279          format_ip4_address, mp->collector_address,
18280          ntohs (mp->collector_port),
18281          format_ip4_address, mp->src_address,
18282          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
18283          ntohl (mp->template_interval), mp->udp_checksum);
18284
18285   vam->retval = 0;
18286   vam->result_ready = 1;
18287 }
18288
18289 static void
18290   vl_api_ipfix_exporter_details_t_handler_json
18291   (vl_api_ipfix_exporter_details_t * mp)
18292 {
18293   vat_main_t *vam = &vat_main;
18294   vat_json_node_t node;
18295   struct in_addr collector_address;
18296   struct in_addr src_address;
18297
18298   vat_json_init_object (&node);
18299   clib_memcpy (&collector_address, &mp->collector_address,
18300                sizeof (collector_address));
18301   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
18302   vat_json_object_add_uint (&node, "collector_port",
18303                             ntohs (mp->collector_port));
18304   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
18305   vat_json_object_add_ip4 (&node, "src_address", src_address);
18306   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
18307   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
18308   vat_json_object_add_uint (&node, "template_interval",
18309                             ntohl (mp->template_interval));
18310   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
18311
18312   vat_json_print (vam->ofp, &node);
18313   vat_json_free (&node);
18314   vam->retval = 0;
18315   vam->result_ready = 1;
18316 }
18317
18318 int
18319 api_ipfix_exporter_dump (vat_main_t * vam)
18320 {
18321   vl_api_ipfix_exporter_dump_t *mp;
18322   int ret;
18323
18324   /* Construct the API message */
18325   M (IPFIX_EXPORTER_DUMP, mp);
18326   mp->context = 0;
18327
18328   S (mp);
18329   W (ret);
18330   return ret;
18331 }
18332
18333 static int
18334 api_ipfix_classify_stream_dump (vat_main_t * vam)
18335 {
18336   vl_api_ipfix_classify_stream_dump_t *mp;
18337   int ret;
18338
18339   /* Construct the API message */
18340   M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
18341   mp->context = 0;
18342
18343   S (mp);
18344   W (ret);
18345   return ret;
18346   /* NOTREACHED */
18347   return 0;
18348 }
18349
18350 static void
18351   vl_api_ipfix_classify_stream_details_t_handler
18352   (vl_api_ipfix_classify_stream_details_t * mp)
18353 {
18354   vat_main_t *vam = &vat_main;
18355   print (vam->ofp, "domain_id %d, src_port %d",
18356          ntohl (mp->domain_id), ntohs (mp->src_port));
18357   vam->retval = 0;
18358   vam->result_ready = 1;
18359 }
18360
18361 static void
18362   vl_api_ipfix_classify_stream_details_t_handler_json
18363   (vl_api_ipfix_classify_stream_details_t * mp)
18364 {
18365   vat_main_t *vam = &vat_main;
18366   vat_json_node_t node;
18367
18368   vat_json_init_object (&node);
18369   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
18370   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
18371
18372   vat_json_print (vam->ofp, &node);
18373   vat_json_free (&node);
18374   vam->retval = 0;
18375   vam->result_ready = 1;
18376 }
18377
18378 static int
18379 api_ipfix_classify_table_dump (vat_main_t * vam)
18380 {
18381   vl_api_ipfix_classify_table_dump_t *mp;
18382   vl_api_control_ping_t *mp_ping;
18383   int ret;
18384
18385   if (!vam->json_output)
18386     {
18387       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
18388              "transport_protocol");
18389     }
18390
18391   /* Construct the API message */
18392   M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
18393
18394   /* send it... */
18395   S (mp);
18396
18397   /* Use a control ping for synchronization */
18398   MPING (CONTROL_PING, mp_ping);
18399   S (mp_ping);
18400
18401   W (ret);
18402   return ret;
18403 }
18404
18405 static void
18406   vl_api_ipfix_classify_table_details_t_handler
18407   (vl_api_ipfix_classify_table_details_t * mp)
18408 {
18409   vat_main_t *vam = &vat_main;
18410   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
18411          mp->transport_protocol);
18412 }
18413
18414 static void
18415   vl_api_ipfix_classify_table_details_t_handler_json
18416   (vl_api_ipfix_classify_table_details_t * mp)
18417 {
18418   vat_json_node_t *node = NULL;
18419   vat_main_t *vam = &vat_main;
18420
18421   if (VAT_JSON_ARRAY != vam->json_tree.type)
18422     {
18423       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18424       vat_json_init_array (&vam->json_tree);
18425     }
18426
18427   node = vat_json_array_add (&vam->json_tree);
18428   vat_json_init_object (node);
18429
18430   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
18431   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
18432   vat_json_object_add_uint (node, "transport_protocol",
18433                             mp->transport_protocol);
18434 }
18435
18436 static int
18437 api_sw_interface_span_enable_disable (vat_main_t * vam)
18438 {
18439   unformat_input_t *i = vam->input;
18440   vl_api_sw_interface_span_enable_disable_t *mp;
18441   u32 src_sw_if_index = ~0;
18442   u32 dst_sw_if_index = ~0;
18443   u8 state = 3;
18444   int ret;
18445   u8 is_l2 = 0;
18446
18447   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18448     {
18449       if (unformat
18450           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
18451         ;
18452       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
18453         ;
18454       else
18455         if (unformat
18456             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
18457         ;
18458       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
18459         ;
18460       else if (unformat (i, "disable"))
18461         state = 0;
18462       else if (unformat (i, "rx"))
18463         state = 1;
18464       else if (unformat (i, "tx"))
18465         state = 2;
18466       else if (unformat (i, "both"))
18467         state = 3;
18468       else if (unformat (i, "l2"))
18469         is_l2 = 1;
18470       else
18471         break;
18472     }
18473
18474   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
18475
18476   mp->sw_if_index_from = htonl (src_sw_if_index);
18477   mp->sw_if_index_to = htonl (dst_sw_if_index);
18478   mp->state = state;
18479   mp->is_l2 = is_l2;
18480
18481   S (mp);
18482   W (ret);
18483   return ret;
18484 }
18485
18486 static void
18487 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
18488                                             * mp)
18489 {
18490   vat_main_t *vam = &vat_main;
18491   u8 *sw_if_from_name = 0;
18492   u8 *sw_if_to_name = 0;
18493   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
18494   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
18495   char *states[] = { "none", "rx", "tx", "both" };
18496   hash_pair_t *p;
18497
18498   /* *INDENT-OFF* */
18499   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
18500   ({
18501     if ((u32) p->value[0] == sw_if_index_from)
18502       {
18503         sw_if_from_name = (u8 *)(p->key);
18504         if (sw_if_to_name)
18505           break;
18506       }
18507     if ((u32) p->value[0] == sw_if_index_to)
18508       {
18509         sw_if_to_name = (u8 *)(p->key);
18510         if (sw_if_from_name)
18511           break;
18512       }
18513   }));
18514   /* *INDENT-ON* */
18515   print (vam->ofp, "%20s => %20s (%s) %s",
18516          sw_if_from_name, sw_if_to_name, states[mp->state],
18517          mp->is_l2 ? "l2" : "device");
18518 }
18519
18520 static void
18521   vl_api_sw_interface_span_details_t_handler_json
18522   (vl_api_sw_interface_span_details_t * mp)
18523 {
18524   vat_main_t *vam = &vat_main;
18525   vat_json_node_t *node = NULL;
18526   u8 *sw_if_from_name = 0;
18527   u8 *sw_if_to_name = 0;
18528   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
18529   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
18530   hash_pair_t *p;
18531
18532   /* *INDENT-OFF* */
18533   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
18534   ({
18535     if ((u32) p->value[0] == sw_if_index_from)
18536       {
18537         sw_if_from_name = (u8 *)(p->key);
18538         if (sw_if_to_name)
18539           break;
18540       }
18541     if ((u32) p->value[0] == sw_if_index_to)
18542       {
18543         sw_if_to_name = (u8 *)(p->key);
18544         if (sw_if_from_name)
18545           break;
18546       }
18547   }));
18548   /* *INDENT-ON* */
18549
18550   if (VAT_JSON_ARRAY != vam->json_tree.type)
18551     {
18552       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18553       vat_json_init_array (&vam->json_tree);
18554     }
18555   node = vat_json_array_add (&vam->json_tree);
18556
18557   vat_json_init_object (node);
18558   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
18559   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
18560   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
18561   if (0 != sw_if_to_name)
18562     {
18563       vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
18564     }
18565   vat_json_object_add_uint (node, "state", mp->state);
18566   vat_json_object_add_uint (node, "is-l2", mp->is_l2);
18567 }
18568
18569 static int
18570 api_sw_interface_span_dump (vat_main_t * vam)
18571 {
18572   unformat_input_t *input = vam->input;
18573   vl_api_sw_interface_span_dump_t *mp;
18574   vl_api_control_ping_t *mp_ping;
18575   u8 is_l2 = 0;
18576   int ret;
18577
18578   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18579     {
18580       if (unformat (input, "l2"))
18581         is_l2 = 1;
18582       else
18583         break;
18584     }
18585
18586   M (SW_INTERFACE_SPAN_DUMP, mp);
18587   mp->is_l2 = is_l2;
18588   S (mp);
18589
18590   /* Use a control ping for synchronization */
18591   MPING (CONTROL_PING, mp_ping);
18592   S (mp_ping);
18593
18594   W (ret);
18595   return ret;
18596 }
18597
18598 int
18599 api_pg_create_interface (vat_main_t * vam)
18600 {
18601   unformat_input_t *input = vam->input;
18602   vl_api_pg_create_interface_t *mp;
18603
18604   u32 if_id = ~0, gso_size = 0;
18605   u8 gso_enabled = 0;
18606   int ret;
18607   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18608     {
18609       if (unformat (input, "if_id %d", &if_id))
18610         ;
18611       else if (unformat (input, "gso-enabled"))
18612         {
18613           gso_enabled = 1;
18614           if (unformat (input, "gso-size %u", &gso_size))
18615             ;
18616           else
18617             {
18618               errmsg ("missing gso-size");
18619               return -99;
18620             }
18621         }
18622       else
18623         break;
18624     }
18625   if (if_id == ~0)
18626     {
18627       errmsg ("missing pg interface index");
18628       return -99;
18629     }
18630
18631   /* Construct the API message */
18632   M (PG_CREATE_INTERFACE, mp);
18633   mp->context = 0;
18634   mp->interface_id = ntohl (if_id);
18635   mp->gso_enabled = gso_enabled;
18636
18637   S (mp);
18638   W (ret);
18639   return ret;
18640 }
18641
18642 int
18643 api_pg_capture (vat_main_t * vam)
18644 {
18645   unformat_input_t *input = vam->input;
18646   vl_api_pg_capture_t *mp;
18647
18648   u32 if_id = ~0;
18649   u8 enable = 1;
18650   u32 count = 1;
18651   u8 pcap_file_set = 0;
18652   u8 *pcap_file = 0;
18653   int ret;
18654   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18655     {
18656       if (unformat (input, "if_id %d", &if_id))
18657         ;
18658       else if (unformat (input, "pcap %s", &pcap_file))
18659         pcap_file_set = 1;
18660       else if (unformat (input, "count %d", &count))
18661         ;
18662       else if (unformat (input, "disable"))
18663         enable = 0;
18664       else
18665         break;
18666     }
18667   if (if_id == ~0)
18668     {
18669       errmsg ("missing pg interface index");
18670       return -99;
18671     }
18672   if (pcap_file_set > 0)
18673     {
18674       if (vec_len (pcap_file) > 255)
18675         {
18676           errmsg ("pcap file name is too long");
18677           return -99;
18678         }
18679     }
18680
18681   u32 name_len = vec_len (pcap_file);
18682   /* Construct the API message */
18683   M (PG_CAPTURE, mp);
18684   mp->context = 0;
18685   mp->interface_id = ntohl (if_id);
18686   mp->is_enabled = enable;
18687   mp->count = ntohl (count);
18688   mp->pcap_name_length = ntohl (name_len);
18689   if (pcap_file_set != 0)
18690     {
18691       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
18692     }
18693   vec_free (pcap_file);
18694
18695   S (mp);
18696   W (ret);
18697   return ret;
18698 }
18699
18700 int
18701 api_pg_enable_disable (vat_main_t * vam)
18702 {
18703   unformat_input_t *input = vam->input;
18704   vl_api_pg_enable_disable_t *mp;
18705
18706   u8 enable = 1;
18707   u8 stream_name_set = 0;
18708   u8 *stream_name = 0;
18709   int ret;
18710   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18711     {
18712       if (unformat (input, "stream %s", &stream_name))
18713         stream_name_set = 1;
18714       else if (unformat (input, "disable"))
18715         enable = 0;
18716       else
18717         break;
18718     }
18719
18720   if (stream_name_set > 0)
18721     {
18722       if (vec_len (stream_name) > 255)
18723         {
18724           errmsg ("stream name too long");
18725           return -99;
18726         }
18727     }
18728
18729   u32 name_len = vec_len (stream_name);
18730   /* Construct the API message */
18731   M (PG_ENABLE_DISABLE, mp);
18732   mp->context = 0;
18733   mp->is_enabled = enable;
18734   if (stream_name_set != 0)
18735     {
18736       mp->stream_name_length = ntohl (name_len);
18737       clib_memcpy (mp->stream_name, stream_name, name_len);
18738     }
18739   vec_free (stream_name);
18740
18741   S (mp);
18742   W (ret);
18743   return ret;
18744 }
18745
18746 int
18747 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
18748 {
18749   unformat_input_t *input = vam->input;
18750   vl_api_ip_source_and_port_range_check_add_del_t *mp;
18751
18752   u16 *low_ports = 0;
18753   u16 *high_ports = 0;
18754   u16 this_low;
18755   u16 this_hi;
18756   vl_api_prefix_t prefix;
18757   u32 tmp, tmp2;
18758   u8 prefix_set = 0;
18759   u32 vrf_id = ~0;
18760   u8 is_add = 1;
18761   int ret;
18762
18763   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18764     {
18765       if (unformat (input, "%U", unformat_vl_api_prefix, &prefix))
18766         prefix_set = 1;
18767       else if (unformat (input, "vrf %d", &vrf_id))
18768         ;
18769       else if (unformat (input, "del"))
18770         is_add = 0;
18771       else if (unformat (input, "port %d", &tmp))
18772         {
18773           if (tmp == 0 || tmp > 65535)
18774             {
18775               errmsg ("port %d out of range", tmp);
18776               return -99;
18777             }
18778           this_low = tmp;
18779           this_hi = this_low + 1;
18780           vec_add1 (low_ports, this_low);
18781           vec_add1 (high_ports, this_hi);
18782         }
18783       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
18784         {
18785           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
18786             {
18787               errmsg ("incorrect range parameters");
18788               return -99;
18789             }
18790           this_low = tmp;
18791           /* Note: in debug CLI +1 is added to high before
18792              passing to real fn that does "the work"
18793              (ip_source_and_port_range_check_add_del).
18794              This fn is a wrapper around the binary API fn a
18795              control plane will call, which expects this increment
18796              to have occurred. Hence letting the binary API control
18797              plane fn do the increment for consistency between VAT
18798              and other control planes.
18799            */
18800           this_hi = tmp2;
18801           vec_add1 (low_ports, this_low);
18802           vec_add1 (high_ports, this_hi);
18803         }
18804       else
18805         break;
18806     }
18807
18808   if (prefix_set == 0)
18809     {
18810       errmsg ("<address>/<mask> not specified");
18811       return -99;
18812     }
18813
18814   if (vrf_id == ~0)
18815     {
18816       errmsg ("VRF ID required, not specified");
18817       return -99;
18818     }
18819
18820   if (vrf_id == 0)
18821     {
18822       errmsg
18823         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
18824       return -99;
18825     }
18826
18827   if (vec_len (low_ports) == 0)
18828     {
18829       errmsg ("At least one port or port range required");
18830       return -99;
18831     }
18832
18833   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
18834
18835   mp->is_add = is_add;
18836
18837   clib_memcpy (&mp->prefix, &prefix, sizeof (prefix));
18838
18839   mp->number_of_ranges = vec_len (low_ports);
18840
18841   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
18842   vec_free (low_ports);
18843
18844   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
18845   vec_free (high_ports);
18846
18847   mp->vrf_id = ntohl (vrf_id);
18848
18849   S (mp);
18850   W (ret);
18851   return ret;
18852 }
18853
18854 int
18855 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
18856 {
18857   unformat_input_t *input = vam->input;
18858   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
18859   u32 sw_if_index = ~0;
18860   int vrf_set = 0;
18861   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
18862   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
18863   u8 is_add = 1;
18864   int ret;
18865
18866   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18867     {
18868       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18869         ;
18870       else if (unformat (input, "sw_if_index %d", &sw_if_index))
18871         ;
18872       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
18873         vrf_set = 1;
18874       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
18875         vrf_set = 1;
18876       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
18877         vrf_set = 1;
18878       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
18879         vrf_set = 1;
18880       else if (unformat (input, "del"))
18881         is_add = 0;
18882       else
18883         break;
18884     }
18885
18886   if (sw_if_index == ~0)
18887     {
18888       errmsg ("Interface required but not specified");
18889       return -99;
18890     }
18891
18892   if (vrf_set == 0)
18893     {
18894       errmsg ("VRF ID required but not specified");
18895       return -99;
18896     }
18897
18898   if (tcp_out_vrf_id == 0
18899       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
18900     {
18901       errmsg
18902         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
18903       return -99;
18904     }
18905
18906   /* Construct the API message */
18907   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
18908
18909   mp->sw_if_index = ntohl (sw_if_index);
18910   mp->is_add = is_add;
18911   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
18912   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
18913   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
18914   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
18915
18916   /* send it... */
18917   S (mp);
18918
18919   /* Wait for a reply... */
18920   W (ret);
18921   return ret;
18922 }
18923
18924 static int
18925 api_set_punt (vat_main_t * vam)
18926 {
18927   unformat_input_t *i = vam->input;
18928   vl_api_address_family_t af;
18929   vl_api_set_punt_t *mp;
18930   u32 protocol = ~0;
18931   u32 port = ~0;
18932   int is_add = 1;
18933   int ret;
18934
18935   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18936     {
18937       if (unformat (i, "%U", unformat_vl_api_address_family, &af))
18938         ;
18939       else if (unformat (i, "protocol %d", &protocol))
18940         ;
18941       else if (unformat (i, "port %d", &port))
18942         ;
18943       else if (unformat (i, "del"))
18944         is_add = 0;
18945       else
18946         {
18947           clib_warning ("parse error '%U'", format_unformat_error, i);
18948           return -99;
18949         }
18950     }
18951
18952   M (SET_PUNT, mp);
18953
18954   mp->is_add = (u8) is_add;
18955   mp->punt.type = PUNT_API_TYPE_L4;
18956   mp->punt.punt.l4.af = af;
18957   mp->punt.punt.l4.protocol = (u8) protocol;
18958   mp->punt.punt.l4.port = htons ((u16) port);
18959
18960   S (mp);
18961   W (ret);
18962   return ret;
18963 }
18964
18965 static int
18966 api_delete_subif (vat_main_t * vam)
18967 {
18968   unformat_input_t *i = vam->input;
18969   vl_api_delete_subif_t *mp;
18970   u32 sw_if_index = ~0;
18971   int ret;
18972
18973   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18974     {
18975       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18976         ;
18977       if (unformat (i, "sw_if_index %d", &sw_if_index))
18978         ;
18979       else
18980         break;
18981     }
18982
18983   if (sw_if_index == ~0)
18984     {
18985       errmsg ("missing sw_if_index");
18986       return -99;
18987     }
18988
18989   /* Construct the API message */
18990   M (DELETE_SUBIF, mp);
18991   mp->sw_if_index = ntohl (sw_if_index);
18992
18993   S (mp);
18994   W (ret);
18995   return ret;
18996 }
18997
18998 #define foreach_pbb_vtr_op      \
18999 _("disable",  L2_VTR_DISABLED)  \
19000 _("pop",  L2_VTR_POP_2)         \
19001 _("push",  L2_VTR_PUSH_2)
19002
19003 static int
19004 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
19005 {
19006   unformat_input_t *i = vam->input;
19007   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
19008   u32 sw_if_index = ~0, vtr_op = ~0;
19009   u16 outer_tag = ~0;
19010   u8 dmac[6], smac[6];
19011   u8 dmac_set = 0, smac_set = 0;
19012   u16 vlanid = 0;
19013   u32 sid = ~0;
19014   u32 tmp;
19015   int ret;
19016
19017   /* Shut up coverity */
19018   clib_memset (dmac, 0, sizeof (dmac));
19019   clib_memset (smac, 0, sizeof (smac));
19020
19021   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19022     {
19023       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19024         ;
19025       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19026         ;
19027       else if (unformat (i, "vtr_op %d", &vtr_op))
19028         ;
19029 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
19030       foreach_pbb_vtr_op
19031 #undef _
19032         else if (unformat (i, "translate_pbb_stag"))
19033         {
19034           if (unformat (i, "%d", &tmp))
19035             {
19036               vtr_op = L2_VTR_TRANSLATE_2_1;
19037               outer_tag = tmp;
19038             }
19039           else
19040             {
19041               errmsg
19042                 ("translate_pbb_stag operation requires outer tag definition");
19043               return -99;
19044             }
19045         }
19046       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
19047         dmac_set++;
19048       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
19049         smac_set++;
19050       else if (unformat (i, "sid %d", &sid))
19051         ;
19052       else if (unformat (i, "vlanid %d", &tmp))
19053         vlanid = tmp;
19054       else
19055         {
19056           clib_warning ("parse error '%U'", format_unformat_error, i);
19057           return -99;
19058         }
19059     }
19060
19061   if ((sw_if_index == ~0) || (vtr_op == ~0))
19062     {
19063       errmsg ("missing sw_if_index or vtr operation");
19064       return -99;
19065     }
19066   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
19067       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
19068     {
19069       errmsg
19070         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
19071       return -99;
19072     }
19073
19074   M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
19075   mp->sw_if_index = ntohl (sw_if_index);
19076   mp->vtr_op = ntohl (vtr_op);
19077   mp->outer_tag = ntohs (outer_tag);
19078   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
19079   clib_memcpy (mp->b_smac, smac, sizeof (smac));
19080   mp->b_vlanid = ntohs (vlanid);
19081   mp->i_sid = ntohl (sid);
19082
19083   S (mp);
19084   W (ret);
19085   return ret;
19086 }
19087
19088 static int
19089 api_flow_classify_set_interface (vat_main_t * vam)
19090 {
19091   unformat_input_t *i = vam->input;
19092   vl_api_flow_classify_set_interface_t *mp;
19093   u32 sw_if_index;
19094   int sw_if_index_set;
19095   u32 ip4_table_index = ~0;
19096   u32 ip6_table_index = ~0;
19097   u8 is_add = 1;
19098   int ret;
19099
19100   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19101     {
19102       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19103         sw_if_index_set = 1;
19104       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19105         sw_if_index_set = 1;
19106       else if (unformat (i, "del"))
19107         is_add = 0;
19108       else if (unformat (i, "ip4-table %d", &ip4_table_index))
19109         ;
19110       else if (unformat (i, "ip6-table %d", &ip6_table_index))
19111         ;
19112       else
19113         {
19114           clib_warning ("parse error '%U'", format_unformat_error, i);
19115           return -99;
19116         }
19117     }
19118
19119   if (sw_if_index_set == 0)
19120     {
19121       errmsg ("missing interface name or sw_if_index");
19122       return -99;
19123     }
19124
19125   M (FLOW_CLASSIFY_SET_INTERFACE, mp);
19126
19127   mp->sw_if_index = ntohl (sw_if_index);
19128   mp->ip4_table_index = ntohl (ip4_table_index);
19129   mp->ip6_table_index = ntohl (ip6_table_index);
19130   mp->is_add = is_add;
19131
19132   S (mp);
19133   W (ret);
19134   return ret;
19135 }
19136
19137 static int
19138 api_flow_classify_dump (vat_main_t * vam)
19139 {
19140   unformat_input_t *i = vam->input;
19141   vl_api_flow_classify_dump_t *mp;
19142   vl_api_control_ping_t *mp_ping;
19143   u8 type = FLOW_CLASSIFY_N_TABLES;
19144   int ret;
19145
19146   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
19147     ;
19148   else
19149     {
19150       errmsg ("classify table type must be specified");
19151       return -99;
19152     }
19153
19154   if (!vam->json_output)
19155     {
19156       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
19157     }
19158
19159   M (FLOW_CLASSIFY_DUMP, mp);
19160   mp->type = type;
19161   /* send it... */
19162   S (mp);
19163
19164   /* Use a control ping for synchronization */
19165   MPING (CONTROL_PING, mp_ping);
19166   S (mp_ping);
19167
19168   /* Wait for a reply... */
19169   W (ret);
19170   return ret;
19171 }
19172
19173 static int
19174 api_feature_enable_disable (vat_main_t * vam)
19175 {
19176   unformat_input_t *i = vam->input;
19177   vl_api_feature_enable_disable_t *mp;
19178   u8 *arc_name = 0;
19179   u8 *feature_name = 0;
19180   u32 sw_if_index = ~0;
19181   u8 enable = 1;
19182   int ret;
19183
19184   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19185     {
19186       if (unformat (i, "arc_name %s", &arc_name))
19187         ;
19188       else if (unformat (i, "feature_name %s", &feature_name))
19189         ;
19190       else
19191         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19192         ;
19193       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19194         ;
19195       else if (unformat (i, "disable"))
19196         enable = 0;
19197       else
19198         break;
19199     }
19200
19201   if (arc_name == 0)
19202     {
19203       errmsg ("missing arc name");
19204       return -99;
19205     }
19206   if (vec_len (arc_name) > 63)
19207     {
19208       errmsg ("arc name too long");
19209     }
19210
19211   if (feature_name == 0)
19212     {
19213       errmsg ("missing feature name");
19214       return -99;
19215     }
19216   if (vec_len (feature_name) > 63)
19217     {
19218       errmsg ("feature name too long");
19219     }
19220
19221   if (sw_if_index == ~0)
19222     {
19223       errmsg ("missing interface name or sw_if_index");
19224       return -99;
19225     }
19226
19227   /* Construct the API message */
19228   M (FEATURE_ENABLE_DISABLE, mp);
19229   mp->sw_if_index = ntohl (sw_if_index);
19230   mp->enable = enable;
19231   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
19232   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
19233   vec_free (arc_name);
19234   vec_free (feature_name);
19235
19236   S (mp);
19237   W (ret);
19238   return ret;
19239 }
19240
19241 static int
19242 api_feature_gso_enable_disable (vat_main_t * vam)
19243 {
19244   unformat_input_t *i = vam->input;
19245   vl_api_feature_gso_enable_disable_t *mp;
19246   u32 sw_if_index = ~0;
19247   u8 enable = 1;
19248   int ret;
19249
19250   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19251     {
19252       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19253         ;
19254       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19255         ;
19256       else if (unformat (i, "enable"))
19257         enable = 1;
19258       else if (unformat (i, "disable"))
19259         enable = 0;
19260       else
19261         break;
19262     }
19263
19264   if (sw_if_index == ~0)
19265     {
19266       errmsg ("missing interface name or sw_if_index");
19267       return -99;
19268     }
19269
19270   /* Construct the API message */
19271   M (FEATURE_GSO_ENABLE_DISABLE, mp);
19272   mp->sw_if_index = ntohl (sw_if_index);
19273   mp->enable_disable = enable;
19274
19275   S (mp);
19276   W (ret);
19277   return ret;
19278 }
19279
19280 static int
19281 api_sw_interface_tag_add_del (vat_main_t * vam)
19282 {
19283   unformat_input_t *i = vam->input;
19284   vl_api_sw_interface_tag_add_del_t *mp;
19285   u32 sw_if_index = ~0;
19286   u8 *tag = 0;
19287   u8 enable = 1;
19288   int ret;
19289
19290   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19291     {
19292       if (unformat (i, "tag %s", &tag))
19293         ;
19294       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19295         ;
19296       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19297         ;
19298       else if (unformat (i, "del"))
19299         enable = 0;
19300       else
19301         break;
19302     }
19303
19304   if (sw_if_index == ~0)
19305     {
19306       errmsg ("missing interface name or sw_if_index");
19307       return -99;
19308     }
19309
19310   if (enable && (tag == 0))
19311     {
19312       errmsg ("no tag specified");
19313       return -99;
19314     }
19315
19316   /* Construct the API message */
19317   M (SW_INTERFACE_TAG_ADD_DEL, mp);
19318   mp->sw_if_index = ntohl (sw_if_index);
19319   mp->is_add = enable;
19320   if (enable)
19321     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
19322   vec_free (tag);
19323
19324   S (mp);
19325   W (ret);
19326   return ret;
19327 }
19328
19329 static int
19330 api_sw_interface_add_del_mac_address (vat_main_t * vam)
19331 {
19332   unformat_input_t *i = vam->input;
19333   vl_api_mac_address_t mac = { 0 };
19334   vl_api_sw_interface_add_del_mac_address_t *mp;
19335   u32 sw_if_index = ~0;
19336   u8 is_add = 1;
19337   u8 mac_set = 0;
19338   int ret;
19339
19340   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19341     {
19342       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19343         ;
19344       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19345         ;
19346       else if (unformat (i, "%U", unformat_vl_api_mac_address, &mac))
19347         mac_set++;
19348       else if (unformat (i, "del"))
19349         is_add = 0;
19350       else
19351         break;
19352     }
19353
19354   if (sw_if_index == ~0)
19355     {
19356       errmsg ("missing interface name or sw_if_index");
19357       return -99;
19358     }
19359
19360   if (!mac_set)
19361     {
19362       errmsg ("missing MAC address");
19363       return -99;
19364     }
19365
19366   /* Construct the API message */
19367   M (SW_INTERFACE_ADD_DEL_MAC_ADDRESS, mp);
19368   mp->sw_if_index = ntohl (sw_if_index);
19369   mp->is_add = is_add;
19370   clib_memcpy (&mp->addr, &mac, sizeof (mac));
19371
19372   S (mp);
19373   W (ret);
19374   return ret;
19375 }
19376
19377 static void vl_api_l2_xconnect_details_t_handler
19378   (vl_api_l2_xconnect_details_t * mp)
19379 {
19380   vat_main_t *vam = &vat_main;
19381
19382   print (vam->ofp, "%15d%15d",
19383          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
19384 }
19385
19386 static void vl_api_l2_xconnect_details_t_handler_json
19387   (vl_api_l2_xconnect_details_t * mp)
19388 {
19389   vat_main_t *vam = &vat_main;
19390   vat_json_node_t *node = NULL;
19391
19392   if (VAT_JSON_ARRAY != vam->json_tree.type)
19393     {
19394       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19395       vat_json_init_array (&vam->json_tree);
19396     }
19397   node = vat_json_array_add (&vam->json_tree);
19398
19399   vat_json_init_object (node);
19400   vat_json_object_add_uint (node, "rx_sw_if_index",
19401                             ntohl (mp->rx_sw_if_index));
19402   vat_json_object_add_uint (node, "tx_sw_if_index",
19403                             ntohl (mp->tx_sw_if_index));
19404 }
19405
19406 static int
19407 api_l2_xconnect_dump (vat_main_t * vam)
19408 {
19409   vl_api_l2_xconnect_dump_t *mp;
19410   vl_api_control_ping_t *mp_ping;
19411   int ret;
19412
19413   if (!vam->json_output)
19414     {
19415       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
19416     }
19417
19418   M (L2_XCONNECT_DUMP, mp);
19419
19420   S (mp);
19421
19422   /* Use a control ping for synchronization */
19423   MPING (CONTROL_PING, mp_ping);
19424   S (mp_ping);
19425
19426   W (ret);
19427   return ret;
19428 }
19429
19430 static int
19431 api_hw_interface_set_mtu (vat_main_t * vam)
19432 {
19433   unformat_input_t *i = vam->input;
19434   vl_api_hw_interface_set_mtu_t *mp;
19435   u32 sw_if_index = ~0;
19436   u32 mtu = 0;
19437   int ret;
19438
19439   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19440     {
19441       if (unformat (i, "mtu %d", &mtu))
19442         ;
19443       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19444         ;
19445       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19446         ;
19447       else
19448         break;
19449     }
19450
19451   if (sw_if_index == ~0)
19452     {
19453       errmsg ("missing interface name or sw_if_index");
19454       return -99;
19455     }
19456
19457   if (mtu == 0)
19458     {
19459       errmsg ("no mtu specified");
19460       return -99;
19461     }
19462
19463   /* Construct the API message */
19464   M (HW_INTERFACE_SET_MTU, mp);
19465   mp->sw_if_index = ntohl (sw_if_index);
19466   mp->mtu = ntohs ((u16) mtu);
19467
19468   S (mp);
19469   W (ret);
19470   return ret;
19471 }
19472
19473 static int
19474 api_p2p_ethernet_add (vat_main_t * vam)
19475 {
19476   unformat_input_t *i = vam->input;
19477   vl_api_p2p_ethernet_add_t *mp;
19478   u32 parent_if_index = ~0;
19479   u32 sub_id = ~0;
19480   u8 remote_mac[6];
19481   u8 mac_set = 0;
19482   int ret;
19483
19484   clib_memset (remote_mac, 0, sizeof (remote_mac));
19485   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19486     {
19487       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
19488         ;
19489       else if (unformat (i, "sw_if_index %d", &parent_if_index))
19490         ;
19491       else
19492         if (unformat
19493             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
19494         mac_set++;
19495       else if (unformat (i, "sub_id %d", &sub_id))
19496         ;
19497       else
19498         {
19499           clib_warning ("parse error '%U'", format_unformat_error, i);
19500           return -99;
19501         }
19502     }
19503
19504   if (parent_if_index == ~0)
19505     {
19506       errmsg ("missing interface name or sw_if_index");
19507       return -99;
19508     }
19509   if (mac_set == 0)
19510     {
19511       errmsg ("missing remote mac address");
19512       return -99;
19513     }
19514   if (sub_id == ~0)
19515     {
19516       errmsg ("missing sub-interface id");
19517       return -99;
19518     }
19519
19520   M (P2P_ETHERNET_ADD, mp);
19521   mp->parent_if_index = ntohl (parent_if_index);
19522   mp->subif_id = ntohl (sub_id);
19523   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
19524
19525   S (mp);
19526   W (ret);
19527   return ret;
19528 }
19529
19530 static int
19531 api_p2p_ethernet_del (vat_main_t * vam)
19532 {
19533   unformat_input_t *i = vam->input;
19534   vl_api_p2p_ethernet_del_t *mp;
19535   u32 parent_if_index = ~0;
19536   u8 remote_mac[6];
19537   u8 mac_set = 0;
19538   int ret;
19539
19540   clib_memset (remote_mac, 0, sizeof (remote_mac));
19541   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19542     {
19543       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
19544         ;
19545       else if (unformat (i, "sw_if_index %d", &parent_if_index))
19546         ;
19547       else
19548         if (unformat
19549             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
19550         mac_set++;
19551       else
19552         {
19553           clib_warning ("parse error '%U'", format_unformat_error, i);
19554           return -99;
19555         }
19556     }
19557
19558   if (parent_if_index == ~0)
19559     {
19560       errmsg ("missing interface name or sw_if_index");
19561       return -99;
19562     }
19563   if (mac_set == 0)
19564     {
19565       errmsg ("missing remote mac address");
19566       return -99;
19567     }
19568
19569   M (P2P_ETHERNET_DEL, mp);
19570   mp->parent_if_index = ntohl (parent_if_index);
19571   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
19572
19573   S (mp);
19574   W (ret);
19575   return ret;
19576 }
19577
19578 static int
19579 api_lldp_config (vat_main_t * vam)
19580 {
19581   unformat_input_t *i = vam->input;
19582   vl_api_lldp_config_t *mp;
19583   int tx_hold = 0;
19584   int tx_interval = 0;
19585   u8 *sys_name = NULL;
19586   int ret;
19587
19588   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19589     {
19590       if (unformat (i, "system-name %s", &sys_name))
19591         ;
19592       else if (unformat (i, "tx-hold %d", &tx_hold))
19593         ;
19594       else if (unformat (i, "tx-interval %d", &tx_interval))
19595         ;
19596       else
19597         {
19598           clib_warning ("parse error '%U'", format_unformat_error, i);
19599           return -99;
19600         }
19601     }
19602
19603   vec_add1 (sys_name, 0);
19604
19605   M (LLDP_CONFIG, mp);
19606   mp->tx_hold = htonl (tx_hold);
19607   mp->tx_interval = htonl (tx_interval);
19608   clib_memcpy (mp->system_name, sys_name, vec_len (sys_name));
19609   vec_free (sys_name);
19610
19611   S (mp);
19612   W (ret);
19613   return ret;
19614 }
19615
19616 static int
19617 api_sw_interface_set_lldp (vat_main_t * vam)
19618 {
19619   unformat_input_t *i = vam->input;
19620   vl_api_sw_interface_set_lldp_t *mp;
19621   u32 sw_if_index = ~0;
19622   u32 enable = 1;
19623   u8 *port_desc = NULL, *mgmt_oid = NULL;
19624   ip4_address_t ip4_addr;
19625   ip6_address_t ip6_addr;
19626   int ret;
19627
19628   clib_memset (&ip4_addr, 0, sizeof (ip4_addr));
19629   clib_memset (&ip6_addr, 0, sizeof (ip6_addr));
19630
19631   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19632     {
19633       if (unformat (i, "disable"))
19634         enable = 0;
19635       else
19636         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19637         ;
19638       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19639         ;
19640       else if (unformat (i, "port-desc %s", &port_desc))
19641         ;
19642       else if (unformat (i, "mgmt-ip4 %U", unformat_ip4_address, &ip4_addr))
19643         ;
19644       else if (unformat (i, "mgmt-ip6 %U", unformat_ip6_address, &ip6_addr))
19645         ;
19646       else if (unformat (i, "mgmt-oid %s", &mgmt_oid))
19647         ;
19648       else
19649         break;
19650     }
19651
19652   if (sw_if_index == ~0)
19653     {
19654       errmsg ("missing interface name or sw_if_index");
19655       return -99;
19656     }
19657
19658   /* Construct the API message */
19659   vec_add1 (port_desc, 0);
19660   vec_add1 (mgmt_oid, 0);
19661   M (SW_INTERFACE_SET_LLDP, mp);
19662   mp->sw_if_index = ntohl (sw_if_index);
19663   mp->enable = enable;
19664   clib_memcpy (mp->port_desc, port_desc, vec_len (port_desc));
19665   clib_memcpy (mp->mgmt_oid, mgmt_oid, vec_len (mgmt_oid));
19666   clib_memcpy (mp->mgmt_ip4, &ip4_addr, sizeof (ip4_addr));
19667   clib_memcpy (mp->mgmt_ip6, &ip6_addr, sizeof (ip6_addr));
19668   vec_free (port_desc);
19669   vec_free (mgmt_oid);
19670
19671   S (mp);
19672   W (ret);
19673   return ret;
19674 }
19675
19676 static int
19677 api_tcp_configure_src_addresses (vat_main_t * vam)
19678 {
19679   vl_api_tcp_configure_src_addresses_t *mp;
19680   unformat_input_t *i = vam->input;
19681   vl_api_address_t first, last;
19682   u8 range_set = 0;
19683   u32 vrf_id = 0;
19684   int ret;
19685
19686   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19687     {
19688       if (unformat (i, "%U - %U",
19689                     unformat_vl_api_address, &first,
19690                     unformat_vl_api_address, &last))
19691         {
19692           if (range_set)
19693             {
19694               errmsg ("one range per message (range already set)");
19695               return -99;
19696             }
19697           range_set = 1;
19698         }
19699       else if (unformat (i, "vrf %d", &vrf_id))
19700         ;
19701       else
19702         break;
19703     }
19704
19705   if (range_set == 0)
19706     {
19707       errmsg ("address range not set");
19708       return -99;
19709     }
19710
19711   M (TCP_CONFIGURE_SRC_ADDRESSES, mp);
19712
19713   mp->vrf_id = ntohl (vrf_id);
19714   clib_memcpy (&mp->first_address, &first, sizeof (first));
19715   clib_memcpy (&mp->last_address, &last, sizeof (last));
19716
19717   S (mp);
19718   W (ret);
19719   return ret;
19720 }
19721
19722 static void vl_api_app_namespace_add_del_reply_t_handler
19723   (vl_api_app_namespace_add_del_reply_t * mp)
19724 {
19725   vat_main_t *vam = &vat_main;
19726   i32 retval = ntohl (mp->retval);
19727   if (vam->async_mode)
19728     {
19729       vam->async_errors += (retval < 0);
19730     }
19731   else
19732     {
19733       vam->retval = retval;
19734       if (retval == 0)
19735         errmsg ("app ns index %d\n", ntohl (mp->appns_index));
19736       vam->result_ready = 1;
19737     }
19738 }
19739
19740 static void vl_api_app_namespace_add_del_reply_t_handler_json
19741   (vl_api_app_namespace_add_del_reply_t * mp)
19742 {
19743   vat_main_t *vam = &vat_main;
19744   vat_json_node_t node;
19745
19746   vat_json_init_object (&node);
19747   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
19748   vat_json_object_add_uint (&node, "appns_index", ntohl (mp->appns_index));
19749
19750   vat_json_print (vam->ofp, &node);
19751   vat_json_free (&node);
19752
19753   vam->retval = ntohl (mp->retval);
19754   vam->result_ready = 1;
19755 }
19756
19757 static int
19758 api_app_namespace_add_del (vat_main_t * vam)
19759 {
19760   vl_api_app_namespace_add_del_t *mp;
19761   unformat_input_t *i = vam->input;
19762   u8 *ns_id = 0, secret_set = 0, sw_if_index_set = 0;
19763   u32 sw_if_index, ip4_fib_id, ip6_fib_id;
19764   u64 secret;
19765   int ret;
19766
19767   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19768     {
19769       if (unformat (i, "id %_%v%_", &ns_id))
19770         ;
19771       else if (unformat (i, "secret %lu", &secret))
19772         secret_set = 1;
19773       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19774         sw_if_index_set = 1;
19775       else if (unformat (i, "ip4_fib_id %d", &ip4_fib_id))
19776         ;
19777       else if (unformat (i, "ip6_fib_id %d", &ip6_fib_id))
19778         ;
19779       else
19780         break;
19781     }
19782   if (!ns_id || !secret_set || !sw_if_index_set)
19783     {
19784       errmsg ("namespace id, secret and sw_if_index must be set");
19785       return -99;
19786     }
19787   if (vec_len (ns_id) > 64)
19788     {
19789       errmsg ("namespace id too long");
19790       return -99;
19791     }
19792   M (APP_NAMESPACE_ADD_DEL, mp);
19793
19794   clib_memcpy (mp->namespace_id, ns_id, vec_len (ns_id));
19795   mp->namespace_id_len = vec_len (ns_id);
19796   mp->secret = clib_host_to_net_u64 (secret);
19797   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
19798   mp->ip4_fib_id = clib_host_to_net_u32 (ip4_fib_id);
19799   mp->ip6_fib_id = clib_host_to_net_u32 (ip6_fib_id);
19800   vec_free (ns_id);
19801   S (mp);
19802   W (ret);
19803   return ret;
19804 }
19805
19806 static int
19807 api_sock_init_shm (vat_main_t * vam)
19808 {
19809 #if VPP_API_TEST_BUILTIN == 0
19810   unformat_input_t *i = vam->input;
19811   vl_api_shm_elem_config_t *config = 0;
19812   u64 size = 64 << 20;
19813   int rv;
19814
19815   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19816     {
19817       if (unformat (i, "size %U", unformat_memory_size, &size))
19818         ;
19819       else
19820         break;
19821     }
19822
19823   /*
19824    * Canned custom ring allocator config.
19825    * Should probably parse all of this
19826    */
19827   vec_validate (config, 6);
19828   config[0].type = VL_API_VLIB_RING;
19829   config[0].size = 256;
19830   config[0].count = 32;
19831
19832   config[1].type = VL_API_VLIB_RING;
19833   config[1].size = 1024;
19834   config[1].count = 16;
19835
19836   config[2].type = VL_API_VLIB_RING;
19837   config[2].size = 4096;
19838   config[2].count = 2;
19839
19840   config[3].type = VL_API_CLIENT_RING;
19841   config[3].size = 256;
19842   config[3].count = 32;
19843
19844   config[4].type = VL_API_CLIENT_RING;
19845   config[4].size = 1024;
19846   config[4].count = 16;
19847
19848   config[5].type = VL_API_CLIENT_RING;
19849   config[5].size = 4096;
19850   config[5].count = 2;
19851
19852   config[6].type = VL_API_QUEUE;
19853   config[6].count = 128;
19854   config[6].size = sizeof (uword);
19855
19856   rv = vl_socket_client_init_shm (config, 1 /* want_pthread */ );
19857   if (!rv)
19858     vam->client_index_invalid = 1;
19859   return rv;
19860 #else
19861   return -99;
19862 #endif
19863 }
19864
19865 static void
19866 vl_api_session_rules_details_t_handler (vl_api_session_rules_details_t * mp)
19867 {
19868   vat_main_t *vam = &vat_main;
19869
19870   if (mp->is_ip4)
19871     {
19872       print (vam->ofp,
19873              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
19874              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
19875              mp->scope, format_ip4_address, &mp->lcl_ip, mp->lcl_plen,
19876              clib_net_to_host_u16 (mp->lcl_port), format_ip4_address,
19877              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
19878              clib_net_to_host_u32 (mp->action_index), mp->tag);
19879     }
19880   else
19881     {
19882       print (vam->ofp,
19883              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
19884              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
19885              mp->scope, format_ip6_address, &mp->lcl_ip, mp->lcl_plen,
19886              clib_net_to_host_u16 (mp->lcl_port), format_ip6_address,
19887              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
19888              clib_net_to_host_u32 (mp->action_index), mp->tag);
19889     }
19890 }
19891
19892 static void
19893 vl_api_session_rules_details_t_handler_json (vl_api_session_rules_details_t *
19894                                              mp)
19895 {
19896   vat_main_t *vam = &vat_main;
19897   vat_json_node_t *node = NULL;
19898   struct in6_addr ip6;
19899   struct in_addr ip4;
19900
19901   if (VAT_JSON_ARRAY != vam->json_tree.type)
19902     {
19903       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19904       vat_json_init_array (&vam->json_tree);
19905     }
19906   node = vat_json_array_add (&vam->json_tree);
19907   vat_json_init_object (node);
19908
19909   vat_json_object_add_uint (node, "is_ip4", mp->is_ip4 ? 1 : 0);
19910   vat_json_object_add_uint (node, "appns_index",
19911                             clib_net_to_host_u32 (mp->appns_index));
19912   vat_json_object_add_uint (node, "transport_proto", mp->transport_proto);
19913   vat_json_object_add_uint (node, "scope", mp->scope);
19914   vat_json_object_add_uint (node, "action_index",
19915                             clib_net_to_host_u32 (mp->action_index));
19916   vat_json_object_add_uint (node, "lcl_port",
19917                             clib_net_to_host_u16 (mp->lcl_port));
19918   vat_json_object_add_uint (node, "rmt_port",
19919                             clib_net_to_host_u16 (mp->rmt_port));
19920   vat_json_object_add_uint (node, "lcl_plen", mp->lcl_plen);
19921   vat_json_object_add_uint (node, "rmt_plen", mp->rmt_plen);
19922   vat_json_object_add_string_copy (node, "tag", mp->tag);
19923   if (mp->is_ip4)
19924     {
19925       clib_memcpy (&ip4, mp->lcl_ip, sizeof (ip4));
19926       vat_json_object_add_ip4 (node, "lcl_ip", ip4);
19927       clib_memcpy (&ip4, mp->rmt_ip, sizeof (ip4));
19928       vat_json_object_add_ip4 (node, "rmt_ip", ip4);
19929     }
19930   else
19931     {
19932       clib_memcpy (&ip6, mp->lcl_ip, sizeof (ip6));
19933       vat_json_object_add_ip6 (node, "lcl_ip", ip6);
19934       clib_memcpy (&ip6, mp->rmt_ip, sizeof (ip6));
19935       vat_json_object_add_ip6 (node, "rmt_ip", ip6);
19936     }
19937 }
19938
19939 static int
19940 api_session_rule_add_del (vat_main_t * vam)
19941 {
19942   vl_api_session_rule_add_del_t *mp;
19943   unformat_input_t *i = vam->input;
19944   u32 proto = ~0, lcl_port, rmt_port, action = 0, lcl_plen, rmt_plen;
19945   u32 appns_index = 0, scope = 0;
19946   ip4_address_t lcl_ip4, rmt_ip4;
19947   ip6_address_t lcl_ip6, rmt_ip6;
19948   u8 is_ip4 = 1, conn_set = 0;
19949   u8 is_add = 1, *tag = 0;
19950   int ret;
19951
19952   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19953     {
19954       if (unformat (i, "del"))
19955         is_add = 0;
19956       else if (unformat (i, "add"))
19957         ;
19958       else if (unformat (i, "proto tcp"))
19959         proto = 0;
19960       else if (unformat (i, "proto udp"))
19961         proto = 1;
19962       else if (unformat (i, "appns %d", &appns_index))
19963         ;
19964       else if (unformat (i, "scope %d", &scope))
19965         ;
19966       else if (unformat (i, "tag %_%v%_", &tag))
19967         ;
19968       else
19969         if (unformat
19970             (i, "%U/%d %d %U/%d %d", unformat_ip4_address, &lcl_ip4,
19971              &lcl_plen, &lcl_port, unformat_ip4_address, &rmt_ip4, &rmt_plen,
19972              &rmt_port))
19973         {
19974           is_ip4 = 1;
19975           conn_set = 1;
19976         }
19977       else
19978         if (unformat
19979             (i, "%U/%d %d %U/%d %d", unformat_ip6_address, &lcl_ip6,
19980              &lcl_plen, &lcl_port, unformat_ip6_address, &rmt_ip6, &rmt_plen,
19981              &rmt_port))
19982         {
19983           is_ip4 = 0;
19984           conn_set = 1;
19985         }
19986       else if (unformat (i, "action %d", &action))
19987         ;
19988       else
19989         break;
19990     }
19991   if (proto == ~0 || !conn_set || action == ~0)
19992     {
19993       errmsg ("transport proto, connection and action must be set");
19994       return -99;
19995     }
19996
19997   if (scope > 3)
19998     {
19999       errmsg ("scope should be 0-3");
20000       return -99;
20001     }
20002
20003   M (SESSION_RULE_ADD_DEL, mp);
20004
20005   mp->is_ip4 = is_ip4;
20006   mp->transport_proto = proto;
20007   mp->lcl_port = clib_host_to_net_u16 ((u16) lcl_port);
20008   mp->rmt_port = clib_host_to_net_u16 ((u16) rmt_port);
20009   mp->lcl_plen = lcl_plen;
20010   mp->rmt_plen = rmt_plen;
20011   mp->action_index = clib_host_to_net_u32 (action);
20012   mp->appns_index = clib_host_to_net_u32 (appns_index);
20013   mp->scope = scope;
20014   mp->is_add = is_add;
20015   if (is_ip4)
20016     {
20017       clib_memcpy (mp->lcl_ip, &lcl_ip4, sizeof (lcl_ip4));
20018       clib_memcpy (mp->rmt_ip, &rmt_ip4, sizeof (rmt_ip4));
20019     }
20020   else
20021     {
20022       clib_memcpy (mp->lcl_ip, &lcl_ip6, sizeof (lcl_ip6));
20023       clib_memcpy (mp->rmt_ip, &rmt_ip6, sizeof (rmt_ip6));
20024     }
20025   if (tag)
20026     {
20027       clib_memcpy (mp->tag, tag, vec_len (tag));
20028       vec_free (tag);
20029     }
20030
20031   S (mp);
20032   W (ret);
20033   return ret;
20034 }
20035
20036 static int
20037 api_session_rules_dump (vat_main_t * vam)
20038 {
20039   vl_api_session_rules_dump_t *mp;
20040   vl_api_control_ping_t *mp_ping;
20041   int ret;
20042
20043   if (!vam->json_output)
20044     {
20045       print (vam->ofp, "%=20s", "Session Rules");
20046     }
20047
20048   M (SESSION_RULES_DUMP, mp);
20049   /* send it... */
20050   S (mp);
20051
20052   /* Use a control ping for synchronization */
20053   MPING (CONTROL_PING, mp_ping);
20054   S (mp_ping);
20055
20056   /* Wait for a reply... */
20057   W (ret);
20058   return ret;
20059 }
20060
20061 static int
20062 api_ip_container_proxy_add_del (vat_main_t * vam)
20063 {
20064   vl_api_ip_container_proxy_add_del_t *mp;
20065   unformat_input_t *i = vam->input;
20066   u32 sw_if_index = ~0;
20067   vl_api_prefix_t pfx = { };
20068   u8 is_add = 1;
20069   int ret;
20070
20071   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20072     {
20073       if (unformat (i, "del"))
20074         is_add = 0;
20075       else if (unformat (i, "add"))
20076         ;
20077       if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
20078         ;
20079       else if (unformat (i, "sw_if_index %u", &sw_if_index))
20080         ;
20081       else
20082         break;
20083     }
20084   if (sw_if_index == ~0 || pfx.len == 0)
20085     {
20086       errmsg ("address and sw_if_index must be set");
20087       return -99;
20088     }
20089
20090   M (IP_CONTAINER_PROXY_ADD_DEL, mp);
20091
20092   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
20093   mp->is_add = is_add;
20094   clib_memcpy (&mp->pfx, &pfx, sizeof (pfx));
20095
20096   S (mp);
20097   W (ret);
20098   return ret;
20099 }
20100
20101 static int
20102 api_qos_record_enable_disable (vat_main_t * vam)
20103 {
20104   unformat_input_t *i = vam->input;
20105   vl_api_qos_record_enable_disable_t *mp;
20106   u32 sw_if_index, qs = 0xff;
20107   u8 sw_if_index_set = 0;
20108   u8 enable = 1;
20109   int ret;
20110
20111   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20112     {
20113       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20114         sw_if_index_set = 1;
20115       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20116         sw_if_index_set = 1;
20117       else if (unformat (i, "%U", unformat_qos_source, &qs))
20118         ;
20119       else if (unformat (i, "disable"))
20120         enable = 0;
20121       else
20122         {
20123           clib_warning ("parse error '%U'", format_unformat_error, i);
20124           return -99;
20125         }
20126     }
20127
20128   if (sw_if_index_set == 0)
20129     {
20130       errmsg ("missing interface name or sw_if_index");
20131       return -99;
20132     }
20133   if (qs == 0xff)
20134     {
20135       errmsg ("input location must be specified");
20136       return -99;
20137     }
20138
20139   M (QOS_RECORD_ENABLE_DISABLE, mp);
20140
20141   mp->record.sw_if_index = ntohl (sw_if_index);
20142   mp->record.input_source = qs;
20143   mp->enable = enable;
20144
20145   S (mp);
20146   W (ret);
20147   return ret;
20148 }
20149
20150
20151 static int
20152 q_or_quit (vat_main_t * vam)
20153 {
20154 #if VPP_API_TEST_BUILTIN == 0
20155   longjmp (vam->jump_buf, 1);
20156 #endif
20157   return 0;                     /* not so much */
20158 }
20159
20160 static int
20161 q (vat_main_t * vam)
20162 {
20163   return q_or_quit (vam);
20164 }
20165
20166 static int
20167 quit (vat_main_t * vam)
20168 {
20169   return q_or_quit (vam);
20170 }
20171
20172 static int
20173 comment (vat_main_t * vam)
20174 {
20175   return 0;
20176 }
20177
20178 static int
20179 elog_save (vat_main_t * vam)
20180 {
20181 #if VPP_API_TEST_BUILTIN == 0
20182   elog_main_t *em = &vam->elog_main;
20183   unformat_input_t *i = vam->input;
20184   char *file, *chroot_file;
20185   clib_error_t *error;
20186
20187   if (!unformat (i, "%s", &file))
20188     {
20189       errmsg ("expected file name, got `%U'", format_unformat_error, i);
20190       return 0;
20191     }
20192
20193   /* It's fairly hard to get "../oopsie" through unformat; just in case */
20194   if (strstr (file, "..") || index (file, '/'))
20195     {
20196       errmsg ("illegal characters in filename '%s'", file);
20197       return 0;
20198     }
20199
20200   chroot_file = (char *) format (0, "/tmp/%s%c", file, 0);
20201
20202   vec_free (file);
20203
20204   errmsg ("Saving %wd of %wd events to %s",
20205           elog_n_events_in_buffer (em),
20206           elog_buffer_capacity (em), chroot_file);
20207
20208   error = elog_write_file (em, chroot_file, 1 /* flush ring */ );
20209   vec_free (chroot_file);
20210
20211   if (error)
20212     clib_error_report (error);
20213 #else
20214   errmsg ("Use the vpp event loger...");
20215 #endif
20216
20217   return 0;
20218 }
20219
20220 static int
20221 elog_setup (vat_main_t * vam)
20222 {
20223 #if VPP_API_TEST_BUILTIN == 0
20224   elog_main_t *em = &vam->elog_main;
20225   unformat_input_t *i = vam->input;
20226   u32 nevents = 128 << 10;
20227
20228   (void) unformat (i, "nevents %d", &nevents);
20229
20230   elog_init (em, nevents);
20231   vl_api_set_elog_main (em);
20232   vl_api_set_elog_trace_api_messages (1);
20233   errmsg ("Event logger initialized with %u events", nevents);
20234 #else
20235   errmsg ("Use the vpp event loger...");
20236 #endif
20237   return 0;
20238 }
20239
20240 static int
20241 elog_enable (vat_main_t * vam)
20242 {
20243 #if VPP_API_TEST_BUILTIN == 0
20244   elog_main_t *em = &vam->elog_main;
20245
20246   elog_enable_disable (em, 1 /* enable */ );
20247   vl_api_set_elog_trace_api_messages (1);
20248   errmsg ("Event logger enabled...");
20249 #else
20250   errmsg ("Use the vpp event loger...");
20251 #endif
20252   return 0;
20253 }
20254
20255 static int
20256 elog_disable (vat_main_t * vam)
20257 {
20258 #if VPP_API_TEST_BUILTIN == 0
20259   elog_main_t *em = &vam->elog_main;
20260
20261   elog_enable_disable (em, 0 /* enable */ );
20262   vl_api_set_elog_trace_api_messages (1);
20263   errmsg ("Event logger disabled...");
20264 #else
20265   errmsg ("Use the vpp event loger...");
20266 #endif
20267   return 0;
20268 }
20269
20270 static int
20271 statseg (vat_main_t * vam)
20272 {
20273   ssvm_private_t *ssvmp = &vam->stat_segment;
20274   ssvm_shared_header_t *shared_header = ssvmp->sh;
20275   vlib_counter_t **counters;
20276   u64 thread0_index1_packets;
20277   u64 thread0_index1_bytes;
20278   f64 vector_rate, input_rate;
20279   uword *p;
20280
20281   uword *counter_vector_by_name;
20282   if (vam->stat_segment_lockp == 0)
20283     {
20284       errmsg ("Stat segment not mapped...");
20285       return -99;
20286     }
20287
20288   /* look up "/if/rx for sw_if_index 1 as a test */
20289
20290   clib_spinlock_lock (vam->stat_segment_lockp);
20291
20292   counter_vector_by_name = (uword *) shared_header->opaque[1];
20293
20294   p = hash_get_mem (counter_vector_by_name, "/if/rx");
20295   if (p == 0)
20296     {
20297       clib_spinlock_unlock (vam->stat_segment_lockp);
20298       errmsg ("/if/tx not found?");
20299       return -99;
20300     }
20301
20302   /* Fish per-thread vector of combined counters from shared memory */
20303   counters = (vlib_counter_t **) p[0];
20304
20305   if (vec_len (counters[0]) < 2)
20306     {
20307       clib_spinlock_unlock (vam->stat_segment_lockp);
20308       errmsg ("/if/tx vector length %d", vec_len (counters[0]));
20309       return -99;
20310     }
20311
20312   /* Read thread 0 sw_if_index 1 counter */
20313   thread0_index1_packets = counters[0][1].packets;
20314   thread0_index1_bytes = counters[0][1].bytes;
20315
20316   p = hash_get_mem (counter_vector_by_name, "vector_rate");
20317   if (p == 0)
20318     {
20319       clib_spinlock_unlock (vam->stat_segment_lockp);
20320       errmsg ("vector_rate not found?");
20321       return -99;
20322     }
20323
20324   vector_rate = *(f64 *) (p[0]);
20325   p = hash_get_mem (counter_vector_by_name, "input_rate");
20326   if (p == 0)
20327     {
20328       clib_spinlock_unlock (vam->stat_segment_lockp);
20329       errmsg ("input_rate not found?");
20330       return -99;
20331     }
20332   input_rate = *(f64 *) (p[0]);
20333
20334   clib_spinlock_unlock (vam->stat_segment_lockp);
20335
20336   print (vam->ofp, "vector_rate %.2f input_rate %.2f",
20337          vector_rate, input_rate);
20338   print (vam->ofp, "thread 0 sw_if_index 1 rx pkts %lld, bytes %lld",
20339          thread0_index1_packets, thread0_index1_bytes);
20340
20341   return 0;
20342 }
20343
20344 static int
20345 cmd_cmp (void *a1, void *a2)
20346 {
20347   u8 **c1 = a1;
20348   u8 **c2 = a2;
20349
20350   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
20351 }
20352
20353 static int
20354 help (vat_main_t * vam)
20355 {
20356   u8 **cmds = 0;
20357   u8 *name = 0;
20358   hash_pair_t *p;
20359   unformat_input_t *i = vam->input;
20360   int j;
20361
20362   if (unformat (i, "%s", &name))
20363     {
20364       uword *hs;
20365
20366       vec_add1 (name, 0);
20367
20368       hs = hash_get_mem (vam->help_by_name, name);
20369       if (hs)
20370         print (vam->ofp, "usage: %s %s", name, hs[0]);
20371       else
20372         print (vam->ofp, "No such msg / command '%s'", name);
20373       vec_free (name);
20374       return 0;
20375     }
20376
20377   print (vam->ofp, "Help is available for the following:");
20378
20379     /* *INDENT-OFF* */
20380     hash_foreach_pair (p, vam->function_by_name,
20381     ({
20382       vec_add1 (cmds, (u8 *)(p->key));
20383     }));
20384     /* *INDENT-ON* */
20385
20386   vec_sort_with_function (cmds, cmd_cmp);
20387
20388   for (j = 0; j < vec_len (cmds); j++)
20389     print (vam->ofp, "%s", cmds[j]);
20390
20391   vec_free (cmds);
20392   return 0;
20393 }
20394
20395 static int
20396 set (vat_main_t * vam)
20397 {
20398   u8 *name = 0, *value = 0;
20399   unformat_input_t *i = vam->input;
20400
20401   if (unformat (i, "%s", &name))
20402     {
20403       /* The input buffer is a vector, not a string. */
20404       value = vec_dup (i->buffer);
20405       vec_delete (value, i->index, 0);
20406       /* Almost certainly has a trailing newline */
20407       if (value[vec_len (value) - 1] == '\n')
20408         value[vec_len (value) - 1] = 0;
20409       /* Make sure it's a proper string, one way or the other */
20410       vec_add1 (value, 0);
20411       (void) clib_macro_set_value (&vam->macro_main,
20412                                    (char *) name, (char *) value);
20413     }
20414   else
20415     errmsg ("usage: set <name> <value>");
20416
20417   vec_free (name);
20418   vec_free (value);
20419   return 0;
20420 }
20421
20422 static int
20423 unset (vat_main_t * vam)
20424 {
20425   u8 *name = 0;
20426
20427   if (unformat (vam->input, "%s", &name))
20428     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
20429       errmsg ("unset: %s wasn't set", name);
20430   vec_free (name);
20431   return 0;
20432 }
20433
20434 typedef struct
20435 {
20436   u8 *name;
20437   u8 *value;
20438 } macro_sort_t;
20439
20440
20441 static int
20442 macro_sort_cmp (void *a1, void *a2)
20443 {
20444   macro_sort_t *s1 = a1;
20445   macro_sort_t *s2 = a2;
20446
20447   return strcmp ((char *) (s1->name), (char *) (s2->name));
20448 }
20449
20450 static int
20451 dump_macro_table (vat_main_t * vam)
20452 {
20453   macro_sort_t *sort_me = 0, *sm;
20454   int i;
20455   hash_pair_t *p;
20456
20457     /* *INDENT-OFF* */
20458     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
20459     ({
20460       vec_add2 (sort_me, sm, 1);
20461       sm->name = (u8 *)(p->key);
20462       sm->value = (u8 *) (p->value[0]);
20463     }));
20464     /* *INDENT-ON* */
20465
20466   vec_sort_with_function (sort_me, macro_sort_cmp);
20467
20468   if (vec_len (sort_me))
20469     print (vam->ofp, "%-15s%s", "Name", "Value");
20470   else
20471     print (vam->ofp, "The macro table is empty...");
20472
20473   for (i = 0; i < vec_len (sort_me); i++)
20474     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
20475   return 0;
20476 }
20477
20478 static int
20479 dump_node_table (vat_main_t * vam)
20480 {
20481   int i, j;
20482   vlib_node_t *node, *next_node;
20483
20484   if (vec_len (vam->graph_nodes) == 0)
20485     {
20486       print (vam->ofp, "Node table empty, issue get_node_graph...");
20487       return 0;
20488     }
20489
20490   for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
20491     {
20492       node = vam->graph_nodes[0][i];
20493       print (vam->ofp, "[%d] %s", i, node->name);
20494       for (j = 0; j < vec_len (node->next_nodes); j++)
20495         {
20496           if (node->next_nodes[j] != ~0)
20497             {
20498               next_node = vam->graph_nodes[0][node->next_nodes[j]];
20499               print (vam->ofp, "  [%d] %s", j, next_node->name);
20500             }
20501         }
20502     }
20503   return 0;
20504 }
20505
20506 static int
20507 value_sort_cmp (void *a1, void *a2)
20508 {
20509   name_sort_t *n1 = a1;
20510   name_sort_t *n2 = a2;
20511
20512   if (n1->value < n2->value)
20513     return -1;
20514   if (n1->value > n2->value)
20515     return 1;
20516   return 0;
20517 }
20518
20519
20520 static int
20521 dump_msg_api_table (vat_main_t * vam)
20522 {
20523   api_main_t *am = vlibapi_get_main ();
20524   name_sort_t *nses = 0, *ns;
20525   hash_pair_t *hp;
20526   int i;
20527
20528   /* *INDENT-OFF* */
20529   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
20530   ({
20531     vec_add2 (nses, ns, 1);
20532     ns->name = (u8 *)(hp->key);
20533     ns->value = (u32) hp->value[0];
20534   }));
20535   /* *INDENT-ON* */
20536
20537   vec_sort_with_function (nses, value_sort_cmp);
20538
20539   for (i = 0; i < vec_len (nses); i++)
20540     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
20541   vec_free (nses);
20542   return 0;
20543 }
20544
20545 static int
20546 get_msg_id (vat_main_t * vam)
20547 {
20548   u8 *name_and_crc;
20549   u32 message_index;
20550
20551   if (unformat (vam->input, "%s", &name_and_crc))
20552     {
20553       message_index = vl_msg_api_get_msg_index (name_and_crc);
20554       if (message_index == ~0)
20555         {
20556           print (vam->ofp, " '%s' not found", name_and_crc);
20557           return 0;
20558         }
20559       print (vam->ofp, " '%s' has message index %d",
20560              name_and_crc, message_index);
20561       return 0;
20562     }
20563   errmsg ("name_and_crc required...");
20564   return 0;
20565 }
20566
20567 static int
20568 search_node_table (vat_main_t * vam)
20569 {
20570   unformat_input_t *line_input = vam->input;
20571   u8 *node_to_find;
20572   int j;
20573   vlib_node_t *node, *next_node;
20574   uword *p;
20575
20576   if (vam->graph_node_index_by_name == 0)
20577     {
20578       print (vam->ofp, "Node table empty, issue get_node_graph...");
20579       return 0;
20580     }
20581
20582   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
20583     {
20584       if (unformat (line_input, "%s", &node_to_find))
20585         {
20586           vec_add1 (node_to_find, 0);
20587           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
20588           if (p == 0)
20589             {
20590               print (vam->ofp, "%s not found...", node_to_find);
20591               goto out;
20592             }
20593           node = vam->graph_nodes[0][p[0]];
20594           print (vam->ofp, "[%d] %s", p[0], node->name);
20595           for (j = 0; j < vec_len (node->next_nodes); j++)
20596             {
20597               if (node->next_nodes[j] != ~0)
20598                 {
20599                   next_node = vam->graph_nodes[0][node->next_nodes[j]];
20600                   print (vam->ofp, "  [%d] %s", j, next_node->name);
20601                 }
20602             }
20603         }
20604
20605       else
20606         {
20607           clib_warning ("parse error '%U'", format_unformat_error,
20608                         line_input);
20609           return -99;
20610         }
20611
20612     out:
20613       vec_free (node_to_find);
20614
20615     }
20616
20617   return 0;
20618 }
20619
20620
20621 static int
20622 script (vat_main_t * vam)
20623 {
20624 #if (VPP_API_TEST_BUILTIN==0)
20625   u8 *s = 0;
20626   char *save_current_file;
20627   unformat_input_t save_input;
20628   jmp_buf save_jump_buf;
20629   u32 save_line_number;
20630
20631   FILE *new_fp, *save_ifp;
20632
20633   if (unformat (vam->input, "%s", &s))
20634     {
20635       new_fp = fopen ((char *) s, "r");
20636       if (new_fp == 0)
20637         {
20638           errmsg ("Couldn't open script file %s", s);
20639           vec_free (s);
20640           return -99;
20641         }
20642     }
20643   else
20644     {
20645       errmsg ("Missing script name");
20646       return -99;
20647     }
20648
20649   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
20650   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
20651   save_ifp = vam->ifp;
20652   save_line_number = vam->input_line_number;
20653   save_current_file = (char *) vam->current_file;
20654
20655   vam->input_line_number = 0;
20656   vam->ifp = new_fp;
20657   vam->current_file = s;
20658   do_one_file (vam);
20659
20660   clib_memcpy (&vam->input, &save_input, sizeof (save_input));
20661   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
20662   vam->ifp = save_ifp;
20663   vam->input_line_number = save_line_number;
20664   vam->current_file = (u8 *) save_current_file;
20665   vec_free (s);
20666
20667   return 0;
20668 #else
20669   clib_warning ("use the exec command...");
20670   return -99;
20671 #endif
20672 }
20673
20674 static int
20675 echo (vat_main_t * vam)
20676 {
20677   print (vam->ofp, "%v", vam->input->buffer);
20678   return 0;
20679 }
20680
20681 /* List of API message constructors, CLI names map to api_xxx */
20682 #define foreach_vpe_api_msg                                             \
20683 _(create_loopback,"[mac <mac-addr>] [instance <instance>]")             \
20684 _(sw_interface_dump,"")                                                 \
20685 _(sw_interface_set_flags,                                               \
20686   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
20687 _(sw_interface_add_del_address,                                         \
20688   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
20689 _(sw_interface_set_rx_mode,                                             \
20690   "<intfc> | sw_if_index <id> [queue <id>] <polling | interrupt | adaptive>") \
20691 _(sw_interface_set_rx_placement,                                        \
20692   "<intfc> | sw_if_index <id> [queue <id>] [worker <id> | main]")       \
20693 _(sw_interface_rx_placement_dump,                                       \
20694   "[<intfc> | sw_if_index <id>]")                                         \
20695 _(sw_interface_set_table,                                               \
20696   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
20697 _(sw_interface_set_mpls_enable,                                         \
20698   "<intfc> | sw_if_index [disable | dis]")                              \
20699 _(sw_interface_set_vpath,                                               \
20700   "<intfc> | sw_if_index <id> enable | disable")                        \
20701 _(sw_interface_set_vxlan_bypass,                                        \
20702   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
20703 _(sw_interface_set_geneve_bypass,                                       \
20704   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
20705 _(sw_interface_set_l2_xconnect,                                         \
20706   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
20707   "enable | disable")                                                   \
20708 _(sw_interface_set_l2_bridge,                                           \
20709   "{<intfc> | sw_if_index <id>} bd_id <bridge-domain-id>\n"             \
20710   "[shg <split-horizon-group>] [bvi]\n"                                 \
20711   "enable | disable")                                                   \
20712 _(bridge_domain_set_mac_age, "bd_id <bridge-domain-id> mac-age 0-255")  \
20713 _(bridge_domain_add_del,                                                \
20714   "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") \
20715 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
20716 _(l2fib_add_del,                                                        \
20717   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
20718 _(l2fib_flush_bd, "bd_id <bridge-domain-id>")                           \
20719 _(l2fib_flush_int, "<intfc> | sw_if_index <id>")                        \
20720 _(l2_flags,                                                             \
20721   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
20722 _(bridge_flags,                                                         \
20723   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
20724 _(tap_create_v2,                                                        \
20725   "id <num> [hw-addr <mac-addr>] [host-ns <name>] [rx-ring-size <num> [tx-ring-size <num>] [host-mtu-size <mtu>] [gso | no-gso]") \
20726 _(tap_delete_v2,                                                        \
20727   "<vpp-if-name> | sw_if_index <id>")                                   \
20728 _(sw_interface_tap_v2_dump, "")                                         \
20729 _(virtio_pci_create,                                                    \
20730   "pci-addr <pci-address> [use_random_mac | hw-addr <mac-addr>] [features <hex-value>] [gso-enabled | csum-offload-enabled]") \
20731 _(virtio_pci_delete,                                                    \
20732   "<vpp-if-name> | sw_if_index <id>")                                   \
20733 _(sw_interface_virtio_pci_dump, "")                                     \
20734 _(bond_create,                                                          \
20735   "[hw-addr <mac-addr>] {round-robin | active-backup | "                \
20736   "broadcast | {lacp | xor} [load-balance { l2 | l23 | l34 }]} "        \
20737   "[id <if-id>]")                                                       \
20738 _(bond_delete,                                                          \
20739   "<vpp-if-name> | sw_if_index <id>")                                   \
20740 _(bond_enslave,                                                         \
20741   "sw_if_index <n> bond <sw_if_index> [is_passive] [is_long_timeout]")  \
20742 _(bond_detach_slave,                                                    \
20743   "sw_if_index <n>")                                                    \
20744  _(sw_interface_set_bond_weight, "<intfc> | sw_if_index <nn> weight <value>") \
20745 _(sw_interface_bond_dump, "")                                           \
20746 _(sw_interface_slave_dump,                                              \
20747   "<vpp-if-name> | sw_if_index <id>")                                   \
20748 _(ip_table_add_del,                                                     \
20749   "table <n> [ipv6] [add | del]\n")                                     \
20750 _(ip_route_add_del,                                                     \
20751   "<addr>/<mask> via <<addr>|<intfc>|sw_if_index <id>|via-label <n>>\n" \
20752   "[table-id <n>] [<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"\
20753   "[weight <n>] [drop] [local] [classify <n>]  [out-label <n>]\n"       \
20754   "[multipath] [count <n>] [del]")                                      \
20755 _(ip_mroute_add_del,                                                    \
20756   "<src> <grp>/<mask> [table-id <n>]\n"                                 \
20757   "[<intfc> | sw_if_index <id>] [local] [del]")                         \
20758 _(mpls_table_add_del,                                                   \
20759   "table <n> [add | del]\n")                                            \
20760 _(mpls_route_add_del,                                                   \
20761   "<label> <eos> via <addr | next-hop-table <n> | via-label <n> |\n"    \
20762   "lookup-ip4-table <n> | lookup-in-ip6-table <n> |\n"                  \
20763   "l2-input-on <intfc> | l2-input-on sw_if_index <id>>\n"               \
20764   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>] [weight <n>]\n"  \
20765   "[drop] [local] [classify <n>] [out-label <n>] [multipath]\n"         \
20766   "[count <n>] [del]")                                                  \
20767 _(mpls_ip_bind_unbind,                                                  \
20768   "<label> <addr/len>")                                                 \
20769 _(mpls_tunnel_add_del,                                                  \
20770   "[add | del <intfc | sw_if_index <id>>] via <addr | via-label <n>>\n" \
20771   "[<intfc> | sw_if_index <id> | next-hop-table <id>]\n"                \
20772   "[l2-only]  [out-label <n>]")                                         \
20773 _(sr_mpls_policy_add,                                                   \
20774   "bsid <id> [weight <n>] [spray] next <sid> [next <sid>]")             \
20775 _(sr_mpls_policy_del,                                                   \
20776   "bsid <id>")                                                          \
20777 _(bier_table_add_del,                                                   \
20778   "<label> <sub-domain> <set> <bsl> [del]")                             \
20779 _(bier_route_add_del,                                                   \
20780   "<bit-position> <sub-domain> <set> <bsl> via <addr> [table-id <n>]\n" \
20781   "[<intfc> | sw_if_index <id>]"                                        \
20782   "[weight <n>] [del] [multipath]")                                     \
20783 _(sw_interface_set_unnumbered,                                          \
20784   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
20785 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
20786 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
20787   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
20788   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
20789   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
20790 _(ip_table_replace_begin, "table <n> [ipv6]")                           \
20791 _(ip_table_flush, "table <n> [ipv6]")                                   \
20792 _(ip_table_replace_end, "table <n> [ipv6]")                             \
20793 _(set_ip_flow_hash,                                                     \
20794   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
20795 _(sw_interface_ip6_enable_disable,                                      \
20796   "<intfc> | sw_if_index <id> enable | disable")                        \
20797 _(l2_patch_add_del,                                                     \
20798   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
20799   "enable | disable")                                                   \
20800 _(sr_localsid_add_del,                                                  \
20801   "(del) address <addr> next_hop <addr> behavior <beh>\n"               \
20802   "fib-table <num> (end.psp) sw_if_index <num>")                        \
20803 _(classify_add_del_table,                                               \
20804   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
20805   " [del] [del-chain] mask <mask-value>\n"                              \
20806   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
20807   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
20808 _(classify_add_del_session,                                             \
20809   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
20810   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
20811   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
20812   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
20813 _(classify_set_interface_ip_table,                                      \
20814   "<intfc> | sw_if_index <nn> table <nn>")                              \
20815 _(classify_set_interface_l2_tables,                                     \
20816   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
20817   "  [other-table <nn>]")                                               \
20818 _(get_node_index, "node <node-name")                                    \
20819 _(add_node_next, "node <node-name> next <next-node-name>")              \
20820 _(l2tpv3_create_tunnel,                                                 \
20821   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
20822   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
20823   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
20824 _(l2tpv3_set_tunnel_cookies,                                            \
20825   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
20826   "[new_remote_cookie <nn>]\n")                                         \
20827 _(l2tpv3_interface_enable_disable,                                      \
20828   "<intfc> | sw_if_index <nn> enable | disable")                        \
20829 _(l2tpv3_set_lookup_key,                                                \
20830   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
20831 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
20832 _(vxlan_offload_rx,                                                     \
20833   "hw { <interface name> | hw_if_index <nn>} "                          \
20834   "rx { <vxlan tunnel name> | sw_if_index <nn> } [del]")                \
20835 _(vxlan_add_del_tunnel,                                                 \
20836   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
20837   "{ <intfc> | mcast_sw_if_index <nn> } [instance <id>]}\n"             \
20838   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
20839 _(geneve_add_del_tunnel,                                                \
20840   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
20841   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
20842   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
20843 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
20844 _(geneve_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                   \
20845 _(gre_tunnel_add_del,                                                   \
20846   "src <ip-addr> dst <ip-addr> [outer-fib-id <nn>] [instance <n>]\n"    \
20847   "[teb | erspan <session-id>] [del]")                                  \
20848 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
20849 _(l2_fib_clear_table, "")                                               \
20850 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
20851 _(l2_interface_vlan_tag_rewrite,                                        \
20852   "<intfc> | sw_if_index <nn> \n"                                       \
20853   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
20854   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
20855 _(create_vhost_user_if,                                                 \
20856         "socket <filename> [server] [renumber <dev_instance>] "         \
20857         "[disable_mrg_rxbuf] [disable_indirect_desc] [gso] "            \
20858         "[mac <mac_address>]")                                          \
20859 _(modify_vhost_user_if,                                                 \
20860         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
20861         "[server] [renumber <dev_instance>] [gso]")                     \
20862 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
20863 _(sw_interface_vhost_user_dump, "")                                     \
20864 _(show_version, "")                                                     \
20865 _(show_threads, "")                                                     \
20866 _(vxlan_gpe_add_del_tunnel,                                             \
20867   "local <addr> remote <addr>  | group <mcast-ip-addr>\n"               \
20868   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
20869   "vni <nn> [encap-vrf-id <nn>] [decap-vrf-id <nn>]\n"                  \
20870   "[next-ip4][next-ip6][next-ethernet] [next-nsh] [del]\n")             \
20871 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
20872 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
20873 _(interface_name_renumber,                                              \
20874   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
20875 _(input_acl_set_interface,                                              \
20876   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
20877   "  [l2-table <nn>] [del]")                                            \
20878 _(want_l2_macs_events, "[disable] [learn-limit <n>] [scan-delay <n>] [max-entries <n>]") \
20879 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
20880 _(ip_dump, "ipv4 | ipv6")                                               \
20881 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
20882 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
20883   "  spid_id <n> ")                                                     \
20884 _(ipsec_sad_entry_add_del, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
20885   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
20886   "  integ_alg <alg> integ_key <hex>")                                  \
20887 _(ipsec_spd_entry_add_del, "spd_id <n> priority <n> action <action>\n"  \
20888   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
20889   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
20890   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
20891 _(ipsec_tunnel_if_add_del, "local_spi <n> remote_spi <n>\n"             \
20892   "  crypto_alg <alg> local_crypto_key <hex> remote_crypto_key <hex>\n" \
20893   "  integ_alg <alg> local_integ_key <hex> remote_integ_key <hex>\n"    \
20894   "  local_ip <addr> remote_ip <addr> [esn] [anti_replay] [del]\n"      \
20895   "  [instance <n>]")     \
20896 _(ipsec_sa_dump, "[sa_id <n>]")                                         \
20897 _(ipsec_tunnel_if_set_sa, "<intfc> sa_id <n> <inbound|outbound>\n")     \
20898 _(delete_loopback,"sw_if_index <nn>")                                   \
20899 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
20900 _(bd_ip_mac_flush, "bd_id <bridge-domain-id>")                          \
20901 _(bd_ip_mac_dump, "[bd_id] <bridge-domain-id>")                         \
20902 _(want_interface_events,  "enable|disable")                             \
20903 _(get_first_msg_id, "client <name>")                                    \
20904 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
20905 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
20906   "fib-id <nn> [ip4][ip6][default]")                                    \
20907 _(get_node_graph, " ")                                                  \
20908 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
20909 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
20910 _(ioam_disable, "")                                                     \
20911 _(one_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
20912                             " sw_if_index <sw_if_index> p <priority> "  \
20913                             "w <weight>] [del]")                        \
20914 _(one_add_del_locator, "locator-set <locator_name> "                    \
20915                         "iface <intf> | sw_if_index <sw_if_index> "     \
20916                         "p <priority> w <weight> [del]")                \
20917 _(one_add_del_local_eid,"vni <vni> eid "                                \
20918                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
20919                          "locator-set <locator_name> [del]"             \
20920                          "[key-id sha1|sha256 secret-key <secret-key>]")\
20921 _(one_add_del_map_resolver, "<ip4|6-addr> [del]")                       \
20922 _(one_add_del_map_server, "<ip4|6-addr> [del]")                         \
20923 _(one_enable_disable, "enable|disable")                                 \
20924 _(one_map_register_enable_disable, "enable|disable")                    \
20925 _(one_map_register_fallback_threshold, "<value>")                       \
20926 _(one_rloc_probe_enable_disable, "enable|disable")                      \
20927 _(one_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "       \
20928                                "[seid <seid>] "                         \
20929                                "rloc <locator> p <prio> "               \
20930                                "w <weight> [rloc <loc> ... ] "          \
20931                                "action <action> [del-all]")             \
20932 _(one_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "    \
20933                           "<local-eid>")                                \
20934 _(one_pitr_set_locator_set, "locator-set <loc-set-name> | del")         \
20935 _(one_use_petr, "ip-address> | disable")                                \
20936 _(one_map_request_mode, "src-dst|dst-only")                             \
20937 _(one_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")            \
20938 _(one_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")               \
20939 _(one_locator_set_dump, "[local | remote]")                             \
20940 _(one_locator_dump, "ls_index <index> | ls_name <name>")                \
20941 _(one_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "       \
20942                        "[local] | [remote]")                            \
20943 _(one_add_del_ndp_entry, "[del] mac <mac> bd <bd> ip6 <ip6>")           \
20944 _(one_ndp_bd_get, "")                                                   \
20945 _(one_ndp_entries_get, "bd <bridge-domain>")                            \
20946 _(one_add_del_l2_arp_entry, "[del] mac <mac> bd <bd> ip4 <ip4>")        \
20947 _(one_l2_arp_bd_get, "")                                                \
20948 _(one_l2_arp_entries_get, "bd <bridge-domain>")                         \
20949 _(one_stats_enable_disable, "enable|disable")                           \
20950 _(show_one_stats_enable_disable, "")                                    \
20951 _(one_eid_table_vni_dump, "")                                           \
20952 _(one_eid_table_map_dump, "l2|l3")                                      \
20953 _(one_map_resolver_dump, "")                                            \
20954 _(one_map_server_dump, "")                                              \
20955 _(one_adjacencies_get, "vni <vni>")                                     \
20956 _(one_nsh_set_locator_set, "[del] ls <locator-set-name>")               \
20957 _(show_one_rloc_probe_state, "")                                        \
20958 _(show_one_map_register_state, "")                                      \
20959 _(show_one_status, "")                                                  \
20960 _(one_stats_dump, "")                                                   \
20961 _(one_stats_flush, "")                                                  \
20962 _(one_get_map_request_itr_rlocs, "")                                    \
20963 _(one_map_register_set_ttl, "<ttl>")                                    \
20964 _(one_set_transport_protocol, "udp|api")                                \
20965 _(one_get_transport_protocol, "")                                       \
20966 _(one_enable_disable_xtr_mode, "enable|disable")                        \
20967 _(one_show_xtr_mode, "")                                                \
20968 _(one_enable_disable_pitr_mode, "enable|disable")                       \
20969 _(one_show_pitr_mode, "")                                               \
20970 _(one_enable_disable_petr_mode, "enable|disable")                       \
20971 _(one_show_petr_mode, "")                                               \
20972 _(show_one_nsh_mapping, "")                                             \
20973 _(show_one_pitr, "")                                                    \
20974 _(show_one_use_petr, "")                                                \
20975 _(show_one_map_request_mode, "")                                        \
20976 _(show_one_map_register_ttl, "")                                        \
20977 _(show_one_map_register_fallback_threshold, "")                         \
20978 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
20979                             " sw_if_index <sw_if_index> p <priority> "  \
20980                             "w <weight>] [del]")                        \
20981 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
20982                         "iface <intf> | sw_if_index <sw_if_index> "     \
20983                         "p <priority> w <weight> [del]")                \
20984 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
20985                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
20986                          "locator-set <locator_name> [del]"             \
20987                          "[key-id sha1|sha256 secret-key <secret-key>]") \
20988 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
20989 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
20990 _(lisp_enable_disable, "enable|disable")                                \
20991 _(lisp_map_register_enable_disable, "enable|disable")                   \
20992 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
20993 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
20994                                "[seid <seid>] "                         \
20995                                "rloc <locator> p <prio> "               \
20996                                "w <weight> [rloc <loc> ... ] "          \
20997                                "action <action> [del-all]")             \
20998 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
20999                           "<local-eid>")                                \
21000 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
21001 _(lisp_use_petr, "<ip-address> | disable")                              \
21002 _(lisp_map_request_mode, "src-dst|dst-only")                            \
21003 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
21004 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
21005 _(lisp_locator_set_dump, "[local | remote]")                            \
21006 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
21007 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
21008                        "[local] | [remote]")                            \
21009 _(lisp_eid_table_vni_dump, "")                                          \
21010 _(lisp_eid_table_map_dump, "l2|l3")                                     \
21011 _(lisp_map_resolver_dump, "")                                           \
21012 _(lisp_map_server_dump, "")                                             \
21013 _(lisp_adjacencies_get, "vni <vni>")                                    \
21014 _(gpe_fwd_entry_vnis_get, "")                                           \
21015 _(gpe_native_fwd_rpaths_get, "ip4 | ip6")                               \
21016 _(gpe_add_del_native_fwd_rpath, "[del] via <nh-ip-addr> [iface] "       \
21017                                 "[table <table-id>]")                   \
21018 _(lisp_gpe_fwd_entries_get, "vni <vni>")                                \
21019 _(lisp_gpe_fwd_entry_path_dump, "index <fwd_entry_index>")              \
21020 _(gpe_set_encap_mode, "lisp|vxlan")                                     \
21021 _(gpe_get_encap_mode, "")                                               \
21022 _(lisp_gpe_add_del_iface, "up|down")                                    \
21023 _(lisp_gpe_enable_disable, "enable|disable")                            \
21024 _(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>"       \
21025   "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
21026 _(show_lisp_rloc_probe_state, "")                                       \
21027 _(show_lisp_map_register_state, "")                                     \
21028 _(show_lisp_status, "")                                                 \
21029 _(lisp_get_map_request_itr_rlocs, "")                                   \
21030 _(show_lisp_pitr, "")                                                   \
21031 _(show_lisp_use_petr, "")                                               \
21032 _(show_lisp_map_request_mode, "")                                       \
21033 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
21034 _(af_packet_delete, "name <host interface name>")                       \
21035 _(af_packet_dump, "")                                                   \
21036 _(policer_add_del, "name <policer name> <params> [del]")                \
21037 _(policer_dump, "[name <policer name>]")                                \
21038 _(policer_classify_set_interface,                                       \
21039   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
21040   "  [l2-table <nn>] [del]")                                            \
21041 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
21042 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
21043     "[master|slave]")                                                   \
21044 _(netmap_delete, "name <interface name>")                               \
21045 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
21046 _(mpls_table_dump, "")                                                  \
21047 _(mpls_route_dump, "table-id <ID>")                                     \
21048 _(classify_table_ids, "")                                               \
21049 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
21050 _(classify_table_info, "table_id <nn>")                                 \
21051 _(classify_session_dump, "table_id <nn>")                               \
21052 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
21053     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
21054     "[template_interval <nn>] [udp_checksum]")                          \
21055 _(ipfix_exporter_dump, "")                                              \
21056 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
21057 _(ipfix_classify_stream_dump, "")                                       \
21058 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
21059 _(ipfix_classify_table_dump, "")                                        \
21060 _(sw_interface_span_enable_disable, "[l2] [src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
21061 _(sw_interface_span_dump, "[l2]")                                           \
21062 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
21063 _(pg_create_interface, "if_id <nn> [gso-enabled gso-size <size>]")      \
21064 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
21065 _(pg_enable_disable, "[stream <id>] disable")                           \
21066 _(ip_source_and_port_range_check_add_del,                               \
21067   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
21068 _(ip_source_and_port_range_check_interface_add_del,                     \
21069   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
21070   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
21071 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
21072 _(l2_interface_pbb_tag_rewrite,                                         \
21073   "<intfc> | sw_if_index <nn> \n"                                       \
21074   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
21075   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
21076 _(set_punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
21077 _(flow_classify_set_interface,                                          \
21078   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
21079 _(flow_classify_dump, "type [ip4|ip6]")                                 \
21080 _(ip_table_dump, "")                                                    \
21081 _(ip_route_dump, "table-id [ip4|ip6]")                                  \
21082 _(ip_mtable_dump, "")                                                   \
21083 _(ip_mroute_dump, "table-id [ip4|ip6]")                                 \
21084 _(feature_enable_disable, "arc_name <arc_name> "                        \
21085   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
21086 _(feature_gso_enable_disable, "<intfc> | sw_if_index <nn> "             \
21087   "[enable | disable] ")                                                \
21088 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
21089 "[disable]")                                                            \
21090 _(sw_interface_add_del_mac_address, "<intfc> | sw_if_index <nn> "       \
21091   "mac <mac-address> [del]")                                            \
21092 _(l2_xconnect_dump, "")                                                 \
21093 _(hw_interface_set_mtu, "<intfc> | hw_if_index <nn> mtu <nn>")        \
21094 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")          \
21095 _(p2p_ethernet_add, "<intfc> | sw_if_index <nn> remote_mac <mac-address> sub_id <id>") \
21096 _(p2p_ethernet_del, "<intfc> | sw_if_index <nn> remote_mac <mac-address>") \
21097 _(lldp_config, "system-name <name> tx-hold <nn> tx-interval <nn>") \
21098 _(sw_interface_set_lldp, "<intfc> | sw_if_index <nn> [port-desc <description>]\n" \
21099   " [mgmt-ip4 <ip4>] [mgmt-ip6 <ip6>] [mgmt-oid <object id>] [disable]") \
21100 _(tcp_configure_src_addresses, "<ip4|6>first-<ip4|6>last [vrf <id>]")   \
21101 _(sock_init_shm, "size <nnn>")                                          \
21102 _(app_namespace_add_del, "[add] id <ns-id> secret <nn> sw_if_index <nn>")\
21103 _(session_rule_add_del, "[add|del] proto <tcp/udp> <lcl-ip>/<plen> "    \
21104   "<lcl-port> <rmt-ip>/<plen> <rmt-port> action <nn>")                  \
21105 _(session_rules_dump, "")                                               \
21106 _(ip_container_proxy_add_del, "[add|del] <address> <sw_if_index>")      \
21107 _(output_acl_set_interface,                                             \
21108   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
21109   "  [l2-table <nn>] [del]")                                            \
21110 _(qos_record_enable_disable, "<record-source> <intfc> | sw_if_index <id> [disable]")
21111
21112 /* List of command functions, CLI names map directly to functions */
21113 #define foreach_cli_function                                    \
21114 _(comment, "usage: comment <ignore-rest-of-line>")              \
21115 _(dump_interface_table, "usage: dump_interface_table")          \
21116 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
21117 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
21118 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
21119 _(dump_macro_table, "usage: dump_macro_table ")                 \
21120 _(dump_node_table, "usage: dump_node_table")                    \
21121 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
21122 _(elog_setup, "usage: elog_setup [nevents, default 128K]")      \
21123 _(elog_disable, "usage: elog_disable")                          \
21124 _(elog_enable, "usage: elog_enable")                            \
21125 _(elog_save, "usage: elog_save <filename>")                     \
21126 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
21127 _(echo, "usage: echo <message>")                                \
21128 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
21129 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
21130 _(help, "usage: help")                                          \
21131 _(q, "usage: quit")                                             \
21132 _(quit, "usage: quit")                                          \
21133 _(search_node_table, "usage: search_node_table <name>...")      \
21134 _(set, "usage: set <variable-name> <value>")                    \
21135 _(script, "usage: script <file-name>")                          \
21136 _(statseg, "usage: statseg")                                    \
21137 _(unset, "usage: unset <variable-name>")
21138
21139 #define _(N,n)                                  \
21140     static void vl_api_##n##_t_handler_uni      \
21141     (vl_api_##n##_t * mp)                       \
21142     {                                           \
21143         vat_main_t * vam = &vat_main;           \
21144         if (vam->json_output) {                 \
21145             vl_api_##n##_t_handler_json(mp);    \
21146         } else {                                \
21147             vl_api_##n##_t_handler(mp);         \
21148         }                                       \
21149     }
21150 foreach_vpe_api_reply_msg;
21151 #if VPP_API_TEST_BUILTIN == 0
21152 foreach_standalone_reply_msg;
21153 #endif
21154 #undef _
21155
21156 void
21157 vat_api_hookup (vat_main_t * vam)
21158 {
21159 #define _(N,n)                                                  \
21160     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
21161                            vl_api_##n##_t_handler_uni,          \
21162                            vl_noop_handler,                     \
21163                            vl_api_##n##_t_endian,               \
21164                            vl_api_##n##_t_print,                \
21165                            sizeof(vl_api_##n##_t), 1);
21166   foreach_vpe_api_reply_msg;
21167 #if VPP_API_TEST_BUILTIN == 0
21168   foreach_standalone_reply_msg;
21169 #endif
21170 #undef _
21171
21172 #if (VPP_API_TEST_BUILTIN==0)
21173   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
21174
21175   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
21176
21177   vam->function_by_name = hash_create_string (0, sizeof (uword));
21178
21179   vam->help_by_name = hash_create_string (0, sizeof (uword));
21180 #endif
21181
21182   /* API messages we can send */
21183 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
21184   foreach_vpe_api_msg;
21185 #undef _
21186
21187   /* Help strings */
21188 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
21189   foreach_vpe_api_msg;
21190 #undef _
21191
21192   /* CLI functions */
21193 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
21194   foreach_cli_function;
21195 #undef _
21196
21197   /* Help strings */
21198 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
21199   foreach_cli_function;
21200 #undef _
21201 }
21202
21203 #if VPP_API_TEST_BUILTIN
21204 static clib_error_t *
21205 vat_api_hookup_shim (vlib_main_t * vm)
21206 {
21207   vat_api_hookup (&vat_main);
21208   return 0;
21209 }
21210
21211 VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
21212 #endif
21213
21214 /*
21215  * fd.io coding-style-patch-verification: ON
21216  *
21217  * Local Variables:
21218  * eval: (c-set-style "gnu")
21219  * End:
21220  */