virtio: 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
7345         break;
7346     }
7347
7348   if (vec_len (host_if_name) > 63)
7349     {
7350       errmsg ("tap name too long. ");
7351       return -99;
7352     }
7353   if (vec_len (host_ns) > 63)
7354     {
7355       errmsg ("host name space too long. ");
7356       return -99;
7357     }
7358   if (vec_len (host_bridge) > 63)
7359     {
7360       errmsg ("host bridge name too long. ");
7361       return -99;
7362     }
7363   if (host_ip4_prefix_len > 32)
7364     {
7365       errmsg ("host ip4 prefix length not valid. ");
7366       return -99;
7367     }
7368   if (host_ip6_prefix_len > 128)
7369     {
7370       errmsg ("host ip6 prefix length not valid. ");
7371       return -99;
7372     }
7373   if (!is_pow2 (rx_ring_sz))
7374     {
7375       errmsg ("rx ring size must be power of 2. ");
7376       return -99;
7377     }
7378   if (rx_ring_sz > 32768)
7379     {
7380       errmsg ("rx ring size must be 32768 or lower. ");
7381       return -99;
7382     }
7383   if (!is_pow2 (tx_ring_sz))
7384     {
7385       errmsg ("tx ring size must be power of 2. ");
7386       return -99;
7387     }
7388   if (tx_ring_sz > 32768)
7389     {
7390       errmsg ("tx ring size must be 32768 or lower. ");
7391       return -99;
7392     }
7393   if (host_mtu_set && (host_mtu_size < 64 || host_mtu_size > 65355))
7394     {
7395       errmsg ("host MTU size must be in between 64 and 65355. ");
7396       return -99;
7397     }
7398
7399   /* Construct the API message */
7400   M (TAP_CREATE_V2, mp);
7401
7402   mp->use_random_mac = random_mac;
7403
7404   mp->id = ntohl (id);
7405   mp->host_namespace_set = host_ns != 0;
7406   mp->host_bridge_set = host_bridge != 0;
7407   mp->host_ip4_prefix_set = host_ip4_prefix_len != 0;
7408   mp->host_ip6_prefix_set = host_ip6_prefix_len != 0;
7409   mp->rx_ring_sz = ntohs (rx_ring_sz);
7410   mp->tx_ring_sz = ntohs (tx_ring_sz);
7411   mp->host_mtu_set = host_mtu_set;
7412   mp->host_mtu_size = ntohl (host_mtu_size);
7413   mp->tap_flags = ntohl (tap_flags);
7414
7415   if (random_mac == 0)
7416     clib_memcpy (mp->mac_address, mac_address, 6);
7417   if (host_mac_addr_set)
7418     clib_memcpy (mp->host_mac_addr, host_mac_addr, 6);
7419   if (host_if_name)
7420     clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
7421   if (host_ns)
7422     clib_memcpy (mp->host_namespace, host_ns, vec_len (host_ns));
7423   if (host_bridge)
7424     clib_memcpy (mp->host_bridge, host_bridge, vec_len (host_bridge));
7425   if (host_ip4_prefix_len)
7426     clib_memcpy (mp->host_ip4_prefix.address, &host_ip4_addr, 4);
7427   if (host_ip6_prefix_len)
7428     clib_memcpy (mp->host_ip6_prefix.address, &host_ip6_addr, 16);
7429   if (host_ip4_gw_set)
7430     clib_memcpy (mp->host_ip4_gw, &host_ip4_gw, 4);
7431   if (host_ip6_gw_set)
7432     clib_memcpy (mp->host_ip6_gw, &host_ip6_gw, 16);
7433
7434   vec_free (host_ns);
7435   vec_free (host_if_name);
7436   vec_free (host_bridge);
7437
7438   /* send it... */
7439   S (mp);
7440
7441   /* Wait for a reply... */
7442   W (ret);
7443   return ret;
7444 }
7445
7446 static int
7447 api_tap_delete_v2 (vat_main_t * vam)
7448 {
7449   unformat_input_t *i = vam->input;
7450   vl_api_tap_delete_v2_t *mp;
7451   u32 sw_if_index = ~0;
7452   u8 sw_if_index_set = 0;
7453   int ret;
7454
7455   /* Parse args required to build the message */
7456   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7457     {
7458       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7459         sw_if_index_set = 1;
7460       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7461         sw_if_index_set = 1;
7462       else
7463         break;
7464     }
7465
7466   if (sw_if_index_set == 0)
7467     {
7468       errmsg ("missing vpp interface name. ");
7469       return -99;
7470     }
7471
7472   /* Construct the API message */
7473   M (TAP_DELETE_V2, mp);
7474
7475   mp->sw_if_index = ntohl (sw_if_index);
7476
7477   /* send it... */
7478   S (mp);
7479
7480   /* Wait for a reply... */
7481   W (ret);
7482   return ret;
7483 }
7484
7485 uword
7486 unformat_vlib_pci_addr (unformat_input_t * input, va_list * args)
7487 {
7488   vlib_pci_addr_t *addr = va_arg (*args, vlib_pci_addr_t *);
7489   u32 x[4];
7490
7491   if (!unformat (input, "%x:%x:%x.%x", &x[0], &x[1], &x[2], &x[3]))
7492     return 0;
7493
7494   addr->domain = x[0];
7495   addr->bus = x[1];
7496   addr->slot = x[2];
7497   addr->function = x[3];
7498
7499   return 1;
7500 }
7501
7502 static int
7503 api_virtio_pci_create (vat_main_t * vam)
7504 {
7505   unformat_input_t *i = vam->input;
7506   vl_api_virtio_pci_create_t *mp;
7507   u8 mac_address[6];
7508   u8 random_mac = 1;
7509   u8 gso_enabled = 0;
7510   u8 checksum_offload_enabled = 0;
7511   u32 pci_addr = 0;
7512   u64 features = (u64) ~ (0ULL);
7513   int ret;
7514
7515   clib_memset (mac_address, 0, sizeof (mac_address));
7516
7517   /* Parse args required to build the message */
7518   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7519     {
7520       if (unformat (i, "hw-addr %U", unformat_ethernet_address, mac_address))
7521         {
7522           random_mac = 0;
7523         }
7524       else if (unformat (i, "pci-addr %U", unformat_vlib_pci_addr, &pci_addr))
7525         ;
7526       else if (unformat (i, "features 0x%llx", &features))
7527         ;
7528       else if (unformat (i, "gso-enabled"))
7529         gso_enabled = 1;
7530       else if (unformat (i, "csum-offload-enabled"))
7531         checksum_offload_enabled = 1;
7532       else
7533         break;
7534     }
7535
7536   if (pci_addr == 0)
7537     {
7538       errmsg ("pci address must be non zero. ");
7539       return -99;
7540     }
7541
7542   /* Construct the API message */
7543   M (VIRTIO_PCI_CREATE, mp);
7544
7545   mp->use_random_mac = random_mac;
7546
7547   mp->pci_addr.domain = htons (((vlib_pci_addr_t) pci_addr).domain);
7548   mp->pci_addr.bus = ((vlib_pci_addr_t) pci_addr).bus;
7549   mp->pci_addr.slot = ((vlib_pci_addr_t) pci_addr).slot;
7550   mp->pci_addr.function = ((vlib_pci_addr_t) pci_addr).function;
7551
7552   mp->features = clib_host_to_net_u64 (features);
7553   mp->gso_enabled = gso_enabled;
7554   mp->checksum_offload_enabled = checksum_offload_enabled;
7555
7556   if (random_mac == 0)
7557     clib_memcpy (mp->mac_address, mac_address, 6);
7558
7559   /* send it... */
7560   S (mp);
7561
7562   /* Wait for a reply... */
7563   W (ret);
7564   return ret;
7565 }
7566
7567 static int
7568 api_virtio_pci_delete (vat_main_t * vam)
7569 {
7570   unformat_input_t *i = vam->input;
7571   vl_api_virtio_pci_delete_t *mp;
7572   u32 sw_if_index = ~0;
7573   u8 sw_if_index_set = 0;
7574   int ret;
7575
7576   /* Parse args required to build the message */
7577   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7578     {
7579       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7580         sw_if_index_set = 1;
7581       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7582         sw_if_index_set = 1;
7583       else
7584         break;
7585     }
7586
7587   if (sw_if_index_set == 0)
7588     {
7589       errmsg ("missing vpp interface name. ");
7590       return -99;
7591     }
7592
7593   /* Construct the API message */
7594   M (VIRTIO_PCI_DELETE, mp);
7595
7596   mp->sw_if_index = htonl (sw_if_index);
7597
7598   /* send it... */
7599   S (mp);
7600
7601   /* Wait for a reply... */
7602   W (ret);
7603   return ret;
7604 }
7605
7606 static int
7607 api_bond_create (vat_main_t * vam)
7608 {
7609   unformat_input_t *i = vam->input;
7610   vl_api_bond_create_t *mp;
7611   u8 mac_address[6];
7612   u8 custom_mac = 0;
7613   int ret;
7614   u8 mode;
7615   u8 lb;
7616   u8 mode_is_set = 0;
7617   u32 id = ~0;
7618   u8 numa_only = 0;
7619
7620   clib_memset (mac_address, 0, sizeof (mac_address));
7621   lb = BOND_LB_L2;
7622
7623   /* Parse args required to build the message */
7624   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7625     {
7626       if (unformat (i, "mode %U", unformat_bond_mode, &mode))
7627         mode_is_set = 1;
7628       else if (((mode == BOND_MODE_LACP) || (mode == BOND_MODE_XOR))
7629                && unformat (i, "lb %U", unformat_bond_load_balance, &lb))
7630         ;
7631       else if (unformat (i, "hw-addr %U", unformat_ethernet_address,
7632                          mac_address))
7633         custom_mac = 1;
7634       else if (unformat (i, "numa-only"))
7635         numa_only = 1;
7636       else if (unformat (i, "id %u", &id))
7637         ;
7638       else
7639         break;
7640     }
7641
7642   if (mode_is_set == 0)
7643     {
7644       errmsg ("Missing bond mode. ");
7645       return -99;
7646     }
7647
7648   /* Construct the API message */
7649   M (BOND_CREATE, mp);
7650
7651   mp->use_custom_mac = custom_mac;
7652
7653   mp->mode = htonl (mode);
7654   mp->lb = htonl (lb);
7655   mp->id = htonl (id);
7656   mp->numa_only = numa_only;
7657
7658   if (custom_mac)
7659     clib_memcpy (mp->mac_address, mac_address, 6);
7660
7661   /* send it... */
7662   S (mp);
7663
7664   /* Wait for a reply... */
7665   W (ret);
7666   return ret;
7667 }
7668
7669 static int
7670 api_bond_delete (vat_main_t * vam)
7671 {
7672   unformat_input_t *i = vam->input;
7673   vl_api_bond_delete_t *mp;
7674   u32 sw_if_index = ~0;
7675   u8 sw_if_index_set = 0;
7676   int ret;
7677
7678   /* Parse args required to build the message */
7679   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7680     {
7681       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7682         sw_if_index_set = 1;
7683       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7684         sw_if_index_set = 1;
7685       else
7686         break;
7687     }
7688
7689   if (sw_if_index_set == 0)
7690     {
7691       errmsg ("missing vpp interface name. ");
7692       return -99;
7693     }
7694
7695   /* Construct the API message */
7696   M (BOND_DELETE, mp);
7697
7698   mp->sw_if_index = ntohl (sw_if_index);
7699
7700   /* send it... */
7701   S (mp);
7702
7703   /* Wait for a reply... */
7704   W (ret);
7705   return ret;
7706 }
7707
7708 static int
7709 api_bond_enslave (vat_main_t * vam)
7710 {
7711   unformat_input_t *i = vam->input;
7712   vl_api_bond_enslave_t *mp;
7713   u32 bond_sw_if_index;
7714   int ret;
7715   u8 is_passive;
7716   u8 is_long_timeout;
7717   u32 bond_sw_if_index_is_set = 0;
7718   u32 sw_if_index;
7719   u8 sw_if_index_is_set = 0;
7720
7721   /* Parse args required to build the message */
7722   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7723     {
7724       if (unformat (i, "sw_if_index %d", &sw_if_index))
7725         sw_if_index_is_set = 1;
7726       else if (unformat (i, "bond %u", &bond_sw_if_index))
7727         bond_sw_if_index_is_set = 1;
7728       else if (unformat (i, "passive %d", &is_passive))
7729         ;
7730       else if (unformat (i, "long-timeout %d", &is_long_timeout))
7731         ;
7732       else
7733         break;
7734     }
7735
7736   if (bond_sw_if_index_is_set == 0)
7737     {
7738       errmsg ("Missing bond sw_if_index. ");
7739       return -99;
7740     }
7741   if (sw_if_index_is_set == 0)
7742     {
7743       errmsg ("Missing slave sw_if_index. ");
7744       return -99;
7745     }
7746
7747   /* Construct the API message */
7748   M (BOND_ENSLAVE, mp);
7749
7750   mp->bond_sw_if_index = ntohl (bond_sw_if_index);
7751   mp->sw_if_index = ntohl (sw_if_index);
7752   mp->is_long_timeout = is_long_timeout;
7753   mp->is_passive = is_passive;
7754
7755   /* send it... */
7756   S (mp);
7757
7758   /* Wait for a reply... */
7759   W (ret);
7760   return ret;
7761 }
7762
7763 static int
7764 api_bond_detach_slave (vat_main_t * vam)
7765 {
7766   unformat_input_t *i = vam->input;
7767   vl_api_bond_detach_slave_t *mp;
7768   u32 sw_if_index = ~0;
7769   u8 sw_if_index_set = 0;
7770   int ret;
7771
7772   /* Parse args required to build the message */
7773   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7774     {
7775       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7776         sw_if_index_set = 1;
7777       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7778         sw_if_index_set = 1;
7779       else
7780         break;
7781     }
7782
7783   if (sw_if_index_set == 0)
7784     {
7785       errmsg ("missing vpp interface name. ");
7786       return -99;
7787     }
7788
7789   /* Construct the API message */
7790   M (BOND_DETACH_SLAVE, mp);
7791
7792   mp->sw_if_index = ntohl (sw_if_index);
7793
7794   /* send it... */
7795   S (mp);
7796
7797   /* Wait for a reply... */
7798   W (ret);
7799   return ret;
7800 }
7801
7802 static int
7803 api_ip_table_add_del (vat_main_t * vam)
7804 {
7805   unformat_input_t *i = vam->input;
7806   vl_api_ip_table_add_del_t *mp;
7807   u32 table_id = ~0;
7808   u8 is_ipv6 = 0;
7809   u8 is_add = 1;
7810   int ret = 0;
7811
7812   /* Parse args required to build the message */
7813   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7814     {
7815       if (unformat (i, "ipv6"))
7816         is_ipv6 = 1;
7817       else if (unformat (i, "del"))
7818         is_add = 0;
7819       else if (unformat (i, "add"))
7820         is_add = 1;
7821       else if (unformat (i, "table %d", &table_id))
7822         ;
7823       else
7824         {
7825           clib_warning ("parse error '%U'", format_unformat_error, i);
7826           return -99;
7827         }
7828     }
7829
7830   if (~0 == table_id)
7831     {
7832       errmsg ("missing table-ID");
7833       return -99;
7834     }
7835
7836   /* Construct the API message */
7837   M (IP_TABLE_ADD_DEL, mp);
7838
7839   mp->table.table_id = ntohl (table_id);
7840   mp->table.is_ip6 = is_ipv6;
7841   mp->is_add = is_add;
7842
7843   /* send it... */
7844   S (mp);
7845
7846   /* Wait for a reply... */
7847   W (ret);
7848
7849   return ret;
7850 }
7851
7852 uword
7853 unformat_fib_path (unformat_input_t * input, va_list * args)
7854 {
7855   vat_main_t *vam = va_arg (*args, vat_main_t *);
7856   vl_api_fib_path_t *path = va_arg (*args, vl_api_fib_path_t *);
7857   u32 weight, preference;
7858   mpls_label_t out_label;
7859
7860   clib_memset (path, 0, sizeof (*path));
7861   path->weight = 1;
7862   path->sw_if_index = ~0;
7863   path->rpf_id = ~0;
7864   path->n_labels = 0;
7865
7866   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7867     {
7868       if (unformat (input, "%U %U",
7869                     unformat_vl_api_ip4_address,
7870                     &path->nh.address.ip4,
7871                     api_unformat_sw_if_index, vam, &path->sw_if_index))
7872         {
7873           path->proto = FIB_API_PATH_NH_PROTO_IP4;
7874         }
7875       else if (unformat (input, "%U %U",
7876                          unformat_vl_api_ip6_address,
7877                          &path->nh.address.ip6,
7878                          api_unformat_sw_if_index, vam, &path->sw_if_index))
7879         {
7880           path->proto = FIB_API_PATH_NH_PROTO_IP6;
7881         }
7882       else if (unformat (input, "weight %u", &weight))
7883         {
7884           path->weight = weight;
7885         }
7886       else if (unformat (input, "preference %u", &preference))
7887         {
7888           path->preference = preference;
7889         }
7890       else if (unformat (input, "%U next-hop-table %d",
7891                          unformat_vl_api_ip4_address,
7892                          &path->nh.address.ip4, &path->table_id))
7893         {
7894           path->proto = FIB_API_PATH_NH_PROTO_IP4;
7895         }
7896       else if (unformat (input, "%U next-hop-table %d",
7897                          unformat_vl_api_ip6_address,
7898                          &path->nh.address.ip6, &path->table_id))
7899         {
7900           path->proto = FIB_API_PATH_NH_PROTO_IP6;
7901         }
7902       else if (unformat (input, "%U",
7903                          unformat_vl_api_ip4_address, &path->nh.address.ip4))
7904         {
7905           /*
7906            * the recursive next-hops are by default in the default table
7907            */
7908           path->table_id = 0;
7909           path->sw_if_index = ~0;
7910           path->proto = FIB_API_PATH_NH_PROTO_IP4;
7911         }
7912       else if (unformat (input, "%U",
7913                          unformat_vl_api_ip6_address, &path->nh.address.ip6))
7914         {
7915           /*
7916            * the recursive next-hops are by default in the default table
7917            */
7918           path->table_id = 0;
7919           path->sw_if_index = ~0;
7920           path->proto = FIB_API_PATH_NH_PROTO_IP6;
7921         }
7922       else if (unformat (input, "resolve-via-host"))
7923         {
7924           path->flags |= FIB_API_PATH_FLAG_RESOLVE_VIA_HOST;
7925         }
7926       else if (unformat (input, "resolve-via-attached"))
7927         {
7928           path->flags |= FIB_API_PATH_FLAG_RESOLVE_VIA_ATTACHED;
7929         }
7930       else if (unformat (input, "ip4-lookup-in-table %d", &path->table_id))
7931         {
7932           path->type = FIB_API_PATH_TYPE_LOCAL;
7933           path->sw_if_index = ~0;
7934           path->proto = FIB_API_PATH_NH_PROTO_IP4;
7935         }
7936       else if (unformat (input, "ip6-lookup-in-table %d", &path->table_id))
7937         {
7938           path->type = FIB_API_PATH_TYPE_LOCAL;
7939           path->sw_if_index = ~0;
7940           path->proto = FIB_API_PATH_NH_PROTO_IP6;
7941         }
7942       else if (unformat (input, "sw_if_index %d", &path->sw_if_index))
7943         ;
7944       else if (unformat (input, "via-label %d", &path->nh.via_label))
7945         {
7946           path->proto = FIB_API_PATH_NH_PROTO_MPLS;
7947           path->sw_if_index = ~0;
7948         }
7949       else if (unformat (input, "l2-input-on %d", &path->sw_if_index))
7950         {
7951           path->proto = FIB_API_PATH_NH_PROTO_ETHERNET;
7952           path->type = FIB_API_PATH_TYPE_INTERFACE_RX;
7953         }
7954       else if (unformat (input, "local"))
7955         {
7956           path->type = FIB_API_PATH_TYPE_LOCAL;
7957         }
7958       else if (unformat (input, "out-labels"))
7959         {
7960           while (unformat (input, "%d", &out_label))
7961             {
7962               path->label_stack[path->n_labels].label = out_label;
7963               path->label_stack[path->n_labels].is_uniform = 0;
7964               path->label_stack[path->n_labels].ttl = 64;
7965               path->n_labels++;
7966             }
7967         }
7968       else if (unformat (input, "via"))
7969         {
7970           /* new path, back up and return */
7971           unformat_put_input (input);
7972           unformat_put_input (input);
7973           unformat_put_input (input);
7974           unformat_put_input (input);
7975           break;
7976         }
7977       else
7978         {
7979           return (0);
7980         }
7981     }
7982
7983   path->proto = ntohl (path->proto);
7984   path->type = ntohl (path->type);
7985   path->flags = ntohl (path->flags);
7986   path->table_id = ntohl (path->table_id);
7987   path->sw_if_index = ntohl (path->sw_if_index);
7988
7989   return (1);
7990 }
7991
7992 static int
7993 api_ip_route_add_del (vat_main_t * vam)
7994 {
7995   unformat_input_t *i = vam->input;
7996   vl_api_ip_route_add_del_t *mp;
7997   u32 vrf_id = 0;
7998   u8 is_add = 1;
7999   u8 is_multipath = 0;
8000   u8 prefix_set = 0;
8001   u8 path_count = 0;
8002   vl_api_prefix_t pfx = { };
8003   vl_api_fib_path_t paths[8];
8004   int count = 1;
8005   int j;
8006   f64 before = 0;
8007   u32 random_add_del = 0;
8008   u32 *random_vector = 0;
8009   u32 random_seed = 0xdeaddabe;
8010
8011   /* Parse args required to build the message */
8012   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8013     {
8014       if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
8015         prefix_set = 1;
8016       else if (unformat (i, "del"))
8017         is_add = 0;
8018       else if (unformat (i, "add"))
8019         is_add = 1;
8020       else if (unformat (i, "vrf %d", &vrf_id))
8021         ;
8022       else if (unformat (i, "count %d", &count))
8023         ;
8024       else if (unformat (i, "random"))
8025         random_add_del = 1;
8026       else if (unformat (i, "multipath"))
8027         is_multipath = 1;
8028       else if (unformat (i, "seed %d", &random_seed))
8029         ;
8030       else
8031         if (unformat
8032             (i, "via %U", unformat_fib_path, vam, &paths[path_count]))
8033         {
8034           path_count++;
8035           if (8 == path_count)
8036             {
8037               errmsg ("max 8 paths");
8038               return -99;
8039             }
8040         }
8041       else
8042         {
8043           clib_warning ("parse error '%U'", format_unformat_error, i);
8044           return -99;
8045         }
8046     }
8047
8048   if (!path_count)
8049     {
8050       errmsg ("specify a path; via ...");
8051       return -99;
8052     }
8053   if (prefix_set == 0)
8054     {
8055       errmsg ("missing prefix");
8056       return -99;
8057     }
8058
8059   /* Generate a pile of unique, random routes */
8060   if (random_add_del)
8061     {
8062       ip4_address_t *i = (ip4_address_t *) & paths[0].nh.address.ip4;
8063       u32 this_random_address;
8064       uword *random_hash;
8065
8066       random_hash = hash_create (count, sizeof (uword));
8067
8068       hash_set (random_hash, i->as_u32, 1);
8069       for (j = 0; j <= count; j++)
8070         {
8071           do
8072             {
8073               this_random_address = random_u32 (&random_seed);
8074               this_random_address =
8075                 clib_host_to_net_u32 (this_random_address);
8076             }
8077           while (hash_get (random_hash, this_random_address));
8078           vec_add1 (random_vector, this_random_address);
8079           hash_set (random_hash, this_random_address, 1);
8080         }
8081       hash_free (random_hash);
8082       set_ip4_address (&pfx.address, random_vector[0]);
8083     }
8084
8085   if (count > 1)
8086     {
8087       /* Turn on async mode */
8088       vam->async_mode = 1;
8089       vam->async_errors = 0;
8090       before = vat_time_now (vam);
8091     }
8092
8093   for (j = 0; j < count; j++)
8094     {
8095       /* Construct the API message */
8096       M2 (IP_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t) * path_count);
8097
8098       mp->is_add = is_add;
8099       mp->is_multipath = is_multipath;
8100
8101       clib_memcpy (&mp->route.prefix, &pfx, sizeof (pfx));
8102       mp->route.table_id = ntohl (vrf_id);
8103       mp->route.n_paths = path_count;
8104
8105       clib_memcpy (&mp->route.paths, &paths, sizeof (paths[0]) * path_count);
8106
8107       if (random_add_del)
8108         set_ip4_address (&pfx.address, random_vector[j + 1]);
8109       else
8110         increment_address (&pfx.address);
8111       /* send it... */
8112       S (mp);
8113       /* If we receive SIGTERM, stop now... */
8114       if (vam->do_exit)
8115         break;
8116     }
8117
8118   /* When testing multiple add/del ops, use a control-ping to sync */
8119   if (count > 1)
8120     {
8121       vl_api_control_ping_t *mp_ping;
8122       f64 after;
8123       f64 timeout;
8124
8125       /* Shut off async mode */
8126       vam->async_mode = 0;
8127
8128       MPING (CONTROL_PING, mp_ping);
8129       S (mp_ping);
8130
8131       timeout = vat_time_now (vam) + 1.0;
8132       while (vat_time_now (vam) < timeout)
8133         if (vam->result_ready == 1)
8134           goto out;
8135       vam->retval = -99;
8136
8137     out:
8138       if (vam->retval == -99)
8139         errmsg ("timeout");
8140
8141       if (vam->async_errors > 0)
8142         {
8143           errmsg ("%d asynchronous errors", vam->async_errors);
8144           vam->retval = -98;
8145         }
8146       vam->async_errors = 0;
8147       after = vat_time_now (vam);
8148
8149       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8150       if (j > 0)
8151         count = j;
8152
8153       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8154              count, after - before, count / (after - before));
8155     }
8156   else
8157     {
8158       int ret;
8159
8160       /* Wait for a reply... */
8161       W (ret);
8162       return ret;
8163     }
8164
8165   /* Return the good/bad news */
8166   return (vam->retval);
8167 }
8168
8169 static int
8170 api_ip_mroute_add_del (vat_main_t * vam)
8171 {
8172   unformat_input_t *i = vam->input;
8173   u8 path_set = 0, prefix_set = 0, is_add = 1;
8174   vl_api_ip_mroute_add_del_t *mp;
8175   mfib_entry_flags_t eflags = 0;
8176   vl_api_mfib_path_t path;
8177   vl_api_mprefix_t pfx = { };
8178   u32 vrf_id = 0;
8179   int ret;
8180
8181   /* Parse args required to build the message */
8182   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8183     {
8184       if (unformat (i, "%U", unformat_vl_api_mprefix, &pfx))
8185         {
8186           prefix_set = 1;
8187           pfx.grp_address_length = htons (pfx.grp_address_length);
8188         }
8189       else if (unformat (i, "del"))
8190         is_add = 0;
8191       else if (unformat (i, "add"))
8192         is_add = 1;
8193       else if (unformat (i, "vrf %d", &vrf_id))
8194         ;
8195       else if (unformat (i, "%U", unformat_mfib_itf_flags, &path.itf_flags))
8196         path.itf_flags = htonl (path.itf_flags);
8197       else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
8198         ;
8199       else if (unformat (i, "via %U", unformat_fib_path, vam, &path.path))
8200         path_set = 1;
8201       else
8202         {
8203           clib_warning ("parse error '%U'", format_unformat_error, i);
8204           return -99;
8205         }
8206     }
8207
8208   if (prefix_set == 0)
8209     {
8210       errmsg ("missing addresses\n");
8211       return -99;
8212     }
8213   if (path_set == 0)
8214     {
8215       errmsg ("missing path\n");
8216       return -99;
8217     }
8218
8219   /* Construct the API message */
8220   M (IP_MROUTE_ADD_DEL, mp);
8221
8222   mp->is_add = is_add;
8223   mp->is_multipath = 1;
8224
8225   clib_memcpy (&mp->route.prefix, &pfx, sizeof (pfx));
8226   mp->route.table_id = htonl (vrf_id);
8227   mp->route.n_paths = 1;
8228   mp->route.entry_flags = htonl (eflags);
8229
8230   clib_memcpy (&mp->route.paths, &path, sizeof (path));
8231
8232   /* send it... */
8233   S (mp);
8234   /* Wait for a reply... */
8235   W (ret);
8236   return ret;
8237 }
8238
8239 static int
8240 api_mpls_table_add_del (vat_main_t * vam)
8241 {
8242   unformat_input_t *i = vam->input;
8243   vl_api_mpls_table_add_del_t *mp;
8244   u32 table_id = ~0;
8245   u8 is_add = 1;
8246   int ret = 0;
8247
8248   /* Parse args required to build the message */
8249   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8250     {
8251       if (unformat (i, "table %d", &table_id))
8252         ;
8253       else if (unformat (i, "del"))
8254         is_add = 0;
8255       else if (unformat (i, "add"))
8256         is_add = 1;
8257       else
8258         {
8259           clib_warning ("parse error '%U'", format_unformat_error, i);
8260           return -99;
8261         }
8262     }
8263
8264   if (~0 == table_id)
8265     {
8266       errmsg ("missing table-ID");
8267       return -99;
8268     }
8269
8270   /* Construct the API message */
8271   M (MPLS_TABLE_ADD_DEL, mp);
8272
8273   mp->mt_table.mt_table_id = ntohl (table_id);
8274   mp->mt_is_add = is_add;
8275
8276   /* send it... */
8277   S (mp);
8278
8279   /* Wait for a reply... */
8280   W (ret);
8281
8282   return ret;
8283 }
8284
8285 static int
8286 api_mpls_route_add_del (vat_main_t * vam)
8287 {
8288   u8 is_add = 1, path_count = 0, is_multipath = 0, is_eos = 0;
8289   mpls_label_t local_label = MPLS_LABEL_INVALID;
8290   unformat_input_t *i = vam->input;
8291   vl_api_mpls_route_add_del_t *mp;
8292   vl_api_fib_path_t paths[8];
8293   int count = 1, j;
8294   f64 before = 0;
8295
8296   /* Parse args required to build the message */
8297   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8298     {
8299       if (unformat (i, "%d", &local_label))
8300         ;
8301       else if (unformat (i, "eos"))
8302         is_eos = 1;
8303       else if (unformat (i, "non-eos"))
8304         is_eos = 0;
8305       else if (unformat (i, "del"))
8306         is_add = 0;
8307       else if (unformat (i, "add"))
8308         is_add = 1;
8309       else if (unformat (i, "multipath"))
8310         is_multipath = 1;
8311       else if (unformat (i, "count %d", &count))
8312         ;
8313       else
8314         if (unformat
8315             (i, "via %U", unformat_fib_path, vam, &paths[path_count]))
8316         {
8317           path_count++;
8318           if (8 == path_count)
8319             {
8320               errmsg ("max 8 paths");
8321               return -99;
8322             }
8323         }
8324       else
8325         {
8326           clib_warning ("parse error '%U'", format_unformat_error, i);
8327           return -99;
8328         }
8329     }
8330
8331   if (!path_count)
8332     {
8333       errmsg ("specify a path; via ...");
8334       return -99;
8335     }
8336
8337   if (MPLS_LABEL_INVALID == local_label)
8338     {
8339       errmsg ("missing label");
8340       return -99;
8341     }
8342
8343   if (count > 1)
8344     {
8345       /* Turn on async mode */
8346       vam->async_mode = 1;
8347       vam->async_errors = 0;
8348       before = vat_time_now (vam);
8349     }
8350
8351   for (j = 0; j < count; j++)
8352     {
8353       /* Construct the API message */
8354       M2 (MPLS_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t) * path_count);
8355
8356       mp->mr_is_add = is_add;
8357       mp->mr_is_multipath = is_multipath;
8358
8359       mp->mr_route.mr_label = local_label;
8360       mp->mr_route.mr_eos = is_eos;
8361       mp->mr_route.mr_table_id = 0;
8362       mp->mr_route.mr_n_paths = path_count;
8363
8364       clib_memcpy (&mp->mr_route.mr_paths, paths,
8365                    sizeof (paths[0]) * path_count);
8366
8367       local_label++;
8368
8369       /* send it... */
8370       S (mp);
8371       /* If we receive SIGTERM, stop now... */
8372       if (vam->do_exit)
8373         break;
8374     }
8375
8376   /* When testing multiple add/del ops, use a control-ping to sync */
8377   if (count > 1)
8378     {
8379       vl_api_control_ping_t *mp_ping;
8380       f64 after;
8381       f64 timeout;
8382
8383       /* Shut off async mode */
8384       vam->async_mode = 0;
8385
8386       MPING (CONTROL_PING, mp_ping);
8387       S (mp_ping);
8388
8389       timeout = vat_time_now (vam) + 1.0;
8390       while (vat_time_now (vam) < timeout)
8391         if (vam->result_ready == 1)
8392           goto out;
8393       vam->retval = -99;
8394
8395     out:
8396       if (vam->retval == -99)
8397         errmsg ("timeout");
8398
8399       if (vam->async_errors > 0)
8400         {
8401           errmsg ("%d asynchronous errors", vam->async_errors);
8402           vam->retval = -98;
8403         }
8404       vam->async_errors = 0;
8405       after = vat_time_now (vam);
8406
8407       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8408       if (j > 0)
8409         count = j;
8410
8411       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8412              count, after - before, count / (after - before));
8413     }
8414   else
8415     {
8416       int ret;
8417
8418       /* Wait for a reply... */
8419       W (ret);
8420       return ret;
8421     }
8422
8423   /* Return the good/bad news */
8424   return (vam->retval);
8425   return (0);
8426 }
8427
8428 static int
8429 api_mpls_ip_bind_unbind (vat_main_t * vam)
8430 {
8431   unformat_input_t *i = vam->input;
8432   vl_api_mpls_ip_bind_unbind_t *mp;
8433   u32 ip_table_id = 0;
8434   u8 is_bind = 1;
8435   vl_api_prefix_t pfx;
8436   u8 prefix_set = 0;
8437   mpls_label_t local_label = MPLS_LABEL_INVALID;
8438   int ret;
8439
8440   /* Parse args required to build the message */
8441   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8442     {
8443       if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
8444         prefix_set = 1;
8445       else if (unformat (i, "%d", &local_label))
8446         ;
8447       else if (unformat (i, "table-id %d", &ip_table_id))
8448         ;
8449       else if (unformat (i, "unbind"))
8450         is_bind = 0;
8451       else if (unformat (i, "bind"))
8452         is_bind = 1;
8453       else
8454         {
8455           clib_warning ("parse error '%U'", format_unformat_error, i);
8456           return -99;
8457         }
8458     }
8459
8460   if (!prefix_set)
8461     {
8462       errmsg ("IP prefix not set");
8463       return -99;
8464     }
8465
8466   if (MPLS_LABEL_INVALID == local_label)
8467     {
8468       errmsg ("missing label");
8469       return -99;
8470     }
8471
8472   /* Construct the API message */
8473   M (MPLS_IP_BIND_UNBIND, mp);
8474
8475   mp->mb_is_bind = is_bind;
8476   mp->mb_ip_table_id = ntohl (ip_table_id);
8477   mp->mb_mpls_table_id = 0;
8478   mp->mb_label = ntohl (local_label);
8479   clib_memcpy (&mp->mb_prefix, &pfx, sizeof (pfx));
8480
8481   /* send it... */
8482   S (mp);
8483
8484   /* Wait for a reply... */
8485   W (ret);
8486   return ret;
8487   return (0);
8488 }
8489
8490 static int
8491 api_sr_mpls_policy_add (vat_main_t * vam)
8492 {
8493   unformat_input_t *i = vam->input;
8494   vl_api_sr_mpls_policy_add_t *mp;
8495   u32 bsid = 0;
8496   u32 weight = 1;
8497   u8 type = 0;
8498   u8 n_segments = 0;
8499   u32 sid;
8500   u32 *segments = NULL;
8501   int ret;
8502
8503   /* Parse args required to build the message */
8504   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8505     {
8506       if (unformat (i, "bsid %d", &bsid))
8507         ;
8508       else if (unformat (i, "weight %d", &weight))
8509         ;
8510       else if (unformat (i, "spray"))
8511         type = 1;
8512       else if (unformat (i, "next %d", &sid))
8513         {
8514           n_segments += 1;
8515           vec_add1 (segments, htonl (sid));
8516         }
8517       else
8518         {
8519           clib_warning ("parse error '%U'", format_unformat_error, i);
8520           return -99;
8521         }
8522     }
8523
8524   if (bsid == 0)
8525     {
8526       errmsg ("bsid not set");
8527       return -99;
8528     }
8529
8530   if (n_segments == 0)
8531     {
8532       errmsg ("no sid in segment stack");
8533       return -99;
8534     }
8535
8536   /* Construct the API message */
8537   M2 (SR_MPLS_POLICY_ADD, mp, sizeof (u32) * n_segments);
8538
8539   mp->bsid = htonl (bsid);
8540   mp->weight = htonl (weight);
8541   mp->type = type;
8542   mp->n_segments = n_segments;
8543   memcpy (mp->segments, segments, sizeof (u32) * n_segments);
8544   vec_free (segments);
8545
8546   /* send it... */
8547   S (mp);
8548
8549   /* Wait for a reply... */
8550   W (ret);
8551   return ret;
8552 }
8553
8554 static int
8555 api_sr_mpls_policy_del (vat_main_t * vam)
8556 {
8557   unformat_input_t *i = vam->input;
8558   vl_api_sr_mpls_policy_del_t *mp;
8559   u32 bsid = 0;
8560   int ret;
8561
8562   /* Parse args required to build the message */
8563   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8564     {
8565       if (unformat (i, "bsid %d", &bsid))
8566         ;
8567       else
8568         {
8569           clib_warning ("parse error '%U'", format_unformat_error, i);
8570           return -99;
8571         }
8572     }
8573
8574   if (bsid == 0)
8575     {
8576       errmsg ("bsid not set");
8577       return -99;
8578     }
8579
8580   /* Construct the API message */
8581   M (SR_MPLS_POLICY_DEL, mp);
8582
8583   mp->bsid = htonl (bsid);
8584
8585   /* send it... */
8586   S (mp);
8587
8588   /* Wait for a reply... */
8589   W (ret);
8590   return ret;
8591 }
8592
8593 static int
8594 api_bier_table_add_del (vat_main_t * vam)
8595 {
8596   unformat_input_t *i = vam->input;
8597   vl_api_bier_table_add_del_t *mp;
8598   u8 is_add = 1;
8599   u32 set = 0, sub_domain = 0, hdr_len = 3;
8600   mpls_label_t local_label = MPLS_LABEL_INVALID;
8601   int ret;
8602
8603   /* Parse args required to build the message */
8604   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8605     {
8606       if (unformat (i, "sub-domain %d", &sub_domain))
8607         ;
8608       else if (unformat (i, "set %d", &set))
8609         ;
8610       else if (unformat (i, "label %d", &local_label))
8611         ;
8612       else if (unformat (i, "hdr-len %d", &hdr_len))
8613         ;
8614       else if (unformat (i, "add"))
8615         is_add = 1;
8616       else if (unformat (i, "del"))
8617         is_add = 0;
8618       else
8619         {
8620           clib_warning ("parse error '%U'", format_unformat_error, i);
8621           return -99;
8622         }
8623     }
8624
8625   if (MPLS_LABEL_INVALID == local_label)
8626     {
8627       errmsg ("missing label\n");
8628       return -99;
8629     }
8630
8631   /* Construct the API message */
8632   M (BIER_TABLE_ADD_DEL, mp);
8633
8634   mp->bt_is_add = is_add;
8635   mp->bt_label = ntohl (local_label);
8636   mp->bt_tbl_id.bt_set = set;
8637   mp->bt_tbl_id.bt_sub_domain = sub_domain;
8638   mp->bt_tbl_id.bt_hdr_len_id = hdr_len;
8639
8640   /* send it... */
8641   S (mp);
8642
8643   /* Wait for a reply... */
8644   W (ret);
8645
8646   return (ret);
8647 }
8648
8649 static int
8650 api_bier_route_add_del (vat_main_t * vam)
8651 {
8652   unformat_input_t *i = vam->input;
8653   vl_api_bier_route_add_del_t *mp;
8654   u8 is_add = 1;
8655   u32 set = 0, sub_domain = 0, hdr_len = 3, bp = 0;
8656   ip4_address_t v4_next_hop_address;
8657   ip6_address_t v6_next_hop_address;
8658   u8 next_hop_set = 0;
8659   u8 next_hop_proto_is_ip4 = 1;
8660   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8661   int ret;
8662
8663   /* Parse args required to build the message */
8664   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8665     {
8666       if (unformat (i, "%U", unformat_ip4_address, &v4_next_hop_address))
8667         {
8668           next_hop_proto_is_ip4 = 1;
8669           next_hop_set = 1;
8670         }
8671       else if (unformat (i, "%U", unformat_ip6_address, &v6_next_hop_address))
8672         {
8673           next_hop_proto_is_ip4 = 0;
8674           next_hop_set = 1;
8675         }
8676       if (unformat (i, "sub-domain %d", &sub_domain))
8677         ;
8678       else if (unformat (i, "set %d", &set))
8679         ;
8680       else if (unformat (i, "hdr-len %d", &hdr_len))
8681         ;
8682       else if (unformat (i, "bp %d", &bp))
8683         ;
8684       else if (unformat (i, "add"))
8685         is_add = 1;
8686       else if (unformat (i, "del"))
8687         is_add = 0;
8688       else if (unformat (i, "out-label %d", &next_hop_out_label))
8689         ;
8690       else
8691         {
8692           clib_warning ("parse error '%U'", format_unformat_error, i);
8693           return -99;
8694         }
8695     }
8696
8697   if (!next_hop_set || (MPLS_LABEL_INVALID == next_hop_out_label))
8698     {
8699       errmsg ("next hop / label set\n");
8700       return -99;
8701     }
8702   if (0 == bp)
8703     {
8704       errmsg ("bit=position not set\n");
8705       return -99;
8706     }
8707
8708   /* Construct the API message */
8709   M2 (BIER_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t));
8710
8711   mp->br_is_add = is_add;
8712   mp->br_route.br_tbl_id.bt_set = set;
8713   mp->br_route.br_tbl_id.bt_sub_domain = sub_domain;
8714   mp->br_route.br_tbl_id.bt_hdr_len_id = hdr_len;
8715   mp->br_route.br_bp = ntohs (bp);
8716   mp->br_route.br_n_paths = 1;
8717   mp->br_route.br_paths[0].n_labels = 1;
8718   mp->br_route.br_paths[0].label_stack[0].label = ntohl (next_hop_out_label);
8719   mp->br_route.br_paths[0].proto = (next_hop_proto_is_ip4 ?
8720                                     FIB_API_PATH_NH_PROTO_IP4 :
8721                                     FIB_API_PATH_NH_PROTO_IP6);
8722
8723   if (next_hop_proto_is_ip4)
8724     {
8725       clib_memcpy (&mp->br_route.br_paths[0].nh.address.ip4,
8726                    &v4_next_hop_address, sizeof (v4_next_hop_address));
8727     }
8728   else
8729     {
8730       clib_memcpy (&mp->br_route.br_paths[0].nh.address.ip6,
8731                    &v6_next_hop_address, sizeof (v6_next_hop_address));
8732     }
8733
8734   /* send it... */
8735   S (mp);
8736
8737   /* Wait for a reply... */
8738   W (ret);
8739
8740   return (ret);
8741 }
8742
8743 static int
8744 api_mpls_tunnel_add_del (vat_main_t * vam)
8745 {
8746   unformat_input_t *i = vam->input;
8747   vl_api_mpls_tunnel_add_del_t *mp;
8748
8749   vl_api_fib_path_t paths[8];
8750   u32 sw_if_index = ~0;
8751   u8 path_count = 0;
8752   u8 l2_only = 0;
8753   u8 is_add = 1;
8754   int ret;
8755
8756   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8757     {
8758       if (unformat (i, "add"))
8759         is_add = 1;
8760       else
8761         if (unformat
8762             (i, "del %U", api_unformat_sw_if_index, vam, &sw_if_index))
8763         is_add = 0;
8764       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
8765         is_add = 0;
8766       else if (unformat (i, "l2-only"))
8767         l2_only = 1;
8768       else
8769         if (unformat
8770             (i, "via %U", unformat_fib_path, vam, &paths[path_count]))
8771         {
8772           path_count++;
8773           if (8 == path_count)
8774             {
8775               errmsg ("max 8 paths");
8776               return -99;
8777             }
8778         }
8779       else
8780         {
8781           clib_warning ("parse error '%U'", format_unformat_error, i);
8782           return -99;
8783         }
8784     }
8785
8786   M2 (MPLS_TUNNEL_ADD_DEL, mp, sizeof (vl_api_fib_path_t) * path_count);
8787
8788   mp->mt_is_add = is_add;
8789   mp->mt_tunnel.mt_sw_if_index = ntohl (sw_if_index);
8790   mp->mt_tunnel.mt_l2_only = l2_only;
8791   mp->mt_tunnel.mt_is_multicast = 0;
8792   mp->mt_tunnel.mt_n_paths = path_count;
8793
8794   clib_memcpy (&mp->mt_tunnel.mt_paths, &paths,
8795                sizeof (paths[0]) * path_count);
8796
8797   S (mp);
8798   W (ret);
8799   return ret;
8800 }
8801
8802 static int
8803 api_sw_interface_set_unnumbered (vat_main_t * vam)
8804 {
8805   unformat_input_t *i = vam->input;
8806   vl_api_sw_interface_set_unnumbered_t *mp;
8807   u32 sw_if_index;
8808   u32 unnum_sw_index = ~0;
8809   u8 is_add = 1;
8810   u8 sw_if_index_set = 0;
8811   int ret;
8812
8813   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8814     {
8815       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8816         sw_if_index_set = 1;
8817       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8818         sw_if_index_set = 1;
8819       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
8820         ;
8821       else if (unformat (i, "del"))
8822         is_add = 0;
8823       else
8824         {
8825           clib_warning ("parse error '%U'", format_unformat_error, i);
8826           return -99;
8827         }
8828     }
8829
8830   if (sw_if_index_set == 0)
8831     {
8832       errmsg ("missing interface name or sw_if_index");
8833       return -99;
8834     }
8835
8836   M (SW_INTERFACE_SET_UNNUMBERED, mp);
8837
8838   mp->sw_if_index = ntohl (sw_if_index);
8839   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
8840   mp->is_add = is_add;
8841
8842   S (mp);
8843   W (ret);
8844   return ret;
8845 }
8846
8847
8848 static int
8849 api_create_vlan_subif (vat_main_t * vam)
8850 {
8851   unformat_input_t *i = vam->input;
8852   vl_api_create_vlan_subif_t *mp;
8853   u32 sw_if_index;
8854   u8 sw_if_index_set = 0;
8855   u32 vlan_id;
8856   u8 vlan_id_set = 0;
8857   int ret;
8858
8859   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8860     {
8861       if (unformat (i, "sw_if_index %d", &sw_if_index))
8862         sw_if_index_set = 1;
8863       else
8864         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8865         sw_if_index_set = 1;
8866       else if (unformat (i, "vlan %d", &vlan_id))
8867         vlan_id_set = 1;
8868       else
8869         {
8870           clib_warning ("parse error '%U'", format_unformat_error, i);
8871           return -99;
8872         }
8873     }
8874
8875   if (sw_if_index_set == 0)
8876     {
8877       errmsg ("missing interface name or sw_if_index");
8878       return -99;
8879     }
8880
8881   if (vlan_id_set == 0)
8882     {
8883       errmsg ("missing vlan_id");
8884       return -99;
8885     }
8886   M (CREATE_VLAN_SUBIF, mp);
8887
8888   mp->sw_if_index = ntohl (sw_if_index);
8889   mp->vlan_id = ntohl (vlan_id);
8890
8891   S (mp);
8892   W (ret);
8893   return ret;
8894 }
8895
8896 #define foreach_create_subif_bit                \
8897 _(no_tags)                                      \
8898 _(one_tag)                                      \
8899 _(two_tags)                                     \
8900 _(dot1ad)                                       \
8901 _(exact_match)                                  \
8902 _(default_sub)                                  \
8903 _(outer_vlan_id_any)                            \
8904 _(inner_vlan_id_any)
8905
8906 #define foreach_create_subif_flag               \
8907 _(0, "no_tags")                                 \
8908 _(1, "one_tag")                                 \
8909 _(2, "two_tags")                                \
8910 _(3, "dot1ad")                                  \
8911 _(4, "exact_match")                             \
8912 _(5, "default_sub")                             \
8913 _(6, "outer_vlan_id_any")                       \
8914 _(7, "inner_vlan_id_any")
8915
8916 static int
8917 api_create_subif (vat_main_t * vam)
8918 {
8919   unformat_input_t *i = vam->input;
8920   vl_api_create_subif_t *mp;
8921   u32 sw_if_index;
8922   u8 sw_if_index_set = 0;
8923   u32 sub_id;
8924   u8 sub_id_set = 0;
8925   u32 __attribute__ ((unused)) no_tags = 0;
8926   u32 __attribute__ ((unused)) one_tag = 0;
8927   u32 __attribute__ ((unused)) two_tags = 0;
8928   u32 __attribute__ ((unused)) dot1ad = 0;
8929   u32 __attribute__ ((unused)) exact_match = 0;
8930   u32 __attribute__ ((unused)) default_sub = 0;
8931   u32 __attribute__ ((unused)) outer_vlan_id_any = 0;
8932   u32 __attribute__ ((unused)) inner_vlan_id_any = 0;
8933   u32 tmp;
8934   u16 outer_vlan_id = 0;
8935   u16 inner_vlan_id = 0;
8936   int ret;
8937
8938   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8939     {
8940       if (unformat (i, "sw_if_index %d", &sw_if_index))
8941         sw_if_index_set = 1;
8942       else
8943         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8944         sw_if_index_set = 1;
8945       else if (unformat (i, "sub_id %d", &sub_id))
8946         sub_id_set = 1;
8947       else if (unformat (i, "outer_vlan_id %d", &tmp))
8948         outer_vlan_id = tmp;
8949       else if (unformat (i, "inner_vlan_id %d", &tmp))
8950         inner_vlan_id = tmp;
8951
8952 #define _(a) else if (unformat (i, #a)) a = 1 ;
8953       foreach_create_subif_bit
8954 #undef _
8955         else
8956         {
8957           clib_warning ("parse error '%U'", format_unformat_error, i);
8958           return -99;
8959         }
8960     }
8961
8962   if (sw_if_index_set == 0)
8963     {
8964       errmsg ("missing interface name or sw_if_index");
8965       return -99;
8966     }
8967
8968   if (sub_id_set == 0)
8969     {
8970       errmsg ("missing sub_id");
8971       return -99;
8972     }
8973   M (CREATE_SUBIF, mp);
8974
8975   mp->sw_if_index = ntohl (sw_if_index);
8976   mp->sub_id = ntohl (sub_id);
8977
8978 #define _(a,b) mp->sub_if_flags |= (1 << a);
8979   foreach_create_subif_flag;
8980 #undef _
8981
8982   mp->outer_vlan_id = ntohs (outer_vlan_id);
8983   mp->inner_vlan_id = ntohs (inner_vlan_id);
8984
8985   S (mp);
8986   W (ret);
8987   return ret;
8988 }
8989
8990 static int
8991 api_ip_table_replace_begin (vat_main_t * vam)
8992 {
8993   unformat_input_t *i = vam->input;
8994   vl_api_ip_table_replace_begin_t *mp;
8995   u32 table_id = 0;
8996   u8 is_ipv6 = 0;
8997
8998   int ret;
8999   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9000     {
9001       if (unformat (i, "table %d", &table_id))
9002         ;
9003       else if (unformat (i, "ipv6"))
9004         is_ipv6 = 1;
9005       else
9006         {
9007           clib_warning ("parse error '%U'", format_unformat_error, i);
9008           return -99;
9009         }
9010     }
9011
9012   M (IP_TABLE_REPLACE_BEGIN, mp);
9013
9014   mp->table.table_id = ntohl (table_id);
9015   mp->table.is_ip6 = is_ipv6;
9016
9017   S (mp);
9018   W (ret);
9019   return ret;
9020 }
9021
9022 static int
9023 api_ip_table_flush (vat_main_t * vam)
9024 {
9025   unformat_input_t *i = vam->input;
9026   vl_api_ip_table_flush_t *mp;
9027   u32 table_id = 0;
9028   u8 is_ipv6 = 0;
9029
9030   int ret;
9031   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9032     {
9033       if (unformat (i, "table %d", &table_id))
9034         ;
9035       else if (unformat (i, "ipv6"))
9036         is_ipv6 = 1;
9037       else
9038         {
9039           clib_warning ("parse error '%U'", format_unformat_error, i);
9040           return -99;
9041         }
9042     }
9043
9044   M (IP_TABLE_FLUSH, mp);
9045
9046   mp->table.table_id = ntohl (table_id);
9047   mp->table.is_ip6 = is_ipv6;
9048
9049   S (mp);
9050   W (ret);
9051   return ret;
9052 }
9053
9054 static int
9055 api_ip_table_replace_end (vat_main_t * vam)
9056 {
9057   unformat_input_t *i = vam->input;
9058   vl_api_ip_table_replace_end_t *mp;
9059   u32 table_id = 0;
9060   u8 is_ipv6 = 0;
9061
9062   int ret;
9063   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9064     {
9065       if (unformat (i, "table %d", &table_id))
9066         ;
9067       else if (unformat (i, "ipv6"))
9068         is_ipv6 = 1;
9069       else
9070         {
9071           clib_warning ("parse error '%U'", format_unformat_error, i);
9072           return -99;
9073         }
9074     }
9075
9076   M (IP_TABLE_REPLACE_END, mp);
9077
9078   mp->table.table_id = ntohl (table_id);
9079   mp->table.is_ip6 = is_ipv6;
9080
9081   S (mp);
9082   W (ret);
9083   return ret;
9084 }
9085
9086 static int
9087 api_set_ip_flow_hash (vat_main_t * vam)
9088 {
9089   unformat_input_t *i = vam->input;
9090   vl_api_set_ip_flow_hash_t *mp;
9091   u32 vrf_id = 0;
9092   u8 is_ipv6 = 0;
9093   u8 vrf_id_set = 0;
9094   u8 src = 0;
9095   u8 dst = 0;
9096   u8 sport = 0;
9097   u8 dport = 0;
9098   u8 proto = 0;
9099   u8 reverse = 0;
9100   int ret;
9101
9102   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9103     {
9104       if (unformat (i, "vrf %d", &vrf_id))
9105         vrf_id_set = 1;
9106       else if (unformat (i, "ipv6"))
9107         is_ipv6 = 1;
9108       else if (unformat (i, "src"))
9109         src = 1;
9110       else if (unformat (i, "dst"))
9111         dst = 1;
9112       else if (unformat (i, "sport"))
9113         sport = 1;
9114       else if (unformat (i, "dport"))
9115         dport = 1;
9116       else if (unformat (i, "proto"))
9117         proto = 1;
9118       else if (unformat (i, "reverse"))
9119         reverse = 1;
9120
9121       else
9122         {
9123           clib_warning ("parse error '%U'", format_unformat_error, i);
9124           return -99;
9125         }
9126     }
9127
9128   if (vrf_id_set == 0)
9129     {
9130       errmsg ("missing vrf id");
9131       return -99;
9132     }
9133
9134   M (SET_IP_FLOW_HASH, mp);
9135   mp->src = src;
9136   mp->dst = dst;
9137   mp->sport = sport;
9138   mp->dport = dport;
9139   mp->proto = proto;
9140   mp->reverse = reverse;
9141   mp->vrf_id = ntohl (vrf_id);
9142   mp->is_ipv6 = is_ipv6;
9143
9144   S (mp);
9145   W (ret);
9146   return ret;
9147 }
9148
9149 static int
9150 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
9151 {
9152   unformat_input_t *i = vam->input;
9153   vl_api_sw_interface_ip6_enable_disable_t *mp;
9154   u32 sw_if_index;
9155   u8 sw_if_index_set = 0;
9156   u8 enable = 0;
9157   int ret;
9158
9159   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9160     {
9161       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9162         sw_if_index_set = 1;
9163       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9164         sw_if_index_set = 1;
9165       else if (unformat (i, "enable"))
9166         enable = 1;
9167       else if (unformat (i, "disable"))
9168         enable = 0;
9169       else
9170         {
9171           clib_warning ("parse error '%U'", format_unformat_error, i);
9172           return -99;
9173         }
9174     }
9175
9176   if (sw_if_index_set == 0)
9177     {
9178       errmsg ("missing interface name or sw_if_index");
9179       return -99;
9180     }
9181
9182   M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
9183
9184   mp->sw_if_index = ntohl (sw_if_index);
9185   mp->enable = enable;
9186
9187   S (mp);
9188   W (ret);
9189   return ret;
9190 }
9191
9192
9193 static int
9194 api_l2_patch_add_del (vat_main_t * vam)
9195 {
9196   unformat_input_t *i = vam->input;
9197   vl_api_l2_patch_add_del_t *mp;
9198   u32 rx_sw_if_index;
9199   u8 rx_sw_if_index_set = 0;
9200   u32 tx_sw_if_index;
9201   u8 tx_sw_if_index_set = 0;
9202   u8 is_add = 1;
9203   int ret;
9204
9205   /* Parse args required to build the message */
9206   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9207     {
9208       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
9209         rx_sw_if_index_set = 1;
9210       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
9211         tx_sw_if_index_set = 1;
9212       else if (unformat (i, "rx"))
9213         {
9214           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9215             {
9216               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
9217                             &rx_sw_if_index))
9218                 rx_sw_if_index_set = 1;
9219             }
9220           else
9221             break;
9222         }
9223       else if (unformat (i, "tx"))
9224         {
9225           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9226             {
9227               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
9228                             &tx_sw_if_index))
9229                 tx_sw_if_index_set = 1;
9230             }
9231           else
9232             break;
9233         }
9234       else if (unformat (i, "del"))
9235         is_add = 0;
9236       else
9237         break;
9238     }
9239
9240   if (rx_sw_if_index_set == 0)
9241     {
9242       errmsg ("missing rx interface name or rx_sw_if_index");
9243       return -99;
9244     }
9245
9246   if (tx_sw_if_index_set == 0)
9247     {
9248       errmsg ("missing tx interface name or tx_sw_if_index");
9249       return -99;
9250     }
9251
9252   M (L2_PATCH_ADD_DEL, mp);
9253
9254   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
9255   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
9256   mp->is_add = is_add;
9257
9258   S (mp);
9259   W (ret);
9260   return ret;
9261 }
9262
9263 u8 is_del;
9264 u8 localsid_addr[16];
9265 u8 end_psp;
9266 u8 behavior;
9267 u32 sw_if_index;
9268 u32 vlan_index;
9269 u32 fib_table;
9270 u8 nh_addr[16];
9271
9272 static int
9273 api_sr_localsid_add_del (vat_main_t * vam)
9274 {
9275   unformat_input_t *i = vam->input;
9276   vl_api_sr_localsid_add_del_t *mp;
9277
9278   u8 is_del;
9279   ip6_address_t localsid;
9280   u8 end_psp = 0;
9281   u8 behavior = ~0;
9282   u32 sw_if_index;
9283   u32 fib_table = ~(u32) 0;
9284   ip6_address_t nh_addr6;
9285   ip4_address_t nh_addr4;
9286   clib_memset (&nh_addr6, 0, sizeof (ip6_address_t));
9287   clib_memset (&nh_addr4, 0, sizeof (ip4_address_t));
9288
9289   bool nexthop_set = 0;
9290
9291   int ret;
9292
9293   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9294     {
9295       if (unformat (i, "del"))
9296         is_del = 1;
9297       else if (unformat (i, "address %U", unformat_ip6_address, &localsid));
9298       else if (unformat (i, "next-hop %U", unformat_ip4_address, &nh_addr4))
9299         nexthop_set = 1;
9300       else if (unformat (i, "next-hop %U", unformat_ip6_address, &nh_addr6))
9301         nexthop_set = 1;
9302       else if (unformat (i, "behavior %u", &behavior));
9303       else if (unformat (i, "sw_if_index %u", &sw_if_index));
9304       else if (unformat (i, "fib-table %u", &fib_table));
9305       else if (unformat (i, "end.psp %u", &behavior));
9306       else
9307         break;
9308     }
9309
9310   M (SR_LOCALSID_ADD_DEL, mp);
9311
9312   clib_memcpy (mp->localsid.addr, &localsid, sizeof (mp->localsid));
9313
9314   if (nexthop_set)
9315     {
9316       clib_memcpy (mp->nh_addr6, &nh_addr6, sizeof (mp->nh_addr6));
9317       clib_memcpy (mp->nh_addr4, &nh_addr4, sizeof (mp->nh_addr4));
9318     }
9319   mp->behavior = behavior;
9320   mp->sw_if_index = ntohl (sw_if_index);
9321   mp->fib_table = ntohl (fib_table);
9322   mp->end_psp = end_psp;
9323   mp->is_del = is_del;
9324
9325   S (mp);
9326   W (ret);
9327   return ret;
9328 }
9329
9330 static int
9331 api_ioam_enable (vat_main_t * vam)
9332 {
9333   unformat_input_t *input = vam->input;
9334   vl_api_ioam_enable_t *mp;
9335   u32 id = 0;
9336   int has_trace_option = 0;
9337   int has_pot_option = 0;
9338   int has_seqno_option = 0;
9339   int has_analyse_option = 0;
9340   int ret;
9341
9342   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9343     {
9344       if (unformat (input, "trace"))
9345         has_trace_option = 1;
9346       else if (unformat (input, "pot"))
9347         has_pot_option = 1;
9348       else if (unformat (input, "seqno"))
9349         has_seqno_option = 1;
9350       else if (unformat (input, "analyse"))
9351         has_analyse_option = 1;
9352       else
9353         break;
9354     }
9355   M (IOAM_ENABLE, mp);
9356   mp->id = htons (id);
9357   mp->seqno = has_seqno_option;
9358   mp->analyse = has_analyse_option;
9359   mp->pot_enable = has_pot_option;
9360   mp->trace_enable = has_trace_option;
9361
9362   S (mp);
9363   W (ret);
9364   return ret;
9365 }
9366
9367
9368 static int
9369 api_ioam_disable (vat_main_t * vam)
9370 {
9371   vl_api_ioam_disable_t *mp;
9372   int ret;
9373
9374   M (IOAM_DISABLE, mp);
9375   S (mp);
9376   W (ret);
9377   return ret;
9378 }
9379
9380 #define foreach_tcp_proto_field                 \
9381 _(src_port)                                     \
9382 _(dst_port)
9383
9384 #define foreach_udp_proto_field                 \
9385 _(src_port)                                     \
9386 _(dst_port)
9387
9388 #define foreach_ip4_proto_field                 \
9389 _(src_address)                                  \
9390 _(dst_address)                                  \
9391 _(tos)                                          \
9392 _(length)                                       \
9393 _(fragment_id)                                  \
9394 _(ttl)                                          \
9395 _(protocol)                                     \
9396 _(checksum)
9397
9398 typedef struct
9399 {
9400   u16 src_port, dst_port;
9401 } tcpudp_header_t;
9402
9403 #if VPP_API_TEST_BUILTIN == 0
9404 uword
9405 unformat_tcp_mask (unformat_input_t * input, va_list * args)
9406 {
9407   u8 **maskp = va_arg (*args, u8 **);
9408   u8 *mask = 0;
9409   u8 found_something = 0;
9410   tcp_header_t *tcp;
9411
9412 #define _(a) u8 a=0;
9413   foreach_tcp_proto_field;
9414 #undef _
9415
9416   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9417     {
9418       if (0);
9419 #define _(a) else if (unformat (input, #a)) a=1;
9420       foreach_tcp_proto_field
9421 #undef _
9422         else
9423         break;
9424     }
9425
9426 #define _(a) found_something += a;
9427   foreach_tcp_proto_field;
9428 #undef _
9429
9430   if (found_something == 0)
9431     return 0;
9432
9433   vec_validate (mask, sizeof (*tcp) - 1);
9434
9435   tcp = (tcp_header_t *) mask;
9436
9437 #define _(a) if (a) clib_memset (&tcp->a, 0xff, sizeof (tcp->a));
9438   foreach_tcp_proto_field;
9439 #undef _
9440
9441   *maskp = mask;
9442   return 1;
9443 }
9444
9445 uword
9446 unformat_udp_mask (unformat_input_t * input, va_list * args)
9447 {
9448   u8 **maskp = va_arg (*args, u8 **);
9449   u8 *mask = 0;
9450   u8 found_something = 0;
9451   udp_header_t *udp;
9452
9453 #define _(a) u8 a=0;
9454   foreach_udp_proto_field;
9455 #undef _
9456
9457   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9458     {
9459       if (0);
9460 #define _(a) else if (unformat (input, #a)) a=1;
9461       foreach_udp_proto_field
9462 #undef _
9463         else
9464         break;
9465     }
9466
9467 #define _(a) found_something += a;
9468   foreach_udp_proto_field;
9469 #undef _
9470
9471   if (found_something == 0)
9472     return 0;
9473
9474   vec_validate (mask, sizeof (*udp) - 1);
9475
9476   udp = (udp_header_t *) mask;
9477
9478 #define _(a) if (a) clib_memset (&udp->a, 0xff, sizeof (udp->a));
9479   foreach_udp_proto_field;
9480 #undef _
9481
9482   *maskp = mask;
9483   return 1;
9484 }
9485
9486 uword
9487 unformat_l4_mask (unformat_input_t * input, va_list * args)
9488 {
9489   u8 **maskp = va_arg (*args, u8 **);
9490   u16 src_port = 0, dst_port = 0;
9491   tcpudp_header_t *tcpudp;
9492
9493   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9494     {
9495       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
9496         return 1;
9497       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
9498         return 1;
9499       else if (unformat (input, "src_port"))
9500         src_port = 0xFFFF;
9501       else if (unformat (input, "dst_port"))
9502         dst_port = 0xFFFF;
9503       else
9504         return 0;
9505     }
9506
9507   if (!src_port && !dst_port)
9508     return 0;
9509
9510   u8 *mask = 0;
9511   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
9512
9513   tcpudp = (tcpudp_header_t *) mask;
9514   tcpudp->src_port = src_port;
9515   tcpudp->dst_port = dst_port;
9516
9517   *maskp = mask;
9518
9519   return 1;
9520 }
9521
9522 uword
9523 unformat_ip4_mask (unformat_input_t * input, va_list * args)
9524 {
9525   u8 **maskp = va_arg (*args, u8 **);
9526   u8 *mask = 0;
9527   u8 found_something = 0;
9528   ip4_header_t *ip;
9529
9530 #define _(a) u8 a=0;
9531   foreach_ip4_proto_field;
9532 #undef _
9533   u8 version = 0;
9534   u8 hdr_length = 0;
9535
9536
9537   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9538     {
9539       if (unformat (input, "version"))
9540         version = 1;
9541       else if (unformat (input, "hdr_length"))
9542         hdr_length = 1;
9543       else if (unformat (input, "src"))
9544         src_address = 1;
9545       else if (unformat (input, "dst"))
9546         dst_address = 1;
9547       else if (unformat (input, "proto"))
9548         protocol = 1;
9549
9550 #define _(a) else if (unformat (input, #a)) a=1;
9551       foreach_ip4_proto_field
9552 #undef _
9553         else
9554         break;
9555     }
9556
9557 #define _(a) found_something += a;
9558   foreach_ip4_proto_field;
9559 #undef _
9560
9561   if (found_something == 0)
9562     return 0;
9563
9564   vec_validate (mask, sizeof (*ip) - 1);
9565
9566   ip = (ip4_header_t *) mask;
9567
9568 #define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
9569   foreach_ip4_proto_field;
9570 #undef _
9571
9572   ip->ip_version_and_header_length = 0;
9573
9574   if (version)
9575     ip->ip_version_and_header_length |= 0xF0;
9576
9577   if (hdr_length)
9578     ip->ip_version_and_header_length |= 0x0F;
9579
9580   *maskp = mask;
9581   return 1;
9582 }
9583
9584 #define foreach_ip6_proto_field                 \
9585 _(src_address)                                  \
9586 _(dst_address)                                  \
9587 _(payload_length)                               \
9588 _(hop_limit)                                    \
9589 _(protocol)
9590
9591 uword
9592 unformat_ip6_mask (unformat_input_t * input, va_list * args)
9593 {
9594   u8 **maskp = va_arg (*args, u8 **);
9595   u8 *mask = 0;
9596   u8 found_something = 0;
9597   ip6_header_t *ip;
9598   u32 ip_version_traffic_class_and_flow_label;
9599
9600 #define _(a) u8 a=0;
9601   foreach_ip6_proto_field;
9602 #undef _
9603   u8 version = 0;
9604   u8 traffic_class = 0;
9605   u8 flow_label = 0;
9606
9607   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9608     {
9609       if (unformat (input, "version"))
9610         version = 1;
9611       else if (unformat (input, "traffic-class"))
9612         traffic_class = 1;
9613       else if (unformat (input, "flow-label"))
9614         flow_label = 1;
9615       else if (unformat (input, "src"))
9616         src_address = 1;
9617       else if (unformat (input, "dst"))
9618         dst_address = 1;
9619       else if (unformat (input, "proto"))
9620         protocol = 1;
9621
9622 #define _(a) else if (unformat (input, #a)) a=1;
9623       foreach_ip6_proto_field
9624 #undef _
9625         else
9626         break;
9627     }
9628
9629 #define _(a) found_something += a;
9630   foreach_ip6_proto_field;
9631 #undef _
9632
9633   if (found_something == 0)
9634     return 0;
9635
9636   vec_validate (mask, sizeof (*ip) - 1);
9637
9638   ip = (ip6_header_t *) mask;
9639
9640 #define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
9641   foreach_ip6_proto_field;
9642 #undef _
9643
9644   ip_version_traffic_class_and_flow_label = 0;
9645
9646   if (version)
9647     ip_version_traffic_class_and_flow_label |= 0xF0000000;
9648
9649   if (traffic_class)
9650     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
9651
9652   if (flow_label)
9653     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
9654
9655   ip->ip_version_traffic_class_and_flow_label =
9656     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
9657
9658   *maskp = mask;
9659   return 1;
9660 }
9661
9662 uword
9663 unformat_l3_mask (unformat_input_t * input, va_list * args)
9664 {
9665   u8 **maskp = va_arg (*args, u8 **);
9666
9667   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9668     {
9669       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
9670         return 1;
9671       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
9672         return 1;
9673       else
9674         break;
9675     }
9676   return 0;
9677 }
9678
9679 uword
9680 unformat_l2_mask (unformat_input_t * input, va_list * args)
9681 {
9682   u8 **maskp = va_arg (*args, u8 **);
9683   u8 *mask = 0;
9684   u8 src = 0;
9685   u8 dst = 0;
9686   u8 proto = 0;
9687   u8 tag1 = 0;
9688   u8 tag2 = 0;
9689   u8 ignore_tag1 = 0;
9690   u8 ignore_tag2 = 0;
9691   u8 cos1 = 0;
9692   u8 cos2 = 0;
9693   u8 dot1q = 0;
9694   u8 dot1ad = 0;
9695   int len = 14;
9696
9697   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9698     {
9699       if (unformat (input, "src"))
9700         src = 1;
9701       else if (unformat (input, "dst"))
9702         dst = 1;
9703       else if (unformat (input, "proto"))
9704         proto = 1;
9705       else if (unformat (input, "tag1"))
9706         tag1 = 1;
9707       else if (unformat (input, "tag2"))
9708         tag2 = 1;
9709       else if (unformat (input, "ignore-tag1"))
9710         ignore_tag1 = 1;
9711       else if (unformat (input, "ignore-tag2"))
9712         ignore_tag2 = 1;
9713       else if (unformat (input, "cos1"))
9714         cos1 = 1;
9715       else if (unformat (input, "cos2"))
9716         cos2 = 1;
9717       else if (unformat (input, "dot1q"))
9718         dot1q = 1;
9719       else if (unformat (input, "dot1ad"))
9720         dot1ad = 1;
9721       else
9722         break;
9723     }
9724   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
9725        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
9726     return 0;
9727
9728   if (tag1 || ignore_tag1 || cos1 || dot1q)
9729     len = 18;
9730   if (tag2 || ignore_tag2 || cos2 || dot1ad)
9731     len = 22;
9732
9733   vec_validate (mask, len - 1);
9734
9735   if (dst)
9736     clib_memset (mask, 0xff, 6);
9737
9738   if (src)
9739     clib_memset (mask + 6, 0xff, 6);
9740
9741   if (tag2 || dot1ad)
9742     {
9743       /* inner vlan tag */
9744       if (tag2)
9745         {
9746           mask[19] = 0xff;
9747           mask[18] = 0x0f;
9748         }
9749       if (cos2)
9750         mask[18] |= 0xe0;
9751       if (proto)
9752         mask[21] = mask[20] = 0xff;
9753       if (tag1)
9754         {
9755           mask[15] = 0xff;
9756           mask[14] = 0x0f;
9757         }
9758       if (cos1)
9759         mask[14] |= 0xe0;
9760       *maskp = mask;
9761       return 1;
9762     }
9763   if (tag1 | dot1q)
9764     {
9765       if (tag1)
9766         {
9767           mask[15] = 0xff;
9768           mask[14] = 0x0f;
9769         }
9770       if (cos1)
9771         mask[14] |= 0xe0;
9772       if (proto)
9773         mask[16] = mask[17] = 0xff;
9774
9775       *maskp = mask;
9776       return 1;
9777     }
9778   if (cos2)
9779     mask[18] |= 0xe0;
9780   if (cos1)
9781     mask[14] |= 0xe0;
9782   if (proto)
9783     mask[12] = mask[13] = 0xff;
9784
9785   *maskp = mask;
9786   return 1;
9787 }
9788
9789 uword
9790 unformat_classify_mask (unformat_input_t * input, va_list * args)
9791 {
9792   u8 **maskp = va_arg (*args, u8 **);
9793   u32 *skipp = va_arg (*args, u32 *);
9794   u32 *matchp = va_arg (*args, u32 *);
9795   u32 match;
9796   u8 *mask = 0;
9797   u8 *l2 = 0;
9798   u8 *l3 = 0;
9799   u8 *l4 = 0;
9800   int i;
9801
9802   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9803     {
9804       if (unformat (input, "hex %U", unformat_hex_string, &mask))
9805         ;
9806       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
9807         ;
9808       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
9809         ;
9810       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
9811         ;
9812       else
9813         break;
9814     }
9815
9816   if (l4 && !l3)
9817     {
9818       vec_free (mask);
9819       vec_free (l2);
9820       vec_free (l4);
9821       return 0;
9822     }
9823
9824   if (mask || l2 || l3 || l4)
9825     {
9826       if (l2 || l3 || l4)
9827         {
9828           /* "With a free Ethernet header in every package" */
9829           if (l2 == 0)
9830             vec_validate (l2, 13);
9831           mask = l2;
9832           if (vec_len (l3))
9833             {
9834               vec_append (mask, l3);
9835               vec_free (l3);
9836             }
9837           if (vec_len (l4))
9838             {
9839               vec_append (mask, l4);
9840               vec_free (l4);
9841             }
9842         }
9843
9844       /* Scan forward looking for the first significant mask octet */
9845       for (i = 0; i < vec_len (mask); i++)
9846         if (mask[i])
9847           break;
9848
9849       /* compute (skip, match) params */
9850       *skipp = i / sizeof (u32x4);
9851       vec_delete (mask, *skipp * sizeof (u32x4), 0);
9852
9853       /* Pad mask to an even multiple of the vector size */
9854       while (vec_len (mask) % sizeof (u32x4))
9855         vec_add1 (mask, 0);
9856
9857       match = vec_len (mask) / sizeof (u32x4);
9858
9859       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
9860         {
9861           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
9862           if (*tmp || *(tmp + 1))
9863             break;
9864           match--;
9865         }
9866       if (match == 0)
9867         clib_warning ("BUG: match 0");
9868
9869       _vec_len (mask) = match * sizeof (u32x4);
9870
9871       *matchp = match;
9872       *maskp = mask;
9873
9874       return 1;
9875     }
9876
9877   return 0;
9878 }
9879 #endif /* VPP_API_TEST_BUILTIN */
9880
9881 #define foreach_l2_next                         \
9882 _(drop, DROP)                                   \
9883 _(ethernet, ETHERNET_INPUT)                     \
9884 _(ip4, IP4_INPUT)                               \
9885 _(ip6, IP6_INPUT)
9886
9887 uword
9888 unformat_l2_next_index (unformat_input_t * input, va_list * args)
9889 {
9890   u32 *miss_next_indexp = va_arg (*args, u32 *);
9891   u32 next_index = 0;
9892   u32 tmp;
9893
9894 #define _(n,N) \
9895   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
9896   foreach_l2_next;
9897 #undef _
9898
9899   if (unformat (input, "%d", &tmp))
9900     {
9901       next_index = tmp;
9902       goto out;
9903     }
9904
9905   return 0;
9906
9907 out:
9908   *miss_next_indexp = next_index;
9909   return 1;
9910 }
9911
9912 #define foreach_ip_next                         \
9913 _(drop, DROP)                                   \
9914 _(local, LOCAL)                                 \
9915 _(rewrite, REWRITE)
9916
9917 uword
9918 api_unformat_ip_next_index (unformat_input_t * input, va_list * args)
9919 {
9920   u32 *miss_next_indexp = va_arg (*args, u32 *);
9921   u32 next_index = 0;
9922   u32 tmp;
9923
9924 #define _(n,N) \
9925   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
9926   foreach_ip_next;
9927 #undef _
9928
9929   if (unformat (input, "%d", &tmp))
9930     {
9931       next_index = tmp;
9932       goto out;
9933     }
9934
9935   return 0;
9936
9937 out:
9938   *miss_next_indexp = next_index;
9939   return 1;
9940 }
9941
9942 #define foreach_acl_next                        \
9943 _(deny, DENY)
9944
9945 uword
9946 api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
9947 {
9948   u32 *miss_next_indexp = va_arg (*args, u32 *);
9949   u32 next_index = 0;
9950   u32 tmp;
9951
9952 #define _(n,N) \
9953   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
9954   foreach_acl_next;
9955 #undef _
9956
9957   if (unformat (input, "permit"))
9958     {
9959       next_index = ~0;
9960       goto out;
9961     }
9962   else if (unformat (input, "%d", &tmp))
9963     {
9964       next_index = tmp;
9965       goto out;
9966     }
9967
9968   return 0;
9969
9970 out:
9971   *miss_next_indexp = next_index;
9972   return 1;
9973 }
9974
9975 uword
9976 unformat_policer_precolor (unformat_input_t * input, va_list * args)
9977 {
9978   u32 *r = va_arg (*args, u32 *);
9979
9980   if (unformat (input, "conform-color"))
9981     *r = POLICE_CONFORM;
9982   else if (unformat (input, "exceed-color"))
9983     *r = POLICE_EXCEED;
9984   else
9985     return 0;
9986
9987   return 1;
9988 }
9989
9990 static int
9991 api_classify_add_del_table (vat_main_t * vam)
9992 {
9993   unformat_input_t *i = vam->input;
9994   vl_api_classify_add_del_table_t *mp;
9995
9996   u32 nbuckets = 2;
9997   u32 skip = ~0;
9998   u32 match = ~0;
9999   int is_add = 1;
10000   int del_chain = 0;
10001   u32 table_index = ~0;
10002   u32 next_table_index = ~0;
10003   u32 miss_next_index = ~0;
10004   u32 memory_size = 32 << 20;
10005   u8 *mask = 0;
10006   u32 current_data_flag = 0;
10007   int current_data_offset = 0;
10008   int ret;
10009
10010   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10011     {
10012       if (unformat (i, "del"))
10013         is_add = 0;
10014       else if (unformat (i, "del-chain"))
10015         {
10016           is_add = 0;
10017           del_chain = 1;
10018         }
10019       else if (unformat (i, "buckets %d", &nbuckets))
10020         ;
10021       else if (unformat (i, "memory_size %d", &memory_size))
10022         ;
10023       else if (unformat (i, "skip %d", &skip))
10024         ;
10025       else if (unformat (i, "match %d", &match))
10026         ;
10027       else if (unformat (i, "table %d", &table_index))
10028         ;
10029       else if (unformat (i, "mask %U", unformat_classify_mask,
10030                          &mask, &skip, &match))
10031         ;
10032       else if (unformat (i, "next-table %d", &next_table_index))
10033         ;
10034       else if (unformat (i, "miss-next %U", api_unformat_ip_next_index,
10035                          &miss_next_index))
10036         ;
10037       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
10038                          &miss_next_index))
10039         ;
10040       else if (unformat (i, "acl-miss-next %U", api_unformat_acl_next_index,
10041                          &miss_next_index))
10042         ;
10043       else if (unformat (i, "current-data-flag %d", &current_data_flag))
10044         ;
10045       else if (unformat (i, "current-data-offset %d", &current_data_offset))
10046         ;
10047       else
10048         break;
10049     }
10050
10051   if (is_add && mask == 0)
10052     {
10053       errmsg ("Mask required");
10054       return -99;
10055     }
10056
10057   if (is_add && skip == ~0)
10058     {
10059       errmsg ("skip count required");
10060       return -99;
10061     }
10062
10063   if (is_add && match == ~0)
10064     {
10065       errmsg ("match count required");
10066       return -99;
10067     }
10068
10069   if (!is_add && table_index == ~0)
10070     {
10071       errmsg ("table index required for delete");
10072       return -99;
10073     }
10074
10075   M2 (CLASSIFY_ADD_DEL_TABLE, mp, vec_len (mask));
10076
10077   mp->is_add = is_add;
10078   mp->del_chain = del_chain;
10079   mp->table_index = ntohl (table_index);
10080   mp->nbuckets = ntohl (nbuckets);
10081   mp->memory_size = ntohl (memory_size);
10082   mp->skip_n_vectors = ntohl (skip);
10083   mp->match_n_vectors = ntohl (match);
10084   mp->next_table_index = ntohl (next_table_index);
10085   mp->miss_next_index = ntohl (miss_next_index);
10086   mp->current_data_flag = ntohl (current_data_flag);
10087   mp->current_data_offset = ntohl (current_data_offset);
10088   mp->mask_len = ntohl (vec_len (mask));
10089   clib_memcpy (mp->mask, mask, vec_len (mask));
10090
10091   vec_free (mask);
10092
10093   S (mp);
10094   W (ret);
10095   return ret;
10096 }
10097
10098 #if VPP_API_TEST_BUILTIN == 0
10099 uword
10100 unformat_l4_match (unformat_input_t * input, va_list * args)
10101 {
10102   u8 **matchp = va_arg (*args, u8 **);
10103
10104   u8 *proto_header = 0;
10105   int src_port = 0;
10106   int dst_port = 0;
10107
10108   tcpudp_header_t h;
10109
10110   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10111     {
10112       if (unformat (input, "src_port %d", &src_port))
10113         ;
10114       else if (unformat (input, "dst_port %d", &dst_port))
10115         ;
10116       else
10117         return 0;
10118     }
10119
10120   h.src_port = clib_host_to_net_u16 (src_port);
10121   h.dst_port = clib_host_to_net_u16 (dst_port);
10122   vec_validate (proto_header, sizeof (h) - 1);
10123   memcpy (proto_header, &h, sizeof (h));
10124
10125   *matchp = proto_header;
10126
10127   return 1;
10128 }
10129
10130 uword
10131 unformat_ip4_match (unformat_input_t * input, va_list * args)
10132 {
10133   u8 **matchp = va_arg (*args, u8 **);
10134   u8 *match = 0;
10135   ip4_header_t *ip;
10136   int version = 0;
10137   u32 version_val;
10138   int hdr_length = 0;
10139   u32 hdr_length_val;
10140   int src = 0, dst = 0;
10141   ip4_address_t src_val, dst_val;
10142   int proto = 0;
10143   u32 proto_val;
10144   int tos = 0;
10145   u32 tos_val;
10146   int length = 0;
10147   u32 length_val;
10148   int fragment_id = 0;
10149   u32 fragment_id_val;
10150   int ttl = 0;
10151   int ttl_val;
10152   int checksum = 0;
10153   u32 checksum_val;
10154
10155   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10156     {
10157       if (unformat (input, "version %d", &version_val))
10158         version = 1;
10159       else if (unformat (input, "hdr_length %d", &hdr_length_val))
10160         hdr_length = 1;
10161       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
10162         src = 1;
10163       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
10164         dst = 1;
10165       else if (unformat (input, "proto %d", &proto_val))
10166         proto = 1;
10167       else if (unformat (input, "tos %d", &tos_val))
10168         tos = 1;
10169       else if (unformat (input, "length %d", &length_val))
10170         length = 1;
10171       else if (unformat (input, "fragment_id %d", &fragment_id_val))
10172         fragment_id = 1;
10173       else if (unformat (input, "ttl %d", &ttl_val))
10174         ttl = 1;
10175       else if (unformat (input, "checksum %d", &checksum_val))
10176         checksum = 1;
10177       else
10178         break;
10179     }
10180
10181   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
10182       + ttl + checksum == 0)
10183     return 0;
10184
10185   /*
10186    * Aligned because we use the real comparison functions
10187    */
10188   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
10189
10190   ip = (ip4_header_t *) match;
10191
10192   /* These are realistically matched in practice */
10193   if (src)
10194     ip->src_address.as_u32 = src_val.as_u32;
10195
10196   if (dst)
10197     ip->dst_address.as_u32 = dst_val.as_u32;
10198
10199   if (proto)
10200     ip->protocol = proto_val;
10201
10202
10203   /* These are not, but they're included for completeness */
10204   if (version)
10205     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
10206
10207   if (hdr_length)
10208     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
10209
10210   if (tos)
10211     ip->tos = tos_val;
10212
10213   if (length)
10214     ip->length = clib_host_to_net_u16 (length_val);
10215
10216   if (ttl)
10217     ip->ttl = ttl_val;
10218
10219   if (checksum)
10220     ip->checksum = clib_host_to_net_u16 (checksum_val);
10221
10222   *matchp = match;
10223   return 1;
10224 }
10225
10226 uword
10227 unformat_ip6_match (unformat_input_t * input, va_list * args)
10228 {
10229   u8 **matchp = va_arg (*args, u8 **);
10230   u8 *match = 0;
10231   ip6_header_t *ip;
10232   int version = 0;
10233   u32 version_val;
10234   u8 traffic_class = 0;
10235   u32 traffic_class_val = 0;
10236   u8 flow_label = 0;
10237   u8 flow_label_val;
10238   int src = 0, dst = 0;
10239   ip6_address_t src_val, dst_val;
10240   int proto = 0;
10241   u32 proto_val;
10242   int payload_length = 0;
10243   u32 payload_length_val;
10244   int hop_limit = 0;
10245   int hop_limit_val;
10246   u32 ip_version_traffic_class_and_flow_label;
10247
10248   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10249     {
10250       if (unformat (input, "version %d", &version_val))
10251         version = 1;
10252       else if (unformat (input, "traffic_class %d", &traffic_class_val))
10253         traffic_class = 1;
10254       else if (unformat (input, "flow_label %d", &flow_label_val))
10255         flow_label = 1;
10256       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
10257         src = 1;
10258       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
10259         dst = 1;
10260       else if (unformat (input, "proto %d", &proto_val))
10261         proto = 1;
10262       else if (unformat (input, "payload_length %d", &payload_length_val))
10263         payload_length = 1;
10264       else if (unformat (input, "hop_limit %d", &hop_limit_val))
10265         hop_limit = 1;
10266       else
10267         break;
10268     }
10269
10270   if (version + traffic_class + flow_label + src + dst + proto +
10271       payload_length + hop_limit == 0)
10272     return 0;
10273
10274   /*
10275    * Aligned because we use the real comparison functions
10276    */
10277   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
10278
10279   ip = (ip6_header_t *) match;
10280
10281   if (src)
10282     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
10283
10284   if (dst)
10285     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
10286
10287   if (proto)
10288     ip->protocol = proto_val;
10289
10290   ip_version_traffic_class_and_flow_label = 0;
10291
10292   if (version)
10293     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
10294
10295   if (traffic_class)
10296     ip_version_traffic_class_and_flow_label |=
10297       (traffic_class_val & 0xFF) << 20;
10298
10299   if (flow_label)
10300     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
10301
10302   ip->ip_version_traffic_class_and_flow_label =
10303     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
10304
10305   if (payload_length)
10306     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
10307
10308   if (hop_limit)
10309     ip->hop_limit = hop_limit_val;
10310
10311   *matchp = match;
10312   return 1;
10313 }
10314
10315 uword
10316 unformat_l3_match (unformat_input_t * input, va_list * args)
10317 {
10318   u8 **matchp = va_arg (*args, u8 **);
10319
10320   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10321     {
10322       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
10323         return 1;
10324       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
10325         return 1;
10326       else
10327         break;
10328     }
10329   return 0;
10330 }
10331
10332 uword
10333 unformat_vlan_tag (unformat_input_t * input, va_list * args)
10334 {
10335   u8 *tagp = va_arg (*args, u8 *);
10336   u32 tag;
10337
10338   if (unformat (input, "%d", &tag))
10339     {
10340       tagp[0] = (tag >> 8) & 0x0F;
10341       tagp[1] = tag & 0xFF;
10342       return 1;
10343     }
10344
10345   return 0;
10346 }
10347
10348 uword
10349 unformat_l2_match (unformat_input_t * input, va_list * args)
10350 {
10351   u8 **matchp = va_arg (*args, u8 **);
10352   u8 *match = 0;
10353   u8 src = 0;
10354   u8 src_val[6];
10355   u8 dst = 0;
10356   u8 dst_val[6];
10357   u8 proto = 0;
10358   u16 proto_val;
10359   u8 tag1 = 0;
10360   u8 tag1_val[2];
10361   u8 tag2 = 0;
10362   u8 tag2_val[2];
10363   int len = 14;
10364   u8 ignore_tag1 = 0;
10365   u8 ignore_tag2 = 0;
10366   u8 cos1 = 0;
10367   u8 cos2 = 0;
10368   u32 cos1_val = 0;
10369   u32 cos2_val = 0;
10370
10371   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10372     {
10373       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
10374         src = 1;
10375       else
10376         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
10377         dst = 1;
10378       else if (unformat (input, "proto %U",
10379                          unformat_ethernet_type_host_byte_order, &proto_val))
10380         proto = 1;
10381       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
10382         tag1 = 1;
10383       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
10384         tag2 = 1;
10385       else if (unformat (input, "ignore-tag1"))
10386         ignore_tag1 = 1;
10387       else if (unformat (input, "ignore-tag2"))
10388         ignore_tag2 = 1;
10389       else if (unformat (input, "cos1 %d", &cos1_val))
10390         cos1 = 1;
10391       else if (unformat (input, "cos2 %d", &cos2_val))
10392         cos2 = 1;
10393       else
10394         break;
10395     }
10396   if ((src + dst + proto + tag1 + tag2 +
10397        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
10398     return 0;
10399
10400   if (tag1 || ignore_tag1 || cos1)
10401     len = 18;
10402   if (tag2 || ignore_tag2 || cos2)
10403     len = 22;
10404
10405   vec_validate_aligned (match, len - 1, sizeof (u32x4));
10406
10407   if (dst)
10408     clib_memcpy (match, dst_val, 6);
10409
10410   if (src)
10411     clib_memcpy (match + 6, src_val, 6);
10412
10413   if (tag2)
10414     {
10415       /* inner vlan tag */
10416       match[19] = tag2_val[1];
10417       match[18] = tag2_val[0];
10418       if (cos2)
10419         match[18] |= (cos2_val & 0x7) << 5;
10420       if (proto)
10421         {
10422           match[21] = proto_val & 0xff;
10423           match[20] = proto_val >> 8;
10424         }
10425       if (tag1)
10426         {
10427           match[15] = tag1_val[1];
10428           match[14] = tag1_val[0];
10429         }
10430       if (cos1)
10431         match[14] |= (cos1_val & 0x7) << 5;
10432       *matchp = match;
10433       return 1;
10434     }
10435   if (tag1)
10436     {
10437       match[15] = tag1_val[1];
10438       match[14] = tag1_val[0];
10439       if (proto)
10440         {
10441           match[17] = proto_val & 0xff;
10442           match[16] = proto_val >> 8;
10443         }
10444       if (cos1)
10445         match[14] |= (cos1_val & 0x7) << 5;
10446
10447       *matchp = match;
10448       return 1;
10449     }
10450   if (cos2)
10451     match[18] |= (cos2_val & 0x7) << 5;
10452   if (cos1)
10453     match[14] |= (cos1_val & 0x7) << 5;
10454   if (proto)
10455     {
10456       match[13] = proto_val & 0xff;
10457       match[12] = proto_val >> 8;
10458     }
10459
10460   *matchp = match;
10461   return 1;
10462 }
10463
10464 uword
10465 unformat_qos_source (unformat_input_t * input, va_list * args)
10466 {
10467   int *qs = va_arg (*args, int *);
10468
10469   if (unformat (input, "ip"))
10470     *qs = QOS_SOURCE_IP;
10471   else if (unformat (input, "mpls"))
10472     *qs = QOS_SOURCE_MPLS;
10473   else if (unformat (input, "ext"))
10474     *qs = QOS_SOURCE_EXT;
10475   else if (unformat (input, "vlan"))
10476     *qs = QOS_SOURCE_VLAN;
10477   else
10478     return 0;
10479
10480   return 1;
10481 }
10482 #endif
10483
10484 uword
10485 api_unformat_classify_match (unformat_input_t * input, va_list * args)
10486 {
10487   u8 **matchp = va_arg (*args, u8 **);
10488   u32 skip_n_vectors = va_arg (*args, u32);
10489   u32 match_n_vectors = va_arg (*args, u32);
10490
10491   u8 *match = 0;
10492   u8 *l2 = 0;
10493   u8 *l3 = 0;
10494   u8 *l4 = 0;
10495
10496   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10497     {
10498       if (unformat (input, "hex %U", unformat_hex_string, &match))
10499         ;
10500       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
10501         ;
10502       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
10503         ;
10504       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
10505         ;
10506       else
10507         break;
10508     }
10509
10510   if (l4 && !l3)
10511     {
10512       vec_free (match);
10513       vec_free (l2);
10514       vec_free (l4);
10515       return 0;
10516     }
10517
10518   if (match || l2 || l3 || l4)
10519     {
10520       if (l2 || l3 || l4)
10521         {
10522           /* "Win a free Ethernet header in every packet" */
10523           if (l2 == 0)
10524             vec_validate_aligned (l2, 13, sizeof (u32x4));
10525           match = l2;
10526           if (vec_len (l3))
10527             {
10528               vec_append_aligned (match, l3, sizeof (u32x4));
10529               vec_free (l3);
10530             }
10531           if (vec_len (l4))
10532             {
10533               vec_append_aligned (match, l4, sizeof (u32x4));
10534               vec_free (l4);
10535             }
10536         }
10537
10538       /* Make sure the vector is big enough even if key is all 0's */
10539       vec_validate_aligned
10540         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
10541          sizeof (u32x4));
10542
10543       /* Set size, include skipped vectors */
10544       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
10545
10546       *matchp = match;
10547
10548       return 1;
10549     }
10550
10551   return 0;
10552 }
10553
10554 static int
10555 api_classify_add_del_session (vat_main_t * vam)
10556 {
10557   unformat_input_t *i = vam->input;
10558   vl_api_classify_add_del_session_t *mp;
10559   int is_add = 1;
10560   u32 table_index = ~0;
10561   u32 hit_next_index = ~0;
10562   u32 opaque_index = ~0;
10563   u8 *match = 0;
10564   i32 advance = 0;
10565   u32 skip_n_vectors = 0;
10566   u32 match_n_vectors = 0;
10567   u32 action = 0;
10568   u32 metadata = 0;
10569   int ret;
10570
10571   /*
10572    * Warning: you have to supply skip_n and match_n
10573    * because the API client cant simply look at the classify
10574    * table object.
10575    */
10576
10577   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10578     {
10579       if (unformat (i, "del"))
10580         is_add = 0;
10581       else if (unformat (i, "hit-next %U", api_unformat_ip_next_index,
10582                          &hit_next_index))
10583         ;
10584       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
10585                          &hit_next_index))
10586         ;
10587       else if (unformat (i, "acl-hit-next %U", api_unformat_acl_next_index,
10588                          &hit_next_index))
10589         ;
10590       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
10591         ;
10592       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
10593         ;
10594       else if (unformat (i, "opaque-index %d", &opaque_index))
10595         ;
10596       else if (unformat (i, "skip_n %d", &skip_n_vectors))
10597         ;
10598       else if (unformat (i, "match_n %d", &match_n_vectors))
10599         ;
10600       else if (unformat (i, "match %U", api_unformat_classify_match,
10601                          &match, skip_n_vectors, match_n_vectors))
10602         ;
10603       else if (unformat (i, "advance %d", &advance))
10604         ;
10605       else if (unformat (i, "table-index %d", &table_index))
10606         ;
10607       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
10608         action = 1;
10609       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
10610         action = 2;
10611       else if (unformat (i, "action %d", &action))
10612         ;
10613       else if (unformat (i, "metadata %d", &metadata))
10614         ;
10615       else
10616         break;
10617     }
10618
10619   if (table_index == ~0)
10620     {
10621       errmsg ("Table index required");
10622       return -99;
10623     }
10624
10625   if (is_add && match == 0)
10626     {
10627       errmsg ("Match value required");
10628       return -99;
10629     }
10630
10631   M2 (CLASSIFY_ADD_DEL_SESSION, mp, vec_len (match));
10632
10633   mp->is_add = is_add;
10634   mp->table_index = ntohl (table_index);
10635   mp->hit_next_index = ntohl (hit_next_index);
10636   mp->opaque_index = ntohl (opaque_index);
10637   mp->advance = ntohl (advance);
10638   mp->action = action;
10639   mp->metadata = ntohl (metadata);
10640   mp->match_len = ntohl (vec_len (match));
10641   clib_memcpy (mp->match, match, vec_len (match));
10642   vec_free (match);
10643
10644   S (mp);
10645   W (ret);
10646   return ret;
10647 }
10648
10649 static int
10650 api_classify_set_interface_ip_table (vat_main_t * vam)
10651 {
10652   unformat_input_t *i = vam->input;
10653   vl_api_classify_set_interface_ip_table_t *mp;
10654   u32 sw_if_index;
10655   int sw_if_index_set;
10656   u32 table_index = ~0;
10657   u8 is_ipv6 = 0;
10658   int ret;
10659
10660   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10661     {
10662       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10663         sw_if_index_set = 1;
10664       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10665         sw_if_index_set = 1;
10666       else if (unformat (i, "table %d", &table_index))
10667         ;
10668       else
10669         {
10670           clib_warning ("parse error '%U'", format_unformat_error, i);
10671           return -99;
10672         }
10673     }
10674
10675   if (sw_if_index_set == 0)
10676     {
10677       errmsg ("missing interface name or sw_if_index");
10678       return -99;
10679     }
10680
10681
10682   M (CLASSIFY_SET_INTERFACE_IP_TABLE, mp);
10683
10684   mp->sw_if_index = ntohl (sw_if_index);
10685   mp->table_index = ntohl (table_index);
10686   mp->is_ipv6 = is_ipv6;
10687
10688   S (mp);
10689   W (ret);
10690   return ret;
10691 }
10692
10693 static int
10694 api_classify_set_interface_l2_tables (vat_main_t * vam)
10695 {
10696   unformat_input_t *i = vam->input;
10697   vl_api_classify_set_interface_l2_tables_t *mp;
10698   u32 sw_if_index;
10699   int sw_if_index_set;
10700   u32 ip4_table_index = ~0;
10701   u32 ip6_table_index = ~0;
10702   u32 other_table_index = ~0;
10703   u32 is_input = 1;
10704   int ret;
10705
10706   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10707     {
10708       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10709         sw_if_index_set = 1;
10710       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10711         sw_if_index_set = 1;
10712       else if (unformat (i, "ip4-table %d", &ip4_table_index))
10713         ;
10714       else if (unformat (i, "ip6-table %d", &ip6_table_index))
10715         ;
10716       else if (unformat (i, "other-table %d", &other_table_index))
10717         ;
10718       else if (unformat (i, "is-input %d", &is_input))
10719         ;
10720       else
10721         {
10722           clib_warning ("parse error '%U'", format_unformat_error, i);
10723           return -99;
10724         }
10725     }
10726
10727   if (sw_if_index_set == 0)
10728     {
10729       errmsg ("missing interface name or sw_if_index");
10730       return -99;
10731     }
10732
10733
10734   M (CLASSIFY_SET_INTERFACE_L2_TABLES, mp);
10735
10736   mp->sw_if_index = ntohl (sw_if_index);
10737   mp->ip4_table_index = ntohl (ip4_table_index);
10738   mp->ip6_table_index = ntohl (ip6_table_index);
10739   mp->other_table_index = ntohl (other_table_index);
10740   mp->is_input = (u8) is_input;
10741
10742   S (mp);
10743   W (ret);
10744   return ret;
10745 }
10746
10747 static int
10748 api_set_ipfix_exporter (vat_main_t * vam)
10749 {
10750   unformat_input_t *i = vam->input;
10751   vl_api_set_ipfix_exporter_t *mp;
10752   ip4_address_t collector_address;
10753   u8 collector_address_set = 0;
10754   u32 collector_port = ~0;
10755   ip4_address_t src_address;
10756   u8 src_address_set = 0;
10757   u32 vrf_id = ~0;
10758   u32 path_mtu = ~0;
10759   u32 template_interval = ~0;
10760   u8 udp_checksum = 0;
10761   int ret;
10762
10763   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10764     {
10765       if (unformat (i, "collector_address %U", unformat_ip4_address,
10766                     &collector_address))
10767         collector_address_set = 1;
10768       else if (unformat (i, "collector_port %d", &collector_port))
10769         ;
10770       else if (unformat (i, "src_address %U", unformat_ip4_address,
10771                          &src_address))
10772         src_address_set = 1;
10773       else if (unformat (i, "vrf_id %d", &vrf_id))
10774         ;
10775       else if (unformat (i, "path_mtu %d", &path_mtu))
10776         ;
10777       else if (unformat (i, "template_interval %d", &template_interval))
10778         ;
10779       else if (unformat (i, "udp_checksum"))
10780         udp_checksum = 1;
10781       else
10782         break;
10783     }
10784
10785   if (collector_address_set == 0)
10786     {
10787       errmsg ("collector_address required");
10788       return -99;
10789     }
10790
10791   if (src_address_set == 0)
10792     {
10793       errmsg ("src_address required");
10794       return -99;
10795     }
10796
10797   M (SET_IPFIX_EXPORTER, mp);
10798
10799   memcpy (mp->collector_address.un.ip4, collector_address.data,
10800           sizeof (collector_address.data));
10801   mp->collector_port = htons ((u16) collector_port);
10802   memcpy (mp->src_address.un.ip4, src_address.data,
10803           sizeof (src_address.data));
10804   mp->vrf_id = htonl (vrf_id);
10805   mp->path_mtu = htonl (path_mtu);
10806   mp->template_interval = htonl (template_interval);
10807   mp->udp_checksum = udp_checksum;
10808
10809   S (mp);
10810   W (ret);
10811   return ret;
10812 }
10813
10814 static int
10815 api_set_ipfix_classify_stream (vat_main_t * vam)
10816 {
10817   unformat_input_t *i = vam->input;
10818   vl_api_set_ipfix_classify_stream_t *mp;
10819   u32 domain_id = 0;
10820   u32 src_port = UDP_DST_PORT_ipfix;
10821   int ret;
10822
10823   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10824     {
10825       if (unformat (i, "domain %d", &domain_id))
10826         ;
10827       else if (unformat (i, "src_port %d", &src_port))
10828         ;
10829       else
10830         {
10831           errmsg ("unknown input `%U'", format_unformat_error, i);
10832           return -99;
10833         }
10834     }
10835
10836   M (SET_IPFIX_CLASSIFY_STREAM, mp);
10837
10838   mp->domain_id = htonl (domain_id);
10839   mp->src_port = htons ((u16) src_port);
10840
10841   S (mp);
10842   W (ret);
10843   return ret;
10844 }
10845
10846 static int
10847 api_ipfix_classify_table_add_del (vat_main_t * vam)
10848 {
10849   unformat_input_t *i = vam->input;
10850   vl_api_ipfix_classify_table_add_del_t *mp;
10851   int is_add = -1;
10852   u32 classify_table_index = ~0;
10853   u8 ip_version = 0;
10854   u8 transport_protocol = 255;
10855   int ret;
10856
10857   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10858     {
10859       if (unformat (i, "add"))
10860         is_add = 1;
10861       else if (unformat (i, "del"))
10862         is_add = 0;
10863       else if (unformat (i, "table %d", &classify_table_index))
10864         ;
10865       else if (unformat (i, "ip4"))
10866         ip_version = 4;
10867       else if (unformat (i, "ip6"))
10868         ip_version = 6;
10869       else if (unformat (i, "tcp"))
10870         transport_protocol = 6;
10871       else if (unformat (i, "udp"))
10872         transport_protocol = 17;
10873       else
10874         {
10875           errmsg ("unknown input `%U'", format_unformat_error, i);
10876           return -99;
10877         }
10878     }
10879
10880   if (is_add == -1)
10881     {
10882       errmsg ("expecting: add|del");
10883       return -99;
10884     }
10885   if (classify_table_index == ~0)
10886     {
10887       errmsg ("classifier table not specified");
10888       return -99;
10889     }
10890   if (ip_version == 0)
10891     {
10892       errmsg ("IP version not specified");
10893       return -99;
10894     }
10895
10896   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, mp);
10897
10898   mp->is_add = is_add;
10899   mp->table_id = htonl (classify_table_index);
10900   mp->ip_version = ip_version;
10901   mp->transport_protocol = transport_protocol;
10902
10903   S (mp);
10904   W (ret);
10905   return ret;
10906 }
10907
10908 static int
10909 api_get_node_index (vat_main_t * vam)
10910 {
10911   unformat_input_t *i = vam->input;
10912   vl_api_get_node_index_t *mp;
10913   u8 *name = 0;
10914   int ret;
10915
10916   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10917     {
10918       if (unformat (i, "node %s", &name))
10919         ;
10920       else
10921         break;
10922     }
10923   if (name == 0)
10924     {
10925       errmsg ("node name required");
10926       return -99;
10927     }
10928   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
10929     {
10930       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
10931       return -99;
10932     }
10933
10934   M (GET_NODE_INDEX, mp);
10935   clib_memcpy (mp->node_name, name, vec_len (name));
10936   vec_free (name);
10937
10938   S (mp);
10939   W (ret);
10940   return ret;
10941 }
10942
10943 static int
10944 api_get_next_index (vat_main_t * vam)
10945 {
10946   unformat_input_t *i = vam->input;
10947   vl_api_get_next_index_t *mp;
10948   u8 *node_name = 0, *next_node_name = 0;
10949   int ret;
10950
10951   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10952     {
10953       if (unformat (i, "node-name %s", &node_name))
10954         ;
10955       else if (unformat (i, "next-node-name %s", &next_node_name))
10956         break;
10957     }
10958
10959   if (node_name == 0)
10960     {
10961       errmsg ("node name required");
10962       return -99;
10963     }
10964   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
10965     {
10966       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
10967       return -99;
10968     }
10969
10970   if (next_node_name == 0)
10971     {
10972       errmsg ("next node name required");
10973       return -99;
10974     }
10975   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
10976     {
10977       errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
10978       return -99;
10979     }
10980
10981   M (GET_NEXT_INDEX, mp);
10982   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
10983   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
10984   vec_free (node_name);
10985   vec_free (next_node_name);
10986
10987   S (mp);
10988   W (ret);
10989   return ret;
10990 }
10991
10992 static int
10993 api_add_node_next (vat_main_t * vam)
10994 {
10995   unformat_input_t *i = vam->input;
10996   vl_api_add_node_next_t *mp;
10997   u8 *name = 0;
10998   u8 *next = 0;
10999   int ret;
11000
11001   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11002     {
11003       if (unformat (i, "node %s", &name))
11004         ;
11005       else if (unformat (i, "next %s", &next))
11006         ;
11007       else
11008         break;
11009     }
11010   if (name == 0)
11011     {
11012       errmsg ("node name required");
11013       return -99;
11014     }
11015   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
11016     {
11017       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11018       return -99;
11019     }
11020   if (next == 0)
11021     {
11022       errmsg ("next node required");
11023       return -99;
11024     }
11025   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
11026     {
11027       errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
11028       return -99;
11029     }
11030
11031   M (ADD_NODE_NEXT, mp);
11032   clib_memcpy (mp->node_name, name, vec_len (name));
11033   clib_memcpy (mp->next_name, next, vec_len (next));
11034   vec_free (name);
11035   vec_free (next);
11036
11037   S (mp);
11038   W (ret);
11039   return ret;
11040 }
11041
11042 static int
11043 api_l2tpv3_create_tunnel (vat_main_t * vam)
11044 {
11045   unformat_input_t *i = vam->input;
11046   ip6_address_t client_address, our_address;
11047   int client_address_set = 0;
11048   int our_address_set = 0;
11049   u32 local_session_id = 0;
11050   u32 remote_session_id = 0;
11051   u64 local_cookie = 0;
11052   u64 remote_cookie = 0;
11053   u8 l2_sublayer_present = 0;
11054   vl_api_l2tpv3_create_tunnel_t *mp;
11055   int ret;
11056
11057   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11058     {
11059       if (unformat (i, "client_address %U", unformat_ip6_address,
11060                     &client_address))
11061         client_address_set = 1;
11062       else if (unformat (i, "our_address %U", unformat_ip6_address,
11063                          &our_address))
11064         our_address_set = 1;
11065       else if (unformat (i, "local_session_id %d", &local_session_id))
11066         ;
11067       else if (unformat (i, "remote_session_id %d", &remote_session_id))
11068         ;
11069       else if (unformat (i, "local_cookie %lld", &local_cookie))
11070         ;
11071       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
11072         ;
11073       else if (unformat (i, "l2-sublayer-present"))
11074         l2_sublayer_present = 1;
11075       else
11076         break;
11077     }
11078
11079   if (client_address_set == 0)
11080     {
11081       errmsg ("client_address required");
11082       return -99;
11083     }
11084
11085   if (our_address_set == 0)
11086     {
11087       errmsg ("our_address required");
11088       return -99;
11089     }
11090
11091   M (L2TPV3_CREATE_TUNNEL, mp);
11092
11093   clib_memcpy (mp->client_address.un.ip6, client_address.as_u8,
11094                sizeof (ip6_address_t));
11095
11096   clib_memcpy (mp->our_address.un.ip6, our_address.as_u8,
11097                sizeof (ip6_address_t));
11098
11099   mp->local_session_id = ntohl (local_session_id);
11100   mp->remote_session_id = ntohl (remote_session_id);
11101   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
11102   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
11103   mp->l2_sublayer_present = l2_sublayer_present;
11104
11105   S (mp);
11106   W (ret);
11107   return ret;
11108 }
11109
11110 static int
11111 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
11112 {
11113   unformat_input_t *i = vam->input;
11114   u32 sw_if_index;
11115   u8 sw_if_index_set = 0;
11116   u64 new_local_cookie = 0;
11117   u64 new_remote_cookie = 0;
11118   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
11119   int ret;
11120
11121   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11122     {
11123       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11124         sw_if_index_set = 1;
11125       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11126         sw_if_index_set = 1;
11127       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
11128         ;
11129       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
11130         ;
11131       else
11132         break;
11133     }
11134
11135   if (sw_if_index_set == 0)
11136     {
11137       errmsg ("missing interface name or sw_if_index");
11138       return -99;
11139     }
11140
11141   M (L2TPV3_SET_TUNNEL_COOKIES, mp);
11142
11143   mp->sw_if_index = ntohl (sw_if_index);
11144   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
11145   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
11146
11147   S (mp);
11148   W (ret);
11149   return ret;
11150 }
11151
11152 static int
11153 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
11154 {
11155   unformat_input_t *i = vam->input;
11156   vl_api_l2tpv3_interface_enable_disable_t *mp;
11157   u32 sw_if_index;
11158   u8 sw_if_index_set = 0;
11159   u8 enable_disable = 1;
11160   int ret;
11161
11162   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11163     {
11164       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11165         sw_if_index_set = 1;
11166       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11167         sw_if_index_set = 1;
11168       else if (unformat (i, "enable"))
11169         enable_disable = 1;
11170       else if (unformat (i, "disable"))
11171         enable_disable = 0;
11172       else
11173         break;
11174     }
11175
11176   if (sw_if_index_set == 0)
11177     {
11178       errmsg ("missing interface name or sw_if_index");
11179       return -99;
11180     }
11181
11182   M (L2TPV3_INTERFACE_ENABLE_DISABLE, mp);
11183
11184   mp->sw_if_index = ntohl (sw_if_index);
11185   mp->enable_disable = enable_disable;
11186
11187   S (mp);
11188   W (ret);
11189   return ret;
11190 }
11191
11192 static int
11193 api_l2tpv3_set_lookup_key (vat_main_t * vam)
11194 {
11195   unformat_input_t *i = vam->input;
11196   vl_api_l2tpv3_set_lookup_key_t *mp;
11197   u8 key = ~0;
11198   int ret;
11199
11200   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11201     {
11202       if (unformat (i, "lookup_v6_src"))
11203         key = L2T_LOOKUP_SRC_ADDRESS;
11204       else if (unformat (i, "lookup_v6_dst"))
11205         key = L2T_LOOKUP_DST_ADDRESS;
11206       else if (unformat (i, "lookup_session_id"))
11207         key = L2T_LOOKUP_SESSION_ID;
11208       else
11209         break;
11210     }
11211
11212   if (key == (u8) ~ 0)
11213     {
11214       errmsg ("l2tp session lookup key unset");
11215       return -99;
11216     }
11217
11218   M (L2TPV3_SET_LOOKUP_KEY, mp);
11219
11220   mp->key = key;
11221
11222   S (mp);
11223   W (ret);
11224   return ret;
11225 }
11226
11227 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
11228   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
11229 {
11230   vat_main_t *vam = &vat_main;
11231
11232   print (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)",
11233          format_ip6_address, mp->our_address,
11234          format_ip6_address, mp->client_address,
11235          clib_net_to_host_u32 (mp->sw_if_index));
11236
11237   print (vam->ofp,
11238          "   local cookies %016llx %016llx remote cookie %016llx",
11239          clib_net_to_host_u64 (mp->local_cookie[0]),
11240          clib_net_to_host_u64 (mp->local_cookie[1]),
11241          clib_net_to_host_u64 (mp->remote_cookie));
11242
11243   print (vam->ofp, "   local session-id %d remote session-id %d",
11244          clib_net_to_host_u32 (mp->local_session_id),
11245          clib_net_to_host_u32 (mp->remote_session_id));
11246
11247   print (vam->ofp, "   l2 specific sublayer %s\n",
11248          mp->l2_sublayer_present ? "preset" : "absent");
11249
11250 }
11251
11252 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
11253   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
11254 {
11255   vat_main_t *vam = &vat_main;
11256   vat_json_node_t *node = NULL;
11257   struct in6_addr addr;
11258
11259   if (VAT_JSON_ARRAY != vam->json_tree.type)
11260     {
11261       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11262       vat_json_init_array (&vam->json_tree);
11263     }
11264   node = vat_json_array_add (&vam->json_tree);
11265
11266   vat_json_init_object (node);
11267
11268   clib_memcpy (&addr, mp->our_address.un.ip6, sizeof (addr));
11269   vat_json_object_add_ip6 (node, "our_address", addr);
11270   clib_memcpy (&addr, mp->client_address.un.ip6, sizeof (addr));
11271   vat_json_object_add_ip6 (node, "client_address", addr);
11272
11273   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
11274   vat_json_init_array (lc);
11275   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
11276   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
11277   vat_json_object_add_uint (node, "remote_cookie",
11278                             clib_net_to_host_u64 (mp->remote_cookie));
11279
11280   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
11281   vat_json_object_add_uint (node, "local_session_id",
11282                             clib_net_to_host_u32 (mp->local_session_id));
11283   vat_json_object_add_uint (node, "remote_session_id",
11284                             clib_net_to_host_u32 (mp->remote_session_id));
11285   vat_json_object_add_string_copy (node, "l2_sublayer",
11286                                    mp->l2_sublayer_present ? (u8 *) "present"
11287                                    : (u8 *) "absent");
11288 }
11289
11290 static int
11291 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
11292 {
11293   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
11294   vl_api_control_ping_t *mp_ping;
11295   int ret;
11296
11297   /* Get list of l2tpv3-tunnel interfaces */
11298   M (SW_IF_L2TPV3_TUNNEL_DUMP, mp);
11299   S (mp);
11300
11301   /* Use a control ping for synchronization */
11302   MPING (CONTROL_PING, mp_ping);
11303   S (mp_ping);
11304
11305   W (ret);
11306   return ret;
11307 }
11308
11309
11310 static void vl_api_sw_interface_tap_v2_details_t_handler
11311   (vl_api_sw_interface_tap_v2_details_t * mp)
11312 {
11313   vat_main_t *vam = &vat_main;
11314
11315   u8 *ip4 =
11316     format (0, "%U/%d", format_ip4_address, mp->host_ip4_prefix.address,
11317             mp->host_ip4_prefix.len);
11318   u8 *ip6 =
11319     format (0, "%U/%d", format_ip6_address, mp->host_ip6_prefix.address,
11320             mp->host_ip6_prefix.len);
11321
11322   print (vam->ofp,
11323          "\n%-16s %-12d %-5d %-12d %-12d %-14U %-30s %-20s %-20s %-30s 0x%-08x",
11324          mp->dev_name, ntohl (mp->sw_if_index), ntohl (mp->id),
11325          ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
11326          format_ethernet_address, mp->host_mac_addr, mp->host_namespace,
11327          mp->host_bridge, ip4, ip6, ntohl (mp->tap_flags));
11328
11329   vec_free (ip4);
11330   vec_free (ip6);
11331 }
11332
11333 static void vl_api_sw_interface_tap_v2_details_t_handler_json
11334   (vl_api_sw_interface_tap_v2_details_t * mp)
11335 {
11336   vat_main_t *vam = &vat_main;
11337   vat_json_node_t *node = NULL;
11338
11339   if (VAT_JSON_ARRAY != vam->json_tree.type)
11340     {
11341       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11342       vat_json_init_array (&vam->json_tree);
11343     }
11344   node = vat_json_array_add (&vam->json_tree);
11345
11346   vat_json_init_object (node);
11347   vat_json_object_add_uint (node, "id", ntohl (mp->id));
11348   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11349   vat_json_object_add_uint (node, "tap_flags", ntohl (mp->tap_flags));
11350   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
11351   vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
11352   vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
11353   vat_json_object_add_string_copy (node, "host_mac_addr",
11354                                    format (0, "%U", format_ethernet_address,
11355                                            &mp->host_mac_addr));
11356   vat_json_object_add_string_copy (node, "host_namespace",
11357                                    mp->host_namespace);
11358   vat_json_object_add_string_copy (node, "host_bridge", mp->host_bridge);
11359   vat_json_object_add_string_copy (node, "host_ip4_addr",
11360                                    format (0, "%U/%d", format_ip4_address,
11361                                            mp->host_ip4_prefix.address,
11362                                            mp->host_ip4_prefix.len));
11363   vat_json_object_add_string_copy (node, "host_ip6_prefix",
11364                                    format (0, "%U/%d", format_ip6_address,
11365                                            mp->host_ip6_prefix.address,
11366                                            mp->host_ip6_prefix.len));
11367
11368 }
11369
11370 static int
11371 api_sw_interface_tap_v2_dump (vat_main_t * vam)
11372 {
11373   vl_api_sw_interface_tap_v2_dump_t *mp;
11374   vl_api_control_ping_t *mp_ping;
11375   int ret;
11376
11377   print (vam->ofp,
11378          "\n%-16s %-12s %-5s %-12s %-12s %-14s %-30s %-20s %-20s %-30s",
11379          "dev_name", "sw_if_index", "id", "rx_ring_sz", "tx_ring_sz",
11380          "host_mac_addr", "host_namespace", "host_bridge", "host_ip4_addr",
11381          "host_ip6_addr");
11382
11383   /* Get list of tap interfaces */
11384   M (SW_INTERFACE_TAP_V2_DUMP, mp);
11385   S (mp);
11386
11387   /* Use a control ping for synchronization */
11388   MPING (CONTROL_PING, mp_ping);
11389   S (mp_ping);
11390
11391   W (ret);
11392   return ret;
11393 }
11394
11395 static void vl_api_sw_interface_virtio_pci_details_t_handler
11396   (vl_api_sw_interface_virtio_pci_details_t * mp)
11397 {
11398   vat_main_t *vam = &vat_main;
11399
11400   typedef union
11401   {
11402     struct
11403     {
11404       u16 domain;
11405       u8 bus;
11406       u8 slot:5;
11407       u8 function:3;
11408     };
11409     u32 as_u32;
11410   } pci_addr_t;
11411   pci_addr_t addr;
11412
11413   addr.domain = ntohs (mp->pci_addr.domain);
11414   addr.bus = mp->pci_addr.bus;
11415   addr.slot = mp->pci_addr.slot;
11416   addr.function = mp->pci_addr.function;
11417
11418   u8 *pci_addr = format (0, "%04x:%02x:%02x.%x", addr.domain, addr.bus,
11419                          addr.slot, addr.function);
11420
11421   print (vam->ofp,
11422          "\n%-12s %-12d %-12d %-12d %-17U 0x%-08llx",
11423          pci_addr, ntohl (mp->sw_if_index),
11424          ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
11425          format_ethernet_address, mp->mac_addr,
11426          clib_net_to_host_u64 (mp->features));
11427   vec_free (pci_addr);
11428 }
11429
11430 static void vl_api_sw_interface_virtio_pci_details_t_handler_json
11431   (vl_api_sw_interface_virtio_pci_details_t * mp)
11432 {
11433   vat_main_t *vam = &vat_main;
11434   vat_json_node_t *node = NULL;
11435   vlib_pci_addr_t pci_addr;
11436
11437   if (VAT_JSON_ARRAY != vam->json_tree.type)
11438     {
11439       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11440       vat_json_init_array (&vam->json_tree);
11441     }
11442   node = vat_json_array_add (&vam->json_tree);
11443
11444   pci_addr.domain = ntohs (mp->pci_addr.domain);
11445   pci_addr.bus = mp->pci_addr.bus;
11446   pci_addr.slot = mp->pci_addr.slot;
11447   pci_addr.function = mp->pci_addr.function;
11448
11449   vat_json_init_object (node);
11450   vat_json_object_add_uint (node, "pci-addr", pci_addr.as_u32);
11451   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11452   vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
11453   vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
11454   vat_json_object_add_uint (node, "features",
11455                             clib_net_to_host_u64 (mp->features));
11456   vat_json_object_add_string_copy (node, "mac_addr",
11457                                    format (0, "%U", format_ethernet_address,
11458                                            &mp->mac_addr));
11459 }
11460
11461 static int
11462 api_sw_interface_virtio_pci_dump (vat_main_t * vam)
11463 {
11464   vl_api_sw_interface_virtio_pci_dump_t *mp;
11465   vl_api_control_ping_t *mp_ping;
11466   int ret;
11467
11468   print (vam->ofp,
11469          "\n%-12s %-12s %-12s %-12s %-17s %-08s",
11470          "pci_addr", "sw_if_index", "rx_ring_sz", "tx_ring_sz",
11471          "mac_addr", "features");
11472
11473   /* Get list of tap interfaces */
11474   M (SW_INTERFACE_VIRTIO_PCI_DUMP, mp);
11475   S (mp);
11476
11477   /* Use a control ping for synchronization */
11478   MPING (CONTROL_PING, mp_ping);
11479   S (mp_ping);
11480
11481   W (ret);
11482   return ret;
11483 }
11484
11485 static int
11486 api_vxlan_offload_rx (vat_main_t * vam)
11487 {
11488   unformat_input_t *line_input = vam->input;
11489   vl_api_vxlan_offload_rx_t *mp;
11490   u32 hw_if_index = ~0, rx_if_index = ~0;
11491   u8 is_add = 1;
11492   int ret;
11493
11494   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11495     {
11496       if (unformat (line_input, "del"))
11497         is_add = 0;
11498       else if (unformat (line_input, "hw %U", api_unformat_hw_if_index, vam,
11499                          &hw_if_index))
11500         ;
11501       else if (unformat (line_input, "hw hw_if_index %u", &hw_if_index))
11502         ;
11503       else if (unformat (line_input, "rx %U", api_unformat_sw_if_index, vam,
11504                          &rx_if_index))
11505         ;
11506       else if (unformat (line_input, "rx sw_if_index %u", &rx_if_index))
11507         ;
11508       else
11509         {
11510           errmsg ("parse error '%U'", format_unformat_error, line_input);
11511           return -99;
11512         }
11513     }
11514
11515   if (hw_if_index == ~0)
11516     {
11517       errmsg ("no hw interface");
11518       return -99;
11519     }
11520
11521   if (rx_if_index == ~0)
11522     {
11523       errmsg ("no rx tunnel");
11524       return -99;
11525     }
11526
11527   M (VXLAN_OFFLOAD_RX, mp);
11528
11529   mp->hw_if_index = ntohl (hw_if_index);
11530   mp->sw_if_index = ntohl (rx_if_index);
11531   mp->enable = is_add;
11532
11533   S (mp);
11534   W (ret);
11535   return ret;
11536 }
11537
11538 static uword unformat_vxlan_decap_next
11539   (unformat_input_t * input, va_list * args)
11540 {
11541   u32 *result = va_arg (*args, u32 *);
11542   u32 tmp;
11543
11544   if (unformat (input, "l2"))
11545     *result = VXLAN_INPUT_NEXT_L2_INPUT;
11546   else if (unformat (input, "%d", &tmp))
11547     *result = tmp;
11548   else
11549     return 0;
11550   return 1;
11551 }
11552
11553 static int
11554 api_vxlan_add_del_tunnel (vat_main_t * vam)
11555 {
11556   unformat_input_t *line_input = vam->input;
11557   vl_api_vxlan_add_del_tunnel_t *mp;
11558   ip46_address_t src, dst;
11559   u8 is_add = 1;
11560   u8 ipv4_set = 0, ipv6_set = 0;
11561   u8 src_set = 0;
11562   u8 dst_set = 0;
11563   u8 grp_set = 0;
11564   u32 instance = ~0;
11565   u32 mcast_sw_if_index = ~0;
11566   u32 encap_vrf_id = 0;
11567   u32 decap_next_index = ~0;
11568   u32 vni = 0;
11569   int ret;
11570
11571   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
11572   clib_memset (&src, 0, sizeof src);
11573   clib_memset (&dst, 0, sizeof dst);
11574
11575   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11576     {
11577       if (unformat (line_input, "del"))
11578         is_add = 0;
11579       else if (unformat (line_input, "instance %d", &instance))
11580         ;
11581       else
11582         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
11583         {
11584           ipv4_set = 1;
11585           src_set = 1;
11586         }
11587       else
11588         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
11589         {
11590           ipv4_set = 1;
11591           dst_set = 1;
11592         }
11593       else
11594         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
11595         {
11596           ipv6_set = 1;
11597           src_set = 1;
11598         }
11599       else
11600         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
11601         {
11602           ipv6_set = 1;
11603           dst_set = 1;
11604         }
11605       else if (unformat (line_input, "group %U %U",
11606                          unformat_ip4_address, &dst.ip4,
11607                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
11608         {
11609           grp_set = dst_set = 1;
11610           ipv4_set = 1;
11611         }
11612       else if (unformat (line_input, "group %U",
11613                          unformat_ip4_address, &dst.ip4))
11614         {
11615           grp_set = dst_set = 1;
11616           ipv4_set = 1;
11617         }
11618       else if (unformat (line_input, "group %U %U",
11619                          unformat_ip6_address, &dst.ip6,
11620                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
11621         {
11622           grp_set = dst_set = 1;
11623           ipv6_set = 1;
11624         }
11625       else if (unformat (line_input, "group %U",
11626                          unformat_ip6_address, &dst.ip6))
11627         {
11628           grp_set = dst_set = 1;
11629           ipv6_set = 1;
11630         }
11631       else
11632         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
11633         ;
11634       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
11635         ;
11636       else if (unformat (line_input, "decap-next %U",
11637                          unformat_vxlan_decap_next, &decap_next_index))
11638         ;
11639       else if (unformat (line_input, "vni %d", &vni))
11640         ;
11641       else
11642         {
11643           errmsg ("parse error '%U'", format_unformat_error, line_input);
11644           return -99;
11645         }
11646     }
11647
11648   if (src_set == 0)
11649     {
11650       errmsg ("tunnel src address not specified");
11651       return -99;
11652     }
11653   if (dst_set == 0)
11654     {
11655       errmsg ("tunnel dst address not specified");
11656       return -99;
11657     }
11658
11659   if (grp_set && !ip46_address_is_multicast (&dst))
11660     {
11661       errmsg ("tunnel group address not multicast");
11662       return -99;
11663     }
11664   if (grp_set && mcast_sw_if_index == ~0)
11665     {
11666       errmsg ("tunnel nonexistent multicast device");
11667       return -99;
11668     }
11669   if (grp_set == 0 && ip46_address_is_multicast (&dst))
11670     {
11671       errmsg ("tunnel dst address must be unicast");
11672       return -99;
11673     }
11674
11675
11676   if (ipv4_set && ipv6_set)
11677     {
11678       errmsg ("both IPv4 and IPv6 addresses specified");
11679       return -99;
11680     }
11681
11682   if ((vni == 0) || (vni >> 24))
11683     {
11684       errmsg ("vni not specified or out of range");
11685       return -99;
11686     }
11687
11688   M (VXLAN_ADD_DEL_TUNNEL, mp);
11689
11690   if (ipv6_set)
11691     {
11692       clib_memcpy (mp->src_address, &src.ip6, sizeof (src.ip6));
11693       clib_memcpy (mp->dst_address, &dst.ip6, sizeof (dst.ip6));
11694     }
11695   else
11696     {
11697       clib_memcpy (mp->src_address, &src.ip4, sizeof (src.ip4));
11698       clib_memcpy (mp->dst_address, &dst.ip4, sizeof (dst.ip4));
11699     }
11700
11701   mp->instance = htonl (instance);
11702   mp->encap_vrf_id = ntohl (encap_vrf_id);
11703   mp->decap_next_index = ntohl (decap_next_index);
11704   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
11705   mp->vni = ntohl (vni);
11706   mp->is_add = is_add;
11707   mp->is_ipv6 = ipv6_set;
11708
11709   S (mp);
11710   W (ret);
11711   return ret;
11712 }
11713
11714 static void vl_api_vxlan_tunnel_details_t_handler
11715   (vl_api_vxlan_tunnel_details_t * mp)
11716 {
11717   vat_main_t *vam = &vat_main;
11718   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
11719   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
11720
11721   print (vam->ofp, "%11d%11d%24U%24U%14d%18d%13d%19d",
11722          ntohl (mp->sw_if_index),
11723          ntohl (mp->instance),
11724          format_ip46_address, &src, IP46_TYPE_ANY,
11725          format_ip46_address, &dst, IP46_TYPE_ANY,
11726          ntohl (mp->encap_vrf_id),
11727          ntohl (mp->decap_next_index), ntohl (mp->vni),
11728          ntohl (mp->mcast_sw_if_index));
11729 }
11730
11731 static void vl_api_vxlan_tunnel_details_t_handler_json
11732   (vl_api_vxlan_tunnel_details_t * mp)
11733 {
11734   vat_main_t *vam = &vat_main;
11735   vat_json_node_t *node = NULL;
11736
11737   if (VAT_JSON_ARRAY != vam->json_tree.type)
11738     {
11739       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11740       vat_json_init_array (&vam->json_tree);
11741     }
11742   node = vat_json_array_add (&vam->json_tree);
11743
11744   vat_json_init_object (node);
11745   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11746
11747   vat_json_object_add_uint (node, "instance", ntohl (mp->instance));
11748
11749   if (mp->is_ipv6)
11750     {
11751       struct in6_addr ip6;
11752
11753       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
11754       vat_json_object_add_ip6 (node, "src_address", ip6);
11755       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
11756       vat_json_object_add_ip6 (node, "dst_address", ip6);
11757     }
11758   else
11759     {
11760       struct in_addr ip4;
11761
11762       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
11763       vat_json_object_add_ip4 (node, "src_address", ip4);
11764       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
11765       vat_json_object_add_ip4 (node, "dst_address", ip4);
11766     }
11767   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
11768   vat_json_object_add_uint (node, "decap_next_index",
11769                             ntohl (mp->decap_next_index));
11770   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
11771   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
11772   vat_json_object_add_uint (node, "mcast_sw_if_index",
11773                             ntohl (mp->mcast_sw_if_index));
11774 }
11775
11776 static int
11777 api_vxlan_tunnel_dump (vat_main_t * vam)
11778 {
11779   unformat_input_t *i = vam->input;
11780   vl_api_vxlan_tunnel_dump_t *mp;
11781   vl_api_control_ping_t *mp_ping;
11782   u32 sw_if_index;
11783   u8 sw_if_index_set = 0;
11784   int ret;
11785
11786   /* Parse args required to build the message */
11787   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11788     {
11789       if (unformat (i, "sw_if_index %d", &sw_if_index))
11790         sw_if_index_set = 1;
11791       else
11792         break;
11793     }
11794
11795   if (sw_if_index_set == 0)
11796     {
11797       sw_if_index = ~0;
11798     }
11799
11800   if (!vam->json_output)
11801     {
11802       print (vam->ofp, "%11s%11s%24s%24s%14s%18s%13s%19s",
11803              "sw_if_index", "instance", "src_address", "dst_address",
11804              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
11805     }
11806
11807   /* Get list of vxlan-tunnel interfaces */
11808   M (VXLAN_TUNNEL_DUMP, mp);
11809
11810   mp->sw_if_index = htonl (sw_if_index);
11811
11812   S (mp);
11813
11814   /* Use a control ping for synchronization */
11815   MPING (CONTROL_PING, mp_ping);
11816   S (mp_ping);
11817
11818   W (ret);
11819   return ret;
11820 }
11821
11822 static uword unformat_geneve_decap_next
11823   (unformat_input_t * input, va_list * args)
11824 {
11825   u32 *result = va_arg (*args, u32 *);
11826   u32 tmp;
11827
11828   if (unformat (input, "l2"))
11829     *result = GENEVE_INPUT_NEXT_L2_INPUT;
11830   else if (unformat (input, "%d", &tmp))
11831     *result = tmp;
11832   else
11833     return 0;
11834   return 1;
11835 }
11836
11837 static int
11838 api_geneve_add_del_tunnel (vat_main_t * vam)
11839 {
11840   unformat_input_t *line_input = vam->input;
11841   vl_api_geneve_add_del_tunnel_t *mp;
11842   ip46_address_t src, dst;
11843   u8 is_add = 1;
11844   u8 ipv4_set = 0, ipv6_set = 0;
11845   u8 src_set = 0;
11846   u8 dst_set = 0;
11847   u8 grp_set = 0;
11848   u32 mcast_sw_if_index = ~0;
11849   u32 encap_vrf_id = 0;
11850   u32 decap_next_index = ~0;
11851   u32 vni = 0;
11852   int ret;
11853
11854   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
11855   clib_memset (&src, 0, sizeof src);
11856   clib_memset (&dst, 0, sizeof dst);
11857
11858   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11859     {
11860       if (unformat (line_input, "del"))
11861         is_add = 0;
11862       else
11863         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
11864         {
11865           ipv4_set = 1;
11866           src_set = 1;
11867         }
11868       else
11869         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
11870         {
11871           ipv4_set = 1;
11872           dst_set = 1;
11873         }
11874       else
11875         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
11876         {
11877           ipv6_set = 1;
11878           src_set = 1;
11879         }
11880       else
11881         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
11882         {
11883           ipv6_set = 1;
11884           dst_set = 1;
11885         }
11886       else if (unformat (line_input, "group %U %U",
11887                          unformat_ip4_address, &dst.ip4,
11888                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
11889         {
11890           grp_set = dst_set = 1;
11891           ipv4_set = 1;
11892         }
11893       else if (unformat (line_input, "group %U",
11894                          unformat_ip4_address, &dst.ip4))
11895         {
11896           grp_set = dst_set = 1;
11897           ipv4_set = 1;
11898         }
11899       else if (unformat (line_input, "group %U %U",
11900                          unformat_ip6_address, &dst.ip6,
11901                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
11902         {
11903           grp_set = dst_set = 1;
11904           ipv6_set = 1;
11905         }
11906       else if (unformat (line_input, "group %U",
11907                          unformat_ip6_address, &dst.ip6))
11908         {
11909           grp_set = dst_set = 1;
11910           ipv6_set = 1;
11911         }
11912       else
11913         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
11914         ;
11915       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
11916         ;
11917       else if (unformat (line_input, "decap-next %U",
11918                          unformat_geneve_decap_next, &decap_next_index))
11919         ;
11920       else if (unformat (line_input, "vni %d", &vni))
11921         ;
11922       else
11923         {
11924           errmsg ("parse error '%U'", format_unformat_error, line_input);
11925           return -99;
11926         }
11927     }
11928
11929   if (src_set == 0)
11930     {
11931       errmsg ("tunnel src address not specified");
11932       return -99;
11933     }
11934   if (dst_set == 0)
11935     {
11936       errmsg ("tunnel dst address not specified");
11937       return -99;
11938     }
11939
11940   if (grp_set && !ip46_address_is_multicast (&dst))
11941     {
11942       errmsg ("tunnel group address not multicast");
11943       return -99;
11944     }
11945   if (grp_set && mcast_sw_if_index == ~0)
11946     {
11947       errmsg ("tunnel nonexistent multicast device");
11948       return -99;
11949     }
11950   if (grp_set == 0 && ip46_address_is_multicast (&dst))
11951     {
11952       errmsg ("tunnel dst address must be unicast");
11953       return -99;
11954     }
11955
11956
11957   if (ipv4_set && ipv6_set)
11958     {
11959       errmsg ("both IPv4 and IPv6 addresses specified");
11960       return -99;
11961     }
11962
11963   if ((vni == 0) || (vni >> 24))
11964     {
11965       errmsg ("vni not specified or out of range");
11966       return -99;
11967     }
11968
11969   M (GENEVE_ADD_DEL_TUNNEL, mp);
11970
11971   if (ipv6_set)
11972     {
11973       clib_memcpy (&mp->local_address.un.ip6, &src.ip6, sizeof (src.ip6));
11974       clib_memcpy (&mp->remote_address.un.ip6, &dst.ip6, sizeof (dst.ip6));
11975     }
11976   else
11977     {
11978       clib_memcpy (&mp->local_address.un.ip4, &src.ip4, sizeof (src.ip4));
11979       clib_memcpy (&mp->remote_address.un.ip4, &dst.ip4, sizeof (dst.ip4));
11980     }
11981   mp->encap_vrf_id = ntohl (encap_vrf_id);
11982   mp->decap_next_index = ntohl (decap_next_index);
11983   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
11984   mp->vni = ntohl (vni);
11985   mp->is_add = is_add;
11986
11987   S (mp);
11988   W (ret);
11989   return ret;
11990 }
11991
11992 static void vl_api_geneve_tunnel_details_t_handler
11993   (vl_api_geneve_tunnel_details_t * mp)
11994 {
11995   vat_main_t *vam = &vat_main;
11996   ip46_address_t src = {.as_u64[0] = 0,.as_u64[1] = 0 };
11997   ip46_address_t dst = {.as_u64[0] = 0,.as_u64[1] = 0 };
11998
11999   if (mp->src_address.af == ADDRESS_IP6)
12000     {
12001       clib_memcpy (&src.ip6, &mp->src_address.un.ip6, sizeof (ip6_address_t));
12002       clib_memcpy (&dst.ip6, &mp->dst_address.un.ip6, sizeof (ip6_address_t));
12003     }
12004   else
12005     {
12006       clib_memcpy (&src.ip4, &mp->src_address.un.ip4, sizeof (ip4_address_t));
12007       clib_memcpy (&dst.ip4, &mp->dst_address.un.ip4, sizeof (ip4_address_t));
12008     }
12009
12010   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
12011          ntohl (mp->sw_if_index),
12012          format_ip46_address, &src, IP46_TYPE_ANY,
12013          format_ip46_address, &dst, IP46_TYPE_ANY,
12014          ntohl (mp->encap_vrf_id),
12015          ntohl (mp->decap_next_index), ntohl (mp->vni),
12016          ntohl (mp->mcast_sw_if_index));
12017 }
12018
12019 static void vl_api_geneve_tunnel_details_t_handler_json
12020   (vl_api_geneve_tunnel_details_t * mp)
12021 {
12022   vat_main_t *vam = &vat_main;
12023   vat_json_node_t *node = NULL;
12024   bool is_ipv6;
12025
12026   if (VAT_JSON_ARRAY != vam->json_tree.type)
12027     {
12028       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12029       vat_json_init_array (&vam->json_tree);
12030     }
12031   node = vat_json_array_add (&vam->json_tree);
12032
12033   vat_json_init_object (node);
12034   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12035   is_ipv6 = mp->src_address.af == ADDRESS_IP6;
12036   if (is_ipv6)
12037     {
12038       struct in6_addr ip6;
12039
12040       clib_memcpy (&ip6, &mp->src_address.un.ip6, sizeof (ip6));
12041       vat_json_object_add_ip6 (node, "src_address", ip6);
12042       clib_memcpy (&ip6, &mp->dst_address.un.ip6, sizeof (ip6));
12043       vat_json_object_add_ip6 (node, "dst_address", ip6);
12044     }
12045   else
12046     {
12047       struct in_addr ip4;
12048
12049       clib_memcpy (&ip4, &mp->src_address.un.ip4, sizeof (ip4));
12050       vat_json_object_add_ip4 (node, "src_address", ip4);
12051       clib_memcpy (&ip4, &mp->dst_address.un.ip4, sizeof (ip4));
12052       vat_json_object_add_ip4 (node, "dst_address", ip4);
12053     }
12054   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
12055   vat_json_object_add_uint (node, "decap_next_index",
12056                             ntohl (mp->decap_next_index));
12057   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
12058   vat_json_object_add_uint (node, "mcast_sw_if_index",
12059                             ntohl (mp->mcast_sw_if_index));
12060 }
12061
12062 static int
12063 api_geneve_tunnel_dump (vat_main_t * vam)
12064 {
12065   unformat_input_t *i = vam->input;
12066   vl_api_geneve_tunnel_dump_t *mp;
12067   vl_api_control_ping_t *mp_ping;
12068   u32 sw_if_index;
12069   u8 sw_if_index_set = 0;
12070   int ret;
12071
12072   /* Parse args required to build the message */
12073   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12074     {
12075       if (unformat (i, "sw_if_index %d", &sw_if_index))
12076         sw_if_index_set = 1;
12077       else
12078         break;
12079     }
12080
12081   if (sw_if_index_set == 0)
12082     {
12083       sw_if_index = ~0;
12084     }
12085
12086   if (!vam->json_output)
12087     {
12088       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
12089              "sw_if_index", "local_address", "remote_address",
12090              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
12091     }
12092
12093   /* Get list of geneve-tunnel interfaces */
12094   M (GENEVE_TUNNEL_DUMP, mp);
12095
12096   mp->sw_if_index = htonl (sw_if_index);
12097
12098   S (mp);
12099
12100   /* Use a control ping for synchronization */
12101   M (CONTROL_PING, mp_ping);
12102   S (mp_ping);
12103
12104   W (ret);
12105   return ret;
12106 }
12107
12108 static int
12109 api_gre_tunnel_add_del (vat_main_t * vam)
12110 {
12111   unformat_input_t *line_input = vam->input;
12112   vl_api_address_t src = { }, dst =
12113   {
12114   };
12115   vl_api_gre_tunnel_add_del_t *mp;
12116   vl_api_gre_tunnel_type_t t_type;
12117   u8 is_add = 1;
12118   u8 src_set = 0;
12119   u8 dst_set = 0;
12120   u32 outer_table_id = 0;
12121   u32 session_id = 0;
12122   u32 instance = ~0;
12123   int ret;
12124
12125   t_type = GRE_API_TUNNEL_TYPE_L3;
12126
12127   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12128     {
12129       if (unformat (line_input, "del"))
12130         is_add = 0;
12131       else if (unformat (line_input, "instance %d", &instance))
12132         ;
12133       else if (unformat (line_input, "src %U", unformat_vl_api_address, &src))
12134         {
12135           src_set = 1;
12136         }
12137       else if (unformat (line_input, "dst %U", unformat_vl_api_address, &dst))
12138         {
12139           dst_set = 1;
12140         }
12141       else if (unformat (line_input, "outer-table-id %d", &outer_table_id))
12142         ;
12143       else if (unformat (line_input, "teb"))
12144         t_type = GRE_API_TUNNEL_TYPE_TEB;
12145       else if (unformat (line_input, "erspan %d", &session_id))
12146         t_type = GRE_API_TUNNEL_TYPE_ERSPAN;
12147       else
12148         {
12149           errmsg ("parse error '%U'", format_unformat_error, line_input);
12150           return -99;
12151         }
12152     }
12153
12154   if (src_set == 0)
12155     {
12156       errmsg ("tunnel src address not specified");
12157       return -99;
12158     }
12159   if (dst_set == 0)
12160     {
12161       errmsg ("tunnel dst address not specified");
12162       return -99;
12163     }
12164
12165   M (GRE_TUNNEL_ADD_DEL, mp);
12166
12167   clib_memcpy (&mp->tunnel.src, &src, sizeof (mp->tunnel.src));
12168   clib_memcpy (&mp->tunnel.dst, &dst, sizeof (mp->tunnel.dst));
12169
12170   mp->tunnel.instance = htonl (instance);
12171   mp->tunnel.outer_table_id = htonl (outer_table_id);
12172   mp->is_add = is_add;
12173   mp->tunnel.session_id = htons ((u16) session_id);
12174   mp->tunnel.type = htonl (t_type);
12175
12176   S (mp);
12177   W (ret);
12178   return ret;
12179 }
12180
12181 static void vl_api_gre_tunnel_details_t_handler
12182   (vl_api_gre_tunnel_details_t * mp)
12183 {
12184   vat_main_t *vam = &vat_main;
12185
12186   print (vam->ofp, "%11d%11d%24U%24U%13d%14d%12d",
12187          ntohl (mp->tunnel.sw_if_index),
12188          ntohl (mp->tunnel.instance),
12189          format_vl_api_address, &mp->tunnel.src,
12190          format_vl_api_address, &mp->tunnel.dst,
12191          mp->tunnel.type, ntohl (mp->tunnel.outer_table_id),
12192          ntohl (mp->tunnel.session_id));
12193 }
12194
12195 static void vl_api_gre_tunnel_details_t_handler_json
12196   (vl_api_gre_tunnel_details_t * mp)
12197 {
12198   vat_main_t *vam = &vat_main;
12199   vat_json_node_t *node = NULL;
12200
12201   if (VAT_JSON_ARRAY != vam->json_tree.type)
12202     {
12203       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12204       vat_json_init_array (&vam->json_tree);
12205     }
12206   node = vat_json_array_add (&vam->json_tree);
12207
12208   vat_json_init_object (node);
12209   vat_json_object_add_uint (node, "sw_if_index",
12210                             ntohl (mp->tunnel.sw_if_index));
12211   vat_json_object_add_uint (node, "instance", ntohl (mp->tunnel.instance));
12212
12213   vat_json_object_add_address (node, "src", &mp->tunnel.src);
12214   vat_json_object_add_address (node, "dst", &mp->tunnel.dst);
12215   vat_json_object_add_uint (node, "tunnel_type", mp->tunnel.type);
12216   vat_json_object_add_uint (node, "outer_table_id",
12217                             ntohl (mp->tunnel.outer_table_id));
12218   vat_json_object_add_uint (node, "session_id", mp->tunnel.session_id);
12219 }
12220
12221 static int
12222 api_gre_tunnel_dump (vat_main_t * vam)
12223 {
12224   unformat_input_t *i = vam->input;
12225   vl_api_gre_tunnel_dump_t *mp;
12226   vl_api_control_ping_t *mp_ping;
12227   u32 sw_if_index;
12228   u8 sw_if_index_set = 0;
12229   int ret;
12230
12231   /* Parse args required to build the message */
12232   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12233     {
12234       if (unformat (i, "sw_if_index %d", &sw_if_index))
12235         sw_if_index_set = 1;
12236       else
12237         break;
12238     }
12239
12240   if (sw_if_index_set == 0)
12241     {
12242       sw_if_index = ~0;
12243     }
12244
12245   if (!vam->json_output)
12246     {
12247       print (vam->ofp, "%11s%11s%24s%24s%13s%14s%12s",
12248              "sw_if_index", "instance", "src_address", "dst_address",
12249              "tunnel_type", "outer_fib_id", "session_id");
12250     }
12251
12252   /* Get list of gre-tunnel interfaces */
12253   M (GRE_TUNNEL_DUMP, mp);
12254
12255   mp->sw_if_index = htonl (sw_if_index);
12256
12257   S (mp);
12258
12259   /* Use a control ping for synchronization */
12260   MPING (CONTROL_PING, mp_ping);
12261   S (mp_ping);
12262
12263   W (ret);
12264   return ret;
12265 }
12266
12267 static int
12268 api_l2_fib_clear_table (vat_main_t * vam)
12269 {
12270 //  unformat_input_t * i = vam->input;
12271   vl_api_l2_fib_clear_table_t *mp;
12272   int ret;
12273
12274   M (L2_FIB_CLEAR_TABLE, mp);
12275
12276   S (mp);
12277   W (ret);
12278   return ret;
12279 }
12280
12281 static int
12282 api_l2_interface_efp_filter (vat_main_t * vam)
12283 {
12284   unformat_input_t *i = vam->input;
12285   vl_api_l2_interface_efp_filter_t *mp;
12286   u32 sw_if_index;
12287   u8 enable = 1;
12288   u8 sw_if_index_set = 0;
12289   int ret;
12290
12291   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12292     {
12293       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12294         sw_if_index_set = 1;
12295       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12296         sw_if_index_set = 1;
12297       else if (unformat (i, "enable"))
12298         enable = 1;
12299       else if (unformat (i, "disable"))
12300         enable = 0;
12301       else
12302         {
12303           clib_warning ("parse error '%U'", format_unformat_error, i);
12304           return -99;
12305         }
12306     }
12307
12308   if (sw_if_index_set == 0)
12309     {
12310       errmsg ("missing sw_if_index");
12311       return -99;
12312     }
12313
12314   M (L2_INTERFACE_EFP_FILTER, mp);
12315
12316   mp->sw_if_index = ntohl (sw_if_index);
12317   mp->enable_disable = enable;
12318
12319   S (mp);
12320   W (ret);
12321   return ret;
12322 }
12323
12324 #define foreach_vtr_op                          \
12325 _("disable",  L2_VTR_DISABLED)                  \
12326 _("push-1",  L2_VTR_PUSH_1)                     \
12327 _("push-2",  L2_VTR_PUSH_2)                     \
12328 _("pop-1",  L2_VTR_POP_1)                       \
12329 _("pop-2",  L2_VTR_POP_2)                       \
12330 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
12331 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
12332 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
12333 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
12334
12335 static int
12336 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
12337 {
12338   unformat_input_t *i = vam->input;
12339   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
12340   u32 sw_if_index;
12341   u8 sw_if_index_set = 0;
12342   u8 vtr_op_set = 0;
12343   u32 vtr_op = 0;
12344   u32 push_dot1q = 1;
12345   u32 tag1 = ~0;
12346   u32 tag2 = ~0;
12347   int ret;
12348
12349   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12350     {
12351       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12352         sw_if_index_set = 1;
12353       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12354         sw_if_index_set = 1;
12355       else if (unformat (i, "vtr_op %d", &vtr_op))
12356         vtr_op_set = 1;
12357 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
12358       foreach_vtr_op
12359 #undef _
12360         else if (unformat (i, "push_dot1q %d", &push_dot1q))
12361         ;
12362       else if (unformat (i, "tag1 %d", &tag1))
12363         ;
12364       else if (unformat (i, "tag2 %d", &tag2))
12365         ;
12366       else
12367         {
12368           clib_warning ("parse error '%U'", format_unformat_error, i);
12369           return -99;
12370         }
12371     }
12372
12373   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
12374     {
12375       errmsg ("missing vtr operation or sw_if_index");
12376       return -99;
12377     }
12378
12379   M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
12380   mp->sw_if_index = ntohl (sw_if_index);
12381   mp->vtr_op = ntohl (vtr_op);
12382   mp->push_dot1q = ntohl (push_dot1q);
12383   mp->tag1 = ntohl (tag1);
12384   mp->tag2 = ntohl (tag2);
12385
12386   S (mp);
12387   W (ret);
12388   return ret;
12389 }
12390
12391 static int
12392 api_create_vhost_user_if (vat_main_t * vam)
12393 {
12394   unformat_input_t *i = vam->input;
12395   vl_api_create_vhost_user_if_t *mp;
12396   u8 *file_name;
12397   u8 is_server = 0;
12398   u8 file_name_set = 0;
12399   u32 custom_dev_instance = ~0;
12400   u8 hwaddr[6];
12401   u8 use_custom_mac = 0;
12402   u8 disable_mrg_rxbuf = 0;
12403   u8 disable_indirect_desc = 0;
12404   u8 *tag = 0;
12405   u8 enable_gso = 0;
12406   int ret;
12407
12408   /* Shut up coverity */
12409   clib_memset (hwaddr, 0, sizeof (hwaddr));
12410
12411   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12412     {
12413       if (unformat (i, "socket %s", &file_name))
12414         {
12415           file_name_set = 1;
12416         }
12417       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
12418         ;
12419       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
12420         use_custom_mac = 1;
12421       else if (unformat (i, "server"))
12422         is_server = 1;
12423       else if (unformat (i, "disable_mrg_rxbuf"))
12424         disable_mrg_rxbuf = 1;
12425       else if (unformat (i, "disable_indirect_desc"))
12426         disable_indirect_desc = 1;
12427       else if (unformat (i, "gso"))
12428         enable_gso = 1;
12429       else if (unformat (i, "tag %s", &tag))
12430         ;
12431       else
12432         break;
12433     }
12434
12435   if (file_name_set == 0)
12436     {
12437       errmsg ("missing socket file name");
12438       return -99;
12439     }
12440
12441   if (vec_len (file_name) > 255)
12442     {
12443       errmsg ("socket file name too long");
12444       return -99;
12445     }
12446   vec_add1 (file_name, 0);
12447
12448   M (CREATE_VHOST_USER_IF, mp);
12449
12450   mp->is_server = is_server;
12451   mp->disable_mrg_rxbuf = disable_mrg_rxbuf;
12452   mp->disable_indirect_desc = disable_indirect_desc;
12453   mp->enable_gso = enable_gso;
12454   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
12455   vec_free (file_name);
12456   if (custom_dev_instance != ~0)
12457     {
12458       mp->renumber = 1;
12459       mp->custom_dev_instance = ntohl (custom_dev_instance);
12460     }
12461
12462   mp->use_custom_mac = use_custom_mac;
12463   clib_memcpy (mp->mac_address, hwaddr, 6);
12464   if (tag)
12465     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
12466   vec_free (tag);
12467
12468   S (mp);
12469   W (ret);
12470   return ret;
12471 }
12472
12473 static int
12474 api_modify_vhost_user_if (vat_main_t * vam)
12475 {
12476   unformat_input_t *i = vam->input;
12477   vl_api_modify_vhost_user_if_t *mp;
12478   u8 *file_name;
12479   u8 is_server = 0;
12480   u8 file_name_set = 0;
12481   u32 custom_dev_instance = ~0;
12482   u8 sw_if_index_set = 0;
12483   u32 sw_if_index = (u32) ~ 0;
12484   u8 enable_gso = 0;
12485   int ret;
12486
12487   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12488     {
12489       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12490         sw_if_index_set = 1;
12491       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12492         sw_if_index_set = 1;
12493       else if (unformat (i, "socket %s", &file_name))
12494         {
12495           file_name_set = 1;
12496         }
12497       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
12498         ;
12499       else if (unformat (i, "server"))
12500         is_server = 1;
12501       else if (unformat (i, "gso"))
12502         enable_gso = 1;
12503       else
12504         break;
12505     }
12506
12507   if (sw_if_index_set == 0)
12508     {
12509       errmsg ("missing sw_if_index or interface name");
12510       return -99;
12511     }
12512
12513   if (file_name_set == 0)
12514     {
12515       errmsg ("missing socket file name");
12516       return -99;
12517     }
12518
12519   if (vec_len (file_name) > 255)
12520     {
12521       errmsg ("socket file name too long");
12522       return -99;
12523     }
12524   vec_add1 (file_name, 0);
12525
12526   M (MODIFY_VHOST_USER_IF, mp);
12527
12528   mp->sw_if_index = ntohl (sw_if_index);
12529   mp->is_server = is_server;
12530   mp->enable_gso = enable_gso;
12531   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
12532   vec_free (file_name);
12533   if (custom_dev_instance != ~0)
12534     {
12535       mp->renumber = 1;
12536       mp->custom_dev_instance = ntohl (custom_dev_instance);
12537     }
12538
12539   S (mp);
12540   W (ret);
12541   return ret;
12542 }
12543
12544 static int
12545 api_delete_vhost_user_if (vat_main_t * vam)
12546 {
12547   unformat_input_t *i = vam->input;
12548   vl_api_delete_vhost_user_if_t *mp;
12549   u32 sw_if_index = ~0;
12550   u8 sw_if_index_set = 0;
12551   int ret;
12552
12553   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12554     {
12555       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12556         sw_if_index_set = 1;
12557       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12558         sw_if_index_set = 1;
12559       else
12560         break;
12561     }
12562
12563   if (sw_if_index_set == 0)
12564     {
12565       errmsg ("missing sw_if_index or interface name");
12566       return -99;
12567     }
12568
12569
12570   M (DELETE_VHOST_USER_IF, mp);
12571
12572   mp->sw_if_index = ntohl (sw_if_index);
12573
12574   S (mp);
12575   W (ret);
12576   return ret;
12577 }
12578
12579 static void vl_api_sw_interface_vhost_user_details_t_handler
12580   (vl_api_sw_interface_vhost_user_details_t * mp)
12581 {
12582   vat_main_t *vam = &vat_main;
12583   u64 features;
12584
12585   features =
12586     clib_net_to_host_u32 (mp->features_first_32) | ((u64)
12587                                                     clib_net_to_host_u32
12588                                                     (mp->features_last_32) <<
12589                                                     32);
12590
12591   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s",
12592          (char *) mp->interface_name,
12593          ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
12594          features, mp->is_server,
12595          ntohl (mp->num_regions), (char *) mp->sock_filename);
12596   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
12597 }
12598
12599 static void vl_api_sw_interface_vhost_user_details_t_handler_json
12600   (vl_api_sw_interface_vhost_user_details_t * mp)
12601 {
12602   vat_main_t *vam = &vat_main;
12603   vat_json_node_t *node = NULL;
12604
12605   if (VAT_JSON_ARRAY != vam->json_tree.type)
12606     {
12607       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12608       vat_json_init_array (&vam->json_tree);
12609     }
12610   node = vat_json_array_add (&vam->json_tree);
12611
12612   vat_json_init_object (node);
12613   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12614   vat_json_object_add_string_copy (node, "interface_name",
12615                                    mp->interface_name);
12616   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
12617                             ntohl (mp->virtio_net_hdr_sz));
12618   vat_json_object_add_uint (node, "features_first_32",
12619                             clib_net_to_host_u32 (mp->features_first_32));
12620   vat_json_object_add_uint (node, "features_last_32",
12621                             clib_net_to_host_u32 (mp->features_last_32));
12622   vat_json_object_add_uint (node, "is_server", mp->is_server);
12623   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
12624   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
12625   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
12626 }
12627
12628 static int
12629 api_sw_interface_vhost_user_dump (vat_main_t * vam)
12630 {
12631   vl_api_sw_interface_vhost_user_dump_t *mp;
12632   vl_api_control_ping_t *mp_ping;
12633   int ret;
12634   print (vam->ofp,
12635          "Interface name            idx hdr_sz features server regions filename");
12636
12637   /* Get list of vhost-user interfaces */
12638   M (SW_INTERFACE_VHOST_USER_DUMP, mp);
12639   S (mp);
12640
12641   /* Use a control ping for synchronization */
12642   MPING (CONTROL_PING, mp_ping);
12643   S (mp_ping);
12644
12645   W (ret);
12646   return ret;
12647 }
12648
12649 static int
12650 api_show_version (vat_main_t * vam)
12651 {
12652   vl_api_show_version_t *mp;
12653   int ret;
12654
12655   M (SHOW_VERSION, mp);
12656
12657   S (mp);
12658   W (ret);
12659   return ret;
12660 }
12661
12662
12663 static int
12664 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
12665 {
12666   unformat_input_t *line_input = vam->input;
12667   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
12668   ip4_address_t local4, remote4;
12669   ip6_address_t local6, remote6;
12670   u8 is_add = 1;
12671   u8 ipv4_set = 0, ipv6_set = 0;
12672   u8 local_set = 0;
12673   u8 remote_set = 0;
12674   u8 grp_set = 0;
12675   u32 mcast_sw_if_index = ~0;
12676   u32 encap_vrf_id = 0;
12677   u32 decap_vrf_id = 0;
12678   u8 protocol = ~0;
12679   u32 vni;
12680   u8 vni_set = 0;
12681   int ret;
12682
12683   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
12684   clib_memset (&local4, 0, sizeof local4);
12685   clib_memset (&remote4, 0, sizeof remote4);
12686   clib_memset (&local6, 0, sizeof local6);
12687   clib_memset (&remote6, 0, sizeof remote6);
12688
12689   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12690     {
12691       if (unformat (line_input, "del"))
12692         is_add = 0;
12693       else if (unformat (line_input, "local %U",
12694                          unformat_ip4_address, &local4))
12695         {
12696           local_set = 1;
12697           ipv4_set = 1;
12698         }
12699       else if (unformat (line_input, "remote %U",
12700                          unformat_ip4_address, &remote4))
12701         {
12702           remote_set = 1;
12703           ipv4_set = 1;
12704         }
12705       else if (unformat (line_input, "local %U",
12706                          unformat_ip6_address, &local6))
12707         {
12708           local_set = 1;
12709           ipv6_set = 1;
12710         }
12711       else if (unformat (line_input, "remote %U",
12712                          unformat_ip6_address, &remote6))
12713         {
12714           remote_set = 1;
12715           ipv6_set = 1;
12716         }
12717       else if (unformat (line_input, "group %U %U",
12718                          unformat_ip4_address, &remote4,
12719                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12720         {
12721           grp_set = remote_set = 1;
12722           ipv4_set = 1;
12723         }
12724       else if (unformat (line_input, "group %U",
12725                          unformat_ip4_address, &remote4))
12726         {
12727           grp_set = remote_set = 1;
12728           ipv4_set = 1;
12729         }
12730       else if (unformat (line_input, "group %U %U",
12731                          unformat_ip6_address, &remote6,
12732                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12733         {
12734           grp_set = remote_set = 1;
12735           ipv6_set = 1;
12736         }
12737       else if (unformat (line_input, "group %U",
12738                          unformat_ip6_address, &remote6))
12739         {
12740           grp_set = remote_set = 1;
12741           ipv6_set = 1;
12742         }
12743       else
12744         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
12745         ;
12746       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
12747         ;
12748       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
12749         ;
12750       else if (unformat (line_input, "vni %d", &vni))
12751         vni_set = 1;
12752       else if (unformat (line_input, "next-ip4"))
12753         protocol = 1;
12754       else if (unformat (line_input, "next-ip6"))
12755         protocol = 2;
12756       else if (unformat (line_input, "next-ethernet"))
12757         protocol = 3;
12758       else if (unformat (line_input, "next-nsh"))
12759         protocol = 4;
12760       else
12761         {
12762           errmsg ("parse error '%U'", format_unformat_error, line_input);
12763           return -99;
12764         }
12765     }
12766
12767   if (local_set == 0)
12768     {
12769       errmsg ("tunnel local address not specified");
12770       return -99;
12771     }
12772   if (remote_set == 0)
12773     {
12774       errmsg ("tunnel remote address not specified");
12775       return -99;
12776     }
12777   if (grp_set && mcast_sw_if_index == ~0)
12778     {
12779       errmsg ("tunnel nonexistent multicast device");
12780       return -99;
12781     }
12782   if (ipv4_set && ipv6_set)
12783     {
12784       errmsg ("both IPv4 and IPv6 addresses specified");
12785       return -99;
12786     }
12787
12788   if (vni_set == 0)
12789     {
12790       errmsg ("vni not specified");
12791       return -99;
12792     }
12793
12794   M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
12795
12796
12797   if (ipv6_set)
12798     {
12799       clib_memcpy (&mp->local, &local6, sizeof (local6));
12800       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
12801     }
12802   else
12803     {
12804       clib_memcpy (&mp->local, &local4, sizeof (local4));
12805       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
12806     }
12807
12808   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
12809   mp->encap_vrf_id = ntohl (encap_vrf_id);
12810   mp->decap_vrf_id = ntohl (decap_vrf_id);
12811   mp->protocol = protocol;
12812   mp->vni = ntohl (vni);
12813   mp->is_add = is_add;
12814   mp->is_ipv6 = ipv6_set;
12815
12816   S (mp);
12817   W (ret);
12818   return ret;
12819 }
12820
12821 static void vl_api_vxlan_gpe_tunnel_details_t_handler
12822   (vl_api_vxlan_gpe_tunnel_details_t * mp)
12823 {
12824   vat_main_t *vam = &vat_main;
12825   ip46_address_t local = to_ip46 (mp->is_ipv6, mp->local);
12826   ip46_address_t remote = to_ip46 (mp->is_ipv6, mp->remote);
12827
12828   print (vam->ofp, "%11d%24U%24U%13d%12d%19d%14d%14d",
12829          ntohl (mp->sw_if_index),
12830          format_ip46_address, &local, IP46_TYPE_ANY,
12831          format_ip46_address, &remote, IP46_TYPE_ANY,
12832          ntohl (mp->vni), mp->protocol,
12833          ntohl (mp->mcast_sw_if_index),
12834          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
12835 }
12836
12837
12838 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
12839   (vl_api_vxlan_gpe_tunnel_details_t * mp)
12840 {
12841   vat_main_t *vam = &vat_main;
12842   vat_json_node_t *node = NULL;
12843   struct in_addr ip4;
12844   struct in6_addr ip6;
12845
12846   if (VAT_JSON_ARRAY != vam->json_tree.type)
12847     {
12848       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12849       vat_json_init_array (&vam->json_tree);
12850     }
12851   node = vat_json_array_add (&vam->json_tree);
12852
12853   vat_json_init_object (node);
12854   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12855   if (mp->is_ipv6)
12856     {
12857       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
12858       vat_json_object_add_ip6 (node, "local", ip6);
12859       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
12860       vat_json_object_add_ip6 (node, "remote", ip6);
12861     }
12862   else
12863     {
12864       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
12865       vat_json_object_add_ip4 (node, "local", ip4);
12866       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
12867       vat_json_object_add_ip4 (node, "remote", ip4);
12868     }
12869   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
12870   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
12871   vat_json_object_add_uint (node, "mcast_sw_if_index",
12872                             ntohl (mp->mcast_sw_if_index));
12873   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
12874   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
12875   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
12876 }
12877
12878 static int
12879 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
12880 {
12881   unformat_input_t *i = vam->input;
12882   vl_api_vxlan_gpe_tunnel_dump_t *mp;
12883   vl_api_control_ping_t *mp_ping;
12884   u32 sw_if_index;
12885   u8 sw_if_index_set = 0;
12886   int ret;
12887
12888   /* Parse args required to build the message */
12889   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12890     {
12891       if (unformat (i, "sw_if_index %d", &sw_if_index))
12892         sw_if_index_set = 1;
12893       else
12894         break;
12895     }
12896
12897   if (sw_if_index_set == 0)
12898     {
12899       sw_if_index = ~0;
12900     }
12901
12902   if (!vam->json_output)
12903     {
12904       print (vam->ofp, "%11s%24s%24s%13s%15s%19s%14s%14s",
12905              "sw_if_index", "local", "remote", "vni",
12906              "protocol", "mcast_sw_if_index", "encap_vrf_id", "decap_vrf_id");
12907     }
12908
12909   /* Get list of vxlan-tunnel interfaces */
12910   M (VXLAN_GPE_TUNNEL_DUMP, mp);
12911
12912   mp->sw_if_index = htonl (sw_if_index);
12913
12914   S (mp);
12915
12916   /* Use a control ping for synchronization */
12917   MPING (CONTROL_PING, mp_ping);
12918   S (mp_ping);
12919
12920   W (ret);
12921   return ret;
12922 }
12923
12924 static void vl_api_l2_fib_table_details_t_handler
12925   (vl_api_l2_fib_table_details_t * mp)
12926 {
12927   vat_main_t *vam = &vat_main;
12928
12929   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
12930          "       %d       %d     %d",
12931          ntohl (mp->bd_id), format_ethernet_address, mp->mac,
12932          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
12933          mp->bvi_mac);
12934 }
12935
12936 static void vl_api_l2_fib_table_details_t_handler_json
12937   (vl_api_l2_fib_table_details_t * mp)
12938 {
12939   vat_main_t *vam = &vat_main;
12940   vat_json_node_t *node = NULL;
12941
12942   if (VAT_JSON_ARRAY != vam->json_tree.type)
12943     {
12944       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12945       vat_json_init_array (&vam->json_tree);
12946     }
12947   node = vat_json_array_add (&vam->json_tree);
12948
12949   vat_json_init_object (node);
12950   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
12951   vat_json_object_add_bytes (node, "mac", mp->mac, 6);
12952   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12953   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
12954   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
12955   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
12956 }
12957
12958 static int
12959 api_l2_fib_table_dump (vat_main_t * vam)
12960 {
12961   unformat_input_t *i = vam->input;
12962   vl_api_l2_fib_table_dump_t *mp;
12963   vl_api_control_ping_t *mp_ping;
12964   u32 bd_id;
12965   u8 bd_id_set = 0;
12966   int ret;
12967
12968   /* Parse args required to build the message */
12969   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12970     {
12971       if (unformat (i, "bd_id %d", &bd_id))
12972         bd_id_set = 1;
12973       else
12974         break;
12975     }
12976
12977   if (bd_id_set == 0)
12978     {
12979       errmsg ("missing bridge domain");
12980       return -99;
12981     }
12982
12983   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
12984
12985   /* Get list of l2 fib entries */
12986   M (L2_FIB_TABLE_DUMP, mp);
12987
12988   mp->bd_id = ntohl (bd_id);
12989   S (mp);
12990
12991   /* Use a control ping for synchronization */
12992   MPING (CONTROL_PING, mp_ping);
12993   S (mp_ping);
12994
12995   W (ret);
12996   return ret;
12997 }
12998
12999
13000 static int
13001 api_interface_name_renumber (vat_main_t * vam)
13002 {
13003   unformat_input_t *line_input = vam->input;
13004   vl_api_interface_name_renumber_t *mp;
13005   u32 sw_if_index = ~0;
13006   u32 new_show_dev_instance = ~0;
13007   int ret;
13008
13009   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13010     {
13011       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
13012                     &sw_if_index))
13013         ;
13014       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
13015         ;
13016       else if (unformat (line_input, "new_show_dev_instance %d",
13017                          &new_show_dev_instance))
13018         ;
13019       else
13020         break;
13021     }
13022
13023   if (sw_if_index == ~0)
13024     {
13025       errmsg ("missing interface name or sw_if_index");
13026       return -99;
13027     }
13028
13029   if (new_show_dev_instance == ~0)
13030     {
13031       errmsg ("missing new_show_dev_instance");
13032       return -99;
13033     }
13034
13035   M (INTERFACE_NAME_RENUMBER, mp);
13036
13037   mp->sw_if_index = ntohl (sw_if_index);
13038   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
13039
13040   S (mp);
13041   W (ret);
13042   return ret;
13043 }
13044
13045 static int
13046 api_want_l2_macs_events (vat_main_t * vam)
13047 {
13048   unformat_input_t *line_input = vam->input;
13049   vl_api_want_l2_macs_events_t *mp;
13050   u8 enable_disable = 1;
13051   u32 scan_delay = 0;
13052   u32 max_macs_in_event = 0;
13053   u32 learn_limit = 0;
13054   int ret;
13055
13056   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13057     {
13058       if (unformat (line_input, "learn-limit %d", &learn_limit))
13059         ;
13060       else if (unformat (line_input, "scan-delay %d", &scan_delay))
13061         ;
13062       else if (unformat (line_input, "max-entries %d", &max_macs_in_event))
13063         ;
13064       else if (unformat (line_input, "disable"))
13065         enable_disable = 0;
13066       else
13067         break;
13068     }
13069
13070   M (WANT_L2_MACS_EVENTS, mp);
13071   mp->enable_disable = enable_disable;
13072   mp->pid = htonl (getpid ());
13073   mp->learn_limit = htonl (learn_limit);
13074   mp->scan_delay = (u8) scan_delay;
13075   mp->max_macs_in_event = (u8) (max_macs_in_event / 10);
13076   S (mp);
13077   W (ret);
13078   return ret;
13079 }
13080
13081 static int
13082 api_input_acl_set_interface (vat_main_t * vam)
13083 {
13084   unformat_input_t *i = vam->input;
13085   vl_api_input_acl_set_interface_t *mp;
13086   u32 sw_if_index;
13087   int sw_if_index_set;
13088   u32 ip4_table_index = ~0;
13089   u32 ip6_table_index = ~0;
13090   u32 l2_table_index = ~0;
13091   u8 is_add = 1;
13092   int ret;
13093
13094   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13095     {
13096       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13097         sw_if_index_set = 1;
13098       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13099         sw_if_index_set = 1;
13100       else if (unformat (i, "del"))
13101         is_add = 0;
13102       else if (unformat (i, "ip4-table %d", &ip4_table_index))
13103         ;
13104       else if (unformat (i, "ip6-table %d", &ip6_table_index))
13105         ;
13106       else if (unformat (i, "l2-table %d", &l2_table_index))
13107         ;
13108       else
13109         {
13110           clib_warning ("parse error '%U'", format_unformat_error, i);
13111           return -99;
13112         }
13113     }
13114
13115   if (sw_if_index_set == 0)
13116     {
13117       errmsg ("missing interface name or sw_if_index");
13118       return -99;
13119     }
13120
13121   M (INPUT_ACL_SET_INTERFACE, mp);
13122
13123   mp->sw_if_index = ntohl (sw_if_index);
13124   mp->ip4_table_index = ntohl (ip4_table_index);
13125   mp->ip6_table_index = ntohl (ip6_table_index);
13126   mp->l2_table_index = ntohl (l2_table_index);
13127   mp->is_add = is_add;
13128
13129   S (mp);
13130   W (ret);
13131   return ret;
13132 }
13133
13134 static int
13135 api_output_acl_set_interface (vat_main_t * vam)
13136 {
13137   unformat_input_t *i = vam->input;
13138   vl_api_output_acl_set_interface_t *mp;
13139   u32 sw_if_index;
13140   int sw_if_index_set;
13141   u32 ip4_table_index = ~0;
13142   u32 ip6_table_index = ~0;
13143   u32 l2_table_index = ~0;
13144   u8 is_add = 1;
13145   int ret;
13146
13147   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13148     {
13149       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13150         sw_if_index_set = 1;
13151       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13152         sw_if_index_set = 1;
13153       else if (unformat (i, "del"))
13154         is_add = 0;
13155       else if (unformat (i, "ip4-table %d", &ip4_table_index))
13156         ;
13157       else if (unformat (i, "ip6-table %d", &ip6_table_index))
13158         ;
13159       else if (unformat (i, "l2-table %d", &l2_table_index))
13160         ;
13161       else
13162         {
13163           clib_warning ("parse error '%U'", format_unformat_error, i);
13164           return -99;
13165         }
13166     }
13167
13168   if (sw_if_index_set == 0)
13169     {
13170       errmsg ("missing interface name or sw_if_index");
13171       return -99;
13172     }
13173
13174   M (OUTPUT_ACL_SET_INTERFACE, mp);
13175
13176   mp->sw_if_index = ntohl (sw_if_index);
13177   mp->ip4_table_index = ntohl (ip4_table_index);
13178   mp->ip6_table_index = ntohl (ip6_table_index);
13179   mp->l2_table_index = ntohl (l2_table_index);
13180   mp->is_add = is_add;
13181
13182   S (mp);
13183   W (ret);
13184   return ret;
13185 }
13186
13187 static int
13188 api_ip_address_dump (vat_main_t * vam)
13189 {
13190   unformat_input_t *i = vam->input;
13191   vl_api_ip_address_dump_t *mp;
13192   vl_api_control_ping_t *mp_ping;
13193   u32 sw_if_index = ~0;
13194   u8 sw_if_index_set = 0;
13195   u8 ipv4_set = 0;
13196   u8 ipv6_set = 0;
13197   int ret;
13198
13199   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13200     {
13201       if (unformat (i, "sw_if_index %d", &sw_if_index))
13202         sw_if_index_set = 1;
13203       else
13204         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13205         sw_if_index_set = 1;
13206       else if (unformat (i, "ipv4"))
13207         ipv4_set = 1;
13208       else if (unformat (i, "ipv6"))
13209         ipv6_set = 1;
13210       else
13211         break;
13212     }
13213
13214   if (ipv4_set && ipv6_set)
13215     {
13216       errmsg ("ipv4 and ipv6 flags cannot be both set");
13217       return -99;
13218     }
13219
13220   if ((!ipv4_set) && (!ipv6_set))
13221     {
13222       errmsg ("no ipv4 nor ipv6 flag set");
13223       return -99;
13224     }
13225
13226   if (sw_if_index_set == 0)
13227     {
13228       errmsg ("missing interface name or sw_if_index");
13229       return -99;
13230     }
13231
13232   vam->current_sw_if_index = sw_if_index;
13233   vam->is_ipv6 = ipv6_set;
13234
13235   M (IP_ADDRESS_DUMP, mp);
13236   mp->sw_if_index = ntohl (sw_if_index);
13237   mp->is_ipv6 = ipv6_set;
13238   S (mp);
13239
13240   /* Use a control ping for synchronization */
13241   MPING (CONTROL_PING, mp_ping);
13242   S (mp_ping);
13243
13244   W (ret);
13245   return ret;
13246 }
13247
13248 static int
13249 api_ip_dump (vat_main_t * vam)
13250 {
13251   vl_api_ip_dump_t *mp;
13252   vl_api_control_ping_t *mp_ping;
13253   unformat_input_t *in = vam->input;
13254   int ipv4_set = 0;
13255   int ipv6_set = 0;
13256   int is_ipv6;
13257   int i;
13258   int ret;
13259
13260   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
13261     {
13262       if (unformat (in, "ipv4"))
13263         ipv4_set = 1;
13264       else if (unformat (in, "ipv6"))
13265         ipv6_set = 1;
13266       else
13267         break;
13268     }
13269
13270   if (ipv4_set && ipv6_set)
13271     {
13272       errmsg ("ipv4 and ipv6 flags cannot be both set");
13273       return -99;
13274     }
13275
13276   if ((!ipv4_set) && (!ipv6_set))
13277     {
13278       errmsg ("no ipv4 nor ipv6 flag set");
13279       return -99;
13280     }
13281
13282   is_ipv6 = ipv6_set;
13283   vam->is_ipv6 = is_ipv6;
13284
13285   /* free old data */
13286   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
13287     {
13288       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
13289     }
13290   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
13291
13292   M (IP_DUMP, mp);
13293   mp->is_ipv6 = ipv6_set;
13294   S (mp);
13295
13296   /* Use a control ping for synchronization */
13297   MPING (CONTROL_PING, mp_ping);
13298   S (mp_ping);
13299
13300   W (ret);
13301   return ret;
13302 }
13303
13304 static int
13305 api_ipsec_spd_add_del (vat_main_t * vam)
13306 {
13307   unformat_input_t *i = vam->input;
13308   vl_api_ipsec_spd_add_del_t *mp;
13309   u32 spd_id = ~0;
13310   u8 is_add = 1;
13311   int ret;
13312
13313   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13314     {
13315       if (unformat (i, "spd_id %d", &spd_id))
13316         ;
13317       else if (unformat (i, "del"))
13318         is_add = 0;
13319       else
13320         {
13321           clib_warning ("parse error '%U'", format_unformat_error, i);
13322           return -99;
13323         }
13324     }
13325   if (spd_id == ~0)
13326     {
13327       errmsg ("spd_id must be set");
13328       return -99;
13329     }
13330
13331   M (IPSEC_SPD_ADD_DEL, mp);
13332
13333   mp->spd_id = ntohl (spd_id);
13334   mp->is_add = is_add;
13335
13336   S (mp);
13337   W (ret);
13338   return ret;
13339 }
13340
13341 static int
13342 api_ipsec_interface_add_del_spd (vat_main_t * vam)
13343 {
13344   unformat_input_t *i = vam->input;
13345   vl_api_ipsec_interface_add_del_spd_t *mp;
13346   u32 sw_if_index;
13347   u8 sw_if_index_set = 0;
13348   u32 spd_id = (u32) ~ 0;
13349   u8 is_add = 1;
13350   int ret;
13351
13352   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13353     {
13354       if (unformat (i, "del"))
13355         is_add = 0;
13356       else if (unformat (i, "spd_id %d", &spd_id))
13357         ;
13358       else
13359         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13360         sw_if_index_set = 1;
13361       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13362         sw_if_index_set = 1;
13363       else
13364         {
13365           clib_warning ("parse error '%U'", format_unformat_error, i);
13366           return -99;
13367         }
13368
13369     }
13370
13371   if (spd_id == (u32) ~ 0)
13372     {
13373       errmsg ("spd_id must be set");
13374       return -99;
13375     }
13376
13377   if (sw_if_index_set == 0)
13378     {
13379       errmsg ("missing interface name or sw_if_index");
13380       return -99;
13381     }
13382
13383   M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
13384
13385   mp->spd_id = ntohl (spd_id);
13386   mp->sw_if_index = ntohl (sw_if_index);
13387   mp->is_add = is_add;
13388
13389   S (mp);
13390   W (ret);
13391   return ret;
13392 }
13393
13394 static int
13395 api_ipsec_spd_entry_add_del (vat_main_t * vam)
13396 {
13397   unformat_input_t *i = vam->input;
13398   vl_api_ipsec_spd_entry_add_del_t *mp;
13399   u8 is_add = 1, is_outbound = 0;
13400   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
13401   i32 priority = 0;
13402   u32 rport_start = 0, rport_stop = (u32) ~ 0;
13403   u32 lport_start = 0, lport_stop = (u32) ~ 0;
13404   vl_api_address_t laddr_start = { }, laddr_stop =
13405   {
13406   }, raddr_start =
13407   {
13408   }, raddr_stop =
13409   {
13410   };
13411   int ret;
13412
13413   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13414     {
13415       if (unformat (i, "del"))
13416         is_add = 0;
13417       if (unformat (i, "outbound"))
13418         is_outbound = 1;
13419       if (unformat (i, "inbound"))
13420         is_outbound = 0;
13421       else if (unformat (i, "spd_id %d", &spd_id))
13422         ;
13423       else if (unformat (i, "sa_id %d", &sa_id))
13424         ;
13425       else if (unformat (i, "priority %d", &priority))
13426         ;
13427       else if (unformat (i, "protocol %d", &protocol))
13428         ;
13429       else if (unformat (i, "lport_start %d", &lport_start))
13430         ;
13431       else if (unformat (i, "lport_stop %d", &lport_stop))
13432         ;
13433       else if (unformat (i, "rport_start %d", &rport_start))
13434         ;
13435       else if (unformat (i, "rport_stop %d", &rport_stop))
13436         ;
13437       else if (unformat (i, "laddr_start %U",
13438                          unformat_vl_api_address, &laddr_start))
13439         ;
13440       else if (unformat (i, "laddr_stop %U", unformat_vl_api_address,
13441                          &laddr_stop))
13442         ;
13443       else if (unformat (i, "raddr_start %U", unformat_vl_api_address,
13444                          &raddr_start))
13445         ;
13446       else if (unformat (i, "raddr_stop %U", unformat_vl_api_address,
13447                          &raddr_stop))
13448         ;
13449       else
13450         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
13451         {
13452           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
13453             {
13454               clib_warning ("unsupported action: 'resolve'");
13455               return -99;
13456             }
13457         }
13458       else
13459         {
13460           clib_warning ("parse error '%U'", format_unformat_error, i);
13461           return -99;
13462         }
13463
13464     }
13465
13466   M (IPSEC_SPD_ENTRY_ADD_DEL, mp);
13467
13468   mp->is_add = is_add;
13469
13470   mp->entry.spd_id = ntohl (spd_id);
13471   mp->entry.priority = ntohl (priority);
13472   mp->entry.is_outbound = is_outbound;
13473
13474   clib_memcpy (&mp->entry.remote_address_start, &raddr_start,
13475                sizeof (vl_api_address_t));
13476   clib_memcpy (&mp->entry.remote_address_stop, &raddr_stop,
13477                sizeof (vl_api_address_t));
13478   clib_memcpy (&mp->entry.local_address_start, &laddr_start,
13479                sizeof (vl_api_address_t));
13480   clib_memcpy (&mp->entry.local_address_stop, &laddr_stop,
13481                sizeof (vl_api_address_t));
13482
13483   mp->entry.protocol = (u8) protocol;
13484   mp->entry.local_port_start = ntohs ((u16) lport_start);
13485   mp->entry.local_port_stop = ntohs ((u16) lport_stop);
13486   mp->entry.remote_port_start = ntohs ((u16) rport_start);
13487   mp->entry.remote_port_stop = ntohs ((u16) rport_stop);
13488   mp->entry.policy = (u8) policy;
13489   mp->entry.sa_id = ntohl (sa_id);
13490
13491   S (mp);
13492   W (ret);
13493   return ret;
13494 }
13495
13496 static int
13497 api_ipsec_sad_entry_add_del (vat_main_t * vam)
13498 {
13499   unformat_input_t *i = vam->input;
13500   vl_api_ipsec_sad_entry_add_del_t *mp;
13501   u32 sad_id = 0, spi = 0;
13502   u8 *ck = 0, *ik = 0;
13503   u8 is_add = 1;
13504
13505   vl_api_ipsec_crypto_alg_t crypto_alg = IPSEC_API_CRYPTO_ALG_NONE;
13506   vl_api_ipsec_integ_alg_t integ_alg = IPSEC_API_INTEG_ALG_NONE;
13507   vl_api_ipsec_sad_flags_t flags = IPSEC_API_SAD_FLAG_NONE;
13508   vl_api_ipsec_proto_t protocol = IPSEC_API_PROTO_AH;
13509   vl_api_address_t tun_src, tun_dst;
13510   int ret;
13511
13512   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13513     {
13514       if (unformat (i, "del"))
13515         is_add = 0;
13516       else if (unformat (i, "sad_id %d", &sad_id))
13517         ;
13518       else if (unformat (i, "spi %d", &spi))
13519         ;
13520       else if (unformat (i, "esp"))
13521         protocol = IPSEC_API_PROTO_ESP;
13522       else
13523         if (unformat (i, "tunnel_src %U", unformat_vl_api_address, &tun_src))
13524         {
13525           flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL;
13526           if (ADDRESS_IP6 == tun_src.af)
13527             flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL_V6;
13528         }
13529       else
13530         if (unformat (i, "tunnel_dst %U", unformat_vl_api_address, &tun_dst))
13531         {
13532           flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL;
13533           if (ADDRESS_IP6 == tun_src.af)
13534             flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL_V6;
13535         }
13536       else
13537         if (unformat (i, "crypto_alg %U",
13538                       unformat_ipsec_api_crypto_alg, &crypto_alg))
13539         ;
13540       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
13541         ;
13542       else if (unformat (i, "integ_alg %U",
13543                          unformat_ipsec_api_integ_alg, &integ_alg))
13544         ;
13545       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
13546         ;
13547       else
13548         {
13549           clib_warning ("parse error '%U'", format_unformat_error, i);
13550           return -99;
13551         }
13552
13553     }
13554
13555   M (IPSEC_SAD_ENTRY_ADD_DEL, mp);
13556
13557   mp->is_add = is_add;
13558   mp->entry.sad_id = ntohl (sad_id);
13559   mp->entry.protocol = protocol;
13560   mp->entry.spi = ntohl (spi);
13561   mp->entry.flags = flags;
13562
13563   mp->entry.crypto_algorithm = crypto_alg;
13564   mp->entry.integrity_algorithm = integ_alg;
13565   mp->entry.crypto_key.length = vec_len (ck);
13566   mp->entry.integrity_key.length = vec_len (ik);
13567
13568   if (mp->entry.crypto_key.length > sizeof (mp->entry.crypto_key.data))
13569     mp->entry.crypto_key.length = sizeof (mp->entry.crypto_key.data);
13570
13571   if (mp->entry.integrity_key.length > sizeof (mp->entry.integrity_key.data))
13572     mp->entry.integrity_key.length = sizeof (mp->entry.integrity_key.data);
13573
13574   if (ck)
13575     clib_memcpy (mp->entry.crypto_key.data, ck, mp->entry.crypto_key.length);
13576   if (ik)
13577     clib_memcpy (mp->entry.integrity_key.data, ik,
13578                  mp->entry.integrity_key.length);
13579
13580   if (flags & IPSEC_API_SAD_FLAG_IS_TUNNEL)
13581     {
13582       clib_memcpy (&mp->entry.tunnel_src, &tun_src,
13583                    sizeof (mp->entry.tunnel_src));
13584       clib_memcpy (&mp->entry.tunnel_dst, &tun_dst,
13585                    sizeof (mp->entry.tunnel_dst));
13586     }
13587
13588   S (mp);
13589   W (ret);
13590   return ret;
13591 }
13592
13593 static int
13594 api_ipsec_tunnel_if_add_del (vat_main_t * vam)
13595 {
13596   unformat_input_t *i = vam->input;
13597   vl_api_ipsec_tunnel_if_add_del_t *mp;
13598   u32 local_spi = 0, remote_spi = 0;
13599   u32 crypto_alg = 0, integ_alg = 0;
13600   u8 *lck = NULL, *rck = NULL;
13601   u8 *lik = NULL, *rik = NULL;
13602   vl_api_address_t local_ip = { 0 };
13603   vl_api_address_t remote_ip = { 0 };
13604   f64 before = 0;
13605   u8 is_add = 1;
13606   u8 esn = 0;
13607   u8 anti_replay = 0;
13608   u8 renumber = 0;
13609   u32 instance = ~0;
13610   u32 count = 1, jj;
13611   int ret = -1;
13612
13613   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13614     {
13615       if (unformat (i, "del"))
13616         is_add = 0;
13617       else if (unformat (i, "esn"))
13618         esn = 1;
13619       else if (unformat (i, "anti-replay"))
13620         anti_replay = 1;
13621       else if (unformat (i, "count %d", &count))
13622         ;
13623       else if (unformat (i, "local_spi %d", &local_spi))
13624         ;
13625       else if (unformat (i, "remote_spi %d", &remote_spi))
13626         ;
13627       else
13628         if (unformat (i, "local_ip %U", unformat_vl_api_address, &local_ip))
13629         ;
13630       else
13631         if (unformat (i, "remote_ip %U", unformat_vl_api_address, &remote_ip))
13632         ;
13633       else if (unformat (i, "local_crypto_key %U", unformat_hex_string, &lck))
13634         ;
13635       else
13636         if (unformat (i, "remote_crypto_key %U", unformat_hex_string, &rck))
13637         ;
13638       else if (unformat (i, "local_integ_key %U", unformat_hex_string, &lik))
13639         ;
13640       else if (unformat (i, "remote_integ_key %U", unformat_hex_string, &rik))
13641         ;
13642       else
13643         if (unformat
13644             (i, "crypto_alg %U", unformat_ipsec_api_crypto_alg, &crypto_alg))
13645         {
13646           if (crypto_alg >= IPSEC_CRYPTO_N_ALG)
13647             {
13648               errmsg ("unsupported crypto-alg: '%U'\n",
13649                       format_ipsec_crypto_alg, crypto_alg);
13650               return -99;
13651             }
13652         }
13653       else
13654         if (unformat
13655             (i, "integ_alg %U", unformat_ipsec_api_integ_alg, &integ_alg))
13656         {
13657           if (integ_alg >= IPSEC_INTEG_N_ALG)
13658             {
13659               errmsg ("unsupported integ-alg: '%U'\n",
13660                       format_ipsec_integ_alg, integ_alg);
13661               return -99;
13662             }
13663         }
13664       else if (unformat (i, "instance %u", &instance))
13665         renumber = 1;
13666       else
13667         {
13668           errmsg ("parse error '%U'\n", format_unformat_error, i);
13669           return -99;
13670         }
13671     }
13672
13673   if (count > 1)
13674     {
13675       /* Turn on async mode */
13676       vam->async_mode = 1;
13677       vam->async_errors = 0;
13678       before = vat_time_now (vam);
13679     }
13680
13681   for (jj = 0; jj < count; jj++)
13682     {
13683       M (IPSEC_TUNNEL_IF_ADD_DEL, mp);
13684
13685       mp->is_add = is_add;
13686       mp->esn = esn;
13687       mp->anti_replay = anti_replay;
13688
13689       if (jj > 0)
13690         increment_address (&remote_ip);
13691
13692       clib_memcpy (&mp->local_ip, &local_ip, sizeof (local_ip));
13693       clib_memcpy (&mp->remote_ip, &remote_ip, sizeof (remote_ip));
13694
13695       mp->local_spi = htonl (local_spi + jj);
13696       mp->remote_spi = htonl (remote_spi + jj);
13697       mp->crypto_alg = (u8) crypto_alg;
13698
13699       mp->local_crypto_key_len = 0;
13700       if (lck)
13701         {
13702           mp->local_crypto_key_len = vec_len (lck);
13703           if (mp->local_crypto_key_len > sizeof (mp->local_crypto_key))
13704             mp->local_crypto_key_len = sizeof (mp->local_crypto_key);
13705           clib_memcpy (mp->local_crypto_key, lck, mp->local_crypto_key_len);
13706         }
13707
13708       mp->remote_crypto_key_len = 0;
13709       if (rck)
13710         {
13711           mp->remote_crypto_key_len = vec_len (rck);
13712           if (mp->remote_crypto_key_len > sizeof (mp->remote_crypto_key))
13713             mp->remote_crypto_key_len = sizeof (mp->remote_crypto_key);
13714           clib_memcpy (mp->remote_crypto_key, rck, mp->remote_crypto_key_len);
13715         }
13716
13717       mp->integ_alg = (u8) integ_alg;
13718
13719       mp->local_integ_key_len = 0;
13720       if (lik)
13721         {
13722           mp->local_integ_key_len = vec_len (lik);
13723           if (mp->local_integ_key_len > sizeof (mp->local_integ_key))
13724             mp->local_integ_key_len = sizeof (mp->local_integ_key);
13725           clib_memcpy (mp->local_integ_key, lik, mp->local_integ_key_len);
13726         }
13727
13728       mp->remote_integ_key_len = 0;
13729       if (rik)
13730         {
13731           mp->remote_integ_key_len = vec_len (rik);
13732           if (mp->remote_integ_key_len > sizeof (mp->remote_integ_key))
13733             mp->remote_integ_key_len = sizeof (mp->remote_integ_key);
13734           clib_memcpy (mp->remote_integ_key, rik, mp->remote_integ_key_len);
13735         }
13736
13737       if (renumber)
13738         {
13739           mp->renumber = renumber;
13740           mp->show_instance = ntohl (instance);
13741         }
13742       S (mp);
13743     }
13744
13745   /* When testing multiple add/del ops, use a control-ping to sync */
13746   if (count > 1)
13747     {
13748       vl_api_control_ping_t *mp_ping;
13749       f64 after;
13750       f64 timeout;
13751
13752       /* Shut off async mode */
13753       vam->async_mode = 0;
13754
13755       MPING (CONTROL_PING, mp_ping);
13756       S (mp_ping);
13757
13758       timeout = vat_time_now (vam) + 1.0;
13759       while (vat_time_now (vam) < timeout)
13760         if (vam->result_ready == 1)
13761           goto out;
13762       vam->retval = -99;
13763
13764     out:
13765       if (vam->retval == -99)
13766         errmsg ("timeout");
13767
13768       if (vam->async_errors > 0)
13769         {
13770           errmsg ("%d asynchronous errors", vam->async_errors);
13771           vam->retval = -98;
13772         }
13773       vam->async_errors = 0;
13774       after = vat_time_now (vam);
13775
13776       /* slim chance, but we might have eaten SIGTERM on the first iteration */
13777       if (jj > 0)
13778         count = jj;
13779
13780       print (vam->ofp, "%d tunnels in %.6f secs, %.2f tunnels/sec",
13781              count, after - before, count / (after - before));
13782     }
13783   else
13784     {
13785       /* Wait for a reply... */
13786       W (ret);
13787       return ret;
13788     }
13789
13790   return ret;
13791 }
13792
13793 static void
13794 vl_api_ipsec_sa_details_t_handler (vl_api_ipsec_sa_details_t * mp)
13795 {
13796   vat_main_t *vam = &vat_main;
13797
13798   print (vam->ofp, "sa_id %u sw_if_index %u spi %u proto %u crypto_alg %u "
13799          "crypto_key %U integ_alg %u integ_key %U flags %x "
13800          "tunnel_src_addr %U tunnel_dst_addr %U "
13801          "salt %u seq_outbound %lu last_seq_inbound %lu "
13802          "replay_window %lu\n",
13803          ntohl (mp->entry.sad_id),
13804          ntohl (mp->sw_if_index),
13805          ntohl (mp->entry.spi),
13806          ntohl (mp->entry.protocol),
13807          ntohl (mp->entry.crypto_algorithm),
13808          format_hex_bytes, mp->entry.crypto_key.data,
13809          mp->entry.crypto_key.length, ntohl (mp->entry.integrity_algorithm),
13810          format_hex_bytes, mp->entry.integrity_key.data,
13811          mp->entry.integrity_key.length, ntohl (mp->entry.flags),
13812          format_vl_api_address, &mp->entry.tunnel_src, format_vl_api_address,
13813          &mp->entry.tunnel_dst, ntohl (mp->salt),
13814          clib_net_to_host_u64 (mp->seq_outbound),
13815          clib_net_to_host_u64 (mp->last_seq_inbound),
13816          clib_net_to_host_u64 (mp->replay_window));
13817 }
13818
13819 #define vl_api_ipsec_sa_details_t_endian vl_noop_handler
13820 #define vl_api_ipsec_sa_details_t_print vl_noop_handler
13821
13822 static void vl_api_ipsec_sa_details_t_handler_json
13823   (vl_api_ipsec_sa_details_t * mp)
13824 {
13825   vat_main_t *vam = &vat_main;
13826   vat_json_node_t *node = NULL;
13827   vl_api_ipsec_sad_flags_t flags;
13828
13829   if (VAT_JSON_ARRAY != vam->json_tree.type)
13830     {
13831       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13832       vat_json_init_array (&vam->json_tree);
13833     }
13834   node = vat_json_array_add (&vam->json_tree);
13835
13836   vat_json_init_object (node);
13837   vat_json_object_add_uint (node, "sa_id", ntohl (mp->entry.sad_id));
13838   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13839   vat_json_object_add_uint (node, "spi", ntohl (mp->entry.spi));
13840   vat_json_object_add_uint (node, "proto", ntohl (mp->entry.protocol));
13841   vat_json_object_add_uint (node, "crypto_alg",
13842                             ntohl (mp->entry.crypto_algorithm));
13843   vat_json_object_add_uint (node, "integ_alg",
13844                             ntohl (mp->entry.integrity_algorithm));
13845   flags = ntohl (mp->entry.flags);
13846   vat_json_object_add_uint (node, "use_esn",
13847                             ! !(flags & IPSEC_API_SAD_FLAG_USE_ESN));
13848   vat_json_object_add_uint (node, "use_anti_replay",
13849                             ! !(flags & IPSEC_API_SAD_FLAG_USE_ANTI_REPLAY));
13850   vat_json_object_add_uint (node, "is_tunnel",
13851                             ! !(flags & IPSEC_API_SAD_FLAG_IS_TUNNEL));
13852   vat_json_object_add_uint (node, "is_tunnel_ip6",
13853                             ! !(flags & IPSEC_API_SAD_FLAG_IS_TUNNEL_V6));
13854   vat_json_object_add_uint (node, "udp_encap",
13855                             ! !(flags & IPSEC_API_SAD_FLAG_UDP_ENCAP));
13856   vat_json_object_add_bytes (node, "crypto_key", mp->entry.crypto_key.data,
13857                              mp->entry.crypto_key.length);
13858   vat_json_object_add_bytes (node, "integ_key", mp->entry.integrity_key.data,
13859                              mp->entry.integrity_key.length);
13860   vat_json_object_add_address (node, "src", &mp->entry.tunnel_src);
13861   vat_json_object_add_address (node, "dst", &mp->entry.tunnel_dst);
13862   vat_json_object_add_uint (node, "replay_window",
13863                             clib_net_to_host_u64 (mp->replay_window));
13864 }
13865
13866 static int
13867 api_ipsec_sa_dump (vat_main_t * vam)
13868 {
13869   unformat_input_t *i = vam->input;
13870   vl_api_ipsec_sa_dump_t *mp;
13871   vl_api_control_ping_t *mp_ping;
13872   u32 sa_id = ~0;
13873   int ret;
13874
13875   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13876     {
13877       if (unformat (i, "sa_id %d", &sa_id))
13878         ;
13879       else
13880         {
13881           clib_warning ("parse error '%U'", format_unformat_error, i);
13882           return -99;
13883         }
13884     }
13885
13886   M (IPSEC_SA_DUMP, mp);
13887
13888   mp->sa_id = ntohl (sa_id);
13889
13890   S (mp);
13891
13892   /* Use a control ping for synchronization */
13893   M (CONTROL_PING, mp_ping);
13894   S (mp_ping);
13895
13896   W (ret);
13897   return ret;
13898 }
13899
13900 static int
13901 api_ipsec_tunnel_if_set_sa (vat_main_t * vam)
13902 {
13903   unformat_input_t *i = vam->input;
13904   vl_api_ipsec_tunnel_if_set_sa_t *mp;
13905   u32 sw_if_index = ~0;
13906   u32 sa_id = ~0;
13907   u8 is_outbound = (u8) ~ 0;
13908   int ret;
13909
13910   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13911     {
13912       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13913         ;
13914       else if (unformat (i, "sa_id %d", &sa_id))
13915         ;
13916       else if (unformat (i, "outbound"))
13917         is_outbound = 1;
13918       else if (unformat (i, "inbound"))
13919         is_outbound = 0;
13920       else
13921         {
13922           clib_warning ("parse error '%U'", format_unformat_error, i);
13923           return -99;
13924         }
13925     }
13926
13927   if (sw_if_index == ~0)
13928     {
13929       errmsg ("interface must be specified");
13930       return -99;
13931     }
13932
13933   if (sa_id == ~0)
13934     {
13935       errmsg ("SA ID must be specified");
13936       return -99;
13937     }
13938
13939   M (IPSEC_TUNNEL_IF_SET_SA, mp);
13940
13941   mp->sw_if_index = htonl (sw_if_index);
13942   mp->sa_id = htonl (sa_id);
13943   mp->is_outbound = is_outbound;
13944
13945   S (mp);
13946   W (ret);
13947
13948   return ret;
13949 }
13950
13951 static int
13952 api_get_first_msg_id (vat_main_t * vam)
13953 {
13954   vl_api_get_first_msg_id_t *mp;
13955   unformat_input_t *i = vam->input;
13956   u8 *name;
13957   u8 name_set = 0;
13958   int ret;
13959
13960   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13961     {
13962       if (unformat (i, "client %s", &name))
13963         name_set = 1;
13964       else
13965         break;
13966     }
13967
13968   if (name_set == 0)
13969     {
13970       errmsg ("missing client name");
13971       return -99;
13972     }
13973   vec_add1 (name, 0);
13974
13975   if (vec_len (name) > 63)
13976     {
13977       errmsg ("client name too long");
13978       return -99;
13979     }
13980
13981   M (GET_FIRST_MSG_ID, mp);
13982   clib_memcpy (mp->name, name, vec_len (name));
13983   S (mp);
13984   W (ret);
13985   return ret;
13986 }
13987
13988 static int
13989 api_cop_interface_enable_disable (vat_main_t * vam)
13990 {
13991   unformat_input_t *line_input = vam->input;
13992   vl_api_cop_interface_enable_disable_t *mp;
13993   u32 sw_if_index = ~0;
13994   u8 enable_disable = 1;
13995   int ret;
13996
13997   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13998     {
13999       if (unformat (line_input, "disable"))
14000         enable_disable = 0;
14001       if (unformat (line_input, "enable"))
14002         enable_disable = 1;
14003       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
14004                          vam, &sw_if_index))
14005         ;
14006       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
14007         ;
14008       else
14009         break;
14010     }
14011
14012   if (sw_if_index == ~0)
14013     {
14014       errmsg ("missing interface name or sw_if_index");
14015       return -99;
14016     }
14017
14018   /* Construct the API message */
14019   M (COP_INTERFACE_ENABLE_DISABLE, mp);
14020   mp->sw_if_index = ntohl (sw_if_index);
14021   mp->enable_disable = enable_disable;
14022
14023   /* send it... */
14024   S (mp);
14025   /* Wait for the reply */
14026   W (ret);
14027   return ret;
14028 }
14029
14030 static int
14031 api_cop_whitelist_enable_disable (vat_main_t * vam)
14032 {
14033   unformat_input_t *line_input = vam->input;
14034   vl_api_cop_whitelist_enable_disable_t *mp;
14035   u32 sw_if_index = ~0;
14036   u8 ip4 = 0, ip6 = 0, default_cop = 0;
14037   u32 fib_id = 0;
14038   int ret;
14039
14040   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14041     {
14042       if (unformat (line_input, "ip4"))
14043         ip4 = 1;
14044       else if (unformat (line_input, "ip6"))
14045         ip6 = 1;
14046       else if (unformat (line_input, "default"))
14047         default_cop = 1;
14048       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
14049                          vam, &sw_if_index))
14050         ;
14051       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
14052         ;
14053       else if (unformat (line_input, "fib-id %d", &fib_id))
14054         ;
14055       else
14056         break;
14057     }
14058
14059   if (sw_if_index == ~0)
14060     {
14061       errmsg ("missing interface name or sw_if_index");
14062       return -99;
14063     }
14064
14065   /* Construct the API message */
14066   M (COP_WHITELIST_ENABLE_DISABLE, mp);
14067   mp->sw_if_index = ntohl (sw_if_index);
14068   mp->fib_id = ntohl (fib_id);
14069   mp->ip4 = ip4;
14070   mp->ip6 = ip6;
14071   mp->default_cop = default_cop;
14072
14073   /* send it... */
14074   S (mp);
14075   /* Wait for the reply */
14076   W (ret);
14077   return ret;
14078 }
14079
14080 static int
14081 api_get_node_graph (vat_main_t * vam)
14082 {
14083   vl_api_get_node_graph_t *mp;
14084   int ret;
14085
14086   M (GET_NODE_GRAPH, mp);
14087
14088   /* send it... */
14089   S (mp);
14090   /* Wait for the reply */
14091   W (ret);
14092   return ret;
14093 }
14094
14095 /* *INDENT-OFF* */
14096 /** Used for parsing LISP eids */
14097 typedef CLIB_PACKED(struct{
14098   u8 addr[16];   /**< eid address */
14099   u32 len;       /**< prefix length if IP */
14100   u8 type;      /**< type of eid */
14101 }) lisp_eid_vat_t;
14102 /* *INDENT-ON* */
14103
14104 static uword
14105 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
14106 {
14107   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
14108
14109   clib_memset (a, 0, sizeof (a[0]));
14110
14111   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
14112     {
14113       a->type = 0;              /* ipv4 type */
14114     }
14115   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
14116     {
14117       a->type = 1;              /* ipv6 type */
14118     }
14119   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
14120     {
14121       a->type = 2;              /* mac type */
14122     }
14123   else if (unformat (input, "%U", unformat_nsh_address, a->addr))
14124     {
14125       a->type = 3;              /* NSH type */
14126       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) a->addr;
14127       nsh->spi = clib_host_to_net_u32 (nsh->spi);
14128     }
14129   else
14130     {
14131       return 0;
14132     }
14133
14134   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
14135     {
14136       return 0;
14137     }
14138
14139   return 1;
14140 }
14141
14142 static int
14143 lisp_eid_size_vat (u8 type)
14144 {
14145   switch (type)
14146     {
14147     case 0:
14148       return 4;
14149     case 1:
14150       return 16;
14151     case 2:
14152       return 6;
14153     case 3:
14154       return 5;
14155     }
14156   return 0;
14157 }
14158
14159 static void
14160 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
14161 {
14162   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
14163 }
14164
14165 static int
14166 api_one_add_del_locator_set (vat_main_t * vam)
14167 {
14168   unformat_input_t *input = vam->input;
14169   vl_api_one_add_del_locator_set_t *mp;
14170   u8 is_add = 1;
14171   u8 *locator_set_name = NULL;
14172   u8 locator_set_name_set = 0;
14173   vl_api_local_locator_t locator, *locators = 0;
14174   u32 sw_if_index, priority, weight;
14175   u32 data_len = 0;
14176
14177   int ret;
14178   /* Parse args required to build the message */
14179   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14180     {
14181       if (unformat (input, "del"))
14182         {
14183           is_add = 0;
14184         }
14185       else if (unformat (input, "locator-set %s", &locator_set_name))
14186         {
14187           locator_set_name_set = 1;
14188         }
14189       else if (unformat (input, "sw_if_index %u p %u w %u",
14190                          &sw_if_index, &priority, &weight))
14191         {
14192           locator.sw_if_index = htonl (sw_if_index);
14193           locator.priority = priority;
14194           locator.weight = weight;
14195           vec_add1 (locators, locator);
14196         }
14197       else
14198         if (unformat
14199             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
14200              &sw_if_index, &priority, &weight))
14201         {
14202           locator.sw_if_index = htonl (sw_if_index);
14203           locator.priority = priority;
14204           locator.weight = weight;
14205           vec_add1 (locators, locator);
14206         }
14207       else
14208         break;
14209     }
14210
14211   if (locator_set_name_set == 0)
14212     {
14213       errmsg ("missing locator-set name");
14214       vec_free (locators);
14215       return -99;
14216     }
14217
14218   if (vec_len (locator_set_name) > 64)
14219     {
14220       errmsg ("locator-set name too long");
14221       vec_free (locator_set_name);
14222       vec_free (locators);
14223       return -99;
14224     }
14225   vec_add1 (locator_set_name, 0);
14226
14227   data_len = sizeof (vl_api_local_locator_t) * vec_len (locators);
14228
14229   /* Construct the API message */
14230   M2 (ONE_ADD_DEL_LOCATOR_SET, mp, data_len);
14231
14232   mp->is_add = is_add;
14233   clib_memcpy (mp->locator_set_name, locator_set_name,
14234                vec_len (locator_set_name));
14235   vec_free (locator_set_name);
14236
14237   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
14238   if (locators)
14239     clib_memcpy (mp->locators, locators, data_len);
14240   vec_free (locators);
14241
14242   /* send it... */
14243   S (mp);
14244
14245   /* Wait for a reply... */
14246   W (ret);
14247   return ret;
14248 }
14249
14250 #define api_lisp_add_del_locator_set api_one_add_del_locator_set
14251
14252 static int
14253 api_one_add_del_locator (vat_main_t * vam)
14254 {
14255   unformat_input_t *input = vam->input;
14256   vl_api_one_add_del_locator_t *mp;
14257   u32 tmp_if_index = ~0;
14258   u32 sw_if_index = ~0;
14259   u8 sw_if_index_set = 0;
14260   u8 sw_if_index_if_name_set = 0;
14261   u32 priority = ~0;
14262   u8 priority_set = 0;
14263   u32 weight = ~0;
14264   u8 weight_set = 0;
14265   u8 is_add = 1;
14266   u8 *locator_set_name = NULL;
14267   u8 locator_set_name_set = 0;
14268   int ret;
14269
14270   /* Parse args required to build the message */
14271   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14272     {
14273       if (unformat (input, "del"))
14274         {
14275           is_add = 0;
14276         }
14277       else if (unformat (input, "locator-set %s", &locator_set_name))
14278         {
14279           locator_set_name_set = 1;
14280         }
14281       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
14282                          &tmp_if_index))
14283         {
14284           sw_if_index_if_name_set = 1;
14285           sw_if_index = tmp_if_index;
14286         }
14287       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
14288         {
14289           sw_if_index_set = 1;
14290           sw_if_index = tmp_if_index;
14291         }
14292       else if (unformat (input, "p %d", &priority))
14293         {
14294           priority_set = 1;
14295         }
14296       else if (unformat (input, "w %d", &weight))
14297         {
14298           weight_set = 1;
14299         }
14300       else
14301         break;
14302     }
14303
14304   if (locator_set_name_set == 0)
14305     {
14306       errmsg ("missing locator-set name");
14307       return -99;
14308     }
14309
14310   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
14311     {
14312       errmsg ("missing sw_if_index");
14313       vec_free (locator_set_name);
14314       return -99;
14315     }
14316
14317   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
14318     {
14319       errmsg ("cannot use both params interface name and sw_if_index");
14320       vec_free (locator_set_name);
14321       return -99;
14322     }
14323
14324   if (priority_set == 0)
14325     {
14326       errmsg ("missing locator-set priority");
14327       vec_free (locator_set_name);
14328       return -99;
14329     }
14330
14331   if (weight_set == 0)
14332     {
14333       errmsg ("missing locator-set weight");
14334       vec_free (locator_set_name);
14335       return -99;
14336     }
14337
14338   if (vec_len (locator_set_name) > 64)
14339     {
14340       errmsg ("locator-set name too long");
14341       vec_free (locator_set_name);
14342       return -99;
14343     }
14344   vec_add1 (locator_set_name, 0);
14345
14346   /* Construct the API message */
14347   M (ONE_ADD_DEL_LOCATOR, mp);
14348
14349   mp->is_add = is_add;
14350   mp->sw_if_index = ntohl (sw_if_index);
14351   mp->priority = priority;
14352   mp->weight = weight;
14353   clib_memcpy (mp->locator_set_name, locator_set_name,
14354                vec_len (locator_set_name));
14355   vec_free (locator_set_name);
14356
14357   /* send it... */
14358   S (mp);
14359
14360   /* Wait for a reply... */
14361   W (ret);
14362   return ret;
14363 }
14364
14365 #define api_lisp_add_del_locator api_one_add_del_locator
14366
14367 uword
14368 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
14369 {
14370   u32 *key_id = va_arg (*args, u32 *);
14371   u8 *s = 0;
14372
14373   if (unformat (input, "%s", &s))
14374     {
14375       if (!strcmp ((char *) s, "sha1"))
14376         key_id[0] = HMAC_SHA_1_96;
14377       else if (!strcmp ((char *) s, "sha256"))
14378         key_id[0] = HMAC_SHA_256_128;
14379       else
14380         {
14381           clib_warning ("invalid key_id: '%s'", s);
14382           key_id[0] = HMAC_NO_KEY;
14383         }
14384     }
14385   else
14386     return 0;
14387
14388   vec_free (s);
14389   return 1;
14390 }
14391
14392 static int
14393 api_one_add_del_local_eid (vat_main_t * vam)
14394 {
14395   unformat_input_t *input = vam->input;
14396   vl_api_one_add_del_local_eid_t *mp;
14397   u8 is_add = 1;
14398   u8 eid_set = 0;
14399   lisp_eid_vat_t _eid, *eid = &_eid;
14400   u8 *locator_set_name = 0;
14401   u8 locator_set_name_set = 0;
14402   u32 vni = 0;
14403   u16 key_id = 0;
14404   u8 *key = 0;
14405   int ret;
14406
14407   /* Parse args required to build the message */
14408   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14409     {
14410       if (unformat (input, "del"))
14411         {
14412           is_add = 0;
14413         }
14414       else if (unformat (input, "vni %d", &vni))
14415         {
14416           ;
14417         }
14418       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
14419         {
14420           eid_set = 1;
14421         }
14422       else if (unformat (input, "locator-set %s", &locator_set_name))
14423         {
14424           locator_set_name_set = 1;
14425         }
14426       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
14427         ;
14428       else if (unformat (input, "secret-key %_%v%_", &key))
14429         ;
14430       else
14431         break;
14432     }
14433
14434   if (locator_set_name_set == 0)
14435     {
14436       errmsg ("missing locator-set name");
14437       return -99;
14438     }
14439
14440   if (0 == eid_set)
14441     {
14442       errmsg ("EID address not set!");
14443       vec_free (locator_set_name);
14444       return -99;
14445     }
14446
14447   if (key && (0 == key_id))
14448     {
14449       errmsg ("invalid key_id!");
14450       return -99;
14451     }
14452
14453   if (vec_len (key) > 64)
14454     {
14455       errmsg ("key too long");
14456       vec_free (key);
14457       return -99;
14458     }
14459
14460   if (vec_len (locator_set_name) > 64)
14461     {
14462       errmsg ("locator-set name too long");
14463       vec_free (locator_set_name);
14464       return -99;
14465     }
14466   vec_add1 (locator_set_name, 0);
14467
14468   /* Construct the API message */
14469   M (ONE_ADD_DEL_LOCAL_EID, mp);
14470
14471   mp->is_add = is_add;
14472   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
14473   mp->eid_type = eid->type;
14474   mp->prefix_len = eid->len;
14475   mp->vni = clib_host_to_net_u32 (vni);
14476   mp->key_id = clib_host_to_net_u16 (key_id);
14477   clib_memcpy (mp->locator_set_name, locator_set_name,
14478                vec_len (locator_set_name));
14479   clib_memcpy (mp->key, key, vec_len (key));
14480
14481   vec_free (locator_set_name);
14482   vec_free (key);
14483
14484   /* send it... */
14485   S (mp);
14486
14487   /* Wait for a reply... */
14488   W (ret);
14489   return ret;
14490 }
14491
14492 #define api_lisp_add_del_local_eid api_one_add_del_local_eid
14493
14494 static int
14495 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
14496 {
14497   u32 dp_table = 0, vni = 0;;
14498   unformat_input_t *input = vam->input;
14499   vl_api_gpe_add_del_fwd_entry_t *mp;
14500   u8 is_add = 1;
14501   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
14502   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
14503   u8 rmt_eid_set = 0, lcl_eid_set = 0;
14504   u32 action = ~0, w;
14505   ip4_address_t rmt_rloc4, lcl_rloc4;
14506   ip6_address_t rmt_rloc6, lcl_rloc6;
14507   vl_api_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
14508   int ret;
14509
14510   clib_memset (&rloc, 0, sizeof (rloc));
14511
14512   /* Parse args required to build the message */
14513   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14514     {
14515       if (unformat (input, "del"))
14516         is_add = 0;
14517       else if (unformat (input, "add"))
14518         is_add = 1;
14519       else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
14520         {
14521           rmt_eid_set = 1;
14522         }
14523       else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
14524         {
14525           lcl_eid_set = 1;
14526         }
14527       else if (unformat (input, "vrf %d", &dp_table))
14528         ;
14529       else if (unformat (input, "bd %d", &dp_table))
14530         ;
14531       else if (unformat (input, "vni %d", &vni))
14532         ;
14533       else if (unformat (input, "w %d", &w))
14534         {
14535           if (!curr_rloc)
14536             {
14537               errmsg ("No RLOC configured for setting priority/weight!");
14538               return -99;
14539             }
14540           curr_rloc->weight = w;
14541         }
14542       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
14543                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
14544         {
14545           rloc.is_ip4 = 1;
14546
14547           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
14548           rloc.weight = 0;
14549           vec_add1 (lcl_locs, rloc);
14550
14551           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
14552           vec_add1 (rmt_locs, rloc);
14553           /* weight saved in rmt loc */
14554           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
14555         }
14556       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
14557                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
14558         {
14559           rloc.is_ip4 = 0;
14560           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
14561           rloc.weight = 0;
14562           vec_add1 (lcl_locs, rloc);
14563
14564           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
14565           vec_add1 (rmt_locs, rloc);
14566           /* weight saved in rmt loc */
14567           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
14568         }
14569       else if (unformat (input, "action %d", &action))
14570         {
14571           ;
14572         }
14573       else
14574         {
14575           clib_warning ("parse error '%U'", format_unformat_error, input);
14576           return -99;
14577         }
14578     }
14579
14580   if (!rmt_eid_set)
14581     {
14582       errmsg ("remote eid addresses not set");
14583       return -99;
14584     }
14585
14586   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
14587     {
14588       errmsg ("eid types don't match");
14589       return -99;
14590     }
14591
14592   if (0 == rmt_locs && (u32) ~ 0 == action)
14593     {
14594       errmsg ("action not set for negative mapping");
14595       return -99;
14596     }
14597
14598   /* Construct the API message */
14599   M2 (GPE_ADD_DEL_FWD_ENTRY, mp,
14600       sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs) * 2);
14601
14602   mp->is_add = is_add;
14603   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
14604   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
14605   mp->eid_type = rmt_eid->type;
14606   mp->dp_table = clib_host_to_net_u32 (dp_table);
14607   mp->vni = clib_host_to_net_u32 (vni);
14608   mp->rmt_len = rmt_eid->len;
14609   mp->lcl_len = lcl_eid->len;
14610   mp->action = action;
14611
14612   if (0 != rmt_locs && 0 != lcl_locs)
14613     {
14614       mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
14615       clib_memcpy (mp->locs, lcl_locs,
14616                    (sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs)));
14617
14618       u32 offset = sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs);
14619       clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
14620                    (sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs)));
14621     }
14622   vec_free (lcl_locs);
14623   vec_free (rmt_locs);
14624
14625   /* send it... */
14626   S (mp);
14627
14628   /* Wait for a reply... */
14629   W (ret);
14630   return ret;
14631 }
14632
14633 static int
14634 api_one_add_del_map_server (vat_main_t * vam)
14635 {
14636   unformat_input_t *input = vam->input;
14637   vl_api_one_add_del_map_server_t *mp;
14638   u8 is_add = 1;
14639   u8 ipv4_set = 0;
14640   u8 ipv6_set = 0;
14641   ip4_address_t ipv4;
14642   ip6_address_t ipv6;
14643   int ret;
14644
14645   /* Parse args required to build the message */
14646   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14647     {
14648       if (unformat (input, "del"))
14649         {
14650           is_add = 0;
14651         }
14652       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
14653         {
14654           ipv4_set = 1;
14655         }
14656       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
14657         {
14658           ipv6_set = 1;
14659         }
14660       else
14661         break;
14662     }
14663
14664   if (ipv4_set && ipv6_set)
14665     {
14666       errmsg ("both eid v4 and v6 addresses set");
14667       return -99;
14668     }
14669
14670   if (!ipv4_set && !ipv6_set)
14671     {
14672       errmsg ("eid addresses not set");
14673       return -99;
14674     }
14675
14676   /* Construct the API message */
14677   M (ONE_ADD_DEL_MAP_SERVER, mp);
14678
14679   mp->is_add = is_add;
14680   if (ipv6_set)
14681     {
14682       mp->is_ipv6 = 1;
14683       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
14684     }
14685   else
14686     {
14687       mp->is_ipv6 = 0;
14688       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
14689     }
14690
14691   /* send it... */
14692   S (mp);
14693
14694   /* Wait for a reply... */
14695   W (ret);
14696   return ret;
14697 }
14698
14699 #define api_lisp_add_del_map_server api_one_add_del_map_server
14700
14701 static int
14702 api_one_add_del_map_resolver (vat_main_t * vam)
14703 {
14704   unformat_input_t *input = vam->input;
14705   vl_api_one_add_del_map_resolver_t *mp;
14706   u8 is_add = 1;
14707   u8 ipv4_set = 0;
14708   u8 ipv6_set = 0;
14709   ip4_address_t ipv4;
14710   ip6_address_t ipv6;
14711   int ret;
14712
14713   /* Parse args required to build the message */
14714   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14715     {
14716       if (unformat (input, "del"))
14717         {
14718           is_add = 0;
14719         }
14720       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
14721         {
14722           ipv4_set = 1;
14723         }
14724       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
14725         {
14726           ipv6_set = 1;
14727         }
14728       else
14729         break;
14730     }
14731
14732   if (ipv4_set && ipv6_set)
14733     {
14734       errmsg ("both eid v4 and v6 addresses set");
14735       return -99;
14736     }
14737
14738   if (!ipv4_set && !ipv6_set)
14739     {
14740       errmsg ("eid addresses not set");
14741       return -99;
14742     }
14743
14744   /* Construct the API message */
14745   M (ONE_ADD_DEL_MAP_RESOLVER, mp);
14746
14747   mp->is_add = is_add;
14748   if (ipv6_set)
14749     {
14750       mp->is_ipv6 = 1;
14751       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
14752     }
14753   else
14754     {
14755       mp->is_ipv6 = 0;
14756       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
14757     }
14758
14759   /* send it... */
14760   S (mp);
14761
14762   /* Wait for a reply... */
14763   W (ret);
14764   return ret;
14765 }
14766
14767 #define api_lisp_add_del_map_resolver api_one_add_del_map_resolver
14768
14769 static int
14770 api_lisp_gpe_enable_disable (vat_main_t * vam)
14771 {
14772   unformat_input_t *input = vam->input;
14773   vl_api_gpe_enable_disable_t *mp;
14774   u8 is_set = 0;
14775   u8 is_en = 1;
14776   int ret;
14777
14778   /* Parse args required to build the message */
14779   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14780     {
14781       if (unformat (input, "enable"))
14782         {
14783           is_set = 1;
14784           is_en = 1;
14785         }
14786       else if (unformat (input, "disable"))
14787         {
14788           is_set = 1;
14789           is_en = 0;
14790         }
14791       else
14792         break;
14793     }
14794
14795   if (is_set == 0)
14796     {
14797       errmsg ("Value not set");
14798       return -99;
14799     }
14800
14801   /* Construct the API message */
14802   M (GPE_ENABLE_DISABLE, mp);
14803
14804   mp->is_en = is_en;
14805
14806   /* send it... */
14807   S (mp);
14808
14809   /* Wait for a reply... */
14810   W (ret);
14811   return ret;
14812 }
14813
14814 static int
14815 api_one_rloc_probe_enable_disable (vat_main_t * vam)
14816 {
14817   unformat_input_t *input = vam->input;
14818   vl_api_one_rloc_probe_enable_disable_t *mp;
14819   u8 is_set = 0;
14820   u8 is_en = 0;
14821   int ret;
14822
14823   /* Parse args required to build the message */
14824   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14825     {
14826       if (unformat (input, "enable"))
14827         {
14828           is_set = 1;
14829           is_en = 1;
14830         }
14831       else if (unformat (input, "disable"))
14832         is_set = 1;
14833       else
14834         break;
14835     }
14836
14837   if (!is_set)
14838     {
14839       errmsg ("Value not set");
14840       return -99;
14841     }
14842
14843   /* Construct the API message */
14844   M (ONE_RLOC_PROBE_ENABLE_DISABLE, mp);
14845
14846   mp->is_enabled = is_en;
14847
14848   /* send it... */
14849   S (mp);
14850
14851   /* Wait for a reply... */
14852   W (ret);
14853   return ret;
14854 }
14855
14856 #define api_lisp_rloc_probe_enable_disable api_one_rloc_probe_enable_disable
14857
14858 static int
14859 api_one_map_register_enable_disable (vat_main_t * vam)
14860 {
14861   unformat_input_t *input = vam->input;
14862   vl_api_one_map_register_enable_disable_t *mp;
14863   u8 is_set = 0;
14864   u8 is_en = 0;
14865   int ret;
14866
14867   /* Parse args required to build the message */
14868   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14869     {
14870       if (unformat (input, "enable"))
14871         {
14872           is_set = 1;
14873           is_en = 1;
14874         }
14875       else if (unformat (input, "disable"))
14876         is_set = 1;
14877       else
14878         break;
14879     }
14880
14881   if (!is_set)
14882     {
14883       errmsg ("Value not set");
14884       return -99;
14885     }
14886
14887   /* Construct the API message */
14888   M (ONE_MAP_REGISTER_ENABLE_DISABLE, mp);
14889
14890   mp->is_enabled = is_en;
14891
14892   /* send it... */
14893   S (mp);
14894
14895   /* Wait for a reply... */
14896   W (ret);
14897   return ret;
14898 }
14899
14900 #define api_lisp_map_register_enable_disable api_one_map_register_enable_disable
14901
14902 static int
14903 api_one_enable_disable (vat_main_t * vam)
14904 {
14905   unformat_input_t *input = vam->input;
14906   vl_api_one_enable_disable_t *mp;
14907   u8 is_set = 0;
14908   u8 is_en = 0;
14909   int ret;
14910
14911   /* Parse args required to build the message */
14912   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14913     {
14914       if (unformat (input, "enable"))
14915         {
14916           is_set = 1;
14917           is_en = 1;
14918         }
14919       else if (unformat (input, "disable"))
14920         {
14921           is_set = 1;
14922         }
14923       else
14924         break;
14925     }
14926
14927   if (!is_set)
14928     {
14929       errmsg ("Value not set");
14930       return -99;
14931     }
14932
14933   /* Construct the API message */
14934   M (ONE_ENABLE_DISABLE, mp);
14935
14936   mp->is_en = is_en;
14937
14938   /* send it... */
14939   S (mp);
14940
14941   /* Wait for a reply... */
14942   W (ret);
14943   return ret;
14944 }
14945
14946 #define api_lisp_enable_disable api_one_enable_disable
14947
14948 static int
14949 api_one_enable_disable_xtr_mode (vat_main_t * vam)
14950 {
14951   unformat_input_t *input = vam->input;
14952   vl_api_one_enable_disable_xtr_mode_t *mp;
14953   u8 is_set = 0;
14954   u8 is_en = 0;
14955   int ret;
14956
14957   /* Parse args required to build the message */
14958   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14959     {
14960       if (unformat (input, "enable"))
14961         {
14962           is_set = 1;
14963           is_en = 1;
14964         }
14965       else if (unformat (input, "disable"))
14966         {
14967           is_set = 1;
14968         }
14969       else
14970         break;
14971     }
14972
14973   if (!is_set)
14974     {
14975       errmsg ("Value not set");
14976       return -99;
14977     }
14978
14979   /* Construct the API message */
14980   M (ONE_ENABLE_DISABLE_XTR_MODE, mp);
14981
14982   mp->is_en = is_en;
14983
14984   /* send it... */
14985   S (mp);
14986
14987   /* Wait for a reply... */
14988   W (ret);
14989   return ret;
14990 }
14991
14992 static int
14993 api_one_show_xtr_mode (vat_main_t * vam)
14994 {
14995   vl_api_one_show_xtr_mode_t *mp;
14996   int ret;
14997
14998   /* Construct the API message */
14999   M (ONE_SHOW_XTR_MODE, mp);
15000
15001   /* send it... */
15002   S (mp);
15003
15004   /* Wait for a reply... */
15005   W (ret);
15006   return ret;
15007 }
15008
15009 static int
15010 api_one_enable_disable_pitr_mode (vat_main_t * vam)
15011 {
15012   unformat_input_t *input = vam->input;
15013   vl_api_one_enable_disable_pitr_mode_t *mp;
15014   u8 is_set = 0;
15015   u8 is_en = 0;
15016   int ret;
15017
15018   /* Parse args required to build the message */
15019   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15020     {
15021       if (unformat (input, "enable"))
15022         {
15023           is_set = 1;
15024           is_en = 1;
15025         }
15026       else if (unformat (input, "disable"))
15027         {
15028           is_set = 1;
15029         }
15030       else
15031         break;
15032     }
15033
15034   if (!is_set)
15035     {
15036       errmsg ("Value not set");
15037       return -99;
15038     }
15039
15040   /* Construct the API message */
15041   M (ONE_ENABLE_DISABLE_PITR_MODE, mp);
15042
15043   mp->is_en = is_en;
15044
15045   /* send it... */
15046   S (mp);
15047
15048   /* Wait for a reply... */
15049   W (ret);
15050   return ret;
15051 }
15052
15053 static int
15054 api_one_show_pitr_mode (vat_main_t * vam)
15055 {
15056   vl_api_one_show_pitr_mode_t *mp;
15057   int ret;
15058
15059   /* Construct the API message */
15060   M (ONE_SHOW_PITR_MODE, mp);
15061
15062   /* send it... */
15063   S (mp);
15064
15065   /* Wait for a reply... */
15066   W (ret);
15067   return ret;
15068 }
15069
15070 static int
15071 api_one_enable_disable_petr_mode (vat_main_t * vam)
15072 {
15073   unformat_input_t *input = vam->input;
15074   vl_api_one_enable_disable_petr_mode_t *mp;
15075   u8 is_set = 0;
15076   u8 is_en = 0;
15077   int ret;
15078
15079   /* Parse args required to build the message */
15080   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15081     {
15082       if (unformat (input, "enable"))
15083         {
15084           is_set = 1;
15085           is_en = 1;
15086         }
15087       else if (unformat (input, "disable"))
15088         {
15089           is_set = 1;
15090         }
15091       else
15092         break;
15093     }
15094
15095   if (!is_set)
15096     {
15097       errmsg ("Value not set");
15098       return -99;
15099     }
15100
15101   /* Construct the API message */
15102   M (ONE_ENABLE_DISABLE_PETR_MODE, mp);
15103
15104   mp->is_en = is_en;
15105
15106   /* send it... */
15107   S (mp);
15108
15109   /* Wait for a reply... */
15110   W (ret);
15111   return ret;
15112 }
15113
15114 static int
15115 api_one_show_petr_mode (vat_main_t * vam)
15116 {
15117   vl_api_one_show_petr_mode_t *mp;
15118   int ret;
15119
15120   /* Construct the API message */
15121   M (ONE_SHOW_PETR_MODE, mp);
15122
15123   /* send it... */
15124   S (mp);
15125
15126   /* Wait for a reply... */
15127   W (ret);
15128   return ret;
15129 }
15130
15131 static int
15132 api_show_one_map_register_state (vat_main_t * vam)
15133 {
15134   vl_api_show_one_map_register_state_t *mp;
15135   int ret;
15136
15137   M (SHOW_ONE_MAP_REGISTER_STATE, mp);
15138
15139   /* send */
15140   S (mp);
15141
15142   /* wait for reply */
15143   W (ret);
15144   return ret;
15145 }
15146
15147 #define api_show_lisp_map_register_state api_show_one_map_register_state
15148
15149 static int
15150 api_show_one_rloc_probe_state (vat_main_t * vam)
15151 {
15152   vl_api_show_one_rloc_probe_state_t *mp;
15153   int ret;
15154
15155   M (SHOW_ONE_RLOC_PROBE_STATE, mp);
15156
15157   /* send */
15158   S (mp);
15159
15160   /* wait for reply */
15161   W (ret);
15162   return ret;
15163 }
15164
15165 #define api_show_lisp_rloc_probe_state api_show_one_rloc_probe_state
15166
15167 static int
15168 api_one_add_del_ndp_entry (vat_main_t * vam)
15169 {
15170   vl_api_one_add_del_ndp_entry_t *mp;
15171   unformat_input_t *input = vam->input;
15172   u8 is_add = 1;
15173   u8 mac_set = 0;
15174   u8 bd_set = 0;
15175   u8 ip_set = 0;
15176   u8 mac[6] = { 0, };
15177   u8 ip6[16] = { 0, };
15178   u32 bd = ~0;
15179   int ret;
15180
15181   /* Parse args required to build the message */
15182   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15183     {
15184       if (unformat (input, "del"))
15185         is_add = 0;
15186       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
15187         mac_set = 1;
15188       else if (unformat (input, "ip %U", unformat_ip6_address, ip6))
15189         ip_set = 1;
15190       else if (unformat (input, "bd %d", &bd))
15191         bd_set = 1;
15192       else
15193         {
15194           errmsg ("parse error '%U'", format_unformat_error, input);
15195           return -99;
15196         }
15197     }
15198
15199   if (!bd_set || !ip_set || (!mac_set && is_add))
15200     {
15201       errmsg ("Missing BD, IP or MAC!");
15202       return -99;
15203     }
15204
15205   M (ONE_ADD_DEL_NDP_ENTRY, mp);
15206   mp->is_add = is_add;
15207   clib_memcpy (mp->mac, mac, 6);
15208   mp->bd = clib_host_to_net_u32 (bd);
15209   clib_memcpy (mp->ip6, ip6, sizeof (mp->ip6));
15210
15211   /* send */
15212   S (mp);
15213
15214   /* wait for reply */
15215   W (ret);
15216   return ret;
15217 }
15218
15219 static int
15220 api_one_add_del_l2_arp_entry (vat_main_t * vam)
15221 {
15222   vl_api_one_add_del_l2_arp_entry_t *mp;
15223   unformat_input_t *input = vam->input;
15224   u8 is_add = 1;
15225   u8 mac_set = 0;
15226   u8 bd_set = 0;
15227   u8 ip_set = 0;
15228   u8 mac[6] = { 0, };
15229   u32 ip4 = 0, bd = ~0;
15230   int ret;
15231
15232   /* Parse args required to build the message */
15233   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15234     {
15235       if (unformat (input, "del"))
15236         is_add = 0;
15237       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
15238         mac_set = 1;
15239       else if (unformat (input, "ip %U", unformat_ip4_address, &ip4))
15240         ip_set = 1;
15241       else if (unformat (input, "bd %d", &bd))
15242         bd_set = 1;
15243       else
15244         {
15245           errmsg ("parse error '%U'", format_unformat_error, input);
15246           return -99;
15247         }
15248     }
15249
15250   if (!bd_set || !ip_set || (!mac_set && is_add))
15251     {
15252       errmsg ("Missing BD, IP or MAC!");
15253       return -99;
15254     }
15255
15256   M (ONE_ADD_DEL_L2_ARP_ENTRY, mp);
15257   mp->is_add = is_add;
15258   clib_memcpy (mp->mac, mac, 6);
15259   mp->bd = clib_host_to_net_u32 (bd);
15260   mp->ip4 = ip4;
15261
15262   /* send */
15263   S (mp);
15264
15265   /* wait for reply */
15266   W (ret);
15267   return ret;
15268 }
15269
15270 static int
15271 api_one_ndp_bd_get (vat_main_t * vam)
15272 {
15273   vl_api_one_ndp_bd_get_t *mp;
15274   int ret;
15275
15276   M (ONE_NDP_BD_GET, mp);
15277
15278   /* send */
15279   S (mp);
15280
15281   /* wait for reply */
15282   W (ret);
15283   return ret;
15284 }
15285
15286 static int
15287 api_one_ndp_entries_get (vat_main_t * vam)
15288 {
15289   vl_api_one_ndp_entries_get_t *mp;
15290   unformat_input_t *input = vam->input;
15291   u8 bd_set = 0;
15292   u32 bd = ~0;
15293   int ret;
15294
15295   /* Parse args required to build the message */
15296   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15297     {
15298       if (unformat (input, "bd %d", &bd))
15299         bd_set = 1;
15300       else
15301         {
15302           errmsg ("parse error '%U'", format_unformat_error, input);
15303           return -99;
15304         }
15305     }
15306
15307   if (!bd_set)
15308     {
15309       errmsg ("Expected bridge domain!");
15310       return -99;
15311     }
15312
15313   M (ONE_NDP_ENTRIES_GET, mp);
15314   mp->bd = clib_host_to_net_u32 (bd);
15315
15316   /* send */
15317   S (mp);
15318
15319   /* wait for reply */
15320   W (ret);
15321   return ret;
15322 }
15323
15324 static int
15325 api_one_l2_arp_bd_get (vat_main_t * vam)
15326 {
15327   vl_api_one_l2_arp_bd_get_t *mp;
15328   int ret;
15329
15330   M (ONE_L2_ARP_BD_GET, mp);
15331
15332   /* send */
15333   S (mp);
15334
15335   /* wait for reply */
15336   W (ret);
15337   return ret;
15338 }
15339
15340 static int
15341 api_one_l2_arp_entries_get (vat_main_t * vam)
15342 {
15343   vl_api_one_l2_arp_entries_get_t *mp;
15344   unformat_input_t *input = vam->input;
15345   u8 bd_set = 0;
15346   u32 bd = ~0;
15347   int ret;
15348
15349   /* Parse args required to build the message */
15350   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15351     {
15352       if (unformat (input, "bd %d", &bd))
15353         bd_set = 1;
15354       else
15355         {
15356           errmsg ("parse error '%U'", format_unformat_error, input);
15357           return -99;
15358         }
15359     }
15360
15361   if (!bd_set)
15362     {
15363       errmsg ("Expected bridge domain!");
15364       return -99;
15365     }
15366
15367   M (ONE_L2_ARP_ENTRIES_GET, mp);
15368   mp->bd = clib_host_to_net_u32 (bd);
15369
15370   /* send */
15371   S (mp);
15372
15373   /* wait for reply */
15374   W (ret);
15375   return ret;
15376 }
15377
15378 static int
15379 api_one_stats_enable_disable (vat_main_t * vam)
15380 {
15381   vl_api_one_stats_enable_disable_t *mp;
15382   unformat_input_t *input = vam->input;
15383   u8 is_set = 0;
15384   u8 is_en = 0;
15385   int ret;
15386
15387   /* Parse args required to build the message */
15388   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15389     {
15390       if (unformat (input, "enable"))
15391         {
15392           is_set = 1;
15393           is_en = 1;
15394         }
15395       else if (unformat (input, "disable"))
15396         {
15397           is_set = 1;
15398         }
15399       else
15400         break;
15401     }
15402
15403   if (!is_set)
15404     {
15405       errmsg ("Value not set");
15406       return -99;
15407     }
15408
15409   M (ONE_STATS_ENABLE_DISABLE, mp);
15410   mp->is_en = is_en;
15411
15412   /* send */
15413   S (mp);
15414
15415   /* wait for reply */
15416   W (ret);
15417   return ret;
15418 }
15419
15420 static int
15421 api_show_one_stats_enable_disable (vat_main_t * vam)
15422 {
15423   vl_api_show_one_stats_enable_disable_t *mp;
15424   int ret;
15425
15426   M (SHOW_ONE_STATS_ENABLE_DISABLE, mp);
15427
15428   /* send */
15429   S (mp);
15430
15431   /* wait for reply */
15432   W (ret);
15433   return ret;
15434 }
15435
15436 static int
15437 api_show_one_map_request_mode (vat_main_t * vam)
15438 {
15439   vl_api_show_one_map_request_mode_t *mp;
15440   int ret;
15441
15442   M (SHOW_ONE_MAP_REQUEST_MODE, mp);
15443
15444   /* send */
15445   S (mp);
15446
15447   /* wait for reply */
15448   W (ret);
15449   return ret;
15450 }
15451
15452 #define api_show_lisp_map_request_mode api_show_one_map_request_mode
15453
15454 static int
15455 api_one_map_request_mode (vat_main_t * vam)
15456 {
15457   unformat_input_t *input = vam->input;
15458   vl_api_one_map_request_mode_t *mp;
15459   u8 mode = 0;
15460   int ret;
15461
15462   /* Parse args required to build the message */
15463   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15464     {
15465       if (unformat (input, "dst-only"))
15466         mode = 0;
15467       else if (unformat (input, "src-dst"))
15468         mode = 1;
15469       else
15470         {
15471           errmsg ("parse error '%U'", format_unformat_error, input);
15472           return -99;
15473         }
15474     }
15475
15476   M (ONE_MAP_REQUEST_MODE, mp);
15477
15478   mp->mode = mode;
15479
15480   /* send */
15481   S (mp);
15482
15483   /* wait for reply */
15484   W (ret);
15485   return ret;
15486 }
15487
15488 #define api_lisp_map_request_mode api_one_map_request_mode
15489
15490 /**
15491  * Enable/disable ONE proxy ITR.
15492  *
15493  * @param vam vpp API test context
15494  * @return return code
15495  */
15496 static int
15497 api_one_pitr_set_locator_set (vat_main_t * vam)
15498 {
15499   u8 ls_name_set = 0;
15500   unformat_input_t *input = vam->input;
15501   vl_api_one_pitr_set_locator_set_t *mp;
15502   u8 is_add = 1;
15503   u8 *ls_name = 0;
15504   int ret;
15505
15506   /* Parse args required to build the message */
15507   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15508     {
15509       if (unformat (input, "del"))
15510         is_add = 0;
15511       else if (unformat (input, "locator-set %s", &ls_name))
15512         ls_name_set = 1;
15513       else
15514         {
15515           errmsg ("parse error '%U'", format_unformat_error, input);
15516           return -99;
15517         }
15518     }
15519
15520   if (!ls_name_set)
15521     {
15522       errmsg ("locator-set name not set!");
15523       return -99;
15524     }
15525
15526   M (ONE_PITR_SET_LOCATOR_SET, mp);
15527
15528   mp->is_add = is_add;
15529   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
15530   vec_free (ls_name);
15531
15532   /* send */
15533   S (mp);
15534
15535   /* wait for reply */
15536   W (ret);
15537   return ret;
15538 }
15539
15540 #define api_lisp_pitr_set_locator_set api_one_pitr_set_locator_set
15541
15542 static int
15543 api_one_nsh_set_locator_set (vat_main_t * vam)
15544 {
15545   u8 ls_name_set = 0;
15546   unformat_input_t *input = vam->input;
15547   vl_api_one_nsh_set_locator_set_t *mp;
15548   u8 is_add = 1;
15549   u8 *ls_name = 0;
15550   int ret;
15551
15552   /* Parse args required to build the message */
15553   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15554     {
15555       if (unformat (input, "del"))
15556         is_add = 0;
15557       else if (unformat (input, "ls %s", &ls_name))
15558         ls_name_set = 1;
15559       else
15560         {
15561           errmsg ("parse error '%U'", format_unformat_error, input);
15562           return -99;
15563         }
15564     }
15565
15566   if (!ls_name_set && is_add)
15567     {
15568       errmsg ("locator-set name not set!");
15569       return -99;
15570     }
15571
15572   M (ONE_NSH_SET_LOCATOR_SET, mp);
15573
15574   mp->is_add = is_add;
15575   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
15576   vec_free (ls_name);
15577
15578   /* send */
15579   S (mp);
15580
15581   /* wait for reply */
15582   W (ret);
15583   return ret;
15584 }
15585
15586 static int
15587 api_show_one_pitr (vat_main_t * vam)
15588 {
15589   vl_api_show_one_pitr_t *mp;
15590   int ret;
15591
15592   if (!vam->json_output)
15593     {
15594       print (vam->ofp, "%=20s", "lisp status:");
15595     }
15596
15597   M (SHOW_ONE_PITR, mp);
15598   /* send it... */
15599   S (mp);
15600
15601   /* Wait for a reply... */
15602   W (ret);
15603   return ret;
15604 }
15605
15606 #define api_show_lisp_pitr api_show_one_pitr
15607
15608 static int
15609 api_one_use_petr (vat_main_t * vam)
15610 {
15611   unformat_input_t *input = vam->input;
15612   vl_api_one_use_petr_t *mp;
15613   u8 is_add = 0;
15614   ip_address_t ip;
15615   int ret;
15616
15617   clib_memset (&ip, 0, sizeof (ip));
15618
15619   /* Parse args required to build the message */
15620   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15621     {
15622       if (unformat (input, "disable"))
15623         is_add = 0;
15624       else
15625         if (unformat (input, "%U", unformat_ip4_address, &ip_addr_v4 (&ip)))
15626         {
15627           is_add = 1;
15628           ip_addr_version (&ip) = AF_IP4;
15629         }
15630       else
15631         if (unformat (input, "%U", unformat_ip6_address, &ip_addr_v6 (&ip)))
15632         {
15633           is_add = 1;
15634           ip_addr_version (&ip) = AF_IP6;
15635         }
15636       else
15637         {
15638           errmsg ("parse error '%U'", format_unformat_error, input);
15639           return -99;
15640         }
15641     }
15642
15643   M (ONE_USE_PETR, mp);
15644
15645   mp->is_add = is_add;
15646   if (is_add)
15647     {
15648       mp->is_ip4 = ip_addr_version (&ip) == AF_IP4 ? 1 : 0;
15649       if (mp->is_ip4)
15650         clib_memcpy (mp->address, &ip, 4);
15651       else
15652         clib_memcpy (mp->address, &ip, 16);
15653     }
15654
15655   /* send */
15656   S (mp);
15657
15658   /* wait for reply */
15659   W (ret);
15660   return ret;
15661 }
15662
15663 #define api_lisp_use_petr api_one_use_petr
15664
15665 static int
15666 api_show_one_nsh_mapping (vat_main_t * vam)
15667 {
15668   vl_api_show_one_use_petr_t *mp;
15669   int ret;
15670
15671   if (!vam->json_output)
15672     {
15673       print (vam->ofp, "%=20s", "local ONE NSH mapping:");
15674     }
15675
15676   M (SHOW_ONE_NSH_MAPPING, mp);
15677   /* send it... */
15678   S (mp);
15679
15680   /* Wait for a reply... */
15681   W (ret);
15682   return ret;
15683 }
15684
15685 static int
15686 api_show_one_use_petr (vat_main_t * vam)
15687 {
15688   vl_api_show_one_use_petr_t *mp;
15689   int ret;
15690
15691   if (!vam->json_output)
15692     {
15693       print (vam->ofp, "%=20s", "Proxy-ETR status:");
15694     }
15695
15696   M (SHOW_ONE_USE_PETR, mp);
15697   /* send it... */
15698   S (mp);
15699
15700   /* Wait for a reply... */
15701   W (ret);
15702   return ret;
15703 }
15704
15705 #define api_show_lisp_use_petr api_show_one_use_petr
15706
15707 /**
15708  * Add/delete mapping between vni and vrf
15709  */
15710 static int
15711 api_one_eid_table_add_del_map (vat_main_t * vam)
15712 {
15713   unformat_input_t *input = vam->input;
15714   vl_api_one_eid_table_add_del_map_t *mp;
15715   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
15716   u32 vni, vrf, bd_index;
15717   int ret;
15718
15719   /* Parse args required to build the message */
15720   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15721     {
15722       if (unformat (input, "del"))
15723         is_add = 0;
15724       else if (unformat (input, "vrf %d", &vrf))
15725         vrf_set = 1;
15726       else if (unformat (input, "bd_index %d", &bd_index))
15727         bd_index_set = 1;
15728       else if (unformat (input, "vni %d", &vni))
15729         vni_set = 1;
15730       else
15731         break;
15732     }
15733
15734   if (!vni_set || (!vrf_set && !bd_index_set))
15735     {
15736       errmsg ("missing arguments!");
15737       return -99;
15738     }
15739
15740   if (vrf_set && bd_index_set)
15741     {
15742       errmsg ("error: both vrf and bd entered!");
15743       return -99;
15744     }
15745
15746   M (ONE_EID_TABLE_ADD_DEL_MAP, mp);
15747
15748   mp->is_add = is_add;
15749   mp->vni = htonl (vni);
15750   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
15751   mp->is_l2 = bd_index_set;
15752
15753   /* send */
15754   S (mp);
15755
15756   /* wait for reply */
15757   W (ret);
15758   return ret;
15759 }
15760
15761 #define api_lisp_eid_table_add_del_map api_one_eid_table_add_del_map
15762
15763 uword
15764 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
15765 {
15766   u32 *action = va_arg (*args, u32 *);
15767   u8 *s = 0;
15768
15769   if (unformat (input, "%s", &s))
15770     {
15771       if (!strcmp ((char *) s, "no-action"))
15772         action[0] = 0;
15773       else if (!strcmp ((char *) s, "natively-forward"))
15774         action[0] = 1;
15775       else if (!strcmp ((char *) s, "send-map-request"))
15776         action[0] = 2;
15777       else if (!strcmp ((char *) s, "drop"))
15778         action[0] = 3;
15779       else
15780         {
15781           clib_warning ("invalid action: '%s'", s);
15782           action[0] = 3;
15783         }
15784     }
15785   else
15786     return 0;
15787
15788   vec_free (s);
15789   return 1;
15790 }
15791
15792 /**
15793  * Add/del remote mapping to/from ONE control plane
15794  *
15795  * @param vam vpp API test context
15796  * @return return code
15797  */
15798 static int
15799 api_one_add_del_remote_mapping (vat_main_t * vam)
15800 {
15801   unformat_input_t *input = vam->input;
15802   vl_api_one_add_del_remote_mapping_t *mp;
15803   u32 vni = 0;
15804   lisp_eid_vat_t _eid, *eid = &_eid;
15805   lisp_eid_vat_t _seid, *seid = &_seid;
15806   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
15807   u32 action = ~0, p, w, data_len;
15808   ip4_address_t rloc4;
15809   ip6_address_t rloc6;
15810   vl_api_remote_locator_t *rlocs = 0, rloc, *curr_rloc = 0;
15811   int ret;
15812
15813   clib_memset (&rloc, 0, sizeof (rloc));
15814
15815   /* Parse args required to build the message */
15816   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15817     {
15818       if (unformat (input, "del-all"))
15819         {
15820           del_all = 1;
15821         }
15822       else if (unformat (input, "del"))
15823         {
15824           is_add = 0;
15825         }
15826       else if (unformat (input, "add"))
15827         {
15828           is_add = 1;
15829         }
15830       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
15831         {
15832           eid_set = 1;
15833         }
15834       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
15835         {
15836           seid_set = 1;
15837         }
15838       else if (unformat (input, "vni %d", &vni))
15839         {
15840           ;
15841         }
15842       else if (unformat (input, "p %d w %d", &p, &w))
15843         {
15844           if (!curr_rloc)
15845             {
15846               errmsg ("No RLOC configured for setting priority/weight!");
15847               return -99;
15848             }
15849           curr_rloc->priority = p;
15850           curr_rloc->weight = w;
15851         }
15852       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
15853         {
15854           rloc.is_ip4 = 1;
15855           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
15856           vec_add1 (rlocs, rloc);
15857           curr_rloc = &rlocs[vec_len (rlocs) - 1];
15858         }
15859       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
15860         {
15861           rloc.is_ip4 = 0;
15862           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
15863           vec_add1 (rlocs, rloc);
15864           curr_rloc = &rlocs[vec_len (rlocs) - 1];
15865         }
15866       else if (unformat (input, "action %U",
15867                          unformat_negative_mapping_action, &action))
15868         {
15869           ;
15870         }
15871       else
15872         {
15873           clib_warning ("parse error '%U'", format_unformat_error, input);
15874           return -99;
15875         }
15876     }
15877
15878   if (0 == eid_set)
15879     {
15880       errmsg ("missing params!");
15881       return -99;
15882     }
15883
15884   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
15885     {
15886       errmsg ("no action set for negative map-reply!");
15887       return -99;
15888     }
15889
15890   data_len = vec_len (rlocs) * sizeof (vl_api_remote_locator_t);
15891
15892   M2 (ONE_ADD_DEL_REMOTE_MAPPING, mp, data_len);
15893   mp->is_add = is_add;
15894   mp->vni = htonl (vni);
15895   mp->action = (u8) action;
15896   mp->is_src_dst = seid_set;
15897   mp->eid_len = eid->len;
15898   mp->seid_len = seid->len;
15899   mp->del_all = del_all;
15900   mp->eid_type = eid->type;
15901   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
15902   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
15903
15904   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
15905   clib_memcpy (mp->rlocs, rlocs, data_len);
15906   vec_free (rlocs);
15907
15908   /* send it... */
15909   S (mp);
15910
15911   /* Wait for a reply... */
15912   W (ret);
15913   return ret;
15914 }
15915
15916 #define api_lisp_add_del_remote_mapping api_one_add_del_remote_mapping
15917
15918 /**
15919  * Add/del ONE adjacency. Saves mapping in ONE control plane and updates
15920  * forwarding entries in data-plane accordingly.
15921  *
15922  * @param vam vpp API test context
15923  * @return return code
15924  */
15925 static int
15926 api_one_add_del_adjacency (vat_main_t * vam)
15927 {
15928   unformat_input_t *input = vam->input;
15929   vl_api_one_add_del_adjacency_t *mp;
15930   u32 vni = 0;
15931   ip4_address_t leid4, reid4;
15932   ip6_address_t leid6, reid6;
15933   u8 reid_mac[6] = { 0 };
15934   u8 leid_mac[6] = { 0 };
15935   u8 reid_type, leid_type;
15936   u32 leid_len = 0, reid_len = 0, len;
15937   u8 is_add = 1;
15938   int ret;
15939
15940   leid_type = reid_type = (u8) ~ 0;
15941
15942   /* Parse args required to build the message */
15943   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15944     {
15945       if (unformat (input, "del"))
15946         {
15947           is_add = 0;
15948         }
15949       else if (unformat (input, "add"))
15950         {
15951           is_add = 1;
15952         }
15953       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
15954                          &reid4, &len))
15955         {
15956           reid_type = 0;        /* ipv4 */
15957           reid_len = len;
15958         }
15959       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
15960                          &reid6, &len))
15961         {
15962           reid_type = 1;        /* ipv6 */
15963           reid_len = len;
15964         }
15965       else if (unformat (input, "reid %U", unformat_ethernet_address,
15966                          reid_mac))
15967         {
15968           reid_type = 2;        /* mac */
15969         }
15970       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
15971                          &leid4, &len))
15972         {
15973           leid_type = 0;        /* ipv4 */
15974           leid_len = len;
15975         }
15976       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
15977                          &leid6, &len))
15978         {
15979           leid_type = 1;        /* ipv6 */
15980           leid_len = len;
15981         }
15982       else if (unformat (input, "leid %U", unformat_ethernet_address,
15983                          leid_mac))
15984         {
15985           leid_type = 2;        /* mac */
15986         }
15987       else if (unformat (input, "vni %d", &vni))
15988         {
15989           ;
15990         }
15991       else
15992         {
15993           errmsg ("parse error '%U'", format_unformat_error, input);
15994           return -99;
15995         }
15996     }
15997
15998   if ((u8) ~ 0 == reid_type)
15999     {
16000       errmsg ("missing params!");
16001       return -99;
16002     }
16003
16004   if (leid_type != reid_type)
16005     {
16006       errmsg ("remote and local EIDs are of different types!");
16007       return -99;
16008     }
16009
16010   M (ONE_ADD_DEL_ADJACENCY, mp);
16011   mp->is_add = is_add;
16012   mp->vni = htonl (vni);
16013   mp->leid_len = leid_len;
16014   mp->reid_len = reid_len;
16015   mp->eid_type = reid_type;
16016
16017   switch (mp->eid_type)
16018     {
16019     case 0:
16020       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
16021       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
16022       break;
16023     case 1:
16024       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
16025       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
16026       break;
16027     case 2:
16028       clib_memcpy (mp->leid, leid_mac, 6);
16029       clib_memcpy (mp->reid, reid_mac, 6);
16030       break;
16031     default:
16032       errmsg ("unknown EID type %d!", mp->eid_type);
16033       return 0;
16034     }
16035
16036   /* send it... */
16037   S (mp);
16038
16039   /* Wait for a reply... */
16040   W (ret);
16041   return ret;
16042 }
16043
16044 #define api_lisp_add_del_adjacency api_one_add_del_adjacency
16045
16046 uword
16047 unformat_gpe_encap_mode (unformat_input_t * input, va_list * args)
16048 {
16049   u32 *mode = va_arg (*args, u32 *);
16050
16051   if (unformat (input, "lisp"))
16052     *mode = 0;
16053   else if (unformat (input, "vxlan"))
16054     *mode = 1;
16055   else
16056     return 0;
16057
16058   return 1;
16059 }
16060
16061 static int
16062 api_gpe_get_encap_mode (vat_main_t * vam)
16063 {
16064   vl_api_gpe_get_encap_mode_t *mp;
16065   int ret;
16066
16067   /* Construct the API message */
16068   M (GPE_GET_ENCAP_MODE, mp);
16069
16070   /* send it... */
16071   S (mp);
16072
16073   /* Wait for a reply... */
16074   W (ret);
16075   return ret;
16076 }
16077
16078 static int
16079 api_gpe_set_encap_mode (vat_main_t * vam)
16080 {
16081   unformat_input_t *input = vam->input;
16082   vl_api_gpe_set_encap_mode_t *mp;
16083   int ret;
16084   u32 mode = 0;
16085
16086   /* Parse args required to build the message */
16087   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16088     {
16089       if (unformat (input, "%U", unformat_gpe_encap_mode, &mode))
16090         ;
16091       else
16092         break;
16093     }
16094
16095   /* Construct the API message */
16096   M (GPE_SET_ENCAP_MODE, mp);
16097
16098   mp->mode = mode;
16099
16100   /* send it... */
16101   S (mp);
16102
16103   /* Wait for a reply... */
16104   W (ret);
16105   return ret;
16106 }
16107
16108 static int
16109 api_lisp_gpe_add_del_iface (vat_main_t * vam)
16110 {
16111   unformat_input_t *input = vam->input;
16112   vl_api_gpe_add_del_iface_t *mp;
16113   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
16114   u32 dp_table = 0, vni = 0;
16115   int ret;
16116
16117   /* Parse args required to build the message */
16118   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16119     {
16120       if (unformat (input, "up"))
16121         {
16122           action_set = 1;
16123           is_add = 1;
16124         }
16125       else if (unformat (input, "down"))
16126         {
16127           action_set = 1;
16128           is_add = 0;
16129         }
16130       else if (unformat (input, "table_id %d", &dp_table))
16131         {
16132           dp_table_set = 1;
16133         }
16134       else if (unformat (input, "bd_id %d", &dp_table))
16135         {
16136           dp_table_set = 1;
16137           is_l2 = 1;
16138         }
16139       else if (unformat (input, "vni %d", &vni))
16140         {
16141           vni_set = 1;
16142         }
16143       else
16144         break;
16145     }
16146
16147   if (action_set == 0)
16148     {
16149       errmsg ("Action not set");
16150       return -99;
16151     }
16152   if (dp_table_set == 0 || vni_set == 0)
16153     {
16154       errmsg ("vni and dp_table must be set");
16155       return -99;
16156     }
16157
16158   /* Construct the API message */
16159   M (GPE_ADD_DEL_IFACE, mp);
16160
16161   mp->is_add = is_add;
16162   mp->dp_table = clib_host_to_net_u32 (dp_table);
16163   mp->is_l2 = is_l2;
16164   mp->vni = clib_host_to_net_u32 (vni);
16165
16166   /* send it... */
16167   S (mp);
16168
16169   /* Wait for a reply... */
16170   W (ret);
16171   return ret;
16172 }
16173
16174 static int
16175 api_one_map_register_fallback_threshold (vat_main_t * vam)
16176 {
16177   unformat_input_t *input = vam->input;
16178   vl_api_one_map_register_fallback_threshold_t *mp;
16179   u32 value = 0;
16180   u8 is_set = 0;
16181   int ret;
16182
16183   /* Parse args required to build the message */
16184   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16185     {
16186       if (unformat (input, "%u", &value))
16187         is_set = 1;
16188       else
16189         {
16190           clib_warning ("parse error '%U'", format_unformat_error, input);
16191           return -99;
16192         }
16193     }
16194
16195   if (!is_set)
16196     {
16197       errmsg ("fallback threshold value is missing!");
16198       return -99;
16199     }
16200
16201   M (ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
16202   mp->value = clib_host_to_net_u32 (value);
16203
16204   /* send it... */
16205   S (mp);
16206
16207   /* Wait for a reply... */
16208   W (ret);
16209   return ret;
16210 }
16211
16212 static int
16213 api_show_one_map_register_fallback_threshold (vat_main_t * vam)
16214 {
16215   vl_api_show_one_map_register_fallback_threshold_t *mp;
16216   int ret;
16217
16218   M (SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
16219
16220   /* send it... */
16221   S (mp);
16222
16223   /* Wait for a reply... */
16224   W (ret);
16225   return ret;
16226 }
16227
16228 uword
16229 unformat_lisp_transport_protocol (unformat_input_t * input, va_list * args)
16230 {
16231   u32 *proto = va_arg (*args, u32 *);
16232
16233   if (unformat (input, "udp"))
16234     *proto = 1;
16235   else if (unformat (input, "api"))
16236     *proto = 2;
16237   else
16238     return 0;
16239
16240   return 1;
16241 }
16242
16243 static int
16244 api_one_set_transport_protocol (vat_main_t * vam)
16245 {
16246   unformat_input_t *input = vam->input;
16247   vl_api_one_set_transport_protocol_t *mp;
16248   u8 is_set = 0;
16249   u32 protocol = 0;
16250   int ret;
16251
16252   /* Parse args required to build the message */
16253   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16254     {
16255       if (unformat (input, "%U", unformat_lisp_transport_protocol, &protocol))
16256         is_set = 1;
16257       else
16258         {
16259           clib_warning ("parse error '%U'", format_unformat_error, input);
16260           return -99;
16261         }
16262     }
16263
16264   if (!is_set)
16265     {
16266       errmsg ("Transport protocol missing!");
16267       return -99;
16268     }
16269
16270   M (ONE_SET_TRANSPORT_PROTOCOL, mp);
16271   mp->protocol = (u8) protocol;
16272
16273   /* send it... */
16274   S (mp);
16275
16276   /* Wait for a reply... */
16277   W (ret);
16278   return ret;
16279 }
16280
16281 static int
16282 api_one_get_transport_protocol (vat_main_t * vam)
16283 {
16284   vl_api_one_get_transport_protocol_t *mp;
16285   int ret;
16286
16287   M (ONE_GET_TRANSPORT_PROTOCOL, mp);
16288
16289   /* send it... */
16290   S (mp);
16291
16292   /* Wait for a reply... */
16293   W (ret);
16294   return ret;
16295 }
16296
16297 static int
16298 api_one_map_register_set_ttl (vat_main_t * vam)
16299 {
16300   unformat_input_t *input = vam->input;
16301   vl_api_one_map_register_set_ttl_t *mp;
16302   u32 ttl = 0;
16303   u8 is_set = 0;
16304   int ret;
16305
16306   /* Parse args required to build the message */
16307   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16308     {
16309       if (unformat (input, "%u", &ttl))
16310         is_set = 1;
16311       else
16312         {
16313           clib_warning ("parse error '%U'", format_unformat_error, input);
16314           return -99;
16315         }
16316     }
16317
16318   if (!is_set)
16319     {
16320       errmsg ("TTL value missing!");
16321       return -99;
16322     }
16323
16324   M (ONE_MAP_REGISTER_SET_TTL, mp);
16325   mp->ttl = clib_host_to_net_u32 (ttl);
16326
16327   /* send it... */
16328   S (mp);
16329
16330   /* Wait for a reply... */
16331   W (ret);
16332   return ret;
16333 }
16334
16335 static int
16336 api_show_one_map_register_ttl (vat_main_t * vam)
16337 {
16338   vl_api_show_one_map_register_ttl_t *mp;
16339   int ret;
16340
16341   M (SHOW_ONE_MAP_REGISTER_TTL, mp);
16342
16343   /* send it... */
16344   S (mp);
16345
16346   /* Wait for a reply... */
16347   W (ret);
16348   return ret;
16349 }
16350
16351 /**
16352  * Add/del map request itr rlocs from ONE control plane and updates
16353  *
16354  * @param vam vpp API test context
16355  * @return return code
16356  */
16357 static int
16358 api_one_add_del_map_request_itr_rlocs (vat_main_t * vam)
16359 {
16360   unformat_input_t *input = vam->input;
16361   vl_api_one_add_del_map_request_itr_rlocs_t *mp;
16362   u8 *locator_set_name = 0;
16363   u8 locator_set_name_set = 0;
16364   u8 is_add = 1;
16365   int ret;
16366
16367   /* Parse args required to build the message */
16368   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16369     {
16370       if (unformat (input, "del"))
16371         {
16372           is_add = 0;
16373         }
16374       else if (unformat (input, "%_%v%_", &locator_set_name))
16375         {
16376           locator_set_name_set = 1;
16377         }
16378       else
16379         {
16380           clib_warning ("parse error '%U'", format_unformat_error, input);
16381           return -99;
16382         }
16383     }
16384
16385   if (is_add && !locator_set_name_set)
16386     {
16387       errmsg ("itr-rloc is not set!");
16388       return -99;
16389     }
16390
16391   if (is_add && vec_len (locator_set_name) > 64)
16392     {
16393       errmsg ("itr-rloc locator-set name too long");
16394       vec_free (locator_set_name);
16395       return -99;
16396     }
16397
16398   M (ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS, mp);
16399   mp->is_add = is_add;
16400   if (is_add)
16401     {
16402       clib_memcpy (mp->locator_set_name, locator_set_name,
16403                    vec_len (locator_set_name));
16404     }
16405   else
16406     {
16407       clib_memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
16408     }
16409   vec_free (locator_set_name);
16410
16411   /* send it... */
16412   S (mp);
16413
16414   /* Wait for a reply... */
16415   W (ret);
16416   return ret;
16417 }
16418
16419 #define api_lisp_add_del_map_request_itr_rlocs api_one_add_del_map_request_itr_rlocs
16420
16421 static int
16422 api_one_locator_dump (vat_main_t * vam)
16423 {
16424   unformat_input_t *input = vam->input;
16425   vl_api_one_locator_dump_t *mp;
16426   vl_api_control_ping_t *mp_ping;
16427   u8 is_index_set = 0, is_name_set = 0;
16428   u8 *ls_name = 0;
16429   u32 ls_index = ~0;
16430   int ret;
16431
16432   /* Parse args required to build the message */
16433   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16434     {
16435       if (unformat (input, "ls_name %_%v%_", &ls_name))
16436         {
16437           is_name_set = 1;
16438         }
16439       else if (unformat (input, "ls_index %d", &ls_index))
16440         {
16441           is_index_set = 1;
16442         }
16443       else
16444         {
16445           errmsg ("parse error '%U'", format_unformat_error, input);
16446           return -99;
16447         }
16448     }
16449
16450   if (!is_index_set && !is_name_set)
16451     {
16452       errmsg ("error: expected one of index or name!");
16453       return -99;
16454     }
16455
16456   if (is_index_set && is_name_set)
16457     {
16458       errmsg ("error: only one param expected!");
16459       return -99;
16460     }
16461
16462   if (vec_len (ls_name) > 62)
16463     {
16464       errmsg ("error: locator set name too long!");
16465       return -99;
16466     }
16467
16468   if (!vam->json_output)
16469     {
16470       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
16471     }
16472
16473   M (ONE_LOCATOR_DUMP, mp);
16474   mp->is_index_set = is_index_set;
16475
16476   if (is_index_set)
16477     mp->ls_index = clib_host_to_net_u32 (ls_index);
16478   else
16479     {
16480       vec_add1 (ls_name, 0);
16481       strncpy ((char *) mp->ls_name, (char *) ls_name,
16482                sizeof (mp->ls_name) - 1);
16483     }
16484
16485   /* send it... */
16486   S (mp);
16487
16488   /* Use a control ping for synchronization */
16489   MPING (CONTROL_PING, mp_ping);
16490   S (mp_ping);
16491
16492   /* Wait for a reply... */
16493   W (ret);
16494   return ret;
16495 }
16496
16497 #define api_lisp_locator_dump api_one_locator_dump
16498
16499 static int
16500 api_one_locator_set_dump (vat_main_t * vam)
16501 {
16502   vl_api_one_locator_set_dump_t *mp;
16503   vl_api_control_ping_t *mp_ping;
16504   unformat_input_t *input = vam->input;
16505   u8 filter = 0;
16506   int ret;
16507
16508   /* Parse args required to build the message */
16509   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16510     {
16511       if (unformat (input, "local"))
16512         {
16513           filter = 1;
16514         }
16515       else if (unformat (input, "remote"))
16516         {
16517           filter = 2;
16518         }
16519       else
16520         {
16521           errmsg ("parse error '%U'", format_unformat_error, input);
16522           return -99;
16523         }
16524     }
16525
16526   if (!vam->json_output)
16527     {
16528       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
16529     }
16530
16531   M (ONE_LOCATOR_SET_DUMP, mp);
16532
16533   mp->filter = filter;
16534
16535   /* send it... */
16536   S (mp);
16537
16538   /* Use a control ping for synchronization */
16539   MPING (CONTROL_PING, mp_ping);
16540   S (mp_ping);
16541
16542   /* Wait for a reply... */
16543   W (ret);
16544   return ret;
16545 }
16546
16547 #define api_lisp_locator_set_dump api_one_locator_set_dump
16548
16549 static int
16550 api_one_eid_table_map_dump (vat_main_t * vam)
16551 {
16552   u8 is_l2 = 0;
16553   u8 mode_set = 0;
16554   unformat_input_t *input = vam->input;
16555   vl_api_one_eid_table_map_dump_t *mp;
16556   vl_api_control_ping_t *mp_ping;
16557   int ret;
16558
16559   /* Parse args required to build the message */
16560   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16561     {
16562       if (unformat (input, "l2"))
16563         {
16564           is_l2 = 1;
16565           mode_set = 1;
16566         }
16567       else if (unformat (input, "l3"))
16568         {
16569           is_l2 = 0;
16570           mode_set = 1;
16571         }
16572       else
16573         {
16574           errmsg ("parse error '%U'", format_unformat_error, input);
16575           return -99;
16576         }
16577     }
16578
16579   if (!mode_set)
16580     {
16581       errmsg ("expected one of 'l2' or 'l3' parameter!");
16582       return -99;
16583     }
16584
16585   if (!vam->json_output)
16586     {
16587       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
16588     }
16589
16590   M (ONE_EID_TABLE_MAP_DUMP, mp);
16591   mp->is_l2 = is_l2;
16592
16593   /* send it... */
16594   S (mp);
16595
16596   /* Use a control ping for synchronization */
16597   MPING (CONTROL_PING, mp_ping);
16598   S (mp_ping);
16599
16600   /* Wait for a reply... */
16601   W (ret);
16602   return ret;
16603 }
16604
16605 #define api_lisp_eid_table_map_dump api_one_eid_table_map_dump
16606
16607 static int
16608 api_one_eid_table_vni_dump (vat_main_t * vam)
16609 {
16610   vl_api_one_eid_table_vni_dump_t *mp;
16611   vl_api_control_ping_t *mp_ping;
16612   int ret;
16613
16614   if (!vam->json_output)
16615     {
16616       print (vam->ofp, "VNI");
16617     }
16618
16619   M (ONE_EID_TABLE_VNI_DUMP, mp);
16620
16621   /* send it... */
16622   S (mp);
16623
16624   /* Use a control ping for synchronization */
16625   MPING (CONTROL_PING, mp_ping);
16626   S (mp_ping);
16627
16628   /* Wait for a reply... */
16629   W (ret);
16630   return ret;
16631 }
16632
16633 #define api_lisp_eid_table_vni_dump api_one_eid_table_vni_dump
16634
16635 static int
16636 api_one_eid_table_dump (vat_main_t * vam)
16637 {
16638   unformat_input_t *i = vam->input;
16639   vl_api_one_eid_table_dump_t *mp;
16640   vl_api_control_ping_t *mp_ping;
16641   struct in_addr ip4;
16642   struct in6_addr ip6;
16643   u8 mac[6];
16644   u8 eid_type = ~0, eid_set = 0;
16645   u32 prefix_length = ~0, t, vni = 0;
16646   u8 filter = 0;
16647   int ret;
16648   lisp_nsh_api_t nsh;
16649
16650   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16651     {
16652       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
16653         {
16654           eid_set = 1;
16655           eid_type = 0;
16656           prefix_length = t;
16657         }
16658       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
16659         {
16660           eid_set = 1;
16661           eid_type = 1;
16662           prefix_length = t;
16663         }
16664       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
16665         {
16666           eid_set = 1;
16667           eid_type = 2;
16668         }
16669       else if (unformat (i, "eid %U", unformat_nsh_address, &nsh))
16670         {
16671           eid_set = 1;
16672           eid_type = 3;
16673         }
16674       else if (unformat (i, "vni %d", &t))
16675         {
16676           vni = t;
16677         }
16678       else if (unformat (i, "local"))
16679         {
16680           filter = 1;
16681         }
16682       else if (unformat (i, "remote"))
16683         {
16684           filter = 2;
16685         }
16686       else
16687         {
16688           errmsg ("parse error '%U'", format_unformat_error, i);
16689           return -99;
16690         }
16691     }
16692
16693   if (!vam->json_output)
16694     {
16695       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
16696              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
16697     }
16698
16699   M (ONE_EID_TABLE_DUMP, mp);
16700
16701   mp->filter = filter;
16702   if (eid_set)
16703     {
16704       mp->eid_set = 1;
16705       mp->vni = htonl (vni);
16706       mp->eid_type = eid_type;
16707       switch (eid_type)
16708         {
16709         case 0:
16710           mp->prefix_length = prefix_length;
16711           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
16712           break;
16713         case 1:
16714           mp->prefix_length = prefix_length;
16715           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
16716           break;
16717         case 2:
16718           clib_memcpy (mp->eid, mac, sizeof (mac));
16719           break;
16720         case 3:
16721           clib_memcpy (mp->eid, &nsh, sizeof (nsh));
16722           break;
16723         default:
16724           errmsg ("unknown EID type %d!", eid_type);
16725           return -99;
16726         }
16727     }
16728
16729   /* send it... */
16730   S (mp);
16731
16732   /* Use a control ping for synchronization */
16733   MPING (CONTROL_PING, mp_ping);
16734   S (mp_ping);
16735
16736   /* Wait for a reply... */
16737   W (ret);
16738   return ret;
16739 }
16740
16741 #define api_lisp_eid_table_dump api_one_eid_table_dump
16742
16743 static int
16744 api_lisp_gpe_fwd_entries_get (vat_main_t * vam)
16745 {
16746   unformat_input_t *i = vam->input;
16747   vl_api_gpe_fwd_entries_get_t *mp;
16748   u8 vni_set = 0;
16749   u32 vni = ~0;
16750   int ret;
16751
16752   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16753     {
16754       if (unformat (i, "vni %d", &vni))
16755         {
16756           vni_set = 1;
16757         }
16758       else
16759         {
16760           errmsg ("parse error '%U'", format_unformat_error, i);
16761           return -99;
16762         }
16763     }
16764
16765   if (!vni_set)
16766     {
16767       errmsg ("vni not set!");
16768       return -99;
16769     }
16770
16771   if (!vam->json_output)
16772     {
16773       print (vam->ofp, "%10s %10s %s %40s", "fwd_index", "dp_table",
16774              "leid", "reid");
16775     }
16776
16777   M (GPE_FWD_ENTRIES_GET, mp);
16778   mp->vni = clib_host_to_net_u32 (vni);
16779
16780   /* send it... */
16781   S (mp);
16782
16783   /* Wait for a reply... */
16784   W (ret);
16785   return ret;
16786 }
16787
16788 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_endian vl_noop_handler
16789 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_print vl_noop_handler
16790 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_endian vl_noop_handler
16791 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_print vl_noop_handler
16792 #define vl_api_gpe_fwd_entries_get_reply_t_endian vl_noop_handler
16793 #define vl_api_gpe_fwd_entries_get_reply_t_print vl_noop_handler
16794 #define vl_api_gpe_fwd_entry_path_details_t_endian vl_noop_handler
16795 #define vl_api_gpe_fwd_entry_path_details_t_print vl_noop_handler
16796
16797 static int
16798 api_one_adjacencies_get (vat_main_t * vam)
16799 {
16800   unformat_input_t *i = vam->input;
16801   vl_api_one_adjacencies_get_t *mp;
16802   u8 vni_set = 0;
16803   u32 vni = ~0;
16804   int ret;
16805
16806   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16807     {
16808       if (unformat (i, "vni %d", &vni))
16809         {
16810           vni_set = 1;
16811         }
16812       else
16813         {
16814           errmsg ("parse error '%U'", format_unformat_error, i);
16815           return -99;
16816         }
16817     }
16818
16819   if (!vni_set)
16820     {
16821       errmsg ("vni not set!");
16822       return -99;
16823     }
16824
16825   if (!vam->json_output)
16826     {
16827       print (vam->ofp, "%s %40s", "leid", "reid");
16828     }
16829
16830   M (ONE_ADJACENCIES_GET, mp);
16831   mp->vni = clib_host_to_net_u32 (vni);
16832
16833   /* send it... */
16834   S (mp);
16835
16836   /* Wait for a reply... */
16837   W (ret);
16838   return ret;
16839 }
16840
16841 #define api_lisp_adjacencies_get api_one_adjacencies_get
16842
16843 static int
16844 api_gpe_native_fwd_rpaths_get (vat_main_t * vam)
16845 {
16846   unformat_input_t *i = vam->input;
16847   vl_api_gpe_native_fwd_rpaths_get_t *mp;
16848   int ret;
16849   u8 ip_family_set = 0, is_ip4 = 1;
16850
16851   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16852     {
16853       if (unformat (i, "ip4"))
16854         {
16855           ip_family_set = 1;
16856           is_ip4 = 1;
16857         }
16858       else if (unformat (i, "ip6"))
16859         {
16860           ip_family_set = 1;
16861           is_ip4 = 0;
16862         }
16863       else
16864         {
16865           errmsg ("parse error '%U'", format_unformat_error, i);
16866           return -99;
16867         }
16868     }
16869
16870   if (!ip_family_set)
16871     {
16872       errmsg ("ip family not set!");
16873       return -99;
16874     }
16875
16876   M (GPE_NATIVE_FWD_RPATHS_GET, mp);
16877   mp->is_ip4 = is_ip4;
16878
16879   /* send it... */
16880   S (mp);
16881
16882   /* Wait for a reply... */
16883   W (ret);
16884   return ret;
16885 }
16886
16887 static int
16888 api_gpe_fwd_entry_vnis_get (vat_main_t * vam)
16889 {
16890   vl_api_gpe_fwd_entry_vnis_get_t *mp;
16891   int ret;
16892
16893   if (!vam->json_output)
16894     {
16895       print (vam->ofp, "VNIs");
16896     }
16897
16898   M (GPE_FWD_ENTRY_VNIS_GET, mp);
16899
16900   /* send it... */
16901   S (mp);
16902
16903   /* Wait for a reply... */
16904   W (ret);
16905   return ret;
16906 }
16907
16908 static int
16909 api_gpe_add_del_native_fwd_rpath (vat_main_t * vam)
16910 {
16911   unformat_input_t *i = vam->input;
16912   vl_api_gpe_add_del_native_fwd_rpath_t *mp;
16913   int ret = 0;
16914   u8 is_add = 1, ip_set = 0, is_ip4 = 1;
16915   struct in_addr ip4;
16916   struct in6_addr ip6;
16917   u32 table_id = 0, nh_sw_if_index = ~0;
16918
16919   clib_memset (&ip4, 0, sizeof (ip4));
16920   clib_memset (&ip6, 0, sizeof (ip6));
16921
16922   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16923     {
16924       if (unformat (i, "del"))
16925         is_add = 0;
16926       else if (unformat (i, "via %U %U", unformat_ip4_address, &ip4,
16927                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
16928         {
16929           ip_set = 1;
16930           is_ip4 = 1;
16931         }
16932       else if (unformat (i, "via %U %U", unformat_ip6_address, &ip6,
16933                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
16934         {
16935           ip_set = 1;
16936           is_ip4 = 0;
16937         }
16938       else if (unformat (i, "via %U", unformat_ip4_address, &ip4))
16939         {
16940           ip_set = 1;
16941           is_ip4 = 1;
16942           nh_sw_if_index = ~0;
16943         }
16944       else if (unformat (i, "via %U", unformat_ip6_address, &ip6))
16945         {
16946           ip_set = 1;
16947           is_ip4 = 0;
16948           nh_sw_if_index = ~0;
16949         }
16950       else if (unformat (i, "table %d", &table_id))
16951         ;
16952       else
16953         {
16954           errmsg ("parse error '%U'", format_unformat_error, i);
16955           return -99;
16956         }
16957     }
16958
16959   if (!ip_set)
16960     {
16961       errmsg ("nh addr not set!");
16962       return -99;
16963     }
16964
16965   M (GPE_ADD_DEL_NATIVE_FWD_RPATH, mp);
16966   mp->is_add = is_add;
16967   mp->table_id = clib_host_to_net_u32 (table_id);
16968   mp->nh_sw_if_index = clib_host_to_net_u32 (nh_sw_if_index);
16969   mp->is_ip4 = is_ip4;
16970   if (is_ip4)
16971     clib_memcpy (mp->nh_addr, &ip4, sizeof (ip4));
16972   else
16973     clib_memcpy (mp->nh_addr, &ip6, sizeof (ip6));
16974
16975   /* send it... */
16976   S (mp);
16977
16978   /* Wait for a reply... */
16979   W (ret);
16980   return ret;
16981 }
16982
16983 static int
16984 api_one_map_server_dump (vat_main_t * vam)
16985 {
16986   vl_api_one_map_server_dump_t *mp;
16987   vl_api_control_ping_t *mp_ping;
16988   int ret;
16989
16990   if (!vam->json_output)
16991     {
16992       print (vam->ofp, "%=20s", "Map server");
16993     }
16994
16995   M (ONE_MAP_SERVER_DUMP, mp);
16996   /* send it... */
16997   S (mp);
16998
16999   /* Use a control ping for synchronization */
17000   MPING (CONTROL_PING, mp_ping);
17001   S (mp_ping);
17002
17003   /* Wait for a reply... */
17004   W (ret);
17005   return ret;
17006 }
17007
17008 #define api_lisp_map_server_dump api_one_map_server_dump
17009
17010 static int
17011 api_one_map_resolver_dump (vat_main_t * vam)
17012 {
17013   vl_api_one_map_resolver_dump_t *mp;
17014   vl_api_control_ping_t *mp_ping;
17015   int ret;
17016
17017   if (!vam->json_output)
17018     {
17019       print (vam->ofp, "%=20s", "Map resolver");
17020     }
17021
17022   M (ONE_MAP_RESOLVER_DUMP, mp);
17023   /* send it... */
17024   S (mp);
17025
17026   /* Use a control ping for synchronization */
17027   MPING (CONTROL_PING, mp_ping);
17028   S (mp_ping);
17029
17030   /* Wait for a reply... */
17031   W (ret);
17032   return ret;
17033 }
17034
17035 #define api_lisp_map_resolver_dump api_one_map_resolver_dump
17036
17037 static int
17038 api_one_stats_flush (vat_main_t * vam)
17039 {
17040   vl_api_one_stats_flush_t *mp;
17041   int ret = 0;
17042
17043   M (ONE_STATS_FLUSH, mp);
17044   S (mp);
17045   W (ret);
17046   return ret;
17047 }
17048
17049 static int
17050 api_one_stats_dump (vat_main_t * vam)
17051 {
17052   vl_api_one_stats_dump_t *mp;
17053   vl_api_control_ping_t *mp_ping;
17054   int ret;
17055
17056   M (ONE_STATS_DUMP, mp);
17057   /* send it... */
17058   S (mp);
17059
17060   /* Use a control ping for synchronization */
17061   MPING (CONTROL_PING, mp_ping);
17062   S (mp_ping);
17063
17064   /* Wait for a reply... */
17065   W (ret);
17066   return ret;
17067 }
17068
17069 static int
17070 api_show_one_status (vat_main_t * vam)
17071 {
17072   vl_api_show_one_status_t *mp;
17073   int ret;
17074
17075   if (!vam->json_output)
17076     {
17077       print (vam->ofp, "%-20s%-16s", "ONE status", "locator-set");
17078     }
17079
17080   M (SHOW_ONE_STATUS, mp);
17081   /* send it... */
17082   S (mp);
17083   /* Wait for a reply... */
17084   W (ret);
17085   return ret;
17086 }
17087
17088 #define api_show_lisp_status api_show_one_status
17089
17090 static int
17091 api_lisp_gpe_fwd_entry_path_dump (vat_main_t * vam)
17092 {
17093   vl_api_gpe_fwd_entry_path_dump_t *mp;
17094   vl_api_control_ping_t *mp_ping;
17095   unformat_input_t *i = vam->input;
17096   u32 fwd_entry_index = ~0;
17097   int ret;
17098
17099   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17100     {
17101       if (unformat (i, "index %d", &fwd_entry_index))
17102         ;
17103       else
17104         break;
17105     }
17106
17107   if (~0 == fwd_entry_index)
17108     {
17109       errmsg ("no index specified!");
17110       return -99;
17111     }
17112
17113   if (!vam->json_output)
17114     {
17115       print (vam->ofp, "first line");
17116     }
17117
17118   M (GPE_FWD_ENTRY_PATH_DUMP, mp);
17119
17120   /* send it... */
17121   S (mp);
17122   /* Use a control ping for synchronization */
17123   MPING (CONTROL_PING, mp_ping);
17124   S (mp_ping);
17125
17126   /* Wait for a reply... */
17127   W (ret);
17128   return ret;
17129 }
17130
17131 static int
17132 api_one_get_map_request_itr_rlocs (vat_main_t * vam)
17133 {
17134   vl_api_one_get_map_request_itr_rlocs_t *mp;
17135   int ret;
17136
17137   if (!vam->json_output)
17138     {
17139       print (vam->ofp, "%=20s", "itr-rlocs:");
17140     }
17141
17142   M (ONE_GET_MAP_REQUEST_ITR_RLOCS, mp);
17143   /* send it... */
17144   S (mp);
17145   /* Wait for a reply... */
17146   W (ret);
17147   return ret;
17148 }
17149
17150 #define api_lisp_get_map_request_itr_rlocs api_one_get_map_request_itr_rlocs
17151
17152 static int
17153 api_af_packet_create (vat_main_t * vam)
17154 {
17155   unformat_input_t *i = vam->input;
17156   vl_api_af_packet_create_t *mp;
17157   u8 *host_if_name = 0;
17158   u8 hw_addr[6];
17159   u8 random_hw_addr = 1;
17160   int ret;
17161
17162   clib_memset (hw_addr, 0, sizeof (hw_addr));
17163
17164   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17165     {
17166       if (unformat (i, "name %s", &host_if_name))
17167         vec_add1 (host_if_name, 0);
17168       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
17169         random_hw_addr = 0;
17170       else
17171         break;
17172     }
17173
17174   if (!vec_len (host_if_name))
17175     {
17176       errmsg ("host-interface name must be specified");
17177       return -99;
17178     }
17179
17180   if (vec_len (host_if_name) > 64)
17181     {
17182       errmsg ("host-interface name too long");
17183       return -99;
17184     }
17185
17186   M (AF_PACKET_CREATE, mp);
17187
17188   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
17189   clib_memcpy (mp->hw_addr, hw_addr, 6);
17190   mp->use_random_hw_addr = random_hw_addr;
17191   vec_free (host_if_name);
17192
17193   S (mp);
17194
17195   /* *INDENT-OFF* */
17196   W2 (ret,
17197       ({
17198         if (ret == 0)
17199           fprintf (vam->ofp ? vam->ofp : stderr,
17200                    " new sw_if_index = %d\n", vam->sw_if_index);
17201       }));
17202   /* *INDENT-ON* */
17203   return ret;
17204 }
17205
17206 static int
17207 api_af_packet_delete (vat_main_t * vam)
17208 {
17209   unformat_input_t *i = vam->input;
17210   vl_api_af_packet_delete_t *mp;
17211   u8 *host_if_name = 0;
17212   int ret;
17213
17214   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17215     {
17216       if (unformat (i, "name %s", &host_if_name))
17217         vec_add1 (host_if_name, 0);
17218       else
17219         break;
17220     }
17221
17222   if (!vec_len (host_if_name))
17223     {
17224       errmsg ("host-interface name must be specified");
17225       return -99;
17226     }
17227
17228   if (vec_len (host_if_name) > 64)
17229     {
17230       errmsg ("host-interface name too long");
17231       return -99;
17232     }
17233
17234   M (AF_PACKET_DELETE, mp);
17235
17236   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
17237   vec_free (host_if_name);
17238
17239   S (mp);
17240   W (ret);
17241   return ret;
17242 }
17243
17244 static void vl_api_af_packet_details_t_handler
17245   (vl_api_af_packet_details_t * mp)
17246 {
17247   vat_main_t *vam = &vat_main;
17248
17249   print (vam->ofp, "%-16s %d",
17250          mp->host_if_name, clib_net_to_host_u32 (mp->sw_if_index));
17251 }
17252
17253 static void vl_api_af_packet_details_t_handler_json
17254   (vl_api_af_packet_details_t * mp)
17255 {
17256   vat_main_t *vam = &vat_main;
17257   vat_json_node_t *node = NULL;
17258
17259   if (VAT_JSON_ARRAY != vam->json_tree.type)
17260     {
17261       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17262       vat_json_init_array (&vam->json_tree);
17263     }
17264   node = vat_json_array_add (&vam->json_tree);
17265
17266   vat_json_init_object (node);
17267   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
17268   vat_json_object_add_string_copy (node, "dev_name", mp->host_if_name);
17269 }
17270
17271 static int
17272 api_af_packet_dump (vat_main_t * vam)
17273 {
17274   vl_api_af_packet_dump_t *mp;
17275   vl_api_control_ping_t *mp_ping;
17276   int ret;
17277
17278   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
17279   /* Get list of tap interfaces */
17280   M (AF_PACKET_DUMP, mp);
17281   S (mp);
17282
17283   /* Use a control ping for synchronization */
17284   MPING (CONTROL_PING, mp_ping);
17285   S (mp_ping);
17286
17287   W (ret);
17288   return ret;
17289 }
17290
17291 static int
17292 api_policer_add_del (vat_main_t * vam)
17293 {
17294   unformat_input_t *i = vam->input;
17295   vl_api_policer_add_del_t *mp;
17296   u8 is_add = 1;
17297   u8 *name = 0;
17298   u32 cir = 0;
17299   u32 eir = 0;
17300   u64 cb = 0;
17301   u64 eb = 0;
17302   u8 rate_type = 0;
17303   u8 round_type = 0;
17304   u8 type = 0;
17305   u8 color_aware = 0;
17306   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
17307   int ret;
17308
17309   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
17310   conform_action.dscp = 0;
17311   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
17312   exceed_action.dscp = 0;
17313   violate_action.action_type = SSE2_QOS_ACTION_DROP;
17314   violate_action.dscp = 0;
17315
17316   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17317     {
17318       if (unformat (i, "del"))
17319         is_add = 0;
17320       else if (unformat (i, "name %s", &name))
17321         vec_add1 (name, 0);
17322       else if (unformat (i, "cir %u", &cir))
17323         ;
17324       else if (unformat (i, "eir %u", &eir))
17325         ;
17326       else if (unformat (i, "cb %u", &cb))
17327         ;
17328       else if (unformat (i, "eb %u", &eb))
17329         ;
17330       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
17331                          &rate_type))
17332         ;
17333       else if (unformat (i, "round_type %U", unformat_policer_round_type,
17334                          &round_type))
17335         ;
17336       else if (unformat (i, "type %U", unformat_policer_type, &type))
17337         ;
17338       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
17339                          &conform_action))
17340         ;
17341       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
17342                          &exceed_action))
17343         ;
17344       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
17345                          &violate_action))
17346         ;
17347       else if (unformat (i, "color-aware"))
17348         color_aware = 1;
17349       else
17350         break;
17351     }
17352
17353   if (!vec_len (name))
17354     {
17355       errmsg ("policer name must be specified");
17356       return -99;
17357     }
17358
17359   if (vec_len (name) > 64)
17360     {
17361       errmsg ("policer name too long");
17362       return -99;
17363     }
17364
17365   M (POLICER_ADD_DEL, mp);
17366
17367   clib_memcpy (mp->name, name, vec_len (name));
17368   vec_free (name);
17369   mp->is_add = is_add;
17370   mp->cir = ntohl (cir);
17371   mp->eir = ntohl (eir);
17372   mp->cb = clib_net_to_host_u64 (cb);
17373   mp->eb = clib_net_to_host_u64 (eb);
17374   mp->rate_type = rate_type;
17375   mp->round_type = round_type;
17376   mp->type = type;
17377   mp->conform_action_type = conform_action.action_type;
17378   mp->conform_dscp = conform_action.dscp;
17379   mp->exceed_action_type = exceed_action.action_type;
17380   mp->exceed_dscp = exceed_action.dscp;
17381   mp->violate_action_type = violate_action.action_type;
17382   mp->violate_dscp = violate_action.dscp;
17383   mp->color_aware = color_aware;
17384
17385   S (mp);
17386   W (ret);
17387   return ret;
17388 }
17389
17390 static int
17391 api_policer_dump (vat_main_t * vam)
17392 {
17393   unformat_input_t *i = vam->input;
17394   vl_api_policer_dump_t *mp;
17395   vl_api_control_ping_t *mp_ping;
17396   u8 *match_name = 0;
17397   u8 match_name_valid = 0;
17398   int ret;
17399
17400   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17401     {
17402       if (unformat (i, "name %s", &match_name))
17403         {
17404           vec_add1 (match_name, 0);
17405           match_name_valid = 1;
17406         }
17407       else
17408         break;
17409     }
17410
17411   M (POLICER_DUMP, mp);
17412   mp->match_name_valid = match_name_valid;
17413   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
17414   vec_free (match_name);
17415   /* send it... */
17416   S (mp);
17417
17418   /* Use a control ping for synchronization */
17419   MPING (CONTROL_PING, mp_ping);
17420   S (mp_ping);
17421
17422   /* Wait for a reply... */
17423   W (ret);
17424   return ret;
17425 }
17426
17427 static int
17428 api_policer_classify_set_interface (vat_main_t * vam)
17429 {
17430   unformat_input_t *i = vam->input;
17431   vl_api_policer_classify_set_interface_t *mp;
17432   u32 sw_if_index;
17433   int sw_if_index_set;
17434   u32 ip4_table_index = ~0;
17435   u32 ip6_table_index = ~0;
17436   u32 l2_table_index = ~0;
17437   u8 is_add = 1;
17438   int ret;
17439
17440   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17441     {
17442       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17443         sw_if_index_set = 1;
17444       else if (unformat (i, "sw_if_index %d", &sw_if_index))
17445         sw_if_index_set = 1;
17446       else if (unformat (i, "del"))
17447         is_add = 0;
17448       else if (unformat (i, "ip4-table %d", &ip4_table_index))
17449         ;
17450       else if (unformat (i, "ip6-table %d", &ip6_table_index))
17451         ;
17452       else if (unformat (i, "l2-table %d", &l2_table_index))
17453         ;
17454       else
17455         {
17456           clib_warning ("parse error '%U'", format_unformat_error, i);
17457           return -99;
17458         }
17459     }
17460
17461   if (sw_if_index_set == 0)
17462     {
17463       errmsg ("missing interface name or sw_if_index");
17464       return -99;
17465     }
17466
17467   M (POLICER_CLASSIFY_SET_INTERFACE, mp);
17468
17469   mp->sw_if_index = ntohl (sw_if_index);
17470   mp->ip4_table_index = ntohl (ip4_table_index);
17471   mp->ip6_table_index = ntohl (ip6_table_index);
17472   mp->l2_table_index = ntohl (l2_table_index);
17473   mp->is_add = is_add;
17474
17475   S (mp);
17476   W (ret);
17477   return ret;
17478 }
17479
17480 static int
17481 api_policer_classify_dump (vat_main_t * vam)
17482 {
17483   unformat_input_t *i = vam->input;
17484   vl_api_policer_classify_dump_t *mp;
17485   vl_api_control_ping_t *mp_ping;
17486   u8 type = POLICER_CLASSIFY_N_TABLES;
17487   int ret;
17488
17489   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
17490     ;
17491   else
17492     {
17493       errmsg ("classify table type must be specified");
17494       return -99;
17495     }
17496
17497   if (!vam->json_output)
17498     {
17499       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
17500     }
17501
17502   M (POLICER_CLASSIFY_DUMP, mp);
17503   mp->type = type;
17504   /* send it... */
17505   S (mp);
17506
17507   /* Use a control ping for synchronization */
17508   MPING (CONTROL_PING, mp_ping);
17509   S (mp_ping);
17510
17511   /* Wait for a reply... */
17512   W (ret);
17513   return ret;
17514 }
17515
17516 static int
17517 api_netmap_create (vat_main_t * vam)
17518 {
17519   unformat_input_t *i = vam->input;
17520   vl_api_netmap_create_t *mp;
17521   u8 *if_name = 0;
17522   u8 hw_addr[6];
17523   u8 random_hw_addr = 1;
17524   u8 is_pipe = 0;
17525   u8 is_master = 0;
17526   int ret;
17527
17528   clib_memset (hw_addr, 0, sizeof (hw_addr));
17529
17530   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17531     {
17532       if (unformat (i, "name %s", &if_name))
17533         vec_add1 (if_name, 0);
17534       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
17535         random_hw_addr = 0;
17536       else if (unformat (i, "pipe"))
17537         is_pipe = 1;
17538       else if (unformat (i, "master"))
17539         is_master = 1;
17540       else if (unformat (i, "slave"))
17541         is_master = 0;
17542       else
17543         break;
17544     }
17545
17546   if (!vec_len (if_name))
17547     {
17548       errmsg ("interface name must be specified");
17549       return -99;
17550     }
17551
17552   if (vec_len (if_name) > 64)
17553     {
17554       errmsg ("interface name too long");
17555       return -99;
17556     }
17557
17558   M (NETMAP_CREATE, mp);
17559
17560   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
17561   clib_memcpy (mp->hw_addr, hw_addr, 6);
17562   mp->use_random_hw_addr = random_hw_addr;
17563   mp->is_pipe = is_pipe;
17564   mp->is_master = is_master;
17565   vec_free (if_name);
17566
17567   S (mp);
17568   W (ret);
17569   return ret;
17570 }
17571
17572 static int
17573 api_netmap_delete (vat_main_t * vam)
17574 {
17575   unformat_input_t *i = vam->input;
17576   vl_api_netmap_delete_t *mp;
17577   u8 *if_name = 0;
17578   int ret;
17579
17580   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17581     {
17582       if (unformat (i, "name %s", &if_name))
17583         vec_add1 (if_name, 0);
17584       else
17585         break;
17586     }
17587
17588   if (!vec_len (if_name))
17589     {
17590       errmsg ("interface name must be specified");
17591       return -99;
17592     }
17593
17594   if (vec_len (if_name) > 64)
17595     {
17596       errmsg ("interface name too long");
17597       return -99;
17598     }
17599
17600   M (NETMAP_DELETE, mp);
17601
17602   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
17603   vec_free (if_name);
17604
17605   S (mp);
17606   W (ret);
17607   return ret;
17608 }
17609
17610 static u8 *
17611 format_fib_api_path_nh_proto (u8 * s, va_list * args)
17612 {
17613   vl_api_fib_path_nh_proto_t proto =
17614     va_arg (*args, vl_api_fib_path_nh_proto_t);
17615
17616   switch (proto)
17617     {
17618     case FIB_API_PATH_NH_PROTO_IP4:
17619       s = format (s, "ip4");
17620       break;
17621     case FIB_API_PATH_NH_PROTO_IP6:
17622       s = format (s, "ip6");
17623       break;
17624     case FIB_API_PATH_NH_PROTO_MPLS:
17625       s = format (s, "mpls");
17626       break;
17627     case FIB_API_PATH_NH_PROTO_BIER:
17628       s = format (s, "bier");
17629       break;
17630     case FIB_API_PATH_NH_PROTO_ETHERNET:
17631       s = format (s, "ethernet");
17632       break;
17633     }
17634
17635   return (s);
17636 }
17637
17638 static u8 *
17639 format_vl_api_ip_address_union (u8 * s, va_list * args)
17640 {
17641   vl_api_address_family_t af = va_arg (*args, vl_api_address_family_t);
17642   const vl_api_address_union_t *u = va_arg (*args, vl_api_address_union_t *);
17643
17644   switch (af)
17645     {
17646     case ADDRESS_IP4:
17647       s = format (s, "%U", format_ip4_address, u->ip4);
17648       break;
17649     case ADDRESS_IP6:
17650       s = format (s, "%U", format_ip6_address, u->ip6);
17651       break;
17652     }
17653   return (s);
17654 }
17655
17656 static u8 *
17657 format_vl_api_fib_path_type (u8 * s, va_list * args)
17658 {
17659   vl_api_fib_path_type_t t = va_arg (*args, vl_api_fib_path_type_t);
17660
17661   switch (t)
17662     {
17663     case FIB_API_PATH_TYPE_NORMAL:
17664       s = format (s, "normal");
17665       break;
17666     case FIB_API_PATH_TYPE_LOCAL:
17667       s = format (s, "local");
17668       break;
17669     case FIB_API_PATH_TYPE_DROP:
17670       s = format (s, "drop");
17671       break;
17672     case FIB_API_PATH_TYPE_UDP_ENCAP:
17673       s = format (s, "udp-encap");
17674       break;
17675     case FIB_API_PATH_TYPE_BIER_IMP:
17676       s = format (s, "bier-imp");
17677       break;
17678     case FIB_API_PATH_TYPE_ICMP_UNREACH:
17679       s = format (s, "unreach");
17680       break;
17681     case FIB_API_PATH_TYPE_ICMP_PROHIBIT:
17682       s = format (s, "prohibit");
17683       break;
17684     case FIB_API_PATH_TYPE_SOURCE_LOOKUP:
17685       s = format (s, "src-lookup");
17686       break;
17687     case FIB_API_PATH_TYPE_DVR:
17688       s = format (s, "dvr");
17689       break;
17690     case FIB_API_PATH_TYPE_INTERFACE_RX:
17691       s = format (s, "interface-rx");
17692       break;
17693     case FIB_API_PATH_TYPE_CLASSIFY:
17694       s = format (s, "classify");
17695       break;
17696     }
17697
17698   return (s);
17699 }
17700
17701 static void
17702 vl_api_fib_path_print (vat_main_t * vam, vl_api_fib_path_t * fp)
17703 {
17704   print (vam->ofp,
17705          "  weight %d, sw_if_index %d, type %U, afi %U, next_hop %U",
17706          ntohl (fp->weight), ntohl (fp->sw_if_index),
17707          format_vl_api_fib_path_type, fp->type,
17708          format_fib_api_path_nh_proto, fp->proto,
17709          format_vl_api_ip_address_union, &fp->nh.address);
17710 }
17711
17712 static void
17713 vl_api_mpls_fib_path_json_print (vat_json_node_t * node,
17714                                  vl_api_fib_path_t * fp)
17715 {
17716   struct in_addr ip4;
17717   struct in6_addr ip6;
17718
17719   vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
17720   vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
17721   vat_json_object_add_uint (node, "type", fp->type);
17722   vat_json_object_add_uint (node, "next_hop_proto", fp->proto);
17723   if (fp->proto == FIB_API_PATH_NH_PROTO_IP4)
17724     {
17725       clib_memcpy (&ip4, &fp->nh.address.ip4, sizeof (ip4));
17726       vat_json_object_add_ip4 (node, "next_hop", ip4);
17727     }
17728   else if (fp->proto == FIB_API_PATH_NH_PROTO_IP4)
17729     {
17730       clib_memcpy (&ip6, &fp->nh.address.ip6, sizeof (ip6));
17731       vat_json_object_add_ip6 (node, "next_hop", ip6);
17732     }
17733 }
17734
17735 static void
17736 vl_api_mpls_tunnel_details_t_handler (vl_api_mpls_tunnel_details_t * mp)
17737 {
17738   vat_main_t *vam = &vat_main;
17739   int count = ntohl (mp->mt_tunnel.mt_n_paths);
17740   vl_api_fib_path_t *fp;
17741   i32 i;
17742
17743   print (vam->ofp, "sw_if_index %d via:",
17744          ntohl (mp->mt_tunnel.mt_sw_if_index));
17745   fp = mp->mt_tunnel.mt_paths;
17746   for (i = 0; i < count; i++)
17747     {
17748       vl_api_fib_path_print (vam, fp);
17749       fp++;
17750     }
17751
17752   print (vam->ofp, "");
17753 }
17754
17755 #define vl_api_mpls_tunnel_details_t_endian vl_noop_handler
17756 #define vl_api_mpls_tunnel_details_t_print vl_noop_handler
17757
17758 static void
17759 vl_api_mpls_tunnel_details_t_handler_json (vl_api_mpls_tunnel_details_t * mp)
17760 {
17761   vat_main_t *vam = &vat_main;
17762   vat_json_node_t *node = NULL;
17763   int count = ntohl (mp->mt_tunnel.mt_n_paths);
17764   vl_api_fib_path_t *fp;
17765   i32 i;
17766
17767   if (VAT_JSON_ARRAY != vam->json_tree.type)
17768     {
17769       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17770       vat_json_init_array (&vam->json_tree);
17771     }
17772   node = vat_json_array_add (&vam->json_tree);
17773
17774   vat_json_init_object (node);
17775   vat_json_object_add_uint (node, "sw_if_index",
17776                             ntohl (mp->mt_tunnel.mt_sw_if_index));
17777
17778   vat_json_object_add_uint (node, "l2_only", mp->mt_tunnel.mt_l2_only);
17779
17780   fp = mp->mt_tunnel.mt_paths;
17781   for (i = 0; i < count; i++)
17782     {
17783       vl_api_mpls_fib_path_json_print (node, fp);
17784       fp++;
17785     }
17786 }
17787
17788 static int
17789 api_mpls_tunnel_dump (vat_main_t * vam)
17790 {
17791   vl_api_mpls_tunnel_dump_t *mp;
17792   vl_api_control_ping_t *mp_ping;
17793   int ret;
17794
17795   M (MPLS_TUNNEL_DUMP, mp);
17796
17797   S (mp);
17798
17799   /* Use a control ping for synchronization */
17800   MPING (CONTROL_PING, mp_ping);
17801   S (mp_ping);
17802
17803   W (ret);
17804   return ret;
17805 }
17806
17807 #define vl_api_mpls_table_details_t_endian vl_noop_handler
17808 #define vl_api_mpls_table_details_t_print vl_noop_handler
17809
17810
17811 static void
17812 vl_api_mpls_table_details_t_handler (vl_api_mpls_table_details_t * mp)
17813 {
17814   vat_main_t *vam = &vat_main;
17815
17816   print (vam->ofp, "table-id %d,", ntohl (mp->mt_table.mt_table_id));
17817 }
17818
17819 static void vl_api_mpls_table_details_t_handler_json
17820   (vl_api_mpls_table_details_t * mp)
17821 {
17822   vat_main_t *vam = &vat_main;
17823   vat_json_node_t *node = NULL;
17824
17825   if (VAT_JSON_ARRAY != vam->json_tree.type)
17826     {
17827       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17828       vat_json_init_array (&vam->json_tree);
17829     }
17830   node = vat_json_array_add (&vam->json_tree);
17831
17832   vat_json_init_object (node);
17833   vat_json_object_add_uint (node, "table", ntohl (mp->mt_table.mt_table_id));
17834 }
17835
17836 static int
17837 api_mpls_table_dump (vat_main_t * vam)
17838 {
17839   vl_api_mpls_table_dump_t *mp;
17840   vl_api_control_ping_t *mp_ping;
17841   int ret;
17842
17843   M (MPLS_TABLE_DUMP, mp);
17844   S (mp);
17845
17846   /* Use a control ping for synchronization */
17847   MPING (CONTROL_PING, mp_ping);
17848   S (mp_ping);
17849
17850   W (ret);
17851   return ret;
17852 }
17853
17854 #define vl_api_mpls_route_details_t_endian vl_noop_handler
17855 #define vl_api_mpls_route_details_t_print vl_noop_handler
17856
17857 static void
17858 vl_api_mpls_route_details_t_handler (vl_api_mpls_route_details_t * mp)
17859 {
17860   vat_main_t *vam = &vat_main;
17861   int count = (int) clib_net_to_host_u32 (mp->mr_route.mr_n_paths);
17862   vl_api_fib_path_t *fp;
17863   int i;
17864
17865   print (vam->ofp,
17866          "table-id %d, label %u, ess_bit %u",
17867          ntohl (mp->mr_route.mr_table_id),
17868          ntohl (mp->mr_route.mr_label), mp->mr_route.mr_eos);
17869   fp = mp->mr_route.mr_paths;
17870   for (i = 0; i < count; i++)
17871     {
17872       vl_api_fib_path_print (vam, fp);
17873       fp++;
17874     }
17875 }
17876
17877 static void vl_api_mpls_route_details_t_handler_json
17878   (vl_api_mpls_route_details_t * mp)
17879 {
17880   vat_main_t *vam = &vat_main;
17881   int count = (int) clib_host_to_net_u32 (mp->mr_route.mr_n_paths);
17882   vat_json_node_t *node = NULL;
17883   vl_api_fib_path_t *fp;
17884   int i;
17885
17886   if (VAT_JSON_ARRAY != vam->json_tree.type)
17887     {
17888       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17889       vat_json_init_array (&vam->json_tree);
17890     }
17891   node = vat_json_array_add (&vam->json_tree);
17892
17893   vat_json_init_object (node);
17894   vat_json_object_add_uint (node, "table", ntohl (mp->mr_route.mr_table_id));
17895   vat_json_object_add_uint (node, "s_bit", mp->mr_route.mr_eos);
17896   vat_json_object_add_uint (node, "label", ntohl (mp->mr_route.mr_label));
17897   vat_json_object_add_uint (node, "path_count", count);
17898   fp = mp->mr_route.mr_paths;
17899   for (i = 0; i < count; i++)
17900     {
17901       vl_api_mpls_fib_path_json_print (node, fp);
17902       fp++;
17903     }
17904 }
17905
17906 static int
17907 api_mpls_route_dump (vat_main_t * vam)
17908 {
17909   unformat_input_t *input = vam->input;
17910   vl_api_mpls_route_dump_t *mp;
17911   vl_api_control_ping_t *mp_ping;
17912   u32 table_id;
17913   int ret;
17914
17915   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17916     {
17917       if (unformat (input, "table_id %d", &table_id))
17918         ;
17919       else
17920         break;
17921     }
17922   if (table_id == ~0)
17923     {
17924       errmsg ("missing table id");
17925       return -99;
17926     }
17927
17928   M (MPLS_ROUTE_DUMP, mp);
17929
17930   mp->table.mt_table_id = ntohl (table_id);
17931   S (mp);
17932
17933   /* Use a control ping for synchronization */
17934   MPING (CONTROL_PING, mp_ping);
17935   S (mp_ping);
17936
17937   W (ret);
17938   return ret;
17939 }
17940
17941 #define vl_api_ip_table_details_t_endian vl_noop_handler
17942 #define vl_api_ip_table_details_t_print vl_noop_handler
17943
17944 static void
17945 vl_api_ip_table_details_t_handler (vl_api_ip_table_details_t * mp)
17946 {
17947   vat_main_t *vam = &vat_main;
17948
17949   print (vam->ofp,
17950          "%s; table-id %d, prefix %U/%d",
17951          mp->table.name, ntohl (mp->table.table_id));
17952 }
17953
17954
17955 static void vl_api_ip_table_details_t_handler_json
17956   (vl_api_ip_table_details_t * mp)
17957 {
17958   vat_main_t *vam = &vat_main;
17959   vat_json_node_t *node = NULL;
17960
17961   if (VAT_JSON_ARRAY != vam->json_tree.type)
17962     {
17963       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17964       vat_json_init_array (&vam->json_tree);
17965     }
17966   node = vat_json_array_add (&vam->json_tree);
17967
17968   vat_json_init_object (node);
17969   vat_json_object_add_uint (node, "table", ntohl (mp->table.table_id));
17970 }
17971
17972 static int
17973 api_ip_table_dump (vat_main_t * vam)
17974 {
17975   vl_api_ip_table_dump_t *mp;
17976   vl_api_control_ping_t *mp_ping;
17977   int ret;
17978
17979   M (IP_TABLE_DUMP, mp);
17980   S (mp);
17981
17982   /* Use a control ping for synchronization */
17983   MPING (CONTROL_PING, mp_ping);
17984   S (mp_ping);
17985
17986   W (ret);
17987   return ret;
17988 }
17989
17990 static int
17991 api_ip_mtable_dump (vat_main_t * vam)
17992 {
17993   vl_api_ip_mtable_dump_t *mp;
17994   vl_api_control_ping_t *mp_ping;
17995   int ret;
17996
17997   M (IP_MTABLE_DUMP, mp);
17998   S (mp);
17999
18000   /* Use a control ping for synchronization */
18001   MPING (CONTROL_PING, mp_ping);
18002   S (mp_ping);
18003
18004   W (ret);
18005   return ret;
18006 }
18007
18008 static int
18009 api_ip_mroute_dump (vat_main_t * vam)
18010 {
18011   unformat_input_t *input = vam->input;
18012   vl_api_control_ping_t *mp_ping;
18013   vl_api_ip_mroute_dump_t *mp;
18014   int ret, is_ip6;
18015   u32 table_id;
18016
18017   is_ip6 = 0;
18018   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18019     {
18020       if (unformat (input, "table_id %d", &table_id))
18021         ;
18022       else if (unformat (input, "ip6"))
18023         is_ip6 = 1;
18024       else if (unformat (input, "ip4"))
18025         is_ip6 = 0;
18026       else
18027         break;
18028     }
18029   if (table_id == ~0)
18030     {
18031       errmsg ("missing table id");
18032       return -99;
18033     }
18034
18035   M (IP_MROUTE_DUMP, mp);
18036   mp->table.table_id = table_id;
18037   mp->table.is_ip6 = is_ip6;
18038   S (mp);
18039
18040   /* Use a control ping for synchronization */
18041   MPING (CONTROL_PING, mp_ping);
18042   S (mp_ping);
18043
18044   W (ret);
18045   return ret;
18046 }
18047
18048 #define vl_api_ip_route_details_t_endian vl_noop_handler
18049 #define vl_api_ip_route_details_t_print vl_noop_handler
18050
18051 static void
18052 vl_api_ip_route_details_t_handler (vl_api_ip_route_details_t * mp)
18053 {
18054   vat_main_t *vam = &vat_main;
18055   u8 count = mp->route.n_paths;
18056   vl_api_fib_path_t *fp;
18057   int i;
18058
18059   print (vam->ofp,
18060          "table-id %d, prefix %U/%d",
18061          ntohl (mp->route.table_id),
18062          format_ip46_address, mp->route.prefix.address, mp->route.prefix.len);
18063   for (i = 0; i < count; i++)
18064     {
18065       fp = &mp->route.paths[i];
18066
18067       vl_api_fib_path_print (vam, fp);
18068       fp++;
18069     }
18070 }
18071
18072 static void vl_api_ip_route_details_t_handler_json
18073   (vl_api_ip_route_details_t * mp)
18074 {
18075   vat_main_t *vam = &vat_main;
18076   u8 count = mp->route.n_paths;
18077   vat_json_node_t *node = NULL;
18078   struct in_addr ip4;
18079   struct in6_addr ip6;
18080   vl_api_fib_path_t *fp;
18081   int i;
18082
18083   if (VAT_JSON_ARRAY != vam->json_tree.type)
18084     {
18085       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18086       vat_json_init_array (&vam->json_tree);
18087     }
18088   node = vat_json_array_add (&vam->json_tree);
18089
18090   vat_json_init_object (node);
18091   vat_json_object_add_uint (node, "table", ntohl (mp->route.table_id));
18092   if (ADDRESS_IP6 == mp->route.prefix.address.af)
18093     {
18094       clib_memcpy (&ip6, &mp->route.prefix.address.un.ip6, sizeof (ip6));
18095       vat_json_object_add_ip6 (node, "prefix", ip6);
18096     }
18097   else
18098     {
18099       clib_memcpy (&ip4, &mp->route.prefix.address.un.ip4, sizeof (ip4));
18100       vat_json_object_add_ip4 (node, "prefix", ip4);
18101     }
18102   vat_json_object_add_uint (node, "mask_length", mp->route.prefix.len);
18103   vat_json_object_add_uint (node, "path_count", count);
18104   for (i = 0; i < count; i++)
18105     {
18106       fp = &mp->route.paths[i];
18107       vl_api_mpls_fib_path_json_print (node, fp);
18108     }
18109 }
18110
18111 static int
18112 api_ip_route_dump (vat_main_t * vam)
18113 {
18114   unformat_input_t *input = vam->input;
18115   vl_api_ip_route_dump_t *mp;
18116   vl_api_control_ping_t *mp_ping;
18117   u32 table_id;
18118   u8 is_ip6;
18119   int ret;
18120
18121   is_ip6 = 0;
18122   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18123     {
18124       if (unformat (input, "table_id %d", &table_id))
18125         ;
18126       else if (unformat (input, "ip6"))
18127         is_ip6 = 1;
18128       else if (unformat (input, "ip4"))
18129         is_ip6 = 0;
18130       else
18131         break;
18132     }
18133   if (table_id == ~0)
18134     {
18135       errmsg ("missing table id");
18136       return -99;
18137     }
18138
18139   M (IP_ROUTE_DUMP, mp);
18140
18141   mp->table.table_id = table_id;
18142   mp->table.is_ip6 = is_ip6;
18143
18144   S (mp);
18145
18146   /* Use a control ping for synchronization */
18147   MPING (CONTROL_PING, mp_ping);
18148   S (mp_ping);
18149
18150   W (ret);
18151   return ret;
18152 }
18153
18154 int
18155 api_classify_table_ids (vat_main_t * vam)
18156 {
18157   vl_api_classify_table_ids_t *mp;
18158   int ret;
18159
18160   /* Construct the API message */
18161   M (CLASSIFY_TABLE_IDS, mp);
18162   mp->context = 0;
18163
18164   S (mp);
18165   W (ret);
18166   return ret;
18167 }
18168
18169 int
18170 api_classify_table_by_interface (vat_main_t * vam)
18171 {
18172   unformat_input_t *input = vam->input;
18173   vl_api_classify_table_by_interface_t *mp;
18174
18175   u32 sw_if_index = ~0;
18176   int ret;
18177   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18178     {
18179       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18180         ;
18181       else if (unformat (input, "sw_if_index %d", &sw_if_index))
18182         ;
18183       else
18184         break;
18185     }
18186   if (sw_if_index == ~0)
18187     {
18188       errmsg ("missing interface name or sw_if_index");
18189       return -99;
18190     }
18191
18192   /* Construct the API message */
18193   M (CLASSIFY_TABLE_BY_INTERFACE, mp);
18194   mp->context = 0;
18195   mp->sw_if_index = ntohl (sw_if_index);
18196
18197   S (mp);
18198   W (ret);
18199   return ret;
18200 }
18201
18202 int
18203 api_classify_table_info (vat_main_t * vam)
18204 {
18205   unformat_input_t *input = vam->input;
18206   vl_api_classify_table_info_t *mp;
18207
18208   u32 table_id = ~0;
18209   int ret;
18210   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18211     {
18212       if (unformat (input, "table_id %d", &table_id))
18213         ;
18214       else
18215         break;
18216     }
18217   if (table_id == ~0)
18218     {
18219       errmsg ("missing table id");
18220       return -99;
18221     }
18222
18223   /* Construct the API message */
18224   M (CLASSIFY_TABLE_INFO, mp);
18225   mp->context = 0;
18226   mp->table_id = ntohl (table_id);
18227
18228   S (mp);
18229   W (ret);
18230   return ret;
18231 }
18232
18233 int
18234 api_classify_session_dump (vat_main_t * vam)
18235 {
18236   unformat_input_t *input = vam->input;
18237   vl_api_classify_session_dump_t *mp;
18238   vl_api_control_ping_t *mp_ping;
18239
18240   u32 table_id = ~0;
18241   int ret;
18242   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18243     {
18244       if (unformat (input, "table_id %d", &table_id))
18245         ;
18246       else
18247         break;
18248     }
18249   if (table_id == ~0)
18250     {
18251       errmsg ("missing table id");
18252       return -99;
18253     }
18254
18255   /* Construct the API message */
18256   M (CLASSIFY_SESSION_DUMP, mp);
18257   mp->context = 0;
18258   mp->table_id = ntohl (table_id);
18259   S (mp);
18260
18261   /* Use a control ping for synchronization */
18262   MPING (CONTROL_PING, mp_ping);
18263   S (mp_ping);
18264
18265   W (ret);
18266   return ret;
18267 }
18268
18269 static void
18270 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
18271 {
18272   vat_main_t *vam = &vat_main;
18273
18274   print (vam->ofp, "collector_address %U, collector_port %d, "
18275          "src_address %U, vrf_id %d, path_mtu %u, "
18276          "template_interval %u, udp_checksum %d",
18277          format_ip4_address, mp->collector_address,
18278          ntohs (mp->collector_port),
18279          format_ip4_address, mp->src_address,
18280          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
18281          ntohl (mp->template_interval), mp->udp_checksum);
18282
18283   vam->retval = 0;
18284   vam->result_ready = 1;
18285 }
18286
18287 static void
18288   vl_api_ipfix_exporter_details_t_handler_json
18289   (vl_api_ipfix_exporter_details_t * mp)
18290 {
18291   vat_main_t *vam = &vat_main;
18292   vat_json_node_t node;
18293   struct in_addr collector_address;
18294   struct in_addr src_address;
18295
18296   vat_json_init_object (&node);
18297   clib_memcpy (&collector_address, &mp->collector_address,
18298                sizeof (collector_address));
18299   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
18300   vat_json_object_add_uint (&node, "collector_port",
18301                             ntohs (mp->collector_port));
18302   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
18303   vat_json_object_add_ip4 (&node, "src_address", src_address);
18304   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
18305   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
18306   vat_json_object_add_uint (&node, "template_interval",
18307                             ntohl (mp->template_interval));
18308   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
18309
18310   vat_json_print (vam->ofp, &node);
18311   vat_json_free (&node);
18312   vam->retval = 0;
18313   vam->result_ready = 1;
18314 }
18315
18316 int
18317 api_ipfix_exporter_dump (vat_main_t * vam)
18318 {
18319   vl_api_ipfix_exporter_dump_t *mp;
18320   int ret;
18321
18322   /* Construct the API message */
18323   M (IPFIX_EXPORTER_DUMP, mp);
18324   mp->context = 0;
18325
18326   S (mp);
18327   W (ret);
18328   return ret;
18329 }
18330
18331 static int
18332 api_ipfix_classify_stream_dump (vat_main_t * vam)
18333 {
18334   vl_api_ipfix_classify_stream_dump_t *mp;
18335   int ret;
18336
18337   /* Construct the API message */
18338   M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
18339   mp->context = 0;
18340
18341   S (mp);
18342   W (ret);
18343   return ret;
18344   /* NOTREACHED */
18345   return 0;
18346 }
18347
18348 static void
18349   vl_api_ipfix_classify_stream_details_t_handler
18350   (vl_api_ipfix_classify_stream_details_t * mp)
18351 {
18352   vat_main_t *vam = &vat_main;
18353   print (vam->ofp, "domain_id %d, src_port %d",
18354          ntohl (mp->domain_id), ntohs (mp->src_port));
18355   vam->retval = 0;
18356   vam->result_ready = 1;
18357 }
18358
18359 static void
18360   vl_api_ipfix_classify_stream_details_t_handler_json
18361   (vl_api_ipfix_classify_stream_details_t * mp)
18362 {
18363   vat_main_t *vam = &vat_main;
18364   vat_json_node_t node;
18365
18366   vat_json_init_object (&node);
18367   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
18368   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
18369
18370   vat_json_print (vam->ofp, &node);
18371   vat_json_free (&node);
18372   vam->retval = 0;
18373   vam->result_ready = 1;
18374 }
18375
18376 static int
18377 api_ipfix_classify_table_dump (vat_main_t * vam)
18378 {
18379   vl_api_ipfix_classify_table_dump_t *mp;
18380   vl_api_control_ping_t *mp_ping;
18381   int ret;
18382
18383   if (!vam->json_output)
18384     {
18385       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
18386              "transport_protocol");
18387     }
18388
18389   /* Construct the API message */
18390   M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
18391
18392   /* send it... */
18393   S (mp);
18394
18395   /* Use a control ping for synchronization */
18396   MPING (CONTROL_PING, mp_ping);
18397   S (mp_ping);
18398
18399   W (ret);
18400   return ret;
18401 }
18402
18403 static void
18404   vl_api_ipfix_classify_table_details_t_handler
18405   (vl_api_ipfix_classify_table_details_t * mp)
18406 {
18407   vat_main_t *vam = &vat_main;
18408   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
18409          mp->transport_protocol);
18410 }
18411
18412 static void
18413   vl_api_ipfix_classify_table_details_t_handler_json
18414   (vl_api_ipfix_classify_table_details_t * mp)
18415 {
18416   vat_json_node_t *node = NULL;
18417   vat_main_t *vam = &vat_main;
18418
18419   if (VAT_JSON_ARRAY != vam->json_tree.type)
18420     {
18421       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18422       vat_json_init_array (&vam->json_tree);
18423     }
18424
18425   node = vat_json_array_add (&vam->json_tree);
18426   vat_json_init_object (node);
18427
18428   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
18429   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
18430   vat_json_object_add_uint (node, "transport_protocol",
18431                             mp->transport_protocol);
18432 }
18433
18434 static int
18435 api_sw_interface_span_enable_disable (vat_main_t * vam)
18436 {
18437   unformat_input_t *i = vam->input;
18438   vl_api_sw_interface_span_enable_disable_t *mp;
18439   u32 src_sw_if_index = ~0;
18440   u32 dst_sw_if_index = ~0;
18441   u8 state = 3;
18442   int ret;
18443   u8 is_l2 = 0;
18444
18445   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18446     {
18447       if (unformat
18448           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
18449         ;
18450       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
18451         ;
18452       else
18453         if (unformat
18454             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
18455         ;
18456       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
18457         ;
18458       else if (unformat (i, "disable"))
18459         state = 0;
18460       else if (unformat (i, "rx"))
18461         state = 1;
18462       else if (unformat (i, "tx"))
18463         state = 2;
18464       else if (unformat (i, "both"))
18465         state = 3;
18466       else if (unformat (i, "l2"))
18467         is_l2 = 1;
18468       else
18469         break;
18470     }
18471
18472   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
18473
18474   mp->sw_if_index_from = htonl (src_sw_if_index);
18475   mp->sw_if_index_to = htonl (dst_sw_if_index);
18476   mp->state = state;
18477   mp->is_l2 = is_l2;
18478
18479   S (mp);
18480   W (ret);
18481   return ret;
18482 }
18483
18484 static void
18485 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
18486                                             * mp)
18487 {
18488   vat_main_t *vam = &vat_main;
18489   u8 *sw_if_from_name = 0;
18490   u8 *sw_if_to_name = 0;
18491   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
18492   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
18493   char *states[] = { "none", "rx", "tx", "both" };
18494   hash_pair_t *p;
18495
18496   /* *INDENT-OFF* */
18497   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
18498   ({
18499     if ((u32) p->value[0] == sw_if_index_from)
18500       {
18501         sw_if_from_name = (u8 *)(p->key);
18502         if (sw_if_to_name)
18503           break;
18504       }
18505     if ((u32) p->value[0] == sw_if_index_to)
18506       {
18507         sw_if_to_name = (u8 *)(p->key);
18508         if (sw_if_from_name)
18509           break;
18510       }
18511   }));
18512   /* *INDENT-ON* */
18513   print (vam->ofp, "%20s => %20s (%s) %s",
18514          sw_if_from_name, sw_if_to_name, states[mp->state],
18515          mp->is_l2 ? "l2" : "device");
18516 }
18517
18518 static void
18519   vl_api_sw_interface_span_details_t_handler_json
18520   (vl_api_sw_interface_span_details_t * mp)
18521 {
18522   vat_main_t *vam = &vat_main;
18523   vat_json_node_t *node = NULL;
18524   u8 *sw_if_from_name = 0;
18525   u8 *sw_if_to_name = 0;
18526   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
18527   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
18528   hash_pair_t *p;
18529
18530   /* *INDENT-OFF* */
18531   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
18532   ({
18533     if ((u32) p->value[0] == sw_if_index_from)
18534       {
18535         sw_if_from_name = (u8 *)(p->key);
18536         if (sw_if_to_name)
18537           break;
18538       }
18539     if ((u32) p->value[0] == sw_if_index_to)
18540       {
18541         sw_if_to_name = (u8 *)(p->key);
18542         if (sw_if_from_name)
18543           break;
18544       }
18545   }));
18546   /* *INDENT-ON* */
18547
18548   if (VAT_JSON_ARRAY != vam->json_tree.type)
18549     {
18550       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18551       vat_json_init_array (&vam->json_tree);
18552     }
18553   node = vat_json_array_add (&vam->json_tree);
18554
18555   vat_json_init_object (node);
18556   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
18557   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
18558   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
18559   if (0 != sw_if_to_name)
18560     {
18561       vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
18562     }
18563   vat_json_object_add_uint (node, "state", mp->state);
18564   vat_json_object_add_uint (node, "is-l2", mp->is_l2);
18565 }
18566
18567 static int
18568 api_sw_interface_span_dump (vat_main_t * vam)
18569 {
18570   unformat_input_t *input = vam->input;
18571   vl_api_sw_interface_span_dump_t *mp;
18572   vl_api_control_ping_t *mp_ping;
18573   u8 is_l2 = 0;
18574   int ret;
18575
18576   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18577     {
18578       if (unformat (input, "l2"))
18579         is_l2 = 1;
18580       else
18581         break;
18582     }
18583
18584   M (SW_INTERFACE_SPAN_DUMP, mp);
18585   mp->is_l2 = is_l2;
18586   S (mp);
18587
18588   /* Use a control ping for synchronization */
18589   MPING (CONTROL_PING, mp_ping);
18590   S (mp_ping);
18591
18592   W (ret);
18593   return ret;
18594 }
18595
18596 int
18597 api_pg_create_interface (vat_main_t * vam)
18598 {
18599   unformat_input_t *input = vam->input;
18600   vl_api_pg_create_interface_t *mp;
18601
18602   u32 if_id = ~0, gso_size = 0;
18603   u8 gso_enabled = 0;
18604   int ret;
18605   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18606     {
18607       if (unformat (input, "if_id %d", &if_id))
18608         ;
18609       else if (unformat (input, "gso-enabled"))
18610         {
18611           gso_enabled = 1;
18612           if (unformat (input, "gso-size %u", &gso_size))
18613             ;
18614           else
18615             {
18616               errmsg ("missing gso-size");
18617               return -99;
18618             }
18619         }
18620       else
18621         break;
18622     }
18623   if (if_id == ~0)
18624     {
18625       errmsg ("missing pg interface index");
18626       return -99;
18627     }
18628
18629   /* Construct the API message */
18630   M (PG_CREATE_INTERFACE, mp);
18631   mp->context = 0;
18632   mp->interface_id = ntohl (if_id);
18633   mp->gso_enabled = gso_enabled;
18634
18635   S (mp);
18636   W (ret);
18637   return ret;
18638 }
18639
18640 int
18641 api_pg_capture (vat_main_t * vam)
18642 {
18643   unformat_input_t *input = vam->input;
18644   vl_api_pg_capture_t *mp;
18645
18646   u32 if_id = ~0;
18647   u8 enable = 1;
18648   u32 count = 1;
18649   u8 pcap_file_set = 0;
18650   u8 *pcap_file = 0;
18651   int ret;
18652   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18653     {
18654       if (unformat (input, "if_id %d", &if_id))
18655         ;
18656       else if (unformat (input, "pcap %s", &pcap_file))
18657         pcap_file_set = 1;
18658       else if (unformat (input, "count %d", &count))
18659         ;
18660       else if (unformat (input, "disable"))
18661         enable = 0;
18662       else
18663         break;
18664     }
18665   if (if_id == ~0)
18666     {
18667       errmsg ("missing pg interface index");
18668       return -99;
18669     }
18670   if (pcap_file_set > 0)
18671     {
18672       if (vec_len (pcap_file) > 255)
18673         {
18674           errmsg ("pcap file name is too long");
18675           return -99;
18676         }
18677     }
18678
18679   u32 name_len = vec_len (pcap_file);
18680   /* Construct the API message */
18681   M (PG_CAPTURE, mp);
18682   mp->context = 0;
18683   mp->interface_id = ntohl (if_id);
18684   mp->is_enabled = enable;
18685   mp->count = ntohl (count);
18686   mp->pcap_name_length = ntohl (name_len);
18687   if (pcap_file_set != 0)
18688     {
18689       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
18690     }
18691   vec_free (pcap_file);
18692
18693   S (mp);
18694   W (ret);
18695   return ret;
18696 }
18697
18698 int
18699 api_pg_enable_disable (vat_main_t * vam)
18700 {
18701   unformat_input_t *input = vam->input;
18702   vl_api_pg_enable_disable_t *mp;
18703
18704   u8 enable = 1;
18705   u8 stream_name_set = 0;
18706   u8 *stream_name = 0;
18707   int ret;
18708   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18709     {
18710       if (unformat (input, "stream %s", &stream_name))
18711         stream_name_set = 1;
18712       else if (unformat (input, "disable"))
18713         enable = 0;
18714       else
18715         break;
18716     }
18717
18718   if (stream_name_set > 0)
18719     {
18720       if (vec_len (stream_name) > 255)
18721         {
18722           errmsg ("stream name too long");
18723           return -99;
18724         }
18725     }
18726
18727   u32 name_len = vec_len (stream_name);
18728   /* Construct the API message */
18729   M (PG_ENABLE_DISABLE, mp);
18730   mp->context = 0;
18731   mp->is_enabled = enable;
18732   if (stream_name_set != 0)
18733     {
18734       mp->stream_name_length = ntohl (name_len);
18735       clib_memcpy (mp->stream_name, stream_name, name_len);
18736     }
18737   vec_free (stream_name);
18738
18739   S (mp);
18740   W (ret);
18741   return ret;
18742 }
18743
18744 int
18745 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
18746 {
18747   unformat_input_t *input = vam->input;
18748   vl_api_ip_source_and_port_range_check_add_del_t *mp;
18749
18750   u16 *low_ports = 0;
18751   u16 *high_ports = 0;
18752   u16 this_low;
18753   u16 this_hi;
18754   vl_api_prefix_t prefix;
18755   u32 tmp, tmp2;
18756   u8 prefix_set = 0;
18757   u32 vrf_id = ~0;
18758   u8 is_add = 1;
18759   int ret;
18760
18761   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18762     {
18763       if (unformat (input, "%U", unformat_vl_api_prefix, &prefix))
18764         prefix_set = 1;
18765       else if (unformat (input, "vrf %d", &vrf_id))
18766         ;
18767       else if (unformat (input, "del"))
18768         is_add = 0;
18769       else if (unformat (input, "port %d", &tmp))
18770         {
18771           if (tmp == 0 || tmp > 65535)
18772             {
18773               errmsg ("port %d out of range", tmp);
18774               return -99;
18775             }
18776           this_low = tmp;
18777           this_hi = this_low + 1;
18778           vec_add1 (low_ports, this_low);
18779           vec_add1 (high_ports, this_hi);
18780         }
18781       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
18782         {
18783           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
18784             {
18785               errmsg ("incorrect range parameters");
18786               return -99;
18787             }
18788           this_low = tmp;
18789           /* Note: in debug CLI +1 is added to high before
18790              passing to real fn that does "the work"
18791              (ip_source_and_port_range_check_add_del).
18792              This fn is a wrapper around the binary API fn a
18793              control plane will call, which expects this increment
18794              to have occurred. Hence letting the binary API control
18795              plane fn do the increment for consistency between VAT
18796              and other control planes.
18797            */
18798           this_hi = tmp2;
18799           vec_add1 (low_ports, this_low);
18800           vec_add1 (high_ports, this_hi);
18801         }
18802       else
18803         break;
18804     }
18805
18806   if (prefix_set == 0)
18807     {
18808       errmsg ("<address>/<mask> not specified");
18809       return -99;
18810     }
18811
18812   if (vrf_id == ~0)
18813     {
18814       errmsg ("VRF ID required, not specified");
18815       return -99;
18816     }
18817
18818   if (vrf_id == 0)
18819     {
18820       errmsg
18821         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
18822       return -99;
18823     }
18824
18825   if (vec_len (low_ports) == 0)
18826     {
18827       errmsg ("At least one port or port range required");
18828       return -99;
18829     }
18830
18831   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
18832
18833   mp->is_add = is_add;
18834
18835   clib_memcpy (&mp->prefix, &prefix, sizeof (prefix));
18836
18837   mp->number_of_ranges = vec_len (low_ports);
18838
18839   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
18840   vec_free (low_ports);
18841
18842   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
18843   vec_free (high_ports);
18844
18845   mp->vrf_id = ntohl (vrf_id);
18846
18847   S (mp);
18848   W (ret);
18849   return ret;
18850 }
18851
18852 int
18853 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
18854 {
18855   unformat_input_t *input = vam->input;
18856   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
18857   u32 sw_if_index = ~0;
18858   int vrf_set = 0;
18859   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
18860   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
18861   u8 is_add = 1;
18862   int ret;
18863
18864   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18865     {
18866       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18867         ;
18868       else if (unformat (input, "sw_if_index %d", &sw_if_index))
18869         ;
18870       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
18871         vrf_set = 1;
18872       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
18873         vrf_set = 1;
18874       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
18875         vrf_set = 1;
18876       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
18877         vrf_set = 1;
18878       else if (unformat (input, "del"))
18879         is_add = 0;
18880       else
18881         break;
18882     }
18883
18884   if (sw_if_index == ~0)
18885     {
18886       errmsg ("Interface required but not specified");
18887       return -99;
18888     }
18889
18890   if (vrf_set == 0)
18891     {
18892       errmsg ("VRF ID required but not specified");
18893       return -99;
18894     }
18895
18896   if (tcp_out_vrf_id == 0
18897       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
18898     {
18899       errmsg
18900         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
18901       return -99;
18902     }
18903
18904   /* Construct the API message */
18905   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
18906
18907   mp->sw_if_index = ntohl (sw_if_index);
18908   mp->is_add = is_add;
18909   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
18910   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
18911   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
18912   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
18913
18914   /* send it... */
18915   S (mp);
18916
18917   /* Wait for a reply... */
18918   W (ret);
18919   return ret;
18920 }
18921
18922 static int
18923 api_set_punt (vat_main_t * vam)
18924 {
18925   unformat_input_t *i = vam->input;
18926   vl_api_address_family_t af;
18927   vl_api_set_punt_t *mp;
18928   u32 protocol = ~0;
18929   u32 port = ~0;
18930   int is_add = 1;
18931   int ret;
18932
18933   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18934     {
18935       if (unformat (i, "%U", unformat_vl_api_address_family, &af))
18936         ;
18937       else if (unformat (i, "protocol %d", &protocol))
18938         ;
18939       else if (unformat (i, "port %d", &port))
18940         ;
18941       else if (unformat (i, "del"))
18942         is_add = 0;
18943       else
18944         {
18945           clib_warning ("parse error '%U'", format_unformat_error, i);
18946           return -99;
18947         }
18948     }
18949
18950   M (SET_PUNT, mp);
18951
18952   mp->is_add = (u8) is_add;
18953   mp->punt.type = PUNT_API_TYPE_L4;
18954   mp->punt.punt.l4.af = af;
18955   mp->punt.punt.l4.protocol = (u8) protocol;
18956   mp->punt.punt.l4.port = htons ((u16) port);
18957
18958   S (mp);
18959   W (ret);
18960   return ret;
18961 }
18962
18963 static int
18964 api_delete_subif (vat_main_t * vam)
18965 {
18966   unformat_input_t *i = vam->input;
18967   vl_api_delete_subif_t *mp;
18968   u32 sw_if_index = ~0;
18969   int ret;
18970
18971   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18972     {
18973       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18974         ;
18975       if (unformat (i, "sw_if_index %d", &sw_if_index))
18976         ;
18977       else
18978         break;
18979     }
18980
18981   if (sw_if_index == ~0)
18982     {
18983       errmsg ("missing sw_if_index");
18984       return -99;
18985     }
18986
18987   /* Construct the API message */
18988   M (DELETE_SUBIF, mp);
18989   mp->sw_if_index = ntohl (sw_if_index);
18990
18991   S (mp);
18992   W (ret);
18993   return ret;
18994 }
18995
18996 #define foreach_pbb_vtr_op      \
18997 _("disable",  L2_VTR_DISABLED)  \
18998 _("pop",  L2_VTR_POP_2)         \
18999 _("push",  L2_VTR_PUSH_2)
19000
19001 static int
19002 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
19003 {
19004   unformat_input_t *i = vam->input;
19005   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
19006   u32 sw_if_index = ~0, vtr_op = ~0;
19007   u16 outer_tag = ~0;
19008   u8 dmac[6], smac[6];
19009   u8 dmac_set = 0, smac_set = 0;
19010   u16 vlanid = 0;
19011   u32 sid = ~0;
19012   u32 tmp;
19013   int ret;
19014
19015   /* Shut up coverity */
19016   clib_memset (dmac, 0, sizeof (dmac));
19017   clib_memset (smac, 0, sizeof (smac));
19018
19019   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19020     {
19021       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19022         ;
19023       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19024         ;
19025       else if (unformat (i, "vtr_op %d", &vtr_op))
19026         ;
19027 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
19028       foreach_pbb_vtr_op
19029 #undef _
19030         else if (unformat (i, "translate_pbb_stag"))
19031         {
19032           if (unformat (i, "%d", &tmp))
19033             {
19034               vtr_op = L2_VTR_TRANSLATE_2_1;
19035               outer_tag = tmp;
19036             }
19037           else
19038             {
19039               errmsg
19040                 ("translate_pbb_stag operation requires outer tag definition");
19041               return -99;
19042             }
19043         }
19044       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
19045         dmac_set++;
19046       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
19047         smac_set++;
19048       else if (unformat (i, "sid %d", &sid))
19049         ;
19050       else if (unformat (i, "vlanid %d", &tmp))
19051         vlanid = tmp;
19052       else
19053         {
19054           clib_warning ("parse error '%U'", format_unformat_error, i);
19055           return -99;
19056         }
19057     }
19058
19059   if ((sw_if_index == ~0) || (vtr_op == ~0))
19060     {
19061       errmsg ("missing sw_if_index or vtr operation");
19062       return -99;
19063     }
19064   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
19065       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
19066     {
19067       errmsg
19068         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
19069       return -99;
19070     }
19071
19072   M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
19073   mp->sw_if_index = ntohl (sw_if_index);
19074   mp->vtr_op = ntohl (vtr_op);
19075   mp->outer_tag = ntohs (outer_tag);
19076   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
19077   clib_memcpy (mp->b_smac, smac, sizeof (smac));
19078   mp->b_vlanid = ntohs (vlanid);
19079   mp->i_sid = ntohl (sid);
19080
19081   S (mp);
19082   W (ret);
19083   return ret;
19084 }
19085
19086 static int
19087 api_flow_classify_set_interface (vat_main_t * vam)
19088 {
19089   unformat_input_t *i = vam->input;
19090   vl_api_flow_classify_set_interface_t *mp;
19091   u32 sw_if_index;
19092   int sw_if_index_set;
19093   u32 ip4_table_index = ~0;
19094   u32 ip6_table_index = ~0;
19095   u8 is_add = 1;
19096   int ret;
19097
19098   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19099     {
19100       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19101         sw_if_index_set = 1;
19102       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19103         sw_if_index_set = 1;
19104       else if (unformat (i, "del"))
19105         is_add = 0;
19106       else if (unformat (i, "ip4-table %d", &ip4_table_index))
19107         ;
19108       else if (unformat (i, "ip6-table %d", &ip6_table_index))
19109         ;
19110       else
19111         {
19112           clib_warning ("parse error '%U'", format_unformat_error, i);
19113           return -99;
19114         }
19115     }
19116
19117   if (sw_if_index_set == 0)
19118     {
19119       errmsg ("missing interface name or sw_if_index");
19120       return -99;
19121     }
19122
19123   M (FLOW_CLASSIFY_SET_INTERFACE, mp);
19124
19125   mp->sw_if_index = ntohl (sw_if_index);
19126   mp->ip4_table_index = ntohl (ip4_table_index);
19127   mp->ip6_table_index = ntohl (ip6_table_index);
19128   mp->is_add = is_add;
19129
19130   S (mp);
19131   W (ret);
19132   return ret;
19133 }
19134
19135 static int
19136 api_flow_classify_dump (vat_main_t * vam)
19137 {
19138   unformat_input_t *i = vam->input;
19139   vl_api_flow_classify_dump_t *mp;
19140   vl_api_control_ping_t *mp_ping;
19141   u8 type = FLOW_CLASSIFY_N_TABLES;
19142   int ret;
19143
19144   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
19145     ;
19146   else
19147     {
19148       errmsg ("classify table type must be specified");
19149       return -99;
19150     }
19151
19152   if (!vam->json_output)
19153     {
19154       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
19155     }
19156
19157   M (FLOW_CLASSIFY_DUMP, mp);
19158   mp->type = type;
19159   /* send it... */
19160   S (mp);
19161
19162   /* Use a control ping for synchronization */
19163   MPING (CONTROL_PING, mp_ping);
19164   S (mp_ping);
19165
19166   /* Wait for a reply... */
19167   W (ret);
19168   return ret;
19169 }
19170
19171 static int
19172 api_feature_enable_disable (vat_main_t * vam)
19173 {
19174   unformat_input_t *i = vam->input;
19175   vl_api_feature_enable_disable_t *mp;
19176   u8 *arc_name = 0;
19177   u8 *feature_name = 0;
19178   u32 sw_if_index = ~0;
19179   u8 enable = 1;
19180   int ret;
19181
19182   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19183     {
19184       if (unformat (i, "arc_name %s", &arc_name))
19185         ;
19186       else if (unformat (i, "feature_name %s", &feature_name))
19187         ;
19188       else
19189         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19190         ;
19191       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19192         ;
19193       else if (unformat (i, "disable"))
19194         enable = 0;
19195       else
19196         break;
19197     }
19198
19199   if (arc_name == 0)
19200     {
19201       errmsg ("missing arc name");
19202       return -99;
19203     }
19204   if (vec_len (arc_name) > 63)
19205     {
19206       errmsg ("arc name too long");
19207     }
19208
19209   if (feature_name == 0)
19210     {
19211       errmsg ("missing feature name");
19212       return -99;
19213     }
19214   if (vec_len (feature_name) > 63)
19215     {
19216       errmsg ("feature name too long");
19217     }
19218
19219   if (sw_if_index == ~0)
19220     {
19221       errmsg ("missing interface name or sw_if_index");
19222       return -99;
19223     }
19224
19225   /* Construct the API message */
19226   M (FEATURE_ENABLE_DISABLE, mp);
19227   mp->sw_if_index = ntohl (sw_if_index);
19228   mp->enable = enable;
19229   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
19230   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
19231   vec_free (arc_name);
19232   vec_free (feature_name);
19233
19234   S (mp);
19235   W (ret);
19236   return ret;
19237 }
19238
19239 static int
19240 api_feature_gso_enable_disable (vat_main_t * vam)
19241 {
19242   unformat_input_t *i = vam->input;
19243   vl_api_feature_gso_enable_disable_t *mp;
19244   u32 sw_if_index = ~0;
19245   u8 enable = 1;
19246   int ret;
19247
19248   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19249     {
19250       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19251         ;
19252       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19253         ;
19254       else if (unformat (i, "enable"))
19255         enable = 1;
19256       else if (unformat (i, "disable"))
19257         enable = 0;
19258       else
19259         break;
19260     }
19261
19262   if (sw_if_index == ~0)
19263     {
19264       errmsg ("missing interface name or sw_if_index");
19265       return -99;
19266     }
19267
19268   /* Construct the API message */
19269   M (FEATURE_GSO_ENABLE_DISABLE, mp);
19270   mp->sw_if_index = ntohl (sw_if_index);
19271   mp->enable_disable = enable;
19272
19273   S (mp);
19274   W (ret);
19275   return ret;
19276 }
19277
19278 static int
19279 api_sw_interface_tag_add_del (vat_main_t * vam)
19280 {
19281   unformat_input_t *i = vam->input;
19282   vl_api_sw_interface_tag_add_del_t *mp;
19283   u32 sw_if_index = ~0;
19284   u8 *tag = 0;
19285   u8 enable = 1;
19286   int ret;
19287
19288   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19289     {
19290       if (unformat (i, "tag %s", &tag))
19291         ;
19292       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19293         ;
19294       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19295         ;
19296       else if (unformat (i, "del"))
19297         enable = 0;
19298       else
19299         break;
19300     }
19301
19302   if (sw_if_index == ~0)
19303     {
19304       errmsg ("missing interface name or sw_if_index");
19305       return -99;
19306     }
19307
19308   if (enable && (tag == 0))
19309     {
19310       errmsg ("no tag specified");
19311       return -99;
19312     }
19313
19314   /* Construct the API message */
19315   M (SW_INTERFACE_TAG_ADD_DEL, mp);
19316   mp->sw_if_index = ntohl (sw_if_index);
19317   mp->is_add = enable;
19318   if (enable)
19319     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
19320   vec_free (tag);
19321
19322   S (mp);
19323   W (ret);
19324   return ret;
19325 }
19326
19327 static int
19328 api_sw_interface_add_del_mac_address (vat_main_t * vam)
19329 {
19330   unformat_input_t *i = vam->input;
19331   vl_api_mac_address_t mac = { 0 };
19332   vl_api_sw_interface_add_del_mac_address_t *mp;
19333   u32 sw_if_index = ~0;
19334   u8 is_add = 1;
19335   u8 mac_set = 0;
19336   int ret;
19337
19338   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19339     {
19340       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19341         ;
19342       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19343         ;
19344       else if (unformat (i, "%U", unformat_vl_api_mac_address, &mac))
19345         mac_set++;
19346       else if (unformat (i, "del"))
19347         is_add = 0;
19348       else
19349         break;
19350     }
19351
19352   if (sw_if_index == ~0)
19353     {
19354       errmsg ("missing interface name or sw_if_index");
19355       return -99;
19356     }
19357
19358   if (!mac_set)
19359     {
19360       errmsg ("missing MAC address");
19361       return -99;
19362     }
19363
19364   /* Construct the API message */
19365   M (SW_INTERFACE_ADD_DEL_MAC_ADDRESS, mp);
19366   mp->sw_if_index = ntohl (sw_if_index);
19367   mp->is_add = is_add;
19368   clib_memcpy (&mp->addr, &mac, sizeof (mac));
19369
19370   S (mp);
19371   W (ret);
19372   return ret;
19373 }
19374
19375 static void vl_api_l2_xconnect_details_t_handler
19376   (vl_api_l2_xconnect_details_t * mp)
19377 {
19378   vat_main_t *vam = &vat_main;
19379
19380   print (vam->ofp, "%15d%15d",
19381          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
19382 }
19383
19384 static void vl_api_l2_xconnect_details_t_handler_json
19385   (vl_api_l2_xconnect_details_t * mp)
19386 {
19387   vat_main_t *vam = &vat_main;
19388   vat_json_node_t *node = NULL;
19389
19390   if (VAT_JSON_ARRAY != vam->json_tree.type)
19391     {
19392       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19393       vat_json_init_array (&vam->json_tree);
19394     }
19395   node = vat_json_array_add (&vam->json_tree);
19396
19397   vat_json_init_object (node);
19398   vat_json_object_add_uint (node, "rx_sw_if_index",
19399                             ntohl (mp->rx_sw_if_index));
19400   vat_json_object_add_uint (node, "tx_sw_if_index",
19401                             ntohl (mp->tx_sw_if_index));
19402 }
19403
19404 static int
19405 api_l2_xconnect_dump (vat_main_t * vam)
19406 {
19407   vl_api_l2_xconnect_dump_t *mp;
19408   vl_api_control_ping_t *mp_ping;
19409   int ret;
19410
19411   if (!vam->json_output)
19412     {
19413       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
19414     }
19415
19416   M (L2_XCONNECT_DUMP, mp);
19417
19418   S (mp);
19419
19420   /* Use a control ping for synchronization */
19421   MPING (CONTROL_PING, mp_ping);
19422   S (mp_ping);
19423
19424   W (ret);
19425   return ret;
19426 }
19427
19428 static int
19429 api_hw_interface_set_mtu (vat_main_t * vam)
19430 {
19431   unformat_input_t *i = vam->input;
19432   vl_api_hw_interface_set_mtu_t *mp;
19433   u32 sw_if_index = ~0;
19434   u32 mtu = 0;
19435   int ret;
19436
19437   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19438     {
19439       if (unformat (i, "mtu %d", &mtu))
19440         ;
19441       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19442         ;
19443       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19444         ;
19445       else
19446         break;
19447     }
19448
19449   if (sw_if_index == ~0)
19450     {
19451       errmsg ("missing interface name or sw_if_index");
19452       return -99;
19453     }
19454
19455   if (mtu == 0)
19456     {
19457       errmsg ("no mtu specified");
19458       return -99;
19459     }
19460
19461   /* Construct the API message */
19462   M (HW_INTERFACE_SET_MTU, mp);
19463   mp->sw_if_index = ntohl (sw_if_index);
19464   mp->mtu = ntohs ((u16) mtu);
19465
19466   S (mp);
19467   W (ret);
19468   return ret;
19469 }
19470
19471 static int
19472 api_p2p_ethernet_add (vat_main_t * vam)
19473 {
19474   unformat_input_t *i = vam->input;
19475   vl_api_p2p_ethernet_add_t *mp;
19476   u32 parent_if_index = ~0;
19477   u32 sub_id = ~0;
19478   u8 remote_mac[6];
19479   u8 mac_set = 0;
19480   int ret;
19481
19482   clib_memset (remote_mac, 0, sizeof (remote_mac));
19483   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19484     {
19485       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
19486         ;
19487       else if (unformat (i, "sw_if_index %d", &parent_if_index))
19488         ;
19489       else
19490         if (unformat
19491             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
19492         mac_set++;
19493       else if (unformat (i, "sub_id %d", &sub_id))
19494         ;
19495       else
19496         {
19497           clib_warning ("parse error '%U'", format_unformat_error, i);
19498           return -99;
19499         }
19500     }
19501
19502   if (parent_if_index == ~0)
19503     {
19504       errmsg ("missing interface name or sw_if_index");
19505       return -99;
19506     }
19507   if (mac_set == 0)
19508     {
19509       errmsg ("missing remote mac address");
19510       return -99;
19511     }
19512   if (sub_id == ~0)
19513     {
19514       errmsg ("missing sub-interface id");
19515       return -99;
19516     }
19517
19518   M (P2P_ETHERNET_ADD, mp);
19519   mp->parent_if_index = ntohl (parent_if_index);
19520   mp->subif_id = ntohl (sub_id);
19521   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
19522
19523   S (mp);
19524   W (ret);
19525   return ret;
19526 }
19527
19528 static int
19529 api_p2p_ethernet_del (vat_main_t * vam)
19530 {
19531   unformat_input_t *i = vam->input;
19532   vl_api_p2p_ethernet_del_t *mp;
19533   u32 parent_if_index = ~0;
19534   u8 remote_mac[6];
19535   u8 mac_set = 0;
19536   int ret;
19537
19538   clib_memset (remote_mac, 0, sizeof (remote_mac));
19539   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19540     {
19541       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
19542         ;
19543       else if (unformat (i, "sw_if_index %d", &parent_if_index))
19544         ;
19545       else
19546         if (unformat
19547             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
19548         mac_set++;
19549       else
19550         {
19551           clib_warning ("parse error '%U'", format_unformat_error, i);
19552           return -99;
19553         }
19554     }
19555
19556   if (parent_if_index == ~0)
19557     {
19558       errmsg ("missing interface name or sw_if_index");
19559       return -99;
19560     }
19561   if (mac_set == 0)
19562     {
19563       errmsg ("missing remote mac address");
19564       return -99;
19565     }
19566
19567   M (P2P_ETHERNET_DEL, mp);
19568   mp->parent_if_index = ntohl (parent_if_index);
19569   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
19570
19571   S (mp);
19572   W (ret);
19573   return ret;
19574 }
19575
19576 static int
19577 api_lldp_config (vat_main_t * vam)
19578 {
19579   unformat_input_t *i = vam->input;
19580   vl_api_lldp_config_t *mp;
19581   int tx_hold = 0;
19582   int tx_interval = 0;
19583   u8 *sys_name = NULL;
19584   int ret;
19585
19586   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19587     {
19588       if (unformat (i, "system-name %s", &sys_name))
19589         ;
19590       else if (unformat (i, "tx-hold %d", &tx_hold))
19591         ;
19592       else if (unformat (i, "tx-interval %d", &tx_interval))
19593         ;
19594       else
19595         {
19596           clib_warning ("parse error '%U'", format_unformat_error, i);
19597           return -99;
19598         }
19599     }
19600
19601   vec_add1 (sys_name, 0);
19602
19603   M (LLDP_CONFIG, mp);
19604   mp->tx_hold = htonl (tx_hold);
19605   mp->tx_interval = htonl (tx_interval);
19606   clib_memcpy (mp->system_name, sys_name, vec_len (sys_name));
19607   vec_free (sys_name);
19608
19609   S (mp);
19610   W (ret);
19611   return ret;
19612 }
19613
19614 static int
19615 api_sw_interface_set_lldp (vat_main_t * vam)
19616 {
19617   unformat_input_t *i = vam->input;
19618   vl_api_sw_interface_set_lldp_t *mp;
19619   u32 sw_if_index = ~0;
19620   u32 enable = 1;
19621   u8 *port_desc = NULL, *mgmt_oid = NULL;
19622   ip4_address_t ip4_addr;
19623   ip6_address_t ip6_addr;
19624   int ret;
19625
19626   clib_memset (&ip4_addr, 0, sizeof (ip4_addr));
19627   clib_memset (&ip6_addr, 0, sizeof (ip6_addr));
19628
19629   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19630     {
19631       if (unformat (i, "disable"))
19632         enable = 0;
19633       else
19634         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19635         ;
19636       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19637         ;
19638       else if (unformat (i, "port-desc %s", &port_desc))
19639         ;
19640       else if (unformat (i, "mgmt-ip4 %U", unformat_ip4_address, &ip4_addr))
19641         ;
19642       else if (unformat (i, "mgmt-ip6 %U", unformat_ip6_address, &ip6_addr))
19643         ;
19644       else if (unformat (i, "mgmt-oid %s", &mgmt_oid))
19645         ;
19646       else
19647         break;
19648     }
19649
19650   if (sw_if_index == ~0)
19651     {
19652       errmsg ("missing interface name or sw_if_index");
19653       return -99;
19654     }
19655
19656   /* Construct the API message */
19657   vec_add1 (port_desc, 0);
19658   vec_add1 (mgmt_oid, 0);
19659   M (SW_INTERFACE_SET_LLDP, mp);
19660   mp->sw_if_index = ntohl (sw_if_index);
19661   mp->enable = enable;
19662   clib_memcpy (mp->port_desc, port_desc, vec_len (port_desc));
19663   clib_memcpy (mp->mgmt_oid, mgmt_oid, vec_len (mgmt_oid));
19664   clib_memcpy (mp->mgmt_ip4, &ip4_addr, sizeof (ip4_addr));
19665   clib_memcpy (mp->mgmt_ip6, &ip6_addr, sizeof (ip6_addr));
19666   vec_free (port_desc);
19667   vec_free (mgmt_oid);
19668
19669   S (mp);
19670   W (ret);
19671   return ret;
19672 }
19673
19674 static int
19675 api_tcp_configure_src_addresses (vat_main_t * vam)
19676 {
19677   vl_api_tcp_configure_src_addresses_t *mp;
19678   unformat_input_t *i = vam->input;
19679   vl_api_address_t first, last;
19680   u8 range_set = 0;
19681   u32 vrf_id = 0;
19682   int ret;
19683
19684   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19685     {
19686       if (unformat (i, "%U - %U",
19687                     unformat_vl_api_address, &first,
19688                     unformat_vl_api_address, &last))
19689         {
19690           if (range_set)
19691             {
19692               errmsg ("one range per message (range already set)");
19693               return -99;
19694             }
19695           range_set = 1;
19696         }
19697       else if (unformat (i, "vrf %d", &vrf_id))
19698         ;
19699       else
19700         break;
19701     }
19702
19703   if (range_set == 0)
19704     {
19705       errmsg ("address range not set");
19706       return -99;
19707     }
19708
19709   M (TCP_CONFIGURE_SRC_ADDRESSES, mp);
19710
19711   mp->vrf_id = ntohl (vrf_id);
19712   clib_memcpy (&mp->first_address, &first, sizeof (first));
19713   clib_memcpy (&mp->last_address, &last, sizeof (last));
19714
19715   S (mp);
19716   W (ret);
19717   return ret;
19718 }
19719
19720 static void vl_api_app_namespace_add_del_reply_t_handler
19721   (vl_api_app_namespace_add_del_reply_t * mp)
19722 {
19723   vat_main_t *vam = &vat_main;
19724   i32 retval = ntohl (mp->retval);
19725   if (vam->async_mode)
19726     {
19727       vam->async_errors += (retval < 0);
19728     }
19729   else
19730     {
19731       vam->retval = retval;
19732       if (retval == 0)
19733         errmsg ("app ns index %d\n", ntohl (mp->appns_index));
19734       vam->result_ready = 1;
19735     }
19736 }
19737
19738 static void vl_api_app_namespace_add_del_reply_t_handler_json
19739   (vl_api_app_namespace_add_del_reply_t * mp)
19740 {
19741   vat_main_t *vam = &vat_main;
19742   vat_json_node_t node;
19743
19744   vat_json_init_object (&node);
19745   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
19746   vat_json_object_add_uint (&node, "appns_index", ntohl (mp->appns_index));
19747
19748   vat_json_print (vam->ofp, &node);
19749   vat_json_free (&node);
19750
19751   vam->retval = ntohl (mp->retval);
19752   vam->result_ready = 1;
19753 }
19754
19755 static int
19756 api_app_namespace_add_del (vat_main_t * vam)
19757 {
19758   vl_api_app_namespace_add_del_t *mp;
19759   unformat_input_t *i = vam->input;
19760   u8 *ns_id = 0, secret_set = 0, sw_if_index_set = 0;
19761   u32 sw_if_index, ip4_fib_id, ip6_fib_id;
19762   u64 secret;
19763   int ret;
19764
19765   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19766     {
19767       if (unformat (i, "id %_%v%_", &ns_id))
19768         ;
19769       else if (unformat (i, "secret %lu", &secret))
19770         secret_set = 1;
19771       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19772         sw_if_index_set = 1;
19773       else if (unformat (i, "ip4_fib_id %d", &ip4_fib_id))
19774         ;
19775       else if (unformat (i, "ip6_fib_id %d", &ip6_fib_id))
19776         ;
19777       else
19778         break;
19779     }
19780   if (!ns_id || !secret_set || !sw_if_index_set)
19781     {
19782       errmsg ("namespace id, secret and sw_if_index must be set");
19783       return -99;
19784     }
19785   if (vec_len (ns_id) > 64)
19786     {
19787       errmsg ("namespace id too long");
19788       return -99;
19789     }
19790   M (APP_NAMESPACE_ADD_DEL, mp);
19791
19792   clib_memcpy (mp->namespace_id, ns_id, vec_len (ns_id));
19793   mp->namespace_id_len = vec_len (ns_id);
19794   mp->secret = clib_host_to_net_u64 (secret);
19795   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
19796   mp->ip4_fib_id = clib_host_to_net_u32 (ip4_fib_id);
19797   mp->ip6_fib_id = clib_host_to_net_u32 (ip6_fib_id);
19798   vec_free (ns_id);
19799   S (mp);
19800   W (ret);
19801   return ret;
19802 }
19803
19804 static int
19805 api_sock_init_shm (vat_main_t * vam)
19806 {
19807 #if VPP_API_TEST_BUILTIN == 0
19808   unformat_input_t *i = vam->input;
19809   vl_api_shm_elem_config_t *config = 0;
19810   u64 size = 64 << 20;
19811   int rv;
19812
19813   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19814     {
19815       if (unformat (i, "size %U", unformat_memory_size, &size))
19816         ;
19817       else
19818         break;
19819     }
19820
19821   /*
19822    * Canned custom ring allocator config.
19823    * Should probably parse all of this
19824    */
19825   vec_validate (config, 6);
19826   config[0].type = VL_API_VLIB_RING;
19827   config[0].size = 256;
19828   config[0].count = 32;
19829
19830   config[1].type = VL_API_VLIB_RING;
19831   config[1].size = 1024;
19832   config[1].count = 16;
19833
19834   config[2].type = VL_API_VLIB_RING;
19835   config[2].size = 4096;
19836   config[2].count = 2;
19837
19838   config[3].type = VL_API_CLIENT_RING;
19839   config[3].size = 256;
19840   config[3].count = 32;
19841
19842   config[4].type = VL_API_CLIENT_RING;
19843   config[4].size = 1024;
19844   config[4].count = 16;
19845
19846   config[5].type = VL_API_CLIENT_RING;
19847   config[5].size = 4096;
19848   config[5].count = 2;
19849
19850   config[6].type = VL_API_QUEUE;
19851   config[6].count = 128;
19852   config[6].size = sizeof (uword);
19853
19854   rv = vl_socket_client_init_shm (config, 1 /* want_pthread */ );
19855   if (!rv)
19856     vam->client_index_invalid = 1;
19857   return rv;
19858 #else
19859   return -99;
19860 #endif
19861 }
19862
19863 static void
19864 vl_api_session_rules_details_t_handler (vl_api_session_rules_details_t * mp)
19865 {
19866   vat_main_t *vam = &vat_main;
19867
19868   if (mp->is_ip4)
19869     {
19870       print (vam->ofp,
19871              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
19872              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
19873              mp->scope, format_ip4_address, &mp->lcl_ip, mp->lcl_plen,
19874              clib_net_to_host_u16 (mp->lcl_port), format_ip4_address,
19875              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
19876              clib_net_to_host_u32 (mp->action_index), mp->tag);
19877     }
19878   else
19879     {
19880       print (vam->ofp,
19881              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
19882              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
19883              mp->scope, format_ip6_address, &mp->lcl_ip, mp->lcl_plen,
19884              clib_net_to_host_u16 (mp->lcl_port), format_ip6_address,
19885              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
19886              clib_net_to_host_u32 (mp->action_index), mp->tag);
19887     }
19888 }
19889
19890 static void
19891 vl_api_session_rules_details_t_handler_json (vl_api_session_rules_details_t *
19892                                              mp)
19893 {
19894   vat_main_t *vam = &vat_main;
19895   vat_json_node_t *node = NULL;
19896   struct in6_addr ip6;
19897   struct in_addr ip4;
19898
19899   if (VAT_JSON_ARRAY != vam->json_tree.type)
19900     {
19901       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19902       vat_json_init_array (&vam->json_tree);
19903     }
19904   node = vat_json_array_add (&vam->json_tree);
19905   vat_json_init_object (node);
19906
19907   vat_json_object_add_uint (node, "is_ip4", mp->is_ip4 ? 1 : 0);
19908   vat_json_object_add_uint (node, "appns_index",
19909                             clib_net_to_host_u32 (mp->appns_index));
19910   vat_json_object_add_uint (node, "transport_proto", mp->transport_proto);
19911   vat_json_object_add_uint (node, "scope", mp->scope);
19912   vat_json_object_add_uint (node, "action_index",
19913                             clib_net_to_host_u32 (mp->action_index));
19914   vat_json_object_add_uint (node, "lcl_port",
19915                             clib_net_to_host_u16 (mp->lcl_port));
19916   vat_json_object_add_uint (node, "rmt_port",
19917                             clib_net_to_host_u16 (mp->rmt_port));
19918   vat_json_object_add_uint (node, "lcl_plen", mp->lcl_plen);
19919   vat_json_object_add_uint (node, "rmt_plen", mp->rmt_plen);
19920   vat_json_object_add_string_copy (node, "tag", mp->tag);
19921   if (mp->is_ip4)
19922     {
19923       clib_memcpy (&ip4, mp->lcl_ip, sizeof (ip4));
19924       vat_json_object_add_ip4 (node, "lcl_ip", ip4);
19925       clib_memcpy (&ip4, mp->rmt_ip, sizeof (ip4));
19926       vat_json_object_add_ip4 (node, "rmt_ip", ip4);
19927     }
19928   else
19929     {
19930       clib_memcpy (&ip6, mp->lcl_ip, sizeof (ip6));
19931       vat_json_object_add_ip6 (node, "lcl_ip", ip6);
19932       clib_memcpy (&ip6, mp->rmt_ip, sizeof (ip6));
19933       vat_json_object_add_ip6 (node, "rmt_ip", ip6);
19934     }
19935 }
19936
19937 static int
19938 api_session_rule_add_del (vat_main_t * vam)
19939 {
19940   vl_api_session_rule_add_del_t *mp;
19941   unformat_input_t *i = vam->input;
19942   u32 proto = ~0, lcl_port, rmt_port, action = 0, lcl_plen, rmt_plen;
19943   u32 appns_index = 0, scope = 0;
19944   ip4_address_t lcl_ip4, rmt_ip4;
19945   ip6_address_t lcl_ip6, rmt_ip6;
19946   u8 is_ip4 = 1, conn_set = 0;
19947   u8 is_add = 1, *tag = 0;
19948   int ret;
19949
19950   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19951     {
19952       if (unformat (i, "del"))
19953         is_add = 0;
19954       else if (unformat (i, "add"))
19955         ;
19956       else if (unformat (i, "proto tcp"))
19957         proto = 0;
19958       else if (unformat (i, "proto udp"))
19959         proto = 1;
19960       else if (unformat (i, "appns %d", &appns_index))
19961         ;
19962       else if (unformat (i, "scope %d", &scope))
19963         ;
19964       else if (unformat (i, "tag %_%v%_", &tag))
19965         ;
19966       else
19967         if (unformat
19968             (i, "%U/%d %d %U/%d %d", unformat_ip4_address, &lcl_ip4,
19969              &lcl_plen, &lcl_port, unformat_ip4_address, &rmt_ip4, &rmt_plen,
19970              &rmt_port))
19971         {
19972           is_ip4 = 1;
19973           conn_set = 1;
19974         }
19975       else
19976         if (unformat
19977             (i, "%U/%d %d %U/%d %d", unformat_ip6_address, &lcl_ip6,
19978              &lcl_plen, &lcl_port, unformat_ip6_address, &rmt_ip6, &rmt_plen,
19979              &rmt_port))
19980         {
19981           is_ip4 = 0;
19982           conn_set = 1;
19983         }
19984       else if (unformat (i, "action %d", &action))
19985         ;
19986       else
19987         break;
19988     }
19989   if (proto == ~0 || !conn_set || action == ~0)
19990     {
19991       errmsg ("transport proto, connection and action must be set");
19992       return -99;
19993     }
19994
19995   if (scope > 3)
19996     {
19997       errmsg ("scope should be 0-3");
19998       return -99;
19999     }
20000
20001   M (SESSION_RULE_ADD_DEL, mp);
20002
20003   mp->is_ip4 = is_ip4;
20004   mp->transport_proto = proto;
20005   mp->lcl_port = clib_host_to_net_u16 ((u16) lcl_port);
20006   mp->rmt_port = clib_host_to_net_u16 ((u16) rmt_port);
20007   mp->lcl_plen = lcl_plen;
20008   mp->rmt_plen = rmt_plen;
20009   mp->action_index = clib_host_to_net_u32 (action);
20010   mp->appns_index = clib_host_to_net_u32 (appns_index);
20011   mp->scope = scope;
20012   mp->is_add = is_add;
20013   if (is_ip4)
20014     {
20015       clib_memcpy (mp->lcl_ip, &lcl_ip4, sizeof (lcl_ip4));
20016       clib_memcpy (mp->rmt_ip, &rmt_ip4, sizeof (rmt_ip4));
20017     }
20018   else
20019     {
20020       clib_memcpy (mp->lcl_ip, &lcl_ip6, sizeof (lcl_ip6));
20021       clib_memcpy (mp->rmt_ip, &rmt_ip6, sizeof (rmt_ip6));
20022     }
20023   if (tag)
20024     {
20025       clib_memcpy (mp->tag, tag, vec_len (tag));
20026       vec_free (tag);
20027     }
20028
20029   S (mp);
20030   W (ret);
20031   return ret;
20032 }
20033
20034 static int
20035 api_session_rules_dump (vat_main_t * vam)
20036 {
20037   vl_api_session_rules_dump_t *mp;
20038   vl_api_control_ping_t *mp_ping;
20039   int ret;
20040
20041   if (!vam->json_output)
20042     {
20043       print (vam->ofp, "%=20s", "Session Rules");
20044     }
20045
20046   M (SESSION_RULES_DUMP, mp);
20047   /* send it... */
20048   S (mp);
20049
20050   /* Use a control ping for synchronization */
20051   MPING (CONTROL_PING, mp_ping);
20052   S (mp_ping);
20053
20054   /* Wait for a reply... */
20055   W (ret);
20056   return ret;
20057 }
20058
20059 static int
20060 api_ip_container_proxy_add_del (vat_main_t * vam)
20061 {
20062   vl_api_ip_container_proxy_add_del_t *mp;
20063   unformat_input_t *i = vam->input;
20064   u32 sw_if_index = ~0;
20065   vl_api_prefix_t pfx = { };
20066   u8 is_add = 1;
20067   int ret;
20068
20069   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20070     {
20071       if (unformat (i, "del"))
20072         is_add = 0;
20073       else if (unformat (i, "add"))
20074         ;
20075       if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
20076         ;
20077       else if (unformat (i, "sw_if_index %u", &sw_if_index))
20078         ;
20079       else
20080         break;
20081     }
20082   if (sw_if_index == ~0 || pfx.len == 0)
20083     {
20084       errmsg ("address and sw_if_index must be set");
20085       return -99;
20086     }
20087
20088   M (IP_CONTAINER_PROXY_ADD_DEL, mp);
20089
20090   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
20091   mp->is_add = is_add;
20092   clib_memcpy (&mp->pfx, &pfx, sizeof (pfx));
20093
20094   S (mp);
20095   W (ret);
20096   return ret;
20097 }
20098
20099 static int
20100 api_qos_record_enable_disable (vat_main_t * vam)
20101 {
20102   unformat_input_t *i = vam->input;
20103   vl_api_qos_record_enable_disable_t *mp;
20104   u32 sw_if_index, qs = 0xff;
20105   u8 sw_if_index_set = 0;
20106   u8 enable = 1;
20107   int ret;
20108
20109   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20110     {
20111       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20112         sw_if_index_set = 1;
20113       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20114         sw_if_index_set = 1;
20115       else if (unformat (i, "%U", unformat_qos_source, &qs))
20116         ;
20117       else if (unformat (i, "disable"))
20118         enable = 0;
20119       else
20120         {
20121           clib_warning ("parse error '%U'", format_unformat_error, i);
20122           return -99;
20123         }
20124     }
20125
20126   if (sw_if_index_set == 0)
20127     {
20128       errmsg ("missing interface name or sw_if_index");
20129       return -99;
20130     }
20131   if (qs == 0xff)
20132     {
20133       errmsg ("input location must be specified");
20134       return -99;
20135     }
20136
20137   M (QOS_RECORD_ENABLE_DISABLE, mp);
20138
20139   mp->record.sw_if_index = ntohl (sw_if_index);
20140   mp->record.input_source = qs;
20141   mp->enable = enable;
20142
20143   S (mp);
20144   W (ret);
20145   return ret;
20146 }
20147
20148
20149 static int
20150 q_or_quit (vat_main_t * vam)
20151 {
20152 #if VPP_API_TEST_BUILTIN == 0
20153   longjmp (vam->jump_buf, 1);
20154 #endif
20155   return 0;                     /* not so much */
20156 }
20157
20158 static int
20159 q (vat_main_t * vam)
20160 {
20161   return q_or_quit (vam);
20162 }
20163
20164 static int
20165 quit (vat_main_t * vam)
20166 {
20167   return q_or_quit (vam);
20168 }
20169
20170 static int
20171 comment (vat_main_t * vam)
20172 {
20173   return 0;
20174 }
20175
20176 static int
20177 elog_save (vat_main_t * vam)
20178 {
20179 #if VPP_API_TEST_BUILTIN == 0
20180   elog_main_t *em = &vam->elog_main;
20181   unformat_input_t *i = vam->input;
20182   char *file, *chroot_file;
20183   clib_error_t *error;
20184
20185   if (!unformat (i, "%s", &file))
20186     {
20187       errmsg ("expected file name, got `%U'", format_unformat_error, i);
20188       return 0;
20189     }
20190
20191   /* It's fairly hard to get "../oopsie" through unformat; just in case */
20192   if (strstr (file, "..") || index (file, '/'))
20193     {
20194       errmsg ("illegal characters in filename '%s'", file);
20195       return 0;
20196     }
20197
20198   chroot_file = (char *) format (0, "/tmp/%s%c", file, 0);
20199
20200   vec_free (file);
20201
20202   errmsg ("Saving %wd of %wd events to %s",
20203           elog_n_events_in_buffer (em),
20204           elog_buffer_capacity (em), chroot_file);
20205
20206   error = elog_write_file (em, chroot_file, 1 /* flush ring */ );
20207   vec_free (chroot_file);
20208
20209   if (error)
20210     clib_error_report (error);
20211 #else
20212   errmsg ("Use the vpp event loger...");
20213 #endif
20214
20215   return 0;
20216 }
20217
20218 static int
20219 elog_setup (vat_main_t * vam)
20220 {
20221 #if VPP_API_TEST_BUILTIN == 0
20222   elog_main_t *em = &vam->elog_main;
20223   unformat_input_t *i = vam->input;
20224   u32 nevents = 128 << 10;
20225
20226   (void) unformat (i, "nevents %d", &nevents);
20227
20228   elog_init (em, nevents);
20229   vl_api_set_elog_main (em);
20230   vl_api_set_elog_trace_api_messages (1);
20231   errmsg ("Event logger initialized with %u events", nevents);
20232 #else
20233   errmsg ("Use the vpp event loger...");
20234 #endif
20235   return 0;
20236 }
20237
20238 static int
20239 elog_enable (vat_main_t * vam)
20240 {
20241 #if VPP_API_TEST_BUILTIN == 0
20242   elog_main_t *em = &vam->elog_main;
20243
20244   elog_enable_disable (em, 1 /* enable */ );
20245   vl_api_set_elog_trace_api_messages (1);
20246   errmsg ("Event logger enabled...");
20247 #else
20248   errmsg ("Use the vpp event loger...");
20249 #endif
20250   return 0;
20251 }
20252
20253 static int
20254 elog_disable (vat_main_t * vam)
20255 {
20256 #if VPP_API_TEST_BUILTIN == 0
20257   elog_main_t *em = &vam->elog_main;
20258
20259   elog_enable_disable (em, 0 /* enable */ );
20260   vl_api_set_elog_trace_api_messages (1);
20261   errmsg ("Event logger disabled...");
20262 #else
20263   errmsg ("Use the vpp event loger...");
20264 #endif
20265   return 0;
20266 }
20267
20268 static int
20269 statseg (vat_main_t * vam)
20270 {
20271   ssvm_private_t *ssvmp = &vam->stat_segment;
20272   ssvm_shared_header_t *shared_header = ssvmp->sh;
20273   vlib_counter_t **counters;
20274   u64 thread0_index1_packets;
20275   u64 thread0_index1_bytes;
20276   f64 vector_rate, input_rate;
20277   uword *p;
20278
20279   uword *counter_vector_by_name;
20280   if (vam->stat_segment_lockp == 0)
20281     {
20282       errmsg ("Stat segment not mapped...");
20283       return -99;
20284     }
20285
20286   /* look up "/if/rx for sw_if_index 1 as a test */
20287
20288   clib_spinlock_lock (vam->stat_segment_lockp);
20289
20290   counter_vector_by_name = (uword *) shared_header->opaque[1];
20291
20292   p = hash_get_mem (counter_vector_by_name, "/if/rx");
20293   if (p == 0)
20294     {
20295       clib_spinlock_unlock (vam->stat_segment_lockp);
20296       errmsg ("/if/tx not found?");
20297       return -99;
20298     }
20299
20300   /* Fish per-thread vector of combined counters from shared memory */
20301   counters = (vlib_counter_t **) p[0];
20302
20303   if (vec_len (counters[0]) < 2)
20304     {
20305       clib_spinlock_unlock (vam->stat_segment_lockp);
20306       errmsg ("/if/tx vector length %d", vec_len (counters[0]));
20307       return -99;
20308     }
20309
20310   /* Read thread 0 sw_if_index 1 counter */
20311   thread0_index1_packets = counters[0][1].packets;
20312   thread0_index1_bytes = counters[0][1].bytes;
20313
20314   p = hash_get_mem (counter_vector_by_name, "vector_rate");
20315   if (p == 0)
20316     {
20317       clib_spinlock_unlock (vam->stat_segment_lockp);
20318       errmsg ("vector_rate not found?");
20319       return -99;
20320     }
20321
20322   vector_rate = *(f64 *) (p[0]);
20323   p = hash_get_mem (counter_vector_by_name, "input_rate");
20324   if (p == 0)
20325     {
20326       clib_spinlock_unlock (vam->stat_segment_lockp);
20327       errmsg ("input_rate not found?");
20328       return -99;
20329     }
20330   input_rate = *(f64 *) (p[0]);
20331
20332   clib_spinlock_unlock (vam->stat_segment_lockp);
20333
20334   print (vam->ofp, "vector_rate %.2f input_rate %.2f",
20335          vector_rate, input_rate);
20336   print (vam->ofp, "thread 0 sw_if_index 1 rx pkts %lld, bytes %lld",
20337          thread0_index1_packets, thread0_index1_bytes);
20338
20339   return 0;
20340 }
20341
20342 static int
20343 cmd_cmp (void *a1, void *a2)
20344 {
20345   u8 **c1 = a1;
20346   u8 **c2 = a2;
20347
20348   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
20349 }
20350
20351 static int
20352 help (vat_main_t * vam)
20353 {
20354   u8 **cmds = 0;
20355   u8 *name = 0;
20356   hash_pair_t *p;
20357   unformat_input_t *i = vam->input;
20358   int j;
20359
20360   if (unformat (i, "%s", &name))
20361     {
20362       uword *hs;
20363
20364       vec_add1 (name, 0);
20365
20366       hs = hash_get_mem (vam->help_by_name, name);
20367       if (hs)
20368         print (vam->ofp, "usage: %s %s", name, hs[0]);
20369       else
20370         print (vam->ofp, "No such msg / command '%s'", name);
20371       vec_free (name);
20372       return 0;
20373     }
20374
20375   print (vam->ofp, "Help is available for the following:");
20376
20377     /* *INDENT-OFF* */
20378     hash_foreach_pair (p, vam->function_by_name,
20379     ({
20380       vec_add1 (cmds, (u8 *)(p->key));
20381     }));
20382     /* *INDENT-ON* */
20383
20384   vec_sort_with_function (cmds, cmd_cmp);
20385
20386   for (j = 0; j < vec_len (cmds); j++)
20387     print (vam->ofp, "%s", cmds[j]);
20388
20389   vec_free (cmds);
20390   return 0;
20391 }
20392
20393 static int
20394 set (vat_main_t * vam)
20395 {
20396   u8 *name = 0, *value = 0;
20397   unformat_input_t *i = vam->input;
20398
20399   if (unformat (i, "%s", &name))
20400     {
20401       /* The input buffer is a vector, not a string. */
20402       value = vec_dup (i->buffer);
20403       vec_delete (value, i->index, 0);
20404       /* Almost certainly has a trailing newline */
20405       if (value[vec_len (value) - 1] == '\n')
20406         value[vec_len (value) - 1] = 0;
20407       /* Make sure it's a proper string, one way or the other */
20408       vec_add1 (value, 0);
20409       (void) clib_macro_set_value (&vam->macro_main,
20410                                    (char *) name, (char *) value);
20411     }
20412   else
20413     errmsg ("usage: set <name> <value>");
20414
20415   vec_free (name);
20416   vec_free (value);
20417   return 0;
20418 }
20419
20420 static int
20421 unset (vat_main_t * vam)
20422 {
20423   u8 *name = 0;
20424
20425   if (unformat (vam->input, "%s", &name))
20426     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
20427       errmsg ("unset: %s wasn't set", name);
20428   vec_free (name);
20429   return 0;
20430 }
20431
20432 typedef struct
20433 {
20434   u8 *name;
20435   u8 *value;
20436 } macro_sort_t;
20437
20438
20439 static int
20440 macro_sort_cmp (void *a1, void *a2)
20441 {
20442   macro_sort_t *s1 = a1;
20443   macro_sort_t *s2 = a2;
20444
20445   return strcmp ((char *) (s1->name), (char *) (s2->name));
20446 }
20447
20448 static int
20449 dump_macro_table (vat_main_t * vam)
20450 {
20451   macro_sort_t *sort_me = 0, *sm;
20452   int i;
20453   hash_pair_t *p;
20454
20455     /* *INDENT-OFF* */
20456     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
20457     ({
20458       vec_add2 (sort_me, sm, 1);
20459       sm->name = (u8 *)(p->key);
20460       sm->value = (u8 *) (p->value[0]);
20461     }));
20462     /* *INDENT-ON* */
20463
20464   vec_sort_with_function (sort_me, macro_sort_cmp);
20465
20466   if (vec_len (sort_me))
20467     print (vam->ofp, "%-15s%s", "Name", "Value");
20468   else
20469     print (vam->ofp, "The macro table is empty...");
20470
20471   for (i = 0; i < vec_len (sort_me); i++)
20472     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
20473   return 0;
20474 }
20475
20476 static int
20477 dump_node_table (vat_main_t * vam)
20478 {
20479   int i, j;
20480   vlib_node_t *node, *next_node;
20481
20482   if (vec_len (vam->graph_nodes) == 0)
20483     {
20484       print (vam->ofp, "Node table empty, issue get_node_graph...");
20485       return 0;
20486     }
20487
20488   for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
20489     {
20490       node = vam->graph_nodes[0][i];
20491       print (vam->ofp, "[%d] %s", i, node->name);
20492       for (j = 0; j < vec_len (node->next_nodes); j++)
20493         {
20494           if (node->next_nodes[j] != ~0)
20495             {
20496               next_node = vam->graph_nodes[0][node->next_nodes[j]];
20497               print (vam->ofp, "  [%d] %s", j, next_node->name);
20498             }
20499         }
20500     }
20501   return 0;
20502 }
20503
20504 static int
20505 value_sort_cmp (void *a1, void *a2)
20506 {
20507   name_sort_t *n1 = a1;
20508   name_sort_t *n2 = a2;
20509
20510   if (n1->value < n2->value)
20511     return -1;
20512   if (n1->value > n2->value)
20513     return 1;
20514   return 0;
20515 }
20516
20517
20518 static int
20519 dump_msg_api_table (vat_main_t * vam)
20520 {
20521   api_main_t *am = vlibapi_get_main ();
20522   name_sort_t *nses = 0, *ns;
20523   hash_pair_t *hp;
20524   int i;
20525
20526   /* *INDENT-OFF* */
20527   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
20528   ({
20529     vec_add2 (nses, ns, 1);
20530     ns->name = (u8 *)(hp->key);
20531     ns->value = (u32) hp->value[0];
20532   }));
20533   /* *INDENT-ON* */
20534
20535   vec_sort_with_function (nses, value_sort_cmp);
20536
20537   for (i = 0; i < vec_len (nses); i++)
20538     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
20539   vec_free (nses);
20540   return 0;
20541 }
20542
20543 static int
20544 get_msg_id (vat_main_t * vam)
20545 {
20546   u8 *name_and_crc;
20547   u32 message_index;
20548
20549   if (unformat (vam->input, "%s", &name_and_crc))
20550     {
20551       message_index = vl_msg_api_get_msg_index (name_and_crc);
20552       if (message_index == ~0)
20553         {
20554           print (vam->ofp, " '%s' not found", name_and_crc);
20555           return 0;
20556         }
20557       print (vam->ofp, " '%s' has message index %d",
20558              name_and_crc, message_index);
20559       return 0;
20560     }
20561   errmsg ("name_and_crc required...");
20562   return 0;
20563 }
20564
20565 static int
20566 search_node_table (vat_main_t * vam)
20567 {
20568   unformat_input_t *line_input = vam->input;
20569   u8 *node_to_find;
20570   int j;
20571   vlib_node_t *node, *next_node;
20572   uword *p;
20573
20574   if (vam->graph_node_index_by_name == 0)
20575     {
20576       print (vam->ofp, "Node table empty, issue get_node_graph...");
20577       return 0;
20578     }
20579
20580   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
20581     {
20582       if (unformat (line_input, "%s", &node_to_find))
20583         {
20584           vec_add1 (node_to_find, 0);
20585           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
20586           if (p == 0)
20587             {
20588               print (vam->ofp, "%s not found...", node_to_find);
20589               goto out;
20590             }
20591           node = vam->graph_nodes[0][p[0]];
20592           print (vam->ofp, "[%d] %s", p[0], node->name);
20593           for (j = 0; j < vec_len (node->next_nodes); j++)
20594             {
20595               if (node->next_nodes[j] != ~0)
20596                 {
20597                   next_node = vam->graph_nodes[0][node->next_nodes[j]];
20598                   print (vam->ofp, "  [%d] %s", j, next_node->name);
20599                 }
20600             }
20601         }
20602
20603       else
20604         {
20605           clib_warning ("parse error '%U'", format_unformat_error,
20606                         line_input);
20607           return -99;
20608         }
20609
20610     out:
20611       vec_free (node_to_find);
20612
20613     }
20614
20615   return 0;
20616 }
20617
20618
20619 static int
20620 script (vat_main_t * vam)
20621 {
20622 #if (VPP_API_TEST_BUILTIN==0)
20623   u8 *s = 0;
20624   char *save_current_file;
20625   unformat_input_t save_input;
20626   jmp_buf save_jump_buf;
20627   u32 save_line_number;
20628
20629   FILE *new_fp, *save_ifp;
20630
20631   if (unformat (vam->input, "%s", &s))
20632     {
20633       new_fp = fopen ((char *) s, "r");
20634       if (new_fp == 0)
20635         {
20636           errmsg ("Couldn't open script file %s", s);
20637           vec_free (s);
20638           return -99;
20639         }
20640     }
20641   else
20642     {
20643       errmsg ("Missing script name");
20644       return -99;
20645     }
20646
20647   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
20648   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
20649   save_ifp = vam->ifp;
20650   save_line_number = vam->input_line_number;
20651   save_current_file = (char *) vam->current_file;
20652
20653   vam->input_line_number = 0;
20654   vam->ifp = new_fp;
20655   vam->current_file = s;
20656   do_one_file (vam);
20657
20658   clib_memcpy (&vam->input, &save_input, sizeof (save_input));
20659   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
20660   vam->ifp = save_ifp;
20661   vam->input_line_number = save_line_number;
20662   vam->current_file = (u8 *) save_current_file;
20663   vec_free (s);
20664
20665   return 0;
20666 #else
20667   clib_warning ("use the exec command...");
20668   return -99;
20669 #endif
20670 }
20671
20672 static int
20673 echo (vat_main_t * vam)
20674 {
20675   print (vam->ofp, "%v", vam->input->buffer);
20676   return 0;
20677 }
20678
20679 /* List of API message constructors, CLI names map to api_xxx */
20680 #define foreach_vpe_api_msg                                             \
20681 _(create_loopback,"[mac <mac-addr>] [instance <instance>]")             \
20682 _(sw_interface_dump,"")                                                 \
20683 _(sw_interface_set_flags,                                               \
20684   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
20685 _(sw_interface_add_del_address,                                         \
20686   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
20687 _(sw_interface_set_rx_mode,                                             \
20688   "<intfc> | sw_if_index <id> [queue <id>] <polling | interrupt | adaptive>") \
20689 _(sw_interface_set_rx_placement,                                        \
20690   "<intfc> | sw_if_index <id> [queue <id>] [worker <id> | main]")       \
20691 _(sw_interface_rx_placement_dump,                                       \
20692   "[<intfc> | sw_if_index <id>]")                                         \
20693 _(sw_interface_set_table,                                               \
20694   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
20695 _(sw_interface_set_mpls_enable,                                         \
20696   "<intfc> | sw_if_index [disable | dis]")                              \
20697 _(sw_interface_set_vpath,                                               \
20698   "<intfc> | sw_if_index <id> enable | disable")                        \
20699 _(sw_interface_set_vxlan_bypass,                                        \
20700   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
20701 _(sw_interface_set_geneve_bypass,                                       \
20702   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
20703 _(sw_interface_set_l2_xconnect,                                         \
20704   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
20705   "enable | disable")                                                   \
20706 _(sw_interface_set_l2_bridge,                                           \
20707   "{<intfc> | sw_if_index <id>} bd_id <bridge-domain-id>\n"             \
20708   "[shg <split-horizon-group>] [bvi]\n"                                 \
20709   "enable | disable")                                                   \
20710 _(bridge_domain_set_mac_age, "bd_id <bridge-domain-id> mac-age 0-255")  \
20711 _(bridge_domain_add_del,                                                \
20712   "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") \
20713 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
20714 _(l2fib_add_del,                                                        \
20715   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
20716 _(l2fib_flush_bd, "bd_id <bridge-domain-id>")                           \
20717 _(l2fib_flush_int, "<intfc> | sw_if_index <id>")                        \
20718 _(l2_flags,                                                             \
20719   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
20720 _(bridge_flags,                                                         \
20721   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
20722 _(tap_create_v2,                                                        \
20723   "id <num> [hw-addr <mac-addr>] [host-ns <name>] [rx-ring-size <num> [tx-ring-size <num>] [host-mtu-size <mtu>] [gso | no-gso]") \
20724 _(tap_delete_v2,                                                        \
20725   "<vpp-if-name> | sw_if_index <id>")                                   \
20726 _(sw_interface_tap_v2_dump, "")                                         \
20727 _(virtio_pci_create,                                                    \
20728   "pci-addr <pci-address> [use_random_mac | hw-addr <mac-addr>] [features <hex-value>] [gso-enabled | csum-offload-enabled]") \
20729 _(virtio_pci_delete,                                                    \
20730   "<vpp-if-name> | sw_if_index <id>")                                   \
20731 _(sw_interface_virtio_pci_dump, "")                                     \
20732 _(bond_create,                                                          \
20733   "[hw-addr <mac-addr>] {round-robin | active-backup | "                \
20734   "broadcast | {lacp | xor} [load-balance { l2 | l23 | l34 }]} "        \
20735   "[id <if-id>]")                                                       \
20736 _(bond_delete,                                                          \
20737   "<vpp-if-name> | sw_if_index <id>")                                   \
20738 _(bond_enslave,                                                         \
20739   "sw_if_index <n> bond <sw_if_index> [is_passive] [is_long_timeout]")  \
20740 _(bond_detach_slave,                                                    \
20741   "sw_if_index <n>")                                                    \
20742  _(sw_interface_set_bond_weight, "<intfc> | sw_if_index <nn> weight <value>") \
20743 _(sw_interface_bond_dump, "")                                           \
20744 _(sw_interface_slave_dump,                                              \
20745   "<vpp-if-name> | sw_if_index <id>")                                   \
20746 _(ip_table_add_del,                                                     \
20747   "table <n> [ipv6] [add | del]\n")                                     \
20748 _(ip_route_add_del,                                                     \
20749   "<addr>/<mask> via <<addr>|<intfc>|sw_if_index <id>|via-label <n>>\n" \
20750   "[table-id <n>] [<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"\
20751   "[weight <n>] [drop] [local] [classify <n>]  [out-label <n>]\n"       \
20752   "[multipath] [count <n>] [del]")                                      \
20753 _(ip_mroute_add_del,                                                    \
20754   "<src> <grp>/<mask> [table-id <n>]\n"                                 \
20755   "[<intfc> | sw_if_index <id>] [local] [del]")                         \
20756 _(mpls_table_add_del,                                                   \
20757   "table <n> [add | del]\n")                                            \
20758 _(mpls_route_add_del,                                                   \
20759   "<label> <eos> via <addr | next-hop-table <n> | via-label <n> |\n"    \
20760   "lookup-ip4-table <n> | lookup-in-ip6-table <n> |\n"                  \
20761   "l2-input-on <intfc> | l2-input-on sw_if_index <id>>\n"               \
20762   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>] [weight <n>]\n"  \
20763   "[drop] [local] [classify <n>] [out-label <n>] [multipath]\n"         \
20764   "[count <n>] [del]")                                                  \
20765 _(mpls_ip_bind_unbind,                                                  \
20766   "<label> <addr/len>")                                                 \
20767 _(mpls_tunnel_add_del,                                                  \
20768   "[add | del <intfc | sw_if_index <id>>] via <addr | via-label <n>>\n" \
20769   "[<intfc> | sw_if_index <id> | next-hop-table <id>]\n"                \
20770   "[l2-only]  [out-label <n>]")                                         \
20771 _(sr_mpls_policy_add,                                                   \
20772   "bsid <id> [weight <n>] [spray] next <sid> [next <sid>]")             \
20773 _(sr_mpls_policy_del,                                                   \
20774   "bsid <id>")                                                          \
20775 _(bier_table_add_del,                                                   \
20776   "<label> <sub-domain> <set> <bsl> [del]")                             \
20777 _(bier_route_add_del,                                                   \
20778   "<bit-position> <sub-domain> <set> <bsl> via <addr> [table-id <n>]\n" \
20779   "[<intfc> | sw_if_index <id>]"                                        \
20780   "[weight <n>] [del] [multipath]")                                     \
20781 _(sw_interface_set_unnumbered,                                          \
20782   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
20783 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
20784 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
20785   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
20786   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
20787   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
20788 _(ip_table_replace_begin, "table <n> [ipv6]")                           \
20789 _(ip_table_flush, "table <n> [ipv6]")                                   \
20790 _(ip_table_replace_end, "table <n> [ipv6]")                             \
20791 _(set_ip_flow_hash,                                                     \
20792   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
20793 _(sw_interface_ip6_enable_disable,                                      \
20794   "<intfc> | sw_if_index <id> enable | disable")                        \
20795 _(l2_patch_add_del,                                                     \
20796   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
20797   "enable | disable")                                                   \
20798 _(sr_localsid_add_del,                                                  \
20799   "(del) address <addr> next_hop <addr> behavior <beh>\n"               \
20800   "fib-table <num> (end.psp) sw_if_index <num>")                        \
20801 _(classify_add_del_table,                                               \
20802   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
20803   " [del] [del-chain] mask <mask-value>\n"                              \
20804   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
20805   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
20806 _(classify_add_del_session,                                             \
20807   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
20808   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
20809   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
20810   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
20811 _(classify_set_interface_ip_table,                                      \
20812   "<intfc> | sw_if_index <nn> table <nn>")                              \
20813 _(classify_set_interface_l2_tables,                                     \
20814   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
20815   "  [other-table <nn>]")                                               \
20816 _(get_node_index, "node <node-name")                                    \
20817 _(add_node_next, "node <node-name> next <next-node-name>")              \
20818 _(l2tpv3_create_tunnel,                                                 \
20819   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
20820   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
20821   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
20822 _(l2tpv3_set_tunnel_cookies,                                            \
20823   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
20824   "[new_remote_cookie <nn>]\n")                                         \
20825 _(l2tpv3_interface_enable_disable,                                      \
20826   "<intfc> | sw_if_index <nn> enable | disable")                        \
20827 _(l2tpv3_set_lookup_key,                                                \
20828   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
20829 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
20830 _(vxlan_offload_rx,                                                     \
20831   "hw { <interface name> | hw_if_index <nn>} "                          \
20832   "rx { <vxlan tunnel name> | sw_if_index <nn> } [del]")                \
20833 _(vxlan_add_del_tunnel,                                                 \
20834   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
20835   "{ <intfc> | mcast_sw_if_index <nn> } [instance <id>]}\n"             \
20836   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
20837 _(geneve_add_del_tunnel,                                                \
20838   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
20839   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
20840   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
20841 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
20842 _(geneve_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                   \
20843 _(gre_tunnel_add_del,                                                   \
20844   "src <ip-addr> dst <ip-addr> [outer-fib-id <nn>] [instance <n>]\n"    \
20845   "[teb | erspan <session-id>] [del]")                                  \
20846 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
20847 _(l2_fib_clear_table, "")                                               \
20848 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
20849 _(l2_interface_vlan_tag_rewrite,                                        \
20850   "<intfc> | sw_if_index <nn> \n"                                       \
20851   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
20852   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
20853 _(create_vhost_user_if,                                                 \
20854         "socket <filename> [server] [renumber <dev_instance>] "         \
20855         "[disable_mrg_rxbuf] [disable_indirect_desc] [gso] "            \
20856         "[mac <mac_address>]")                                          \
20857 _(modify_vhost_user_if,                                                 \
20858         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
20859         "[server] [renumber <dev_instance>] [gso]")                     \
20860 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
20861 _(sw_interface_vhost_user_dump, "")                                     \
20862 _(show_version, "")                                                     \
20863 _(show_threads, "")                                                     \
20864 _(vxlan_gpe_add_del_tunnel,                                             \
20865   "local <addr> remote <addr>  | group <mcast-ip-addr>\n"               \
20866   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
20867   "vni <nn> [encap-vrf-id <nn>] [decap-vrf-id <nn>]\n"                  \
20868   "[next-ip4][next-ip6][next-ethernet] [next-nsh] [del]\n")             \
20869 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
20870 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
20871 _(interface_name_renumber,                                              \
20872   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
20873 _(input_acl_set_interface,                                              \
20874   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
20875   "  [l2-table <nn>] [del]")                                            \
20876 _(want_l2_macs_events, "[disable] [learn-limit <n>] [scan-delay <n>] [max-entries <n>]") \
20877 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
20878 _(ip_dump, "ipv4 | ipv6")                                               \
20879 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
20880 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
20881   "  spid_id <n> ")                                                     \
20882 _(ipsec_sad_entry_add_del, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
20883   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
20884   "  integ_alg <alg> integ_key <hex>")                                  \
20885 _(ipsec_spd_entry_add_del, "spd_id <n> priority <n> action <action>\n"  \
20886   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
20887   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
20888   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
20889 _(ipsec_tunnel_if_add_del, "local_spi <n> remote_spi <n>\n"             \
20890   "  crypto_alg <alg> local_crypto_key <hex> remote_crypto_key <hex>\n" \
20891   "  integ_alg <alg> local_integ_key <hex> remote_integ_key <hex>\n"    \
20892   "  local_ip <addr> remote_ip <addr> [esn] [anti_replay] [del]\n"      \
20893   "  [instance <n>]")     \
20894 _(ipsec_sa_dump, "[sa_id <n>]")                                         \
20895 _(ipsec_tunnel_if_set_sa, "<intfc> sa_id <n> <inbound|outbound>\n")     \
20896 _(delete_loopback,"sw_if_index <nn>")                                   \
20897 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
20898 _(bd_ip_mac_flush, "bd_id <bridge-domain-id>")                          \
20899 _(bd_ip_mac_dump, "[bd_id] <bridge-domain-id>")                         \
20900 _(want_interface_events,  "enable|disable")                             \
20901 _(get_first_msg_id, "client <name>")                                    \
20902 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
20903 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
20904   "fib-id <nn> [ip4][ip6][default]")                                    \
20905 _(get_node_graph, " ")                                                  \
20906 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
20907 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
20908 _(ioam_disable, "")                                                     \
20909 _(one_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
20910                             " sw_if_index <sw_if_index> p <priority> "  \
20911                             "w <weight>] [del]")                        \
20912 _(one_add_del_locator, "locator-set <locator_name> "                    \
20913                         "iface <intf> | sw_if_index <sw_if_index> "     \
20914                         "p <priority> w <weight> [del]")                \
20915 _(one_add_del_local_eid,"vni <vni> eid "                                \
20916                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
20917                          "locator-set <locator_name> [del]"             \
20918                          "[key-id sha1|sha256 secret-key <secret-key>]")\
20919 _(one_add_del_map_resolver, "<ip4|6-addr> [del]")                       \
20920 _(one_add_del_map_server, "<ip4|6-addr> [del]")                         \
20921 _(one_enable_disable, "enable|disable")                                 \
20922 _(one_map_register_enable_disable, "enable|disable")                    \
20923 _(one_map_register_fallback_threshold, "<value>")                       \
20924 _(one_rloc_probe_enable_disable, "enable|disable")                      \
20925 _(one_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "       \
20926                                "[seid <seid>] "                         \
20927                                "rloc <locator> p <prio> "               \
20928                                "w <weight> [rloc <loc> ... ] "          \
20929                                "action <action> [del-all]")             \
20930 _(one_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "    \
20931                           "<local-eid>")                                \
20932 _(one_pitr_set_locator_set, "locator-set <loc-set-name> | del")         \
20933 _(one_use_petr, "ip-address> | disable")                                \
20934 _(one_map_request_mode, "src-dst|dst-only")                             \
20935 _(one_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")            \
20936 _(one_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")               \
20937 _(one_locator_set_dump, "[local | remote]")                             \
20938 _(one_locator_dump, "ls_index <index> | ls_name <name>")                \
20939 _(one_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "       \
20940                        "[local] | [remote]")                            \
20941 _(one_add_del_ndp_entry, "[del] mac <mac> bd <bd> ip6 <ip6>")           \
20942 _(one_ndp_bd_get, "")                                                   \
20943 _(one_ndp_entries_get, "bd <bridge-domain>")                            \
20944 _(one_add_del_l2_arp_entry, "[del] mac <mac> bd <bd> ip4 <ip4>")        \
20945 _(one_l2_arp_bd_get, "")                                                \
20946 _(one_l2_arp_entries_get, "bd <bridge-domain>")                         \
20947 _(one_stats_enable_disable, "enable|disable")                           \
20948 _(show_one_stats_enable_disable, "")                                    \
20949 _(one_eid_table_vni_dump, "")                                           \
20950 _(one_eid_table_map_dump, "l2|l3")                                      \
20951 _(one_map_resolver_dump, "")                                            \
20952 _(one_map_server_dump, "")                                              \
20953 _(one_adjacencies_get, "vni <vni>")                                     \
20954 _(one_nsh_set_locator_set, "[del] ls <locator-set-name>")               \
20955 _(show_one_rloc_probe_state, "")                                        \
20956 _(show_one_map_register_state, "")                                      \
20957 _(show_one_status, "")                                                  \
20958 _(one_stats_dump, "")                                                   \
20959 _(one_stats_flush, "")                                                  \
20960 _(one_get_map_request_itr_rlocs, "")                                    \
20961 _(one_map_register_set_ttl, "<ttl>")                                    \
20962 _(one_set_transport_protocol, "udp|api")                                \
20963 _(one_get_transport_protocol, "")                                       \
20964 _(one_enable_disable_xtr_mode, "enable|disable")                        \
20965 _(one_show_xtr_mode, "")                                                \
20966 _(one_enable_disable_pitr_mode, "enable|disable")                       \
20967 _(one_show_pitr_mode, "")                                               \
20968 _(one_enable_disable_petr_mode, "enable|disable")                       \
20969 _(one_show_petr_mode, "")                                               \
20970 _(show_one_nsh_mapping, "")                                             \
20971 _(show_one_pitr, "")                                                    \
20972 _(show_one_use_petr, "")                                                \
20973 _(show_one_map_request_mode, "")                                        \
20974 _(show_one_map_register_ttl, "")                                        \
20975 _(show_one_map_register_fallback_threshold, "")                         \
20976 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
20977                             " sw_if_index <sw_if_index> p <priority> "  \
20978                             "w <weight>] [del]")                        \
20979 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
20980                         "iface <intf> | sw_if_index <sw_if_index> "     \
20981                         "p <priority> w <weight> [del]")                \
20982 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
20983                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
20984                          "locator-set <locator_name> [del]"             \
20985                          "[key-id sha1|sha256 secret-key <secret-key>]") \
20986 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
20987 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
20988 _(lisp_enable_disable, "enable|disable")                                \
20989 _(lisp_map_register_enable_disable, "enable|disable")                   \
20990 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
20991 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
20992                                "[seid <seid>] "                         \
20993                                "rloc <locator> p <prio> "               \
20994                                "w <weight> [rloc <loc> ... ] "          \
20995                                "action <action> [del-all]")             \
20996 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
20997                           "<local-eid>")                                \
20998 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
20999 _(lisp_use_petr, "<ip-address> | disable")                              \
21000 _(lisp_map_request_mode, "src-dst|dst-only")                            \
21001 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
21002 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
21003 _(lisp_locator_set_dump, "[local | remote]")                            \
21004 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
21005 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
21006                        "[local] | [remote]")                            \
21007 _(lisp_eid_table_vni_dump, "")                                          \
21008 _(lisp_eid_table_map_dump, "l2|l3")                                     \
21009 _(lisp_map_resolver_dump, "")                                           \
21010 _(lisp_map_server_dump, "")                                             \
21011 _(lisp_adjacencies_get, "vni <vni>")                                    \
21012 _(gpe_fwd_entry_vnis_get, "")                                           \
21013 _(gpe_native_fwd_rpaths_get, "ip4 | ip6")                               \
21014 _(gpe_add_del_native_fwd_rpath, "[del] via <nh-ip-addr> [iface] "       \
21015                                 "[table <table-id>]")                   \
21016 _(lisp_gpe_fwd_entries_get, "vni <vni>")                                \
21017 _(lisp_gpe_fwd_entry_path_dump, "index <fwd_entry_index>")              \
21018 _(gpe_set_encap_mode, "lisp|vxlan")                                     \
21019 _(gpe_get_encap_mode, "")                                               \
21020 _(lisp_gpe_add_del_iface, "up|down")                                    \
21021 _(lisp_gpe_enable_disable, "enable|disable")                            \
21022 _(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>"       \
21023   "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
21024 _(show_lisp_rloc_probe_state, "")                                       \
21025 _(show_lisp_map_register_state, "")                                     \
21026 _(show_lisp_status, "")                                                 \
21027 _(lisp_get_map_request_itr_rlocs, "")                                   \
21028 _(show_lisp_pitr, "")                                                   \
21029 _(show_lisp_use_petr, "")                                               \
21030 _(show_lisp_map_request_mode, "")                                       \
21031 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
21032 _(af_packet_delete, "name <host interface name>")                       \
21033 _(af_packet_dump, "")                                                   \
21034 _(policer_add_del, "name <policer name> <params> [del]")                \
21035 _(policer_dump, "[name <policer name>]")                                \
21036 _(policer_classify_set_interface,                                       \
21037   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
21038   "  [l2-table <nn>] [del]")                                            \
21039 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
21040 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
21041     "[master|slave]")                                                   \
21042 _(netmap_delete, "name <interface name>")                               \
21043 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
21044 _(mpls_table_dump, "")                                                  \
21045 _(mpls_route_dump, "table-id <ID>")                                     \
21046 _(classify_table_ids, "")                                               \
21047 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
21048 _(classify_table_info, "table_id <nn>")                                 \
21049 _(classify_session_dump, "table_id <nn>")                               \
21050 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
21051     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
21052     "[template_interval <nn>] [udp_checksum]")                          \
21053 _(ipfix_exporter_dump, "")                                              \
21054 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
21055 _(ipfix_classify_stream_dump, "")                                       \
21056 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
21057 _(ipfix_classify_table_dump, "")                                        \
21058 _(sw_interface_span_enable_disable, "[l2] [src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
21059 _(sw_interface_span_dump, "[l2]")                                           \
21060 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
21061 _(pg_create_interface, "if_id <nn> [gso-enabled gso-size <size>]")      \
21062 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
21063 _(pg_enable_disable, "[stream <id>] disable")                           \
21064 _(ip_source_and_port_range_check_add_del,                               \
21065   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
21066 _(ip_source_and_port_range_check_interface_add_del,                     \
21067   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
21068   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
21069 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
21070 _(l2_interface_pbb_tag_rewrite,                                         \
21071   "<intfc> | sw_if_index <nn> \n"                                       \
21072   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
21073   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
21074 _(set_punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
21075 _(flow_classify_set_interface,                                          \
21076   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
21077 _(flow_classify_dump, "type [ip4|ip6]")                                 \
21078 _(ip_table_dump, "")                                                    \
21079 _(ip_route_dump, "table-id [ip4|ip6]")                                  \
21080 _(ip_mtable_dump, "")                                                   \
21081 _(ip_mroute_dump, "table-id [ip4|ip6]")                                 \
21082 _(feature_enable_disable, "arc_name <arc_name> "                        \
21083   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
21084 _(feature_gso_enable_disable, "<intfc> | sw_if_index <nn> "             \
21085   "[enable | disable] ")                                                \
21086 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
21087 "[disable]")                                                            \
21088 _(sw_interface_add_del_mac_address, "<intfc> | sw_if_index <nn> "       \
21089   "mac <mac-address> [del]")                                            \
21090 _(l2_xconnect_dump, "")                                                 \
21091 _(hw_interface_set_mtu, "<intfc> | hw_if_index <nn> mtu <nn>")        \
21092 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")          \
21093 _(p2p_ethernet_add, "<intfc> | sw_if_index <nn> remote_mac <mac-address> sub_id <id>") \
21094 _(p2p_ethernet_del, "<intfc> | sw_if_index <nn> remote_mac <mac-address>") \
21095 _(lldp_config, "system-name <name> tx-hold <nn> tx-interval <nn>") \
21096 _(sw_interface_set_lldp, "<intfc> | sw_if_index <nn> [port-desc <description>]\n" \
21097   " [mgmt-ip4 <ip4>] [mgmt-ip6 <ip6>] [mgmt-oid <object id>] [disable]") \
21098 _(tcp_configure_src_addresses, "<ip4|6>first-<ip4|6>last [vrf <id>]")   \
21099 _(sock_init_shm, "size <nnn>")                                          \
21100 _(app_namespace_add_del, "[add] id <ns-id> secret <nn> sw_if_index <nn>")\
21101 _(session_rule_add_del, "[add|del] proto <tcp/udp> <lcl-ip>/<plen> "    \
21102   "<lcl-port> <rmt-ip>/<plen> <rmt-port> action <nn>")                  \
21103 _(session_rules_dump, "")                                               \
21104 _(ip_container_proxy_add_del, "[add|del] <address> <sw_if_index>")      \
21105 _(output_acl_set_interface,                                             \
21106   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
21107   "  [l2-table <nn>] [del]")                                            \
21108 _(qos_record_enable_disable, "<record-source> <intfc> | sw_if_index <id> [disable]")
21109
21110 /* List of command functions, CLI names map directly to functions */
21111 #define foreach_cli_function                                    \
21112 _(comment, "usage: comment <ignore-rest-of-line>")              \
21113 _(dump_interface_table, "usage: dump_interface_table")          \
21114 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
21115 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
21116 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
21117 _(dump_macro_table, "usage: dump_macro_table ")                 \
21118 _(dump_node_table, "usage: dump_node_table")                    \
21119 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
21120 _(elog_setup, "usage: elog_setup [nevents, default 128K]")      \
21121 _(elog_disable, "usage: elog_disable")                          \
21122 _(elog_enable, "usage: elog_enable")                            \
21123 _(elog_save, "usage: elog_save <filename>")                     \
21124 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
21125 _(echo, "usage: echo <message>")                                \
21126 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
21127 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
21128 _(help, "usage: help")                                          \
21129 _(q, "usage: quit")                                             \
21130 _(quit, "usage: quit")                                          \
21131 _(search_node_table, "usage: search_node_table <name>...")      \
21132 _(set, "usage: set <variable-name> <value>")                    \
21133 _(script, "usage: script <file-name>")                          \
21134 _(statseg, "usage: statseg")                                    \
21135 _(unset, "usage: unset <variable-name>")
21136
21137 #define _(N,n)                                  \
21138     static void vl_api_##n##_t_handler_uni      \
21139     (vl_api_##n##_t * mp)                       \
21140     {                                           \
21141         vat_main_t * vam = &vat_main;           \
21142         if (vam->json_output) {                 \
21143             vl_api_##n##_t_handler_json(mp);    \
21144         } else {                                \
21145             vl_api_##n##_t_handler(mp);         \
21146         }                                       \
21147     }
21148 foreach_vpe_api_reply_msg;
21149 #if VPP_API_TEST_BUILTIN == 0
21150 foreach_standalone_reply_msg;
21151 #endif
21152 #undef _
21153
21154 void
21155 vat_api_hookup (vat_main_t * vam)
21156 {
21157 #define _(N,n)                                                  \
21158     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
21159                            vl_api_##n##_t_handler_uni,          \
21160                            vl_noop_handler,                     \
21161                            vl_api_##n##_t_endian,               \
21162                            vl_api_##n##_t_print,                \
21163                            sizeof(vl_api_##n##_t), 1);
21164   foreach_vpe_api_reply_msg;
21165 #if VPP_API_TEST_BUILTIN == 0
21166   foreach_standalone_reply_msg;
21167 #endif
21168 #undef _
21169
21170 #if (VPP_API_TEST_BUILTIN==0)
21171   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
21172
21173   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
21174
21175   vam->function_by_name = hash_create_string (0, sizeof (uword));
21176
21177   vam->help_by_name = hash_create_string (0, sizeof (uword));
21178 #endif
21179
21180   /* API messages we can send */
21181 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
21182   foreach_vpe_api_msg;
21183 #undef _
21184
21185   /* Help strings */
21186 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
21187   foreach_vpe_api_msg;
21188 #undef _
21189
21190   /* CLI functions */
21191 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
21192   foreach_cli_function;
21193 #undef _
21194
21195   /* Help strings */
21196 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
21197   foreach_cli_function;
21198 #undef _
21199 }
21200
21201 #if VPP_API_TEST_BUILTIN
21202 static clib_error_t *
21203 vat_api_hookup_shim (vlib_main_t * vm)
21204 {
21205   vat_api_hookup (&vat_main);
21206   return 0;
21207 }
21208
21209 VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
21210 #endif
21211
21212 /*
21213  * fd.io coding-style-patch-verification: ON
21214  *
21215  * Local Variables:
21216  * eval: (c-set-style "gnu")
21217  * End:
21218  */