misc: binary-api sw_interface_vhost_user_dump is broken
[vpp.git] / src / vat / api_format.c
1 /*
2  *------------------------------------------------------------------
3  * api_format.c
4  *
5  * Copyright (c) 2014-2016 Cisco and/or its affiliates.
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at:
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *------------------------------------------------------------------
18  */
19
20 #include <vat/vat.h>
21 #include <vlib/pci/pci.h>
22 #include <vpp/api/types.h>
23 #include <vppinfra/socket.h>
24 #include <vlibapi/api.h>
25 #include <vlibmemory/api.h>
26 #include <vnet/ip/ip.h>
27 #include <vnet/ip-neighbor/ip_neighbor.h>
28 #include <vnet/ip/ip_types_api.h>
29 #include <vnet/l2/l2_input.h>
30 #include <vnet/l2tp/l2tp.h>
31 #include <vnet/vxlan/vxlan.h>
32 #include <vnet/geneve/geneve.h>
33 #include <vnet/gre/gre.h>
34 #include <vnet/vxlan-gpe/vxlan_gpe.h>
35 #include <vnet/lisp-gpe/lisp_gpe.h>
36
37 #include <vpp/api/vpe_msg_enum.h>
38 #include <vnet/l2/l2_classify.h>
39 #include <vnet/l2/l2_vtr.h>
40 #include <vnet/classify/in_out_acl.h>
41 #include <vnet/classify/policer_classify.h>
42 #include <vnet/classify/flow_classify.h>
43 #include <vnet/mpls/mpls.h>
44 #include <vnet/ipsec/ipsec.h>
45 #include <inttypes.h>
46 #include <vnet/cop/cop.h>
47 #include <vnet/ip/ip6_hop_by_hop.h>
48 #include <vnet/ip/ip_source_and_port_range_check.h>
49 #include <vnet/policer/xlate.h>
50 #include <vnet/span/span.h>
51 #include <vnet/policer/policer.h>
52 #include <vnet/policer/police.h>
53 #include <vnet/mfib/mfib_types.h>
54 #include <vnet/bonding/node.h>
55 #include <vnet/qos/qos_types.h>
56 #include <vnet/ethernet/ethernet_types_api.h>
57 #include <vnet/ip/ip_types_api.h>
58 #include "vat/json_format.h"
59 #include <vnet/ip/ip_types_api.h>
60 #include <vnet/ethernet/ethernet_types_api.h>
61
62 #include <inttypes.h>
63 #include <sys/stat.h>
64
65 #define vl_typedefs             /* define message structures */
66 #include <vpp/api/vpe_all_api_h.h>
67 #undef vl_typedefs
68
69 /* declare message handlers for each api */
70
71 #define vl_endianfun            /* define message structures */
72 #include <vpp/api/vpe_all_api_h.h>
73 #undef vl_endianfun
74
75 /* instantiate all the print functions we know about */
76 #if VPP_API_TEST_BUILTIN == 0
77 #define vl_print(handle, ...)
78 #else
79 #define vl_print(handle, ...) vlib_cli_output (handle, __VA_ARGS__)
80 #endif
81 #define vl_printfun
82 #include <vpp/api/vpe_all_api_h.h>
83 #undef vl_printfun
84
85 #define __plugin_msg_base 0
86 #include <vlibapi/vat_helper_macros.h>
87
88 #include <vnet/format_fns.h>
89
90 void vl_api_set_elog_main (elog_main_t * m);
91 int vl_api_set_elog_trace_api_messages (int enable);
92
93 #if VPP_API_TEST_BUILTIN == 0
94 #include <netdb.h>
95
96 u32
97 vl (void *p)
98 {
99   return vec_len (p);
100 }
101
102 int
103 vat_socket_connect (vat_main_t * vam)
104 {
105   int rv;
106   vam->socket_client_main = &socket_client_main;
107   if ((rv = vl_socket_client_connect ((char *) vam->socket_name,
108                                       "vpp_api_test",
109                                       0 /* default socket rx, tx buffer */ )))
110     return rv;
111   /* vpp expects the client index in network order */
112   vam->my_client_index = htonl (socket_client_main.client_index);
113   return 0;
114 }
115 #else /* vpp built-in case, we don't do sockets... */
116 int
117 vat_socket_connect (vat_main_t * vam)
118 {
119   return 0;
120 }
121
122 int
123 vl_socket_client_read (int wait)
124 {
125   return -1;
126 };
127
128 int
129 vl_socket_client_write ()
130 {
131   return -1;
132 };
133
134 void *
135 vl_socket_client_msg_alloc (int nbytes)
136 {
137   return 0;
138 }
139 #endif
140
141
142 f64
143 vat_time_now (vat_main_t * vam)
144 {
145 #if VPP_API_TEST_BUILTIN
146   return vlib_time_now (vam->vlib_main);
147 #else
148   return clib_time_now (&vam->clib_time);
149 #endif
150 }
151
152 void
153 errmsg (char *fmt, ...)
154 {
155   vat_main_t *vam = &vat_main;
156   va_list va;
157   u8 *s;
158
159   va_start (va, fmt);
160   s = va_format (0, fmt, &va);
161   va_end (va);
162
163   vec_add1 (s, 0);
164
165 #if VPP_API_TEST_BUILTIN
166   vlib_cli_output (vam->vlib_main, (char *) s);
167 #else
168   {
169     if (vam->ifp != stdin)
170       fformat (vam->ofp, "%s(%d): \n", vam->current_file,
171                vam->input_line_number);
172     else
173       fformat (vam->ofp, "%s\n", (char *) s);
174     fflush (vam->ofp);
175   }
176 #endif
177
178   vec_free (s);
179 }
180
181 #if VPP_API_TEST_BUILTIN == 0
182 static uword
183 api_unformat_sw_if_index (unformat_input_t * input, va_list * args)
184 {
185   vat_main_t *vam = va_arg (*args, vat_main_t *);
186   u32 *result = va_arg (*args, u32 *);
187   u8 *if_name;
188   uword *p;
189
190   if (!unformat (input, "%s", &if_name))
191     return 0;
192
193   p = hash_get_mem (vam->sw_if_index_by_interface_name, if_name);
194   if (p == 0)
195     return 0;
196   *result = p[0];
197   return 1;
198 }
199
200 static uword
201 api_unformat_hw_if_index (unformat_input_t * input, va_list * args)
202 {
203   return 0;
204 }
205
206 /* Parse an IP4 address %d.%d.%d.%d. */
207 uword
208 unformat_ip4_address (unformat_input_t * input, va_list * args)
209 {
210   u8 *result = va_arg (*args, u8 *);
211   unsigned a[4];
212
213   if (!unformat (input, "%d.%d.%d.%d", &a[0], &a[1], &a[2], &a[3]))
214     return 0;
215
216   if (a[0] >= 256 || a[1] >= 256 || a[2] >= 256 || a[3] >= 256)
217     return 0;
218
219   result[0] = a[0];
220   result[1] = a[1];
221   result[2] = a[2];
222   result[3] = a[3];
223
224   return 1;
225 }
226
227 uword
228 unformat_ethernet_address (unformat_input_t * input, va_list * args)
229 {
230   u8 *result = va_arg (*args, u8 *);
231   u32 i, a[6];
232
233   if (!unformat (input, "%_%x:%x:%x:%x:%x:%x%_",
234                  &a[0], &a[1], &a[2], &a[3], &a[4], &a[5]))
235     return 0;
236
237   /* Check range. */
238   for (i = 0; i < 6; i++)
239     if (a[i] >= (1 << 8))
240       return 0;
241
242   for (i = 0; i < 6; i++)
243     result[i] = a[i];
244
245   return 1;
246 }
247
248 /* Returns ethernet type as an int in host byte order. */
249 uword
250 unformat_ethernet_type_host_byte_order (unformat_input_t * input,
251                                         va_list * args)
252 {
253   u16 *result = va_arg (*args, u16 *);
254   int type;
255
256   /* Numeric type. */
257   if (unformat (input, "0x%x", &type) || unformat (input, "%d", &type))
258     {
259       if (type >= (1 << 16))
260         return 0;
261       *result = type;
262       return 1;
263     }
264   return 0;
265 }
266
267 /* Parse an IP6 address. */
268 uword
269 unformat_ip6_address (unformat_input_t * input, va_list * args)
270 {
271   ip6_address_t *result = va_arg (*args, ip6_address_t *);
272   u16 hex_quads[8];
273   uword hex_quad, n_hex_quads, hex_digit, n_hex_digits;
274   uword c, n_colon, double_colon_index;
275
276   n_hex_quads = hex_quad = n_hex_digits = n_colon = 0;
277   double_colon_index = ARRAY_LEN (hex_quads);
278   while ((c = unformat_get_input (input)) != UNFORMAT_END_OF_INPUT)
279     {
280       hex_digit = 16;
281       if (c >= '0' && c <= '9')
282         hex_digit = c - '0';
283       else if (c >= 'a' && c <= 'f')
284         hex_digit = c + 10 - 'a';
285       else if (c >= 'A' && c <= 'F')
286         hex_digit = c + 10 - 'A';
287       else if (c == ':' && n_colon < 2)
288         n_colon++;
289       else
290         {
291           unformat_put_input (input);
292           break;
293         }
294
295       /* Too many hex quads. */
296       if (n_hex_quads >= ARRAY_LEN (hex_quads))
297         return 0;
298
299       if (hex_digit < 16)
300         {
301           hex_quad = (hex_quad << 4) | hex_digit;
302
303           /* Hex quad must fit in 16 bits. */
304           if (n_hex_digits >= 4)
305             return 0;
306
307           n_colon = 0;
308           n_hex_digits++;
309         }
310
311       /* Save position of :: */
312       if (n_colon == 2)
313         {
314           /* More than one :: ? */
315           if (double_colon_index < ARRAY_LEN (hex_quads))
316             return 0;
317           double_colon_index = n_hex_quads;
318         }
319
320       if (n_colon > 0 && n_hex_digits > 0)
321         {
322           hex_quads[n_hex_quads++] = hex_quad;
323           hex_quad = 0;
324           n_hex_digits = 0;
325         }
326     }
327
328   if (n_hex_digits > 0)
329     hex_quads[n_hex_quads++] = hex_quad;
330
331   {
332     word i;
333
334     /* Expand :: to appropriate number of zero hex quads. */
335     if (double_colon_index < ARRAY_LEN (hex_quads))
336       {
337         word n_zero = ARRAY_LEN (hex_quads) - n_hex_quads;
338
339         for (i = n_hex_quads - 1; i >= (signed) double_colon_index; i--)
340           hex_quads[n_zero + i] = hex_quads[i];
341
342         for (i = 0; i < n_zero; i++)
343           hex_quads[double_colon_index + i] = 0;
344
345         n_hex_quads = ARRAY_LEN (hex_quads);
346       }
347
348     /* Too few hex quads given. */
349     if (n_hex_quads < ARRAY_LEN (hex_quads))
350       return 0;
351
352     for (i = 0; i < ARRAY_LEN (hex_quads); i++)
353       result->as_u16[i] = clib_host_to_net_u16 (hex_quads[i]);
354
355     return 1;
356   }
357 }
358
359 uword
360 unformat_ipsec_policy_action (unformat_input_t * input, va_list * args)
361 {
362   u32 *r = va_arg (*args, u32 *);
363
364   if (0);
365 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_POLICY_ACTION_##f;
366   foreach_ipsec_policy_action
367 #undef _
368     else
369     return 0;
370   return 1;
371 }
372
373 u8 *
374 format_ipsec_crypto_alg (u8 * s, va_list * args)
375 {
376   u32 i = va_arg (*args, u32);
377   u8 *t = 0;
378
379   switch (i)
380     {
381 #define _(v,f,str) case IPSEC_CRYPTO_ALG_##f: t = (u8 *) str; break;
382       foreach_ipsec_crypto_alg
383 #undef _
384     default:
385       return format (s, "unknown");
386     }
387   return format (s, "%s", t);
388 }
389
390 u8 *
391 format_ipsec_integ_alg (u8 * s, va_list * args)
392 {
393   u32 i = va_arg (*args, u32);
394   u8 *t = 0;
395
396   switch (i)
397     {
398 #define _(v,f,str) case IPSEC_INTEG_ALG_##f: t = (u8 *) str; break;
399       foreach_ipsec_integ_alg
400 #undef _
401     default:
402       return format (s, "unknown");
403     }
404   return format (s, "%s", t);
405 }
406
407 #else /* VPP_API_TEST_BUILTIN == 1 */
408 static uword
409 api_unformat_sw_if_index (unformat_input_t * input, va_list * args)
410 {
411   vat_main_t *vam __clib_unused = va_arg (*args, vat_main_t *);
412   vnet_main_t *vnm = vnet_get_main ();
413   u32 *result = va_arg (*args, u32 *);
414
415   return unformat (input, "%U", unformat_vnet_sw_interface, vnm, result);
416 }
417
418 static uword
419 api_unformat_hw_if_index (unformat_input_t * input, va_list * args)
420 {
421   vat_main_t *vam __clib_unused = va_arg (*args, vat_main_t *);
422   vnet_main_t *vnm = vnet_get_main ();
423   u32 *result = va_arg (*args, u32 *);
424
425   return unformat (input, "%U", unformat_vnet_hw_interface, vnm, result);
426 }
427
428 #endif /* VPP_API_TEST_BUILTIN */
429
430 uword
431 unformat_ipsec_api_crypto_alg (unformat_input_t * input, va_list * args)
432 {
433   u32 *r = va_arg (*args, u32 *);
434
435   if (0);
436 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_API_CRYPTO_ALG_##f;
437   foreach_ipsec_crypto_alg
438 #undef _
439     else
440     return 0;
441   return 1;
442 }
443
444 uword
445 unformat_ipsec_api_integ_alg (unformat_input_t * input, va_list * args)
446 {
447   u32 *r = va_arg (*args, u32 *);
448
449   if (0);
450 #define _(v,f,s) else if (unformat (input, s)) *r = IPSEC_API_INTEG_ALG_##f;
451   foreach_ipsec_integ_alg
452 #undef _
453     else
454     return 0;
455   return 1;
456 }
457
458 static uword
459 unformat_policer_rate_type (unformat_input_t * input, va_list * args)
460 {
461   u8 *r = va_arg (*args, u8 *);
462
463   if (unformat (input, "kbps"))
464     *r = SSE2_QOS_RATE_KBPS;
465   else if (unformat (input, "pps"))
466     *r = SSE2_QOS_RATE_PPS;
467   else
468     return 0;
469   return 1;
470 }
471
472 static uword
473 unformat_policer_round_type (unformat_input_t * input, va_list * args)
474 {
475   u8 *r = va_arg (*args, u8 *);
476
477   if (unformat (input, "closest"))
478     *r = SSE2_QOS_ROUND_TO_CLOSEST;
479   else if (unformat (input, "up"))
480     *r = SSE2_QOS_ROUND_TO_UP;
481   else if (unformat (input, "down"))
482     *r = SSE2_QOS_ROUND_TO_DOWN;
483   else
484     return 0;
485   return 1;
486 }
487
488 static uword
489 unformat_policer_type (unformat_input_t * input, va_list * args)
490 {
491   u8 *r = va_arg (*args, u8 *);
492
493   if (unformat (input, "1r2c"))
494     *r = SSE2_QOS_POLICER_TYPE_1R2C;
495   else if (unformat (input, "1r3c"))
496     *r = SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697;
497   else if (unformat (input, "2r3c-2698"))
498     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698;
499   else if (unformat (input, "2r3c-4115"))
500     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115;
501   else if (unformat (input, "2r3c-mef5cf1"))
502     *r = SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1;
503   else
504     return 0;
505   return 1;
506 }
507
508 static uword
509 unformat_dscp (unformat_input_t * input, va_list * va)
510 {
511   u8 *r = va_arg (*va, u8 *);
512
513   if (0);
514 #define _(v,f,str) else if (unformat (input, str)) *r = VNET_DSCP_##f;
515   foreach_vnet_dscp
516 #undef _
517     else
518     return 0;
519   return 1;
520 }
521
522 static uword
523 unformat_policer_action_type (unformat_input_t * input, va_list * va)
524 {
525   sse2_qos_pol_action_params_st *a
526     = va_arg (*va, sse2_qos_pol_action_params_st *);
527
528   if (unformat (input, "drop"))
529     a->action_type = SSE2_QOS_ACTION_DROP;
530   else if (unformat (input, "transmit"))
531     a->action_type = SSE2_QOS_ACTION_TRANSMIT;
532   else if (unformat (input, "mark-and-transmit %U", unformat_dscp, &a->dscp))
533     a->action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
534   else
535     return 0;
536   return 1;
537 }
538
539 static uword
540 unformat_policer_classify_table_type (unformat_input_t * input, va_list * va)
541 {
542   u32 *r = va_arg (*va, u32 *);
543   u32 tid;
544
545   if (unformat (input, "ip4"))
546     tid = POLICER_CLASSIFY_TABLE_IP4;
547   else if (unformat (input, "ip6"))
548     tid = POLICER_CLASSIFY_TABLE_IP6;
549   else if (unformat (input, "l2"))
550     tid = POLICER_CLASSIFY_TABLE_L2;
551   else
552     return 0;
553
554   *r = tid;
555   return 1;
556 }
557
558 static uword
559 unformat_flow_classify_table_type (unformat_input_t * input, va_list * va)
560 {
561   u32 *r = va_arg (*va, u32 *);
562   u32 tid;
563
564   if (unformat (input, "ip4"))
565     tid = FLOW_CLASSIFY_TABLE_IP4;
566   else if (unformat (input, "ip6"))
567     tid = FLOW_CLASSIFY_TABLE_IP6;
568   else
569     return 0;
570
571   *r = tid;
572   return 1;
573 }
574
575 #if (VPP_API_TEST_BUILTIN==0)
576
577 static const char *mfib_flag_names[] = MFIB_ENTRY_NAMES_SHORT;
578 static const char *mfib_flag_long_names[] = MFIB_ENTRY_NAMES_LONG;
579 static const char *mfib_itf_flag_long_names[] = MFIB_ITF_NAMES_LONG;
580 static const char *mfib_itf_flag_names[] = MFIB_ITF_NAMES_SHORT;
581
582 uword
583 unformat_mfib_itf_flags (unformat_input_t * input, va_list * args)
584 {
585   mfib_itf_flags_t old, *iflags = va_arg (*args, mfib_itf_flags_t *);
586   mfib_itf_attribute_t attr;
587
588   old = *iflags;
589   FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
590   {
591     if (unformat (input, mfib_itf_flag_long_names[attr]))
592       *iflags |= (1 << attr);
593   }
594   FOR_EACH_MFIB_ITF_ATTRIBUTE (attr)
595   {
596     if (unformat (input, mfib_itf_flag_names[attr]))
597       *iflags |= (1 << attr);
598   }
599
600   return (old == *iflags ? 0 : 1);
601 }
602
603 uword
604 unformat_mfib_entry_flags (unformat_input_t * input, va_list * args)
605 {
606   mfib_entry_flags_t old, *eflags = va_arg (*args, mfib_entry_flags_t *);
607   mfib_entry_attribute_t attr;
608
609   old = *eflags;
610   FOR_EACH_MFIB_ATTRIBUTE (attr)
611   {
612     if (unformat (input, mfib_flag_long_names[attr]))
613       *eflags |= (1 << attr);
614   }
615   FOR_EACH_MFIB_ATTRIBUTE (attr)
616   {
617     if (unformat (input, mfib_flag_names[attr]))
618       *eflags |= (1 << attr);
619   }
620
621   return (old == *eflags ? 0 : 1);
622 }
623
624 u8 *
625 format_ip4_address (u8 * s, va_list * args)
626 {
627   u8 *a = va_arg (*args, u8 *);
628   return format (s, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]);
629 }
630
631 u8 *
632 format_ip6_address (u8 * s, va_list * args)
633 {
634   ip6_address_t *a = va_arg (*args, ip6_address_t *);
635   u32 i, i_max_n_zero, max_n_zeros, i_first_zero, n_zeros, last_double_colon;
636
637   i_max_n_zero = ARRAY_LEN (a->as_u16);
638   max_n_zeros = 0;
639   i_first_zero = i_max_n_zero;
640   n_zeros = 0;
641   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
642     {
643       u32 is_zero = a->as_u16[i] == 0;
644       if (is_zero && i_first_zero >= ARRAY_LEN (a->as_u16))
645         {
646           i_first_zero = i;
647           n_zeros = 0;
648         }
649       n_zeros += is_zero;
650       if ((!is_zero && n_zeros > max_n_zeros)
651           || (i + 1 >= ARRAY_LEN (a->as_u16) && n_zeros > max_n_zeros))
652         {
653           i_max_n_zero = i_first_zero;
654           max_n_zeros = n_zeros;
655           i_first_zero = ARRAY_LEN (a->as_u16);
656           n_zeros = 0;
657         }
658     }
659
660   last_double_colon = 0;
661   for (i = 0; i < ARRAY_LEN (a->as_u16); i++)
662     {
663       if (i == i_max_n_zero && max_n_zeros > 1)
664         {
665           s = format (s, "::");
666           i += max_n_zeros - 1;
667           last_double_colon = 1;
668         }
669       else
670         {
671           s = format (s, "%s%x",
672                       (last_double_colon || i == 0) ? "" : ":",
673                       clib_net_to_host_u16 (a->as_u16[i]));
674           last_double_colon = 0;
675         }
676     }
677
678   return s;
679 }
680
681 /* Format an IP46 address. */
682 u8 *
683 format_ip46_address (u8 * s, va_list * args)
684 {
685   ip46_address_t *ip46 = va_arg (*args, ip46_address_t *);
686   ip46_type_t type = va_arg (*args, ip46_type_t);
687   int is_ip4 = 1;
688
689   switch (type)
690     {
691     case IP46_TYPE_ANY:
692       is_ip4 = ip46_address_is_ip4 (ip46);
693       break;
694     case IP46_TYPE_IP4:
695       is_ip4 = 1;
696       break;
697     case IP46_TYPE_IP6:
698       is_ip4 = 0;
699       break;
700     }
701
702   return is_ip4 ?
703     format (s, "%U", format_ip4_address, &ip46->ip4) :
704     format (s, "%U", format_ip6_address, &ip46->ip6);
705 }
706
707 u8 *
708 format_ethernet_address (u8 * s, va_list * args)
709 {
710   u8 *a = va_arg (*args, u8 *);
711
712   return format (s, "%02x:%02x:%02x:%02x:%02x:%02x",
713                  a[0], a[1], a[2], a[3], a[4], a[5]);
714 }
715 #endif
716
717 static void
718 increment_v4_address (vl_api_ip4_address_t * i)
719 {
720   ip4_address_t *a = (ip4_address_t *) i;
721   u32 v;
722
723   v = ntohl (a->as_u32) + 1;
724   a->as_u32 = ntohl (v);
725 }
726
727 static void
728 increment_v6_address (vl_api_ip6_address_t * i)
729 {
730   ip6_address_t *a = (ip6_address_t *) i;
731   u64 v0, v1;
732
733   v0 = clib_net_to_host_u64 (a->as_u64[0]);
734   v1 = clib_net_to_host_u64 (a->as_u64[1]);
735
736   v1 += 1;
737   if (v1 == 0)
738     v0 += 1;
739   a->as_u64[0] = clib_net_to_host_u64 (v0);
740   a->as_u64[1] = clib_net_to_host_u64 (v1);
741 }
742
743 static void
744 increment_address (vl_api_address_t * a)
745 {
746   if (clib_net_to_host_u32 (a->af) == ADDRESS_IP4)
747     increment_v4_address (&a->un.ip4);
748   else if (clib_net_to_host_u32 (a->af) == ADDRESS_IP6)
749     increment_v6_address (&a->un.ip6);
750 }
751
752 static void
753 set_ip4_address (vl_api_address_t * a, u32 v)
754 {
755   if (a->af == ADDRESS_IP4)
756     {
757       ip4_address_t *i = (ip4_address_t *) & a->un.ip4;
758       i->as_u32 = v;
759     }
760 }
761
762 static void
763 increment_mac_address (u8 * mac)
764 {
765   u64 tmp = *((u64 *) mac);
766   tmp = clib_net_to_host_u64 (tmp);
767   tmp += 1 << 16;               /* skip unused (least significant) octets */
768   tmp = clib_host_to_net_u64 (tmp);
769
770   clib_memcpy (mac, &tmp, 6);
771 }
772
773 static void
774 vat_json_object_add_address (vat_json_node_t * node,
775                              const char *str, const vl_api_address_t * addr)
776 {
777   if (ADDRESS_IP6 == addr->af)
778     {
779       struct in6_addr ip6;
780
781       clib_memcpy (&ip6, &addr->un.ip6, sizeof (ip6));
782       vat_json_object_add_ip6 (node, str, ip6);
783     }
784   else
785     {
786       struct in_addr ip4;
787
788       clib_memcpy (&ip4, &addr->un.ip4, sizeof (ip4));
789       vat_json_object_add_ip4 (node, str, ip4);
790     }
791 }
792
793 static void
794 vat_json_object_add_prefix (vat_json_node_t * node,
795                             const vl_api_prefix_t * prefix)
796 {
797   vat_json_object_add_uint (node, "len", prefix->len);
798   vat_json_object_add_address (node, "address", &prefix->address);
799 }
800
801 static void vl_api_create_loopback_reply_t_handler
802   (vl_api_create_loopback_reply_t * mp)
803 {
804   vat_main_t *vam = &vat_main;
805   i32 retval = ntohl (mp->retval);
806
807   vam->retval = retval;
808   vam->regenerate_interface_table = 1;
809   vam->sw_if_index = ntohl (mp->sw_if_index);
810   vam->result_ready = 1;
811 }
812
813 static void vl_api_create_loopback_reply_t_handler_json
814   (vl_api_create_loopback_reply_t * mp)
815 {
816   vat_main_t *vam = &vat_main;
817   vat_json_node_t node;
818
819   vat_json_init_object (&node);
820   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
821   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
822
823   vat_json_print (vam->ofp, &node);
824   vat_json_free (&node);
825   vam->retval = ntohl (mp->retval);
826   vam->result_ready = 1;
827 }
828
829 static void vl_api_create_loopback_instance_reply_t_handler
830   (vl_api_create_loopback_instance_reply_t * mp)
831 {
832   vat_main_t *vam = &vat_main;
833   i32 retval = ntohl (mp->retval);
834
835   vam->retval = retval;
836   vam->regenerate_interface_table = 1;
837   vam->sw_if_index = ntohl (mp->sw_if_index);
838   vam->result_ready = 1;
839 }
840
841 static void vl_api_create_loopback_instance_reply_t_handler_json
842   (vl_api_create_loopback_instance_reply_t * mp)
843 {
844   vat_main_t *vam = &vat_main;
845   vat_json_node_t node;
846
847   vat_json_init_object (&node);
848   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
849   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
850
851   vat_json_print (vam->ofp, &node);
852   vat_json_free (&node);
853   vam->retval = ntohl (mp->retval);
854   vam->result_ready = 1;
855 }
856
857 static void vl_api_af_packet_create_reply_t_handler
858   (vl_api_af_packet_create_reply_t * mp)
859 {
860   vat_main_t *vam = &vat_main;
861   i32 retval = ntohl (mp->retval);
862
863   vam->retval = retval;
864   vam->regenerate_interface_table = 1;
865   vam->sw_if_index = ntohl (mp->sw_if_index);
866   vam->result_ready = 1;
867 }
868
869 static void vl_api_af_packet_create_reply_t_handler_json
870   (vl_api_af_packet_create_reply_t * mp)
871 {
872   vat_main_t *vam = &vat_main;
873   vat_json_node_t node;
874
875   vat_json_init_object (&node);
876   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
877   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
878
879   vat_json_print (vam->ofp, &node);
880   vat_json_free (&node);
881
882   vam->retval = ntohl (mp->retval);
883   vam->result_ready = 1;
884 }
885
886 static void vl_api_create_vlan_subif_reply_t_handler
887   (vl_api_create_vlan_subif_reply_t * mp)
888 {
889   vat_main_t *vam = &vat_main;
890   i32 retval = ntohl (mp->retval);
891
892   vam->retval = retval;
893   vam->regenerate_interface_table = 1;
894   vam->sw_if_index = ntohl (mp->sw_if_index);
895   vam->result_ready = 1;
896 }
897
898 static void vl_api_create_vlan_subif_reply_t_handler_json
899   (vl_api_create_vlan_subif_reply_t * mp)
900 {
901   vat_main_t *vam = &vat_main;
902   vat_json_node_t node;
903
904   vat_json_init_object (&node);
905   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
906   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
907
908   vat_json_print (vam->ofp, &node);
909   vat_json_free (&node);
910
911   vam->retval = ntohl (mp->retval);
912   vam->result_ready = 1;
913 }
914
915 static void vl_api_create_subif_reply_t_handler
916   (vl_api_create_subif_reply_t * mp)
917 {
918   vat_main_t *vam = &vat_main;
919   i32 retval = ntohl (mp->retval);
920
921   vam->retval = retval;
922   vam->regenerate_interface_table = 1;
923   vam->sw_if_index = ntohl (mp->sw_if_index);
924   vam->result_ready = 1;
925 }
926
927 static void vl_api_create_subif_reply_t_handler_json
928   (vl_api_create_subif_reply_t * mp)
929 {
930   vat_main_t *vam = &vat_main;
931   vat_json_node_t node;
932
933   vat_json_init_object (&node);
934   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
935   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
936
937   vat_json_print (vam->ofp, &node);
938   vat_json_free (&node);
939
940   vam->retval = ntohl (mp->retval);
941   vam->result_ready = 1;
942 }
943
944 static void vl_api_interface_name_renumber_reply_t_handler
945   (vl_api_interface_name_renumber_reply_t * mp)
946 {
947   vat_main_t *vam = &vat_main;
948   i32 retval = ntohl (mp->retval);
949
950   vam->retval = retval;
951   vam->regenerate_interface_table = 1;
952   vam->result_ready = 1;
953 }
954
955 static void vl_api_interface_name_renumber_reply_t_handler_json
956   (vl_api_interface_name_renumber_reply_t * mp)
957 {
958   vat_main_t *vam = &vat_main;
959   vat_json_node_t node;
960
961   vat_json_init_object (&node);
962   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
963
964   vat_json_print (vam->ofp, &node);
965   vat_json_free (&node);
966
967   vam->retval = ntohl (mp->retval);
968   vam->result_ready = 1;
969 }
970
971 /*
972  * Special-case: build the interface table, maintain
973  * the next loopback sw_if_index vbl.
974  */
975 static void vl_api_sw_interface_details_t_handler
976   (vl_api_sw_interface_details_t * mp)
977 {
978   vat_main_t *vam = &vat_main;
979   u8 *s = format (0, "%s%c", mp->interface_name, 0);
980
981   hash_set_mem (vam->sw_if_index_by_interface_name, s,
982                 ntohl (mp->sw_if_index));
983
984   /* In sub interface case, fill the sub interface table entry */
985   if (mp->sw_if_index != mp->sup_sw_if_index)
986     {
987       sw_interface_subif_t *sub = NULL;
988
989       vec_add2 (vam->sw_if_subif_table, sub, 1);
990
991       vec_validate (sub->interface_name, strlen ((char *) s) + 1);
992       strncpy ((char *) sub->interface_name, (char *) s,
993                vec_len (sub->interface_name));
994       sub->sw_if_index = ntohl (mp->sw_if_index);
995       sub->sub_id = ntohl (mp->sub_id);
996
997       sub->raw_flags = ntohl (mp->sub_if_flags & SUB_IF_API_FLAG_MASK_VNET);
998
999       sub->sub_number_of_tags = mp->sub_number_of_tags;
1000       sub->sub_outer_vlan_id = ntohs (mp->sub_outer_vlan_id);
1001       sub->sub_inner_vlan_id = ntohs (mp->sub_inner_vlan_id);
1002
1003       /* vlan tag rewrite */
1004       sub->vtr_op = ntohl (mp->vtr_op);
1005       sub->vtr_push_dot1q = ntohl (mp->vtr_push_dot1q);
1006       sub->vtr_tag1 = ntohl (mp->vtr_tag1);
1007       sub->vtr_tag2 = ntohl (mp->vtr_tag2);
1008     }
1009 }
1010
1011 static void vl_api_sw_interface_details_t_handler_json
1012   (vl_api_sw_interface_details_t * mp)
1013 {
1014   vat_main_t *vam = &vat_main;
1015   vat_json_node_t *node = NULL;
1016
1017   if (VAT_JSON_ARRAY != vam->json_tree.type)
1018     {
1019       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1020       vat_json_init_array (&vam->json_tree);
1021     }
1022   node = vat_json_array_add (&vam->json_tree);
1023
1024   vat_json_init_object (node);
1025   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
1026   vat_json_object_add_uint (node, "sup_sw_if_index",
1027                             ntohl (mp->sup_sw_if_index));
1028   vat_json_object_add_bytes (node, "l2_address", mp->l2_address,
1029                              sizeof (mp->l2_address));
1030   vat_json_object_add_string_copy (node, "interface_name",
1031                                    mp->interface_name);
1032   vat_json_object_add_string_copy (node, "interface_dev_type",
1033                                    mp->interface_dev_type);
1034   vat_json_object_add_uint (node, "flags", mp->flags);
1035   vat_json_object_add_uint (node, "link_duplex", mp->link_duplex);
1036   vat_json_object_add_uint (node, "link_speed", mp->link_speed);
1037   vat_json_object_add_uint (node, "mtu", ntohs (mp->link_mtu));
1038   vat_json_object_add_uint (node, "sub_id", ntohl (mp->sub_id));
1039   vat_json_object_add_uint (node, "sub_number_of_tags",
1040                             mp->sub_number_of_tags);
1041   vat_json_object_add_uint (node, "sub_outer_vlan_id",
1042                             ntohs (mp->sub_outer_vlan_id));
1043   vat_json_object_add_uint (node, "sub_inner_vlan_id",
1044                             ntohs (mp->sub_inner_vlan_id));
1045   vat_json_object_add_uint (node, "sub_if_flags", ntohl (mp->sub_if_flags));
1046   vat_json_object_add_uint (node, "vtr_op", ntohl (mp->vtr_op));
1047   vat_json_object_add_uint (node, "vtr_push_dot1q",
1048                             ntohl (mp->vtr_push_dot1q));
1049   vat_json_object_add_uint (node, "vtr_tag1", ntohl (mp->vtr_tag1));
1050   vat_json_object_add_uint (node, "vtr_tag2", ntohl (mp->vtr_tag2));
1051   if (ntohl (mp->sub_if_flags) & SUB_IF_API_FLAG_DOT1AH)
1052     {
1053       vat_json_object_add_string_copy (node, "pbb_vtr_dmac",
1054                                        format (0, "%U",
1055                                                format_ethernet_address,
1056                                                &mp->b_dmac));
1057       vat_json_object_add_string_copy (node, "pbb_vtr_smac",
1058                                        format (0, "%U",
1059                                                format_ethernet_address,
1060                                                &mp->b_smac));
1061       vat_json_object_add_uint (node, "pbb_vtr_b_vlanid", mp->b_vlanid);
1062       vat_json_object_add_uint (node, "pbb_vtr_i_sid", mp->i_sid);
1063     }
1064 }
1065
1066 #if VPP_API_TEST_BUILTIN == 0
1067 static void vl_api_sw_interface_event_t_handler
1068   (vl_api_sw_interface_event_t * mp)
1069 {
1070   vat_main_t *vam = &vat_main;
1071   if (vam->interface_event_display)
1072     errmsg ("interface flags: sw_if_index %d %s %s",
1073             ntohl (mp->sw_if_index),
1074             ((ntohl (mp->flags)) & IF_STATUS_API_FLAG_ADMIN_UP) ?
1075             "admin-up" : "admin-down",
1076             ((ntohl (mp->flags)) & IF_STATUS_API_FLAG_LINK_UP) ?
1077             "link-up" : "link-down");
1078 }
1079 #endif
1080
1081 __clib_unused static void
1082 vl_api_sw_interface_event_t_handler_json (vl_api_sw_interface_event_t * mp)
1083 {
1084   /* JSON output not supported */
1085 }
1086
1087 static void
1088 vl_api_cli_reply_t_handler (vl_api_cli_reply_t * mp)
1089 {
1090   vat_main_t *vam = &vat_main;
1091   i32 retval = ntohl (mp->retval);
1092
1093   vam->retval = retval;
1094   vam->shmem_result = uword_to_pointer (mp->reply_in_shmem, u8 *);
1095   vam->result_ready = 1;
1096 }
1097
1098 static void
1099 vl_api_cli_reply_t_handler_json (vl_api_cli_reply_t * mp)
1100 {
1101   vat_main_t *vam = &vat_main;
1102   vat_json_node_t node;
1103   void *oldheap;
1104   u8 *reply;
1105
1106   vat_json_init_object (&node);
1107   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1108   vat_json_object_add_uint (&node, "reply_in_shmem",
1109                             ntohl (mp->reply_in_shmem));
1110   /* Toss the shared-memory original... */
1111   oldheap = vl_msg_push_heap ();
1112
1113   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
1114   vec_free (reply);
1115
1116   vl_msg_pop_heap (oldheap);
1117
1118   vat_json_print (vam->ofp, &node);
1119   vat_json_free (&node);
1120
1121   vam->retval = ntohl (mp->retval);
1122   vam->result_ready = 1;
1123 }
1124
1125 static void
1126 vl_api_cli_inband_reply_t_handler (vl_api_cli_inband_reply_t * mp)
1127 {
1128   vat_main_t *vam = &vat_main;
1129   i32 retval = ntohl (mp->retval);
1130   u32 length = vl_api_string_len (&mp->reply);
1131
1132   vec_reset_length (vam->cmd_reply);
1133
1134   vam->retval = retval;
1135   if (retval == 0)
1136     {
1137       vec_validate (vam->cmd_reply, length);
1138       clib_memcpy ((char *) (vam->cmd_reply),
1139                    vl_api_from_api_string (&mp->reply), length);
1140       vam->cmd_reply[length] = 0;
1141     }
1142   vam->result_ready = 1;
1143 }
1144
1145 static void
1146 vl_api_cli_inband_reply_t_handler_json (vl_api_cli_inband_reply_t * mp)
1147 {
1148   vat_main_t *vam = &vat_main;
1149   vat_json_node_t node;
1150
1151   vec_reset_length (vam->cmd_reply);
1152
1153   vat_json_init_object (&node);
1154   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1155   vat_json_object_add_string_copy (&node, "reply",
1156                                    vl_api_from_api_string (&mp->reply));
1157
1158   vat_json_print (vam->ofp, &node);
1159   vat_json_free (&node);
1160
1161   vam->retval = ntohl (mp->retval);
1162   vam->result_ready = 1;
1163 }
1164
1165 static void vl_api_classify_add_del_table_reply_t_handler
1166   (vl_api_classify_add_del_table_reply_t * mp)
1167 {
1168   vat_main_t *vam = &vat_main;
1169   i32 retval = ntohl (mp->retval);
1170   if (vam->async_mode)
1171     {
1172       vam->async_errors += (retval < 0);
1173     }
1174   else
1175     {
1176       vam->retval = retval;
1177       if (retval == 0 &&
1178           ((mp->new_table_index != 0xFFFFFFFF) ||
1179            (mp->skip_n_vectors != 0xFFFFFFFF) ||
1180            (mp->match_n_vectors != 0xFFFFFFFF)))
1181         /*
1182          * Note: this is just barely thread-safe, depends on
1183          * the main thread spinning waiting for an answer...
1184          */
1185         errmsg ("new index %d, skip_n_vectors %d, match_n_vectors %d",
1186                 ntohl (mp->new_table_index),
1187                 ntohl (mp->skip_n_vectors), ntohl (mp->match_n_vectors));
1188       vam->result_ready = 1;
1189     }
1190 }
1191
1192 static void vl_api_classify_add_del_table_reply_t_handler_json
1193   (vl_api_classify_add_del_table_reply_t * mp)
1194 {
1195   vat_main_t *vam = &vat_main;
1196   vat_json_node_t node;
1197
1198   vat_json_init_object (&node);
1199   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1200   vat_json_object_add_uint (&node, "new_table_index",
1201                             ntohl (mp->new_table_index));
1202   vat_json_object_add_uint (&node, "skip_n_vectors",
1203                             ntohl (mp->skip_n_vectors));
1204   vat_json_object_add_uint (&node, "match_n_vectors",
1205                             ntohl (mp->match_n_vectors));
1206
1207   vat_json_print (vam->ofp, &node);
1208   vat_json_free (&node);
1209
1210   vam->retval = ntohl (mp->retval);
1211   vam->result_ready = 1;
1212 }
1213
1214 static void vl_api_get_node_index_reply_t_handler
1215   (vl_api_get_node_index_reply_t * mp)
1216 {
1217   vat_main_t *vam = &vat_main;
1218   i32 retval = ntohl (mp->retval);
1219   if (vam->async_mode)
1220     {
1221       vam->async_errors += (retval < 0);
1222     }
1223   else
1224     {
1225       vam->retval = retval;
1226       if (retval == 0)
1227         errmsg ("node index %d", ntohl (mp->node_index));
1228       vam->result_ready = 1;
1229     }
1230 }
1231
1232 static void vl_api_get_node_index_reply_t_handler_json
1233   (vl_api_get_node_index_reply_t * mp)
1234 {
1235   vat_main_t *vam = &vat_main;
1236   vat_json_node_t node;
1237
1238   vat_json_init_object (&node);
1239   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1240   vat_json_object_add_uint (&node, "node_index", ntohl (mp->node_index));
1241
1242   vat_json_print (vam->ofp, &node);
1243   vat_json_free (&node);
1244
1245   vam->retval = ntohl (mp->retval);
1246   vam->result_ready = 1;
1247 }
1248
1249 static void vl_api_get_next_index_reply_t_handler
1250   (vl_api_get_next_index_reply_t * mp)
1251 {
1252   vat_main_t *vam = &vat_main;
1253   i32 retval = ntohl (mp->retval);
1254   if (vam->async_mode)
1255     {
1256       vam->async_errors += (retval < 0);
1257     }
1258   else
1259     {
1260       vam->retval = retval;
1261       if (retval == 0)
1262         errmsg ("next node index %d", ntohl (mp->next_index));
1263       vam->result_ready = 1;
1264     }
1265 }
1266
1267 static void vl_api_get_next_index_reply_t_handler_json
1268   (vl_api_get_next_index_reply_t * mp)
1269 {
1270   vat_main_t *vam = &vat_main;
1271   vat_json_node_t node;
1272
1273   vat_json_init_object (&node);
1274   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1275   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1276
1277   vat_json_print (vam->ofp, &node);
1278   vat_json_free (&node);
1279
1280   vam->retval = ntohl (mp->retval);
1281   vam->result_ready = 1;
1282 }
1283
1284 static void vl_api_add_node_next_reply_t_handler
1285   (vl_api_add_node_next_reply_t * mp)
1286 {
1287   vat_main_t *vam = &vat_main;
1288   i32 retval = ntohl (mp->retval);
1289   if (vam->async_mode)
1290     {
1291       vam->async_errors += (retval < 0);
1292     }
1293   else
1294     {
1295       vam->retval = retval;
1296       if (retval == 0)
1297         errmsg ("next index %d", ntohl (mp->next_index));
1298       vam->result_ready = 1;
1299     }
1300 }
1301
1302 static void vl_api_add_node_next_reply_t_handler_json
1303   (vl_api_add_node_next_reply_t * mp)
1304 {
1305   vat_main_t *vam = &vat_main;
1306   vat_json_node_t node;
1307
1308   vat_json_init_object (&node);
1309   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1310   vat_json_object_add_uint (&node, "next_index", ntohl (mp->next_index));
1311
1312   vat_json_print (vam->ofp, &node);
1313   vat_json_free (&node);
1314
1315   vam->retval = ntohl (mp->retval);
1316   vam->result_ready = 1;
1317 }
1318
1319 static void vl_api_show_version_reply_t_handler
1320   (vl_api_show_version_reply_t * mp)
1321 {
1322   vat_main_t *vam = &vat_main;
1323   i32 retval = ntohl (mp->retval);
1324
1325   if (retval >= 0)
1326     {
1327       errmsg ("        program: %s", mp->program);
1328       errmsg ("        version: %s", mp->version);
1329       errmsg ("     build date: %s", mp->build_date);
1330       errmsg ("build directory: %s", mp->build_directory);
1331     }
1332   vam->retval = retval;
1333   vam->result_ready = 1;
1334 }
1335
1336 static void vl_api_show_version_reply_t_handler_json
1337   (vl_api_show_version_reply_t * mp)
1338 {
1339   vat_main_t *vam = &vat_main;
1340   vat_json_node_t node;
1341
1342   vat_json_init_object (&node);
1343   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1344   vat_json_object_add_string_copy (&node, "program", mp->program);
1345   vat_json_object_add_string_copy (&node, "version", mp->version);
1346   vat_json_object_add_string_copy (&node, "build_date", mp->build_date);
1347   vat_json_object_add_string_copy (&node, "build_directory",
1348                                    mp->build_directory);
1349
1350   vat_json_print (vam->ofp, &node);
1351   vat_json_free (&node);
1352
1353   vam->retval = ntohl (mp->retval);
1354   vam->result_ready = 1;
1355 }
1356
1357 static void vl_api_show_threads_reply_t_handler
1358   (vl_api_show_threads_reply_t * mp)
1359 {
1360   vat_main_t *vam = &vat_main;
1361   i32 retval = ntohl (mp->retval);
1362   int i, count = 0;
1363
1364   if (retval >= 0)
1365     count = ntohl (mp->count);
1366
1367   for (i = 0; i < count; i++)
1368     print (vam->ofp,
1369            "\n%-2d %-11s %-11s %-5d %-6d %-4d %-6d",
1370            ntohl (mp->thread_data[i].id), mp->thread_data[i].name,
1371            mp->thread_data[i].type, ntohl (mp->thread_data[i].pid),
1372            ntohl (mp->thread_data[i].cpu_id), ntohl (mp->thread_data[i].core),
1373            ntohl (mp->thread_data[i].cpu_socket));
1374
1375   vam->retval = retval;
1376   vam->result_ready = 1;
1377 }
1378
1379 static void vl_api_show_threads_reply_t_handler_json
1380   (vl_api_show_threads_reply_t * mp)
1381 {
1382   vat_main_t *vam = &vat_main;
1383   vat_json_node_t node;
1384   vl_api_thread_data_t *td;
1385   i32 retval = ntohl (mp->retval);
1386   int i, count = 0;
1387
1388   if (retval >= 0)
1389     count = ntohl (mp->count);
1390
1391   vat_json_init_object (&node);
1392   vat_json_object_add_int (&node, "retval", retval);
1393   vat_json_object_add_uint (&node, "count", count);
1394
1395   for (i = 0; i < count; i++)
1396     {
1397       td = &mp->thread_data[i];
1398       vat_json_object_add_uint (&node, "id", ntohl (td->id));
1399       vat_json_object_add_string_copy (&node, "name", td->name);
1400       vat_json_object_add_string_copy (&node, "type", td->type);
1401       vat_json_object_add_uint (&node, "pid", ntohl (td->pid));
1402       vat_json_object_add_int (&node, "cpu_id", ntohl (td->cpu_id));
1403       vat_json_object_add_int (&node, "core", ntohl (td->id));
1404       vat_json_object_add_int (&node, "cpu_socket", ntohl (td->cpu_socket));
1405     }
1406
1407   vat_json_print (vam->ofp, &node);
1408   vat_json_free (&node);
1409
1410   vam->retval = retval;
1411   vam->result_ready = 1;
1412 }
1413
1414 static int
1415 api_show_threads (vat_main_t * vam)
1416 {
1417   vl_api_show_threads_t *mp;
1418   int ret;
1419
1420   print (vam->ofp,
1421          "\n%-2s %-11s %-11s %-5s %-6s %-4s %-6s",
1422          "ID", "Name", "Type", "LWP", "cpu_id", "Core", "Socket");
1423
1424   M (SHOW_THREADS, mp);
1425
1426   S (mp);
1427   W (ret);
1428   return ret;
1429 }
1430
1431 static void
1432 vl_api_l2_macs_event_t_handler (vl_api_l2_macs_event_t * mp)
1433 {
1434   u32 n_macs = ntohl (mp->n_macs);
1435   errmsg ("L2MAC event received with pid %d cl-idx %d for %d macs: \n",
1436           ntohl (mp->pid), mp->client_index, n_macs);
1437   int i;
1438   for (i = 0; i < n_macs; i++)
1439     {
1440       vl_api_mac_entry_t *mac = &mp->mac[i];
1441       errmsg (" [%d] sw_if_index %d  mac_addr %U  action %d \n",
1442               i + 1, ntohl (mac->sw_if_index),
1443               format_ethernet_address, mac->mac_addr, mac->action);
1444       if (i == 1000)
1445         break;
1446     }
1447 }
1448
1449 static void
1450 vl_api_l2_macs_event_t_handler_json (vl_api_l2_macs_event_t * mp)
1451 {
1452   /* JSON output not supported */
1453 }
1454
1455 #define vl_api_bridge_domain_details_t_endian vl_noop_handler
1456 #define vl_api_bridge_domain_details_t_print vl_noop_handler
1457
1458 /*
1459  * Special-case: build the bridge domain table, maintain
1460  * the next bd id vbl.
1461  */
1462 static void vl_api_bridge_domain_details_t_handler
1463   (vl_api_bridge_domain_details_t * mp)
1464 {
1465   vat_main_t *vam = &vat_main;
1466   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1467   int i;
1468
1469   print (vam->ofp, "\n%-3s %-3s %-3s %-3s %-3s %-6s %-3s",
1470          " ID", "LRN", "FWD", "FLD", "BVI", "UU-FWD", "#IF");
1471
1472   print (vam->ofp, "%3d %3d %3d %3d %3d %6d %3d",
1473          ntohl (mp->bd_id), mp->learn, mp->forward,
1474          mp->flood, ntohl (mp->bvi_sw_if_index),
1475          ntohl (mp->uu_fwd_sw_if_index), n_sw_ifs);
1476
1477   if (n_sw_ifs)
1478     {
1479       vl_api_bridge_domain_sw_if_t *sw_ifs;
1480       print (vam->ofp, "\n\n%s %s  %s", "sw_if_index", "SHG",
1481              "Interface Name");
1482
1483       sw_ifs = mp->sw_if_details;
1484       for (i = 0; i < n_sw_ifs; i++)
1485         {
1486           u8 *sw_if_name = 0;
1487           u32 sw_if_index;
1488           hash_pair_t *p;
1489
1490           sw_if_index = ntohl (sw_ifs->sw_if_index);
1491
1492           /* *INDENT-OFF* */
1493           hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
1494                              ({
1495                                if ((u32) p->value[0] == sw_if_index)
1496                                  {
1497                                    sw_if_name = (u8 *)(p->key);
1498                                    break;
1499                                  }
1500                              }));
1501           /* *INDENT-ON* */
1502           print (vam->ofp, "%7d     %3d  %s", sw_if_index,
1503                  sw_ifs->shg, sw_if_name ? (char *) sw_if_name :
1504                  "sw_if_index not found!");
1505
1506           sw_ifs++;
1507         }
1508     }
1509 }
1510
1511 static void vl_api_bridge_domain_details_t_handler_json
1512   (vl_api_bridge_domain_details_t * mp)
1513 {
1514   vat_main_t *vam = &vat_main;
1515   vat_json_node_t *node, *array = NULL;
1516   u32 n_sw_ifs = ntohl (mp->n_sw_ifs);
1517
1518   if (VAT_JSON_ARRAY != vam->json_tree.type)
1519     {
1520       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
1521       vat_json_init_array (&vam->json_tree);
1522     }
1523   node = vat_json_array_add (&vam->json_tree);
1524
1525   vat_json_init_object (node);
1526   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
1527   vat_json_object_add_uint (node, "flood", mp->flood);
1528   vat_json_object_add_uint (node, "forward", mp->forward);
1529   vat_json_object_add_uint (node, "learn", mp->learn);
1530   vat_json_object_add_uint (node, "bvi_sw_if_index",
1531                             ntohl (mp->bvi_sw_if_index));
1532   vat_json_object_add_uint (node, "n_sw_ifs", n_sw_ifs);
1533   array = vat_json_object_add (node, "sw_if");
1534   vat_json_init_array (array);
1535
1536
1537
1538   if (n_sw_ifs)
1539     {
1540       vl_api_bridge_domain_sw_if_t *sw_ifs;
1541       int i;
1542
1543       sw_ifs = mp->sw_if_details;
1544       for (i = 0; i < n_sw_ifs; i++)
1545         {
1546           node = vat_json_array_add (array);
1547           vat_json_init_object (node);
1548           vat_json_object_add_uint (node, "sw_if_index",
1549                                     ntohl (sw_ifs->sw_if_index));
1550           vat_json_object_add_uint (node, "shg", sw_ifs->shg);
1551           sw_ifs++;
1552         }
1553     }
1554 }
1555
1556 static void vl_api_control_ping_reply_t_handler
1557   (vl_api_control_ping_reply_t * mp)
1558 {
1559   vat_main_t *vam = &vat_main;
1560   i32 retval = ntohl (mp->retval);
1561   if (vam->async_mode)
1562     {
1563       vam->async_errors += (retval < 0);
1564     }
1565   else
1566     {
1567       vam->retval = retval;
1568       vam->result_ready = 1;
1569     }
1570   if (vam->socket_client_main)
1571     vam->socket_client_main->control_pings_outstanding--;
1572 }
1573
1574 static void vl_api_control_ping_reply_t_handler_json
1575   (vl_api_control_ping_reply_t * mp)
1576 {
1577   vat_main_t *vam = &vat_main;
1578   i32 retval = ntohl (mp->retval);
1579
1580   if (VAT_JSON_NONE != vam->json_tree.type)
1581     {
1582       vat_json_print (vam->ofp, &vam->json_tree);
1583       vat_json_free (&vam->json_tree);
1584       vam->json_tree.type = VAT_JSON_NONE;
1585     }
1586   else
1587     {
1588       /* just print [] */
1589       vat_json_init_array (&vam->json_tree);
1590       vat_json_print (vam->ofp, &vam->json_tree);
1591       vam->json_tree.type = VAT_JSON_NONE;
1592     }
1593
1594   vam->retval = retval;
1595   vam->result_ready = 1;
1596 }
1597
1598 static void
1599   vl_api_bridge_domain_set_mac_age_reply_t_handler
1600   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1601 {
1602   vat_main_t *vam = &vat_main;
1603   i32 retval = ntohl (mp->retval);
1604   if (vam->async_mode)
1605     {
1606       vam->async_errors += (retval < 0);
1607     }
1608   else
1609     {
1610       vam->retval = retval;
1611       vam->result_ready = 1;
1612     }
1613 }
1614
1615 static void vl_api_bridge_domain_set_mac_age_reply_t_handler_json
1616   (vl_api_bridge_domain_set_mac_age_reply_t * mp)
1617 {
1618   vat_main_t *vam = &vat_main;
1619   vat_json_node_t node;
1620
1621   vat_json_init_object (&node);
1622   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1623
1624   vat_json_print (vam->ofp, &node);
1625   vat_json_free (&node);
1626
1627   vam->retval = ntohl (mp->retval);
1628   vam->result_ready = 1;
1629 }
1630
1631 static void
1632 vl_api_l2_flags_reply_t_handler (vl_api_l2_flags_reply_t * mp)
1633 {
1634   vat_main_t *vam = &vat_main;
1635   i32 retval = ntohl (mp->retval);
1636   if (vam->async_mode)
1637     {
1638       vam->async_errors += (retval < 0);
1639     }
1640   else
1641     {
1642       vam->retval = retval;
1643       vam->result_ready = 1;
1644     }
1645 }
1646
1647 static void vl_api_l2_flags_reply_t_handler_json
1648   (vl_api_l2_flags_reply_t * mp)
1649 {
1650   vat_main_t *vam = &vat_main;
1651   vat_json_node_t node;
1652
1653   vat_json_init_object (&node);
1654   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1655   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1656                             ntohl (mp->resulting_feature_bitmap));
1657
1658   vat_json_print (vam->ofp, &node);
1659   vat_json_free (&node);
1660
1661   vam->retval = ntohl (mp->retval);
1662   vam->result_ready = 1;
1663 }
1664
1665 static void vl_api_bridge_flags_reply_t_handler
1666   (vl_api_bridge_flags_reply_t * mp)
1667 {
1668   vat_main_t *vam = &vat_main;
1669   i32 retval = ntohl (mp->retval);
1670   if (vam->async_mode)
1671     {
1672       vam->async_errors += (retval < 0);
1673     }
1674   else
1675     {
1676       vam->retval = retval;
1677       vam->result_ready = 1;
1678     }
1679 }
1680
1681 static void vl_api_bridge_flags_reply_t_handler_json
1682   (vl_api_bridge_flags_reply_t * mp)
1683 {
1684   vat_main_t *vam = &vat_main;
1685   vat_json_node_t node;
1686
1687   vat_json_init_object (&node);
1688   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1689   vat_json_object_add_uint (&node, "resulting_feature_bitmap",
1690                             ntohl (mp->resulting_feature_bitmap));
1691
1692   vat_json_print (vam->ofp, &node);
1693   vat_json_free (&node);
1694
1695   vam->retval = ntohl (mp->retval);
1696   vam->result_ready = 1;
1697 }
1698
1699 static void
1700 vl_api_tap_create_v2_reply_t_handler (vl_api_tap_create_v2_reply_t * mp)
1701 {
1702   vat_main_t *vam = &vat_main;
1703   i32 retval = ntohl (mp->retval);
1704   if (vam->async_mode)
1705     {
1706       vam->async_errors += (retval < 0);
1707     }
1708   else
1709     {
1710       vam->retval = retval;
1711       vam->sw_if_index = ntohl (mp->sw_if_index);
1712       vam->result_ready = 1;
1713     }
1714
1715 }
1716
1717 static void vl_api_tap_create_v2_reply_t_handler_json
1718   (vl_api_tap_create_v2_reply_t * mp)
1719 {
1720   vat_main_t *vam = &vat_main;
1721   vat_json_node_t node;
1722
1723   vat_json_init_object (&node);
1724   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1725   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1726
1727   vat_json_print (vam->ofp, &node);
1728   vat_json_free (&node);
1729
1730   vam->retval = ntohl (mp->retval);
1731   vam->result_ready = 1;
1732
1733 }
1734
1735 static void
1736 vl_api_tap_delete_v2_reply_t_handler (vl_api_tap_delete_v2_reply_t * mp)
1737 {
1738   vat_main_t *vam = &vat_main;
1739   i32 retval = ntohl (mp->retval);
1740   if (vam->async_mode)
1741     {
1742       vam->async_errors += (retval < 0);
1743     }
1744   else
1745     {
1746       vam->retval = retval;
1747       vam->result_ready = 1;
1748     }
1749 }
1750
1751 static void vl_api_tap_delete_v2_reply_t_handler_json
1752   (vl_api_tap_delete_v2_reply_t * mp)
1753 {
1754   vat_main_t *vam = &vat_main;
1755   vat_json_node_t node;
1756
1757   vat_json_init_object (&node);
1758   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1759
1760   vat_json_print (vam->ofp, &node);
1761   vat_json_free (&node);
1762
1763   vam->retval = ntohl (mp->retval);
1764   vam->result_ready = 1;
1765 }
1766
1767 static void
1768 vl_api_virtio_pci_create_reply_t_handler (vl_api_virtio_pci_create_reply_t *
1769                                           mp)
1770 {
1771   vat_main_t *vam = &vat_main;
1772   i32 retval = ntohl (mp->retval);
1773   if (vam->async_mode)
1774     {
1775       vam->async_errors += (retval < 0);
1776     }
1777   else
1778     {
1779       vam->retval = retval;
1780       vam->sw_if_index = ntohl (mp->sw_if_index);
1781       vam->result_ready = 1;
1782     }
1783 }
1784
1785 static void vl_api_virtio_pci_create_reply_t_handler_json
1786   (vl_api_virtio_pci_create_reply_t * mp)
1787 {
1788   vat_main_t *vam = &vat_main;
1789   vat_json_node_t node;
1790
1791   vat_json_init_object (&node);
1792   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1793   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1794
1795   vat_json_print (vam->ofp, &node);
1796   vat_json_free (&node);
1797
1798   vam->retval = ntohl (mp->retval);
1799   vam->result_ready = 1;
1800
1801 }
1802
1803 static void
1804 vl_api_virtio_pci_delete_reply_t_handler (vl_api_virtio_pci_delete_reply_t *
1805                                           mp)
1806 {
1807   vat_main_t *vam = &vat_main;
1808   i32 retval = ntohl (mp->retval);
1809   if (vam->async_mode)
1810     {
1811       vam->async_errors += (retval < 0);
1812     }
1813   else
1814     {
1815       vam->retval = retval;
1816       vam->result_ready = 1;
1817     }
1818 }
1819
1820 static void vl_api_virtio_pci_delete_reply_t_handler_json
1821   (vl_api_virtio_pci_delete_reply_t * mp)
1822 {
1823   vat_main_t *vam = &vat_main;
1824   vat_json_node_t node;
1825
1826   vat_json_init_object (&node);
1827   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1828
1829   vat_json_print (vam->ofp, &node);
1830   vat_json_free (&node);
1831
1832   vam->retval = ntohl (mp->retval);
1833   vam->result_ready = 1;
1834 }
1835
1836 static void
1837 vl_api_bond_create_reply_t_handler (vl_api_bond_create_reply_t * mp)
1838 {
1839   vat_main_t *vam = &vat_main;
1840   i32 retval = ntohl (mp->retval);
1841
1842   if (vam->async_mode)
1843     {
1844       vam->async_errors += (retval < 0);
1845     }
1846   else
1847     {
1848       vam->retval = retval;
1849       vam->sw_if_index = ntohl (mp->sw_if_index);
1850       vam->result_ready = 1;
1851     }
1852 }
1853
1854 static void vl_api_bond_create_reply_t_handler_json
1855   (vl_api_bond_create_reply_t * mp)
1856 {
1857   vat_main_t *vam = &vat_main;
1858   vat_json_node_t node;
1859
1860   vat_json_init_object (&node);
1861   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1862   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
1863
1864   vat_json_print (vam->ofp, &node);
1865   vat_json_free (&node);
1866
1867   vam->retval = ntohl (mp->retval);
1868   vam->result_ready = 1;
1869 }
1870
1871 static void
1872 vl_api_bond_delete_reply_t_handler (vl_api_bond_delete_reply_t * mp)
1873 {
1874   vat_main_t *vam = &vat_main;
1875   i32 retval = ntohl (mp->retval);
1876
1877   if (vam->async_mode)
1878     {
1879       vam->async_errors += (retval < 0);
1880     }
1881   else
1882     {
1883       vam->retval = retval;
1884       vam->result_ready = 1;
1885     }
1886 }
1887
1888 static void vl_api_bond_delete_reply_t_handler_json
1889   (vl_api_bond_delete_reply_t * mp)
1890 {
1891   vat_main_t *vam = &vat_main;
1892   vat_json_node_t node;
1893
1894   vat_json_init_object (&node);
1895   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1896
1897   vat_json_print (vam->ofp, &node);
1898   vat_json_free (&node);
1899
1900   vam->retval = ntohl (mp->retval);
1901   vam->result_ready = 1;
1902 }
1903
1904 static void
1905 vl_api_bond_enslave_reply_t_handler (vl_api_bond_enslave_reply_t * mp)
1906 {
1907   vat_main_t *vam = &vat_main;
1908   i32 retval = ntohl (mp->retval);
1909
1910   if (vam->async_mode)
1911     {
1912       vam->async_errors += (retval < 0);
1913     }
1914   else
1915     {
1916       vam->retval = retval;
1917       vam->result_ready = 1;
1918     }
1919 }
1920
1921 static void vl_api_bond_enslave_reply_t_handler_json
1922   (vl_api_bond_enslave_reply_t * mp)
1923 {
1924   vat_main_t *vam = &vat_main;
1925   vat_json_node_t node;
1926
1927   vat_json_init_object (&node);
1928   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1929
1930   vat_json_print (vam->ofp, &node);
1931   vat_json_free (&node);
1932
1933   vam->retval = ntohl (mp->retval);
1934   vam->result_ready = 1;
1935 }
1936
1937 static void
1938 vl_api_bond_detach_slave_reply_t_handler (vl_api_bond_detach_slave_reply_t *
1939                                           mp)
1940 {
1941   vat_main_t *vam = &vat_main;
1942   i32 retval = ntohl (mp->retval);
1943
1944   if (vam->async_mode)
1945     {
1946       vam->async_errors += (retval < 0);
1947     }
1948   else
1949     {
1950       vam->retval = retval;
1951       vam->result_ready = 1;
1952     }
1953 }
1954
1955 static void vl_api_bond_detach_slave_reply_t_handler_json
1956   (vl_api_bond_detach_slave_reply_t * mp)
1957 {
1958   vat_main_t *vam = &vat_main;
1959   vat_json_node_t node;
1960
1961   vat_json_init_object (&node);
1962   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
1963
1964   vat_json_print (vam->ofp, &node);
1965   vat_json_free (&node);
1966
1967   vam->retval = ntohl (mp->retval);
1968   vam->result_ready = 1;
1969 }
1970
1971 static int
1972 api_sw_interface_set_bond_weight (vat_main_t * vam)
1973 {
1974   unformat_input_t *i = vam->input;
1975   vl_api_sw_interface_set_bond_weight_t *mp;
1976   u32 sw_if_index = ~0;
1977   u32 weight = 0;
1978   u8 weight_enter = 0;
1979   int ret;
1980
1981   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
1982     {
1983       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
1984         ;
1985       else if (unformat (i, "sw_if_index %d", &sw_if_index))
1986         ;
1987       else if (unformat (i, "weight %u", &weight))
1988         weight_enter = 1;
1989       else
1990         break;
1991     }
1992
1993   if (sw_if_index == ~0)
1994     {
1995       errmsg ("missing interface name or sw_if_index");
1996       return -99;
1997     }
1998   if (weight_enter == 0)
1999     {
2000       errmsg ("missing valid weight");
2001       return -99;
2002     }
2003
2004   /* Construct the API message */
2005   M (SW_INTERFACE_SET_BOND_WEIGHT, mp);
2006   mp->sw_if_index = ntohl (sw_if_index);
2007   mp->weight = ntohl (weight);
2008
2009   S (mp);
2010   W (ret);
2011   return ret;
2012 }
2013
2014 static void vl_api_sw_interface_bond_details_t_handler
2015   (vl_api_sw_interface_bond_details_t * mp)
2016 {
2017   vat_main_t *vam = &vat_main;
2018
2019   print (vam->ofp,
2020          "%-16s %-12d %-12U %-13U %-14u %-14u",
2021          mp->interface_name, ntohl (mp->sw_if_index),
2022          format_bond_mode, ntohl (mp->mode), format_bond_load_balance,
2023          ntohl (mp->lb), ntohl (mp->active_slaves), ntohl (mp->slaves));
2024 }
2025
2026 static void vl_api_sw_interface_bond_details_t_handler_json
2027   (vl_api_sw_interface_bond_details_t * mp)
2028 {
2029   vat_main_t *vam = &vat_main;
2030   vat_json_node_t *node = NULL;
2031
2032   if (VAT_JSON_ARRAY != vam->json_tree.type)
2033     {
2034       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2035       vat_json_init_array (&vam->json_tree);
2036     }
2037   node = vat_json_array_add (&vam->json_tree);
2038
2039   vat_json_init_object (node);
2040   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
2041   vat_json_object_add_string_copy (node, "interface_name",
2042                                    mp->interface_name);
2043   vat_json_object_add_uint (node, "mode", ntohl (mp->mode));
2044   vat_json_object_add_uint (node, "load_balance", ntohl (mp->lb));
2045   vat_json_object_add_uint (node, "active_slaves", ntohl (mp->active_slaves));
2046   vat_json_object_add_uint (node, "slaves", ntohl (mp->slaves));
2047 }
2048
2049 static int
2050 api_sw_interface_bond_dump (vat_main_t * vam)
2051 {
2052   vl_api_sw_interface_bond_dump_t *mp;
2053   vl_api_control_ping_t *mp_ping;
2054   int ret;
2055
2056   print (vam->ofp,
2057          "\n%-16s %-12s %-12s %-13s %-14s %-14s",
2058          "interface name", "sw_if_index", "mode", "load balance",
2059          "active slaves", "slaves");
2060
2061   /* Get list of bond interfaces */
2062   M (SW_INTERFACE_BOND_DUMP, mp);
2063   S (mp);
2064
2065   /* Use a control ping for synchronization */
2066   MPING (CONTROL_PING, mp_ping);
2067   S (mp_ping);
2068
2069   W (ret);
2070   return ret;
2071 }
2072
2073 static void vl_api_sw_interface_slave_details_t_handler
2074   (vl_api_sw_interface_slave_details_t * mp)
2075 {
2076   vat_main_t *vam = &vat_main;
2077
2078   print (vam->ofp,
2079          "%-25s %-12d %-7d %-12d %-10d %-10d", mp->interface_name,
2080          ntohl (mp->sw_if_index), mp->is_passive, mp->is_long_timeout,
2081          ntohl (mp->weight), mp->is_local_numa);
2082 }
2083
2084 static void vl_api_sw_interface_slave_details_t_handler_json
2085   (vl_api_sw_interface_slave_details_t * mp)
2086 {
2087   vat_main_t *vam = &vat_main;
2088   vat_json_node_t *node = NULL;
2089
2090   if (VAT_JSON_ARRAY != vam->json_tree.type)
2091     {
2092       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2093       vat_json_init_array (&vam->json_tree);
2094     }
2095   node = vat_json_array_add (&vam->json_tree);
2096
2097   vat_json_init_object (node);
2098   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
2099   vat_json_object_add_string_copy (node, "interface_name",
2100                                    mp->interface_name);
2101   vat_json_object_add_uint (node, "passive", mp->is_passive);
2102   vat_json_object_add_uint (node, "long_timeout", mp->is_long_timeout);
2103   vat_json_object_add_uint (node, "weight", ntohl (mp->weight));
2104   vat_json_object_add_uint (node, "is_local_numa", mp->is_local_numa);
2105 }
2106
2107 static int
2108 api_sw_interface_slave_dump (vat_main_t * vam)
2109 {
2110   unformat_input_t *i = vam->input;
2111   vl_api_sw_interface_slave_dump_t *mp;
2112   vl_api_control_ping_t *mp_ping;
2113   u32 sw_if_index = ~0;
2114   u8 sw_if_index_set = 0;
2115   int ret;
2116
2117   /* Parse args required to build the message */
2118   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
2119     {
2120       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
2121         sw_if_index_set = 1;
2122       else if (unformat (i, "sw_if_index %d", &sw_if_index))
2123         sw_if_index_set = 1;
2124       else
2125         break;
2126     }
2127
2128   if (sw_if_index_set == 0)
2129     {
2130       errmsg ("missing vpp interface name. ");
2131       return -99;
2132     }
2133
2134   print (vam->ofp,
2135          "\n%-25s %-12s %-7s %-12s %-10s %-10s",
2136          "slave interface name", "sw_if_index", "passive", "long_timeout",
2137          "weight", "local numa");
2138
2139   /* Get list of bond interfaces */
2140   M (SW_INTERFACE_SLAVE_DUMP, mp);
2141   mp->sw_if_index = ntohl (sw_if_index);
2142   S (mp);
2143
2144   /* Use a control ping for synchronization */
2145   MPING (CONTROL_PING, mp_ping);
2146   S (mp_ping);
2147
2148   W (ret);
2149   return ret;
2150 }
2151
2152 static void vl_api_mpls_tunnel_add_del_reply_t_handler
2153   (vl_api_mpls_tunnel_add_del_reply_t * mp)
2154 {
2155   vat_main_t *vam = &vat_main;
2156   i32 retval = ntohl (mp->retval);
2157   if (vam->async_mode)
2158     {
2159       vam->async_errors += (retval < 0);
2160     }
2161   else
2162     {
2163       vam->retval = retval;
2164       vam->sw_if_index = ntohl (mp->sw_if_index);
2165       vam->result_ready = 1;
2166     }
2167   vam->regenerate_interface_table = 1;
2168 }
2169
2170 static void vl_api_mpls_tunnel_add_del_reply_t_handler_json
2171   (vl_api_mpls_tunnel_add_del_reply_t * mp)
2172 {
2173   vat_main_t *vam = &vat_main;
2174   vat_json_node_t node;
2175
2176   vat_json_init_object (&node);
2177   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2178   vat_json_object_add_uint (&node, "tunnel_sw_if_index",
2179                             ntohl (mp->sw_if_index));
2180
2181   vat_json_print (vam->ofp, &node);
2182   vat_json_free (&node);
2183
2184   vam->retval = ntohl (mp->retval);
2185   vam->result_ready = 1;
2186 }
2187
2188 static void vl_api_l2tpv3_create_tunnel_reply_t_handler
2189   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
2190 {
2191   vat_main_t *vam = &vat_main;
2192   i32 retval = ntohl (mp->retval);
2193   if (vam->async_mode)
2194     {
2195       vam->async_errors += (retval < 0);
2196     }
2197   else
2198     {
2199       vam->retval = retval;
2200       vam->sw_if_index = ntohl (mp->sw_if_index);
2201       vam->result_ready = 1;
2202     }
2203 }
2204
2205 static void vl_api_l2tpv3_create_tunnel_reply_t_handler_json
2206   (vl_api_l2tpv3_create_tunnel_reply_t * mp)
2207 {
2208   vat_main_t *vam = &vat_main;
2209   vat_json_node_t node;
2210
2211   vat_json_init_object (&node);
2212   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2213   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2214
2215   vat_json_print (vam->ofp, &node);
2216   vat_json_free (&node);
2217
2218   vam->retval = ntohl (mp->retval);
2219   vam->result_ready = 1;
2220 }
2221
2222 static void vl_api_gpe_add_del_fwd_entry_reply_t_handler
2223   (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
2224 {
2225   vat_main_t *vam = &vat_main;
2226   i32 retval = ntohl (mp->retval);
2227   if (vam->async_mode)
2228     {
2229       vam->async_errors += (retval < 0);
2230     }
2231   else
2232     {
2233       vam->retval = retval;
2234       vam->result_ready = 1;
2235     }
2236 }
2237
2238 static void vl_api_gpe_add_del_fwd_entry_reply_t_handler_json
2239   (vl_api_gpe_add_del_fwd_entry_reply_t * mp)
2240 {
2241   vat_main_t *vam = &vat_main;
2242   vat_json_node_t node;
2243
2244   vat_json_init_object (&node);
2245   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2246   vat_json_object_add_uint (&node, "fwd_entry_index",
2247                             clib_net_to_host_u32 (mp->fwd_entry_index));
2248
2249   vat_json_print (vam->ofp, &node);
2250   vat_json_free (&node);
2251
2252   vam->retval = ntohl (mp->retval);
2253   vam->result_ready = 1;
2254 }
2255
2256 u8 *
2257 format_lisp_transport_protocol (u8 * s, va_list * args)
2258 {
2259   u32 proto = va_arg (*args, u32);
2260
2261   switch (proto)
2262     {
2263     case 1:
2264       return format (s, "udp");
2265     case 2:
2266       return format (s, "api");
2267     default:
2268       return 0;
2269     }
2270   return 0;
2271 }
2272
2273 static void vl_api_one_get_transport_protocol_reply_t_handler
2274   (vl_api_one_get_transport_protocol_reply_t * mp)
2275 {
2276   vat_main_t *vam = &vat_main;
2277   i32 retval = ntohl (mp->retval);
2278   if (vam->async_mode)
2279     {
2280       vam->async_errors += (retval < 0);
2281     }
2282   else
2283     {
2284       u32 proto = mp->protocol;
2285       print (vam->ofp, "Transport protocol: %U",
2286              format_lisp_transport_protocol, proto);
2287       vam->retval = retval;
2288       vam->result_ready = 1;
2289     }
2290 }
2291
2292 static void vl_api_one_get_transport_protocol_reply_t_handler_json
2293   (vl_api_one_get_transport_protocol_reply_t * mp)
2294 {
2295   vat_main_t *vam = &vat_main;
2296   vat_json_node_t node;
2297   u8 *s;
2298
2299   s = format (0, "%U", format_lisp_transport_protocol, mp->protocol);
2300   vec_add1 (s, 0);
2301
2302   vat_json_init_object (&node);
2303   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2304   vat_json_object_add_string_copy (&node, "transport-protocol", s);
2305
2306   vec_free (s);
2307   vat_json_print (vam->ofp, &node);
2308   vat_json_free (&node);
2309
2310   vam->retval = ntohl (mp->retval);
2311   vam->result_ready = 1;
2312 }
2313
2314 static void vl_api_one_add_del_locator_set_reply_t_handler
2315   (vl_api_one_add_del_locator_set_reply_t * mp)
2316 {
2317   vat_main_t *vam = &vat_main;
2318   i32 retval = ntohl (mp->retval);
2319   if (vam->async_mode)
2320     {
2321       vam->async_errors += (retval < 0);
2322     }
2323   else
2324     {
2325       vam->retval = retval;
2326       vam->result_ready = 1;
2327     }
2328 }
2329
2330 static void vl_api_one_add_del_locator_set_reply_t_handler_json
2331   (vl_api_one_add_del_locator_set_reply_t * mp)
2332 {
2333   vat_main_t *vam = &vat_main;
2334   vat_json_node_t node;
2335
2336   vat_json_init_object (&node);
2337   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2338   vat_json_object_add_uint (&node, "locator_set_index", ntohl (mp->ls_index));
2339
2340   vat_json_print (vam->ofp, &node);
2341   vat_json_free (&node);
2342
2343   vam->retval = ntohl (mp->retval);
2344   vam->result_ready = 1;
2345 }
2346
2347 static void vl_api_vxlan_add_del_tunnel_reply_t_handler
2348   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
2349 {
2350   vat_main_t *vam = &vat_main;
2351   i32 retval = ntohl (mp->retval);
2352   if (vam->async_mode)
2353     {
2354       vam->async_errors += (retval < 0);
2355     }
2356   else
2357     {
2358       vam->retval = retval;
2359       vam->sw_if_index = ntohl (mp->sw_if_index);
2360       vam->result_ready = 1;
2361     }
2362   vam->regenerate_interface_table = 1;
2363 }
2364
2365 static void vl_api_vxlan_add_del_tunnel_reply_t_handler_json
2366   (vl_api_vxlan_add_del_tunnel_reply_t * mp)
2367 {
2368   vat_main_t *vam = &vat_main;
2369   vat_json_node_t node;
2370
2371   vat_json_init_object (&node);
2372   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2373   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2374
2375   vat_json_print (vam->ofp, &node);
2376   vat_json_free (&node);
2377
2378   vam->retval = ntohl (mp->retval);
2379   vam->result_ready = 1;
2380 }
2381
2382 static void vl_api_vxlan_offload_rx_reply_t_handler
2383   (vl_api_vxlan_offload_rx_reply_t * mp)
2384 {
2385   vat_main_t *vam = &vat_main;
2386   i32 retval = ntohl (mp->retval);
2387   if (vam->async_mode)
2388     {
2389       vam->async_errors += (retval < 0);
2390     }
2391   else
2392     {
2393       vam->retval = retval;
2394       vam->result_ready = 1;
2395     }
2396 }
2397
2398 static void vl_api_vxlan_offload_rx_reply_t_handler_json
2399   (vl_api_vxlan_offload_rx_reply_t * mp)
2400 {
2401   vat_main_t *vam = &vat_main;
2402   vat_json_node_t node;
2403
2404   vat_json_init_object (&node);
2405   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2406
2407   vat_json_print (vam->ofp, &node);
2408   vat_json_free (&node);
2409
2410   vam->retval = ntohl (mp->retval);
2411   vam->result_ready = 1;
2412 }
2413
2414 static void vl_api_geneve_add_del_tunnel_reply_t_handler
2415   (vl_api_geneve_add_del_tunnel_reply_t * mp)
2416 {
2417   vat_main_t *vam = &vat_main;
2418   i32 retval = ntohl (mp->retval);
2419   if (vam->async_mode)
2420     {
2421       vam->async_errors += (retval < 0);
2422     }
2423   else
2424     {
2425       vam->retval = retval;
2426       vam->sw_if_index = ntohl (mp->sw_if_index);
2427       vam->result_ready = 1;
2428     }
2429 }
2430
2431 static void vl_api_geneve_add_del_tunnel_reply_t_handler_json
2432   (vl_api_geneve_add_del_tunnel_reply_t * mp)
2433 {
2434   vat_main_t *vam = &vat_main;
2435   vat_json_node_t node;
2436
2437   vat_json_init_object (&node);
2438   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2439   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2440
2441   vat_json_print (vam->ofp, &node);
2442   vat_json_free (&node);
2443
2444   vam->retval = ntohl (mp->retval);
2445   vam->result_ready = 1;
2446 }
2447
2448 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler
2449   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
2450 {
2451   vat_main_t *vam = &vat_main;
2452   i32 retval = ntohl (mp->retval);
2453   if (vam->async_mode)
2454     {
2455       vam->async_errors += (retval < 0);
2456     }
2457   else
2458     {
2459       vam->retval = retval;
2460       vam->sw_if_index = ntohl (mp->sw_if_index);
2461       vam->result_ready = 1;
2462     }
2463   vam->regenerate_interface_table = 1;
2464 }
2465
2466 static void vl_api_vxlan_gpe_add_del_tunnel_reply_t_handler_json
2467   (vl_api_vxlan_gpe_add_del_tunnel_reply_t * mp)
2468 {
2469   vat_main_t *vam = &vat_main;
2470   vat_json_node_t node;
2471
2472   vat_json_init_object (&node);
2473   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2474   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2475
2476   vat_json_print (vam->ofp, &node);
2477   vat_json_free (&node);
2478
2479   vam->retval = ntohl (mp->retval);
2480   vam->result_ready = 1;
2481 }
2482
2483 static void vl_api_gre_tunnel_add_del_reply_t_handler
2484   (vl_api_gre_tunnel_add_del_reply_t * mp)
2485 {
2486   vat_main_t *vam = &vat_main;
2487   i32 retval = ntohl (mp->retval);
2488   if (vam->async_mode)
2489     {
2490       vam->async_errors += (retval < 0);
2491     }
2492   else
2493     {
2494       vam->retval = retval;
2495       vam->sw_if_index = ntohl (mp->sw_if_index);
2496       vam->result_ready = 1;
2497     }
2498 }
2499
2500 static void vl_api_gre_tunnel_add_del_reply_t_handler_json
2501   (vl_api_gre_tunnel_add_del_reply_t * mp)
2502 {
2503   vat_main_t *vam = &vat_main;
2504   vat_json_node_t node;
2505
2506   vat_json_init_object (&node);
2507   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2508   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2509
2510   vat_json_print (vam->ofp, &node);
2511   vat_json_free (&node);
2512
2513   vam->retval = ntohl (mp->retval);
2514   vam->result_ready = 1;
2515 }
2516
2517 static void vl_api_create_vhost_user_if_reply_t_handler
2518   (vl_api_create_vhost_user_if_reply_t * mp)
2519 {
2520   vat_main_t *vam = &vat_main;
2521   i32 retval = ntohl (mp->retval);
2522   if (vam->async_mode)
2523     {
2524       vam->async_errors += (retval < 0);
2525     }
2526   else
2527     {
2528       vam->retval = retval;
2529       vam->sw_if_index = ntohl (mp->sw_if_index);
2530       vam->result_ready = 1;
2531     }
2532   vam->regenerate_interface_table = 1;
2533 }
2534
2535 static void vl_api_create_vhost_user_if_reply_t_handler_json
2536   (vl_api_create_vhost_user_if_reply_t * mp)
2537 {
2538   vat_main_t *vam = &vat_main;
2539   vat_json_node_t node;
2540
2541   vat_json_init_object (&node);
2542   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2543   vat_json_object_add_uint (&node, "sw_if_index", ntohl (mp->sw_if_index));
2544
2545   vat_json_print (vam->ofp, &node);
2546   vat_json_free (&node);
2547
2548   vam->retval = ntohl (mp->retval);
2549   vam->result_ready = 1;
2550 }
2551
2552 static void vl_api_ip_address_details_t_handler
2553   (vl_api_ip_address_details_t * mp)
2554 {
2555   vat_main_t *vam = &vat_main;
2556   static ip_address_details_t empty_ip_address_details = { {0} };
2557   ip_address_details_t *address = NULL;
2558   ip_details_t *current_ip_details = NULL;
2559   ip_details_t *details = NULL;
2560
2561   details = vam->ip_details_by_sw_if_index[vam->is_ipv6];
2562
2563   if (!details || vam->current_sw_if_index >= vec_len (details)
2564       || !details[vam->current_sw_if_index].present)
2565     {
2566       errmsg ("ip address details arrived but not stored");
2567       errmsg ("ip_dump should be called first");
2568       return;
2569     }
2570
2571   current_ip_details = vec_elt_at_index (details, vam->current_sw_if_index);
2572
2573 #define addresses (current_ip_details->addr)
2574
2575   vec_validate_init_empty (addresses, vec_len (addresses),
2576                            empty_ip_address_details);
2577
2578   address = vec_elt_at_index (addresses, vec_len (addresses) - 1);
2579
2580   clib_memcpy (&address->ip, &mp->prefix.address.un, sizeof (address->ip));
2581   address->prefix_length = mp->prefix.len;
2582 #undef addresses
2583 }
2584
2585 static void vl_api_ip_address_details_t_handler_json
2586   (vl_api_ip_address_details_t * mp)
2587 {
2588   vat_main_t *vam = &vat_main;
2589   vat_json_node_t *node = NULL;
2590
2591   if (VAT_JSON_ARRAY != vam->json_tree.type)
2592     {
2593       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2594       vat_json_init_array (&vam->json_tree);
2595     }
2596   node = vat_json_array_add (&vam->json_tree);
2597
2598   vat_json_init_object (node);
2599   vat_json_object_add_prefix (node, &mp->prefix);
2600 }
2601
2602 static void
2603 vl_api_ip_details_t_handler (vl_api_ip_details_t * mp)
2604 {
2605   vat_main_t *vam = &vat_main;
2606   static ip_details_t empty_ip_details = { 0 };
2607   ip_details_t *ip = NULL;
2608   u32 sw_if_index = ~0;
2609
2610   sw_if_index = ntohl (mp->sw_if_index);
2611
2612   vec_validate_init_empty (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2613                            sw_if_index, empty_ip_details);
2614
2615   ip = vec_elt_at_index (vam->ip_details_by_sw_if_index[vam->is_ipv6],
2616                          sw_if_index);
2617
2618   ip->present = 1;
2619 }
2620
2621 static void
2622 vl_api_ip_details_t_handler_json (vl_api_ip_details_t * mp)
2623 {
2624   vat_main_t *vam = &vat_main;
2625
2626   if (VAT_JSON_ARRAY != vam->json_tree.type)
2627     {
2628       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2629       vat_json_init_array (&vam->json_tree);
2630     }
2631   vat_json_array_add_uint (&vam->json_tree,
2632                            clib_net_to_host_u32 (mp->sw_if_index));
2633 }
2634
2635 static void vl_api_get_first_msg_id_reply_t_handler
2636   (vl_api_get_first_msg_id_reply_t * mp)
2637 {
2638   vat_main_t *vam = &vat_main;
2639   i32 retval = ntohl (mp->retval);
2640
2641   if (vam->async_mode)
2642     {
2643       vam->async_errors += (retval < 0);
2644     }
2645   else
2646     {
2647       vam->retval = retval;
2648       vam->result_ready = 1;
2649     }
2650   if (retval >= 0)
2651     {
2652       errmsg ("first message id %d", ntohs (mp->first_msg_id));
2653     }
2654 }
2655
2656 static void vl_api_get_first_msg_id_reply_t_handler_json
2657   (vl_api_get_first_msg_id_reply_t * mp)
2658 {
2659   vat_main_t *vam = &vat_main;
2660   vat_json_node_t node;
2661
2662   vat_json_init_object (&node);
2663   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2664   vat_json_object_add_uint (&node, "first_msg_id",
2665                             (uint) ntohs (mp->first_msg_id));
2666
2667   vat_json_print (vam->ofp, &node);
2668   vat_json_free (&node);
2669
2670   vam->retval = ntohl (mp->retval);
2671   vam->result_ready = 1;
2672 }
2673
2674 static void vl_api_get_node_graph_reply_t_handler
2675   (vl_api_get_node_graph_reply_t * mp)
2676 {
2677   vat_main_t *vam = &vat_main;
2678   i32 retval = ntohl (mp->retval);
2679   u8 *pvt_copy, *reply;
2680   void *oldheap;
2681   vlib_node_t *node;
2682   int i;
2683
2684   if (vam->async_mode)
2685     {
2686       vam->async_errors += (retval < 0);
2687     }
2688   else
2689     {
2690       vam->retval = retval;
2691       vam->result_ready = 1;
2692     }
2693
2694   /* "Should never happen..." */
2695   if (retval != 0)
2696     return;
2697
2698   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2699   pvt_copy = vec_dup (reply);
2700
2701   /* Toss the shared-memory original... */
2702   oldheap = vl_msg_push_heap ();
2703
2704   vec_free (reply);
2705
2706   vl_msg_pop_heap (oldheap);
2707
2708   if (vam->graph_nodes)
2709     {
2710       hash_free (vam->graph_node_index_by_name);
2711
2712       for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
2713         {
2714           node = vam->graph_nodes[0][i];
2715           vec_free (node->name);
2716           vec_free (node->next_nodes);
2717           vec_free (node);
2718         }
2719       vec_free (vam->graph_nodes[0]);
2720       vec_free (vam->graph_nodes);
2721     }
2722
2723   vam->graph_node_index_by_name = hash_create_string (0, sizeof (uword));
2724   vam->graph_nodes = vlib_node_unserialize (pvt_copy);
2725   vec_free (pvt_copy);
2726
2727   for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
2728     {
2729       node = vam->graph_nodes[0][i];
2730       hash_set_mem (vam->graph_node_index_by_name, node->name, i);
2731     }
2732 }
2733
2734 static void vl_api_get_node_graph_reply_t_handler_json
2735   (vl_api_get_node_graph_reply_t * mp)
2736 {
2737   vat_main_t *vam = &vat_main;
2738   void *oldheap;
2739   vat_json_node_t node;
2740   u8 *reply;
2741
2742   /* $$$$ make this real? */
2743   vat_json_init_object (&node);
2744   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
2745   vat_json_object_add_uint (&node, "reply_in_shmem", mp->reply_in_shmem);
2746
2747   reply = uword_to_pointer (mp->reply_in_shmem, u8 *);
2748
2749   /* Toss the shared-memory original... */
2750   oldheap = vl_msg_push_heap ();
2751
2752   vec_free (reply);
2753
2754   vl_msg_pop_heap (oldheap);
2755
2756   vat_json_print (vam->ofp, &node);
2757   vat_json_free (&node);
2758
2759   vam->retval = ntohl (mp->retval);
2760   vam->result_ready = 1;
2761 }
2762
2763 static void
2764 vl_api_one_locator_details_t_handler (vl_api_one_locator_details_t * mp)
2765 {
2766   vat_main_t *vam = &vat_main;
2767   u8 *s = 0;
2768
2769   if (mp->local)
2770     {
2771       s = format (s, "%=16d%=16d%=16d",
2772                   ntohl (mp->sw_if_index), mp->priority, mp->weight);
2773     }
2774   else
2775     {
2776       s = format (s, "%=16U%=16d%=16d",
2777                   mp->is_ipv6 ? format_ip6_address :
2778                   format_ip4_address,
2779                   mp->ip_address, mp->priority, mp->weight);
2780     }
2781
2782   print (vam->ofp, "%v", s);
2783   vec_free (s);
2784 }
2785
2786 static void
2787 vl_api_one_locator_details_t_handler_json (vl_api_one_locator_details_t * mp)
2788 {
2789   vat_main_t *vam = &vat_main;
2790   vat_json_node_t *node = NULL;
2791   struct in6_addr ip6;
2792   struct in_addr ip4;
2793
2794   if (VAT_JSON_ARRAY != vam->json_tree.type)
2795     {
2796       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2797       vat_json_init_array (&vam->json_tree);
2798     }
2799   node = vat_json_array_add (&vam->json_tree);
2800   vat_json_init_object (node);
2801
2802   vat_json_object_add_uint (node, "local", mp->local ? 1 : 0);
2803   vat_json_object_add_uint (node, "priority", mp->priority);
2804   vat_json_object_add_uint (node, "weight", mp->weight);
2805
2806   if (mp->local)
2807     vat_json_object_add_uint (node, "sw_if_index",
2808                               clib_net_to_host_u32 (mp->sw_if_index));
2809   else
2810     {
2811       if (mp->is_ipv6)
2812         {
2813           clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
2814           vat_json_object_add_ip6 (node, "address", ip6);
2815         }
2816       else
2817         {
2818           clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
2819           vat_json_object_add_ip4 (node, "address", ip4);
2820         }
2821     }
2822 }
2823
2824 static void
2825 vl_api_one_locator_set_details_t_handler (vl_api_one_locator_set_details_t *
2826                                           mp)
2827 {
2828   vat_main_t *vam = &vat_main;
2829   u8 *ls_name = 0;
2830
2831   ls_name = format (0, "%s", mp->ls_name);
2832
2833   print (vam->ofp, "%=10d%=15v", clib_net_to_host_u32 (mp->ls_index),
2834          ls_name);
2835   vec_free (ls_name);
2836 }
2837
2838 static void
2839   vl_api_one_locator_set_details_t_handler_json
2840   (vl_api_one_locator_set_details_t * mp)
2841 {
2842   vat_main_t *vam = &vat_main;
2843   vat_json_node_t *node = 0;
2844   u8 *ls_name = 0;
2845
2846   ls_name = format (0, "%s", mp->ls_name);
2847   vec_add1 (ls_name, 0);
2848
2849   if (VAT_JSON_ARRAY != vam->json_tree.type)
2850     {
2851       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2852       vat_json_init_array (&vam->json_tree);
2853     }
2854   node = vat_json_array_add (&vam->json_tree);
2855
2856   vat_json_init_object (node);
2857   vat_json_object_add_string_copy (node, "ls_name", ls_name);
2858   vat_json_object_add_uint (node, "ls_index",
2859                             clib_net_to_host_u32 (mp->ls_index));
2860   vec_free (ls_name);
2861 }
2862
2863 typedef struct
2864 {
2865   u32 spi;
2866   u8 si;
2867 } __attribute__ ((__packed__)) lisp_nsh_api_t;
2868
2869 uword
2870 unformat_nsh_address (unformat_input_t * input, va_list * args)
2871 {
2872   lisp_nsh_api_t *nsh = va_arg (*args, lisp_nsh_api_t *);
2873   return unformat (input, "SPI:%d SI:%d", &nsh->spi, &nsh->si);
2874 }
2875
2876 u8 *
2877 format_nsh_address_vat (u8 * s, va_list * args)
2878 {
2879   nsh_t *a = va_arg (*args, nsh_t *);
2880   return format (s, "SPI:%d SI:%d", clib_net_to_host_u32 (a->spi), a->si);
2881 }
2882
2883 static u8 *
2884 format_lisp_flat_eid (u8 * s, va_list * args)
2885 {
2886   u32 type = va_arg (*args, u32);
2887   u8 *eid = va_arg (*args, u8 *);
2888   u32 eid_len = va_arg (*args, u32);
2889
2890   switch (type)
2891     {
2892     case 0:
2893       return format (s, "%U/%d", format_ip4_address, eid, eid_len);
2894     case 1:
2895       return format (s, "%U/%d", format_ip6_address, eid, eid_len);
2896     case 2:
2897       return format (s, "%U", format_ethernet_address, eid);
2898     case 3:
2899       return format (s, "%U", format_nsh_address_vat, eid);
2900     }
2901   return 0;
2902 }
2903
2904 static u8 *
2905 format_lisp_eid_vat (u8 * s, va_list * args)
2906 {
2907   u32 type = va_arg (*args, u32);
2908   u8 *eid = va_arg (*args, u8 *);
2909   u32 eid_len = va_arg (*args, u32);
2910   u8 *seid = va_arg (*args, u8 *);
2911   u32 seid_len = va_arg (*args, u32);
2912   u32 is_src_dst = va_arg (*args, u32);
2913
2914   if (is_src_dst)
2915     s = format (s, "%U|", format_lisp_flat_eid, type, seid, seid_len);
2916
2917   s = format (s, "%U", format_lisp_flat_eid, type, eid, eid_len);
2918
2919   return s;
2920 }
2921
2922 static void
2923 vl_api_one_eid_table_details_t_handler (vl_api_one_eid_table_details_t * mp)
2924 {
2925   vat_main_t *vam = &vat_main;
2926   u8 *s = 0, *eid = 0;
2927
2928   if (~0 == mp->locator_set_index)
2929     s = format (0, "action: %d", mp->action);
2930   else
2931     s = format (0, "%d", clib_net_to_host_u32 (mp->locator_set_index));
2932
2933   eid = format (0, "%U", format_lisp_eid_vat,
2934                 mp->eid_type,
2935                 mp->eid,
2936                 mp->eid_prefix_len,
2937                 mp->seid, mp->seid_prefix_len, mp->is_src_dst);
2938   vec_add1 (eid, 0);
2939
2940   print (vam->ofp, "[%d] %-35s%-20s%-30s%-20d%-20d%-10d%-20s",
2941          clib_net_to_host_u32 (mp->vni),
2942          eid,
2943          mp->is_local ? "local" : "remote",
2944          s, clib_net_to_host_u32 (mp->ttl), mp->authoritative,
2945          clib_net_to_host_u16 (mp->key_id), mp->key);
2946
2947   vec_free (s);
2948   vec_free (eid);
2949 }
2950
2951 static void
2952 vl_api_one_eid_table_details_t_handler_json (vl_api_one_eid_table_details_t
2953                                              * mp)
2954 {
2955   vat_main_t *vam = &vat_main;
2956   vat_json_node_t *node = 0;
2957   u8 *eid = 0;
2958
2959   if (VAT_JSON_ARRAY != vam->json_tree.type)
2960     {
2961       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
2962       vat_json_init_array (&vam->json_tree);
2963     }
2964   node = vat_json_array_add (&vam->json_tree);
2965
2966   vat_json_init_object (node);
2967   if (~0 == mp->locator_set_index)
2968     vat_json_object_add_uint (node, "action", mp->action);
2969   else
2970     vat_json_object_add_uint (node, "locator_set_index",
2971                               clib_net_to_host_u32 (mp->locator_set_index));
2972
2973   vat_json_object_add_uint (node, "is_local", mp->is_local ? 1 : 0);
2974   if (mp->eid_type == 3)
2975     {
2976       vat_json_node_t *nsh_json = vat_json_object_add (node, "eid");
2977       vat_json_init_object (nsh_json);
2978       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) mp->eid;
2979       vat_json_object_add_uint (nsh_json, "spi",
2980                                 clib_net_to_host_u32 (nsh->spi));
2981       vat_json_object_add_uint (nsh_json, "si", nsh->si);
2982     }
2983   else
2984     {
2985       eid = format (0, "%U", format_lisp_eid_vat,
2986                     mp->eid_type,
2987                     mp->eid,
2988                     mp->eid_prefix_len,
2989                     mp->seid, mp->seid_prefix_len, mp->is_src_dst);
2990       vec_add1 (eid, 0);
2991       vat_json_object_add_string_copy (node, "eid", eid);
2992       vec_free (eid);
2993     }
2994   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
2995   vat_json_object_add_uint (node, "ttl", clib_net_to_host_u32 (mp->ttl));
2996   vat_json_object_add_uint (node, "authoritative", (mp->authoritative));
2997
2998   if (mp->key_id)
2999     {
3000       vat_json_object_add_uint (node, "key_id",
3001                                 clib_net_to_host_u16 (mp->key_id));
3002       vat_json_object_add_string_copy (node, "key", mp->key);
3003     }
3004 }
3005
3006 static void
3007 vl_api_one_stats_details_t_handler (vl_api_one_stats_details_t * mp)
3008 {
3009   vat_main_t *vam = &vat_main;
3010   u8 *seid = 0, *deid = 0;
3011   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3012
3013   deid = format (0, "%U", format_lisp_eid_vat,
3014                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
3015
3016   seid = format (0, "%U", format_lisp_eid_vat,
3017                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
3018
3019   vec_add1 (deid, 0);
3020   vec_add1 (seid, 0);
3021
3022   if (mp->is_ip4)
3023     format_ip_address_fcn = format_ip4_address;
3024   else
3025     format_ip_address_fcn = format_ip6_address;
3026
3027
3028   print (vam->ofp, "([%d] %s %s) (%U %U) %u %u",
3029          clib_net_to_host_u32 (mp->vni),
3030          seid, deid,
3031          format_ip_address_fcn, mp->lloc,
3032          format_ip_address_fcn, mp->rloc,
3033          clib_net_to_host_u32 (mp->pkt_count),
3034          clib_net_to_host_u32 (mp->bytes));
3035
3036   vec_free (deid);
3037   vec_free (seid);
3038 }
3039
3040 static void
3041 vl_api_one_stats_details_t_handler_json (vl_api_one_stats_details_t * mp)
3042 {
3043   struct in6_addr ip6;
3044   struct in_addr ip4;
3045   vat_main_t *vam = &vat_main;
3046   vat_json_node_t *node = 0;
3047   u8 *deid = 0, *seid = 0;
3048
3049   if (VAT_JSON_ARRAY != vam->json_tree.type)
3050     {
3051       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3052       vat_json_init_array (&vam->json_tree);
3053     }
3054   node = vat_json_array_add (&vam->json_tree);
3055
3056   vat_json_init_object (node);
3057   deid = format (0, "%U", format_lisp_eid_vat,
3058                  mp->eid_type, mp->deid, mp->deid_pref_len, 0, 0, 0);
3059
3060   seid = format (0, "%U", format_lisp_eid_vat,
3061                  mp->eid_type, mp->seid, mp->seid_pref_len, 0, 0, 0);
3062
3063   vec_add1 (deid, 0);
3064   vec_add1 (seid, 0);
3065
3066   vat_json_object_add_string_copy (node, "seid", seid);
3067   vat_json_object_add_string_copy (node, "deid", deid);
3068   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3069
3070   if (mp->is_ip4)
3071     {
3072       clib_memcpy (&ip4, mp->lloc, sizeof (ip4));
3073       vat_json_object_add_ip4 (node, "lloc", ip4);
3074       clib_memcpy (&ip4, mp->rloc, sizeof (ip4));
3075       vat_json_object_add_ip4 (node, "rloc", ip4);
3076     }
3077   else
3078     {
3079       clib_memcpy (&ip6, mp->lloc, sizeof (ip6));
3080       vat_json_object_add_ip6 (node, "lloc", ip6);
3081       clib_memcpy (&ip6, mp->rloc, sizeof (ip6));
3082       vat_json_object_add_ip6 (node, "rloc", ip6);
3083     }
3084   vat_json_object_add_uint (node, "pkt_count",
3085                             clib_net_to_host_u32 (mp->pkt_count));
3086   vat_json_object_add_uint (node, "bytes", clib_net_to_host_u32 (mp->bytes));
3087
3088   vec_free (deid);
3089   vec_free (seid);
3090 }
3091
3092 static void
3093   vl_api_one_eid_table_map_details_t_handler
3094   (vl_api_one_eid_table_map_details_t * mp)
3095 {
3096   vat_main_t *vam = &vat_main;
3097
3098   u8 *line = format (0, "%=10d%=10d",
3099                      clib_net_to_host_u32 (mp->vni),
3100                      clib_net_to_host_u32 (mp->dp_table));
3101   print (vam->ofp, "%v", line);
3102   vec_free (line);
3103 }
3104
3105 static void
3106   vl_api_one_eid_table_map_details_t_handler_json
3107   (vl_api_one_eid_table_map_details_t * mp)
3108 {
3109   vat_main_t *vam = &vat_main;
3110   vat_json_node_t *node = NULL;
3111
3112   if (VAT_JSON_ARRAY != vam->json_tree.type)
3113     {
3114       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3115       vat_json_init_array (&vam->json_tree);
3116     }
3117   node = vat_json_array_add (&vam->json_tree);
3118   vat_json_init_object (node);
3119   vat_json_object_add_uint (node, "dp_table",
3120                             clib_net_to_host_u32 (mp->dp_table));
3121   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3122 }
3123
3124 static void
3125   vl_api_one_eid_table_vni_details_t_handler
3126   (vl_api_one_eid_table_vni_details_t * mp)
3127 {
3128   vat_main_t *vam = &vat_main;
3129
3130   u8 *line = format (0, "%d", clib_net_to_host_u32 (mp->vni));
3131   print (vam->ofp, "%v", line);
3132   vec_free (line);
3133 }
3134
3135 static void
3136   vl_api_one_eid_table_vni_details_t_handler_json
3137   (vl_api_one_eid_table_vni_details_t * mp)
3138 {
3139   vat_main_t *vam = &vat_main;
3140   vat_json_node_t *node = NULL;
3141
3142   if (VAT_JSON_ARRAY != vam->json_tree.type)
3143     {
3144       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3145       vat_json_init_array (&vam->json_tree);
3146     }
3147   node = vat_json_array_add (&vam->json_tree);
3148   vat_json_init_object (node);
3149   vat_json_object_add_uint (node, "vni", clib_net_to_host_u32 (mp->vni));
3150 }
3151
3152 static void
3153   vl_api_show_one_map_register_fallback_threshold_reply_t_handler
3154   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
3155 {
3156   vat_main_t *vam = &vat_main;
3157   int retval = clib_net_to_host_u32 (mp->retval);
3158
3159   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
3160   print (vam->ofp, "fallback threshold value: %d", mp->value);
3161
3162   vam->retval = retval;
3163   vam->result_ready = 1;
3164 }
3165
3166 static void
3167   vl_api_show_one_map_register_fallback_threshold_reply_t_handler_json
3168   (vl_api_show_one_map_register_fallback_threshold_reply_t * mp)
3169 {
3170   vat_main_t *vam = &vat_main;
3171   vat_json_node_t _node, *node = &_node;
3172   int retval = clib_net_to_host_u32 (mp->retval);
3173
3174   vl_api_show_one_map_register_fallback_threshold_reply_t_endian (mp);
3175   vat_json_init_object (node);
3176   vat_json_object_add_uint (node, "value", mp->value);
3177
3178   vat_json_print (vam->ofp, node);
3179   vat_json_free (node);
3180
3181   vam->retval = retval;
3182   vam->result_ready = 1;
3183 }
3184
3185 static void
3186   vl_api_show_one_map_register_state_reply_t_handler
3187   (vl_api_show_one_map_register_state_reply_t * mp)
3188 {
3189   vat_main_t *vam = &vat_main;
3190   int retval = clib_net_to_host_u32 (mp->retval);
3191
3192   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
3193
3194   vam->retval = retval;
3195   vam->result_ready = 1;
3196 }
3197
3198 static void
3199   vl_api_show_one_map_register_state_reply_t_handler_json
3200   (vl_api_show_one_map_register_state_reply_t * mp)
3201 {
3202   vat_main_t *vam = &vat_main;
3203   vat_json_node_t _node, *node = &_node;
3204   int retval = clib_net_to_host_u32 (mp->retval);
3205
3206   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
3207
3208   vat_json_init_object (node);
3209   vat_json_object_add_string_copy (node, "state", s);
3210
3211   vat_json_print (vam->ofp, node);
3212   vat_json_free (node);
3213
3214   vam->retval = retval;
3215   vam->result_ready = 1;
3216   vec_free (s);
3217 }
3218
3219 static void
3220   vl_api_show_one_rloc_probe_state_reply_t_handler
3221   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3222 {
3223   vat_main_t *vam = &vat_main;
3224   int retval = clib_net_to_host_u32 (mp->retval);
3225
3226   if (retval)
3227     goto end;
3228
3229   print (vam->ofp, "%s", mp->is_enabled ? "enabled" : "disabled");
3230 end:
3231   vam->retval = retval;
3232   vam->result_ready = 1;
3233 }
3234
3235 static void
3236   vl_api_show_one_rloc_probe_state_reply_t_handler_json
3237   (vl_api_show_one_rloc_probe_state_reply_t * mp)
3238 {
3239   vat_main_t *vam = &vat_main;
3240   vat_json_node_t _node, *node = &_node;
3241   int retval = clib_net_to_host_u32 (mp->retval);
3242
3243   u8 *s = format (0, "%s", mp->is_enabled ? "enabled" : "disabled");
3244   vat_json_init_object (node);
3245   vat_json_object_add_string_copy (node, "state", s);
3246
3247   vat_json_print (vam->ofp, node);
3248   vat_json_free (node);
3249
3250   vam->retval = retval;
3251   vam->result_ready = 1;
3252   vec_free (s);
3253 }
3254
3255 static void
3256   vl_api_show_one_stats_enable_disable_reply_t_handler
3257   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3258 {
3259   vat_main_t *vam = &vat_main;
3260   int retval = clib_net_to_host_u32 (mp->retval);
3261
3262   if (retval)
3263     goto end;
3264
3265   print (vam->ofp, "%s", mp->is_en ? "enabled" : "disabled");
3266 end:
3267   vam->retval = retval;
3268   vam->result_ready = 1;
3269 }
3270
3271 static void
3272   vl_api_show_one_stats_enable_disable_reply_t_handler_json
3273   (vl_api_show_one_stats_enable_disable_reply_t * mp)
3274 {
3275   vat_main_t *vam = &vat_main;
3276   vat_json_node_t _node, *node = &_node;
3277   int retval = clib_net_to_host_u32 (mp->retval);
3278
3279   u8 *s = format (0, "%s", mp->is_en ? "enabled" : "disabled");
3280   vat_json_init_object (node);
3281   vat_json_object_add_string_copy (node, "state", s);
3282
3283   vat_json_print (vam->ofp, node);
3284   vat_json_free (node);
3285
3286   vam->retval = retval;
3287   vam->result_ready = 1;
3288   vec_free (s);
3289 }
3290
3291 static void
3292 api_gpe_fwd_entry_net_to_host (vl_api_gpe_fwd_entry_t * e)
3293 {
3294   e->dp_table = clib_net_to_host_u32 (e->dp_table);
3295   e->fwd_entry_index = clib_net_to_host_u32 (e->fwd_entry_index);
3296   e->vni = clib_net_to_host_u32 (e->vni);
3297 }
3298
3299 static void
3300   gpe_fwd_entries_get_reply_t_net_to_host
3301   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3302 {
3303   u32 i;
3304
3305   mp->count = clib_net_to_host_u32 (mp->count);
3306   for (i = 0; i < mp->count; i++)
3307     {
3308       api_gpe_fwd_entry_net_to_host (&mp->entries[i]);
3309     }
3310 }
3311
3312 static u8 *
3313 format_gpe_encap_mode (u8 * s, va_list * args)
3314 {
3315   u32 mode = va_arg (*args, u32);
3316
3317   switch (mode)
3318     {
3319     case 0:
3320       return format (s, "lisp");
3321     case 1:
3322       return format (s, "vxlan");
3323     }
3324   return 0;
3325 }
3326
3327 static void
3328   vl_api_gpe_get_encap_mode_reply_t_handler
3329   (vl_api_gpe_get_encap_mode_reply_t * mp)
3330 {
3331   vat_main_t *vam = &vat_main;
3332
3333   print (vam->ofp, "gpe mode: %U", format_gpe_encap_mode, mp->encap_mode);
3334   vam->retval = ntohl (mp->retval);
3335   vam->result_ready = 1;
3336 }
3337
3338 static void
3339   vl_api_gpe_get_encap_mode_reply_t_handler_json
3340   (vl_api_gpe_get_encap_mode_reply_t * mp)
3341 {
3342   vat_main_t *vam = &vat_main;
3343   vat_json_node_t node;
3344
3345   u8 *encap_mode = format (0, "%U", format_gpe_encap_mode, mp->encap_mode);
3346   vec_add1 (encap_mode, 0);
3347
3348   vat_json_init_object (&node);
3349   vat_json_object_add_string_copy (&node, "gpe_mode", encap_mode);
3350
3351   vec_free (encap_mode);
3352   vat_json_print (vam->ofp, &node);
3353   vat_json_free (&node);
3354
3355   vam->retval = ntohl (mp->retval);
3356   vam->result_ready = 1;
3357 }
3358
3359 static void
3360   vl_api_gpe_fwd_entry_path_details_t_handler
3361   (vl_api_gpe_fwd_entry_path_details_t * mp)
3362 {
3363   vat_main_t *vam = &vat_main;
3364   u8 *(*format_ip_address_fcn) (u8 *, va_list *) = 0;
3365
3366   if (mp->lcl_loc.is_ip4)
3367     format_ip_address_fcn = format_ip4_address;
3368   else
3369     format_ip_address_fcn = format_ip6_address;
3370
3371   print (vam->ofp, "w:%d %30U %30U", mp->rmt_loc.weight,
3372          format_ip_address_fcn, &mp->lcl_loc,
3373          format_ip_address_fcn, &mp->rmt_loc);
3374 }
3375
3376 static void
3377 lisp_fill_locator_node (vat_json_node_t * n, vl_api_gpe_locator_t * loc)
3378 {
3379   struct in6_addr ip6;
3380   struct in_addr ip4;
3381
3382   if (loc->is_ip4)
3383     {
3384       clib_memcpy (&ip4, loc->addr, sizeof (ip4));
3385       vat_json_object_add_ip4 (n, "address", ip4);
3386     }
3387   else
3388     {
3389       clib_memcpy (&ip6, loc->addr, sizeof (ip6));
3390       vat_json_object_add_ip6 (n, "address", ip6);
3391     }
3392   vat_json_object_add_uint (n, "weight", loc->weight);
3393 }
3394
3395 static void
3396   vl_api_gpe_fwd_entry_path_details_t_handler_json
3397   (vl_api_gpe_fwd_entry_path_details_t * mp)
3398 {
3399   vat_main_t *vam = &vat_main;
3400   vat_json_node_t *node = NULL;
3401   vat_json_node_t *loc_node;
3402
3403   if (VAT_JSON_ARRAY != vam->json_tree.type)
3404     {
3405       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3406       vat_json_init_array (&vam->json_tree);
3407     }
3408   node = vat_json_array_add (&vam->json_tree);
3409   vat_json_init_object (node);
3410
3411   loc_node = vat_json_object_add (node, "local_locator");
3412   vat_json_init_object (loc_node);
3413   lisp_fill_locator_node (loc_node, &mp->lcl_loc);
3414
3415   loc_node = vat_json_object_add (node, "remote_locator");
3416   vat_json_init_object (loc_node);
3417   lisp_fill_locator_node (loc_node, &mp->rmt_loc);
3418 }
3419
3420 static void
3421   vl_api_gpe_fwd_entries_get_reply_t_handler
3422   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3423 {
3424   vat_main_t *vam = &vat_main;
3425   u32 i;
3426   int retval = clib_net_to_host_u32 (mp->retval);
3427   vl_api_gpe_fwd_entry_t *e;
3428
3429   if (retval)
3430     goto end;
3431
3432   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3433
3434   for (i = 0; i < mp->count; i++)
3435     {
3436       e = &mp->entries[i];
3437       print (vam->ofp, "%10d %10d %U %40U", e->fwd_entry_index, e->dp_table,
3438              format_lisp_flat_eid, e->eid_type, e->leid, e->leid_prefix_len,
3439              format_lisp_flat_eid, e->eid_type, e->reid, e->reid_prefix_len);
3440     }
3441
3442 end:
3443   vam->retval = retval;
3444   vam->result_ready = 1;
3445 }
3446
3447 static void
3448   vl_api_gpe_fwd_entries_get_reply_t_handler_json
3449   (vl_api_gpe_fwd_entries_get_reply_t * mp)
3450 {
3451   u8 *s = 0;
3452   vat_main_t *vam = &vat_main;
3453   vat_json_node_t *e = 0, root;
3454   u32 i;
3455   int retval = clib_net_to_host_u32 (mp->retval);
3456   vl_api_gpe_fwd_entry_t *fwd;
3457
3458   if (retval)
3459     goto end;
3460
3461   gpe_fwd_entries_get_reply_t_net_to_host (mp);
3462   vat_json_init_array (&root);
3463
3464   for (i = 0; i < mp->count; i++)
3465     {
3466       e = vat_json_array_add (&root);
3467       fwd = &mp->entries[i];
3468
3469       vat_json_init_object (e);
3470       vat_json_object_add_int (e, "fwd_entry_index", fwd->fwd_entry_index);
3471       vat_json_object_add_int (e, "dp_table", fwd->dp_table);
3472       vat_json_object_add_int (e, "vni", fwd->vni);
3473       vat_json_object_add_int (e, "action", fwd->action);
3474
3475       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->leid,
3476                   fwd->leid_prefix_len);
3477       vec_add1 (s, 0);
3478       vat_json_object_add_string_copy (e, "leid", s);
3479       vec_free (s);
3480
3481       s = format (0, "%U", format_lisp_flat_eid, fwd->eid_type, fwd->reid,
3482                   fwd->reid_prefix_len);
3483       vec_add1 (s, 0);
3484       vat_json_object_add_string_copy (e, "reid", s);
3485       vec_free (s);
3486     }
3487
3488   vat_json_print (vam->ofp, &root);
3489   vat_json_free (&root);
3490
3491 end:
3492   vam->retval = retval;
3493   vam->result_ready = 1;
3494 }
3495
3496 static void
3497   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler
3498   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3499 {
3500   vat_main_t *vam = &vat_main;
3501   u32 i, n;
3502   int retval = clib_net_to_host_u32 (mp->retval);
3503   vl_api_gpe_native_fwd_rpath_t *r;
3504
3505   if (retval)
3506     goto end;
3507
3508   n = clib_net_to_host_u32 (mp->count);
3509
3510   for (i = 0; i < n; i++)
3511     {
3512       r = &mp->entries[i];
3513       print (vam->ofp, "fib_index: %d sw_if_index %d nh %U",
3514              clib_net_to_host_u32 (r->fib_index),
3515              clib_net_to_host_u32 (r->nh_sw_if_index),
3516              r->is_ip4 ? format_ip4_address : format_ip6_address, r->nh_addr);
3517     }
3518
3519 end:
3520   vam->retval = retval;
3521   vam->result_ready = 1;
3522 }
3523
3524 static void
3525   vl_api_gpe_native_fwd_rpaths_get_reply_t_handler_json
3526   (vl_api_gpe_native_fwd_rpaths_get_reply_t * mp)
3527 {
3528   vat_main_t *vam = &vat_main;
3529   vat_json_node_t root, *e;
3530   u32 i, n;
3531   int retval = clib_net_to_host_u32 (mp->retval);
3532   vl_api_gpe_native_fwd_rpath_t *r;
3533   u8 *s;
3534
3535   if (retval)
3536     goto end;
3537
3538   n = clib_net_to_host_u32 (mp->count);
3539   vat_json_init_array (&root);
3540
3541   for (i = 0; i < n; i++)
3542     {
3543       e = vat_json_array_add (&root);
3544       vat_json_init_object (e);
3545       r = &mp->entries[i];
3546       s =
3547         format (0, "%U", r->is_ip4 ? format_ip4_address : format_ip6_address,
3548                 r->nh_addr);
3549       vec_add1 (s, 0);
3550       vat_json_object_add_string_copy (e, "ip4", s);
3551       vec_free (s);
3552
3553       vat_json_object_add_uint (e, "fib_index",
3554                                 clib_net_to_host_u32 (r->fib_index));
3555       vat_json_object_add_uint (e, "nh_sw_if_index",
3556                                 clib_net_to_host_u32 (r->nh_sw_if_index));
3557     }
3558
3559   vat_json_print (vam->ofp, &root);
3560   vat_json_free (&root);
3561
3562 end:
3563   vam->retval = retval;
3564   vam->result_ready = 1;
3565 }
3566
3567 static void
3568   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler
3569   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3570 {
3571   vat_main_t *vam = &vat_main;
3572   u32 i, n;
3573   int retval = clib_net_to_host_u32 (mp->retval);
3574
3575   if (retval)
3576     goto end;
3577
3578   n = clib_net_to_host_u32 (mp->count);
3579
3580   for (i = 0; i < n; i++)
3581     print (vam->ofp, "%d", clib_net_to_host_u32 (mp->vnis[i]));
3582
3583 end:
3584   vam->retval = retval;
3585   vam->result_ready = 1;
3586 }
3587
3588 static void
3589   vl_api_gpe_fwd_entry_vnis_get_reply_t_handler_json
3590   (vl_api_gpe_fwd_entry_vnis_get_reply_t * mp)
3591 {
3592   vat_main_t *vam = &vat_main;
3593   vat_json_node_t root;
3594   u32 i, n;
3595   int retval = clib_net_to_host_u32 (mp->retval);
3596
3597   if (retval)
3598     goto end;
3599
3600   n = clib_net_to_host_u32 (mp->count);
3601   vat_json_init_array (&root);
3602
3603   for (i = 0; i < n; i++)
3604     vat_json_array_add_uint (&root, clib_net_to_host_u32 (mp->vnis[i]));
3605
3606   vat_json_print (vam->ofp, &root);
3607   vat_json_free (&root);
3608
3609 end:
3610   vam->retval = retval;
3611   vam->result_ready = 1;
3612 }
3613
3614 static void
3615   vl_api_one_ndp_entries_get_reply_t_handler
3616   (vl_api_one_ndp_entries_get_reply_t * mp)
3617 {
3618   vat_main_t *vam = &vat_main;
3619   u32 i, n;
3620   int retval = clib_net_to_host_u32 (mp->retval);
3621
3622   if (retval)
3623     goto end;
3624
3625   n = clib_net_to_host_u32 (mp->count);
3626
3627   for (i = 0; i < n; i++)
3628     print (vam->ofp, "%U -> %U", format_ip6_address, &mp->entries[i].ip6,
3629            format_ethernet_address, mp->entries[i].mac);
3630
3631 end:
3632   vam->retval = retval;
3633   vam->result_ready = 1;
3634 }
3635
3636 static void
3637   vl_api_one_ndp_entries_get_reply_t_handler_json
3638   (vl_api_one_ndp_entries_get_reply_t * mp)
3639 {
3640   u8 *s = 0;
3641   vat_main_t *vam = &vat_main;
3642   vat_json_node_t *e = 0, root;
3643   u32 i, n;
3644   int retval = clib_net_to_host_u32 (mp->retval);
3645   vl_api_one_ndp_entry_t *arp_entry;
3646
3647   if (retval)
3648     goto end;
3649
3650   n = clib_net_to_host_u32 (mp->count);
3651   vat_json_init_array (&root);
3652
3653   for (i = 0; i < n; i++)
3654     {
3655       e = vat_json_array_add (&root);
3656       arp_entry = &mp->entries[i];
3657
3658       vat_json_init_object (e);
3659       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
3660       vec_add1 (s, 0);
3661
3662       vat_json_object_add_string_copy (e, "mac", s);
3663       vec_free (s);
3664
3665       s = format (0, "%U", format_ip6_address, &arp_entry->ip6);
3666       vec_add1 (s, 0);
3667       vat_json_object_add_string_copy (e, "ip6", s);
3668       vec_free (s);
3669     }
3670
3671   vat_json_print (vam->ofp, &root);
3672   vat_json_free (&root);
3673
3674 end:
3675   vam->retval = retval;
3676   vam->result_ready = 1;
3677 }
3678
3679 static void
3680   vl_api_one_l2_arp_entries_get_reply_t_handler
3681   (vl_api_one_l2_arp_entries_get_reply_t * mp)
3682 {
3683   vat_main_t *vam = &vat_main;
3684   u32 i, n;
3685   int retval = clib_net_to_host_u32 (mp->retval);
3686
3687   if (retval)
3688     goto end;
3689
3690   n = clib_net_to_host_u32 (mp->count);
3691
3692   for (i = 0; i < n; i++)
3693     print (vam->ofp, "%U -> %U", format_ip4_address, &mp->entries[i].ip4,
3694            format_ethernet_address, mp->entries[i].mac);
3695
3696 end:
3697   vam->retval = retval;
3698   vam->result_ready = 1;
3699 }
3700
3701 static void
3702   vl_api_one_l2_arp_entries_get_reply_t_handler_json
3703   (vl_api_one_l2_arp_entries_get_reply_t * mp)
3704 {
3705   u8 *s = 0;
3706   vat_main_t *vam = &vat_main;
3707   vat_json_node_t *e = 0, root;
3708   u32 i, n;
3709   int retval = clib_net_to_host_u32 (mp->retval);
3710   vl_api_one_l2_arp_entry_t *arp_entry;
3711
3712   if (retval)
3713     goto end;
3714
3715   n = clib_net_to_host_u32 (mp->count);
3716   vat_json_init_array (&root);
3717
3718   for (i = 0; i < n; i++)
3719     {
3720       e = vat_json_array_add (&root);
3721       arp_entry = &mp->entries[i];
3722
3723       vat_json_init_object (e);
3724       s = format (0, "%U", format_ethernet_address, arp_entry->mac);
3725       vec_add1 (s, 0);
3726
3727       vat_json_object_add_string_copy (e, "mac", s);
3728       vec_free (s);
3729
3730       s = format (0, "%U", format_ip4_address, &arp_entry->ip4);
3731       vec_add1 (s, 0);
3732       vat_json_object_add_string_copy (e, "ip4", s);
3733       vec_free (s);
3734     }
3735
3736   vat_json_print (vam->ofp, &root);
3737   vat_json_free (&root);
3738
3739 end:
3740   vam->retval = retval;
3741   vam->result_ready = 1;
3742 }
3743
3744 static void
3745 vl_api_one_ndp_bd_get_reply_t_handler (vl_api_one_ndp_bd_get_reply_t * mp)
3746 {
3747   vat_main_t *vam = &vat_main;
3748   u32 i, n;
3749   int retval = clib_net_to_host_u32 (mp->retval);
3750
3751   if (retval)
3752     goto end;
3753
3754   n = clib_net_to_host_u32 (mp->count);
3755
3756   for (i = 0; i < n; i++)
3757     {
3758       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
3759     }
3760
3761 end:
3762   vam->retval = retval;
3763   vam->result_ready = 1;
3764 }
3765
3766 static void
3767   vl_api_one_ndp_bd_get_reply_t_handler_json
3768   (vl_api_one_ndp_bd_get_reply_t * mp)
3769 {
3770   vat_main_t *vam = &vat_main;
3771   vat_json_node_t root;
3772   u32 i, n;
3773   int retval = clib_net_to_host_u32 (mp->retval);
3774
3775   if (retval)
3776     goto end;
3777
3778   n = clib_net_to_host_u32 (mp->count);
3779   vat_json_init_array (&root);
3780
3781   for (i = 0; i < n; i++)
3782     {
3783       vat_json_array_add_uint (&root,
3784                                clib_net_to_host_u32 (mp->bridge_domains[i]));
3785     }
3786
3787   vat_json_print (vam->ofp, &root);
3788   vat_json_free (&root);
3789
3790 end:
3791   vam->retval = retval;
3792   vam->result_ready = 1;
3793 }
3794
3795 static void
3796   vl_api_one_l2_arp_bd_get_reply_t_handler
3797   (vl_api_one_l2_arp_bd_get_reply_t * mp)
3798 {
3799   vat_main_t *vam = &vat_main;
3800   u32 i, n;
3801   int retval = clib_net_to_host_u32 (mp->retval);
3802
3803   if (retval)
3804     goto end;
3805
3806   n = clib_net_to_host_u32 (mp->count);
3807
3808   for (i = 0; i < n; i++)
3809     {
3810       print (vam->ofp, "%d", clib_net_to_host_u32 (mp->bridge_domains[i]));
3811     }
3812
3813 end:
3814   vam->retval = retval;
3815   vam->result_ready = 1;
3816 }
3817
3818 static void
3819   vl_api_one_l2_arp_bd_get_reply_t_handler_json
3820   (vl_api_one_l2_arp_bd_get_reply_t * mp)
3821 {
3822   vat_main_t *vam = &vat_main;
3823   vat_json_node_t root;
3824   u32 i, n;
3825   int retval = clib_net_to_host_u32 (mp->retval);
3826
3827   if (retval)
3828     goto end;
3829
3830   n = clib_net_to_host_u32 (mp->count);
3831   vat_json_init_array (&root);
3832
3833   for (i = 0; i < n; i++)
3834     {
3835       vat_json_array_add_uint (&root,
3836                                clib_net_to_host_u32 (mp->bridge_domains[i]));
3837     }
3838
3839   vat_json_print (vam->ofp, &root);
3840   vat_json_free (&root);
3841
3842 end:
3843   vam->retval = retval;
3844   vam->result_ready = 1;
3845 }
3846
3847 static void
3848   vl_api_one_adjacencies_get_reply_t_handler
3849   (vl_api_one_adjacencies_get_reply_t * mp)
3850 {
3851   vat_main_t *vam = &vat_main;
3852   u32 i, n;
3853   int retval = clib_net_to_host_u32 (mp->retval);
3854   vl_api_one_adjacency_t *a;
3855
3856   if (retval)
3857     goto end;
3858
3859   n = clib_net_to_host_u32 (mp->count);
3860
3861   for (i = 0; i < n; i++)
3862     {
3863       a = &mp->adjacencies[i];
3864       print (vam->ofp, "%U %40U",
3865              format_lisp_flat_eid, a->eid_type, a->leid, a->leid_prefix_len,
3866              format_lisp_flat_eid, a->eid_type, a->reid, a->reid_prefix_len);
3867     }
3868
3869 end:
3870   vam->retval = retval;
3871   vam->result_ready = 1;
3872 }
3873
3874 static void
3875   vl_api_one_adjacencies_get_reply_t_handler_json
3876   (vl_api_one_adjacencies_get_reply_t * mp)
3877 {
3878   u8 *s = 0;
3879   vat_main_t *vam = &vat_main;
3880   vat_json_node_t *e = 0, root;
3881   u32 i, n;
3882   int retval = clib_net_to_host_u32 (mp->retval);
3883   vl_api_one_adjacency_t *a;
3884
3885   if (retval)
3886     goto end;
3887
3888   n = clib_net_to_host_u32 (mp->count);
3889   vat_json_init_array (&root);
3890
3891   for (i = 0; i < n; i++)
3892     {
3893       e = vat_json_array_add (&root);
3894       a = &mp->adjacencies[i];
3895
3896       vat_json_init_object (e);
3897       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->leid,
3898                   a->leid_prefix_len);
3899       vec_add1 (s, 0);
3900       vat_json_object_add_string_copy (e, "leid", s);
3901       vec_free (s);
3902
3903       s = format (0, "%U", format_lisp_flat_eid, a->eid_type, a->reid,
3904                   a->reid_prefix_len);
3905       vec_add1 (s, 0);
3906       vat_json_object_add_string_copy (e, "reid", s);
3907       vec_free (s);
3908     }
3909
3910   vat_json_print (vam->ofp, &root);
3911   vat_json_free (&root);
3912
3913 end:
3914   vam->retval = retval;
3915   vam->result_ready = 1;
3916 }
3917
3918 static void
3919 vl_api_one_map_server_details_t_handler (vl_api_one_map_server_details_t * mp)
3920 {
3921   vat_main_t *vam = &vat_main;
3922
3923   print (vam->ofp, "%=20U",
3924          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
3925          mp->ip_address);
3926 }
3927
3928 static void
3929   vl_api_one_map_server_details_t_handler_json
3930   (vl_api_one_map_server_details_t * mp)
3931 {
3932   vat_main_t *vam = &vat_main;
3933   vat_json_node_t *node = NULL;
3934   struct in6_addr ip6;
3935   struct in_addr ip4;
3936
3937   if (VAT_JSON_ARRAY != vam->json_tree.type)
3938     {
3939       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3940       vat_json_init_array (&vam->json_tree);
3941     }
3942   node = vat_json_array_add (&vam->json_tree);
3943
3944   vat_json_init_object (node);
3945   if (mp->is_ipv6)
3946     {
3947       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
3948       vat_json_object_add_ip6 (node, "map-server", ip6);
3949     }
3950   else
3951     {
3952       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
3953       vat_json_object_add_ip4 (node, "map-server", ip4);
3954     }
3955 }
3956
3957 static void
3958 vl_api_one_map_resolver_details_t_handler (vl_api_one_map_resolver_details_t
3959                                            * mp)
3960 {
3961   vat_main_t *vam = &vat_main;
3962
3963   print (vam->ofp, "%=20U",
3964          mp->is_ipv6 ? format_ip6_address : format_ip4_address,
3965          mp->ip_address);
3966 }
3967
3968 static void
3969   vl_api_one_map_resolver_details_t_handler_json
3970   (vl_api_one_map_resolver_details_t * mp)
3971 {
3972   vat_main_t *vam = &vat_main;
3973   vat_json_node_t *node = NULL;
3974   struct in6_addr ip6;
3975   struct in_addr ip4;
3976
3977   if (VAT_JSON_ARRAY != vam->json_tree.type)
3978     {
3979       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
3980       vat_json_init_array (&vam->json_tree);
3981     }
3982   node = vat_json_array_add (&vam->json_tree);
3983
3984   vat_json_init_object (node);
3985   if (mp->is_ipv6)
3986     {
3987       clib_memcpy (&ip6, mp->ip_address, sizeof (ip6));
3988       vat_json_object_add_ip6 (node, "map resolver", ip6);
3989     }
3990   else
3991     {
3992       clib_memcpy (&ip4, mp->ip_address, sizeof (ip4));
3993       vat_json_object_add_ip4 (node, "map resolver", ip4);
3994     }
3995 }
3996
3997 static void
3998 vl_api_show_one_status_reply_t_handler (vl_api_show_one_status_reply_t * mp)
3999 {
4000   vat_main_t *vam = &vat_main;
4001   i32 retval = ntohl (mp->retval);
4002
4003   if (0 <= retval)
4004     {
4005       print (vam->ofp, "feature: %s\ngpe: %s",
4006              mp->feature_status ? "enabled" : "disabled",
4007              mp->gpe_status ? "enabled" : "disabled");
4008     }
4009
4010   vam->retval = retval;
4011   vam->result_ready = 1;
4012 }
4013
4014 static void
4015   vl_api_show_one_status_reply_t_handler_json
4016   (vl_api_show_one_status_reply_t * mp)
4017 {
4018   vat_main_t *vam = &vat_main;
4019   vat_json_node_t node;
4020   u8 *gpe_status = NULL;
4021   u8 *feature_status = NULL;
4022
4023   gpe_status = format (0, "%s", mp->gpe_status ? "enabled" : "disabled");
4024   feature_status = format (0, "%s",
4025                            mp->feature_status ? "enabled" : "disabled");
4026   vec_add1 (gpe_status, 0);
4027   vec_add1 (feature_status, 0);
4028
4029   vat_json_init_object (&node);
4030   vat_json_object_add_string_copy (&node, "gpe_status", gpe_status);
4031   vat_json_object_add_string_copy (&node, "feature_status", feature_status);
4032
4033   vec_free (gpe_status);
4034   vec_free (feature_status);
4035
4036   vat_json_print (vam->ofp, &node);
4037   vat_json_free (&node);
4038
4039   vam->retval = ntohl (mp->retval);
4040   vam->result_ready = 1;
4041 }
4042
4043 static void
4044   vl_api_one_get_map_request_itr_rlocs_reply_t_handler
4045   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
4046 {
4047   vat_main_t *vam = &vat_main;
4048   i32 retval = ntohl (mp->retval);
4049
4050   if (retval >= 0)
4051     {
4052       print (vam->ofp, "%=20s", mp->locator_set_name);
4053     }
4054
4055   vam->retval = retval;
4056   vam->result_ready = 1;
4057 }
4058
4059 static void
4060   vl_api_one_get_map_request_itr_rlocs_reply_t_handler_json
4061   (vl_api_one_get_map_request_itr_rlocs_reply_t * mp)
4062 {
4063   vat_main_t *vam = &vat_main;
4064   vat_json_node_t *node = NULL;
4065
4066   if (VAT_JSON_ARRAY != vam->json_tree.type)
4067     {
4068       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4069       vat_json_init_array (&vam->json_tree);
4070     }
4071   node = vat_json_array_add (&vam->json_tree);
4072
4073   vat_json_init_object (node);
4074   vat_json_object_add_string_copy (node, "itr-rlocs", mp->locator_set_name);
4075
4076   vat_json_print (vam->ofp, node);
4077   vat_json_free (node);
4078
4079   vam->retval = ntohl (mp->retval);
4080   vam->result_ready = 1;
4081 }
4082
4083 static u8 *
4084 format_lisp_map_request_mode (u8 * s, va_list * args)
4085 {
4086   u32 mode = va_arg (*args, u32);
4087
4088   switch (mode)
4089     {
4090     case 0:
4091       return format (0, "dst-only");
4092     case 1:
4093       return format (0, "src-dst");
4094     }
4095   return 0;
4096 }
4097
4098 static void
4099   vl_api_show_one_map_request_mode_reply_t_handler
4100   (vl_api_show_one_map_request_mode_reply_t * mp)
4101 {
4102   vat_main_t *vam = &vat_main;
4103   i32 retval = ntohl (mp->retval);
4104
4105   if (0 <= retval)
4106     {
4107       u32 mode = mp->mode;
4108       print (vam->ofp, "map_request_mode: %U",
4109              format_lisp_map_request_mode, mode);
4110     }
4111
4112   vam->retval = retval;
4113   vam->result_ready = 1;
4114 }
4115
4116 static void
4117   vl_api_show_one_map_request_mode_reply_t_handler_json
4118   (vl_api_show_one_map_request_mode_reply_t * mp)
4119 {
4120   vat_main_t *vam = &vat_main;
4121   vat_json_node_t node;
4122   u8 *s = 0;
4123   u32 mode;
4124
4125   mode = mp->mode;
4126   s = format (0, "%U", format_lisp_map_request_mode, mode);
4127   vec_add1 (s, 0);
4128
4129   vat_json_init_object (&node);
4130   vat_json_object_add_string_copy (&node, "map_request_mode", s);
4131   vat_json_print (vam->ofp, &node);
4132   vat_json_free (&node);
4133
4134   vec_free (s);
4135   vam->retval = ntohl (mp->retval);
4136   vam->result_ready = 1;
4137 }
4138
4139 static void
4140   vl_api_one_show_xtr_mode_reply_t_handler
4141   (vl_api_one_show_xtr_mode_reply_t * mp)
4142 {
4143   vat_main_t *vam = &vat_main;
4144   i32 retval = ntohl (mp->retval);
4145
4146   if (0 <= retval)
4147     {
4148       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4149     }
4150
4151   vam->retval = retval;
4152   vam->result_ready = 1;
4153 }
4154
4155 static void
4156   vl_api_one_show_xtr_mode_reply_t_handler_json
4157   (vl_api_one_show_xtr_mode_reply_t * mp)
4158 {
4159   vat_main_t *vam = &vat_main;
4160   vat_json_node_t node;
4161   u8 *status = 0;
4162
4163   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4164   vec_add1 (status, 0);
4165
4166   vat_json_init_object (&node);
4167   vat_json_object_add_string_copy (&node, "status", status);
4168
4169   vec_free (status);
4170
4171   vat_json_print (vam->ofp, &node);
4172   vat_json_free (&node);
4173
4174   vam->retval = ntohl (mp->retval);
4175   vam->result_ready = 1;
4176 }
4177
4178 static void
4179   vl_api_one_show_pitr_mode_reply_t_handler
4180   (vl_api_one_show_pitr_mode_reply_t * mp)
4181 {
4182   vat_main_t *vam = &vat_main;
4183   i32 retval = ntohl (mp->retval);
4184
4185   if (0 <= retval)
4186     {
4187       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4188     }
4189
4190   vam->retval = retval;
4191   vam->result_ready = 1;
4192 }
4193
4194 static void
4195   vl_api_one_show_pitr_mode_reply_t_handler_json
4196   (vl_api_one_show_pitr_mode_reply_t * mp)
4197 {
4198   vat_main_t *vam = &vat_main;
4199   vat_json_node_t node;
4200   u8 *status = 0;
4201
4202   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4203   vec_add1 (status, 0);
4204
4205   vat_json_init_object (&node);
4206   vat_json_object_add_string_copy (&node, "status", status);
4207
4208   vec_free (status);
4209
4210   vat_json_print (vam->ofp, &node);
4211   vat_json_free (&node);
4212
4213   vam->retval = ntohl (mp->retval);
4214   vam->result_ready = 1;
4215 }
4216
4217 static void
4218   vl_api_one_show_petr_mode_reply_t_handler
4219   (vl_api_one_show_petr_mode_reply_t * mp)
4220 {
4221   vat_main_t *vam = &vat_main;
4222   i32 retval = ntohl (mp->retval);
4223
4224   if (0 <= retval)
4225     {
4226       print (vam->ofp, "%s\n", mp->is_en ? "enabled" : "disabled");
4227     }
4228
4229   vam->retval = retval;
4230   vam->result_ready = 1;
4231 }
4232
4233 static void
4234   vl_api_one_show_petr_mode_reply_t_handler_json
4235   (vl_api_one_show_petr_mode_reply_t * mp)
4236 {
4237   vat_main_t *vam = &vat_main;
4238   vat_json_node_t node;
4239   u8 *status = 0;
4240
4241   status = format (0, "%s", mp->is_en ? "enabled" : "disabled");
4242   vec_add1 (status, 0);
4243
4244   vat_json_init_object (&node);
4245   vat_json_object_add_string_copy (&node, "status", status);
4246
4247   vec_free (status);
4248
4249   vat_json_print (vam->ofp, &node);
4250   vat_json_free (&node);
4251
4252   vam->retval = ntohl (mp->retval);
4253   vam->result_ready = 1;
4254 }
4255
4256 static void
4257   vl_api_show_one_use_petr_reply_t_handler
4258   (vl_api_show_one_use_petr_reply_t * mp)
4259 {
4260   vat_main_t *vam = &vat_main;
4261   i32 retval = ntohl (mp->retval);
4262
4263   if (0 <= retval)
4264     {
4265       print (vam->ofp, "%s\n", mp->status ? "enabled" : "disabled");
4266       if (mp->status)
4267         {
4268           print (vam->ofp, "Proxy-ETR address; %U",
4269                  mp->is_ip4 ? format_ip4_address : format_ip6_address,
4270                  mp->address);
4271         }
4272     }
4273
4274   vam->retval = retval;
4275   vam->result_ready = 1;
4276 }
4277
4278 static void
4279   vl_api_show_one_use_petr_reply_t_handler_json
4280   (vl_api_show_one_use_petr_reply_t * mp)
4281 {
4282   vat_main_t *vam = &vat_main;
4283   vat_json_node_t node;
4284   u8 *status = 0;
4285   struct in_addr ip4;
4286   struct in6_addr ip6;
4287
4288   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4289   vec_add1 (status, 0);
4290
4291   vat_json_init_object (&node);
4292   vat_json_object_add_string_copy (&node, "status", status);
4293   if (mp->status)
4294     {
4295       if (mp->is_ip4)
4296         {
4297           clib_memcpy (&ip6, mp->address, sizeof (ip6));
4298           vat_json_object_add_ip6 (&node, "address", ip6);
4299         }
4300       else
4301         {
4302           clib_memcpy (&ip4, mp->address, sizeof (ip4));
4303           vat_json_object_add_ip4 (&node, "address", ip4);
4304         }
4305     }
4306
4307   vec_free (status);
4308
4309   vat_json_print (vam->ofp, &node);
4310   vat_json_free (&node);
4311
4312   vam->retval = ntohl (mp->retval);
4313   vam->result_ready = 1;
4314 }
4315
4316 static void
4317   vl_api_show_one_nsh_mapping_reply_t_handler
4318   (vl_api_show_one_nsh_mapping_reply_t * mp)
4319 {
4320   vat_main_t *vam = &vat_main;
4321   i32 retval = ntohl (mp->retval);
4322
4323   if (0 <= retval)
4324     {
4325       print (vam->ofp, "%-20s%-16s",
4326              mp->is_set ? "set" : "not-set",
4327              mp->is_set ? (char *) mp->locator_set_name : "");
4328     }
4329
4330   vam->retval = retval;
4331   vam->result_ready = 1;
4332 }
4333
4334 static void
4335   vl_api_show_one_nsh_mapping_reply_t_handler_json
4336   (vl_api_show_one_nsh_mapping_reply_t * mp)
4337 {
4338   vat_main_t *vam = &vat_main;
4339   vat_json_node_t node;
4340   u8 *status = 0;
4341
4342   status = format (0, "%s", mp->is_set ? "yes" : "no");
4343   vec_add1 (status, 0);
4344
4345   vat_json_init_object (&node);
4346   vat_json_object_add_string_copy (&node, "is_set", status);
4347   if (mp->is_set)
4348     {
4349       vat_json_object_add_string_copy (&node, "locator_set",
4350                                        mp->locator_set_name);
4351     }
4352
4353   vec_free (status);
4354
4355   vat_json_print (vam->ofp, &node);
4356   vat_json_free (&node);
4357
4358   vam->retval = ntohl (mp->retval);
4359   vam->result_ready = 1;
4360 }
4361
4362 static void
4363   vl_api_show_one_map_register_ttl_reply_t_handler
4364   (vl_api_show_one_map_register_ttl_reply_t * mp)
4365 {
4366   vat_main_t *vam = &vat_main;
4367   i32 retval = ntohl (mp->retval);
4368
4369   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4370
4371   if (0 <= retval)
4372     {
4373       print (vam->ofp, "ttl: %u", mp->ttl);
4374     }
4375
4376   vam->retval = retval;
4377   vam->result_ready = 1;
4378 }
4379
4380 static void
4381   vl_api_show_one_map_register_ttl_reply_t_handler_json
4382   (vl_api_show_one_map_register_ttl_reply_t * mp)
4383 {
4384   vat_main_t *vam = &vat_main;
4385   vat_json_node_t node;
4386
4387   vl_api_show_one_map_register_ttl_reply_t_endian (mp);
4388   vat_json_init_object (&node);
4389   vat_json_object_add_uint (&node, "ttl", mp->ttl);
4390
4391   vat_json_print (vam->ofp, &node);
4392   vat_json_free (&node);
4393
4394   vam->retval = ntohl (mp->retval);
4395   vam->result_ready = 1;
4396 }
4397
4398 static void
4399 vl_api_show_one_pitr_reply_t_handler (vl_api_show_one_pitr_reply_t * mp)
4400 {
4401   vat_main_t *vam = &vat_main;
4402   i32 retval = ntohl (mp->retval);
4403
4404   if (0 <= retval)
4405     {
4406       print (vam->ofp, "%-20s%-16s",
4407              mp->status ? "enabled" : "disabled",
4408              mp->status ? (char *) mp->locator_set_name : "");
4409     }
4410
4411   vam->retval = retval;
4412   vam->result_ready = 1;
4413 }
4414
4415 static void
4416 vl_api_show_one_pitr_reply_t_handler_json (vl_api_show_one_pitr_reply_t * mp)
4417 {
4418   vat_main_t *vam = &vat_main;
4419   vat_json_node_t node;
4420   u8 *status = 0;
4421
4422   status = format (0, "%s", mp->status ? "enabled" : "disabled");
4423   vec_add1 (status, 0);
4424
4425   vat_json_init_object (&node);
4426   vat_json_object_add_string_copy (&node, "status", status);
4427   if (mp->status)
4428     {
4429       vat_json_object_add_string_copy (&node, "locator_set",
4430                                        mp->locator_set_name);
4431     }
4432
4433   vec_free (status);
4434
4435   vat_json_print (vam->ofp, &node);
4436   vat_json_free (&node);
4437
4438   vam->retval = ntohl (mp->retval);
4439   vam->result_ready = 1;
4440 }
4441
4442 static u8 *
4443 format_policer_type (u8 * s, va_list * va)
4444 {
4445   u32 i = va_arg (*va, u32);
4446
4447   if (i == SSE2_QOS_POLICER_TYPE_1R2C)
4448     s = format (s, "1r2c");
4449   else if (i == SSE2_QOS_POLICER_TYPE_1R3C_RFC_2697)
4450     s = format (s, "1r3c");
4451   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_2698)
4452     s = format (s, "2r3c-2698");
4453   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_4115)
4454     s = format (s, "2r3c-4115");
4455   else if (i == SSE2_QOS_POLICER_TYPE_2R3C_RFC_MEF5CF1)
4456     s = format (s, "2r3c-mef5cf1");
4457   else
4458     s = format (s, "ILLEGAL");
4459   return s;
4460 }
4461
4462 static u8 *
4463 format_policer_rate_type (u8 * s, va_list * va)
4464 {
4465   u32 i = va_arg (*va, u32);
4466
4467   if (i == SSE2_QOS_RATE_KBPS)
4468     s = format (s, "kbps");
4469   else if (i == SSE2_QOS_RATE_PPS)
4470     s = format (s, "pps");
4471   else
4472     s = format (s, "ILLEGAL");
4473   return s;
4474 }
4475
4476 static u8 *
4477 format_policer_round_type (u8 * s, va_list * va)
4478 {
4479   u32 i = va_arg (*va, u32);
4480
4481   if (i == SSE2_QOS_ROUND_TO_CLOSEST)
4482     s = format (s, "closest");
4483   else if (i == SSE2_QOS_ROUND_TO_UP)
4484     s = format (s, "up");
4485   else if (i == SSE2_QOS_ROUND_TO_DOWN)
4486     s = format (s, "down");
4487   else
4488     s = format (s, "ILLEGAL");
4489   return s;
4490 }
4491
4492 static u8 *
4493 format_policer_action_type (u8 * s, va_list * va)
4494 {
4495   u32 i = va_arg (*va, u32);
4496
4497   if (i == SSE2_QOS_ACTION_DROP)
4498     s = format (s, "drop");
4499   else if (i == SSE2_QOS_ACTION_TRANSMIT)
4500     s = format (s, "transmit");
4501   else if (i == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4502     s = format (s, "mark-and-transmit");
4503   else
4504     s = format (s, "ILLEGAL");
4505   return s;
4506 }
4507
4508 static u8 *
4509 format_dscp (u8 * s, va_list * va)
4510 {
4511   u32 i = va_arg (*va, u32);
4512   char *t = 0;
4513
4514   switch (i)
4515     {
4516 #define _(v,f,str) case VNET_DSCP_##f: t = str; break;
4517       foreach_vnet_dscp
4518 #undef _
4519     default:
4520       return format (s, "ILLEGAL");
4521     }
4522   s = format (s, "%s", t);
4523   return s;
4524 }
4525
4526 static void
4527 vl_api_policer_details_t_handler (vl_api_policer_details_t * mp)
4528 {
4529   vat_main_t *vam = &vat_main;
4530   u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str;
4531
4532   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4533     conform_dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
4534   else
4535     conform_dscp_str = format (0, "");
4536
4537   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4538     exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
4539   else
4540     exceed_dscp_str = format (0, "");
4541
4542   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4543     violate_dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
4544   else
4545     violate_dscp_str = format (0, "");
4546
4547   print (vam->ofp, "Name \"%s\", type %U, cir %u, eir %u, cb %u, eb %u, "
4548          "rate type %U, round type %U, %s rate, %s color-aware, "
4549          "cir %u tok/period, pir %u tok/period, scale %u, cur lim %u, "
4550          "cur bkt %u, ext lim %u, ext bkt %u, last update %llu"
4551          "conform action %U%s, exceed action %U%s, violate action %U%s",
4552          mp->name,
4553          format_policer_type, mp->type,
4554          ntohl (mp->cir),
4555          ntohl (mp->eir),
4556          clib_net_to_host_u64 (mp->cb),
4557          clib_net_to_host_u64 (mp->eb),
4558          format_policer_rate_type, mp->rate_type,
4559          format_policer_round_type, mp->round_type,
4560          mp->single_rate ? "single" : "dual",
4561          mp->color_aware ? "is" : "not",
4562          ntohl (mp->cir_tokens_per_period),
4563          ntohl (mp->pir_tokens_per_period),
4564          ntohl (mp->scale),
4565          ntohl (mp->current_limit),
4566          ntohl (mp->current_bucket),
4567          ntohl (mp->extended_limit),
4568          ntohl (mp->extended_bucket),
4569          clib_net_to_host_u64 (mp->last_update_time),
4570          format_policer_action_type, mp->conform_action_type,
4571          conform_dscp_str,
4572          format_policer_action_type, mp->exceed_action_type,
4573          exceed_dscp_str,
4574          format_policer_action_type, mp->violate_action_type,
4575          violate_dscp_str);
4576
4577   vec_free (conform_dscp_str);
4578   vec_free (exceed_dscp_str);
4579   vec_free (violate_dscp_str);
4580 }
4581
4582 static void vl_api_policer_details_t_handler_json
4583   (vl_api_policer_details_t * mp)
4584 {
4585   vat_main_t *vam = &vat_main;
4586   vat_json_node_t *node;
4587   u8 *rate_type_str, *round_type_str, *type_str;
4588   u8 *conform_action_str, *exceed_action_str, *violate_action_str;
4589
4590   rate_type_str = format (0, "%U", format_policer_rate_type, mp->rate_type);
4591   round_type_str =
4592     format (0, "%U", format_policer_round_type, mp->round_type);
4593   type_str = format (0, "%U", format_policer_type, mp->type);
4594   conform_action_str = format (0, "%U", format_policer_action_type,
4595                                mp->conform_action_type);
4596   exceed_action_str = format (0, "%U", format_policer_action_type,
4597                               mp->exceed_action_type);
4598   violate_action_str = format (0, "%U", format_policer_action_type,
4599                                mp->violate_action_type);
4600
4601   if (VAT_JSON_ARRAY != vam->json_tree.type)
4602     {
4603       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4604       vat_json_init_array (&vam->json_tree);
4605     }
4606   node = vat_json_array_add (&vam->json_tree);
4607
4608   vat_json_init_object (node);
4609   vat_json_object_add_string_copy (node, "name", mp->name);
4610   vat_json_object_add_uint (node, "cir", ntohl (mp->cir));
4611   vat_json_object_add_uint (node, "eir", ntohl (mp->eir));
4612   vat_json_object_add_uint (node, "cb", clib_net_to_host_u64 (mp->cb));
4613   vat_json_object_add_uint (node, "eb", clib_net_to_host_u64 (mp->eb));
4614   vat_json_object_add_string_copy (node, "rate_type", rate_type_str);
4615   vat_json_object_add_string_copy (node, "round_type", round_type_str);
4616   vat_json_object_add_string_copy (node, "type", type_str);
4617   vat_json_object_add_uint (node, "single_rate", mp->single_rate);
4618   vat_json_object_add_uint (node, "color_aware", mp->color_aware);
4619   vat_json_object_add_uint (node, "scale", ntohl (mp->scale));
4620   vat_json_object_add_uint (node, "cir_tokens_per_period",
4621                             ntohl (mp->cir_tokens_per_period));
4622   vat_json_object_add_uint (node, "eir_tokens_per_period",
4623                             ntohl (mp->pir_tokens_per_period));
4624   vat_json_object_add_uint (node, "current_limit", ntohl (mp->current_limit));
4625   vat_json_object_add_uint (node, "current_bucket",
4626                             ntohl (mp->current_bucket));
4627   vat_json_object_add_uint (node, "extended_limit",
4628                             ntohl (mp->extended_limit));
4629   vat_json_object_add_uint (node, "extended_bucket",
4630                             ntohl (mp->extended_bucket));
4631   vat_json_object_add_uint (node, "last_update_time",
4632                             ntohl (mp->last_update_time));
4633   vat_json_object_add_string_copy (node, "conform_action",
4634                                    conform_action_str);
4635   if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4636     {
4637       u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_dscp);
4638       vat_json_object_add_string_copy (node, "conform_dscp", dscp_str);
4639       vec_free (dscp_str);
4640     }
4641   vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str);
4642   if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4643     {
4644       u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp);
4645       vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str);
4646       vec_free (dscp_str);
4647     }
4648   vat_json_object_add_string_copy (node, "violate_action",
4649                                    violate_action_str);
4650   if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT)
4651     {
4652       u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_dscp);
4653       vat_json_object_add_string_copy (node, "violate_dscp", dscp_str);
4654       vec_free (dscp_str);
4655     }
4656
4657   vec_free (rate_type_str);
4658   vec_free (round_type_str);
4659   vec_free (type_str);
4660   vec_free (conform_action_str);
4661   vec_free (exceed_action_str);
4662   vec_free (violate_action_str);
4663 }
4664
4665 static void
4666 vl_api_classify_table_ids_reply_t_handler (vl_api_classify_table_ids_reply_t *
4667                                            mp)
4668 {
4669   vat_main_t *vam = &vat_main;
4670   int i, count = ntohl (mp->count);
4671
4672   if (count > 0)
4673     print (vam->ofp, "classify table ids (%d) : ", count);
4674   for (i = 0; i < count; i++)
4675     {
4676       print (vam->ofp, "%d", ntohl (mp->ids[i]));
4677       print (vam->ofp, (i < count - 1) ? "," : "");
4678     }
4679   vam->retval = ntohl (mp->retval);
4680   vam->result_ready = 1;
4681 }
4682
4683 static void
4684   vl_api_classify_table_ids_reply_t_handler_json
4685   (vl_api_classify_table_ids_reply_t * mp)
4686 {
4687   vat_main_t *vam = &vat_main;
4688   int i, count = ntohl (mp->count);
4689
4690   if (count > 0)
4691     {
4692       vat_json_node_t node;
4693
4694       vat_json_init_object (&node);
4695       for (i = 0; i < count; i++)
4696         {
4697           vat_json_object_add_uint (&node, "table_id", ntohl (mp->ids[i]));
4698         }
4699       vat_json_print (vam->ofp, &node);
4700       vat_json_free (&node);
4701     }
4702   vam->retval = ntohl (mp->retval);
4703   vam->result_ready = 1;
4704 }
4705
4706 static void
4707   vl_api_classify_table_by_interface_reply_t_handler
4708   (vl_api_classify_table_by_interface_reply_t * mp)
4709 {
4710   vat_main_t *vam = &vat_main;
4711   u32 table_id;
4712
4713   table_id = ntohl (mp->l2_table_id);
4714   if (table_id != ~0)
4715     print (vam->ofp, "l2 table id : %d", table_id);
4716   else
4717     print (vam->ofp, "l2 table id : No input ACL tables configured");
4718   table_id = ntohl (mp->ip4_table_id);
4719   if (table_id != ~0)
4720     print (vam->ofp, "ip4 table id : %d", table_id);
4721   else
4722     print (vam->ofp, "ip4 table id : No input ACL tables configured");
4723   table_id = ntohl (mp->ip6_table_id);
4724   if (table_id != ~0)
4725     print (vam->ofp, "ip6 table id : %d", table_id);
4726   else
4727     print (vam->ofp, "ip6 table id : No input ACL tables configured");
4728   vam->retval = ntohl (mp->retval);
4729   vam->result_ready = 1;
4730 }
4731
4732 static void
4733   vl_api_classify_table_by_interface_reply_t_handler_json
4734   (vl_api_classify_table_by_interface_reply_t * mp)
4735 {
4736   vat_main_t *vam = &vat_main;
4737   vat_json_node_t node;
4738
4739   vat_json_init_object (&node);
4740
4741   vat_json_object_add_int (&node, "l2_table_id", ntohl (mp->l2_table_id));
4742   vat_json_object_add_int (&node, "ip4_table_id", ntohl (mp->ip4_table_id));
4743   vat_json_object_add_int (&node, "ip6_table_id", ntohl (mp->ip6_table_id));
4744
4745   vat_json_print (vam->ofp, &node);
4746   vat_json_free (&node);
4747
4748   vam->retval = ntohl (mp->retval);
4749   vam->result_ready = 1;
4750 }
4751
4752 static void vl_api_policer_add_del_reply_t_handler
4753   (vl_api_policer_add_del_reply_t * mp)
4754 {
4755   vat_main_t *vam = &vat_main;
4756   i32 retval = ntohl (mp->retval);
4757   if (vam->async_mode)
4758     {
4759       vam->async_errors += (retval < 0);
4760     }
4761   else
4762     {
4763       vam->retval = retval;
4764       vam->result_ready = 1;
4765       if (retval == 0 && mp->policer_index != 0xFFFFFFFF)
4766         /*
4767          * Note: this is just barely thread-safe, depends on
4768          * the main thread spinning waiting for an answer...
4769          */
4770         errmsg ("policer index %d", ntohl (mp->policer_index));
4771     }
4772 }
4773
4774 static void vl_api_policer_add_del_reply_t_handler_json
4775   (vl_api_policer_add_del_reply_t * mp)
4776 {
4777   vat_main_t *vam = &vat_main;
4778   vat_json_node_t node;
4779
4780   vat_json_init_object (&node);
4781   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
4782   vat_json_object_add_uint (&node, "policer_index",
4783                             ntohl (mp->policer_index));
4784
4785   vat_json_print (vam->ofp, &node);
4786   vat_json_free (&node);
4787
4788   vam->retval = ntohl (mp->retval);
4789   vam->result_ready = 1;
4790 }
4791
4792 /* Format hex dump. */
4793 u8 *
4794 format_hex_bytes (u8 * s, va_list * va)
4795 {
4796   u8 *bytes = va_arg (*va, u8 *);
4797   int n_bytes = va_arg (*va, int);
4798   uword i;
4799
4800   /* Print short or long form depending on byte count. */
4801   uword short_form = n_bytes <= 32;
4802   u32 indent = format_get_indent (s);
4803
4804   if (n_bytes == 0)
4805     return s;
4806
4807   for (i = 0; i < n_bytes; i++)
4808     {
4809       if (!short_form && (i % 32) == 0)
4810         s = format (s, "%08x: ", i);
4811       s = format (s, "%02x", bytes[i]);
4812       if (!short_form && ((i + 1) % 32) == 0 && (i + 1) < n_bytes)
4813         s = format (s, "\n%U", format_white_space, indent);
4814     }
4815
4816   return s;
4817 }
4818
4819 static void
4820 vl_api_classify_table_info_reply_t_handler (vl_api_classify_table_info_reply_t
4821                                             * mp)
4822 {
4823   vat_main_t *vam = &vat_main;
4824   i32 retval = ntohl (mp->retval);
4825   if (retval == 0)
4826     {
4827       print (vam->ofp, "classify table info :");
4828       print (vam->ofp, "sessions: %d nexttbl: %d nextnode: %d",
4829              ntohl (mp->active_sessions), ntohl (mp->next_table_index),
4830              ntohl (mp->miss_next_index));
4831       print (vam->ofp, "nbuckets: %d skip: %d match: %d",
4832              ntohl (mp->nbuckets), ntohl (mp->skip_n_vectors),
4833              ntohl (mp->match_n_vectors));
4834       print (vam->ofp, "mask: %U", format_hex_bytes, mp->mask,
4835              ntohl (mp->mask_length));
4836     }
4837   vam->retval = retval;
4838   vam->result_ready = 1;
4839 }
4840
4841 static void
4842   vl_api_classify_table_info_reply_t_handler_json
4843   (vl_api_classify_table_info_reply_t * mp)
4844 {
4845   vat_main_t *vam = &vat_main;
4846   vat_json_node_t node;
4847
4848   i32 retval = ntohl (mp->retval);
4849   if (retval == 0)
4850     {
4851       vat_json_init_object (&node);
4852
4853       vat_json_object_add_int (&node, "sessions",
4854                                ntohl (mp->active_sessions));
4855       vat_json_object_add_int (&node, "nexttbl",
4856                                ntohl (mp->next_table_index));
4857       vat_json_object_add_int (&node, "nextnode",
4858                                ntohl (mp->miss_next_index));
4859       vat_json_object_add_int (&node, "nbuckets", ntohl (mp->nbuckets));
4860       vat_json_object_add_int (&node, "skip", ntohl (mp->skip_n_vectors));
4861       vat_json_object_add_int (&node, "match", ntohl (mp->match_n_vectors));
4862       u8 *s = format (0, "%U%c", format_hex_bytes, mp->mask,
4863                       ntohl (mp->mask_length), 0);
4864       vat_json_object_add_string_copy (&node, "mask", s);
4865
4866       vat_json_print (vam->ofp, &node);
4867       vat_json_free (&node);
4868     }
4869   vam->retval = ntohl (mp->retval);
4870   vam->result_ready = 1;
4871 }
4872
4873 static void
4874 vl_api_classify_session_details_t_handler (vl_api_classify_session_details_t *
4875                                            mp)
4876 {
4877   vat_main_t *vam = &vat_main;
4878
4879   print (vam->ofp, "next_index: %d advance: %d opaque: %d ",
4880          ntohl (mp->hit_next_index), ntohl (mp->advance),
4881          ntohl (mp->opaque_index));
4882   print (vam->ofp, "mask: %U", format_hex_bytes, mp->match,
4883          ntohl (mp->match_length));
4884 }
4885
4886 static void
4887   vl_api_classify_session_details_t_handler_json
4888   (vl_api_classify_session_details_t * mp)
4889 {
4890   vat_main_t *vam = &vat_main;
4891   vat_json_node_t *node = NULL;
4892
4893   if (VAT_JSON_ARRAY != vam->json_tree.type)
4894     {
4895       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4896       vat_json_init_array (&vam->json_tree);
4897     }
4898   node = vat_json_array_add (&vam->json_tree);
4899
4900   vat_json_init_object (node);
4901   vat_json_object_add_int (node, "next_index", ntohl (mp->hit_next_index));
4902   vat_json_object_add_int (node, "advance", ntohl (mp->advance));
4903   vat_json_object_add_int (node, "opaque", ntohl (mp->opaque_index));
4904   u8 *s =
4905     format (0, "%U%c", format_hex_bytes, mp->match, ntohl (mp->match_length),
4906             0);
4907   vat_json_object_add_string_copy (node, "match", s);
4908 }
4909
4910 static void vl_api_pg_create_interface_reply_t_handler
4911   (vl_api_pg_create_interface_reply_t * mp)
4912 {
4913   vat_main_t *vam = &vat_main;
4914
4915   vam->retval = ntohl (mp->retval);
4916   vam->result_ready = 1;
4917 }
4918
4919 static void vl_api_pg_create_interface_reply_t_handler_json
4920   (vl_api_pg_create_interface_reply_t * mp)
4921 {
4922   vat_main_t *vam = &vat_main;
4923   vat_json_node_t node;
4924
4925   i32 retval = ntohl (mp->retval);
4926   if (retval == 0)
4927     {
4928       vat_json_init_object (&node);
4929
4930       vat_json_object_add_int (&node, "sw_if_index", ntohl (mp->sw_if_index));
4931
4932       vat_json_print (vam->ofp, &node);
4933       vat_json_free (&node);
4934     }
4935   vam->retval = ntohl (mp->retval);
4936   vam->result_ready = 1;
4937 }
4938
4939 static void vl_api_policer_classify_details_t_handler
4940   (vl_api_policer_classify_details_t * mp)
4941 {
4942   vat_main_t *vam = &vat_main;
4943
4944   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
4945          ntohl (mp->table_index));
4946 }
4947
4948 static void vl_api_policer_classify_details_t_handler_json
4949   (vl_api_policer_classify_details_t * mp)
4950 {
4951   vat_main_t *vam = &vat_main;
4952   vat_json_node_t *node;
4953
4954   if (VAT_JSON_ARRAY != vam->json_tree.type)
4955     {
4956       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4957       vat_json_init_array (&vam->json_tree);
4958     }
4959   node = vat_json_array_add (&vam->json_tree);
4960
4961   vat_json_init_object (node);
4962   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
4963   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
4964 }
4965
4966 static void vl_api_flow_classify_details_t_handler
4967   (vl_api_flow_classify_details_t * mp)
4968 {
4969   vat_main_t *vam = &vat_main;
4970
4971   print (vam->ofp, "%10d%20d", ntohl (mp->sw_if_index),
4972          ntohl (mp->table_index));
4973 }
4974
4975 static void vl_api_flow_classify_details_t_handler_json
4976   (vl_api_flow_classify_details_t * mp)
4977 {
4978   vat_main_t *vam = &vat_main;
4979   vat_json_node_t *node;
4980
4981   if (VAT_JSON_ARRAY != vam->json_tree.type)
4982     {
4983       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
4984       vat_json_init_array (&vam->json_tree);
4985     }
4986   node = vat_json_array_add (&vam->json_tree);
4987
4988   vat_json_init_object (node);
4989   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
4990   vat_json_object_add_uint (node, "table_index", ntohl (mp->table_index));
4991 }
4992
4993 #define vl_api_one_adjacencies_get_reply_t_endian vl_noop_handler
4994 #define vl_api_one_adjacencies_get_reply_t_print vl_noop_handler
4995 #define vl_api_one_l2_arp_bd_get_reply_t_print vl_noop_handler
4996 #define vl_api_one_l2_arp_entries_get_reply_t_endian vl_noop_handler
4997 #define vl_api_one_l2_arp_entries_get_reply_t_print vl_noop_handler
4998 #define vl_api_one_l2_arp_bd_get_reply_t_endian vl_noop_handler
4999 #define vl_api_one_ndp_bd_get_reply_t_endian vl_noop_handler
5000 #define vl_api_one_ndp_bd_get_reply_t_print vl_noop_handler
5001 #define vl_api_one_ndp_entries_get_reply_t_print vl_noop_handler
5002 #define vl_api_one_ndp_entries_get_reply_t_endian vl_noop_handler
5003
5004 /*
5005  * Generate boilerplate reply handlers, which
5006  * dig the return value out of the xxx_reply_t API message,
5007  * stick it into vam->retval, and set vam->result_ready
5008  *
5009  * Could also do this by pointing N message decode slots at
5010  * a single function, but that could break in subtle ways.
5011  */
5012
5013 #define foreach_standard_reply_retval_handler           \
5014 _(sw_interface_set_flags_reply)                         \
5015 _(sw_interface_add_del_address_reply)                   \
5016 _(sw_interface_set_rx_mode_reply)                       \
5017 _(sw_interface_set_rx_placement_reply)                  \
5018 _(sw_interface_set_table_reply)                         \
5019 _(sw_interface_set_mpls_enable_reply)                   \
5020 _(sw_interface_set_vpath_reply)                         \
5021 _(sw_interface_set_vxlan_bypass_reply)                  \
5022 _(sw_interface_set_geneve_bypass_reply)                 \
5023 _(sw_interface_set_vxlan_gpe_bypass_reply)              \
5024 _(sw_interface_set_l2_bridge_reply)                     \
5025 _(sw_interface_set_bond_weight_reply)                   \
5026 _(bridge_domain_add_del_reply)                          \
5027 _(sw_interface_set_l2_xconnect_reply)                   \
5028 _(l2fib_add_del_reply)                                  \
5029 _(l2fib_flush_int_reply)                                \
5030 _(l2fib_flush_bd_reply)                                 \
5031 _(ip_route_add_del_reply)                               \
5032 _(ip_table_add_del_reply)                               \
5033 _(ip_table_replace_begin_reply)                         \
5034 _(ip_table_flush_reply)                                 \
5035 _(ip_table_replace_end_reply)                           \
5036 _(ip_mroute_add_del_reply)                              \
5037 _(mpls_route_add_del_reply)                             \
5038 _(mpls_table_add_del_reply)                             \
5039 _(mpls_ip_bind_unbind_reply)                            \
5040 _(bier_route_add_del_reply)                             \
5041 _(bier_table_add_del_reply)                             \
5042 _(sw_interface_set_unnumbered_reply)                    \
5043 _(set_ip_flow_hash_reply)                               \
5044 _(sw_interface_ip6_enable_disable_reply)                \
5045 _(l2_patch_add_del_reply)                               \
5046 _(sr_mpls_policy_add_reply)                             \
5047 _(sr_mpls_policy_mod_reply)                             \
5048 _(sr_mpls_policy_del_reply)                             \
5049 _(sr_policy_add_reply)                                  \
5050 _(sr_policy_mod_reply)                                  \
5051 _(sr_policy_del_reply)                                  \
5052 _(sr_localsid_add_del_reply)                            \
5053 _(sr_steering_add_del_reply)                            \
5054 _(classify_add_del_session_reply)                       \
5055 _(classify_set_interface_ip_table_reply)                \
5056 _(classify_set_interface_l2_tables_reply)               \
5057 _(l2tpv3_set_tunnel_cookies_reply)                      \
5058 _(l2tpv3_interface_enable_disable_reply)                \
5059 _(l2tpv3_set_lookup_key_reply)                          \
5060 _(l2_fib_clear_table_reply)                             \
5061 _(l2_interface_efp_filter_reply)                        \
5062 _(l2_interface_vlan_tag_rewrite_reply)                  \
5063 _(modify_vhost_user_if_reply)                           \
5064 _(delete_vhost_user_if_reply)                           \
5065 _(want_l2_macs_events_reply)                            \
5066 _(input_acl_set_interface_reply)                        \
5067 _(ipsec_spd_add_del_reply)                              \
5068 _(ipsec_interface_add_del_spd_reply)                    \
5069 _(ipsec_spd_entry_add_del_reply)                        \
5070 _(ipsec_sad_entry_add_del_reply)                        \
5071 _(ipsec_tunnel_if_add_del_reply)                        \
5072 _(ipsec_tunnel_if_set_sa_reply)                         \
5073 _(delete_loopback_reply)                                \
5074 _(bd_ip_mac_add_del_reply)                              \
5075 _(bd_ip_mac_flush_reply)                                \
5076 _(want_interface_events_reply)                          \
5077 _(cop_interface_enable_disable_reply)                   \
5078 _(cop_whitelist_enable_disable_reply)                   \
5079 _(sw_interface_clear_stats_reply)                       \
5080 _(ioam_enable_reply)                                    \
5081 _(ioam_disable_reply)                                   \
5082 _(one_add_del_locator_reply)                            \
5083 _(one_add_del_local_eid_reply)                          \
5084 _(one_add_del_remote_mapping_reply)                     \
5085 _(one_add_del_adjacency_reply)                          \
5086 _(one_add_del_map_resolver_reply)                       \
5087 _(one_add_del_map_server_reply)                         \
5088 _(one_enable_disable_reply)                             \
5089 _(one_rloc_probe_enable_disable_reply)                  \
5090 _(one_map_register_enable_disable_reply)                \
5091 _(one_map_register_set_ttl_reply)                       \
5092 _(one_set_transport_protocol_reply)                     \
5093 _(one_map_register_fallback_threshold_reply)            \
5094 _(one_pitr_set_locator_set_reply)                       \
5095 _(one_map_request_mode_reply)                           \
5096 _(one_add_del_map_request_itr_rlocs_reply)              \
5097 _(one_eid_table_add_del_map_reply)                      \
5098 _(one_use_petr_reply)                                   \
5099 _(one_stats_enable_disable_reply)                       \
5100 _(one_add_del_l2_arp_entry_reply)                       \
5101 _(one_add_del_ndp_entry_reply)                          \
5102 _(one_stats_flush_reply)                                \
5103 _(one_enable_disable_xtr_mode_reply)                    \
5104 _(one_enable_disable_pitr_mode_reply)                   \
5105 _(one_enable_disable_petr_mode_reply)                   \
5106 _(gpe_enable_disable_reply)                             \
5107 _(gpe_set_encap_mode_reply)                             \
5108 _(gpe_add_del_iface_reply)                              \
5109 _(gpe_add_del_native_fwd_rpath_reply)                   \
5110 _(af_packet_delete_reply)                               \
5111 _(policer_classify_set_interface_reply)                 \
5112 _(netmap_create_reply)                                  \
5113 _(netmap_delete_reply)                                  \
5114 _(set_ipfix_exporter_reply)                             \
5115 _(set_ipfix_classify_stream_reply)                      \
5116 _(ipfix_classify_table_add_del_reply)                   \
5117 _(flow_classify_set_interface_reply)                    \
5118 _(sw_interface_span_enable_disable_reply)               \
5119 _(pg_capture_reply)                                     \
5120 _(pg_enable_disable_reply)                              \
5121 _(ip_source_and_port_range_check_add_del_reply)         \
5122 _(ip_source_and_port_range_check_interface_add_del_reply)\
5123 _(delete_subif_reply)                                   \
5124 _(l2_interface_pbb_tag_rewrite_reply)                   \
5125 _(set_punt_reply)                                       \
5126 _(feature_enable_disable_reply)                         \
5127 _(feature_gso_enable_disable_reply)                     \
5128 _(sw_interface_tag_add_del_reply)                       \
5129 _(sw_interface_add_del_mac_address_reply)               \
5130 _(hw_interface_set_mtu_reply)                           \
5131 _(p2p_ethernet_add_reply)                               \
5132 _(p2p_ethernet_del_reply)                               \
5133 _(lldp_config_reply)                                    \
5134 _(sw_interface_set_lldp_reply)                          \
5135 _(tcp_configure_src_addresses_reply)                    \
5136 _(session_rule_add_del_reply)                           \
5137 _(ip_container_proxy_add_del_reply)                     \
5138 _(output_acl_set_interface_reply)                       \
5139 _(qos_record_enable_disable_reply)
5140
5141 #define _(n)                                    \
5142     static void vl_api_##n##_t_handler          \
5143     (vl_api_##n##_t * mp)                       \
5144     {                                           \
5145         vat_main_t * vam = &vat_main;           \
5146         i32 retval = ntohl(mp->retval);         \
5147         if (vam->async_mode) {                  \
5148             vam->async_errors += (retval < 0);  \
5149         } else {                                \
5150             vam->retval = retval;               \
5151             vam->result_ready = 1;              \
5152         }                                       \
5153     }
5154 foreach_standard_reply_retval_handler;
5155 #undef _
5156
5157 #define _(n)                                    \
5158     static void vl_api_##n##_t_handler_json     \
5159     (vl_api_##n##_t * mp)                       \
5160     {                                           \
5161         vat_main_t * vam = &vat_main;           \
5162         vat_json_node_t node;                   \
5163         vat_json_init_object(&node);            \
5164         vat_json_object_add_int(&node, "retval", ntohl(mp->retval));    \
5165         vat_json_print(vam->ofp, &node);        \
5166         vam->retval = ntohl(mp->retval);        \
5167         vam->result_ready = 1;                  \
5168     }
5169 foreach_standard_reply_retval_handler;
5170 #undef _
5171
5172 /*
5173  * Table of message reply handlers, must include boilerplate handlers
5174  * we just generated
5175  */
5176
5177 #define foreach_vpe_api_reply_msg                                       \
5178 _(CREATE_LOOPBACK_REPLY, create_loopback_reply)                         \
5179 _(CREATE_LOOPBACK_INSTANCE_REPLY, create_loopback_instance_reply)       \
5180 _(SW_INTERFACE_DETAILS, sw_interface_details)                           \
5181 _(SW_INTERFACE_SET_FLAGS_REPLY, sw_interface_set_flags_reply)           \
5182 _(CONTROL_PING_REPLY, control_ping_reply)                               \
5183 _(CLI_REPLY, cli_reply)                                                 \
5184 _(CLI_INBAND_REPLY, cli_inband_reply)                                   \
5185 _(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY,                                   \
5186   sw_interface_add_del_address_reply)                                   \
5187 _(SW_INTERFACE_SET_RX_MODE_REPLY, sw_interface_set_rx_mode_reply)       \
5188 _(SW_INTERFACE_SET_RX_PLACEMENT_REPLY, sw_interface_set_rx_placement_reply)     \
5189 _(SW_INTERFACE_RX_PLACEMENT_DETAILS, sw_interface_rx_placement_details) \
5190 _(SW_INTERFACE_SET_TABLE_REPLY, sw_interface_set_table_reply)           \
5191 _(SW_INTERFACE_SET_MPLS_ENABLE_REPLY, sw_interface_set_mpls_enable_reply) \
5192 _(SW_INTERFACE_SET_VPATH_REPLY, sw_interface_set_vpath_reply)           \
5193 _(SW_INTERFACE_SET_VXLAN_BYPASS_REPLY, sw_interface_set_vxlan_bypass_reply) \
5194 _(SW_INTERFACE_SET_GENEVE_BYPASS_REPLY, sw_interface_set_geneve_bypass_reply) \
5195 _(SW_INTERFACE_SET_VXLAN_GPE_BYPASS_REPLY, sw_interface_set_vxlan_gpe_bypass_reply) \
5196 _(SW_INTERFACE_SET_L2_XCONNECT_REPLY,                                   \
5197   sw_interface_set_l2_xconnect_reply)                                   \
5198 _(SW_INTERFACE_SET_L2_BRIDGE_REPLY,                                     \
5199   sw_interface_set_l2_bridge_reply)                                     \
5200 _(BRIDGE_DOMAIN_ADD_DEL_REPLY, bridge_domain_add_del_reply)             \
5201 _(BRIDGE_DOMAIN_DETAILS, bridge_domain_details)                         \
5202 _(BRIDGE_DOMAIN_SET_MAC_AGE_REPLY, bridge_domain_set_mac_age_reply)     \
5203 _(L2FIB_ADD_DEL_REPLY, l2fib_add_del_reply)                             \
5204 _(L2FIB_FLUSH_INT_REPLY, l2fib_flush_int_reply)                         \
5205 _(L2FIB_FLUSH_BD_REPLY, l2fib_flush_bd_reply)                           \
5206 _(L2_FLAGS_REPLY, l2_flags_reply)                                       \
5207 _(BRIDGE_FLAGS_REPLY, bridge_flags_reply)                               \
5208 _(TAP_CREATE_V2_REPLY, tap_create_v2_reply)                             \
5209 _(TAP_DELETE_V2_REPLY, tap_delete_v2_reply)                             \
5210 _(SW_INTERFACE_TAP_V2_DETAILS, sw_interface_tap_v2_details)             \
5211 _(VIRTIO_PCI_CREATE_REPLY, virtio_pci_create_reply)                     \
5212 _(VIRTIO_PCI_DELETE_REPLY, virtio_pci_delete_reply)                     \
5213 _(SW_INTERFACE_VIRTIO_PCI_DETAILS, sw_interface_virtio_pci_details)     \
5214 _(BOND_CREATE_REPLY, bond_create_reply)                                 \
5215 _(BOND_DELETE_REPLY, bond_delete_reply)                                 \
5216 _(BOND_ENSLAVE_REPLY, bond_enslave_reply)                               \
5217 _(BOND_DETACH_SLAVE_REPLY, bond_detach_slave_reply)                     \
5218 _(SW_INTERFACE_SET_BOND_WEIGHT_REPLY, sw_interface_set_bond_weight_reply) \
5219 _(SW_INTERFACE_BOND_DETAILS, sw_interface_bond_details)                 \
5220 _(SW_INTERFACE_SLAVE_DETAILS, sw_interface_slave_details)               \
5221 _(IP_ROUTE_ADD_DEL_REPLY, ip_route_add_del_reply)                       \
5222 _(IP_TABLE_ADD_DEL_REPLY, ip_table_add_del_reply)                       \
5223 _(IP_TABLE_REPLACE_BEGIN_REPLY, ip_table_replace_begin_reply)           \
5224 _(IP_TABLE_FLUSH_REPLY, ip_table_flush_reply)                           \
5225 _(IP_TABLE_REPLACE_END_REPLY, ip_table_replace_end_reply)               \
5226 _(IP_MROUTE_ADD_DEL_REPLY, ip_mroute_add_del_reply)                     \
5227 _(MPLS_TABLE_ADD_DEL_REPLY, mpls_table_add_del_reply)                   \
5228 _(MPLS_ROUTE_ADD_DEL_REPLY, mpls_route_add_del_reply)                   \
5229 _(MPLS_IP_BIND_UNBIND_REPLY, mpls_ip_bind_unbind_reply)                 \
5230 _(BIER_ROUTE_ADD_DEL_REPLY, bier_route_add_del_reply)                   \
5231 _(BIER_TABLE_ADD_DEL_REPLY, bier_table_add_del_reply)                   \
5232 _(MPLS_TUNNEL_ADD_DEL_REPLY, mpls_tunnel_add_del_reply)                 \
5233 _(SW_INTERFACE_SET_UNNUMBERED_REPLY,                                    \
5234   sw_interface_set_unnumbered_reply)                                    \
5235 _(CREATE_VLAN_SUBIF_REPLY, create_vlan_subif_reply)                     \
5236 _(CREATE_SUBIF_REPLY, create_subif_reply)                               \
5237 _(SET_IP_FLOW_HASH_REPLY, set_ip_flow_hash_reply)                       \
5238 _(SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY,                                \
5239   sw_interface_ip6_enable_disable_reply)                                \
5240 _(L2_PATCH_ADD_DEL_REPLY, l2_patch_add_del_reply)                       \
5241 _(SR_MPLS_POLICY_ADD_REPLY, sr_mpls_policy_add_reply)                   \
5242 _(SR_MPLS_POLICY_MOD_REPLY, sr_mpls_policy_mod_reply)                   \
5243 _(SR_MPLS_POLICY_DEL_REPLY, sr_mpls_policy_del_reply)                   \
5244 _(SR_POLICY_ADD_REPLY, sr_policy_add_reply)                             \
5245 _(SR_POLICY_MOD_REPLY, sr_policy_mod_reply)                             \
5246 _(SR_POLICY_DEL_REPLY, sr_policy_del_reply)                             \
5247 _(SR_LOCALSID_ADD_DEL_REPLY, sr_localsid_add_del_reply)                 \
5248 _(SR_STEERING_ADD_DEL_REPLY, sr_steering_add_del_reply)                 \
5249 _(CLASSIFY_ADD_DEL_TABLE_REPLY, classify_add_del_table_reply)           \
5250 _(CLASSIFY_ADD_DEL_SESSION_REPLY, classify_add_del_session_reply)       \
5251 _(CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY,                                \
5252 classify_set_interface_ip_table_reply)                                  \
5253 _(CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY,                               \
5254   classify_set_interface_l2_tables_reply)                               \
5255 _(GET_NODE_INDEX_REPLY, get_node_index_reply)                           \
5256 _(ADD_NODE_NEXT_REPLY, add_node_next_reply)                             \
5257 _(L2TPV3_CREATE_TUNNEL_REPLY, l2tpv3_create_tunnel_reply)               \
5258 _(L2TPV3_SET_TUNNEL_COOKIES_REPLY, l2tpv3_set_tunnel_cookies_reply)     \
5259 _(L2TPV3_INTERFACE_ENABLE_DISABLE_REPLY,                                \
5260   l2tpv3_interface_enable_disable_reply)                                \
5261 _(L2TPV3_SET_LOOKUP_KEY_REPLY, l2tpv3_set_lookup_key_reply)             \
5262 _(SW_IF_L2TPV3_TUNNEL_DETAILS, sw_if_l2tpv3_tunnel_details)             \
5263 _(VXLAN_ADD_DEL_TUNNEL_REPLY, vxlan_add_del_tunnel_reply)               \
5264 _(VXLAN_OFFLOAD_RX_REPLY, vxlan_offload_rx_reply)               \
5265 _(GENEVE_ADD_DEL_TUNNEL_REPLY, geneve_add_del_tunnel_reply)             \
5266 _(VXLAN_TUNNEL_DETAILS, vxlan_tunnel_details)                           \
5267 _(GENEVE_TUNNEL_DETAILS, geneve_tunnel_details)                         \
5268 _(GRE_TUNNEL_ADD_DEL_REPLY, gre_tunnel_add_del_reply)                   \
5269 _(GRE_TUNNEL_DETAILS, gre_tunnel_details)                               \
5270 _(L2_FIB_CLEAR_TABLE_REPLY, l2_fib_clear_table_reply)                   \
5271 _(L2_INTERFACE_EFP_FILTER_REPLY, l2_interface_efp_filter_reply)         \
5272 _(L2_INTERFACE_VLAN_TAG_REWRITE_REPLY, l2_interface_vlan_tag_rewrite_reply) \
5273 _(SW_INTERFACE_VHOST_USER_DETAILS, sw_interface_vhost_user_details)     \
5274 _(CREATE_VHOST_USER_IF_REPLY, create_vhost_user_if_reply)               \
5275 _(MODIFY_VHOST_USER_IF_REPLY, modify_vhost_user_if_reply)               \
5276 _(DELETE_VHOST_USER_IF_REPLY, delete_vhost_user_if_reply)               \
5277 _(SHOW_VERSION_REPLY, show_version_reply)                               \
5278 _(SHOW_THREADS_REPLY, show_threads_reply)                               \
5279 _(L2_FIB_TABLE_DETAILS, l2_fib_table_details)                           \
5280 _(VXLAN_GPE_ADD_DEL_TUNNEL_REPLY, vxlan_gpe_add_del_tunnel_reply)       \
5281 _(VXLAN_GPE_TUNNEL_DETAILS, vxlan_gpe_tunnel_details)                   \
5282 _(INTERFACE_NAME_RENUMBER_REPLY, interface_name_renumber_reply)         \
5283 _(WANT_L2_MACS_EVENTS_REPLY, want_l2_macs_events_reply)                 \
5284 _(L2_MACS_EVENT, l2_macs_event)                                         \
5285 _(INPUT_ACL_SET_INTERFACE_REPLY, input_acl_set_interface_reply)         \
5286 _(IP_ADDRESS_DETAILS, ip_address_details)                               \
5287 _(IP_DETAILS, ip_details)                                               \
5288 _(IPSEC_SPD_ADD_DEL_REPLY, ipsec_spd_add_del_reply)                     \
5289 _(IPSEC_INTERFACE_ADD_DEL_SPD_REPLY, ipsec_interface_add_del_spd_reply) \
5290 _(IPSEC_SPD_ENTRY_ADD_DEL_REPLY, ipsec_spd_entry_add_del_reply)         \
5291 _(IPSEC_SAD_ENTRY_ADD_DEL_REPLY, ipsec_sad_entry_add_del_reply)         \
5292 _(IPSEC_SA_DETAILS, ipsec_sa_details)                                   \
5293 _(IPSEC_TUNNEL_IF_ADD_DEL_REPLY, ipsec_tunnel_if_add_del_reply)         \
5294 _(IPSEC_TUNNEL_IF_SET_SA_REPLY, ipsec_tunnel_if_set_sa_reply)           \
5295 _(DELETE_LOOPBACK_REPLY, delete_loopback_reply)                         \
5296 _(BD_IP_MAC_ADD_DEL_REPLY, bd_ip_mac_add_del_reply)                     \
5297 _(BD_IP_MAC_FLUSH_REPLY, bd_ip_mac_flush_reply)                         \
5298 _(BD_IP_MAC_DETAILS, bd_ip_mac_details)                                 \
5299 _(WANT_INTERFACE_EVENTS_REPLY, want_interface_events_reply)             \
5300 _(GET_FIRST_MSG_ID_REPLY, get_first_msg_id_reply)                       \
5301 _(COP_INTERFACE_ENABLE_DISABLE_REPLY, cop_interface_enable_disable_reply) \
5302 _(COP_WHITELIST_ENABLE_DISABLE_REPLY, cop_whitelist_enable_disable_reply) \
5303 _(GET_NODE_GRAPH_REPLY, get_node_graph_reply)                           \
5304 _(SW_INTERFACE_CLEAR_STATS_REPLY, sw_interface_clear_stats_reply)      \
5305 _(IOAM_ENABLE_REPLY, ioam_enable_reply)                   \
5306 _(IOAM_DISABLE_REPLY, ioam_disable_reply)                     \
5307 _(ONE_ADD_DEL_LOCATOR_SET_REPLY, one_add_del_locator_set_reply)         \
5308 _(ONE_ADD_DEL_LOCATOR_REPLY, one_add_del_locator_reply)                 \
5309 _(ONE_ADD_DEL_LOCAL_EID_REPLY, one_add_del_local_eid_reply)             \
5310 _(ONE_ADD_DEL_REMOTE_MAPPING_REPLY, one_add_del_remote_mapping_reply)   \
5311 _(ONE_ADD_DEL_ADJACENCY_REPLY, one_add_del_adjacency_reply)             \
5312 _(ONE_ADD_DEL_MAP_RESOLVER_REPLY, one_add_del_map_resolver_reply)       \
5313 _(ONE_ADD_DEL_MAP_SERVER_REPLY, one_add_del_map_server_reply)           \
5314 _(ONE_ENABLE_DISABLE_REPLY, one_enable_disable_reply)                   \
5315 _(ONE_MAP_REGISTER_ENABLE_DISABLE_REPLY,                                \
5316   one_map_register_enable_disable_reply)                                \
5317 _(ONE_MAP_REGISTER_SET_TTL_REPLY, one_map_register_set_ttl_reply)       \
5318 _(ONE_SET_TRANSPORT_PROTOCOL_REPLY, one_set_transport_protocol_reply)   \
5319 _(ONE_GET_TRANSPORT_PROTOCOL_REPLY, one_get_transport_protocol_reply)   \
5320 _(ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                            \
5321   one_map_register_fallback_threshold_reply)                            \
5322 _(ONE_RLOC_PROBE_ENABLE_DISABLE_REPLY,                                  \
5323   one_rloc_probe_enable_disable_reply)                                  \
5324 _(ONE_PITR_SET_LOCATOR_SET_REPLY, one_pitr_set_locator_set_reply)       \
5325 _(ONE_USE_PETR_REPLY, one_use_petr_reply)                               \
5326 _(ONE_MAP_REQUEST_MODE_REPLY, one_map_request_mode_reply)               \
5327 _(ONE_EID_TABLE_ADD_DEL_MAP_REPLY, one_eid_table_add_del_map_reply)     \
5328 _(ONE_LOCATOR_SET_DETAILS, one_locator_set_details)                     \
5329 _(ONE_LOCATOR_DETAILS, one_locator_details)                             \
5330 _(ONE_EID_TABLE_DETAILS, one_eid_table_details)                         \
5331 _(ONE_EID_TABLE_MAP_DETAILS, one_eid_table_map_details)                 \
5332 _(ONE_EID_TABLE_VNI_DETAILS, one_eid_table_vni_details)                 \
5333 _(ONE_MAP_RESOLVER_DETAILS, one_map_resolver_details)                   \
5334 _(ONE_MAP_SERVER_DETAILS, one_map_server_details)                       \
5335 _(ONE_ADJACENCIES_GET_REPLY, one_adjacencies_get_reply)                 \
5336 _(ONE_STATS_DETAILS, one_stats_details)                                 \
5337 _(ONE_STATS_FLUSH_REPLY, one_stats_flush_reply)                         \
5338 _(ONE_STATS_ENABLE_DISABLE_REPLY, one_stats_enable_disable_reply)       \
5339 _(SHOW_ONE_STATS_ENABLE_DISABLE_REPLY,                                  \
5340   show_one_stats_enable_disable_reply)                                  \
5341 _(ONE_ADD_DEL_NDP_ENTRY_REPLY, one_add_del_ndp_entry_reply)             \
5342 _(ONE_NDP_BD_GET_REPLY, one_ndp_bd_get_reply)                           \
5343 _(ONE_NDP_ENTRIES_GET_REPLY, one_ndp_entries_get_reply)                 \
5344 _(ONE_ADD_DEL_L2_ARP_ENTRY_REPLY, one_add_del_l2_arp_entry_reply)       \
5345 _(ONE_L2_ARP_BD_GET_REPLY, one_l2_arp_bd_get_reply)                     \
5346 _(ONE_L2_ARP_ENTRIES_GET_REPLY, one_l2_arp_entries_get_reply)           \
5347 _(ONE_ENABLE_DISABLE_XTR_MODE_REPLY, one_enable_disable_xtr_mode_reply) \
5348 _(ONE_ENABLE_DISABLE_PITR_MODE_REPLY,                                   \
5349   one_enable_disable_pitr_mode_reply)                                   \
5350 _(ONE_ENABLE_DISABLE_PETR_MODE_REPLY,                                   \
5351   one_enable_disable_petr_mode_reply)                                   \
5352 _(ONE_SHOW_XTR_MODE_REPLY, one_show_xtr_mode_reply)                     \
5353 _(ONE_SHOW_PITR_MODE_REPLY, one_show_pitr_mode_reply)                   \
5354 _(ONE_SHOW_PETR_MODE_REPLY, one_show_petr_mode_reply)                   \
5355 _(GPE_SET_ENCAP_MODE_REPLY, gpe_set_encap_mode_reply)                   \
5356 _(GPE_GET_ENCAP_MODE_REPLY, gpe_get_encap_mode_reply)                   \
5357 _(GPE_ADD_DEL_IFACE_REPLY, gpe_add_del_iface_reply)                     \
5358 _(GPE_ENABLE_DISABLE_REPLY, gpe_enable_disable_reply)                   \
5359 _(GPE_ADD_DEL_FWD_ENTRY_REPLY, gpe_add_del_fwd_entry_reply)             \
5360 _(GPE_FWD_ENTRY_VNIS_GET_REPLY, gpe_fwd_entry_vnis_get_reply)           \
5361 _(GPE_FWD_ENTRIES_GET_REPLY, gpe_fwd_entries_get_reply)                 \
5362 _(GPE_NATIVE_FWD_RPATHS_GET_REPLY, gpe_native_fwd_rpaths_get_reply)     \
5363 _(GPE_ADD_DEL_NATIVE_FWD_RPATH_REPLY,                                   \
5364   gpe_add_del_native_fwd_rpath_reply)                                   \
5365 _(GPE_FWD_ENTRY_PATH_DETAILS,                                           \
5366   gpe_fwd_entry_path_details)                                           \
5367 _(SHOW_ONE_STATUS_REPLY, show_one_status_reply)                         \
5368 _(ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS_REPLY,                              \
5369   one_add_del_map_request_itr_rlocs_reply)                              \
5370 _(ONE_GET_MAP_REQUEST_ITR_RLOCS_REPLY,                                  \
5371   one_get_map_request_itr_rlocs_reply)                                  \
5372 _(SHOW_ONE_NSH_MAPPING_REPLY, show_one_nsh_mapping_reply)               \
5373 _(SHOW_ONE_PITR_REPLY, show_one_pitr_reply)                             \
5374 _(SHOW_ONE_USE_PETR_REPLY, show_one_use_petr_reply)                     \
5375 _(SHOW_ONE_MAP_REQUEST_MODE_REPLY, show_one_map_request_mode_reply)     \
5376 _(SHOW_ONE_RLOC_PROBE_STATE_REPLY, show_one_rloc_probe_state_reply)     \
5377 _(SHOW_ONE_MAP_REGISTER_STATE_REPLY,                                    \
5378   show_one_map_register_state_reply)                                    \
5379 _(SHOW_ONE_MAP_REGISTER_TTL_REPLY, show_one_map_register_ttl_reply)     \
5380 _(SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD_REPLY,                       \
5381   show_one_map_register_fallback_threshold_reply)                       \
5382 _(AF_PACKET_CREATE_REPLY, af_packet_create_reply)                       \
5383 _(AF_PACKET_DELETE_REPLY, af_packet_delete_reply)                       \
5384 _(AF_PACKET_DETAILS, af_packet_details)                                 \
5385 _(POLICER_ADD_DEL_REPLY, policer_add_del_reply)                         \
5386 _(POLICER_DETAILS, policer_details)                                     \
5387 _(POLICER_CLASSIFY_SET_INTERFACE_REPLY, policer_classify_set_interface_reply) \
5388 _(POLICER_CLASSIFY_DETAILS, policer_classify_details)                   \
5389 _(NETMAP_CREATE_REPLY, netmap_create_reply)                             \
5390 _(NETMAP_DELETE_REPLY, netmap_delete_reply)                             \
5391 _(MPLS_TUNNEL_DETAILS, mpls_tunnel_details)                             \
5392 _(MPLS_TABLE_DETAILS, mpls_table_details)                               \
5393 _(MPLS_ROUTE_DETAILS, mpls_route_details)                               \
5394 _(CLASSIFY_TABLE_IDS_REPLY, classify_table_ids_reply)                   \
5395 _(CLASSIFY_TABLE_BY_INTERFACE_REPLY, classify_table_by_interface_reply) \
5396 _(CLASSIFY_TABLE_INFO_REPLY, classify_table_info_reply)                 \
5397 _(CLASSIFY_SESSION_DETAILS, classify_session_details)                   \
5398 _(SET_IPFIX_EXPORTER_REPLY, set_ipfix_exporter_reply)                   \
5399 _(IPFIX_EXPORTER_DETAILS, ipfix_exporter_details)                       \
5400 _(SET_IPFIX_CLASSIFY_STREAM_REPLY, set_ipfix_classify_stream_reply)     \
5401 _(IPFIX_CLASSIFY_STREAM_DETAILS, ipfix_classify_stream_details)         \
5402 _(IPFIX_CLASSIFY_TABLE_ADD_DEL_REPLY, ipfix_classify_table_add_del_reply) \
5403 _(IPFIX_CLASSIFY_TABLE_DETAILS, ipfix_classify_table_details)           \
5404 _(FLOW_CLASSIFY_SET_INTERFACE_REPLY, flow_classify_set_interface_reply) \
5405 _(FLOW_CLASSIFY_DETAILS, flow_classify_details)                         \
5406 _(SW_INTERFACE_SPAN_ENABLE_DISABLE_REPLY, sw_interface_span_enable_disable_reply) \
5407 _(SW_INTERFACE_SPAN_DETAILS, sw_interface_span_details)                 \
5408 _(GET_NEXT_INDEX_REPLY, get_next_index_reply)                           \
5409 _(PG_CREATE_INTERFACE_REPLY, pg_create_interface_reply)                 \
5410 _(PG_CAPTURE_REPLY, pg_capture_reply)                                   \
5411 _(PG_ENABLE_DISABLE_REPLY, pg_enable_disable_reply)                     \
5412 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY,                         \
5413  ip_source_and_port_range_check_add_del_reply)                          \
5414 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY,               \
5415  ip_source_and_port_range_check_interface_add_del_reply)                \
5416 _(DELETE_SUBIF_REPLY, delete_subif_reply)                               \
5417 _(L2_INTERFACE_PBB_TAG_REWRITE_REPLY, l2_interface_pbb_tag_rewrite_reply) \
5418 _(SET_PUNT_REPLY, set_punt_reply)                                       \
5419 _(IP_TABLE_DETAILS, ip_table_details)                                   \
5420 _(IP_ROUTE_DETAILS, ip_route_details)                                   \
5421 _(FEATURE_ENABLE_DISABLE_REPLY, feature_enable_disable_reply)           \
5422 _(FEATURE_GSO_ENABLE_DISABLE_REPLY, feature_gso_enable_disable_reply)   \
5423 _(SW_INTERFACE_TAG_ADD_DEL_REPLY, sw_interface_tag_add_del_reply)       \
5424 _(SW_INTERFACE_ADD_DEL_MAC_ADDRESS_REPLY, sw_interface_add_del_mac_address_reply) \
5425 _(L2_XCONNECT_DETAILS, l2_xconnect_details)                             \
5426 _(HW_INTERFACE_SET_MTU_REPLY, hw_interface_set_mtu_reply)               \
5427 _(SW_INTERFACE_GET_TABLE_REPLY, sw_interface_get_table_reply)           \
5428 _(P2P_ETHERNET_ADD_REPLY, p2p_ethernet_add_reply)                       \
5429 _(P2P_ETHERNET_DEL_REPLY, p2p_ethernet_del_reply)                       \
5430 _(LLDP_CONFIG_REPLY, lldp_config_reply)                                 \
5431 _(SW_INTERFACE_SET_LLDP_REPLY, sw_interface_set_lldp_reply)             \
5432 _(TCP_CONFIGURE_SRC_ADDRESSES_REPLY, tcp_configure_src_addresses_reply) \
5433 _(APP_NAMESPACE_ADD_DEL_REPLY, app_namespace_add_del_reply)             \
5434 _(SESSION_RULE_ADD_DEL_REPLY, session_rule_add_del_reply)               \
5435 _(SESSION_RULES_DETAILS, session_rules_details)                         \
5436 _(IP_CONTAINER_PROXY_ADD_DEL_REPLY, ip_container_proxy_add_del_reply)   \
5437 _(OUTPUT_ACL_SET_INTERFACE_REPLY, output_acl_set_interface_reply)       \
5438 _(QOS_RECORD_ENABLE_DISABLE_REPLY, qos_record_enable_disable_reply)
5439
5440 #define foreach_standalone_reply_msg                                    \
5441 _(SW_INTERFACE_EVENT, sw_interface_event)
5442
5443 typedef struct
5444 {
5445   u8 *name;
5446   u32 value;
5447 } name_sort_t;
5448
5449 #define STR_VTR_OP_CASE(op)     \
5450     case L2_VTR_ ## op:         \
5451         return "" # op;
5452
5453 static const char *
5454 str_vtr_op (u32 vtr_op)
5455 {
5456   switch (vtr_op)
5457     {
5458       STR_VTR_OP_CASE (DISABLED);
5459       STR_VTR_OP_CASE (PUSH_1);
5460       STR_VTR_OP_CASE (PUSH_2);
5461       STR_VTR_OP_CASE (POP_1);
5462       STR_VTR_OP_CASE (POP_2);
5463       STR_VTR_OP_CASE (TRANSLATE_1_1);
5464       STR_VTR_OP_CASE (TRANSLATE_1_2);
5465       STR_VTR_OP_CASE (TRANSLATE_2_1);
5466       STR_VTR_OP_CASE (TRANSLATE_2_2);
5467     }
5468
5469   return "UNKNOWN";
5470 }
5471
5472 static int
5473 dump_sub_interface_table (vat_main_t * vam)
5474 {
5475   const sw_interface_subif_t *sub = NULL;
5476
5477   if (vam->json_output)
5478     {
5479       clib_warning
5480         ("JSON output supported only for VPE API calls and dump_stats_table");
5481       return -99;
5482     }
5483
5484   print (vam->ofp,
5485          "%-30s%-12s%-11s%-7s%-5s%-9s%-9s%-6s%-8s%-10s%-10s",
5486          "Interface", "sw_if_index",
5487          "sub id", "dot1ad", "tags", "outer id",
5488          "inner id", "exact", "default", "outer any", "inner any");
5489
5490   vec_foreach (sub, vam->sw_if_subif_table)
5491   {
5492     print (vam->ofp,
5493            "%-30s%-12d%-11d%-7s%-5d%-9d%-9d%-6d%-8d%-10d%-10d",
5494            sub->interface_name,
5495            sub->sw_if_index,
5496            sub->sub_id, sub->sub_dot1ad ? "dot1ad" : "dot1q",
5497            sub->sub_number_of_tags, sub->sub_outer_vlan_id,
5498            sub->sub_inner_vlan_id, sub->sub_exact_match, sub->sub_default,
5499            sub->sub_outer_vlan_id_any, sub->sub_inner_vlan_id_any);
5500     if (sub->vtr_op != L2_VTR_DISABLED)
5501       {
5502         print (vam->ofp,
5503                "  vlan-tag-rewrite - op: %-14s [ dot1q: %d "
5504                "tag1: %d tag2: %d ]",
5505                str_vtr_op (sub->vtr_op), sub->vtr_push_dot1q,
5506                sub->vtr_tag1, sub->vtr_tag2);
5507       }
5508   }
5509
5510   return 0;
5511 }
5512
5513 static int
5514 name_sort_cmp (void *a1, void *a2)
5515 {
5516   name_sort_t *n1 = a1;
5517   name_sort_t *n2 = a2;
5518
5519   return strcmp ((char *) n1->name, (char *) n2->name);
5520 }
5521
5522 static int
5523 dump_interface_table (vat_main_t * vam)
5524 {
5525   hash_pair_t *p;
5526   name_sort_t *nses = 0, *ns;
5527
5528   if (vam->json_output)
5529     {
5530       clib_warning
5531         ("JSON output supported only for VPE API calls and dump_stats_table");
5532       return -99;
5533     }
5534
5535   /* *INDENT-OFF* */
5536   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5537   ({
5538     vec_add2 (nses, ns, 1);
5539     ns->name = (u8 *)(p->key);
5540     ns->value = (u32) p->value[0];
5541   }));
5542   /* *INDENT-ON* */
5543
5544   vec_sort_with_function (nses, name_sort_cmp);
5545
5546   print (vam->ofp, "%-25s%-15s", "Interface", "sw_if_index");
5547   vec_foreach (ns, nses)
5548   {
5549     print (vam->ofp, "%-25s%-15d", ns->name, ns->value);
5550   }
5551   vec_free (nses);
5552   return 0;
5553 }
5554
5555 static int
5556 dump_ip_table (vat_main_t * vam, int is_ipv6)
5557 {
5558   const ip_details_t *det = NULL;
5559   const ip_address_details_t *address = NULL;
5560   u32 i = ~0;
5561
5562   print (vam->ofp, "%-12s", "sw_if_index");
5563
5564   vec_foreach (det, vam->ip_details_by_sw_if_index[is_ipv6])
5565   {
5566     i++;
5567     if (!det->present)
5568       {
5569         continue;
5570       }
5571     print (vam->ofp, "%-12d", i);
5572     print (vam->ofp, "            %-30s%-13s", "Address", "Prefix length");
5573     if (!det->addr)
5574       {
5575         continue;
5576       }
5577     vec_foreach (address, det->addr)
5578     {
5579       print (vam->ofp,
5580              "            %-30U%-13d",
5581              is_ipv6 ? format_ip6_address : format_ip4_address,
5582              address->ip, address->prefix_length);
5583     }
5584   }
5585
5586   return 0;
5587 }
5588
5589 static int
5590 dump_ipv4_table (vat_main_t * vam)
5591 {
5592   if (vam->json_output)
5593     {
5594       clib_warning
5595         ("JSON output supported only for VPE API calls and dump_stats_table");
5596       return -99;
5597     }
5598
5599   return dump_ip_table (vam, 0);
5600 }
5601
5602 static int
5603 dump_ipv6_table (vat_main_t * vam)
5604 {
5605   if (vam->json_output)
5606     {
5607       clib_warning
5608         ("JSON output supported only for VPE API calls and dump_stats_table");
5609       return -99;
5610     }
5611
5612   return dump_ip_table (vam, 1);
5613 }
5614
5615 /*
5616  * Pass CLI buffers directly in the CLI_INBAND API message,
5617  * instead of an additional shared memory area.
5618  */
5619 static int
5620 exec_inband (vat_main_t * vam)
5621 {
5622   vl_api_cli_inband_t *mp;
5623   unformat_input_t *i = vam->input;
5624   int ret;
5625
5626   if (vec_len (i->buffer) == 0)
5627     return -1;
5628
5629   if (vam->exec_mode == 0 && unformat (i, "mode"))
5630     {
5631       vam->exec_mode = 1;
5632       return 0;
5633     }
5634   if (vam->exec_mode == 1 && (unformat (i, "exit") || unformat (i, "quit")))
5635     {
5636       vam->exec_mode = 0;
5637       return 0;
5638     }
5639
5640   /*
5641    * In order for the CLI command to work, it
5642    * must be a vector ending in \n, not a C-string ending
5643    * in \n\0.
5644    */
5645   u32 len = vec_len (vam->input->buffer);
5646   M2 (CLI_INBAND, mp, len);
5647   vl_api_to_api_string (len - 1, (const char *) vam->input->buffer, &mp->cmd);
5648
5649   S (mp);
5650   W (ret);
5651   /* json responses may or may not include a useful reply... */
5652   if (vec_len (vam->cmd_reply))
5653     print (vam->ofp, "%v", (char *) (vam->cmd_reply));
5654   return ret;
5655 }
5656
5657 int
5658 exec (vat_main_t * vam)
5659 {
5660   return exec_inband (vam);
5661 }
5662
5663 static int
5664 api_create_loopback (vat_main_t * vam)
5665 {
5666   unformat_input_t *i = vam->input;
5667   vl_api_create_loopback_t *mp;
5668   vl_api_create_loopback_instance_t *mp_lbi;
5669   u8 mac_address[6];
5670   u8 mac_set = 0;
5671   u8 is_specified = 0;
5672   u32 user_instance = 0;
5673   int ret;
5674
5675   clib_memset (mac_address, 0, sizeof (mac_address));
5676
5677   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5678     {
5679       if (unformat (i, "mac %U", unformat_ethernet_address, mac_address))
5680         mac_set = 1;
5681       if (unformat (i, "instance %d", &user_instance))
5682         is_specified = 1;
5683       else
5684         break;
5685     }
5686
5687   if (is_specified)
5688     {
5689       M (CREATE_LOOPBACK_INSTANCE, mp_lbi);
5690       mp_lbi->is_specified = is_specified;
5691       if (is_specified)
5692         mp_lbi->user_instance = htonl (user_instance);
5693       if (mac_set)
5694         clib_memcpy (mp_lbi->mac_address, mac_address, sizeof (mac_address));
5695       S (mp_lbi);
5696     }
5697   else
5698     {
5699       /* Construct the API message */
5700       M (CREATE_LOOPBACK, mp);
5701       if (mac_set)
5702         clib_memcpy (mp->mac_address, mac_address, sizeof (mac_address));
5703       S (mp);
5704     }
5705
5706   W (ret);
5707   return ret;
5708 }
5709
5710 static int
5711 api_delete_loopback (vat_main_t * vam)
5712 {
5713   unformat_input_t *i = vam->input;
5714   vl_api_delete_loopback_t *mp;
5715   u32 sw_if_index = ~0;
5716   int ret;
5717
5718   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5719     {
5720       if (unformat (i, "sw_if_index %d", &sw_if_index))
5721         ;
5722       else
5723         break;
5724     }
5725
5726   if (sw_if_index == ~0)
5727     {
5728       errmsg ("missing sw_if_index");
5729       return -99;
5730     }
5731
5732   /* Construct the API message */
5733   M (DELETE_LOOPBACK, mp);
5734   mp->sw_if_index = ntohl (sw_if_index);
5735
5736   S (mp);
5737   W (ret);
5738   return ret;
5739 }
5740
5741 static int
5742 api_want_interface_events (vat_main_t * vam)
5743 {
5744   unformat_input_t *i = vam->input;
5745   vl_api_want_interface_events_t *mp;
5746   int enable = -1;
5747   int ret;
5748
5749   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5750     {
5751       if (unformat (i, "enable"))
5752         enable = 1;
5753       else if (unformat (i, "disable"))
5754         enable = 0;
5755       else
5756         break;
5757     }
5758
5759   if (enable == -1)
5760     {
5761       errmsg ("missing enable|disable");
5762       return -99;
5763     }
5764
5765   M (WANT_INTERFACE_EVENTS, mp);
5766   mp->enable_disable = enable;
5767
5768   vam->interface_event_display = enable;
5769
5770   S (mp);
5771   W (ret);
5772   return ret;
5773 }
5774
5775
5776 /* Note: non-static, called once to set up the initial intfc table */
5777 int
5778 api_sw_interface_dump (vat_main_t * vam)
5779 {
5780   vl_api_sw_interface_dump_t *mp;
5781   vl_api_control_ping_t *mp_ping;
5782   hash_pair_t *p;
5783   name_sort_t *nses = 0, *ns;
5784   sw_interface_subif_t *sub = NULL;
5785   int ret;
5786
5787   /* Toss the old name table */
5788   /* *INDENT-OFF* */
5789   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
5790   ({
5791     vec_add2 (nses, ns, 1);
5792     ns->name = (u8 *)(p->key);
5793     ns->value = (u32) p->value[0];
5794   }));
5795   /* *INDENT-ON* */
5796
5797   hash_free (vam->sw_if_index_by_interface_name);
5798
5799   vec_foreach (ns, nses) vec_free (ns->name);
5800
5801   vec_free (nses);
5802
5803   vec_foreach (sub, vam->sw_if_subif_table)
5804   {
5805     vec_free (sub->interface_name);
5806   }
5807   vec_free (vam->sw_if_subif_table);
5808
5809   /* recreate the interface name hash table */
5810   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
5811
5812   /*
5813    * Ask for all interface names. Otherwise, the epic catalog of
5814    * name filters becomes ridiculously long, and vat ends up needing
5815    * to be taught about new interface types.
5816    */
5817   M (SW_INTERFACE_DUMP, mp);
5818   S (mp);
5819
5820   /* Use a control ping for synchronization */
5821   MPING (CONTROL_PING, mp_ping);
5822   S (mp_ping);
5823
5824   W (ret);
5825   return ret;
5826 }
5827
5828 static int
5829 api_sw_interface_set_flags (vat_main_t * vam)
5830 {
5831   unformat_input_t *i = vam->input;
5832   vl_api_sw_interface_set_flags_t *mp;
5833   u32 sw_if_index;
5834   u8 sw_if_index_set = 0;
5835   u8 admin_up = 0;
5836   int ret;
5837
5838   /* Parse args required to build the message */
5839   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5840     {
5841       if (unformat (i, "admin-up"))
5842         admin_up = 1;
5843       else if (unformat (i, "admin-down"))
5844         admin_up = 0;
5845       else
5846         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5847         sw_if_index_set = 1;
5848       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5849         sw_if_index_set = 1;
5850       else
5851         break;
5852     }
5853
5854   if (sw_if_index_set == 0)
5855     {
5856       errmsg ("missing interface name or sw_if_index");
5857       return -99;
5858     }
5859
5860   /* Construct the API message */
5861   M (SW_INTERFACE_SET_FLAGS, mp);
5862   mp->sw_if_index = ntohl (sw_if_index);
5863   mp->flags = ntohl ((admin_up) ? IF_STATUS_API_FLAG_ADMIN_UP : 0);
5864
5865   /* send it... */
5866   S (mp);
5867
5868   /* Wait for a reply, return the good/bad news... */
5869   W (ret);
5870   return ret;
5871 }
5872
5873 static int
5874 api_sw_interface_set_rx_mode (vat_main_t * vam)
5875 {
5876   unformat_input_t *i = vam->input;
5877   vl_api_sw_interface_set_rx_mode_t *mp;
5878   u32 sw_if_index;
5879   u8 sw_if_index_set = 0;
5880   int ret;
5881   u8 queue_id_valid = 0;
5882   u32 queue_id;
5883   vnet_hw_interface_rx_mode mode = VNET_HW_INTERFACE_RX_MODE_UNKNOWN;
5884
5885   /* Parse args required to build the message */
5886   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5887     {
5888       if (unformat (i, "queue %d", &queue_id))
5889         queue_id_valid = 1;
5890       else if (unformat (i, "polling"))
5891         mode = VNET_HW_INTERFACE_RX_MODE_POLLING;
5892       else if (unformat (i, "interrupt"))
5893         mode = VNET_HW_INTERFACE_RX_MODE_INTERRUPT;
5894       else if (unformat (i, "adaptive"))
5895         mode = VNET_HW_INTERFACE_RX_MODE_ADAPTIVE;
5896       else
5897         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5898         sw_if_index_set = 1;
5899       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5900         sw_if_index_set = 1;
5901       else
5902         break;
5903     }
5904
5905   if (sw_if_index_set == 0)
5906     {
5907       errmsg ("missing interface name or sw_if_index");
5908       return -99;
5909     }
5910   if (mode == VNET_HW_INTERFACE_RX_MODE_UNKNOWN)
5911     {
5912       errmsg ("missing rx-mode");
5913       return -99;
5914     }
5915
5916   /* Construct the API message */
5917   M (SW_INTERFACE_SET_RX_MODE, mp);
5918   mp->sw_if_index = ntohl (sw_if_index);
5919   mp->mode = (vl_api_rx_mode_t) mode;
5920   mp->queue_id_valid = queue_id_valid;
5921   mp->queue_id = queue_id_valid ? ntohl (queue_id) : ~0;
5922
5923   /* send it... */
5924   S (mp);
5925
5926   /* Wait for a reply, return the good/bad news... */
5927   W (ret);
5928   return ret;
5929 }
5930
5931 static int
5932 api_sw_interface_set_rx_placement (vat_main_t * vam)
5933 {
5934   unformat_input_t *i = vam->input;
5935   vl_api_sw_interface_set_rx_placement_t *mp;
5936   u32 sw_if_index;
5937   u8 sw_if_index_set = 0;
5938   int ret;
5939   u8 is_main = 0;
5940   u32 queue_id, thread_index;
5941
5942   /* Parse args required to build the message */
5943   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
5944     {
5945       if (unformat (i, "queue %d", &queue_id))
5946         ;
5947       else if (unformat (i, "main"))
5948         is_main = 1;
5949       else if (unformat (i, "worker %d", &thread_index))
5950         ;
5951       else
5952         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
5953         sw_if_index_set = 1;
5954       else if (unformat (i, "sw_if_index %d", &sw_if_index))
5955         sw_if_index_set = 1;
5956       else
5957         break;
5958     }
5959
5960   if (sw_if_index_set == 0)
5961     {
5962       errmsg ("missing interface name or sw_if_index");
5963       return -99;
5964     }
5965
5966   if (is_main)
5967     thread_index = 0;
5968   /* Construct the API message */
5969   M (SW_INTERFACE_SET_RX_PLACEMENT, mp);
5970   mp->sw_if_index = ntohl (sw_if_index);
5971   mp->worker_id = ntohl (thread_index);
5972   mp->queue_id = ntohl (queue_id);
5973   mp->is_main = is_main;
5974
5975   /* send it... */
5976   S (mp);
5977   /* Wait for a reply, return the good/bad news... */
5978   W (ret);
5979   return ret;
5980 }
5981
5982 static void vl_api_sw_interface_rx_placement_details_t_handler
5983   (vl_api_sw_interface_rx_placement_details_t * mp)
5984 {
5985   vat_main_t *vam = &vat_main;
5986   u32 worker_id = ntohl (mp->worker_id);
5987
5988   print (vam->ofp,
5989          "\n%-11d %-11s %-6d %-5d %-9s",
5990          ntohl (mp->sw_if_index), (worker_id == 0) ? "main" : "worker",
5991          worker_id, ntohl (mp->queue_id),
5992          (mp->mode ==
5993           1) ? "polling" : ((mp->mode == 2) ? "interrupt" : "adaptive"));
5994 }
5995
5996 static void vl_api_sw_interface_rx_placement_details_t_handler_json
5997   (vl_api_sw_interface_rx_placement_details_t * mp)
5998 {
5999   vat_main_t *vam = &vat_main;
6000   vat_json_node_t *node = NULL;
6001
6002   if (VAT_JSON_ARRAY != vam->json_tree.type)
6003     {
6004       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
6005       vat_json_init_array (&vam->json_tree);
6006     }
6007   node = vat_json_array_add (&vam->json_tree);
6008
6009   vat_json_init_object (node);
6010   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
6011   vat_json_object_add_uint (node, "worker_id", ntohl (mp->worker_id));
6012   vat_json_object_add_uint (node, "queue_id", ntohl (mp->queue_id));
6013   vat_json_object_add_uint (node, "mode", mp->mode);
6014 }
6015
6016 static int
6017 api_sw_interface_rx_placement_dump (vat_main_t * vam)
6018 {
6019   unformat_input_t *i = vam->input;
6020   vl_api_sw_interface_rx_placement_dump_t *mp;
6021   vl_api_control_ping_t *mp_ping;
6022   int ret;
6023   u32 sw_if_index;
6024   u8 sw_if_index_set = 0;
6025
6026   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6027     {
6028       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6029         sw_if_index_set++;
6030       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6031         sw_if_index_set++;
6032       else
6033         break;
6034     }
6035
6036   print (vam->ofp,
6037          "\n%-11s %-11s %-6s %-5s %-4s",
6038          "sw_if_index", "main/worker", "thread", "queue", "mode");
6039
6040   /* Dump Interface rx placement */
6041   M (SW_INTERFACE_RX_PLACEMENT_DUMP, mp);
6042
6043   if (sw_if_index_set)
6044     mp->sw_if_index = htonl (sw_if_index);
6045   else
6046     mp->sw_if_index = ~0;
6047
6048   S (mp);
6049
6050   /* Use a control ping for synchronization */
6051   MPING (CONTROL_PING, mp_ping);
6052   S (mp_ping);
6053
6054   W (ret);
6055   return ret;
6056 }
6057
6058 static int
6059 api_sw_interface_clear_stats (vat_main_t * vam)
6060 {
6061   unformat_input_t *i = vam->input;
6062   vl_api_sw_interface_clear_stats_t *mp;
6063   u32 sw_if_index;
6064   u8 sw_if_index_set = 0;
6065   int ret;
6066
6067   /* Parse args required to build the message */
6068   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6069     {
6070       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6071         sw_if_index_set = 1;
6072       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6073         sw_if_index_set = 1;
6074       else
6075         break;
6076     }
6077
6078   /* Construct the API message */
6079   M (SW_INTERFACE_CLEAR_STATS, mp);
6080
6081   if (sw_if_index_set == 1)
6082     mp->sw_if_index = ntohl (sw_if_index);
6083   else
6084     mp->sw_if_index = ~0;
6085
6086   /* send it... */
6087   S (mp);
6088
6089   /* Wait for a reply, return the good/bad news... */
6090   W (ret);
6091   return ret;
6092 }
6093
6094 static int
6095 api_sw_interface_add_del_address (vat_main_t * vam)
6096 {
6097   unformat_input_t *i = vam->input;
6098   vl_api_sw_interface_add_del_address_t *mp;
6099   u32 sw_if_index;
6100   u8 sw_if_index_set = 0;
6101   u8 is_add = 1, del_all = 0;
6102   u32 address_length = 0;
6103   u8 v4_address_set = 0;
6104   u8 v6_address_set = 0;
6105   ip4_address_t v4address;
6106   ip6_address_t v6address;
6107   int ret;
6108
6109   /* Parse args required to build the message */
6110   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6111     {
6112       if (unformat (i, "del-all"))
6113         del_all = 1;
6114       else if (unformat (i, "del"))
6115         is_add = 0;
6116       else
6117         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6118         sw_if_index_set = 1;
6119       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6120         sw_if_index_set = 1;
6121       else if (unformat (i, "%U/%d",
6122                          unformat_ip4_address, &v4address, &address_length))
6123         v4_address_set = 1;
6124       else if (unformat (i, "%U/%d",
6125                          unformat_ip6_address, &v6address, &address_length))
6126         v6_address_set = 1;
6127       else
6128         break;
6129     }
6130
6131   if (sw_if_index_set == 0)
6132     {
6133       errmsg ("missing interface name or sw_if_index");
6134       return -99;
6135     }
6136   if (v4_address_set && v6_address_set)
6137     {
6138       errmsg ("both v4 and v6 addresses set");
6139       return -99;
6140     }
6141   if (!v4_address_set && !v6_address_set && !del_all)
6142     {
6143       errmsg ("no addresses set");
6144       return -99;
6145     }
6146
6147   /* Construct the API message */
6148   M (SW_INTERFACE_ADD_DEL_ADDRESS, mp);
6149
6150   mp->sw_if_index = ntohl (sw_if_index);
6151   mp->is_add = is_add;
6152   mp->del_all = del_all;
6153   if (v6_address_set)
6154     {
6155       mp->prefix.address.af = ADDRESS_IP6;
6156       clib_memcpy (mp->prefix.address.un.ip6, &v6address, sizeof (v6address));
6157     }
6158   else
6159     {
6160       mp->prefix.address.af = ADDRESS_IP4;
6161       clib_memcpy (mp->prefix.address.un.ip4, &v4address, sizeof (v4address));
6162     }
6163   mp->prefix.len = address_length;
6164
6165   /* send it... */
6166   S (mp);
6167
6168   /* Wait for a reply, return good/bad news  */
6169   W (ret);
6170   return ret;
6171 }
6172
6173 static int
6174 api_sw_interface_set_mpls_enable (vat_main_t * vam)
6175 {
6176   unformat_input_t *i = vam->input;
6177   vl_api_sw_interface_set_mpls_enable_t *mp;
6178   u32 sw_if_index;
6179   u8 sw_if_index_set = 0;
6180   u8 enable = 1;
6181   int ret;
6182
6183   /* Parse args required to build the message */
6184   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6185     {
6186       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6187         sw_if_index_set = 1;
6188       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6189         sw_if_index_set = 1;
6190       else if (unformat (i, "disable"))
6191         enable = 0;
6192       else if (unformat (i, "dis"))
6193         enable = 0;
6194       else
6195         break;
6196     }
6197
6198   if (sw_if_index_set == 0)
6199     {
6200       errmsg ("missing interface name or sw_if_index");
6201       return -99;
6202     }
6203
6204   /* Construct the API message */
6205   M (SW_INTERFACE_SET_MPLS_ENABLE, mp);
6206
6207   mp->sw_if_index = ntohl (sw_if_index);
6208   mp->enable = enable;
6209
6210   /* send it... */
6211   S (mp);
6212
6213   /* Wait for a reply... */
6214   W (ret);
6215   return ret;
6216 }
6217
6218 static int
6219 api_sw_interface_set_table (vat_main_t * vam)
6220 {
6221   unformat_input_t *i = vam->input;
6222   vl_api_sw_interface_set_table_t *mp;
6223   u32 sw_if_index, vrf_id = 0;
6224   u8 sw_if_index_set = 0;
6225   u8 is_ipv6 = 0;
6226   int ret;
6227
6228   /* Parse args required to build the message */
6229   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6230     {
6231       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6232         sw_if_index_set = 1;
6233       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6234         sw_if_index_set = 1;
6235       else if (unformat (i, "vrf %d", &vrf_id))
6236         ;
6237       else if (unformat (i, "ipv6"))
6238         is_ipv6 = 1;
6239       else
6240         break;
6241     }
6242
6243   if (sw_if_index_set == 0)
6244     {
6245       errmsg ("missing interface name or sw_if_index");
6246       return -99;
6247     }
6248
6249   /* Construct the API message */
6250   M (SW_INTERFACE_SET_TABLE, mp);
6251
6252   mp->sw_if_index = ntohl (sw_if_index);
6253   mp->is_ipv6 = is_ipv6;
6254   mp->vrf_id = ntohl (vrf_id);
6255
6256   /* send it... */
6257   S (mp);
6258
6259   /* Wait for a reply... */
6260   W (ret);
6261   return ret;
6262 }
6263
6264 static void vl_api_sw_interface_get_table_reply_t_handler
6265   (vl_api_sw_interface_get_table_reply_t * mp)
6266 {
6267   vat_main_t *vam = &vat_main;
6268
6269   print (vam->ofp, "%d", ntohl (mp->vrf_id));
6270
6271   vam->retval = ntohl (mp->retval);
6272   vam->result_ready = 1;
6273
6274 }
6275
6276 static void vl_api_sw_interface_get_table_reply_t_handler_json
6277   (vl_api_sw_interface_get_table_reply_t * mp)
6278 {
6279   vat_main_t *vam = &vat_main;
6280   vat_json_node_t node;
6281
6282   vat_json_init_object (&node);
6283   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
6284   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
6285
6286   vat_json_print (vam->ofp, &node);
6287   vat_json_free (&node);
6288
6289   vam->retval = ntohl (mp->retval);
6290   vam->result_ready = 1;
6291 }
6292
6293 static int
6294 api_sw_interface_get_table (vat_main_t * vam)
6295 {
6296   unformat_input_t *i = vam->input;
6297   vl_api_sw_interface_get_table_t *mp;
6298   u32 sw_if_index;
6299   u8 sw_if_index_set = 0;
6300   u8 is_ipv6 = 0;
6301   int ret;
6302
6303   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6304     {
6305       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6306         sw_if_index_set = 1;
6307       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6308         sw_if_index_set = 1;
6309       else if (unformat (i, "ipv6"))
6310         is_ipv6 = 1;
6311       else
6312         break;
6313     }
6314
6315   if (sw_if_index_set == 0)
6316     {
6317       errmsg ("missing interface name or sw_if_index");
6318       return -99;
6319     }
6320
6321   M (SW_INTERFACE_GET_TABLE, mp);
6322   mp->sw_if_index = htonl (sw_if_index);
6323   mp->is_ipv6 = is_ipv6;
6324
6325   S (mp);
6326   W (ret);
6327   return ret;
6328 }
6329
6330 static int
6331 api_sw_interface_set_vpath (vat_main_t * vam)
6332 {
6333   unformat_input_t *i = vam->input;
6334   vl_api_sw_interface_set_vpath_t *mp;
6335   u32 sw_if_index = 0;
6336   u8 sw_if_index_set = 0;
6337   u8 is_enable = 0;
6338   int ret;
6339
6340   /* Parse args required to build the message */
6341   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6342     {
6343       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6344         sw_if_index_set = 1;
6345       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6346         sw_if_index_set = 1;
6347       else if (unformat (i, "enable"))
6348         is_enable = 1;
6349       else if (unformat (i, "disable"))
6350         is_enable = 0;
6351       else
6352         break;
6353     }
6354
6355   if (sw_if_index_set == 0)
6356     {
6357       errmsg ("missing interface name or sw_if_index");
6358       return -99;
6359     }
6360
6361   /* Construct the API message */
6362   M (SW_INTERFACE_SET_VPATH, mp);
6363
6364   mp->sw_if_index = ntohl (sw_if_index);
6365   mp->enable = is_enable;
6366
6367   /* send it... */
6368   S (mp);
6369
6370   /* Wait for a reply... */
6371   W (ret);
6372   return ret;
6373 }
6374
6375 static int
6376 api_sw_interface_set_vxlan_bypass (vat_main_t * vam)
6377 {
6378   unformat_input_t *i = vam->input;
6379   vl_api_sw_interface_set_vxlan_bypass_t *mp;
6380   u32 sw_if_index = 0;
6381   u8 sw_if_index_set = 0;
6382   u8 is_enable = 1;
6383   u8 is_ipv6 = 0;
6384   int ret;
6385
6386   /* Parse args required to build the message */
6387   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6388     {
6389       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6390         sw_if_index_set = 1;
6391       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6392         sw_if_index_set = 1;
6393       else if (unformat (i, "enable"))
6394         is_enable = 1;
6395       else if (unformat (i, "disable"))
6396         is_enable = 0;
6397       else if (unformat (i, "ip4"))
6398         is_ipv6 = 0;
6399       else if (unformat (i, "ip6"))
6400         is_ipv6 = 1;
6401       else
6402         break;
6403     }
6404
6405   if (sw_if_index_set == 0)
6406     {
6407       errmsg ("missing interface name or sw_if_index");
6408       return -99;
6409     }
6410
6411   /* Construct the API message */
6412   M (SW_INTERFACE_SET_VXLAN_BYPASS, mp);
6413
6414   mp->sw_if_index = ntohl (sw_if_index);
6415   mp->enable = is_enable;
6416   mp->is_ipv6 = is_ipv6;
6417
6418   /* send it... */
6419   S (mp);
6420
6421   /* Wait for a reply... */
6422   W (ret);
6423   return ret;
6424 }
6425
6426 static int
6427 api_sw_interface_set_geneve_bypass (vat_main_t * vam)
6428 {
6429   unformat_input_t *i = vam->input;
6430   vl_api_sw_interface_set_geneve_bypass_t *mp;
6431   u32 sw_if_index = 0;
6432   u8 sw_if_index_set = 0;
6433   u8 is_enable = 1;
6434   u8 is_ipv6 = 0;
6435   int ret;
6436
6437   /* Parse args required to build the message */
6438   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6439     {
6440       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6441         sw_if_index_set = 1;
6442       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6443         sw_if_index_set = 1;
6444       else if (unformat (i, "enable"))
6445         is_enable = 1;
6446       else if (unformat (i, "disable"))
6447         is_enable = 0;
6448       else if (unformat (i, "ip4"))
6449         is_ipv6 = 0;
6450       else if (unformat (i, "ip6"))
6451         is_ipv6 = 1;
6452       else
6453         break;
6454     }
6455
6456   if (sw_if_index_set == 0)
6457     {
6458       errmsg ("missing interface name or sw_if_index");
6459       return -99;
6460     }
6461
6462   /* Construct the API message */
6463   M (SW_INTERFACE_SET_GENEVE_BYPASS, mp);
6464
6465   mp->sw_if_index = ntohl (sw_if_index);
6466   mp->enable = is_enable;
6467   mp->is_ipv6 = is_ipv6;
6468
6469   /* send it... */
6470   S (mp);
6471
6472   /* Wait for a reply... */
6473   W (ret);
6474   return ret;
6475 }
6476
6477 static int
6478 api_sw_interface_set_l2_xconnect (vat_main_t * vam)
6479 {
6480   unformat_input_t *i = vam->input;
6481   vl_api_sw_interface_set_l2_xconnect_t *mp;
6482   u32 rx_sw_if_index;
6483   u8 rx_sw_if_index_set = 0;
6484   u32 tx_sw_if_index;
6485   u8 tx_sw_if_index_set = 0;
6486   u8 enable = 1;
6487   int ret;
6488
6489   /* Parse args required to build the message */
6490   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6491     {
6492       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
6493         rx_sw_if_index_set = 1;
6494       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
6495         tx_sw_if_index_set = 1;
6496       else if (unformat (i, "rx"))
6497         {
6498           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6499             {
6500               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6501                             &rx_sw_if_index))
6502                 rx_sw_if_index_set = 1;
6503             }
6504           else
6505             break;
6506         }
6507       else if (unformat (i, "tx"))
6508         {
6509           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6510             {
6511               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
6512                             &tx_sw_if_index))
6513                 tx_sw_if_index_set = 1;
6514             }
6515           else
6516             break;
6517         }
6518       else if (unformat (i, "enable"))
6519         enable = 1;
6520       else if (unformat (i, "disable"))
6521         enable = 0;
6522       else
6523         break;
6524     }
6525
6526   if (rx_sw_if_index_set == 0)
6527     {
6528       errmsg ("missing rx interface name or rx_sw_if_index");
6529       return -99;
6530     }
6531
6532   if (enable && (tx_sw_if_index_set == 0))
6533     {
6534       errmsg ("missing tx interface name or tx_sw_if_index");
6535       return -99;
6536     }
6537
6538   M (SW_INTERFACE_SET_L2_XCONNECT, mp);
6539
6540   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6541   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
6542   mp->enable = enable;
6543
6544   S (mp);
6545   W (ret);
6546   return ret;
6547 }
6548
6549 static int
6550 api_sw_interface_set_l2_bridge (vat_main_t * vam)
6551 {
6552   unformat_input_t *i = vam->input;
6553   vl_api_sw_interface_set_l2_bridge_t *mp;
6554   vl_api_l2_port_type_t port_type;
6555   u32 rx_sw_if_index;
6556   u8 rx_sw_if_index_set = 0;
6557   u32 bd_id;
6558   u8 bd_id_set = 0;
6559   u32 shg = 0;
6560   u8 enable = 1;
6561   int ret;
6562
6563   port_type = L2_API_PORT_TYPE_NORMAL;
6564
6565   /* Parse args required to build the message */
6566   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6567     {
6568       if (unformat (i, "sw_if_index %d", &rx_sw_if_index))
6569         rx_sw_if_index_set = 1;
6570       else if (unformat (i, "bd_id %d", &bd_id))
6571         bd_id_set = 1;
6572       else
6573         if (unformat
6574             (i, "%U", api_unformat_sw_if_index, vam, &rx_sw_if_index))
6575         rx_sw_if_index_set = 1;
6576       else if (unformat (i, "shg %d", &shg))
6577         ;
6578       else if (unformat (i, "bvi"))
6579         port_type = L2_API_PORT_TYPE_BVI;
6580       else if (unformat (i, "uu-fwd"))
6581         port_type = L2_API_PORT_TYPE_UU_FWD;
6582       else if (unformat (i, "enable"))
6583         enable = 1;
6584       else if (unformat (i, "disable"))
6585         enable = 0;
6586       else
6587         break;
6588     }
6589
6590   if (rx_sw_if_index_set == 0)
6591     {
6592       errmsg ("missing rx interface name or sw_if_index");
6593       return -99;
6594     }
6595
6596   if (enable && (bd_id_set == 0))
6597     {
6598       errmsg ("missing bridge domain");
6599       return -99;
6600     }
6601
6602   M (SW_INTERFACE_SET_L2_BRIDGE, mp);
6603
6604   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
6605   mp->bd_id = ntohl (bd_id);
6606   mp->shg = (u8) shg;
6607   mp->port_type = ntohl (port_type);
6608   mp->enable = enable;
6609
6610   S (mp);
6611   W (ret);
6612   return ret;
6613 }
6614
6615 static int
6616 api_bridge_domain_dump (vat_main_t * vam)
6617 {
6618   unformat_input_t *i = vam->input;
6619   vl_api_bridge_domain_dump_t *mp;
6620   vl_api_control_ping_t *mp_ping;
6621   u32 bd_id = ~0;
6622   int ret;
6623
6624   /* Parse args required to build the message */
6625   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6626     {
6627       if (unformat (i, "bd_id %d", &bd_id))
6628         ;
6629       else
6630         break;
6631     }
6632
6633   M (BRIDGE_DOMAIN_DUMP, mp);
6634   mp->bd_id = ntohl (bd_id);
6635   S (mp);
6636
6637   /* Use a control ping for synchronization */
6638   MPING (CONTROL_PING, mp_ping);
6639   S (mp_ping);
6640
6641   W (ret);
6642   return ret;
6643 }
6644
6645 static int
6646 api_bridge_domain_add_del (vat_main_t * vam)
6647 {
6648   unformat_input_t *i = vam->input;
6649   vl_api_bridge_domain_add_del_t *mp;
6650   u32 bd_id = ~0;
6651   u8 is_add = 1;
6652   u32 flood = 1, forward = 1, learn = 1, uu_flood = 1, arp_term = 0;
6653   u8 *bd_tag = NULL;
6654   u32 mac_age = 0;
6655   int ret;
6656
6657   /* Parse args required to build the message */
6658   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6659     {
6660       if (unformat (i, "bd_id %d", &bd_id))
6661         ;
6662       else if (unformat (i, "flood %d", &flood))
6663         ;
6664       else if (unformat (i, "uu-flood %d", &uu_flood))
6665         ;
6666       else if (unformat (i, "forward %d", &forward))
6667         ;
6668       else if (unformat (i, "learn %d", &learn))
6669         ;
6670       else if (unformat (i, "arp-term %d", &arp_term))
6671         ;
6672       else if (unformat (i, "mac-age %d", &mac_age))
6673         ;
6674       else if (unformat (i, "bd-tag %s", &bd_tag))
6675         ;
6676       else if (unformat (i, "del"))
6677         {
6678           is_add = 0;
6679           flood = uu_flood = forward = learn = 0;
6680         }
6681       else
6682         break;
6683     }
6684
6685   if (bd_id == ~0)
6686     {
6687       errmsg ("missing bridge domain");
6688       ret = -99;
6689       goto done;
6690     }
6691
6692   if (mac_age > 255)
6693     {
6694       errmsg ("mac age must be less than 256 ");
6695       ret = -99;
6696       goto done;
6697     }
6698
6699   if ((bd_tag) && (vec_len (bd_tag) > 63))
6700     {
6701       errmsg ("bd-tag cannot be longer than 63");
6702       ret = -99;
6703       goto done;
6704     }
6705
6706   M (BRIDGE_DOMAIN_ADD_DEL, mp);
6707
6708   mp->bd_id = ntohl (bd_id);
6709   mp->flood = flood;
6710   mp->uu_flood = uu_flood;
6711   mp->forward = forward;
6712   mp->learn = learn;
6713   mp->arp_term = arp_term;
6714   mp->is_add = is_add;
6715   mp->mac_age = (u8) mac_age;
6716   if (bd_tag)
6717     {
6718       clib_memcpy (mp->bd_tag, bd_tag, vec_len (bd_tag));
6719       mp->bd_tag[vec_len (bd_tag)] = 0;
6720     }
6721   S (mp);
6722   W (ret);
6723
6724 done:
6725   vec_free (bd_tag);
6726   return ret;
6727 }
6728
6729 static int
6730 api_l2fib_flush_bd (vat_main_t * vam)
6731 {
6732   unformat_input_t *i = vam->input;
6733   vl_api_l2fib_flush_bd_t *mp;
6734   u32 bd_id = ~0;
6735   int ret;
6736
6737   /* Parse args required to build the message */
6738   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6739     {
6740       if (unformat (i, "bd_id %d", &bd_id));
6741       else
6742         break;
6743     }
6744
6745   if (bd_id == ~0)
6746     {
6747       errmsg ("missing bridge domain");
6748       return -99;
6749     }
6750
6751   M (L2FIB_FLUSH_BD, mp);
6752
6753   mp->bd_id = htonl (bd_id);
6754
6755   S (mp);
6756   W (ret);
6757   return ret;
6758 }
6759
6760 static int
6761 api_l2fib_flush_int (vat_main_t * vam)
6762 {
6763   unformat_input_t *i = vam->input;
6764   vl_api_l2fib_flush_int_t *mp;
6765   u32 sw_if_index = ~0;
6766   int ret;
6767
6768   /* Parse args required to build the message */
6769   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6770     {
6771       if (unformat (i, "sw_if_index %d", &sw_if_index));
6772       else
6773         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index));
6774       else
6775         break;
6776     }
6777
6778   if (sw_if_index == ~0)
6779     {
6780       errmsg ("missing interface name or sw_if_index");
6781       return -99;
6782     }
6783
6784   M (L2FIB_FLUSH_INT, mp);
6785
6786   mp->sw_if_index = ntohl (sw_if_index);
6787
6788   S (mp);
6789   W (ret);
6790   return ret;
6791 }
6792
6793 static int
6794 api_l2fib_add_del (vat_main_t * vam)
6795 {
6796   unformat_input_t *i = vam->input;
6797   vl_api_l2fib_add_del_t *mp;
6798   f64 timeout;
6799   u8 mac[6] = { 0 };
6800   u8 mac_set = 0;
6801   u32 bd_id;
6802   u8 bd_id_set = 0;
6803   u32 sw_if_index = 0;
6804   u8 sw_if_index_set = 0;
6805   u8 is_add = 1;
6806   u8 static_mac = 0;
6807   u8 filter_mac = 0;
6808   u8 bvi_mac = 0;
6809   int count = 1;
6810   f64 before = 0;
6811   int j;
6812
6813   /* Parse args required to build the message */
6814   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6815     {
6816       if (unformat (i, "mac %U", unformat_ethernet_address, mac))
6817         mac_set = 1;
6818       else if (unformat (i, "bd_id %d", &bd_id))
6819         bd_id_set = 1;
6820       else if (unformat (i, "sw_if_index %d", &sw_if_index))
6821         sw_if_index_set = 1;
6822       else if (unformat (i, "sw_if"))
6823         {
6824           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6825             {
6826               if (unformat
6827                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
6828                 sw_if_index_set = 1;
6829             }
6830           else
6831             break;
6832         }
6833       else if (unformat (i, "static"))
6834         static_mac = 1;
6835       else if (unformat (i, "filter"))
6836         {
6837           filter_mac = 1;
6838           static_mac = 1;
6839         }
6840       else if (unformat (i, "bvi"))
6841         {
6842           bvi_mac = 1;
6843           static_mac = 1;
6844         }
6845       else if (unformat (i, "del"))
6846         is_add = 0;
6847       else if (unformat (i, "count %d", &count))
6848         ;
6849       else
6850         break;
6851     }
6852
6853   if (mac_set == 0)
6854     {
6855       errmsg ("missing mac address");
6856       return -99;
6857     }
6858
6859   if (bd_id_set == 0)
6860     {
6861       errmsg ("missing bridge domain");
6862       return -99;
6863     }
6864
6865   if (is_add && sw_if_index_set == 0 && filter_mac == 0)
6866     {
6867       errmsg ("missing interface name or sw_if_index");
6868       return -99;
6869     }
6870
6871   if (count > 1)
6872     {
6873       /* Turn on async mode */
6874       vam->async_mode = 1;
6875       vam->async_errors = 0;
6876       before = vat_time_now (vam);
6877     }
6878
6879   for (j = 0; j < count; j++)
6880     {
6881       M (L2FIB_ADD_DEL, mp);
6882
6883       clib_memcpy (mp->mac, mac, 6);
6884       mp->bd_id = ntohl (bd_id);
6885       mp->is_add = is_add;
6886       mp->sw_if_index = ntohl (sw_if_index);
6887
6888       if (is_add)
6889         {
6890           mp->static_mac = static_mac;
6891           mp->filter_mac = filter_mac;
6892           mp->bvi_mac = bvi_mac;
6893         }
6894       increment_mac_address (mac);
6895       /* send it... */
6896       S (mp);
6897     }
6898
6899   if (count > 1)
6900     {
6901       vl_api_control_ping_t *mp_ping;
6902       f64 after;
6903
6904       /* Shut off async mode */
6905       vam->async_mode = 0;
6906
6907       MPING (CONTROL_PING, mp_ping);
6908       S (mp_ping);
6909
6910       timeout = vat_time_now (vam) + 1.0;
6911       while (vat_time_now (vam) < timeout)
6912         if (vam->result_ready == 1)
6913           goto out;
6914       vam->retval = -99;
6915
6916     out:
6917       if (vam->retval == -99)
6918         errmsg ("timeout");
6919
6920       if (vam->async_errors > 0)
6921         {
6922           errmsg ("%d asynchronous errors", vam->async_errors);
6923           vam->retval = -98;
6924         }
6925       vam->async_errors = 0;
6926       after = vat_time_now (vam);
6927
6928       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
6929              count, after - before, count / (after - before));
6930     }
6931   else
6932     {
6933       int ret;
6934
6935       /* Wait for a reply... */
6936       W (ret);
6937       return ret;
6938     }
6939   /* Return the good/bad news */
6940   return (vam->retval);
6941 }
6942
6943 static int
6944 api_bridge_domain_set_mac_age (vat_main_t * vam)
6945 {
6946   unformat_input_t *i = vam->input;
6947   vl_api_bridge_domain_set_mac_age_t *mp;
6948   u32 bd_id = ~0;
6949   u32 mac_age = 0;
6950   int ret;
6951
6952   /* Parse args required to build the message */
6953   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6954     {
6955       if (unformat (i, "bd_id %d", &bd_id));
6956       else if (unformat (i, "mac-age %d", &mac_age));
6957       else
6958         break;
6959     }
6960
6961   if (bd_id == ~0)
6962     {
6963       errmsg ("missing bridge domain");
6964       return -99;
6965     }
6966
6967   if (mac_age > 255)
6968     {
6969       errmsg ("mac age must be less than 256 ");
6970       return -99;
6971     }
6972
6973   M (BRIDGE_DOMAIN_SET_MAC_AGE, mp);
6974
6975   mp->bd_id = htonl (bd_id);
6976   mp->mac_age = (u8) mac_age;
6977
6978   S (mp);
6979   W (ret);
6980   return ret;
6981 }
6982
6983 static int
6984 api_l2_flags (vat_main_t * vam)
6985 {
6986   unformat_input_t *i = vam->input;
6987   vl_api_l2_flags_t *mp;
6988   u32 sw_if_index;
6989   u32 flags = 0;
6990   u8 sw_if_index_set = 0;
6991   u8 is_set = 0;
6992   int ret;
6993
6994   /* Parse args required to build the message */
6995   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
6996     {
6997       if (unformat (i, "sw_if_index %d", &sw_if_index))
6998         sw_if_index_set = 1;
6999       else if (unformat (i, "sw_if"))
7000         {
7001           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7002             {
7003               if (unformat
7004                   (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7005                 sw_if_index_set = 1;
7006             }
7007           else
7008             break;
7009         }
7010       else if (unformat (i, "learn"))
7011         flags |= L2_LEARN;
7012       else if (unformat (i, "forward"))
7013         flags |= L2_FWD;
7014       else if (unformat (i, "flood"))
7015         flags |= L2_FLOOD;
7016       else if (unformat (i, "uu-flood"))
7017         flags |= L2_UU_FLOOD;
7018       else if (unformat (i, "arp-term"))
7019         flags |= L2_ARP_TERM;
7020       else if (unformat (i, "off"))
7021         is_set = 0;
7022       else if (unformat (i, "disable"))
7023         is_set = 0;
7024       else
7025         break;
7026     }
7027
7028   if (sw_if_index_set == 0)
7029     {
7030       errmsg ("missing interface name or sw_if_index");
7031       return -99;
7032     }
7033
7034   M (L2_FLAGS, mp);
7035
7036   mp->sw_if_index = ntohl (sw_if_index);
7037   mp->feature_bitmap = ntohl (flags);
7038   mp->is_set = is_set;
7039
7040   S (mp);
7041   W (ret);
7042   return ret;
7043 }
7044
7045 static int
7046 api_bridge_flags (vat_main_t * vam)
7047 {
7048   unformat_input_t *i = vam->input;
7049   vl_api_bridge_flags_t *mp;
7050   u32 bd_id;
7051   u8 bd_id_set = 0;
7052   u8 is_set = 1;
7053   bd_flags_t flags = 0;
7054   int ret;
7055
7056   /* Parse args required to build the message */
7057   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7058     {
7059       if (unformat (i, "bd_id %d", &bd_id))
7060         bd_id_set = 1;
7061       else if (unformat (i, "learn"))
7062         flags |= BRIDGE_API_FLAG_LEARN;
7063       else if (unformat (i, "forward"))
7064         flags |= BRIDGE_API_FLAG_FWD;
7065       else if (unformat (i, "flood"))
7066         flags |= BRIDGE_API_FLAG_FLOOD;
7067       else if (unformat (i, "uu-flood"))
7068         flags |= BRIDGE_API_FLAG_UU_FLOOD;
7069       else if (unformat (i, "arp-term"))
7070         flags |= BRIDGE_API_FLAG_ARP_TERM;
7071       else if (unformat (i, "off"))
7072         is_set = 0;
7073       else if (unformat (i, "disable"))
7074         is_set = 0;
7075       else
7076         break;
7077     }
7078
7079   if (bd_id_set == 0)
7080     {
7081       errmsg ("missing bridge domain");
7082       return -99;
7083     }
7084
7085   M (BRIDGE_FLAGS, mp);
7086
7087   mp->bd_id = ntohl (bd_id);
7088   mp->flags = ntohl (flags);
7089   mp->is_set = is_set;
7090
7091   S (mp);
7092   W (ret);
7093   return ret;
7094 }
7095
7096 static int
7097 api_bd_ip_mac_add_del (vat_main_t * vam)
7098 {
7099   vl_api_address_t ip = VL_API_ZERO_ADDRESS;
7100   vl_api_mac_address_t mac = { 0 };
7101   unformat_input_t *i = vam->input;
7102   vl_api_bd_ip_mac_add_del_t *mp;
7103   u32 bd_id;
7104   u8 is_add = 1;
7105   u8 bd_id_set = 0;
7106   u8 ip_set = 0;
7107   u8 mac_set = 0;
7108   int ret;
7109
7110
7111   /* Parse args required to build the message */
7112   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7113     {
7114       if (unformat (i, "bd_id %d", &bd_id))
7115         {
7116           bd_id_set++;
7117         }
7118       else if (unformat (i, "%U", unformat_vl_api_address, &ip))
7119         {
7120           ip_set++;
7121         }
7122       else if (unformat (i, "%U", unformat_vl_api_mac_address, &mac))
7123         {
7124           mac_set++;
7125         }
7126       else if (unformat (i, "del"))
7127         is_add = 0;
7128       else
7129         break;
7130     }
7131
7132   if (bd_id_set == 0)
7133     {
7134       errmsg ("missing bridge domain");
7135       return -99;
7136     }
7137   else if (ip_set == 0)
7138     {
7139       errmsg ("missing IP address");
7140       return -99;
7141     }
7142   else if (mac_set == 0)
7143     {
7144       errmsg ("missing MAC address");
7145       return -99;
7146     }
7147
7148   M (BD_IP_MAC_ADD_DEL, mp);
7149
7150   mp->entry.bd_id = ntohl (bd_id);
7151   mp->is_add = is_add;
7152
7153   clib_memcpy (&mp->entry.ip, &ip, sizeof (ip));
7154   clib_memcpy (&mp->entry.mac, &mac, sizeof (mac));
7155
7156   S (mp);
7157   W (ret);
7158   return ret;
7159 }
7160
7161 static int
7162 api_bd_ip_mac_flush (vat_main_t * vam)
7163 {
7164   unformat_input_t *i = vam->input;
7165   vl_api_bd_ip_mac_flush_t *mp;
7166   u32 bd_id;
7167   u8 bd_id_set = 0;
7168   int ret;
7169
7170   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7171     {
7172       if (unformat (i, "bd_id %d", &bd_id))
7173         {
7174           bd_id_set++;
7175         }
7176       else
7177         break;
7178     }
7179
7180   if (bd_id_set == 0)
7181     {
7182       errmsg ("missing bridge domain");
7183       return -99;
7184     }
7185
7186   M (BD_IP_MAC_FLUSH, mp);
7187
7188   mp->bd_id = ntohl (bd_id);
7189
7190   S (mp);
7191   W (ret);
7192   return ret;
7193 }
7194
7195 static void vl_api_bd_ip_mac_details_t_handler
7196   (vl_api_bd_ip_mac_details_t * mp)
7197 {
7198   vat_main_t *vam = &vat_main;
7199
7200   print (vam->ofp,
7201          "\n%-5d %U %U",
7202          ntohl (mp->entry.bd_id),
7203          format_vl_api_mac_address, mp->entry.mac,
7204          format_vl_api_address, &mp->entry.ip);
7205 }
7206
7207 static void vl_api_bd_ip_mac_details_t_handler_json
7208   (vl_api_bd_ip_mac_details_t * mp)
7209 {
7210   vat_main_t *vam = &vat_main;
7211   vat_json_node_t *node = NULL;
7212
7213   if (VAT_JSON_ARRAY != vam->json_tree.type)
7214     {
7215       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
7216       vat_json_init_array (&vam->json_tree);
7217     }
7218   node = vat_json_array_add (&vam->json_tree);
7219
7220   vat_json_init_object (node);
7221   vat_json_object_add_uint (node, "bd_id", ntohl (mp->entry.bd_id));
7222   vat_json_object_add_string_copy (node, "mac_address",
7223                                    format (0, "%U", format_vl_api_mac_address,
7224                                            &mp->entry.mac));
7225   u8 *ip = 0;
7226
7227   ip = format (0, "%U", format_vl_api_address, &mp->entry.ip);
7228   vat_json_object_add_string_copy (node, "ip_address", ip);
7229   vec_free (ip);
7230 }
7231
7232 static int
7233 api_bd_ip_mac_dump (vat_main_t * vam)
7234 {
7235   unformat_input_t *i = vam->input;
7236   vl_api_bd_ip_mac_dump_t *mp;
7237   vl_api_control_ping_t *mp_ping;
7238   int ret;
7239   u32 bd_id;
7240   u8 bd_id_set = 0;
7241
7242   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7243     {
7244       if (unformat (i, "bd_id %d", &bd_id))
7245         {
7246           bd_id_set++;
7247         }
7248       else
7249         break;
7250     }
7251
7252   print (vam->ofp,
7253          "\n%-5s %-7s %-20s %-30s",
7254          "bd_id", "is_ipv6", "mac_address", "ip_address");
7255
7256   /* Dump Bridge Domain Ip to Mac entries */
7257   M (BD_IP_MAC_DUMP, mp);
7258
7259   if (bd_id_set)
7260     mp->bd_id = htonl (bd_id);
7261   else
7262     mp->bd_id = ~0;
7263
7264   S (mp);
7265
7266   /* Use a control ping for synchronization */
7267   MPING (CONTROL_PING, mp_ping);
7268   S (mp_ping);
7269
7270   W (ret);
7271   return ret;
7272 }
7273
7274 static int
7275 api_tap_create_v2 (vat_main_t * vam)
7276 {
7277   unformat_input_t *i = vam->input;
7278   vl_api_tap_create_v2_t *mp;
7279 #define TAP_FLAG_GSO (1 << 0)
7280   u8 mac_address[6];
7281   u8 random_mac = 1;
7282   u32 id = ~0;
7283   u8 *host_if_name = 0;
7284   u8 *host_ns = 0;
7285   u8 host_mac_addr[6];
7286   u8 host_mac_addr_set = 0;
7287   u8 *host_bridge = 0;
7288   ip4_address_t host_ip4_addr;
7289   ip4_address_t host_ip4_gw;
7290   u8 host_ip4_gw_set = 0;
7291   u32 host_ip4_prefix_len = 0;
7292   ip6_address_t host_ip6_addr;
7293   ip6_address_t host_ip6_gw;
7294   u8 host_ip6_gw_set = 0;
7295   u32 host_ip6_prefix_len = 0;
7296   u8 host_mtu_set = 0;
7297   u32 host_mtu_size = 0;
7298   u32 tap_flags = 0;
7299   int ret;
7300   u32 rx_ring_sz = 0, tx_ring_sz = 0;
7301
7302   clib_memset (mac_address, 0, sizeof (mac_address));
7303
7304   /* Parse args required to build the message */
7305   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7306     {
7307       if (unformat (i, "hw-addr %U", unformat_ethernet_address, mac_address))
7308         {
7309           random_mac = 0;
7310         }
7311       else if (unformat (i, "id %u", &id))
7312         ;
7313       else if (unformat (i, "host-if-name %s", &host_if_name))
7314         ;
7315       else if (unformat (i, "host-ns %s", &host_ns))
7316         ;
7317       else if (unformat (i, "host-mac-addr %U", unformat_ethernet_address,
7318                          host_mac_addr))
7319         host_mac_addr_set = 1;
7320       else if (unformat (i, "host-bridge %s", &host_bridge))
7321         ;
7322       else if (unformat (i, "host-ip4-addr %U/%d", unformat_ip4_address,
7323                          &host_ip4_addr, &host_ip4_prefix_len))
7324         ;
7325       else if (unformat (i, "host-ip6-addr %U/%d", unformat_ip6_address,
7326                          &host_ip6_addr, &host_ip6_prefix_len))
7327         ;
7328       else if (unformat (i, "host-ip4-gw %U", unformat_ip4_address,
7329                          &host_ip4_gw))
7330         host_ip4_gw_set = 1;
7331       else if (unformat (i, "host-ip6-gw %U", unformat_ip6_address,
7332                          &host_ip6_gw))
7333         host_ip6_gw_set = 1;
7334       else if (unformat (i, "rx-ring-size %d", &rx_ring_sz))
7335         ;
7336       else if (unformat (i, "tx-ring-size %d", &tx_ring_sz))
7337         ;
7338       else if (unformat (i, "host-mtu-size %d", &host_mtu_size))
7339         host_mtu_set = 1;
7340       else if (unformat (i, "no-gso"))
7341         tap_flags &= ~TAP_FLAG_GSO;
7342       else if (unformat (i, "gso"))
7343         tap_flags |= TAP_FLAG_GSO;
7344       else if (unformat (i, "csum-offload"))
7345         tap_flags |= TAP_FLAG_CSUM_OFFLOAD;
7346       else
7347         break;
7348     }
7349
7350   if (vec_len (host_if_name) > 63)
7351     {
7352       errmsg ("tap name too long. ");
7353       return -99;
7354     }
7355   if (vec_len (host_ns) > 63)
7356     {
7357       errmsg ("host name space too long. ");
7358       return -99;
7359     }
7360   if (vec_len (host_bridge) > 63)
7361     {
7362       errmsg ("host bridge name too long. ");
7363       return -99;
7364     }
7365   if (host_ip4_prefix_len > 32)
7366     {
7367       errmsg ("host ip4 prefix length not valid. ");
7368       return -99;
7369     }
7370   if (host_ip6_prefix_len > 128)
7371     {
7372       errmsg ("host ip6 prefix length not valid. ");
7373       return -99;
7374     }
7375   if (!is_pow2 (rx_ring_sz))
7376     {
7377       errmsg ("rx ring size must be power of 2. ");
7378       return -99;
7379     }
7380   if (rx_ring_sz > 32768)
7381     {
7382       errmsg ("rx ring size must be 32768 or lower. ");
7383       return -99;
7384     }
7385   if (!is_pow2 (tx_ring_sz))
7386     {
7387       errmsg ("tx ring size must be power of 2. ");
7388       return -99;
7389     }
7390   if (tx_ring_sz > 32768)
7391     {
7392       errmsg ("tx ring size must be 32768 or lower. ");
7393       return -99;
7394     }
7395   if (host_mtu_set && (host_mtu_size < 64 || host_mtu_size > 65355))
7396     {
7397       errmsg ("host MTU size must be in between 64 and 65355. ");
7398       return -99;
7399     }
7400
7401   /* Construct the API message */
7402   M (TAP_CREATE_V2, mp);
7403
7404   mp->use_random_mac = random_mac;
7405
7406   mp->id = ntohl (id);
7407   mp->host_namespace_set = host_ns != 0;
7408   mp->host_bridge_set = host_bridge != 0;
7409   mp->host_ip4_prefix_set = host_ip4_prefix_len != 0;
7410   mp->host_ip6_prefix_set = host_ip6_prefix_len != 0;
7411   mp->rx_ring_sz = ntohs (rx_ring_sz);
7412   mp->tx_ring_sz = ntohs (tx_ring_sz);
7413   mp->host_mtu_set = host_mtu_set;
7414   mp->host_mtu_size = ntohl (host_mtu_size);
7415   mp->tap_flags = ntohl (tap_flags);
7416
7417   if (random_mac == 0)
7418     clib_memcpy (mp->mac_address, mac_address, 6);
7419   if (host_mac_addr_set)
7420     clib_memcpy (mp->host_mac_addr, host_mac_addr, 6);
7421   if (host_if_name)
7422     clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
7423   if (host_ns)
7424     clib_memcpy (mp->host_namespace, host_ns, vec_len (host_ns));
7425   if (host_bridge)
7426     clib_memcpy (mp->host_bridge, host_bridge, vec_len (host_bridge));
7427   if (host_ip4_prefix_len)
7428     clib_memcpy (mp->host_ip4_prefix.address, &host_ip4_addr, 4);
7429   if (host_ip6_prefix_len)
7430     clib_memcpy (mp->host_ip6_prefix.address, &host_ip6_addr, 16);
7431   if (host_ip4_gw_set)
7432     clib_memcpy (mp->host_ip4_gw, &host_ip4_gw, 4);
7433   if (host_ip6_gw_set)
7434     clib_memcpy (mp->host_ip6_gw, &host_ip6_gw, 16);
7435
7436   vec_free (host_ns);
7437   vec_free (host_if_name);
7438   vec_free (host_bridge);
7439
7440   /* send it... */
7441   S (mp);
7442
7443   /* Wait for a reply... */
7444   W (ret);
7445   return ret;
7446 }
7447
7448 static int
7449 api_tap_delete_v2 (vat_main_t * vam)
7450 {
7451   unformat_input_t *i = vam->input;
7452   vl_api_tap_delete_v2_t *mp;
7453   u32 sw_if_index = ~0;
7454   u8 sw_if_index_set = 0;
7455   int ret;
7456
7457   /* Parse args required to build the message */
7458   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7459     {
7460       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7461         sw_if_index_set = 1;
7462       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7463         sw_if_index_set = 1;
7464       else
7465         break;
7466     }
7467
7468   if (sw_if_index_set == 0)
7469     {
7470       errmsg ("missing vpp interface name. ");
7471       return -99;
7472     }
7473
7474   /* Construct the API message */
7475   M (TAP_DELETE_V2, mp);
7476
7477   mp->sw_if_index = ntohl (sw_if_index);
7478
7479   /* send it... */
7480   S (mp);
7481
7482   /* Wait for a reply... */
7483   W (ret);
7484   return ret;
7485 }
7486
7487 uword
7488 unformat_vlib_pci_addr (unformat_input_t * input, va_list * args)
7489 {
7490   vlib_pci_addr_t *addr = va_arg (*args, vlib_pci_addr_t *);
7491   u32 x[4];
7492
7493   if (!unformat (input, "%x:%x:%x.%x", &x[0], &x[1], &x[2], &x[3]))
7494     return 0;
7495
7496   addr->domain = x[0];
7497   addr->bus = x[1];
7498   addr->slot = x[2];
7499   addr->function = x[3];
7500
7501   return 1;
7502 }
7503
7504 static int
7505 api_virtio_pci_create (vat_main_t * vam)
7506 {
7507   unformat_input_t *i = vam->input;
7508   vl_api_virtio_pci_create_t *mp;
7509   u8 mac_address[6];
7510   u8 random_mac = 1;
7511   u8 gso_enabled = 0;
7512   u8 checksum_offload_enabled = 0;
7513   u32 pci_addr = 0;
7514   u64 features = (u64) ~ (0ULL);
7515   int ret;
7516
7517   clib_memset (mac_address, 0, sizeof (mac_address));
7518
7519   /* Parse args required to build the message */
7520   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7521     {
7522       if (unformat (i, "hw-addr %U", unformat_ethernet_address, mac_address))
7523         {
7524           random_mac = 0;
7525         }
7526       else if (unformat (i, "pci-addr %U", unformat_vlib_pci_addr, &pci_addr))
7527         ;
7528       else if (unformat (i, "features 0x%llx", &features))
7529         ;
7530       else if (unformat (i, "gso-enabled"))
7531         gso_enabled = 1;
7532       else if (unformat (i, "csum-offload-enabled"))
7533         checksum_offload_enabled = 1;
7534       else
7535         break;
7536     }
7537
7538   if (pci_addr == 0)
7539     {
7540       errmsg ("pci address must be non zero. ");
7541       return -99;
7542     }
7543
7544   /* Construct the API message */
7545   M (VIRTIO_PCI_CREATE, mp);
7546
7547   mp->use_random_mac = random_mac;
7548
7549   mp->pci_addr.domain = htons (((vlib_pci_addr_t) pci_addr).domain);
7550   mp->pci_addr.bus = ((vlib_pci_addr_t) pci_addr).bus;
7551   mp->pci_addr.slot = ((vlib_pci_addr_t) pci_addr).slot;
7552   mp->pci_addr.function = ((vlib_pci_addr_t) pci_addr).function;
7553
7554   mp->features = clib_host_to_net_u64 (features);
7555   mp->gso_enabled = gso_enabled;
7556   mp->checksum_offload_enabled = checksum_offload_enabled;
7557
7558   if (random_mac == 0)
7559     clib_memcpy (mp->mac_address, mac_address, 6);
7560
7561   /* send it... */
7562   S (mp);
7563
7564   /* Wait for a reply... */
7565   W (ret);
7566   return ret;
7567 }
7568
7569 static int
7570 api_virtio_pci_delete (vat_main_t * vam)
7571 {
7572   unformat_input_t *i = vam->input;
7573   vl_api_virtio_pci_delete_t *mp;
7574   u32 sw_if_index = ~0;
7575   u8 sw_if_index_set = 0;
7576   int ret;
7577
7578   /* Parse args required to build the message */
7579   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7580     {
7581       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7582         sw_if_index_set = 1;
7583       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7584         sw_if_index_set = 1;
7585       else
7586         break;
7587     }
7588
7589   if (sw_if_index_set == 0)
7590     {
7591       errmsg ("missing vpp interface name. ");
7592       return -99;
7593     }
7594
7595   /* Construct the API message */
7596   M (VIRTIO_PCI_DELETE, mp);
7597
7598   mp->sw_if_index = htonl (sw_if_index);
7599
7600   /* send it... */
7601   S (mp);
7602
7603   /* Wait for a reply... */
7604   W (ret);
7605   return ret;
7606 }
7607
7608 static int
7609 api_bond_create (vat_main_t * vam)
7610 {
7611   unformat_input_t *i = vam->input;
7612   vl_api_bond_create_t *mp;
7613   u8 mac_address[6];
7614   u8 custom_mac = 0;
7615   int ret;
7616   u8 mode;
7617   u8 lb;
7618   u8 mode_is_set = 0;
7619   u32 id = ~0;
7620   u8 numa_only = 0;
7621
7622   clib_memset (mac_address, 0, sizeof (mac_address));
7623   lb = BOND_LB_L2;
7624
7625   /* Parse args required to build the message */
7626   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7627     {
7628       if (unformat (i, "mode %U", unformat_bond_mode, &mode))
7629         mode_is_set = 1;
7630       else if (((mode == BOND_MODE_LACP) || (mode == BOND_MODE_XOR))
7631                && unformat (i, "lb %U", unformat_bond_load_balance, &lb))
7632         ;
7633       else if (unformat (i, "hw-addr %U", unformat_ethernet_address,
7634                          mac_address))
7635         custom_mac = 1;
7636       else if (unformat (i, "numa-only"))
7637         numa_only = 1;
7638       else if (unformat (i, "id %u", &id))
7639         ;
7640       else
7641         break;
7642     }
7643
7644   if (mode_is_set == 0)
7645     {
7646       errmsg ("Missing bond mode. ");
7647       return -99;
7648     }
7649
7650   /* Construct the API message */
7651   M (BOND_CREATE, mp);
7652
7653   mp->use_custom_mac = custom_mac;
7654
7655   mp->mode = htonl (mode);
7656   mp->lb = htonl (lb);
7657   mp->id = htonl (id);
7658   mp->numa_only = numa_only;
7659
7660   if (custom_mac)
7661     clib_memcpy (mp->mac_address, mac_address, 6);
7662
7663   /* send it... */
7664   S (mp);
7665
7666   /* Wait for a reply... */
7667   W (ret);
7668   return ret;
7669 }
7670
7671 static int
7672 api_bond_delete (vat_main_t * vam)
7673 {
7674   unformat_input_t *i = vam->input;
7675   vl_api_bond_delete_t *mp;
7676   u32 sw_if_index = ~0;
7677   u8 sw_if_index_set = 0;
7678   int ret;
7679
7680   /* Parse args required to build the message */
7681   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7682     {
7683       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7684         sw_if_index_set = 1;
7685       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7686         sw_if_index_set = 1;
7687       else
7688         break;
7689     }
7690
7691   if (sw_if_index_set == 0)
7692     {
7693       errmsg ("missing vpp interface name. ");
7694       return -99;
7695     }
7696
7697   /* Construct the API message */
7698   M (BOND_DELETE, mp);
7699
7700   mp->sw_if_index = ntohl (sw_if_index);
7701
7702   /* send it... */
7703   S (mp);
7704
7705   /* Wait for a reply... */
7706   W (ret);
7707   return ret;
7708 }
7709
7710 static int
7711 api_bond_enslave (vat_main_t * vam)
7712 {
7713   unformat_input_t *i = vam->input;
7714   vl_api_bond_enslave_t *mp;
7715   u32 bond_sw_if_index;
7716   int ret;
7717   u8 is_passive;
7718   u8 is_long_timeout;
7719   u32 bond_sw_if_index_is_set = 0;
7720   u32 sw_if_index;
7721   u8 sw_if_index_is_set = 0;
7722
7723   /* Parse args required to build the message */
7724   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7725     {
7726       if (unformat (i, "sw_if_index %d", &sw_if_index))
7727         sw_if_index_is_set = 1;
7728       else if (unformat (i, "bond %u", &bond_sw_if_index))
7729         bond_sw_if_index_is_set = 1;
7730       else if (unformat (i, "passive %d", &is_passive))
7731         ;
7732       else if (unformat (i, "long-timeout %d", &is_long_timeout))
7733         ;
7734       else
7735         break;
7736     }
7737
7738   if (bond_sw_if_index_is_set == 0)
7739     {
7740       errmsg ("Missing bond sw_if_index. ");
7741       return -99;
7742     }
7743   if (sw_if_index_is_set == 0)
7744     {
7745       errmsg ("Missing slave sw_if_index. ");
7746       return -99;
7747     }
7748
7749   /* Construct the API message */
7750   M (BOND_ENSLAVE, mp);
7751
7752   mp->bond_sw_if_index = ntohl (bond_sw_if_index);
7753   mp->sw_if_index = ntohl (sw_if_index);
7754   mp->is_long_timeout = is_long_timeout;
7755   mp->is_passive = is_passive;
7756
7757   /* send it... */
7758   S (mp);
7759
7760   /* Wait for a reply... */
7761   W (ret);
7762   return ret;
7763 }
7764
7765 static int
7766 api_bond_detach_slave (vat_main_t * vam)
7767 {
7768   unformat_input_t *i = vam->input;
7769   vl_api_bond_detach_slave_t *mp;
7770   u32 sw_if_index = ~0;
7771   u8 sw_if_index_set = 0;
7772   int ret;
7773
7774   /* Parse args required to build the message */
7775   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7776     {
7777       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
7778         sw_if_index_set = 1;
7779       else if (unformat (i, "sw_if_index %d", &sw_if_index))
7780         sw_if_index_set = 1;
7781       else
7782         break;
7783     }
7784
7785   if (sw_if_index_set == 0)
7786     {
7787       errmsg ("missing vpp interface name. ");
7788       return -99;
7789     }
7790
7791   /* Construct the API message */
7792   M (BOND_DETACH_SLAVE, mp);
7793
7794   mp->sw_if_index = ntohl (sw_if_index);
7795
7796   /* send it... */
7797   S (mp);
7798
7799   /* Wait for a reply... */
7800   W (ret);
7801   return ret;
7802 }
7803
7804 static int
7805 api_ip_table_add_del (vat_main_t * vam)
7806 {
7807   unformat_input_t *i = vam->input;
7808   vl_api_ip_table_add_del_t *mp;
7809   u32 table_id = ~0;
7810   u8 is_ipv6 = 0;
7811   u8 is_add = 1;
7812   int ret = 0;
7813
7814   /* Parse args required to build the message */
7815   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
7816     {
7817       if (unformat (i, "ipv6"))
7818         is_ipv6 = 1;
7819       else if (unformat (i, "del"))
7820         is_add = 0;
7821       else if (unformat (i, "add"))
7822         is_add = 1;
7823       else if (unformat (i, "table %d", &table_id))
7824         ;
7825       else
7826         {
7827           clib_warning ("parse error '%U'", format_unformat_error, i);
7828           return -99;
7829         }
7830     }
7831
7832   if (~0 == table_id)
7833     {
7834       errmsg ("missing table-ID");
7835       return -99;
7836     }
7837
7838   /* Construct the API message */
7839   M (IP_TABLE_ADD_DEL, mp);
7840
7841   mp->table.table_id = ntohl (table_id);
7842   mp->table.is_ip6 = is_ipv6;
7843   mp->is_add = is_add;
7844
7845   /* send it... */
7846   S (mp);
7847
7848   /* Wait for a reply... */
7849   W (ret);
7850
7851   return ret;
7852 }
7853
7854 uword
7855 unformat_fib_path (unformat_input_t * input, va_list * args)
7856 {
7857   vat_main_t *vam = va_arg (*args, vat_main_t *);
7858   vl_api_fib_path_t *path = va_arg (*args, vl_api_fib_path_t *);
7859   u32 weight, preference;
7860   mpls_label_t out_label;
7861
7862   clib_memset (path, 0, sizeof (*path));
7863   path->weight = 1;
7864   path->sw_if_index = ~0;
7865   path->rpf_id = ~0;
7866   path->n_labels = 0;
7867
7868   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
7869     {
7870       if (unformat (input, "%U %U",
7871                     unformat_vl_api_ip4_address,
7872                     &path->nh.address.ip4,
7873                     api_unformat_sw_if_index, vam, &path->sw_if_index))
7874         {
7875           path->proto = FIB_API_PATH_NH_PROTO_IP4;
7876         }
7877       else if (unformat (input, "%U %U",
7878                          unformat_vl_api_ip6_address,
7879                          &path->nh.address.ip6,
7880                          api_unformat_sw_if_index, vam, &path->sw_if_index))
7881         {
7882           path->proto = FIB_API_PATH_NH_PROTO_IP6;
7883         }
7884       else if (unformat (input, "weight %u", &weight))
7885         {
7886           path->weight = weight;
7887         }
7888       else if (unformat (input, "preference %u", &preference))
7889         {
7890           path->preference = preference;
7891         }
7892       else if (unformat (input, "%U next-hop-table %d",
7893                          unformat_vl_api_ip4_address,
7894                          &path->nh.address.ip4, &path->table_id))
7895         {
7896           path->proto = FIB_API_PATH_NH_PROTO_IP4;
7897         }
7898       else if (unformat (input, "%U next-hop-table %d",
7899                          unformat_vl_api_ip6_address,
7900                          &path->nh.address.ip6, &path->table_id))
7901         {
7902           path->proto = FIB_API_PATH_NH_PROTO_IP6;
7903         }
7904       else if (unformat (input, "%U",
7905                          unformat_vl_api_ip4_address, &path->nh.address.ip4))
7906         {
7907           /*
7908            * the recursive next-hops are by default in the default table
7909            */
7910           path->table_id = 0;
7911           path->sw_if_index = ~0;
7912           path->proto = FIB_API_PATH_NH_PROTO_IP4;
7913         }
7914       else if (unformat (input, "%U",
7915                          unformat_vl_api_ip6_address, &path->nh.address.ip6))
7916         {
7917           /*
7918            * the recursive next-hops are by default in the default table
7919            */
7920           path->table_id = 0;
7921           path->sw_if_index = ~0;
7922           path->proto = FIB_API_PATH_NH_PROTO_IP6;
7923         }
7924       else if (unformat (input, "resolve-via-host"))
7925         {
7926           path->flags |= FIB_API_PATH_FLAG_RESOLVE_VIA_HOST;
7927         }
7928       else if (unformat (input, "resolve-via-attached"))
7929         {
7930           path->flags |= FIB_API_PATH_FLAG_RESOLVE_VIA_ATTACHED;
7931         }
7932       else if (unformat (input, "ip4-lookup-in-table %d", &path->table_id))
7933         {
7934           path->type = FIB_API_PATH_TYPE_LOCAL;
7935           path->sw_if_index = ~0;
7936           path->proto = FIB_API_PATH_NH_PROTO_IP4;
7937         }
7938       else if (unformat (input, "ip6-lookup-in-table %d", &path->table_id))
7939         {
7940           path->type = FIB_API_PATH_TYPE_LOCAL;
7941           path->sw_if_index = ~0;
7942           path->proto = FIB_API_PATH_NH_PROTO_IP6;
7943         }
7944       else if (unformat (input, "sw_if_index %d", &path->sw_if_index))
7945         ;
7946       else if (unformat (input, "via-label %d", &path->nh.via_label))
7947         {
7948           path->proto = FIB_API_PATH_NH_PROTO_MPLS;
7949           path->sw_if_index = ~0;
7950         }
7951       else if (unformat (input, "l2-input-on %d", &path->sw_if_index))
7952         {
7953           path->proto = FIB_API_PATH_NH_PROTO_ETHERNET;
7954           path->type = FIB_API_PATH_TYPE_INTERFACE_RX;
7955         }
7956       else if (unformat (input, "local"))
7957         {
7958           path->type = FIB_API_PATH_TYPE_LOCAL;
7959         }
7960       else if (unformat (input, "out-labels"))
7961         {
7962           while (unformat (input, "%d", &out_label))
7963             {
7964               path->label_stack[path->n_labels].label = out_label;
7965               path->label_stack[path->n_labels].is_uniform = 0;
7966               path->label_stack[path->n_labels].ttl = 64;
7967               path->n_labels++;
7968             }
7969         }
7970       else if (unformat (input, "via"))
7971         {
7972           /* new path, back up and return */
7973           unformat_put_input (input);
7974           unformat_put_input (input);
7975           unformat_put_input (input);
7976           unformat_put_input (input);
7977           break;
7978         }
7979       else
7980         {
7981           return (0);
7982         }
7983     }
7984
7985   path->proto = ntohl (path->proto);
7986   path->type = ntohl (path->type);
7987   path->flags = ntohl (path->flags);
7988   path->table_id = ntohl (path->table_id);
7989   path->sw_if_index = ntohl (path->sw_if_index);
7990
7991   return (1);
7992 }
7993
7994 static int
7995 api_ip_route_add_del (vat_main_t * vam)
7996 {
7997   unformat_input_t *i = vam->input;
7998   vl_api_ip_route_add_del_t *mp;
7999   u32 vrf_id = 0;
8000   u8 is_add = 1;
8001   u8 is_multipath = 0;
8002   u8 prefix_set = 0;
8003   u8 path_count = 0;
8004   vl_api_prefix_t pfx = { };
8005   vl_api_fib_path_t paths[8];
8006   int count = 1;
8007   int j;
8008   f64 before = 0;
8009   u32 random_add_del = 0;
8010   u32 *random_vector = 0;
8011   u32 random_seed = 0xdeaddabe;
8012
8013   /* Parse args required to build the message */
8014   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8015     {
8016       if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
8017         prefix_set = 1;
8018       else if (unformat (i, "del"))
8019         is_add = 0;
8020       else if (unformat (i, "add"))
8021         is_add = 1;
8022       else if (unformat (i, "vrf %d", &vrf_id))
8023         ;
8024       else if (unformat (i, "count %d", &count))
8025         ;
8026       else if (unformat (i, "random"))
8027         random_add_del = 1;
8028       else if (unformat (i, "multipath"))
8029         is_multipath = 1;
8030       else if (unformat (i, "seed %d", &random_seed))
8031         ;
8032       else
8033         if (unformat
8034             (i, "via %U", unformat_fib_path, vam, &paths[path_count]))
8035         {
8036           path_count++;
8037           if (8 == path_count)
8038             {
8039               errmsg ("max 8 paths");
8040               return -99;
8041             }
8042         }
8043       else
8044         {
8045           clib_warning ("parse error '%U'", format_unformat_error, i);
8046           return -99;
8047         }
8048     }
8049
8050   if (!path_count)
8051     {
8052       errmsg ("specify a path; via ...");
8053       return -99;
8054     }
8055   if (prefix_set == 0)
8056     {
8057       errmsg ("missing prefix");
8058       return -99;
8059     }
8060
8061   /* Generate a pile of unique, random routes */
8062   if (random_add_del)
8063     {
8064       ip4_address_t *i = (ip4_address_t *) & paths[0].nh.address.ip4;
8065       u32 this_random_address;
8066       uword *random_hash;
8067
8068       random_hash = hash_create (count, sizeof (uword));
8069
8070       hash_set (random_hash, i->as_u32, 1);
8071       for (j = 0; j <= count; j++)
8072         {
8073           do
8074             {
8075               this_random_address = random_u32 (&random_seed);
8076               this_random_address =
8077                 clib_host_to_net_u32 (this_random_address);
8078             }
8079           while (hash_get (random_hash, this_random_address));
8080           vec_add1 (random_vector, this_random_address);
8081           hash_set (random_hash, this_random_address, 1);
8082         }
8083       hash_free (random_hash);
8084       set_ip4_address (&pfx.address, random_vector[0]);
8085     }
8086
8087   if (count > 1)
8088     {
8089       /* Turn on async mode */
8090       vam->async_mode = 1;
8091       vam->async_errors = 0;
8092       before = vat_time_now (vam);
8093     }
8094
8095   for (j = 0; j < count; j++)
8096     {
8097       /* Construct the API message */
8098       M2 (IP_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t) * path_count);
8099
8100       mp->is_add = is_add;
8101       mp->is_multipath = is_multipath;
8102
8103       clib_memcpy (&mp->route.prefix, &pfx, sizeof (pfx));
8104       mp->route.table_id = ntohl (vrf_id);
8105       mp->route.n_paths = path_count;
8106
8107       clib_memcpy (&mp->route.paths, &paths, sizeof (paths[0]) * path_count);
8108
8109       if (random_add_del)
8110         set_ip4_address (&pfx.address, random_vector[j + 1]);
8111       else
8112         increment_address (&pfx.address);
8113       /* send it... */
8114       S (mp);
8115       /* If we receive SIGTERM, stop now... */
8116       if (vam->do_exit)
8117         break;
8118     }
8119
8120   /* When testing multiple add/del ops, use a control-ping to sync */
8121   if (count > 1)
8122     {
8123       vl_api_control_ping_t *mp_ping;
8124       f64 after;
8125       f64 timeout;
8126
8127       /* Shut off async mode */
8128       vam->async_mode = 0;
8129
8130       MPING (CONTROL_PING, mp_ping);
8131       S (mp_ping);
8132
8133       timeout = vat_time_now (vam) + 1.0;
8134       while (vat_time_now (vam) < timeout)
8135         if (vam->result_ready == 1)
8136           goto out;
8137       vam->retval = -99;
8138
8139     out:
8140       if (vam->retval == -99)
8141         errmsg ("timeout");
8142
8143       if (vam->async_errors > 0)
8144         {
8145           errmsg ("%d asynchronous errors", vam->async_errors);
8146           vam->retval = -98;
8147         }
8148       vam->async_errors = 0;
8149       after = vat_time_now (vam);
8150
8151       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8152       if (j > 0)
8153         count = j;
8154
8155       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8156              count, after - before, count / (after - before));
8157     }
8158   else
8159     {
8160       int ret;
8161
8162       /* Wait for a reply... */
8163       W (ret);
8164       return ret;
8165     }
8166
8167   /* Return the good/bad news */
8168   return (vam->retval);
8169 }
8170
8171 static int
8172 api_ip_mroute_add_del (vat_main_t * vam)
8173 {
8174   unformat_input_t *i = vam->input;
8175   u8 path_set = 0, prefix_set = 0, is_add = 1;
8176   vl_api_ip_mroute_add_del_t *mp;
8177   mfib_entry_flags_t eflags = 0;
8178   vl_api_mfib_path_t path;
8179   vl_api_mprefix_t pfx = { };
8180   u32 vrf_id = 0;
8181   int ret;
8182
8183   /* Parse args required to build the message */
8184   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8185     {
8186       if (unformat (i, "%U", unformat_vl_api_mprefix, &pfx))
8187         {
8188           prefix_set = 1;
8189           pfx.grp_address_length = htons (pfx.grp_address_length);
8190         }
8191       else if (unformat (i, "del"))
8192         is_add = 0;
8193       else if (unformat (i, "add"))
8194         is_add = 1;
8195       else if (unformat (i, "vrf %d", &vrf_id))
8196         ;
8197       else if (unformat (i, "%U", unformat_mfib_itf_flags, &path.itf_flags))
8198         path.itf_flags = htonl (path.itf_flags);
8199       else if (unformat (i, "%U", unformat_mfib_entry_flags, &eflags))
8200         ;
8201       else if (unformat (i, "via %U", unformat_fib_path, vam, &path.path))
8202         path_set = 1;
8203       else
8204         {
8205           clib_warning ("parse error '%U'", format_unformat_error, i);
8206           return -99;
8207         }
8208     }
8209
8210   if (prefix_set == 0)
8211     {
8212       errmsg ("missing addresses\n");
8213       return -99;
8214     }
8215   if (path_set == 0)
8216     {
8217       errmsg ("missing path\n");
8218       return -99;
8219     }
8220
8221   /* Construct the API message */
8222   M (IP_MROUTE_ADD_DEL, mp);
8223
8224   mp->is_add = is_add;
8225   mp->is_multipath = 1;
8226
8227   clib_memcpy (&mp->route.prefix, &pfx, sizeof (pfx));
8228   mp->route.table_id = htonl (vrf_id);
8229   mp->route.n_paths = 1;
8230   mp->route.entry_flags = htonl (eflags);
8231
8232   clib_memcpy (&mp->route.paths, &path, sizeof (path));
8233
8234   /* send it... */
8235   S (mp);
8236   /* Wait for a reply... */
8237   W (ret);
8238   return ret;
8239 }
8240
8241 static int
8242 api_mpls_table_add_del (vat_main_t * vam)
8243 {
8244   unformat_input_t *i = vam->input;
8245   vl_api_mpls_table_add_del_t *mp;
8246   u32 table_id = ~0;
8247   u8 is_add = 1;
8248   int ret = 0;
8249
8250   /* Parse args required to build the message */
8251   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8252     {
8253       if (unformat (i, "table %d", &table_id))
8254         ;
8255       else if (unformat (i, "del"))
8256         is_add = 0;
8257       else if (unformat (i, "add"))
8258         is_add = 1;
8259       else
8260         {
8261           clib_warning ("parse error '%U'", format_unformat_error, i);
8262           return -99;
8263         }
8264     }
8265
8266   if (~0 == table_id)
8267     {
8268       errmsg ("missing table-ID");
8269       return -99;
8270     }
8271
8272   /* Construct the API message */
8273   M (MPLS_TABLE_ADD_DEL, mp);
8274
8275   mp->mt_table.mt_table_id = ntohl (table_id);
8276   mp->mt_is_add = is_add;
8277
8278   /* send it... */
8279   S (mp);
8280
8281   /* Wait for a reply... */
8282   W (ret);
8283
8284   return ret;
8285 }
8286
8287 static int
8288 api_mpls_route_add_del (vat_main_t * vam)
8289 {
8290   u8 is_add = 1, path_count = 0, is_multipath = 0, is_eos = 0;
8291   mpls_label_t local_label = MPLS_LABEL_INVALID;
8292   unformat_input_t *i = vam->input;
8293   vl_api_mpls_route_add_del_t *mp;
8294   vl_api_fib_path_t paths[8];
8295   int count = 1, j;
8296   f64 before = 0;
8297
8298   /* Parse args required to build the message */
8299   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8300     {
8301       if (unformat (i, "%d", &local_label))
8302         ;
8303       else if (unformat (i, "eos"))
8304         is_eos = 1;
8305       else if (unformat (i, "non-eos"))
8306         is_eos = 0;
8307       else if (unformat (i, "del"))
8308         is_add = 0;
8309       else if (unformat (i, "add"))
8310         is_add = 1;
8311       else if (unformat (i, "multipath"))
8312         is_multipath = 1;
8313       else if (unformat (i, "count %d", &count))
8314         ;
8315       else
8316         if (unformat
8317             (i, "via %U", unformat_fib_path, vam, &paths[path_count]))
8318         {
8319           path_count++;
8320           if (8 == path_count)
8321             {
8322               errmsg ("max 8 paths");
8323               return -99;
8324             }
8325         }
8326       else
8327         {
8328           clib_warning ("parse error '%U'", format_unformat_error, i);
8329           return -99;
8330         }
8331     }
8332
8333   if (!path_count)
8334     {
8335       errmsg ("specify a path; via ...");
8336       return -99;
8337     }
8338
8339   if (MPLS_LABEL_INVALID == local_label)
8340     {
8341       errmsg ("missing label");
8342       return -99;
8343     }
8344
8345   if (count > 1)
8346     {
8347       /* Turn on async mode */
8348       vam->async_mode = 1;
8349       vam->async_errors = 0;
8350       before = vat_time_now (vam);
8351     }
8352
8353   for (j = 0; j < count; j++)
8354     {
8355       /* Construct the API message */
8356       M2 (MPLS_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t) * path_count);
8357
8358       mp->mr_is_add = is_add;
8359       mp->mr_is_multipath = is_multipath;
8360
8361       mp->mr_route.mr_label = local_label;
8362       mp->mr_route.mr_eos = is_eos;
8363       mp->mr_route.mr_table_id = 0;
8364       mp->mr_route.mr_n_paths = path_count;
8365
8366       clib_memcpy (&mp->mr_route.mr_paths, paths,
8367                    sizeof (paths[0]) * path_count);
8368
8369       local_label++;
8370
8371       /* send it... */
8372       S (mp);
8373       /* If we receive SIGTERM, stop now... */
8374       if (vam->do_exit)
8375         break;
8376     }
8377
8378   /* When testing multiple add/del ops, use a control-ping to sync */
8379   if (count > 1)
8380     {
8381       vl_api_control_ping_t *mp_ping;
8382       f64 after;
8383       f64 timeout;
8384
8385       /* Shut off async mode */
8386       vam->async_mode = 0;
8387
8388       MPING (CONTROL_PING, mp_ping);
8389       S (mp_ping);
8390
8391       timeout = vat_time_now (vam) + 1.0;
8392       while (vat_time_now (vam) < timeout)
8393         if (vam->result_ready == 1)
8394           goto out;
8395       vam->retval = -99;
8396
8397     out:
8398       if (vam->retval == -99)
8399         errmsg ("timeout");
8400
8401       if (vam->async_errors > 0)
8402         {
8403           errmsg ("%d asynchronous errors", vam->async_errors);
8404           vam->retval = -98;
8405         }
8406       vam->async_errors = 0;
8407       after = vat_time_now (vam);
8408
8409       /* slim chance, but we might have eaten SIGTERM on the first iteration */
8410       if (j > 0)
8411         count = j;
8412
8413       print (vam->ofp, "%d routes in %.6f secs, %.2f routes/sec",
8414              count, after - before, count / (after - before));
8415     }
8416   else
8417     {
8418       int ret;
8419
8420       /* Wait for a reply... */
8421       W (ret);
8422       return ret;
8423     }
8424
8425   /* Return the good/bad news */
8426   return (vam->retval);
8427   return (0);
8428 }
8429
8430 static int
8431 api_mpls_ip_bind_unbind (vat_main_t * vam)
8432 {
8433   unformat_input_t *i = vam->input;
8434   vl_api_mpls_ip_bind_unbind_t *mp;
8435   u32 ip_table_id = 0;
8436   u8 is_bind = 1;
8437   vl_api_prefix_t pfx;
8438   u8 prefix_set = 0;
8439   mpls_label_t local_label = MPLS_LABEL_INVALID;
8440   int ret;
8441
8442   /* Parse args required to build the message */
8443   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8444     {
8445       if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
8446         prefix_set = 1;
8447       else if (unformat (i, "%d", &local_label))
8448         ;
8449       else if (unformat (i, "table-id %d", &ip_table_id))
8450         ;
8451       else if (unformat (i, "unbind"))
8452         is_bind = 0;
8453       else if (unformat (i, "bind"))
8454         is_bind = 1;
8455       else
8456         {
8457           clib_warning ("parse error '%U'", format_unformat_error, i);
8458           return -99;
8459         }
8460     }
8461
8462   if (!prefix_set)
8463     {
8464       errmsg ("IP prefix not set");
8465       return -99;
8466     }
8467
8468   if (MPLS_LABEL_INVALID == local_label)
8469     {
8470       errmsg ("missing label");
8471       return -99;
8472     }
8473
8474   /* Construct the API message */
8475   M (MPLS_IP_BIND_UNBIND, mp);
8476
8477   mp->mb_is_bind = is_bind;
8478   mp->mb_ip_table_id = ntohl (ip_table_id);
8479   mp->mb_mpls_table_id = 0;
8480   mp->mb_label = ntohl (local_label);
8481   clib_memcpy (&mp->mb_prefix, &pfx, sizeof (pfx));
8482
8483   /* send it... */
8484   S (mp);
8485
8486   /* Wait for a reply... */
8487   W (ret);
8488   return ret;
8489   return (0);
8490 }
8491
8492 static int
8493 api_sr_mpls_policy_add (vat_main_t * vam)
8494 {
8495   unformat_input_t *i = vam->input;
8496   vl_api_sr_mpls_policy_add_t *mp;
8497   u32 bsid = 0;
8498   u32 weight = 1;
8499   u8 type = 0;
8500   u8 n_segments = 0;
8501   u32 sid;
8502   u32 *segments = NULL;
8503   int ret;
8504
8505   /* Parse args required to build the message */
8506   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8507     {
8508       if (unformat (i, "bsid %d", &bsid))
8509         ;
8510       else if (unformat (i, "weight %d", &weight))
8511         ;
8512       else if (unformat (i, "spray"))
8513         type = 1;
8514       else if (unformat (i, "next %d", &sid))
8515         {
8516           n_segments += 1;
8517           vec_add1 (segments, htonl (sid));
8518         }
8519       else
8520         {
8521           clib_warning ("parse error '%U'", format_unformat_error, i);
8522           return -99;
8523         }
8524     }
8525
8526   if (bsid == 0)
8527     {
8528       errmsg ("bsid not set");
8529       return -99;
8530     }
8531
8532   if (n_segments == 0)
8533     {
8534       errmsg ("no sid in segment stack");
8535       return -99;
8536     }
8537
8538   /* Construct the API message */
8539   M2 (SR_MPLS_POLICY_ADD, mp, sizeof (u32) * n_segments);
8540
8541   mp->bsid = htonl (bsid);
8542   mp->weight = htonl (weight);
8543   mp->type = type;
8544   mp->n_segments = n_segments;
8545   memcpy (mp->segments, segments, sizeof (u32) * n_segments);
8546   vec_free (segments);
8547
8548   /* send it... */
8549   S (mp);
8550
8551   /* Wait for a reply... */
8552   W (ret);
8553   return ret;
8554 }
8555
8556 static int
8557 api_sr_mpls_policy_del (vat_main_t * vam)
8558 {
8559   unformat_input_t *i = vam->input;
8560   vl_api_sr_mpls_policy_del_t *mp;
8561   u32 bsid = 0;
8562   int ret;
8563
8564   /* Parse args required to build the message */
8565   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8566     {
8567       if (unformat (i, "bsid %d", &bsid))
8568         ;
8569       else
8570         {
8571           clib_warning ("parse error '%U'", format_unformat_error, i);
8572           return -99;
8573         }
8574     }
8575
8576   if (bsid == 0)
8577     {
8578       errmsg ("bsid not set");
8579       return -99;
8580     }
8581
8582   /* Construct the API message */
8583   M (SR_MPLS_POLICY_DEL, mp);
8584
8585   mp->bsid = htonl (bsid);
8586
8587   /* send it... */
8588   S (mp);
8589
8590   /* Wait for a reply... */
8591   W (ret);
8592   return ret;
8593 }
8594
8595 static int
8596 api_bier_table_add_del (vat_main_t * vam)
8597 {
8598   unformat_input_t *i = vam->input;
8599   vl_api_bier_table_add_del_t *mp;
8600   u8 is_add = 1;
8601   u32 set = 0, sub_domain = 0, hdr_len = 3;
8602   mpls_label_t local_label = MPLS_LABEL_INVALID;
8603   int ret;
8604
8605   /* Parse args required to build the message */
8606   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8607     {
8608       if (unformat (i, "sub-domain %d", &sub_domain))
8609         ;
8610       else if (unformat (i, "set %d", &set))
8611         ;
8612       else if (unformat (i, "label %d", &local_label))
8613         ;
8614       else if (unformat (i, "hdr-len %d", &hdr_len))
8615         ;
8616       else if (unformat (i, "add"))
8617         is_add = 1;
8618       else if (unformat (i, "del"))
8619         is_add = 0;
8620       else
8621         {
8622           clib_warning ("parse error '%U'", format_unformat_error, i);
8623           return -99;
8624         }
8625     }
8626
8627   if (MPLS_LABEL_INVALID == local_label)
8628     {
8629       errmsg ("missing label\n");
8630       return -99;
8631     }
8632
8633   /* Construct the API message */
8634   M (BIER_TABLE_ADD_DEL, mp);
8635
8636   mp->bt_is_add = is_add;
8637   mp->bt_label = ntohl (local_label);
8638   mp->bt_tbl_id.bt_set = set;
8639   mp->bt_tbl_id.bt_sub_domain = sub_domain;
8640   mp->bt_tbl_id.bt_hdr_len_id = hdr_len;
8641
8642   /* send it... */
8643   S (mp);
8644
8645   /* Wait for a reply... */
8646   W (ret);
8647
8648   return (ret);
8649 }
8650
8651 static int
8652 api_bier_route_add_del (vat_main_t * vam)
8653 {
8654   unformat_input_t *i = vam->input;
8655   vl_api_bier_route_add_del_t *mp;
8656   u8 is_add = 1;
8657   u32 set = 0, sub_domain = 0, hdr_len = 3, bp = 0;
8658   ip4_address_t v4_next_hop_address;
8659   ip6_address_t v6_next_hop_address;
8660   u8 next_hop_set = 0;
8661   u8 next_hop_proto_is_ip4 = 1;
8662   mpls_label_t next_hop_out_label = MPLS_LABEL_INVALID;
8663   int ret;
8664
8665   /* Parse args required to build the message */
8666   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8667     {
8668       if (unformat (i, "%U", unformat_ip4_address, &v4_next_hop_address))
8669         {
8670           next_hop_proto_is_ip4 = 1;
8671           next_hop_set = 1;
8672         }
8673       else if (unformat (i, "%U", unformat_ip6_address, &v6_next_hop_address))
8674         {
8675           next_hop_proto_is_ip4 = 0;
8676           next_hop_set = 1;
8677         }
8678       if (unformat (i, "sub-domain %d", &sub_domain))
8679         ;
8680       else if (unformat (i, "set %d", &set))
8681         ;
8682       else if (unformat (i, "hdr-len %d", &hdr_len))
8683         ;
8684       else if (unformat (i, "bp %d", &bp))
8685         ;
8686       else if (unformat (i, "add"))
8687         is_add = 1;
8688       else if (unformat (i, "del"))
8689         is_add = 0;
8690       else if (unformat (i, "out-label %d", &next_hop_out_label))
8691         ;
8692       else
8693         {
8694           clib_warning ("parse error '%U'", format_unformat_error, i);
8695           return -99;
8696         }
8697     }
8698
8699   if (!next_hop_set || (MPLS_LABEL_INVALID == next_hop_out_label))
8700     {
8701       errmsg ("next hop / label set\n");
8702       return -99;
8703     }
8704   if (0 == bp)
8705     {
8706       errmsg ("bit=position not set\n");
8707       return -99;
8708     }
8709
8710   /* Construct the API message */
8711   M2 (BIER_ROUTE_ADD_DEL, mp, sizeof (vl_api_fib_path_t));
8712
8713   mp->br_is_add = is_add;
8714   mp->br_route.br_tbl_id.bt_set = set;
8715   mp->br_route.br_tbl_id.bt_sub_domain = sub_domain;
8716   mp->br_route.br_tbl_id.bt_hdr_len_id = hdr_len;
8717   mp->br_route.br_bp = ntohs (bp);
8718   mp->br_route.br_n_paths = 1;
8719   mp->br_route.br_paths[0].n_labels = 1;
8720   mp->br_route.br_paths[0].label_stack[0].label = ntohl (next_hop_out_label);
8721   mp->br_route.br_paths[0].proto = (next_hop_proto_is_ip4 ?
8722                                     FIB_API_PATH_NH_PROTO_IP4 :
8723                                     FIB_API_PATH_NH_PROTO_IP6);
8724
8725   if (next_hop_proto_is_ip4)
8726     {
8727       clib_memcpy (&mp->br_route.br_paths[0].nh.address.ip4,
8728                    &v4_next_hop_address, sizeof (v4_next_hop_address));
8729     }
8730   else
8731     {
8732       clib_memcpy (&mp->br_route.br_paths[0].nh.address.ip6,
8733                    &v6_next_hop_address, sizeof (v6_next_hop_address));
8734     }
8735
8736   /* send it... */
8737   S (mp);
8738
8739   /* Wait for a reply... */
8740   W (ret);
8741
8742   return (ret);
8743 }
8744
8745 static int
8746 api_mpls_tunnel_add_del (vat_main_t * vam)
8747 {
8748   unformat_input_t *i = vam->input;
8749   vl_api_mpls_tunnel_add_del_t *mp;
8750
8751   vl_api_fib_path_t paths[8];
8752   u32 sw_if_index = ~0;
8753   u8 path_count = 0;
8754   u8 l2_only = 0;
8755   u8 is_add = 1;
8756   int ret;
8757
8758   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8759     {
8760       if (unformat (i, "add"))
8761         is_add = 1;
8762       else
8763         if (unformat
8764             (i, "del %U", api_unformat_sw_if_index, vam, &sw_if_index))
8765         is_add = 0;
8766       else if (unformat (i, "del sw_if_index %d", &sw_if_index))
8767         is_add = 0;
8768       else if (unformat (i, "l2-only"))
8769         l2_only = 1;
8770       else
8771         if (unformat
8772             (i, "via %U", unformat_fib_path, vam, &paths[path_count]))
8773         {
8774           path_count++;
8775           if (8 == path_count)
8776             {
8777               errmsg ("max 8 paths");
8778               return -99;
8779             }
8780         }
8781       else
8782         {
8783           clib_warning ("parse error '%U'", format_unformat_error, i);
8784           return -99;
8785         }
8786     }
8787
8788   M2 (MPLS_TUNNEL_ADD_DEL, mp, sizeof (vl_api_fib_path_t) * path_count);
8789
8790   mp->mt_is_add = is_add;
8791   mp->mt_tunnel.mt_sw_if_index = ntohl (sw_if_index);
8792   mp->mt_tunnel.mt_l2_only = l2_only;
8793   mp->mt_tunnel.mt_is_multicast = 0;
8794   mp->mt_tunnel.mt_n_paths = path_count;
8795
8796   clib_memcpy (&mp->mt_tunnel.mt_paths, &paths,
8797                sizeof (paths[0]) * path_count);
8798
8799   S (mp);
8800   W (ret);
8801   return ret;
8802 }
8803
8804 static int
8805 api_sw_interface_set_unnumbered (vat_main_t * vam)
8806 {
8807   unformat_input_t *i = vam->input;
8808   vl_api_sw_interface_set_unnumbered_t *mp;
8809   u32 sw_if_index;
8810   u32 unnum_sw_index = ~0;
8811   u8 is_add = 1;
8812   u8 sw_if_index_set = 0;
8813   int ret;
8814
8815   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8816     {
8817       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8818         sw_if_index_set = 1;
8819       else if (unformat (i, "sw_if_index %d", &sw_if_index))
8820         sw_if_index_set = 1;
8821       else if (unformat (i, "unnum_if_index %d", &unnum_sw_index))
8822         ;
8823       else if (unformat (i, "del"))
8824         is_add = 0;
8825       else
8826         {
8827           clib_warning ("parse error '%U'", format_unformat_error, i);
8828           return -99;
8829         }
8830     }
8831
8832   if (sw_if_index_set == 0)
8833     {
8834       errmsg ("missing interface name or sw_if_index");
8835       return -99;
8836     }
8837
8838   M (SW_INTERFACE_SET_UNNUMBERED, mp);
8839
8840   mp->sw_if_index = ntohl (sw_if_index);
8841   mp->unnumbered_sw_if_index = ntohl (unnum_sw_index);
8842   mp->is_add = is_add;
8843
8844   S (mp);
8845   W (ret);
8846   return ret;
8847 }
8848
8849
8850 static int
8851 api_create_vlan_subif (vat_main_t * vam)
8852 {
8853   unformat_input_t *i = vam->input;
8854   vl_api_create_vlan_subif_t *mp;
8855   u32 sw_if_index;
8856   u8 sw_if_index_set = 0;
8857   u32 vlan_id;
8858   u8 vlan_id_set = 0;
8859   int ret;
8860
8861   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8862     {
8863       if (unformat (i, "sw_if_index %d", &sw_if_index))
8864         sw_if_index_set = 1;
8865       else
8866         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8867         sw_if_index_set = 1;
8868       else if (unformat (i, "vlan %d", &vlan_id))
8869         vlan_id_set = 1;
8870       else
8871         {
8872           clib_warning ("parse error '%U'", format_unformat_error, i);
8873           return -99;
8874         }
8875     }
8876
8877   if (sw_if_index_set == 0)
8878     {
8879       errmsg ("missing interface name or sw_if_index");
8880       return -99;
8881     }
8882
8883   if (vlan_id_set == 0)
8884     {
8885       errmsg ("missing vlan_id");
8886       return -99;
8887     }
8888   M (CREATE_VLAN_SUBIF, mp);
8889
8890   mp->sw_if_index = ntohl (sw_if_index);
8891   mp->vlan_id = ntohl (vlan_id);
8892
8893   S (mp);
8894   W (ret);
8895   return ret;
8896 }
8897
8898 #define foreach_create_subif_bit                \
8899 _(no_tags)                                      \
8900 _(one_tag)                                      \
8901 _(two_tags)                                     \
8902 _(dot1ad)                                       \
8903 _(exact_match)                                  \
8904 _(default_sub)                                  \
8905 _(outer_vlan_id_any)                            \
8906 _(inner_vlan_id_any)
8907
8908 #define foreach_create_subif_flag               \
8909 _(0, "no_tags")                                 \
8910 _(1, "one_tag")                                 \
8911 _(2, "two_tags")                                \
8912 _(3, "dot1ad")                                  \
8913 _(4, "exact_match")                             \
8914 _(5, "default_sub")                             \
8915 _(6, "outer_vlan_id_any")                       \
8916 _(7, "inner_vlan_id_any")
8917
8918 static int
8919 api_create_subif (vat_main_t * vam)
8920 {
8921   unformat_input_t *i = vam->input;
8922   vl_api_create_subif_t *mp;
8923   u32 sw_if_index;
8924   u8 sw_if_index_set = 0;
8925   u32 sub_id;
8926   u8 sub_id_set = 0;
8927   u32 __attribute__ ((unused)) no_tags = 0;
8928   u32 __attribute__ ((unused)) one_tag = 0;
8929   u32 __attribute__ ((unused)) two_tags = 0;
8930   u32 __attribute__ ((unused)) dot1ad = 0;
8931   u32 __attribute__ ((unused)) exact_match = 0;
8932   u32 __attribute__ ((unused)) default_sub = 0;
8933   u32 __attribute__ ((unused)) outer_vlan_id_any = 0;
8934   u32 __attribute__ ((unused)) inner_vlan_id_any = 0;
8935   u32 tmp;
8936   u16 outer_vlan_id = 0;
8937   u16 inner_vlan_id = 0;
8938   int ret;
8939
8940   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
8941     {
8942       if (unformat (i, "sw_if_index %d", &sw_if_index))
8943         sw_if_index_set = 1;
8944       else
8945         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
8946         sw_if_index_set = 1;
8947       else if (unformat (i, "sub_id %d", &sub_id))
8948         sub_id_set = 1;
8949       else if (unformat (i, "outer_vlan_id %d", &tmp))
8950         outer_vlan_id = tmp;
8951       else if (unformat (i, "inner_vlan_id %d", &tmp))
8952         inner_vlan_id = tmp;
8953
8954 #define _(a) else if (unformat (i, #a)) a = 1 ;
8955       foreach_create_subif_bit
8956 #undef _
8957         else
8958         {
8959           clib_warning ("parse error '%U'", format_unformat_error, i);
8960           return -99;
8961         }
8962     }
8963
8964   if (sw_if_index_set == 0)
8965     {
8966       errmsg ("missing interface name or sw_if_index");
8967       return -99;
8968     }
8969
8970   if (sub_id_set == 0)
8971     {
8972       errmsg ("missing sub_id");
8973       return -99;
8974     }
8975   M (CREATE_SUBIF, mp);
8976
8977   mp->sw_if_index = ntohl (sw_if_index);
8978   mp->sub_id = ntohl (sub_id);
8979
8980 #define _(a,b) mp->sub_if_flags |= (1 << a);
8981   foreach_create_subif_flag;
8982 #undef _
8983
8984   mp->outer_vlan_id = ntohs (outer_vlan_id);
8985   mp->inner_vlan_id = ntohs (inner_vlan_id);
8986
8987   S (mp);
8988   W (ret);
8989   return ret;
8990 }
8991
8992 static int
8993 api_ip_table_replace_begin (vat_main_t * vam)
8994 {
8995   unformat_input_t *i = vam->input;
8996   vl_api_ip_table_replace_begin_t *mp;
8997   u32 table_id = 0;
8998   u8 is_ipv6 = 0;
8999
9000   int ret;
9001   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9002     {
9003       if (unformat (i, "table %d", &table_id))
9004         ;
9005       else if (unformat (i, "ipv6"))
9006         is_ipv6 = 1;
9007       else
9008         {
9009           clib_warning ("parse error '%U'", format_unformat_error, i);
9010           return -99;
9011         }
9012     }
9013
9014   M (IP_TABLE_REPLACE_BEGIN, mp);
9015
9016   mp->table.table_id = ntohl (table_id);
9017   mp->table.is_ip6 = is_ipv6;
9018
9019   S (mp);
9020   W (ret);
9021   return ret;
9022 }
9023
9024 static int
9025 api_ip_table_flush (vat_main_t * vam)
9026 {
9027   unformat_input_t *i = vam->input;
9028   vl_api_ip_table_flush_t *mp;
9029   u32 table_id = 0;
9030   u8 is_ipv6 = 0;
9031
9032   int ret;
9033   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9034     {
9035       if (unformat (i, "table %d", &table_id))
9036         ;
9037       else if (unformat (i, "ipv6"))
9038         is_ipv6 = 1;
9039       else
9040         {
9041           clib_warning ("parse error '%U'", format_unformat_error, i);
9042           return -99;
9043         }
9044     }
9045
9046   M (IP_TABLE_FLUSH, mp);
9047
9048   mp->table.table_id = ntohl (table_id);
9049   mp->table.is_ip6 = is_ipv6;
9050
9051   S (mp);
9052   W (ret);
9053   return ret;
9054 }
9055
9056 static int
9057 api_ip_table_replace_end (vat_main_t * vam)
9058 {
9059   unformat_input_t *i = vam->input;
9060   vl_api_ip_table_replace_end_t *mp;
9061   u32 table_id = 0;
9062   u8 is_ipv6 = 0;
9063
9064   int ret;
9065   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9066     {
9067       if (unformat (i, "table %d", &table_id))
9068         ;
9069       else if (unformat (i, "ipv6"))
9070         is_ipv6 = 1;
9071       else
9072         {
9073           clib_warning ("parse error '%U'", format_unformat_error, i);
9074           return -99;
9075         }
9076     }
9077
9078   M (IP_TABLE_REPLACE_END, mp);
9079
9080   mp->table.table_id = ntohl (table_id);
9081   mp->table.is_ip6 = is_ipv6;
9082
9083   S (mp);
9084   W (ret);
9085   return ret;
9086 }
9087
9088 static int
9089 api_set_ip_flow_hash (vat_main_t * vam)
9090 {
9091   unformat_input_t *i = vam->input;
9092   vl_api_set_ip_flow_hash_t *mp;
9093   u32 vrf_id = 0;
9094   u8 is_ipv6 = 0;
9095   u8 vrf_id_set = 0;
9096   u8 src = 0;
9097   u8 dst = 0;
9098   u8 sport = 0;
9099   u8 dport = 0;
9100   u8 proto = 0;
9101   u8 reverse = 0;
9102   int ret;
9103
9104   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9105     {
9106       if (unformat (i, "vrf %d", &vrf_id))
9107         vrf_id_set = 1;
9108       else if (unformat (i, "ipv6"))
9109         is_ipv6 = 1;
9110       else if (unformat (i, "src"))
9111         src = 1;
9112       else if (unformat (i, "dst"))
9113         dst = 1;
9114       else if (unformat (i, "sport"))
9115         sport = 1;
9116       else if (unformat (i, "dport"))
9117         dport = 1;
9118       else if (unformat (i, "proto"))
9119         proto = 1;
9120       else if (unformat (i, "reverse"))
9121         reverse = 1;
9122
9123       else
9124         {
9125           clib_warning ("parse error '%U'", format_unformat_error, i);
9126           return -99;
9127         }
9128     }
9129
9130   if (vrf_id_set == 0)
9131     {
9132       errmsg ("missing vrf id");
9133       return -99;
9134     }
9135
9136   M (SET_IP_FLOW_HASH, mp);
9137   mp->src = src;
9138   mp->dst = dst;
9139   mp->sport = sport;
9140   mp->dport = dport;
9141   mp->proto = proto;
9142   mp->reverse = reverse;
9143   mp->vrf_id = ntohl (vrf_id);
9144   mp->is_ipv6 = is_ipv6;
9145
9146   S (mp);
9147   W (ret);
9148   return ret;
9149 }
9150
9151 static int
9152 api_sw_interface_ip6_enable_disable (vat_main_t * vam)
9153 {
9154   unformat_input_t *i = vam->input;
9155   vl_api_sw_interface_ip6_enable_disable_t *mp;
9156   u32 sw_if_index;
9157   u8 sw_if_index_set = 0;
9158   u8 enable = 0;
9159   int ret;
9160
9161   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9162     {
9163       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
9164         sw_if_index_set = 1;
9165       else if (unformat (i, "sw_if_index %d", &sw_if_index))
9166         sw_if_index_set = 1;
9167       else if (unformat (i, "enable"))
9168         enable = 1;
9169       else if (unformat (i, "disable"))
9170         enable = 0;
9171       else
9172         {
9173           clib_warning ("parse error '%U'", format_unformat_error, i);
9174           return -99;
9175         }
9176     }
9177
9178   if (sw_if_index_set == 0)
9179     {
9180       errmsg ("missing interface name or sw_if_index");
9181       return -99;
9182     }
9183
9184   M (SW_INTERFACE_IP6_ENABLE_DISABLE, mp);
9185
9186   mp->sw_if_index = ntohl (sw_if_index);
9187   mp->enable = enable;
9188
9189   S (mp);
9190   W (ret);
9191   return ret;
9192 }
9193
9194
9195 static int
9196 api_l2_patch_add_del (vat_main_t * vam)
9197 {
9198   unformat_input_t *i = vam->input;
9199   vl_api_l2_patch_add_del_t *mp;
9200   u32 rx_sw_if_index;
9201   u8 rx_sw_if_index_set = 0;
9202   u32 tx_sw_if_index;
9203   u8 tx_sw_if_index_set = 0;
9204   u8 is_add = 1;
9205   int ret;
9206
9207   /* Parse args required to build the message */
9208   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9209     {
9210       if (unformat (i, "rx_sw_if_index %d", &rx_sw_if_index))
9211         rx_sw_if_index_set = 1;
9212       else if (unformat (i, "tx_sw_if_index %d", &tx_sw_if_index))
9213         tx_sw_if_index_set = 1;
9214       else if (unformat (i, "rx"))
9215         {
9216           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9217             {
9218               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
9219                             &rx_sw_if_index))
9220                 rx_sw_if_index_set = 1;
9221             }
9222           else
9223             break;
9224         }
9225       else if (unformat (i, "tx"))
9226         {
9227           if (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9228             {
9229               if (unformat (i, "%U", api_unformat_sw_if_index, vam,
9230                             &tx_sw_if_index))
9231                 tx_sw_if_index_set = 1;
9232             }
9233           else
9234             break;
9235         }
9236       else if (unformat (i, "del"))
9237         is_add = 0;
9238       else
9239         break;
9240     }
9241
9242   if (rx_sw_if_index_set == 0)
9243     {
9244       errmsg ("missing rx interface name or rx_sw_if_index");
9245       return -99;
9246     }
9247
9248   if (tx_sw_if_index_set == 0)
9249     {
9250       errmsg ("missing tx interface name or tx_sw_if_index");
9251       return -99;
9252     }
9253
9254   M (L2_PATCH_ADD_DEL, mp);
9255
9256   mp->rx_sw_if_index = ntohl (rx_sw_if_index);
9257   mp->tx_sw_if_index = ntohl (tx_sw_if_index);
9258   mp->is_add = is_add;
9259
9260   S (mp);
9261   W (ret);
9262   return ret;
9263 }
9264
9265 u8 is_del;
9266 u8 localsid_addr[16];
9267 u8 end_psp;
9268 u8 behavior;
9269 u32 sw_if_index;
9270 u32 vlan_index;
9271 u32 fib_table;
9272 u8 nh_addr[16];
9273
9274 static int
9275 api_sr_localsid_add_del (vat_main_t * vam)
9276 {
9277   unformat_input_t *i = vam->input;
9278   vl_api_sr_localsid_add_del_t *mp;
9279
9280   u8 is_del;
9281   ip6_address_t localsid;
9282   u8 end_psp = 0;
9283   u8 behavior = ~0;
9284   u32 sw_if_index;
9285   u32 fib_table = ~(u32) 0;
9286   ip6_address_t nh_addr6;
9287   ip4_address_t nh_addr4;
9288   clib_memset (&nh_addr6, 0, sizeof (ip6_address_t));
9289   clib_memset (&nh_addr4, 0, sizeof (ip4_address_t));
9290
9291   bool nexthop_set = 0;
9292
9293   int ret;
9294
9295   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
9296     {
9297       if (unformat (i, "del"))
9298         is_del = 1;
9299       else if (unformat (i, "address %U", unformat_ip6_address, &localsid));
9300       else if (unformat (i, "next-hop %U", unformat_ip4_address, &nh_addr4))
9301         nexthop_set = 1;
9302       else if (unformat (i, "next-hop %U", unformat_ip6_address, &nh_addr6))
9303         nexthop_set = 1;
9304       else if (unformat (i, "behavior %u", &behavior));
9305       else if (unformat (i, "sw_if_index %u", &sw_if_index));
9306       else if (unformat (i, "fib-table %u", &fib_table));
9307       else if (unformat (i, "end.psp %u", &behavior));
9308       else
9309         break;
9310     }
9311
9312   M (SR_LOCALSID_ADD_DEL, mp);
9313
9314   clib_memcpy (mp->localsid.addr, &localsid, sizeof (mp->localsid));
9315
9316   if (nexthop_set)
9317     {
9318       clib_memcpy (mp->nh_addr6, &nh_addr6, sizeof (mp->nh_addr6));
9319       clib_memcpy (mp->nh_addr4, &nh_addr4, sizeof (mp->nh_addr4));
9320     }
9321   mp->behavior = behavior;
9322   mp->sw_if_index = ntohl (sw_if_index);
9323   mp->fib_table = ntohl (fib_table);
9324   mp->end_psp = end_psp;
9325   mp->is_del = is_del;
9326
9327   S (mp);
9328   W (ret);
9329   return ret;
9330 }
9331
9332 static int
9333 api_ioam_enable (vat_main_t * vam)
9334 {
9335   unformat_input_t *input = vam->input;
9336   vl_api_ioam_enable_t *mp;
9337   u32 id = 0;
9338   int has_trace_option = 0;
9339   int has_pot_option = 0;
9340   int has_seqno_option = 0;
9341   int has_analyse_option = 0;
9342   int ret;
9343
9344   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9345     {
9346       if (unformat (input, "trace"))
9347         has_trace_option = 1;
9348       else if (unformat (input, "pot"))
9349         has_pot_option = 1;
9350       else if (unformat (input, "seqno"))
9351         has_seqno_option = 1;
9352       else if (unformat (input, "analyse"))
9353         has_analyse_option = 1;
9354       else
9355         break;
9356     }
9357   M (IOAM_ENABLE, mp);
9358   mp->id = htons (id);
9359   mp->seqno = has_seqno_option;
9360   mp->analyse = has_analyse_option;
9361   mp->pot_enable = has_pot_option;
9362   mp->trace_enable = has_trace_option;
9363
9364   S (mp);
9365   W (ret);
9366   return ret;
9367 }
9368
9369
9370 static int
9371 api_ioam_disable (vat_main_t * vam)
9372 {
9373   vl_api_ioam_disable_t *mp;
9374   int ret;
9375
9376   M (IOAM_DISABLE, mp);
9377   S (mp);
9378   W (ret);
9379   return ret;
9380 }
9381
9382 #define foreach_tcp_proto_field                 \
9383 _(src_port)                                     \
9384 _(dst_port)
9385
9386 #define foreach_udp_proto_field                 \
9387 _(src_port)                                     \
9388 _(dst_port)
9389
9390 #define foreach_ip4_proto_field                 \
9391 _(src_address)                                  \
9392 _(dst_address)                                  \
9393 _(tos)                                          \
9394 _(length)                                       \
9395 _(fragment_id)                                  \
9396 _(ttl)                                          \
9397 _(protocol)                                     \
9398 _(checksum)
9399
9400 typedef struct
9401 {
9402   u16 src_port, dst_port;
9403 } tcpudp_header_t;
9404
9405 #if VPP_API_TEST_BUILTIN == 0
9406 uword
9407 unformat_tcp_mask (unformat_input_t * input, va_list * args)
9408 {
9409   u8 **maskp = va_arg (*args, u8 **);
9410   u8 *mask = 0;
9411   u8 found_something = 0;
9412   tcp_header_t *tcp;
9413
9414 #define _(a) u8 a=0;
9415   foreach_tcp_proto_field;
9416 #undef _
9417
9418   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9419     {
9420       if (0);
9421 #define _(a) else if (unformat (input, #a)) a=1;
9422       foreach_tcp_proto_field
9423 #undef _
9424         else
9425         break;
9426     }
9427
9428 #define _(a) found_something += a;
9429   foreach_tcp_proto_field;
9430 #undef _
9431
9432   if (found_something == 0)
9433     return 0;
9434
9435   vec_validate (mask, sizeof (*tcp) - 1);
9436
9437   tcp = (tcp_header_t *) mask;
9438
9439 #define _(a) if (a) clib_memset (&tcp->a, 0xff, sizeof (tcp->a));
9440   foreach_tcp_proto_field;
9441 #undef _
9442
9443   *maskp = mask;
9444   return 1;
9445 }
9446
9447 uword
9448 unformat_udp_mask (unformat_input_t * input, va_list * args)
9449 {
9450   u8 **maskp = va_arg (*args, u8 **);
9451   u8 *mask = 0;
9452   u8 found_something = 0;
9453   udp_header_t *udp;
9454
9455 #define _(a) u8 a=0;
9456   foreach_udp_proto_field;
9457 #undef _
9458
9459   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9460     {
9461       if (0);
9462 #define _(a) else if (unformat (input, #a)) a=1;
9463       foreach_udp_proto_field
9464 #undef _
9465         else
9466         break;
9467     }
9468
9469 #define _(a) found_something += a;
9470   foreach_udp_proto_field;
9471 #undef _
9472
9473   if (found_something == 0)
9474     return 0;
9475
9476   vec_validate (mask, sizeof (*udp) - 1);
9477
9478   udp = (udp_header_t *) mask;
9479
9480 #define _(a) if (a) clib_memset (&udp->a, 0xff, sizeof (udp->a));
9481   foreach_udp_proto_field;
9482 #undef _
9483
9484   *maskp = mask;
9485   return 1;
9486 }
9487
9488 uword
9489 unformat_l4_mask (unformat_input_t * input, va_list * args)
9490 {
9491   u8 **maskp = va_arg (*args, u8 **);
9492   u16 src_port = 0, dst_port = 0;
9493   tcpudp_header_t *tcpudp;
9494
9495   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9496     {
9497       if (unformat (input, "tcp %U", unformat_tcp_mask, maskp))
9498         return 1;
9499       else if (unformat (input, "udp %U", unformat_udp_mask, maskp))
9500         return 1;
9501       else if (unformat (input, "src_port"))
9502         src_port = 0xFFFF;
9503       else if (unformat (input, "dst_port"))
9504         dst_port = 0xFFFF;
9505       else
9506         return 0;
9507     }
9508
9509   if (!src_port && !dst_port)
9510     return 0;
9511
9512   u8 *mask = 0;
9513   vec_validate (mask, sizeof (tcpudp_header_t) - 1);
9514
9515   tcpudp = (tcpudp_header_t *) mask;
9516   tcpudp->src_port = src_port;
9517   tcpudp->dst_port = dst_port;
9518
9519   *maskp = mask;
9520
9521   return 1;
9522 }
9523
9524 uword
9525 unformat_ip4_mask (unformat_input_t * input, va_list * args)
9526 {
9527   u8 **maskp = va_arg (*args, u8 **);
9528   u8 *mask = 0;
9529   u8 found_something = 0;
9530   ip4_header_t *ip;
9531
9532 #define _(a) u8 a=0;
9533   foreach_ip4_proto_field;
9534 #undef _
9535   u8 version = 0;
9536   u8 hdr_length = 0;
9537
9538
9539   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9540     {
9541       if (unformat (input, "version"))
9542         version = 1;
9543       else if (unformat (input, "hdr_length"))
9544         hdr_length = 1;
9545       else if (unformat (input, "src"))
9546         src_address = 1;
9547       else if (unformat (input, "dst"))
9548         dst_address = 1;
9549       else if (unformat (input, "proto"))
9550         protocol = 1;
9551
9552 #define _(a) else if (unformat (input, #a)) a=1;
9553       foreach_ip4_proto_field
9554 #undef _
9555         else
9556         break;
9557     }
9558
9559 #define _(a) found_something += a;
9560   foreach_ip4_proto_field;
9561 #undef _
9562
9563   if (found_something == 0)
9564     return 0;
9565
9566   vec_validate (mask, sizeof (*ip) - 1);
9567
9568   ip = (ip4_header_t *) mask;
9569
9570 #define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
9571   foreach_ip4_proto_field;
9572 #undef _
9573
9574   ip->ip_version_and_header_length = 0;
9575
9576   if (version)
9577     ip->ip_version_and_header_length |= 0xF0;
9578
9579   if (hdr_length)
9580     ip->ip_version_and_header_length |= 0x0F;
9581
9582   *maskp = mask;
9583   return 1;
9584 }
9585
9586 #define foreach_ip6_proto_field                 \
9587 _(src_address)                                  \
9588 _(dst_address)                                  \
9589 _(payload_length)                               \
9590 _(hop_limit)                                    \
9591 _(protocol)
9592
9593 uword
9594 unformat_ip6_mask (unformat_input_t * input, va_list * args)
9595 {
9596   u8 **maskp = va_arg (*args, u8 **);
9597   u8 *mask = 0;
9598   u8 found_something = 0;
9599   ip6_header_t *ip;
9600   u32 ip_version_traffic_class_and_flow_label;
9601
9602 #define _(a) u8 a=0;
9603   foreach_ip6_proto_field;
9604 #undef _
9605   u8 version = 0;
9606   u8 traffic_class = 0;
9607   u8 flow_label = 0;
9608
9609   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9610     {
9611       if (unformat (input, "version"))
9612         version = 1;
9613       else if (unformat (input, "traffic-class"))
9614         traffic_class = 1;
9615       else if (unformat (input, "flow-label"))
9616         flow_label = 1;
9617       else if (unformat (input, "src"))
9618         src_address = 1;
9619       else if (unformat (input, "dst"))
9620         dst_address = 1;
9621       else if (unformat (input, "proto"))
9622         protocol = 1;
9623
9624 #define _(a) else if (unformat (input, #a)) a=1;
9625       foreach_ip6_proto_field
9626 #undef _
9627         else
9628         break;
9629     }
9630
9631 #define _(a) found_something += a;
9632   foreach_ip6_proto_field;
9633 #undef _
9634
9635   if (found_something == 0)
9636     return 0;
9637
9638   vec_validate (mask, sizeof (*ip) - 1);
9639
9640   ip = (ip6_header_t *) mask;
9641
9642 #define _(a) if (a) clib_memset (&ip->a, 0xff, sizeof (ip->a));
9643   foreach_ip6_proto_field;
9644 #undef _
9645
9646   ip_version_traffic_class_and_flow_label = 0;
9647
9648   if (version)
9649     ip_version_traffic_class_and_flow_label |= 0xF0000000;
9650
9651   if (traffic_class)
9652     ip_version_traffic_class_and_flow_label |= 0x0FF00000;
9653
9654   if (flow_label)
9655     ip_version_traffic_class_and_flow_label |= 0x000FFFFF;
9656
9657   ip->ip_version_traffic_class_and_flow_label =
9658     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
9659
9660   *maskp = mask;
9661   return 1;
9662 }
9663
9664 uword
9665 unformat_l3_mask (unformat_input_t * input, va_list * args)
9666 {
9667   u8 **maskp = va_arg (*args, u8 **);
9668
9669   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9670     {
9671       if (unformat (input, "ip4 %U", unformat_ip4_mask, maskp))
9672         return 1;
9673       else if (unformat (input, "ip6 %U", unformat_ip6_mask, maskp))
9674         return 1;
9675       else
9676         break;
9677     }
9678   return 0;
9679 }
9680
9681 uword
9682 unformat_l2_mask (unformat_input_t * input, va_list * args)
9683 {
9684   u8 **maskp = va_arg (*args, u8 **);
9685   u8 *mask = 0;
9686   u8 src = 0;
9687   u8 dst = 0;
9688   u8 proto = 0;
9689   u8 tag1 = 0;
9690   u8 tag2 = 0;
9691   u8 ignore_tag1 = 0;
9692   u8 ignore_tag2 = 0;
9693   u8 cos1 = 0;
9694   u8 cos2 = 0;
9695   u8 dot1q = 0;
9696   u8 dot1ad = 0;
9697   int len = 14;
9698
9699   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9700     {
9701       if (unformat (input, "src"))
9702         src = 1;
9703       else if (unformat (input, "dst"))
9704         dst = 1;
9705       else if (unformat (input, "proto"))
9706         proto = 1;
9707       else if (unformat (input, "tag1"))
9708         tag1 = 1;
9709       else if (unformat (input, "tag2"))
9710         tag2 = 1;
9711       else if (unformat (input, "ignore-tag1"))
9712         ignore_tag1 = 1;
9713       else if (unformat (input, "ignore-tag2"))
9714         ignore_tag2 = 1;
9715       else if (unformat (input, "cos1"))
9716         cos1 = 1;
9717       else if (unformat (input, "cos2"))
9718         cos2 = 1;
9719       else if (unformat (input, "dot1q"))
9720         dot1q = 1;
9721       else if (unformat (input, "dot1ad"))
9722         dot1ad = 1;
9723       else
9724         break;
9725     }
9726   if ((src + dst + proto + tag1 + tag2 + dot1q + dot1ad +
9727        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
9728     return 0;
9729
9730   if (tag1 || ignore_tag1 || cos1 || dot1q)
9731     len = 18;
9732   if (tag2 || ignore_tag2 || cos2 || dot1ad)
9733     len = 22;
9734
9735   vec_validate (mask, len - 1);
9736
9737   if (dst)
9738     clib_memset (mask, 0xff, 6);
9739
9740   if (src)
9741     clib_memset (mask + 6, 0xff, 6);
9742
9743   if (tag2 || dot1ad)
9744     {
9745       /* inner vlan tag */
9746       if (tag2)
9747         {
9748           mask[19] = 0xff;
9749           mask[18] = 0x0f;
9750         }
9751       if (cos2)
9752         mask[18] |= 0xe0;
9753       if (proto)
9754         mask[21] = mask[20] = 0xff;
9755       if (tag1)
9756         {
9757           mask[15] = 0xff;
9758           mask[14] = 0x0f;
9759         }
9760       if (cos1)
9761         mask[14] |= 0xe0;
9762       *maskp = mask;
9763       return 1;
9764     }
9765   if (tag1 | dot1q)
9766     {
9767       if (tag1)
9768         {
9769           mask[15] = 0xff;
9770           mask[14] = 0x0f;
9771         }
9772       if (cos1)
9773         mask[14] |= 0xe0;
9774       if (proto)
9775         mask[16] = mask[17] = 0xff;
9776
9777       *maskp = mask;
9778       return 1;
9779     }
9780   if (cos2)
9781     mask[18] |= 0xe0;
9782   if (cos1)
9783     mask[14] |= 0xe0;
9784   if (proto)
9785     mask[12] = mask[13] = 0xff;
9786
9787   *maskp = mask;
9788   return 1;
9789 }
9790
9791 uword
9792 unformat_classify_mask (unformat_input_t * input, va_list * args)
9793 {
9794   u8 **maskp = va_arg (*args, u8 **);
9795   u32 *skipp = va_arg (*args, u32 *);
9796   u32 *matchp = va_arg (*args, u32 *);
9797   u32 match;
9798   u8 *mask = 0;
9799   u8 *l2 = 0;
9800   u8 *l3 = 0;
9801   u8 *l4 = 0;
9802   int i;
9803
9804   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
9805     {
9806       if (unformat (input, "hex %U", unformat_hex_string, &mask))
9807         ;
9808       else if (unformat (input, "l2 %U", unformat_l2_mask, &l2))
9809         ;
9810       else if (unformat (input, "l3 %U", unformat_l3_mask, &l3))
9811         ;
9812       else if (unformat (input, "l4 %U", unformat_l4_mask, &l4))
9813         ;
9814       else
9815         break;
9816     }
9817
9818   if (l4 && !l3)
9819     {
9820       vec_free (mask);
9821       vec_free (l2);
9822       vec_free (l4);
9823       return 0;
9824     }
9825
9826   if (mask || l2 || l3 || l4)
9827     {
9828       if (l2 || l3 || l4)
9829         {
9830           /* "With a free Ethernet header in every package" */
9831           if (l2 == 0)
9832             vec_validate (l2, 13);
9833           mask = l2;
9834           if (vec_len (l3))
9835             {
9836               vec_append (mask, l3);
9837               vec_free (l3);
9838             }
9839           if (vec_len (l4))
9840             {
9841               vec_append (mask, l4);
9842               vec_free (l4);
9843             }
9844         }
9845
9846       /* Scan forward looking for the first significant mask octet */
9847       for (i = 0; i < vec_len (mask); i++)
9848         if (mask[i])
9849           break;
9850
9851       /* compute (skip, match) params */
9852       *skipp = i / sizeof (u32x4);
9853       vec_delete (mask, *skipp * sizeof (u32x4), 0);
9854
9855       /* Pad mask to an even multiple of the vector size */
9856       while (vec_len (mask) % sizeof (u32x4))
9857         vec_add1 (mask, 0);
9858
9859       match = vec_len (mask) / sizeof (u32x4);
9860
9861       for (i = match * sizeof (u32x4); i > 0; i -= sizeof (u32x4))
9862         {
9863           u64 *tmp = (u64 *) (mask + (i - sizeof (u32x4)));
9864           if (*tmp || *(tmp + 1))
9865             break;
9866           match--;
9867         }
9868       if (match == 0)
9869         clib_warning ("BUG: match 0");
9870
9871       _vec_len (mask) = match * sizeof (u32x4);
9872
9873       *matchp = match;
9874       *maskp = mask;
9875
9876       return 1;
9877     }
9878
9879   return 0;
9880 }
9881 #endif /* VPP_API_TEST_BUILTIN */
9882
9883 #define foreach_l2_next                         \
9884 _(drop, DROP)                                   \
9885 _(ethernet, ETHERNET_INPUT)                     \
9886 _(ip4, IP4_INPUT)                               \
9887 _(ip6, IP6_INPUT)
9888
9889 uword
9890 unformat_l2_next_index (unformat_input_t * input, va_list * args)
9891 {
9892   u32 *miss_next_indexp = va_arg (*args, u32 *);
9893   u32 next_index = 0;
9894   u32 tmp;
9895
9896 #define _(n,N) \
9897   if (unformat (input, #n)) { next_index = L2_INPUT_CLASSIFY_NEXT_##N; goto out;}
9898   foreach_l2_next;
9899 #undef _
9900
9901   if (unformat (input, "%d", &tmp))
9902     {
9903       next_index = tmp;
9904       goto out;
9905     }
9906
9907   return 0;
9908
9909 out:
9910   *miss_next_indexp = next_index;
9911   return 1;
9912 }
9913
9914 #define foreach_ip_next                         \
9915 _(drop, DROP)                                   \
9916 _(local, LOCAL)                                 \
9917 _(rewrite, REWRITE)
9918
9919 uword
9920 api_unformat_ip_next_index (unformat_input_t * input, va_list * args)
9921 {
9922   u32 *miss_next_indexp = va_arg (*args, u32 *);
9923   u32 next_index = 0;
9924   u32 tmp;
9925
9926 #define _(n,N) \
9927   if (unformat (input, #n)) { next_index = IP_LOOKUP_NEXT_##N; goto out;}
9928   foreach_ip_next;
9929 #undef _
9930
9931   if (unformat (input, "%d", &tmp))
9932     {
9933       next_index = tmp;
9934       goto out;
9935     }
9936
9937   return 0;
9938
9939 out:
9940   *miss_next_indexp = next_index;
9941   return 1;
9942 }
9943
9944 #define foreach_acl_next                        \
9945 _(deny, DENY)
9946
9947 uword
9948 api_unformat_acl_next_index (unformat_input_t * input, va_list * args)
9949 {
9950   u32 *miss_next_indexp = va_arg (*args, u32 *);
9951   u32 next_index = 0;
9952   u32 tmp;
9953
9954 #define _(n,N) \
9955   if (unformat (input, #n)) { next_index = ACL_NEXT_INDEX_##N; goto out;}
9956   foreach_acl_next;
9957 #undef _
9958
9959   if (unformat (input, "permit"))
9960     {
9961       next_index = ~0;
9962       goto out;
9963     }
9964   else if (unformat (input, "%d", &tmp))
9965     {
9966       next_index = tmp;
9967       goto out;
9968     }
9969
9970   return 0;
9971
9972 out:
9973   *miss_next_indexp = next_index;
9974   return 1;
9975 }
9976
9977 uword
9978 unformat_policer_precolor (unformat_input_t * input, va_list * args)
9979 {
9980   u32 *r = va_arg (*args, u32 *);
9981
9982   if (unformat (input, "conform-color"))
9983     *r = POLICE_CONFORM;
9984   else if (unformat (input, "exceed-color"))
9985     *r = POLICE_EXCEED;
9986   else
9987     return 0;
9988
9989   return 1;
9990 }
9991
9992 static int
9993 api_classify_add_del_table (vat_main_t * vam)
9994 {
9995   unformat_input_t *i = vam->input;
9996   vl_api_classify_add_del_table_t *mp;
9997
9998   u32 nbuckets = 2;
9999   u32 skip = ~0;
10000   u32 match = ~0;
10001   int is_add = 1;
10002   int del_chain = 0;
10003   u32 table_index = ~0;
10004   u32 next_table_index = ~0;
10005   u32 miss_next_index = ~0;
10006   u32 memory_size = 32 << 20;
10007   u8 *mask = 0;
10008   u32 current_data_flag = 0;
10009   int current_data_offset = 0;
10010   int ret;
10011
10012   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10013     {
10014       if (unformat (i, "del"))
10015         is_add = 0;
10016       else if (unformat (i, "del-chain"))
10017         {
10018           is_add = 0;
10019           del_chain = 1;
10020         }
10021       else if (unformat (i, "buckets %d", &nbuckets))
10022         ;
10023       else if (unformat (i, "memory_size %d", &memory_size))
10024         ;
10025       else if (unformat (i, "skip %d", &skip))
10026         ;
10027       else if (unformat (i, "match %d", &match))
10028         ;
10029       else if (unformat (i, "table %d", &table_index))
10030         ;
10031       else if (unformat (i, "mask %U", unformat_classify_mask,
10032                          &mask, &skip, &match))
10033         ;
10034       else if (unformat (i, "next-table %d", &next_table_index))
10035         ;
10036       else if (unformat (i, "miss-next %U", api_unformat_ip_next_index,
10037                          &miss_next_index))
10038         ;
10039       else if (unformat (i, "l2-miss-next %U", unformat_l2_next_index,
10040                          &miss_next_index))
10041         ;
10042       else if (unformat (i, "acl-miss-next %U", api_unformat_acl_next_index,
10043                          &miss_next_index))
10044         ;
10045       else if (unformat (i, "current-data-flag %d", &current_data_flag))
10046         ;
10047       else if (unformat (i, "current-data-offset %d", &current_data_offset))
10048         ;
10049       else
10050         break;
10051     }
10052
10053   if (is_add && mask == 0)
10054     {
10055       errmsg ("Mask required");
10056       return -99;
10057     }
10058
10059   if (is_add && skip == ~0)
10060     {
10061       errmsg ("skip count required");
10062       return -99;
10063     }
10064
10065   if (is_add && match == ~0)
10066     {
10067       errmsg ("match count required");
10068       return -99;
10069     }
10070
10071   if (!is_add && table_index == ~0)
10072     {
10073       errmsg ("table index required for delete");
10074       return -99;
10075     }
10076
10077   M2 (CLASSIFY_ADD_DEL_TABLE, mp, vec_len (mask));
10078
10079   mp->is_add = is_add;
10080   mp->del_chain = del_chain;
10081   mp->table_index = ntohl (table_index);
10082   mp->nbuckets = ntohl (nbuckets);
10083   mp->memory_size = ntohl (memory_size);
10084   mp->skip_n_vectors = ntohl (skip);
10085   mp->match_n_vectors = ntohl (match);
10086   mp->next_table_index = ntohl (next_table_index);
10087   mp->miss_next_index = ntohl (miss_next_index);
10088   mp->current_data_flag = ntohl (current_data_flag);
10089   mp->current_data_offset = ntohl (current_data_offset);
10090   mp->mask_len = ntohl (vec_len (mask));
10091   clib_memcpy (mp->mask, mask, vec_len (mask));
10092
10093   vec_free (mask);
10094
10095   S (mp);
10096   W (ret);
10097   return ret;
10098 }
10099
10100 #if VPP_API_TEST_BUILTIN == 0
10101 uword
10102 unformat_l4_match (unformat_input_t * input, va_list * args)
10103 {
10104   u8 **matchp = va_arg (*args, u8 **);
10105
10106   u8 *proto_header = 0;
10107   int src_port = 0;
10108   int dst_port = 0;
10109
10110   tcpudp_header_t h;
10111
10112   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10113     {
10114       if (unformat (input, "src_port %d", &src_port))
10115         ;
10116       else if (unformat (input, "dst_port %d", &dst_port))
10117         ;
10118       else
10119         return 0;
10120     }
10121
10122   h.src_port = clib_host_to_net_u16 (src_port);
10123   h.dst_port = clib_host_to_net_u16 (dst_port);
10124   vec_validate (proto_header, sizeof (h) - 1);
10125   memcpy (proto_header, &h, sizeof (h));
10126
10127   *matchp = proto_header;
10128
10129   return 1;
10130 }
10131
10132 uword
10133 unformat_ip4_match (unformat_input_t * input, va_list * args)
10134 {
10135   u8 **matchp = va_arg (*args, u8 **);
10136   u8 *match = 0;
10137   ip4_header_t *ip;
10138   int version = 0;
10139   u32 version_val;
10140   int hdr_length = 0;
10141   u32 hdr_length_val;
10142   int src = 0, dst = 0;
10143   ip4_address_t src_val, dst_val;
10144   int proto = 0;
10145   u32 proto_val;
10146   int tos = 0;
10147   u32 tos_val;
10148   int length = 0;
10149   u32 length_val;
10150   int fragment_id = 0;
10151   u32 fragment_id_val;
10152   int ttl = 0;
10153   int ttl_val;
10154   int checksum = 0;
10155   u32 checksum_val;
10156
10157   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10158     {
10159       if (unformat (input, "version %d", &version_val))
10160         version = 1;
10161       else if (unformat (input, "hdr_length %d", &hdr_length_val))
10162         hdr_length = 1;
10163       else if (unformat (input, "src %U", unformat_ip4_address, &src_val))
10164         src = 1;
10165       else if (unformat (input, "dst %U", unformat_ip4_address, &dst_val))
10166         dst = 1;
10167       else if (unformat (input, "proto %d", &proto_val))
10168         proto = 1;
10169       else if (unformat (input, "tos %d", &tos_val))
10170         tos = 1;
10171       else if (unformat (input, "length %d", &length_val))
10172         length = 1;
10173       else if (unformat (input, "fragment_id %d", &fragment_id_val))
10174         fragment_id = 1;
10175       else if (unformat (input, "ttl %d", &ttl_val))
10176         ttl = 1;
10177       else if (unformat (input, "checksum %d", &checksum_val))
10178         checksum = 1;
10179       else
10180         break;
10181     }
10182
10183   if (version + hdr_length + src + dst + proto + tos + length + fragment_id
10184       + ttl + checksum == 0)
10185     return 0;
10186
10187   /*
10188    * Aligned because we use the real comparison functions
10189    */
10190   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
10191
10192   ip = (ip4_header_t *) match;
10193
10194   /* These are realistically matched in practice */
10195   if (src)
10196     ip->src_address.as_u32 = src_val.as_u32;
10197
10198   if (dst)
10199     ip->dst_address.as_u32 = dst_val.as_u32;
10200
10201   if (proto)
10202     ip->protocol = proto_val;
10203
10204
10205   /* These are not, but they're included for completeness */
10206   if (version)
10207     ip->ip_version_and_header_length |= (version_val & 0xF) << 4;
10208
10209   if (hdr_length)
10210     ip->ip_version_and_header_length |= (hdr_length_val & 0xF);
10211
10212   if (tos)
10213     ip->tos = tos_val;
10214
10215   if (length)
10216     ip->length = clib_host_to_net_u16 (length_val);
10217
10218   if (ttl)
10219     ip->ttl = ttl_val;
10220
10221   if (checksum)
10222     ip->checksum = clib_host_to_net_u16 (checksum_val);
10223
10224   *matchp = match;
10225   return 1;
10226 }
10227
10228 uword
10229 unformat_ip6_match (unformat_input_t * input, va_list * args)
10230 {
10231   u8 **matchp = va_arg (*args, u8 **);
10232   u8 *match = 0;
10233   ip6_header_t *ip;
10234   int version = 0;
10235   u32 version_val;
10236   u8 traffic_class = 0;
10237   u32 traffic_class_val = 0;
10238   u8 flow_label = 0;
10239   u8 flow_label_val;
10240   int src = 0, dst = 0;
10241   ip6_address_t src_val, dst_val;
10242   int proto = 0;
10243   u32 proto_val;
10244   int payload_length = 0;
10245   u32 payload_length_val;
10246   int hop_limit = 0;
10247   int hop_limit_val;
10248   u32 ip_version_traffic_class_and_flow_label;
10249
10250   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10251     {
10252       if (unformat (input, "version %d", &version_val))
10253         version = 1;
10254       else if (unformat (input, "traffic_class %d", &traffic_class_val))
10255         traffic_class = 1;
10256       else if (unformat (input, "flow_label %d", &flow_label_val))
10257         flow_label = 1;
10258       else if (unformat (input, "src %U", unformat_ip6_address, &src_val))
10259         src = 1;
10260       else if (unformat (input, "dst %U", unformat_ip6_address, &dst_val))
10261         dst = 1;
10262       else if (unformat (input, "proto %d", &proto_val))
10263         proto = 1;
10264       else if (unformat (input, "payload_length %d", &payload_length_val))
10265         payload_length = 1;
10266       else if (unformat (input, "hop_limit %d", &hop_limit_val))
10267         hop_limit = 1;
10268       else
10269         break;
10270     }
10271
10272   if (version + traffic_class + flow_label + src + dst + proto +
10273       payload_length + hop_limit == 0)
10274     return 0;
10275
10276   /*
10277    * Aligned because we use the real comparison functions
10278    */
10279   vec_validate_aligned (match, sizeof (*ip) - 1, sizeof (u32x4));
10280
10281   ip = (ip6_header_t *) match;
10282
10283   if (src)
10284     clib_memcpy (&ip->src_address, &src_val, sizeof (ip->src_address));
10285
10286   if (dst)
10287     clib_memcpy (&ip->dst_address, &dst_val, sizeof (ip->dst_address));
10288
10289   if (proto)
10290     ip->protocol = proto_val;
10291
10292   ip_version_traffic_class_and_flow_label = 0;
10293
10294   if (version)
10295     ip_version_traffic_class_and_flow_label |= (version_val & 0xF) << 28;
10296
10297   if (traffic_class)
10298     ip_version_traffic_class_and_flow_label |=
10299       (traffic_class_val & 0xFF) << 20;
10300
10301   if (flow_label)
10302     ip_version_traffic_class_and_flow_label |= (flow_label_val & 0xFFFFF);
10303
10304   ip->ip_version_traffic_class_and_flow_label =
10305     clib_host_to_net_u32 (ip_version_traffic_class_and_flow_label);
10306
10307   if (payload_length)
10308     ip->payload_length = clib_host_to_net_u16 (payload_length_val);
10309
10310   if (hop_limit)
10311     ip->hop_limit = hop_limit_val;
10312
10313   *matchp = match;
10314   return 1;
10315 }
10316
10317 uword
10318 unformat_l3_match (unformat_input_t * input, va_list * args)
10319 {
10320   u8 **matchp = va_arg (*args, u8 **);
10321
10322   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10323     {
10324       if (unformat (input, "ip4 %U", unformat_ip4_match, matchp))
10325         return 1;
10326       else if (unformat (input, "ip6 %U", unformat_ip6_match, matchp))
10327         return 1;
10328       else
10329         break;
10330     }
10331   return 0;
10332 }
10333
10334 uword
10335 unformat_vlan_tag (unformat_input_t * input, va_list * args)
10336 {
10337   u8 *tagp = va_arg (*args, u8 *);
10338   u32 tag;
10339
10340   if (unformat (input, "%d", &tag))
10341     {
10342       tagp[0] = (tag >> 8) & 0x0F;
10343       tagp[1] = tag & 0xFF;
10344       return 1;
10345     }
10346
10347   return 0;
10348 }
10349
10350 uword
10351 unformat_l2_match (unformat_input_t * input, va_list * args)
10352 {
10353   u8 **matchp = va_arg (*args, u8 **);
10354   u8 *match = 0;
10355   u8 src = 0;
10356   u8 src_val[6];
10357   u8 dst = 0;
10358   u8 dst_val[6];
10359   u8 proto = 0;
10360   u16 proto_val;
10361   u8 tag1 = 0;
10362   u8 tag1_val[2];
10363   u8 tag2 = 0;
10364   u8 tag2_val[2];
10365   int len = 14;
10366   u8 ignore_tag1 = 0;
10367   u8 ignore_tag2 = 0;
10368   u8 cos1 = 0;
10369   u8 cos2 = 0;
10370   u32 cos1_val = 0;
10371   u32 cos2_val = 0;
10372
10373   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10374     {
10375       if (unformat (input, "src %U", unformat_ethernet_address, &src_val))
10376         src = 1;
10377       else
10378         if (unformat (input, "dst %U", unformat_ethernet_address, &dst_val))
10379         dst = 1;
10380       else if (unformat (input, "proto %U",
10381                          unformat_ethernet_type_host_byte_order, &proto_val))
10382         proto = 1;
10383       else if (unformat (input, "tag1 %U", unformat_vlan_tag, tag1_val))
10384         tag1 = 1;
10385       else if (unformat (input, "tag2 %U", unformat_vlan_tag, tag2_val))
10386         tag2 = 1;
10387       else if (unformat (input, "ignore-tag1"))
10388         ignore_tag1 = 1;
10389       else if (unformat (input, "ignore-tag2"))
10390         ignore_tag2 = 1;
10391       else if (unformat (input, "cos1 %d", &cos1_val))
10392         cos1 = 1;
10393       else if (unformat (input, "cos2 %d", &cos2_val))
10394         cos2 = 1;
10395       else
10396         break;
10397     }
10398   if ((src + dst + proto + tag1 + tag2 +
10399        ignore_tag1 + ignore_tag2 + cos1 + cos2) == 0)
10400     return 0;
10401
10402   if (tag1 || ignore_tag1 || cos1)
10403     len = 18;
10404   if (tag2 || ignore_tag2 || cos2)
10405     len = 22;
10406
10407   vec_validate_aligned (match, len - 1, sizeof (u32x4));
10408
10409   if (dst)
10410     clib_memcpy (match, dst_val, 6);
10411
10412   if (src)
10413     clib_memcpy (match + 6, src_val, 6);
10414
10415   if (tag2)
10416     {
10417       /* inner vlan tag */
10418       match[19] = tag2_val[1];
10419       match[18] = tag2_val[0];
10420       if (cos2)
10421         match[18] |= (cos2_val & 0x7) << 5;
10422       if (proto)
10423         {
10424           match[21] = proto_val & 0xff;
10425           match[20] = proto_val >> 8;
10426         }
10427       if (tag1)
10428         {
10429           match[15] = tag1_val[1];
10430           match[14] = tag1_val[0];
10431         }
10432       if (cos1)
10433         match[14] |= (cos1_val & 0x7) << 5;
10434       *matchp = match;
10435       return 1;
10436     }
10437   if (tag1)
10438     {
10439       match[15] = tag1_val[1];
10440       match[14] = tag1_val[0];
10441       if (proto)
10442         {
10443           match[17] = proto_val & 0xff;
10444           match[16] = proto_val >> 8;
10445         }
10446       if (cos1)
10447         match[14] |= (cos1_val & 0x7) << 5;
10448
10449       *matchp = match;
10450       return 1;
10451     }
10452   if (cos2)
10453     match[18] |= (cos2_val & 0x7) << 5;
10454   if (cos1)
10455     match[14] |= (cos1_val & 0x7) << 5;
10456   if (proto)
10457     {
10458       match[13] = proto_val & 0xff;
10459       match[12] = proto_val >> 8;
10460     }
10461
10462   *matchp = match;
10463   return 1;
10464 }
10465
10466 uword
10467 unformat_qos_source (unformat_input_t * input, va_list * args)
10468 {
10469   int *qs = va_arg (*args, int *);
10470
10471   if (unformat (input, "ip"))
10472     *qs = QOS_SOURCE_IP;
10473   else if (unformat (input, "mpls"))
10474     *qs = QOS_SOURCE_MPLS;
10475   else if (unformat (input, "ext"))
10476     *qs = QOS_SOURCE_EXT;
10477   else if (unformat (input, "vlan"))
10478     *qs = QOS_SOURCE_VLAN;
10479   else
10480     return 0;
10481
10482   return 1;
10483 }
10484 #endif
10485
10486 uword
10487 api_unformat_classify_match (unformat_input_t * input, va_list * args)
10488 {
10489   u8 **matchp = va_arg (*args, u8 **);
10490   u32 skip_n_vectors = va_arg (*args, u32);
10491   u32 match_n_vectors = va_arg (*args, u32);
10492
10493   u8 *match = 0;
10494   u8 *l2 = 0;
10495   u8 *l3 = 0;
10496   u8 *l4 = 0;
10497
10498   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
10499     {
10500       if (unformat (input, "hex %U", unformat_hex_string, &match))
10501         ;
10502       else if (unformat (input, "l2 %U", unformat_l2_match, &l2))
10503         ;
10504       else if (unformat (input, "l3 %U", unformat_l3_match, &l3))
10505         ;
10506       else if (unformat (input, "l4 %U", unformat_l4_match, &l4))
10507         ;
10508       else
10509         break;
10510     }
10511
10512   if (l4 && !l3)
10513     {
10514       vec_free (match);
10515       vec_free (l2);
10516       vec_free (l4);
10517       return 0;
10518     }
10519
10520   if (match || l2 || l3 || l4)
10521     {
10522       if (l2 || l3 || l4)
10523         {
10524           /* "Win a free Ethernet header in every packet" */
10525           if (l2 == 0)
10526             vec_validate_aligned (l2, 13, sizeof (u32x4));
10527           match = l2;
10528           if (vec_len (l3))
10529             {
10530               vec_append_aligned (match, l3, sizeof (u32x4));
10531               vec_free (l3);
10532             }
10533           if (vec_len (l4))
10534             {
10535               vec_append_aligned (match, l4, sizeof (u32x4));
10536               vec_free (l4);
10537             }
10538         }
10539
10540       /* Make sure the vector is big enough even if key is all 0's */
10541       vec_validate_aligned
10542         (match, ((match_n_vectors + skip_n_vectors) * sizeof (u32x4)) - 1,
10543          sizeof (u32x4));
10544
10545       /* Set size, include skipped vectors */
10546       _vec_len (match) = (match_n_vectors + skip_n_vectors) * sizeof (u32x4);
10547
10548       *matchp = match;
10549
10550       return 1;
10551     }
10552
10553   return 0;
10554 }
10555
10556 static int
10557 api_classify_add_del_session (vat_main_t * vam)
10558 {
10559   unformat_input_t *i = vam->input;
10560   vl_api_classify_add_del_session_t *mp;
10561   int is_add = 1;
10562   u32 table_index = ~0;
10563   u32 hit_next_index = ~0;
10564   u32 opaque_index = ~0;
10565   u8 *match = 0;
10566   i32 advance = 0;
10567   u32 skip_n_vectors = 0;
10568   u32 match_n_vectors = 0;
10569   u32 action = 0;
10570   u32 metadata = 0;
10571   int ret;
10572
10573   /*
10574    * Warning: you have to supply skip_n and match_n
10575    * because the API client cant simply look at the classify
10576    * table object.
10577    */
10578
10579   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10580     {
10581       if (unformat (i, "del"))
10582         is_add = 0;
10583       else if (unformat (i, "hit-next %U", api_unformat_ip_next_index,
10584                          &hit_next_index))
10585         ;
10586       else if (unformat (i, "l2-hit-next %U", unformat_l2_next_index,
10587                          &hit_next_index))
10588         ;
10589       else if (unformat (i, "acl-hit-next %U", api_unformat_acl_next_index,
10590                          &hit_next_index))
10591         ;
10592       else if (unformat (i, "policer-hit-next %d", &hit_next_index))
10593         ;
10594       else if (unformat (i, "%U", unformat_policer_precolor, &opaque_index))
10595         ;
10596       else if (unformat (i, "opaque-index %d", &opaque_index))
10597         ;
10598       else if (unformat (i, "skip_n %d", &skip_n_vectors))
10599         ;
10600       else if (unformat (i, "match_n %d", &match_n_vectors))
10601         ;
10602       else if (unformat (i, "match %U", api_unformat_classify_match,
10603                          &match, skip_n_vectors, match_n_vectors))
10604         ;
10605       else if (unformat (i, "advance %d", &advance))
10606         ;
10607       else if (unformat (i, "table-index %d", &table_index))
10608         ;
10609       else if (unformat (i, "action set-ip4-fib-id %d", &metadata))
10610         action = 1;
10611       else if (unformat (i, "action set-ip6-fib-id %d", &metadata))
10612         action = 2;
10613       else if (unformat (i, "action %d", &action))
10614         ;
10615       else if (unformat (i, "metadata %d", &metadata))
10616         ;
10617       else
10618         break;
10619     }
10620
10621   if (table_index == ~0)
10622     {
10623       errmsg ("Table index required");
10624       return -99;
10625     }
10626
10627   if (is_add && match == 0)
10628     {
10629       errmsg ("Match value required");
10630       return -99;
10631     }
10632
10633   M2 (CLASSIFY_ADD_DEL_SESSION, mp, vec_len (match));
10634
10635   mp->is_add = is_add;
10636   mp->table_index = ntohl (table_index);
10637   mp->hit_next_index = ntohl (hit_next_index);
10638   mp->opaque_index = ntohl (opaque_index);
10639   mp->advance = ntohl (advance);
10640   mp->action = action;
10641   mp->metadata = ntohl (metadata);
10642   mp->match_len = ntohl (vec_len (match));
10643   clib_memcpy (mp->match, match, vec_len (match));
10644   vec_free (match);
10645
10646   S (mp);
10647   W (ret);
10648   return ret;
10649 }
10650
10651 static int
10652 api_classify_set_interface_ip_table (vat_main_t * vam)
10653 {
10654   unformat_input_t *i = vam->input;
10655   vl_api_classify_set_interface_ip_table_t *mp;
10656   u32 sw_if_index;
10657   int sw_if_index_set;
10658   u32 table_index = ~0;
10659   u8 is_ipv6 = 0;
10660   int ret;
10661
10662   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10663     {
10664       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10665         sw_if_index_set = 1;
10666       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10667         sw_if_index_set = 1;
10668       else if (unformat (i, "table %d", &table_index))
10669         ;
10670       else
10671         {
10672           clib_warning ("parse error '%U'", format_unformat_error, i);
10673           return -99;
10674         }
10675     }
10676
10677   if (sw_if_index_set == 0)
10678     {
10679       errmsg ("missing interface name or sw_if_index");
10680       return -99;
10681     }
10682
10683
10684   M (CLASSIFY_SET_INTERFACE_IP_TABLE, mp);
10685
10686   mp->sw_if_index = ntohl (sw_if_index);
10687   mp->table_index = ntohl (table_index);
10688   mp->is_ipv6 = is_ipv6;
10689
10690   S (mp);
10691   W (ret);
10692   return ret;
10693 }
10694
10695 static int
10696 api_classify_set_interface_l2_tables (vat_main_t * vam)
10697 {
10698   unformat_input_t *i = vam->input;
10699   vl_api_classify_set_interface_l2_tables_t *mp;
10700   u32 sw_if_index;
10701   int sw_if_index_set;
10702   u32 ip4_table_index = ~0;
10703   u32 ip6_table_index = ~0;
10704   u32 other_table_index = ~0;
10705   u32 is_input = 1;
10706   int ret;
10707
10708   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10709     {
10710       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
10711         sw_if_index_set = 1;
10712       else if (unformat (i, "sw_if_index %d", &sw_if_index))
10713         sw_if_index_set = 1;
10714       else if (unformat (i, "ip4-table %d", &ip4_table_index))
10715         ;
10716       else if (unformat (i, "ip6-table %d", &ip6_table_index))
10717         ;
10718       else if (unformat (i, "other-table %d", &other_table_index))
10719         ;
10720       else if (unformat (i, "is-input %d", &is_input))
10721         ;
10722       else
10723         {
10724           clib_warning ("parse error '%U'", format_unformat_error, i);
10725           return -99;
10726         }
10727     }
10728
10729   if (sw_if_index_set == 0)
10730     {
10731       errmsg ("missing interface name or sw_if_index");
10732       return -99;
10733     }
10734
10735
10736   M (CLASSIFY_SET_INTERFACE_L2_TABLES, mp);
10737
10738   mp->sw_if_index = ntohl (sw_if_index);
10739   mp->ip4_table_index = ntohl (ip4_table_index);
10740   mp->ip6_table_index = ntohl (ip6_table_index);
10741   mp->other_table_index = ntohl (other_table_index);
10742   mp->is_input = (u8) is_input;
10743
10744   S (mp);
10745   W (ret);
10746   return ret;
10747 }
10748
10749 static int
10750 api_set_ipfix_exporter (vat_main_t * vam)
10751 {
10752   unformat_input_t *i = vam->input;
10753   vl_api_set_ipfix_exporter_t *mp;
10754   ip4_address_t collector_address;
10755   u8 collector_address_set = 0;
10756   u32 collector_port = ~0;
10757   ip4_address_t src_address;
10758   u8 src_address_set = 0;
10759   u32 vrf_id = ~0;
10760   u32 path_mtu = ~0;
10761   u32 template_interval = ~0;
10762   u8 udp_checksum = 0;
10763   int ret;
10764
10765   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10766     {
10767       if (unformat (i, "collector_address %U", unformat_ip4_address,
10768                     &collector_address))
10769         collector_address_set = 1;
10770       else if (unformat (i, "collector_port %d", &collector_port))
10771         ;
10772       else if (unformat (i, "src_address %U", unformat_ip4_address,
10773                          &src_address))
10774         src_address_set = 1;
10775       else if (unformat (i, "vrf_id %d", &vrf_id))
10776         ;
10777       else if (unformat (i, "path_mtu %d", &path_mtu))
10778         ;
10779       else if (unformat (i, "template_interval %d", &template_interval))
10780         ;
10781       else if (unformat (i, "udp_checksum"))
10782         udp_checksum = 1;
10783       else
10784         break;
10785     }
10786
10787   if (collector_address_set == 0)
10788     {
10789       errmsg ("collector_address required");
10790       return -99;
10791     }
10792
10793   if (src_address_set == 0)
10794     {
10795       errmsg ("src_address required");
10796       return -99;
10797     }
10798
10799   M (SET_IPFIX_EXPORTER, mp);
10800
10801   memcpy (mp->collector_address.un.ip4, collector_address.data,
10802           sizeof (collector_address.data));
10803   mp->collector_port = htons ((u16) collector_port);
10804   memcpy (mp->src_address.un.ip4, src_address.data,
10805           sizeof (src_address.data));
10806   mp->vrf_id = htonl (vrf_id);
10807   mp->path_mtu = htonl (path_mtu);
10808   mp->template_interval = htonl (template_interval);
10809   mp->udp_checksum = udp_checksum;
10810
10811   S (mp);
10812   W (ret);
10813   return ret;
10814 }
10815
10816 static int
10817 api_set_ipfix_classify_stream (vat_main_t * vam)
10818 {
10819   unformat_input_t *i = vam->input;
10820   vl_api_set_ipfix_classify_stream_t *mp;
10821   u32 domain_id = 0;
10822   u32 src_port = UDP_DST_PORT_ipfix;
10823   int ret;
10824
10825   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10826     {
10827       if (unformat (i, "domain %d", &domain_id))
10828         ;
10829       else if (unformat (i, "src_port %d", &src_port))
10830         ;
10831       else
10832         {
10833           errmsg ("unknown input `%U'", format_unformat_error, i);
10834           return -99;
10835         }
10836     }
10837
10838   M (SET_IPFIX_CLASSIFY_STREAM, mp);
10839
10840   mp->domain_id = htonl (domain_id);
10841   mp->src_port = htons ((u16) src_port);
10842
10843   S (mp);
10844   W (ret);
10845   return ret;
10846 }
10847
10848 static int
10849 api_ipfix_classify_table_add_del (vat_main_t * vam)
10850 {
10851   unformat_input_t *i = vam->input;
10852   vl_api_ipfix_classify_table_add_del_t *mp;
10853   int is_add = -1;
10854   u32 classify_table_index = ~0;
10855   u8 ip_version = 0;
10856   u8 transport_protocol = 255;
10857   int ret;
10858
10859   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10860     {
10861       if (unformat (i, "add"))
10862         is_add = 1;
10863       else if (unformat (i, "del"))
10864         is_add = 0;
10865       else if (unformat (i, "table %d", &classify_table_index))
10866         ;
10867       else if (unformat (i, "ip4"))
10868         ip_version = 4;
10869       else if (unformat (i, "ip6"))
10870         ip_version = 6;
10871       else if (unformat (i, "tcp"))
10872         transport_protocol = 6;
10873       else if (unformat (i, "udp"))
10874         transport_protocol = 17;
10875       else
10876         {
10877           errmsg ("unknown input `%U'", format_unformat_error, i);
10878           return -99;
10879         }
10880     }
10881
10882   if (is_add == -1)
10883     {
10884       errmsg ("expecting: add|del");
10885       return -99;
10886     }
10887   if (classify_table_index == ~0)
10888     {
10889       errmsg ("classifier table not specified");
10890       return -99;
10891     }
10892   if (ip_version == 0)
10893     {
10894       errmsg ("IP version not specified");
10895       return -99;
10896     }
10897
10898   M (IPFIX_CLASSIFY_TABLE_ADD_DEL, mp);
10899
10900   mp->is_add = is_add;
10901   mp->table_id = htonl (classify_table_index);
10902   mp->ip_version = ip_version;
10903   mp->transport_protocol = transport_protocol;
10904
10905   S (mp);
10906   W (ret);
10907   return ret;
10908 }
10909
10910 static int
10911 api_get_node_index (vat_main_t * vam)
10912 {
10913   unformat_input_t *i = vam->input;
10914   vl_api_get_node_index_t *mp;
10915   u8 *name = 0;
10916   int ret;
10917
10918   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10919     {
10920       if (unformat (i, "node %s", &name))
10921         ;
10922       else
10923         break;
10924     }
10925   if (name == 0)
10926     {
10927       errmsg ("node name required");
10928       return -99;
10929     }
10930   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
10931     {
10932       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
10933       return -99;
10934     }
10935
10936   M (GET_NODE_INDEX, mp);
10937   clib_memcpy (mp->node_name, name, vec_len (name));
10938   vec_free (name);
10939
10940   S (mp);
10941   W (ret);
10942   return ret;
10943 }
10944
10945 static int
10946 api_get_next_index (vat_main_t * vam)
10947 {
10948   unformat_input_t *i = vam->input;
10949   vl_api_get_next_index_t *mp;
10950   u8 *node_name = 0, *next_node_name = 0;
10951   int ret;
10952
10953   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
10954     {
10955       if (unformat (i, "node-name %s", &node_name))
10956         ;
10957       else if (unformat (i, "next-node-name %s", &next_node_name))
10958         break;
10959     }
10960
10961   if (node_name == 0)
10962     {
10963       errmsg ("node name required");
10964       return -99;
10965     }
10966   if (vec_len (node_name) >= ARRAY_LEN (mp->node_name))
10967     {
10968       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
10969       return -99;
10970     }
10971
10972   if (next_node_name == 0)
10973     {
10974       errmsg ("next node name required");
10975       return -99;
10976     }
10977   if (vec_len (next_node_name) >= ARRAY_LEN (mp->next_name))
10978     {
10979       errmsg ("next node name too long, max %d", ARRAY_LEN (mp->next_name));
10980       return -99;
10981     }
10982
10983   M (GET_NEXT_INDEX, mp);
10984   clib_memcpy (mp->node_name, node_name, vec_len (node_name));
10985   clib_memcpy (mp->next_name, next_node_name, vec_len (next_node_name));
10986   vec_free (node_name);
10987   vec_free (next_node_name);
10988
10989   S (mp);
10990   W (ret);
10991   return ret;
10992 }
10993
10994 static int
10995 api_add_node_next (vat_main_t * vam)
10996 {
10997   unformat_input_t *i = vam->input;
10998   vl_api_add_node_next_t *mp;
10999   u8 *name = 0;
11000   u8 *next = 0;
11001   int ret;
11002
11003   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11004     {
11005       if (unformat (i, "node %s", &name))
11006         ;
11007       else if (unformat (i, "next %s", &next))
11008         ;
11009       else
11010         break;
11011     }
11012   if (name == 0)
11013     {
11014       errmsg ("node name required");
11015       return -99;
11016     }
11017   if (vec_len (name) >= ARRAY_LEN (mp->node_name))
11018     {
11019       errmsg ("node name too long, max %d", ARRAY_LEN (mp->node_name));
11020       return -99;
11021     }
11022   if (next == 0)
11023     {
11024       errmsg ("next node required");
11025       return -99;
11026     }
11027   if (vec_len (next) >= ARRAY_LEN (mp->next_name))
11028     {
11029       errmsg ("next name too long, max %d", ARRAY_LEN (mp->next_name));
11030       return -99;
11031     }
11032
11033   M (ADD_NODE_NEXT, mp);
11034   clib_memcpy (mp->node_name, name, vec_len (name));
11035   clib_memcpy (mp->next_name, next, vec_len (next));
11036   vec_free (name);
11037   vec_free (next);
11038
11039   S (mp);
11040   W (ret);
11041   return ret;
11042 }
11043
11044 static int
11045 api_l2tpv3_create_tunnel (vat_main_t * vam)
11046 {
11047   unformat_input_t *i = vam->input;
11048   ip6_address_t client_address, our_address;
11049   int client_address_set = 0;
11050   int our_address_set = 0;
11051   u32 local_session_id = 0;
11052   u32 remote_session_id = 0;
11053   u64 local_cookie = 0;
11054   u64 remote_cookie = 0;
11055   u8 l2_sublayer_present = 0;
11056   vl_api_l2tpv3_create_tunnel_t *mp;
11057   int ret;
11058
11059   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11060     {
11061       if (unformat (i, "client_address %U", unformat_ip6_address,
11062                     &client_address))
11063         client_address_set = 1;
11064       else if (unformat (i, "our_address %U", unformat_ip6_address,
11065                          &our_address))
11066         our_address_set = 1;
11067       else if (unformat (i, "local_session_id %d", &local_session_id))
11068         ;
11069       else if (unformat (i, "remote_session_id %d", &remote_session_id))
11070         ;
11071       else if (unformat (i, "local_cookie %lld", &local_cookie))
11072         ;
11073       else if (unformat (i, "remote_cookie %lld", &remote_cookie))
11074         ;
11075       else if (unformat (i, "l2-sublayer-present"))
11076         l2_sublayer_present = 1;
11077       else
11078         break;
11079     }
11080
11081   if (client_address_set == 0)
11082     {
11083       errmsg ("client_address required");
11084       return -99;
11085     }
11086
11087   if (our_address_set == 0)
11088     {
11089       errmsg ("our_address required");
11090       return -99;
11091     }
11092
11093   M (L2TPV3_CREATE_TUNNEL, mp);
11094
11095   clib_memcpy (mp->client_address.un.ip6, client_address.as_u8,
11096                sizeof (ip6_address_t));
11097
11098   clib_memcpy (mp->our_address.un.ip6, our_address.as_u8,
11099                sizeof (ip6_address_t));
11100
11101   mp->local_session_id = ntohl (local_session_id);
11102   mp->remote_session_id = ntohl (remote_session_id);
11103   mp->local_cookie = clib_host_to_net_u64 (local_cookie);
11104   mp->remote_cookie = clib_host_to_net_u64 (remote_cookie);
11105   mp->l2_sublayer_present = l2_sublayer_present;
11106
11107   S (mp);
11108   W (ret);
11109   return ret;
11110 }
11111
11112 static int
11113 api_l2tpv3_set_tunnel_cookies (vat_main_t * vam)
11114 {
11115   unformat_input_t *i = vam->input;
11116   u32 sw_if_index;
11117   u8 sw_if_index_set = 0;
11118   u64 new_local_cookie = 0;
11119   u64 new_remote_cookie = 0;
11120   vl_api_l2tpv3_set_tunnel_cookies_t *mp;
11121   int ret;
11122
11123   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11124     {
11125       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11126         sw_if_index_set = 1;
11127       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11128         sw_if_index_set = 1;
11129       else if (unformat (i, "new_local_cookie %lld", &new_local_cookie))
11130         ;
11131       else if (unformat (i, "new_remote_cookie %lld", &new_remote_cookie))
11132         ;
11133       else
11134         break;
11135     }
11136
11137   if (sw_if_index_set == 0)
11138     {
11139       errmsg ("missing interface name or sw_if_index");
11140       return -99;
11141     }
11142
11143   M (L2TPV3_SET_TUNNEL_COOKIES, mp);
11144
11145   mp->sw_if_index = ntohl (sw_if_index);
11146   mp->new_local_cookie = clib_host_to_net_u64 (new_local_cookie);
11147   mp->new_remote_cookie = clib_host_to_net_u64 (new_remote_cookie);
11148
11149   S (mp);
11150   W (ret);
11151   return ret;
11152 }
11153
11154 static int
11155 api_l2tpv3_interface_enable_disable (vat_main_t * vam)
11156 {
11157   unformat_input_t *i = vam->input;
11158   vl_api_l2tpv3_interface_enable_disable_t *mp;
11159   u32 sw_if_index;
11160   u8 sw_if_index_set = 0;
11161   u8 enable_disable = 1;
11162   int ret;
11163
11164   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11165     {
11166       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
11167         sw_if_index_set = 1;
11168       else if (unformat (i, "sw_if_index %d", &sw_if_index))
11169         sw_if_index_set = 1;
11170       else if (unformat (i, "enable"))
11171         enable_disable = 1;
11172       else if (unformat (i, "disable"))
11173         enable_disable = 0;
11174       else
11175         break;
11176     }
11177
11178   if (sw_if_index_set == 0)
11179     {
11180       errmsg ("missing interface name or sw_if_index");
11181       return -99;
11182     }
11183
11184   M (L2TPV3_INTERFACE_ENABLE_DISABLE, mp);
11185
11186   mp->sw_if_index = ntohl (sw_if_index);
11187   mp->enable_disable = enable_disable;
11188
11189   S (mp);
11190   W (ret);
11191   return ret;
11192 }
11193
11194 static int
11195 api_l2tpv3_set_lookup_key (vat_main_t * vam)
11196 {
11197   unformat_input_t *i = vam->input;
11198   vl_api_l2tpv3_set_lookup_key_t *mp;
11199   u8 key = ~0;
11200   int ret;
11201
11202   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11203     {
11204       if (unformat (i, "lookup_v6_src"))
11205         key = L2T_LOOKUP_SRC_ADDRESS;
11206       else if (unformat (i, "lookup_v6_dst"))
11207         key = L2T_LOOKUP_DST_ADDRESS;
11208       else if (unformat (i, "lookup_session_id"))
11209         key = L2T_LOOKUP_SESSION_ID;
11210       else
11211         break;
11212     }
11213
11214   if (key == (u8) ~ 0)
11215     {
11216       errmsg ("l2tp session lookup key unset");
11217       return -99;
11218     }
11219
11220   M (L2TPV3_SET_LOOKUP_KEY, mp);
11221
11222   mp->key = key;
11223
11224   S (mp);
11225   W (ret);
11226   return ret;
11227 }
11228
11229 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler
11230   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
11231 {
11232   vat_main_t *vam = &vat_main;
11233
11234   print (vam->ofp, "* %U (our) %U (client) (sw_if_index %d)",
11235          format_ip6_address, mp->our_address,
11236          format_ip6_address, mp->client_address,
11237          clib_net_to_host_u32 (mp->sw_if_index));
11238
11239   print (vam->ofp,
11240          "   local cookies %016llx %016llx remote cookie %016llx",
11241          clib_net_to_host_u64 (mp->local_cookie[0]),
11242          clib_net_to_host_u64 (mp->local_cookie[1]),
11243          clib_net_to_host_u64 (mp->remote_cookie));
11244
11245   print (vam->ofp, "   local session-id %d remote session-id %d",
11246          clib_net_to_host_u32 (mp->local_session_id),
11247          clib_net_to_host_u32 (mp->remote_session_id));
11248
11249   print (vam->ofp, "   l2 specific sublayer %s\n",
11250          mp->l2_sublayer_present ? "preset" : "absent");
11251
11252 }
11253
11254 static void vl_api_sw_if_l2tpv3_tunnel_details_t_handler_json
11255   (vl_api_sw_if_l2tpv3_tunnel_details_t * mp)
11256 {
11257   vat_main_t *vam = &vat_main;
11258   vat_json_node_t *node = NULL;
11259   struct in6_addr addr;
11260
11261   if (VAT_JSON_ARRAY != vam->json_tree.type)
11262     {
11263       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11264       vat_json_init_array (&vam->json_tree);
11265     }
11266   node = vat_json_array_add (&vam->json_tree);
11267
11268   vat_json_init_object (node);
11269
11270   clib_memcpy (&addr, mp->our_address.un.ip6, sizeof (addr));
11271   vat_json_object_add_ip6 (node, "our_address", addr);
11272   clib_memcpy (&addr, mp->client_address.un.ip6, sizeof (addr));
11273   vat_json_object_add_ip6 (node, "client_address", addr);
11274
11275   vat_json_node_t *lc = vat_json_object_add (node, "local_cookie");
11276   vat_json_init_array (lc);
11277   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[0]));
11278   vat_json_array_add_uint (lc, clib_net_to_host_u64 (mp->local_cookie[1]));
11279   vat_json_object_add_uint (node, "remote_cookie",
11280                             clib_net_to_host_u64 (mp->remote_cookie));
11281
11282   printf ("local id: %u", clib_net_to_host_u32 (mp->local_session_id));
11283   vat_json_object_add_uint (node, "local_session_id",
11284                             clib_net_to_host_u32 (mp->local_session_id));
11285   vat_json_object_add_uint (node, "remote_session_id",
11286                             clib_net_to_host_u32 (mp->remote_session_id));
11287   vat_json_object_add_string_copy (node, "l2_sublayer",
11288                                    mp->l2_sublayer_present ? (u8 *) "present"
11289                                    : (u8 *) "absent");
11290 }
11291
11292 static int
11293 api_sw_if_l2tpv3_tunnel_dump (vat_main_t * vam)
11294 {
11295   vl_api_sw_if_l2tpv3_tunnel_dump_t *mp;
11296   vl_api_control_ping_t *mp_ping;
11297   int ret;
11298
11299   /* Get list of l2tpv3-tunnel interfaces */
11300   M (SW_IF_L2TPV3_TUNNEL_DUMP, mp);
11301   S (mp);
11302
11303   /* Use a control ping for synchronization */
11304   MPING (CONTROL_PING, mp_ping);
11305   S (mp_ping);
11306
11307   W (ret);
11308   return ret;
11309 }
11310
11311
11312 static void vl_api_sw_interface_tap_v2_details_t_handler
11313   (vl_api_sw_interface_tap_v2_details_t * mp)
11314 {
11315   vat_main_t *vam = &vat_main;
11316
11317   u8 *ip4 =
11318     format (0, "%U/%d", format_ip4_address, mp->host_ip4_prefix.address,
11319             mp->host_ip4_prefix.len);
11320   u8 *ip6 =
11321     format (0, "%U/%d", format_ip6_address, mp->host_ip6_prefix.address,
11322             mp->host_ip6_prefix.len);
11323
11324   print (vam->ofp,
11325          "\n%-16s %-12d %-5d %-12d %-12d %-14U %-30s %-20s %-20s %-30s 0x%-08x",
11326          mp->dev_name, ntohl (mp->sw_if_index), ntohl (mp->id),
11327          ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
11328          format_ethernet_address, mp->host_mac_addr, mp->host_namespace,
11329          mp->host_bridge, ip4, ip6, ntohl (mp->tap_flags));
11330
11331   vec_free (ip4);
11332   vec_free (ip6);
11333 }
11334
11335 static void vl_api_sw_interface_tap_v2_details_t_handler_json
11336   (vl_api_sw_interface_tap_v2_details_t * mp)
11337 {
11338   vat_main_t *vam = &vat_main;
11339   vat_json_node_t *node = NULL;
11340
11341   if (VAT_JSON_ARRAY != vam->json_tree.type)
11342     {
11343       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11344       vat_json_init_array (&vam->json_tree);
11345     }
11346   node = vat_json_array_add (&vam->json_tree);
11347
11348   vat_json_init_object (node);
11349   vat_json_object_add_uint (node, "id", ntohl (mp->id));
11350   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11351   vat_json_object_add_uint (node, "tap_flags", ntohl (mp->tap_flags));
11352   vat_json_object_add_string_copy (node, "dev_name", mp->dev_name);
11353   vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
11354   vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
11355   vat_json_object_add_string_copy (node, "host_mac_addr",
11356                                    format (0, "%U", format_ethernet_address,
11357                                            &mp->host_mac_addr));
11358   vat_json_object_add_string_copy (node, "host_namespace",
11359                                    mp->host_namespace);
11360   vat_json_object_add_string_copy (node, "host_bridge", mp->host_bridge);
11361   vat_json_object_add_string_copy (node, "host_ip4_addr",
11362                                    format (0, "%U/%d", format_ip4_address,
11363                                            mp->host_ip4_prefix.address,
11364                                            mp->host_ip4_prefix.len));
11365   vat_json_object_add_string_copy (node, "host_ip6_prefix",
11366                                    format (0, "%U/%d", format_ip6_address,
11367                                            mp->host_ip6_prefix.address,
11368                                            mp->host_ip6_prefix.len));
11369
11370 }
11371
11372 static int
11373 api_sw_interface_tap_v2_dump (vat_main_t * vam)
11374 {
11375   vl_api_sw_interface_tap_v2_dump_t *mp;
11376   vl_api_control_ping_t *mp_ping;
11377   int ret;
11378
11379   print (vam->ofp,
11380          "\n%-16s %-12s %-5s %-12s %-12s %-14s %-30s %-20s %-20s %-30s",
11381          "dev_name", "sw_if_index", "id", "rx_ring_sz", "tx_ring_sz",
11382          "host_mac_addr", "host_namespace", "host_bridge", "host_ip4_addr",
11383          "host_ip6_addr");
11384
11385   /* Get list of tap interfaces */
11386   M (SW_INTERFACE_TAP_V2_DUMP, mp);
11387   S (mp);
11388
11389   /* Use a control ping for synchronization */
11390   MPING (CONTROL_PING, mp_ping);
11391   S (mp_ping);
11392
11393   W (ret);
11394   return ret;
11395 }
11396
11397 static void vl_api_sw_interface_virtio_pci_details_t_handler
11398   (vl_api_sw_interface_virtio_pci_details_t * mp)
11399 {
11400   vat_main_t *vam = &vat_main;
11401
11402   typedef union
11403   {
11404     struct
11405     {
11406       u16 domain;
11407       u8 bus;
11408       u8 slot:5;
11409       u8 function:3;
11410     };
11411     u32 as_u32;
11412   } pci_addr_t;
11413   pci_addr_t addr;
11414
11415   addr.domain = ntohs (mp->pci_addr.domain);
11416   addr.bus = mp->pci_addr.bus;
11417   addr.slot = mp->pci_addr.slot;
11418   addr.function = mp->pci_addr.function;
11419
11420   u8 *pci_addr = format (0, "%04x:%02x:%02x.%x", addr.domain, addr.bus,
11421                          addr.slot, addr.function);
11422
11423   print (vam->ofp,
11424          "\n%-12s %-12d %-12d %-12d %-17U 0x%-08llx",
11425          pci_addr, ntohl (mp->sw_if_index),
11426          ntohs (mp->rx_ring_sz), ntohs (mp->tx_ring_sz),
11427          format_ethernet_address, mp->mac_addr,
11428          clib_net_to_host_u64 (mp->features));
11429   vec_free (pci_addr);
11430 }
11431
11432 static void vl_api_sw_interface_virtio_pci_details_t_handler_json
11433   (vl_api_sw_interface_virtio_pci_details_t * mp)
11434 {
11435   vat_main_t *vam = &vat_main;
11436   vat_json_node_t *node = NULL;
11437   vlib_pci_addr_t pci_addr;
11438
11439   if (VAT_JSON_ARRAY != vam->json_tree.type)
11440     {
11441       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11442       vat_json_init_array (&vam->json_tree);
11443     }
11444   node = vat_json_array_add (&vam->json_tree);
11445
11446   pci_addr.domain = ntohs (mp->pci_addr.domain);
11447   pci_addr.bus = mp->pci_addr.bus;
11448   pci_addr.slot = mp->pci_addr.slot;
11449   pci_addr.function = mp->pci_addr.function;
11450
11451   vat_json_init_object (node);
11452   vat_json_object_add_uint (node, "pci-addr", pci_addr.as_u32);
11453   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11454   vat_json_object_add_uint (node, "rx_ring_sz", ntohs (mp->rx_ring_sz));
11455   vat_json_object_add_uint (node, "tx_ring_sz", ntohs (mp->tx_ring_sz));
11456   vat_json_object_add_uint (node, "features",
11457                             clib_net_to_host_u64 (mp->features));
11458   vat_json_object_add_string_copy (node, "mac_addr",
11459                                    format (0, "%U", format_ethernet_address,
11460                                            &mp->mac_addr));
11461 }
11462
11463 static int
11464 api_sw_interface_virtio_pci_dump (vat_main_t * vam)
11465 {
11466   vl_api_sw_interface_virtio_pci_dump_t *mp;
11467   vl_api_control_ping_t *mp_ping;
11468   int ret;
11469
11470   print (vam->ofp,
11471          "\n%-12s %-12s %-12s %-12s %-17s %-08s",
11472          "pci_addr", "sw_if_index", "rx_ring_sz", "tx_ring_sz",
11473          "mac_addr", "features");
11474
11475   /* Get list of tap interfaces */
11476   M (SW_INTERFACE_VIRTIO_PCI_DUMP, mp);
11477   S (mp);
11478
11479   /* Use a control ping for synchronization */
11480   MPING (CONTROL_PING, mp_ping);
11481   S (mp_ping);
11482
11483   W (ret);
11484   return ret;
11485 }
11486
11487 static int
11488 api_vxlan_offload_rx (vat_main_t * vam)
11489 {
11490   unformat_input_t *line_input = vam->input;
11491   vl_api_vxlan_offload_rx_t *mp;
11492   u32 hw_if_index = ~0, rx_if_index = ~0;
11493   u8 is_add = 1;
11494   int ret;
11495
11496   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11497     {
11498       if (unformat (line_input, "del"))
11499         is_add = 0;
11500       else if (unformat (line_input, "hw %U", api_unformat_hw_if_index, vam,
11501                          &hw_if_index))
11502         ;
11503       else if (unformat (line_input, "hw hw_if_index %u", &hw_if_index))
11504         ;
11505       else if (unformat (line_input, "rx %U", api_unformat_sw_if_index, vam,
11506                          &rx_if_index))
11507         ;
11508       else if (unformat (line_input, "rx sw_if_index %u", &rx_if_index))
11509         ;
11510       else
11511         {
11512           errmsg ("parse error '%U'", format_unformat_error, line_input);
11513           return -99;
11514         }
11515     }
11516
11517   if (hw_if_index == ~0)
11518     {
11519       errmsg ("no hw interface");
11520       return -99;
11521     }
11522
11523   if (rx_if_index == ~0)
11524     {
11525       errmsg ("no rx tunnel");
11526       return -99;
11527     }
11528
11529   M (VXLAN_OFFLOAD_RX, mp);
11530
11531   mp->hw_if_index = ntohl (hw_if_index);
11532   mp->sw_if_index = ntohl (rx_if_index);
11533   mp->enable = is_add;
11534
11535   S (mp);
11536   W (ret);
11537   return ret;
11538 }
11539
11540 static uword unformat_vxlan_decap_next
11541   (unformat_input_t * input, va_list * args)
11542 {
11543   u32 *result = va_arg (*args, u32 *);
11544   u32 tmp;
11545
11546   if (unformat (input, "l2"))
11547     *result = VXLAN_INPUT_NEXT_L2_INPUT;
11548   else if (unformat (input, "%d", &tmp))
11549     *result = tmp;
11550   else
11551     return 0;
11552   return 1;
11553 }
11554
11555 static int
11556 api_vxlan_add_del_tunnel (vat_main_t * vam)
11557 {
11558   unformat_input_t *line_input = vam->input;
11559   vl_api_vxlan_add_del_tunnel_t *mp;
11560   ip46_address_t src, dst;
11561   u8 is_add = 1;
11562   u8 ipv4_set = 0, ipv6_set = 0;
11563   u8 src_set = 0;
11564   u8 dst_set = 0;
11565   u8 grp_set = 0;
11566   u32 instance = ~0;
11567   u32 mcast_sw_if_index = ~0;
11568   u32 encap_vrf_id = 0;
11569   u32 decap_next_index = ~0;
11570   u32 vni = 0;
11571   int ret;
11572
11573   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
11574   clib_memset (&src, 0, sizeof src);
11575   clib_memset (&dst, 0, sizeof dst);
11576
11577   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11578     {
11579       if (unformat (line_input, "del"))
11580         is_add = 0;
11581       else if (unformat (line_input, "instance %d", &instance))
11582         ;
11583       else
11584         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
11585         {
11586           ipv4_set = 1;
11587           src_set = 1;
11588         }
11589       else
11590         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
11591         {
11592           ipv4_set = 1;
11593           dst_set = 1;
11594         }
11595       else
11596         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
11597         {
11598           ipv6_set = 1;
11599           src_set = 1;
11600         }
11601       else
11602         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
11603         {
11604           ipv6_set = 1;
11605           dst_set = 1;
11606         }
11607       else if (unformat (line_input, "group %U %U",
11608                          unformat_ip4_address, &dst.ip4,
11609                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
11610         {
11611           grp_set = dst_set = 1;
11612           ipv4_set = 1;
11613         }
11614       else if (unformat (line_input, "group %U",
11615                          unformat_ip4_address, &dst.ip4))
11616         {
11617           grp_set = dst_set = 1;
11618           ipv4_set = 1;
11619         }
11620       else if (unformat (line_input, "group %U %U",
11621                          unformat_ip6_address, &dst.ip6,
11622                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
11623         {
11624           grp_set = dst_set = 1;
11625           ipv6_set = 1;
11626         }
11627       else if (unformat (line_input, "group %U",
11628                          unformat_ip6_address, &dst.ip6))
11629         {
11630           grp_set = dst_set = 1;
11631           ipv6_set = 1;
11632         }
11633       else
11634         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
11635         ;
11636       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
11637         ;
11638       else if (unformat (line_input, "decap-next %U",
11639                          unformat_vxlan_decap_next, &decap_next_index))
11640         ;
11641       else if (unformat (line_input, "vni %d", &vni))
11642         ;
11643       else
11644         {
11645           errmsg ("parse error '%U'", format_unformat_error, line_input);
11646           return -99;
11647         }
11648     }
11649
11650   if (src_set == 0)
11651     {
11652       errmsg ("tunnel src address not specified");
11653       return -99;
11654     }
11655   if (dst_set == 0)
11656     {
11657       errmsg ("tunnel dst address not specified");
11658       return -99;
11659     }
11660
11661   if (grp_set && !ip46_address_is_multicast (&dst))
11662     {
11663       errmsg ("tunnel group address not multicast");
11664       return -99;
11665     }
11666   if (grp_set && mcast_sw_if_index == ~0)
11667     {
11668       errmsg ("tunnel nonexistent multicast device");
11669       return -99;
11670     }
11671   if (grp_set == 0 && ip46_address_is_multicast (&dst))
11672     {
11673       errmsg ("tunnel dst address must be unicast");
11674       return -99;
11675     }
11676
11677
11678   if (ipv4_set && ipv6_set)
11679     {
11680       errmsg ("both IPv4 and IPv6 addresses specified");
11681       return -99;
11682     }
11683
11684   if ((vni == 0) || (vni >> 24))
11685     {
11686       errmsg ("vni not specified or out of range");
11687       return -99;
11688     }
11689
11690   M (VXLAN_ADD_DEL_TUNNEL, mp);
11691
11692   if (ipv6_set)
11693     {
11694       clib_memcpy (mp->src_address, &src.ip6, sizeof (src.ip6));
11695       clib_memcpy (mp->dst_address, &dst.ip6, sizeof (dst.ip6));
11696     }
11697   else
11698     {
11699       clib_memcpy (mp->src_address, &src.ip4, sizeof (src.ip4));
11700       clib_memcpy (mp->dst_address, &dst.ip4, sizeof (dst.ip4));
11701     }
11702
11703   mp->instance = htonl (instance);
11704   mp->encap_vrf_id = ntohl (encap_vrf_id);
11705   mp->decap_next_index = ntohl (decap_next_index);
11706   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
11707   mp->vni = ntohl (vni);
11708   mp->is_add = is_add;
11709   mp->is_ipv6 = ipv6_set;
11710
11711   S (mp);
11712   W (ret);
11713   return ret;
11714 }
11715
11716 static void vl_api_vxlan_tunnel_details_t_handler
11717   (vl_api_vxlan_tunnel_details_t * mp)
11718 {
11719   vat_main_t *vam = &vat_main;
11720   ip46_address_t src = to_ip46 (mp->is_ipv6, mp->dst_address);
11721   ip46_address_t dst = to_ip46 (mp->is_ipv6, mp->src_address);
11722
11723   print (vam->ofp, "%11d%11d%24U%24U%14d%18d%13d%19d",
11724          ntohl (mp->sw_if_index),
11725          ntohl (mp->instance),
11726          format_ip46_address, &src, IP46_TYPE_ANY,
11727          format_ip46_address, &dst, IP46_TYPE_ANY,
11728          ntohl (mp->encap_vrf_id),
11729          ntohl (mp->decap_next_index), ntohl (mp->vni),
11730          ntohl (mp->mcast_sw_if_index));
11731 }
11732
11733 static void vl_api_vxlan_tunnel_details_t_handler_json
11734   (vl_api_vxlan_tunnel_details_t * mp)
11735 {
11736   vat_main_t *vam = &vat_main;
11737   vat_json_node_t *node = NULL;
11738
11739   if (VAT_JSON_ARRAY != vam->json_tree.type)
11740     {
11741       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
11742       vat_json_init_array (&vam->json_tree);
11743     }
11744   node = vat_json_array_add (&vam->json_tree);
11745
11746   vat_json_init_object (node);
11747   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
11748
11749   vat_json_object_add_uint (node, "instance", ntohl (mp->instance));
11750
11751   if (mp->is_ipv6)
11752     {
11753       struct in6_addr ip6;
11754
11755       clib_memcpy (&ip6, mp->src_address, sizeof (ip6));
11756       vat_json_object_add_ip6 (node, "src_address", ip6);
11757       clib_memcpy (&ip6, mp->dst_address, sizeof (ip6));
11758       vat_json_object_add_ip6 (node, "dst_address", ip6);
11759     }
11760   else
11761     {
11762       struct in_addr ip4;
11763
11764       clib_memcpy (&ip4, mp->src_address, sizeof (ip4));
11765       vat_json_object_add_ip4 (node, "src_address", ip4);
11766       clib_memcpy (&ip4, mp->dst_address, sizeof (ip4));
11767       vat_json_object_add_ip4 (node, "dst_address", ip4);
11768     }
11769   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
11770   vat_json_object_add_uint (node, "decap_next_index",
11771                             ntohl (mp->decap_next_index));
11772   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
11773   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
11774   vat_json_object_add_uint (node, "mcast_sw_if_index",
11775                             ntohl (mp->mcast_sw_if_index));
11776 }
11777
11778 static int
11779 api_vxlan_tunnel_dump (vat_main_t * vam)
11780 {
11781   unformat_input_t *i = vam->input;
11782   vl_api_vxlan_tunnel_dump_t *mp;
11783   vl_api_control_ping_t *mp_ping;
11784   u32 sw_if_index;
11785   u8 sw_if_index_set = 0;
11786   int ret;
11787
11788   /* Parse args required to build the message */
11789   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
11790     {
11791       if (unformat (i, "sw_if_index %d", &sw_if_index))
11792         sw_if_index_set = 1;
11793       else
11794         break;
11795     }
11796
11797   if (sw_if_index_set == 0)
11798     {
11799       sw_if_index = ~0;
11800     }
11801
11802   if (!vam->json_output)
11803     {
11804       print (vam->ofp, "%11s%11s%24s%24s%14s%18s%13s%19s",
11805              "sw_if_index", "instance", "src_address", "dst_address",
11806              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
11807     }
11808
11809   /* Get list of vxlan-tunnel interfaces */
11810   M (VXLAN_TUNNEL_DUMP, mp);
11811
11812   mp->sw_if_index = htonl (sw_if_index);
11813
11814   S (mp);
11815
11816   /* Use a control ping for synchronization */
11817   MPING (CONTROL_PING, mp_ping);
11818   S (mp_ping);
11819
11820   W (ret);
11821   return ret;
11822 }
11823
11824 static uword unformat_geneve_decap_next
11825   (unformat_input_t * input, va_list * args)
11826 {
11827   u32 *result = va_arg (*args, u32 *);
11828   u32 tmp;
11829
11830   if (unformat (input, "l2"))
11831     *result = GENEVE_INPUT_NEXT_L2_INPUT;
11832   else if (unformat (input, "%d", &tmp))
11833     *result = tmp;
11834   else
11835     return 0;
11836   return 1;
11837 }
11838
11839 static int
11840 api_geneve_add_del_tunnel (vat_main_t * vam)
11841 {
11842   unformat_input_t *line_input = vam->input;
11843   vl_api_geneve_add_del_tunnel_t *mp;
11844   ip46_address_t src, dst;
11845   u8 is_add = 1;
11846   u8 ipv4_set = 0, ipv6_set = 0;
11847   u8 src_set = 0;
11848   u8 dst_set = 0;
11849   u8 grp_set = 0;
11850   u32 mcast_sw_if_index = ~0;
11851   u32 encap_vrf_id = 0;
11852   u32 decap_next_index = ~0;
11853   u32 vni = 0;
11854   int ret;
11855
11856   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
11857   clib_memset (&src, 0, sizeof src);
11858   clib_memset (&dst, 0, sizeof dst);
11859
11860   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
11861     {
11862       if (unformat (line_input, "del"))
11863         is_add = 0;
11864       else
11865         if (unformat (line_input, "src %U", unformat_ip4_address, &src.ip4))
11866         {
11867           ipv4_set = 1;
11868           src_set = 1;
11869         }
11870       else
11871         if (unformat (line_input, "dst %U", unformat_ip4_address, &dst.ip4))
11872         {
11873           ipv4_set = 1;
11874           dst_set = 1;
11875         }
11876       else
11877         if (unformat (line_input, "src %U", unformat_ip6_address, &src.ip6))
11878         {
11879           ipv6_set = 1;
11880           src_set = 1;
11881         }
11882       else
11883         if (unformat (line_input, "dst %U", unformat_ip6_address, &dst.ip6))
11884         {
11885           ipv6_set = 1;
11886           dst_set = 1;
11887         }
11888       else if (unformat (line_input, "group %U %U",
11889                          unformat_ip4_address, &dst.ip4,
11890                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
11891         {
11892           grp_set = dst_set = 1;
11893           ipv4_set = 1;
11894         }
11895       else if (unformat (line_input, "group %U",
11896                          unformat_ip4_address, &dst.ip4))
11897         {
11898           grp_set = dst_set = 1;
11899           ipv4_set = 1;
11900         }
11901       else if (unformat (line_input, "group %U %U",
11902                          unformat_ip6_address, &dst.ip6,
11903                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
11904         {
11905           grp_set = dst_set = 1;
11906           ipv6_set = 1;
11907         }
11908       else if (unformat (line_input, "group %U",
11909                          unformat_ip6_address, &dst.ip6))
11910         {
11911           grp_set = dst_set = 1;
11912           ipv6_set = 1;
11913         }
11914       else
11915         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
11916         ;
11917       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
11918         ;
11919       else if (unformat (line_input, "decap-next %U",
11920                          unformat_geneve_decap_next, &decap_next_index))
11921         ;
11922       else if (unformat (line_input, "vni %d", &vni))
11923         ;
11924       else
11925         {
11926           errmsg ("parse error '%U'", format_unformat_error, line_input);
11927           return -99;
11928         }
11929     }
11930
11931   if (src_set == 0)
11932     {
11933       errmsg ("tunnel src address not specified");
11934       return -99;
11935     }
11936   if (dst_set == 0)
11937     {
11938       errmsg ("tunnel dst address not specified");
11939       return -99;
11940     }
11941
11942   if (grp_set && !ip46_address_is_multicast (&dst))
11943     {
11944       errmsg ("tunnel group address not multicast");
11945       return -99;
11946     }
11947   if (grp_set && mcast_sw_if_index == ~0)
11948     {
11949       errmsg ("tunnel nonexistent multicast device");
11950       return -99;
11951     }
11952   if (grp_set == 0 && ip46_address_is_multicast (&dst))
11953     {
11954       errmsg ("tunnel dst address must be unicast");
11955       return -99;
11956     }
11957
11958
11959   if (ipv4_set && ipv6_set)
11960     {
11961       errmsg ("both IPv4 and IPv6 addresses specified");
11962       return -99;
11963     }
11964
11965   if ((vni == 0) || (vni >> 24))
11966     {
11967       errmsg ("vni not specified or out of range");
11968       return -99;
11969     }
11970
11971   M (GENEVE_ADD_DEL_TUNNEL, mp);
11972
11973   if (ipv6_set)
11974     {
11975       clib_memcpy (&mp->local_address.un.ip6, &src.ip6, sizeof (src.ip6));
11976       clib_memcpy (&mp->remote_address.un.ip6, &dst.ip6, sizeof (dst.ip6));
11977     }
11978   else
11979     {
11980       clib_memcpy (&mp->local_address.un.ip4, &src.ip4, sizeof (src.ip4));
11981       clib_memcpy (&mp->remote_address.un.ip4, &dst.ip4, sizeof (dst.ip4));
11982     }
11983   mp->encap_vrf_id = ntohl (encap_vrf_id);
11984   mp->decap_next_index = ntohl (decap_next_index);
11985   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
11986   mp->vni = ntohl (vni);
11987   mp->is_add = is_add;
11988
11989   S (mp);
11990   W (ret);
11991   return ret;
11992 }
11993
11994 static void vl_api_geneve_tunnel_details_t_handler
11995   (vl_api_geneve_tunnel_details_t * mp)
11996 {
11997   vat_main_t *vam = &vat_main;
11998   ip46_address_t src = {.as_u64[0] = 0,.as_u64[1] = 0 };
11999   ip46_address_t dst = {.as_u64[0] = 0,.as_u64[1] = 0 };
12000
12001   if (mp->src_address.af == ADDRESS_IP6)
12002     {
12003       clib_memcpy (&src.ip6, &mp->src_address.un.ip6, sizeof (ip6_address_t));
12004       clib_memcpy (&dst.ip6, &mp->dst_address.un.ip6, sizeof (ip6_address_t));
12005     }
12006   else
12007     {
12008       clib_memcpy (&src.ip4, &mp->src_address.un.ip4, sizeof (ip4_address_t));
12009       clib_memcpy (&dst.ip4, &mp->dst_address.un.ip4, sizeof (ip4_address_t));
12010     }
12011
12012   print (vam->ofp, "%11d%24U%24U%14d%18d%13d%19d",
12013          ntohl (mp->sw_if_index),
12014          format_ip46_address, &src, IP46_TYPE_ANY,
12015          format_ip46_address, &dst, IP46_TYPE_ANY,
12016          ntohl (mp->encap_vrf_id),
12017          ntohl (mp->decap_next_index), ntohl (mp->vni),
12018          ntohl (mp->mcast_sw_if_index));
12019 }
12020
12021 static void vl_api_geneve_tunnel_details_t_handler_json
12022   (vl_api_geneve_tunnel_details_t * mp)
12023 {
12024   vat_main_t *vam = &vat_main;
12025   vat_json_node_t *node = NULL;
12026   bool is_ipv6;
12027
12028   if (VAT_JSON_ARRAY != vam->json_tree.type)
12029     {
12030       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12031       vat_json_init_array (&vam->json_tree);
12032     }
12033   node = vat_json_array_add (&vam->json_tree);
12034
12035   vat_json_init_object (node);
12036   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12037   is_ipv6 = mp->src_address.af == ADDRESS_IP6;
12038   if (is_ipv6)
12039     {
12040       struct in6_addr ip6;
12041
12042       clib_memcpy (&ip6, &mp->src_address.un.ip6, sizeof (ip6));
12043       vat_json_object_add_ip6 (node, "src_address", ip6);
12044       clib_memcpy (&ip6, &mp->dst_address.un.ip6, sizeof (ip6));
12045       vat_json_object_add_ip6 (node, "dst_address", ip6);
12046     }
12047   else
12048     {
12049       struct in_addr ip4;
12050
12051       clib_memcpy (&ip4, &mp->src_address.un.ip4, sizeof (ip4));
12052       vat_json_object_add_ip4 (node, "src_address", ip4);
12053       clib_memcpy (&ip4, &mp->dst_address.un.ip4, sizeof (ip4));
12054       vat_json_object_add_ip4 (node, "dst_address", ip4);
12055     }
12056   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
12057   vat_json_object_add_uint (node, "decap_next_index",
12058                             ntohl (mp->decap_next_index));
12059   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
12060   vat_json_object_add_uint (node, "mcast_sw_if_index",
12061                             ntohl (mp->mcast_sw_if_index));
12062 }
12063
12064 static int
12065 api_geneve_tunnel_dump (vat_main_t * vam)
12066 {
12067   unformat_input_t *i = vam->input;
12068   vl_api_geneve_tunnel_dump_t *mp;
12069   vl_api_control_ping_t *mp_ping;
12070   u32 sw_if_index;
12071   u8 sw_if_index_set = 0;
12072   int ret;
12073
12074   /* Parse args required to build the message */
12075   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12076     {
12077       if (unformat (i, "sw_if_index %d", &sw_if_index))
12078         sw_if_index_set = 1;
12079       else
12080         break;
12081     }
12082
12083   if (sw_if_index_set == 0)
12084     {
12085       sw_if_index = ~0;
12086     }
12087
12088   if (!vam->json_output)
12089     {
12090       print (vam->ofp, "%11s%24s%24s%14s%18s%13s%19s",
12091              "sw_if_index", "local_address", "remote_address",
12092              "encap_vrf_id", "decap_next_index", "vni", "mcast_sw_if_index");
12093     }
12094
12095   /* Get list of geneve-tunnel interfaces */
12096   M (GENEVE_TUNNEL_DUMP, mp);
12097
12098   mp->sw_if_index = htonl (sw_if_index);
12099
12100   S (mp);
12101
12102   /* Use a control ping for synchronization */
12103   M (CONTROL_PING, mp_ping);
12104   S (mp_ping);
12105
12106   W (ret);
12107   return ret;
12108 }
12109
12110 static int
12111 api_gre_tunnel_add_del (vat_main_t * vam)
12112 {
12113   unformat_input_t *line_input = vam->input;
12114   vl_api_address_t src = { }, dst =
12115   {
12116   };
12117   vl_api_gre_tunnel_add_del_t *mp;
12118   vl_api_gre_tunnel_type_t t_type;
12119   u8 is_add = 1;
12120   u8 src_set = 0;
12121   u8 dst_set = 0;
12122   u32 outer_table_id = 0;
12123   u32 session_id = 0;
12124   u32 instance = ~0;
12125   int ret;
12126
12127   t_type = GRE_API_TUNNEL_TYPE_L3;
12128
12129   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12130     {
12131       if (unformat (line_input, "del"))
12132         is_add = 0;
12133       else if (unformat (line_input, "instance %d", &instance))
12134         ;
12135       else if (unformat (line_input, "src %U", unformat_vl_api_address, &src))
12136         {
12137           src_set = 1;
12138         }
12139       else if (unformat (line_input, "dst %U", unformat_vl_api_address, &dst))
12140         {
12141           dst_set = 1;
12142         }
12143       else if (unformat (line_input, "outer-table-id %d", &outer_table_id))
12144         ;
12145       else if (unformat (line_input, "teb"))
12146         t_type = GRE_API_TUNNEL_TYPE_TEB;
12147       else if (unformat (line_input, "erspan %d", &session_id))
12148         t_type = GRE_API_TUNNEL_TYPE_ERSPAN;
12149       else
12150         {
12151           errmsg ("parse error '%U'", format_unformat_error, line_input);
12152           return -99;
12153         }
12154     }
12155
12156   if (src_set == 0)
12157     {
12158       errmsg ("tunnel src address not specified");
12159       return -99;
12160     }
12161   if (dst_set == 0)
12162     {
12163       errmsg ("tunnel dst address not specified");
12164       return -99;
12165     }
12166
12167   M (GRE_TUNNEL_ADD_DEL, mp);
12168
12169   clib_memcpy (&mp->tunnel.src, &src, sizeof (mp->tunnel.src));
12170   clib_memcpy (&mp->tunnel.dst, &dst, sizeof (mp->tunnel.dst));
12171
12172   mp->tunnel.instance = htonl (instance);
12173   mp->tunnel.outer_table_id = htonl (outer_table_id);
12174   mp->is_add = is_add;
12175   mp->tunnel.session_id = htons ((u16) session_id);
12176   mp->tunnel.type = htonl (t_type);
12177
12178   S (mp);
12179   W (ret);
12180   return ret;
12181 }
12182
12183 static void vl_api_gre_tunnel_details_t_handler
12184   (vl_api_gre_tunnel_details_t * mp)
12185 {
12186   vat_main_t *vam = &vat_main;
12187
12188   print (vam->ofp, "%11d%11d%24U%24U%13d%14d%12d",
12189          ntohl (mp->tunnel.sw_if_index),
12190          ntohl (mp->tunnel.instance),
12191          format_vl_api_address, &mp->tunnel.src,
12192          format_vl_api_address, &mp->tunnel.dst,
12193          mp->tunnel.type, ntohl (mp->tunnel.outer_table_id),
12194          ntohl (mp->tunnel.session_id));
12195 }
12196
12197 static void vl_api_gre_tunnel_details_t_handler_json
12198   (vl_api_gre_tunnel_details_t * mp)
12199 {
12200   vat_main_t *vam = &vat_main;
12201   vat_json_node_t *node = NULL;
12202
12203   if (VAT_JSON_ARRAY != vam->json_tree.type)
12204     {
12205       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12206       vat_json_init_array (&vam->json_tree);
12207     }
12208   node = vat_json_array_add (&vam->json_tree);
12209
12210   vat_json_init_object (node);
12211   vat_json_object_add_uint (node, "sw_if_index",
12212                             ntohl (mp->tunnel.sw_if_index));
12213   vat_json_object_add_uint (node, "instance", ntohl (mp->tunnel.instance));
12214
12215   vat_json_object_add_address (node, "src", &mp->tunnel.src);
12216   vat_json_object_add_address (node, "dst", &mp->tunnel.dst);
12217   vat_json_object_add_uint (node, "tunnel_type", mp->tunnel.type);
12218   vat_json_object_add_uint (node, "outer_table_id",
12219                             ntohl (mp->tunnel.outer_table_id));
12220   vat_json_object_add_uint (node, "session_id", mp->tunnel.session_id);
12221 }
12222
12223 static int
12224 api_gre_tunnel_dump (vat_main_t * vam)
12225 {
12226   unformat_input_t *i = vam->input;
12227   vl_api_gre_tunnel_dump_t *mp;
12228   vl_api_control_ping_t *mp_ping;
12229   u32 sw_if_index;
12230   u8 sw_if_index_set = 0;
12231   int ret;
12232
12233   /* Parse args required to build the message */
12234   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12235     {
12236       if (unformat (i, "sw_if_index %d", &sw_if_index))
12237         sw_if_index_set = 1;
12238       else
12239         break;
12240     }
12241
12242   if (sw_if_index_set == 0)
12243     {
12244       sw_if_index = ~0;
12245     }
12246
12247   if (!vam->json_output)
12248     {
12249       print (vam->ofp, "%11s%11s%24s%24s%13s%14s%12s",
12250              "sw_if_index", "instance", "src_address", "dst_address",
12251              "tunnel_type", "outer_fib_id", "session_id");
12252     }
12253
12254   /* Get list of gre-tunnel interfaces */
12255   M (GRE_TUNNEL_DUMP, mp);
12256
12257   mp->sw_if_index = htonl (sw_if_index);
12258
12259   S (mp);
12260
12261   /* Use a control ping for synchronization */
12262   MPING (CONTROL_PING, mp_ping);
12263   S (mp_ping);
12264
12265   W (ret);
12266   return ret;
12267 }
12268
12269 static int
12270 api_l2_fib_clear_table (vat_main_t * vam)
12271 {
12272 //  unformat_input_t * i = vam->input;
12273   vl_api_l2_fib_clear_table_t *mp;
12274   int ret;
12275
12276   M (L2_FIB_CLEAR_TABLE, mp);
12277
12278   S (mp);
12279   W (ret);
12280   return ret;
12281 }
12282
12283 static int
12284 api_l2_interface_efp_filter (vat_main_t * vam)
12285 {
12286   unformat_input_t *i = vam->input;
12287   vl_api_l2_interface_efp_filter_t *mp;
12288   u32 sw_if_index;
12289   u8 enable = 1;
12290   u8 sw_if_index_set = 0;
12291   int ret;
12292
12293   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12294     {
12295       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12296         sw_if_index_set = 1;
12297       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12298         sw_if_index_set = 1;
12299       else if (unformat (i, "enable"))
12300         enable = 1;
12301       else if (unformat (i, "disable"))
12302         enable = 0;
12303       else
12304         {
12305           clib_warning ("parse error '%U'", format_unformat_error, i);
12306           return -99;
12307         }
12308     }
12309
12310   if (sw_if_index_set == 0)
12311     {
12312       errmsg ("missing sw_if_index");
12313       return -99;
12314     }
12315
12316   M (L2_INTERFACE_EFP_FILTER, mp);
12317
12318   mp->sw_if_index = ntohl (sw_if_index);
12319   mp->enable_disable = enable;
12320
12321   S (mp);
12322   W (ret);
12323   return ret;
12324 }
12325
12326 #define foreach_vtr_op                          \
12327 _("disable",  L2_VTR_DISABLED)                  \
12328 _("push-1",  L2_VTR_PUSH_1)                     \
12329 _("push-2",  L2_VTR_PUSH_2)                     \
12330 _("pop-1",  L2_VTR_POP_1)                       \
12331 _("pop-2",  L2_VTR_POP_2)                       \
12332 _("translate-1-1",  L2_VTR_TRANSLATE_1_1)       \
12333 _("translate-1-2",  L2_VTR_TRANSLATE_1_2)       \
12334 _("translate-2-1",  L2_VTR_TRANSLATE_2_1)       \
12335 _("translate-2-2",  L2_VTR_TRANSLATE_2_2)
12336
12337 static int
12338 api_l2_interface_vlan_tag_rewrite (vat_main_t * vam)
12339 {
12340   unformat_input_t *i = vam->input;
12341   vl_api_l2_interface_vlan_tag_rewrite_t *mp;
12342   u32 sw_if_index;
12343   u8 sw_if_index_set = 0;
12344   u8 vtr_op_set = 0;
12345   u32 vtr_op = 0;
12346   u32 push_dot1q = 1;
12347   u32 tag1 = ~0;
12348   u32 tag2 = ~0;
12349   int ret;
12350
12351   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12352     {
12353       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12354         sw_if_index_set = 1;
12355       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12356         sw_if_index_set = 1;
12357       else if (unformat (i, "vtr_op %d", &vtr_op))
12358         vtr_op_set = 1;
12359 #define _(n,v) else if (unformat(i, n)) {vtr_op = v; vtr_op_set = 1;}
12360       foreach_vtr_op
12361 #undef _
12362         else if (unformat (i, "push_dot1q %d", &push_dot1q))
12363         ;
12364       else if (unformat (i, "tag1 %d", &tag1))
12365         ;
12366       else if (unformat (i, "tag2 %d", &tag2))
12367         ;
12368       else
12369         {
12370           clib_warning ("parse error '%U'", format_unformat_error, i);
12371           return -99;
12372         }
12373     }
12374
12375   if ((sw_if_index_set == 0) || (vtr_op_set == 0))
12376     {
12377       errmsg ("missing vtr operation or sw_if_index");
12378       return -99;
12379     }
12380
12381   M (L2_INTERFACE_VLAN_TAG_REWRITE, mp);
12382   mp->sw_if_index = ntohl (sw_if_index);
12383   mp->vtr_op = ntohl (vtr_op);
12384   mp->push_dot1q = ntohl (push_dot1q);
12385   mp->tag1 = ntohl (tag1);
12386   mp->tag2 = ntohl (tag2);
12387
12388   S (mp);
12389   W (ret);
12390   return ret;
12391 }
12392
12393 static int
12394 api_create_vhost_user_if (vat_main_t * vam)
12395 {
12396   unformat_input_t *i = vam->input;
12397   vl_api_create_vhost_user_if_t *mp;
12398   u8 *file_name;
12399   u8 is_server = 0;
12400   u8 file_name_set = 0;
12401   u32 custom_dev_instance = ~0;
12402   u8 hwaddr[6];
12403   u8 use_custom_mac = 0;
12404   u8 disable_mrg_rxbuf = 0;
12405   u8 disable_indirect_desc = 0;
12406   u8 *tag = 0;
12407   u8 enable_gso = 0;
12408   int ret;
12409
12410   /* Shut up coverity */
12411   clib_memset (hwaddr, 0, sizeof (hwaddr));
12412
12413   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12414     {
12415       if (unformat (i, "socket %s", &file_name))
12416         {
12417           file_name_set = 1;
12418         }
12419       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
12420         ;
12421       else if (unformat (i, "mac %U", unformat_ethernet_address, hwaddr))
12422         use_custom_mac = 1;
12423       else if (unformat (i, "server"))
12424         is_server = 1;
12425       else if (unformat (i, "disable_mrg_rxbuf"))
12426         disable_mrg_rxbuf = 1;
12427       else if (unformat (i, "disable_indirect_desc"))
12428         disable_indirect_desc = 1;
12429       else if (unformat (i, "gso"))
12430         enable_gso = 1;
12431       else if (unformat (i, "tag %s", &tag))
12432         ;
12433       else
12434         break;
12435     }
12436
12437   if (file_name_set == 0)
12438     {
12439       errmsg ("missing socket file name");
12440       return -99;
12441     }
12442
12443   if (vec_len (file_name) > 255)
12444     {
12445       errmsg ("socket file name too long");
12446       return -99;
12447     }
12448   vec_add1 (file_name, 0);
12449
12450   M (CREATE_VHOST_USER_IF, mp);
12451
12452   mp->is_server = is_server;
12453   mp->disable_mrg_rxbuf = disable_mrg_rxbuf;
12454   mp->disable_indirect_desc = disable_indirect_desc;
12455   mp->enable_gso = enable_gso;
12456   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
12457   vec_free (file_name);
12458   if (custom_dev_instance != ~0)
12459     {
12460       mp->renumber = 1;
12461       mp->custom_dev_instance = ntohl (custom_dev_instance);
12462     }
12463
12464   mp->use_custom_mac = use_custom_mac;
12465   clib_memcpy (mp->mac_address, hwaddr, 6);
12466   if (tag)
12467     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
12468   vec_free (tag);
12469
12470   S (mp);
12471   W (ret);
12472   return ret;
12473 }
12474
12475 static int
12476 api_modify_vhost_user_if (vat_main_t * vam)
12477 {
12478   unformat_input_t *i = vam->input;
12479   vl_api_modify_vhost_user_if_t *mp;
12480   u8 *file_name;
12481   u8 is_server = 0;
12482   u8 file_name_set = 0;
12483   u32 custom_dev_instance = ~0;
12484   u8 sw_if_index_set = 0;
12485   u32 sw_if_index = (u32) ~ 0;
12486   u8 enable_gso = 0;
12487   int ret;
12488
12489   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12490     {
12491       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12492         sw_if_index_set = 1;
12493       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12494         sw_if_index_set = 1;
12495       else if (unformat (i, "socket %s", &file_name))
12496         {
12497           file_name_set = 1;
12498         }
12499       else if (unformat (i, "renumber %" PRIu32, &custom_dev_instance))
12500         ;
12501       else if (unformat (i, "server"))
12502         is_server = 1;
12503       else if (unformat (i, "gso"))
12504         enable_gso = 1;
12505       else
12506         break;
12507     }
12508
12509   if (sw_if_index_set == 0)
12510     {
12511       errmsg ("missing sw_if_index or interface name");
12512       return -99;
12513     }
12514
12515   if (file_name_set == 0)
12516     {
12517       errmsg ("missing socket file name");
12518       return -99;
12519     }
12520
12521   if (vec_len (file_name) > 255)
12522     {
12523       errmsg ("socket file name too long");
12524       return -99;
12525     }
12526   vec_add1 (file_name, 0);
12527
12528   M (MODIFY_VHOST_USER_IF, mp);
12529
12530   mp->sw_if_index = ntohl (sw_if_index);
12531   mp->is_server = is_server;
12532   mp->enable_gso = enable_gso;
12533   clib_memcpy (mp->sock_filename, file_name, vec_len (file_name));
12534   vec_free (file_name);
12535   if (custom_dev_instance != ~0)
12536     {
12537       mp->renumber = 1;
12538       mp->custom_dev_instance = ntohl (custom_dev_instance);
12539     }
12540
12541   S (mp);
12542   W (ret);
12543   return ret;
12544 }
12545
12546 static int
12547 api_delete_vhost_user_if (vat_main_t * vam)
12548 {
12549   unformat_input_t *i = vam->input;
12550   vl_api_delete_vhost_user_if_t *mp;
12551   u32 sw_if_index = ~0;
12552   u8 sw_if_index_set = 0;
12553   int ret;
12554
12555   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12556     {
12557       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
12558         sw_if_index_set = 1;
12559       else if (unformat (i, "sw_if_index %d", &sw_if_index))
12560         sw_if_index_set = 1;
12561       else
12562         break;
12563     }
12564
12565   if (sw_if_index_set == 0)
12566     {
12567       errmsg ("missing sw_if_index or interface name");
12568       return -99;
12569     }
12570
12571
12572   M (DELETE_VHOST_USER_IF, mp);
12573
12574   mp->sw_if_index = ntohl (sw_if_index);
12575
12576   S (mp);
12577   W (ret);
12578   return ret;
12579 }
12580
12581 static void vl_api_sw_interface_vhost_user_details_t_handler
12582   (vl_api_sw_interface_vhost_user_details_t * mp)
12583 {
12584   vat_main_t *vam = &vat_main;
12585   u64 features;
12586
12587   features =
12588     clib_net_to_host_u32 (mp->features_first_32) | ((u64)
12589                                                     clib_net_to_host_u32
12590                                                     (mp->features_last_32) <<
12591                                                     32);
12592
12593   print (vam->ofp, "%-25s %3" PRIu32 " %6" PRIu32 " %8x %6d %7d %s",
12594          (char *) mp->interface_name,
12595          ntohl (mp->sw_if_index), ntohl (mp->virtio_net_hdr_sz),
12596          features, mp->is_server,
12597          ntohl (mp->num_regions), (char *) mp->sock_filename);
12598   print (vam->ofp, "    Status: '%s'", strerror (ntohl (mp->sock_errno)));
12599 }
12600
12601 static void vl_api_sw_interface_vhost_user_details_t_handler_json
12602   (vl_api_sw_interface_vhost_user_details_t * mp)
12603 {
12604   vat_main_t *vam = &vat_main;
12605   vat_json_node_t *node = NULL;
12606
12607   if (VAT_JSON_ARRAY != vam->json_tree.type)
12608     {
12609       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12610       vat_json_init_array (&vam->json_tree);
12611     }
12612   node = vat_json_array_add (&vam->json_tree);
12613
12614   vat_json_init_object (node);
12615   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12616   vat_json_object_add_string_copy (node, "interface_name",
12617                                    mp->interface_name);
12618   vat_json_object_add_uint (node, "virtio_net_hdr_sz",
12619                             ntohl (mp->virtio_net_hdr_sz));
12620   vat_json_object_add_uint (node, "features_first_32",
12621                             clib_net_to_host_u32 (mp->features_first_32));
12622   vat_json_object_add_uint (node, "features_last_32",
12623                             clib_net_to_host_u32 (mp->features_last_32));
12624   vat_json_object_add_uint (node, "is_server", mp->is_server);
12625   vat_json_object_add_string_copy (node, "sock_filename", mp->sock_filename);
12626   vat_json_object_add_uint (node, "num_regions", ntohl (mp->num_regions));
12627   vat_json_object_add_uint (node, "sock_errno", ntohl (mp->sock_errno));
12628 }
12629
12630 static int
12631 api_sw_interface_vhost_user_dump (vat_main_t * vam)
12632 {
12633   vl_api_sw_interface_vhost_user_dump_t *mp;
12634   vl_api_control_ping_t *mp_ping;
12635   int ret;
12636   print (vam->ofp,
12637          "Interface name            idx hdr_sz features server regions filename");
12638
12639   /* Get list of vhost-user interfaces */
12640   M (SW_INTERFACE_VHOST_USER_DUMP, mp);
12641   mp->sw_if_index = ntohl (~0);
12642   S (mp);
12643
12644   /* Use a control ping for synchronization */
12645   MPING (CONTROL_PING, mp_ping);
12646   S (mp_ping);
12647
12648   W (ret);
12649   return ret;
12650 }
12651
12652 static int
12653 api_show_version (vat_main_t * vam)
12654 {
12655   vl_api_show_version_t *mp;
12656   int ret;
12657
12658   M (SHOW_VERSION, mp);
12659
12660   S (mp);
12661   W (ret);
12662   return ret;
12663 }
12664
12665
12666 static int
12667 api_vxlan_gpe_add_del_tunnel (vat_main_t * vam)
12668 {
12669   unformat_input_t *line_input = vam->input;
12670   vl_api_vxlan_gpe_add_del_tunnel_t *mp;
12671   ip4_address_t local4, remote4;
12672   ip6_address_t local6, remote6;
12673   u8 is_add = 1;
12674   u8 ipv4_set = 0, ipv6_set = 0;
12675   u8 local_set = 0;
12676   u8 remote_set = 0;
12677   u8 grp_set = 0;
12678   u32 mcast_sw_if_index = ~0;
12679   u32 encap_vrf_id = 0;
12680   u32 decap_vrf_id = 0;
12681   u8 protocol = ~0;
12682   u32 vni;
12683   u8 vni_set = 0;
12684   int ret;
12685
12686   /* Can't "universally zero init" (={0}) due to GCC bug 53119 */
12687   clib_memset (&local4, 0, sizeof local4);
12688   clib_memset (&remote4, 0, sizeof remote4);
12689   clib_memset (&local6, 0, sizeof local6);
12690   clib_memset (&remote6, 0, sizeof remote6);
12691
12692   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
12693     {
12694       if (unformat (line_input, "del"))
12695         is_add = 0;
12696       else if (unformat (line_input, "local %U",
12697                          unformat_ip4_address, &local4))
12698         {
12699           local_set = 1;
12700           ipv4_set = 1;
12701         }
12702       else if (unformat (line_input, "remote %U",
12703                          unformat_ip4_address, &remote4))
12704         {
12705           remote_set = 1;
12706           ipv4_set = 1;
12707         }
12708       else if (unformat (line_input, "local %U",
12709                          unformat_ip6_address, &local6))
12710         {
12711           local_set = 1;
12712           ipv6_set = 1;
12713         }
12714       else if (unformat (line_input, "remote %U",
12715                          unformat_ip6_address, &remote6))
12716         {
12717           remote_set = 1;
12718           ipv6_set = 1;
12719         }
12720       else if (unformat (line_input, "group %U %U",
12721                          unformat_ip4_address, &remote4,
12722                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12723         {
12724           grp_set = remote_set = 1;
12725           ipv4_set = 1;
12726         }
12727       else if (unformat (line_input, "group %U",
12728                          unformat_ip4_address, &remote4))
12729         {
12730           grp_set = remote_set = 1;
12731           ipv4_set = 1;
12732         }
12733       else if (unformat (line_input, "group %U %U",
12734                          unformat_ip6_address, &remote6,
12735                          api_unformat_sw_if_index, vam, &mcast_sw_if_index))
12736         {
12737           grp_set = remote_set = 1;
12738           ipv6_set = 1;
12739         }
12740       else if (unformat (line_input, "group %U",
12741                          unformat_ip6_address, &remote6))
12742         {
12743           grp_set = remote_set = 1;
12744           ipv6_set = 1;
12745         }
12746       else
12747         if (unformat (line_input, "mcast_sw_if_index %u", &mcast_sw_if_index))
12748         ;
12749       else if (unformat (line_input, "encap-vrf-id %d", &encap_vrf_id))
12750         ;
12751       else if (unformat (line_input, "decap-vrf-id %d", &decap_vrf_id))
12752         ;
12753       else if (unformat (line_input, "vni %d", &vni))
12754         vni_set = 1;
12755       else if (unformat (line_input, "next-ip4"))
12756         protocol = 1;
12757       else if (unformat (line_input, "next-ip6"))
12758         protocol = 2;
12759       else if (unformat (line_input, "next-ethernet"))
12760         protocol = 3;
12761       else if (unformat (line_input, "next-nsh"))
12762         protocol = 4;
12763       else
12764         {
12765           errmsg ("parse error '%U'", format_unformat_error, line_input);
12766           return -99;
12767         }
12768     }
12769
12770   if (local_set == 0)
12771     {
12772       errmsg ("tunnel local address not specified");
12773       return -99;
12774     }
12775   if (remote_set == 0)
12776     {
12777       errmsg ("tunnel remote address not specified");
12778       return -99;
12779     }
12780   if (grp_set && mcast_sw_if_index == ~0)
12781     {
12782       errmsg ("tunnel nonexistent multicast device");
12783       return -99;
12784     }
12785   if (ipv4_set && ipv6_set)
12786     {
12787       errmsg ("both IPv4 and IPv6 addresses specified");
12788       return -99;
12789     }
12790
12791   if (vni_set == 0)
12792     {
12793       errmsg ("vni not specified");
12794       return -99;
12795     }
12796
12797   M (VXLAN_GPE_ADD_DEL_TUNNEL, mp);
12798
12799
12800   if (ipv6_set)
12801     {
12802       clib_memcpy (&mp->local, &local6, sizeof (local6));
12803       clib_memcpy (&mp->remote, &remote6, sizeof (remote6));
12804     }
12805   else
12806     {
12807       clib_memcpy (&mp->local, &local4, sizeof (local4));
12808       clib_memcpy (&mp->remote, &remote4, sizeof (remote4));
12809     }
12810
12811   mp->mcast_sw_if_index = ntohl (mcast_sw_if_index);
12812   mp->encap_vrf_id = ntohl (encap_vrf_id);
12813   mp->decap_vrf_id = ntohl (decap_vrf_id);
12814   mp->protocol = protocol;
12815   mp->vni = ntohl (vni);
12816   mp->is_add = is_add;
12817   mp->is_ipv6 = ipv6_set;
12818
12819   S (mp);
12820   W (ret);
12821   return ret;
12822 }
12823
12824 static void vl_api_vxlan_gpe_tunnel_details_t_handler
12825   (vl_api_vxlan_gpe_tunnel_details_t * mp)
12826 {
12827   vat_main_t *vam = &vat_main;
12828   ip46_address_t local = to_ip46 (mp->is_ipv6, mp->local);
12829   ip46_address_t remote = to_ip46 (mp->is_ipv6, mp->remote);
12830
12831   print (vam->ofp, "%11d%24U%24U%13d%12d%19d%14d%14d",
12832          ntohl (mp->sw_if_index),
12833          format_ip46_address, &local, IP46_TYPE_ANY,
12834          format_ip46_address, &remote, IP46_TYPE_ANY,
12835          ntohl (mp->vni), mp->protocol,
12836          ntohl (mp->mcast_sw_if_index),
12837          ntohl (mp->encap_vrf_id), ntohl (mp->decap_vrf_id));
12838 }
12839
12840
12841 static void vl_api_vxlan_gpe_tunnel_details_t_handler_json
12842   (vl_api_vxlan_gpe_tunnel_details_t * mp)
12843 {
12844   vat_main_t *vam = &vat_main;
12845   vat_json_node_t *node = NULL;
12846   struct in_addr ip4;
12847   struct in6_addr ip6;
12848
12849   if (VAT_JSON_ARRAY != vam->json_tree.type)
12850     {
12851       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12852       vat_json_init_array (&vam->json_tree);
12853     }
12854   node = vat_json_array_add (&vam->json_tree);
12855
12856   vat_json_init_object (node);
12857   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12858   if (mp->is_ipv6)
12859     {
12860       clib_memcpy (&ip6, &(mp->local[0]), sizeof (ip6));
12861       vat_json_object_add_ip6 (node, "local", ip6);
12862       clib_memcpy (&ip6, &(mp->remote[0]), sizeof (ip6));
12863       vat_json_object_add_ip6 (node, "remote", ip6);
12864     }
12865   else
12866     {
12867       clib_memcpy (&ip4, &(mp->local[0]), sizeof (ip4));
12868       vat_json_object_add_ip4 (node, "local", ip4);
12869       clib_memcpy (&ip4, &(mp->remote[0]), sizeof (ip4));
12870       vat_json_object_add_ip4 (node, "remote", ip4);
12871     }
12872   vat_json_object_add_uint (node, "vni", ntohl (mp->vni));
12873   vat_json_object_add_uint (node, "protocol", ntohl (mp->protocol));
12874   vat_json_object_add_uint (node, "mcast_sw_if_index",
12875                             ntohl (mp->mcast_sw_if_index));
12876   vat_json_object_add_uint (node, "encap_vrf_id", ntohl (mp->encap_vrf_id));
12877   vat_json_object_add_uint (node, "decap_vrf_id", ntohl (mp->decap_vrf_id));
12878   vat_json_object_add_uint (node, "is_ipv6", mp->is_ipv6 ? 1 : 0);
12879 }
12880
12881 static int
12882 api_vxlan_gpe_tunnel_dump (vat_main_t * vam)
12883 {
12884   unformat_input_t *i = vam->input;
12885   vl_api_vxlan_gpe_tunnel_dump_t *mp;
12886   vl_api_control_ping_t *mp_ping;
12887   u32 sw_if_index;
12888   u8 sw_if_index_set = 0;
12889   int ret;
12890
12891   /* Parse args required to build the message */
12892   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12893     {
12894       if (unformat (i, "sw_if_index %d", &sw_if_index))
12895         sw_if_index_set = 1;
12896       else
12897         break;
12898     }
12899
12900   if (sw_if_index_set == 0)
12901     {
12902       sw_if_index = ~0;
12903     }
12904
12905   if (!vam->json_output)
12906     {
12907       print (vam->ofp, "%11s%24s%24s%13s%15s%19s%14s%14s",
12908              "sw_if_index", "local", "remote", "vni",
12909              "protocol", "mcast_sw_if_index", "encap_vrf_id", "decap_vrf_id");
12910     }
12911
12912   /* Get list of vxlan-tunnel interfaces */
12913   M (VXLAN_GPE_TUNNEL_DUMP, mp);
12914
12915   mp->sw_if_index = htonl (sw_if_index);
12916
12917   S (mp);
12918
12919   /* Use a control ping for synchronization */
12920   MPING (CONTROL_PING, mp_ping);
12921   S (mp_ping);
12922
12923   W (ret);
12924   return ret;
12925 }
12926
12927 static void vl_api_l2_fib_table_details_t_handler
12928   (vl_api_l2_fib_table_details_t * mp)
12929 {
12930   vat_main_t *vam = &vat_main;
12931
12932   print (vam->ofp, "%3" PRIu32 "    %U    %3" PRIu32
12933          "       %d       %d     %d",
12934          ntohl (mp->bd_id), format_ethernet_address, mp->mac,
12935          ntohl (mp->sw_if_index), mp->static_mac, mp->filter_mac,
12936          mp->bvi_mac);
12937 }
12938
12939 static void vl_api_l2_fib_table_details_t_handler_json
12940   (vl_api_l2_fib_table_details_t * mp)
12941 {
12942   vat_main_t *vam = &vat_main;
12943   vat_json_node_t *node = NULL;
12944
12945   if (VAT_JSON_ARRAY != vam->json_tree.type)
12946     {
12947       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
12948       vat_json_init_array (&vam->json_tree);
12949     }
12950   node = vat_json_array_add (&vam->json_tree);
12951
12952   vat_json_init_object (node);
12953   vat_json_object_add_uint (node, "bd_id", ntohl (mp->bd_id));
12954   vat_json_object_add_bytes (node, "mac", mp->mac, 6);
12955   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
12956   vat_json_object_add_uint (node, "static_mac", mp->static_mac);
12957   vat_json_object_add_uint (node, "filter_mac", mp->filter_mac);
12958   vat_json_object_add_uint (node, "bvi_mac", mp->bvi_mac);
12959 }
12960
12961 static int
12962 api_l2_fib_table_dump (vat_main_t * vam)
12963 {
12964   unformat_input_t *i = vam->input;
12965   vl_api_l2_fib_table_dump_t *mp;
12966   vl_api_control_ping_t *mp_ping;
12967   u32 bd_id;
12968   u8 bd_id_set = 0;
12969   int ret;
12970
12971   /* Parse args required to build the message */
12972   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
12973     {
12974       if (unformat (i, "bd_id %d", &bd_id))
12975         bd_id_set = 1;
12976       else
12977         break;
12978     }
12979
12980   if (bd_id_set == 0)
12981     {
12982       errmsg ("missing bridge domain");
12983       return -99;
12984     }
12985
12986   print (vam->ofp, "BD-ID     Mac Address      sw-ndx  Static  Filter  BVI");
12987
12988   /* Get list of l2 fib entries */
12989   M (L2_FIB_TABLE_DUMP, mp);
12990
12991   mp->bd_id = ntohl (bd_id);
12992   S (mp);
12993
12994   /* Use a control ping for synchronization */
12995   MPING (CONTROL_PING, mp_ping);
12996   S (mp_ping);
12997
12998   W (ret);
12999   return ret;
13000 }
13001
13002
13003 static int
13004 api_interface_name_renumber (vat_main_t * vam)
13005 {
13006   unformat_input_t *line_input = vam->input;
13007   vl_api_interface_name_renumber_t *mp;
13008   u32 sw_if_index = ~0;
13009   u32 new_show_dev_instance = ~0;
13010   int ret;
13011
13012   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13013     {
13014       if (unformat (line_input, "%U", api_unformat_sw_if_index, vam,
13015                     &sw_if_index))
13016         ;
13017       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
13018         ;
13019       else if (unformat (line_input, "new_show_dev_instance %d",
13020                          &new_show_dev_instance))
13021         ;
13022       else
13023         break;
13024     }
13025
13026   if (sw_if_index == ~0)
13027     {
13028       errmsg ("missing interface name or sw_if_index");
13029       return -99;
13030     }
13031
13032   if (new_show_dev_instance == ~0)
13033     {
13034       errmsg ("missing new_show_dev_instance");
13035       return -99;
13036     }
13037
13038   M (INTERFACE_NAME_RENUMBER, mp);
13039
13040   mp->sw_if_index = ntohl (sw_if_index);
13041   mp->new_show_dev_instance = ntohl (new_show_dev_instance);
13042
13043   S (mp);
13044   W (ret);
13045   return ret;
13046 }
13047
13048 static int
13049 api_want_l2_macs_events (vat_main_t * vam)
13050 {
13051   unformat_input_t *line_input = vam->input;
13052   vl_api_want_l2_macs_events_t *mp;
13053   u8 enable_disable = 1;
13054   u32 scan_delay = 0;
13055   u32 max_macs_in_event = 0;
13056   u32 learn_limit = 0;
13057   int ret;
13058
13059   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
13060     {
13061       if (unformat (line_input, "learn-limit %d", &learn_limit))
13062         ;
13063       else if (unformat (line_input, "scan-delay %d", &scan_delay))
13064         ;
13065       else if (unformat (line_input, "max-entries %d", &max_macs_in_event))
13066         ;
13067       else if (unformat (line_input, "disable"))
13068         enable_disable = 0;
13069       else
13070         break;
13071     }
13072
13073   M (WANT_L2_MACS_EVENTS, mp);
13074   mp->enable_disable = enable_disable;
13075   mp->pid = htonl (getpid ());
13076   mp->learn_limit = htonl (learn_limit);
13077   mp->scan_delay = (u8) scan_delay;
13078   mp->max_macs_in_event = (u8) (max_macs_in_event / 10);
13079   S (mp);
13080   W (ret);
13081   return ret;
13082 }
13083
13084 static int
13085 api_input_acl_set_interface (vat_main_t * vam)
13086 {
13087   unformat_input_t *i = vam->input;
13088   vl_api_input_acl_set_interface_t *mp;
13089   u32 sw_if_index;
13090   int sw_if_index_set;
13091   u32 ip4_table_index = ~0;
13092   u32 ip6_table_index = ~0;
13093   u32 l2_table_index = ~0;
13094   u8 is_add = 1;
13095   int ret;
13096
13097   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13098     {
13099       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13100         sw_if_index_set = 1;
13101       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13102         sw_if_index_set = 1;
13103       else if (unformat (i, "del"))
13104         is_add = 0;
13105       else if (unformat (i, "ip4-table %d", &ip4_table_index))
13106         ;
13107       else if (unformat (i, "ip6-table %d", &ip6_table_index))
13108         ;
13109       else if (unformat (i, "l2-table %d", &l2_table_index))
13110         ;
13111       else
13112         {
13113           clib_warning ("parse error '%U'", format_unformat_error, i);
13114           return -99;
13115         }
13116     }
13117
13118   if (sw_if_index_set == 0)
13119     {
13120       errmsg ("missing interface name or sw_if_index");
13121       return -99;
13122     }
13123
13124   M (INPUT_ACL_SET_INTERFACE, mp);
13125
13126   mp->sw_if_index = ntohl (sw_if_index);
13127   mp->ip4_table_index = ntohl (ip4_table_index);
13128   mp->ip6_table_index = ntohl (ip6_table_index);
13129   mp->l2_table_index = ntohl (l2_table_index);
13130   mp->is_add = is_add;
13131
13132   S (mp);
13133   W (ret);
13134   return ret;
13135 }
13136
13137 static int
13138 api_output_acl_set_interface (vat_main_t * vam)
13139 {
13140   unformat_input_t *i = vam->input;
13141   vl_api_output_acl_set_interface_t *mp;
13142   u32 sw_if_index;
13143   int sw_if_index_set;
13144   u32 ip4_table_index = ~0;
13145   u32 ip6_table_index = ~0;
13146   u32 l2_table_index = ~0;
13147   u8 is_add = 1;
13148   int ret;
13149
13150   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13151     {
13152       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13153         sw_if_index_set = 1;
13154       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13155         sw_if_index_set = 1;
13156       else if (unformat (i, "del"))
13157         is_add = 0;
13158       else if (unformat (i, "ip4-table %d", &ip4_table_index))
13159         ;
13160       else if (unformat (i, "ip6-table %d", &ip6_table_index))
13161         ;
13162       else if (unformat (i, "l2-table %d", &l2_table_index))
13163         ;
13164       else
13165         {
13166           clib_warning ("parse error '%U'", format_unformat_error, i);
13167           return -99;
13168         }
13169     }
13170
13171   if (sw_if_index_set == 0)
13172     {
13173       errmsg ("missing interface name or sw_if_index");
13174       return -99;
13175     }
13176
13177   M (OUTPUT_ACL_SET_INTERFACE, mp);
13178
13179   mp->sw_if_index = ntohl (sw_if_index);
13180   mp->ip4_table_index = ntohl (ip4_table_index);
13181   mp->ip6_table_index = ntohl (ip6_table_index);
13182   mp->l2_table_index = ntohl (l2_table_index);
13183   mp->is_add = is_add;
13184
13185   S (mp);
13186   W (ret);
13187   return ret;
13188 }
13189
13190 static int
13191 api_ip_address_dump (vat_main_t * vam)
13192 {
13193   unformat_input_t *i = vam->input;
13194   vl_api_ip_address_dump_t *mp;
13195   vl_api_control_ping_t *mp_ping;
13196   u32 sw_if_index = ~0;
13197   u8 sw_if_index_set = 0;
13198   u8 ipv4_set = 0;
13199   u8 ipv6_set = 0;
13200   int ret;
13201
13202   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13203     {
13204       if (unformat (i, "sw_if_index %d", &sw_if_index))
13205         sw_if_index_set = 1;
13206       else
13207         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13208         sw_if_index_set = 1;
13209       else if (unformat (i, "ipv4"))
13210         ipv4_set = 1;
13211       else if (unformat (i, "ipv6"))
13212         ipv6_set = 1;
13213       else
13214         break;
13215     }
13216
13217   if (ipv4_set && ipv6_set)
13218     {
13219       errmsg ("ipv4 and ipv6 flags cannot be both set");
13220       return -99;
13221     }
13222
13223   if ((!ipv4_set) && (!ipv6_set))
13224     {
13225       errmsg ("no ipv4 nor ipv6 flag set");
13226       return -99;
13227     }
13228
13229   if (sw_if_index_set == 0)
13230     {
13231       errmsg ("missing interface name or sw_if_index");
13232       return -99;
13233     }
13234
13235   vam->current_sw_if_index = sw_if_index;
13236   vam->is_ipv6 = ipv6_set;
13237
13238   M (IP_ADDRESS_DUMP, mp);
13239   mp->sw_if_index = ntohl (sw_if_index);
13240   mp->is_ipv6 = ipv6_set;
13241   S (mp);
13242
13243   /* Use a control ping for synchronization */
13244   MPING (CONTROL_PING, mp_ping);
13245   S (mp_ping);
13246
13247   W (ret);
13248   return ret;
13249 }
13250
13251 static int
13252 api_ip_dump (vat_main_t * vam)
13253 {
13254   vl_api_ip_dump_t *mp;
13255   vl_api_control_ping_t *mp_ping;
13256   unformat_input_t *in = vam->input;
13257   int ipv4_set = 0;
13258   int ipv6_set = 0;
13259   int is_ipv6;
13260   int i;
13261   int ret;
13262
13263   while (unformat_check_input (in) != UNFORMAT_END_OF_INPUT)
13264     {
13265       if (unformat (in, "ipv4"))
13266         ipv4_set = 1;
13267       else if (unformat (in, "ipv6"))
13268         ipv6_set = 1;
13269       else
13270         break;
13271     }
13272
13273   if (ipv4_set && ipv6_set)
13274     {
13275       errmsg ("ipv4 and ipv6 flags cannot be both set");
13276       return -99;
13277     }
13278
13279   if ((!ipv4_set) && (!ipv6_set))
13280     {
13281       errmsg ("no ipv4 nor ipv6 flag set");
13282       return -99;
13283     }
13284
13285   is_ipv6 = ipv6_set;
13286   vam->is_ipv6 = is_ipv6;
13287
13288   /* free old data */
13289   for (i = 0; i < vec_len (vam->ip_details_by_sw_if_index[is_ipv6]); i++)
13290     {
13291       vec_free (vam->ip_details_by_sw_if_index[is_ipv6][i].addr);
13292     }
13293   vec_free (vam->ip_details_by_sw_if_index[is_ipv6]);
13294
13295   M (IP_DUMP, mp);
13296   mp->is_ipv6 = ipv6_set;
13297   S (mp);
13298
13299   /* Use a control ping for synchronization */
13300   MPING (CONTROL_PING, mp_ping);
13301   S (mp_ping);
13302
13303   W (ret);
13304   return ret;
13305 }
13306
13307 static int
13308 api_ipsec_spd_add_del (vat_main_t * vam)
13309 {
13310   unformat_input_t *i = vam->input;
13311   vl_api_ipsec_spd_add_del_t *mp;
13312   u32 spd_id = ~0;
13313   u8 is_add = 1;
13314   int ret;
13315
13316   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13317     {
13318       if (unformat (i, "spd_id %d", &spd_id))
13319         ;
13320       else if (unformat (i, "del"))
13321         is_add = 0;
13322       else
13323         {
13324           clib_warning ("parse error '%U'", format_unformat_error, i);
13325           return -99;
13326         }
13327     }
13328   if (spd_id == ~0)
13329     {
13330       errmsg ("spd_id must be set");
13331       return -99;
13332     }
13333
13334   M (IPSEC_SPD_ADD_DEL, mp);
13335
13336   mp->spd_id = ntohl (spd_id);
13337   mp->is_add = is_add;
13338
13339   S (mp);
13340   W (ret);
13341   return ret;
13342 }
13343
13344 static int
13345 api_ipsec_interface_add_del_spd (vat_main_t * vam)
13346 {
13347   unformat_input_t *i = vam->input;
13348   vl_api_ipsec_interface_add_del_spd_t *mp;
13349   u32 sw_if_index;
13350   u8 sw_if_index_set = 0;
13351   u32 spd_id = (u32) ~ 0;
13352   u8 is_add = 1;
13353   int ret;
13354
13355   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13356     {
13357       if (unformat (i, "del"))
13358         is_add = 0;
13359       else if (unformat (i, "spd_id %d", &spd_id))
13360         ;
13361       else
13362         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13363         sw_if_index_set = 1;
13364       else if (unformat (i, "sw_if_index %d", &sw_if_index))
13365         sw_if_index_set = 1;
13366       else
13367         {
13368           clib_warning ("parse error '%U'", format_unformat_error, i);
13369           return -99;
13370         }
13371
13372     }
13373
13374   if (spd_id == (u32) ~ 0)
13375     {
13376       errmsg ("spd_id must be set");
13377       return -99;
13378     }
13379
13380   if (sw_if_index_set == 0)
13381     {
13382       errmsg ("missing interface name or sw_if_index");
13383       return -99;
13384     }
13385
13386   M (IPSEC_INTERFACE_ADD_DEL_SPD, mp);
13387
13388   mp->spd_id = ntohl (spd_id);
13389   mp->sw_if_index = ntohl (sw_if_index);
13390   mp->is_add = is_add;
13391
13392   S (mp);
13393   W (ret);
13394   return ret;
13395 }
13396
13397 static int
13398 api_ipsec_spd_entry_add_del (vat_main_t * vam)
13399 {
13400   unformat_input_t *i = vam->input;
13401   vl_api_ipsec_spd_entry_add_del_t *mp;
13402   u8 is_add = 1, is_outbound = 0;
13403   u32 spd_id = 0, sa_id = 0, protocol = 0, policy = 0;
13404   i32 priority = 0;
13405   u32 rport_start = 0, rport_stop = (u32) ~ 0;
13406   u32 lport_start = 0, lport_stop = (u32) ~ 0;
13407   vl_api_address_t laddr_start = { }, laddr_stop =
13408   {
13409   }, raddr_start =
13410   {
13411   }, raddr_stop =
13412   {
13413   };
13414   int ret;
13415
13416   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13417     {
13418       if (unformat (i, "del"))
13419         is_add = 0;
13420       if (unformat (i, "outbound"))
13421         is_outbound = 1;
13422       if (unformat (i, "inbound"))
13423         is_outbound = 0;
13424       else if (unformat (i, "spd_id %d", &spd_id))
13425         ;
13426       else if (unformat (i, "sa_id %d", &sa_id))
13427         ;
13428       else if (unformat (i, "priority %d", &priority))
13429         ;
13430       else if (unformat (i, "protocol %d", &protocol))
13431         ;
13432       else if (unformat (i, "lport_start %d", &lport_start))
13433         ;
13434       else if (unformat (i, "lport_stop %d", &lport_stop))
13435         ;
13436       else if (unformat (i, "rport_start %d", &rport_start))
13437         ;
13438       else if (unformat (i, "rport_stop %d", &rport_stop))
13439         ;
13440       else if (unformat (i, "laddr_start %U",
13441                          unformat_vl_api_address, &laddr_start))
13442         ;
13443       else if (unformat (i, "laddr_stop %U", unformat_vl_api_address,
13444                          &laddr_stop))
13445         ;
13446       else if (unformat (i, "raddr_start %U", unformat_vl_api_address,
13447                          &raddr_start))
13448         ;
13449       else if (unformat (i, "raddr_stop %U", unformat_vl_api_address,
13450                          &raddr_stop))
13451         ;
13452       else
13453         if (unformat (i, "action %U", unformat_ipsec_policy_action, &policy))
13454         {
13455           if (policy == IPSEC_POLICY_ACTION_RESOLVE)
13456             {
13457               clib_warning ("unsupported action: 'resolve'");
13458               return -99;
13459             }
13460         }
13461       else
13462         {
13463           clib_warning ("parse error '%U'", format_unformat_error, i);
13464           return -99;
13465         }
13466
13467     }
13468
13469   M (IPSEC_SPD_ENTRY_ADD_DEL, mp);
13470
13471   mp->is_add = is_add;
13472
13473   mp->entry.spd_id = ntohl (spd_id);
13474   mp->entry.priority = ntohl (priority);
13475   mp->entry.is_outbound = is_outbound;
13476
13477   clib_memcpy (&mp->entry.remote_address_start, &raddr_start,
13478                sizeof (vl_api_address_t));
13479   clib_memcpy (&mp->entry.remote_address_stop, &raddr_stop,
13480                sizeof (vl_api_address_t));
13481   clib_memcpy (&mp->entry.local_address_start, &laddr_start,
13482                sizeof (vl_api_address_t));
13483   clib_memcpy (&mp->entry.local_address_stop, &laddr_stop,
13484                sizeof (vl_api_address_t));
13485
13486   mp->entry.protocol = (u8) protocol;
13487   mp->entry.local_port_start = ntohs ((u16) lport_start);
13488   mp->entry.local_port_stop = ntohs ((u16) lport_stop);
13489   mp->entry.remote_port_start = ntohs ((u16) rport_start);
13490   mp->entry.remote_port_stop = ntohs ((u16) rport_stop);
13491   mp->entry.policy = (u8) policy;
13492   mp->entry.sa_id = ntohl (sa_id);
13493
13494   S (mp);
13495   W (ret);
13496   return ret;
13497 }
13498
13499 static int
13500 api_ipsec_sad_entry_add_del (vat_main_t * vam)
13501 {
13502   unformat_input_t *i = vam->input;
13503   vl_api_ipsec_sad_entry_add_del_t *mp;
13504   u32 sad_id = 0, spi = 0;
13505   u8 *ck = 0, *ik = 0;
13506   u8 is_add = 1;
13507
13508   vl_api_ipsec_crypto_alg_t crypto_alg = IPSEC_API_CRYPTO_ALG_NONE;
13509   vl_api_ipsec_integ_alg_t integ_alg = IPSEC_API_INTEG_ALG_NONE;
13510   vl_api_ipsec_sad_flags_t flags = IPSEC_API_SAD_FLAG_NONE;
13511   vl_api_ipsec_proto_t protocol = IPSEC_API_PROTO_AH;
13512   vl_api_address_t tun_src, tun_dst;
13513   int ret;
13514
13515   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13516     {
13517       if (unformat (i, "del"))
13518         is_add = 0;
13519       else if (unformat (i, "sad_id %d", &sad_id))
13520         ;
13521       else if (unformat (i, "spi %d", &spi))
13522         ;
13523       else if (unformat (i, "esp"))
13524         protocol = IPSEC_API_PROTO_ESP;
13525       else
13526         if (unformat (i, "tunnel_src %U", unformat_vl_api_address, &tun_src))
13527         {
13528           flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL;
13529           if (ADDRESS_IP6 == tun_src.af)
13530             flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL_V6;
13531         }
13532       else
13533         if (unformat (i, "tunnel_dst %U", unformat_vl_api_address, &tun_dst))
13534         {
13535           flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL;
13536           if (ADDRESS_IP6 == tun_src.af)
13537             flags |= IPSEC_API_SAD_FLAG_IS_TUNNEL_V6;
13538         }
13539       else
13540         if (unformat (i, "crypto_alg %U",
13541                       unformat_ipsec_api_crypto_alg, &crypto_alg))
13542         ;
13543       else if (unformat (i, "crypto_key %U", unformat_hex_string, &ck))
13544         ;
13545       else if (unformat (i, "integ_alg %U",
13546                          unformat_ipsec_api_integ_alg, &integ_alg))
13547         ;
13548       else if (unformat (i, "integ_key %U", unformat_hex_string, &ik))
13549         ;
13550       else
13551         {
13552           clib_warning ("parse error '%U'", format_unformat_error, i);
13553           return -99;
13554         }
13555
13556     }
13557
13558   M (IPSEC_SAD_ENTRY_ADD_DEL, mp);
13559
13560   mp->is_add = is_add;
13561   mp->entry.sad_id = ntohl (sad_id);
13562   mp->entry.protocol = protocol;
13563   mp->entry.spi = ntohl (spi);
13564   mp->entry.flags = flags;
13565
13566   mp->entry.crypto_algorithm = crypto_alg;
13567   mp->entry.integrity_algorithm = integ_alg;
13568   mp->entry.crypto_key.length = vec_len (ck);
13569   mp->entry.integrity_key.length = vec_len (ik);
13570
13571   if (mp->entry.crypto_key.length > sizeof (mp->entry.crypto_key.data))
13572     mp->entry.crypto_key.length = sizeof (mp->entry.crypto_key.data);
13573
13574   if (mp->entry.integrity_key.length > sizeof (mp->entry.integrity_key.data))
13575     mp->entry.integrity_key.length = sizeof (mp->entry.integrity_key.data);
13576
13577   if (ck)
13578     clib_memcpy (mp->entry.crypto_key.data, ck, mp->entry.crypto_key.length);
13579   if (ik)
13580     clib_memcpy (mp->entry.integrity_key.data, ik,
13581                  mp->entry.integrity_key.length);
13582
13583   if (flags & IPSEC_API_SAD_FLAG_IS_TUNNEL)
13584     {
13585       clib_memcpy (&mp->entry.tunnel_src, &tun_src,
13586                    sizeof (mp->entry.tunnel_src));
13587       clib_memcpy (&mp->entry.tunnel_dst, &tun_dst,
13588                    sizeof (mp->entry.tunnel_dst));
13589     }
13590
13591   S (mp);
13592   W (ret);
13593   return ret;
13594 }
13595
13596 static int
13597 api_ipsec_tunnel_if_add_del (vat_main_t * vam)
13598 {
13599   unformat_input_t *i = vam->input;
13600   vl_api_ipsec_tunnel_if_add_del_t *mp;
13601   u32 local_spi = 0, remote_spi = 0;
13602   u32 crypto_alg = 0, integ_alg = 0;
13603   u8 *lck = NULL, *rck = NULL;
13604   u8 *lik = NULL, *rik = NULL;
13605   vl_api_address_t local_ip = { 0 };
13606   vl_api_address_t remote_ip = { 0 };
13607   f64 before = 0;
13608   u8 is_add = 1;
13609   u8 esn = 0;
13610   u8 anti_replay = 0;
13611   u8 renumber = 0;
13612   u32 instance = ~0;
13613   u32 count = 1, jj;
13614   int ret = -1;
13615
13616   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13617     {
13618       if (unformat (i, "del"))
13619         is_add = 0;
13620       else if (unformat (i, "esn"))
13621         esn = 1;
13622       else if (unformat (i, "anti-replay"))
13623         anti_replay = 1;
13624       else if (unformat (i, "count %d", &count))
13625         ;
13626       else if (unformat (i, "local_spi %d", &local_spi))
13627         ;
13628       else if (unformat (i, "remote_spi %d", &remote_spi))
13629         ;
13630       else
13631         if (unformat (i, "local_ip %U", unformat_vl_api_address, &local_ip))
13632         ;
13633       else
13634         if (unformat (i, "remote_ip %U", unformat_vl_api_address, &remote_ip))
13635         ;
13636       else if (unformat (i, "local_crypto_key %U", unformat_hex_string, &lck))
13637         ;
13638       else
13639         if (unformat (i, "remote_crypto_key %U", unformat_hex_string, &rck))
13640         ;
13641       else if (unformat (i, "local_integ_key %U", unformat_hex_string, &lik))
13642         ;
13643       else if (unformat (i, "remote_integ_key %U", unformat_hex_string, &rik))
13644         ;
13645       else
13646         if (unformat
13647             (i, "crypto_alg %U", unformat_ipsec_api_crypto_alg, &crypto_alg))
13648         {
13649           if (crypto_alg >= IPSEC_CRYPTO_N_ALG)
13650             {
13651               errmsg ("unsupported crypto-alg: '%U'\n",
13652                       format_ipsec_crypto_alg, crypto_alg);
13653               return -99;
13654             }
13655         }
13656       else
13657         if (unformat
13658             (i, "integ_alg %U", unformat_ipsec_api_integ_alg, &integ_alg))
13659         {
13660           if (integ_alg >= IPSEC_INTEG_N_ALG)
13661             {
13662               errmsg ("unsupported integ-alg: '%U'\n",
13663                       format_ipsec_integ_alg, integ_alg);
13664               return -99;
13665             }
13666         }
13667       else if (unformat (i, "instance %u", &instance))
13668         renumber = 1;
13669       else
13670         {
13671           errmsg ("parse error '%U'\n", format_unformat_error, i);
13672           return -99;
13673         }
13674     }
13675
13676   if (count > 1)
13677     {
13678       /* Turn on async mode */
13679       vam->async_mode = 1;
13680       vam->async_errors = 0;
13681       before = vat_time_now (vam);
13682     }
13683
13684   for (jj = 0; jj < count; jj++)
13685     {
13686       M (IPSEC_TUNNEL_IF_ADD_DEL, mp);
13687
13688       mp->is_add = is_add;
13689       mp->esn = esn;
13690       mp->anti_replay = anti_replay;
13691
13692       if (jj > 0)
13693         increment_address (&remote_ip);
13694
13695       clib_memcpy (&mp->local_ip, &local_ip, sizeof (local_ip));
13696       clib_memcpy (&mp->remote_ip, &remote_ip, sizeof (remote_ip));
13697
13698       mp->local_spi = htonl (local_spi + jj);
13699       mp->remote_spi = htonl (remote_spi + jj);
13700       mp->crypto_alg = (u8) crypto_alg;
13701
13702       mp->local_crypto_key_len = 0;
13703       if (lck)
13704         {
13705           mp->local_crypto_key_len = vec_len (lck);
13706           if (mp->local_crypto_key_len > sizeof (mp->local_crypto_key))
13707             mp->local_crypto_key_len = sizeof (mp->local_crypto_key);
13708           clib_memcpy (mp->local_crypto_key, lck, mp->local_crypto_key_len);
13709         }
13710
13711       mp->remote_crypto_key_len = 0;
13712       if (rck)
13713         {
13714           mp->remote_crypto_key_len = vec_len (rck);
13715           if (mp->remote_crypto_key_len > sizeof (mp->remote_crypto_key))
13716             mp->remote_crypto_key_len = sizeof (mp->remote_crypto_key);
13717           clib_memcpy (mp->remote_crypto_key, rck, mp->remote_crypto_key_len);
13718         }
13719
13720       mp->integ_alg = (u8) integ_alg;
13721
13722       mp->local_integ_key_len = 0;
13723       if (lik)
13724         {
13725           mp->local_integ_key_len = vec_len (lik);
13726           if (mp->local_integ_key_len > sizeof (mp->local_integ_key))
13727             mp->local_integ_key_len = sizeof (mp->local_integ_key);
13728           clib_memcpy (mp->local_integ_key, lik, mp->local_integ_key_len);
13729         }
13730
13731       mp->remote_integ_key_len = 0;
13732       if (rik)
13733         {
13734           mp->remote_integ_key_len = vec_len (rik);
13735           if (mp->remote_integ_key_len > sizeof (mp->remote_integ_key))
13736             mp->remote_integ_key_len = sizeof (mp->remote_integ_key);
13737           clib_memcpy (mp->remote_integ_key, rik, mp->remote_integ_key_len);
13738         }
13739
13740       if (renumber)
13741         {
13742           mp->renumber = renumber;
13743           mp->show_instance = ntohl (instance);
13744         }
13745       S (mp);
13746     }
13747
13748   /* When testing multiple add/del ops, use a control-ping to sync */
13749   if (count > 1)
13750     {
13751       vl_api_control_ping_t *mp_ping;
13752       f64 after;
13753       f64 timeout;
13754
13755       /* Shut off async mode */
13756       vam->async_mode = 0;
13757
13758       MPING (CONTROL_PING, mp_ping);
13759       S (mp_ping);
13760
13761       timeout = vat_time_now (vam) + 1.0;
13762       while (vat_time_now (vam) < timeout)
13763         if (vam->result_ready == 1)
13764           goto out;
13765       vam->retval = -99;
13766
13767     out:
13768       if (vam->retval == -99)
13769         errmsg ("timeout");
13770
13771       if (vam->async_errors > 0)
13772         {
13773           errmsg ("%d asynchronous errors", vam->async_errors);
13774           vam->retval = -98;
13775         }
13776       vam->async_errors = 0;
13777       after = vat_time_now (vam);
13778
13779       /* slim chance, but we might have eaten SIGTERM on the first iteration */
13780       if (jj > 0)
13781         count = jj;
13782
13783       print (vam->ofp, "%d tunnels in %.6f secs, %.2f tunnels/sec",
13784              count, after - before, count / (after - before));
13785     }
13786   else
13787     {
13788       /* Wait for a reply... */
13789       W (ret);
13790       return ret;
13791     }
13792
13793   return ret;
13794 }
13795
13796 static void
13797 vl_api_ipsec_sa_details_t_handler (vl_api_ipsec_sa_details_t * mp)
13798 {
13799   vat_main_t *vam = &vat_main;
13800
13801   print (vam->ofp, "sa_id %u sw_if_index %u spi %u proto %u crypto_alg %u "
13802          "crypto_key %U integ_alg %u integ_key %U flags %x "
13803          "tunnel_src_addr %U tunnel_dst_addr %U "
13804          "salt %u seq_outbound %lu last_seq_inbound %lu "
13805          "replay_window %lu\n",
13806          ntohl (mp->entry.sad_id),
13807          ntohl (mp->sw_if_index),
13808          ntohl (mp->entry.spi),
13809          ntohl (mp->entry.protocol),
13810          ntohl (mp->entry.crypto_algorithm),
13811          format_hex_bytes, mp->entry.crypto_key.data,
13812          mp->entry.crypto_key.length, ntohl (mp->entry.integrity_algorithm),
13813          format_hex_bytes, mp->entry.integrity_key.data,
13814          mp->entry.integrity_key.length, ntohl (mp->entry.flags),
13815          format_vl_api_address, &mp->entry.tunnel_src, format_vl_api_address,
13816          &mp->entry.tunnel_dst, ntohl (mp->salt),
13817          clib_net_to_host_u64 (mp->seq_outbound),
13818          clib_net_to_host_u64 (mp->last_seq_inbound),
13819          clib_net_to_host_u64 (mp->replay_window));
13820 }
13821
13822 #define vl_api_ipsec_sa_details_t_endian vl_noop_handler
13823 #define vl_api_ipsec_sa_details_t_print vl_noop_handler
13824
13825 static void vl_api_ipsec_sa_details_t_handler_json
13826   (vl_api_ipsec_sa_details_t * mp)
13827 {
13828   vat_main_t *vam = &vat_main;
13829   vat_json_node_t *node = NULL;
13830   vl_api_ipsec_sad_flags_t flags;
13831
13832   if (VAT_JSON_ARRAY != vam->json_tree.type)
13833     {
13834       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
13835       vat_json_init_array (&vam->json_tree);
13836     }
13837   node = vat_json_array_add (&vam->json_tree);
13838
13839   vat_json_init_object (node);
13840   vat_json_object_add_uint (node, "sa_id", ntohl (mp->entry.sad_id));
13841   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
13842   vat_json_object_add_uint (node, "spi", ntohl (mp->entry.spi));
13843   vat_json_object_add_uint (node, "proto", ntohl (mp->entry.protocol));
13844   vat_json_object_add_uint (node, "crypto_alg",
13845                             ntohl (mp->entry.crypto_algorithm));
13846   vat_json_object_add_uint (node, "integ_alg",
13847                             ntohl (mp->entry.integrity_algorithm));
13848   flags = ntohl (mp->entry.flags);
13849   vat_json_object_add_uint (node, "use_esn",
13850                             ! !(flags & IPSEC_API_SAD_FLAG_USE_ESN));
13851   vat_json_object_add_uint (node, "use_anti_replay",
13852                             ! !(flags & IPSEC_API_SAD_FLAG_USE_ANTI_REPLAY));
13853   vat_json_object_add_uint (node, "is_tunnel",
13854                             ! !(flags & IPSEC_API_SAD_FLAG_IS_TUNNEL));
13855   vat_json_object_add_uint (node, "is_tunnel_ip6",
13856                             ! !(flags & IPSEC_API_SAD_FLAG_IS_TUNNEL_V6));
13857   vat_json_object_add_uint (node, "udp_encap",
13858                             ! !(flags & IPSEC_API_SAD_FLAG_UDP_ENCAP));
13859   vat_json_object_add_bytes (node, "crypto_key", mp->entry.crypto_key.data,
13860                              mp->entry.crypto_key.length);
13861   vat_json_object_add_bytes (node, "integ_key", mp->entry.integrity_key.data,
13862                              mp->entry.integrity_key.length);
13863   vat_json_object_add_address (node, "src", &mp->entry.tunnel_src);
13864   vat_json_object_add_address (node, "dst", &mp->entry.tunnel_dst);
13865   vat_json_object_add_uint (node, "replay_window",
13866                             clib_net_to_host_u64 (mp->replay_window));
13867 }
13868
13869 static int
13870 api_ipsec_sa_dump (vat_main_t * vam)
13871 {
13872   unformat_input_t *i = vam->input;
13873   vl_api_ipsec_sa_dump_t *mp;
13874   vl_api_control_ping_t *mp_ping;
13875   u32 sa_id = ~0;
13876   int ret;
13877
13878   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13879     {
13880       if (unformat (i, "sa_id %d", &sa_id))
13881         ;
13882       else
13883         {
13884           clib_warning ("parse error '%U'", format_unformat_error, i);
13885           return -99;
13886         }
13887     }
13888
13889   M (IPSEC_SA_DUMP, mp);
13890
13891   mp->sa_id = ntohl (sa_id);
13892
13893   S (mp);
13894
13895   /* Use a control ping for synchronization */
13896   M (CONTROL_PING, mp_ping);
13897   S (mp_ping);
13898
13899   W (ret);
13900   return ret;
13901 }
13902
13903 static int
13904 api_ipsec_tunnel_if_set_sa (vat_main_t * vam)
13905 {
13906   unformat_input_t *i = vam->input;
13907   vl_api_ipsec_tunnel_if_set_sa_t *mp;
13908   u32 sw_if_index = ~0;
13909   u32 sa_id = ~0;
13910   u8 is_outbound = (u8) ~ 0;
13911   int ret;
13912
13913   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13914     {
13915       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
13916         ;
13917       else if (unformat (i, "sa_id %d", &sa_id))
13918         ;
13919       else if (unformat (i, "outbound"))
13920         is_outbound = 1;
13921       else if (unformat (i, "inbound"))
13922         is_outbound = 0;
13923       else
13924         {
13925           clib_warning ("parse error '%U'", format_unformat_error, i);
13926           return -99;
13927         }
13928     }
13929
13930   if (sw_if_index == ~0)
13931     {
13932       errmsg ("interface must be specified");
13933       return -99;
13934     }
13935
13936   if (sa_id == ~0)
13937     {
13938       errmsg ("SA ID must be specified");
13939       return -99;
13940     }
13941
13942   M (IPSEC_TUNNEL_IF_SET_SA, mp);
13943
13944   mp->sw_if_index = htonl (sw_if_index);
13945   mp->sa_id = htonl (sa_id);
13946   mp->is_outbound = is_outbound;
13947
13948   S (mp);
13949   W (ret);
13950
13951   return ret;
13952 }
13953
13954 static int
13955 api_get_first_msg_id (vat_main_t * vam)
13956 {
13957   vl_api_get_first_msg_id_t *mp;
13958   unformat_input_t *i = vam->input;
13959   u8 *name;
13960   u8 name_set = 0;
13961   int ret;
13962
13963   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
13964     {
13965       if (unformat (i, "client %s", &name))
13966         name_set = 1;
13967       else
13968         break;
13969     }
13970
13971   if (name_set == 0)
13972     {
13973       errmsg ("missing client name");
13974       return -99;
13975     }
13976   vec_add1 (name, 0);
13977
13978   if (vec_len (name) > 63)
13979     {
13980       errmsg ("client name too long");
13981       return -99;
13982     }
13983
13984   M (GET_FIRST_MSG_ID, mp);
13985   clib_memcpy (mp->name, name, vec_len (name));
13986   S (mp);
13987   W (ret);
13988   return ret;
13989 }
13990
13991 static int
13992 api_cop_interface_enable_disable (vat_main_t * vam)
13993 {
13994   unformat_input_t *line_input = vam->input;
13995   vl_api_cop_interface_enable_disable_t *mp;
13996   u32 sw_if_index = ~0;
13997   u8 enable_disable = 1;
13998   int ret;
13999
14000   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14001     {
14002       if (unformat (line_input, "disable"))
14003         enable_disable = 0;
14004       if (unformat (line_input, "enable"))
14005         enable_disable = 1;
14006       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
14007                          vam, &sw_if_index))
14008         ;
14009       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
14010         ;
14011       else
14012         break;
14013     }
14014
14015   if (sw_if_index == ~0)
14016     {
14017       errmsg ("missing interface name or sw_if_index");
14018       return -99;
14019     }
14020
14021   /* Construct the API message */
14022   M (COP_INTERFACE_ENABLE_DISABLE, mp);
14023   mp->sw_if_index = ntohl (sw_if_index);
14024   mp->enable_disable = enable_disable;
14025
14026   /* send it... */
14027   S (mp);
14028   /* Wait for the reply */
14029   W (ret);
14030   return ret;
14031 }
14032
14033 static int
14034 api_cop_whitelist_enable_disable (vat_main_t * vam)
14035 {
14036   unformat_input_t *line_input = vam->input;
14037   vl_api_cop_whitelist_enable_disable_t *mp;
14038   u32 sw_if_index = ~0;
14039   u8 ip4 = 0, ip6 = 0, default_cop = 0;
14040   u32 fib_id = 0;
14041   int ret;
14042
14043   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
14044     {
14045       if (unformat (line_input, "ip4"))
14046         ip4 = 1;
14047       else if (unformat (line_input, "ip6"))
14048         ip6 = 1;
14049       else if (unformat (line_input, "default"))
14050         default_cop = 1;
14051       else if (unformat (line_input, "%U", api_unformat_sw_if_index,
14052                          vam, &sw_if_index))
14053         ;
14054       else if (unformat (line_input, "sw_if_index %d", &sw_if_index))
14055         ;
14056       else if (unformat (line_input, "fib-id %d", &fib_id))
14057         ;
14058       else
14059         break;
14060     }
14061
14062   if (sw_if_index == ~0)
14063     {
14064       errmsg ("missing interface name or sw_if_index");
14065       return -99;
14066     }
14067
14068   /* Construct the API message */
14069   M (COP_WHITELIST_ENABLE_DISABLE, mp);
14070   mp->sw_if_index = ntohl (sw_if_index);
14071   mp->fib_id = ntohl (fib_id);
14072   mp->ip4 = ip4;
14073   mp->ip6 = ip6;
14074   mp->default_cop = default_cop;
14075
14076   /* send it... */
14077   S (mp);
14078   /* Wait for the reply */
14079   W (ret);
14080   return ret;
14081 }
14082
14083 static int
14084 api_get_node_graph (vat_main_t * vam)
14085 {
14086   vl_api_get_node_graph_t *mp;
14087   int ret;
14088
14089   M (GET_NODE_GRAPH, mp);
14090
14091   /* send it... */
14092   S (mp);
14093   /* Wait for the reply */
14094   W (ret);
14095   return ret;
14096 }
14097
14098 /* *INDENT-OFF* */
14099 /** Used for parsing LISP eids */
14100 typedef CLIB_PACKED(struct{
14101   u8 addr[16];   /**< eid address */
14102   u32 len;       /**< prefix length if IP */
14103   u8 type;      /**< type of eid */
14104 }) lisp_eid_vat_t;
14105 /* *INDENT-ON* */
14106
14107 static uword
14108 unformat_lisp_eid_vat (unformat_input_t * input, va_list * args)
14109 {
14110   lisp_eid_vat_t *a = va_arg (*args, lisp_eid_vat_t *);
14111
14112   clib_memset (a, 0, sizeof (a[0]));
14113
14114   if (unformat (input, "%U/%d", unformat_ip4_address, a->addr, &a->len))
14115     {
14116       a->type = 0;              /* ipv4 type */
14117     }
14118   else if (unformat (input, "%U/%d", unformat_ip6_address, a->addr, &a->len))
14119     {
14120       a->type = 1;              /* ipv6 type */
14121     }
14122   else if (unformat (input, "%U", unformat_ethernet_address, a->addr))
14123     {
14124       a->type = 2;              /* mac type */
14125     }
14126   else if (unformat (input, "%U", unformat_nsh_address, a->addr))
14127     {
14128       a->type = 3;              /* NSH type */
14129       lisp_nsh_api_t *nsh = (lisp_nsh_api_t *) a->addr;
14130       nsh->spi = clib_host_to_net_u32 (nsh->spi);
14131     }
14132   else
14133     {
14134       return 0;
14135     }
14136
14137   if ((a->type == 0 && a->len > 32) || (a->type == 1 && a->len > 128))
14138     {
14139       return 0;
14140     }
14141
14142   return 1;
14143 }
14144
14145 static int
14146 lisp_eid_size_vat (u8 type)
14147 {
14148   switch (type)
14149     {
14150     case 0:
14151       return 4;
14152     case 1:
14153       return 16;
14154     case 2:
14155       return 6;
14156     case 3:
14157       return 5;
14158     }
14159   return 0;
14160 }
14161
14162 static void
14163 lisp_eid_put_vat (u8 * dst, u8 eid[16], u8 type)
14164 {
14165   clib_memcpy (dst, eid, lisp_eid_size_vat (type));
14166 }
14167
14168 static int
14169 api_one_add_del_locator_set (vat_main_t * vam)
14170 {
14171   unformat_input_t *input = vam->input;
14172   vl_api_one_add_del_locator_set_t *mp;
14173   u8 is_add = 1;
14174   u8 *locator_set_name = NULL;
14175   u8 locator_set_name_set = 0;
14176   vl_api_local_locator_t locator, *locators = 0;
14177   u32 sw_if_index, priority, weight;
14178   u32 data_len = 0;
14179
14180   int ret;
14181   /* Parse args required to build the message */
14182   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14183     {
14184       if (unformat (input, "del"))
14185         {
14186           is_add = 0;
14187         }
14188       else if (unformat (input, "locator-set %s", &locator_set_name))
14189         {
14190           locator_set_name_set = 1;
14191         }
14192       else if (unformat (input, "sw_if_index %u p %u w %u",
14193                          &sw_if_index, &priority, &weight))
14194         {
14195           locator.sw_if_index = htonl (sw_if_index);
14196           locator.priority = priority;
14197           locator.weight = weight;
14198           vec_add1 (locators, locator);
14199         }
14200       else
14201         if (unformat
14202             (input, "iface %U p %u w %u", api_unformat_sw_if_index, vam,
14203              &sw_if_index, &priority, &weight))
14204         {
14205           locator.sw_if_index = htonl (sw_if_index);
14206           locator.priority = priority;
14207           locator.weight = weight;
14208           vec_add1 (locators, locator);
14209         }
14210       else
14211         break;
14212     }
14213
14214   if (locator_set_name_set == 0)
14215     {
14216       errmsg ("missing locator-set name");
14217       vec_free (locators);
14218       return -99;
14219     }
14220
14221   if (vec_len (locator_set_name) > 64)
14222     {
14223       errmsg ("locator-set name too long");
14224       vec_free (locator_set_name);
14225       vec_free (locators);
14226       return -99;
14227     }
14228   vec_add1 (locator_set_name, 0);
14229
14230   data_len = sizeof (vl_api_local_locator_t) * vec_len (locators);
14231
14232   /* Construct the API message */
14233   M2 (ONE_ADD_DEL_LOCATOR_SET, mp, data_len);
14234
14235   mp->is_add = is_add;
14236   clib_memcpy (mp->locator_set_name, locator_set_name,
14237                vec_len (locator_set_name));
14238   vec_free (locator_set_name);
14239
14240   mp->locator_num = clib_host_to_net_u32 (vec_len (locators));
14241   if (locators)
14242     clib_memcpy (mp->locators, locators, data_len);
14243   vec_free (locators);
14244
14245   /* send it... */
14246   S (mp);
14247
14248   /* Wait for a reply... */
14249   W (ret);
14250   return ret;
14251 }
14252
14253 #define api_lisp_add_del_locator_set api_one_add_del_locator_set
14254
14255 static int
14256 api_one_add_del_locator (vat_main_t * vam)
14257 {
14258   unformat_input_t *input = vam->input;
14259   vl_api_one_add_del_locator_t *mp;
14260   u32 tmp_if_index = ~0;
14261   u32 sw_if_index = ~0;
14262   u8 sw_if_index_set = 0;
14263   u8 sw_if_index_if_name_set = 0;
14264   u32 priority = ~0;
14265   u8 priority_set = 0;
14266   u32 weight = ~0;
14267   u8 weight_set = 0;
14268   u8 is_add = 1;
14269   u8 *locator_set_name = NULL;
14270   u8 locator_set_name_set = 0;
14271   int ret;
14272
14273   /* Parse args required to build the message */
14274   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14275     {
14276       if (unformat (input, "del"))
14277         {
14278           is_add = 0;
14279         }
14280       else if (unformat (input, "locator-set %s", &locator_set_name))
14281         {
14282           locator_set_name_set = 1;
14283         }
14284       else if (unformat (input, "iface %U", api_unformat_sw_if_index, vam,
14285                          &tmp_if_index))
14286         {
14287           sw_if_index_if_name_set = 1;
14288           sw_if_index = tmp_if_index;
14289         }
14290       else if (unformat (input, "sw_if_index %d", &tmp_if_index))
14291         {
14292           sw_if_index_set = 1;
14293           sw_if_index = tmp_if_index;
14294         }
14295       else if (unformat (input, "p %d", &priority))
14296         {
14297           priority_set = 1;
14298         }
14299       else if (unformat (input, "w %d", &weight))
14300         {
14301           weight_set = 1;
14302         }
14303       else
14304         break;
14305     }
14306
14307   if (locator_set_name_set == 0)
14308     {
14309       errmsg ("missing locator-set name");
14310       return -99;
14311     }
14312
14313   if (sw_if_index_set == 0 && sw_if_index_if_name_set == 0)
14314     {
14315       errmsg ("missing sw_if_index");
14316       vec_free (locator_set_name);
14317       return -99;
14318     }
14319
14320   if (sw_if_index_set != 0 && sw_if_index_if_name_set != 0)
14321     {
14322       errmsg ("cannot use both params interface name and sw_if_index");
14323       vec_free (locator_set_name);
14324       return -99;
14325     }
14326
14327   if (priority_set == 0)
14328     {
14329       errmsg ("missing locator-set priority");
14330       vec_free (locator_set_name);
14331       return -99;
14332     }
14333
14334   if (weight_set == 0)
14335     {
14336       errmsg ("missing locator-set weight");
14337       vec_free (locator_set_name);
14338       return -99;
14339     }
14340
14341   if (vec_len (locator_set_name) > 64)
14342     {
14343       errmsg ("locator-set name too long");
14344       vec_free (locator_set_name);
14345       return -99;
14346     }
14347   vec_add1 (locator_set_name, 0);
14348
14349   /* Construct the API message */
14350   M (ONE_ADD_DEL_LOCATOR, mp);
14351
14352   mp->is_add = is_add;
14353   mp->sw_if_index = ntohl (sw_if_index);
14354   mp->priority = priority;
14355   mp->weight = weight;
14356   clib_memcpy (mp->locator_set_name, locator_set_name,
14357                vec_len (locator_set_name));
14358   vec_free (locator_set_name);
14359
14360   /* send it... */
14361   S (mp);
14362
14363   /* Wait for a reply... */
14364   W (ret);
14365   return ret;
14366 }
14367
14368 #define api_lisp_add_del_locator api_one_add_del_locator
14369
14370 uword
14371 unformat_hmac_key_id (unformat_input_t * input, va_list * args)
14372 {
14373   u32 *key_id = va_arg (*args, u32 *);
14374   u8 *s = 0;
14375
14376   if (unformat (input, "%s", &s))
14377     {
14378       if (!strcmp ((char *) s, "sha1"))
14379         key_id[0] = HMAC_SHA_1_96;
14380       else if (!strcmp ((char *) s, "sha256"))
14381         key_id[0] = HMAC_SHA_256_128;
14382       else
14383         {
14384           clib_warning ("invalid key_id: '%s'", s);
14385           key_id[0] = HMAC_NO_KEY;
14386         }
14387     }
14388   else
14389     return 0;
14390
14391   vec_free (s);
14392   return 1;
14393 }
14394
14395 static int
14396 api_one_add_del_local_eid (vat_main_t * vam)
14397 {
14398   unformat_input_t *input = vam->input;
14399   vl_api_one_add_del_local_eid_t *mp;
14400   u8 is_add = 1;
14401   u8 eid_set = 0;
14402   lisp_eid_vat_t _eid, *eid = &_eid;
14403   u8 *locator_set_name = 0;
14404   u8 locator_set_name_set = 0;
14405   u32 vni = 0;
14406   u16 key_id = 0;
14407   u8 *key = 0;
14408   int ret;
14409
14410   /* Parse args required to build the message */
14411   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14412     {
14413       if (unformat (input, "del"))
14414         {
14415           is_add = 0;
14416         }
14417       else if (unformat (input, "vni %d", &vni))
14418         {
14419           ;
14420         }
14421       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
14422         {
14423           eid_set = 1;
14424         }
14425       else if (unformat (input, "locator-set %s", &locator_set_name))
14426         {
14427           locator_set_name_set = 1;
14428         }
14429       else if (unformat (input, "key-id %U", unformat_hmac_key_id, &key_id))
14430         ;
14431       else if (unformat (input, "secret-key %_%v%_", &key))
14432         ;
14433       else
14434         break;
14435     }
14436
14437   if (locator_set_name_set == 0)
14438     {
14439       errmsg ("missing locator-set name");
14440       return -99;
14441     }
14442
14443   if (0 == eid_set)
14444     {
14445       errmsg ("EID address not set!");
14446       vec_free (locator_set_name);
14447       return -99;
14448     }
14449
14450   if (key && (0 == key_id))
14451     {
14452       errmsg ("invalid key_id!");
14453       return -99;
14454     }
14455
14456   if (vec_len (key) > 64)
14457     {
14458       errmsg ("key too long");
14459       vec_free (key);
14460       return -99;
14461     }
14462
14463   if (vec_len (locator_set_name) > 64)
14464     {
14465       errmsg ("locator-set name too long");
14466       vec_free (locator_set_name);
14467       return -99;
14468     }
14469   vec_add1 (locator_set_name, 0);
14470
14471   /* Construct the API message */
14472   M (ONE_ADD_DEL_LOCAL_EID, mp);
14473
14474   mp->is_add = is_add;
14475   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
14476   mp->eid_type = eid->type;
14477   mp->prefix_len = eid->len;
14478   mp->vni = clib_host_to_net_u32 (vni);
14479   mp->key_id = clib_host_to_net_u16 (key_id);
14480   clib_memcpy (mp->locator_set_name, locator_set_name,
14481                vec_len (locator_set_name));
14482   clib_memcpy (mp->key, key, vec_len (key));
14483
14484   vec_free (locator_set_name);
14485   vec_free (key);
14486
14487   /* send it... */
14488   S (mp);
14489
14490   /* Wait for a reply... */
14491   W (ret);
14492   return ret;
14493 }
14494
14495 #define api_lisp_add_del_local_eid api_one_add_del_local_eid
14496
14497 static int
14498 api_lisp_gpe_add_del_fwd_entry (vat_main_t * vam)
14499 {
14500   u32 dp_table = 0, vni = 0;;
14501   unformat_input_t *input = vam->input;
14502   vl_api_gpe_add_del_fwd_entry_t *mp;
14503   u8 is_add = 1;
14504   lisp_eid_vat_t _rmt_eid, *rmt_eid = &_rmt_eid;
14505   lisp_eid_vat_t _lcl_eid, *lcl_eid = &_lcl_eid;
14506   u8 rmt_eid_set = 0, lcl_eid_set = 0;
14507   u32 action = ~0, w;
14508   ip4_address_t rmt_rloc4, lcl_rloc4;
14509   ip6_address_t rmt_rloc6, lcl_rloc6;
14510   vl_api_gpe_locator_t *rmt_locs = 0, *lcl_locs = 0, rloc, *curr_rloc = 0;
14511   int ret;
14512
14513   clib_memset (&rloc, 0, sizeof (rloc));
14514
14515   /* Parse args required to build the message */
14516   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14517     {
14518       if (unformat (input, "del"))
14519         is_add = 0;
14520       else if (unformat (input, "add"))
14521         is_add = 1;
14522       else if (unformat (input, "reid %U", unformat_lisp_eid_vat, rmt_eid))
14523         {
14524           rmt_eid_set = 1;
14525         }
14526       else if (unformat (input, "leid %U", unformat_lisp_eid_vat, lcl_eid))
14527         {
14528           lcl_eid_set = 1;
14529         }
14530       else if (unformat (input, "vrf %d", &dp_table))
14531         ;
14532       else if (unformat (input, "bd %d", &dp_table))
14533         ;
14534       else if (unformat (input, "vni %d", &vni))
14535         ;
14536       else if (unformat (input, "w %d", &w))
14537         {
14538           if (!curr_rloc)
14539             {
14540               errmsg ("No RLOC configured for setting priority/weight!");
14541               return -99;
14542             }
14543           curr_rloc->weight = w;
14544         }
14545       else if (unformat (input, "loc-pair %U %U", unformat_ip4_address,
14546                          &lcl_rloc4, unformat_ip4_address, &rmt_rloc4))
14547         {
14548           rloc.is_ip4 = 1;
14549
14550           clib_memcpy (&rloc.addr, &lcl_rloc4, sizeof (lcl_rloc4));
14551           rloc.weight = 0;
14552           vec_add1 (lcl_locs, rloc);
14553
14554           clib_memcpy (&rloc.addr, &rmt_rloc4, sizeof (rmt_rloc4));
14555           vec_add1 (rmt_locs, rloc);
14556           /* weight saved in rmt loc */
14557           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
14558         }
14559       else if (unformat (input, "loc-pair %U %U", unformat_ip6_address,
14560                          &lcl_rloc6, unformat_ip6_address, &rmt_rloc6))
14561         {
14562           rloc.is_ip4 = 0;
14563           clib_memcpy (&rloc.addr, &lcl_rloc6, sizeof (lcl_rloc6));
14564           rloc.weight = 0;
14565           vec_add1 (lcl_locs, rloc);
14566
14567           clib_memcpy (&rloc.addr, &rmt_rloc6, sizeof (rmt_rloc6));
14568           vec_add1 (rmt_locs, rloc);
14569           /* weight saved in rmt loc */
14570           curr_rloc = &rmt_locs[vec_len (rmt_locs) - 1];
14571         }
14572       else if (unformat (input, "action %d", &action))
14573         {
14574           ;
14575         }
14576       else
14577         {
14578           clib_warning ("parse error '%U'", format_unformat_error, input);
14579           return -99;
14580         }
14581     }
14582
14583   if (!rmt_eid_set)
14584     {
14585       errmsg ("remote eid addresses not set");
14586       return -99;
14587     }
14588
14589   if (lcl_eid_set && rmt_eid->type != lcl_eid->type)
14590     {
14591       errmsg ("eid types don't match");
14592       return -99;
14593     }
14594
14595   if (0 == rmt_locs && (u32) ~ 0 == action)
14596     {
14597       errmsg ("action not set for negative mapping");
14598       return -99;
14599     }
14600
14601   /* Construct the API message */
14602   M2 (GPE_ADD_DEL_FWD_ENTRY, mp,
14603       sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs) * 2);
14604
14605   mp->is_add = is_add;
14606   lisp_eid_put_vat (mp->rmt_eid, rmt_eid->addr, rmt_eid->type);
14607   lisp_eid_put_vat (mp->lcl_eid, lcl_eid->addr, lcl_eid->type);
14608   mp->eid_type = rmt_eid->type;
14609   mp->dp_table = clib_host_to_net_u32 (dp_table);
14610   mp->vni = clib_host_to_net_u32 (vni);
14611   mp->rmt_len = rmt_eid->len;
14612   mp->lcl_len = lcl_eid->len;
14613   mp->action = action;
14614
14615   if (0 != rmt_locs && 0 != lcl_locs)
14616     {
14617       mp->loc_num = clib_host_to_net_u32 (vec_len (rmt_locs) * 2);
14618       clib_memcpy (mp->locs, lcl_locs,
14619                    (sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs)));
14620
14621       u32 offset = sizeof (vl_api_gpe_locator_t) * vec_len (lcl_locs);
14622       clib_memcpy (((u8 *) mp->locs) + offset, rmt_locs,
14623                    (sizeof (vl_api_gpe_locator_t) * vec_len (rmt_locs)));
14624     }
14625   vec_free (lcl_locs);
14626   vec_free (rmt_locs);
14627
14628   /* send it... */
14629   S (mp);
14630
14631   /* Wait for a reply... */
14632   W (ret);
14633   return ret;
14634 }
14635
14636 static int
14637 api_one_add_del_map_server (vat_main_t * vam)
14638 {
14639   unformat_input_t *input = vam->input;
14640   vl_api_one_add_del_map_server_t *mp;
14641   u8 is_add = 1;
14642   u8 ipv4_set = 0;
14643   u8 ipv6_set = 0;
14644   ip4_address_t ipv4;
14645   ip6_address_t ipv6;
14646   int ret;
14647
14648   /* Parse args required to build the message */
14649   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14650     {
14651       if (unformat (input, "del"))
14652         {
14653           is_add = 0;
14654         }
14655       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
14656         {
14657           ipv4_set = 1;
14658         }
14659       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
14660         {
14661           ipv6_set = 1;
14662         }
14663       else
14664         break;
14665     }
14666
14667   if (ipv4_set && ipv6_set)
14668     {
14669       errmsg ("both eid v4 and v6 addresses set");
14670       return -99;
14671     }
14672
14673   if (!ipv4_set && !ipv6_set)
14674     {
14675       errmsg ("eid addresses not set");
14676       return -99;
14677     }
14678
14679   /* Construct the API message */
14680   M (ONE_ADD_DEL_MAP_SERVER, mp);
14681
14682   mp->is_add = is_add;
14683   if (ipv6_set)
14684     {
14685       mp->is_ipv6 = 1;
14686       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
14687     }
14688   else
14689     {
14690       mp->is_ipv6 = 0;
14691       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
14692     }
14693
14694   /* send it... */
14695   S (mp);
14696
14697   /* Wait for a reply... */
14698   W (ret);
14699   return ret;
14700 }
14701
14702 #define api_lisp_add_del_map_server api_one_add_del_map_server
14703
14704 static int
14705 api_one_add_del_map_resolver (vat_main_t * vam)
14706 {
14707   unformat_input_t *input = vam->input;
14708   vl_api_one_add_del_map_resolver_t *mp;
14709   u8 is_add = 1;
14710   u8 ipv4_set = 0;
14711   u8 ipv6_set = 0;
14712   ip4_address_t ipv4;
14713   ip6_address_t ipv6;
14714   int ret;
14715
14716   /* Parse args required to build the message */
14717   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14718     {
14719       if (unformat (input, "del"))
14720         {
14721           is_add = 0;
14722         }
14723       else if (unformat (input, "%U", unformat_ip4_address, &ipv4))
14724         {
14725           ipv4_set = 1;
14726         }
14727       else if (unformat (input, "%U", unformat_ip6_address, &ipv6))
14728         {
14729           ipv6_set = 1;
14730         }
14731       else
14732         break;
14733     }
14734
14735   if (ipv4_set && ipv6_set)
14736     {
14737       errmsg ("both eid v4 and v6 addresses set");
14738       return -99;
14739     }
14740
14741   if (!ipv4_set && !ipv6_set)
14742     {
14743       errmsg ("eid addresses not set");
14744       return -99;
14745     }
14746
14747   /* Construct the API message */
14748   M (ONE_ADD_DEL_MAP_RESOLVER, mp);
14749
14750   mp->is_add = is_add;
14751   if (ipv6_set)
14752     {
14753       mp->is_ipv6 = 1;
14754       clib_memcpy (mp->ip_address, &ipv6, sizeof (ipv6));
14755     }
14756   else
14757     {
14758       mp->is_ipv6 = 0;
14759       clib_memcpy (mp->ip_address, &ipv4, sizeof (ipv4));
14760     }
14761
14762   /* send it... */
14763   S (mp);
14764
14765   /* Wait for a reply... */
14766   W (ret);
14767   return ret;
14768 }
14769
14770 #define api_lisp_add_del_map_resolver api_one_add_del_map_resolver
14771
14772 static int
14773 api_lisp_gpe_enable_disable (vat_main_t * vam)
14774 {
14775   unformat_input_t *input = vam->input;
14776   vl_api_gpe_enable_disable_t *mp;
14777   u8 is_set = 0;
14778   u8 is_en = 1;
14779   int ret;
14780
14781   /* Parse args required to build the message */
14782   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14783     {
14784       if (unformat (input, "enable"))
14785         {
14786           is_set = 1;
14787           is_en = 1;
14788         }
14789       else if (unformat (input, "disable"))
14790         {
14791           is_set = 1;
14792           is_en = 0;
14793         }
14794       else
14795         break;
14796     }
14797
14798   if (is_set == 0)
14799     {
14800       errmsg ("Value not set");
14801       return -99;
14802     }
14803
14804   /* Construct the API message */
14805   M (GPE_ENABLE_DISABLE, mp);
14806
14807   mp->is_en = is_en;
14808
14809   /* send it... */
14810   S (mp);
14811
14812   /* Wait for a reply... */
14813   W (ret);
14814   return ret;
14815 }
14816
14817 static int
14818 api_one_rloc_probe_enable_disable (vat_main_t * vam)
14819 {
14820   unformat_input_t *input = vam->input;
14821   vl_api_one_rloc_probe_enable_disable_t *mp;
14822   u8 is_set = 0;
14823   u8 is_en = 0;
14824   int ret;
14825
14826   /* Parse args required to build the message */
14827   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14828     {
14829       if (unformat (input, "enable"))
14830         {
14831           is_set = 1;
14832           is_en = 1;
14833         }
14834       else if (unformat (input, "disable"))
14835         is_set = 1;
14836       else
14837         break;
14838     }
14839
14840   if (!is_set)
14841     {
14842       errmsg ("Value not set");
14843       return -99;
14844     }
14845
14846   /* Construct the API message */
14847   M (ONE_RLOC_PROBE_ENABLE_DISABLE, mp);
14848
14849   mp->is_enabled = is_en;
14850
14851   /* send it... */
14852   S (mp);
14853
14854   /* Wait for a reply... */
14855   W (ret);
14856   return ret;
14857 }
14858
14859 #define api_lisp_rloc_probe_enable_disable api_one_rloc_probe_enable_disable
14860
14861 static int
14862 api_one_map_register_enable_disable (vat_main_t * vam)
14863 {
14864   unformat_input_t *input = vam->input;
14865   vl_api_one_map_register_enable_disable_t *mp;
14866   u8 is_set = 0;
14867   u8 is_en = 0;
14868   int ret;
14869
14870   /* Parse args required to build the message */
14871   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14872     {
14873       if (unformat (input, "enable"))
14874         {
14875           is_set = 1;
14876           is_en = 1;
14877         }
14878       else if (unformat (input, "disable"))
14879         is_set = 1;
14880       else
14881         break;
14882     }
14883
14884   if (!is_set)
14885     {
14886       errmsg ("Value not set");
14887       return -99;
14888     }
14889
14890   /* Construct the API message */
14891   M (ONE_MAP_REGISTER_ENABLE_DISABLE, mp);
14892
14893   mp->is_enabled = is_en;
14894
14895   /* send it... */
14896   S (mp);
14897
14898   /* Wait for a reply... */
14899   W (ret);
14900   return ret;
14901 }
14902
14903 #define api_lisp_map_register_enable_disable api_one_map_register_enable_disable
14904
14905 static int
14906 api_one_enable_disable (vat_main_t * vam)
14907 {
14908   unformat_input_t *input = vam->input;
14909   vl_api_one_enable_disable_t *mp;
14910   u8 is_set = 0;
14911   u8 is_en = 0;
14912   int ret;
14913
14914   /* Parse args required to build the message */
14915   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14916     {
14917       if (unformat (input, "enable"))
14918         {
14919           is_set = 1;
14920           is_en = 1;
14921         }
14922       else if (unformat (input, "disable"))
14923         {
14924           is_set = 1;
14925         }
14926       else
14927         break;
14928     }
14929
14930   if (!is_set)
14931     {
14932       errmsg ("Value not set");
14933       return -99;
14934     }
14935
14936   /* Construct the API message */
14937   M (ONE_ENABLE_DISABLE, mp);
14938
14939   mp->is_en = is_en;
14940
14941   /* send it... */
14942   S (mp);
14943
14944   /* Wait for a reply... */
14945   W (ret);
14946   return ret;
14947 }
14948
14949 #define api_lisp_enable_disable api_one_enable_disable
14950
14951 static int
14952 api_one_enable_disable_xtr_mode (vat_main_t * vam)
14953 {
14954   unformat_input_t *input = vam->input;
14955   vl_api_one_enable_disable_xtr_mode_t *mp;
14956   u8 is_set = 0;
14957   u8 is_en = 0;
14958   int ret;
14959
14960   /* Parse args required to build the message */
14961   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
14962     {
14963       if (unformat (input, "enable"))
14964         {
14965           is_set = 1;
14966           is_en = 1;
14967         }
14968       else if (unformat (input, "disable"))
14969         {
14970           is_set = 1;
14971         }
14972       else
14973         break;
14974     }
14975
14976   if (!is_set)
14977     {
14978       errmsg ("Value not set");
14979       return -99;
14980     }
14981
14982   /* Construct the API message */
14983   M (ONE_ENABLE_DISABLE_XTR_MODE, mp);
14984
14985   mp->is_en = is_en;
14986
14987   /* send it... */
14988   S (mp);
14989
14990   /* Wait for a reply... */
14991   W (ret);
14992   return ret;
14993 }
14994
14995 static int
14996 api_one_show_xtr_mode (vat_main_t * vam)
14997 {
14998   vl_api_one_show_xtr_mode_t *mp;
14999   int ret;
15000
15001   /* Construct the API message */
15002   M (ONE_SHOW_XTR_MODE, mp);
15003
15004   /* send it... */
15005   S (mp);
15006
15007   /* Wait for a reply... */
15008   W (ret);
15009   return ret;
15010 }
15011
15012 static int
15013 api_one_enable_disable_pitr_mode (vat_main_t * vam)
15014 {
15015   unformat_input_t *input = vam->input;
15016   vl_api_one_enable_disable_pitr_mode_t *mp;
15017   u8 is_set = 0;
15018   u8 is_en = 0;
15019   int ret;
15020
15021   /* Parse args required to build the message */
15022   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15023     {
15024       if (unformat (input, "enable"))
15025         {
15026           is_set = 1;
15027           is_en = 1;
15028         }
15029       else if (unformat (input, "disable"))
15030         {
15031           is_set = 1;
15032         }
15033       else
15034         break;
15035     }
15036
15037   if (!is_set)
15038     {
15039       errmsg ("Value not set");
15040       return -99;
15041     }
15042
15043   /* Construct the API message */
15044   M (ONE_ENABLE_DISABLE_PITR_MODE, mp);
15045
15046   mp->is_en = is_en;
15047
15048   /* send it... */
15049   S (mp);
15050
15051   /* Wait for a reply... */
15052   W (ret);
15053   return ret;
15054 }
15055
15056 static int
15057 api_one_show_pitr_mode (vat_main_t * vam)
15058 {
15059   vl_api_one_show_pitr_mode_t *mp;
15060   int ret;
15061
15062   /* Construct the API message */
15063   M (ONE_SHOW_PITR_MODE, mp);
15064
15065   /* send it... */
15066   S (mp);
15067
15068   /* Wait for a reply... */
15069   W (ret);
15070   return ret;
15071 }
15072
15073 static int
15074 api_one_enable_disable_petr_mode (vat_main_t * vam)
15075 {
15076   unformat_input_t *input = vam->input;
15077   vl_api_one_enable_disable_petr_mode_t *mp;
15078   u8 is_set = 0;
15079   u8 is_en = 0;
15080   int ret;
15081
15082   /* Parse args required to build the message */
15083   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15084     {
15085       if (unformat (input, "enable"))
15086         {
15087           is_set = 1;
15088           is_en = 1;
15089         }
15090       else if (unformat (input, "disable"))
15091         {
15092           is_set = 1;
15093         }
15094       else
15095         break;
15096     }
15097
15098   if (!is_set)
15099     {
15100       errmsg ("Value not set");
15101       return -99;
15102     }
15103
15104   /* Construct the API message */
15105   M (ONE_ENABLE_DISABLE_PETR_MODE, mp);
15106
15107   mp->is_en = is_en;
15108
15109   /* send it... */
15110   S (mp);
15111
15112   /* Wait for a reply... */
15113   W (ret);
15114   return ret;
15115 }
15116
15117 static int
15118 api_one_show_petr_mode (vat_main_t * vam)
15119 {
15120   vl_api_one_show_petr_mode_t *mp;
15121   int ret;
15122
15123   /* Construct the API message */
15124   M (ONE_SHOW_PETR_MODE, mp);
15125
15126   /* send it... */
15127   S (mp);
15128
15129   /* Wait for a reply... */
15130   W (ret);
15131   return ret;
15132 }
15133
15134 static int
15135 api_show_one_map_register_state (vat_main_t * vam)
15136 {
15137   vl_api_show_one_map_register_state_t *mp;
15138   int ret;
15139
15140   M (SHOW_ONE_MAP_REGISTER_STATE, mp);
15141
15142   /* send */
15143   S (mp);
15144
15145   /* wait for reply */
15146   W (ret);
15147   return ret;
15148 }
15149
15150 #define api_show_lisp_map_register_state api_show_one_map_register_state
15151
15152 static int
15153 api_show_one_rloc_probe_state (vat_main_t * vam)
15154 {
15155   vl_api_show_one_rloc_probe_state_t *mp;
15156   int ret;
15157
15158   M (SHOW_ONE_RLOC_PROBE_STATE, mp);
15159
15160   /* send */
15161   S (mp);
15162
15163   /* wait for reply */
15164   W (ret);
15165   return ret;
15166 }
15167
15168 #define api_show_lisp_rloc_probe_state api_show_one_rloc_probe_state
15169
15170 static int
15171 api_one_add_del_ndp_entry (vat_main_t * vam)
15172 {
15173   vl_api_one_add_del_ndp_entry_t *mp;
15174   unformat_input_t *input = vam->input;
15175   u8 is_add = 1;
15176   u8 mac_set = 0;
15177   u8 bd_set = 0;
15178   u8 ip_set = 0;
15179   u8 mac[6] = { 0, };
15180   u8 ip6[16] = { 0, };
15181   u32 bd = ~0;
15182   int ret;
15183
15184   /* Parse args required to build the message */
15185   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15186     {
15187       if (unformat (input, "del"))
15188         is_add = 0;
15189       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
15190         mac_set = 1;
15191       else if (unformat (input, "ip %U", unformat_ip6_address, ip6))
15192         ip_set = 1;
15193       else if (unformat (input, "bd %d", &bd))
15194         bd_set = 1;
15195       else
15196         {
15197           errmsg ("parse error '%U'", format_unformat_error, input);
15198           return -99;
15199         }
15200     }
15201
15202   if (!bd_set || !ip_set || (!mac_set && is_add))
15203     {
15204       errmsg ("Missing BD, IP or MAC!");
15205       return -99;
15206     }
15207
15208   M (ONE_ADD_DEL_NDP_ENTRY, mp);
15209   mp->is_add = is_add;
15210   clib_memcpy (mp->mac, mac, 6);
15211   mp->bd = clib_host_to_net_u32 (bd);
15212   clib_memcpy (mp->ip6, ip6, sizeof (mp->ip6));
15213
15214   /* send */
15215   S (mp);
15216
15217   /* wait for reply */
15218   W (ret);
15219   return ret;
15220 }
15221
15222 static int
15223 api_one_add_del_l2_arp_entry (vat_main_t * vam)
15224 {
15225   vl_api_one_add_del_l2_arp_entry_t *mp;
15226   unformat_input_t *input = vam->input;
15227   u8 is_add = 1;
15228   u8 mac_set = 0;
15229   u8 bd_set = 0;
15230   u8 ip_set = 0;
15231   u8 mac[6] = { 0, };
15232   u32 ip4 = 0, bd = ~0;
15233   int ret;
15234
15235   /* Parse args required to build the message */
15236   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15237     {
15238       if (unformat (input, "del"))
15239         is_add = 0;
15240       else if (unformat (input, "mac %U", unformat_ethernet_address, mac))
15241         mac_set = 1;
15242       else if (unformat (input, "ip %U", unformat_ip4_address, &ip4))
15243         ip_set = 1;
15244       else if (unformat (input, "bd %d", &bd))
15245         bd_set = 1;
15246       else
15247         {
15248           errmsg ("parse error '%U'", format_unformat_error, input);
15249           return -99;
15250         }
15251     }
15252
15253   if (!bd_set || !ip_set || (!mac_set && is_add))
15254     {
15255       errmsg ("Missing BD, IP or MAC!");
15256       return -99;
15257     }
15258
15259   M (ONE_ADD_DEL_L2_ARP_ENTRY, mp);
15260   mp->is_add = is_add;
15261   clib_memcpy (mp->mac, mac, 6);
15262   mp->bd = clib_host_to_net_u32 (bd);
15263   mp->ip4 = ip4;
15264
15265   /* send */
15266   S (mp);
15267
15268   /* wait for reply */
15269   W (ret);
15270   return ret;
15271 }
15272
15273 static int
15274 api_one_ndp_bd_get (vat_main_t * vam)
15275 {
15276   vl_api_one_ndp_bd_get_t *mp;
15277   int ret;
15278
15279   M (ONE_NDP_BD_GET, mp);
15280
15281   /* send */
15282   S (mp);
15283
15284   /* wait for reply */
15285   W (ret);
15286   return ret;
15287 }
15288
15289 static int
15290 api_one_ndp_entries_get (vat_main_t * vam)
15291 {
15292   vl_api_one_ndp_entries_get_t *mp;
15293   unformat_input_t *input = vam->input;
15294   u8 bd_set = 0;
15295   u32 bd = ~0;
15296   int ret;
15297
15298   /* Parse args required to build the message */
15299   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15300     {
15301       if (unformat (input, "bd %d", &bd))
15302         bd_set = 1;
15303       else
15304         {
15305           errmsg ("parse error '%U'", format_unformat_error, input);
15306           return -99;
15307         }
15308     }
15309
15310   if (!bd_set)
15311     {
15312       errmsg ("Expected bridge domain!");
15313       return -99;
15314     }
15315
15316   M (ONE_NDP_ENTRIES_GET, mp);
15317   mp->bd = clib_host_to_net_u32 (bd);
15318
15319   /* send */
15320   S (mp);
15321
15322   /* wait for reply */
15323   W (ret);
15324   return ret;
15325 }
15326
15327 static int
15328 api_one_l2_arp_bd_get (vat_main_t * vam)
15329 {
15330   vl_api_one_l2_arp_bd_get_t *mp;
15331   int ret;
15332
15333   M (ONE_L2_ARP_BD_GET, mp);
15334
15335   /* send */
15336   S (mp);
15337
15338   /* wait for reply */
15339   W (ret);
15340   return ret;
15341 }
15342
15343 static int
15344 api_one_l2_arp_entries_get (vat_main_t * vam)
15345 {
15346   vl_api_one_l2_arp_entries_get_t *mp;
15347   unformat_input_t *input = vam->input;
15348   u8 bd_set = 0;
15349   u32 bd = ~0;
15350   int ret;
15351
15352   /* Parse args required to build the message */
15353   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15354     {
15355       if (unformat (input, "bd %d", &bd))
15356         bd_set = 1;
15357       else
15358         {
15359           errmsg ("parse error '%U'", format_unformat_error, input);
15360           return -99;
15361         }
15362     }
15363
15364   if (!bd_set)
15365     {
15366       errmsg ("Expected bridge domain!");
15367       return -99;
15368     }
15369
15370   M (ONE_L2_ARP_ENTRIES_GET, mp);
15371   mp->bd = clib_host_to_net_u32 (bd);
15372
15373   /* send */
15374   S (mp);
15375
15376   /* wait for reply */
15377   W (ret);
15378   return ret;
15379 }
15380
15381 static int
15382 api_one_stats_enable_disable (vat_main_t * vam)
15383 {
15384   vl_api_one_stats_enable_disable_t *mp;
15385   unformat_input_t *input = vam->input;
15386   u8 is_set = 0;
15387   u8 is_en = 0;
15388   int ret;
15389
15390   /* Parse args required to build the message */
15391   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15392     {
15393       if (unformat (input, "enable"))
15394         {
15395           is_set = 1;
15396           is_en = 1;
15397         }
15398       else if (unformat (input, "disable"))
15399         {
15400           is_set = 1;
15401         }
15402       else
15403         break;
15404     }
15405
15406   if (!is_set)
15407     {
15408       errmsg ("Value not set");
15409       return -99;
15410     }
15411
15412   M (ONE_STATS_ENABLE_DISABLE, mp);
15413   mp->is_en = is_en;
15414
15415   /* send */
15416   S (mp);
15417
15418   /* wait for reply */
15419   W (ret);
15420   return ret;
15421 }
15422
15423 static int
15424 api_show_one_stats_enable_disable (vat_main_t * vam)
15425 {
15426   vl_api_show_one_stats_enable_disable_t *mp;
15427   int ret;
15428
15429   M (SHOW_ONE_STATS_ENABLE_DISABLE, mp);
15430
15431   /* send */
15432   S (mp);
15433
15434   /* wait for reply */
15435   W (ret);
15436   return ret;
15437 }
15438
15439 static int
15440 api_show_one_map_request_mode (vat_main_t * vam)
15441 {
15442   vl_api_show_one_map_request_mode_t *mp;
15443   int ret;
15444
15445   M (SHOW_ONE_MAP_REQUEST_MODE, mp);
15446
15447   /* send */
15448   S (mp);
15449
15450   /* wait for reply */
15451   W (ret);
15452   return ret;
15453 }
15454
15455 #define api_show_lisp_map_request_mode api_show_one_map_request_mode
15456
15457 static int
15458 api_one_map_request_mode (vat_main_t * vam)
15459 {
15460   unformat_input_t *input = vam->input;
15461   vl_api_one_map_request_mode_t *mp;
15462   u8 mode = 0;
15463   int ret;
15464
15465   /* Parse args required to build the message */
15466   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15467     {
15468       if (unformat (input, "dst-only"))
15469         mode = 0;
15470       else if (unformat (input, "src-dst"))
15471         mode = 1;
15472       else
15473         {
15474           errmsg ("parse error '%U'", format_unformat_error, input);
15475           return -99;
15476         }
15477     }
15478
15479   M (ONE_MAP_REQUEST_MODE, mp);
15480
15481   mp->mode = mode;
15482
15483   /* send */
15484   S (mp);
15485
15486   /* wait for reply */
15487   W (ret);
15488   return ret;
15489 }
15490
15491 #define api_lisp_map_request_mode api_one_map_request_mode
15492
15493 /**
15494  * Enable/disable ONE proxy ITR.
15495  *
15496  * @param vam vpp API test context
15497  * @return return code
15498  */
15499 static int
15500 api_one_pitr_set_locator_set (vat_main_t * vam)
15501 {
15502   u8 ls_name_set = 0;
15503   unformat_input_t *input = vam->input;
15504   vl_api_one_pitr_set_locator_set_t *mp;
15505   u8 is_add = 1;
15506   u8 *ls_name = 0;
15507   int ret;
15508
15509   /* Parse args required to build the message */
15510   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15511     {
15512       if (unformat (input, "del"))
15513         is_add = 0;
15514       else if (unformat (input, "locator-set %s", &ls_name))
15515         ls_name_set = 1;
15516       else
15517         {
15518           errmsg ("parse error '%U'", format_unformat_error, input);
15519           return -99;
15520         }
15521     }
15522
15523   if (!ls_name_set)
15524     {
15525       errmsg ("locator-set name not set!");
15526       return -99;
15527     }
15528
15529   M (ONE_PITR_SET_LOCATOR_SET, mp);
15530
15531   mp->is_add = is_add;
15532   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
15533   vec_free (ls_name);
15534
15535   /* send */
15536   S (mp);
15537
15538   /* wait for reply */
15539   W (ret);
15540   return ret;
15541 }
15542
15543 #define api_lisp_pitr_set_locator_set api_one_pitr_set_locator_set
15544
15545 static int
15546 api_one_nsh_set_locator_set (vat_main_t * vam)
15547 {
15548   u8 ls_name_set = 0;
15549   unformat_input_t *input = vam->input;
15550   vl_api_one_nsh_set_locator_set_t *mp;
15551   u8 is_add = 1;
15552   u8 *ls_name = 0;
15553   int ret;
15554
15555   /* Parse args required to build the message */
15556   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15557     {
15558       if (unformat (input, "del"))
15559         is_add = 0;
15560       else if (unformat (input, "ls %s", &ls_name))
15561         ls_name_set = 1;
15562       else
15563         {
15564           errmsg ("parse error '%U'", format_unformat_error, input);
15565           return -99;
15566         }
15567     }
15568
15569   if (!ls_name_set && is_add)
15570     {
15571       errmsg ("locator-set name not set!");
15572       return -99;
15573     }
15574
15575   M (ONE_NSH_SET_LOCATOR_SET, mp);
15576
15577   mp->is_add = is_add;
15578   clib_memcpy (mp->ls_name, ls_name, vec_len (ls_name));
15579   vec_free (ls_name);
15580
15581   /* send */
15582   S (mp);
15583
15584   /* wait for reply */
15585   W (ret);
15586   return ret;
15587 }
15588
15589 static int
15590 api_show_one_pitr (vat_main_t * vam)
15591 {
15592   vl_api_show_one_pitr_t *mp;
15593   int ret;
15594
15595   if (!vam->json_output)
15596     {
15597       print (vam->ofp, "%=20s", "lisp status:");
15598     }
15599
15600   M (SHOW_ONE_PITR, mp);
15601   /* send it... */
15602   S (mp);
15603
15604   /* Wait for a reply... */
15605   W (ret);
15606   return ret;
15607 }
15608
15609 #define api_show_lisp_pitr api_show_one_pitr
15610
15611 static int
15612 api_one_use_petr (vat_main_t * vam)
15613 {
15614   unformat_input_t *input = vam->input;
15615   vl_api_one_use_petr_t *mp;
15616   u8 is_add = 0;
15617   ip_address_t ip;
15618   int ret;
15619
15620   clib_memset (&ip, 0, sizeof (ip));
15621
15622   /* Parse args required to build the message */
15623   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15624     {
15625       if (unformat (input, "disable"))
15626         is_add = 0;
15627       else
15628         if (unformat (input, "%U", unformat_ip4_address, &ip_addr_v4 (&ip)))
15629         {
15630           is_add = 1;
15631           ip_addr_version (&ip) = AF_IP4;
15632         }
15633       else
15634         if (unformat (input, "%U", unformat_ip6_address, &ip_addr_v6 (&ip)))
15635         {
15636           is_add = 1;
15637           ip_addr_version (&ip) = AF_IP6;
15638         }
15639       else
15640         {
15641           errmsg ("parse error '%U'", format_unformat_error, input);
15642           return -99;
15643         }
15644     }
15645
15646   M (ONE_USE_PETR, mp);
15647
15648   mp->is_add = is_add;
15649   if (is_add)
15650     {
15651       mp->is_ip4 = ip_addr_version (&ip) == AF_IP4 ? 1 : 0;
15652       if (mp->is_ip4)
15653         clib_memcpy (mp->address, &ip, 4);
15654       else
15655         clib_memcpy (mp->address, &ip, 16);
15656     }
15657
15658   /* send */
15659   S (mp);
15660
15661   /* wait for reply */
15662   W (ret);
15663   return ret;
15664 }
15665
15666 #define api_lisp_use_petr api_one_use_petr
15667
15668 static int
15669 api_show_one_nsh_mapping (vat_main_t * vam)
15670 {
15671   vl_api_show_one_use_petr_t *mp;
15672   int ret;
15673
15674   if (!vam->json_output)
15675     {
15676       print (vam->ofp, "%=20s", "local ONE NSH mapping:");
15677     }
15678
15679   M (SHOW_ONE_NSH_MAPPING, mp);
15680   /* send it... */
15681   S (mp);
15682
15683   /* Wait for a reply... */
15684   W (ret);
15685   return ret;
15686 }
15687
15688 static int
15689 api_show_one_use_petr (vat_main_t * vam)
15690 {
15691   vl_api_show_one_use_petr_t *mp;
15692   int ret;
15693
15694   if (!vam->json_output)
15695     {
15696       print (vam->ofp, "%=20s", "Proxy-ETR status:");
15697     }
15698
15699   M (SHOW_ONE_USE_PETR, mp);
15700   /* send it... */
15701   S (mp);
15702
15703   /* Wait for a reply... */
15704   W (ret);
15705   return ret;
15706 }
15707
15708 #define api_show_lisp_use_petr api_show_one_use_petr
15709
15710 /**
15711  * Add/delete mapping between vni and vrf
15712  */
15713 static int
15714 api_one_eid_table_add_del_map (vat_main_t * vam)
15715 {
15716   unformat_input_t *input = vam->input;
15717   vl_api_one_eid_table_add_del_map_t *mp;
15718   u8 is_add = 1, vni_set = 0, vrf_set = 0, bd_index_set = 0;
15719   u32 vni, vrf, bd_index;
15720   int ret;
15721
15722   /* Parse args required to build the message */
15723   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15724     {
15725       if (unformat (input, "del"))
15726         is_add = 0;
15727       else if (unformat (input, "vrf %d", &vrf))
15728         vrf_set = 1;
15729       else if (unformat (input, "bd_index %d", &bd_index))
15730         bd_index_set = 1;
15731       else if (unformat (input, "vni %d", &vni))
15732         vni_set = 1;
15733       else
15734         break;
15735     }
15736
15737   if (!vni_set || (!vrf_set && !bd_index_set))
15738     {
15739       errmsg ("missing arguments!");
15740       return -99;
15741     }
15742
15743   if (vrf_set && bd_index_set)
15744     {
15745       errmsg ("error: both vrf and bd entered!");
15746       return -99;
15747     }
15748
15749   M (ONE_EID_TABLE_ADD_DEL_MAP, mp);
15750
15751   mp->is_add = is_add;
15752   mp->vni = htonl (vni);
15753   mp->dp_table = vrf_set ? htonl (vrf) : htonl (bd_index);
15754   mp->is_l2 = bd_index_set;
15755
15756   /* send */
15757   S (mp);
15758
15759   /* wait for reply */
15760   W (ret);
15761   return ret;
15762 }
15763
15764 #define api_lisp_eid_table_add_del_map api_one_eid_table_add_del_map
15765
15766 uword
15767 unformat_negative_mapping_action (unformat_input_t * input, va_list * args)
15768 {
15769   u32 *action = va_arg (*args, u32 *);
15770   u8 *s = 0;
15771
15772   if (unformat (input, "%s", &s))
15773     {
15774       if (!strcmp ((char *) s, "no-action"))
15775         action[0] = 0;
15776       else if (!strcmp ((char *) s, "natively-forward"))
15777         action[0] = 1;
15778       else if (!strcmp ((char *) s, "send-map-request"))
15779         action[0] = 2;
15780       else if (!strcmp ((char *) s, "drop"))
15781         action[0] = 3;
15782       else
15783         {
15784           clib_warning ("invalid action: '%s'", s);
15785           action[0] = 3;
15786         }
15787     }
15788   else
15789     return 0;
15790
15791   vec_free (s);
15792   return 1;
15793 }
15794
15795 /**
15796  * Add/del remote mapping to/from ONE control plane
15797  *
15798  * @param vam vpp API test context
15799  * @return return code
15800  */
15801 static int
15802 api_one_add_del_remote_mapping (vat_main_t * vam)
15803 {
15804   unformat_input_t *input = vam->input;
15805   vl_api_one_add_del_remote_mapping_t *mp;
15806   u32 vni = 0;
15807   lisp_eid_vat_t _eid, *eid = &_eid;
15808   lisp_eid_vat_t _seid, *seid = &_seid;
15809   u8 is_add = 1, del_all = 0, eid_set = 0, seid_set = 0;
15810   u32 action = ~0, p, w, data_len;
15811   ip4_address_t rloc4;
15812   ip6_address_t rloc6;
15813   vl_api_remote_locator_t *rlocs = 0, rloc, *curr_rloc = 0;
15814   int ret;
15815
15816   clib_memset (&rloc, 0, sizeof (rloc));
15817
15818   /* Parse args required to build the message */
15819   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15820     {
15821       if (unformat (input, "del-all"))
15822         {
15823           del_all = 1;
15824         }
15825       else if (unformat (input, "del"))
15826         {
15827           is_add = 0;
15828         }
15829       else if (unformat (input, "add"))
15830         {
15831           is_add = 1;
15832         }
15833       else if (unformat (input, "eid %U", unformat_lisp_eid_vat, eid))
15834         {
15835           eid_set = 1;
15836         }
15837       else if (unformat (input, "seid %U", unformat_lisp_eid_vat, seid))
15838         {
15839           seid_set = 1;
15840         }
15841       else if (unformat (input, "vni %d", &vni))
15842         {
15843           ;
15844         }
15845       else if (unformat (input, "p %d w %d", &p, &w))
15846         {
15847           if (!curr_rloc)
15848             {
15849               errmsg ("No RLOC configured for setting priority/weight!");
15850               return -99;
15851             }
15852           curr_rloc->priority = p;
15853           curr_rloc->weight = w;
15854         }
15855       else if (unformat (input, "rloc %U", unformat_ip4_address, &rloc4))
15856         {
15857           rloc.is_ip4 = 1;
15858           clib_memcpy (&rloc.addr, &rloc4, sizeof (rloc4));
15859           vec_add1 (rlocs, rloc);
15860           curr_rloc = &rlocs[vec_len (rlocs) - 1];
15861         }
15862       else if (unformat (input, "rloc %U", unformat_ip6_address, &rloc6))
15863         {
15864           rloc.is_ip4 = 0;
15865           clib_memcpy (&rloc.addr, &rloc6, sizeof (rloc6));
15866           vec_add1 (rlocs, rloc);
15867           curr_rloc = &rlocs[vec_len (rlocs) - 1];
15868         }
15869       else if (unformat (input, "action %U",
15870                          unformat_negative_mapping_action, &action))
15871         {
15872           ;
15873         }
15874       else
15875         {
15876           clib_warning ("parse error '%U'", format_unformat_error, input);
15877           return -99;
15878         }
15879     }
15880
15881   if (0 == eid_set)
15882     {
15883       errmsg ("missing params!");
15884       return -99;
15885     }
15886
15887   if (is_add && (~0 == action) && 0 == vec_len (rlocs))
15888     {
15889       errmsg ("no action set for negative map-reply!");
15890       return -99;
15891     }
15892
15893   data_len = vec_len (rlocs) * sizeof (vl_api_remote_locator_t);
15894
15895   M2 (ONE_ADD_DEL_REMOTE_MAPPING, mp, data_len);
15896   mp->is_add = is_add;
15897   mp->vni = htonl (vni);
15898   mp->action = (u8) action;
15899   mp->is_src_dst = seid_set;
15900   mp->eid_len = eid->len;
15901   mp->seid_len = seid->len;
15902   mp->del_all = del_all;
15903   mp->eid_type = eid->type;
15904   lisp_eid_put_vat (mp->eid, eid->addr, eid->type);
15905   lisp_eid_put_vat (mp->seid, seid->addr, seid->type);
15906
15907   mp->rloc_num = clib_host_to_net_u32 (vec_len (rlocs));
15908   clib_memcpy (mp->rlocs, rlocs, data_len);
15909   vec_free (rlocs);
15910
15911   /* send it... */
15912   S (mp);
15913
15914   /* Wait for a reply... */
15915   W (ret);
15916   return ret;
15917 }
15918
15919 #define api_lisp_add_del_remote_mapping api_one_add_del_remote_mapping
15920
15921 /**
15922  * Add/del ONE adjacency. Saves mapping in ONE control plane and updates
15923  * forwarding entries in data-plane accordingly.
15924  *
15925  * @param vam vpp API test context
15926  * @return return code
15927  */
15928 static int
15929 api_one_add_del_adjacency (vat_main_t * vam)
15930 {
15931   unformat_input_t *input = vam->input;
15932   vl_api_one_add_del_adjacency_t *mp;
15933   u32 vni = 0;
15934   ip4_address_t leid4, reid4;
15935   ip6_address_t leid6, reid6;
15936   u8 reid_mac[6] = { 0 };
15937   u8 leid_mac[6] = { 0 };
15938   u8 reid_type, leid_type;
15939   u32 leid_len = 0, reid_len = 0, len;
15940   u8 is_add = 1;
15941   int ret;
15942
15943   leid_type = reid_type = (u8) ~ 0;
15944
15945   /* Parse args required to build the message */
15946   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
15947     {
15948       if (unformat (input, "del"))
15949         {
15950           is_add = 0;
15951         }
15952       else if (unformat (input, "add"))
15953         {
15954           is_add = 1;
15955         }
15956       else if (unformat (input, "reid %U/%d", unformat_ip4_address,
15957                          &reid4, &len))
15958         {
15959           reid_type = 0;        /* ipv4 */
15960           reid_len = len;
15961         }
15962       else if (unformat (input, "reid %U/%d", unformat_ip6_address,
15963                          &reid6, &len))
15964         {
15965           reid_type = 1;        /* ipv6 */
15966           reid_len = len;
15967         }
15968       else if (unformat (input, "reid %U", unformat_ethernet_address,
15969                          reid_mac))
15970         {
15971           reid_type = 2;        /* mac */
15972         }
15973       else if (unformat (input, "leid %U/%d", unformat_ip4_address,
15974                          &leid4, &len))
15975         {
15976           leid_type = 0;        /* ipv4 */
15977           leid_len = len;
15978         }
15979       else if (unformat (input, "leid %U/%d", unformat_ip6_address,
15980                          &leid6, &len))
15981         {
15982           leid_type = 1;        /* ipv6 */
15983           leid_len = len;
15984         }
15985       else if (unformat (input, "leid %U", unformat_ethernet_address,
15986                          leid_mac))
15987         {
15988           leid_type = 2;        /* mac */
15989         }
15990       else if (unformat (input, "vni %d", &vni))
15991         {
15992           ;
15993         }
15994       else
15995         {
15996           errmsg ("parse error '%U'", format_unformat_error, input);
15997           return -99;
15998         }
15999     }
16000
16001   if ((u8) ~ 0 == reid_type)
16002     {
16003       errmsg ("missing params!");
16004       return -99;
16005     }
16006
16007   if (leid_type != reid_type)
16008     {
16009       errmsg ("remote and local EIDs are of different types!");
16010       return -99;
16011     }
16012
16013   M (ONE_ADD_DEL_ADJACENCY, mp);
16014   mp->is_add = is_add;
16015   mp->vni = htonl (vni);
16016   mp->leid_len = leid_len;
16017   mp->reid_len = reid_len;
16018   mp->eid_type = reid_type;
16019
16020   switch (mp->eid_type)
16021     {
16022     case 0:
16023       clib_memcpy (mp->leid, &leid4, sizeof (leid4));
16024       clib_memcpy (mp->reid, &reid4, sizeof (reid4));
16025       break;
16026     case 1:
16027       clib_memcpy (mp->leid, &leid6, sizeof (leid6));
16028       clib_memcpy (mp->reid, &reid6, sizeof (reid6));
16029       break;
16030     case 2:
16031       clib_memcpy (mp->leid, leid_mac, 6);
16032       clib_memcpy (mp->reid, reid_mac, 6);
16033       break;
16034     default:
16035       errmsg ("unknown EID type %d!", mp->eid_type);
16036       return 0;
16037     }
16038
16039   /* send it... */
16040   S (mp);
16041
16042   /* Wait for a reply... */
16043   W (ret);
16044   return ret;
16045 }
16046
16047 #define api_lisp_add_del_adjacency api_one_add_del_adjacency
16048
16049 uword
16050 unformat_gpe_encap_mode (unformat_input_t * input, va_list * args)
16051 {
16052   u32 *mode = va_arg (*args, u32 *);
16053
16054   if (unformat (input, "lisp"))
16055     *mode = 0;
16056   else if (unformat (input, "vxlan"))
16057     *mode = 1;
16058   else
16059     return 0;
16060
16061   return 1;
16062 }
16063
16064 static int
16065 api_gpe_get_encap_mode (vat_main_t * vam)
16066 {
16067   vl_api_gpe_get_encap_mode_t *mp;
16068   int ret;
16069
16070   /* Construct the API message */
16071   M (GPE_GET_ENCAP_MODE, mp);
16072
16073   /* send it... */
16074   S (mp);
16075
16076   /* Wait for a reply... */
16077   W (ret);
16078   return ret;
16079 }
16080
16081 static int
16082 api_gpe_set_encap_mode (vat_main_t * vam)
16083 {
16084   unformat_input_t *input = vam->input;
16085   vl_api_gpe_set_encap_mode_t *mp;
16086   int ret;
16087   u32 mode = 0;
16088
16089   /* Parse args required to build the message */
16090   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16091     {
16092       if (unformat (input, "%U", unformat_gpe_encap_mode, &mode))
16093         ;
16094       else
16095         break;
16096     }
16097
16098   /* Construct the API message */
16099   M (GPE_SET_ENCAP_MODE, mp);
16100
16101   mp->mode = mode;
16102
16103   /* send it... */
16104   S (mp);
16105
16106   /* Wait for a reply... */
16107   W (ret);
16108   return ret;
16109 }
16110
16111 static int
16112 api_lisp_gpe_add_del_iface (vat_main_t * vam)
16113 {
16114   unformat_input_t *input = vam->input;
16115   vl_api_gpe_add_del_iface_t *mp;
16116   u8 action_set = 0, is_add = 1, is_l2 = 0, dp_table_set = 0, vni_set = 0;
16117   u32 dp_table = 0, vni = 0;
16118   int ret;
16119
16120   /* Parse args required to build the message */
16121   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16122     {
16123       if (unformat (input, "up"))
16124         {
16125           action_set = 1;
16126           is_add = 1;
16127         }
16128       else if (unformat (input, "down"))
16129         {
16130           action_set = 1;
16131           is_add = 0;
16132         }
16133       else if (unformat (input, "table_id %d", &dp_table))
16134         {
16135           dp_table_set = 1;
16136         }
16137       else if (unformat (input, "bd_id %d", &dp_table))
16138         {
16139           dp_table_set = 1;
16140           is_l2 = 1;
16141         }
16142       else if (unformat (input, "vni %d", &vni))
16143         {
16144           vni_set = 1;
16145         }
16146       else
16147         break;
16148     }
16149
16150   if (action_set == 0)
16151     {
16152       errmsg ("Action not set");
16153       return -99;
16154     }
16155   if (dp_table_set == 0 || vni_set == 0)
16156     {
16157       errmsg ("vni and dp_table must be set");
16158       return -99;
16159     }
16160
16161   /* Construct the API message */
16162   M (GPE_ADD_DEL_IFACE, mp);
16163
16164   mp->is_add = is_add;
16165   mp->dp_table = clib_host_to_net_u32 (dp_table);
16166   mp->is_l2 = is_l2;
16167   mp->vni = clib_host_to_net_u32 (vni);
16168
16169   /* send it... */
16170   S (mp);
16171
16172   /* Wait for a reply... */
16173   W (ret);
16174   return ret;
16175 }
16176
16177 static int
16178 api_one_map_register_fallback_threshold (vat_main_t * vam)
16179 {
16180   unformat_input_t *input = vam->input;
16181   vl_api_one_map_register_fallback_threshold_t *mp;
16182   u32 value = 0;
16183   u8 is_set = 0;
16184   int ret;
16185
16186   /* Parse args required to build the message */
16187   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16188     {
16189       if (unformat (input, "%u", &value))
16190         is_set = 1;
16191       else
16192         {
16193           clib_warning ("parse error '%U'", format_unformat_error, input);
16194           return -99;
16195         }
16196     }
16197
16198   if (!is_set)
16199     {
16200       errmsg ("fallback threshold value is missing!");
16201       return -99;
16202     }
16203
16204   M (ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
16205   mp->value = clib_host_to_net_u32 (value);
16206
16207   /* send it... */
16208   S (mp);
16209
16210   /* Wait for a reply... */
16211   W (ret);
16212   return ret;
16213 }
16214
16215 static int
16216 api_show_one_map_register_fallback_threshold (vat_main_t * vam)
16217 {
16218   vl_api_show_one_map_register_fallback_threshold_t *mp;
16219   int ret;
16220
16221   M (SHOW_ONE_MAP_REGISTER_FALLBACK_THRESHOLD, mp);
16222
16223   /* send it... */
16224   S (mp);
16225
16226   /* Wait for a reply... */
16227   W (ret);
16228   return ret;
16229 }
16230
16231 uword
16232 unformat_lisp_transport_protocol (unformat_input_t * input, va_list * args)
16233 {
16234   u32 *proto = va_arg (*args, u32 *);
16235
16236   if (unformat (input, "udp"))
16237     *proto = 1;
16238   else if (unformat (input, "api"))
16239     *proto = 2;
16240   else
16241     return 0;
16242
16243   return 1;
16244 }
16245
16246 static int
16247 api_one_set_transport_protocol (vat_main_t * vam)
16248 {
16249   unformat_input_t *input = vam->input;
16250   vl_api_one_set_transport_protocol_t *mp;
16251   u8 is_set = 0;
16252   u32 protocol = 0;
16253   int ret;
16254
16255   /* Parse args required to build the message */
16256   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16257     {
16258       if (unformat (input, "%U", unformat_lisp_transport_protocol, &protocol))
16259         is_set = 1;
16260       else
16261         {
16262           clib_warning ("parse error '%U'", format_unformat_error, input);
16263           return -99;
16264         }
16265     }
16266
16267   if (!is_set)
16268     {
16269       errmsg ("Transport protocol missing!");
16270       return -99;
16271     }
16272
16273   M (ONE_SET_TRANSPORT_PROTOCOL, mp);
16274   mp->protocol = (u8) protocol;
16275
16276   /* send it... */
16277   S (mp);
16278
16279   /* Wait for a reply... */
16280   W (ret);
16281   return ret;
16282 }
16283
16284 static int
16285 api_one_get_transport_protocol (vat_main_t * vam)
16286 {
16287   vl_api_one_get_transport_protocol_t *mp;
16288   int ret;
16289
16290   M (ONE_GET_TRANSPORT_PROTOCOL, mp);
16291
16292   /* send it... */
16293   S (mp);
16294
16295   /* Wait for a reply... */
16296   W (ret);
16297   return ret;
16298 }
16299
16300 static int
16301 api_one_map_register_set_ttl (vat_main_t * vam)
16302 {
16303   unformat_input_t *input = vam->input;
16304   vl_api_one_map_register_set_ttl_t *mp;
16305   u32 ttl = 0;
16306   u8 is_set = 0;
16307   int ret;
16308
16309   /* Parse args required to build the message */
16310   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16311     {
16312       if (unformat (input, "%u", &ttl))
16313         is_set = 1;
16314       else
16315         {
16316           clib_warning ("parse error '%U'", format_unformat_error, input);
16317           return -99;
16318         }
16319     }
16320
16321   if (!is_set)
16322     {
16323       errmsg ("TTL value missing!");
16324       return -99;
16325     }
16326
16327   M (ONE_MAP_REGISTER_SET_TTL, mp);
16328   mp->ttl = clib_host_to_net_u32 (ttl);
16329
16330   /* send it... */
16331   S (mp);
16332
16333   /* Wait for a reply... */
16334   W (ret);
16335   return ret;
16336 }
16337
16338 static int
16339 api_show_one_map_register_ttl (vat_main_t * vam)
16340 {
16341   vl_api_show_one_map_register_ttl_t *mp;
16342   int ret;
16343
16344   M (SHOW_ONE_MAP_REGISTER_TTL, mp);
16345
16346   /* send it... */
16347   S (mp);
16348
16349   /* Wait for a reply... */
16350   W (ret);
16351   return ret;
16352 }
16353
16354 /**
16355  * Add/del map request itr rlocs from ONE control plane and updates
16356  *
16357  * @param vam vpp API test context
16358  * @return return code
16359  */
16360 static int
16361 api_one_add_del_map_request_itr_rlocs (vat_main_t * vam)
16362 {
16363   unformat_input_t *input = vam->input;
16364   vl_api_one_add_del_map_request_itr_rlocs_t *mp;
16365   u8 *locator_set_name = 0;
16366   u8 locator_set_name_set = 0;
16367   u8 is_add = 1;
16368   int ret;
16369
16370   /* Parse args required to build the message */
16371   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16372     {
16373       if (unformat (input, "del"))
16374         {
16375           is_add = 0;
16376         }
16377       else if (unformat (input, "%_%v%_", &locator_set_name))
16378         {
16379           locator_set_name_set = 1;
16380         }
16381       else
16382         {
16383           clib_warning ("parse error '%U'", format_unformat_error, input);
16384           return -99;
16385         }
16386     }
16387
16388   if (is_add && !locator_set_name_set)
16389     {
16390       errmsg ("itr-rloc is not set!");
16391       return -99;
16392     }
16393
16394   if (is_add && vec_len (locator_set_name) > 64)
16395     {
16396       errmsg ("itr-rloc locator-set name too long");
16397       vec_free (locator_set_name);
16398       return -99;
16399     }
16400
16401   M (ONE_ADD_DEL_MAP_REQUEST_ITR_RLOCS, mp);
16402   mp->is_add = is_add;
16403   if (is_add)
16404     {
16405       clib_memcpy (mp->locator_set_name, locator_set_name,
16406                    vec_len (locator_set_name));
16407     }
16408   else
16409     {
16410       clib_memset (mp->locator_set_name, 0, sizeof (mp->locator_set_name));
16411     }
16412   vec_free (locator_set_name);
16413
16414   /* send it... */
16415   S (mp);
16416
16417   /* Wait for a reply... */
16418   W (ret);
16419   return ret;
16420 }
16421
16422 #define api_lisp_add_del_map_request_itr_rlocs api_one_add_del_map_request_itr_rlocs
16423
16424 static int
16425 api_one_locator_dump (vat_main_t * vam)
16426 {
16427   unformat_input_t *input = vam->input;
16428   vl_api_one_locator_dump_t *mp;
16429   vl_api_control_ping_t *mp_ping;
16430   u8 is_index_set = 0, is_name_set = 0;
16431   u8 *ls_name = 0;
16432   u32 ls_index = ~0;
16433   int ret;
16434
16435   /* Parse args required to build the message */
16436   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16437     {
16438       if (unformat (input, "ls_name %_%v%_", &ls_name))
16439         {
16440           is_name_set = 1;
16441         }
16442       else if (unformat (input, "ls_index %d", &ls_index))
16443         {
16444           is_index_set = 1;
16445         }
16446       else
16447         {
16448           errmsg ("parse error '%U'", format_unformat_error, input);
16449           return -99;
16450         }
16451     }
16452
16453   if (!is_index_set && !is_name_set)
16454     {
16455       errmsg ("error: expected one of index or name!");
16456       return -99;
16457     }
16458
16459   if (is_index_set && is_name_set)
16460     {
16461       errmsg ("error: only one param expected!");
16462       return -99;
16463     }
16464
16465   if (vec_len (ls_name) > 62)
16466     {
16467       errmsg ("error: locator set name too long!");
16468       return -99;
16469     }
16470
16471   if (!vam->json_output)
16472     {
16473       print (vam->ofp, "%=16s%=16s%=16s", "locator", "priority", "weight");
16474     }
16475
16476   M (ONE_LOCATOR_DUMP, mp);
16477   mp->is_index_set = is_index_set;
16478
16479   if (is_index_set)
16480     mp->ls_index = clib_host_to_net_u32 (ls_index);
16481   else
16482     {
16483       vec_add1 (ls_name, 0);
16484       strncpy ((char *) mp->ls_name, (char *) ls_name,
16485                sizeof (mp->ls_name) - 1);
16486     }
16487
16488   /* send it... */
16489   S (mp);
16490
16491   /* Use a control ping for synchronization */
16492   MPING (CONTROL_PING, mp_ping);
16493   S (mp_ping);
16494
16495   /* Wait for a reply... */
16496   W (ret);
16497   return ret;
16498 }
16499
16500 #define api_lisp_locator_dump api_one_locator_dump
16501
16502 static int
16503 api_one_locator_set_dump (vat_main_t * vam)
16504 {
16505   vl_api_one_locator_set_dump_t *mp;
16506   vl_api_control_ping_t *mp_ping;
16507   unformat_input_t *input = vam->input;
16508   u8 filter = 0;
16509   int ret;
16510
16511   /* Parse args required to build the message */
16512   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16513     {
16514       if (unformat (input, "local"))
16515         {
16516           filter = 1;
16517         }
16518       else if (unformat (input, "remote"))
16519         {
16520           filter = 2;
16521         }
16522       else
16523         {
16524           errmsg ("parse error '%U'", format_unformat_error, input);
16525           return -99;
16526         }
16527     }
16528
16529   if (!vam->json_output)
16530     {
16531       print (vam->ofp, "%=10s%=15s", "ls_index", "ls_name");
16532     }
16533
16534   M (ONE_LOCATOR_SET_DUMP, mp);
16535
16536   mp->filter = filter;
16537
16538   /* send it... */
16539   S (mp);
16540
16541   /* Use a control ping for synchronization */
16542   MPING (CONTROL_PING, mp_ping);
16543   S (mp_ping);
16544
16545   /* Wait for a reply... */
16546   W (ret);
16547   return ret;
16548 }
16549
16550 #define api_lisp_locator_set_dump api_one_locator_set_dump
16551
16552 static int
16553 api_one_eid_table_map_dump (vat_main_t * vam)
16554 {
16555   u8 is_l2 = 0;
16556   u8 mode_set = 0;
16557   unformat_input_t *input = vam->input;
16558   vl_api_one_eid_table_map_dump_t *mp;
16559   vl_api_control_ping_t *mp_ping;
16560   int ret;
16561
16562   /* Parse args required to build the message */
16563   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
16564     {
16565       if (unformat (input, "l2"))
16566         {
16567           is_l2 = 1;
16568           mode_set = 1;
16569         }
16570       else if (unformat (input, "l3"))
16571         {
16572           is_l2 = 0;
16573           mode_set = 1;
16574         }
16575       else
16576         {
16577           errmsg ("parse error '%U'", format_unformat_error, input);
16578           return -99;
16579         }
16580     }
16581
16582   if (!mode_set)
16583     {
16584       errmsg ("expected one of 'l2' or 'l3' parameter!");
16585       return -99;
16586     }
16587
16588   if (!vam->json_output)
16589     {
16590       print (vam->ofp, "%=10s%=10s", "VNI", is_l2 ? "BD" : "VRF");
16591     }
16592
16593   M (ONE_EID_TABLE_MAP_DUMP, mp);
16594   mp->is_l2 = is_l2;
16595
16596   /* send it... */
16597   S (mp);
16598
16599   /* Use a control ping for synchronization */
16600   MPING (CONTROL_PING, mp_ping);
16601   S (mp_ping);
16602
16603   /* Wait for a reply... */
16604   W (ret);
16605   return ret;
16606 }
16607
16608 #define api_lisp_eid_table_map_dump api_one_eid_table_map_dump
16609
16610 static int
16611 api_one_eid_table_vni_dump (vat_main_t * vam)
16612 {
16613   vl_api_one_eid_table_vni_dump_t *mp;
16614   vl_api_control_ping_t *mp_ping;
16615   int ret;
16616
16617   if (!vam->json_output)
16618     {
16619       print (vam->ofp, "VNI");
16620     }
16621
16622   M (ONE_EID_TABLE_VNI_DUMP, mp);
16623
16624   /* send it... */
16625   S (mp);
16626
16627   /* Use a control ping for synchronization */
16628   MPING (CONTROL_PING, mp_ping);
16629   S (mp_ping);
16630
16631   /* Wait for a reply... */
16632   W (ret);
16633   return ret;
16634 }
16635
16636 #define api_lisp_eid_table_vni_dump api_one_eid_table_vni_dump
16637
16638 static int
16639 api_one_eid_table_dump (vat_main_t * vam)
16640 {
16641   unformat_input_t *i = vam->input;
16642   vl_api_one_eid_table_dump_t *mp;
16643   vl_api_control_ping_t *mp_ping;
16644   struct in_addr ip4;
16645   struct in6_addr ip6;
16646   u8 mac[6];
16647   u8 eid_type = ~0, eid_set = 0;
16648   u32 prefix_length = ~0, t, vni = 0;
16649   u8 filter = 0;
16650   int ret;
16651   lisp_nsh_api_t nsh;
16652
16653   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16654     {
16655       if (unformat (i, "eid %U/%d", unformat_ip4_address, &ip4, &t))
16656         {
16657           eid_set = 1;
16658           eid_type = 0;
16659           prefix_length = t;
16660         }
16661       else if (unformat (i, "eid %U/%d", unformat_ip6_address, &ip6, &t))
16662         {
16663           eid_set = 1;
16664           eid_type = 1;
16665           prefix_length = t;
16666         }
16667       else if (unformat (i, "eid %U", unformat_ethernet_address, mac))
16668         {
16669           eid_set = 1;
16670           eid_type = 2;
16671         }
16672       else if (unformat (i, "eid %U", unformat_nsh_address, &nsh))
16673         {
16674           eid_set = 1;
16675           eid_type = 3;
16676         }
16677       else if (unformat (i, "vni %d", &t))
16678         {
16679           vni = t;
16680         }
16681       else if (unformat (i, "local"))
16682         {
16683           filter = 1;
16684         }
16685       else if (unformat (i, "remote"))
16686         {
16687           filter = 2;
16688         }
16689       else
16690         {
16691           errmsg ("parse error '%U'", format_unformat_error, i);
16692           return -99;
16693         }
16694     }
16695
16696   if (!vam->json_output)
16697     {
16698       print (vam->ofp, "%-35s%-20s%-30s%-20s%-20s%-10s%-20s", "EID",
16699              "type", "ls_index", "ttl", "authoritative", "key_id", "key");
16700     }
16701
16702   M (ONE_EID_TABLE_DUMP, mp);
16703
16704   mp->filter = filter;
16705   if (eid_set)
16706     {
16707       mp->eid_set = 1;
16708       mp->vni = htonl (vni);
16709       mp->eid_type = eid_type;
16710       switch (eid_type)
16711         {
16712         case 0:
16713           mp->prefix_length = prefix_length;
16714           clib_memcpy (mp->eid, &ip4, sizeof (ip4));
16715           break;
16716         case 1:
16717           mp->prefix_length = prefix_length;
16718           clib_memcpy (mp->eid, &ip6, sizeof (ip6));
16719           break;
16720         case 2:
16721           clib_memcpy (mp->eid, mac, sizeof (mac));
16722           break;
16723         case 3:
16724           clib_memcpy (mp->eid, &nsh, sizeof (nsh));
16725           break;
16726         default:
16727           errmsg ("unknown EID type %d!", eid_type);
16728           return -99;
16729         }
16730     }
16731
16732   /* send it... */
16733   S (mp);
16734
16735   /* Use a control ping for synchronization */
16736   MPING (CONTROL_PING, mp_ping);
16737   S (mp_ping);
16738
16739   /* Wait for a reply... */
16740   W (ret);
16741   return ret;
16742 }
16743
16744 #define api_lisp_eid_table_dump api_one_eid_table_dump
16745
16746 static int
16747 api_lisp_gpe_fwd_entries_get (vat_main_t * vam)
16748 {
16749   unformat_input_t *i = vam->input;
16750   vl_api_gpe_fwd_entries_get_t *mp;
16751   u8 vni_set = 0;
16752   u32 vni = ~0;
16753   int ret;
16754
16755   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16756     {
16757       if (unformat (i, "vni %d", &vni))
16758         {
16759           vni_set = 1;
16760         }
16761       else
16762         {
16763           errmsg ("parse error '%U'", format_unformat_error, i);
16764           return -99;
16765         }
16766     }
16767
16768   if (!vni_set)
16769     {
16770       errmsg ("vni not set!");
16771       return -99;
16772     }
16773
16774   if (!vam->json_output)
16775     {
16776       print (vam->ofp, "%10s %10s %s %40s", "fwd_index", "dp_table",
16777              "leid", "reid");
16778     }
16779
16780   M (GPE_FWD_ENTRIES_GET, mp);
16781   mp->vni = clib_host_to_net_u32 (vni);
16782
16783   /* send it... */
16784   S (mp);
16785
16786   /* Wait for a reply... */
16787   W (ret);
16788   return ret;
16789 }
16790
16791 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_endian vl_noop_handler
16792 #define vl_api_gpe_native_fwd_rpaths_get_reply_t_print vl_noop_handler
16793 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_endian vl_noop_handler
16794 #define vl_api_gpe_fwd_entry_vnis_get_reply_t_print vl_noop_handler
16795 #define vl_api_gpe_fwd_entries_get_reply_t_endian vl_noop_handler
16796 #define vl_api_gpe_fwd_entries_get_reply_t_print vl_noop_handler
16797 #define vl_api_gpe_fwd_entry_path_details_t_endian vl_noop_handler
16798 #define vl_api_gpe_fwd_entry_path_details_t_print vl_noop_handler
16799
16800 static int
16801 api_one_adjacencies_get (vat_main_t * vam)
16802 {
16803   unformat_input_t *i = vam->input;
16804   vl_api_one_adjacencies_get_t *mp;
16805   u8 vni_set = 0;
16806   u32 vni = ~0;
16807   int ret;
16808
16809   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16810     {
16811       if (unformat (i, "vni %d", &vni))
16812         {
16813           vni_set = 1;
16814         }
16815       else
16816         {
16817           errmsg ("parse error '%U'", format_unformat_error, i);
16818           return -99;
16819         }
16820     }
16821
16822   if (!vni_set)
16823     {
16824       errmsg ("vni not set!");
16825       return -99;
16826     }
16827
16828   if (!vam->json_output)
16829     {
16830       print (vam->ofp, "%s %40s", "leid", "reid");
16831     }
16832
16833   M (ONE_ADJACENCIES_GET, mp);
16834   mp->vni = clib_host_to_net_u32 (vni);
16835
16836   /* send it... */
16837   S (mp);
16838
16839   /* Wait for a reply... */
16840   W (ret);
16841   return ret;
16842 }
16843
16844 #define api_lisp_adjacencies_get api_one_adjacencies_get
16845
16846 static int
16847 api_gpe_native_fwd_rpaths_get (vat_main_t * vam)
16848 {
16849   unformat_input_t *i = vam->input;
16850   vl_api_gpe_native_fwd_rpaths_get_t *mp;
16851   int ret;
16852   u8 ip_family_set = 0, is_ip4 = 1;
16853
16854   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16855     {
16856       if (unformat (i, "ip4"))
16857         {
16858           ip_family_set = 1;
16859           is_ip4 = 1;
16860         }
16861       else if (unformat (i, "ip6"))
16862         {
16863           ip_family_set = 1;
16864           is_ip4 = 0;
16865         }
16866       else
16867         {
16868           errmsg ("parse error '%U'", format_unformat_error, i);
16869           return -99;
16870         }
16871     }
16872
16873   if (!ip_family_set)
16874     {
16875       errmsg ("ip family not set!");
16876       return -99;
16877     }
16878
16879   M (GPE_NATIVE_FWD_RPATHS_GET, mp);
16880   mp->is_ip4 = is_ip4;
16881
16882   /* send it... */
16883   S (mp);
16884
16885   /* Wait for a reply... */
16886   W (ret);
16887   return ret;
16888 }
16889
16890 static int
16891 api_gpe_fwd_entry_vnis_get (vat_main_t * vam)
16892 {
16893   vl_api_gpe_fwd_entry_vnis_get_t *mp;
16894   int ret;
16895
16896   if (!vam->json_output)
16897     {
16898       print (vam->ofp, "VNIs");
16899     }
16900
16901   M (GPE_FWD_ENTRY_VNIS_GET, mp);
16902
16903   /* send it... */
16904   S (mp);
16905
16906   /* Wait for a reply... */
16907   W (ret);
16908   return ret;
16909 }
16910
16911 static int
16912 api_gpe_add_del_native_fwd_rpath (vat_main_t * vam)
16913 {
16914   unformat_input_t *i = vam->input;
16915   vl_api_gpe_add_del_native_fwd_rpath_t *mp;
16916   int ret = 0;
16917   u8 is_add = 1, ip_set = 0, is_ip4 = 1;
16918   struct in_addr ip4;
16919   struct in6_addr ip6;
16920   u32 table_id = 0, nh_sw_if_index = ~0;
16921
16922   clib_memset (&ip4, 0, sizeof (ip4));
16923   clib_memset (&ip6, 0, sizeof (ip6));
16924
16925   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
16926     {
16927       if (unformat (i, "del"))
16928         is_add = 0;
16929       else if (unformat (i, "via %U %U", unformat_ip4_address, &ip4,
16930                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
16931         {
16932           ip_set = 1;
16933           is_ip4 = 1;
16934         }
16935       else if (unformat (i, "via %U %U", unformat_ip6_address, &ip6,
16936                          api_unformat_sw_if_index, vam, &nh_sw_if_index))
16937         {
16938           ip_set = 1;
16939           is_ip4 = 0;
16940         }
16941       else if (unformat (i, "via %U", unformat_ip4_address, &ip4))
16942         {
16943           ip_set = 1;
16944           is_ip4 = 1;
16945           nh_sw_if_index = ~0;
16946         }
16947       else if (unformat (i, "via %U", unformat_ip6_address, &ip6))
16948         {
16949           ip_set = 1;
16950           is_ip4 = 0;
16951           nh_sw_if_index = ~0;
16952         }
16953       else if (unformat (i, "table %d", &table_id))
16954         ;
16955       else
16956         {
16957           errmsg ("parse error '%U'", format_unformat_error, i);
16958           return -99;
16959         }
16960     }
16961
16962   if (!ip_set)
16963     {
16964       errmsg ("nh addr not set!");
16965       return -99;
16966     }
16967
16968   M (GPE_ADD_DEL_NATIVE_FWD_RPATH, mp);
16969   mp->is_add = is_add;
16970   mp->table_id = clib_host_to_net_u32 (table_id);
16971   mp->nh_sw_if_index = clib_host_to_net_u32 (nh_sw_if_index);
16972   mp->is_ip4 = is_ip4;
16973   if (is_ip4)
16974     clib_memcpy (mp->nh_addr, &ip4, sizeof (ip4));
16975   else
16976     clib_memcpy (mp->nh_addr, &ip6, sizeof (ip6));
16977
16978   /* send it... */
16979   S (mp);
16980
16981   /* Wait for a reply... */
16982   W (ret);
16983   return ret;
16984 }
16985
16986 static int
16987 api_one_map_server_dump (vat_main_t * vam)
16988 {
16989   vl_api_one_map_server_dump_t *mp;
16990   vl_api_control_ping_t *mp_ping;
16991   int ret;
16992
16993   if (!vam->json_output)
16994     {
16995       print (vam->ofp, "%=20s", "Map server");
16996     }
16997
16998   M (ONE_MAP_SERVER_DUMP, mp);
16999   /* send it... */
17000   S (mp);
17001
17002   /* Use a control ping for synchronization */
17003   MPING (CONTROL_PING, mp_ping);
17004   S (mp_ping);
17005
17006   /* Wait for a reply... */
17007   W (ret);
17008   return ret;
17009 }
17010
17011 #define api_lisp_map_server_dump api_one_map_server_dump
17012
17013 static int
17014 api_one_map_resolver_dump (vat_main_t * vam)
17015 {
17016   vl_api_one_map_resolver_dump_t *mp;
17017   vl_api_control_ping_t *mp_ping;
17018   int ret;
17019
17020   if (!vam->json_output)
17021     {
17022       print (vam->ofp, "%=20s", "Map resolver");
17023     }
17024
17025   M (ONE_MAP_RESOLVER_DUMP, mp);
17026   /* send it... */
17027   S (mp);
17028
17029   /* Use a control ping for synchronization */
17030   MPING (CONTROL_PING, mp_ping);
17031   S (mp_ping);
17032
17033   /* Wait for a reply... */
17034   W (ret);
17035   return ret;
17036 }
17037
17038 #define api_lisp_map_resolver_dump api_one_map_resolver_dump
17039
17040 static int
17041 api_one_stats_flush (vat_main_t * vam)
17042 {
17043   vl_api_one_stats_flush_t *mp;
17044   int ret = 0;
17045
17046   M (ONE_STATS_FLUSH, mp);
17047   S (mp);
17048   W (ret);
17049   return ret;
17050 }
17051
17052 static int
17053 api_one_stats_dump (vat_main_t * vam)
17054 {
17055   vl_api_one_stats_dump_t *mp;
17056   vl_api_control_ping_t *mp_ping;
17057   int ret;
17058
17059   M (ONE_STATS_DUMP, mp);
17060   /* send it... */
17061   S (mp);
17062
17063   /* Use a control ping for synchronization */
17064   MPING (CONTROL_PING, mp_ping);
17065   S (mp_ping);
17066
17067   /* Wait for a reply... */
17068   W (ret);
17069   return ret;
17070 }
17071
17072 static int
17073 api_show_one_status (vat_main_t * vam)
17074 {
17075   vl_api_show_one_status_t *mp;
17076   int ret;
17077
17078   if (!vam->json_output)
17079     {
17080       print (vam->ofp, "%-20s%-16s", "ONE status", "locator-set");
17081     }
17082
17083   M (SHOW_ONE_STATUS, mp);
17084   /* send it... */
17085   S (mp);
17086   /* Wait for a reply... */
17087   W (ret);
17088   return ret;
17089 }
17090
17091 #define api_show_lisp_status api_show_one_status
17092
17093 static int
17094 api_lisp_gpe_fwd_entry_path_dump (vat_main_t * vam)
17095 {
17096   vl_api_gpe_fwd_entry_path_dump_t *mp;
17097   vl_api_control_ping_t *mp_ping;
17098   unformat_input_t *i = vam->input;
17099   u32 fwd_entry_index = ~0;
17100   int ret;
17101
17102   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17103     {
17104       if (unformat (i, "index %d", &fwd_entry_index))
17105         ;
17106       else
17107         break;
17108     }
17109
17110   if (~0 == fwd_entry_index)
17111     {
17112       errmsg ("no index specified!");
17113       return -99;
17114     }
17115
17116   if (!vam->json_output)
17117     {
17118       print (vam->ofp, "first line");
17119     }
17120
17121   M (GPE_FWD_ENTRY_PATH_DUMP, mp);
17122
17123   /* send it... */
17124   S (mp);
17125   /* Use a control ping for synchronization */
17126   MPING (CONTROL_PING, mp_ping);
17127   S (mp_ping);
17128
17129   /* Wait for a reply... */
17130   W (ret);
17131   return ret;
17132 }
17133
17134 static int
17135 api_one_get_map_request_itr_rlocs (vat_main_t * vam)
17136 {
17137   vl_api_one_get_map_request_itr_rlocs_t *mp;
17138   int ret;
17139
17140   if (!vam->json_output)
17141     {
17142       print (vam->ofp, "%=20s", "itr-rlocs:");
17143     }
17144
17145   M (ONE_GET_MAP_REQUEST_ITR_RLOCS, mp);
17146   /* send it... */
17147   S (mp);
17148   /* Wait for a reply... */
17149   W (ret);
17150   return ret;
17151 }
17152
17153 #define api_lisp_get_map_request_itr_rlocs api_one_get_map_request_itr_rlocs
17154
17155 static int
17156 api_af_packet_create (vat_main_t * vam)
17157 {
17158   unformat_input_t *i = vam->input;
17159   vl_api_af_packet_create_t *mp;
17160   u8 *host_if_name = 0;
17161   u8 hw_addr[6];
17162   u8 random_hw_addr = 1;
17163   int ret;
17164
17165   clib_memset (hw_addr, 0, sizeof (hw_addr));
17166
17167   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17168     {
17169       if (unformat (i, "name %s", &host_if_name))
17170         vec_add1 (host_if_name, 0);
17171       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
17172         random_hw_addr = 0;
17173       else
17174         break;
17175     }
17176
17177   if (!vec_len (host_if_name))
17178     {
17179       errmsg ("host-interface name must be specified");
17180       return -99;
17181     }
17182
17183   if (vec_len (host_if_name) > 64)
17184     {
17185       errmsg ("host-interface name too long");
17186       return -99;
17187     }
17188
17189   M (AF_PACKET_CREATE, mp);
17190
17191   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
17192   clib_memcpy (mp->hw_addr, hw_addr, 6);
17193   mp->use_random_hw_addr = random_hw_addr;
17194   vec_free (host_if_name);
17195
17196   S (mp);
17197
17198   /* *INDENT-OFF* */
17199   W2 (ret,
17200       ({
17201         if (ret == 0)
17202           fprintf (vam->ofp ? vam->ofp : stderr,
17203                    " new sw_if_index = %d\n", vam->sw_if_index);
17204       }));
17205   /* *INDENT-ON* */
17206   return ret;
17207 }
17208
17209 static int
17210 api_af_packet_delete (vat_main_t * vam)
17211 {
17212   unformat_input_t *i = vam->input;
17213   vl_api_af_packet_delete_t *mp;
17214   u8 *host_if_name = 0;
17215   int ret;
17216
17217   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17218     {
17219       if (unformat (i, "name %s", &host_if_name))
17220         vec_add1 (host_if_name, 0);
17221       else
17222         break;
17223     }
17224
17225   if (!vec_len (host_if_name))
17226     {
17227       errmsg ("host-interface name must be specified");
17228       return -99;
17229     }
17230
17231   if (vec_len (host_if_name) > 64)
17232     {
17233       errmsg ("host-interface name too long");
17234       return -99;
17235     }
17236
17237   M (AF_PACKET_DELETE, mp);
17238
17239   clib_memcpy (mp->host_if_name, host_if_name, vec_len (host_if_name));
17240   vec_free (host_if_name);
17241
17242   S (mp);
17243   W (ret);
17244   return ret;
17245 }
17246
17247 static void vl_api_af_packet_details_t_handler
17248   (vl_api_af_packet_details_t * mp)
17249 {
17250   vat_main_t *vam = &vat_main;
17251
17252   print (vam->ofp, "%-16s %d",
17253          mp->host_if_name, clib_net_to_host_u32 (mp->sw_if_index));
17254 }
17255
17256 static void vl_api_af_packet_details_t_handler_json
17257   (vl_api_af_packet_details_t * mp)
17258 {
17259   vat_main_t *vam = &vat_main;
17260   vat_json_node_t *node = NULL;
17261
17262   if (VAT_JSON_ARRAY != vam->json_tree.type)
17263     {
17264       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17265       vat_json_init_array (&vam->json_tree);
17266     }
17267   node = vat_json_array_add (&vam->json_tree);
17268
17269   vat_json_init_object (node);
17270   vat_json_object_add_uint (node, "sw_if_index", ntohl (mp->sw_if_index));
17271   vat_json_object_add_string_copy (node, "dev_name", mp->host_if_name);
17272 }
17273
17274 static int
17275 api_af_packet_dump (vat_main_t * vam)
17276 {
17277   vl_api_af_packet_dump_t *mp;
17278   vl_api_control_ping_t *mp_ping;
17279   int ret;
17280
17281   print (vam->ofp, "\n%-16s %s", "dev_name", "sw_if_index");
17282   /* Get list of tap interfaces */
17283   M (AF_PACKET_DUMP, mp);
17284   S (mp);
17285
17286   /* Use a control ping for synchronization */
17287   MPING (CONTROL_PING, mp_ping);
17288   S (mp_ping);
17289
17290   W (ret);
17291   return ret;
17292 }
17293
17294 static int
17295 api_policer_add_del (vat_main_t * vam)
17296 {
17297   unformat_input_t *i = vam->input;
17298   vl_api_policer_add_del_t *mp;
17299   u8 is_add = 1;
17300   u8 *name = 0;
17301   u32 cir = 0;
17302   u32 eir = 0;
17303   u64 cb = 0;
17304   u64 eb = 0;
17305   u8 rate_type = 0;
17306   u8 round_type = 0;
17307   u8 type = 0;
17308   u8 color_aware = 0;
17309   sse2_qos_pol_action_params_st conform_action, exceed_action, violate_action;
17310   int ret;
17311
17312   conform_action.action_type = SSE2_QOS_ACTION_TRANSMIT;
17313   conform_action.dscp = 0;
17314   exceed_action.action_type = SSE2_QOS_ACTION_MARK_AND_TRANSMIT;
17315   exceed_action.dscp = 0;
17316   violate_action.action_type = SSE2_QOS_ACTION_DROP;
17317   violate_action.dscp = 0;
17318
17319   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17320     {
17321       if (unformat (i, "del"))
17322         is_add = 0;
17323       else if (unformat (i, "name %s", &name))
17324         vec_add1 (name, 0);
17325       else if (unformat (i, "cir %u", &cir))
17326         ;
17327       else if (unformat (i, "eir %u", &eir))
17328         ;
17329       else if (unformat (i, "cb %u", &cb))
17330         ;
17331       else if (unformat (i, "eb %u", &eb))
17332         ;
17333       else if (unformat (i, "rate_type %U", unformat_policer_rate_type,
17334                          &rate_type))
17335         ;
17336       else if (unformat (i, "round_type %U", unformat_policer_round_type,
17337                          &round_type))
17338         ;
17339       else if (unformat (i, "type %U", unformat_policer_type, &type))
17340         ;
17341       else if (unformat (i, "conform_action %U", unformat_policer_action_type,
17342                          &conform_action))
17343         ;
17344       else if (unformat (i, "exceed_action %U", unformat_policer_action_type,
17345                          &exceed_action))
17346         ;
17347       else if (unformat (i, "violate_action %U", unformat_policer_action_type,
17348                          &violate_action))
17349         ;
17350       else if (unformat (i, "color-aware"))
17351         color_aware = 1;
17352       else
17353         break;
17354     }
17355
17356   if (!vec_len (name))
17357     {
17358       errmsg ("policer name must be specified");
17359       return -99;
17360     }
17361
17362   if (vec_len (name) > 64)
17363     {
17364       errmsg ("policer name too long");
17365       return -99;
17366     }
17367
17368   M (POLICER_ADD_DEL, mp);
17369
17370   clib_memcpy (mp->name, name, vec_len (name));
17371   vec_free (name);
17372   mp->is_add = is_add;
17373   mp->cir = ntohl (cir);
17374   mp->eir = ntohl (eir);
17375   mp->cb = clib_net_to_host_u64 (cb);
17376   mp->eb = clib_net_to_host_u64 (eb);
17377   mp->rate_type = rate_type;
17378   mp->round_type = round_type;
17379   mp->type = type;
17380   mp->conform_action_type = conform_action.action_type;
17381   mp->conform_dscp = conform_action.dscp;
17382   mp->exceed_action_type = exceed_action.action_type;
17383   mp->exceed_dscp = exceed_action.dscp;
17384   mp->violate_action_type = violate_action.action_type;
17385   mp->violate_dscp = violate_action.dscp;
17386   mp->color_aware = color_aware;
17387
17388   S (mp);
17389   W (ret);
17390   return ret;
17391 }
17392
17393 static int
17394 api_policer_dump (vat_main_t * vam)
17395 {
17396   unformat_input_t *i = vam->input;
17397   vl_api_policer_dump_t *mp;
17398   vl_api_control_ping_t *mp_ping;
17399   u8 *match_name = 0;
17400   u8 match_name_valid = 0;
17401   int ret;
17402
17403   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17404     {
17405       if (unformat (i, "name %s", &match_name))
17406         {
17407           vec_add1 (match_name, 0);
17408           match_name_valid = 1;
17409         }
17410       else
17411         break;
17412     }
17413
17414   M (POLICER_DUMP, mp);
17415   mp->match_name_valid = match_name_valid;
17416   clib_memcpy (mp->match_name, match_name, vec_len (match_name));
17417   vec_free (match_name);
17418   /* send it... */
17419   S (mp);
17420
17421   /* Use a control ping for synchronization */
17422   MPING (CONTROL_PING, mp_ping);
17423   S (mp_ping);
17424
17425   /* Wait for a reply... */
17426   W (ret);
17427   return ret;
17428 }
17429
17430 static int
17431 api_policer_classify_set_interface (vat_main_t * vam)
17432 {
17433   unformat_input_t *i = vam->input;
17434   vl_api_policer_classify_set_interface_t *mp;
17435   u32 sw_if_index;
17436   int sw_if_index_set;
17437   u32 ip4_table_index = ~0;
17438   u32 ip6_table_index = ~0;
17439   u32 l2_table_index = ~0;
17440   u8 is_add = 1;
17441   int ret;
17442
17443   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17444     {
17445       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
17446         sw_if_index_set = 1;
17447       else if (unformat (i, "sw_if_index %d", &sw_if_index))
17448         sw_if_index_set = 1;
17449       else if (unformat (i, "del"))
17450         is_add = 0;
17451       else if (unformat (i, "ip4-table %d", &ip4_table_index))
17452         ;
17453       else if (unformat (i, "ip6-table %d", &ip6_table_index))
17454         ;
17455       else if (unformat (i, "l2-table %d", &l2_table_index))
17456         ;
17457       else
17458         {
17459           clib_warning ("parse error '%U'", format_unformat_error, i);
17460           return -99;
17461         }
17462     }
17463
17464   if (sw_if_index_set == 0)
17465     {
17466       errmsg ("missing interface name or sw_if_index");
17467       return -99;
17468     }
17469
17470   M (POLICER_CLASSIFY_SET_INTERFACE, mp);
17471
17472   mp->sw_if_index = ntohl (sw_if_index);
17473   mp->ip4_table_index = ntohl (ip4_table_index);
17474   mp->ip6_table_index = ntohl (ip6_table_index);
17475   mp->l2_table_index = ntohl (l2_table_index);
17476   mp->is_add = is_add;
17477
17478   S (mp);
17479   W (ret);
17480   return ret;
17481 }
17482
17483 static int
17484 api_policer_classify_dump (vat_main_t * vam)
17485 {
17486   unformat_input_t *i = vam->input;
17487   vl_api_policer_classify_dump_t *mp;
17488   vl_api_control_ping_t *mp_ping;
17489   u8 type = POLICER_CLASSIFY_N_TABLES;
17490   int ret;
17491
17492   if (unformat (i, "type %U", unformat_policer_classify_table_type, &type))
17493     ;
17494   else
17495     {
17496       errmsg ("classify table type must be specified");
17497       return -99;
17498     }
17499
17500   if (!vam->json_output)
17501     {
17502       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
17503     }
17504
17505   M (POLICER_CLASSIFY_DUMP, mp);
17506   mp->type = type;
17507   /* send it... */
17508   S (mp);
17509
17510   /* Use a control ping for synchronization */
17511   MPING (CONTROL_PING, mp_ping);
17512   S (mp_ping);
17513
17514   /* Wait for a reply... */
17515   W (ret);
17516   return ret;
17517 }
17518
17519 static int
17520 api_netmap_create (vat_main_t * vam)
17521 {
17522   unformat_input_t *i = vam->input;
17523   vl_api_netmap_create_t *mp;
17524   u8 *if_name = 0;
17525   u8 hw_addr[6];
17526   u8 random_hw_addr = 1;
17527   u8 is_pipe = 0;
17528   u8 is_master = 0;
17529   int ret;
17530
17531   clib_memset (hw_addr, 0, sizeof (hw_addr));
17532
17533   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17534     {
17535       if (unformat (i, "name %s", &if_name))
17536         vec_add1 (if_name, 0);
17537       else if (unformat (i, "hw_addr %U", unformat_ethernet_address, hw_addr))
17538         random_hw_addr = 0;
17539       else if (unformat (i, "pipe"))
17540         is_pipe = 1;
17541       else if (unformat (i, "master"))
17542         is_master = 1;
17543       else if (unformat (i, "slave"))
17544         is_master = 0;
17545       else
17546         break;
17547     }
17548
17549   if (!vec_len (if_name))
17550     {
17551       errmsg ("interface name must be specified");
17552       return -99;
17553     }
17554
17555   if (vec_len (if_name) > 64)
17556     {
17557       errmsg ("interface name too long");
17558       return -99;
17559     }
17560
17561   M (NETMAP_CREATE, mp);
17562
17563   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
17564   clib_memcpy (mp->hw_addr, hw_addr, 6);
17565   mp->use_random_hw_addr = random_hw_addr;
17566   mp->is_pipe = is_pipe;
17567   mp->is_master = is_master;
17568   vec_free (if_name);
17569
17570   S (mp);
17571   W (ret);
17572   return ret;
17573 }
17574
17575 static int
17576 api_netmap_delete (vat_main_t * vam)
17577 {
17578   unformat_input_t *i = vam->input;
17579   vl_api_netmap_delete_t *mp;
17580   u8 *if_name = 0;
17581   int ret;
17582
17583   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
17584     {
17585       if (unformat (i, "name %s", &if_name))
17586         vec_add1 (if_name, 0);
17587       else
17588         break;
17589     }
17590
17591   if (!vec_len (if_name))
17592     {
17593       errmsg ("interface name must be specified");
17594       return -99;
17595     }
17596
17597   if (vec_len (if_name) > 64)
17598     {
17599       errmsg ("interface name too long");
17600       return -99;
17601     }
17602
17603   M (NETMAP_DELETE, mp);
17604
17605   clib_memcpy (mp->netmap_if_name, if_name, vec_len (if_name));
17606   vec_free (if_name);
17607
17608   S (mp);
17609   W (ret);
17610   return ret;
17611 }
17612
17613 static u8 *
17614 format_fib_api_path_nh_proto (u8 * s, va_list * args)
17615 {
17616   vl_api_fib_path_nh_proto_t proto =
17617     va_arg (*args, vl_api_fib_path_nh_proto_t);
17618
17619   switch (proto)
17620     {
17621     case FIB_API_PATH_NH_PROTO_IP4:
17622       s = format (s, "ip4");
17623       break;
17624     case FIB_API_PATH_NH_PROTO_IP6:
17625       s = format (s, "ip6");
17626       break;
17627     case FIB_API_PATH_NH_PROTO_MPLS:
17628       s = format (s, "mpls");
17629       break;
17630     case FIB_API_PATH_NH_PROTO_BIER:
17631       s = format (s, "bier");
17632       break;
17633     case FIB_API_PATH_NH_PROTO_ETHERNET:
17634       s = format (s, "ethernet");
17635       break;
17636     }
17637
17638   return (s);
17639 }
17640
17641 static u8 *
17642 format_vl_api_ip_address_union (u8 * s, va_list * args)
17643 {
17644   vl_api_address_family_t af = va_arg (*args, vl_api_address_family_t);
17645   const vl_api_address_union_t *u = va_arg (*args, vl_api_address_union_t *);
17646
17647   switch (af)
17648     {
17649     case ADDRESS_IP4:
17650       s = format (s, "%U", format_ip4_address, u->ip4);
17651       break;
17652     case ADDRESS_IP6:
17653       s = format (s, "%U", format_ip6_address, u->ip6);
17654       break;
17655     }
17656   return (s);
17657 }
17658
17659 static u8 *
17660 format_vl_api_fib_path_type (u8 * s, va_list * args)
17661 {
17662   vl_api_fib_path_type_t t = va_arg (*args, vl_api_fib_path_type_t);
17663
17664   switch (t)
17665     {
17666     case FIB_API_PATH_TYPE_NORMAL:
17667       s = format (s, "normal");
17668       break;
17669     case FIB_API_PATH_TYPE_LOCAL:
17670       s = format (s, "local");
17671       break;
17672     case FIB_API_PATH_TYPE_DROP:
17673       s = format (s, "drop");
17674       break;
17675     case FIB_API_PATH_TYPE_UDP_ENCAP:
17676       s = format (s, "udp-encap");
17677       break;
17678     case FIB_API_PATH_TYPE_BIER_IMP:
17679       s = format (s, "bier-imp");
17680       break;
17681     case FIB_API_PATH_TYPE_ICMP_UNREACH:
17682       s = format (s, "unreach");
17683       break;
17684     case FIB_API_PATH_TYPE_ICMP_PROHIBIT:
17685       s = format (s, "prohibit");
17686       break;
17687     case FIB_API_PATH_TYPE_SOURCE_LOOKUP:
17688       s = format (s, "src-lookup");
17689       break;
17690     case FIB_API_PATH_TYPE_DVR:
17691       s = format (s, "dvr");
17692       break;
17693     case FIB_API_PATH_TYPE_INTERFACE_RX:
17694       s = format (s, "interface-rx");
17695       break;
17696     case FIB_API_PATH_TYPE_CLASSIFY:
17697       s = format (s, "classify");
17698       break;
17699     }
17700
17701   return (s);
17702 }
17703
17704 static void
17705 vl_api_fib_path_print (vat_main_t * vam, vl_api_fib_path_t * fp)
17706 {
17707   print (vam->ofp,
17708          "  weight %d, sw_if_index %d, type %U, afi %U, next_hop %U",
17709          ntohl (fp->weight), ntohl (fp->sw_if_index),
17710          format_vl_api_fib_path_type, fp->type,
17711          format_fib_api_path_nh_proto, fp->proto,
17712          format_vl_api_ip_address_union, &fp->nh.address);
17713 }
17714
17715 static void
17716 vl_api_mpls_fib_path_json_print (vat_json_node_t * node,
17717                                  vl_api_fib_path_t * fp)
17718 {
17719   struct in_addr ip4;
17720   struct in6_addr ip6;
17721
17722   vat_json_object_add_uint (node, "weight", ntohl (fp->weight));
17723   vat_json_object_add_uint (node, "sw_if_index", ntohl (fp->sw_if_index));
17724   vat_json_object_add_uint (node, "type", fp->type);
17725   vat_json_object_add_uint (node, "next_hop_proto", fp->proto);
17726   if (fp->proto == FIB_API_PATH_NH_PROTO_IP4)
17727     {
17728       clib_memcpy (&ip4, &fp->nh.address.ip4, sizeof (ip4));
17729       vat_json_object_add_ip4 (node, "next_hop", ip4);
17730     }
17731   else if (fp->proto == FIB_API_PATH_NH_PROTO_IP4)
17732     {
17733       clib_memcpy (&ip6, &fp->nh.address.ip6, sizeof (ip6));
17734       vat_json_object_add_ip6 (node, "next_hop", ip6);
17735     }
17736 }
17737
17738 static void
17739 vl_api_mpls_tunnel_details_t_handler (vl_api_mpls_tunnel_details_t * mp)
17740 {
17741   vat_main_t *vam = &vat_main;
17742   int count = ntohl (mp->mt_tunnel.mt_n_paths);
17743   vl_api_fib_path_t *fp;
17744   i32 i;
17745
17746   print (vam->ofp, "sw_if_index %d via:",
17747          ntohl (mp->mt_tunnel.mt_sw_if_index));
17748   fp = mp->mt_tunnel.mt_paths;
17749   for (i = 0; i < count; i++)
17750     {
17751       vl_api_fib_path_print (vam, fp);
17752       fp++;
17753     }
17754
17755   print (vam->ofp, "");
17756 }
17757
17758 #define vl_api_mpls_tunnel_details_t_endian vl_noop_handler
17759 #define vl_api_mpls_tunnel_details_t_print vl_noop_handler
17760
17761 static void
17762 vl_api_mpls_tunnel_details_t_handler_json (vl_api_mpls_tunnel_details_t * mp)
17763 {
17764   vat_main_t *vam = &vat_main;
17765   vat_json_node_t *node = NULL;
17766   int count = ntohl (mp->mt_tunnel.mt_n_paths);
17767   vl_api_fib_path_t *fp;
17768   i32 i;
17769
17770   if (VAT_JSON_ARRAY != vam->json_tree.type)
17771     {
17772       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17773       vat_json_init_array (&vam->json_tree);
17774     }
17775   node = vat_json_array_add (&vam->json_tree);
17776
17777   vat_json_init_object (node);
17778   vat_json_object_add_uint (node, "sw_if_index",
17779                             ntohl (mp->mt_tunnel.mt_sw_if_index));
17780
17781   vat_json_object_add_uint (node, "l2_only", mp->mt_tunnel.mt_l2_only);
17782
17783   fp = mp->mt_tunnel.mt_paths;
17784   for (i = 0; i < count; i++)
17785     {
17786       vl_api_mpls_fib_path_json_print (node, fp);
17787       fp++;
17788     }
17789 }
17790
17791 static int
17792 api_mpls_tunnel_dump (vat_main_t * vam)
17793 {
17794   vl_api_mpls_tunnel_dump_t *mp;
17795   vl_api_control_ping_t *mp_ping;
17796   int ret;
17797
17798   M (MPLS_TUNNEL_DUMP, mp);
17799
17800   S (mp);
17801
17802   /* Use a control ping for synchronization */
17803   MPING (CONTROL_PING, mp_ping);
17804   S (mp_ping);
17805
17806   W (ret);
17807   return ret;
17808 }
17809
17810 #define vl_api_mpls_table_details_t_endian vl_noop_handler
17811 #define vl_api_mpls_table_details_t_print vl_noop_handler
17812
17813
17814 static void
17815 vl_api_mpls_table_details_t_handler (vl_api_mpls_table_details_t * mp)
17816 {
17817   vat_main_t *vam = &vat_main;
17818
17819   print (vam->ofp, "table-id %d,", ntohl (mp->mt_table.mt_table_id));
17820 }
17821
17822 static void vl_api_mpls_table_details_t_handler_json
17823   (vl_api_mpls_table_details_t * mp)
17824 {
17825   vat_main_t *vam = &vat_main;
17826   vat_json_node_t *node = NULL;
17827
17828   if (VAT_JSON_ARRAY != vam->json_tree.type)
17829     {
17830       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17831       vat_json_init_array (&vam->json_tree);
17832     }
17833   node = vat_json_array_add (&vam->json_tree);
17834
17835   vat_json_init_object (node);
17836   vat_json_object_add_uint (node, "table", ntohl (mp->mt_table.mt_table_id));
17837 }
17838
17839 static int
17840 api_mpls_table_dump (vat_main_t * vam)
17841 {
17842   vl_api_mpls_table_dump_t *mp;
17843   vl_api_control_ping_t *mp_ping;
17844   int ret;
17845
17846   M (MPLS_TABLE_DUMP, mp);
17847   S (mp);
17848
17849   /* Use a control ping for synchronization */
17850   MPING (CONTROL_PING, mp_ping);
17851   S (mp_ping);
17852
17853   W (ret);
17854   return ret;
17855 }
17856
17857 #define vl_api_mpls_route_details_t_endian vl_noop_handler
17858 #define vl_api_mpls_route_details_t_print vl_noop_handler
17859
17860 static void
17861 vl_api_mpls_route_details_t_handler (vl_api_mpls_route_details_t * mp)
17862 {
17863   vat_main_t *vam = &vat_main;
17864   int count = (int) clib_net_to_host_u32 (mp->mr_route.mr_n_paths);
17865   vl_api_fib_path_t *fp;
17866   int i;
17867
17868   print (vam->ofp,
17869          "table-id %d, label %u, ess_bit %u",
17870          ntohl (mp->mr_route.mr_table_id),
17871          ntohl (mp->mr_route.mr_label), mp->mr_route.mr_eos);
17872   fp = mp->mr_route.mr_paths;
17873   for (i = 0; i < count; i++)
17874     {
17875       vl_api_fib_path_print (vam, fp);
17876       fp++;
17877     }
17878 }
17879
17880 static void vl_api_mpls_route_details_t_handler_json
17881   (vl_api_mpls_route_details_t * mp)
17882 {
17883   vat_main_t *vam = &vat_main;
17884   int count = (int) clib_host_to_net_u32 (mp->mr_route.mr_n_paths);
17885   vat_json_node_t *node = NULL;
17886   vl_api_fib_path_t *fp;
17887   int i;
17888
17889   if (VAT_JSON_ARRAY != vam->json_tree.type)
17890     {
17891       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17892       vat_json_init_array (&vam->json_tree);
17893     }
17894   node = vat_json_array_add (&vam->json_tree);
17895
17896   vat_json_init_object (node);
17897   vat_json_object_add_uint (node, "table", ntohl (mp->mr_route.mr_table_id));
17898   vat_json_object_add_uint (node, "s_bit", mp->mr_route.mr_eos);
17899   vat_json_object_add_uint (node, "label", ntohl (mp->mr_route.mr_label));
17900   vat_json_object_add_uint (node, "path_count", count);
17901   fp = mp->mr_route.mr_paths;
17902   for (i = 0; i < count; i++)
17903     {
17904       vl_api_mpls_fib_path_json_print (node, fp);
17905       fp++;
17906     }
17907 }
17908
17909 static int
17910 api_mpls_route_dump (vat_main_t * vam)
17911 {
17912   unformat_input_t *input = vam->input;
17913   vl_api_mpls_route_dump_t *mp;
17914   vl_api_control_ping_t *mp_ping;
17915   u32 table_id;
17916   int ret;
17917
17918   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
17919     {
17920       if (unformat (input, "table_id %d", &table_id))
17921         ;
17922       else
17923         break;
17924     }
17925   if (table_id == ~0)
17926     {
17927       errmsg ("missing table id");
17928       return -99;
17929     }
17930
17931   M (MPLS_ROUTE_DUMP, mp);
17932
17933   mp->table.mt_table_id = ntohl (table_id);
17934   S (mp);
17935
17936   /* Use a control ping for synchronization */
17937   MPING (CONTROL_PING, mp_ping);
17938   S (mp_ping);
17939
17940   W (ret);
17941   return ret;
17942 }
17943
17944 #define vl_api_ip_table_details_t_endian vl_noop_handler
17945 #define vl_api_ip_table_details_t_print vl_noop_handler
17946
17947 static void
17948 vl_api_ip_table_details_t_handler (vl_api_ip_table_details_t * mp)
17949 {
17950   vat_main_t *vam = &vat_main;
17951
17952   print (vam->ofp,
17953          "%s; table-id %d, prefix %U/%d",
17954          mp->table.name, ntohl (mp->table.table_id));
17955 }
17956
17957
17958 static void vl_api_ip_table_details_t_handler_json
17959   (vl_api_ip_table_details_t * mp)
17960 {
17961   vat_main_t *vam = &vat_main;
17962   vat_json_node_t *node = NULL;
17963
17964   if (VAT_JSON_ARRAY != vam->json_tree.type)
17965     {
17966       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
17967       vat_json_init_array (&vam->json_tree);
17968     }
17969   node = vat_json_array_add (&vam->json_tree);
17970
17971   vat_json_init_object (node);
17972   vat_json_object_add_uint (node, "table", ntohl (mp->table.table_id));
17973 }
17974
17975 static int
17976 api_ip_table_dump (vat_main_t * vam)
17977 {
17978   vl_api_ip_table_dump_t *mp;
17979   vl_api_control_ping_t *mp_ping;
17980   int ret;
17981
17982   M (IP_TABLE_DUMP, mp);
17983   S (mp);
17984
17985   /* Use a control ping for synchronization */
17986   MPING (CONTROL_PING, mp_ping);
17987   S (mp_ping);
17988
17989   W (ret);
17990   return ret;
17991 }
17992
17993 static int
17994 api_ip_mtable_dump (vat_main_t * vam)
17995 {
17996   vl_api_ip_mtable_dump_t *mp;
17997   vl_api_control_ping_t *mp_ping;
17998   int ret;
17999
18000   M (IP_MTABLE_DUMP, mp);
18001   S (mp);
18002
18003   /* Use a control ping for synchronization */
18004   MPING (CONTROL_PING, mp_ping);
18005   S (mp_ping);
18006
18007   W (ret);
18008   return ret;
18009 }
18010
18011 static int
18012 api_ip_mroute_dump (vat_main_t * vam)
18013 {
18014   unformat_input_t *input = vam->input;
18015   vl_api_control_ping_t *mp_ping;
18016   vl_api_ip_mroute_dump_t *mp;
18017   int ret, is_ip6;
18018   u32 table_id;
18019
18020   is_ip6 = 0;
18021   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18022     {
18023       if (unformat (input, "table_id %d", &table_id))
18024         ;
18025       else if (unformat (input, "ip6"))
18026         is_ip6 = 1;
18027       else if (unformat (input, "ip4"))
18028         is_ip6 = 0;
18029       else
18030         break;
18031     }
18032   if (table_id == ~0)
18033     {
18034       errmsg ("missing table id");
18035       return -99;
18036     }
18037
18038   M (IP_MROUTE_DUMP, mp);
18039   mp->table.table_id = table_id;
18040   mp->table.is_ip6 = is_ip6;
18041   S (mp);
18042
18043   /* Use a control ping for synchronization */
18044   MPING (CONTROL_PING, mp_ping);
18045   S (mp_ping);
18046
18047   W (ret);
18048   return ret;
18049 }
18050
18051 #define vl_api_ip_route_details_t_endian vl_noop_handler
18052 #define vl_api_ip_route_details_t_print vl_noop_handler
18053
18054 static void
18055 vl_api_ip_route_details_t_handler (vl_api_ip_route_details_t * mp)
18056 {
18057   vat_main_t *vam = &vat_main;
18058   u8 count = mp->route.n_paths;
18059   vl_api_fib_path_t *fp;
18060   int i;
18061
18062   print (vam->ofp,
18063          "table-id %d, prefix %U/%d",
18064          ntohl (mp->route.table_id),
18065          format_ip46_address, mp->route.prefix.address, mp->route.prefix.len);
18066   for (i = 0; i < count; i++)
18067     {
18068       fp = &mp->route.paths[i];
18069
18070       vl_api_fib_path_print (vam, fp);
18071       fp++;
18072     }
18073 }
18074
18075 static void vl_api_ip_route_details_t_handler_json
18076   (vl_api_ip_route_details_t * mp)
18077 {
18078   vat_main_t *vam = &vat_main;
18079   u8 count = mp->route.n_paths;
18080   vat_json_node_t *node = NULL;
18081   struct in_addr ip4;
18082   struct in6_addr ip6;
18083   vl_api_fib_path_t *fp;
18084   int i;
18085
18086   if (VAT_JSON_ARRAY != vam->json_tree.type)
18087     {
18088       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18089       vat_json_init_array (&vam->json_tree);
18090     }
18091   node = vat_json_array_add (&vam->json_tree);
18092
18093   vat_json_init_object (node);
18094   vat_json_object_add_uint (node, "table", ntohl (mp->route.table_id));
18095   if (ADDRESS_IP6 == mp->route.prefix.address.af)
18096     {
18097       clib_memcpy (&ip6, &mp->route.prefix.address.un.ip6, sizeof (ip6));
18098       vat_json_object_add_ip6 (node, "prefix", ip6);
18099     }
18100   else
18101     {
18102       clib_memcpy (&ip4, &mp->route.prefix.address.un.ip4, sizeof (ip4));
18103       vat_json_object_add_ip4 (node, "prefix", ip4);
18104     }
18105   vat_json_object_add_uint (node, "mask_length", mp->route.prefix.len);
18106   vat_json_object_add_uint (node, "path_count", count);
18107   for (i = 0; i < count; i++)
18108     {
18109       fp = &mp->route.paths[i];
18110       vl_api_mpls_fib_path_json_print (node, fp);
18111     }
18112 }
18113
18114 static int
18115 api_ip_route_dump (vat_main_t * vam)
18116 {
18117   unformat_input_t *input = vam->input;
18118   vl_api_ip_route_dump_t *mp;
18119   vl_api_control_ping_t *mp_ping;
18120   u32 table_id;
18121   u8 is_ip6;
18122   int ret;
18123
18124   is_ip6 = 0;
18125   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18126     {
18127       if (unformat (input, "table_id %d", &table_id))
18128         ;
18129       else if (unformat (input, "ip6"))
18130         is_ip6 = 1;
18131       else if (unformat (input, "ip4"))
18132         is_ip6 = 0;
18133       else
18134         break;
18135     }
18136   if (table_id == ~0)
18137     {
18138       errmsg ("missing table id");
18139       return -99;
18140     }
18141
18142   M (IP_ROUTE_DUMP, mp);
18143
18144   mp->table.table_id = table_id;
18145   mp->table.is_ip6 = is_ip6;
18146
18147   S (mp);
18148
18149   /* Use a control ping for synchronization */
18150   MPING (CONTROL_PING, mp_ping);
18151   S (mp_ping);
18152
18153   W (ret);
18154   return ret;
18155 }
18156
18157 int
18158 api_classify_table_ids (vat_main_t * vam)
18159 {
18160   vl_api_classify_table_ids_t *mp;
18161   int ret;
18162
18163   /* Construct the API message */
18164   M (CLASSIFY_TABLE_IDS, mp);
18165   mp->context = 0;
18166
18167   S (mp);
18168   W (ret);
18169   return ret;
18170 }
18171
18172 int
18173 api_classify_table_by_interface (vat_main_t * vam)
18174 {
18175   unformat_input_t *input = vam->input;
18176   vl_api_classify_table_by_interface_t *mp;
18177
18178   u32 sw_if_index = ~0;
18179   int ret;
18180   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18181     {
18182       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18183         ;
18184       else if (unformat (input, "sw_if_index %d", &sw_if_index))
18185         ;
18186       else
18187         break;
18188     }
18189   if (sw_if_index == ~0)
18190     {
18191       errmsg ("missing interface name or sw_if_index");
18192       return -99;
18193     }
18194
18195   /* Construct the API message */
18196   M (CLASSIFY_TABLE_BY_INTERFACE, mp);
18197   mp->context = 0;
18198   mp->sw_if_index = ntohl (sw_if_index);
18199
18200   S (mp);
18201   W (ret);
18202   return ret;
18203 }
18204
18205 int
18206 api_classify_table_info (vat_main_t * vam)
18207 {
18208   unformat_input_t *input = vam->input;
18209   vl_api_classify_table_info_t *mp;
18210
18211   u32 table_id = ~0;
18212   int ret;
18213   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18214     {
18215       if (unformat (input, "table_id %d", &table_id))
18216         ;
18217       else
18218         break;
18219     }
18220   if (table_id == ~0)
18221     {
18222       errmsg ("missing table id");
18223       return -99;
18224     }
18225
18226   /* Construct the API message */
18227   M (CLASSIFY_TABLE_INFO, mp);
18228   mp->context = 0;
18229   mp->table_id = ntohl (table_id);
18230
18231   S (mp);
18232   W (ret);
18233   return ret;
18234 }
18235
18236 int
18237 api_classify_session_dump (vat_main_t * vam)
18238 {
18239   unformat_input_t *input = vam->input;
18240   vl_api_classify_session_dump_t *mp;
18241   vl_api_control_ping_t *mp_ping;
18242
18243   u32 table_id = ~0;
18244   int ret;
18245   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18246     {
18247       if (unformat (input, "table_id %d", &table_id))
18248         ;
18249       else
18250         break;
18251     }
18252   if (table_id == ~0)
18253     {
18254       errmsg ("missing table id");
18255       return -99;
18256     }
18257
18258   /* Construct the API message */
18259   M (CLASSIFY_SESSION_DUMP, mp);
18260   mp->context = 0;
18261   mp->table_id = ntohl (table_id);
18262   S (mp);
18263
18264   /* Use a control ping for synchronization */
18265   MPING (CONTROL_PING, mp_ping);
18266   S (mp_ping);
18267
18268   W (ret);
18269   return ret;
18270 }
18271
18272 static void
18273 vl_api_ipfix_exporter_details_t_handler (vl_api_ipfix_exporter_details_t * mp)
18274 {
18275   vat_main_t *vam = &vat_main;
18276
18277   print (vam->ofp, "collector_address %U, collector_port %d, "
18278          "src_address %U, vrf_id %d, path_mtu %u, "
18279          "template_interval %u, udp_checksum %d",
18280          format_ip4_address, mp->collector_address,
18281          ntohs (mp->collector_port),
18282          format_ip4_address, mp->src_address,
18283          ntohl (mp->vrf_id), ntohl (mp->path_mtu),
18284          ntohl (mp->template_interval), mp->udp_checksum);
18285
18286   vam->retval = 0;
18287   vam->result_ready = 1;
18288 }
18289
18290 static void
18291   vl_api_ipfix_exporter_details_t_handler_json
18292   (vl_api_ipfix_exporter_details_t * mp)
18293 {
18294   vat_main_t *vam = &vat_main;
18295   vat_json_node_t node;
18296   struct in_addr collector_address;
18297   struct in_addr src_address;
18298
18299   vat_json_init_object (&node);
18300   clib_memcpy (&collector_address, &mp->collector_address,
18301                sizeof (collector_address));
18302   vat_json_object_add_ip4 (&node, "collector_address", collector_address);
18303   vat_json_object_add_uint (&node, "collector_port",
18304                             ntohs (mp->collector_port));
18305   clib_memcpy (&src_address, &mp->src_address, sizeof (src_address));
18306   vat_json_object_add_ip4 (&node, "src_address", src_address);
18307   vat_json_object_add_int (&node, "vrf_id", ntohl (mp->vrf_id));
18308   vat_json_object_add_uint (&node, "path_mtu", ntohl (mp->path_mtu));
18309   vat_json_object_add_uint (&node, "template_interval",
18310                             ntohl (mp->template_interval));
18311   vat_json_object_add_int (&node, "udp_checksum", mp->udp_checksum);
18312
18313   vat_json_print (vam->ofp, &node);
18314   vat_json_free (&node);
18315   vam->retval = 0;
18316   vam->result_ready = 1;
18317 }
18318
18319 int
18320 api_ipfix_exporter_dump (vat_main_t * vam)
18321 {
18322   vl_api_ipfix_exporter_dump_t *mp;
18323   int ret;
18324
18325   /* Construct the API message */
18326   M (IPFIX_EXPORTER_DUMP, mp);
18327   mp->context = 0;
18328
18329   S (mp);
18330   W (ret);
18331   return ret;
18332 }
18333
18334 static int
18335 api_ipfix_classify_stream_dump (vat_main_t * vam)
18336 {
18337   vl_api_ipfix_classify_stream_dump_t *mp;
18338   int ret;
18339
18340   /* Construct the API message */
18341   M (IPFIX_CLASSIFY_STREAM_DUMP, mp);
18342   mp->context = 0;
18343
18344   S (mp);
18345   W (ret);
18346   return ret;
18347   /* NOTREACHED */
18348   return 0;
18349 }
18350
18351 static void
18352   vl_api_ipfix_classify_stream_details_t_handler
18353   (vl_api_ipfix_classify_stream_details_t * mp)
18354 {
18355   vat_main_t *vam = &vat_main;
18356   print (vam->ofp, "domain_id %d, src_port %d",
18357          ntohl (mp->domain_id), ntohs (mp->src_port));
18358   vam->retval = 0;
18359   vam->result_ready = 1;
18360 }
18361
18362 static void
18363   vl_api_ipfix_classify_stream_details_t_handler_json
18364   (vl_api_ipfix_classify_stream_details_t * mp)
18365 {
18366   vat_main_t *vam = &vat_main;
18367   vat_json_node_t node;
18368
18369   vat_json_init_object (&node);
18370   vat_json_object_add_uint (&node, "domain_id", ntohl (mp->domain_id));
18371   vat_json_object_add_uint (&node, "src_port", ntohs (mp->src_port));
18372
18373   vat_json_print (vam->ofp, &node);
18374   vat_json_free (&node);
18375   vam->retval = 0;
18376   vam->result_ready = 1;
18377 }
18378
18379 static int
18380 api_ipfix_classify_table_dump (vat_main_t * vam)
18381 {
18382   vl_api_ipfix_classify_table_dump_t *mp;
18383   vl_api_control_ping_t *mp_ping;
18384   int ret;
18385
18386   if (!vam->json_output)
18387     {
18388       print (vam->ofp, "%15s%15s%20s", "table_id", "ip_version",
18389              "transport_protocol");
18390     }
18391
18392   /* Construct the API message */
18393   M (IPFIX_CLASSIFY_TABLE_DUMP, mp);
18394
18395   /* send it... */
18396   S (mp);
18397
18398   /* Use a control ping for synchronization */
18399   MPING (CONTROL_PING, mp_ping);
18400   S (mp_ping);
18401
18402   W (ret);
18403   return ret;
18404 }
18405
18406 static void
18407   vl_api_ipfix_classify_table_details_t_handler
18408   (vl_api_ipfix_classify_table_details_t * mp)
18409 {
18410   vat_main_t *vam = &vat_main;
18411   print (vam->ofp, "%15d%15d%20d", ntohl (mp->table_id), mp->ip_version,
18412          mp->transport_protocol);
18413 }
18414
18415 static void
18416   vl_api_ipfix_classify_table_details_t_handler_json
18417   (vl_api_ipfix_classify_table_details_t * mp)
18418 {
18419   vat_json_node_t *node = NULL;
18420   vat_main_t *vam = &vat_main;
18421
18422   if (VAT_JSON_ARRAY != vam->json_tree.type)
18423     {
18424       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18425       vat_json_init_array (&vam->json_tree);
18426     }
18427
18428   node = vat_json_array_add (&vam->json_tree);
18429   vat_json_init_object (node);
18430
18431   vat_json_object_add_uint (node, "table_id", ntohl (mp->table_id));
18432   vat_json_object_add_uint (node, "ip_version", mp->ip_version);
18433   vat_json_object_add_uint (node, "transport_protocol",
18434                             mp->transport_protocol);
18435 }
18436
18437 static int
18438 api_sw_interface_span_enable_disable (vat_main_t * vam)
18439 {
18440   unformat_input_t *i = vam->input;
18441   vl_api_sw_interface_span_enable_disable_t *mp;
18442   u32 src_sw_if_index = ~0;
18443   u32 dst_sw_if_index = ~0;
18444   u8 state = 3;
18445   int ret;
18446   u8 is_l2 = 0;
18447
18448   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18449     {
18450       if (unformat
18451           (i, "src %U", api_unformat_sw_if_index, vam, &src_sw_if_index))
18452         ;
18453       else if (unformat (i, "src_sw_if_index %d", &src_sw_if_index))
18454         ;
18455       else
18456         if (unformat
18457             (i, "dst %U", api_unformat_sw_if_index, vam, &dst_sw_if_index))
18458         ;
18459       else if (unformat (i, "dst_sw_if_index %d", &dst_sw_if_index))
18460         ;
18461       else if (unformat (i, "disable"))
18462         state = 0;
18463       else if (unformat (i, "rx"))
18464         state = 1;
18465       else if (unformat (i, "tx"))
18466         state = 2;
18467       else if (unformat (i, "both"))
18468         state = 3;
18469       else if (unformat (i, "l2"))
18470         is_l2 = 1;
18471       else
18472         break;
18473     }
18474
18475   M (SW_INTERFACE_SPAN_ENABLE_DISABLE, mp);
18476
18477   mp->sw_if_index_from = htonl (src_sw_if_index);
18478   mp->sw_if_index_to = htonl (dst_sw_if_index);
18479   mp->state = state;
18480   mp->is_l2 = is_l2;
18481
18482   S (mp);
18483   W (ret);
18484   return ret;
18485 }
18486
18487 static void
18488 vl_api_sw_interface_span_details_t_handler (vl_api_sw_interface_span_details_t
18489                                             * mp)
18490 {
18491   vat_main_t *vam = &vat_main;
18492   u8 *sw_if_from_name = 0;
18493   u8 *sw_if_to_name = 0;
18494   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
18495   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
18496   char *states[] = { "none", "rx", "tx", "both" };
18497   hash_pair_t *p;
18498
18499   /* *INDENT-OFF* */
18500   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
18501   ({
18502     if ((u32) p->value[0] == sw_if_index_from)
18503       {
18504         sw_if_from_name = (u8 *)(p->key);
18505         if (sw_if_to_name)
18506           break;
18507       }
18508     if ((u32) p->value[0] == sw_if_index_to)
18509       {
18510         sw_if_to_name = (u8 *)(p->key);
18511         if (sw_if_from_name)
18512           break;
18513       }
18514   }));
18515   /* *INDENT-ON* */
18516   print (vam->ofp, "%20s => %20s (%s) %s",
18517          sw_if_from_name, sw_if_to_name, states[mp->state],
18518          mp->is_l2 ? "l2" : "device");
18519 }
18520
18521 static void
18522   vl_api_sw_interface_span_details_t_handler_json
18523   (vl_api_sw_interface_span_details_t * mp)
18524 {
18525   vat_main_t *vam = &vat_main;
18526   vat_json_node_t *node = NULL;
18527   u8 *sw_if_from_name = 0;
18528   u8 *sw_if_to_name = 0;
18529   u32 sw_if_index_from = ntohl (mp->sw_if_index_from);
18530   u32 sw_if_index_to = ntohl (mp->sw_if_index_to);
18531   hash_pair_t *p;
18532
18533   /* *INDENT-OFF* */
18534   hash_foreach_pair (p, vam->sw_if_index_by_interface_name,
18535   ({
18536     if ((u32) p->value[0] == sw_if_index_from)
18537       {
18538         sw_if_from_name = (u8 *)(p->key);
18539         if (sw_if_to_name)
18540           break;
18541       }
18542     if ((u32) p->value[0] == sw_if_index_to)
18543       {
18544         sw_if_to_name = (u8 *)(p->key);
18545         if (sw_if_from_name)
18546           break;
18547       }
18548   }));
18549   /* *INDENT-ON* */
18550
18551   if (VAT_JSON_ARRAY != vam->json_tree.type)
18552     {
18553       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
18554       vat_json_init_array (&vam->json_tree);
18555     }
18556   node = vat_json_array_add (&vam->json_tree);
18557
18558   vat_json_init_object (node);
18559   vat_json_object_add_uint (node, "src-if-index", sw_if_index_from);
18560   vat_json_object_add_string_copy (node, "src-if-name", sw_if_from_name);
18561   vat_json_object_add_uint (node, "dst-if-index", sw_if_index_to);
18562   if (0 != sw_if_to_name)
18563     {
18564       vat_json_object_add_string_copy (node, "dst-if-name", sw_if_to_name);
18565     }
18566   vat_json_object_add_uint (node, "state", mp->state);
18567   vat_json_object_add_uint (node, "is-l2", mp->is_l2);
18568 }
18569
18570 static int
18571 api_sw_interface_span_dump (vat_main_t * vam)
18572 {
18573   unformat_input_t *input = vam->input;
18574   vl_api_sw_interface_span_dump_t *mp;
18575   vl_api_control_ping_t *mp_ping;
18576   u8 is_l2 = 0;
18577   int ret;
18578
18579   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18580     {
18581       if (unformat (input, "l2"))
18582         is_l2 = 1;
18583       else
18584         break;
18585     }
18586
18587   M (SW_INTERFACE_SPAN_DUMP, mp);
18588   mp->is_l2 = is_l2;
18589   S (mp);
18590
18591   /* Use a control ping for synchronization */
18592   MPING (CONTROL_PING, mp_ping);
18593   S (mp_ping);
18594
18595   W (ret);
18596   return ret;
18597 }
18598
18599 int
18600 api_pg_create_interface (vat_main_t * vam)
18601 {
18602   unformat_input_t *input = vam->input;
18603   vl_api_pg_create_interface_t *mp;
18604
18605   u32 if_id = ~0, gso_size = 0;
18606   u8 gso_enabled = 0;
18607   int ret;
18608   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18609     {
18610       if (unformat (input, "if_id %d", &if_id))
18611         ;
18612       else if (unformat (input, "gso-enabled"))
18613         {
18614           gso_enabled = 1;
18615           if (unformat (input, "gso-size %u", &gso_size))
18616             ;
18617           else
18618             {
18619               errmsg ("missing gso-size");
18620               return -99;
18621             }
18622         }
18623       else
18624         break;
18625     }
18626   if (if_id == ~0)
18627     {
18628       errmsg ("missing pg interface index");
18629       return -99;
18630     }
18631
18632   /* Construct the API message */
18633   M (PG_CREATE_INTERFACE, mp);
18634   mp->context = 0;
18635   mp->interface_id = ntohl (if_id);
18636   mp->gso_enabled = gso_enabled;
18637
18638   S (mp);
18639   W (ret);
18640   return ret;
18641 }
18642
18643 int
18644 api_pg_capture (vat_main_t * vam)
18645 {
18646   unformat_input_t *input = vam->input;
18647   vl_api_pg_capture_t *mp;
18648
18649   u32 if_id = ~0;
18650   u8 enable = 1;
18651   u32 count = 1;
18652   u8 pcap_file_set = 0;
18653   u8 *pcap_file = 0;
18654   int ret;
18655   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18656     {
18657       if (unformat (input, "if_id %d", &if_id))
18658         ;
18659       else if (unformat (input, "pcap %s", &pcap_file))
18660         pcap_file_set = 1;
18661       else if (unformat (input, "count %d", &count))
18662         ;
18663       else if (unformat (input, "disable"))
18664         enable = 0;
18665       else
18666         break;
18667     }
18668   if (if_id == ~0)
18669     {
18670       errmsg ("missing pg interface index");
18671       return -99;
18672     }
18673   if (pcap_file_set > 0)
18674     {
18675       if (vec_len (pcap_file) > 255)
18676         {
18677           errmsg ("pcap file name is too long");
18678           return -99;
18679         }
18680     }
18681
18682   u32 name_len = vec_len (pcap_file);
18683   /* Construct the API message */
18684   M (PG_CAPTURE, mp);
18685   mp->context = 0;
18686   mp->interface_id = ntohl (if_id);
18687   mp->is_enabled = enable;
18688   mp->count = ntohl (count);
18689   mp->pcap_name_length = ntohl (name_len);
18690   if (pcap_file_set != 0)
18691     {
18692       clib_memcpy (mp->pcap_file_name, pcap_file, name_len);
18693     }
18694   vec_free (pcap_file);
18695
18696   S (mp);
18697   W (ret);
18698   return ret;
18699 }
18700
18701 int
18702 api_pg_enable_disable (vat_main_t * vam)
18703 {
18704   unformat_input_t *input = vam->input;
18705   vl_api_pg_enable_disable_t *mp;
18706
18707   u8 enable = 1;
18708   u8 stream_name_set = 0;
18709   u8 *stream_name = 0;
18710   int ret;
18711   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18712     {
18713       if (unformat (input, "stream %s", &stream_name))
18714         stream_name_set = 1;
18715       else if (unformat (input, "disable"))
18716         enable = 0;
18717       else
18718         break;
18719     }
18720
18721   if (stream_name_set > 0)
18722     {
18723       if (vec_len (stream_name) > 255)
18724         {
18725           errmsg ("stream name too long");
18726           return -99;
18727         }
18728     }
18729
18730   u32 name_len = vec_len (stream_name);
18731   /* Construct the API message */
18732   M (PG_ENABLE_DISABLE, mp);
18733   mp->context = 0;
18734   mp->is_enabled = enable;
18735   if (stream_name_set != 0)
18736     {
18737       mp->stream_name_length = ntohl (name_len);
18738       clib_memcpy (mp->stream_name, stream_name, name_len);
18739     }
18740   vec_free (stream_name);
18741
18742   S (mp);
18743   W (ret);
18744   return ret;
18745 }
18746
18747 int
18748 api_ip_source_and_port_range_check_add_del (vat_main_t * vam)
18749 {
18750   unformat_input_t *input = vam->input;
18751   vl_api_ip_source_and_port_range_check_add_del_t *mp;
18752
18753   u16 *low_ports = 0;
18754   u16 *high_ports = 0;
18755   u16 this_low;
18756   u16 this_hi;
18757   vl_api_prefix_t prefix;
18758   u32 tmp, tmp2;
18759   u8 prefix_set = 0;
18760   u32 vrf_id = ~0;
18761   u8 is_add = 1;
18762   int ret;
18763
18764   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18765     {
18766       if (unformat (input, "%U", unformat_vl_api_prefix, &prefix))
18767         prefix_set = 1;
18768       else if (unformat (input, "vrf %d", &vrf_id))
18769         ;
18770       else if (unformat (input, "del"))
18771         is_add = 0;
18772       else if (unformat (input, "port %d", &tmp))
18773         {
18774           if (tmp == 0 || tmp > 65535)
18775             {
18776               errmsg ("port %d out of range", tmp);
18777               return -99;
18778             }
18779           this_low = tmp;
18780           this_hi = this_low + 1;
18781           vec_add1 (low_ports, this_low);
18782           vec_add1 (high_ports, this_hi);
18783         }
18784       else if (unformat (input, "range %d - %d", &tmp, &tmp2))
18785         {
18786           if ((tmp > tmp2) || (tmp == 0) || (tmp2 > 65535))
18787             {
18788               errmsg ("incorrect range parameters");
18789               return -99;
18790             }
18791           this_low = tmp;
18792           /* Note: in debug CLI +1 is added to high before
18793              passing to real fn that does "the work"
18794              (ip_source_and_port_range_check_add_del).
18795              This fn is a wrapper around the binary API fn a
18796              control plane will call, which expects this increment
18797              to have occurred. Hence letting the binary API control
18798              plane fn do the increment for consistency between VAT
18799              and other control planes.
18800            */
18801           this_hi = tmp2;
18802           vec_add1 (low_ports, this_low);
18803           vec_add1 (high_ports, this_hi);
18804         }
18805       else
18806         break;
18807     }
18808
18809   if (prefix_set == 0)
18810     {
18811       errmsg ("<address>/<mask> not specified");
18812       return -99;
18813     }
18814
18815   if (vrf_id == ~0)
18816     {
18817       errmsg ("VRF ID required, not specified");
18818       return -99;
18819     }
18820
18821   if (vrf_id == 0)
18822     {
18823       errmsg
18824         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
18825       return -99;
18826     }
18827
18828   if (vec_len (low_ports) == 0)
18829     {
18830       errmsg ("At least one port or port range required");
18831       return -99;
18832     }
18833
18834   M (IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, mp);
18835
18836   mp->is_add = is_add;
18837
18838   clib_memcpy (&mp->prefix, &prefix, sizeof (prefix));
18839
18840   mp->number_of_ranges = vec_len (low_ports);
18841
18842   clib_memcpy (mp->low_ports, low_ports, vec_len (low_ports));
18843   vec_free (low_ports);
18844
18845   clib_memcpy (mp->high_ports, high_ports, vec_len (high_ports));
18846   vec_free (high_ports);
18847
18848   mp->vrf_id = ntohl (vrf_id);
18849
18850   S (mp);
18851   W (ret);
18852   return ret;
18853 }
18854
18855 int
18856 api_ip_source_and_port_range_check_interface_add_del (vat_main_t * vam)
18857 {
18858   unformat_input_t *input = vam->input;
18859   vl_api_ip_source_and_port_range_check_interface_add_del_t *mp;
18860   u32 sw_if_index = ~0;
18861   int vrf_set = 0;
18862   u32 tcp_out_vrf_id = ~0, udp_out_vrf_id = ~0;
18863   u32 tcp_in_vrf_id = ~0, udp_in_vrf_id = ~0;
18864   u8 is_add = 1;
18865   int ret;
18866
18867   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
18868     {
18869       if (unformat (input, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18870         ;
18871       else if (unformat (input, "sw_if_index %d", &sw_if_index))
18872         ;
18873       else if (unformat (input, "tcp-out-vrf %d", &tcp_out_vrf_id))
18874         vrf_set = 1;
18875       else if (unformat (input, "udp-out-vrf %d", &udp_out_vrf_id))
18876         vrf_set = 1;
18877       else if (unformat (input, "tcp-in-vrf %d", &tcp_in_vrf_id))
18878         vrf_set = 1;
18879       else if (unformat (input, "udp-in-vrf %d", &udp_in_vrf_id))
18880         vrf_set = 1;
18881       else if (unformat (input, "del"))
18882         is_add = 0;
18883       else
18884         break;
18885     }
18886
18887   if (sw_if_index == ~0)
18888     {
18889       errmsg ("Interface required but not specified");
18890       return -99;
18891     }
18892
18893   if (vrf_set == 0)
18894     {
18895       errmsg ("VRF ID required but not specified");
18896       return -99;
18897     }
18898
18899   if (tcp_out_vrf_id == 0
18900       || udp_out_vrf_id == 0 || tcp_in_vrf_id == 0 || udp_in_vrf_id == 0)
18901     {
18902       errmsg
18903         ("VRF ID should not be default. Should be distinct VRF for this purpose.");
18904       return -99;
18905     }
18906
18907   /* Construct the API message */
18908   M (IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, mp);
18909
18910   mp->sw_if_index = ntohl (sw_if_index);
18911   mp->is_add = is_add;
18912   mp->tcp_out_vrf_id = ntohl (tcp_out_vrf_id);
18913   mp->udp_out_vrf_id = ntohl (udp_out_vrf_id);
18914   mp->tcp_in_vrf_id = ntohl (tcp_in_vrf_id);
18915   mp->udp_in_vrf_id = ntohl (udp_in_vrf_id);
18916
18917   /* send it... */
18918   S (mp);
18919
18920   /* Wait for a reply... */
18921   W (ret);
18922   return ret;
18923 }
18924
18925 static int
18926 api_set_punt (vat_main_t * vam)
18927 {
18928   unformat_input_t *i = vam->input;
18929   vl_api_address_family_t af;
18930   vl_api_set_punt_t *mp;
18931   u32 protocol = ~0;
18932   u32 port = ~0;
18933   int is_add = 1;
18934   int ret;
18935
18936   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18937     {
18938       if (unformat (i, "%U", unformat_vl_api_address_family, &af))
18939         ;
18940       else if (unformat (i, "protocol %d", &protocol))
18941         ;
18942       else if (unformat (i, "port %d", &port))
18943         ;
18944       else if (unformat (i, "del"))
18945         is_add = 0;
18946       else
18947         {
18948           clib_warning ("parse error '%U'", format_unformat_error, i);
18949           return -99;
18950         }
18951     }
18952
18953   M (SET_PUNT, mp);
18954
18955   mp->is_add = (u8) is_add;
18956   mp->punt.type = PUNT_API_TYPE_L4;
18957   mp->punt.punt.l4.af = af;
18958   mp->punt.punt.l4.protocol = (u8) protocol;
18959   mp->punt.punt.l4.port = htons ((u16) port);
18960
18961   S (mp);
18962   W (ret);
18963   return ret;
18964 }
18965
18966 static int
18967 api_delete_subif (vat_main_t * vam)
18968 {
18969   unformat_input_t *i = vam->input;
18970   vl_api_delete_subif_t *mp;
18971   u32 sw_if_index = ~0;
18972   int ret;
18973
18974   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
18975     {
18976       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
18977         ;
18978       if (unformat (i, "sw_if_index %d", &sw_if_index))
18979         ;
18980       else
18981         break;
18982     }
18983
18984   if (sw_if_index == ~0)
18985     {
18986       errmsg ("missing sw_if_index");
18987       return -99;
18988     }
18989
18990   /* Construct the API message */
18991   M (DELETE_SUBIF, mp);
18992   mp->sw_if_index = ntohl (sw_if_index);
18993
18994   S (mp);
18995   W (ret);
18996   return ret;
18997 }
18998
18999 #define foreach_pbb_vtr_op      \
19000 _("disable",  L2_VTR_DISABLED)  \
19001 _("pop",  L2_VTR_POP_2)         \
19002 _("push",  L2_VTR_PUSH_2)
19003
19004 static int
19005 api_l2_interface_pbb_tag_rewrite (vat_main_t * vam)
19006 {
19007   unformat_input_t *i = vam->input;
19008   vl_api_l2_interface_pbb_tag_rewrite_t *mp;
19009   u32 sw_if_index = ~0, vtr_op = ~0;
19010   u16 outer_tag = ~0;
19011   u8 dmac[6], smac[6];
19012   u8 dmac_set = 0, smac_set = 0;
19013   u16 vlanid = 0;
19014   u32 sid = ~0;
19015   u32 tmp;
19016   int ret;
19017
19018   /* Shut up coverity */
19019   clib_memset (dmac, 0, sizeof (dmac));
19020   clib_memset (smac, 0, sizeof (smac));
19021
19022   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19023     {
19024       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19025         ;
19026       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19027         ;
19028       else if (unformat (i, "vtr_op %d", &vtr_op))
19029         ;
19030 #define _(n,v) else if (unformat(i, n)) {vtr_op = v;}
19031       foreach_pbb_vtr_op
19032 #undef _
19033         else if (unformat (i, "translate_pbb_stag"))
19034         {
19035           if (unformat (i, "%d", &tmp))
19036             {
19037               vtr_op = L2_VTR_TRANSLATE_2_1;
19038               outer_tag = tmp;
19039             }
19040           else
19041             {
19042               errmsg
19043                 ("translate_pbb_stag operation requires outer tag definition");
19044               return -99;
19045             }
19046         }
19047       else if (unformat (i, "dmac %U", unformat_ethernet_address, dmac))
19048         dmac_set++;
19049       else if (unformat (i, "smac %U", unformat_ethernet_address, smac))
19050         smac_set++;
19051       else if (unformat (i, "sid %d", &sid))
19052         ;
19053       else if (unformat (i, "vlanid %d", &tmp))
19054         vlanid = tmp;
19055       else
19056         {
19057           clib_warning ("parse error '%U'", format_unformat_error, i);
19058           return -99;
19059         }
19060     }
19061
19062   if ((sw_if_index == ~0) || (vtr_op == ~0))
19063     {
19064       errmsg ("missing sw_if_index or vtr operation");
19065       return -99;
19066     }
19067   if (((vtr_op == L2_VTR_PUSH_2) || (vtr_op == L2_VTR_TRANSLATE_2_2))
19068       && ((dmac_set == 0) || (smac_set == 0) || (sid == ~0)))
19069     {
19070       errmsg
19071         ("push and translate_qinq operations require dmac, smac, sid and optionally vlanid");
19072       return -99;
19073     }
19074
19075   M (L2_INTERFACE_PBB_TAG_REWRITE, mp);
19076   mp->sw_if_index = ntohl (sw_if_index);
19077   mp->vtr_op = ntohl (vtr_op);
19078   mp->outer_tag = ntohs (outer_tag);
19079   clib_memcpy (mp->b_dmac, dmac, sizeof (dmac));
19080   clib_memcpy (mp->b_smac, smac, sizeof (smac));
19081   mp->b_vlanid = ntohs (vlanid);
19082   mp->i_sid = ntohl (sid);
19083
19084   S (mp);
19085   W (ret);
19086   return ret;
19087 }
19088
19089 static int
19090 api_flow_classify_set_interface (vat_main_t * vam)
19091 {
19092   unformat_input_t *i = vam->input;
19093   vl_api_flow_classify_set_interface_t *mp;
19094   u32 sw_if_index;
19095   int sw_if_index_set;
19096   u32 ip4_table_index = ~0;
19097   u32 ip6_table_index = ~0;
19098   u8 is_add = 1;
19099   int ret;
19100
19101   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19102     {
19103       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19104         sw_if_index_set = 1;
19105       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19106         sw_if_index_set = 1;
19107       else if (unformat (i, "del"))
19108         is_add = 0;
19109       else if (unformat (i, "ip4-table %d", &ip4_table_index))
19110         ;
19111       else if (unformat (i, "ip6-table %d", &ip6_table_index))
19112         ;
19113       else
19114         {
19115           clib_warning ("parse error '%U'", format_unformat_error, i);
19116           return -99;
19117         }
19118     }
19119
19120   if (sw_if_index_set == 0)
19121     {
19122       errmsg ("missing interface name or sw_if_index");
19123       return -99;
19124     }
19125
19126   M (FLOW_CLASSIFY_SET_INTERFACE, mp);
19127
19128   mp->sw_if_index = ntohl (sw_if_index);
19129   mp->ip4_table_index = ntohl (ip4_table_index);
19130   mp->ip6_table_index = ntohl (ip6_table_index);
19131   mp->is_add = is_add;
19132
19133   S (mp);
19134   W (ret);
19135   return ret;
19136 }
19137
19138 static int
19139 api_flow_classify_dump (vat_main_t * vam)
19140 {
19141   unformat_input_t *i = vam->input;
19142   vl_api_flow_classify_dump_t *mp;
19143   vl_api_control_ping_t *mp_ping;
19144   u8 type = FLOW_CLASSIFY_N_TABLES;
19145   int ret;
19146
19147   if (unformat (i, "type %U", unformat_flow_classify_table_type, &type))
19148     ;
19149   else
19150     {
19151       errmsg ("classify table type must be specified");
19152       return -99;
19153     }
19154
19155   if (!vam->json_output)
19156     {
19157       print (vam->ofp, "%10s%20s", "Intfc idx", "Classify table");
19158     }
19159
19160   M (FLOW_CLASSIFY_DUMP, mp);
19161   mp->type = type;
19162   /* send it... */
19163   S (mp);
19164
19165   /* Use a control ping for synchronization */
19166   MPING (CONTROL_PING, mp_ping);
19167   S (mp_ping);
19168
19169   /* Wait for a reply... */
19170   W (ret);
19171   return ret;
19172 }
19173
19174 static int
19175 api_feature_enable_disable (vat_main_t * vam)
19176 {
19177   unformat_input_t *i = vam->input;
19178   vl_api_feature_enable_disable_t *mp;
19179   u8 *arc_name = 0;
19180   u8 *feature_name = 0;
19181   u32 sw_if_index = ~0;
19182   u8 enable = 1;
19183   int ret;
19184
19185   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19186     {
19187       if (unformat (i, "arc_name %s", &arc_name))
19188         ;
19189       else if (unformat (i, "feature_name %s", &feature_name))
19190         ;
19191       else
19192         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19193         ;
19194       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19195         ;
19196       else if (unformat (i, "disable"))
19197         enable = 0;
19198       else
19199         break;
19200     }
19201
19202   if (arc_name == 0)
19203     {
19204       errmsg ("missing arc name");
19205       return -99;
19206     }
19207   if (vec_len (arc_name) > 63)
19208     {
19209       errmsg ("arc name too long");
19210     }
19211
19212   if (feature_name == 0)
19213     {
19214       errmsg ("missing feature name");
19215       return -99;
19216     }
19217   if (vec_len (feature_name) > 63)
19218     {
19219       errmsg ("feature name too long");
19220     }
19221
19222   if (sw_if_index == ~0)
19223     {
19224       errmsg ("missing interface name or sw_if_index");
19225       return -99;
19226     }
19227
19228   /* Construct the API message */
19229   M (FEATURE_ENABLE_DISABLE, mp);
19230   mp->sw_if_index = ntohl (sw_if_index);
19231   mp->enable = enable;
19232   clib_memcpy (mp->arc_name, arc_name, vec_len (arc_name));
19233   clib_memcpy (mp->feature_name, feature_name, vec_len (feature_name));
19234   vec_free (arc_name);
19235   vec_free (feature_name);
19236
19237   S (mp);
19238   W (ret);
19239   return ret;
19240 }
19241
19242 static int
19243 api_feature_gso_enable_disable (vat_main_t * vam)
19244 {
19245   unformat_input_t *i = vam->input;
19246   vl_api_feature_gso_enable_disable_t *mp;
19247   u32 sw_if_index = ~0;
19248   u8 enable = 1;
19249   int ret;
19250
19251   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19252     {
19253       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19254         ;
19255       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19256         ;
19257       else if (unformat (i, "enable"))
19258         enable = 1;
19259       else if (unformat (i, "disable"))
19260         enable = 0;
19261       else
19262         break;
19263     }
19264
19265   if (sw_if_index == ~0)
19266     {
19267       errmsg ("missing interface name or sw_if_index");
19268       return -99;
19269     }
19270
19271   /* Construct the API message */
19272   M (FEATURE_GSO_ENABLE_DISABLE, mp);
19273   mp->sw_if_index = ntohl (sw_if_index);
19274   mp->enable_disable = enable;
19275
19276   S (mp);
19277   W (ret);
19278   return ret;
19279 }
19280
19281 static int
19282 api_sw_interface_tag_add_del (vat_main_t * vam)
19283 {
19284   unformat_input_t *i = vam->input;
19285   vl_api_sw_interface_tag_add_del_t *mp;
19286   u32 sw_if_index = ~0;
19287   u8 *tag = 0;
19288   u8 enable = 1;
19289   int ret;
19290
19291   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19292     {
19293       if (unformat (i, "tag %s", &tag))
19294         ;
19295       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19296         ;
19297       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19298         ;
19299       else if (unformat (i, "del"))
19300         enable = 0;
19301       else
19302         break;
19303     }
19304
19305   if (sw_if_index == ~0)
19306     {
19307       errmsg ("missing interface name or sw_if_index");
19308       return -99;
19309     }
19310
19311   if (enable && (tag == 0))
19312     {
19313       errmsg ("no tag specified");
19314       return -99;
19315     }
19316
19317   /* Construct the API message */
19318   M (SW_INTERFACE_TAG_ADD_DEL, mp);
19319   mp->sw_if_index = ntohl (sw_if_index);
19320   mp->is_add = enable;
19321   if (enable)
19322     strncpy ((char *) mp->tag, (char *) tag, ARRAY_LEN (mp->tag) - 1);
19323   vec_free (tag);
19324
19325   S (mp);
19326   W (ret);
19327   return ret;
19328 }
19329
19330 static int
19331 api_sw_interface_add_del_mac_address (vat_main_t * vam)
19332 {
19333   unformat_input_t *i = vam->input;
19334   vl_api_mac_address_t mac = { 0 };
19335   vl_api_sw_interface_add_del_mac_address_t *mp;
19336   u32 sw_if_index = ~0;
19337   u8 is_add = 1;
19338   u8 mac_set = 0;
19339   int ret;
19340
19341   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19342     {
19343       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19344         ;
19345       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19346         ;
19347       else if (unformat (i, "%U", unformat_vl_api_mac_address, &mac))
19348         mac_set++;
19349       else if (unformat (i, "del"))
19350         is_add = 0;
19351       else
19352         break;
19353     }
19354
19355   if (sw_if_index == ~0)
19356     {
19357       errmsg ("missing interface name or sw_if_index");
19358       return -99;
19359     }
19360
19361   if (!mac_set)
19362     {
19363       errmsg ("missing MAC address");
19364       return -99;
19365     }
19366
19367   /* Construct the API message */
19368   M (SW_INTERFACE_ADD_DEL_MAC_ADDRESS, mp);
19369   mp->sw_if_index = ntohl (sw_if_index);
19370   mp->is_add = is_add;
19371   clib_memcpy (&mp->addr, &mac, sizeof (mac));
19372
19373   S (mp);
19374   W (ret);
19375   return ret;
19376 }
19377
19378 static void vl_api_l2_xconnect_details_t_handler
19379   (vl_api_l2_xconnect_details_t * mp)
19380 {
19381   vat_main_t *vam = &vat_main;
19382
19383   print (vam->ofp, "%15d%15d",
19384          ntohl (mp->rx_sw_if_index), ntohl (mp->tx_sw_if_index));
19385 }
19386
19387 static void vl_api_l2_xconnect_details_t_handler_json
19388   (vl_api_l2_xconnect_details_t * mp)
19389 {
19390   vat_main_t *vam = &vat_main;
19391   vat_json_node_t *node = NULL;
19392
19393   if (VAT_JSON_ARRAY != vam->json_tree.type)
19394     {
19395       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19396       vat_json_init_array (&vam->json_tree);
19397     }
19398   node = vat_json_array_add (&vam->json_tree);
19399
19400   vat_json_init_object (node);
19401   vat_json_object_add_uint (node, "rx_sw_if_index",
19402                             ntohl (mp->rx_sw_if_index));
19403   vat_json_object_add_uint (node, "tx_sw_if_index",
19404                             ntohl (mp->tx_sw_if_index));
19405 }
19406
19407 static int
19408 api_l2_xconnect_dump (vat_main_t * vam)
19409 {
19410   vl_api_l2_xconnect_dump_t *mp;
19411   vl_api_control_ping_t *mp_ping;
19412   int ret;
19413
19414   if (!vam->json_output)
19415     {
19416       print (vam->ofp, "%15s%15s", "rx_sw_if_index", "tx_sw_if_index");
19417     }
19418
19419   M (L2_XCONNECT_DUMP, mp);
19420
19421   S (mp);
19422
19423   /* Use a control ping for synchronization */
19424   MPING (CONTROL_PING, mp_ping);
19425   S (mp_ping);
19426
19427   W (ret);
19428   return ret;
19429 }
19430
19431 static int
19432 api_hw_interface_set_mtu (vat_main_t * vam)
19433 {
19434   unformat_input_t *i = vam->input;
19435   vl_api_hw_interface_set_mtu_t *mp;
19436   u32 sw_if_index = ~0;
19437   u32 mtu = 0;
19438   int ret;
19439
19440   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19441     {
19442       if (unformat (i, "mtu %d", &mtu))
19443         ;
19444       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19445         ;
19446       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19447         ;
19448       else
19449         break;
19450     }
19451
19452   if (sw_if_index == ~0)
19453     {
19454       errmsg ("missing interface name or sw_if_index");
19455       return -99;
19456     }
19457
19458   if (mtu == 0)
19459     {
19460       errmsg ("no mtu specified");
19461       return -99;
19462     }
19463
19464   /* Construct the API message */
19465   M (HW_INTERFACE_SET_MTU, mp);
19466   mp->sw_if_index = ntohl (sw_if_index);
19467   mp->mtu = ntohs ((u16) mtu);
19468
19469   S (mp);
19470   W (ret);
19471   return ret;
19472 }
19473
19474 static int
19475 api_p2p_ethernet_add (vat_main_t * vam)
19476 {
19477   unformat_input_t *i = vam->input;
19478   vl_api_p2p_ethernet_add_t *mp;
19479   u32 parent_if_index = ~0;
19480   u32 sub_id = ~0;
19481   u8 remote_mac[6];
19482   u8 mac_set = 0;
19483   int ret;
19484
19485   clib_memset (remote_mac, 0, sizeof (remote_mac));
19486   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19487     {
19488       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
19489         ;
19490       else if (unformat (i, "sw_if_index %d", &parent_if_index))
19491         ;
19492       else
19493         if (unformat
19494             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
19495         mac_set++;
19496       else if (unformat (i, "sub_id %d", &sub_id))
19497         ;
19498       else
19499         {
19500           clib_warning ("parse error '%U'", format_unformat_error, i);
19501           return -99;
19502         }
19503     }
19504
19505   if (parent_if_index == ~0)
19506     {
19507       errmsg ("missing interface name or sw_if_index");
19508       return -99;
19509     }
19510   if (mac_set == 0)
19511     {
19512       errmsg ("missing remote mac address");
19513       return -99;
19514     }
19515   if (sub_id == ~0)
19516     {
19517       errmsg ("missing sub-interface id");
19518       return -99;
19519     }
19520
19521   M (P2P_ETHERNET_ADD, mp);
19522   mp->parent_if_index = ntohl (parent_if_index);
19523   mp->subif_id = ntohl (sub_id);
19524   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
19525
19526   S (mp);
19527   W (ret);
19528   return ret;
19529 }
19530
19531 static int
19532 api_p2p_ethernet_del (vat_main_t * vam)
19533 {
19534   unformat_input_t *i = vam->input;
19535   vl_api_p2p_ethernet_del_t *mp;
19536   u32 parent_if_index = ~0;
19537   u8 remote_mac[6];
19538   u8 mac_set = 0;
19539   int ret;
19540
19541   clib_memset (remote_mac, 0, sizeof (remote_mac));
19542   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19543     {
19544       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &parent_if_index))
19545         ;
19546       else if (unformat (i, "sw_if_index %d", &parent_if_index))
19547         ;
19548       else
19549         if (unformat
19550             (i, "remote_mac %U", unformat_ethernet_address, remote_mac))
19551         mac_set++;
19552       else
19553         {
19554           clib_warning ("parse error '%U'", format_unformat_error, i);
19555           return -99;
19556         }
19557     }
19558
19559   if (parent_if_index == ~0)
19560     {
19561       errmsg ("missing interface name or sw_if_index");
19562       return -99;
19563     }
19564   if (mac_set == 0)
19565     {
19566       errmsg ("missing remote mac address");
19567       return -99;
19568     }
19569
19570   M (P2P_ETHERNET_DEL, mp);
19571   mp->parent_if_index = ntohl (parent_if_index);
19572   clib_memcpy (mp->remote_mac, remote_mac, sizeof (remote_mac));
19573
19574   S (mp);
19575   W (ret);
19576   return ret;
19577 }
19578
19579 static int
19580 api_lldp_config (vat_main_t * vam)
19581 {
19582   unformat_input_t *i = vam->input;
19583   vl_api_lldp_config_t *mp;
19584   int tx_hold = 0;
19585   int tx_interval = 0;
19586   u8 *sys_name = NULL;
19587   int ret;
19588
19589   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19590     {
19591       if (unformat (i, "system-name %s", &sys_name))
19592         ;
19593       else if (unformat (i, "tx-hold %d", &tx_hold))
19594         ;
19595       else if (unformat (i, "tx-interval %d", &tx_interval))
19596         ;
19597       else
19598         {
19599           clib_warning ("parse error '%U'", format_unformat_error, i);
19600           return -99;
19601         }
19602     }
19603
19604   vec_add1 (sys_name, 0);
19605
19606   M (LLDP_CONFIG, mp);
19607   mp->tx_hold = htonl (tx_hold);
19608   mp->tx_interval = htonl (tx_interval);
19609   clib_memcpy (mp->system_name, sys_name, vec_len (sys_name));
19610   vec_free (sys_name);
19611
19612   S (mp);
19613   W (ret);
19614   return ret;
19615 }
19616
19617 static int
19618 api_sw_interface_set_lldp (vat_main_t * vam)
19619 {
19620   unformat_input_t *i = vam->input;
19621   vl_api_sw_interface_set_lldp_t *mp;
19622   u32 sw_if_index = ~0;
19623   u32 enable = 1;
19624   u8 *port_desc = NULL, *mgmt_oid = NULL;
19625   ip4_address_t ip4_addr;
19626   ip6_address_t ip6_addr;
19627   int ret;
19628
19629   clib_memset (&ip4_addr, 0, sizeof (ip4_addr));
19630   clib_memset (&ip6_addr, 0, sizeof (ip6_addr));
19631
19632   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19633     {
19634       if (unformat (i, "disable"))
19635         enable = 0;
19636       else
19637         if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
19638         ;
19639       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19640         ;
19641       else if (unformat (i, "port-desc %s", &port_desc))
19642         ;
19643       else if (unformat (i, "mgmt-ip4 %U", unformat_ip4_address, &ip4_addr))
19644         ;
19645       else if (unformat (i, "mgmt-ip6 %U", unformat_ip6_address, &ip6_addr))
19646         ;
19647       else if (unformat (i, "mgmt-oid %s", &mgmt_oid))
19648         ;
19649       else
19650         break;
19651     }
19652
19653   if (sw_if_index == ~0)
19654     {
19655       errmsg ("missing interface name or sw_if_index");
19656       return -99;
19657     }
19658
19659   /* Construct the API message */
19660   vec_add1 (port_desc, 0);
19661   vec_add1 (mgmt_oid, 0);
19662   M (SW_INTERFACE_SET_LLDP, mp);
19663   mp->sw_if_index = ntohl (sw_if_index);
19664   mp->enable = enable;
19665   clib_memcpy (mp->port_desc, port_desc, vec_len (port_desc));
19666   clib_memcpy (mp->mgmt_oid, mgmt_oid, vec_len (mgmt_oid));
19667   clib_memcpy (mp->mgmt_ip4, &ip4_addr, sizeof (ip4_addr));
19668   clib_memcpy (mp->mgmt_ip6, &ip6_addr, sizeof (ip6_addr));
19669   vec_free (port_desc);
19670   vec_free (mgmt_oid);
19671
19672   S (mp);
19673   W (ret);
19674   return ret;
19675 }
19676
19677 static int
19678 api_tcp_configure_src_addresses (vat_main_t * vam)
19679 {
19680   vl_api_tcp_configure_src_addresses_t *mp;
19681   unformat_input_t *i = vam->input;
19682   vl_api_address_t first, last;
19683   u8 range_set = 0;
19684   u32 vrf_id = 0;
19685   int ret;
19686
19687   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19688     {
19689       if (unformat (i, "%U - %U",
19690                     unformat_vl_api_address, &first,
19691                     unformat_vl_api_address, &last))
19692         {
19693           if (range_set)
19694             {
19695               errmsg ("one range per message (range already set)");
19696               return -99;
19697             }
19698           range_set = 1;
19699         }
19700       else if (unformat (i, "vrf %d", &vrf_id))
19701         ;
19702       else
19703         break;
19704     }
19705
19706   if (range_set == 0)
19707     {
19708       errmsg ("address range not set");
19709       return -99;
19710     }
19711
19712   M (TCP_CONFIGURE_SRC_ADDRESSES, mp);
19713
19714   mp->vrf_id = ntohl (vrf_id);
19715   clib_memcpy (&mp->first_address, &first, sizeof (first));
19716   clib_memcpy (&mp->last_address, &last, sizeof (last));
19717
19718   S (mp);
19719   W (ret);
19720   return ret;
19721 }
19722
19723 static void vl_api_app_namespace_add_del_reply_t_handler
19724   (vl_api_app_namespace_add_del_reply_t * mp)
19725 {
19726   vat_main_t *vam = &vat_main;
19727   i32 retval = ntohl (mp->retval);
19728   if (vam->async_mode)
19729     {
19730       vam->async_errors += (retval < 0);
19731     }
19732   else
19733     {
19734       vam->retval = retval;
19735       if (retval == 0)
19736         errmsg ("app ns index %d\n", ntohl (mp->appns_index));
19737       vam->result_ready = 1;
19738     }
19739 }
19740
19741 static void vl_api_app_namespace_add_del_reply_t_handler_json
19742   (vl_api_app_namespace_add_del_reply_t * mp)
19743 {
19744   vat_main_t *vam = &vat_main;
19745   vat_json_node_t node;
19746
19747   vat_json_init_object (&node);
19748   vat_json_object_add_int (&node, "retval", ntohl (mp->retval));
19749   vat_json_object_add_uint (&node, "appns_index", ntohl (mp->appns_index));
19750
19751   vat_json_print (vam->ofp, &node);
19752   vat_json_free (&node);
19753
19754   vam->retval = ntohl (mp->retval);
19755   vam->result_ready = 1;
19756 }
19757
19758 static int
19759 api_app_namespace_add_del (vat_main_t * vam)
19760 {
19761   vl_api_app_namespace_add_del_t *mp;
19762   unformat_input_t *i = vam->input;
19763   u8 *ns_id = 0, secret_set = 0, sw_if_index_set = 0;
19764   u32 sw_if_index, ip4_fib_id, ip6_fib_id;
19765   u64 secret;
19766   int ret;
19767
19768   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19769     {
19770       if (unformat (i, "id %_%v%_", &ns_id))
19771         ;
19772       else if (unformat (i, "secret %lu", &secret))
19773         secret_set = 1;
19774       else if (unformat (i, "sw_if_index %d", &sw_if_index))
19775         sw_if_index_set = 1;
19776       else if (unformat (i, "ip4_fib_id %d", &ip4_fib_id))
19777         ;
19778       else if (unformat (i, "ip6_fib_id %d", &ip6_fib_id))
19779         ;
19780       else
19781         break;
19782     }
19783   if (!ns_id || !secret_set || !sw_if_index_set)
19784     {
19785       errmsg ("namespace id, secret and sw_if_index must be set");
19786       return -99;
19787     }
19788   if (vec_len (ns_id) > 64)
19789     {
19790       errmsg ("namespace id too long");
19791       return -99;
19792     }
19793   M (APP_NAMESPACE_ADD_DEL, mp);
19794
19795   clib_memcpy (mp->namespace_id, ns_id, vec_len (ns_id));
19796   mp->namespace_id_len = vec_len (ns_id);
19797   mp->secret = clib_host_to_net_u64 (secret);
19798   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
19799   mp->ip4_fib_id = clib_host_to_net_u32 (ip4_fib_id);
19800   mp->ip6_fib_id = clib_host_to_net_u32 (ip6_fib_id);
19801   vec_free (ns_id);
19802   S (mp);
19803   W (ret);
19804   return ret;
19805 }
19806
19807 static int
19808 api_sock_init_shm (vat_main_t * vam)
19809 {
19810 #if VPP_API_TEST_BUILTIN == 0
19811   unformat_input_t *i = vam->input;
19812   vl_api_shm_elem_config_t *config = 0;
19813   u64 size = 64 << 20;
19814   int rv;
19815
19816   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19817     {
19818       if (unformat (i, "size %U", unformat_memory_size, &size))
19819         ;
19820       else
19821         break;
19822     }
19823
19824   /*
19825    * Canned custom ring allocator config.
19826    * Should probably parse all of this
19827    */
19828   vec_validate (config, 6);
19829   config[0].type = VL_API_VLIB_RING;
19830   config[0].size = 256;
19831   config[0].count = 32;
19832
19833   config[1].type = VL_API_VLIB_RING;
19834   config[1].size = 1024;
19835   config[1].count = 16;
19836
19837   config[2].type = VL_API_VLIB_RING;
19838   config[2].size = 4096;
19839   config[2].count = 2;
19840
19841   config[3].type = VL_API_CLIENT_RING;
19842   config[3].size = 256;
19843   config[3].count = 32;
19844
19845   config[4].type = VL_API_CLIENT_RING;
19846   config[4].size = 1024;
19847   config[4].count = 16;
19848
19849   config[5].type = VL_API_CLIENT_RING;
19850   config[5].size = 4096;
19851   config[5].count = 2;
19852
19853   config[6].type = VL_API_QUEUE;
19854   config[6].count = 128;
19855   config[6].size = sizeof (uword);
19856
19857   rv = vl_socket_client_init_shm (config, 1 /* want_pthread */ );
19858   if (!rv)
19859     vam->client_index_invalid = 1;
19860   return rv;
19861 #else
19862   return -99;
19863 #endif
19864 }
19865
19866 static void
19867 vl_api_session_rules_details_t_handler (vl_api_session_rules_details_t * mp)
19868 {
19869   vat_main_t *vam = &vat_main;
19870
19871   if (mp->is_ip4)
19872     {
19873       print (vam->ofp,
19874              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
19875              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
19876              mp->scope, format_ip4_address, &mp->lcl_ip, mp->lcl_plen,
19877              clib_net_to_host_u16 (mp->lcl_port), format_ip4_address,
19878              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
19879              clib_net_to_host_u32 (mp->action_index), mp->tag);
19880     }
19881   else
19882     {
19883       print (vam->ofp,
19884              "appns %u tp %u scope %d %U/%d %d %U/%d %d action: %d tag: %s",
19885              clib_net_to_host_u32 (mp->appns_index), mp->transport_proto,
19886              mp->scope, format_ip6_address, &mp->lcl_ip, mp->lcl_plen,
19887              clib_net_to_host_u16 (mp->lcl_port), format_ip6_address,
19888              &mp->rmt_ip, mp->rmt_plen, clib_net_to_host_u16 (mp->rmt_port),
19889              clib_net_to_host_u32 (mp->action_index), mp->tag);
19890     }
19891 }
19892
19893 static void
19894 vl_api_session_rules_details_t_handler_json (vl_api_session_rules_details_t *
19895                                              mp)
19896 {
19897   vat_main_t *vam = &vat_main;
19898   vat_json_node_t *node = NULL;
19899   struct in6_addr ip6;
19900   struct in_addr ip4;
19901
19902   if (VAT_JSON_ARRAY != vam->json_tree.type)
19903     {
19904       ASSERT (VAT_JSON_NONE == vam->json_tree.type);
19905       vat_json_init_array (&vam->json_tree);
19906     }
19907   node = vat_json_array_add (&vam->json_tree);
19908   vat_json_init_object (node);
19909
19910   vat_json_object_add_uint (node, "is_ip4", mp->is_ip4 ? 1 : 0);
19911   vat_json_object_add_uint (node, "appns_index",
19912                             clib_net_to_host_u32 (mp->appns_index));
19913   vat_json_object_add_uint (node, "transport_proto", mp->transport_proto);
19914   vat_json_object_add_uint (node, "scope", mp->scope);
19915   vat_json_object_add_uint (node, "action_index",
19916                             clib_net_to_host_u32 (mp->action_index));
19917   vat_json_object_add_uint (node, "lcl_port",
19918                             clib_net_to_host_u16 (mp->lcl_port));
19919   vat_json_object_add_uint (node, "rmt_port",
19920                             clib_net_to_host_u16 (mp->rmt_port));
19921   vat_json_object_add_uint (node, "lcl_plen", mp->lcl_plen);
19922   vat_json_object_add_uint (node, "rmt_plen", mp->rmt_plen);
19923   vat_json_object_add_string_copy (node, "tag", mp->tag);
19924   if (mp->is_ip4)
19925     {
19926       clib_memcpy (&ip4, mp->lcl_ip, sizeof (ip4));
19927       vat_json_object_add_ip4 (node, "lcl_ip", ip4);
19928       clib_memcpy (&ip4, mp->rmt_ip, sizeof (ip4));
19929       vat_json_object_add_ip4 (node, "rmt_ip", ip4);
19930     }
19931   else
19932     {
19933       clib_memcpy (&ip6, mp->lcl_ip, sizeof (ip6));
19934       vat_json_object_add_ip6 (node, "lcl_ip", ip6);
19935       clib_memcpy (&ip6, mp->rmt_ip, sizeof (ip6));
19936       vat_json_object_add_ip6 (node, "rmt_ip", ip6);
19937     }
19938 }
19939
19940 static int
19941 api_session_rule_add_del (vat_main_t * vam)
19942 {
19943   vl_api_session_rule_add_del_t *mp;
19944   unformat_input_t *i = vam->input;
19945   u32 proto = ~0, lcl_port, rmt_port, action = 0, lcl_plen, rmt_plen;
19946   u32 appns_index = 0, scope = 0;
19947   ip4_address_t lcl_ip4, rmt_ip4;
19948   ip6_address_t lcl_ip6, rmt_ip6;
19949   u8 is_ip4 = 1, conn_set = 0;
19950   u8 is_add = 1, *tag = 0;
19951   int ret;
19952
19953   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
19954     {
19955       if (unformat (i, "del"))
19956         is_add = 0;
19957       else if (unformat (i, "add"))
19958         ;
19959       else if (unformat (i, "proto tcp"))
19960         proto = 0;
19961       else if (unformat (i, "proto udp"))
19962         proto = 1;
19963       else if (unformat (i, "appns %d", &appns_index))
19964         ;
19965       else if (unformat (i, "scope %d", &scope))
19966         ;
19967       else if (unformat (i, "tag %_%v%_", &tag))
19968         ;
19969       else
19970         if (unformat
19971             (i, "%U/%d %d %U/%d %d", unformat_ip4_address, &lcl_ip4,
19972              &lcl_plen, &lcl_port, unformat_ip4_address, &rmt_ip4, &rmt_plen,
19973              &rmt_port))
19974         {
19975           is_ip4 = 1;
19976           conn_set = 1;
19977         }
19978       else
19979         if (unformat
19980             (i, "%U/%d %d %U/%d %d", unformat_ip6_address, &lcl_ip6,
19981              &lcl_plen, &lcl_port, unformat_ip6_address, &rmt_ip6, &rmt_plen,
19982              &rmt_port))
19983         {
19984           is_ip4 = 0;
19985           conn_set = 1;
19986         }
19987       else if (unformat (i, "action %d", &action))
19988         ;
19989       else
19990         break;
19991     }
19992   if (proto == ~0 || !conn_set || action == ~0)
19993     {
19994       errmsg ("transport proto, connection and action must be set");
19995       return -99;
19996     }
19997
19998   if (scope > 3)
19999     {
20000       errmsg ("scope should be 0-3");
20001       return -99;
20002     }
20003
20004   M (SESSION_RULE_ADD_DEL, mp);
20005
20006   mp->is_ip4 = is_ip4;
20007   mp->transport_proto = proto;
20008   mp->lcl_port = clib_host_to_net_u16 ((u16) lcl_port);
20009   mp->rmt_port = clib_host_to_net_u16 ((u16) rmt_port);
20010   mp->lcl_plen = lcl_plen;
20011   mp->rmt_plen = rmt_plen;
20012   mp->action_index = clib_host_to_net_u32 (action);
20013   mp->appns_index = clib_host_to_net_u32 (appns_index);
20014   mp->scope = scope;
20015   mp->is_add = is_add;
20016   if (is_ip4)
20017     {
20018       clib_memcpy (mp->lcl_ip, &lcl_ip4, sizeof (lcl_ip4));
20019       clib_memcpy (mp->rmt_ip, &rmt_ip4, sizeof (rmt_ip4));
20020     }
20021   else
20022     {
20023       clib_memcpy (mp->lcl_ip, &lcl_ip6, sizeof (lcl_ip6));
20024       clib_memcpy (mp->rmt_ip, &rmt_ip6, sizeof (rmt_ip6));
20025     }
20026   if (tag)
20027     {
20028       clib_memcpy (mp->tag, tag, vec_len (tag));
20029       vec_free (tag);
20030     }
20031
20032   S (mp);
20033   W (ret);
20034   return ret;
20035 }
20036
20037 static int
20038 api_session_rules_dump (vat_main_t * vam)
20039 {
20040   vl_api_session_rules_dump_t *mp;
20041   vl_api_control_ping_t *mp_ping;
20042   int ret;
20043
20044   if (!vam->json_output)
20045     {
20046       print (vam->ofp, "%=20s", "Session Rules");
20047     }
20048
20049   M (SESSION_RULES_DUMP, mp);
20050   /* send it... */
20051   S (mp);
20052
20053   /* Use a control ping for synchronization */
20054   MPING (CONTROL_PING, mp_ping);
20055   S (mp_ping);
20056
20057   /* Wait for a reply... */
20058   W (ret);
20059   return ret;
20060 }
20061
20062 static int
20063 api_ip_container_proxy_add_del (vat_main_t * vam)
20064 {
20065   vl_api_ip_container_proxy_add_del_t *mp;
20066   unformat_input_t *i = vam->input;
20067   u32 sw_if_index = ~0;
20068   vl_api_prefix_t pfx = { };
20069   u8 is_add = 1;
20070   int ret;
20071
20072   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20073     {
20074       if (unformat (i, "del"))
20075         is_add = 0;
20076       else if (unformat (i, "add"))
20077         ;
20078       if (unformat (i, "%U", unformat_vl_api_prefix, &pfx))
20079         ;
20080       else if (unformat (i, "sw_if_index %u", &sw_if_index))
20081         ;
20082       else
20083         break;
20084     }
20085   if (sw_if_index == ~0 || pfx.len == 0)
20086     {
20087       errmsg ("address and sw_if_index must be set");
20088       return -99;
20089     }
20090
20091   M (IP_CONTAINER_PROXY_ADD_DEL, mp);
20092
20093   mp->sw_if_index = clib_host_to_net_u32 (sw_if_index);
20094   mp->is_add = is_add;
20095   clib_memcpy (&mp->pfx, &pfx, sizeof (pfx));
20096
20097   S (mp);
20098   W (ret);
20099   return ret;
20100 }
20101
20102 static int
20103 api_qos_record_enable_disable (vat_main_t * vam)
20104 {
20105   unformat_input_t *i = vam->input;
20106   vl_api_qos_record_enable_disable_t *mp;
20107   u32 sw_if_index, qs = 0xff;
20108   u8 sw_if_index_set = 0;
20109   u8 enable = 1;
20110   int ret;
20111
20112   while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
20113     {
20114       if (unformat (i, "%U", api_unformat_sw_if_index, vam, &sw_if_index))
20115         sw_if_index_set = 1;
20116       else if (unformat (i, "sw_if_index %d", &sw_if_index))
20117         sw_if_index_set = 1;
20118       else if (unformat (i, "%U", unformat_qos_source, &qs))
20119         ;
20120       else if (unformat (i, "disable"))
20121         enable = 0;
20122       else
20123         {
20124           clib_warning ("parse error '%U'", format_unformat_error, i);
20125           return -99;
20126         }
20127     }
20128
20129   if (sw_if_index_set == 0)
20130     {
20131       errmsg ("missing interface name or sw_if_index");
20132       return -99;
20133     }
20134   if (qs == 0xff)
20135     {
20136       errmsg ("input location must be specified");
20137       return -99;
20138     }
20139
20140   M (QOS_RECORD_ENABLE_DISABLE, mp);
20141
20142   mp->record.sw_if_index = ntohl (sw_if_index);
20143   mp->record.input_source = qs;
20144   mp->enable = enable;
20145
20146   S (mp);
20147   W (ret);
20148   return ret;
20149 }
20150
20151
20152 static int
20153 q_or_quit (vat_main_t * vam)
20154 {
20155 #if VPP_API_TEST_BUILTIN == 0
20156   longjmp (vam->jump_buf, 1);
20157 #endif
20158   return 0;                     /* not so much */
20159 }
20160
20161 static int
20162 q (vat_main_t * vam)
20163 {
20164   return q_or_quit (vam);
20165 }
20166
20167 static int
20168 quit (vat_main_t * vam)
20169 {
20170   return q_or_quit (vam);
20171 }
20172
20173 static int
20174 comment (vat_main_t * vam)
20175 {
20176   return 0;
20177 }
20178
20179 static int
20180 elog_save (vat_main_t * vam)
20181 {
20182 #if VPP_API_TEST_BUILTIN == 0
20183   elog_main_t *em = &vam->elog_main;
20184   unformat_input_t *i = vam->input;
20185   char *file, *chroot_file;
20186   clib_error_t *error;
20187
20188   if (!unformat (i, "%s", &file))
20189     {
20190       errmsg ("expected file name, got `%U'", format_unformat_error, i);
20191       return 0;
20192     }
20193
20194   /* It's fairly hard to get "../oopsie" through unformat; just in case */
20195   if (strstr (file, "..") || index (file, '/'))
20196     {
20197       errmsg ("illegal characters in filename '%s'", file);
20198       return 0;
20199     }
20200
20201   chroot_file = (char *) format (0, "/tmp/%s%c", file, 0);
20202
20203   vec_free (file);
20204
20205   errmsg ("Saving %wd of %wd events to %s",
20206           elog_n_events_in_buffer (em),
20207           elog_buffer_capacity (em), chroot_file);
20208
20209   error = elog_write_file (em, chroot_file, 1 /* flush ring */ );
20210   vec_free (chroot_file);
20211
20212   if (error)
20213     clib_error_report (error);
20214 #else
20215   errmsg ("Use the vpp event loger...");
20216 #endif
20217
20218   return 0;
20219 }
20220
20221 static int
20222 elog_setup (vat_main_t * vam)
20223 {
20224 #if VPP_API_TEST_BUILTIN == 0
20225   elog_main_t *em = &vam->elog_main;
20226   unformat_input_t *i = vam->input;
20227   u32 nevents = 128 << 10;
20228
20229   (void) unformat (i, "nevents %d", &nevents);
20230
20231   elog_init (em, nevents);
20232   vl_api_set_elog_main (em);
20233   vl_api_set_elog_trace_api_messages (1);
20234   errmsg ("Event logger initialized with %u events", nevents);
20235 #else
20236   errmsg ("Use the vpp event loger...");
20237 #endif
20238   return 0;
20239 }
20240
20241 static int
20242 elog_enable (vat_main_t * vam)
20243 {
20244 #if VPP_API_TEST_BUILTIN == 0
20245   elog_main_t *em = &vam->elog_main;
20246
20247   elog_enable_disable (em, 1 /* enable */ );
20248   vl_api_set_elog_trace_api_messages (1);
20249   errmsg ("Event logger enabled...");
20250 #else
20251   errmsg ("Use the vpp event loger...");
20252 #endif
20253   return 0;
20254 }
20255
20256 static int
20257 elog_disable (vat_main_t * vam)
20258 {
20259 #if VPP_API_TEST_BUILTIN == 0
20260   elog_main_t *em = &vam->elog_main;
20261
20262   elog_enable_disable (em, 0 /* enable */ );
20263   vl_api_set_elog_trace_api_messages (1);
20264   errmsg ("Event logger disabled...");
20265 #else
20266   errmsg ("Use the vpp event loger...");
20267 #endif
20268   return 0;
20269 }
20270
20271 static int
20272 statseg (vat_main_t * vam)
20273 {
20274   ssvm_private_t *ssvmp = &vam->stat_segment;
20275   ssvm_shared_header_t *shared_header = ssvmp->sh;
20276   vlib_counter_t **counters;
20277   u64 thread0_index1_packets;
20278   u64 thread0_index1_bytes;
20279   f64 vector_rate, input_rate;
20280   uword *p;
20281
20282   uword *counter_vector_by_name;
20283   if (vam->stat_segment_lockp == 0)
20284     {
20285       errmsg ("Stat segment not mapped...");
20286       return -99;
20287     }
20288
20289   /* look up "/if/rx for sw_if_index 1 as a test */
20290
20291   clib_spinlock_lock (vam->stat_segment_lockp);
20292
20293   counter_vector_by_name = (uword *) shared_header->opaque[1];
20294
20295   p = hash_get_mem (counter_vector_by_name, "/if/rx");
20296   if (p == 0)
20297     {
20298       clib_spinlock_unlock (vam->stat_segment_lockp);
20299       errmsg ("/if/tx not found?");
20300       return -99;
20301     }
20302
20303   /* Fish per-thread vector of combined counters from shared memory */
20304   counters = (vlib_counter_t **) p[0];
20305
20306   if (vec_len (counters[0]) < 2)
20307     {
20308       clib_spinlock_unlock (vam->stat_segment_lockp);
20309       errmsg ("/if/tx vector length %d", vec_len (counters[0]));
20310       return -99;
20311     }
20312
20313   /* Read thread 0 sw_if_index 1 counter */
20314   thread0_index1_packets = counters[0][1].packets;
20315   thread0_index1_bytes = counters[0][1].bytes;
20316
20317   p = hash_get_mem (counter_vector_by_name, "vector_rate");
20318   if (p == 0)
20319     {
20320       clib_spinlock_unlock (vam->stat_segment_lockp);
20321       errmsg ("vector_rate not found?");
20322       return -99;
20323     }
20324
20325   vector_rate = *(f64 *) (p[0]);
20326   p = hash_get_mem (counter_vector_by_name, "input_rate");
20327   if (p == 0)
20328     {
20329       clib_spinlock_unlock (vam->stat_segment_lockp);
20330       errmsg ("input_rate not found?");
20331       return -99;
20332     }
20333   input_rate = *(f64 *) (p[0]);
20334
20335   clib_spinlock_unlock (vam->stat_segment_lockp);
20336
20337   print (vam->ofp, "vector_rate %.2f input_rate %.2f",
20338          vector_rate, input_rate);
20339   print (vam->ofp, "thread 0 sw_if_index 1 rx pkts %lld, bytes %lld",
20340          thread0_index1_packets, thread0_index1_bytes);
20341
20342   return 0;
20343 }
20344
20345 static int
20346 cmd_cmp (void *a1, void *a2)
20347 {
20348   u8 **c1 = a1;
20349   u8 **c2 = a2;
20350
20351   return strcmp ((char *) (c1[0]), (char *) (c2[0]));
20352 }
20353
20354 static int
20355 help (vat_main_t * vam)
20356 {
20357   u8 **cmds = 0;
20358   u8 *name = 0;
20359   hash_pair_t *p;
20360   unformat_input_t *i = vam->input;
20361   int j;
20362
20363   if (unformat (i, "%s", &name))
20364     {
20365       uword *hs;
20366
20367       vec_add1 (name, 0);
20368
20369       hs = hash_get_mem (vam->help_by_name, name);
20370       if (hs)
20371         print (vam->ofp, "usage: %s %s", name, hs[0]);
20372       else
20373         print (vam->ofp, "No such msg / command '%s'", name);
20374       vec_free (name);
20375       return 0;
20376     }
20377
20378   print (vam->ofp, "Help is available for the following:");
20379
20380     /* *INDENT-OFF* */
20381     hash_foreach_pair (p, vam->function_by_name,
20382     ({
20383       vec_add1 (cmds, (u8 *)(p->key));
20384     }));
20385     /* *INDENT-ON* */
20386
20387   vec_sort_with_function (cmds, cmd_cmp);
20388
20389   for (j = 0; j < vec_len (cmds); j++)
20390     print (vam->ofp, "%s", cmds[j]);
20391
20392   vec_free (cmds);
20393   return 0;
20394 }
20395
20396 static int
20397 set (vat_main_t * vam)
20398 {
20399   u8 *name = 0, *value = 0;
20400   unformat_input_t *i = vam->input;
20401
20402   if (unformat (i, "%s", &name))
20403     {
20404       /* The input buffer is a vector, not a string. */
20405       value = vec_dup (i->buffer);
20406       vec_delete (value, i->index, 0);
20407       /* Almost certainly has a trailing newline */
20408       if (value[vec_len (value) - 1] == '\n')
20409         value[vec_len (value) - 1] = 0;
20410       /* Make sure it's a proper string, one way or the other */
20411       vec_add1 (value, 0);
20412       (void) clib_macro_set_value (&vam->macro_main,
20413                                    (char *) name, (char *) value);
20414     }
20415   else
20416     errmsg ("usage: set <name> <value>");
20417
20418   vec_free (name);
20419   vec_free (value);
20420   return 0;
20421 }
20422
20423 static int
20424 unset (vat_main_t * vam)
20425 {
20426   u8 *name = 0;
20427
20428   if (unformat (vam->input, "%s", &name))
20429     if (clib_macro_unset (&vam->macro_main, (char *) name) == 1)
20430       errmsg ("unset: %s wasn't set", name);
20431   vec_free (name);
20432   return 0;
20433 }
20434
20435 typedef struct
20436 {
20437   u8 *name;
20438   u8 *value;
20439 } macro_sort_t;
20440
20441
20442 static int
20443 macro_sort_cmp (void *a1, void *a2)
20444 {
20445   macro_sort_t *s1 = a1;
20446   macro_sort_t *s2 = a2;
20447
20448   return strcmp ((char *) (s1->name), (char *) (s2->name));
20449 }
20450
20451 static int
20452 dump_macro_table (vat_main_t * vam)
20453 {
20454   macro_sort_t *sort_me = 0, *sm;
20455   int i;
20456   hash_pair_t *p;
20457
20458     /* *INDENT-OFF* */
20459     hash_foreach_pair (p, vam->macro_main.the_value_table_hash,
20460     ({
20461       vec_add2 (sort_me, sm, 1);
20462       sm->name = (u8 *)(p->key);
20463       sm->value = (u8 *) (p->value[0]);
20464     }));
20465     /* *INDENT-ON* */
20466
20467   vec_sort_with_function (sort_me, macro_sort_cmp);
20468
20469   if (vec_len (sort_me))
20470     print (vam->ofp, "%-15s%s", "Name", "Value");
20471   else
20472     print (vam->ofp, "The macro table is empty...");
20473
20474   for (i = 0; i < vec_len (sort_me); i++)
20475     print (vam->ofp, "%-15s%s", sort_me[i].name, sort_me[i].value);
20476   return 0;
20477 }
20478
20479 static int
20480 dump_node_table (vat_main_t * vam)
20481 {
20482   int i, j;
20483   vlib_node_t *node, *next_node;
20484
20485   if (vec_len (vam->graph_nodes) == 0)
20486     {
20487       print (vam->ofp, "Node table empty, issue get_node_graph...");
20488       return 0;
20489     }
20490
20491   for (i = 0; i < vec_len (vam->graph_nodes[0]); i++)
20492     {
20493       node = vam->graph_nodes[0][i];
20494       print (vam->ofp, "[%d] %s", i, node->name);
20495       for (j = 0; j < vec_len (node->next_nodes); j++)
20496         {
20497           if (node->next_nodes[j] != ~0)
20498             {
20499               next_node = vam->graph_nodes[0][node->next_nodes[j]];
20500               print (vam->ofp, "  [%d] %s", j, next_node->name);
20501             }
20502         }
20503     }
20504   return 0;
20505 }
20506
20507 static int
20508 value_sort_cmp (void *a1, void *a2)
20509 {
20510   name_sort_t *n1 = a1;
20511   name_sort_t *n2 = a2;
20512
20513   if (n1->value < n2->value)
20514     return -1;
20515   if (n1->value > n2->value)
20516     return 1;
20517   return 0;
20518 }
20519
20520
20521 static int
20522 dump_msg_api_table (vat_main_t * vam)
20523 {
20524   api_main_t *am = vlibapi_get_main ();
20525   name_sort_t *nses = 0, *ns;
20526   hash_pair_t *hp;
20527   int i;
20528
20529   /* *INDENT-OFF* */
20530   hash_foreach_pair (hp, am->msg_index_by_name_and_crc,
20531   ({
20532     vec_add2 (nses, ns, 1);
20533     ns->name = (u8 *)(hp->key);
20534     ns->value = (u32) hp->value[0];
20535   }));
20536   /* *INDENT-ON* */
20537
20538   vec_sort_with_function (nses, value_sort_cmp);
20539
20540   for (i = 0; i < vec_len (nses); i++)
20541     print (vam->ofp, " [%d]: %s", nses[i].value, nses[i].name);
20542   vec_free (nses);
20543   return 0;
20544 }
20545
20546 static int
20547 get_msg_id (vat_main_t * vam)
20548 {
20549   u8 *name_and_crc;
20550   u32 message_index;
20551
20552   if (unformat (vam->input, "%s", &name_and_crc))
20553     {
20554       message_index = vl_msg_api_get_msg_index (name_and_crc);
20555       if (message_index == ~0)
20556         {
20557           print (vam->ofp, " '%s' not found", name_and_crc);
20558           return 0;
20559         }
20560       print (vam->ofp, " '%s' has message index %d",
20561              name_and_crc, message_index);
20562       return 0;
20563     }
20564   errmsg ("name_and_crc required...");
20565   return 0;
20566 }
20567
20568 static int
20569 search_node_table (vat_main_t * vam)
20570 {
20571   unformat_input_t *line_input = vam->input;
20572   u8 *node_to_find;
20573   int j;
20574   vlib_node_t *node, *next_node;
20575   uword *p;
20576
20577   if (vam->graph_node_index_by_name == 0)
20578     {
20579       print (vam->ofp, "Node table empty, issue get_node_graph...");
20580       return 0;
20581     }
20582
20583   while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
20584     {
20585       if (unformat (line_input, "%s", &node_to_find))
20586         {
20587           vec_add1 (node_to_find, 0);
20588           p = hash_get_mem (vam->graph_node_index_by_name, node_to_find);
20589           if (p == 0)
20590             {
20591               print (vam->ofp, "%s not found...", node_to_find);
20592               goto out;
20593             }
20594           node = vam->graph_nodes[0][p[0]];
20595           print (vam->ofp, "[%d] %s", p[0], node->name);
20596           for (j = 0; j < vec_len (node->next_nodes); j++)
20597             {
20598               if (node->next_nodes[j] != ~0)
20599                 {
20600                   next_node = vam->graph_nodes[0][node->next_nodes[j]];
20601                   print (vam->ofp, "  [%d] %s", j, next_node->name);
20602                 }
20603             }
20604         }
20605
20606       else
20607         {
20608           clib_warning ("parse error '%U'", format_unformat_error,
20609                         line_input);
20610           return -99;
20611         }
20612
20613     out:
20614       vec_free (node_to_find);
20615
20616     }
20617
20618   return 0;
20619 }
20620
20621
20622 static int
20623 script (vat_main_t * vam)
20624 {
20625 #if (VPP_API_TEST_BUILTIN==0)
20626   u8 *s = 0;
20627   char *save_current_file;
20628   unformat_input_t save_input;
20629   jmp_buf save_jump_buf;
20630   u32 save_line_number;
20631
20632   FILE *new_fp, *save_ifp;
20633
20634   if (unformat (vam->input, "%s", &s))
20635     {
20636       new_fp = fopen ((char *) s, "r");
20637       if (new_fp == 0)
20638         {
20639           errmsg ("Couldn't open script file %s", s);
20640           vec_free (s);
20641           return -99;
20642         }
20643     }
20644   else
20645     {
20646       errmsg ("Missing script name");
20647       return -99;
20648     }
20649
20650   clib_memcpy (&save_input, &vam->input, sizeof (save_input));
20651   clib_memcpy (&save_jump_buf, &vam->jump_buf, sizeof (save_jump_buf));
20652   save_ifp = vam->ifp;
20653   save_line_number = vam->input_line_number;
20654   save_current_file = (char *) vam->current_file;
20655
20656   vam->input_line_number = 0;
20657   vam->ifp = new_fp;
20658   vam->current_file = s;
20659   do_one_file (vam);
20660
20661   clib_memcpy (&vam->input, &save_input, sizeof (save_input));
20662   clib_memcpy (&vam->jump_buf, &save_jump_buf, sizeof (save_jump_buf));
20663   vam->ifp = save_ifp;
20664   vam->input_line_number = save_line_number;
20665   vam->current_file = (u8 *) save_current_file;
20666   vec_free (s);
20667
20668   return 0;
20669 #else
20670   clib_warning ("use the exec command...");
20671   return -99;
20672 #endif
20673 }
20674
20675 static int
20676 echo (vat_main_t * vam)
20677 {
20678   print (vam->ofp, "%v", vam->input->buffer);
20679   return 0;
20680 }
20681
20682 /* List of API message constructors, CLI names map to api_xxx */
20683 #define foreach_vpe_api_msg                                             \
20684 _(create_loopback,"[mac <mac-addr>] [instance <instance>]")             \
20685 _(sw_interface_dump,"")                                                 \
20686 _(sw_interface_set_flags,                                               \
20687   "<intfc> | sw_if_index <id> admin-up | admin-down link-up | link down") \
20688 _(sw_interface_add_del_address,                                         \
20689   "<intfc> | sw_if_index <id> <ip4-address> | <ip6-address> [del] [del-all] ") \
20690 _(sw_interface_set_rx_mode,                                             \
20691   "<intfc> | sw_if_index <id> [queue <id>] <polling | interrupt | adaptive>") \
20692 _(sw_interface_set_rx_placement,                                        \
20693   "<intfc> | sw_if_index <id> [queue <id>] [worker <id> | main]")       \
20694 _(sw_interface_rx_placement_dump,                                       \
20695   "[<intfc> | sw_if_index <id>]")                                         \
20696 _(sw_interface_set_table,                                               \
20697   "<intfc> | sw_if_index <id> vrf <table-id> [ipv6]")                   \
20698 _(sw_interface_set_mpls_enable,                                         \
20699   "<intfc> | sw_if_index [disable | dis]")                              \
20700 _(sw_interface_set_vpath,                                               \
20701   "<intfc> | sw_if_index <id> enable | disable")                        \
20702 _(sw_interface_set_vxlan_bypass,                                        \
20703   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
20704 _(sw_interface_set_geneve_bypass,                                       \
20705   "<intfc> | sw_if_index <id> [ip4 | ip6] [enable | disable]")          \
20706 _(sw_interface_set_l2_xconnect,                                         \
20707   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
20708   "enable | disable")                                                   \
20709 _(sw_interface_set_l2_bridge,                                           \
20710   "{<intfc> | sw_if_index <id>} bd_id <bridge-domain-id>\n"             \
20711   "[shg <split-horizon-group>] [bvi]\n"                                 \
20712   "enable | disable")                                                   \
20713 _(bridge_domain_set_mac_age, "bd_id <bridge-domain-id> mac-age 0-255")  \
20714 _(bridge_domain_add_del,                                                \
20715   "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") \
20716 _(bridge_domain_dump, "[bd_id <bridge-domain-id>]\n")                   \
20717 _(l2fib_add_del,                                                        \
20718   "mac <mac-addr> bd_id <bridge-domain-id> [del] | sw_if <intfc> | sw_if_index <id> [static] [filter] [bvi] [count <nn>]\n") \
20719 _(l2fib_flush_bd, "bd_id <bridge-domain-id>")                           \
20720 _(l2fib_flush_int, "<intfc> | sw_if_index <id>")                        \
20721 _(l2_flags,                                                             \
20722   "sw_if <intfc> | sw_if_index <id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
20723 _(bridge_flags,                                                         \
20724   "bd_id <bridge-domain-id> [learn] [forward] [uu-flood] [flood] [arp-term] [disable]\n") \
20725 _(tap_create_v2,                                                        \
20726   "id <num> [hw-addr <mac-addr>] [host-ns <name>] [rx-ring-size <num> [tx-ring-size <num>] [host-mtu-size <mtu>] [gso | no-gso]") \
20727 _(tap_delete_v2,                                                        \
20728   "<vpp-if-name> | sw_if_index <id>")                                   \
20729 _(sw_interface_tap_v2_dump, "")                                         \
20730 _(virtio_pci_create,                                                    \
20731   "pci-addr <pci-address> [use_random_mac | hw-addr <mac-addr>] [features <hex-value>] [gso-enabled | csum-offload-enabled]") \
20732 _(virtio_pci_delete,                                                    \
20733   "<vpp-if-name> | sw_if_index <id>")                                   \
20734 _(sw_interface_virtio_pci_dump, "")                                     \
20735 _(bond_create,                                                          \
20736   "[hw-addr <mac-addr>] {round-robin | active-backup | "                \
20737   "broadcast | {lacp | xor} [load-balance { l2 | l23 | l34 }]} "        \
20738   "[id <if-id>]")                                                       \
20739 _(bond_delete,                                                          \
20740   "<vpp-if-name> | sw_if_index <id>")                                   \
20741 _(bond_enslave,                                                         \
20742   "sw_if_index <n> bond <sw_if_index> [is_passive] [is_long_timeout]")  \
20743 _(bond_detach_slave,                                                    \
20744   "sw_if_index <n>")                                                    \
20745  _(sw_interface_set_bond_weight, "<intfc> | sw_if_index <nn> weight <value>") \
20746 _(sw_interface_bond_dump, "")                                           \
20747 _(sw_interface_slave_dump,                                              \
20748   "<vpp-if-name> | sw_if_index <id>")                                   \
20749 _(ip_table_add_del,                                                     \
20750   "table <n> [ipv6] [add | del]\n")                                     \
20751 _(ip_route_add_del,                                                     \
20752   "<addr>/<mask> via <<addr>|<intfc>|sw_if_index <id>|via-label <n>>\n" \
20753   "[table-id <n>] [<intfc> | sw_if_index <id>] [resolve-attempts <n>]\n"\
20754   "[weight <n>] [drop] [local] [classify <n>]  [out-label <n>]\n"       \
20755   "[multipath] [count <n>] [del]")                                      \
20756 _(ip_mroute_add_del,                                                    \
20757   "<src> <grp>/<mask> [table-id <n>]\n"                                 \
20758   "[<intfc> | sw_if_index <id>] [local] [del]")                         \
20759 _(mpls_table_add_del,                                                   \
20760   "table <n> [add | del]\n")                                            \
20761 _(mpls_route_add_del,                                                   \
20762   "<label> <eos> via <addr | next-hop-table <n> | via-label <n> |\n"    \
20763   "lookup-ip4-table <n> | lookup-in-ip6-table <n> |\n"                  \
20764   "l2-input-on <intfc> | l2-input-on sw_if_index <id>>\n"               \
20765   "[<intfc> | sw_if_index <id>] [resolve-attempts <n>] [weight <n>]\n"  \
20766   "[drop] [local] [classify <n>] [out-label <n>] [multipath]\n"         \
20767   "[count <n>] [del]")                                                  \
20768 _(mpls_ip_bind_unbind,                                                  \
20769   "<label> <addr/len>")                                                 \
20770 _(mpls_tunnel_add_del,                                                  \
20771   "[add | del <intfc | sw_if_index <id>>] via <addr | via-label <n>>\n" \
20772   "[<intfc> | sw_if_index <id> | next-hop-table <id>]\n"                \
20773   "[l2-only]  [out-label <n>]")                                         \
20774 _(sr_mpls_policy_add,                                                   \
20775   "bsid <id> [weight <n>] [spray] next <sid> [next <sid>]")             \
20776 _(sr_mpls_policy_del,                                                   \
20777   "bsid <id>")                                                          \
20778 _(bier_table_add_del,                                                   \
20779   "<label> <sub-domain> <set> <bsl> [del]")                             \
20780 _(bier_route_add_del,                                                   \
20781   "<bit-position> <sub-domain> <set> <bsl> via <addr> [table-id <n>]\n" \
20782   "[<intfc> | sw_if_index <id>]"                                        \
20783   "[weight <n>] [del] [multipath]")                                     \
20784 _(sw_interface_set_unnumbered,                                          \
20785   "<intfc> | sw_if_index <id> unnum_if_index <id> [del]")               \
20786 _(create_vlan_subif, "<intfc> | sw_if_index <id> vlan <n>")             \
20787 _(create_subif, "<intfc> | sw_if_index <id> sub_id <n>\n"               \
20788   "[outer_vlan_id <n>][inner_vlan_id <n>]\n"                            \
20789   "[no_tags][one_tag][two_tags][dot1ad][exact_match][default_sub]\n"    \
20790   "[outer_vlan_id_any][inner_vlan_id_any]")                             \
20791 _(ip_table_replace_begin, "table <n> [ipv6]")                           \
20792 _(ip_table_flush, "table <n> [ipv6]")                                   \
20793 _(ip_table_replace_end, "table <n> [ipv6]")                             \
20794 _(set_ip_flow_hash,                                                     \
20795   "vrf <n> [src] [dst] [sport] [dport] [proto] [reverse] [ipv6]")       \
20796 _(sw_interface_ip6_enable_disable,                                      \
20797   "<intfc> | sw_if_index <id> enable | disable")                        \
20798 _(l2_patch_add_del,                                                     \
20799   "rx <intfc> | rx_sw_if_index <id> tx <intfc> | tx_sw_if_index <id>\n" \
20800   "enable | disable")                                                   \
20801 _(sr_localsid_add_del,                                                  \
20802   "(del) address <addr> next_hop <addr> behavior <beh>\n"               \
20803   "fib-table <num> (end.psp) sw_if_index <num>")                        \
20804 _(classify_add_del_table,                                               \
20805   "buckets <nn> [skip <n>] [match <n>] [memory_size <nn-bytes>]\n"      \
20806   " [del] [del-chain] mask <mask-value>\n"                              \
20807   " [l2-miss-next | miss-next | acl-miss-next] <name|nn>\n"             \
20808   " [current-data-flag <n>] [current-data-offset <nn>] [table <nn>]")   \
20809 _(classify_add_del_session,                                             \
20810   "[hit-next|l2-hit-next|acl-hit-next|policer-hit-next] <name|nn>\n"    \
20811   "  table-index <nn> skip_n <nn> match_n <nn> match [hex] [l2]\n"      \
20812   "  [l3 [ip4|ip6]] [action set-ip4-fib-id <nn>]\n"                     \
20813   "  [action set-ip6-fib-id <nn> | action <n> metadata <nn>] [del]")    \
20814 _(classify_set_interface_ip_table,                                      \
20815   "<intfc> | sw_if_index <nn> table <nn>")                              \
20816 _(classify_set_interface_l2_tables,                                     \
20817   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
20818   "  [other-table <nn>]")                                               \
20819 _(get_node_index, "node <node-name")                                    \
20820 _(add_node_next, "node <node-name> next <next-node-name>")              \
20821 _(l2tpv3_create_tunnel,                                                 \
20822   "client_address <ip6-addr> our_address <ip6-addr>\n"                  \
20823   "[local_session_id <nn>][remote_session_id <nn>][local_cookie <nn>]\n" \
20824   "[remote_cookie <nn>]\n[l2-sublayer-preset]\n")                       \
20825 _(l2tpv3_set_tunnel_cookies,                                            \
20826   "<intfc> | sw_if_index <nn> [new_local_cookie <nn>]\n"                \
20827   "[new_remote_cookie <nn>]\n")                                         \
20828 _(l2tpv3_interface_enable_disable,                                      \
20829   "<intfc> | sw_if_index <nn> enable | disable")                        \
20830 _(l2tpv3_set_lookup_key,                                                \
20831   "lookup_v6_src | lookup_v6_dst | lookup_session_id")                  \
20832 _(sw_if_l2tpv3_tunnel_dump, "")                                         \
20833 _(vxlan_offload_rx,                                                     \
20834   "hw { <interface name> | hw_if_index <nn>} "                          \
20835   "rx { <vxlan tunnel name> | sw_if_index <nn> } [del]")                \
20836 _(vxlan_add_del_tunnel,                                                 \
20837   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
20838   "{ <intfc> | mcast_sw_if_index <nn> } [instance <id>]}\n"             \
20839   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
20840 _(geneve_add_del_tunnel,                                                \
20841   "src <ip-addr> { dst <ip-addr> | group <mcast-ip-addr>\n"             \
20842   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
20843   "vni <vni> [encap-vrf-id <nn>] [decap-next <l2|nn>] [del]")           \
20844 _(vxlan_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                    \
20845 _(geneve_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                   \
20846 _(gre_tunnel_add_del,                                                   \
20847   "src <ip-addr> dst <ip-addr> [outer-fib-id <nn>] [instance <n>]\n"    \
20848   "[teb | erspan <session-id>] [del]")                                  \
20849 _(gre_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                      \
20850 _(l2_fib_clear_table, "")                                               \
20851 _(l2_interface_efp_filter, "sw_if_index <nn> enable | disable")         \
20852 _(l2_interface_vlan_tag_rewrite,                                        \
20853   "<intfc> | sw_if_index <nn> \n"                                       \
20854   "[disable][push-[1|2]][pop-[1|2]][translate-1-[1|2]] \n"              \
20855   "[translate-2-[1|2]] [push_dot1q 0] tag1 <nn> tag2 <nn>")             \
20856 _(create_vhost_user_if,                                                 \
20857         "socket <filename> [server] [renumber <dev_instance>] "         \
20858         "[disable_mrg_rxbuf] [disable_indirect_desc] [gso] "            \
20859         "[mac <mac_address>]")                                          \
20860 _(modify_vhost_user_if,                                                 \
20861         "<intfc> | sw_if_index <nn> socket <filename>\n"                \
20862         "[server] [renumber <dev_instance>] [gso]")                     \
20863 _(delete_vhost_user_if, "<intfc> | sw_if_index <nn>")                   \
20864 _(sw_interface_vhost_user_dump, "")                                     \
20865 _(show_version, "")                                                     \
20866 _(show_threads, "")                                                     \
20867 _(vxlan_gpe_add_del_tunnel,                                             \
20868   "local <addr> remote <addr>  | group <mcast-ip-addr>\n"               \
20869   "{ <intfc> | mcast_sw_if_index <nn> } }\n"                            \
20870   "vni <nn> [encap-vrf-id <nn>] [decap-vrf-id <nn>]\n"                  \
20871   "[next-ip4][next-ip6][next-ethernet] [next-nsh] [del]\n")             \
20872 _(vxlan_gpe_tunnel_dump, "[<intfc> | sw_if_index <nn>]")                \
20873 _(l2_fib_table_dump, "bd_id <bridge-domain-id>")                        \
20874 _(interface_name_renumber,                                              \
20875   "<intfc> | sw_if_index <nn> new_show_dev_instance <nn>")              \
20876 _(input_acl_set_interface,                                              \
20877   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
20878   "  [l2-table <nn>] [del]")                                            \
20879 _(want_l2_macs_events, "[disable] [learn-limit <n>] [scan-delay <n>] [max-entries <n>]") \
20880 _(ip_address_dump, "(ipv4 | ipv6) (<intfc> | sw_if_index <id>)")        \
20881 _(ip_dump, "ipv4 | ipv6")                                               \
20882 _(ipsec_spd_add_del, "spd_id <n> [del]")                                \
20883 _(ipsec_interface_add_del_spd, "(<intfc> | sw_if_index <id>)\n"         \
20884   "  spid_id <n> ")                                                     \
20885 _(ipsec_sad_entry_add_del, "sad_id <n> spi <n> crypto_alg <alg>\n"      \
20886   "  crypto_key <hex> tunnel_src <ip4|ip6> tunnel_dst <ip4|ip6>\n"      \
20887   "  integ_alg <alg> integ_key <hex>")                                  \
20888 _(ipsec_spd_entry_add_del, "spd_id <n> priority <n> action <action>\n"  \
20889   "  (inbound|outbound) [sa_id <n>] laddr_start <ip4|ip6>\n"            \
20890   "  laddr_stop <ip4|ip6> raddr_start <ip4|ip6> raddr_stop <ip4|ip6>\n" \
20891   "  [lport_start <n> lport_stop <n>] [rport_start <n> rport_stop <n>]" ) \
20892 _(ipsec_tunnel_if_add_del, "local_spi <n> remote_spi <n>\n"             \
20893   "  crypto_alg <alg> local_crypto_key <hex> remote_crypto_key <hex>\n" \
20894   "  integ_alg <alg> local_integ_key <hex> remote_integ_key <hex>\n"    \
20895   "  local_ip <addr> remote_ip <addr> [esn] [anti_replay] [del]\n"      \
20896   "  [instance <n>]")     \
20897 _(ipsec_sa_dump, "[sa_id <n>]")                                         \
20898 _(ipsec_tunnel_if_set_sa, "<intfc> sa_id <n> <inbound|outbound>\n")     \
20899 _(delete_loopback,"sw_if_index <nn>")                                   \
20900 _(bd_ip_mac_add_del, "bd_id <bridge-domain-id> <ip4/6-addr> <mac-addr> [del]") \
20901 _(bd_ip_mac_flush, "bd_id <bridge-domain-id>")                          \
20902 _(bd_ip_mac_dump, "[bd_id] <bridge-domain-id>")                         \
20903 _(want_interface_events,  "enable|disable")                             \
20904 _(get_first_msg_id, "client <name>")                                    \
20905 _(cop_interface_enable_disable, "<intfc> | sw_if_index <nn> [disable]") \
20906 _(cop_whitelist_enable_disable, "<intfc> | sw_if_index <nn>\n"          \
20907   "fib-id <nn> [ip4][ip6][default]")                                    \
20908 _(get_node_graph, " ")                                                  \
20909 _(sw_interface_clear_stats,"<intfc> | sw_if_index <nn>")                \
20910 _(ioam_enable, "[trace] [pow] [ppc <encap|decap>]")                     \
20911 _(ioam_disable, "")                                                     \
20912 _(one_add_del_locator_set, "locator-set <locator_name> [iface <intf> |" \
20913                             " sw_if_index <sw_if_index> p <priority> "  \
20914                             "w <weight>] [del]")                        \
20915 _(one_add_del_locator, "locator-set <locator_name> "                    \
20916                         "iface <intf> | sw_if_index <sw_if_index> "     \
20917                         "p <priority> w <weight> [del]")                \
20918 _(one_add_del_local_eid,"vni <vni> eid "                                \
20919                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
20920                          "locator-set <locator_name> [del]"             \
20921                          "[key-id sha1|sha256 secret-key <secret-key>]")\
20922 _(one_add_del_map_resolver, "<ip4|6-addr> [del]")                       \
20923 _(one_add_del_map_server, "<ip4|6-addr> [del]")                         \
20924 _(one_enable_disable, "enable|disable")                                 \
20925 _(one_map_register_enable_disable, "enable|disable")                    \
20926 _(one_map_register_fallback_threshold, "<value>")                       \
20927 _(one_rloc_probe_enable_disable, "enable|disable")                      \
20928 _(one_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "       \
20929                                "[seid <seid>] "                         \
20930                                "rloc <locator> p <prio> "               \
20931                                "w <weight> [rloc <loc> ... ] "          \
20932                                "action <action> [del-all]")             \
20933 _(one_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "    \
20934                           "<local-eid>")                                \
20935 _(one_pitr_set_locator_set, "locator-set <loc-set-name> | del")         \
20936 _(one_use_petr, "ip-address> | disable")                                \
20937 _(one_map_request_mode, "src-dst|dst-only")                             \
20938 _(one_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")            \
20939 _(one_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")               \
20940 _(one_locator_set_dump, "[local | remote]")                             \
20941 _(one_locator_dump, "ls_index <index> | ls_name <name>")                \
20942 _(one_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "       \
20943                        "[local] | [remote]")                            \
20944 _(one_add_del_ndp_entry, "[del] mac <mac> bd <bd> ip6 <ip6>")           \
20945 _(one_ndp_bd_get, "")                                                   \
20946 _(one_ndp_entries_get, "bd <bridge-domain>")                            \
20947 _(one_add_del_l2_arp_entry, "[del] mac <mac> bd <bd> ip4 <ip4>")        \
20948 _(one_l2_arp_bd_get, "")                                                \
20949 _(one_l2_arp_entries_get, "bd <bridge-domain>")                         \
20950 _(one_stats_enable_disable, "enable|disable")                           \
20951 _(show_one_stats_enable_disable, "")                                    \
20952 _(one_eid_table_vni_dump, "")                                           \
20953 _(one_eid_table_map_dump, "l2|l3")                                      \
20954 _(one_map_resolver_dump, "")                                            \
20955 _(one_map_server_dump, "")                                              \
20956 _(one_adjacencies_get, "vni <vni>")                                     \
20957 _(one_nsh_set_locator_set, "[del] ls <locator-set-name>")               \
20958 _(show_one_rloc_probe_state, "")                                        \
20959 _(show_one_map_register_state, "")                                      \
20960 _(show_one_status, "")                                                  \
20961 _(one_stats_dump, "")                                                   \
20962 _(one_stats_flush, "")                                                  \
20963 _(one_get_map_request_itr_rlocs, "")                                    \
20964 _(one_map_register_set_ttl, "<ttl>")                                    \
20965 _(one_set_transport_protocol, "udp|api")                                \
20966 _(one_get_transport_protocol, "")                                       \
20967 _(one_enable_disable_xtr_mode, "enable|disable")                        \
20968 _(one_show_xtr_mode, "")                                                \
20969 _(one_enable_disable_pitr_mode, "enable|disable")                       \
20970 _(one_show_pitr_mode, "")                                               \
20971 _(one_enable_disable_petr_mode, "enable|disable")                       \
20972 _(one_show_petr_mode, "")                                               \
20973 _(show_one_nsh_mapping, "")                                             \
20974 _(show_one_pitr, "")                                                    \
20975 _(show_one_use_petr, "")                                                \
20976 _(show_one_map_request_mode, "")                                        \
20977 _(show_one_map_register_ttl, "")                                        \
20978 _(show_one_map_register_fallback_threshold, "")                         \
20979 _(lisp_add_del_locator_set, "locator-set <locator_name> [iface <intf> |"\
20980                             " sw_if_index <sw_if_index> p <priority> "  \
20981                             "w <weight>] [del]")                        \
20982 _(lisp_add_del_locator, "locator-set <locator_name> "                   \
20983                         "iface <intf> | sw_if_index <sw_if_index> "     \
20984                         "p <priority> w <weight> [del]")                \
20985 _(lisp_add_del_local_eid,"vni <vni> eid "                               \
20986                          "<ipv4|ipv6>/<prefix> | <L2 address> "         \
20987                          "locator-set <locator_name> [del]"             \
20988                          "[key-id sha1|sha256 secret-key <secret-key>]") \
20989 _(lisp_add_del_map_resolver, "<ip4|6-addr> [del]")                      \
20990 _(lisp_add_del_map_server, "<ip4|6-addr> [del]")                        \
20991 _(lisp_enable_disable, "enable|disable")                                \
20992 _(lisp_map_register_enable_disable, "enable|disable")                   \
20993 _(lisp_rloc_probe_enable_disable, "enable|disable")                     \
20994 _(lisp_add_del_remote_mapping, "add|del vni <vni> eid <dest-eid> "      \
20995                                "[seid <seid>] "                         \
20996                                "rloc <locator> p <prio> "               \
20997                                "w <weight> [rloc <loc> ... ] "          \
20998                                "action <action> [del-all]")             \
20999 _(lisp_add_del_adjacency, "add|del vni <vni> reid <remote-eid> leid "   \
21000                           "<local-eid>")                                \
21001 _(lisp_pitr_set_locator_set, "locator-set <loc-set-name> | del")        \
21002 _(lisp_use_petr, "<ip-address> | disable")                              \
21003 _(lisp_map_request_mode, "src-dst|dst-only")                            \
21004 _(lisp_add_del_map_request_itr_rlocs, "<loc-set-name> [del]")           \
21005 _(lisp_eid_table_add_del_map, "[del] vni <vni> vrf <vrf>")              \
21006 _(lisp_locator_set_dump, "[local | remote]")                            \
21007 _(lisp_locator_dump, "ls_index <index> | ls_name <name>")               \
21008 _(lisp_eid_table_dump, "[eid <ipv4|ipv6>/<prefix> | <mac>] [vni] "      \
21009                        "[local] | [remote]")                            \
21010 _(lisp_eid_table_vni_dump, "")                                          \
21011 _(lisp_eid_table_map_dump, "l2|l3")                                     \
21012 _(lisp_map_resolver_dump, "")                                           \
21013 _(lisp_map_server_dump, "")                                             \
21014 _(lisp_adjacencies_get, "vni <vni>")                                    \
21015 _(gpe_fwd_entry_vnis_get, "")                                           \
21016 _(gpe_native_fwd_rpaths_get, "ip4 | ip6")                               \
21017 _(gpe_add_del_native_fwd_rpath, "[del] via <nh-ip-addr> [iface] "       \
21018                                 "[table <table-id>]")                   \
21019 _(lisp_gpe_fwd_entries_get, "vni <vni>")                                \
21020 _(lisp_gpe_fwd_entry_path_dump, "index <fwd_entry_index>")              \
21021 _(gpe_set_encap_mode, "lisp|vxlan")                                     \
21022 _(gpe_get_encap_mode, "")                                               \
21023 _(lisp_gpe_add_del_iface, "up|down")                                    \
21024 _(lisp_gpe_enable_disable, "enable|disable")                            \
21025 _(lisp_gpe_add_del_fwd_entry, "reid <eid> [leid <eid>] vni <vni>"       \
21026   "vrf/bd <dp_table> loc-pair <lcl_loc> <rmt_loc> w <weight>... [del]") \
21027 _(show_lisp_rloc_probe_state, "")                                       \
21028 _(show_lisp_map_register_state, "")                                     \
21029 _(show_lisp_status, "")                                                 \
21030 _(lisp_get_map_request_itr_rlocs, "")                                   \
21031 _(show_lisp_pitr, "")                                                   \
21032 _(show_lisp_use_petr, "")                                               \
21033 _(show_lisp_map_request_mode, "")                                       \
21034 _(af_packet_create, "name <host interface name> [hw_addr <mac>]")       \
21035 _(af_packet_delete, "name <host interface name>")                       \
21036 _(af_packet_dump, "")                                                   \
21037 _(policer_add_del, "name <policer name> <params> [del]")                \
21038 _(policer_dump, "[name <policer name>]")                                \
21039 _(policer_classify_set_interface,                                       \
21040   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
21041   "  [l2-table <nn>] [del]")                                            \
21042 _(policer_classify_dump, "type [ip4|ip6|l2]")                           \
21043 _(netmap_create, "name <interface name> [hw-addr <mac>] [pipe] "        \
21044     "[master|slave]")                                                   \
21045 _(netmap_delete, "name <interface name>")                               \
21046 _(mpls_tunnel_dump, "tunnel_index <tunnel-id>")                         \
21047 _(mpls_table_dump, "")                                                  \
21048 _(mpls_route_dump, "table-id <ID>")                                     \
21049 _(classify_table_ids, "")                                               \
21050 _(classify_table_by_interface, "sw_if_index <sw_if_index>")             \
21051 _(classify_table_info, "table_id <nn>")                                 \
21052 _(classify_session_dump, "table_id <nn>")                               \
21053 _(set_ipfix_exporter, "collector_address <ip4> [collector_port <nn>] "  \
21054     "src_address <ip4> [vrf_id <nn>] [path_mtu <nn>] "                  \
21055     "[template_interval <nn>] [udp_checksum]")                          \
21056 _(ipfix_exporter_dump, "")                                              \
21057 _(set_ipfix_classify_stream, "[domain <domain-id>] [src_port <src-port>]") \
21058 _(ipfix_classify_stream_dump, "")                                       \
21059 _(ipfix_classify_table_add_del, "table <table-index> ip4|ip6 [tcp|udp]") \
21060 _(ipfix_classify_table_dump, "")                                        \
21061 _(sw_interface_span_enable_disable, "[l2] [src <intfc> | src_sw_if_index <id>] [disable | [[dst <intfc> | dst_sw_if_index <id>] [both|rx|tx]]]") \
21062 _(sw_interface_span_dump, "[l2]")                                           \
21063 _(get_next_index, "node-name <node-name> next-node-name <node-name>")   \
21064 _(pg_create_interface, "if_id <nn> [gso-enabled gso-size <size>]")      \
21065 _(pg_capture, "if_id <nnn> pcap <file_name> count <nnn> [disable]")     \
21066 _(pg_enable_disable, "[stream <id>] disable")                           \
21067 _(ip_source_and_port_range_check_add_del,                               \
21068   "<ip-addr>/<mask> range <nn>-<nn> vrf <id>")                          \
21069 _(ip_source_and_port_range_check_interface_add_del,                     \
21070   "<intf> | sw_if_index <nn> [tcp-out-vrf <id>] [tcp-in-vrf <id>]"      \
21071   "[udp-in-vrf <id>] [udp-out-vrf <id>]")                               \
21072 _(delete_subif,"<intfc> | sw_if_index <nn>")                            \
21073 _(l2_interface_pbb_tag_rewrite,                                         \
21074   "<intfc> | sw_if_index <nn> \n"                                       \
21075   "[disable | push | pop | translate_pbb_stag <outer_tag>] \n"          \
21076   "dmac <mac> smac <mac> sid <nn> [vlanid <nn>]")                       \
21077 _(set_punt, "protocol <l4-protocol> [ip <ver>] [port <l4-port>] [del]")     \
21078 _(flow_classify_set_interface,                                          \
21079   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>] [del]") \
21080 _(flow_classify_dump, "type [ip4|ip6]")                                 \
21081 _(ip_table_dump, "")                                                    \
21082 _(ip_route_dump, "table-id [ip4|ip6]")                                  \
21083 _(ip_mtable_dump, "")                                                   \
21084 _(ip_mroute_dump, "table-id [ip4|ip6]")                                 \
21085 _(feature_enable_disable, "arc_name <arc_name> "                        \
21086   "feature_name <feature_name> <intfc> | sw_if_index <nn> [disable]")   \
21087 _(feature_gso_enable_disable, "<intfc> | sw_if_index <nn> "             \
21088   "[enable | disable] ")                                                \
21089 _(sw_interface_tag_add_del, "<intfc> | sw_if_index <nn> tag <text>"     \
21090 "[disable]")                                                            \
21091 _(sw_interface_add_del_mac_address, "<intfc> | sw_if_index <nn> "       \
21092   "mac <mac-address> [del]")                                            \
21093 _(l2_xconnect_dump, "")                                                 \
21094 _(hw_interface_set_mtu, "<intfc> | hw_if_index <nn> mtu <nn>")        \
21095 _(sw_interface_get_table, "<intfc> | sw_if_index <id> [ipv6]")          \
21096 _(p2p_ethernet_add, "<intfc> | sw_if_index <nn> remote_mac <mac-address> sub_id <id>") \
21097 _(p2p_ethernet_del, "<intfc> | sw_if_index <nn> remote_mac <mac-address>") \
21098 _(lldp_config, "system-name <name> tx-hold <nn> tx-interval <nn>") \
21099 _(sw_interface_set_lldp, "<intfc> | sw_if_index <nn> [port-desc <description>]\n" \
21100   " [mgmt-ip4 <ip4>] [mgmt-ip6 <ip6>] [mgmt-oid <object id>] [disable]") \
21101 _(tcp_configure_src_addresses, "<ip4|6>first-<ip4|6>last [vrf <id>]")   \
21102 _(sock_init_shm, "size <nnn>")                                          \
21103 _(app_namespace_add_del, "[add] id <ns-id> secret <nn> sw_if_index <nn>")\
21104 _(session_rule_add_del, "[add|del] proto <tcp/udp> <lcl-ip>/<plen> "    \
21105   "<lcl-port> <rmt-ip>/<plen> <rmt-port> action <nn>")                  \
21106 _(session_rules_dump, "")                                               \
21107 _(ip_container_proxy_add_del, "[add|del] <address> <sw_if_index>")      \
21108 _(output_acl_set_interface,                                             \
21109   "<intfc> | sw_if_index <nn> [ip4-table <nn>] [ip6-table <nn>]\n"      \
21110   "  [l2-table <nn>] [del]")                                            \
21111 _(qos_record_enable_disable, "<record-source> <intfc> | sw_if_index <id> [disable]")
21112
21113 /* List of command functions, CLI names map directly to functions */
21114 #define foreach_cli_function                                    \
21115 _(comment, "usage: comment <ignore-rest-of-line>")              \
21116 _(dump_interface_table, "usage: dump_interface_table")          \
21117 _(dump_sub_interface_table, "usage: dump_sub_interface_table")  \
21118 _(dump_ipv4_table, "usage: dump_ipv4_table")                    \
21119 _(dump_ipv6_table, "usage: dump_ipv6_table")                    \
21120 _(dump_macro_table, "usage: dump_macro_table ")                 \
21121 _(dump_node_table, "usage: dump_node_table")                    \
21122 _(dump_msg_api_table, "usage: dump_msg_api_table")              \
21123 _(elog_setup, "usage: elog_setup [nevents, default 128K]")      \
21124 _(elog_disable, "usage: elog_disable")                          \
21125 _(elog_enable, "usage: elog_enable")                            \
21126 _(elog_save, "usage: elog_save <filename>")                     \
21127 _(get_msg_id, "usage: get_msg_id name_and_crc")                 \
21128 _(echo, "usage: echo <message>")                                \
21129 _(exec, "usage: exec <vpe-debug-CLI-command>")                  \
21130 _(exec_inband, "usage: exec_inband <vpe-debug-CLI-command>")    \
21131 _(help, "usage: help")                                          \
21132 _(q, "usage: quit")                                             \
21133 _(quit, "usage: quit")                                          \
21134 _(search_node_table, "usage: search_node_table <name>...")      \
21135 _(set, "usage: set <variable-name> <value>")                    \
21136 _(script, "usage: script <file-name>")                          \
21137 _(statseg, "usage: statseg")                                    \
21138 _(unset, "usage: unset <variable-name>")
21139
21140 #define _(N,n)                                  \
21141     static void vl_api_##n##_t_handler_uni      \
21142     (vl_api_##n##_t * mp)                       \
21143     {                                           \
21144         vat_main_t * vam = &vat_main;           \
21145         if (vam->json_output) {                 \
21146             vl_api_##n##_t_handler_json(mp);    \
21147         } else {                                \
21148             vl_api_##n##_t_handler(mp);         \
21149         }                                       \
21150     }
21151 foreach_vpe_api_reply_msg;
21152 #if VPP_API_TEST_BUILTIN == 0
21153 foreach_standalone_reply_msg;
21154 #endif
21155 #undef _
21156
21157 void
21158 vat_api_hookup (vat_main_t * vam)
21159 {
21160 #define _(N,n)                                                  \
21161     vl_msg_api_set_handlers(VL_API_##N, #n,                     \
21162                            vl_api_##n##_t_handler_uni,          \
21163                            vl_noop_handler,                     \
21164                            vl_api_##n##_t_endian,               \
21165                            vl_api_##n##_t_print,                \
21166                            sizeof(vl_api_##n##_t), 1);
21167   foreach_vpe_api_reply_msg;
21168 #if VPP_API_TEST_BUILTIN == 0
21169   foreach_standalone_reply_msg;
21170 #endif
21171 #undef _
21172
21173 #if (VPP_API_TEST_BUILTIN==0)
21174   vl_msg_api_set_first_available_msg_id (VL_MSG_FIRST_AVAILABLE);
21175
21176   vam->sw_if_index_by_interface_name = hash_create_string (0, sizeof (uword));
21177
21178   vam->function_by_name = hash_create_string (0, sizeof (uword));
21179
21180   vam->help_by_name = hash_create_string (0, sizeof (uword));
21181 #endif
21182
21183   /* API messages we can send */
21184 #define _(n,h) hash_set_mem (vam->function_by_name, #n, api_##n);
21185   foreach_vpe_api_msg;
21186 #undef _
21187
21188   /* Help strings */
21189 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
21190   foreach_vpe_api_msg;
21191 #undef _
21192
21193   /* CLI functions */
21194 #define _(n,h) hash_set_mem (vam->function_by_name, #n, n);
21195   foreach_cli_function;
21196 #undef _
21197
21198   /* Help strings */
21199 #define _(n,h) hash_set_mem (vam->help_by_name, #n, h);
21200   foreach_cli_function;
21201 #undef _
21202 }
21203
21204 #if VPP_API_TEST_BUILTIN
21205 static clib_error_t *
21206 vat_api_hookup_shim (vlib_main_t * vm)
21207 {
21208   vat_api_hookup (&vat_main);
21209   return 0;
21210 }
21211
21212 VLIB_API_INIT_FUNCTION (vat_api_hookup_shim);
21213 #endif
21214
21215 /*
21216  * fd.io coding-style-patch-verification: ON
21217  *
21218  * Local Variables:
21219  * eval: (c-set-style "gnu")
21220  * End:
21221  */